diff --git a/.gitattributes b/.gitattributes index 07764a7..a2eabde 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -* text eol=lf \ No newline at end of file +* text eol=lf +*.png binary \ No newline at end of file diff --git a/.github/workflows/extension.yml b/.github/workflows/extension.yml new file mode 100644 index 0000000..ad8ff4c --- /dev/null +++ b/.github/workflows/extension.yml @@ -0,0 +1,21 @@ +name: Build Extension +on: + push: + branches: [ rust-rewrite ] + pull_request: + branches: [ rust-rewrite ] +jobs: + build-vscode-extension: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: npm i + - uses: HaaLeo/publish-vscode-extension@v0 + id: vsce_build + with: + pat: 'sample text' + dryRun: true + - uses: actions/upload-artifact@v2 + with: + name: vscode-mc-shader.vsix + path: ${{ steps.vsce_build.outputs.vsixPath }} \ No newline at end of file diff --git a/.github/workflows/lsif.yml b/.github/workflows/lsif.yml new file mode 100644 index 0000000..1192789 --- /dev/null +++ b/.github/workflows/lsif.yml @@ -0,0 +1,14 @@ +name: LSIF +on: + - push +jobs: + index: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Generate LSIF data + uses: sourcegraph/lsif-rust-action@main + - name: Upload LSIF data + uses: sourcegraph/lsif-upload-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a15ea1d..fbe234e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,12 +35,19 @@ jobs: - os: ubuntu-18.04 target: x86_64-unknown-linux-gnu dir: server/mcshader-lsp + artifact: x86_64-unknown-linux-gnu - os: windows-latest - target: x86_64-windows-msvc.exe + target: x86_64-pc-windows-msvc dir: server/mcshader-lsp.exe - - os: macos-10.15 + artifact: x86_64-windows-msvc.exe + - os: macos-11 target: x86_64-apple-darwin dir: server/mcshader-lsp + artifact: x86_64-apple-darwin + - os: macos-11 + target: aarch64-apple-darwin + dir: server/mcshader-lsp + artifact: aarch64-apple-darwin steps: - uses: actions/checkout@v2 - name: Install latest nightly @@ -48,8 +55,10 @@ jobs: with: toolchain: nightly default: true + target: ${{ matrix.platforms.target }} + override: true - name: Build server - run: cargo build --release --out-dir . -Z unstable-options + run: cargo build --release --target ${{ matrix.platforms.target }} --out-dir . -Z unstable-options - name: Upload release file uses: actions/upload-release-asset@v1 env: @@ -57,7 +66,7 @@ jobs: with: upload_url: ${{ needs.empty-release.outputs.upload_url }} asset_path: ${{ matrix.platforms.dir }} - asset_name: mcshader-lsp-${{ matrix.platforms.target }} + asset_name: mcshader-lsp-${{ matrix.platforms.artifact }} asset_content_type: application/octet-stream release-vscode-extension: runs-on: ubuntu-20.04 diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index d9e762f..8c3e4ee 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -8,16 +8,44 @@ env: CARGO_TERM_COLOR: always jobs: build-and-test: - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.platforms.os }} defaults: run: working-directory: server strategy: matrix: - os: [ ubuntu-20.04, windows-latest, macos-10.15 ] + platforms: + - os: ubuntu-18.04 + target: x86_64-unknown-linux-gnu + dir: server/mcshader-lsp + artifact: x86_64-unknown-linux-gnu + - os: windows-latest + target: x86_64-pc-windows-msvc + dir: server/mcshader-lsp.exe + artifact: x86_64-windows-msvc.exe + - os: macos-11 + target: x86_64-apple-darwin + dir: server/mcshader-lsp + artifact: x86_64-apple-darwin + - os: macos-11 + target: aarch64-apple-darwin + dir: server/mcshader-lsp + artifact: aarch64-apple-darwin steps: - uses: actions/checkout@v2 + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + default: true + target: ${{ matrix.platforms.target }} + override: true - name: Build server - run: cargo build + run: cargo build --target ${{ matrix.platforms.target }} --out-dir . -Z unstable-options + - uses: actions/upload-artifact@v2 + with: + name: mcshader-lsp-${{ matrix.platforms.artifact }} + path: ${{ matrix.platforms.dir }} - name: Run tests - run: cargo test + run: cargo test --target ${{ matrix.platforms.target }} + if: ${{ matrix.platforms.target != 'aarch64-apple-darwin' }} diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..0cb1099 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,3 @@ +edition = "2021" +fn_args_layout = "compressed" +max_width = 140 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bc78cd..d7e089d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,106 @@ All notable changes to the "vscode-mc-shader" extension will be documented in th The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +## [0.9.9] + +### Added + +- Support for mod world folders, outside the standard world{-1,0,1}. +- Support for compute shader files ending in \_a to \_z. + +### Fixed + +- Crash when running with eglot as LSP client. +- Extension icon client not displaying (encoding issue). + +## [0.9.8] + +### Fixed + +- NVIDIA diagnostics line offset off-by-one due to confusion with erroneous (non-proper) GLSL files resulting in both -1 and -2 offsets appearing to be valid when only the former is. +- Non-toplevel files being treated as toplevel files when they have .fsh/.vsh/etc and not imported into a valid toplevel file. +- Fix issue in the depth-first-search iterator when a file is imported twice into another file with a different include in between. + +## [0.9.7] + +### Fixed + +- Fixed bad release tag format +- Fixed extension silently failing on activation + +## [0.9.6] + +### Added + +- MacOS M1 binary releases +- AMD OpenGL driver diagnostics output support. AMD linting is a-go 🚀 +- Tree-sitter based go-to-definition/find-references/document symbols. Currently disabled until stabilized + +### Fixed + +- Another `#include` merging bug when a file is imported twice into another file at different lines + +## [0.9.5] + +### Added + +- Filesystem watcher reads custom defined file associations + +### Fixed + +- Fixed `#include` merging for when file is merged twice that would normally be `#ifdef` guarded. Please see commit message of [551380a](https://github.com/Strum355/mcshader-lsp/commit/551380a6ed00709287460b7d8c88e7803956052c) for detailed explanation + +## [0.9.4] + +### Fixed + +- `#include` merging when project consists of files with both CRLF and LF files +- Out-of-tree shader files are not linted or added to the dependency graph +- Client no longer attempts to bootstrap server when `MCSHADER_DEBUG=true` + +## [0.9.3] + +### Fixed + +- Language server download for windows + +## [0.9.2] + +### Changed + +- VSCode extension activation predicate to only when `shaders` folder exists at top level + +### Added + +- Additional client-side logging + +## [0.9.1] + +### Fixed + +- Windows support in client not adding `.exe` to language server path +- Binary release CI + +## [0.9.0] + +### Changed + +- Replaced in-process Typescript language server with Rust based language server + +### Fixed + +- Due to the above, `#include` directive handling is vastly improved + +### Added + +- Command to view read-only document representing a top-level file with all includes merged +- Command to generate a DOT graph file of the entire project +- Command to restart language server + +### Removed + +- `glslangValidatorPath` and `shaderpacksPath` config settings + ## [0.8.5] ### Fixed @@ -33,4 +133,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) - Support for #include directives - Basic linting with highlighting with error propogation to all known parents of an include. - Support for .fsh, .vsh, .glsl and .gsh files. -- Incomplete completion items \ No newline at end of file +- Incomplete completion items diff --git a/README.md b/README.md index 2465d12..74fb1d5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Minecraft GLSL Shaders Language Server ## mcshader-lsp -[![Marketplace Version](https://vsmarketplacebadge.apphb.com/version/strum355.vscode-mc-shader.svg)](https://marketplace.visualstudio.com/items?itemName=strum355.vscode-mc-shader) [![Installs](https://vsmarketplacebadge.apphb.com/installs/strum355.vscode-mc-shader.svg)](https://marketplace.visualstudio.com/items?itemName=strum355.vscode-mc-shader) +[![Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/strum355.vscode-mc-shader.svg)](https://marketplace.visualstudio.com/items?itemName=strum355.vscode-mc-shader) [![Installs](https://img.shields.io/visual-studio-marketplace/i/strum355.vscode-mc-shader.svg)](https://marketplace.visualstudio.com/items?itemName=strum355.vscode-mc-shader) [![license](https://img.shields.io/github/license/Strum355/vscode-mc-shader.svg)](https://github.com/Strum355/mcshader-lsp) [![Issues](https://img.shields.io/github/issues-raw/Strum355/mcshader-lsp.svg)](https://github.com/Strum355/mcshader-lsp/issues) [![Build Status](https://img.shields.io/drone/build/Strum355/mcshader-lsp)](https://cloud.drone.io/Strum355/mcshader-lsp) @@ -12,7 +12,7 @@ Currently supported editors: - [Visual Studio Code](https://code.visualstudio.com/) with `vscode-mc-shader` - + ## Features diff --git a/client/package-lock.json b/client/package-lock.json index cb94340..d33cec9 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,314 +1,1002 @@ { - "name": "vscode-mc-shader-client", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@rollup/plugin-commonjs": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", - "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - } - }, - "@rollup/plugin-node-resolve": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.1.1.tgz", - "integrity": "sha512-zlBXR4eRS+2m79TsUZWhsd0slrHUYdRx4JF+aVQm+MI0wsKdlpC2vlDVjmlGvtZY1vsefOT9w3JxvmWSBei+Lg==", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - } - }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - } - } - }, - "@types/adm-zip": { - "version": "0.4.32", - "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.32.tgz", - "integrity": "sha512-hv1O7ySn+XvP5OeDQcJFWwVb2v+GFGO1A9aMTQ5B/bzxb7WW21O8iRhVdsKKr8QwuiagzGmPP+gsUAYZ6bRddQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "@types/node": { - "version": "13.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.1.tgz", - "integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==" - }, - "@types/node-fetch": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.4.tgz", - "integrity": "sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "requires": { - "@types/node": "*" - } - }, - "@types/vscode": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.47.0.tgz", - "integrity": "sha512-nJA37ykkz9FYA0ZOQUSc3OZnhuzEW2vUhUEo4MiduUo82jGwwcLfyvmgd/Q7b0WrZAAceojGhZybg319L24bTA==", - "dev": true - }, - "adm-zip": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz", - "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "requires": { - "@types/estree": "*" - } - }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" - }, - "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - } - }, - "rollup": { - "version": "2.38.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.1.tgz", - "integrity": "sha512-q07T6vU/V1kqM8rGRRyCgEvIQcIAXoKIE5CpkYAlHhfiWM1Iuh4dIPWpIbqFngCK6lwAB2aYHiUVhIbSWHQWhw==", - "requires": { - "fsevents": "~2.1.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "vscode-jsonrpc": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz", - "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==" - }, - "vscode-languageclient": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz", - "integrity": "sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA==", - "requires": { - "semver": "^6.3.0", - "vscode-languageserver-protocol": "^3.15.3" - } - }, - "vscode-languageserver-protocol": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz", - "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==", - "requires": { - "vscode-jsonrpc": "^5.0.1", - "vscode-languageserver-types": "3.15.1" - } - }, - "vscode-languageserver-types": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", - "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } + "name": "vscode-mc-shader-client", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "vscode-mc-shader-client", + "dependencies": { + "@rollup/plugin-json": "^4.1.0", + "adm-zip": "^0.5.9", + "encoding": "^0.1.13", + "node-fetch": "^2.6.7", + "vscode-languageclient": "^6.1.4" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^21.0.2", + "@rollup/plugin-node-resolve": "^13.1.3", + "@types/adm-zip": "^0.4.34", + "@types/node-fetch": "^2.6.1", + "@types/vscode": "^1.65.0", + "rollup": "^2.70.1" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "21.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.2.tgz", + "integrity": "sha512-d/OmjaLVO4j/aQX69bwpWPpbvI3TJkQuxoAk7BH8ew1PyoMBLTOuvJTjzG8oEoW7drIIqB0KCJtfFLu/2GClWg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^2.38.3" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dependencies": { + "@rollup/pluginutils": "^3.0.8" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", + "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^2.42.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/@types/adm-zip": { + "version": "0.4.34", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.34.tgz", + "integrity": "sha512-8ToYLLAYhkRfcmmljrKi22gT2pqu7hGMDtORP1emwIEGmgUTZOsaDjzWFzW5N2frcFRz/50CWt4zA1CxJ73pmQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@types/node": { + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.1.tgz", + "integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==", + "dev": true + }, + "node_modules/@types/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/vscode": { + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", + "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", + "dev": true + }, + "node_modules/adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/vscode-jsonrpc": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz", + "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.4.tgz", + "integrity": "sha512-EUOU+bJu6axmt0RFNo3nrglQLPXMfanbYViJee3Fbn2VuQoX0ZOI4uTYhSRvYLP2vfwTP/juV62P/mksCdTZMA==", + "dependencies": { + "semver": "^6.3.0", + "vscode-languageserver-protocol": "3.15.3" + }, + "engines": { + "vscode": "^1.41.0" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz", + "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==", + "dependencies": { + "vscode-jsonrpc": "^5.0.1", + "vscode-languageserver-types": "3.15.1" + } + }, + "node_modules/vscode-languageserver-types": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", + "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + }, + "dependencies": { + "@rollup/plugin-commonjs": { + "version": "21.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.2.tgz", + "integrity": "sha512-d/OmjaLVO4j/aQX69bwpWPpbvI3TJkQuxoAk7BH8ew1PyoMBLTOuvJTjzG8oEoW7drIIqB0KCJtfFLu/2GClWg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, + "@rollup/plugin-node-resolve": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", + "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + } + } + }, + "@types/adm-zip": { + "version": "0.4.34", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.34.tgz", + "integrity": "sha512-8ToYLLAYhkRfcmmljrKi22gT2pqu7hGMDtORP1emwIEGmgUTZOsaDjzWFzW5N2frcFRz/50CWt4zA1CxJ73pmQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "@types/node": { + "version": "13.7.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.1.tgz", + "integrity": "sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==", + "dev": true + }, + "@types/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/vscode": { + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.65.0.tgz", + "integrity": "sha512-wQhExnh2nEzpjDMSKhUvnNmz3ucpd3E+R7wJkOhBNK3No6fG3VUdmVmMOKD0A8NDZDDDiQcLNxe3oGmX5SjJ5w==", + "dev": true + }, + "adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "vscode-jsonrpc": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz", + "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==" + }, + "vscode-languageclient": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.4.tgz", + "integrity": "sha512-EUOU+bJu6axmt0RFNo3nrglQLPXMfanbYViJee3Fbn2VuQoX0ZOI4uTYhSRvYLP2vfwTP/juV62P/mksCdTZMA==", + "requires": { + "semver": "^6.3.0", + "vscode-languageserver-protocol": "3.15.3" + } + }, + "vscode-languageserver-protocol": { + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz", + "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==", + "requires": { + "vscode-jsonrpc": "^5.0.1", + "vscode-languageserver-types": "3.15.1" + } + }, + "vscode-languageserver-types": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz", + "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } } diff --git a/client/package.json b/client/package.json index 735890c..7e508dd 100644 --- a/client/package.json +++ b/client/package.json @@ -5,16 +5,18 @@ "rollup": "rollup -c" }, "dependencies": { - "adm-zip": "^0.4.14", - "node-fetch": "^2.6.0", - "vscode-languageclient": "^6.1.3" + "@rollup/plugin-json": "^4.1.0", + "adm-zip": "^0.5.9", + "encoding": "^0.1.13", + "node-fetch": "^2.6.7", + "vscode-languageclient": "^6.1.4" }, "devDependencies": { - "rollup": "^2.38.1", - "@rollup/plugin-commonjs": "^17.1.0", - "@rollup/plugin-node-resolve": "^11.1.1", - "@types/vscode": "^1.47.0", - "@types/adm-zip": "^0.4.32", - "@types/node-fetch": "^2.5.4" + "@rollup/plugin-commonjs": "^21.0.2", + "@rollup/plugin-node-resolve": "^13.1.3", + "@types/adm-zip": "^0.4.34", + "@types/node-fetch": "^2.6.1", + "@types/vscode": "^1.65.0", + "rollup": "^2.70.1" } } diff --git a/client/rollup.config.js b/client/rollup.config.js index 0ea37da..2874703 100644 --- a/client/rollup.config.js +++ b/client/rollup.config.js @@ -1,11 +1,13 @@ import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; import nodeBuiltins from 'builtin-modules'; /** @type { import('rollup').RollupOptions } */ export default { input: 'out/extension.js', plugins: [ + json(), resolve({ preferBuiltins: true }), diff --git a/client/src/commands.ts b/client/src/commands.ts index 8b90f29..bb81105 100644 --- a/client/src/commands.ts +++ b/client/src/commands.ts @@ -1,3 +1,4 @@ +import path = require('path') import * as vscode from 'vscode' import * as lsp from 'vscode-languageclient' import { Extension } from './extension' @@ -30,7 +31,7 @@ export function virtualMergedDocument(e: Extension): Command { command: 'virtualMerge', arguments: [path] }) - } catch(e) {} + } catch (e) { } return content } @@ -40,17 +41,67 @@ export function virtualMergedDocument(e: Extension): Command { onDidChange = this.onDidChangeEmitter.event provideTextDocumentContent(uri: vscode.Uri, __: vscode.CancellationToken): vscode.ProviderResult { - return getVirtualDocument(uri.path) + return getVirtualDocument(uri.path.replace('.flattened' + path.extname(uri.path), path.extname(uri.path))) } } e.context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider('mcglsl', docProvider)) return async () => { - const uri = vscode.window.activeTextEditor.document.uri - const path = vscode.Uri.parse('mcglsl:' + uri.path) + if (vscode.window.activeTextEditor.document.languageId != 'glsl') return + + const uri = vscode.window.activeTextEditor.document.uri.path + .substring(0, vscode.window.activeTextEditor.document.uri.path.lastIndexOf('.')) + + '.flattened.' + + vscode.window.activeTextEditor.document.uri.path + .slice(vscode.window.activeTextEditor.document.uri.path.lastIndexOf('.') + 1) + const path = vscode.Uri.parse(`mcglsl:${uri}`) + const doc = await vscode.workspace.openTextDocument(path) docProvider.onDidChangeEmitter.fire(path) - await vscode.window.showTextDocument(doc, {preview: true}) + await vscode.window.showTextDocument(doc, { + viewColumn: vscode.ViewColumn.Two, + preview: true + }) + } +} + +export function parseTree(e: Extension): Command { + const getVirtualDocument = async (path: string): Promise => { + let content: string = '' + try { + content = await e.lspClient.sendRequest(lsp.ExecuteCommandRequest.type.method, { + command: 'parseTree', + arguments: [path] + }) + } catch (e) { } + + return content + } + + const docProvider = new class implements vscode.TextDocumentContentProvider { + onDidChangeEmitter = new vscode.EventEmitter() + onDidChange = this.onDidChangeEmitter.event + + provideTextDocumentContent(uri: vscode.Uri, _: vscode.CancellationToken): vscode.ProviderResult { + if (uri.path.includes('.flattened.')) return '' + return getVirtualDocument(uri.path.substring(0, uri.path.lastIndexOf('.'))) + } + } + + e.context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider('mcglsl', docProvider)) + + return async () => { + if (vscode.window.activeTextEditor.document.languageId != 'glsl') return + + const uri = vscode.window.activeTextEditor.document.uri + const path = vscode.Uri.parse(`mcglsl:${uri.path}.ast`) + + const doc = await vscode.workspace.openTextDocument(path) + docProvider.onDidChangeEmitter.fire(path) + await vscode.window.showTextDocument(doc, { + viewColumn: vscode.ViewColumn.Two, + preview: true + }) } } \ No newline at end of file diff --git a/client/src/extension.ts b/client/src/extension.ts index 9060829..87efbc3 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -6,12 +6,13 @@ import { log } from './log' import { LanguageClient } from './lspClient' import { download, getReleaseInfo } from './net' import { PersistentState } from './persistent_state' -import * as path from 'path' +import * as path from 'path' const platforms: { [key: string]: string } = { - 'x64 win32': 'x86_64-pc-windows-msvc', + 'x64 win32': 'x86_64-windows-msvc', 'x64 linux': 'x86_64-unknown-linux-gnu', 'x64 darwin': 'x86_64-apple-darwin', + 'arm64 darwin': 'aarch64-apple-darwin' } export class Extension { @@ -24,8 +25,8 @@ export class Extension { readonly package: { version: string - } = vscode.extensions.getExtension(this.extensionID)!.packageJSON; - + } = vscode.extensions.getExtension(this.extensionID)!.packageJSON + public get context(): vscode.ExtensionContext { return this.extensionContext } @@ -33,36 +34,67 @@ export class Extension { public get lspClient(): lsp.LanguageClient { return this.client } - + public activate = async (context: vscode.ExtensionContext) => { this.extensionContext = context this.state = new PersistentState(context.globalState) - await this.bootstrap() + if (!process.env['MCSHADER_DEBUG'] && !(vscode.workspace.getConfiguration('mcglsl').get('skipBootstrap') as boolean)) { + await this.bootstrap() + } else { + log.info('skipping language server bootstrap') + } this.registerCommand('graphDot', commands.generateGraphDot) this.registerCommand('restart', commands.restartExtension) this.registerCommand('virtualMerge', commands.virtualMergedDocument) + this.registerCommand('parseTree', commands.parseTree) log.info('starting language server...') - - this.client = await new LanguageClient(this).startServer() - + + const lspBinary = process.env['MCSHADER_DEBUG'] ? + this.context.asAbsolutePath(path.join('server', 'target', 'debug', 'mcshader-lsp')) + + (process.platform === 'win32' ? '.exe' : '') : + path.join(this.context.globalStorageUri.fsPath, 'mcshader-lsp') + + const filewatcherGlob = this.fileAssociationsToGlob(this.getGLSLFileAssociations()) + + this.client = await new LanguageClient(this, lspBinary, filewatcherGlob).startServer() + log.info('language server started!') } + fileAssociationsToGlob = (associations: string[]): string => { + return '**/*.{'.concat( + associations.map(s => s.substring(s.indexOf('.'))).join(',') + ) + '}' + } + + getGLSLFileAssociations = (): string[] => { + const exts = ['.fsh', '.vsh', '.gsh', '.glsl'] + const associations = vscode.workspace.getConfiguration('files').get('associations') as { [key: string]: string } + + Object.keys(associations).forEach((key) => { + if (associations[key] === 'glsl') { + exts.push(key.substring(key.indexOf('*') + 1)) + } + }) + + return exts + } + registerCommand = (name: string, f: (e: Extension) => commands.Command) => { const cmd = f(this) - this.context.subscriptions.push(vscode.commands.registerCommand('mcglsl.'+name, cmd)) + this.context.subscriptions.push(vscode.commands.registerCommand('mcglsl.' + name, cmd)) } - deactivate = async () => { + deactivate = async () => { await this.lspClient.stop() - while(this.context.subscriptions.length > 0) { + while (this.context.subscriptions.length > 0) { this.context.subscriptions.pop()?.dispose() } } - + public updateStatus = (icon: string, text: string) => { this.statusBarItem?.dispose() this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left) @@ -70,20 +102,20 @@ export class Extension { this.statusBarItem.show() this.context.subscriptions.push(this.statusBarItem) } - + public clearStatus = () => { this.statusBarItem?.dispose() } private bootstrap = async () => { mkdirSync(this.extensionContext.globalStoragePath, { recursive: true }) - + const dest = path.join(this.extensionContext.globalStoragePath, 'mcshader-lsp' + (process.platform === 'win32' ? '.exe' : '')) const exists = await fs.stat(dest).then(() => true, () => false) if (!exists) await this.state.updateServerVersion(undefined) const release = await getReleaseInfo(this.package.version) - log.info(`got release info from Github:\n\t`, JSON.stringify(release)) + log.info('got release info from Github:\n\t', JSON.stringify(release)) const platform = platforms[`${process.arch} ${process.platform}`] if (platform === undefined) { @@ -91,9 +123,9 @@ export class Extension { log.warn(`incompatible architecture/platform:\n\t${process.arch} ${process.platform}`) return } - + if (release.tag_name === this.state.serverVersion) { - log.info(`server version is same as extension:\n\t`, this.state.serverVersion) + log.info('server version is same as extension:\n\t', this.state.serverVersion) return } @@ -103,8 +135,8 @@ export class Extension { const userResponse = await vscode.window.showInformationMessage( this.state.serverVersion == undefined ? - `Language server version ${this.package.version} is not installed.` : - `An update is available. Upgrade from ${this.state.serverVersion} to ${release.tag_name}?`, + `Language server version ${this.package.version} is not installed.` : + `An update is available. Upgrade from ${this.state.serverVersion} to ${release.tag_name}?`, 'Download now' ) if (userResponse !== 'Download now') { @@ -113,9 +145,16 @@ export class Extension { } await download(artifact.browser_download_url, dest) - + this.state.updateServerVersion(release.tag_name) } } -export const activate = new Extension().activate \ No newline at end of file +export const activate = async (context: vscode.ExtensionContext) => { + try { + new Extension().activate(context) + } catch (e) { + log.error(`failed to activate extension: ${e}`) + throw(e) + } +} \ No newline at end of file diff --git a/client/src/log.ts b/client/src/log.ts index f9e31ff..880ed52 100644 --- a/client/src/log.ts +++ b/client/src/log.ts @@ -9,33 +9,33 @@ export const log = new class { // Hint: the type [T, ...T[]] means a non-empty array debug(...msg: [unknown, ...unknown[]]): void { - log.write('DEBUG', ...msg) + log.write('DEBUG', ...msg) } info(...msg: [unknown, ...unknown[]]): void { - log.write('INFO ', ...msg) + log.write('INFO ', ...msg) } warn(...msg: [unknown, ...unknown[]]): void { - log.write('WARN ', ...msg) + log.write('WARN ', ...msg) } error(...msg: [unknown, ...unknown[]]): void { - log.write('ERROR', ...msg) + log.write('ERROR', ...msg) } write(label: string, ...messageParts: unknown[]): void { - const message = messageParts.map(log.stringify).join(' ') - const dateTime = new Date().toLocaleString() - log.output.appendLine(`${label} [${dateTime}]: ${message}`) + const message = messageParts.map(log.stringify).join(' ') + const dateTime = new Date().toLocaleString() + log.output.appendLine(`${label} [${dateTime}]: ${message}`) } private stringify(val: unknown): string { - if (typeof val === 'string') return val + if (typeof val === 'string') return val return inspect(val, { - colors: false, - depth: 6, // heuristic - }) + colors: false, + depth: 6, // heuristic + }) } } diff --git a/client/src/lspClient.ts b/client/src/lspClient.ts index 8f20423..7d9d2e7 100644 --- a/client/src/lspClient.ts +++ b/client/src/lspClient.ts @@ -1,38 +1,37 @@ -import * as path from 'path' import { ConfigurationTarget, workspace } from 'vscode' import * as lsp from 'vscode-languageclient' import { Extension } from './extension' -import { lspOutputChannel } from './log' +import { log, lspOutputChannel } from './log' import { ConfigUpdateParams, statusMethod, StatusParams, updateConfigMethod } from './lspExt' export class LanguageClient extends lsp.LanguageClient { private extension: Extension - constructor(ext: Extension) { + constructor(ext: Extension, lspBinary: string, filewatcherGlob: string) { super('vscode-mc-shader', 'VSCode MC Shader', { - command: process.env['MCSHADER_DEBUG'] ? - ext.context.asAbsolutePath(path.join('server', 'target', 'debug', 'mcshader-lsp')) + - (process.platform === 'win32' ? '.exe' : '') : - path.join(ext.context.globalStoragePath, 'mcshader-lsp') + command: lspBinary }, { - documentSelector: [{scheme: 'file', language: 'glsl'}], + documentSelector: [{ scheme: 'file', language: 'glsl' }], outputChannel: lspOutputChannel, synchronize: { configurationSection: 'mcglsl', - fileEvents: workspace.createFileSystemWatcher('**/*.{fsh,gsh,vsh,glsl,inc}') + fileEvents: workspace.createFileSystemWatcher(filewatcherGlob) }, }) this.extension = ext + + log.info('server receiving events for file glob:\n\t', filewatcherGlob) + log.info('running with binary at path:\n\t', lspBinary) } public startServer = async (): Promise => { this.extension.context.subscriptions.push(this.start()) await this.onReady() - + this.onNotification(updateConfigMethod, this.onUpdateConfig) this.onNotification(statusMethod, this.onStatusChange) - + return this } diff --git a/client/src/lspExt.ts b/client/src/lspExt.ts index ec2c6fe..70b40da 100644 --- a/client/src/lspExt.ts +++ b/client/src/lspExt.ts @@ -12,5 +12,5 @@ export const status = new lsp.NotificationType(statusMethod) export const updateConfigMethod = 'mc-glsl/updateConfig' export type ConfigUpdateParams = { - kv: {key: string, value: string}[] + kv: { key: string, value: string }[] } \ No newline at end of file diff --git a/client/src/net.ts b/client/src/net.ts index 14e1242..74438d0 100644 --- a/client/src/net.ts +++ b/client/src/net.ts @@ -16,20 +16,21 @@ interface GithubRelease { } export async function getReleaseInfo(releaseTag: string): Promise { + log.info('fetching release info for tag', releaseTag) const response = await fetch(`https://api.github.com/repos/strum355/mcshader-lsp/releases/tags/${releaseTag}`, { - headers: {Accept: 'application/vnd.github.v3+json'} + headers: { Accept: 'application/vnd.github.v3+json' } }) const isRelease = (obj: unknown): obj is GithubRelease => { - return obj != null && typeof obj === 'object' + return obj != null && typeof obj === 'object' && typeof (obj as GithubRelease).tag_name === 'string' && Array.isArray((obj as GithubRelease).assets) && (obj as GithubRelease).assets.every((a) => typeof a.name === 'string' && typeof a.browser_download_url === 'string') } const json = await response.json() - if(!isRelease(json)) { - throw new TypeError('Received malformed request from Github Release API ' + JSON.stringify(json)) + if (!isRelease(json)) { + throw new TypeError(`Received malformed request from Github Release API ${JSON.stringify(json)}`) } return json } @@ -50,14 +51,14 @@ export async function download(url: string, downloadDest: string) { message: `${newPercentage.toFixed(0)}%`, increment: newPercentage - lastPercentage }) - + lastPercentage = newPercentage } }) } ) } - + async function downloadFile( url: string, destFilePath: fs.PathLike, @@ -69,21 +70,21 @@ async function downloadFile( log.error({ body: await res.text(), headers: res.headers }) throw new Error(`Got response ${res.status} when trying to download ${url}.`) } - + const totalBytes = Number(res.headers.get('content-length')) - + log.debug('downloading file with', totalBytes, 'bytes size from', url, 'to', destFilePath) - + let readBytes = 0 res.body.on('data', (chunk: Buffer) => { readBytes += chunk.length onProgress(readBytes, totalBytes) }) - + const destFileStream = fs.createWriteStream(destFilePath, { mode: 0o755 }) - + await pipeline(res.body, destFileStream) - + // Don't apply the workaround in fixed versions of nodejs, since the process // freezes on them, the process waits for no-longer emitted `close` event. // The fix was applied in commit 7eed9d6bcc in v13.11.0 @@ -91,7 +92,7 @@ async function downloadFile( // https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V13.md const [, major, minor] = /v(\d+)\.(\d+)\.(\d+)/.exec(process.version)! if (+major > 13 || (+major === 13 && +minor >= 11)) return - + await new Promise(resolve => { destFileStream.on('close', resolve) destFileStream.destroy() diff --git a/client/src/persistent_state.ts b/client/src/persistent_state.ts index c54354b..a6bf084 100644 --- a/client/src/persistent_state.ts +++ b/client/src/persistent_state.ts @@ -12,6 +12,6 @@ export class PersistentState { } async updateServerVersion(value: string | undefined) { - await this.state.update('serverVersion', value) + await this.state.update('serverVersion', value) } } \ No newline at end of file diff --git a/logo-min.png b/logo-min.png new file mode 100644 index 0000000..4faf57b Binary files /dev/null and b/logo-min.png differ diff --git a/logo-mini.png b/logo-mini.png new file mode 100644 index 0000000..948748b Binary files /dev/null and b/logo-mini.png differ diff --git a/logo.png b/logo.png index bec83b0..17aba30 100644 Binary files a/logo.png and b/logo.png differ diff --git a/package-lock.json b/package-lock.json index b148cd0..f455284 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1749 +1,5077 @@ { - "name": "vscode-mc-shader", - "version": "0.9.2", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } + "name": "vscode-mc-shader", + "version": "0.9.8", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "vscode-mc-shader", + "version": "0.9.8", + "hasInstallScript": true, + "license": "MIT", + "devDependencies": { + "@types/node": "^17.0.21", + "@typescript-eslint/parser": "^5.15.0", + "concurrently": "^7.0.0", + "eslint": "^8.11.0", + "typescript": "^4.6.2", + "vsce": "^2.7.0" + }, + "engines": { + "vscode": "^1.53.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.15.0.tgz", + "integrity": "sha512-NGAYP/+RDM2sVfmKiKOCgJYPstAO40vPAgACoWPO/+yoYKSgAXIFaBKsV8P0Cc7fwKgvj27SjRNX4L7f4/jCKQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.15.0", + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/typescript-estree": "5.15.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.15.0.tgz", + "integrity": "sha512-EFiZcSKrHh4kWk0pZaa+YNJosvKE50EnmN4IfgjkA3bTHElPtYcd2U37QQkNTqwMCS7LXeDeZzEqnsOH8chjSg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/visitor-keys": "5.15.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.15.0.tgz", + "integrity": "sha512-yEiTN4MDy23vvsIksrShjNwQl2vl6kJeG9YkVJXjXZnkJElzVK8nfPsWKYxcsGWG8GhurYXP4/KGj3aZAxbeOA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.15.0.tgz", + "integrity": "sha512-Hb0e3dGc35b75xLzixM3cSbG1sSbrTBQDfIScqdyvrfJZVEi4XWAT+UL/HMxEdrJNB8Yk28SKxPLtAhfCbBInA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/visitor-keys": "5.15.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.15.0.tgz", + "integrity": "sha512-+vX5FKtgvyHbmIJdxMJ2jKm9z2BIlXJiuewI8dsDYMp5LzPUcuTT78Ya5iwvQg3VqSVdmxyM8Anj1Jeq7733ZQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.15.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/azure-devops-node-api": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz", + "integrity": "sha512-XDG91XzLZ15reP12s3jFkKS8oiagSICjnLwxEYieme4+4h3ZveFOFRA4iYIG40RyHXsiI0mefFYYMFIJbMpWcg==", + "dev": true, + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concurrently": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz", + "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + } + }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.2.1", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@types/node": { - "version": "10.14.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.15.tgz", - "integrity": "sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-abi": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", + "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "dependencies": { + "semver": "^5.1.0" + } + }, + "node_modules/parse-semver/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prebuild-install": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz", + "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@typescript-eslint/experimental-utils": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.6.1.tgz", - "integrity": "sha512-oS+hihzQE5M84ewXrTlVx7eTgc52eu+sVmG7ayLfOhyZmJ8Unvf3osyFQNADHP26yoThFfbxcibbO0d2FjnYhg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/typescript-estree": "3.6.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@typescript-eslint/parser": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.6.1.tgz", - "integrity": "sha512-SLihQU8RMe77YJ/jGTqOt0lMq7k3hlPVfp7v/cxMnXA9T0bQYoMDfTsNgHXpwSJM1Iq2aAJ8WqekxUwGv5F67Q==", - "dev": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.6.1", - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/typescript-estree": "3.6.1", - "eslint-visitor-keys": "^1.1.0" - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@typescript-eslint/types": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.6.1.tgz", - "integrity": "sha512-NPxd5yXG63gx57WDTW1rp0cF3XlNuuFFB5G+Kc48zZ+51ZnQn9yjDEsjTPQ+aWM+V+Z0I4kuTFKjKvgcT1F7xQ==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "@typescript-eslint/typescript-estree": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.6.1.tgz", - "integrity": "sha512-G4XRe/ZbCZkL1fy09DPN3U0mR6SayIv1zSeBNquRFRk7CnVLgkC2ZPj8llEMJg5Y8dJ3T76SvTGtceytniaztQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "3.6.1", - "@typescript-eslint/visitor-keys": "3.6.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "@typescript-eslint/visitor-keys": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.6.1.tgz", - "integrity": "sha512-qC8Olwz5ZyMTZrh4Wl3K4U6tfms0R/mzU4/5W3XeUZptVraGVmbptJbn6h2Ey6Rb3hOs3zWoAUebZk8t47KGiQ==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true - }, - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-color/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-rest-client": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.6.tgz", + "integrity": "sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA==", + "dev": true, + "dependencies": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "node_modules/typescript": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/vsce": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.7.0.tgz", + "integrity": "sha512-CKU34wrQlbKDeJCRBkd1a8iwF9EvNxcYMg9hAUH6AxFGR6Wo2IKWwt3cJIcusHxx6XdjDHWlfAS/fJN30uvVnA==", + "dev": true, + "dependencies": { + "azure-devops-node-api": "^11.0.1", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "commander": "^6.1.0", + "glob": "^7.0.6", + "hosted-git-info": "^4.0.2", + "keytar": "^7.7.0", + "leven": "^3.1.0", + "markdown-it": "^12.3.2", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "^0.2.1", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.4.23", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vsce/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vsce/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3" + } + } + }, + "dependencies": { + "@eslint/eslintrc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", + "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "@typescript-eslint/parser": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.15.0.tgz", + "integrity": "sha512-NGAYP/+RDM2sVfmKiKOCgJYPstAO40vPAgACoWPO/+yoYKSgAXIFaBKsV8P0Cc7fwKgvj27SjRNX4L7f4/jCKQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.15.0", + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/typescript-estree": "5.15.0", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.15.0.tgz", + "integrity": "sha512-EFiZcSKrHh4kWk0pZaa+YNJosvKE50EnmN4IfgjkA3bTHElPtYcd2U37QQkNTqwMCS7LXeDeZzEqnsOH8chjSg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/visitor-keys": "5.15.0" + } + }, + "@typescript-eslint/types": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.15.0.tgz", + "integrity": "sha512-yEiTN4MDy23vvsIksrShjNwQl2vl6kJeG9YkVJXjXZnkJElzVK8nfPsWKYxcsGWG8GhurYXP4/KGj3aZAxbeOA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.15.0.tgz", + "integrity": "sha512-Hb0e3dGc35b75xLzixM3cSbG1sSbrTBQDfIScqdyvrfJZVEi4XWAT+UL/HMxEdrJNB8Yk28SKxPLtAhfCbBInA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.15.0", + "@typescript-eslint/visitor-keys": "5.15.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.15.0.tgz", + "integrity": "sha512-+vX5FKtgvyHbmIJdxMJ2jKm9z2BIlXJiuewI8dsDYMp5LzPUcuTT78Ya5iwvQg3VqSVdmxyM8Anj1Jeq7733ZQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.15.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "azure-devops-node-api": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz", + "integrity": "sha512-XDG91XzLZ15reP12s3jFkKS8oiagSICjnLwxEYieme4+4h3ZveFOFRA4iYIG40RyHXsiI0mefFYYMFIJbMpWcg==", + "dev": true, + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "requires": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "cheerio-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concurrently": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz", + "integrity": "sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": { "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "azure-devops-node-api": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", - "integrity": "sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==", - "dev": true, - "requires": { - "os": "0.1.1", - "tunnel": "0.0.4", - "typed-rest-client": "1.2.0", - "underscore": "1.8.3" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "cheerio": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", - "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", - "dev": true, - "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.1", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } + } }, "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, - "requires": { - "color-name": "1.1.1" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } }, "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concurrently": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz", - "integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "date-fns": "^2.0.1", - "lodash": "^4.17.15", - "read-pkg": "^4.0.1", - "rxjs": "^6.5.2", - "spawn-command": "^0.0.2-1", - "supports-color": "^6.1.0", - "tree-kill": "^1.2.2", - "yargs": "^13.3.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - } - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "date-fns": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.9.0.tgz", - "integrity": "sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.4.0.tgz", - "integrity": "sha512-gU+lxhlPHu45H3JkEGgYhWhkR9wLHHEXC9FbWFnTlEkbKyZKWgWRLgf61E8zWmBuI6g5xKBph9ltg3NtZMVF8g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.0", - "eslint-utils": "^2.0.0", - "eslint-visitor-keys": "^1.2.0", - "espree": "^7.1.0", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", - "dev": true, - "requires": { - "acorn": "^7.2.0", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "dependencies": { - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true - } - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "os": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/os/-/os-0.1.1.tgz", - "integrity": "sha1-IIhF6J4ZOtTZcUdLk5R3NqVtE/M=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-semver": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", - "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", - "dev": true, - "requires": { - "semver": "^5.1.0" - } - }, - "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", - "dev": true, - "requires": { - "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-select": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "dev": true + }, + "date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domhandler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", + "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.2.1", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "tmp": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", - "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "typed-rest-client": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.2.0.tgz", - "integrity": "sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==", - "dev": true, - "requires": { - "tunnel": "0.0.4", - "underscore": "1.8.3" - } - }, - "typescript": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", - "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", - "dev": true - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-join": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", - "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vsce": { - "version": "1.77.0", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.77.0.tgz", - "integrity": "sha512-8vOTCI3jGmOm0JJFu/BMAbqxpaSuka4S3hV9E6K5aWBUsDM1SGFExkIxHblnsI8sls43xP61DHorYT+K0F+GFA==", - "dev": true, - "requires": { - "azure-devops-node-api": "^7.2.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.1", - "commander": "^2.8.1", - "denodeify": "^1.2.1", - "glob": "^7.0.6", - "leven": "^3.1.0", - "lodash": "^4.17.15", - "markdown-it": "^10.0.0", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "osenv": "^0.1.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^5.1.0", - "tmp": "0.0.29", - "typed-rest-client": "1.2.0", - "url-join": "^1.1.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "dev": true, + "requires": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-abi": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", + "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==", + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "dev": true, + "requires": { + "semver": "^5.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prebuild-install": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz", + "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==", + "dev": true, + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typed-rest-client": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.6.tgz", + "integrity": "sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA==", + "dev": true, + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typescript": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vsce": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.7.0.tgz", + "integrity": "sha512-CKU34wrQlbKDeJCRBkd1a8iwF9EvNxcYMg9hAUH6AxFGR6Wo2IKWwt3cJIcusHxx6XdjDHWlfAS/fJN30uvVnA==", + "dev": true, + "requires": { + "azure-devops-node-api": "^11.0.1", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "commander": "^6.1.0", + "glob": "^7.0.6", + "hosted-git-info": "^4.0.2", + "keytar": "^7.7.0", + "leven": "^3.1.0", + "markdown-it": "^12.3.2", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^5.1.0", + "tmp": "^0.2.1", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.4.23", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } } + } } diff --git a/package.json b/package.json index 05f740c..0ecfe79 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,16 @@ "name": "vscode-mc-shader", "displayName": "Minecraft GLSL Shaders", "description": "A Visual Studio Code extension for linting/etc Minecraft GLSL Shaders", - "version": "0.9.2", + "version": "0.9.9", "publisher": "Strum355", "author": "Noah Santschi-Cooney (Strum355)", "license": "MIT", - "icon": "logo.png", + "icon": "logo-min.png", "repository": { - "url": "https://github.com/Strum355/vscode-mc-shader" + "url": "https://github.com/Strum355/mcshader-lsp" }, "engines": { - "vscode": "^1.43.0" + "vscode": "^1.53.0" }, "categories": [ "Linters", @@ -41,6 +41,11 @@ "command": "mcglsl.virtualMerge", "title": "Show flattened file", "category": "Minecraft Shader" + }, + { + "command": "mcglsl.parseTree", + "title": "Show parse tree for file", + "category": "Minecraft Shader" } ], "languages": [ @@ -59,7 +64,19 @@ ], "configuration": { "title": "Minecraft GLSL Shaders", - "properties": {} + "properties": { + "mcglsl.skipBootstrap": { + "type": "boolean", + "default": false, + "description": "[DEBUG] Enable to skip bootstrapping the language server binary from Github. Set this to use a manually provided language server binary." + }, + "mcglsl.logLevel": { + "type": "string", + "default": "info", + "enum": ["trace", "debug", "info", "warn", "error"], + "description": "Change the log level of the language server. This change happens live and does not require a restart." + } + } } }, "scripts": { @@ -72,22 +89,28 @@ "fix": "eslint 'client/**/*.ts' --fix" }, "devDependencies": { - "@types/node": "^10.14.15", - "@typescript-eslint/parser": "^3.6.1", - "concurrently": "^5.1.0", - "eslint": "^7.4.0", - "typescript": "^3.9.7", - "vsce": "^1.77.0" + "@types/node": "^17.0.21", + "@typescript-eslint/parser": "^5.15.0", + "concurrently": "^7.0.0", + "eslint": "^8.11.0", + "typescript": "^4.6.2", + "vsce": "^2.7.0" }, "eslintConfig": { "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module" + "ecmaVersion": 2020, + "sourceType": "module" }, "rules": { - "semi": ["warn", "never"], - "quotes": ["warn", "single"] + "semi": [ + "warn", + "never" + ], + "quotes": [ + "warn", + "single" + ] } } } diff --git a/server/Cargo.lock b/server/Cargo.lock index bc5b733..05c839a 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -1,33 +1,16 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff" +version = 3 [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] -[[package]] -name = "andrew" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4afb09dd642feec8408e33f92f3ffc4052946f6b20f32fb99c1f58cd4fa7cf" -dependencies = [ - "bitflags", - "rusttype", - "walkdir", - "xdg", - "xml-rs", -] - [[package]] name = "android_glue" version = "0.2.3" @@ -36,51 +19,47 @@ checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] name = "anyhow" -version = "1.0.38" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] -name = "autocfg" -version = "1.0.1" +name = "arc-swap" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "c5d78ce20460b82d3fa150275ed9d55e21064fc7951177baacf86a145c4a4b1f" [[package]] -name = "base64" -version = "0.12.3" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "bit-set" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "bit-vec", + "hermit-abi", + "libc", + "winapi", ] [[package]] -name = "bit-vec" -version = "0.6.3" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block" @@ -89,10 +68,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] -name = "calloop" -version = "0.6.5" +name = "bumpalo" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b036167e76041694579972c28cf4877b4f92da222560ddb49008937b6a6727c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" + +[[package]] +name = "calloop" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82" dependencies = [ "log", "nix", @@ -100,9 +85,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.66" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -125,31 +110,6 @@ dependencies = [ "libc", ] -[[package]] -name = "chan" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14956a3dae065ffaa0d92ece848ab4ced88d32361e7fdfbfd653a5c454a1ed8" -dependencies = [ - "rand 0.3.23", -] - -[[package]] -name = "cocoa" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54201c07dcf3a5ca33fececb8042aed767ee4bfd5a0235a8ceabcda956044b2" -dependencies = [ - "bitflags", - "block", - "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", - "foreign-types", - "libc", - "objc", -] - [[package]] name = "cocoa" version = "0.24.0" @@ -159,8 +119,8 @@ dependencies = [ "bitflags", "block", "cocoa-foundation", - "core-foundation 0.9.1", - "core-graphics 0.22.2", + "core-foundation 0.9.3", + "core-graphics 0.22.3", "foreign-types", "libc", "objc", @@ -174,7 +134,7 @@ checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" dependencies = [ "bitflags", "block", - "core-foundation 0.9.1", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -193,11 +153,11 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.2", + "core-foundation-sys 0.8.3", "libc", ] @@ -209,9 +169,9 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "core-graphics" @@ -227,12 +187,12 @@ dependencies = [ [[package]] name = "core-graphics" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags", - "core-foundation 0.9.1", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -245,7 +205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags", - "core-foundation 0.9.1", + "core-foundation 0.9.3", "foreign-types", "libc", ] @@ -265,19 +225,25 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.18" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bcb9d7dcbf7002aaffbb53eac22906b64cdcc127971dcc387d8eb7c95d5560" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", "syn", ] [[package]] -name = "darling" -version = "0.10.2" +name = "cty" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -285,9 +251,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -299,9 +265,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -309,21 +275,37 @@ dependencies = [ ] [[package]] -name = "derivative" -version = "2.1.3" +name = "diff" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaed5874effa6cde088c644ddcdcb4ffd1511391c5be4fdd7a5ccd02c7e4a183" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if 1.0.0", + "dirs-sys-next", ] [[package]] -name = "difference" -version = "2.0.0" +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] [[package]] name = "dispatch" @@ -333,18 +315,18 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dlib" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" dependencies = [ "libloading", ] [[package]] name = "downcast" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" @@ -353,16 +335,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] -name = "fixedbitset" -version = "0.2.0" +name = "either" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "fixedbitset" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" [[package]] name = "float-cmp" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" dependencies = [ "num-traits", ] @@ -390,9 +378,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", "percent-encoding", @@ -400,9 +388,9 @@ dependencies = [ [[package]] name = "fragile" -version = "1.0.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2" +checksum = "e9d758e60b45e8d749c89c1b389ad8aee550f86aa12e2b9298b546dda7a82ab1" [[package]] name = "fs_extra" @@ -416,27 +404,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "futures" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] [[package]] name = "gl" @@ -460,14 +443,14 @@ dependencies = [ [[package]] name = "glutin" -version = "0.26.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae1cbb9176b9151c4ce03f012e3cd1c6c18c4be79edeaeb3d99f5d8085c5fa3" +checksum = "00ea9dbe544bc8a657c4c4a798c2d16cd01b549820e47657297549d28371f6d2" dependencies = [ "android_glue", "cgl", - "cocoa 0.23.0", - "core-foundation 0.9.1", + "cocoa", + "core-foundation 0.9.3", "glutin_egl_sys", "glutin_emscripten_sys", "glutin_gles2_sys", @@ -481,7 +464,7 @@ dependencies = [ "parking_lot", "wayland-client", "wayland-egl", - "winapi 0.3.9", + "winapi", "winit", ] @@ -492,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211" dependencies = [ "gl_generator", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -542,9 +525,18 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] [[package]] name = "ident_case" @@ -554,9 +546,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -565,9 +557,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", @@ -575,27 +567,30 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "iovec" -version = "0.1.4" +name = "itertools" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ - "libc", + "either", ] [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "jni-sys" @@ -604,13 +599,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "js-sys" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "wasm-bindgen", ] [[package]] @@ -625,52 +619,66 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" -version = "0.2.82" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" [[package]] name = "libloading" -version = "0.6.6" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9367bdfa836b7e3cf895867f7a570283444da90562980ec2263d6e1569b16bc" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if 1.0.0", - "winapi 0.3.9", + "winapi", ] [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.11" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", +] + +[[package]] +name = "logging" +version = "0.9.9" +dependencies = [ + "lazy_static", + "rand 0.8.5", + "slog", + "slog-atomic", + "slog-scope", + "slog-term", +] + +[[package]] +name = "logging_macro" +version = "0.9.9" +dependencies = [ + "quote", + "syn", ] [[package]] name = "lsp-types" -version = "0.86.0" -source = "git+https://github.com/gluon-lang/lsp-types?branch=master#1be3254cd8589950a224d92456840c369cd1553a" +version = "0.93.0" +source = "git+https://github.com/gluon-lang/lsp-types?branch=master#36e19b01a385acf475d9fdfaef6738cf76f1a3d8" dependencies = [ - "base64", "bitflags", "serde", "serde_json", @@ -689,30 +697,24 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mcshader-lsp" -version = "0.9.2" +version = "0.9.9" dependencies = [ "anyhow", - "bit-set", - "chan", - "ctor", "fs_extra", "gl", "glutin", "hamcrest2", "lazy_static", + "logging", + "logging_macro", "mockall", + "once_cell", "path-slash", "percent-encoding", "petgraph", @@ -721,75 +723,74 @@ dependencies = [ "rust_lsp", "serde", "serde_json", + "slog", + "slog-scope", "tempdir", "thiserror", + "tree-sitter", + "tree-sitter-glsl", "url", "walkdir", ] [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memmap2" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" +checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "mio" -version = "0.6.23" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", "libc", "log", "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "log", - "mio", - "slab", + "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "winapi", ] [[package]] name = "miow" -version = "0.2.2" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "winapi", ] [[package]] name = "mockall" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619634fd9149c4a06e66d8fd9256e85326d8eeee75abee4565ff76c92e4edfe0" +checksum = "3d4d70639a72f972725db16350db56da68266ca368b2a1fe26724a903ad3d6b8" dependencies = [ "cfg-if 1.0.0", "downcast", @@ -802,9 +803,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83714c95dbf4c24202f0f1b208f0f248e6bd65abfa8989303611a71c0f781548" +checksum = "79ef208208a0dea3f72221e26e904cdc6db2e481d9ade89081ddd494f1dbaa6b" dependencies = [ "cfg-if 1.0.0", "proc-macro2", @@ -814,10 +815,11 @@ dependencies = [ [[package]] name = "ndk" -version = "0.2.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb167c1febed0a496639034d0c76b3b74263636045db5489eee52143c246e73" +checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d" dependencies = [ + "bitflags", "jni-sys", "ndk-sys", "num_enum", @@ -825,24 +827,31 @@ dependencies = [ ] [[package]] -name = "ndk-glue" -version = "0.2.1" +name = "ndk-context" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf399b8b7a39c6fb153c4ec32c72fd5fe789df24a647f229c239aa7adb15241" +checksum = "4e3c5cc68637e21fe8f077f6a1c9e0b9ca495bb74895226b476310f613325884" + +[[package]] +name = "ndk-glue" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1c68f70683c5fc9a747a383744206cd371741b2f0b31781ab6770487ec572e2" dependencies = [ "lazy_static", "libc", "log", "ndk", + "ndk-context", "ndk-macro", "ndk-sys", ] [[package]] name = "ndk-macro" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" dependencies = [ "darling", "proc-macro-crate", @@ -853,41 +862,31 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" [[package]] name = "nix" -version = "0.18.0" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" dependencies = [ "bitflags", "cc", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", + "memoffset", ] [[package]] name = "nom" -version = "6.0.1" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", - "version_check", + "minimal-lexical", ] [[package]] @@ -896,6 +895,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + [[package]] name = "num" version = "0.2.1" @@ -975,19 +983,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.4.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" dependencies = [ - "derivative", "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.4.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -995,6 +1002,15 @@ dependencies = [ "syn", ] +[[package]] +name = "num_threads" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +dependencies = [ + "libc", +] + [[package]] name = "objc" version = "0.2.7" @@ -1006,9 +1022,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.5.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "osmesa-sys" @@ -1021,27 +1037,18 @@ dependencies = [ [[package]] name = "output_vt100" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" -dependencies = [ - "ttf-parser", + "winapi", ] [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -1050,16 +1057,16 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if 1.0.0", "instant", "libc", "redox_syscall", "smallvec", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1076,9 +1083,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "petgraph" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" dependencies = [ "fixedbitset", "indexmap", @@ -1086,18 +1093,25 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "predicates" -version = "1.0.6" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73dd9b7b200044694dfede9edf907c1ca19630908443e9447e624993700c6932" +checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" dependencies = [ - "difference", + "difflib", "float-cmp", + "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -1105,69 +1119,60 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3dbeaaf793584e29c58c7e3a82bbb3c7c06b63cea68d13b0e3cddc124104dc" +checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" [[package]] name = "predicates-tree" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee95d988ee893cb35c06b148c80ed2cd52c8eea927f50ba7a0be1a786aeab73" +checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" dependencies = [ "predicates-core", - "treeline", + "termtree", ] [[package]] name = "pretty_assertions" -version = "0.6.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" +checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563" dependencies = [ "ansi_term", "ctor", - "difference", + "diff", "output_vt100", ] [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ + "thiserror", "toml", ] [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.8" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] - [[package]] name = "rand" version = "0.4.6" @@ -1178,7 +1183,28 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] @@ -1197,12 +1223,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] -name = "raw-window-handle" -version = "0.3.3" +name = "rand_core" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "libc", + "getrandom", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +dependencies = [ + "cty", ] [[package]] @@ -1216,27 +1251,40 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] [[package]] name = "regex" -version = "1.4.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.22" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" @@ -1244,13 +1292,13 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] name = "rust_lsp" version = "0.6.0" -source = "git+https://github.com/Strum355/RustLSP?branch=master#1f6d533300fd64a739930fd42f0572328be48469" +source = "git+https://github.com/Strum355/RustLSP?branch=master#22694b563c8bae1a64cf91f91e80c1933693203f" dependencies = [ "log", "lsp-types", @@ -1279,20 +1327,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cfffa8a89d8758be2dd5605c5fc62bce055af2491ebf3ce953d4d31512c59fd" [[package]] -name = "rusttype" -version = "0.9.2" +name = "rustversion" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" @@ -1317,18 +1361,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.123" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -1337,9 +1381,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -1348,9 +1392,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76" +checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" dependencies = [ "proc-macro2", "quote", @@ -1368,24 +1412,57 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.2" +name = "slog" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + +[[package]] +name = "slog-atomic" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b517f2dda9e1458733eb8350bad1a3632ffed8141be4c0f3d6def899a9b066" +dependencies = [ + "arc-swap", + "slog", +] + +[[package]] +name = "slog-scope" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f95a4b4c3274cd2869549da82b57ccc930859bdbf5bcea0424bc5f140b3c786" +dependencies = [ + "arc-swap", + "lazy_static", + "slog", +] + +[[package]] +name = "slog-term" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87d29185c55b7b258b4f120eab00f48557d4d9bc814f41713f449d35b0f8977c" +dependencies = [ + "atty", + "slog", + "term", + "thread_local", + "time", +] [[package]] name = "smallvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "smithay-client-toolkit" -version = "0.12.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "316e13a3eb853ce7bf72ad3530dc186cb2005c57c521ef5f4ada5ee4eed74de6" +checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3" dependencies = [ - "andrew", "bitflags", "calloop", "dlib", @@ -1393,6 +1470,7 @@ dependencies = [ "log", "memmap2", "nix", + "pkg-config", "wayland-client", "wayland-cursor", "wayland-protocols", @@ -1400,15 +1478,15 @@ dependencies = [ [[package]] name = "strsim" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.60" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -1426,19 +1504,36 @@ dependencies = [ ] [[package]] -name = "thiserror" -version = "1.0.23" +name = "term" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "termtree" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.23" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1447,18 +1542,36 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] -name = "tinyvec" -version = "1.1.0" +name = "time" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +dependencies = [ + "itoa", + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -1479,46 +1592,51 @@ dependencies = [ ] [[package]] -name = "treeline" -version = "0.1.0" +name = "tree-sitter" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" - -[[package]] -name = "ttf-parser" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" - -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +checksum = "09b3b781640108d29892e8b9684642d2cda5ea05951fd58f0fea1db9edeb9b71" dependencies = [ - "matches", + "cc", + "regex", ] [[package]] -name = "unicode-normalization" -version = "0.1.16" +name = "tree-sitter-glsl" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" +checksum = "3d20c93432c782c4f66618ffb06669870ac6231a86b1777813a6c97148f1f0fb" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" -version = "2.2.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", @@ -1527,28 +1645,88 @@ dependencies = [ "serde", ] -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - [[package]] name = "walkdir" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", - "winapi 0.3.9", + "winapi", "winapi-util", ] [[package]] -name = "wayland-client" -version = "0.28.3" +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdbdbe01d03b2267809f3ed99495b37395387fde789e0f2ebb78e8b43f75b6d7" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" + +[[package]] +name = "wayland-client" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f" dependencies = [ "bitflags", "downcast-rs", @@ -1562,9 +1740,9 @@ dependencies = [ [[package]] name = "wayland-commons" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480450f76717edd64ad04a4426280d737fc3d10a236b982df7b1aee19f0e2d56" +checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e" dependencies = [ "nix", "once_cell", @@ -1574,9 +1752,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6eb122c160223a7660feeaf949d0100281d1279acaaed3720eb3c9894496e5f" +checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd" dependencies = [ "nix", "wayland-client", @@ -1585,9 +1763,9 @@ dependencies = [ [[package]] name = "wayland-egl" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c653507447113c967a1aeee413699acb42d96d6302ec967c6d51930eae8aa7f5" +checksum = "83281d69ee162b59031c666385e93bde4039ec553b90c4191cdb128ceea29a3a" dependencies = [ "wayland-client", "wayland-sys", @@ -1595,9 +1773,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "319a82b4d3054dd25acc32d9aee0f84fa95b63bc983fffe4703b6b8d47e01a30" +checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741" dependencies = [ "bitflags", "wayland-client", @@ -1607,9 +1785,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7010ba5767b3fcd350decc59055390b4ebe6bd1b9279a9feb1f1888987f1133d" +checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0" dependencies = [ "proc-macro2", "quote", @@ -1618,9 +1796,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.28.3" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6793834e0c35d11fd96a97297abe03d37be627e1847da52e17d7e0e3b51cc099" +checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4" dependencies = [ "dlib", "lazy_static", @@ -1628,10 +1806,14 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.2.8" +name = "web-sys" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" @@ -1643,12 +1825,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1661,7 +1837,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1672,14 +1848,14 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winit" -version = "0.24.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4eda6fce0eb84bd0a33e3c8794eb902e1033d0a1d5a31bc4f19b1b4bbff597" +checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a" dependencies = [ "bitflags", - "cocoa 0.24.0", - "core-foundation 0.9.1", - "core-graphics 0.22.2", + "cocoa", + "core-foundation 0.9.3", + "core-graphics 0.22.3", "core-video-sys", "dispatch", "instant", @@ -1687,7 +1863,6 @@ dependencies = [ "libc", "log", "mio", - "mio-extras", "ndk", "ndk-glue", "ndk-sys", @@ -1696,50 +1871,36 @@ dependencies = [ "percent-encoding", "raw-window-handle", "smithay-client-toolkit", + "wasm-bindgen", "wayland-client", - "winapi 0.3.9", + "wayland-protocols", + "web-sys", + "winapi", "x11-dl", ] -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "x11-dl" -version = "2.18.5" +version = "2.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" dependencies = [ "lazy_static", "libc", - "maybe-uninit", "pkg-config", ] [[package]] name = "xcursor" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" dependencies = [ "nom", ] -[[package]] -name = "xdg" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" - [[package]] name = "xml-rs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" diff --git a/server/Cargo.toml b/server/Cargo.toml index 02d6163..533392d 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,31 +1,6 @@ -[package] -name = "mcshader-lsp" -version = "0.9.2" -authors = ["Noah Santschi-Cooney "] -edition = "2018" - -[dependencies] -rust_lsp = { git = "https://github.com/Strum355/RustLSP", branch = "master" } -serde_json = "1.0.61" -serde = "1.0.123" -walkdir = "2.3.1" -petgraph = "0.5.1" -lazy_static = "1.4.0" -regex = "1.4.3" -chan = "0.1.23" -url = "2.2.0" -percent-encoding = "2.1.0" -anyhow = "1.0.38" -bit-set = "0.5.2" -thiserror = "1.0.23" -glutin = "0.26.0" -gl = "0.14.0" -ctor = "0.1.18" -mockall = "0.9.0" -path-slash = "0.1.4" - -[dev-dependencies] -tempdir = "0.3.7" -fs_extra = "1.2.0" -hamcrest2 = "*" -pretty_assertions = "0.6.1" \ No newline at end of file +[workspace] +members = [ + "main", + "logging", + "logging_macro" +] \ No newline at end of file diff --git a/server/Makefile b/server/Makefile index 509b9af..867c64c 100644 --- a/server/Makefile +++ b/server/Makefile @@ -4,7 +4,7 @@ watchtest: RUST_BACKTRACE=0 cargo watch -x test -i Makefile test: - RUST_LIB_BACKTRACE=0 RUST_BACKTRACE=0 cargo test + RUST_LIB_BACKTRACE=0 RUST_BACKTRACE=0 cargo test -- --nocapture --color always build: cargo build diff --git a/server/logging/Cargo.toml b/server/logging/Cargo.toml new file mode 100644 index 0000000..2abdf7e --- /dev/null +++ b/server/logging/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "logging" +version = "0.9.9" +authors = ["Noah Santschi-Cooney "] +edition = "2021" + +[dependencies] +slog = { version = "2.7", features = [ "max_level_trace", "release_max_level_trace" ] } +slog-term = "2.9" +slog-scope = "4.4" +slog-atomic = "3.1" +rand = "0.8" +lazy_static = "1.4" \ No newline at end of file diff --git a/server/logging/src/lib.rs b/server/logging/src/lib.rs new file mode 100644 index 0000000..36d7f53 --- /dev/null +++ b/server/logging/src/lib.rs @@ -0,0 +1,43 @@ +use rand::{rngs, Rng}; +use slog::slog_o; +use slog_scope::GlobalLoggerGuard; +use slog_term::{FullFormat, PlainSyncDecorator}; +use std::{cell::RefCell, sync::Arc}; + +use std::io::Stderr; + +use lazy_static::lazy_static; +use slog::*; +use slog_atomic::*; + +fn new_trace_id() -> String { + let rng = CURRENT_RNG.with(|rng| rng.borrow_mut().gen::<[u8; 4]>()); + return format!("{:04x}", u32::from_be_bytes(rng)); +} + +pub fn slog_with_trace_id(f: F) { + slog_scope::scope(&slog_scope::logger().new(slog_o!("trace" => new_trace_id())), f) +} + +pub fn set_logger_with_level(level: Level) -> GlobalLoggerGuard { + let drain = Arc::new(logger_base(level).fuse()); + DRAIN_SWITCH.ctrl().set(drain.clone()); + slog_scope::set_global_logger(Logger::root(drain, o!())) +} + +fn logger_base(level: Level) -> LevelFilter>>> { + let plain = slog_term::PlainSyncDecorator::new(std::io::stderr()); + let drain = slog_term::FullFormat::new(plain).build().fuse(); + drain.filter_level(level) +} + +thread_local! { + static CURRENT_RNG: RefCell = RefCell::new(rngs::ThreadRng::default()); +} + +lazy_static! { + static ref DRAIN_SWITCH: AtomicSwitch<()> = { + let logger = logger_base(Level::Info).fuse(); + AtomicSwitch::new(logger) + }; +} diff --git a/server/logging_macro/Cargo.toml b/server/logging_macro/Cargo.toml new file mode 100644 index 0000000..f1e6957 --- /dev/null +++ b/server/logging_macro/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "logging_macro" +version = "0.9.9" +authors = ["Noah Santschi-Cooney "] +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0" +syn = { version = "1.0", features = [ "full" ] } \ No newline at end of file diff --git a/server/logging_macro/src/lib.rs b/server/logging_macro/src/lib.rs new file mode 100644 index 0000000..99052bb --- /dev/null +++ b/server/logging_macro/src/lib.rs @@ -0,0 +1,24 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, parse_quote, ItemFn}; + +#[proc_macro_attribute] +pub fn log_scope(_args: TokenStream, function: TokenStream) -> TokenStream { + let mut function = parse_macro_input!(function as ItemFn); + + let function_name = function.sig.ident.to_string(); + + let stmts = function.block.stmts; + + function.block = Box::new(parse_quote!({ + use slog::{slog_o, FnValue, Level}; + use std::thread::current; + + let _guard = logging::set_logger_with_level(Level::Trace); + slog_scope::scope(&slog_scope::logger().new(slog_o!("test_name" => #function_name, "thread_num" => FnValue(|_| format!("{:?}", current().id())))), || { + #(#stmts)* + }); + })); + + TokenStream::from(quote!(#function)) +} diff --git a/server/main/Cargo.toml b/server/main/Cargo.toml new file mode 100644 index 0000000..3aa68c2 --- /dev/null +++ b/server/main/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "mcshader-lsp" +version = "0.9.9" +authors = ["Noah Santschi-Cooney "] +edition = "2021" + +[dependencies] +rust_lsp = { git = "https://github.com/Strum355/RustLSP", branch = "master" } +serde_json = "1.0" +serde = "1.0" +walkdir = "2.3" +petgraph = "0.6" +lazy_static = "1.4" +regex = "1.4" +url = "2.2" +percent-encoding = "2.1" +anyhow = "1.0" +thiserror = "1.0" +glutin = "0.28" +gl = "0.14" +mockall = "0.11" +path-slash = "0.1" +slog = { version = "2.7", features = [ "max_level_trace", "release_max_level_trace" ] } +slog-scope = "4.4" +once_cell = "1.7" +tree-sitter = "0.20.6" +tree-sitter-glsl = "0.1.2" +logging = { path = "../logging" } +logging_macro = { path = "../logging_macro" } + +[dev-dependencies] +tempdir = "0.3" +fs_extra = "1.2" +hamcrest2 = "*" +pretty_assertions = "1.1" \ No newline at end of file diff --git a/server/main/src/commands/graph_dot.rs b/server/main/src/commands/graph_dot.rs new file mode 100644 index 0000000..dac35e7 --- /dev/null +++ b/server/main/src/commands/graph_dot.rs @@ -0,0 +1,52 @@ +use std::cell::RefCell; +use std::fs::OpenOptions; +use std::io::prelude::*; +use std::path::Path; +use std::rc::Rc; + +use petgraph::dot::Config; +use serde_json::Value; + +use petgraph::dot; + +use anyhow::{format_err, Result}; +use slog_scope::info; + +use crate::graph::CachedStableGraph; + +use super::Invokeable; + +pub struct GraphDotCommand { + pub graph: Rc>, +} + +impl Invokeable for GraphDotCommand { + fn run_command(&self, root: &Path, _: &[Value]) -> Result { + let filepath = root.join("graph.dot"); + + info!("generating dot file"; "path" => filepath.as_os_str().to_str()); + + let mut file = OpenOptions::new().truncate(true).write(true).create(true).open(filepath).unwrap(); + + let mut write_data_closure = || -> Result<(), std::io::Error> { + let graph = self.graph.as_ref(); + + file.seek(std::io::SeekFrom::Start(0))?; + file.write_all("digraph {\n\tgraph [splines=ortho]\n\tnode [shape=box]\n".as_bytes())?; + file.write_all( + dot::Dot::with_config(&graph.borrow().graph, &[Config::GraphContentOnly]) + .to_string() + .as_bytes(), + )?; + file.write_all("\n}".as_bytes())?; + file.flush()?; + file.seek(std::io::SeekFrom::Start(0))?; + Ok(()) + }; + + match write_data_closure() { + Err(err) => Err(format_err!("error generating graphviz data: {}", err)), + _ => Ok(Value::Null), + } + } +} diff --git a/server/main/src/commands/merged_includes.rs b/server/main/src/commands/merged_includes.rs new file mode 100644 index 0000000..d932213 --- /dev/null +++ b/server/main/src/commands/merged_includes.rs @@ -0,0 +1,114 @@ +use std::cell::RefCell; +use std::rc::Rc; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +use serde_json::Value; + +use petgraph::graph::NodeIndex; + +use anyhow::{format_err, Result}; + +use std::fs; + +use crate::dfs; +use crate::merge_views::FilialTuple; +use crate::source_mapper::SourceMapper; +use crate::{graph::CachedStableGraph, merge_views, url_norm::FromJson}; + +use super::Invokeable; + +pub struct VirtualMergedDocument { + pub graph: Rc>, +} + +impl VirtualMergedDocument { + // TODO: DUPLICATE CODE + fn get_file_toplevel_ancestors(&self, uri: &Path) -> Result>> { + let curr_node = match self.graph.borrow_mut().find_node(uri) { + Some(n) => n, + None => return Err(format_err!("node not found {:?}", uri)), + }; + let roots = self.graph.borrow().collect_root_ancestors(curr_node); + if roots.is_empty() { + return Ok(None); + } + Ok(Some(roots)) + } + + pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result, dfs::error::CycleError> { + let graph_ref = self.graph.borrow(); + + let dfs = dfs::Dfs::new(&graph_ref, root); + + dfs.collect::, _>>() + } + + pub fn load_sources(&self, nodes: &[FilialTuple]) -> Result> { + let mut sources = HashMap::new(); + + for node in nodes { + let graph = self.graph.borrow(); + let path = graph.get_node(node.child); + + if sources.contains_key(&path) { + continue; + } + + let source = match fs::read_to_string(&path) { + Ok(s) => s, + Err(e) => return Err(format_err!("error reading {:?}: {}", path, e)), + }; + let source = source.replace("\r\n", "\n"); + sources.insert(path.clone(), source); + } + + Ok(sources) + } +} + +impl Invokeable for VirtualMergedDocument { + fn run_command(&self, root: &Path, arguments: &[Value]) -> Result { + let path = PathBuf::from_json(arguments.get(0).unwrap())?; + + let file_ancestors = match self.get_file_toplevel_ancestors(&path) { + Ok(opt) => match opt { + Some(ancestors) => ancestors, + None => vec![], + }, + Err(e) => return Err(e), + }; + + //info!("ancestors for {}:\n\t{:?}", path, file_ancestors.iter().map(|e| self.graph.borrow().graph.node_weight(*e).unwrap().clone()).collect::>()); + + // the set of all filepath->content. TODO: change to Url? + let mut all_sources: HashMap = HashMap::new(); + + // if we are a top-level file (this has to be one of the set defined by Optifine, right?) + if file_ancestors.is_empty() { + // gather the list of all descendants + let root = self.graph.borrow_mut().find_node(&path).unwrap(); + let tree = match self.get_dfs_for_node(root) { + Ok(tree) => tree, + Err(e) => return Err(e.into()), + }; + + let sources = match self.load_sources(&tree) { + Ok(s) => s, + Err(e) => return Err(e), + }; + all_sources.extend(sources); + + let mut source_mapper = SourceMapper::new(all_sources.len()); + let graph = self.graph.borrow(); + let view = merge_views::MergeViewBuilder::new(&tree, &all_sources, &graph, &mut source_mapper).build(); + return Ok(serde_json::value::Value::String(view)); + } + return Err(format_err!( + "{:?} is not a top-level file aka has ancestors", + path.strip_prefix(root).unwrap() + )); + } +} diff --git a/server/main/src/commands/mod.rs b/server/main/src/commands/mod.rs new file mode 100644 index 0000000..0bb17f1 --- /dev/null +++ b/server/main/src/commands/mod.rs @@ -0,0 +1,36 @@ +use std::{collections::HashMap, path::Path}; + +use serde_json::Value; + +use anyhow::{format_err, Result}; +use slog_scope::info; + +pub mod graph_dot; +pub mod merged_includes; +pub mod parse_tree; + +pub struct CustomCommandProvider { + commands: HashMap>, +} + +impl CustomCommandProvider { + pub fn new(commands: Vec<(&str, Box)>) -> CustomCommandProvider { + CustomCommandProvider { + commands: commands.into_iter().map(|tup| (tup.0.into(), tup.1)).collect(), + } + } + + pub fn execute(&self, command: &str, args: &[Value], root_path: &Path) -> Result { + if self.commands.contains_key(command) { + info!("running command"; + "command" => command, + "args" => format!("[{}]", args.iter().map(|v| serde_json::to_string(v).unwrap()).collect::>().join(", "))); + return self.commands.get(command).unwrap().run_command(root_path, args); + } + Err(format_err!("command doesn't exist")) + } +} + +pub trait Invokeable { + fn run_command(&self, root: &Path, arguments: &[Value]) -> Result; +} diff --git a/server/main/src/commands/parse_tree.rs b/server/main/src/commands/parse_tree.rs new file mode 100644 index 0000000..fb3d9e7 --- /dev/null +++ b/server/main/src/commands/parse_tree.rs @@ -0,0 +1,94 @@ +use std::{ + cell::RefCell, + fs, + path::{Path, PathBuf}, + rc::Rc, +}; + +use anyhow::{format_err, Result}; +use serde_json::Value; +use slog_scope::warn; +use tree_sitter::{Parser, TreeCursor}; + +use crate::url_norm::FromJson; + +use super::Invokeable; + +pub struct TreeSitterSExpr { + pub tree_sitter: Rc>, +} + +impl Invokeable for TreeSitterSExpr { + fn run_command(&self, _: &Path, arguments: &[Value]) -> Result { + let path = PathBuf::from_json(arguments.get(0).unwrap())?; + + warn!("parsing"; "path" => path.to_str().unwrap().to_string()); + + let source = fs::read_to_string(path)?; + + let tree = match self.tree_sitter.borrow_mut().parse(source, None) { + Some(tree) => tree, + None => return Err(format_err!("tree-sitter parsing resulted in no parse tree")), + }; + + let mut cursor = tree.walk(); + + let rendered = render_parse_tree(&mut cursor); + + Ok(serde_json::value::Value::String(rendered)) + } +} + +fn render_parse_tree(cursor: &mut TreeCursor) -> String { + let mut string = String::new(); + + let mut indent = 0; + let mut visited_children = false; + + loop { + let node = cursor.node(); + + let display_name = if node.is_missing() { + format!("MISSING {}", node.kind()) + } else if node.is_named() { + node.kind().to_string() + } else { + "".to_string() + }; + + if visited_children { + if cursor.goto_next_sibling() { + visited_children = false; + } else if cursor.goto_parent() { + visited_children = true; + indent -= 1; + } else { + break; + } + } else { + if !display_name.is_empty() { + let start = node.start_position(); + let end = node.end_position(); + + let field_name = match cursor.field_name() { + Some(name) => name.to_string() + ": ", + None => "".to_string(), + }; + + string += (" ".repeat(indent) + + format!("{}{} [{}, {}] - [{}, {}]\n", field_name, display_name, start.row, start.column, end.row, end.column) + .trim_start()) + .as_str(); + } + + if cursor.goto_first_child() { + visited_children = false; + indent += 1; + } else { + visited_children = true; + } + } + } + + string +} diff --git a/server/main/src/configuration.rs b/server/main/src/configuration.rs new file mode 100644 index 0000000..779b235 --- /dev/null +++ b/server/main/src/configuration.rs @@ -0,0 +1,12 @@ +use std::str::FromStr; + +use slog::Level; +use slog_scope::error; + + +pub fn handle_log_level_change(log_level: String, callback: F) { + match Level::from_str(log_level.as_str()) { + Ok(level) => callback(level), + Err(_) => error!("got unexpected log level from config"; "level" => log_level), + }; +} \ No newline at end of file diff --git a/server/src/consts.rs b/server/main/src/consts.rs similarity index 100% rename from server/src/consts.rs rename to server/main/src/consts.rs diff --git a/server/main/src/dfs.rs b/server/main/src/dfs.rs new file mode 100644 index 0000000..11d3a6f --- /dev/null +++ b/server/main/src/dfs.rs @@ -0,0 +1,335 @@ +use petgraph::stable_graph::NodeIndex; + +use crate::{graph::CachedStableGraph, merge_views::FilialTuple}; + +use anyhow::Result; + +struct VisitCount { + node: NodeIndex, + touch: usize, + children: usize, +} + +/// Performs a depth-first search with duplicates +pub struct Dfs<'a> { + stack: Vec, + graph: &'a CachedStableGraph, + cycle: Vec, +} + +impl<'a> Dfs<'a> { + pub fn new(graph: &'a CachedStableGraph, start: NodeIndex) -> Self { + Dfs { + stack: vec![start], + graph, + cycle: Vec::new(), + } + } + + fn reset_path_to_branch(&mut self) { + while let Some(par) = self.cycle.last_mut() { + par.touch += 1; + if par.touch > par.children { + self.cycle.pop(); + } else { + break; + } + } + } + + fn check_for_cycle(&self, children: &[NodeIndex]) -> Result<(), error::CycleError> { + for prev in &self.cycle { + for child in children { + if prev.node == *child { + let cycle_nodes: Vec = self.cycle.iter().map(|n| n.node).collect(); + return Err(error::CycleError::new(&cycle_nodes, *child, self.graph)); + } + } + } + Ok(()) + } +} + +impl<'a> Iterator for Dfs<'a> { + type Item = Result; + + fn next(&mut self) -> Option> { + let parent = self.cycle.last().map(|p| p.node); + + if let Some(child) = self.stack.pop() { + self.cycle.push(VisitCount { + node: child, + children: self.graph.graph.edges(child).count(), + touch: 1, + }); + + let mut children: Vec<_> = self + .graph + .get_all_child_positions(child) + .collect(); + children.reverse(); + + if !children.is_empty() { + + let child_indexes: Vec<_> = children.iter().map(|c| c.0).collect(); + match self.check_for_cycle(&child_indexes) { + Ok(_) => {} + Err(e) => return Some(Err(e)), + }; + + for child in children { + self.stack.push(child.0); + } + } else { + self.reset_path_to_branch(); + } + + return Some(Ok(FilialTuple { child, parent })); + } + None + } +} + +pub mod error { + use petgraph::stable_graph::NodeIndex; + + use std::{ + error::Error as StdError, + fmt::{Debug, Display}, + path::PathBuf, + }; + + use crate::{consts, graph::CachedStableGraph}; + + use rust_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; + + #[derive(Debug)] + pub struct CycleError(Vec); + + impl StdError for CycleError {} + + impl CycleError { + pub fn new(nodes: &[NodeIndex], current_node: NodeIndex, graph: &CachedStableGraph) -> Self { + let mut resolved_nodes: Vec = nodes.iter().map(|i| graph.get_node(*i)).collect(); + resolved_nodes.push(graph.get_node(current_node)); + CycleError(resolved_nodes) + } + } + + impl Display for CycleError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut disp = String::new(); + disp.push_str(format!("Include cycle detected:\n{:?} imports ", self.0[0]).as_str()); + for p in &self.0[1..self.0.len() - 1] { + disp.push_str(format!("\n{:?}, which imports ", *p).as_str()); + } + disp.push_str(format!("\n{:?}", self.0[self.0.len() - 1]).as_str()); + f.write_str(disp.as_str()) + } + } + + impl From for Diagnostic { + fn from(e: CycleError) -> Diagnostic { + Diagnostic { + severity: Some(DiagnosticSeverity::ERROR), + range: Range::new(Position::new(0, 0), Position::new(0, 500)), + source: Some(consts::SOURCE.into()), + message: e.into(), + code: None, + tags: None, + related_information: None, + code_description: Option::None, + data: Option::None, + } + } + } + + impl From for String { + fn from(e: CycleError) -> String { + format!("{}", e) + } + } +} + +#[cfg(test)] +mod dfs_test { + use std::path::PathBuf; + + use hamcrest2::prelude::*; + use hamcrest2::{assert_that, ok}; + use petgraph::{algo::is_cyclic_directed, graph::NodeIndex}; + + use crate::graph::CachedStableGraph; + use crate::{dfs, IncludePosition}; + + #[test] + #[logging_macro::log_scope] + fn test_graph_dfs() { + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx0, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 }); + + let dfs = dfs::Dfs::new(&graph, idx0); + + let mut collection = Vec::new(); + + for i in dfs { + assert_that!(&i, ok()); + collection.push(i.unwrap()); + } + + let nodes: Vec = collection.iter().map(|n| n.child).collect(); + let parents: Vec> = collection.iter().map(|n| n.parent).collect(); + // 0 + // / \ + // 1 2 + // / + // 3 + let expected_nodes = vec![idx0, idx1, idx3, idx2]; + + assert_eq!(expected_nodes, nodes); + + let expected_parents = vec![None, Some(idx0), Some(idx1), Some(idx0)]; + + assert_eq!(expected_parents, parents); + + assert!(!is_cyclic_directed(&graph.graph)); + } + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + let idx4 = graph.add_node(&PathBuf::from("4")); + let idx5 = graph.add_node(&PathBuf::from("5")); + let idx6 = graph.add_node(&PathBuf::from("6")); + let idx7 = graph.add_node(&PathBuf::from("7")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx0, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 }); + graph.add_edge(idx1, idx4, IncludePosition { line: 6, start: 0, end: 0 }); + graph.add_edge(idx2, idx4, IncludePosition { line: 5, start: 0, end: 0 }); + graph.add_edge(idx2, idx5, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx3, idx6, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx4, idx6, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx6, idx7, IncludePosition { line: 4, start: 0, end: 0 }); + + let dfs = dfs::Dfs::new(&graph, idx0); + + let mut collection = Vec::new(); + + for i in dfs { + assert_that!(&i, ok()); + collection.push(i.unwrap()); + } + + let nodes: Vec = collection.iter().map(|n| n.child).collect(); + let parents: Vec> = collection.iter().map(|n| n.parent).collect(); + // 0 + // / \ + // 1 2 + // / \ / \ + // 3 4 5 + // \ / + // 6 - 7 + let expected_nodes = vec![idx0, idx1, idx3, idx6, idx7, idx4, idx6, idx7, idx2, idx5, idx4, idx6, idx7]; + + assert_eq!(expected_nodes, nodes); + + let expected_parents = vec![ + None, + Some(idx0), + Some(idx1), + Some(idx3), + Some(idx6), + Some(idx1), + Some(idx4), + Some(idx6), + Some(idx0), + Some(idx2), + Some(idx2), + Some(idx4), + Some(idx6), + ]; + + assert_eq!(expected_parents, parents); + + assert!(!is_cyclic_directed(&graph.graph)); + } + } + + #[test] + #[logging_macro::log_scope] + fn test_graph_dfs_cycle() { + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + let idx4 = graph.add_node(&PathBuf::from("4")); + let idx5 = graph.add_node(&PathBuf::from("5")); + let idx6 = graph.add_node(&PathBuf::from("6")); + let idx7 = graph.add_node(&PathBuf::from("7")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx0, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 }); + graph.add_edge(idx1, idx4, IncludePosition { line: 6, start: 0, end: 0 }); + graph.add_edge(idx2, idx4, IncludePosition { line: 5, start: 0, end: 0 }); + graph.add_edge(idx2, idx5, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx3, idx6, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx4, idx6, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx6, idx7, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx7, idx4, IncludePosition { line: 4, start: 0, end: 0 }); + + let mut dfs = dfs::Dfs::new(&graph, idx0); + + for _ in 0..5 { + if let Some(i) = dfs.next() { + assert_that!(&i, ok()); + } + } + + // 0 + // / \ + // 1 2 + // / \ / \ + // 3 4 5 + // \ / \ + // 6 - 7 + + let next = dfs.next().unwrap(); + assert_that!(next, err()); + + assert!(is_cyclic_directed(&graph.graph)); + } + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx1, idx0, IncludePosition { line: 2, start: 0, end: 0 }); + + let mut dfs = dfs::Dfs::new(&graph, idx1); + + println!("{:?}", dfs.next()); + println!("{:?}", dfs.next()); + println!("{:?}", dfs.next()); + } + } +} diff --git a/server/main/src/diagnostics_parser.rs b/server/main/src/diagnostics_parser.rs new file mode 100644 index 0000000..2f61b64 --- /dev/null +++ b/server/main/src/diagnostics_parser.rs @@ -0,0 +1,194 @@ +use std::{collections::HashMap, cell::OnceCell, path::Path}; + +use regex::Regex; +use rust_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; +use slog_scope::debug; +use url::Url; + +use crate::{ + consts, + graph::CachedStableGraph, + opengl, + source_mapper::{SourceMapper, SourceNum}, +}; + +pub struct DiagnosticsParser<'a, T: opengl::ShaderValidator + ?Sized> { + line_offset: OnceCell, + line_regex: OnceCell, + vendor_querier: &'a T, +} + +impl<'a, T: opengl::ShaderValidator + ?Sized> DiagnosticsParser<'a, T> { + pub fn new(vendor_querier: &'a T) -> Self { + DiagnosticsParser { + line_offset: OnceCell::new(), + line_regex: OnceCell::new(), + vendor_querier, + } + } + + fn get_line_regex(&self) -> &Regex { + self.line_regex.get_or_init(|| match self.vendor_querier.vendor().as_str() { + "NVIDIA Corporation" => { + Regex::new(r#"^(?P\d+)\((?P\d+)\) : (?Perror|warning) [A-C]\d+: (?P.+)"#).unwrap() + } + _ => Regex::new(r#"^(?PERROR|WARNING): (?P[^?<>*|"\n]+):(?P\d+): (?:'.*' :|[a-z]+\(#\d+\)) +(?P.+)$"#) + .unwrap(), + }) + } + + fn get_line_offset(&self) -> u32 { + *self.line_offset.get_or_init(|| match self.vendor_querier.vendor().as_str() { + "ATI Technologies" => 0, + _ => 1, + }) + } + + pub fn parse_diagnostics_output( + &self, output: String, uri: &Path, source_mapper: &SourceMapper, graph: &CachedStableGraph, + ) -> HashMap> { + let output_lines = output.split('\n').collect::>(); + let mut diagnostics: HashMap> = HashMap::with_capacity(output_lines.len()); + + debug!("diagnostics regex selected"; "regex" => self.get_line_regex() .as_str()); + + for line in output_lines { + let diagnostic_capture = match self.get_line_regex().captures(line) { + Some(d) => d, + None => continue, + }; + + debug!("found match for output line"; "line" => line, "capture" => format!("{:?}", diagnostic_capture)); + + let msg = diagnostic_capture.name("output").unwrap().as_str(); + + let line = match diagnostic_capture.name("linenum") { + Some(c) => c.as_str().parse::().unwrap_or(0), + None => 0, + } - self.get_line_offset(); + + // TODO: line matching maybe + /* let line_text = source_lines[line as usize]; + let leading_whitespace = line_text.len() - line_text.trim_start().len(); */ + + let severity = match diagnostic_capture.name("severity") { + Some(c) => match c.as_str().to_lowercase().as_str() { + "error" => DiagnosticSeverity::ERROR, + "warning" => DiagnosticSeverity::WARNING, + _ => DiagnosticSeverity::INFORMATION, + }, + _ => DiagnosticSeverity::INFORMATION, + }; + + let origin = match diagnostic_capture.name("filepath") { + Some(o) => { + let source_num: SourceNum = o.as_str().parse::().unwrap().into(); + let graph_node = source_mapper.get_node(source_num); + graph.get_node(graph_node).to_str().unwrap().to_string() + } + None => uri.to_str().unwrap().to_string(), + }; + + let diagnostic = Diagnostic { + range: Range::new( + /* Position::new(line, leading_whitespace as u64), + Position::new(line, line_text.len() as u64) */ + Position::new(line, 0), + Position::new(line, 1000), + ), + code: None, + severity: Some(severity), + source: Some(consts::SOURCE.into()), + message: msg.trim().into(), + related_information: None, + tags: None, + code_description: Option::None, + data: Option::None, + }; + + let origin_url = Url::from_file_path(origin).unwrap(); + match diagnostics.get_mut(&origin_url) { + Some(d) => d.push(diagnostic), + None => { + diagnostics.insert(origin_url, vec![diagnostic]); + } + }; + } + diagnostics + } +} + +#[cfg(test)] +mod diagnostics_test { + use std::path::PathBuf; + + use slog::slog_o; + use url::Url; + + use crate::{ + diagnostics_parser::DiagnosticsParser, opengl::MockShaderValidator, source_mapper::SourceMapper, test::new_temp_server, + }; + + #[test] + #[logging_macro::log_scope] + fn test_nvidia_diagnostics() { + slog_scope::scope(&slog_scope::logger().new(slog_o!("driver" => "nvidia")), || { + let mut mockgl = MockShaderValidator::new(); + mockgl.expect_vendor().returning(|| "NVIDIA Corporation".into()); + let server = new_temp_server(Some(Box::new(mockgl))); + + let output = "0(9) : error C0000: syntax error, unexpected '}', expecting ',' or ';' at token \"}\""; + + #[cfg(target_family = "unix")] + let path: PathBuf = "/home/noah/.minecraft/shaderpacks/test/shaders/final.fsh".into(); + #[cfg(target_family = "windows")] + let path: PathBuf = "c:\\home\\noah\\.minecraft\\shaderpacks\\test\\shaders\\final.fsh".into(); + + let mut source_mapper = SourceMapper::new(0); + source_mapper.get_num(server.graph.borrow_mut().add_node(&path)); + + let parser = DiagnosticsParser::new(server.opengl_context.as_ref()); + + let results = + parser.parse_diagnostics_output(output.to_string(), path.parent().unwrap(), &source_mapper, &server.graph.borrow()); + + assert_eq!(results.len(), 1); + let first = results.into_iter().next().unwrap(); + assert_eq!(first.0, Url::from_file_path(path).unwrap()); + server.endpoint.request_shutdown(); + }); + } + + #[test] + #[logging_macro::log_scope] + fn test_amd_diagnostics() { + slog_scope::scope(&slog_scope::logger().new(slog_o!("driver" => "amd")), || { + let mut mockgl = MockShaderValidator::new(); + mockgl.expect_vendor().returning(|| "ATI Technologies".into()); + let server = new_temp_server(Some(Box::new(mockgl))); + + let output = "ERROR: 0:1: '' : syntax error: #line +ERROR: 0:10: '' : syntax error: #line +ERROR: 0:15: 'varying' : syntax error: syntax error +"; + + #[cfg(target_family = "unix")] + let path: PathBuf = "/home/noah/.minecraft/shaderpacks/test/shaders/final.fsh".into(); + #[cfg(target_family = "windows")] + let path: PathBuf = "c:\\home\\noah\\.minecraft\\shaderpacks\\test\\shaders\\final.fsh".into(); + + let mut source_mapper = SourceMapper::new(0); + source_mapper.get_num(server.graph.borrow_mut().add_node(&path)); + + let parser = DiagnosticsParser::new(server.opengl_context.as_ref()); + + let results = + parser.parse_diagnostics_output(output.to_string(), path.parent().unwrap(), &source_mapper, &server.graph.borrow()); + + assert_eq!(results.len(), 1); + let first = results.into_iter().next().unwrap(); + assert_eq!(first.1.len(), 3); + server.endpoint.request_shutdown(); + }); + } +} diff --git a/server/main/src/graph.rs b/server/main/src/graph.rs new file mode 100644 index 0000000..608a299 --- /dev/null +++ b/server/main/src/graph.rs @@ -0,0 +1,374 @@ +use petgraph::stable_graph::EdgeIndex; +use petgraph::stable_graph::NodeIndex; +use petgraph::stable_graph::StableDiGraph; +use petgraph::visit::EdgeRef; +use petgraph::Direction; + +use std::{ + collections::{HashMap, HashSet}, + path::{Path, PathBuf}, + str::FromStr, +}; + +use super::IncludePosition; + +/// Wraps a `StableDiGraph` with caching behaviour for node search by maintaining +/// an index for node value to node index and a reverse index. +/// This allows for **O(1)** lookup for a value if it exists, else **O(n)**. +pub struct CachedStableGraph { + // StableDiGraph is used as it allows for String node values, essential for + // generating the GraphViz DOT render. + pub graph: StableDiGraph, + cache: HashMap, + // Maps a node index to its abstracted string representation. + // Mainly used as the graph is based on NodeIndex. + reverse_index: HashMap, +} + +impl CachedStableGraph { + #[allow(clippy::new_without_default)] + pub fn new() -> CachedStableGraph { + CachedStableGraph { + graph: StableDiGraph::new(), + cache: HashMap::new(), + reverse_index: HashMap::new(), + } + } + + /// Returns the `NodeIndex` for a given graph node with the value of `name` + /// and caches the result in the `HashMap`. Complexity is **O(1)** if the value + /// is cached (which should always be the case), else **O(n)** where **n** is + /// the number of node indices, as an exhaustive search must be done. + pub fn find_node(&mut self, name: &Path) -> Option { + match self.cache.get(name) { + Some(n) => Some(*n), + None => { + // If the string is not in cache, O(n) search the graph (i know...) and then cache the NodeIndex + // for later + let n = self.graph.node_indices().find(|n| self.graph[*n] == name.to_str().unwrap()); + if let Some(n) = n { + self.cache.insert(name.into(), n); + } + n + } + } + } + + // Returns the `PathBuf` for a given `NodeIndex` + pub fn get_node(&self, node: NodeIndex) -> PathBuf { + PathBuf::from_str(&self.graph[node]).unwrap() + } + + /// Returns an iterator over all the `IncludePosition`'s between a parent and its child for all the positions + /// that the child may be imported into the parent, in order of import. + pub fn get_child_positions(&self, parent: NodeIndex, child: NodeIndex) -> impl Iterator + '_ { + let mut edges = self + .graph + .edges(parent) + .filter_map(move |edge| { + let target = self.graph.edge_endpoints(edge.id()).unwrap().1; + if target != child { + return None; + } + Some(self.graph[edge.id()]) + }) + .collect::>(); + edges.sort_by(|x, y| x.line.cmp(&y.line)); + edges.into_iter() + } + + /// Returns an iterator over all the `(NodeIndex, IncludePosition)` tuples between a node and all its children, in order + /// of import. + pub fn get_all_child_positions(&self, node: NodeIndex) -> impl Iterator + '_ { + let mut edges = self.graph.edges(node).map(|edge| { + let child = self.graph.edge_endpoints(edge.id()).unwrap().1; + (child, self.graph[edge.id()]) + }) + .collect::>(); + edges.sort_by(|x, y| x.1.line.cmp(&y.1.line)); + edges.into_iter() + } + + pub fn add_node(&mut self, name: &Path) -> NodeIndex { + if let Some(idx) = self.cache.get(name) { + return *idx; + } + let idx = self.graph.add_node(name.to_str().unwrap().to_string()); + self.cache.insert(name.to_owned(), idx); + self.reverse_index.insert(idx, name.to_owned()); + idx + } + + pub fn add_edge(&mut self, parent: NodeIndex, child: NodeIndex, meta: IncludePosition) -> EdgeIndex { + self.graph.add_edge(parent, child, meta) + } + + pub fn remove_edge(&mut self, parent: NodeIndex, child: NodeIndex, position: IncludePosition) { + self.graph + .edges(parent) + .find(|edge| self.graph.edge_endpoints(edge.id()).unwrap().1 == child && *edge.weight() == position) + .map(|edge| edge.id()) + .and_then(|edge| self.graph.remove_edge(edge)); + } + + pub fn child_node_indexes(&self, node: NodeIndex) -> impl Iterator + '_ { + self.graph.neighbors(node) + } + + pub fn collect_root_ancestors(&self, node: NodeIndex) -> Vec { + let mut visited = HashSet::new(); + self.get_root_ancestors(node, node, &mut visited) + } + + // TODO: impl Iterator + fn parent_node_indexes(&self, node: NodeIndex) -> Vec { + self.graph.neighbors_directed(node, Direction::Incoming).collect() + } + + fn get_root_ancestors(&self, initial: NodeIndex, node: NodeIndex, visited: &mut HashSet) -> Vec { + if node == initial && !visited.is_empty() { + return vec![]; + } + + let parents = self.parent_node_indexes(node); + let mut collection = Vec::with_capacity(parents.len()); + + for ancestor in &parents { + visited.insert(*ancestor); + } + + for ancestor in &parents { + let ancestors = self.parent_node_indexes(*ancestor); + if !ancestors.is_empty() { + collection.extend(self.get_root_ancestors(initial, *ancestor, visited)); + } else { + collection.push(*ancestor); + } + } + + collection + } +} + +#[cfg(test)] +impl CachedStableGraph { + fn parent_node_names(&self, node: NodeIndex) -> Vec { + self.graph + .neighbors_directed(node, Direction::Incoming) + .map(|n| self.reverse_index.get(&n).unwrap().clone()) + .collect() + } + + fn child_node_names(&self, node: NodeIndex) -> Vec { + self.graph + .neighbors(node) + .map(|n| self.reverse_index.get(&n).unwrap().clone()) + .collect() + } + + fn remove_node(&mut self, name: &Path) { + let idx = self.cache.remove(name); + if let Some(idx) = idx { + self.graph.remove_node(idx); + } + } +} + +#[cfg(test)] +mod graph_test { + use std::path::PathBuf; + + use petgraph::graph::NodeIndex; + + use crate::{graph::CachedStableGraph, IncludePosition}; + + #[test] + #[logging_macro::log_scope] + fn test_graph_two_connected_nodes() { + let mut graph = CachedStableGraph::new(); + + let idx1 = graph.add_node(&PathBuf::from("sample")); + let idx2 = graph.add_node(&PathBuf::from("banana")); + graph.add_edge(idx1, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + + let children = graph.child_node_names(idx1); + assert_eq!(children.len(), 1); + assert_eq!(children[0], Into::::into("banana".to_string())); + + let children: Vec = graph.child_node_indexes(idx1).collect(); + assert_eq!(children.len(), 1); + assert_eq!(children[0], idx2); + + let parents = graph.parent_node_names(idx1); + assert_eq!(parents.len(), 0); + + let parents = graph.parent_node_names(idx2); + assert_eq!(parents.len(), 1); + assert_eq!(parents[0], Into::::into("sample".to_string())); + + let parents = graph.parent_node_indexes(idx2); + assert_eq!(parents.len(), 1); + assert_eq!(parents[0], idx1); + + let ancestors = graph.collect_root_ancestors(idx2); + assert_eq!(ancestors.len(), 1); + assert_eq!(ancestors[0], idx1); + + let ancestors = graph.collect_root_ancestors(idx1); + assert_eq!(ancestors.len(), 0); + + graph.remove_node(&PathBuf::from("sample")); + assert_eq!(graph.graph.node_count(), 1); + assert!(graph.find_node(&PathBuf::from("sample")).is_none()); + + let neighbors = graph.child_node_names(idx2); + assert_eq!(neighbors.len(), 0); + } + + #[test] + #[logging_macro::log_scope] + fn test_double_import() { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx0, idx1, IncludePosition { line: 4, start: 0, end: 0 }); + + // 0 + // / \ + // 1 1 + + assert_eq!(2, graph.get_child_positions(idx0, idx1).count()); + + let mut edge_metas = graph.get_child_positions(idx0, idx1); + assert_eq!(Some(IncludePosition { line: 2, start: 0, end: 0 }), edge_metas.next()); + assert_eq!(Some(IncludePosition { line: 4, start: 0, end: 0 }), edge_metas.next()); + } + + #[test] + #[logging_macro::log_scope] + fn test_collect_root_ancestors() { + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx1, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx3, idx1, IncludePosition { line: 4, start: 0, end: 0 }); + + // 0 3 + // |/ + // 1 + // | + // 2 + + let roots = graph.collect_root_ancestors(idx2); + assert_eq!(roots, vec![idx3, idx0]); + + let roots = graph.collect_root_ancestors(idx1); + assert_eq!(roots, vec![idx3, idx0]); + + let roots = graph.collect_root_ancestors(idx0); + assert_eq!(roots, vec![]); + + let roots = graph.collect_root_ancestors(idx3); + assert_eq!(roots, vec![]); + } + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx0, idx2, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 }); + + // 0 + // / \ + // 1 2 + // / + // 3 + + let roots = graph.collect_root_ancestors(idx3); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx2); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx1); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx0); + assert_eq!(roots, vec![]); + } + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx2, idx3, IncludePosition { line: 3, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 5, start: 0, end: 0 }); + + // 0 + // \ + // 2 1 + // \ / + // 3 + + let roots = graph.collect_root_ancestors(idx3); + assert_eq!(roots, vec![idx0, idx2]); + + let roots = graph.collect_root_ancestors(idx2); + assert_eq!(roots, vec![]); + + let roots = graph.collect_root_ancestors(idx1); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx0); + assert_eq!(roots, vec![]); + } + { + let mut graph = CachedStableGraph::new(); + + let idx0 = graph.add_node(&PathBuf::from("0")); + let idx1 = graph.add_node(&PathBuf::from("1")); + let idx2 = graph.add_node(&PathBuf::from("2")); + let idx3 = graph.add_node(&PathBuf::from("3")); + + graph.add_edge(idx0, idx1, IncludePosition { line: 2, start: 0, end: 0 }); + graph.add_edge(idx1, idx2, IncludePosition { line: 4, start: 0, end: 0 }); + graph.add_edge(idx1, idx3, IncludePosition { line: 6, start: 0, end: 0 }); + + // 0 + // | + // 1 + // / \ + // 2 3 + + let roots = graph.collect_root_ancestors(idx3); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx2); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx1); + assert_eq!(roots, vec![idx0]); + + let roots = graph.collect_root_ancestors(idx0); + assert_eq!(roots, vec![]); + } + } +} diff --git a/server/main/src/linemap.rs b/server/main/src/linemap.rs new file mode 100644 index 0000000..3995100 --- /dev/null +++ b/server/main/src/linemap.rs @@ -0,0 +1,80 @@ +use rust_lsp::lsp_types::Position; + +pub struct LineMap { + positions: Vec, +} + +impl LineMap { + pub fn new(source: &str) -> Self { + let mut positions = vec![0]; + for (i, char) in source.char_indices() { + if char == '\n' { + positions.push(i + 1); + } + } + + LineMap { positions } + } + + pub fn offset_for_position(&self, position: Position) -> usize { + self.positions[position.line as usize] + (position.character as usize) + } +} + +#[cfg(test)] +mod test { + use rust_lsp::lsp_types::Position; + + use crate::linemap::LineMap; + + #[test] + #[logging_macro::log_scope] + fn test_linemap() { + struct Test { + string: &'static str, + pos: Position, + offset: usize, + } + + let cases = vec![ + Test { + string: "sample\ntext", + pos: Position { line: 1, character: 2 }, + offset: 9, + }, + Test { + string: "banana", + pos: Position { line: 0, character: 0 }, + offset: 0, + }, + Test { + string: "banana", + pos: Position { line: 0, character: 1 }, + offset: 1, + }, + Test { + string: "sample\ntext", + pos: Position { line: 1, character: 0 }, + offset: 7, + }, + Test { + string: "sample\n\ttext", + pos: Position { line: 1, character: 2 }, + offset: 9, + }, + Test { + string: "sample\r\ntext", + pos: Position { line: 1, character: 0 }, + offset: 8, + }, + ]; + + for case in cases { + let linemap = LineMap::new(case.string); + + let offset = linemap.offset_for_position(case.pos); + + assert_eq!(offset, case.offset, "{:?}", case.string); + } + } +} diff --git a/server/src/lsp_ext.rs b/server/main/src/lsp_ext.rs similarity index 99% rename from server/src/lsp_ext.rs rename to server/main/src/lsp_ext.rs index a4eb1b0..bcf1198 100644 --- a/server/src/lsp_ext.rs +++ b/server/main/src/lsp_ext.rs @@ -13,4 +13,4 @@ pub struct StatusParams { pub status: String, pub message: Option, pub icon: Option, -} \ No newline at end of file +} diff --git a/server/main/src/main.rs b/server/main/src/main.rs new file mode 100644 index 0000000..119dbdc --- /dev/null +++ b/server/main/src/main.rs @@ -0,0 +1,959 @@ +#![feature(once_cell)] +#![feature(option_get_or_insert_default)] + +use merge_views::FilialTuple; +use rust_lsp::jsonrpc::{method_types::*, *}; +use rust_lsp::lsp::*; +use rust_lsp::lsp_types::{notification::*, *}; + +use petgraph::stable_graph::NodeIndex; +use path_slash::PathExt; + +use serde::Deserialize; +use serde_json::{from_value, Value}; + +use tree_sitter::Parser; +use url_norm::FromUrl; + +use walkdir::WalkDir; + +use std::collections::{HashMap, HashSet}; +use std::convert::TryFrom; +use std::fmt::{Debug, Display, Formatter}; +use std::fs; +use std::io::{stdin, stdout, BufRead, BufReader}; +use std::iter::{Extend, FromIterator}; +use std::rc::Rc; +use std::str::FromStr; + +use std::{ + cell::RefCell, + path::{Path, PathBuf}, +}; + +use slog::Level; +use slog_scope::{debug, error, info, warn}; + +use path_slash::PathBufExt; + +use anyhow::{anyhow, Result}; + +use regex::Regex; + +use lazy_static::lazy_static; + +mod commands; +mod configuration; +mod consts; +mod dfs; +mod diagnostics_parser; +mod graph; +mod linemap; +mod lsp_ext; +mod merge_views; +mod navigation; +mod opengl; +mod source_mapper; +mod url_norm; + +#[cfg(test)] +mod test; + +pub fn is_top_level(path: &Path) -> bool { + let path = path.to_slash().unwrap(); + if !RE_WORLD_FOLDER.is_match(&path) { + return false; + } + let parts: Vec<&str> = path.split("/").collect(); + let len = parts.len(); + (len == 3 || len == 2) && TOPLEVEL_FILES.contains(parts[len - 1]) +} + +lazy_static! { + static ref RE_INCLUDE: Regex = Regex::new(r#"^(?:\s)*?(?:#include) "(.+)"\r?"#).unwrap(); + static ref RE_WORLD_FOLDER: Regex = Regex::new(r#"^shaders(/world-?\d+)?"#).unwrap(); + static ref TOPLEVEL_FILES: HashSet = { + let mut set = HashSet::with_capacity(1716); + for ext in ["fsh", "vsh", "gsh", "csh"] { + set.insert(format!("composite.{}", ext)); + set.insert(format!("deferred.{}", ext)); + set.insert(format!("prepare.{}", ext)); + set.insert(format!("shadowcomp.{}", ext)); + for i in 1..=99 { + set.insert(format!("composite{}.{}", i, ext)); + set.insert(format!("deferred{}.{}", i, ext)); + set.insert(format!("prepare{}.{}", i, ext)); + set.insert(format!("shadowcomp{}.{}", i, ext)); + } + set.insert(format!("composite_pre.{}", ext)); + set.insert(format!("deferred_pre.{}", ext)); + set.insert(format!("final.{}", ext)); + set.insert(format!("gbuffers_armor_glint.{}", ext)); + set.insert(format!("gbuffers_basic.{}", ext)); + set.insert(format!("gbuffers_beaconbeam.{}", ext)); + set.insert(format!("gbuffers_block.{}", ext)); + set.insert(format!("gbuffers_clouds.{}", ext)); + set.insert(format!("gbuffers_damagedblock.{}", ext)); + set.insert(format!("gbuffers_entities.{}", ext)); + set.insert(format!("gbuffers_entities_glowing.{}", ext)); + set.insert(format!("gbuffers_hand.{}", ext)); + set.insert(format!("gbuffers_hand_water.{}", ext)); + set.insert(format!("gbuffers_item.{}", ext)); + set.insert(format!("gbuffers_line.{}", ext)); + set.insert(format!("gbuffers_skybasic.{}", ext)); + set.insert(format!("gbuffers_skytextured.{}", ext)); + set.insert(format!("gbuffers_spidereyes.{}", ext)); + set.insert(format!("gbuffers_terrain.{}", ext)); + set.insert(format!("gbuffers_terrain_cutout.{}", ext)); + set.insert(format!("gbuffers_terrain_cutout_mip.{}", ext)); + set.insert(format!("gbuffers_terrain_solid.{}", ext)); + set.insert(format!("gbuffers_textured.{}", ext)); + set.insert(format!("gbuffers_textured_lit.{}", ext)); + set.insert(format!("gbuffers_water.{}", ext)); + set.insert(format!("gbuffers_weather.{}", ext)); + set.insert(format!("shadow.{}", ext)); + set.insert(format!("shadow_cutout.{}", ext)); + set.insert(format!("shadow_solid.{}", ext)); + } + let base_char_num = 'a' as u8; + for suffix_num in 0u8..=25u8 { + let suffix_char = (base_char_num + suffix_num) as char; + set.insert(format!("composite_{}.csh", suffix_char)); + set.insert(format!("deferred_{}.csh", suffix_char)); + set.insert(format!("prepare_{}.csh", suffix_char)); + set.insert(format!("shadowcomp_{}.csh", suffix_char)); + for i in 1..=99 { + let total_suffix = format!("{}_{}", i, suffix_char); + set.insert(format!("composite{}.csh", total_suffix)); + set.insert(format!("deferred{}.csh", total_suffix)); + set.insert(format!("prepare{}.csh", total_suffix)); + set.insert(format!("shadowcomp{}.csh", total_suffix)); + } + } + set + }; +} + +fn main() { + let guard = logging::set_logger_with_level(Level::Info); + + let endpoint_output = LSPEndpoint::create_lsp_output_with_output_stream(stdout); + + let cache_graph = graph::CachedStableGraph::new(); + + let mut parser = Parser::new(); + parser.set_language(tree_sitter_glsl::language()).unwrap(); + + let mut langserver = MinecraftShaderLanguageServer { + endpoint: endpoint_output.clone(), + graph: Rc::new(RefCell::new(cache_graph)), + root: "".into(), + command_provider: None, + opengl_context: Rc::new(opengl::OpenGlContext::new()), + tree_sitter: Rc::new(RefCell::new(parser)), + log_guard: Some(guard), + }; + + langserver.command_provider = Some(commands::CustomCommandProvider::new(vec![ + ( + "graphDot", + Box::new(commands::graph_dot::GraphDotCommand { + graph: langserver.graph.clone(), + }), + ), + ( + "virtualMerge", + Box::new(commands::merged_includes::VirtualMergedDocument { + graph: langserver.graph.clone(), + }), + ), + ( + "parseTree", + Box::new(commands::parse_tree::TreeSitterSExpr { + tree_sitter: langserver.tree_sitter.clone(), + }), + ), + ])); + + LSPEndpoint::run_server_from_input(&mut stdin().lock(), endpoint_output, langserver); +} + +pub struct MinecraftShaderLanguageServer { + endpoint: Endpoint, + graph: Rc>, + root: PathBuf, + command_provider: Option, + opengl_context: Rc, + tree_sitter: Rc>, + log_guard: Option, +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct IncludePosition { + // the 0-indexed line on which the include lives. + line: usize, + // the 0-indexed char offset defining the start of the include path string. + start: usize, + // the 0-indexed char offset defining the end of the include path string. + end: usize, +} + +impl Debug for IncludePosition { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{{line: {}}}", self.line) + } +} + +impl Display for IncludePosition { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "{{line: {}}}", self.line) + } +} + +#[derive(Debug)] +pub enum TreeType { + Fragment, + Vertex, + Geometry, + Compute, +} + +impl MinecraftShaderLanguageServer { + pub fn error_not_available(data: DATA) -> MethodError { + let msg = "Functionality not implemented.".to_string(); + MethodError:: { + code: 1, + message: msg, + data, + } + } + + fn build_initial_graph(&self) { + info!("generating graph for current root"; "root" => self.root.to_str().unwrap()); + + // filter directories and files not ending in any of the 3 extensions + WalkDir::new(&self.root) + .into_iter() + .filter_map(|entry| { + if entry.is_err() { + return None; + } + + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + return None; + } + + let ext = match path.extension() { + Some(e) => e, + None => return None, + }; + + // TODO: include user added extensions with a set + if ext != "vsh" && ext != "fsh" && ext != "csh" && ext != "gsh" && ext != "glsl" && ext != "inc" { + return None; + } + + Some(entry.into_path()) + }) + .for_each(|path| { + // iterate all valid found files, search for includes, add a node into the graph for each + // file and add a file->includes KV into the map + self.add_file_and_includes_to_graph(&path); + }); + + info!("finished building project include graph"); + } + + fn add_file_and_includes_to_graph(&self, path: &Path) { + let includes = self.find_includes(path); + + let idx = self.graph.borrow_mut().add_node(path); + + debug!("adding includes for new file"; "file" => path.to_str().unwrap(), "includes" => format!("{:?}", includes)); + for include in includes { + self.add_include(include, idx); + } + } + + fn add_include(&self, include: (PathBuf, IncludePosition), node: NodeIndex) { + let child = self.graph.borrow_mut().add_node(&include.0); + self.graph.borrow_mut().add_edge(node, child, include.1); + } + + pub fn find_includes(&self, file: &Path) -> Vec<(PathBuf, IncludePosition)> { + let mut includes = Vec::default(); + + let buf = BufReader::new(std::fs::File::open(file).unwrap()); + buf.lines() + .enumerate() + .filter_map(|line| match line.1 { + Ok(t) => Some((line.0, t)), + Err(_e) => None, + }) + .filter(|line| RE_INCLUDE.is_match(line.1.as_str())) + .for_each(|line| { + let cap = RE_INCLUDE.captures(line.1.as_str()).unwrap().get(1).unwrap(); + + let start = cap.start(); + let end = cap.end(); + let mut path: String = cap.as_str().into(); + + let full_include = if path.starts_with('/') { + path = path.strip_prefix('/').unwrap().to_string(); + self.root.join("shaders").join(PathBuf::from_slash(&path)) + } else { + file.parent().unwrap().join(PathBuf::from_slash(&path)) + }; + + includes.push((full_include, IncludePosition { line: line.0, start, end })); + }); + + includes + } + + fn update_includes(&self, file: &Path) { + let includes = self.find_includes(file); + + info!("includes found for file"; "file" => file.to_str().unwrap(), "includes" => format!("{:?}", includes)); + + let idx = match self.graph.borrow_mut().find_node(file) { + None => return, + Some(n) => n, + }; + + let prev_children: HashSet<_> = HashSet::from_iter(self.graph.borrow().get_all_child_positions(idx).map(|tup| { + (self.graph.borrow().get_node(tup.0), tup.1) + })); + let new_children: HashSet<_> = includes.iter().cloned().collect(); + + let to_be_added = new_children.difference(&prev_children); + let to_be_removed = prev_children.difference(&new_children); + + debug!( + "include sets diff'd"; + "for removal" => format!("{:?}", to_be_removed), + "for addition" => format!("{:?}", to_be_added) + ); + + for removal in to_be_removed { + let child = self.graph.borrow_mut().find_node(&removal.0).unwrap(); + self.graph.borrow_mut().remove_edge(idx, child, removal.1); + } + + for insertion in to_be_added { + self.add_include(includes.iter().find(|f| f.0 == *insertion.0).unwrap().clone(), idx); + } + } + + pub fn lint(&self, uri: &Path) -> Result>> { + // get all top level ancestors of this file + let file_ancestors = match self.get_file_toplevel_ancestors(uri) { + Ok(opt) => match opt { + Some(ancestors) => ancestors, + None => vec![], + }, + Err(e) => return Err(e), + }; + + info!( + "top-level file ancestors found"; + "uri" => uri.to_str().unwrap(), + "ancestors" => format!("{:?}", file_ancestors + .iter() + .map(|e| PathBuf::from_str( + &self.graph.borrow().graph[*e].clone() + ) + .unwrap()) + .collect::>()) + ); + + // the set of all filepath->content. + let mut all_sources: HashMap = HashMap::new(); + // the set of filepath->list of diagnostics to report + let mut diagnostics: HashMap> = HashMap::new(); + + // we want to backfill the diagnostics map with all linked sources + let back_fill = |all_sources: &HashMap, diagnostics: &mut HashMap>| { + for path in all_sources.keys() { + diagnostics.entry(Url::from_file_path(path).unwrap()).or_default(); + } + }; + + // if we are a top-level file (this has to be one of the set defined by Optifine, right?) + if file_ancestors.is_empty() { + // gather the list of all descendants + let root = self.graph.borrow_mut().find_node(uri).unwrap(); + let tree = match self.get_dfs_for_node(root) { + Ok(tree) => tree, + Err(e) => { + diagnostics.insert(Url::from_file_path(uri).unwrap(), vec![e.into()]); + return Ok(diagnostics); + } + }; + + all_sources.extend(self.load_sources(&tree)?); + + let mut source_mapper = source_mapper::SourceMapper::new(all_sources.len()); + + let view = { + let graph = self.graph.borrow(); + let merged_string = { + merge_views::MergeViewBuilder::new(&tree, &all_sources, &graph, &mut source_mapper).build() + }; + merged_string + }; + + let root_path = self.graph.borrow().get_node(root); + let ext = match root_path.extension() { + Some(ext) => ext.to_str().unwrap(), + None => { + back_fill(&all_sources, &mut diagnostics); + return Ok(diagnostics); + } + }; + + if !is_top_level(root_path.strip_prefix(&self.root).unwrap()) { + warn!("got a non-valid toplevel file"; "root_ancestor" => root_path.to_str().unwrap(), "stripped" => root_path.strip_prefix(&self.root).unwrap().to_str().unwrap()); + back_fill(&all_sources, &mut diagnostics); + return Ok(diagnostics); + } + + let tree_type = if ext == "fsh" { + TreeType::Fragment + } else if ext == "vsh" { + TreeType::Vertex + } else if ext == "gsh" { + TreeType::Geometry + } else if ext == "csh" { + TreeType::Compute + } else { + unreachable!(); + }; + + let stdout = match self.compile_shader_source(&view, tree_type, &root_path) { + Some(s) => s, + None => { + back_fill(&all_sources, &mut diagnostics); + return Ok(diagnostics); + } + }; + + let diagnostics_parser = diagnostics_parser::DiagnosticsParser::new(self.opengl_context.as_ref()); + + diagnostics.extend(diagnostics_parser.parse_diagnostics_output(stdout, uri, &source_mapper, &self.graph.borrow())); + } else { + let mut all_trees: Vec<(TreeType, Vec)> = Vec::new(); + + for root in &file_ancestors { + let nodes = match self.get_dfs_for_node(*root) { + Ok(nodes) => nodes, + Err(e) => { + diagnostics.insert(Url::from_file_path(uri).unwrap(), vec![e.into()]); + back_fill(&all_sources, &mut diagnostics); // TODO: confirm + return Ok(diagnostics); + } + }; + + let root_path = self.graph.borrow().get_node(*root).clone(); + let ext = match root_path.extension() { + Some(ext) => ext.to_str().unwrap(), + None => continue, + }; + + if !is_top_level(root_path.strip_prefix(&self.root).unwrap()) { + warn!("got a non-valid toplevel file"; "root_ancestor" => root_path.to_str().unwrap(), "stripped" => root_path.strip_prefix(&self.root).unwrap().to_str().unwrap()); + continue; + } + + let tree_type = if ext == "fsh" { + TreeType::Fragment + } else if ext == "vsh" { + TreeType::Vertex + } else if ext == "gsh" { + TreeType::Geometry + } else if ext == "csh" { + TreeType::Compute + } else { + unreachable!(); + }; + + let sources = self.load_sources(&nodes)?; + all_trees.push((tree_type, nodes)); + all_sources.extend(sources); + } + + for tree in all_trees { + // bit over-zealous in allocation but better than having to resize + let mut source_mapper = source_mapper::SourceMapper::new(all_sources.len()); + let view = { + let graph = self.graph.borrow(); + let merged_string = { + merge_views::MergeViewBuilder::new(&tree.1, &all_sources, &graph, &mut source_mapper).build() + }; + merged_string + }; + + let root_path = self.graph.borrow().get_node(tree.1.first().unwrap().child); + let stdout = match self.compile_shader_source(&view, tree.0, &root_path) { + Some(s) => s, + None => continue, + }; + + let diagnostics_parser = diagnostics_parser::DiagnosticsParser::new(self.opengl_context.as_ref()); + + diagnostics.extend(diagnostics_parser.parse_diagnostics_output(stdout, uri, &source_mapper, &self.graph.borrow())); + } + }; + + back_fill(&all_sources, &mut diagnostics); + Ok(diagnostics) + } + + fn compile_shader_source(&self, source: &str, tree_type: TreeType, path: &Path) -> Option { + let result = self.opengl_context.clone().validate(tree_type, source); + match &result { + Some(output) => { + info!("compilation errors reported"; "errors" => format!("`{}`", output.replace('\n', "\\n")), "tree_root" => path.to_str().unwrap()) + } + None => info!("compilation reported no errors"; "tree_root" => path.to_str().unwrap()), + }; + result + } + + pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result, dfs::error::CycleError> { + let graph_ref = self.graph.borrow(); + + let dfs = dfs::Dfs::new(&graph_ref, root); + + dfs.collect::>() + } + + pub fn load_sources(&self, nodes: &[FilialTuple]) -> Result> { + let mut sources = HashMap::new(); + + for node in nodes { + let graph = self.graph.borrow(); + let path = graph.get_node(node.child); + + if sources.contains_key(&path) { + continue; + } + + let source = match fs::read_to_string(&path) { + Ok(s) => s, + Err(e) => return Err(anyhow!("error reading {:?}: {}", path, e)), + }; + let source = source.replace("\r\n", "\n"); + sources.insert(path.clone(), source); + } + + Ok(sources) + } + + fn get_file_toplevel_ancestors(&self, uri: &Path) -> Result>> { + let curr_node = match self.graph.borrow_mut().find_node(uri) { + Some(n) => n, + None => return Err(anyhow!("node not found {:?}", uri)), + }; + let roots = self.graph.borrow().collect_root_ancestors(curr_node); + if roots.is_empty() { + return Ok(None); + } + Ok(Some(roots)) + } + + pub fn publish_diagnostic(&self, diagnostics: HashMap>, document_version: Option) { + // info!("DIAGNOSTICS:\n{:?}", diagnostics); + for (uri, diagnostics) in diagnostics { + self.endpoint + .send_notification( + PublishDiagnostics::METHOD, + PublishDiagnosticsParams { + uri, + diagnostics, + version: document_version, + }, + ) + .expect("failed to publish diagnostics"); + } + } + + fn set_status(&self, status: impl Into, message: impl Into, icon: impl Into) { + self.endpoint + .send_notification( + lsp_ext::Status::METHOD, + lsp_ext::StatusParams { + status: status.into(), + message: Some(message.into()), + icon: Some(icon.into()), + }, + ) + .unwrap_or(()); + } +} + +impl LanguageServerHandling for MinecraftShaderLanguageServer { + fn initialize(&mut self, params: InitializeParams, completable: MethodCompletable) { + logging::slog_with_trace_id(|| { + info!("starting server..."); + + let capabilities = ServerCapabilities { + definition_provider: Some(OneOf::Left(true)), + references_provider: Some(OneOf::Left(true)), + document_symbol_provider: Some(OneOf::Left(true)), + document_link_provider: Some(DocumentLinkOptions { + resolve_provider: None, + work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, + }), + execute_command_provider: Some(ExecuteCommandOptions { + commands: vec!["graphDot".into()], + work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, + }), + text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { + open_close: Some(true), + will_save: None, + will_save_wait_until: None, + change: Some(TextDocumentSyncKind::FULL), + save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions { include_text: Some(true) })), + })), + ..ServerCapabilities::default() + }; + + let root = match params.root_uri { + Some(uri) => PathBuf::from_url(uri), + None => { + completable.complete(Err(MethodError { + code: 42069, + message: "Must be in workspace".into(), + data: InitializeError { retry: false }, + })); + return; + } + }; + + completable.complete(Ok(InitializeResult { + capabilities, + server_info: None, + })); + + self.set_status("loading", "Building dependency graph...", "$(loading~spin)"); + + self.root = root; + + + self.build_initial_graph(); + + self.set_status("ready", "Project initialized", "$(check)"); + }); + } + + fn shutdown(&mut self, _: (), completable: LSCompletable<()>) { + warn!("shutting down language server..."); + completable.complete(Ok(())); + } + + fn exit(&mut self, _: ()) { + self.endpoint.request_shutdown(); + } + + fn workspace_change_configuration(&mut self, params: DidChangeConfigurationParams) { + logging::slog_with_trace_id(|| { + #[derive(Deserialize)] + struct Configuration { + #[serde(alias = "logLevel")] + log_level: String, + } + + if let Some(settings) = params.settings.as_object().unwrap().get("mcglsl") { + let config: Configuration = from_value(settings.to_owned()).unwrap(); + + info!("got updated configuration"; "config" => params.settings.as_object().unwrap().get("mcglsl").unwrap().to_string()); + + configuration::handle_log_level_change(config.log_level, |level| { + self.log_guard = None; // set to None so Drop is invoked + self.log_guard = Some(logging::set_logger_with_level(level)); + }) + } + }); + } + + fn did_open_text_document(&mut self, params: DidOpenTextDocumentParams) { + logging::slog_with_trace_id(|| { + //info!("opened doc {}", params.text_document.uri); + let path = PathBuf::from_url(params.text_document.uri); + if !path.starts_with(&self.root) { + return; + } + + if self.graph.borrow_mut().find_node(&path) == None { + self.add_file_and_includes_to_graph(&path); + } + match self.lint(&path) { + Ok(diagnostics) => self.publish_diagnostic(diagnostics, None), + Err(e) => error!("error linting"; "error" => format!("{:?}", e), "path" => path.to_str().unwrap()), + } + }); + } + + fn did_change_text_document(&mut self, _: DidChangeTextDocumentParams) {} + + fn did_close_text_document(&mut self, _: DidCloseTextDocumentParams) {} + + fn did_save_text_document(&mut self, params: DidSaveTextDocumentParams) { + logging::slog_with_trace_id(|| { + let path = PathBuf::from_url(params.text_document.uri); + if !path.starts_with(&self.root) { + return; + } + self.update_includes(&path); + + match self.lint(&path) { + Ok(diagnostics) => self.publish_diagnostic(diagnostics, None), + Err(e) => error!("error linting"; "error" => format!("{:?}", e), "path" => path.to_str().unwrap()), + } + }); + } + + fn did_change_watched_files(&mut self, _: DidChangeWatchedFilesParams) {} + + fn completion(&mut self, _: TextDocumentPositionParams, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn resolve_completion_item(&mut self, _: CompletionItem, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn hover(&mut self, _: TextDocumentPositionParams, _: LSCompletable) { + /* completable.complete(Ok(Hover{ + contents: HoverContents::Markup(MarkupContent{ + kind: MarkupKind::Markdown, + value: String::from("# Hello World"), + }), + range: None, + })); */ + } + + fn execute_command(&mut self, params: ExecuteCommandParams, completable: LSCompletable>) { + logging::slog_with_trace_id(|| { + match self + .command_provider + .as_ref() + .unwrap() + .execute(¶ms.command, ¶ms.arguments, &self.root) + { + Ok(resp) => { + info!("executed command successfully"; "command" => params.command.clone()); + self.endpoint + .send_notification( + ShowMessage::METHOD, + ShowMessageParams { + typ: MessageType::INFO, + message: format!("Command {} executed successfully.", params.command), + }, + ) + .expect("failed to send popup/show message notification"); + completable.complete(Ok(Some(resp))) + } + Err(err) => { + error!("failed to execute command"; "command" => params.command.clone(), "error" => format!("{:?}", err)); + self.endpoint + .send_notification( + ShowMessage::METHOD, + ShowMessageParams { + typ: MessageType::ERROR, + message: format!("Failed to execute `{}`. Reason: {}", params.command, err), + }, + ) + .expect("failed to send popup/show message notification"); + completable.complete(Err(MethodError::new(32420, err.to_string(), ()))) + } + } + }); + } + + fn signature_help(&mut self, _: TextDocumentPositionParams, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn goto_definition(&mut self, params: TextDocumentPositionParams, completable: LSCompletable>) { + logging::slog_with_trace_id(|| { + let path = PathBuf::from_url(params.text_document.uri); + if !path.starts_with(&self.root) { + return; + } + let parser = &mut self.tree_sitter.borrow_mut(); + let parser_ctx = match navigation::ParserContext::new(parser, &path) { + Ok(ctx) => ctx, + Err(e) => { + return completable.complete(Err(MethodError { + code: 42069, + message: format!("error building parser context: error={}, path={:?}", e, path), + data: (), + })) + } + }; + + match parser_ctx.find_definitions(&path, params.position) { + Ok(locations) => completable.complete(Ok(locations.unwrap_or_default())), + Err(e) => completable.complete(Err(MethodError { + code: 42069, + message: format!("error finding definitions: error={}, path={:?}", e, path), + data: (), + })), + } + }); + } + + fn references(&mut self, params: ReferenceParams, completable: LSCompletable>) { + logging::slog_with_trace_id(|| { + let path = PathBuf::from_url(params.text_document_position.text_document.uri); + if !path.starts_with(&self.root) { + return; + } + let parser = &mut self.tree_sitter.borrow_mut(); + let parser_ctx = match navigation::ParserContext::new(parser, &path) { + Ok(ctx) => ctx, + Err(e) => { + return completable.complete(Err(MethodError { + code: 42069, + message: format!("error building parser context: error={}, path={:?}", e, path), + data: (), + })) + } + }; + + match parser_ctx.find_references(&path, params.text_document_position.position) { + Ok(locations) => completable.complete(Ok(locations.unwrap_or_default())), + Err(e) => completable.complete(Err(MethodError { + code: 42069, + message: format!("error finding definitions: error={}, path={:?}", e, path), + data: (), + })), + } + }); + } + + fn document_highlight(&mut self, _: TextDocumentPositionParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn document_symbols(&mut self, params: DocumentSymbolParams, completable: LSCompletable) { + logging::slog_with_trace_id(|| { + let path = PathBuf::from_url(params.text_document.uri); + if !path.starts_with(&self.root) { + return; + } + let parser = &mut self.tree_sitter.borrow_mut(); + let parser_ctx = match navigation::ParserContext::new(parser, &path) { + Ok(ctx) => ctx, + Err(e) => { + return completable.complete(Err(MethodError { + code: 42069, + message: format!("error building parser context: error={}, path={:?}", e, path), + data: (), + })) + } + }; + + match parser_ctx.list_symbols(&path) { + Ok(symbols) => completable.complete(Ok(DocumentSymbolResponse::from(symbols.unwrap_or_default()))), + Err(e) => { + return completable.complete(Err(MethodError { + code: 42069, + message: format!("error finding definitions: error={}, path={:?}", e, path), + data: (), + })) + } + } + }); + } + + fn workspace_symbols(&mut self, _: WorkspaceSymbolParams, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn code_action(&mut self, _: CodeActionParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn code_lens(&mut self, _: CodeLensParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn code_lens_resolve(&mut self, _: CodeLens, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn document_link(&mut self, params: DocumentLinkParams, completable: LSCompletable>) { + logging::slog_with_trace_id(|| { + // node for current document + let curr_doc = PathBuf::from_url(params.text_document.uri); + let node = match self.graph.borrow_mut().find_node(&curr_doc) { + Some(n) => n, + None => { + warn!("document not found in graph"; "path" => curr_doc.to_str().unwrap()); + completable.complete(Ok(vec![])); + return; + } + }; + + let edges: Vec = self + .graph + .borrow() + .child_node_indexes(node) + .filter_map::, _>(|child| { + let graph = self.graph.borrow(); + graph.get_child_positions(node, child).map(|value| { + let path = graph.get_node(child); + let url = match Url::from_file_path(&path) { + Ok(url) => url, + Err(e) => { + error!("error converting into url"; "path" => path.to_str().unwrap(), "error" => format!("{:?}", e)); + return None; + } + }; + + Some(DocumentLink { + range: Range::new( + Position::new(u32::try_from(value.line).unwrap(), u32::try_from(value.start).unwrap()), + Position::new(u32::try_from(value.line).unwrap(), u32::try_from(value.end).unwrap()), + ), + target: Some(url.clone()), + tooltip: Some(url.path().to_string()), + data: None, + }) + }).collect() + }) + .flatten() + .collect(); + debug!("document link results"; + "links" => format!("{:?}", edges.iter().map(|e| (e.range, e.target.as_ref().unwrap().path())).collect::>()), + "path" => curr_doc.to_str().unwrap(), + ); + completable.complete(Ok(edges)); + }); + } + + fn document_link_resolve(&mut self, _: DocumentLink, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn formatting(&mut self, _: DocumentFormattingParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn range_formatting(&mut self, _: DocumentRangeFormattingParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn on_type_formatting(&mut self, _: DocumentOnTypeFormattingParams, completable: LSCompletable>) { + completable.complete(Err(Self::error_not_available(()))); + } + + fn rename(&mut self, _: RenameParams, completable: LSCompletable) { + completable.complete(Err(Self::error_not_available(()))); + } +} diff --git a/server/main/src/merge_views.rs b/server/main/src/merge_views.rs new file mode 100644 index 0000000..8eec146 --- /dev/null +++ b/server/main/src/merge_views.rs @@ -0,0 +1,645 @@ +use std::cmp::min; +use std::iter::Peekable; +use std::{ + collections::{HashMap, LinkedList, VecDeque}, + path::{Path, PathBuf}, +}; + +use core::slice::Iter; + +use petgraph::stable_graph::NodeIndex; +use slog_scope::debug; + +use crate::graph::CachedStableGraph; +use crate::source_mapper::SourceMapper; +use crate::IncludePosition; + +/// FilialTuple represents a tuple (not really) of a child and any legitimate +/// parent. Parent can be nullable in the case of the child being a top level +/// node in the tree. +#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] +pub struct FilialTuple { + pub child: NodeIndex, + pub parent: Option, +} + +/// Merges the source strings according to the nodes comprising a tree of imports into a GLSL source string +/// that can be handed off to the GLSL compiler. +pub struct MergeViewBuilder<'a> { + nodes: &'a [FilialTuple], + nodes_peeker: Peekable>, + + sources: &'a HashMap, + graph: &'a CachedStableGraph, + source_mapper: &'a mut SourceMapper, + + // holds the offset into the child which has been added to the merge list for a parent. + // A child can have multiple parents for a given tree, and be included multiple times + // by the same parent, hence we have to track it for a ((child, parent), line) tuple + // instead of just the child or (child, parent). + last_offset_set: HashMap, + // holds, for any given filial tuple, the iterator yielding all the positions at which the child + // is included into the parent in line-sorted order. This is necessary for files that are imported + // more than once into the same parent, so we can easily get the next include position. + parent_child_edge_iterator: HashMap + 'a)>>, +} + +impl<'a> MergeViewBuilder<'a> { + pub fn new( + nodes: &'a [FilialTuple], sources: &'a HashMap, graph: &'a CachedStableGraph, source_mapper: &'a mut SourceMapper, + ) -> Self { + MergeViewBuilder { + nodes, + nodes_peeker: nodes.iter().peekable(), + sources, + graph, + source_mapper, + last_offset_set: HashMap::new(), + parent_child_edge_iterator: HashMap::new(), + } + } + + pub fn build(&mut self) -> String { + // contains additionally inserted lines such as #line and other directives, preamble defines etc + let mut extra_lines: Vec = Vec::new(); + extra_lines.reserve((self.nodes.len() * 2) + 2); + + // list of source code views onto the below sources + let mut merge_list: LinkedList<&'a str> = LinkedList::new(); + + // invariant: nodes_iter always has _at least_ one element. Can't save a not-file :B + let first = self.nodes_peeker.next().unwrap().child; + let first_path = self.graph.get_node(first); + let first_source = self.sources.get(&first_path).unwrap(); + + // seed source_mapper with top-level file + self.source_mapper.get_num(first); + + let version_line_offset = self.find_version_offset(first_source); + let _version_char_offsets = self.char_offset_for_line(version_line_offset, first_source); + // add_preamble( + // version_line_offset, + // version_char_offsets.1, + // &first_path, + // first, + // first_source, + // &mut merge_list, + // &mut extra_lines, + // source_mapper, + // ); + + // last_offset_set.insert((first, None), version_char_offsets.1); + self.set_last_offset_for_tuple(None, first, 0); + + // stack to keep track of the depth first traversal + let mut stack = VecDeque::::new(); + + self.create_merge_views(&mut merge_list, &mut extra_lines, &mut stack); + + // now we add a view of the remainder of the root file + + let offset = self.get_last_offset_for_tuple(None, first).unwrap(); + + let len = first_source.len(); + merge_list.push_back(&first_source[min(offset, len)..]); + + let total_len = merge_list.iter().fold(0, |a, b| a + b.len()); + + let mut merged = String::with_capacity(total_len); + merged.extend(merge_list); + + merged + } + + fn create_merge_views(&mut self, merge_list: &mut LinkedList<&'a str>, extra_lines: &mut Vec, stack: &mut VecDeque) { + loop { + let n = match self.nodes_peeker.next() { + Some(n) => n, + None => return, + }; + + // invariant: never None as only the first element in `nodes` should have a None, which is popped off in the calling function + let (parent, child) = (n.parent.unwrap(), n.child); + // gets the next include position for the filial tuple, seeding if this is the first time querying this tuple + let edge = self + .parent_child_edge_iterator + .entry(*n) + .or_insert_with(|| { + let child_positions = self.graph.get_child_positions(parent, child); + Box::new(child_positions) + }) + .next() + .unwrap(); + let parent_path = self.graph.get_node(parent).clone(); + let child_path = self.graph.get_node(child).clone(); + + let parent_source = self.sources.get(&parent_path).unwrap(); + let (char_for_line, char_following_line) = self.char_offset_for_line(edge.line, parent_source); + + let offset = *self + .set_last_offset_for_tuple(stack.back().copied(), parent, char_following_line) + .get_or_insert(0); + + debug!("creating view to start child file"; + "parent" => parent_path.to_str().unwrap(), "child" => child_path.to_str().unwrap(), + "grandparent" => stack.back().copied().map(|g| self.graph.get_node(g).to_str().unwrap().to_string()), // self.graph.get_node().to_str().unwrap(), + "last_parent_offset" => offset, "line" => edge.line, "char_for_line" => char_for_line, + "char_following_line" => char_following_line, + ); + + merge_list.push_back(&parent_source[offset..char_for_line]); + self.add_opening_line_directive(&child_path, child, merge_list, extra_lines); + + match self.nodes_peeker.peek() { + Some(next) => { + let next = *next; + // if the next pair's parent is not a child of the current pair, we dump the rest of this childs source + if next.parent.unwrap() != child { + let child_source = self.sources.get(&child_path).unwrap(); + // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad + let offset = { + match child_source.ends_with('\n') { + true => child_source.len() - 1, + false => child_source.len(), + } + }; + merge_list.push_back(&child_source[..offset]); + self.set_last_offset_for_tuple(Some(parent), child, 0); + // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line + self.add_closing_line_directive(edge.line + 2, &parent_path, parent, merge_list, extra_lines); + // if the next pair's parent is not the current pair's parent, we need to bubble up + if stack.contains(&next.parent.unwrap()) { + return; + } + continue; + } + + stack.push_back(parent); + self.create_merge_views(merge_list, extra_lines, stack); + stack.pop_back(); + + let offset = self.get_last_offset_for_tuple(Some(parent), child).unwrap(); + let child_source = self.sources.get(&child_path).unwrap(); + // this evaluates to false once the file contents have been exhausted aka offset = child_source.len() + 1 + let end_offset = match child_source.ends_with('\n') { + true => 1, + false => 0, + }; + if offset < child_source.len() - end_offset { + // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad + merge_list.push_back(&child_source[offset..child_source.len() - end_offset]); + self.set_last_offset_for_tuple(Some(parent), child, 0); + } + + // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line + self.add_closing_line_directive(edge.line + 2, &parent_path, parent, merge_list, extra_lines); + + // we need to check the next item at the point of original return further down the callstack + if self.nodes_peeker.peek().is_some() && stack.contains(&self.nodes_peeker.peek().unwrap().parent.unwrap()) { + return; + } + } + None => { + let child_source = self.sources.get(&child_path).unwrap(); + // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad + let offset = match child_source.ends_with('\n') { + true => child_source.len() - 1, + false => child_source.len(), + }; + merge_list.push_back(&child_source[..offset]); + self.set_last_offset_for_tuple(Some(parent), child, 0); + // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line + self.add_closing_line_directive(edge.line + 2, &parent_path, parent, merge_list, extra_lines); + } + } + } + } + + fn set_last_offset_for_tuple(&mut self, parent: Option, child: NodeIndex, offset: usize) -> Option { + debug!("inserting last offset"; + "parent" => parent.map(|p| self.graph.get_node(p).to_str().unwrap().to_string()), + "child" => self.graph.get_node(child).to_str().unwrap().to_string(), + "offset" => offset); + self.last_offset_set.insert(FilialTuple { child, parent }, offset) + } + + fn get_last_offset_for_tuple(&self, parent: Option, child: NodeIndex) -> Option { + self.last_offset_set.get(&FilialTuple { child, parent }).copied() + } + + // returns the character offset + 1 of the end of line number `line` and the character + // offset + 1 for the end of the line after the previous one + fn char_offset_for_line(&self, line_num: usize, source: &str) -> (usize, usize) { + let mut char_for_line: usize = 0; + let mut char_following_line: usize = 0; + for (n, line) in source.lines().enumerate() { + if n == line_num { + char_following_line += line.len() + 1; + break; + } + char_for_line += line.len() + 1; + char_following_line = char_for_line; + } + (char_for_line, char_following_line) + } + + fn find_version_offset(&self, source: &str) -> usize { + source + .lines() + .enumerate() + .find(|(_, line)| line.starts_with("#version ")) + .map_or(0, |(i, _)| i) + } + + // fn add_preamble<'a>( + // version_line_offset: usize, version_char_offset: usize, path: &Path, node: NodeIndex, source: &'a str, + // merge_list: &mut LinkedList<&'a str>, extra_lines: &mut Vec, source_mapper: &mut SourceMapper, + // ) { + // // TODO: Optifine #define preabmle + // merge_list.push_back(&source[..version_char_offset]); + // let google_line_directive = format!( + // "#extension GL_GOOGLE_cpp_style_line_directive : enable\n#line {} {} // {}\n", + // // +2 because 0 indexed but #line is 1 indexed and references the *following* line + // version_line_offset + 2, + // source_mapper.get_num(node), + // path.to_str().unwrap().replace('\\', "\\\\"), + // ); + // extra_lines.push(google_line_directive); + // unsafe_get_and_insert(merge_list, extra_lines); + // } + + fn add_opening_line_directive( + &mut self, path: &Path, node: NodeIndex, merge_list: &mut LinkedList<&str>, extra_lines: &mut Vec, + ) { + let line_directive = format!( + "#line 1 {} // {}\n", + self.source_mapper.get_num(node), + path.to_str().unwrap().replace('\\', "\\\\") + ); + extra_lines.push(line_directive); + self.unsafe_get_and_insert(merge_list, extra_lines); + } + + fn add_closing_line_directive( + &mut self, line: usize, path: &Path, node: NodeIndex, merge_list: &mut LinkedList<&str>, extra_lines: &mut Vec, + ) { + // Optifine doesn't seem to add a leading newline if the previous line was a #line directive + let line_directive = if let Some(l) = merge_list.back() { + if l.trim().starts_with("#line") { + format!( + "#line {} {} // {}\n", + line, + self.source_mapper.get_num(node), + path.to_str().unwrap().replace('\\', "\\\\") + ) + } else { + format!( + "\n#line {} {} // {}\n", + line, + self.source_mapper.get_num(node), + path.to_str().unwrap().replace('\\', "\\\\") + ) + } + } else { + format!( + "\n#line {} {} // {}\n", + line, + self.source_mapper.get_num(node), + path.to_str().unwrap().replace('\\', "\\\\") + ) + }; + + extra_lines.push(line_directive); + self.unsafe_get_and_insert(merge_list, extra_lines); + } + + fn unsafe_get_and_insert(&self, merge_list: &mut LinkedList<&str>, extra_lines: &[String]) { + // :^) + unsafe { + let vec_ptr_offset = extra_lines.as_ptr().add(extra_lines.len() - 1); + merge_list.push_back(&vec_ptr_offset.as_ref().unwrap()[..]); + } + } +} + +#[cfg(test)] +mod merge_view_test { + use std::fs; + use std::path::PathBuf; + + use crate::merge_views::MergeViewBuilder; + use crate::source_mapper::SourceMapper; + use crate::test::{copy_to_and_set_root, new_temp_server}; + use crate::IncludePosition; + + #[test] + #[logging_macro::log_scope] + fn test_generate_merge_list_01() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/01", &mut server); + server.endpoint.request_shutdown(); + + let final_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("final.fsh")); + let common_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("common.glsl")); + + server + .graph + .borrow_mut() + .add_edge(final_idx, common_idx, IncludePosition { line: 2, start: 0, end: 0 }); + + let nodes = server.get_dfs_for_node(final_idx).unwrap(); + let sources = server.load_sources(&nodes).unwrap(); + + let graph_borrow = server.graph.borrow(); + let mut source_mapper = SourceMapper::new(0); + let result = MergeViewBuilder::new(&nodes, &sources, &graph_borrow, &mut source_mapper).build(); + + let merge_file = tmp_path.join("shaders").join("final.fsh.merge"); + + let mut truth = fs::read_to_string(merge_file).unwrap(); + // truth = truth.replacen( + // "!!", + // &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + // 1, + // ); + truth = truth.replacen( + "!!", + &tmp_path.join("shaders").join("common.glsl").to_str().unwrap().replace('\\', "\\\\"), + 1, + ); + truth = truth.replace( + "!!", + &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + ); + + assert_eq!(result, truth); + } + + #[test] + #[logging_macro::log_scope] + fn test_generate_merge_list_02() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/02", &mut server); + server.endpoint.request_shutdown(); + + let final_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("final.fsh")); + let test_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("test.glsl")); + let burger_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("burger.glsl")); + let sample_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("sample.glsl")); + + server + .graph + .borrow_mut() + .add_edge(final_idx, sample_idx, IncludePosition { line: 2, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(sample_idx, burger_idx, IncludePosition { line: 4, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(sample_idx, test_idx, IncludePosition { line: 6, start: 0, end: 0 }); + + let nodes = server.get_dfs_for_node(final_idx).unwrap(); + let sources = server.load_sources(&nodes).unwrap(); + + let graph_borrow = server.graph.borrow(); + let mut source_mapper = SourceMapper::new(0); + let result = MergeViewBuilder::new(&nodes, &sources, &graph_borrow, &mut source_mapper).build(); + + let merge_file = tmp_path.join("shaders").join("final.fsh.merge"); + + let mut truth = fs::read_to_string(merge_file).unwrap(); + + // truth = truth.replacen( + // "!!", + // &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + // 1, + // ); + + for file in &["sample.glsl", "burger.glsl", "sample.glsl", "test.glsl", "sample.glsl"] { + let path = tmp_path.clone(); + truth = truth.replacen( + "!!", + &path + .join("shaders") + .join("utils") + .join(file) + .to_str() + .unwrap() + .replace('\\', "\\\\"), + 1, + ); + } + truth = truth.replacen( + "!!", + &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + 1, + ); + + assert_eq!(result, truth); + } + + #[test] + #[logging_macro::log_scope] + fn test_generate_merge_list_03() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/03", &mut server); + server.endpoint.request_shutdown(); + + let final_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("final.fsh")); + let test_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("test.glsl")); + let burger_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("burger.glsl")); + let sample_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("sample.glsl")); + + server + .graph + .borrow_mut() + .add_edge(final_idx, sample_idx, IncludePosition { line: 2, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(sample_idx, burger_idx, IncludePosition { line: 4, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(sample_idx, test_idx, IncludePosition { line: 6, start: 0, end: 0 }); + + let nodes = server.get_dfs_for_node(final_idx).unwrap(); + let sources = server.load_sources(&nodes).unwrap(); + + let graph_borrow = server.graph.borrow(); + let mut source_mapper = SourceMapper::new(0); + let result = MergeViewBuilder::new(&nodes, &sources, &graph_borrow, &mut source_mapper).build(); + + let merge_file = tmp_path.join("shaders").join("final.fsh.merge"); + + let mut truth = fs::read_to_string(merge_file).unwrap(); + + // truth = truth.replacen( + // "!!", + // &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + // 1, + // ); + + for file in &["sample.glsl", "burger.glsl", "sample.glsl", "test.glsl", "sample.glsl"] { + let path = tmp_path.clone(); + truth = truth.replacen( + "!!", + &path + .join("shaders") + .join("utils") + .join(file) + .to_str() + .unwrap() + .replace('\\', "\\\\"), + 1, + ); + } + truth = truth.replacen( + "!!", + &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace('\\', "\\\\"), + 1, + ); + + assert_eq!(result, truth); + } + + #[test] + #[logging_macro::log_scope] + fn test_generate_merge_list_04() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/04", &mut server); + server.endpoint.request_shutdown(); + + let final_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("final.fsh")); + let utilities_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("utilities.glsl")); + let stuff1_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("stuff1.glsl")); + let stuff2_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("utils").join("stuff2.glsl")); + let matrices_idx = server + .graph + .borrow_mut() + .add_node(&tmp_path.join("shaders").join("lib").join("matrices.glsl")); + + server + .graph + .borrow_mut() + .add_edge(final_idx, utilities_idx, IncludePosition { line: 2, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(utilities_idx, stuff1_idx, IncludePosition { line: 0, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(utilities_idx, stuff2_idx, IncludePosition { line: 1, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(final_idx, matrices_idx, IncludePosition { line: 3, start: 0, end: 0 }); + + let nodes = server.get_dfs_for_node(final_idx).unwrap(); + let sources = server.load_sources(&nodes).unwrap(); + + let graph_borrow = server.graph.borrow(); + let mut source_mapper = SourceMapper::new(0); + let result = MergeViewBuilder::new(&nodes, &sources, &graph_borrow, &mut source_mapper).build(); + + let merge_file = tmp_path.join("shaders").join("final.fsh.merge"); + + let mut truth = fs::read_to_string(merge_file).unwrap(); + + for file in &[ + // PathBuf::new().join("final.fsh").to_str().unwrap(), + PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), + PathBuf::new().join("utils").join("stuff1.glsl").to_str().unwrap(), + PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), + PathBuf::new().join("utils").join("stuff2.glsl").to_str().unwrap(), + PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), + PathBuf::new().join("final.fsh").to_str().unwrap(), + PathBuf::new().join("lib").join("matrices.glsl").to_str().unwrap(), + PathBuf::new().join("final.fsh").to_str().unwrap(), + ] { + let path = tmp_path.clone(); + truth = truth.replacen("!!", &path.join("shaders").join(file).to_str().unwrap().replace('\\', "\\\\"), 1); + } + + assert_eq!(result, truth); + } + + #[test] + #[logging_macro::log_scope] + fn test_generate_merge_list_06() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/06", &mut server); + server.endpoint.request_shutdown(); + + let final_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("final.fsh")); + let test_idx = server.graph.borrow_mut().add_node(&tmp_path.join("shaders").join("test.glsl")); + + server + .graph + .borrow_mut() + .add_edge(final_idx, test_idx, IncludePosition { line: 3, start: 0, end: 0 }); + server + .graph + .borrow_mut() + .add_edge(final_idx, test_idx, IncludePosition { line: 5, start: 0, end: 0 }); + + let nodes = server.get_dfs_for_node(final_idx).unwrap(); + let sources = server.load_sources(&nodes).unwrap(); + + let graph_borrow = server.graph.borrow(); + let mut source_mapper = SourceMapper::new(0); + let result = MergeViewBuilder::new(&nodes, &sources, &graph_borrow, &mut source_mapper).build(); + + let merge_file = tmp_path.join("shaders").join("final.fsh.merge"); + + let mut truth = fs::read_to_string(merge_file).unwrap(); + + for file in &[ + // PathBuf::new().join("final.fsh").to_str().unwrap(), + PathBuf::new().join("test.glsl").to_str().unwrap(), + PathBuf::new().join("final.fsh").to_str().unwrap(), + PathBuf::new().join("test.glsl").to_str().unwrap(), + PathBuf::new().join("final.fsh").to_str().unwrap(), + ] { + let path = tmp_path.clone(); + truth = truth.replacen("!!", &path.join("shaders").join(file).to_str().unwrap().replace('\\', "\\\\"), 1); + } + + assert_eq!(result, truth); + } +} diff --git a/server/main/src/navigation.rs b/server/main/src/navigation.rs new file mode 100644 index 0000000..9418e86 --- /dev/null +++ b/server/main/src/navigation.rs @@ -0,0 +1,429 @@ +use std::{collections::HashMap, fs::read_to_string, path::Path, vec}; + +use anyhow::Result; +use rust_lsp::lsp_types::{DocumentSymbol, Location, Position, Range, SymbolKind}; +use slog_scope::{debug, info, trace}; +use tree_sitter::{Node, Parser, Point, Query, QueryCursor, Tree}; +use url::Url; + +use crate::linemap::LineMap; + +#[derive(Clone, Debug, Hash, PartialEq, Eq, Default)] +struct SymbolName(String); + +impl SymbolName { + // construct a new SymbolName from a node and its node ID for overload disambiguating. + fn new(node: &Node, source: &str, node_id: usize) -> Self { + let mut fqname = vec![format!("{}[{}]", node.utf8_text(source.as_bytes()).unwrap(), node_id)]; + + // first node will always have a parent + let mut prev = *node; + let mut node = node.parent().unwrap(); + + loop { + match (node.kind(), prev.kind()) { + ("function_definition", "compound_statement") => { + let func_ident = node.child_by_field_name("declarator").unwrap().child(0).unwrap(); + fqname.push(format!("{}[{}]", func_ident.utf8_text(source.as_bytes()).unwrap(), func_ident.id())); + } + ("struct_specifier", "field_declaration_list") => { + let struct_ident = node.child_by_field_name("name").unwrap(); + fqname.push(format!( + "{}[{}]", + struct_ident.utf8_text(source.as_bytes()).unwrap(), + struct_ident.id() + )); + } + _ => (), + } + + prev = node; + node = match node.parent() { + Some(n) => n, + None => break, + }; + } + + fqname.reverse(); + SymbolName(fqname.join("/")) + } + + fn parent(&self) -> Option { + self.0.rsplit_once('/').map(|(left, _)| SymbolName(left.to_string())) + } +} + +impl slog::Value for SymbolName { + fn serialize(&self, record: &slog::Record, key: slog::Key, serializer: &mut dyn slog::Serializer) -> slog::Result { + self.0.serialize(record, key, serializer) + } +} + +macro_rules! find_function_def_str { + () => { + r#" + ( + (function_declarator + (identifier) @function) + (#match? @function "^{}$") + ) + "# + }; +} + +macro_rules! find_function_refs_str { + () => { + r#" + ( + (call_expression + (identifier) @call) + (#match? @call "^{}$") + ) + "# + }; +} + +macro_rules! find_variable_def_str { + () => { + r#" + [ + (init_declarator + (identifier) @variable) + + (parameter_declaration + (identifier) @variable) + + (declaration + (identifier) @variable) + + (#match? @variable "^{}$") + ] + "# + }; +} + +const LIST_SYMBOLS_STR: &str = r#" + ; global consts + (declaration + (type_qualifier) @const_qualifier + (init_declarator + (identifier) @const_ident)) + (#match? @const_qualifier "^const") + + ; global uniforms, varyings, struct variables etc + (translation_unit + (declaration + (identifier) @ident)) + + ; #defines + (preproc_def + (identifier) @define_ident) + + ; function definitions + (function_declarator + (identifier) @func_ident) + + ; struct definitions + (struct_specifier + (type_identifier) @struct_ident) + + ; struct fields + (struct_specifier + (field_declaration_list + (field_declaration + [ + (field_identifier) @field_ident + (array_declarator + (field_identifier) @field_ident) + ])) @field_list) +"#; + +pub struct ParserContext<'a> { + source: String, + tree: Tree, + linemap: LineMap, + parser: &'a mut Parser, +} + +impl<'a> ParserContext<'a> { + pub fn new(parser: &'a mut Parser, path: &Path) -> Result { + let source = read_to_string(path)?; + + let tree = parser.parse(&source, None).unwrap(); + + let linemap = LineMap::new(&source); + + Ok(ParserContext { + source, + tree, + linemap, + parser, + }) + } + + pub fn list_symbols(&self, _path: &Path) -> Result>> { + let query = Query::new(tree_sitter_glsl::language(), LIST_SYMBOLS_STR)?; + let mut query_cursor = QueryCursor::new(); + + let mut parent_child_vec: Vec<(Option, DocumentSymbol)> = vec![]; + let mut fqname_to_index: HashMap = HashMap::new(); + + for (m, _) in query_cursor.captures(&query, self.root_node(), self.source.as_bytes()) { + if m.captures.is_empty() { + continue; + } + + let mut capture_iter = m.captures.iter(); + + let capture = capture_iter.next().unwrap(); + let capture_name = query.capture_names()[capture.index as usize].as_str(); + + trace!("next capture name"; "name" => capture_name, "capture" => format!("{:?}", capture)); + + let (kind, node) = match capture_name { + "const_qualifier" => (SymbolKind::CONSTANT, capture_iter.next().unwrap().node), + "ident" => (SymbolKind::VARIABLE, capture.node), + "func_ident" => (SymbolKind::FUNCTION, capture.node), + "define_ident" => (SymbolKind::STRING, capture.node), + "struct_ident" => (SymbolKind::STRUCT, capture.node), + "field_list" => (SymbolKind::FIELD, capture_iter.next().unwrap().node), + _ => (SymbolKind::NULL, capture.node), + }; + + let range = Range { + start: Position { + line: node.start_position().row as u32, + character: node.start_position().column as u32, + }, + end: Position { + line: node.end_position().row as u32, + character: node.end_position().column as u32, + }, + }; + + let name = node.utf8_text(self.source.as_bytes()).unwrap().to_string(); + + let fqname = SymbolName::new(&node, self.source.as_str(), node.id()); + + debug!("found symbol"; "node_name" => &name, "kind" => format!("{:?}", kind), "fqname" => &fqname); + + let child_symbol = DocumentSymbol { + name, + detail: None, + kind, + tags: None, + deprecated: None, + range, + selection_range: range, + children: None, + }; + parent_child_vec.push((fqname.parent(), child_symbol)); + trace!("inserting fqname"; "fqname" => &fqname, "index" => parent_child_vec.len() - 1); + fqname_to_index.insert(fqname, parent_child_vec.len() - 1); + } + + // let mut symbols = vec![]; + for i in 1..parent_child_vec.len() { + let (left, right) = parent_child_vec.split_at_mut(i); + let parent = &right[0].0; + let child = &right[0].1; + if let Some(parent) = parent { + trace!("finding parent"; "parent_symbol_name" => &parent, "child" => format!("{:?}", child), "split_point" => i, "left_len" => left.len(), "right_len" => right.len()); + let parent_index = fqname_to_index.get(parent).unwrap(); + let parent_sym = &mut left[*parent_index]; + parent_sym.1.children.get_or_insert_default().push(right[0].1.clone()) + } + } + + let symbols = parent_child_vec + .iter() + .filter(|tuple| tuple.0.is_none()) + .map(|tuple| tuple.1.clone()) + .collect(); + + Ok(Some(symbols)) + } + + pub fn find_definitions(&self, path: &Path, point: Position) -> Result>> { + let current_node = match self.find_node_at_point(point) { + Some(node) => node, + None => return Ok(None), + }; + + let parent = match current_node.parent() { + Some(parent) => parent, + None => return Ok(None), + }; + + debug!("matching location lookup method for parent-child tuple"; "parent" => parent.kind(), "child" => current_node.kind()); + + let locations = match (current_node.kind(), parent.kind()) { + (_, "call_expression") => { + let query_str = format!(find_function_def_str!(), current_node.utf8_text(self.source.as_bytes())?); + self.simple_global_search(path, &query_str)? + } + ("identifier", "argument_list") + | ("identifier", "field_expression") + | ("identifier", "binary_expression") + | ("identifier", "assignment_expression") => self.tree_climbing_search(path, current_node)?, + _ => return Ok(None), + }; + + info!("finished searching for definitions"; "count" => locations.len(), "definitions" => format!("{:?}", locations)); + + Ok(Some(locations)) + } + + pub fn find_references(&self, path: &Path, point: Position) -> Result>> { + let current_node = match self.find_node_at_point(point) { + Some(node) => node, + None => return Ok(None), + }; + + let parent = match current_node.parent() { + Some(parent) => parent, + None => return Ok(None), + }; + + let locations = match (current_node.kind(), parent.kind()) { + (_, "function_declarator") => { + let query_str = format!(find_function_refs_str!(), current_node.utf8_text(self.source.as_bytes())?); + self.simple_global_search(path, &query_str)? + } + _ => return Ok(None), + }; + + info!("finished searching for references"; "count" => locations.len(), "references" => format!("{:?}", locations)); + + Ok(Some(locations)) + } + + fn tree_climbing_search(&self, path: &Path, start_node: Node) -> Result> { + let mut locations = vec![]; + + let node_text = start_node.utf8_text(self.source.as_bytes())?; + + let query_str = format!(find_variable_def_str!(), node_text); + + debug!("built query string"; "query" => &query_str); + + let mut parent = start_node.parent(); + + loop { + if parent.is_none() { + trace!("no more parent left, found nothing"); + break; + } + + let query = Query::new(tree_sitter_glsl::language(), &query_str)?; + let mut query_cursor = QueryCursor::new(); + + trace!("running tree-sitter query for node"; "node" => format!("{:?}", parent.unwrap()), "node_text" => parent.unwrap().utf8_text(self.source.as_bytes()).unwrap()); + + for m in query_cursor.matches(&query, parent.unwrap(), self.source.as_bytes()) { + for capture in m.captures { + let start = capture.node.start_position(); + let end = capture.node.end_position(); + + locations.push(Location { + uri: Url::from_file_path(path).unwrap(), + range: Range { + start: Position { + line: start.row as u32, + character: start.column as u32, + }, + end: Position { + line: end.row as u32, + character: end.column as u32, + }, + }, + }); + } + } + + if !locations.is_empty() { + break; + } + + parent = parent.unwrap().parent(); + } + + Ok(locations) + } + + fn simple_global_search(&self, path: &Path, query_str: &str) -> Result> { + let query = Query::new(tree_sitter_glsl::language(), query_str)?; + let mut query_cursor = QueryCursor::new(); + + let mut locations = vec![]; + + for m in query_cursor.matches(&query, self.root_node(), self.source.as_bytes()) { + for capture in m.captures { + let start = capture.node.start_position(); + let end = capture.node.end_position(); + + locations.push(Location { + uri: Url::from_file_path(path).unwrap(), + range: Range { + start: Position { + line: start.row as u32, + character: start.column as u32, + }, + end: Position { + line: end.row as u32, + character: end.column as u32, + }, + }, + }); + } + } + + Ok(locations) + } + + fn root_node(&self) -> Node { + self.tree.root_node() + } + + fn find_node_at_point(&self, pos: Position) -> Option { + // if we're at the end of an ident, we need to look _back_ one char instead + // for tree-sitter to find the right node. + let look_behind = { + let offset = self.linemap.offset_for_position(pos); + let char_at = self.source.as_bytes()[offset]; + trace!("looking for non-alpha for point adjustment"; + "offset" => offset, + "char" => char_at as char, + "point" => format!("{:?}", pos), + "look_behind" => !char_at.is_ascii_alphabetic()); + !char_at.is_ascii_alphabetic() + }; + + let mut start = Point { + row: pos.line as usize, + column: pos.character as usize, + }; + let mut end = Point { + row: pos.line as usize, + column: pos.character as usize, + }; + + if look_behind { + start.column -= 1; + } else { + end.column += 1; + } + + match self.root_node().named_descendant_for_point_range(start, end) { + Some(node) => { + debug!("found a node"; + "node" => format!("{:?}", node), + "text" => node.utf8_text(self.source.as_bytes()).unwrap(), + "start" => format!("{}", start), + "end" => format!("{}", end)); + Some(node) + } + None => None, + } + } +} diff --git a/server/src/opengl.rs b/server/main/src/opengl.rs similarity index 55% rename from server/src/opengl.rs rename to server/main/src/opengl.rs index a78936f..9954e44 100644 --- a/server/src/opengl.rs +++ b/server/main/src/opengl.rs @@ -1,42 +1,48 @@ +use std::ffi::{CStr, CString}; use std::ptr; -use std::ffi::{CString, CStr}; + +use slog_scope::info; #[cfg(test)] use mockall::automock; + #[cfg_attr(test, automock)] pub trait ShaderValidator { - fn validate(&self, tree_type: super::TreeType, source: String) -> Option; + fn validate(&self, tree_type: super::TreeType, source: &str) -> Option; + fn vendor(&self) -> String; } -pub struct OpenGLContext { - _ctx: glutin::Context +pub struct OpenGlContext { + _ctx: glutin::Context, } -impl OpenGLContext { - pub fn new() -> OpenGLContext { +impl OpenGlContext { + pub fn new() -> OpenGlContext { let events_loop = glutin::event_loop::EventLoop::new(); - let gl_window = glutin::ContextBuilder::new().build_headless(&*events_loop, glutin::dpi::PhysicalSize::new(1, 1)).unwrap(); - + let gl_window = glutin::ContextBuilder::new() + .build_headless(&*events_loop, glutin::dpi::PhysicalSize::new(1, 1)) + .unwrap(); + let gl_window = unsafe { let gl_window = gl_window.make_current().unwrap(); gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _); gl_window }; + let gl_ctx = OpenGlContext { _ctx: gl_window }; + unsafe { - eprintln!( - "Using OpenGL device {} {} {}", - String::from_utf8(CStr::from_ptr(gl::GetString(gl::VENDOR) as *const _).to_bytes().to_vec()).unwrap(), - String::from_utf8(CStr::from_ptr(gl::GetString(gl::VERSION) as *const _).to_bytes().to_vec()).unwrap(), - String::from_utf8(CStr::from_ptr(gl::GetString(gl::RENDERER) as *const _).to_bytes().to_vec()).unwrap() + info!( + "OpenGL device"; + "vendor" => gl_ctx.vendor(), + "version" => String::from_utf8(CStr::from_ptr(gl::GetString(gl::VERSION) as *const _).to_bytes().to_vec()).unwrap(), + "renderer" => String::from_utf8(CStr::from_ptr(gl::GetString(gl::RENDERER) as *const _).to_bytes().to_vec()).unwrap() ); } - OpenGLContext{ - _ctx: gl_window, - } + gl_ctx } - unsafe fn compile_and_get_shader_log(&self, shader: gl::types::GLuint, source: String) -> Option { + unsafe fn compile_and_get_shader_log(&self, shader: gl::types::GLuint, source: &str) -> Option { let mut success = i32::from(gl::FALSE); let c_str_frag = CString::new(source).unwrap(); gl::ShaderSource(shader, 1, &c_str_frag.as_ptr(), ptr::null()); @@ -48,7 +54,12 @@ impl OpenGLContext { let mut info_len: gl::types::GLint = 0; gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut info_len); let mut info = vec![0u8; info_len as usize]; - gl::GetShaderInfoLog(shader, info_len as gl::types::GLsizei, ptr::null_mut(), info.as_mut_ptr() as *mut gl::types::GLchar); + gl::GetShaderInfoLog( + shader, + info_len as gl::types::GLsizei, + ptr::null_mut(), + info.as_mut_ptr() as *mut gl::types::GLchar, + ); info.set_len((info_len - 1) as usize); // ignore null for str::from_utf8 Some(String::from_utf8(info).unwrap()) } else { @@ -59,8 +70,8 @@ impl OpenGLContext { } } -impl ShaderValidator for OpenGLContext { - fn validate(&self, tree_type: super::TreeType, source: String) -> Option { +impl ShaderValidator for OpenGlContext { + fn validate(&self, tree_type: super::TreeType, source: &str) -> Option { unsafe { match tree_type { crate::TreeType::Fragment => { @@ -78,7 +89,16 @@ impl ShaderValidator for OpenGLContext { let geometry_shader = gl::CreateShader(gl::GEOMETRY_SHADER); self.compile_and_get_shader_log(geometry_shader, source) } + crate::TreeType::Compute => { + // Compute shader + let compute_shader = gl::CreateShader(gl::COMPUTE_SHADER); + self.compile_and_get_shader_log(compute_shader, source) + } } } } + + fn vendor(&self) -> String { + unsafe { String::from_utf8(CStr::from_ptr(gl::GetString(gl::VENDOR) as *const _).to_bytes().to_vec()).unwrap() } + } } diff --git a/server/main/src/source_mapper.rs b/server/main/src/source_mapper.rs new file mode 100644 index 0000000..efcad0d --- /dev/null +++ b/server/main/src/source_mapper.rs @@ -0,0 +1,52 @@ +use std::{collections::HashMap, fmt::Display}; + +use petgraph::graph::NodeIndex; + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct SourceNum(usize); + +impl Display for SourceNum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(format!("{}", self.0).as_str()) + } +} + +impl From for SourceNum { + fn from(val: usize) -> Self { + SourceNum(val) + } +} + +// Maps from a graph node index to a virtual OpenGL +// source number (for when building the merged source view), +// and in reverse (for when mapping from GLSL error source numbers to their source path). +// What is a source number: https://community.khronos.org/t/what-is-source-string-number/70976 +pub struct SourceMapper { + next: SourceNum, + mapping: HashMap, + reverse_mapping: Vec, +} + +impl SourceMapper { + pub fn new(capacity: usize) -> Self { + SourceMapper { + next: SourceNum(0), + mapping: HashMap::with_capacity(capacity), + reverse_mapping: Vec::with_capacity(capacity), + } + } + + pub fn get_num(&mut self, node: NodeIndex) -> SourceNum { + let num = &*self.mapping.entry(node).or_insert_with(|| { + let next = self.next; + self.next.0 += 1; + self.reverse_mapping.push(node); + next + }); + *num + } + + pub fn get_node(&self, num: SourceNum) -> NodeIndex { + self.reverse_mapping[num.0] + } +} diff --git a/server/main/src/test.rs b/server/main/src/test.rs new file mode 100644 index 0000000..afb4761 --- /dev/null +++ b/server/main/src/test.rs @@ -0,0 +1,281 @@ +use super::*; +use std::fs; +use std::io; +use std::io::Result; + +use pretty_assertions::assert_eq; + +use tempdir::TempDir; + +use fs_extra::{copy_items, dir}; + +use jsonrpc_common::*; +use jsonrpc_response::*; + +struct StdoutNewline { + s: Box, +} + +impl io::Write for StdoutNewline { + fn write(&mut self, buf: &[u8]) -> Result { + let res = self.s.write(buf); + if buf[buf.len() - 1] == b"}"[0] { + #[allow(unused_variables)] + let res = self.s.write(b"\n\n"); + } + res + } + + fn flush(&mut self) -> Result<()> { + self.s.flush() + } +} + +pub fn new_temp_server(opengl_context: Option>) -> MinecraftShaderLanguageServer { + let endpoint = LSPEndpoint::create_lsp_output_with_output_stream(|| StdoutNewline { s: Box::new(io::sink()) }); + + let context = opengl_context.unwrap_or_else(|| Box::new(opengl::MockShaderValidator::new())); + + MinecraftShaderLanguageServer { + endpoint, + graph: Rc::new(RefCell::new(graph::CachedStableGraph::new())), + root: "".into(), + command_provider: None, + opengl_context: context.into(), + log_guard: None, + tree_sitter: Rc::new(RefCell::new(Parser::new())), + } +} + +fn copy_files(files: &str, dest: &TempDir) { + let opts = &dir::CopyOptions::new(); + let files = fs::read_dir(files) + .unwrap() + .map(|e| String::from(e.unwrap().path().to_str().unwrap())) + .collect::>(); + copy_items(&files, dest.path().join("shaders"), opts).unwrap(); +} + +pub fn copy_to_and_set_root(test_path: &str, server: &mut MinecraftShaderLanguageServer) -> (Rc, PathBuf) { + let (_tmp_dir, tmp_path) = copy_to_tmp_dir(test_path); + + server.root = tmp_path.clone(); //format!("{}{}", "file://", tmp_path); + + (_tmp_dir, tmp_path) +} + +fn copy_to_tmp_dir(test_path: &str) -> (Rc, PathBuf) { + let tmp_dir = Rc::new(TempDir::new("mcshader").unwrap()); + fs::create_dir(tmp_dir.path().join("shaders")).unwrap(); + + copy_files(test_path, &tmp_dir); + + let tmp_clone = tmp_dir.clone(); + let tmp_path = tmp_clone.path().to_str().unwrap(); + + (tmp_dir, tmp_path.into()) +} + +#[allow(deprecated)] +#[test] +#[logging_macro::log_scope] +fn test_empty_initialize() { + let mut server = new_temp_server(None); + + let tmp_dir = TempDir::new("mcshader").unwrap(); + let tmp_path = tmp_dir.path(); + + let initialize_params = InitializeParams { + process_id: None, + root_path: None, + root_uri: Some(Url::from_directory_path(tmp_path).unwrap()), + client_info: None, + initialization_options: None, + capabilities: ClientCapabilities { + workspace: None, + text_document: None, + experimental: None, + window: None, + general: Option::None, + }, + trace: None, + workspace_folders: None, + locale: Option::None, + }; + + let on_response = |resp: Option| { + assert!(resp.is_some()); + let respu = resp.unwrap(); + match respu.result_or_error { + ResponseResult::Result(_) => {} + ResponseResult::Error(e) => { + panic!("expected ResponseResult::Result(..), got {:?}", e) + } + } + }; + + let completable = MethodCompletable::new(ResponseCompletable::new(Some(Id::Number(1)), Box::new(on_response))); + server.initialize(initialize_params, completable); + + assert_eq!(server.root, tmp_path); + + assert_eq!(server.graph.borrow().graph.edge_count(), 0); + assert_eq!(server.graph.borrow().graph.node_count(), 0); + + server.endpoint.request_shutdown(); +} + +#[allow(deprecated)] +#[test] +#[logging_macro::log_scope] +fn test_01_initialize() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_tmp_dir("./testdata/01"); + + let initialize_params = InitializeParams { + process_id: None, + root_path: None, + root_uri: Some(Url::from_directory_path(tmp_path.clone()).unwrap()), + client_info: None, + initialization_options: None, + capabilities: ClientCapabilities { + workspace: None, + text_document: None, + experimental: None, + window: None, + general: Option::None, + }, + trace: None, + workspace_folders: None, + locale: Option::None, + }; + + let on_response = |resp: Option| { + assert!(resp.is_some()); + let respu = resp.unwrap(); + match respu.result_or_error { + ResponseResult::Result(_) => {} + ResponseResult::Error(e) => { + panic!("expected ResponseResult::Result(..), got {:?}", e) + } + } + }; + + let completable = MethodCompletable::new(ResponseCompletable::new(Some(Id::Number(1)), Box::new(on_response))); + server.initialize(initialize_params, completable); + server.endpoint.request_shutdown(); + + // Assert there is one edge between two nodes + assert_eq!(server.graph.borrow().graph.edge_count(), 1); + + let edge = server.graph.borrow().graph.edge_indices().next().unwrap(); + let (node1, node2) = server.graph.borrow().graph.edge_endpoints(edge).unwrap(); + + // Assert the values of the two nodes in the tree + assert_eq!( + server.graph.borrow().graph[node1], + //format!("{:?}/{}/{}", tmp_path, "shaders", "final.fsh") + tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string() + ); + assert_eq!( + server.graph.borrow().graph[node2], + //format!("{:?}/{}/{}", tmp_path, "shaders", "common.glsl") + tmp_path.join("shaders").join("common.glsl").to_str().unwrap().to_string() + ); + + assert_eq!(server.graph.borrow().graph.edge_weight(edge).unwrap().line, 2); +} + +#[allow(deprecated)] +#[test] +#[logging_macro::log_scope] +fn test_05_initialize() { + let mut server = new_temp_server(None); + + let (_tmp_dir, tmp_path) = copy_to_tmp_dir("./testdata/05"); + + let initialize_params = InitializeParams { + process_id: None, + root_path: None, + root_uri: Some(Url::from_directory_path(tmp_path.clone()).unwrap()), + client_info: None, + initialization_options: None, + capabilities: ClientCapabilities { + workspace: None, + text_document: None, + experimental: None, + window: None, + general: Option::None, + }, + trace: None, + workspace_folders: None, + locale: Option::None, + }; + + let on_response = |resp: Option| { + assert!(resp.is_some()); + let respu = resp.unwrap(); + match respu.result_or_error { + ResponseResult::Result(_) => {} + ResponseResult::Error(e) => { + panic!("expected ResponseResult::Result(..), got {:?}", e) + } + } + }; + + let completable = MethodCompletable::new(ResponseCompletable::new(Some(Id::Number(1)), Box::new(on_response))); + server.initialize(initialize_params, completable); + server.endpoint.request_shutdown(); + + // Assert there is one edge between two nodes + assert_eq!(server.graph.borrow().graph.edge_count(), 3); + + assert_eq!(server.graph.borrow().graph.node_count(), 4); + + let pairs: HashSet<(PathBuf, PathBuf)> = vec![ + ( + tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string().into(), + tmp_path.join("shaders").join("common.glsl").to_str().unwrap().to_string().into(), + ), + ( + tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string().into(), + tmp_path + .join("shaders") + .join("test") + .join("banana.glsl") + .to_str() + .unwrap() + .to_string() + .into(), + ), + ( + tmp_path + .join("shaders") + .join("test") + .join("banana.glsl") + .to_str() + .unwrap() + .to_string() + .into(), + tmp_path + .join("shaders") + .join("test") + .join("burger.glsl") + .to_str() + .unwrap() + .to_string() + .into(), + ), + ] + .into_iter() + .collect(); + + for edge in server.graph.borrow().graph.edge_indices() { + let endpoints = server.graph.borrow().graph.edge_endpoints(edge).unwrap(); + let first = server.graph.borrow().get_node(endpoints.0); + let second = server.graph.borrow().get_node(endpoints.1); + let contains = pairs.contains(&(first.clone(), second.clone())); + assert!(contains, "doesn't contain ({:?}, {:?})", first, second); + } +} diff --git a/server/src/url_norm.rs b/server/main/src/url_norm.rs similarity index 52% rename from server/src/url_norm.rs rename to server/main/src/url_norm.rs index 276c8a3..67fe813 100644 --- a/server/src/url_norm.rs +++ b/server/main/src/url_norm.rs @@ -1,55 +1,73 @@ use std::path::PathBuf; +use slog_scope::trace; +use anyhow::Result; use path_slash::PathBufExt; use url::Url; -use anyhow::Result; pub trait FromUrl { fn from_url(u: Url) -> Self; } -pub trait FromJSON { - fn from_json(v: &serde_json::value::Value) -> Result where Self: Sized; +pub trait FromJson { + fn from_json(v: &serde_json::value::Value) -> Result + where + Self: Sized; } impl FromUrl for PathBuf { #[cfg(target_family = "windows")] fn from_url(u: Url) -> Self { - let path = percent_encoding::percent_decode_str(u.path().strip_prefix("/").unwrap()).decode_utf8().unwrap(); + let path = percent_encoding::percent_decode_str(u.path().strip_prefix('/').unwrap()) + .decode_utf8() + .unwrap(); + + trace!("converted win path from url"; "old" => u.as_str(), "new" => path.to_string()); + PathBuf::from_slash(path) } #[cfg(target_family = "unix")] fn from_url(u: Url) -> Self { let path = percent_encoding::percent_decode_str(u.path()).decode_utf8().unwrap(); + + trace!("converted unix path from url"; "old" => u.as_str(), "new" => path.to_string()); + PathBuf::from_slash(path) } } -impl FromJSON for PathBuf { +impl FromJson for PathBuf { #[cfg(target_family = "windows")] fn from_json(v: &serde_json::value::Value) -> Result - where Self: Sized { + where + Self: Sized, + { if !v.is_string() { return Err(anyhow::format_err!("cannot convert {:?} to PathBuf", v)); } let path = v.to_string(); - let path = percent_encoding::percent_decode_str( - path.trim_start_matches('"').trim_end_matches('"').strip_prefix("/").unwrap() - ).decode_utf8()?; + let path = percent_encoding::percent_decode_str(path.trim_start_matches('"').trim_end_matches('"').strip_prefix('/').unwrap()) + .decode_utf8()?; + + trace!("converted win path from json"; "old" => v.to_string(), "new" => path.to_string()); + Ok(PathBuf::from_slash(path)) } #[cfg(target_family = "unix")] fn from_json(v: &serde_json::value::Value) -> Result - where Self: Sized { + where + Self: Sized, + { if !v.is_string() { return Err(anyhow::format_err!("cannot convert {:?} to PathBuf", v)); } let path = v.to_string(); - let path = percent_encoding::percent_decode_str( - path.trim_start_matches('"').trim_end_matches('"') - ).decode_utf8()?; + let path = percent_encoding::percent_decode_str(path.trim_start_matches('"').trim_end_matches('"')).decode_utf8()?; + + trace!("converted unix path from json"; "old" => v.to_string(), "new" => path.to_string()); + Ok(PathBuf::from_slash(path)) } -} \ No newline at end of file +} diff --git a/server/testdata/01/common.glsl b/server/main/testdata/01/common.glsl similarity index 100% rename from server/testdata/01/common.glsl rename to server/main/testdata/01/common.glsl diff --git a/server/testdata/01/final.fsh b/server/main/testdata/01/final.fsh similarity index 100% rename from server/testdata/01/final.fsh rename to server/main/testdata/01/final.fsh diff --git a/server/testdata/01/final.fsh.merge b/server/main/testdata/01/final.fsh.merge similarity index 73% rename from server/testdata/01/final.fsh.merge rename to server/main/testdata/01/final.fsh.merge index 609a754..7c606b6 100644 --- a/server/testdata/01/final.fsh.merge +++ b/server/main/testdata/01/final.fsh.merge @@ -1,10 +1,10 @@ #version 120 -#line 1 "!!" +#line 1 1 // !! float test() { return 0.5; } -#line 4 "!!" +#line 4 0 // !! void main() { gl_FragColor[0] = vec4(0.0); diff --git a/server/testdata/02/final.fsh b/server/main/testdata/02/final.fsh similarity index 100% rename from server/testdata/02/final.fsh rename to server/main/testdata/02/final.fsh diff --git a/server/testdata/02/final.fsh.merge b/server/main/testdata/02/final.fsh.merge similarity index 67% rename from server/testdata/02/final.fsh.merge rename to server/main/testdata/02/final.fsh.merge index 550f1d0..6e6d776 100644 --- a/server/testdata/02/final.fsh.merge +++ b/server/main/testdata/02/final.fsh.merge @@ -1,26 +1,26 @@ #version 120 -#line 1 "!!" +#line 1 1 // !! int sample() { return 5; } -#line 1 "!!" +#line 1 2 // !! void burger() { // sample text } -#line 6 "!!" +#line 6 1 // !! -#line 1 "!!" +#line 1 3 // !! float test() { return 3.0; } -#line 8 "!!" +#line 8 1 // !! int sample_more() { return 5; } -#line 4 "!!" +#line 4 0 // !! void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); diff --git a/server/testdata/02/utils/burger.glsl b/server/main/testdata/02/utils/burger.glsl similarity index 100% rename from server/testdata/02/utils/burger.glsl rename to server/main/testdata/02/utils/burger.glsl diff --git a/server/testdata/02/utils/sample.glsl b/server/main/testdata/02/utils/sample.glsl similarity index 100% rename from server/testdata/02/utils/sample.glsl rename to server/main/testdata/02/utils/sample.glsl diff --git a/server/testdata/02/utils/test.glsl b/server/main/testdata/02/utils/test.glsl similarity index 100% rename from server/testdata/02/utils/test.glsl rename to server/main/testdata/02/utils/test.glsl diff --git a/server/testdata/03/final.fsh b/server/main/testdata/03/final.fsh similarity index 100% rename from server/testdata/03/final.fsh rename to server/main/testdata/03/final.fsh diff --git a/server/testdata/03/final.fsh.merge b/server/main/testdata/03/final.fsh.merge similarity index 63% rename from server/testdata/03/final.fsh.merge rename to server/main/testdata/03/final.fsh.merge index 4277745..f317989 100644 --- a/server/testdata/03/final.fsh.merge +++ b/server/main/testdata/03/final.fsh.merge @@ -1,22 +1,22 @@ #version 120 -#line 1 "!!" +#line 1 1 // !! int sample() { return 5; } -#line 1 "!!" +#line 1 2 // !! void burger() { // sample text } -#line 6 "!!" +#line 6 1 // !! -#line 1 "!!" +#line 1 3 // !! float test() { return 3.0; } -#line 8 "!!" -#line 4 "!!" +#line 8 1 // !! +#line 4 0 // !! void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); diff --git a/server/testdata/03/utils/burger.glsl b/server/main/testdata/03/utils/burger.glsl similarity index 100% rename from server/testdata/03/utils/burger.glsl rename to server/main/testdata/03/utils/burger.glsl diff --git a/server/testdata/03/utils/sample.glsl b/server/main/testdata/03/utils/sample.glsl similarity index 100% rename from server/testdata/03/utils/sample.glsl rename to server/main/testdata/03/utils/sample.glsl diff --git a/server/testdata/03/utils/test.glsl b/server/main/testdata/03/utils/test.glsl similarity index 100% rename from server/testdata/03/utils/test.glsl rename to server/main/testdata/03/utils/test.glsl diff --git a/server/testdata/04/final.fsh b/server/main/testdata/04/final.fsh similarity index 100% rename from server/testdata/04/final.fsh rename to server/main/testdata/04/final.fsh diff --git a/server/main/testdata/04/final.fsh.merge b/server/main/testdata/04/final.fsh.merge new file mode 100644 index 0000000..49da4ac --- /dev/null +++ b/server/main/testdata/04/final.fsh.merge @@ -0,0 +1,23 @@ +#version 120 + +#line 1 1 // !! +#line 1 2 // !! +void stuff1() { + +} +#line 2 1 // !! +#line 1 3 // !! +void stuff2() { + +} +#line 3 1 // !! +#line 4 0 // !! +#line 1 4 // !! +void matrix() { + +} +#line 5 0 // !! + +void main() { + +} \ No newline at end of file diff --git a/server/testdata/04/lib/matrices.glsl b/server/main/testdata/04/lib/matrices.glsl similarity index 100% rename from server/testdata/04/lib/matrices.glsl rename to server/main/testdata/04/lib/matrices.glsl diff --git a/server/testdata/04/utils/stuff1.glsl b/server/main/testdata/04/utils/stuff1.glsl similarity index 100% rename from server/testdata/04/utils/stuff1.glsl rename to server/main/testdata/04/utils/stuff1.glsl diff --git a/server/testdata/04/utils/stuff2.glsl b/server/main/testdata/04/utils/stuff2.glsl similarity index 100% rename from server/testdata/04/utils/stuff2.glsl rename to server/main/testdata/04/utils/stuff2.glsl diff --git a/server/testdata/04/utils/utilities.glsl b/server/main/testdata/04/utils/utilities.glsl similarity index 100% rename from server/testdata/04/utils/utilities.glsl rename to server/main/testdata/04/utils/utilities.glsl diff --git a/server/testdata/05/common.glsl b/server/main/testdata/05/common.glsl similarity index 100% rename from server/testdata/05/common.glsl rename to server/main/testdata/05/common.glsl diff --git a/server/testdata/05/final.fsh b/server/main/testdata/05/final.fsh similarity index 100% rename from server/testdata/05/final.fsh rename to server/main/testdata/05/final.fsh diff --git a/server/testdata/05/final.fsh.merge b/server/main/testdata/05/final.fsh.merge similarity index 93% rename from server/testdata/05/final.fsh.merge rename to server/main/testdata/05/final.fsh.merge index 1d44edf..b561479 100644 --- a/server/testdata/05/final.fsh.merge +++ b/server/main/testdata/05/final.fsh.merge @@ -1,5 +1,7 @@ #version 120 +#line 2 "!!" + #line 1 "!!" float test() { return 0.5; diff --git a/server/testdata/05/test/banana.glsl b/server/main/testdata/05/test/banana.glsl similarity index 100% rename from server/testdata/05/test/banana.glsl rename to server/main/testdata/05/test/banana.glsl diff --git a/server/testdata/05/test/burger.glsl b/server/main/testdata/05/test/burger.glsl similarity index 100% rename from server/testdata/05/test/burger.glsl rename to server/main/testdata/05/test/burger.glsl diff --git a/server/main/testdata/06/final.fsh b/server/main/testdata/06/final.fsh new file mode 100644 index 0000000..4c2910b --- /dev/null +++ b/server/main/testdata/06/final.fsh @@ -0,0 +1,9 @@ +#version 120 + +#ifdef BANANA +#include "test.glsl" +#else +#include "test.glsl" +#endif + +void main() {} \ No newline at end of file diff --git a/server/main/testdata/06/final.fsh.merge b/server/main/testdata/06/final.fsh.merge new file mode 100644 index 0000000..8ee023e --- /dev/null +++ b/server/main/testdata/06/final.fsh.merge @@ -0,0 +1,17 @@ +#version 120 + +#ifdef BANANA +#line 1 1 // !! +int test() { + return 1; +} +#line 5 0 // !! +#else +#line 1 1 // !! +int test() { + return 1; +} +#line 7 0 // !! +#endif + +void main() {} \ No newline at end of file diff --git a/server/main/testdata/06/test.glsl b/server/main/testdata/06/test.glsl new file mode 100644 index 0000000..4ae7903 --- /dev/null +++ b/server/main/testdata/06/test.glsl @@ -0,0 +1,3 @@ +int test() { + return 1; +} \ No newline at end of file diff --git a/server/src/commands.rs b/server/src/commands.rs deleted file mode 100644 index b194ad5..0000000 --- a/server/src/commands.rs +++ /dev/null @@ -1,161 +0,0 @@ -use std::{collections::HashMap, path::PathBuf}; -use std::rc::Rc; -use std::cell::RefCell; -use std::fs::OpenOptions; -use std::io::prelude::*; - -use serde_json::Value; - -use petgraph::{dot, graph::NodeIndex}; - -use anyhow::{Result, format_err}; - -use std::fs; - -use crate::{graph::CachedStableGraph, merge_views, url_norm::FromJSON}; -use crate::dfs; - -pub struct CustomCommandProvider { - commands: HashMap> -} - -impl CustomCommandProvider { - pub fn new(commands: Vec<(&str, Box)>) -> CustomCommandProvider { - CustomCommandProvider{ - commands: commands.into_iter().map(|tup| { - (tup.0.into(), tup.1) - }).collect(), - } - } - - pub fn execute(&self, command: &str, args: Vec, root_path: &PathBuf) -> Result { - if self.commands.contains_key(command) { - return self.commands.get(command).unwrap().run_command(root_path, args); - } - Err(format_err!("command doesn't exist")) - } -} - -pub trait Invokeable { - fn run_command(&self, root: &PathBuf, arguments: Vec) -> Result; -} - -pub struct GraphDotCommand { - pub graph: Rc> -} - -impl Invokeable for GraphDotCommand { - fn run_command(&self, root: &PathBuf, _: Vec) -> Result { - let filepath = root.join("graph.dot"); - eprintln!("generating dot file at {:?}", filepath); - let mut file = OpenOptions::new() - .truncate(true) - .write(true) - .create(true) - .open(filepath) - .unwrap(); - - let mut write_data_closure = || -> Result<(), std::io::Error> { - let graph = self.graph.as_ref(); - - file.seek(std::io::SeekFrom::Start(0))?; - file.write_all(dot::Dot::new(&graph.borrow().graph).to_string().as_bytes())?; - file.flush()?; - file.seek(std::io::SeekFrom::Start(0))?; - Ok(()) - }; - - match write_data_closure() { - Err(err) => Err(format_err!("Error generating graphviz data: {}", err)), - _ => Ok(Value::Null) - } - } -} - -pub struct VirtualMergedDocument { - pub graph: Rc> -} - -impl VirtualMergedDocument { - // TODO: DUPLICATE CODE - fn get_file_toplevel_ancestors(&self, uri: &PathBuf) -> Result>> { - let curr_node = match self.graph.borrow_mut().find_node(uri) { - Some(n) => n, - None => return Err(format_err!("node not found {:?}", uri)), - }; - let roots = self.graph.borrow().collect_root_ancestors(curr_node); - if roots.is_empty() { - return Ok(None); - } - Ok(Some(roots)) - } - - pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result)>, dfs::error::CycleError> { - let graph_ref = self.graph.borrow(); - - let dfs = dfs::Dfs::new(&graph_ref, root); - - dfs.collect::, _>>() - } - - pub fn load_sources(&self, nodes: &[(NodeIndex, Option)]) -> Result> { - let mut sources = HashMap::new(); - - for node in nodes { - let graph = self.graph.borrow(); - let path = graph.get_node(node.0); - - if sources.contains_key(&path) { - continue; - } - - let source = match fs::read_to_string(&path) { - Ok(s) => s, - Err(e) => return Err(format_err!("error reading {:?}: {}", path, e)) - }; - sources.insert(path.clone(), source); - } - - Ok(sources) - } -} - -impl Invokeable for VirtualMergedDocument { - fn run_command(&self, root: &PathBuf, arguments: Vec) -> Result { - let path = PathBuf::from_json(arguments.get(0).unwrap())?; - - let file_ancestors = match self.get_file_toplevel_ancestors(&path) { - Ok(opt) => match opt { - Some(ancestors) => ancestors, - None => vec![], - }, - Err(e) => return Err(e), - }; - - //eprintln!("ancestors for {}:\n\t{:?}", path, file_ancestors.iter().map(|e| self.graph.borrow().graph.node_weight(*e).unwrap().clone()).collect::>()); - - // the set of all filepath->content. TODO: change to Url? - let mut all_sources: HashMap = HashMap::new(); - - // if we are a top-level file (this has to be one of the set defined by Optifine, right?) - if file_ancestors.is_empty() { - // gather the list of all descendants - let root = self.graph.borrow_mut().find_node(&path).unwrap(); - let tree = match self.get_dfs_for_node(root) { - Ok(tree) => tree, - Err(e) => return Err(e.into()), - }; - - let sources = match self.load_sources(&tree) { - Ok(s) => s, - Err(e) => return Err(e) - }; - all_sources.extend(sources); - - let graph = self.graph.borrow(); - let view = merge_views::generate_merge_list(&tree, &all_sources, &graph); - return Ok(serde_json::value::Value::String(view)); - } - return Err(format_err!("{:?} is not a top-level file aka has ancestors", path.strip_prefix(root).unwrap())) - } -} \ No newline at end of file diff --git a/server/src/dfs.rs b/server/src/dfs.rs deleted file mode 100644 index dc62798..0000000 --- a/server/src/dfs.rs +++ /dev/null @@ -1,156 +0,0 @@ -use petgraph::stable_graph::NodeIndex; - -use crate::graph::CachedStableGraph; - -use anyhow::Result; - -struct VisitCount { - node: NodeIndex, - touch: usize, - children: usize, -} - -/// Performs a depth-first search with duplicates -pub struct Dfs<'a> { - stack: Vec, - graph: &'a CachedStableGraph, - cycle: Vec -} - -impl <'a> Dfs<'a> { - pub fn new(graph: &'a CachedStableGraph, start: NodeIndex) -> Self { - Dfs { - stack: vec![start], - graph, - cycle: Vec::new() - } - } - - fn reset_path_to_branch(&mut self) { - while let Some(par) = self.cycle.last_mut() { - par.touch += 1; - if par.touch > par.children { - self.cycle.pop(); - } else { - break; - } - } - } - - fn check_for_cycle(&self, children: &[NodeIndex]) -> Result<(), error::CycleError> { - for prev in &self.cycle { - for child in children { - if prev.node == *child { - let cycle_nodes: Vec = self.cycle.iter().map(|n| n.node).collect(); - return Err( - error::CycleError::new(&cycle_nodes, *child, self.graph) - ); - } - } - } - Ok(()) - } -} - -impl <'a> Iterator for Dfs<'a> { - type Item = Result<(NodeIndex, Option), error::CycleError>; - - fn next(&mut self) -> Option), error::CycleError>> { - let parent = match self.cycle.last() { - Some(p) => Some(p.node), - None => None, - }; - - if let Some(node) = self.stack.pop() { - self.cycle.push(VisitCount{ - node, - children: self.graph.graph.edges(node).count(), - touch: 1, - }); - - let mut children = self.graph.child_node_indexes(node); - - if !children.is_empty() { - // sort by line number in parent - children.sort_by(|x, y| { - let graph = &self.graph.graph; - let edge1 = graph.edge_weight(graph.find_edge(node, *x).unwrap()).unwrap(); - let edge2 = graph.edge_weight(graph.find_edge(node, *y).unwrap()).unwrap(); - - edge2.line.cmp(&edge1.line) - }); - - match self.check_for_cycle(&children) { - Ok(_) => {} - Err(e) => return Some(Err(e)), - }; - - for child in children { - self.stack.push(child); - } - } else { - self.reset_path_to_branch(); - } - - return Some(Ok((node, parent))); - } - None - } -} - -pub mod error { - use petgraph::stable_graph::NodeIndex; - - use std::{fmt::{Debug, Display}, path::PathBuf, error::Error as StdError}; - - use crate::{graph::CachedStableGraph, consts}; - - use rust_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range}; - - #[derive(Debug)] - pub struct CycleError(Vec); - - impl StdError for CycleError {} - - impl CycleError { - pub fn new(nodes: &[NodeIndex], current_node: NodeIndex, graph: &CachedStableGraph) -> Self { - let mut resolved_nodes: Vec = nodes.iter().map(|i| graph.get_node(*i).clone()).collect(); - resolved_nodes.push(graph.get_node(current_node).clone()); - CycleError(resolved_nodes) - } - } - - impl Display for CycleError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut disp = String::new(); - disp.push_str(format!("Include cycle detected:\n{:?} imports ", self.0[0]).as_str()); - for p in &self.0[1..self.0.len()-1] { - disp.push_str(format!("\n{:?}, which imports ", *p).as_str()); - } - disp.push_str(format!("\n{:?}", self.0[self.0.len()-1]).as_str()); - f.write_str(disp.as_str()) - } - } - - impl Into for CycleError { - fn into(self) -> Diagnostic { - Diagnostic{ - severity: Some(DiagnosticSeverity::Error), - range: Range::new(Position::new(0, 0), Position::new(0, 500)), - source: Some(consts::SOURCE.into()), - message: self.into(), - code: None, - tags: None, - related_information: None, - code_description: Option::None, - data: Option::None, - } - } - } - - impl Into for CycleError { - fn into(self) -> String { - format!("{}", self) - } - } -} \ No newline at end of file diff --git a/server/src/graph.rs b/server/src/graph.rs deleted file mode 100644 index b5a79bf..0000000 --- a/server/src/graph.rs +++ /dev/null @@ -1,150 +0,0 @@ -use petgraph::stable_graph::StableDiGraph; -use petgraph::stable_graph::NodeIndex; -use petgraph::Direction; -use petgraph::stable_graph::EdgeIndex; - -use std::{collections::{HashMap, HashSet}, path::PathBuf, str::FromStr}; - -use super::IncludePosition; - -/// Wraps a `StableDiGraph` with caching behaviour for node search by maintaining -/// an index for node value to node index and a reverse index. -/// This allows for **O(1)** lookup for a value if it exists, else **O(n)**. -pub struct CachedStableGraph { - // StableDiGraph is used as it allows for String node values, essential for - // generating the GraphViz DOT render. - pub graph: StableDiGraph, - cache: HashMap, - // Maps a node index to its abstracted string representation. - // Mainly used as the graph is based on NodeIndex and - reverse_index: HashMap, -} - -impl CachedStableGraph { - pub fn new() -> CachedStableGraph { - CachedStableGraph{ - graph: StableDiGraph::new(), - cache: HashMap::new(), - reverse_index: HashMap::new(), - } - } - - /// Returns the `NodeIndex` for a given graph node with the value of `name` - /// and caches the result in the `HashMap`. Complexity is **O(1)** if the value - /// is cached (which should always be the case), else **O(n)** where **n** is - /// the number of node indices, as an exhaustive search must be done. - pub fn find_node(&mut self, name: &PathBuf) -> Option { - match self.cache.get(name) { - Some(n) => Some(*n), - None => { - // If the string is not in cache, O(n) search the graph (i know...) and then cache the NodeIndex - // for later - let n = self.graph.node_indices().find(|n| self.graph[*n] == name.to_str().unwrap().to_string()); - if let Some(n) = n { - self.cache.insert(name.into(), n); - } - n - } - } - } - - pub fn get_node(&self, node: NodeIndex) -> PathBuf { - PathBuf::from_str(&self.graph[node]).unwrap() - } - - pub fn get_edge_meta(&self, parent: NodeIndex, child: NodeIndex) -> &IncludePosition { - self.graph.edge_weight(self.graph.find_edge(parent, child).unwrap()).unwrap() - } - - #[allow(dead_code)] - pub fn remove_node(&mut self, name: &PathBuf) { - let idx = self.cache.remove(name); - if let Some(idx) = idx { - self.graph.remove_node(idx); - } - } - - pub fn add_node(&mut self, name: &PathBuf) -> NodeIndex { - if let Some(idx) = self.cache.get(name) { - return *idx; - } - let idx = self.graph.add_node(name.to_str().unwrap().to_string()); - self.cache.insert(name.clone(), idx); - self.reverse_index.insert(idx, name.clone()); - idx - } - - pub fn add_edge(&mut self, parent: NodeIndex, child: NodeIndex, meta: IncludePosition) -> EdgeIndex { - self.graph.add_edge(parent, child, meta) - } - - pub fn remove_edge(&mut self, parent: NodeIndex, child: NodeIndex) { - let edge = self.graph.find_edge(parent, child).unwrap(); - self.graph.remove_edge(edge); - } - - #[allow(dead_code)] - pub fn edge_weights(&self, node: NodeIndex) -> Vec { - self.graph.edges(node).map(|e| e.weight().clone()).collect() - } - - #[allow(dead_code)] - pub fn child_node_names(&self, node: NodeIndex) -> Vec { - self.graph.neighbors(node).map(|n| self.reverse_index.get(&n).unwrap().clone()).collect() - } - - pub fn child_node_meta(&self, node: NodeIndex) -> Vec<(PathBuf, IncludePosition)> { - self.graph.neighbors(node).map(|n| { - let edge = self.graph.find_edge(node, n).unwrap(); - let edge_meta = self.graph.edge_weight(edge).unwrap(); - return (self.reverse_index.get(&n).unwrap().clone(), edge_meta.clone()) - }).collect() - } - - pub fn child_node_indexes(&self, node: NodeIndex) -> Vec { - self.graph.neighbors(node).collect() - } - - #[allow(dead_code)] - pub fn parent_node_names(&self, node: NodeIndex) -> Vec { - self.graph.neighbors_directed(node, Direction::Incoming).map(|n| self.reverse_index.get(&n).unwrap().clone()).collect() - } - - pub fn parent_node_indexes(&self, node: NodeIndex) -> Vec { - self.graph.neighbors_directed(node, Direction::Incoming).collect() - } - - #[allow(dead_code)] - pub fn get_include_meta(&self, node: NodeIndex) -> Vec { - self.graph.edges(node).map(|e| e.weight().clone()).collect() - } - - pub fn collect_root_ancestors(&self, node: NodeIndex) -> Vec { - let mut visited = HashSet::new(); - self.get_root_ancestors(node, node, &mut visited) - } - - fn get_root_ancestors(&self, initial: NodeIndex, node: NodeIndex, visited: &mut HashSet) -> Vec { - if node == initial && !visited.is_empty() { - return vec![]; - } - - let parents = self.parent_node_indexes(node); - let mut collection = Vec::with_capacity(parents.len()); - - for ancestor in &parents { - visited.insert(*ancestor); - } - - for ancestor in &parents { - let ancestors = self.parent_node_indexes(*ancestor); - if !ancestors.is_empty() { - collection.extend(self.get_root_ancestors(initial, *ancestor, visited)); - } else { - collection.push(*ancestor); - } - } - - collection - } -} \ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs deleted file mode 100644 index 8dce1c5..0000000 --- a/server/src/main.rs +++ /dev/null @@ -1,749 +0,0 @@ -use rust_lsp::jsonrpc::{*, method_types::*}; -use rust_lsp::lsp::*; -use rust_lsp::lsp_types::{*, notification::*}; - -use petgraph::stable_graph::NodeIndex; - -use serde_json::Value; -use url_norm::FromUrl; -use walkdir::WalkDir; - -use std::{cell::RefCell, path::PathBuf, str::FromStr}; -use std::collections::{HashMap, HashSet}; -use std::collections::hash_map::RandomState; -use std::convert::TryFrom; -use std::fmt::{Display, Formatter, Debug}; -use std::io::{stdin, stdout, BufRead, BufReader}; -use std::rc::Rc; -use std::fs; -use std::iter::{Extend, FromIterator}; - -use path_slash::PathBufExt; - -use anyhow::{Result, anyhow}; - -use chan::WaitGroup; - -use regex::Regex; - -use lazy_static::lazy_static; - -mod graph; -mod commands; -mod lsp_ext; -mod dfs; -mod merge_views; -mod consts; -mod opengl; -mod url_norm; - -#[cfg(test)] -mod test; - -lazy_static! { - static ref RE_DIAGNOSTIC: Regex = Regex::new(r#"^(?P[^?<>*|"]+)\((?P\d+)\) : (?Perror|warning) [A-C]\d+: (?P.+)"#).unwrap(); - static ref RE_VERSION: Regex = Regex::new(r#"#version [\d]{3}"#).unwrap(); - static ref RE_INCLUDE: Regex = Regex::new(r#"^(?:\s)*?(?:#include) "(.+)"\r?"#).unwrap(); - static ref RE_INCLUDE_EXTENSION: Regex = Regex::new(r#"#extension GL_GOOGLE_include_directive ?: ?require"#).unwrap(); -} - -fn main() { - let stdin = stdin(); - - let endpoint_output = LSPEndpoint::create_lsp_output_with_output_stream(stdout); - - let cache_graph = graph::CachedStableGraph::new(); - - let mut langserver = MinecraftShaderLanguageServer { - endpoint: endpoint_output.clone(), - graph: Rc::new(RefCell::new(cache_graph)), - wait: WaitGroup::new(), - root: "".into(), - command_provider: None, - opengl_context: Rc::new(opengl::OpenGLContext::new()) - }; - - langserver.command_provider = Some(commands::CustomCommandProvider::new(vec![ - ( - "graphDot", - Box::new(commands::GraphDotCommand { - graph: Rc::clone(&langserver.graph), - }), - ), - ( - "virtualMerge", - Box::new(commands::VirtualMergedDocument{ - graph: Rc::clone(&langserver.graph) - }) - ) - ])); - - LSPEndpoint::run_server_from_input(&mut stdin.lock(), endpoint_output, langserver); -} - -struct MinecraftShaderLanguageServer { - endpoint: Endpoint, - graph: Rc>, - wait: WaitGroup, - root: PathBuf, - command_provider: Option, - opengl_context: Rc -} - -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct IncludePosition { - line: usize, - start: usize, - end: usize, -} - -impl Debug for IncludePosition { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{{line: {}}}", self.line) - } -} - -impl Display for IncludePosition { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "{{line: {}}}", self.line) - } -} - -pub enum TreeType { - Fragment, Vertex, Geometry -} - -impl MinecraftShaderLanguageServer { - pub fn error_not_available(data: DATA) -> MethodError { - let msg = "Functionality not implemented.".to_string(); - MethodError:: { - code: 1, - message: msg, - data, - } - } - - pub fn gen_initial_graph(&self) { - eprintln!("root of project is {:?}", self.root); - - // filter directories and files not ending in any of the 3 extensions - WalkDir::new(&self.root).into_iter().filter_map(|entry| { - if entry.is_err() { - return None; - } - - let entry = entry.unwrap(); - let path = entry.path(); - if path.is_dir() { - return None; - } - - let ext = match path.extension() { - Some(e) => e, - None => return None, - }; - - if ext != "vsh" && ext != "fsh" && ext != "glsl" && ext != "inc" { - return None; - } - - Some(entry.into_path()) - }).for_each(|path| { - // iterate all valid found files, search for includes, add a node into the graph for each - // file and add a file->includes KV into the map - self.add_file_and_includes_to_graph(&path); - }); - - eprintln!("finished building project include graph"); - } - - fn add_file_and_includes_to_graph(&self, path: &PathBuf) { - let includes = self.find_includes(path); - - let idx = self.graph.borrow_mut().add_node(&path); - - //eprintln!("adding {:?} with {:?}", path, includes); - for include in includes { - self.add_include(include, idx); - } - } - - fn add_include(&self, include: (PathBuf, IncludePosition), node: NodeIndex) { - let child = self.graph.borrow_mut().add_node(&include.0); - self.graph.borrow_mut().add_edge(node, child, include.1); - } - - pub fn find_includes(&self, file: &PathBuf) -> Vec<(PathBuf, IncludePosition)> { - let mut includes = Vec::default(); - - let buf = BufReader::new(std::fs::File::open(file).unwrap()); - buf.lines() - .enumerate() - .filter_map(|line| match line.1 { - Ok(t) => Some((line.0, t)), - Err(_e) => None, - }) - .filter(|line| RE_INCLUDE.is_match(line.1.as_str())) - .for_each(|line| { - let cap = RE_INCLUDE - .captures(line.1.as_str()) - .unwrap() - .get(1) - .unwrap(); - - let start = cap.start(); - let end = cap.end(); - let mut path: String = cap.as_str().into(); - - // TODO: difference between / and not - let full_include = if path.starts_with('/') { - path = path.strip_prefix('/').unwrap().to_string(); - self.root.join("shaders").join(PathBuf::from_slash(&path)) - } else { - file.parent().unwrap().join(PathBuf::from_slash(&path)) - }; - - includes.push(( - full_include, - IncludePosition { - line: line.0, - start, - end, - } - )); - }); - - includes - } - - fn update_includes(&self, file: &PathBuf) { - let includes = self.find_includes(file); - - eprintln!("updating {:?} with {:?}", file, includes); - - let idx = match self.graph.borrow_mut().find_node(&file) { - None => { - return - }, - Some(n) => n, - }; - - let prev_children: HashSet<_, RandomState> = HashSet::from_iter(self.graph.borrow().child_node_meta(idx)); - let new_children: HashSet<_, RandomState> = HashSet::from_iter(includes.iter().map(|e| e.clone())); - - let to_be_added = new_children.difference(&prev_children); - let to_be_removed = prev_children.difference(&new_children); - - eprintln!("removing:\n\t{:?}\nadding:\n\t{:?}", to_be_removed, to_be_added); - - for removal in to_be_removed { - let child = self.graph.borrow_mut().find_node(&removal.0).unwrap(); - self.graph.borrow_mut().remove_edge(idx, child); - } - - for insertion in to_be_added { - self.add_include(includes.iter().find(|f| f.0 == *insertion.0).unwrap().clone(), idx); - } - } - - pub fn lint(&self, uri: &PathBuf) -> Result>> { - // get all top level ancestors of this file - let file_ancestors = match self.get_file_toplevel_ancestors(uri) { - Ok(opt) => match opt { - Some(ancestors) => ancestors, - None => vec![], - }, - Err(e) => return Err(e), - }; - - eprintln!("ancestors for {:?}:\n\t{:?}", uri, file_ancestors.iter().map(|e| PathBuf::from_str(&self.graph.borrow().graph.node_weight(*e).unwrap().clone()).unwrap()).collect::>()); - - // the set of all filepath->content. TODO: change to Url? - let mut all_sources: HashMap = HashMap::new(); - // the set of filepath->list of diagnostics to report - let mut diagnostics: HashMap> = HashMap::new(); - - // we want to backfill the diagnostics map with all linked sources - let back_fill = |all_sources, diagnostics: &mut HashMap>| { - for (path, _) in all_sources { - diagnostics.entry(Url::from_file_path(path).unwrap()).or_default(); - } - }; - - // if we are a top-level file (this has to be one of the set defined by Optifine, right?) - if file_ancestors.is_empty() { - // gather the list of all descendants - let root = self.graph.borrow_mut().find_node(&uri).unwrap(); - let tree = match self.get_dfs_for_node(root) { - Ok(tree) => tree, - Err(e) => { - diagnostics.insert(Url::from_file_path(uri).unwrap(), vec![e.into()]); - return Ok(diagnostics); - } - }; - - all_sources.extend( self.load_sources(&tree)?); - - let view = { - let graph = self.graph.borrow(); - merge_views::generate_merge_list(&tree, &all_sources, &graph) - }; - - let root_path = self.graph.borrow().get_node(root).clone(); - let tree_type = if root_path.extension().unwrap() == "fsh" { - TreeType::Fragment - } else if root_path.extension().unwrap() == "vsh" { - TreeType::Vertex - } else if root_path.extension().unwrap() == "gsh" { - TreeType::Geometry - } else { - eprintln!("got a non fsh|vsh ({:?}) as a file root ancestor: {:?}", root_path.extension().unwrap(), root_path); - back_fill(&all_sources, &mut diagnostics); - return Ok(diagnostics) - }; - - let stdout = match self.opengl_context.clone().validate(tree_type, view) { - Some(s) => s, - None => { - back_fill(&all_sources, &mut diagnostics); - return Ok(diagnostics) - }, - }; - diagnostics.extend(self.parse_validator_stdout(uri, stdout, "")); - } else { - let mut all_trees: Vec<(TreeType, Vec<(NodeIndex, Option<_>)>)> = Vec::new(); - - for root in &file_ancestors { - let nodes = match self.get_dfs_for_node(*root) { - Ok(nodes) => nodes, - Err(e) => { - diagnostics.insert(Url::from_file_path(uri).unwrap(), vec![e.into()]); - back_fill(&all_sources, &mut diagnostics); // TODO: confirm - return Ok(diagnostics); - } - }; - - let root_path = self.graph.borrow().get_node(*root).clone(); - let tree_type = if root_path.extension().unwrap() == "fsh" { - TreeType::Fragment - } else if root_path.extension().unwrap() == "vsh" { - TreeType::Vertex - } else if root_path.extension().unwrap() == "gsh" { - TreeType::Geometry - } else { - eprintln!("got a non fsh|vsh ({:?}) as a file root ancestor: {:?}", root_path.extension().unwrap(), root_path); - continue; - }; - - let sources = self.load_sources(&nodes)?; - all_trees.push((tree_type, nodes)); - all_sources.extend(sources); - } - - for tree in all_trees { - let view = { - let graph = self.graph.borrow(); - merge_views::generate_merge_list(&tree.1, &all_sources, &graph) - }; - - let stdout = match self.opengl_context.clone().validate(tree.0, view) { - Some(s) => s, - None => continue, - }; - diagnostics.extend(self.parse_validator_stdout(uri, stdout, "")); - } - }; - - back_fill(&all_sources, &mut diagnostics); - Ok(diagnostics) - } - - fn parse_validator_stdout(&self, uri: &PathBuf, stdout: String, _source: &str) -> HashMap> { - let stdout_lines = stdout.split('\n'); - let mut diagnostics: HashMap> = HashMap::with_capacity(stdout_lines.count()); - let stdout_lines = stdout.split('\n'); - - for line in stdout_lines { - let diagnostic_capture = match RE_DIAGNOSTIC.captures(line) { - Some(d) => d, - None => continue - }; - - eprintln!("match {:?}", diagnostic_capture); - - let msg = diagnostic_capture.name("output").unwrap().as_str(); - - let line = match diagnostic_capture.name("linenum") { - Some(c) => match c.as_str().parse::() { - Ok(i) => i, - Err(_) => 0, - }, - None => 0, - } - 2; - - // TODO: line matching maybe - /* let line_text = source_lines[line as usize]; - let leading_whitespace = line_text.len() - line_text.trim_start().len(); */ - - let severity = match diagnostic_capture.name("severity") { - Some(c) => match c.as_str() { - "error" => DiagnosticSeverity::Error, - "warning" => DiagnosticSeverity::Warning, - _ => DiagnosticSeverity::Information, - } - _ => DiagnosticSeverity::Information, - }; - - let origin = match diagnostic_capture.name("filepath") { - Some(o) => { - if o.as_str().to_string() == "0" { - uri.to_str().unwrap().to_string() - } else { - o.as_str().to_string() - } - }, - None => uri.to_str().unwrap().to_string(), - }; - - let diagnostic = Diagnostic { - range: Range::new( - /* Position::new(line, leading_whitespace as u64), - Position::new(line, line_text.len() as u64) */ - Position::new(line, 0), - Position::new(line, 1000), - ), - code: None, - severity: Some(severity), - source: Some(consts::SOURCE.into()), - message: msg.trim().into(), - related_information: None, - tags: None, - code_description: Option::None, - data: Option::None, - }; - - let origin_url = Url::from_file_path(origin).unwrap(); - match diagnostics.get_mut(&origin_url) { - Some(d) => d.push(diagnostic), - None => { - diagnostics.insert(origin_url, vec![diagnostic]); - }, - }; - } - diagnostics - } - - pub fn get_dfs_for_node(&self, root: NodeIndex) -> Result)>, dfs::error::CycleError> { - let graph_ref = self.graph.borrow(); - - let dfs = dfs::Dfs::new(&graph_ref, root); - - dfs.collect::, _>>() - } - - pub fn load_sources(&self, nodes: &[(NodeIndex, Option)]) -> Result> { - let mut sources = HashMap::new(); - - for node in nodes { - let graph = self.graph.borrow(); - let path = graph.get_node(node.0); - - if sources.contains_key(&path) { - continue; - } - - let source = match fs::read_to_string(&path) { - Ok(s) => s, - Err(e) => return Err(anyhow!("error reading {:?}: {}", path, e)) - }; - sources.insert(path.clone(), source); - } - - Ok(sources) - } - - fn get_file_toplevel_ancestors(&self, uri: &PathBuf) -> Result>> { - let curr_node = match self.graph.borrow_mut().find_node(uri) { - Some(n) => n, - None => return Err(anyhow!("node not found {:?}", uri)), - }; - let roots = self.graph.borrow().collect_root_ancestors(curr_node); - if roots.is_empty() { - return Ok(None); - } - Ok(Some(roots)) - } - - pub fn publish_diagnostic(&self, diagnostics: HashMap>, document_version: Option) { - eprintln!("DIAGNOSTICS:\n{:?}", diagnostics); - for (uri, diagnostics) in diagnostics { - self.endpoint.send_notification(PublishDiagnostics::METHOD, PublishDiagnosticsParams { - uri, - diagnostics, - version: document_version, - }).expect("failed to publish diagnostics"); - } - } - - fn set_status(&self, status: impl Into, message: impl Into, icon: impl Into) { - self.endpoint.send_notification(lsp_ext::Status::METHOD, lsp_ext::StatusParams { - status: status.into(), - message: Some(message.into()), - icon: Some(icon.into()), - }).unwrap_or(()); - } -} - -impl LanguageServerHandling for MinecraftShaderLanguageServer { - fn initialize(&mut self, params: InitializeParams, completable: MethodCompletable) { - self.wait.add(1); - - let mut capabilities = ServerCapabilities::default(); - capabilities.hover_provider = None; - capabilities.document_link_provider = Some(DocumentLinkOptions { - resolve_provider: None, - work_done_progress_options: WorkDoneProgressOptions { - work_done_progress: None, - }, - }); - capabilities.execute_command_provider = Some(ExecuteCommandOptions { - commands: vec!["graphDot".into()], - work_done_progress_options: WorkDoneProgressOptions { - work_done_progress: None, - }, - }); - capabilities.text_document_sync = Some(TextDocumentSyncCapability::Options( - TextDocumentSyncOptions { - open_close: Some(true), - will_save: None, - will_save_wait_until: None, - change: Some(TextDocumentSyncKind::Full), - save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions { - include_text: Some(true), - })) - }, - )); - - let root = match params.root_uri { - Some(uri) => PathBuf::from_url(uri), - None => { - completable.complete(Err(MethodError { - code: 42069, - message: "Must be in workspace".into(), - data: InitializeError { - retry: false, - }, - })); - return; - } - }; - - completable.complete(Ok(InitializeResult { - capabilities, - server_info: None, - })); - - self.set_status("loading", "Building dependency graph...", "$(loading~spin)"); - - self.root = root; - - self.gen_initial_graph(); - - self.set_status("ready", "Project initialized", "$(check)"); - } - - fn shutdown(&mut self, _: (), completable: LSCompletable<()>) { - eprintln!("shutting down language server..."); - completable.complete(Ok(())); - } - - fn exit(&mut self, _: ()) { - self.endpoint.request_shutdown(); - } - - fn workspace_change_configuration(&mut self, params: DidChangeConfigurationParams) { - //let config = params.settings.as_object().unwrap().get("mcglsl").unwrap(); - - eprintln!("{:?}", params.settings.as_object().unwrap()); - - self.wait.done(); - } - - fn did_open_text_document(&mut self, params: DidOpenTextDocumentParams) { - //eprintln!("opened doc {}", params.text_document.uri); - let path = PathBuf::from_url(params.text_document.uri); - if self.graph.borrow_mut().find_node(&path) == None { - self.add_file_and_includes_to_graph(&path); - } - match self.lint(&path) { - Ok(diagnostics) => self.publish_diagnostic(diagnostics, None), - Err(e) => eprintln!("error linting: {}", e), - } - } - - fn did_change_text_document(&mut self, _: DidChangeTextDocumentParams) {} - - fn did_close_text_document(&mut self, _: DidCloseTextDocumentParams) {} - - fn did_save_text_document(&mut self, params: DidSaveTextDocumentParams) { - eprintln!("saved doc {}", params.text_document.uri); - - let path = PathBuf::from_url(params.text_document.uri); - self.update_includes(&path); - - match self.lint(&path) { - Ok(diagnostics) => self.publish_diagnostic(diagnostics, None), - Err(e) => eprintln!("error linting: {}", e), - } - } - - fn did_change_watched_files(&mut self, _: DidChangeWatchedFilesParams) {} - - fn completion(&mut self, _: TextDocumentPositionParams, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn resolve_completion_item(&mut self, _: CompletionItem, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn hover(&mut self, _: TextDocumentPositionParams, _: LSCompletable) { - self.wait.wait(); - /* completable.complete(Ok(Hover{ - contents: HoverContents::Markup(MarkupContent{ - kind: MarkupKind::Markdown, - value: String::from("# Hello World"), - }), - range: None, - })); */ - } - - fn execute_command(&mut self, params: ExecuteCommandParams, completable: LSCompletable>) { - match self.command_provider.as_ref().unwrap().execute(¶ms.command, params.arguments, &self.root) { - Ok(resp) => { - eprintln!("executed {} successfully", params.command); - self.endpoint.send_notification(ShowMessage::METHOD, ShowMessageParams { - typ: MessageType::Info, - message: format!("Command {} executed successfully.", params.command), - }).expect("failed to send popup/show message notification"); - completable.complete(Ok(Some(resp))) - }, - Err(err) => { - self.endpoint.send_notification(ShowMessage::METHOD, ShowMessageParams { - typ: MessageType::Error, - message: format!("Failed to execute `{}`. Reason: {}", params.command, err), - }).expect("failed to send popup/show message notification"); - eprintln!("failed to execute {}: {}", params.command, err); - completable.complete(Err(MethodError::new(32420, err.to_string(), ()))) - }, - } - } - - fn signature_help(&mut self, _: TextDocumentPositionParams, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn goto_definition(&mut self, _: TextDocumentPositionParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn references(&mut self, _: ReferenceParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn document_highlight(&mut self, _: TextDocumentPositionParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn document_symbols(&mut self, _: DocumentSymbolParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn workspace_symbols(&mut self, _: WorkspaceSymbolParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn code_action(&mut self, _: CodeActionParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn code_lens(&mut self, _: CodeLensParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn code_lens_resolve(&mut self, _: CodeLens, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn document_link(&mut self, params: DocumentLinkParams, completable: LSCompletable>) { - eprintln!("document link file: {:?}", params.text_document.uri.to_file_path().unwrap()); - // node for current document - let curr_doc = params - .text_document - .uri - .to_file_path() - .unwrap(); - let node = match self.graph.borrow_mut().find_node(&curr_doc) { - Some(n) => n, - None => { - completable.complete(Ok(vec![])); - return - }, - }; - - let edges: Vec = self - .graph - .borrow() - .child_node_indexes(node) - .into_iter() - .filter_map(|child| { - let graph = self.graph.borrow(); - let value = graph.get_edge_meta(node, child); - let path = graph.get_node(child); - let url = match Url::from_file_path(&path) { - Ok(url) => url, - Err(e) => { - eprintln!("error converting {:?} into url: {:?}", path, e); - return None; - } - }; - - Some(DocumentLink { - range: Range::new( - Position::new( - u32::try_from(value.line).unwrap(), - u32::try_from(value.start).unwrap()), - Position::new( - u32::try_from(value.line).unwrap(), - u32::try_from(value.end).unwrap()), - ), - target: Some(url), - //tooltip: Some(url.path().to_string().strip_prefix(self.root.clone().unwrap().as_str()).unwrap().to_string()), - tooltip: None, - data: None, - }) - }).collect(); - eprintln!("links: {:?}", edges); - completable.complete(Ok(edges)); - } - - fn document_link_resolve(&mut self, _: DocumentLink, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn formatting(&mut self, _: DocumentFormattingParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn range_formatting(&mut self, _: DocumentRangeFormattingParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn on_type_formatting(&mut self, _: DocumentOnTypeFormattingParams, completable: LSCompletable>) { - completable.complete(Err(Self::error_not_available(()))); - } - - fn rename(&mut self, _: RenameParams, completable: LSCompletable) { - completable.complete(Err(Self::error_not_available(()))); - } -} diff --git a/server/src/merge_views.rs b/server/src/merge_views.rs deleted file mode 100644 index 1aad5a8..0000000 --- a/server/src/merge_views.rs +++ /dev/null @@ -1,208 +0,0 @@ -use std::{collections::{HashMap, LinkedList, VecDeque}, path::PathBuf}; -use std::iter::Peekable; -use std::cmp::min; - -use core::slice::Iter; - -use petgraph::stable_graph::NodeIndex; - -use crate::graph::CachedStableGraph; - -pub fn generate_merge_list<'a>( - nodes: &'a [(NodeIndex, Option)], - sources: &'a HashMap, - graph: &'a CachedStableGraph -) -> String { - let mut line_directives: Vec = Vec::new(); - - // list of source code views onto the below sources - let mut merge_list: LinkedList<&'a str> = LinkedList::new(); - - line_directives.reserve(nodes.len() * 2); - - let mut last_offset_set: HashMap = HashMap::new(); - - let mut nodes_iter = nodes.iter().peekable(); - - let first = nodes_iter.next().unwrap().0; - let first_path = graph.get_node(first).clone(); - - last_offset_set.insert(first_path.clone(), 0); - - let line_ending_offset = if is_crlf(sources.get(&first_path).unwrap()) { - 2 - } else { - 1 - }; - - // stack to keep track of the depth first traversal - let mut stack = VecDeque::::new(); - - create_merge_views(&mut nodes_iter, &mut merge_list, &mut last_offset_set, graph, sources, &mut line_directives, &mut stack, line_ending_offset); - - // now we add a view of the remainder of the root file - let offset = *last_offset_set.get(&first_path).unwrap(); - - let len = sources.get(&first_path).unwrap().len(); - merge_list.push_back(&sources.get(&first_path).unwrap()[min(offset, len) ..]); - - let total_len = merge_list.iter().fold(0, |a, b| { - a + b.len() - }); - - let mut merged = String::with_capacity(total_len); - for slice in merge_list { - merged.push_str(slice); - } - - merged -} - -fn is_crlf(source: &String) -> bool { - source.contains("\r\n") -} - -fn create_merge_views<'a>( - nodes: &mut Peekable)>>, - merge_list: &mut LinkedList<&'a str>, - last_offset_set: &mut HashMap, - graph: &'a CachedStableGraph, - sources: &'a HashMap, - line_directives: &mut Vec, - stack: &mut VecDeque, - line_ending_offset: usize, -) { - - loop { - let n = match nodes.next() { - Some(n) => n, - None => return, - }; - - let parent = n.1.unwrap(); - let child = n.0; - let edge = graph.get_edge_meta(parent, child); - let parent_path = graph.get_node(parent).clone(); - let child_path = graph.get_node(child).clone(); - - let parent_source = sources.get(&parent_path).unwrap(); - let (char_for_line, char_following_line) = char_offset_for_line(edge.line, parent_source, line_ending_offset); - - let offset = *last_offset_set.insert(parent_path.clone(), char_following_line).get_or_insert(0); - merge_list.push_back(&parent_source[offset..char_for_line]); - add_opening_line_directive(&child_path, merge_list, line_directives); - - match nodes.peek() { - Some(next) => { - let next = *next; - // if the next pair's parent is not a child of the current pair, we dump the rest of this childs source - if next.1.unwrap() != child { - let child_source = sources.get(&child_path).unwrap(); - // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad - let offset = { - match child_source.ends_with("\n") { - true => child_source.len()-line_ending_offset, - false => child_source.len(), - } - }; - merge_list.push_back(&child_source[..offset]); - last_offset_set.insert(child_path.clone(), 0); - // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line - add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); - // if the next pair's parent is not the current pair's parent, we need to bubble up - if stack.contains(&next.1.unwrap()) { - return; - } - continue; - } - - stack.push_back(parent); - create_merge_views(nodes, merge_list, last_offset_set, graph, sources, line_directives, stack, line_ending_offset); - stack.pop_back(); - - let offset = *last_offset_set.get(&child_path).unwrap(); - let child_source = sources.get(&child_path).unwrap(); - // this evaluates to false once the file contents have been exhausted aka offset = child_source.len() + 1 - let end_offset = { - match child_source.ends_with("\n") { - true => line_ending_offset/* child_source.len()-1 */, - false => 0/* child_source.len() */, - } - }; - if offset < child_source.len()-end_offset { - // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad - merge_list.push_back(&child_source[offset../* std::cmp::max( */child_source.len()-end_offset/* , offset) */]); - last_offset_set.insert(child_path.clone(), 0); - } - - // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line - add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); - - // we need to check the next item at the point of original return further down the callstack - if nodes.peek().is_some() && stack.contains(&nodes.peek().unwrap().1.unwrap()) { - return; - } - }, - None => { - let child_source = sources.get(&child_path).unwrap(); - // if ends in \n\n, we want to exclude the last \n for some reason. Ask optilad - let offset = { - match child_source.ends_with("\n") { - true => child_source.len()-line_ending_offset, - false => child_source.len(), - } - }; - merge_list.push_back(&child_source[..offset]); - last_offset_set.insert(child_path.clone(), 0); - // +2 because edge.line is 0 indexed but #line is 1 indexed and references the *following* line - add_closing_line_directive(edge.line+2, &parent_path, merge_list, line_directives); - } - } - } -} - -// returns the character offset + 1 of the end of line number `line` and the character -// offset + 1 for the end of the line after the previous one -fn char_offset_for_line(line_num: usize, source: &str, line_ending_offset: usize) -> (usize, usize) { - let mut char_for_line: usize = 0; - let mut char_following_line: usize = 0; - for (n, line) in source.lines().enumerate() { - if n == line_num { - char_following_line += line.len()+line_ending_offset; - break; - } - char_for_line += line.len()+line_ending_offset; - char_following_line = char_for_line; - } - (char_for_line, char_following_line) -} - -fn add_opening_line_directive(path: &PathBuf, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec) { - let line_directive = format!("#line 1 \"{}\"\n", path.to_str().unwrap().replace("\\", "\\\\")); - line_directives.push(line_directive); - unsafe_get_and_insert(merge_list, line_directives); -} - -fn add_closing_line_directive(line: usize, path: &PathBuf, merge_list: &mut LinkedList<&str>, line_directives: &mut Vec) { - // Optifine doesn't seem to add a leading newline if the previous line was a #line directive - let line_directive = if let Some(l) = merge_list.back() { - if l.trim().starts_with("#line") { - format!("#line {} \"{}\"\n", line, path.to_str().unwrap().replace("\\", "\\\\")) - } else { - format!("\n#line {} \"{}\"\n", line, path.to_str().unwrap().replace("\\", "\\\\")) - } - } else { - format!("\n#line {} \"{}\"\n", line, path.to_str().unwrap().replace("\\", "\\\\")) - }; - - line_directives.push(line_directive); - unsafe_get_and_insert(merge_list, line_directives); -} - -fn unsafe_get_and_insert(merge_list: &mut LinkedList<&str>, line_directives: &Vec) { - // :^) - unsafe { - let vec_ptr_offset = line_directives.as_ptr().add(line_directives.len()-1); - merge_list.push_back(&vec_ptr_offset.as_ref().unwrap()[..]); - } -} \ No newline at end of file diff --git a/server/src/test.rs b/server/src/test.rs deleted file mode 100644 index c07cb2e..0000000 --- a/server/src/test.rs +++ /dev/null @@ -1,1177 +0,0 @@ -use super::*; -use std::fs; -use std::io; -use std::io::Result; - -use hamcrest2::prelude::*; -use pretty_assertions::assert_eq; - -use tempdir::TempDir; - -use petgraph::algo::is_cyclic_directed; - -use fs_extra::{copy_items, dir}; - -use jsonrpc_common::*; -use jsonrpc_response::*; - -struct StdoutNewline { - s: Box, -} - -impl io::Write for StdoutNewline { - fn write(&mut self, buf: &[u8]) -> Result { - let res = self.s.write(buf); - if buf[buf.len() - 1] == b"}"[0] { - #[allow(unused_variables)] - let res = self.s.write(b"\n\n"); - } - res - } - - fn flush(&mut self) -> Result<()> { - self.s.flush() - } -} - -fn new_temp_server() -> MinecraftShaderLanguageServer { - let endpoint = LSPEndpoint::create_lsp_output_with_output_stream(|| StdoutNewline { - s: Box::new(io::sink()), - }); - - MinecraftShaderLanguageServer { - endpoint, - graph: Rc::new(RefCell::new(graph::CachedStableGraph::new())), - wait: WaitGroup::new(), - root: "".into(), - command_provider: None, - opengl_context: Rc::new(opengl::MockShaderValidator::new()), - } -} - -fn copy_files(files: &str, dest: &TempDir) { - let opts = &dir::CopyOptions::new(); - let files = fs::read_dir(files) - .unwrap() - .map(|e| String::from(e.unwrap().path().to_str().unwrap())) - .collect::>(); - copy_items(&files, dest.path().join("shaders"), opts).unwrap(); -} - -fn copy_to_and_set_root(test_path: &str, server: &mut MinecraftShaderLanguageServer,) -> (Rc, PathBuf) { - let (_tmp_dir, tmp_path) = copy_to_tmp_dir(test_path); - - server.root = tmp_path.clone();//format!("{}{}", "file://", tmp_path); - - (_tmp_dir, tmp_path) -} - -fn copy_to_tmp_dir(test_path: &str) -> (Rc, PathBuf) { - let tmp_dir = Rc::new(TempDir::new("mcshader").unwrap()); - fs::create_dir(tmp_dir.path().join("shaders")).unwrap(); - - copy_files(test_path, &tmp_dir); - - let tmp_clone = tmp_dir.clone(); - let tmp_path = tmp_clone.path().to_str().unwrap(); - - (tmp_dir, tmp_path.into()) -} - -#[allow(deprecated)] -#[test] -fn test_empty_initialize() { - let mut server = new_temp_server(); - - let tmp_dir = TempDir::new("mcshader").unwrap(); - let tmp_path = tmp_dir.path(); - - let initialize_params = InitializeParams { - process_id: None, - root_path: None, - root_uri: Some(Url::from_directory_path(tmp_path.clone()).unwrap()), - client_info: None, - initialization_options: None, - capabilities: ClientCapabilities { - workspace: None, - text_document: None, - experimental: None, - window: None, - general: Option::None, - }, - trace: None, - workspace_folders: None, - locale: Option::None, - }; - - let on_response = |resp: Option| { - assert!(resp.is_some()); - let respu = resp.unwrap(); - match respu.result_or_error { - ResponseResult::Result(_) => {} - ResponseResult::Error(e) => { - panic!("expected ResponseResult::Result(..), got {:?}", e) - } - } - }; - - let completable = MethodCompletable::new(ResponseCompletable::new( - Some(Id::Number(1)), - Box::new(on_response), - )); - server.initialize(initialize_params, completable); - - assert_eq!(server.root, tmp_path); - - assert_eq!(server.graph.borrow().graph.edge_count(), 0); - assert_eq!(server.graph.borrow().graph.node_count(), 0); - - assert_eq!(format!("{:?}", server.wait), "WaitGroup { count: 1 }"); - - server.endpoint.request_shutdown(); -} - -#[allow(deprecated)] -#[test] -fn test_01_initialize() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_tmp_dir("./testdata/01"); - - let initialize_params = InitializeParams { - process_id: None, - root_path: None, - root_uri: Some(Url::from_directory_path(tmp_path.clone()).unwrap()), - client_info: None, - initialization_options: None, - capabilities: ClientCapabilities { - workspace: None, - text_document: None, - experimental: None, - window: None, - general: Option::None, - }, - trace: None, - workspace_folders: None, - locale: Option::None, - }; - - let on_response = |resp: Option| { - assert!(resp.is_some()); - let respu = resp.unwrap(); - match respu.result_or_error { - ResponseResult::Result(_) => {} - ResponseResult::Error(e) => { - panic!("expected ResponseResult::Result(..), got {:?}", e) - } - } - }; - - let completable = MethodCompletable::new(ResponseCompletable::new( - Some(Id::Number(1)), - Box::new(on_response), - )); - server.initialize(initialize_params, completable); - server.endpoint.request_shutdown(); - - // Assert there is one edge between two nodes - assert_eq!(server.graph.borrow().graph.edge_count(), 1); - - let edge = server.graph.borrow().graph.edge_indices().next().unwrap(); - let (node1, node2) = server.graph.borrow().graph.edge_endpoints(edge).unwrap(); - - // Assert the values of the two nodes in the tree - assert_eq!( - server.graph.borrow().graph[node1], - //format!("{:?}/{}/{}", tmp_path, "shaders", "final.fsh") - tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string() - ); - assert_eq!( - server.graph.borrow().graph[node2], - //format!("{:?}/{}/{}", tmp_path, "shaders", "common.glsl") - tmp_path.join("shaders").join("common.glsl").to_str().unwrap().to_string() - ); - - assert_eq!( - server.graph.borrow().graph.edge_weight(edge).unwrap().line, - 2 - ); -} - -#[test] -fn test_05_initialize() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_tmp_dir("./testdata/05"); - - let initialize_params = InitializeParams { - process_id: None, - root_path: None, - root_uri: Some(Url::from_directory_path(tmp_path.clone()).unwrap()), - client_info: None, - initialization_options: None, - capabilities: ClientCapabilities { - workspace: None, - text_document: None, - experimental: None, - window: None, - general: Option::None, - }, - trace: None, - workspace_folders: None, - locale: Option::None, - }; - - let on_response = |resp: Option| { - assert!(resp.is_some()); - let respu = resp.unwrap(); - match respu.result_or_error { - ResponseResult::Result(_) => {} - ResponseResult::Error(e) => { - panic!("expected ResponseResult::Result(..), got {:?}", e) - } - } - }; - - let completable = MethodCompletable::new(ResponseCompletable::new( - Some(Id::Number(1)), - Box::new(on_response), - )); - server.initialize(initialize_params, completable); - server.endpoint.request_shutdown(); - - // Assert there is one edge between two nodes - assert_eq!(server.graph.borrow().graph.edge_count(), 3); - - assert_eq!(server.graph.borrow().graph.node_count(), 4); - - let pairs: HashSet<(PathBuf, PathBuf)> = vec![ - ( - tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string().into(), - tmp_path.join("shaders").join("common.glsl").to_str().unwrap().to_string().into() - ), - ( - tmp_path.join("shaders").join("final.fsh").to_str().unwrap().to_string().into(), - tmp_path.join("shaders").join("test").join("banana.glsl").to_str().unwrap().to_string().into() - ), - ( - tmp_path.join("shaders").join("test").join("banana.glsl").to_str().unwrap().to_string().into(), - tmp_path.join("shaders").join("test").join("burger.glsl").to_str().unwrap().to_string().into() - ) - ].into_iter().collect(); - - for edge in server.graph.borrow().graph.edge_indices() { - let endpoints = server.graph.borrow().graph.edge_endpoints(edge).unwrap(); - let first = server.graph.borrow().get_node(endpoints.0); - let second = server.graph.borrow().get_node(endpoints.1); - let contains = pairs.contains(&(first.clone(), second.clone())); - assert!(contains, "doesn't contain ({:?}, {:?})", first, second); - } -} - -#[test] -fn test_graph_two_connected_nodes() { - let mut graph = graph::CachedStableGraph::new(); - - let idx1 = graph.add_node(&("sample".to_string().into())); - let idx2 = graph.add_node(&("banana".to_string().into())); - graph.add_edge( - idx1, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - - let children = graph.child_node_names(idx1); - assert_eq!(children.len(), 1); - assert_eq!(children[0], Into::::into("banana".to_string())); - - let children = graph.child_node_indexes(idx1); - assert_eq!(children.len(), 1); - assert_eq!(children[0], idx2); - - let parents = graph.parent_node_names(idx1); - assert_eq!(parents.len(), 0); - - let parents = graph.parent_node_names(idx2); - assert_eq!(parents.len(), 1); - assert_eq!(parents[0], Into::::into("sample".to_string())); - - let parents = graph.parent_node_indexes(idx2); - assert_eq!(parents.len(), 1); - assert_eq!(parents[0], idx1); - - let ancestors = graph.collect_root_ancestors(idx2); - assert_eq!(ancestors.len(), 1); - assert_eq!(ancestors[0], idx1); - - let ancestors = graph.collect_root_ancestors(idx1); - assert_eq!(ancestors.len(), 0); - - graph.remove_node(&("sample".to_string().into())); - assert_eq!(graph.graph.node_count(), 1); - assert!(graph.find_node(&("sample".to_string().into())).is_none()); - let neighbors = graph.child_node_names(idx2); - assert_eq!(neighbors.len(), 0); -} - -#[test] -fn test_collect_root_ancestors() { - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx3, - idx1, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - - // 0 3 - // |/ - // 1 - // | - // 2 - - let roots = graph.collect_root_ancestors(idx2); - assert_eq!(roots, vec![idx3, idx0]); - - let roots = graph.collect_root_ancestors(idx1); - assert_eq!(roots, vec![idx3, idx0]); - - let roots = graph.collect_root_ancestors(idx0); - assert_eq!(roots, vec![]); - - let roots = graph.collect_root_ancestors(idx3); - assert_eq!(roots, vec![]); - } - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx0, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - - // 0 - // / \ - // 1 2 - // / - // 3 - - let roots = graph.collect_root_ancestors(idx3); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx2); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx1); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx0); - assert_eq!(roots, vec![]); - } - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx2, - idx3, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - - // 0 - // | - // 1 - // \ - // 2 \ - // \ / - // 3 - - let roots = graph.collect_root_ancestors(idx3); - assert_eq!(roots, vec![idx0, idx2]); - - let roots = graph.collect_root_ancestors(idx2); - assert_eq!(roots, vec![]); - - let roots = graph.collect_root_ancestors(idx1); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx0); - assert_eq!(roots, vec![]); - } - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx2, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 6, - start: 0, - end: 0, - }, - ); - - // 0 - // | - // 1 - // / \ - // 2 3 - - let roots = graph.collect_root_ancestors(idx3); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx2); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx1); - assert_eq!(roots, vec![idx0]); - - let roots = graph.collect_root_ancestors(idx0); - assert_eq!(roots, vec![]); - } -} - -#[test] -fn test_graph_dfs() { - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx0, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - - let dfs = dfs::Dfs::new(&graph, idx0); - - let mut collection = Vec::new(); - - for i in dfs { - assert_that!(&i, ok()); - collection.push(i.unwrap()); - } - - let nodes: Vec = collection.iter().map(|n| n.0).collect(); - let parents: Vec> = collection.iter().map(|n| n.1).collect(); - // 0 - // / \ - // 1 2 - // / - // 3 - let expected_nodes = vec![idx0, idx1, idx3, idx2]; - - assert_eq!(expected_nodes, nodes); - - let expected_parents = vec![None, Some(idx0), Some(idx1), Some(idx0)]; - - assert_eq!(expected_parents, parents); - - assert!(!is_cyclic_directed(&graph.graph)); - } - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - let idx4 = graph.add_node(&("4".to_string().into())); - let idx5 = graph.add_node(&("5".to_string().into())); - let idx6 = graph.add_node(&("6".to_string().into())); - let idx7 = graph.add_node(&("7".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx0, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx4, - IncludePosition { - line: 6, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx2, - idx4, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx2, - idx5, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx3, - idx6, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx4, - idx6, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx6, - idx7, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - - let dfs = dfs::Dfs::new(&graph, idx0); - - let mut collection = Vec::new(); - - for i in dfs { - assert_that!(&i, ok()); - collection.push(i.unwrap()); - } - - let nodes: Vec = collection.iter().map(|n| n.0).collect(); - let parents: Vec> = collection.iter().map(|n| n.1).collect(); - // 0 - // / \ - // 1 2 - // / \ / \ - // 3 4 5 - // \ / - // 6 - 7 - let expected_nodes = vec![ - idx0, idx1, idx3, idx6, idx7, idx4, idx6, idx7, idx2, idx5, idx4, idx6, idx7, - ]; - - assert_eq!(expected_nodes, nodes); - - let expected_parents = vec![ - None, - Some(idx0), - Some(idx1), - Some(idx3), - Some(idx6), - Some(idx1), - Some(idx4), - Some(idx6), - Some(idx0), - Some(idx2), - Some(idx2), - Some(idx4), - Some(idx6), - ]; - - assert_eq!(expected_parents, parents); - - assert!(!is_cyclic_directed(&graph.graph)); - } -} - -#[test] -fn test_graph_dfs_cycle() { - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - let idx2 = graph.add_node(&("2".to_string().into())); - let idx3 = graph.add_node(&("3".to_string().into())); - let idx4 = graph.add_node(&("4".to_string().into())); - let idx5 = graph.add_node(&("5".to_string().into())); - let idx6 = graph.add_node(&("6".to_string().into())); - let idx7 = graph.add_node(&("7".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx0, - idx2, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx3, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx4, - IncludePosition { - line: 6, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx2, - idx4, - IncludePosition { - line: 5, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx2, - idx5, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx3, - idx6, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx4, - idx6, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx6, - idx7, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx7, - idx4, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - - let mut dfs = dfs::Dfs::new(&graph, idx0); - - for _ in 0..5 { - if let Some(i) = dfs.next() { - assert_that!(&i, ok()); - } - } - - // 0 - // / \ - // 1 2 - // / \ / \ - // 3 4 5 - // \ / \ - // 6 - 7 - - assert!(is_cyclic_directed(&graph.graph)); - - let next = dfs.next().unwrap(); - assert_that!(next, err()); - } - { - let mut graph = graph::CachedStableGraph::new(); - - let idx0 = graph.add_node(&("0".to_string().into())); - let idx1 = graph.add_node(&("1".to_string().into())); - - graph.add_edge( - idx0, - idx1, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - graph.add_edge( - idx1, - idx0, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - - let mut dfs = dfs::Dfs::new(&graph, idx1); - - println!("{:?}", dfs.next()); - println!("{:?}", dfs.next()); - println!("{:?}", dfs.next()); - } -} - -#[test] -fn test_generate_merge_list_01() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/01", &mut server); - server.endpoint.request_shutdown(); - - let final_idx = server.graph.borrow_mut() - //.add_node(&format!("{:?}/shaders/final.fsh", tmp_path).try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("final.fsh")); - let common_idx = server.graph.borrow_mut() - //.add_node(&format!("{:?}/shaders/common.glsl", tmp_path).try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("common.glsl")); - - server.graph.borrow_mut().add_edge( - final_idx, - common_idx, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - - let nodes = server.get_dfs_for_node(final_idx).unwrap(); - let sources = server.load_sources(&nodes).unwrap(); - - let graph_borrow = server.graph.borrow(); - let result = merge_views::generate_merge_list(&nodes, &sources, &graph_borrow); - - let merge_file = tmp_path.clone().join( "shaders").join("final.fsh.merge"); - - let mut truth = fs::read_to_string(merge_file).unwrap(); - truth = truth.replacen("!!", &tmp_path.clone().join("shaders").join("common.glsl").to_str().unwrap().replace("\\", "\\\\"), 1); - truth = truth.replace("!!", &tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace("\\", "\\\\")); - - assert_eq!(result, truth); -} - -#[test] -fn test_generate_merge_list_02() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/02", &mut server); - server.endpoint.request_shutdown(); - - let final_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("final.fsh")); - let test_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "test.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("test.glsl")); - let burger_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "burger.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("burger.glsl")); - let sample_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "sample.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("sample.glsl")); - - server.graph.borrow_mut().add_edge( - final_idx, - sample_idx, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - sample_idx, - burger_idx, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - sample_idx, - test_idx, - IncludePosition { - line: 6, - start: 0, - end: 0, - }, - ); - - let nodes = server.get_dfs_for_node(final_idx).unwrap(); - let sources = server.load_sources(&nodes).unwrap(); - - let graph_borrow = server.graph.borrow(); - let result = merge_views::generate_merge_list(&nodes, &sources, &graph_borrow); - - let merge_file = tmp_path.clone().join("shaders").join("final.fsh.merge"); - - let mut truth = fs::read_to_string(merge_file).unwrap(); - - for file in &[ - "sample.glsl", - "burger.glsl", - "sample.glsl", - "test.glsl", - "sample.glsl", - ] { - let path = tmp_path.clone(); - truth = truth.replacen("!!", &&path.join("shaders").join("utils").join(file).to_str().unwrap().replace("\\", "\\\\"), 1); - } - truth = truth.replacen("!!", &&tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace("\\", "\\\\"), 1); - - assert_eq!(result, truth); -} - -#[test] -fn test_generate_merge_list_03() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/03", &mut server); - server.endpoint.request_shutdown(); - - let final_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("final.fsh")); - let test_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "test.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("test.glsl")); - let burger_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "burger.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("burger.glsl")); - let sample_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "sample.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("sample.glsl")); - - server.graph.borrow_mut().add_edge( - final_idx, - sample_idx, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - sample_idx, - burger_idx, - IncludePosition { - line: 4, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - sample_idx, - test_idx, - IncludePosition { - line: 6, - start: 0, - end: 0, - }, - ); - - let nodes = server.get_dfs_for_node(final_idx).unwrap(); - let sources = server.load_sources(&nodes).unwrap(); - - let graph_borrow = server.graph.borrow(); - let result = merge_views::generate_merge_list(&nodes, &sources, &graph_borrow); - - let merge_file = tmp_path.clone().join("shaders").join("final.fsh.merge"); - - let mut truth = fs::read_to_string(merge_file).unwrap(); - - for file in &[ - "sample.glsl", - "burger.glsl", - "sample.glsl", - "test.glsl", - "sample.glsl", - ] { - let path = tmp_path.clone(); - truth = truth.replacen("!!", &&&path.join("shaders").join("utils").join(file).to_str().unwrap().replace("\\", "\\\\"), 1); - } - truth = truth.replacen("!!", &&&tmp_path.join("shaders").join("final.fsh").to_str().unwrap().replace("\\", "\\\\"), 1); - - assert_eq!(result, truth); -} - -#[test] -fn test_generate_merge_list_04() { - let mut server = new_temp_server(); - - let (_tmp_dir, tmp_path) = copy_to_and_set_root("./testdata/04", &mut server); - server.endpoint.request_shutdown(); - - let final_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/{}", tmp_path, "final.fsh").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("final.fsh")); - let utilities_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "utilities.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("utilities.glsl")); - let stuff1_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "stuff1.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("stuff1.glsl")); - let stuff2_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/utils/{}", tmp_path, "stuff2.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("utils").join("stuff2.glsl")); - let matrices_idx = server.graph.borrow_mut() - //.add_node(&format!("{}/shaders/lib/{}", tmp_path, "matrices.glsl").try_into().unwrap()); - .add_node(&tmp_path.join("shaders").join("lib").join("matrices.glsl")); - - server.graph.borrow_mut().add_edge( - final_idx, - utilities_idx, - IncludePosition { - line: 2, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - utilities_idx, - stuff1_idx, - IncludePosition { - line: 0, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - utilities_idx, - stuff2_idx, - IncludePosition { - line: 1, - start: 0, - end: 0, - }, - ); - server.graph.borrow_mut().add_edge( - final_idx, - matrices_idx, - IncludePosition { - line: 3, - start: 0, - end: 0, - }, - ); - - let nodes = server.get_dfs_for_node(final_idx).unwrap(); - let sources = server.load_sources(&nodes).unwrap(); - - let graph_borrow = server.graph.borrow(); - let result = merge_views::generate_merge_list(&nodes, &sources, &graph_borrow); - - let merge_file = tmp_path.clone().join("shaders").join("final.fsh.merge"); - - let mut truth = fs::read_to_string(merge_file).unwrap(); - - for file in &[ - PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), - PathBuf::new().join("utils").join("stuff1.glsl").to_str().unwrap(), - PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), - PathBuf::new().join("utils").join("stuff2.glsl").to_str().unwrap(), - PathBuf::new().join("utils").join("utilities.glsl").to_str().unwrap(), - PathBuf::new().join("final.fsh").to_str().unwrap(), - PathBuf::new().join("lib").join("matrices.glsl").to_str().unwrap(), - PathBuf::new().join("final.fsh").to_str().unwrap() - ] { - let path = tmp_path.clone(); - //path.f - truth = truth.replacen("!!", &path.join("shaders").join(file).to_str().unwrap().replace("\\", "\\\\"), 1); - } - - assert_eq!(result, truth); -} diff --git a/server/testdata/04/final.fsh.merge b/server/testdata/04/final.fsh.merge deleted file mode 100644 index ff93439..0000000 --- a/server/testdata/04/final.fsh.merge +++ /dev/null @@ -1,23 +0,0 @@ -#version 120 - -#line 1 "!!" -#line 1 "!!" -void stuff1() { - -} -#line 2 "!!" -#line 1 "!!" -void stuff2() { - -} -#line 3 "!!" -#line 4 "!!" -#line 1 "!!" -void matrix() { - -} -#line 5 "!!" - -void main() { - -} \ No newline at end of file