diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..2197cb7 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "master", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b7ee6ef --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[Makefile] +indent_style = tab +indent_size = 1 + +[*.md] +trim_trailing_whitespace = false +indent_size = 4 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..551d485 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,8 @@ +coverage +es +lib +dist +node_modules +test +rust +__tests__ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..0baaf37 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,38 @@ +module.exports = { + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + + globals: { + window: true, + document: true, + module: true, + }, + + rules: { + 'no-fallthrough': 0, + 'no-empty': 0, + 'no-param-reassign': 0, + 'no-redeclare': 'off', + 'no-useless-escape': 'off', + 'no-case-declarations': 'off', + 'no-constant-condition': 'off', + '@typescript-eslint/no-duplicate-enum-values': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-shadow': 0, + '@typescript-eslint/no-parameter-properties': 0, + '@typescript-eslint/ban-ts-comment': 0, + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/no-invalid-this': 0, + '@typescript-eslint/no-use-before-define': [ + 'error', + { functions: false, classes: false }, + ], + '@typescript-eslint/no-redeclare': ['error'], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'none', + ignoreRestSiblings: true, + }, + ], + }, +}; diff --git a/.github/----please-use-antv-issue-helper---.md b/.github/----please-use-antv-issue-helper---.md new file mode 100644 index 0000000..68e7766 --- /dev/null +++ b/.github/----please-use-antv-issue-helper---.md @@ -0,0 +1,11 @@ +--- +name: '⚠️ Please use https://antv-issue-helper.surge.sh ⚠️' +about: The issue which is not created via https://antv-issue-helper.surge.sh will be closed immediately. +labels: +--- + +The issue which is not created via will be closed immediately. + +--- + +注意:不是用 创建的 issue 会被立即关闭。 diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..3789c55 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c7f22b1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,53 @@ + + +### 🤔 This is a + +- [ ] New feature +- [ ] Bug fix +- [ ] Site / Document optimization +- [ ] TypeScript definition update +- [ ] Refactoring +- [ ] Performance improvement +- [ ] Code style optimization +- [ ] Test Case +- [ ] Branch merge +- [ ] Other (about what?) + +### 🔗 Related issue link + + + +### 💡 Background and solution + + + +### 📝 Changelog + + + +| Language | Changelog | +| ---------- | --------- | +| 🇺🇸 English | | +| 🇨🇳 Chinese | | + +### ☑️ Self Check before Merge + +- [ ] Doc is updated/provided or not needed +- [ ] Demo is updated/provided or not needed +- [ ] TypeScript definition is updated/provided or not needed +- [ ] Changelog is provided or not needed diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..6cb8175 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: 'CodeQL' + +on: + push: + branches: ['master'] + pull_request: + branches: ['master'] + schedule: + - cron: '35 10 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [javascript] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..920e962 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: 🚀 Lint + +on: ['pull_request'] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + # Python 3.11 和 node-gyp 有兼容问题, 导致无法安装依赖 + # https://github.com/slint-ui/slint/commit/a9c48e33502fdebc36c5aa2f4f516c2218424679#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133dd + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - uses: pnpm/action-setup@v2 + with: + version: 7 + + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 # semantic-release 需要 >= 16 的 Node.js 环境 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Lint + run: pnpm lint diff --git a/.github/workflows/pr-translation.yml b/.github/workflows/pr-translation.yml new file mode 100644 index 0000000..96ba813 --- /dev/null +++ b/.github/workflows/pr-translation.yml @@ -0,0 +1,21 @@ +name: PR Translation +on: + pull_request: + types: [opened] + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + pull_request_review: + types: [submitted, dismissed] +jobs: + translate: + runs-on: ubuntu-latest + steps: + - name: Translate + uses: yhosun/pr-translation-action@v1.0.0 + with: + language-1: 'en' + repo-token: ${{ secrets.GITHUB_TOKEN }} + google-project-id: 'ecstatic-branch-398907' + google-credentials: ${{ secrets.GOOGLE_TRANSLATION_API }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6e3b3aa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,35 @@ +name: 🚀 Auto Release +on: + push: + branches: + - master + +jobs: + release: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - uses: actions/checkout@v3 + + # Python 3.11 和 node-gyp 有兼容问题, 导致无法安装依赖 + # https://github.com/slint-ui/slint/commit/a9c48e33502fdebc36c5aa2f4f516c2218424679#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133dd + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - uses: pnpm/action-setup@v2 + with: + version: 7 + + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..caed77c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: 🚀 Test + +on: [pull_request] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + # Python 3.11 和 node-gyp 有兼容问题, 导致无法安装依赖 + # https://github.com/slint-ui/slint/commit/a9c48e33502fdebc36c5aa2f4f516c2218424679#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133dd + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - uses: pnpm/action-setup@v2 + with: + version: 7 + + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build + + - name: Test + run: pnpm test + + - name: Cov + run: | + pnpm cov + env: + CI: true + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml new file mode 100644 index 0000000..dfe1d8b --- /dev/null +++ b/.github/workflows/version.yml @@ -0,0 +1,38 @@ +name: 🚀 Version +on: + push: + branches: + - release + +jobs: + version: + name: Update Package Version + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + # Python 3.11 和 node-gyp 有兼容问题, 导致无法安装依赖 + # https://github.com/slint-ui/slint/commit/a9c48e33502fdebc36c5aa2f4f516c2218424679#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133dd + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - uses: pnpm/action-setup@v2 + with: + version: 7 + + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Create Release Pull Request + uses: changesets/action@v1 + with: + commit: 'chore(release): bump version' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a53c17f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +es +lib +rust/target \ No newline at end of file diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..0bd658f --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx --no-install commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..36af219 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..3e0b45d --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,17 @@ +{ + "default": true, + "no-inline-html": false, + "line-length": false, + "single-h1": false, + "first-line-h1": false, + "no-empty-links": false, + "no-duplicate-heading": false, + "link-fragments": false, + "code-block-style": false, + "MD003": { + "style": "atx" + }, + "front-matter": { + "type": "yaml" + } +} diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 0000000..cc8fd58 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,2 @@ +node_modules +**/CHANGELOG.md \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b2a42ea --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +es +lib +dist +tsconfig.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..994f89c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "always" +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2f5095b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "editor.formatOnSave": true, + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact" + ], + "typescript.tsdk": "node_modules/typescript/lib", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "svg.preview.background": "dark-transparent" +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d5df37 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# @strawberry-vis/g-device-api + +A set of Device API which implements with WebGL1/2 & WebGPU. + +## Installing + +```bash +npm install @strawberry-vis/g-device-api +``` + +Create a Buffer. + +```js +import { + Device, + BufferUsage, + WebGLDeviceContribution, +} from '@strawberry-vis/g-device-api'; + +const deviceContribution = new WebGLDeviceContribution({ + targets: ['webgl1'], +}); + +const swapChain = await deviceContribution.createSwapChain($canvas); +swapChain.configureSwapChain(width, height); +const device = swapChain.getDevice(); + +device.createBuffer({ + viewOrSize: 8, + usage: BufferUsage.VERTEX, +}); +``` + +## API Reference diff --git a/__tests__/buffer.spec.ts b/__tests__/buffer.spec.ts new file mode 100644 index 0000000..89b8b2f --- /dev/null +++ b/__tests__/buffer.spec.ts @@ -0,0 +1,57 @@ +import { + Device, + BufferUsage, + ResourceType, + WebGLDeviceContribution, + GL, +} from '../src'; +import _gl from 'gl'; +import { Buffer_GL } from '../src/webgl/Buffer'; + +let device: Device; +describe('Buffer', () => { + beforeAll(async () => { + const deviceContribution = new WebGLDeviceContribution({ + targets: ['webgl1'], + }); + + const width = 100; + const height = 100; + const gl = _gl(width, height, { + antialias: false, + preserveDrawingBuffer: true, + stencil: true, + }); + const mockCanvas: HTMLCanvasElement = { + width, + height, + // @ts-ignore + getContext: () => { + // @ts-ignore + gl.canvas = mockCanvas; + // 模拟 DOM API,返回小程序 context,它应当和 CanvasRenderingContext2D 一致 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext + return gl; + }, + }; + // create swap chain and get device + const swapChain = await deviceContribution.createSwapChain(mockCanvas); + swapChain.configureSwapChain(width, height); + device = swapChain.getDevice(); + }); + + afterAll(() => { + device.destroy(); + }); + + it('should create Vertex WebGLBuffer correctly.', () => { + const buffer = device.createBuffer({ + viewOrSize: 8, + usage: BufferUsage.VERTEX, + }) as Buffer_GL; + expect(buffer.type).toBe(ResourceType.Buffer); + expect(buffer.byteSize).toBe(8); + expect(buffer.gl_target).toBe(GL.ARRAY_BUFFER); + expect(buffer.gl_buffer_pages.length).toBe(1); + }); +}); diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..478195d --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,11 @@ +module.exports = { + extends: ['@commitlint/config-angular'], + rules: { + 'type-enum': [ + 2, + 'always', + ['build', 'ci', 'docs', 'site', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'chore'], + ], + 'header-max-length': [2, 'always', 100], + }, +}; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..80dfb23 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,24 @@ +module.exports = { + testTimeout: 100000, + testMatch: ['/__tests__/*.spec.+(ts|tsx|js)'], + preset: 'ts-jest', + moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], + modulePathIgnorePatterns: ['dist'], + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + isolatedModules: true, + tsconfig: { + allowJs: true, + target: 'esnext', + esModuleInterop: true, + }, + }, + ], + }, + transformIgnorePatterns: [ + // @see https://stackoverflow.com/a/69179139 + '/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates)', + ], +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..6bc50a8 --- /dev/null +++ b/package.json @@ -0,0 +1,93 @@ +{ + "name": "@strawberry-vis/g-device-api", + "version": "0.0.1", + "description": "A G plugin of renderer implementation with GPUDevice", + "keywords": [ + "antv", + "g" + ], + "repository": { + "type": "git", + "url": "https://github.com/strawberry-vis/g-device-api" + }, + "license": "MIT", + "author": { + "name": "xiaoiver", + "url": "https://github.com/xiaoiver" + }, + "exports": { + "types": "./es/index.d.ts", + "import": "./es/index.js", + "default": "./lib/index.js" + }, + "main": "lib/index.js", + "module": "es/index.js", + "types": "es/index.d.ts", + "files": [ + "lib", + "es" + ], + "scripts": { + "dev": "vite dev", + "build": "npm run build:lib && npm run build:es", + "build:lib": "rm -rf lib && tsc --module commonjs --outDir lib", + "build:es": "rm -rf es && tsc --module esnext --outDir es", + "eslint": "eslint --ext .ts,.js ./src --quiet", + "eslint-fix": "eslint --fix --ext .ts,.js ./src", + "lint": "npm run eslint", + "lint-staged": "lint-staged", + "prepare": "husky install", + "prepublishOnly": "npm run build", + "changeset": "changeset", + "version": "changeset version", + "release": "changeset publish", + "test": "jest", + "wasm": "wasm-pack build ./rust --target web" + }, + "sideEffects": false, + "dependencies": { + "@antv/util": "^3.3.4", + "@webgpu/types": "^0.1.6", + "eventemitter3": "^5.0.1", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + }, + "devDependencies": { + "@commitlint/cli": "^8.3.6", + "@commitlint/config-angular": "^9.1.2", + "@changesets/cli": "^2.26.2", + "@types/gl": "^6.0.2", + "@types/jest": "^26.0.24", + "@types/offscreencanvas": "^2019.6.4", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "case-police": "^0.5.10", + "eslint": "^7.32.0", + "eslint-plugin-jest": "24.3.6", + "gl": "^6.0.2", + "husky": "^7.0.4", + "jest": "^29.0.0", + "lint-staged": "^10.5.4", + "markdownlint-cli": "^0.32.2", + "prettier": "^2.8.8", + "ts-jest": "^29.1.0", + "typescript": "^5.2.2", + "vite": "^4.4.9" + }, + "lint-staged": { + "*.{md,json}": [ + "prettier --write" + ], + "*.md": [ + "markdownlint --fix", + "case-police --fix", + "prettier --write" + ], + "*.{js,jsx,tsx,ts,vue}": [ + "eslint --fix" + ] + }, + "publishConfig": { + "access": "public" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..6ac8e0a --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,6584 @@ +lockfileVersion: '6.0' + +dependencies: + '@antv/util': + specifier: ^3.3.4 + version: 3.3.4 + '@webgpu/types': + specifier: ^0.1.6 + version: 0.1.6 + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 + gl-matrix: + specifier: ^3.4.3 + version: 3.4.3 + tslib: + specifier: ^2.5.3 + version: 2.5.3 + +devDependencies: + '@changesets/cli': + specifier: ^2.26.2 + version: 2.26.2 + '@commitlint/cli': + specifier: ^8.3.6 + version: 8.3.6 + '@commitlint/config-angular': + specifier: ^9.1.2 + version: 9.1.2 + '@types/gl': + specifier: ^6.0.2 + version: 6.0.2 + '@types/jest': + specifier: ^26.0.24 + version: 26.0.24 + '@types/offscreencanvas': + specifier: ^2019.6.4 + version: 2019.6.4 + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.0.0(eslint@7.32.0)(typescript@5.2.2) + case-police: + specifier: ^0.5.10 + version: 0.5.10 + eslint: + specifier: ^7.32.0 + version: 7.32.0 + eslint-plugin-jest: + specifier: 24.3.6 + version: 24.3.6(@typescript-eslint/eslint-plugin@6.0.0)(eslint@7.32.0)(typescript@5.2.2) + gl: + specifier: ^6.0.2 + version: 6.0.2 + husky: + specifier: ^7.0.4 + version: 7.0.4 + jest: + specifier: ^29.0.0 + version: 29.0.0 + lint-staged: + specifier: ^10.5.4 + version: 10.5.4 + markdownlint-cli: + specifier: ^0.32.2 + version: 0.32.2 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + ts-jest: + specifier: ^29.1.0 + version: 29.1.0(@babel/core@7.22.17)(jest@29.0.0)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + vite: + specifier: ^4.4.9 + version: 4.4.9 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@antv/util@3.3.4: + resolution: {integrity: sha512-NGRjPCPje8GIC14Ye7sjebamFIjxoZ+mCIqfXz6wD/M6fA9SgJivzmLB3Ry01Wq8PI36oOVv9BwrAGV1JD8vjA==} + dependencies: + fast-deep-equal: 3.1.3 + gl-matrix: 3.4.3 + tslib: 2.5.3 + dev: false + + /@babel/code-frame@7.12.11: + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} + dependencies: + '@babel/highlight': 7.22.13 + dev: true + + /@babel/code-frame@7.22.13: + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.13 + chalk: 2.4.2 + dev: true + + /@babel/compat-data@7.22.9: + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.22.17: + resolution: {integrity: sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.15 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.22.17(@babel/core@7.22.17) + '@babel/helpers': 7.22.15 + '@babel/parser': 7.22.16 + '@babel/template': 7.22.15 + '@babel/traverse': 7.22.17 + '@babel/types': 7.22.17 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.22.15: + resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.17 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.22.17 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@babel/helper-module-transforms@7.22.17(@babel/core@7.22.17): + resolution: {integrity: sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.15 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.15: + resolution: {integrity: sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.22.15: + resolution: {integrity: sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.22.17 + '@babel/types': 7.22.17 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.22.13: + resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.15 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.22.16: + resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.17): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.17): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.17): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.17): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.17): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.17): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.17): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.17): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.17): + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.17 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/runtime@7.22.15: + resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: true + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.22.16 + '@babel/types': 7.22.17 + dev: true + + /@babel/traverse@7.22.17: + resolution: {integrity: sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.15 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.16 + '@babel/types': 7.22.17 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.22.17: + resolution: {integrity: sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.15 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@changesets/apply-release-plan@6.1.4: + resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/config': 2.3.1 + '@changesets/get-version-range-type': 0.3.2 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.5.4 + dev: true + + /@changesets/assemble-release-plan@5.2.4: + resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + semver: 7.5.4 + dev: true + + /@changesets/changelog-git@0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + dependencies: + '@changesets/types': 5.2.1 + dev: true + + /@changesets/cli@2.26.2: + resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} + hasBin: true + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/apply-release-plan': 6.1.4 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/changelog-git': 0.1.14 + '@changesets/config': 2.3.1 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/get-release-plan': 3.0.17 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@changesets/write': 0.2.3 + '@manypkg/get-packages': 1.1.3 + '@types/is-ci': 3.0.0 + '@types/semver': 7.5.1 + ansi-colors: 4.1.3 + chalk: 2.4.2 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + is-ci: 3.0.1 + meow: 6.1.1 + outdent: 0.5.0 + p-limit: 2.3.0 + preferred-pm: 3.1.2 + resolve-from: 5.0.0 + semver: 7.5.4 + spawndamnit: 2.0.0 + term-size: 2.2.1 + tty-table: 4.2.1 + dev: true + + /@changesets/config@2.3.1: + resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} + dependencies: + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/logger': 0.0.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 + dev: true + + /@changesets/errors@0.1.4: + resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + dependencies: + extendable-error: 0.1.7 + dev: true + + /@changesets/get-dependents-graph@1.3.6: + resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} + dependencies: + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + chalk: 2.4.2 + fs-extra: 7.0.1 + semver: 7.5.4 + dev: true + + /@changesets/get-release-plan@3.0.17: + resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/config': 2.3.1 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + dev: true + + /@changesets/get-version-range-type@0.3.2: + resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + dev: true + + /@changesets/git@2.0.0: + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + dev: true + + /@changesets/logger@0.0.5: + resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + dependencies: + chalk: 2.4.2 + dev: true + + /@changesets/parse@0.3.16: + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + dependencies: + '@changesets/types': 5.2.1 + js-yaml: 3.14.1 + dev: true + + /@changesets/pre@1.0.14: + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: true + + /@changesets/read@0.5.9: + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/parse': 0.3.16 + '@changesets/types': 5.2.1 + chalk: 2.4.2 + fs-extra: 7.0.1 + p-filter: 2.1.0 + dev: true + + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + dev: true + + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + dev: true + + /@changesets/write@0.2.3: + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/types': 5.2.1 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + dev: true + + /@commitlint/cli@8.3.6: + resolution: {integrity: sha512-fg8p9/ZrzhUPIXBGrpzwKu50WT13jYS5OffYlkStPuemuv0GjXu37B8J/zNgu6UhrdBVHbmBR0LriKAzRLG/4g==} + engines: {node: '>=4'} + hasBin: true + dependencies: + '@commitlint/format': 8.3.6 + '@commitlint/lint': 8.3.6 + '@commitlint/load': 8.3.6 + '@commitlint/read': 8.3.6 + babel-polyfill: 6.26.0 + chalk: 2.4.2 + get-stdin: 7.0.0 + lodash: 4.17.21 + meow: 5.0.0 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + dev: true + + /@commitlint/config-angular-type-enum@9.1.2: + resolution: {integrity: sha512-vPdAnL1GbSKbbMhzAgCknQqCwafhjWI9GKnbNgY6MKcXJEvND/OyufUvxyyiews1blenGJupufZ8JrY5qbJwtQ==} + engines: {node: '>=v8.17.0'} + dev: true + + /@commitlint/config-angular@9.1.2: + resolution: {integrity: sha512-zIO26glOlUjFnOiqxBl4fX1p6NYqWzx4OVf56LvrVP4vtrE5z0r/De93iqHLhmx9mBCh8HCUhGjYHR7SkqdepQ==} + engines: {node: '>=v8.17.0'} + dependencies: + '@commitlint/config-angular-type-enum': 9.1.2 + dev: true + + /@commitlint/ensure@8.3.6: + resolution: {integrity: sha512-UUipnA7sX3OSUW39pi4Etf7pKrG76uM33ybs5YTEOZbT6zb3aKUS+A1ygo52eX+tqpxCiV+6qSy5qEKG8c1aeA==} + engines: {node: '>=4'} + dependencies: + lodash: 4.17.21 + dev: true + + /@commitlint/execute-rule@8.3.6: + resolution: {integrity: sha512-kCcf+33LgFBZcVKzTRX7QZBiznFjzjgpyEXFjGsWgCeOXi1q3KPdwH9HvH22xpFZ4+n4lAuv/kQf5XUQMO2OGQ==} + engines: {node: '>=4'} + dev: true + + /@commitlint/format@8.3.6: + resolution: {integrity: sha512-VN9Yq3cJoonLjeoYiTOidsxGM6lwyzcw6ekQCCIzjNbJa+7teTPE2wDSXqhbsF/0XDJUeHcygzgZwv4/lzStTA==} + engines: {node: '>=4'} + dependencies: + chalk: 2.4.2 + dev: true + + /@commitlint/is-ignored@8.3.6: + resolution: {integrity: sha512-wxQImxePfAfIz9C2nWzebs0KUU9MiO8bWsRKNsAk9jknc+bjsre9Lje0sr6jvE840XZSTX/aaXY2g+Mt+9oq+w==} + engines: {node: '>=4'} + dependencies: + semver: 6.3.0 + dev: true + + /@commitlint/lint@8.3.6: + resolution: {integrity: sha512-M/tysLho4KdsXJp7J7q/c1WEb3Dh75cm86eb0buci8C/DOIegLq/B3DE/8dhxOzGElUW/iq55MyWttJ/MRwKsg==} + engines: {node: '>=4'} + dependencies: + '@commitlint/is-ignored': 8.3.6 + '@commitlint/parse': 8.3.6 + '@commitlint/rules': 8.3.6 + babel-runtime: 6.26.0 + lodash: 4.17.21 + dev: true + + /@commitlint/load@8.3.6: + resolution: {integrity: sha512-bqqGg89KnfauJ01GrVBgKyWBXYy2UXmLvRGuepyI1HsNVaEIGBz6R+sTvk3K55Str6soF7HRpl6bDCmnEOVJtA==} + engines: {node: '>=4'} + dependencies: + '@commitlint/execute-rule': 8.3.6 + '@commitlint/resolve-extends': 8.3.6 + babel-runtime: 6.26.0 + chalk: 2.4.2 + cosmiconfig: 5.2.1 + lodash: 4.17.21 + resolve-from: 5.0.0 + dev: true + + /@commitlint/message@8.3.6: + resolution: {integrity: sha512-x30GmsyZTk+QV4o5TRrDkZQm7uRumlKu+7yWeRdSAXyUgi9amsdMFJ8VbAoRsBndOAtEUkaXgK8dvvmgvW3kwg==} + engines: {node: '>=4'} + dev: true + + /@commitlint/parse@8.3.6: + resolution: {integrity: sha512-wL6Z5hZpT8i/3LMwP/CxTMPMU3v4blAbSA8QGPCruFHFtAV8hIiXvD1CNOhyeeuG29GAapopLgNJjtigzlN3kg==} + engines: {node: '>=4'} + dependencies: + conventional-changelog-angular: 1.6.6 + conventional-commits-parser: 3.2.4 + lodash: 4.17.21 + dev: true + + /@commitlint/read@8.3.6: + resolution: {integrity: sha512-ixlvPQO8AGFjE5U4DBwJIZtzIqmGeZKhpNjjuAyTwWfMURpXjv+/pVvq/AY3LvxHJM64DuQp2WqrbwJU6mXvUQ==} + engines: {node: '>=4'} + dependencies: + '@commitlint/top-level': 8.3.6 + '@marionebl/sander': 0.6.1 + babel-runtime: 6.26.0 + git-raw-commits: 2.0.11 + dev: true + + /@commitlint/resolve-extends@8.3.6: + resolution: {integrity: sha512-L0/UOBxc3wiA3gzyE8pN9Yunb6FS/2ZDCjieNH0XAgdF2ac5SHh056QE6aQwP7CSCYNEo2+SXxVZr/WOshsQHg==} + engines: {node: '>=4'} + dependencies: + import-fresh: 3.3.0 + lodash: 4.17.21 + resolve-from: 5.0.0 + resolve-global: 1.0.0 + dev: true + + /@commitlint/rules@8.3.6: + resolution: {integrity: sha512-NmEAWAW0f5Nda7ZJ11vd73PqOt57GvLc1SOfoUKolCC3lSJACj9SCTbfkQh8cEMlLmDpNqaGaVHH1jMYXMqU3g==} + engines: {node: '>=4'} + dependencies: + '@commitlint/ensure': 8.3.6 + '@commitlint/message': 8.3.6 + '@commitlint/to-lines': 8.3.6 + babel-runtime: 6.26.0 + dev: true + + /@commitlint/to-lines@8.3.6: + resolution: {integrity: sha512-4g26G37oh5dABVaRGALdlinjQ/wl8b4HTczLwXLKLM0iHHYFu2A1ZwiVJ8avQk/zThw86/HD6zOgGMNPoamjIQ==} + engines: {node: '>=4'} + dev: true + + /@commitlint/top-level@8.3.6: + resolution: {integrity: sha512-2XG5NhGgEZaFJChCkSTa6wXWYbJqb9DubC6aRuD/cOeHdYh2OYrXT8z0IorN+gR5+MWqdUtIHhRYtz2Xb75gNg==} + engines: {node: '>=4'} + dependencies: + find-up: 4.1.0 + dev: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@7.32.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 7.32.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.8.1: + resolution: {integrity: sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@0.4.3: + resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 7.3.1 + globals: 13.21.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + js-yaml: 3.14.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/config-array@0.5.0: + resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@29.7.0: + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/core@29.7.0: + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@12.20.55) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /@jest/environment@29.7.0: + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-mock: 29.7.0 + dev: true + + /@jest/expect-utils@29.7.0: + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + dev: true + + /@jest/expect@29.7.0: + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@29.7.0: + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 12.20.55 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /@jest/globals@29.7.0: + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@29.7.0: + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.19 + '@types/node': 12.20.55 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 6.0.0 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@29.7.0: + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@29.7.0: + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/transform@29.7.0: + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.17 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.19 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@26.6.2: + resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 12.20.55 + '@types/yargs': 15.0.15 + chalk: 4.1.2 + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 12.20.55 + '@types/yargs': 17.0.24 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + dependencies: + '@babel/runtime': 7.22.15 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: true + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + dependencies: + '@babel/runtime': 7.22.15 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: true + + /@marionebl/sander@0.6.1: + resolution: {integrity: sha512-7f3zZddAk92G1opoX/glbDO6YbrzmMAJAw0RJAcvunnV7sR4L9llyBUAABptKoF1Jf37UQ1QTJy5p2H4J4rBNA==} + dependencies: + graceful-fs: 4.2.11 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@npmcli/fs@3.1.0: + resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + semver: 7.5.4 + dev: true + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.0 + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: true + + /@types/babel__core@7.20.1: + resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} + dependencies: + '@babel/parser': 7.22.16 + '@babel/types': 7.22.17 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.20.1 + dev: true + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.22.16 + '@babel/types': 7.22.17 + dev: true + + /@types/babel__traverse@7.20.1: + resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} + dependencies: + '@babel/types': 7.22.17 + dev: true + + /@types/gl@6.0.2: + resolution: {integrity: sha512-5vlkHzpu25w2zJ6i41rYbglH3sSTvkFPi34J5p/kYhlS3hF31GaDGWif1jSiKSy8+UCuFlejXPya0hkLKIn++A==} + dev: true + + /@types/graceful-fs@4.1.6: + resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} + dependencies: + '@types/node': 12.20.55 + dev: true + + /@types/is-ci@3.0.0: + resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} + dependencies: + ci-info: 3.8.0 + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report@3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports@3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/jest@26.0.24: + resolution: {integrity: sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==} + dependencies: + jest-diff: 26.6.2 + pretty-format: 26.6.2 + dev: true + + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + dev: true + + /@types/minimist@1.2.2: + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + dev: true + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: true + + /@types/normalize-package-data@2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + + /@types/offscreencanvas@2019.6.4: + resolution: {integrity: sha512-u8SAgdZ8ROtkTF+mfZGOscl0or6BSj9A4g37e6nvxDc+YB/oDut0wHkK2PBBiC2bNR8TS0CPV+1gAk4fNisr1Q==} + dev: true + + /@types/parse-json@4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: true + + /@types/semver@7.5.1: + resolution: {integrity: sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==} + dev: true + + /@types/stack-utils@2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + + /@types/yargs-parser@21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs@15.0.15: + resolution: {integrity: sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@types/yargs@17.0.24: + resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.8.1 + '@typescript-eslint/parser': 6.0.0(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.0.0 + '@typescript-eslint/type-utils': 6.0.0(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.0.0(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.0.0 + debug: 4.3.4 + eslint: 7.32.0 + grapheme-splitter: 1.0.4 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + natural-compare-lite: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/experimental-utils@4.33.0(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: '*' + dependencies: + '@types/json-schema': 7.0.12 + '@typescript-eslint/scope-manager': 4.33.0 + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.2.2) + eslint: 7.32.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0(eslint@7.32.0) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/parser@6.0.0(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.0.0 + '@typescript-eslint/types': 6.0.0 + '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.0.0 + debug: 4.3.4 + eslint: 7.32.0 + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@4.33.0: + resolution: {integrity: sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dependencies: + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/visitor-keys': 4.33.0 + dev: true + + /@typescript-eslint/scope-manager@6.0.0: + resolution: {integrity: sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.0.0 + '@typescript-eslint/visitor-keys': 6.0.0 + dev: true + + /@typescript-eslint/type-utils@6.0.0(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.0.0(eslint@7.32.0)(typescript@5.2.2) + debug: 4.3.4 + eslint: 7.32.0 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@4.33.0: + resolution: {integrity: sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dev: true + + /@typescript-eslint/types@6.0.0: + resolution: {integrity: sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@4.33.0(typescript@5.2.2): + resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/visitor-keys': 4.33.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree@6.0.0(typescript@5.2.2): + resolution: {integrity: sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.0.0 + '@typescript-eslint/visitor-keys': 6.0.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@6.0.0(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@7.32.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.1 + '@typescript-eslint/scope-manager': 6.0.0 + '@typescript-eslint/types': 6.0.0 + '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.2.2) + eslint: 7.32.0 + eslint-scope: 5.1.1 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@4.33.0: + resolution: {integrity: sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dependencies: + '@typescript-eslint/types': 4.33.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /@typescript-eslint/visitor-keys@6.0.0: + resolution: {integrity: sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.0.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@webgpu/types@0.1.6: + resolution: {integrity: sha512-5c3ZxNmGwVhTo8nW0b0iEaSVLTx89D056c7JzbzC2f9J+qebRM+U9rH52q9Z/HwZbZQTUAYX5UGp0c4BNv61Ew==} + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-jsx@5.3.2(acorn@7.4.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 7.4.1 + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: true + + /are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + + /array-find-index@1.0.2: + resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} + engines: {node: '>=0.10.0'} + dev: true + + /array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + es-shim-unscopables: 1.0.0 + dev: true + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + get-intrinsic: 1.2.1 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + + /arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /babel-jest@29.7.0(@babel/core@7.22.17): + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.22.17 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.1 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.22.17) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.22.5 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.22.17 + '@types/babel__core': 7.20.1 + '@types/babel__traverse': 7.20.1 + dev: true + + /babel-polyfill@6.26.0: + resolution: {integrity: sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==} + dependencies: + babel-runtime: 6.26.0 + core-js: 2.6.12 + regenerator-runtime: 0.10.5 + dev: true + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.17): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.17 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.17) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.17) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.17) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.17) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.17) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.17) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.17) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.22.17): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.17 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.17) + dev: true + + /babel-runtime@6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + dependencies: + is-windows: 1.0.2 + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /bit-twiddle@1.0.2: + resolution: {integrity: sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==} + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /breakword@1.0.6: + resolution: {integrity: sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==} + dependencies: + wcwidth: 1.0.1 + dev: true + + /browserslist@4.21.10: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001534 + electron-to-chromium: 1.4.520 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.10) + dev: true + + /bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + '@npmcli/fs': 3.1.0 + fs-minipass: 3.0.3 + glob: 10.3.4 + lru-cache: 7.18.3 + minipass: 7.0.3 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.5 + tar: 6.2.0 + unique-filename: 3.0.0 + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /caller-callsite@2.0.0: + resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} + engines: {node: '>=4'} + dependencies: + callsites: 2.0.0 + dev: true + + /caller-path@2.0.0: + resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==} + engines: {node: '>=4'} + dependencies: + caller-callsite: 2.0.0 + dev: true + + /callsites@2.0.0: + resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} + engines: {node: '>=4'} + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-keys@4.2.0: + resolution: {integrity: sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==} + engines: {node: '>=4'} + dependencies: + camelcase: 4.1.0 + map-obj: 2.0.0 + quick-lru: 1.1.0 + dev: true + + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: true + + /camelcase@4.1.0: + resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} + engines: {node: '>=4'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001534: + resolution: {integrity: sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==} + dev: true + + /case-police@0.5.10: + resolution: {integrity: sha512-TCfzHZhQ4n6mfDIfN7si8US5KWilP7onSs8Y7Y0ki5h82ery9q9TJhfXYk6rIynr5kLuyCXCC13TWM0Qu0RtUw==} + hasBin: true + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + dev: true + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + + /commander@9.4.1: + resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /compare-func@1.3.4: + resolution: {integrity: sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==} + dependencies: + array-ify: 1.0.0 + dot-prop: 3.0.0 + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: true + + /conventional-changelog-angular@1.6.6: + resolution: {integrity: sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==} + dependencies: + compare-func: 1.3.4 + q: 1.5.1 + dev: true + + /conventional-commits-parser@3.2.4: + resolution: {integrity: sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==} + engines: {node: '>=10'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + is-text-path: 1.0.1 + lodash: 4.17.21 + meow: 8.1.2 + split2: 3.2.2 + through2: 4.0.2 + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cosmiconfig@5.2.1: + resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} + engines: {node: '>=4'} + dependencies: + import-fresh: 2.0.0 + is-directory: 0.3.1 + js-yaml: 3.14.1 + parse-json: 4.0.0 + dev: true + + /cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@12.20.55) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /csv-generate@3.4.3: + resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} + dev: true + + /csv-parse@4.16.3: + resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + dev: true + + /csv-stringify@5.6.5: + resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + dev: true + + /csv@5.5.3: + resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} + engines: {node: '>= 0.1.90'} + dependencies: + csv-generate: 3.4.3 + csv-parse: 4.16.3 + csv-stringify: 5.6.5 + stream-transform: 2.1.3 + dev: true + + /currently-unhandled@0.4.1: + resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} + engines: {node: '>=0.10.0'} + dependencies: + array-find-index: 1.0.2 + dev: true + + /dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: true + + /dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + + /dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /define-data-property@1.0.1: + resolution: {integrity: sha512-22M+6zEspQHx10bfFQl2ET39IvfuQ7+rZIH7+ard8fCC4hPmkOSy+8JhKxBRLaWUziJ0O63NTYT97LR8zUfPTw==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.0.1 + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff-sequences@26.6.2: + resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==} + engines: {node: '>= 10.14.2'} + dev: true + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dot-prop@3.0.0: + resolution: {integrity: sha512-k4ELWeEU3uCcwub7+dWydqQBRjAjkV9L33HjVRG5Xo2QybI6ja/v+4W73SRi8ubCqJz0l9XsTP1NbewfyqaSlw==} + engines: {node: '>=0.10.0'} + dependencies: + is-obj: 1.0.1 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /electron-to-chromium@1.4.520: + resolution: {integrity: sha512-Frfus2VpYADsrh1lB3v/ft/WVFlVzOIm+Q0p7U7VqHI6qr7NWHYKe+Wif3W50n7JAFoBsWVsoU0+qDks6WQ60g==} + dev: true + + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + requiresBuild: true + dependencies: + iconv-lite: 0.6.3 + dev: true + optional: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + dev: true + + /entities@3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.22.1: + resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.11 + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-plugin-jest@24.3.6(@typescript-eslint/eslint-plugin@6.0.0)(eslint@7.32.0)(typescript@5.2.2): + resolution: {integrity: sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==} + engines: {node: '>=10'} + peerDependencies: + '@typescript-eslint/eslint-plugin': '>= 4' + eslint: '>=5' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@7.32.0)(typescript@5.2.2) + '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.2.2) + eslint: 7.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils@3.0.0(eslint@7.32.0): + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 7.32.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@7.32.0: + resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} + engines: {node: ^10.12.0 || >=12.0.0} + hasBin: true + dependencies: + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.3 + '@humanwhocodes/config-array': 0.5.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + enquirer: 2.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 13.21.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.5.4 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 6.8.1 + text-table: 0.2.0 + v8-compile-cache: 2.4.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: false + + /execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: true + + /expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + dev: true + + /exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + dev: true + + /extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.1.0 + dev: true + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + dependencies: + locate-path: 2.0.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + dependencies: + micromatch: 4.0.5 + pkg-dir: 4.2.0 + dev: true + + /flat-cache@3.1.0: + resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} + engines: {node: '>=12.0.0'} + dependencies: + flatted: 3.2.7 + keyv: 4.5.3 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + minipass: 7.0.3 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + functions-have-names: 1.2.3 + dev: true + + /functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + + /get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stdin@7.0.0: + resolution: {integrity: sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==} + engines: {node: '>=8'} + dev: true + + /get-stdin@9.0.0: + resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} + engines: {node: '>=12'} + dev: true + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + + /git-raw-commits@2.0.11: + resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + dargs: 7.0.0 + lodash: 4.17.21 + meow: 8.1.2 + split2: 3.2.2 + through2: 4.0.2 + dev: true + + /github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + dev: true + + /gl-matrix@3.4.3: + resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==} + dev: false + + /gl@6.0.2: + resolution: {integrity: sha512-yBbfpChOtFvg5D+KtMaBFvj6yt3vUnheNAH+UrQH2TfDB8kr0tERdL0Tjhe0W7xJ6jR6ftQBluTZR9jXUnKe8g==} + engines: {node: '>=14.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + bit-twiddle: 1.0.2 + glsl-tokenizer: 2.1.5 + nan: 2.18.0 + node-abi: 3.47.0 + node-gyp: 9.4.0 + prebuild-install: 7.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@10.3.4: + resolution: {integrity: sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.3 + minimatch: 9.0.3 + minipass: 7.0.3 + path-scurry: 1.10.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@8.0.3: + resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + + /global-dirs@0.1.1: + resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} + engines: {node: '>=4'} + dependencies: + ini: 1.3.8 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /glsl-tokenizer@2.1.5: + resolution: {integrity: sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==} + dependencies: + through2: 0.6.5 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + dependencies: + lru-cache: 6.0.0 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: true + + /http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + dev: true + + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: true + + /husky@7.0.4: + resolution: {integrity: sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==} + engines: {node: '>=12'} + hasBin: true + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + optional: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@2.0.0: + resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} + engines: {node: '>=4'} + dependencies: + caller-path: 2.0.0 + resolve-from: 3.0.0 + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@3.2.0: + resolution: {integrity: sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==} + engines: {node: '>=4'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /ini@3.0.1: + resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dev: true + + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + dependencies: + ci-info: 3.8.0 + dev: true + + /is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-directory@0.3.1: + resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + dependencies: + better-path-resolve: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-text-path@1.0.1: + resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} + engines: {node: '>=0.10.0'} + dependencies: + text-extensions: 1.9.0 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.11 + dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.22.17 + '@babel/parser': 7.22.16 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument@6.0.0: + resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.22.17 + '@babel/parser': 7.22.16 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jackspeak@2.3.3: + resolution: {integrity: sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + dev: true + + /jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.1 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.0.3 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0 + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@12.20.55) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-config@29.7.0(@types/node@12.20.55): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.22.17 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + babel-jest: 29.7.0(@babel/core@7.22.17) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-diff@26.6.2: + resolution: {integrity: sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==} + engines: {node: '>= 10.14.2'} + dependencies: + chalk: 4.1.2 + diff-sequences: 26.6.2 + jest-get-type: 26.3.0 + pretty-format: 26.6.2 + dev: true + + /jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + dev: true + + /jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /jest-get-type@26.3.0: + resolution: {integrity: sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==} + engines: {node: '>= 10.14.2'} + dev: true + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.6 + '@types/node': 12.20.55 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.22.13 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-util: 29.7.0 + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.7.0 + dev: true + + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.4 + resolve.exports: 2.0.2 + slash: 3.0.0 + dev: true + + /jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.17 + '@babel/generator': 7.22.15 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.17) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.17) + '@babel/types': 7.22.17 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.17) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + ci-info: 3.8.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + dev: true + + /jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + dev: true + + /jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 12.20.55 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@29.0.0: + resolution: {integrity: sha512-9uz4Tclskb8WrfRXqu66FsFCFoyYctwWXpruKwnD95FZqkyoEAA1oGH53HUn7nQx7uEgZTKdNl/Yo6DqqU+XMg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-parser@3.1.0: + resolution: {integrity: sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==} + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /keyv@4.5.3: + resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /linkify-it@4.0.1: + resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + dependencies: + uc.micro: 1.0.6 + dev: true + + /lint-staged@10.5.4: + resolution: {integrity: sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==} + hasBin: true + dependencies: + chalk: 4.1.2 + cli-truncate: 2.1.0 + commander: 6.2.1 + cosmiconfig: 7.1.0 + debug: 4.3.4 + dedent: 0.7.0 + enquirer: 2.4.1 + execa: 4.1.0 + listr2: 3.14.0(enquirer@2.4.1) + log-symbols: 4.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + please-upgrade-node: 3.2.0 + string-argv: 0.3.1 + stringify-object: 3.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /listr2@3.14.0(enquirer@2.4.1): + resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + enquirer: 2.4.1 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.0 + rxjs: 7.8.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + + /locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /loud-rejection@1.6.0: + resolution: {integrity: sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==} + engines: {node: '>=0.10.0'} + dependencies: + currently-unhandled: 0.4.1 + signal-exit: 3.0.7 + dev: true + + /lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + agentkeepalive: 4.5.0 + cacache: 17.1.4 + http-cache-semantics: 4.1.1 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 5.0.0 + minipass-fetch: 3.0.4 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 10.0.5 + transitivePeerDependencies: + - supports-color + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj@2.0.0: + resolution: {integrity: sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==} + engines: {node: '>=4'} + dev: true + + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: true + + /markdown-it@13.0.1: + resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 3.0.1 + linkify-it: 4.0.1 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: true + + /markdownlint-cli@0.32.2: + resolution: {integrity: sha512-xmJT1rGueUgT4yGNwk6D0oqQr90UJ7nMyakXtqjgswAkEhYYqjHew9RY8wDbOmh2R270IWjuKSeZzHDEGPAUkQ==} + engines: {node: '>=14'} + hasBin: true + dependencies: + commander: 9.4.1 + get-stdin: 9.0.0 + glob: 8.0.3 + ignore: 5.2.4 + js-yaml: 4.1.0 + jsonc-parser: 3.1.0 + markdownlint: 0.26.2 + markdownlint-rule-helpers: 0.17.2 + minimatch: 5.1.6 + run-con: 1.2.12 + dev: true + + /markdownlint-rule-helpers@0.17.2: + resolution: {integrity: sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==} + engines: {node: '>=12'} + dev: true + + /markdownlint@0.26.2: + resolution: {integrity: sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==} + engines: {node: '>=14'} + dependencies: + markdown-it: 13.0.1 + dev: true + + /mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: true + + /meow@5.0.0: + resolution: {integrity: sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==} + engines: {node: '>=6'} + dependencies: + camelcase-keys: 4.2.0 + decamelize-keys: 1.1.1 + loud-rejection: 1.6.0 + minimist-options: 3.0.2 + normalize-package-data: 2.5.0 + read-pkg-up: 3.0.0 + redent: 2.0.0 + trim-newlines: 2.0.0 + yargs-parser: 10.1.0 + dev: true + + /meow@6.1.1: + resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} + engines: {node: '>=8'} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 2.5.0 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.13.1 + yargs-parser: 18.1.3 + dev: true + + /meow@8.1.2: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} + engines: {node: '>=10'} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist-options@3.0.2: + resolution: {integrity: sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==} + engines: {node: '>= 4'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + dev: true + + /minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass-fetch@3.0.4: + resolution: {integrity: sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + minipass: 7.0.3 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + dev: true + + /minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: true + + /minipass@7.0.3: + resolution: {integrity: sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: true + + /mixme@0.5.9: + resolution: {integrity: sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==} + engines: {node: '>= 8.0.0'} + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nan@2.18.0: + resolution: {integrity: sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==} + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: true + + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /node-abi@3.47.0: + resolution: {integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /node-gyp@9.4.0: + resolution: {integrity: sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 11.1.1 + nopt: 6.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.5.4 + tar: 6.2.0 + which: 2.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + + /nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.4 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.13.0 + semver: 7.5.4 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + dev: true + + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + dependencies: + p-map: 2.1.0 + dev: true + + /p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + dependencies: + p-try: 1.0.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + dependencies: + p-limit: 1.3.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.22.13 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.0.1 + minipass: 7.0.3 + dev: true + + /path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /please-upgrade-node@3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + dependencies: + semver-compare: 1.0.0 + dev: true + + /postcss@8.4.29: + resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /prebuild-install@7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.47.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: true + + /preferred-pm@3.1.2: + resolution: {integrity: sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + find-yarn-workspace-root2: 1.2.16 + path-exists: 4.0.0 + which-pm: 2.0.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-format@26.6.2: + resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} + engines: {node: '>= 10'} + dependencies: + '@jest/types': 26.6.2 + ansi-regex: 5.0.1 + ansi-styles: 4.3.0 + react-is: 17.0.2 + dev: true + + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: true + + /promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /pure-rand@6.0.3: + resolution: {integrity: sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w==} + dev: true + + /q@1.5.1: + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} + engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@1.1.0: + resolution: {integrity: sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==} + engines: {node: '>=4'} + dev: true + + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: true + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: true + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + + /read-pkg-up@3.0.0: + resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} + engines: {node: '>=4'} + dependencies: + find-up: 2.1.0 + read-pkg: 3.0.0 + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + + /readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /redent@2.0.0: + resolution: {integrity: sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==} + engines: {node: '>=4'} + dependencies: + indent-string: 3.2.0 + strip-indent: 2.0.0 + dev: true + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /regenerator-runtime@0.10.5: + resolution: {integrity: sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==} + dev: true + + /regenerator-runtime@0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + set-function-name: 2.0.0 + dev: true + + /regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-global@1.0.0: + resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} + engines: {node: '>=8'} + dependencies: + global-dirs: 0.1.1 + dev: true + + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.4: + resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc@1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@3.29.1: + resolution: {integrity: sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /run-con@1.2.12: + resolution: {integrity: sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 3.0.1 + minimist: 1.2.8 + strip-json-comments: 3.1.1 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.5.3 + dev: true + + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-function-name@2.0.0: + resolution: {integrity: sha512-WmS8UHojv5s1eSoRSmzO5zzgDq8PE1/X/ij0k+9fMYmINCc6+j+SF3Om8YyucKn2yjnK4ItNZOoQycNnHsZJTw==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.0.1 + has-property-descriptors: 1.0.0 + dev: true + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: true + + /simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: true + + /smartwrap@2.0.2: + resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + array.prototype.flat: 1.3.2 + breakword: 1.0.6 + grapheme-splitter: 1.0.4 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 15.4.1 + dev: true + + /socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + dev: true + + /split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + dependencies: + readable-stream: 3.6.2 + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /ssri@10.0.5: + resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + minipass: 7.0.3 + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stream-transform@2.1.3: + resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + dependencies: + mixme: 0.5.9 + dev: true + + /string-argv@0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + dev: true + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.1 + dev: true + + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-indent@2.0.0: + resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} + engines: {node: '>=4'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.12.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-extensions@1.9.0: + resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} + engines: {node: '>=0.10'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /through2@0.6.5: + resolution: {integrity: sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==} + dependencies: + readable-stream: 1.0.34 + xtend: 4.0.2 + dev: true + + /through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + dependencies: + readable-stream: 3.6.2 + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /trim-newlines@2.0.0: + resolution: {integrity: sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==} + engines: {node: '>=4'} + dev: true + + /trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + dev: true + + /ts-api-utils@1.0.3(typescript@5.2.2): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.2.2 + dev: true + + /ts-jest@29.1.0(@babel/core@7.22.17)(jest@29.0.0)(typescript@5.2.2): + resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.22.17 + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.0.0 + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.5.4 + typescript: 5.2.2 + yargs-parser: 21.1.1 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib@2.5.3: + resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} + + /tsutils@3.21.0(typescript@5.2.2): + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + 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' + dependencies: + tslib: 1.14.1 + typescript: 5.2.2 + dev: true + + /tty-table@4.2.1: + resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} + engines: {node: '>=8.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + csv: 5.5.3 + kleur: 4.1.5 + smartwrap: 2.0.2 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 17.7.2 + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + unique-slug: 4.0.0 + dev: true + + /unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + imurmurhash: 0.1.4 + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.10): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.10 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /v8-compile-cache@2.4.0: + resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + dev: true + + /v8-to-istanbul@9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vite@4.4.9: + resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.18.20 + postcss: 8.4.29 + rollup: 3.29.1 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /which-pm@2.0.0: + resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + engines: {node: '>=8.15'} + dependencies: + load-yaml-file: 0.2.0 + path-exists: 4.0.0 + dev: true + + /which-typed-array@1.1.11: + resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser@10.1.0: + resolution: {integrity: sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==} + dependencies: + camelcase: 4.1.0 + dev: true + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..d73df4f --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,311 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "glsl-wgsl-compiler" +version = "0.1.0" +dependencies = [ + "naga", + "wasm-bindgen", + "web-sys", + "wee_alloc", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "naga" +version = "0.13.0" +source = "git+https://github.com/gfx-rs/naga#a0eb1f54629133a05f1bd0c82c28c15e0e3e61a2" +dependencies = [ + "bit-set", + "bitflags", + "indexmap", + "log", + "num-traits", + "pp-rs", + "rustc-hash", + "thiserror", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "pp-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..a764a09 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "glsl-wgsl-compiler" +version = "0.1.0" +authors = ["The wasm-bindgen Developers"] +edition = "2018" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = "0.2.79" +wee_alloc = { version = "0.4.5", optional = true } +naga = { git = "https://github.com/gfx-rs/naga", features = ["glsl-in", "wgsl-out"] } + +[dependencies.web-sys] +version = "0.3.4" +features = [ + 'console' +] \ No newline at end of file diff --git a/rust/pkg/.gitignore b/rust/pkg/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/rust/pkg/glsl_wgsl_compiler.d.ts b/rust/pkg/glsl_wgsl_compiler.d.ts new file mode 100644 index 0000000..e59dfc3 --- /dev/null +++ b/rust/pkg/glsl_wgsl_compiler.d.ts @@ -0,0 +1,41 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* @param {string} source +* @param {string} stage +* @param {boolean} validation_enabled +* @returns {string} +*/ +export function glsl_compile(source: string, stage: string, validation_enabled: boolean): string; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly glsl_compile: (a: number, b: number, c: number, d: number, e: number, f: number) => void; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {SyncInitInput} module +* +* @returns {InitOutput} +*/ +export function initSync(module: SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {InitInput | Promise} module_or_path +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: InitInput | Promise): Promise; diff --git a/rust/pkg/glsl_wgsl_compiler.js b/rust/pkg/glsl_wgsl_compiler.js new file mode 100644 index 0000000..3ce510a --- /dev/null +++ b/rust/pkg/glsl_wgsl_compiler.js @@ -0,0 +1,272 @@ +let wasm; + +const cachedTextDecoder = + typeof TextDecoder !== 'undefined' + ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) + : { + decode: () => { + throw Error('TextDecoder not available'); + }, + }; + +if (typeof TextDecoder !== 'undefined') { + cachedTextDecoder.decode(); +} + +let cachedUint8Memory0 = null; + +function getUint8Memory0() { + if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function getObject(idx) { + return heap[idx]; +} + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +let WASM_VECTOR_LEN = 0; + +const cachedTextEncoder = + typeof TextEncoder !== 'undefined' + ? new TextEncoder('utf-8') + : { + encode: () => { + throw Error('TextEncoder not available'); + }, + }; + +const encodeString = + typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); + } + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length, + }; + }; + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8Memory0() + .subarray(ptr, ptr + buf.length) + .set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7f) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0; + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachedInt32Memory0 = null; + +function getInt32Memory0() { + if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} +/** + * @param {string} source + * @param {string} stage + * @param {boolean} validation_enabled + * @returns {string} + */ +export function glsl_compile(source, stage, validation_enabled) { + let deferred3_0; + let deferred3_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0( + source, + wasm.__wbindgen_malloc, + wasm.__wbindgen_realloc, + ); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0( + stage, + wasm.__wbindgen_malloc, + wasm.__wbindgen_realloc, + ); + const len1 = WASM_VECTOR_LEN; + wasm.glsl_compile(retptr, ptr0, len0, ptr1, len1, validation_enabled); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + deferred3_0 = r0; + deferred3_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn( + '`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n', + e, + ); + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_string_new = function (arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_object_drop_ref = function (arg0) { + takeObject(arg0); + }; + imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function (arg0) { + console.log(getObject(arg0)); + }; + imports.wbg.__wbg_log_576ca876af0d4a77 = function (arg0, arg1) { + console.log(getObject(arg0), getObject(arg1)); + }; + imports.wbg.__wbindgen_throw = function (arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + + return imports; +} + +function __wbg_init_memory(imports, maybe_memory) {} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedInt32Memory0 = null; + cachedUint8Memory0 = null; + + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(input) { + if (wasm !== undefined) return wasm; + + if (typeof input === 'undefined') { + // input = new URL('glsl_wgsl_compiler_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if ( + typeof input === 'string' || + (typeof Request === 'function' && input instanceof Request) || + (typeof URL === 'function' && input instanceof URL) + ) { + input = fetch(input); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await input, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync }; +export default __wbg_init; diff --git a/rust/pkg/glsl_wgsl_compiler_bg.wasm b/rust/pkg/glsl_wgsl_compiler_bg.wasm new file mode 100644 index 0000000..172b691 Binary files /dev/null and b/rust/pkg/glsl_wgsl_compiler_bg.wasm differ diff --git a/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts b/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts new file mode 100644 index 0000000..8110124 --- /dev/null +++ b/rust/pkg/glsl_wgsl_compiler_bg.wasm.d.ts @@ -0,0 +1,8 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export function glsl_compile(a: number, b: number, c: number, d: number, e: number, f: number): void; +export function __wbindgen_add_to_stack_pointer(a: number): number; +export function __wbindgen_malloc(a: number, b: number): number; +export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; +export function __wbindgen_free(a: number, b: number, c: number): void; diff --git a/rust/pkg/package.json b/rust/pkg/package.json new file mode 100644 index 0000000..d21bff3 --- /dev/null +++ b/rust/pkg/package.json @@ -0,0 +1,17 @@ +{ + "name": "glsl-wgsl-compiler", + "collaborators": [ + "The wasm-bindgen Developers" + ], + "version": "0.1.0", + "files": [ + "glsl_wgsl_compiler_bg.wasm", + "glsl_wgsl_compiler.js", + "glsl_wgsl_compiler.d.ts" + ], + "module": "glsl_wgsl_compiler.js", + "types": "glsl_wgsl_compiler.d.ts", + "sideEffects": [ + "./snippets/*" + ] +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 0000000..0c31fe1 --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,65 @@ +use std::error::Error; +use wasm_bindgen::prelude::*; +use web_sys::console; + +fn show_error(place: &str, error: impl Error) { + console::log_2(&place.into(), &error.to_string().into()); + + let mut e = error.source(); + while let Some(source) = e { + console::log_1(&source.to_string().into()); + e = source.source(); + } +} + +#[wasm_bindgen] +pub fn glsl_compile(source: &str, stage: &str, validation_enabled: bool) -> String { + let naga_stage = match stage { + "vertex" => Ok(naga::ShaderStage::Vertex), + "fragment" => Ok(naga::ShaderStage::Fragment), + _ => Err("unknown shader stage"), + } + .unwrap(); + + let mut parser = naga::front::glsl::Frontend::default(); + let module = match parser.parse( + &naga::front::glsl::Options { + stage: naga_stage, + defines: Default::default(), + }, + &source, + ) { + Ok(v) => v, + Err(errors) => { + for e in errors { + show_error(&"glsl::parse_str", e); + } + + panic!(); + } + }; + + let validation_flags = if validation_enabled { + naga::valid::ValidationFlags::all() + } else { + naga::valid::ValidationFlags::empty() + }; + let info = match naga::valid::Validator::new(validation_flags, naga::valid::Capabilities::all()) + .validate(&module) + { + Ok(v) => v, + Err(e) => { + show_error(&"validator", e); + panic!(); + } + }; + + let writer_flags = naga::back::wgsl::WriterFlags::empty(); + match naga::back::wgsl::write_string(&module, &info, writer_flags) { + Ok(v) => v, + Err(e) => { + show_error(&"wgsl::write_string", e); + panic!(); + } + } +} diff --git a/src/api/constants.ts b/src/api/constants.ts new file mode 100644 index 0000000..f84048f --- /dev/null +++ b/src/api/constants.ts @@ -0,0 +1,834 @@ +/** + * ported from @luma.gl/constants + * + * Standard WebGL and WebGL2 constants + * These constants are also defined on the WebGLRenderingContext interface. + */ +export enum GL { + // Clearing buffers + // Constants passed to clear() to clear buffer masks. + + DEPTH_BUFFER_BIT = 0x00000100, + STENCIL_BUFFER_BIT = 0x00000400, + COLOR_BUFFER_BIT = 0x00004000, + + // Rendering primitives + // Constants passed to drawElements() or drawArrays() to specify what kind of primitive to render. + + POINTS = 0x0000, + LINES = 0x0001, + LINE_LOOP = 0x0002, + LINE_STRIP = 0x0003, + TRIANGLES = 0x0004, + TRIANGLE_STRIP = 0x0005, + TRIANGLE_FAN = 0x0006, + + // Blending modes + // Constants passed to blendFunc() or blendFuncSeparate() to specify the blending mode (for both, RBG and alpha, or separately). + + ZERO = 0, + ONE = 1, + SRC_COLOR = 0x0300, + ONE_MINUS_SRC_COLOR = 0x0301, + SRC_ALPHA = 0x0302, + ONE_MINUS_SRC_ALPHA = 0x0303, + DST_ALPHA = 0x0304, + ONE_MINUS_DST_ALPHA = 0x0305, + DST_COLOR = 0x0306, + ONE_MINUS_DST_COLOR = 0x0307, + SRC_ALPHA_SATURATE = 0x0308, + CONSTANT_COLOR = 0x8001, + ONE_MINUS_CONSTANT_COLOR = 0x8002, + CONSTANT_ALPHA = 0x8003, + ONE_MINUS_CONSTANT_ALPHA = 0x8004, + + // Blending equations + // Constants passed to blendEquation() or blendEquationSeparate() to control + // how the blending is calculated (for both, RBG and alpha, or separately). + + FUNC_ADD = 0x8006, + FUNC_SUBTRACT = 0x800a, + FUNC_REVERSE_SUBTRACT = 0x800b, + + // Getting GL parameter information + // Constants passed to getParameter() to specify what information to return. + + BLEND_EQUATION = 0x8009, + BLEND_EQUATION_RGB = 0x8009, + BLEND_EQUATION_ALPHA = 0x883d, + BLEND_DST_RGB = 0x80c8, + BLEND_SRC_RGB = 0x80c9, + BLEND_DST_ALPHA = 0x80ca, + BLEND_SRC_ALPHA = 0x80cb, + BLEND_COLOR = 0x8005, + ARRAY_BUFFER_BINDING = 0x8894, + ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, + LINE_WIDTH = 0x0b21, + ALIASED_POINT_SIZE_RANGE = 0x846d, + ALIASED_LINE_WIDTH_RANGE = 0x846e, + CULL_FACE_MODE = 0x0b45, + FRONT_FACE = 0x0b46, + DEPTH_RANGE = 0x0b70, + DEPTH_WRITEMASK = 0x0b72, + DEPTH_CLEAR_VALUE = 0x0b73, + DEPTH_FUNC = 0x0b74, + STENCIL_CLEAR_VALUE = 0x0b91, + STENCIL_FUNC = 0x0b92, + STENCIL_FAIL = 0x0b94, + STENCIL_PASS_DEPTH_FAIL = 0x0b95, + STENCIL_PASS_DEPTH_PASS = 0x0b96, + STENCIL_REF = 0x0b97, + STENCIL_VALUE_MASK = 0x0b93, + STENCIL_WRITEMASK = 0x0b98, + STENCIL_BACK_FUNC = 0x8800, + STENCIL_BACK_FAIL = 0x8801, + STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, + STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, + STENCIL_BACK_REF = 0x8ca3, + STENCIL_BACK_VALUE_MASK = 0x8ca4, + STENCIL_BACK_WRITEMASK = 0x8ca5, + VIEWPORT = 0x0ba2, + SCISSOR_BOX = 0x0c10, + COLOR_CLEAR_VALUE = 0x0c22, + COLOR_WRITEMASK = 0x0c23, + UNPACK_ALIGNMENT = 0x0cf5, + PACK_ALIGNMENT = 0x0d05, + MAX_TEXTURE_SIZE = 0x0d33, + MAX_VIEWPORT_DIMS = 0x0d3a, + SUBPIXEL_BITS = 0x0d50, + RED_BITS = 0x0d52, + GREEN_BITS = 0x0d53, + BLUE_BITS = 0x0d54, + ALPHA_BITS = 0x0d55, + DEPTH_BITS = 0x0d56, + STENCIL_BITS = 0x0d57, + POLYGON_OFFSET_UNITS = 0x2a00, + POLYGON_OFFSET_FACTOR = 0x8038, + TEXTURE_BINDING_2D = 0x8069, + SAMPLE_BUFFERS = 0x80a8, + SAMPLES = 0x80a9, + SAMPLE_COVERAGE_VALUE = 0x80aa, + SAMPLE_COVERAGE_INVERT = 0x80ab, + COMPRESSED_TEXTURE_FORMATS = 0x86a3, + VENDOR = 0x1f00, + RENDERER = 0x1f01, + VERSION = 0x1f02, + IMPLEMENTATION_COLOR_READ_TYPE = 0x8b9a, + IMPLEMENTATION_COLOR_READ_FORMAT = 0x8b9b, + BROWSER_DEFAULT_WEBGL = 0x9244, + + // Buffers + // Constants passed to bufferData(), bufferSubData(), bindBuffer(), or + // getBufferParameter(). + + STATIC_DRAW = 0x88e4, + STREAM_DRAW = 0x88e0, + DYNAMIC_DRAW = 0x88e8, + ARRAY_BUFFER = 0x8892, + ELEMENT_ARRAY_BUFFER = 0x8893, + BUFFER_SIZE = 0x8764, + BUFFER_USAGE = 0x8765, + + // Vertex attributes + // Constants passed to getVertexAttrib(). + + CURRENT_VERTEX_ATTRIB = 0x8626, + VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, + VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, + VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, + VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, + VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886a, + VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889f, + + // Culling + // Constants passed to cullFace(). + + CULL_FACE = 0x0b44, + FRONT = 0x0404, + BACK = 0x0405, + FRONT_AND_BACK = 0x0408, + + // Enabling and disabling + // Constants passed to enable() or disable(). + + BLEND = 0x0be2, + DEPTH_TEST = 0x0b71, + DITHER = 0x0bd0, + POLYGON_OFFSET_FILL = 0x8037, + SAMPLE_ALPHA_TO_COVERAGE = 0x809e, + SAMPLE_COVERAGE = 0x80a0, + SCISSOR_TEST = 0x0c11, + STENCIL_TEST = 0x0b90, + + // Errors + // Constants returned from getError(). + + NO_ERROR = 0, + INVALID_ENUM = 0x0500, + INVALID_VALUE = 0x0501, + INVALID_OPERATION = 0x0502, + OUT_OF_MEMORY = 0x0505, + CONTEXT_LOST_WEBGL = 0x9242, + + // Front face directions + // Constants passed to frontFace(). + + CW = 0x0900, + CCW = 0x0901, + + // Hints + // Constants passed to hint() + + DONT_CARE = 0x1100, + FASTEST = 0x1101, + NICEST = 0x1102, + GENERATE_MIPMAP_HINT = 0x8192, + + // Data types + + BYTE = 0x1400, + UNSIGNED_BYTE = 0x1401, + SHORT = 0x1402, + UNSIGNED_SHORT = 0x1403, + INT = 0x1404, + UNSIGNED_INT = 0x1405, + FLOAT = 0x1406, + DOUBLE = 0x140a, + + // Pixel formats + + DEPTH_COMPONENT = 0x1902, + ALPHA = 0x1906, + RGB = 0x1907, + RGBA = 0x1908, + LUMINANCE = 0x1909, + LUMINANCE_ALPHA = 0x190a, + + // Pixel types + + // UNSIGNED_BYTE = 0x1401, + UNSIGNED_SHORT_4_4_4_4 = 0x8033, + UNSIGNED_SHORT_5_5_5_1 = 0x8034, + UNSIGNED_SHORT_5_6_5 = 0x8363, + + // Shaders + // Constants passed to createShader() or getShaderParameter() + + FRAGMENT_SHADER = 0x8b30, + VERTEX_SHADER = 0x8b31, + COMPILE_STATUS = 0x8b81, + DELETE_STATUS = 0x8b80, + LINK_STATUS = 0x8b82, + VALIDATE_STATUS = 0x8b83, + ATTACHED_SHADERS = 0x8b85, + ACTIVE_ATTRIBUTES = 0x8b89, + ACTIVE_UNIFORMS = 0x8b86, + MAX_VERTEX_ATTRIBS = 0x8869, + MAX_VERTEX_UNIFORM_VECTORS = 0x8dfb, + MAX_VARYING_VECTORS = 0x8dfc, + MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8b4d, + MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8b4c, + MAX_TEXTURE_IMAGE_UNITS = 0x8872, + MAX_FRAGMENT_UNIFORM_VECTORS = 0x8dfd, + SHADER_TYPE = 0x8b4f, + SHADING_LANGUAGE_VERSION = 0x8b8c, + CURRENT_PROGRAM = 0x8b8d, + + // Depth or stencil tests + // Constants passed to depthFunc() or stencilFunc(). + + NEVER = 0x0200, + ALWAYS = 0x0207, + LESS = 0x0201, + EQUAL = 0x0202, + LEQUAL = 0x0203, + GREATER = 0x0204, + GEQUAL = 0x0206, + NOTEQUAL = 0x0205, + + // Stencil actions + // Constants passed to stencilOp(). + + KEEP = 0x1e00, + REPLACE = 0x1e01, + INCR = 0x1e02, + DECR = 0x1e03, + INVERT = 0x150a, + INCR_WRAP = 0x8507, + DECR_WRAP = 0x8508, + + // Textures + // Constants passed to texParameteri(), + // texParameterf(), bindTexture(), texImage2D(), and others. + + NEAREST = 0x2600, + LINEAR = 0x2601, + NEAREST_MIPMAP_NEAREST = 0x2700, + LINEAR_MIPMAP_NEAREST = 0x2701, + NEAREST_MIPMAP_LINEAR = 0x2702, + LINEAR_MIPMAP_LINEAR = 0x2703, + TEXTURE_MAG_FILTER = 0x2800, + TEXTURE_MIN_FILTER = 0x2801, + TEXTURE_WRAP_S = 0x2802, + TEXTURE_WRAP_T = 0x2803, + TEXTURE_2D = 0x0de1, + TEXTURE = 0x1702, + TEXTURE_CUBE_MAP = 0x8513, + TEXTURE_BINDING_CUBE_MAP = 0x8514, + TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, + TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, + TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, + TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, + TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, + TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a, + MAX_CUBE_MAP_TEXTURE_SIZE = 0x851c, + // TEXTURE0 - 31 0x84C0 - 0x84DF A texture unit. + TEXTURE0 = 0x84c0, + ACTIVE_TEXTURE = 0x84e0, + REPEAT = 0x2901, + CLAMP_TO_EDGE = 0x812f, + MIRRORED_REPEAT = 0x8370, + + // Emulation + TEXTURE_WIDTH = 0x1000, + TEXTURE_HEIGHT = 0x1001, + + // Uniform types + + FLOAT_VEC2 = 0x8b50, + FLOAT_VEC3 = 0x8b51, + FLOAT_VEC4 = 0x8b52, + INT_VEC2 = 0x8b53, + INT_VEC3 = 0x8b54, + INT_VEC4 = 0x8b55, + BOOL = 0x8b56, + BOOL_VEC2 = 0x8b57, + BOOL_VEC3 = 0x8b58, + BOOL_VEC4 = 0x8b59, + FLOAT_MAT2 = 0x8b5a, + FLOAT_MAT3 = 0x8b5b, + FLOAT_MAT4 = 0x8b5c, + SAMPLER_2D = 0x8b5e, + SAMPLER_CUBE = 0x8b60, + + // Shader precision-specified types + + LOW_FLOAT = 0x8df0, + MEDIUM_FLOAT = 0x8df1, + HIGH_FLOAT = 0x8df2, + LOW_INT = 0x8df3, + MEDIUM_INT = 0x8df4, + HIGH_INT = 0x8df5, + + // Framebuffers and renderbuffers + + FRAMEBUFFER = 0x8d40, + RENDERBUFFER = 0x8d41, + RGBA4 = 0x8056, + RGB5_A1 = 0x8057, + RGB565 = 0x8d62, + DEPTH_COMPONENT16 = 0x81a5, + STENCIL_INDEX = 0x1901, + STENCIL_INDEX8 = 0x8d48, + DEPTH_STENCIL = 0x84f9, + RENDERBUFFER_WIDTH = 0x8d42, + RENDERBUFFER_HEIGHT = 0x8d43, + RENDERBUFFER_INTERNAL_FORMAT = 0x8d44, + RENDERBUFFER_RED_SIZE = 0x8d50, + RENDERBUFFER_GREEN_SIZE = 0x8d51, + RENDERBUFFER_BLUE_SIZE = 0x8d52, + RENDERBUFFER_ALPHA_SIZE = 0x8d53, + RENDERBUFFER_DEPTH_SIZE = 0x8d54, + RENDERBUFFER_STENCIL_SIZE = 0x8d55, + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8cd0, + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8cd1, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8cd2, + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8cd3, + COLOR_ATTACHMENT0 = 0x8ce0, + DEPTH_ATTACHMENT = 0x8d00, + STENCIL_ATTACHMENT = 0x8d20, + DEPTH_STENCIL_ATTACHMENT = 0x821a, + NONE = 0, + FRAMEBUFFER_COMPLETE = 0x8cd5, + FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8cd6, + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8cd7, + FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8cd9, + FRAMEBUFFER_UNSUPPORTED = 0x8cdd, + FRAMEBUFFER_BINDING = 0x8ca6, + RENDERBUFFER_BINDING = 0x8ca7, + READ_FRAMEBUFFER = 0x8ca8, + DRAW_FRAMEBUFFER = 0x8ca9, + MAX_RENDERBUFFER_SIZE = 0x84e8, + INVALID_FRAMEBUFFER_OPERATION = 0x0506, + + // Pixel storage modes + // Constants passed to pixelStorei(). + + UNPACK_FLIP_Y_WEBGL = 0x9240, + UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, + UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243, + + // ///////////////////////////////////////////////////// + // Additional constants defined WebGL 2 + // These constants are defined on the WebGL2RenderingContext interface. + // All WebGL 1 constants are also available in a WebGL 2 context. + // ///////////////////////////////////////////////////// + + // Getting GL parameter information + // Constants passed to getParameter() + // to specify what information to return. + + READ_BUFFER = 0x0c02, + UNPACK_ROW_LENGTH = 0x0cf2, + UNPACK_SKIP_ROWS = 0x0cf3, + UNPACK_SKIP_PIXELS = 0x0cf4, + PACK_ROW_LENGTH = 0x0d02, + PACK_SKIP_ROWS = 0x0d03, + PACK_SKIP_PIXELS = 0x0d04, + TEXTURE_BINDING_3D = 0x806a, + UNPACK_SKIP_IMAGES = 0x806d, + UNPACK_IMAGE_HEIGHT = 0x806e, + MAX_3D_TEXTURE_SIZE = 0x8073, + MAX_ELEMENTS_VERTICES = 0x80e8, + MAX_ELEMENTS_INDICES = 0x80e9, + MAX_TEXTURE_LOD_BIAS = 0x84fd, + MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8b49, + MAX_VERTEX_UNIFORM_COMPONENTS = 0x8b4a, + MAX_ARRAY_TEXTURE_LAYERS = 0x88ff, + MIN_PROGRAM_TEXEL_OFFSET = 0x8904, + MAX_PROGRAM_TEXEL_OFFSET = 0x8905, + MAX_VARYING_COMPONENTS = 0x8b4b, + FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8b8b, + RASTERIZER_DISCARD = 0x8c89, + VERTEX_ARRAY_BINDING = 0x85b5, + MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122, + MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125, + MAX_SERVER_WAIT_TIMEOUT = 0x9111, + MAX_ELEMENT_INDEX = 0x8d6b, + + // Textures + // Constants passed to texParameteri(), + // texParameterf(), bindTexture(), texImage2D(), and others. + + RED = 0x1903, + RGB8 = 0x8051, + RGBA8 = 0x8058, + RGB10_A2 = 0x8059, + TEXTURE_3D = 0x806f, + TEXTURE_WRAP_R = 0x8072, + TEXTURE_MIN_LOD = 0x813a, + TEXTURE_MAX_LOD = 0x813b, + TEXTURE_BASE_LEVEL = 0x813c, + TEXTURE_MAX_LEVEL = 0x813d, + TEXTURE_COMPARE_MODE = 0x884c, + TEXTURE_COMPARE_FUNC = 0x884d, + SRGB = 0x8c40, + SRGB8 = 0x8c41, + SRGB8_ALPHA8 = 0x8c43, + COMPARE_REF_TO_TEXTURE = 0x884e, + RGBA32F = 0x8814, + RGB32F = 0x8815, + RGBA16F = 0x881a, + RGB16F = 0x881b, + TEXTURE_2D_ARRAY = 0x8c1a, + TEXTURE_BINDING_2D_ARRAY = 0x8c1d, + R11F_G11F_B10F = 0x8c3a, + RGB9_E5 = 0x8c3d, + RGBA32UI = 0x8d70, + RGB32UI = 0x8d71, + RGBA16UI = 0x8d76, + RGB16UI = 0x8d77, + RGBA8UI = 0x8d7c, + RGB8UI = 0x8d7d, + RGBA32I = 0x8d82, + RGB32I = 0x8d83, + RGBA16I = 0x8d88, + RGB16I = 0x8d89, + RGBA8I = 0x8d8e, + RGB8I = 0x8d8f, + RED_INTEGER = 0x8d94, + RGB_INTEGER = 0x8d98, + RGBA_INTEGER = 0x8d99, + R8 = 0x8229, + RG8 = 0x822b, + R16F = 0x822d, + R32F = 0x822e, + RG16F = 0x822f, + RG32F = 0x8230, + R8I = 0x8231, + R8UI = 0x8232, + R16I = 0x8233, + R16UI = 0x8234, + R32I = 0x8235, + R32UI = 0x8236, + RG8I = 0x8237, + RG8UI = 0x8238, + RG16I = 0x8239, + RG16UI = 0x823a, + RG32I = 0x823b, + RG32UI = 0x823c, + R8_SNORM = 0x8f94, + RG8_SNORM = 0x8f95, + RGB8_SNORM = 0x8f96, + RGBA8_SNORM = 0x8f97, + RGB10_A2UI = 0x906f, + + /* covered by extension + COMPRESSED_R11_EAC = 0x9270, + COMPRESSED_SIGNED_R11_EAC = 0x9271, + COMPRESSED_RG11_EAC = 0x9272, + COMPRESSED_SIGNED_RG11_EAC = 0x9273, + COMPRESSED_RGB8_ETC2 = 0x9274, + COMPRESSED_SRGB8_ETC2 = 0x9275, + COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276, + COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC = 0x9277, + COMPRESSED_RGBA8_ETC2_EAC = 0x9278, + COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279, + */ + TEXTURE_IMMUTABLE_FORMAT = 0x912f, + TEXTURE_IMMUTABLE_LEVELS = 0x82df, + + // Pixel types + + UNSIGNED_INT_2_10_10_10_REV = 0x8368, + UNSIGNED_INT_10F_11F_11F_REV = 0x8c3b, + UNSIGNED_INT_5_9_9_9_REV = 0x8c3e, + FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8dad, + UNSIGNED_INT_24_8 = 0x84fa, + HALF_FLOAT = 0x140b, + RG = 0x8227, + RG_INTEGER = 0x8228, + INT_2_10_10_10_REV = 0x8d9f, + + // Queries + + CURRENT_QUERY = 0x8865, + QUERY_RESULT = 0x8866, + QUERY_RESULT_AVAILABLE = 0x8867, + ANY_SAMPLES_PASSED = 0x8c2f, + ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8d6a, + + // Draw buffers + + MAX_DRAW_BUFFERS = 0x8824, + DRAW_BUFFER0 = 0x8825, + DRAW_BUFFER1 = 0x8826, + DRAW_BUFFER2 = 0x8827, + DRAW_BUFFER3 = 0x8828, + DRAW_BUFFER4 = 0x8829, + DRAW_BUFFER5 = 0x882a, + DRAW_BUFFER6 = 0x882b, + DRAW_BUFFER7 = 0x882c, + DRAW_BUFFER8 = 0x882d, + DRAW_BUFFER9 = 0x882e, + DRAW_BUFFER10 = 0x882f, + DRAW_BUFFER11 = 0x8830, + DRAW_BUFFER12 = 0x8831, + DRAW_BUFFER13 = 0x8832, + DRAW_BUFFER14 = 0x8833, + DRAW_BUFFER15 = 0x8834, + MAX_COLOR_ATTACHMENTS = 0x8cdf, + COLOR_ATTACHMENT1 = 0x8ce1, + COLOR_ATTACHMENT2 = 0x8ce2, + COLOR_ATTACHMENT3 = 0x8ce3, + COLOR_ATTACHMENT4 = 0x8ce4, + COLOR_ATTACHMENT5 = 0x8ce5, + COLOR_ATTACHMENT6 = 0x8ce6, + COLOR_ATTACHMENT7 = 0x8ce7, + COLOR_ATTACHMENT8 = 0x8ce8, + COLOR_ATTACHMENT9 = 0x8ce9, + COLOR_ATTACHMENT10 = 0x8cea, + COLOR_ATTACHMENT11 = 0x8ceb, + COLOR_ATTACHMENT12 = 0x8cec, + COLOR_ATTACHMENT13 = 0x8ced, + COLOR_ATTACHMENT14 = 0x8cee, + COLOR_ATTACHMENT15 = 0x8cef, + + // Samplers + + SAMPLER_3D = 0x8b5f, + SAMPLER_2D_SHADOW = 0x8b62, + SAMPLER_2D_ARRAY = 0x8dc1, + SAMPLER_2D_ARRAY_SHADOW = 0x8dc4, + SAMPLER_CUBE_SHADOW = 0x8dc5, + INT_SAMPLER_2D = 0x8dca, + INT_SAMPLER_3D = 0x8dcb, + INT_SAMPLER_CUBE = 0x8dcc, + INT_SAMPLER_2D_ARRAY = 0x8dcf, + UNSIGNED_INT_SAMPLER_2D = 0x8dd2, + UNSIGNED_INT_SAMPLER_3D = 0x8dd3, + UNSIGNED_INT_SAMPLER_CUBE = 0x8dd4, + UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8dd7, + MAX_SAMPLES = 0x8d57, + SAMPLER_BINDING = 0x8919, + + // Buffers + + PIXEL_PACK_BUFFER = 0x88eb, + PIXEL_UNPACK_BUFFER = 0x88ec, + PIXEL_PACK_BUFFER_BINDING = 0x88ed, + PIXEL_UNPACK_BUFFER_BINDING = 0x88ef, + COPY_READ_BUFFER = 0x8f36, + COPY_WRITE_BUFFER = 0x8f37, + COPY_READ_BUFFER_BINDING = 0x8f36, + COPY_WRITE_BUFFER_BINDING = 0x8f37, + + // Data types + + FLOAT_MAT2x3 = 0x8b65, + FLOAT_MAT2x4 = 0x8b66, + FLOAT_MAT3x2 = 0x8b67, + FLOAT_MAT3x4 = 0x8b68, + FLOAT_MAT4x2 = 0x8b69, + FLOAT_MAT4x3 = 0x8b6a, + UNSIGNED_INT_VEC2 = 0x8dc6, + UNSIGNED_INT_VEC3 = 0x8dc7, + UNSIGNED_INT_VEC4 = 0x8dc8, + UNSIGNED_NORMALIZED = 0x8c17, + SIGNED_NORMALIZED = 0x8f9c, + + // Vertex attributes + + VERTEX_ATTRIB_ARRAY_INTEGER = 0x88fd, + VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88fe, + + // Transform feedback + + TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8c7f, + MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8c80, + TRANSFORM_FEEDBACK_VARYINGS = 0x8c83, + TRANSFORM_FEEDBACK_BUFFER_START = 0x8c84, + TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8c85, + TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8c88, + MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8c8a, + MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8c8b, + INTERLEAVED_ATTRIBS = 0x8c8c, + SEPARATE_ATTRIBS = 0x8c8d, + TRANSFORM_FEEDBACK_BUFFER = 0x8c8e, + TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8c8f, + TRANSFORM_FEEDBACK = 0x8e22, + TRANSFORM_FEEDBACK_PAUSED = 0x8e23, + TRANSFORM_FEEDBACK_ACTIVE = 0x8e24, + TRANSFORM_FEEDBACK_BINDING = 0x8e25, + + // Framebuffers and renderbuffers + + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210, + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211, + FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212, + FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213, + FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214, + FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215, + FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216, + FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217, + FRAMEBUFFER_DEFAULT = 0x8218, + // DEPTH_STENCIL_ATTACHMENT = 0x821A, + // DEPTH_STENCIL = 0x84F9, + DEPTH24_STENCIL8 = 0x88f0, + DRAW_FRAMEBUFFER_BINDING = 0x8ca6, + READ_FRAMEBUFFER_BINDING = 0x8caa, + RENDERBUFFER_SAMPLES = 0x8cab, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8cd4, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8d56, + + // Uniforms + + UNIFORM_BUFFER = 0x8a11, + UNIFORM_BUFFER_BINDING = 0x8a28, + UNIFORM_BUFFER_START = 0x8a29, + UNIFORM_BUFFER_SIZE = 0x8a2a, + MAX_VERTEX_UNIFORM_BLOCKS = 0x8a2b, + MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8a2d, + MAX_COMBINED_UNIFORM_BLOCKS = 0x8a2e, + MAX_UNIFORM_BUFFER_BINDINGS = 0x8a2f, + MAX_UNIFORM_BLOCK_SIZE = 0x8a30, + MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8a31, + MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8a33, + UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8a34, + ACTIVE_UNIFORM_BLOCKS = 0x8a36, + UNIFORM_TYPE = 0x8a37, + UNIFORM_SIZE = 0x8a38, + UNIFORM_BLOCK_INDEX = 0x8a3a, + UNIFORM_OFFSET = 0x8a3b, + UNIFORM_ARRAY_STRIDE = 0x8a3c, + UNIFORM_MATRIX_STRIDE = 0x8a3d, + UNIFORM_IS_ROW_MAJOR = 0x8a3e, + UNIFORM_BLOCK_BINDING = 0x8a3f, + UNIFORM_BLOCK_DATA_SIZE = 0x8a40, + UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8a42, + UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43, + UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44, + UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46, + + // Sync objects + + OBJECT_TYPE = 0x9112, + SYNC_CONDITION = 0x9113, + SYNC_STATUS = 0x9114, + SYNC_FLAGS = 0x9115, + SYNC_FENCE = 0x9116, + SYNC_GPU_COMMANDS_COMPLETE = 0x9117, + UNSIGNALED = 0x9118, + SIGNALED = 0x9119, + ALREADY_SIGNALED = 0x911a, + TIMEOUT_EXPIRED = 0x911b, + CONDITION_SATISFIED = 0x911c, + WAIT_FAILED = 0x911d, + SYNC_FLUSH_COMMANDS_BIT = 0x00000001, + + // Miscellaneous constants + + COLOR = 0x1800, + DEPTH = 0x1801, + STENCIL = 0x1802, + MIN = 0x8007, + MAX = 0x8008, + DEPTH_COMPONENT24 = 0x81a6, + STREAM_READ = 0x88e1, + STREAM_COPY = 0x88e2, + STATIC_READ = 0x88e5, + STATIC_COPY = 0x88e6, + DYNAMIC_READ = 0x88e9, + DYNAMIC_COPY = 0x88ea, + DEPTH_COMPONENT32F = 0x8cac, + DEPTH32F_STENCIL8 = 0x8cad, + INVALID_INDEX = 0xffffffff, + TIMEOUT_IGNORED = -1, + MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247, + + // Constants defined in WebGL extensions + + // ANGLE_instanced_arrays + + VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88fe, + + // WEBGL_debug_renderer_info + + UNMASKED_VENDOR_WEBGL = 0x9245, + UNMASKED_RENDERER_WEBGL = 0x9246, + + // EXT_texture_filter_anisotropic + + MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84ff, + TEXTURE_MAX_ANISOTROPY_EXT = 0x84fe, + + // WEBGL_compressed_texture_s3tc + + COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83f0, + COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83f1, + COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83f2, + COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83f3, + + // WEBGL_compressed_texture_es3 + + COMPRESSED_R11_EAC = 0x9270, + COMPRESSED_SIGNED_R11_EAC = 0x9271, + COMPRESSED_RG11_EAC = 0x9272, + COMPRESSED_SIGNED_RG11_EAC = 0x9273, + COMPRESSED_RGB8_ETC2 = 0x9274, + COMPRESSED_RGBA8_ETC2_EAC = 0x9275, + COMPRESSED_SRGB8_ETC2 = 0x9276, + COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9277, + COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9278, + COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9279, + + // WEBGL_compressed_texture_pvrtc + + COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8c00, + COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8c02, + COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8c01, + COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8c03, + + // WEBGL_compressed_texture_etc1 + + COMPRESSED_RGB_ETC1_WEBGL = 0x8d64, + + // WEBGL_compressed_texture_atc + + COMPRESSED_RGB_ATC_WEBGL = 0x8c92, + COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8c92, + COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87ee, + + // WEBGL_depth_texture + + UNSIGNED_INT_24_8_WEBGL = 0x84fa, + + // OES_texture_half_float + + HALF_FLOAT_OES = 0x8d61, + + // WEBGL_color_buffer_float + + RGBA32F_EXT = 0x8814, + RGB32F_EXT = 0x8815, + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211, + UNSIGNED_NORMALIZED_EXT = 0x8c17, + + // EXT_blend_minmax + + MIN_EXT = 0x8007, + MAX_EXT = 0x8008, + + // EXT_sRGB + + SRGB_EXT = 0x8c40, + SRGB_ALPHA_EXT = 0x8c42, + SRGB8_ALPHA8_EXT = 0x8c43, + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210, + + // OES_standard_derivatives + + FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8b8b, + + // WEBGL_draw_buffers + + COLOR_ATTACHMENT0_WEBGL = 0x8ce0, + COLOR_ATTACHMENT1_WEBGL = 0x8ce1, + COLOR_ATTACHMENT2_WEBGL = 0x8ce2, + COLOR_ATTACHMENT3_WEBGL = 0x8ce3, + COLOR_ATTACHMENT4_WEBGL = 0x8ce4, + COLOR_ATTACHMENT5_WEBGL = 0x8ce5, + COLOR_ATTACHMENT6_WEBGL = 0x8ce6, + COLOR_ATTACHMENT7_WEBGL = 0x8ce7, + COLOR_ATTACHMENT8_WEBGL = 0x8ce8, + COLOR_ATTACHMENT9_WEBGL = 0x8ce9, + COLOR_ATTACHMENT10_WEBGL = 0x8cea, + COLOR_ATTACHMENT11_WEBGL = 0x8ceb, + COLOR_ATTACHMENT12_WEBGL = 0x8cec, + COLOR_ATTACHMENT13_WEBGL = 0x8ced, + COLOR_ATTACHMENT14_WEBGL = 0x8cee, + COLOR_ATTACHMENT15_WEBGL = 0x8cef, + DRAW_BUFFER0_WEBGL = 0x8825, + DRAW_BUFFER1_WEBGL = 0x8826, + DRAW_BUFFER2_WEBGL = 0x8827, + DRAW_BUFFER3_WEBGL = 0x8828, + DRAW_BUFFER4_WEBGL = 0x8829, + DRAW_BUFFER5_WEBGL = 0x882a, + DRAW_BUFFER6_WEBGL = 0x882b, + DRAW_BUFFER7_WEBGL = 0x882c, + DRAW_BUFFER8_WEBGL = 0x882d, + DRAW_BUFFER9_WEBGL = 0x882e, + DRAW_BUFFER10_WEBGL = 0x882f, + DRAW_BUFFER11_WEBGL = 0x8830, + DRAW_BUFFER12_WEBGL = 0x8831, + DRAW_BUFFER13_WEBGL = 0x8832, + DRAW_BUFFER14_WEBGL = 0x8833, + DRAW_BUFFER15_WEBGL = 0x8834, + MAX_COLOR_ATTACHMENTS_WEBGL = 0x8cdf, + MAX_DRAW_BUFFERS_WEBGL = 0x8824, + + // OES_vertex_array_object + + VERTEX_ARRAY_BINDING_OES = 0x85b5, + + // EXT_disjoint_timer_query + + QUERY_COUNTER_BITS_EXT = 0x8864, + CURRENT_QUERY_EXT = 0x8865, + QUERY_RESULT_EXT = 0x8866, + QUERY_RESULT_AVAILABLE_EXT = 0x8867, + TIME_ELAPSED_EXT = 0x88bf, + TIMESTAMP_EXT = 0x8e28, + GPU_DISJOINT_EXT = 0x8fbb, // A Boolean indicating whether or not the GPU performed any disjoint operation. +} diff --git a/src/api/format.ts b/src/api/format.ts new file mode 100644 index 0000000..199670c --- /dev/null +++ b/src/api/format.ts @@ -0,0 +1,400 @@ +import { SamplerFormatKind } from './interfaces'; + +export enum FormatTypeFlags { + U8 = 0x01, + U16, + U32, + S8, + S16, + S32, + F16, + F32, + + // Compressed texture formats. + BC1 = 0x41, + BC2, + BC3, + BC4_UNORM, + BC4_SNORM, + BC5_UNORM, + BC5_SNORM, + + // Special-case packed texture formats. + U16_PACKED_5551 = 0x61, + U16_PACKED_565, + + // Depth/stencil texture formats. + D24 = 0x81, + D32F, + D24S8, + D32FS8, +} + +export enum FormatCompFlags { + R = 0x01, + RG = 0x02, + RGB = 0x03, + RGBA = 0x04, + A = 0x05, +} + +export function getFormatCompFlagsComponentCount(n: FormatCompFlags): number { + // The number of components is the flag value. Easy. + return n; +} + +export enum FormatFlags { + None = 0b00000000, + Normalized = 0b00000001, + sRGB = 0b00000010, + Depth = 0b00000100, + Stencil = 0b00001000, + RenderTarget = 0b00010000, +} + +export function makeFormat( + type: FormatTypeFlags, + comp: FormatCompFlags, + flags: FormatFlags, +): Format { + return (type << 16) | (comp << 8) | flags; +} + +export enum Format { + ALPHA = makeFormat(FormatTypeFlags.U8, FormatCompFlags.A, FormatFlags.None), + F16_R = makeFormat(FormatTypeFlags.F16, FormatCompFlags.R, FormatFlags.None), + F16_RG = makeFormat( + FormatTypeFlags.F16, + FormatCompFlags.RG, + FormatFlags.None, + ), + F16_RGB = makeFormat( + FormatTypeFlags.F16, + FormatCompFlags.RGB, + FormatFlags.None, + ), + F16_RGBA = makeFormat( + FormatTypeFlags.F16, + FormatCompFlags.RGBA, + FormatFlags.None, + ), + F32_R = makeFormat(FormatTypeFlags.F32, FormatCompFlags.R, FormatFlags.None), + F32_RG = makeFormat( + FormatTypeFlags.F32, + FormatCompFlags.RG, + FormatFlags.None, + ), + F32_RGB = makeFormat( + FormatTypeFlags.F32, + FormatCompFlags.RGB, + FormatFlags.None, + ), + F32_RGBA = makeFormat( + FormatTypeFlags.F32, + FormatCompFlags.RGBA, + FormatFlags.None, + ), + U8_R = makeFormat(FormatTypeFlags.U8, FormatCompFlags.R, FormatFlags.None), + U8_R_NORM = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.R, + FormatFlags.Normalized, + ), + U8_RG = makeFormat(FormatTypeFlags.U8, FormatCompFlags.RG, FormatFlags.None), + U8_RG_NORM = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + U8_RGB = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGB, + FormatFlags.None, + ), + U8_RGB_NORM = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGB, + FormatFlags.Normalized, + ), + U8_RGB_SRGB = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGB, + FormatFlags.sRGB | FormatFlags.Normalized, + ), + U8_RGBA = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGBA, + FormatFlags.None, + ), + U8_RGBA_NORM = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + U8_RGBA_SRGB = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGBA, + FormatFlags.sRGB | FormatFlags.Normalized, + ), + U16_R = makeFormat(FormatTypeFlags.U16, FormatCompFlags.R, FormatFlags.None), + U16_R_NORM = makeFormat( + FormatTypeFlags.U16, + FormatCompFlags.R, + FormatFlags.Normalized, + ), + U16_RG_NORM = makeFormat( + FormatTypeFlags.U16, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + U16_RGBA_NORM = makeFormat( + FormatTypeFlags.U16, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + U16_RGB = makeFormat( + FormatTypeFlags.U16, + FormatCompFlags.RGB, + FormatFlags.None, + ), + U32_R = makeFormat(FormatTypeFlags.U32, FormatCompFlags.R, FormatFlags.None), + U32_RG = makeFormat( + FormatTypeFlags.U32, + FormatCompFlags.RG, + FormatFlags.None, + ), + S8_R = makeFormat(FormatTypeFlags.S8, FormatCompFlags.R, FormatFlags.None), + S8_R_NORM = makeFormat( + FormatTypeFlags.S8, + FormatCompFlags.R, + FormatFlags.Normalized, + ), + S8_RG_NORM = makeFormat( + FormatTypeFlags.S8, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + S8_RGB_NORM = makeFormat( + FormatTypeFlags.S8, + FormatCompFlags.RGB, + FormatFlags.Normalized, + ), + S8_RGBA_NORM = makeFormat( + FormatTypeFlags.S8, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + S16_R = makeFormat(FormatTypeFlags.S16, FormatCompFlags.R, FormatFlags.None), + S16_RG = makeFormat( + FormatTypeFlags.S16, + FormatCompFlags.RG, + FormatFlags.None, + ), + S16_RG_NORM = makeFormat( + FormatTypeFlags.S16, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + S16_RGB_NORM = makeFormat( + FormatTypeFlags.S16, + FormatCompFlags.RGB, + FormatFlags.Normalized, + ), + S16_RGBA = makeFormat( + FormatTypeFlags.S16, + FormatCompFlags.RGBA, + FormatFlags.None, + ), + S16_RGBA_NORM = makeFormat( + FormatTypeFlags.S16, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + S32_R = makeFormat(FormatTypeFlags.S32, FormatCompFlags.R, FormatFlags.None), + + // Packed texture formats. + U16_RGBA_5551 = makeFormat( + FormatTypeFlags.U16_PACKED_5551, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + U16_RGB_565 = makeFormat( + FormatTypeFlags.U16_PACKED_565, + FormatCompFlags.RGB, + FormatFlags.Normalized, + ), + + // Compressed + BC1 = makeFormat( + FormatTypeFlags.BC1, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + BC1_SRGB = makeFormat( + FormatTypeFlags.BC1, + FormatCompFlags.RGBA, + FormatFlags.Normalized | FormatFlags.sRGB, + ), + BC2 = makeFormat( + FormatTypeFlags.BC2, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + BC2_SRGB = makeFormat( + FormatTypeFlags.BC2, + FormatCompFlags.RGBA, + FormatFlags.Normalized | FormatFlags.sRGB, + ), + BC3 = makeFormat( + FormatTypeFlags.BC3, + FormatCompFlags.RGBA, + FormatFlags.Normalized, + ), + BC3_SRGB = makeFormat( + FormatTypeFlags.BC3, + FormatCompFlags.RGBA, + FormatFlags.Normalized | FormatFlags.sRGB, + ), + BC4_UNORM = makeFormat( + FormatTypeFlags.BC4_UNORM, + FormatCompFlags.R, + FormatFlags.Normalized, + ), + BC4_SNORM = makeFormat( + FormatTypeFlags.BC4_SNORM, + FormatCompFlags.R, + FormatFlags.Normalized, + ), + BC5_UNORM = makeFormat( + FormatTypeFlags.BC5_UNORM, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + BC5_SNORM = makeFormat( + FormatTypeFlags.BC5_SNORM, + FormatCompFlags.RG, + FormatFlags.Normalized, + ), + + // Depth/Stencil + D24 = makeFormat(FormatTypeFlags.D24, FormatCompFlags.R, FormatFlags.Depth), + D24_S8 = makeFormat( + FormatTypeFlags.D24S8, + FormatCompFlags.RG, + FormatFlags.Depth | FormatFlags.Stencil, + ), + D32F = makeFormat(FormatTypeFlags.D32F, FormatCompFlags.R, FormatFlags.Depth), + D32F_S8 = makeFormat( + FormatTypeFlags.D32FS8, + FormatCompFlags.RG, + FormatFlags.Depth | FormatFlags.Stencil, + ), + + // Special RT formats for preferred backend support. + U8_RGB_RT = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGB, + FormatFlags.RenderTarget | FormatFlags.Normalized, + ), + U8_RGBA_RT = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGBA, + FormatFlags.RenderTarget | FormatFlags.Normalized, + ), + U8_RGBA_RT_SRGB = makeFormat( + FormatTypeFlags.U8, + FormatCompFlags.RGBA, + FormatFlags.RenderTarget | FormatFlags.Normalized | FormatFlags.sRGB, + ), +} + +export function getFormatCompFlags(fmt: Format): FormatCompFlags { + return (fmt >>> 8) & 0xff; +} + +export function getFormatTypeFlags(fmt: Format): FormatTypeFlags { + return (fmt >>> 16) & 0xff; +} + +export function getFormatFlags(fmt: Format): FormatFlags { + return fmt & 0xff; +} + +export function getFormatTypeFlagsByteSize( + typeFlags: FormatTypeFlags, +): 1 | 2 | 4 { + switch (typeFlags) { + case FormatTypeFlags.F32: + case FormatTypeFlags.U32: + case FormatTypeFlags.S32: + return 4; + case FormatTypeFlags.U16: + case FormatTypeFlags.S16: + case FormatTypeFlags.F16: + return 2; + case FormatTypeFlags.U8: + case FormatTypeFlags.S8: + return 1; + default: + throw new Error('whoops'); + } +} + +/** + * Gets the byte size for an individual component. + * e.g. for F32_RGB, this will return "4", since F32 has 4 bytes. + */ +export function getFormatCompByteSize(fmt: Format): 1 | 2 | 4 { + return getFormatTypeFlagsByteSize(getFormatTypeFlags(fmt)); +} + +export function getFormatComponentCount(fmt: Format): number { + return getFormatCompFlagsComponentCount(getFormatCompFlags(fmt)); +} + +export function getFormatByteSize(fmt: Format): number { + const typeByteSize = getFormatTypeFlagsByteSize(getFormatTypeFlags(fmt)); + const componentCount = getFormatCompFlagsComponentCount( + getFormatCompFlags(fmt), + ); + return typeByteSize * componentCount; +} + +export function setFormatFlags(fmt: Format, flags: FormatFlags): Format { + return (fmt & 0xffffff00) | flags; +} + +export function setFormatComponentCount( + fmt: Format, + compFlags: FormatCompFlags, +): Format { + return (fmt & 0xffff00ff) | (compFlags << 8); +} + +export function getFormatSamplerKind(fmt: Format): SamplerFormatKind { + const flags = getFormatFlags(fmt); + if (flags & FormatFlags.Depth) { + return SamplerFormatKind.Depth; + } + if (flags & FormatFlags.Normalized) { + return SamplerFormatKind.Float; + } + const typeFlags = getFormatTypeFlags(fmt); + if (typeFlags === FormatTypeFlags.F16 || typeFlags === FormatTypeFlags.F32) { + return SamplerFormatKind.Float; + } else if ( + typeFlags === FormatTypeFlags.U8 || + typeFlags === FormatTypeFlags.U16 || + typeFlags === FormatTypeFlags.U32 + ) { + return SamplerFormatKind.Uint; + } else if ( + typeFlags === FormatTypeFlags.S8 || + typeFlags === FormatTypeFlags.S16 || + typeFlags === FormatTypeFlags.S32 + ) { + return SamplerFormatKind.Sint; + } else { + throw new Error('whoops'); + } +} diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..81f2121 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,4 @@ +export * from './constants'; +export * from './format'; +export * from './interfaces'; +export * from './utils'; diff --git a/src/api/interfaces.ts b/src/api/interfaces.ts new file mode 100644 index 0000000..dee7420 --- /dev/null +++ b/src/api/interfaces.ts @@ -0,0 +1,777 @@ +import type { EventEmitter } from 'eventemitter3'; +import { GL } from './constants'; +import type { Format } from './format'; + +export interface DeviceContribution { + createSwapChain: ($canvas: HTMLCanvasElement) => Promise; +} + +export enum ResourceType { + Buffer, + Texture, + RenderTarget, + Sampler, + Program, + Bindings, + InputLayout, + RenderPipeline, + ComputePipeline, + Readback, + QueryPool, +} + +export interface Disposable { + destroy: () => void; +} + +export interface ResourceBase extends Disposable, EventEmitter { + id: number; + name?: string; +} +export interface Buffer extends ResourceBase { + type: ResourceType.Buffer; + setSubData: ( + dstByteOffset: number, + src: Uint8Array, + srcByteOffset?: number, + byteLength?: number, + ) => void; +} +export interface Texture extends ResourceBase { + type: ResourceType.Texture; + setImageData: ( + data: (TexImageSource | ArrayBufferView)[], + lod?: number, + ) => void; +} +export interface RenderTarget extends ResourceBase { + type: ResourceType.RenderTarget; +} +export interface Sampler extends ResourceBase { + type: ResourceType.Sampler; +} +export interface Program extends ResourceBase { + type: ResourceType.Program; + // eslint-disable-next-line + setUniformsLegacy: (uniforms: Record) => void; +} +export interface Bindings extends ResourceBase { + type: ResourceType.Bindings; +} +export interface InputLayout extends ResourceBase { + type: ResourceType.InputLayout; +} +export interface RenderPipeline extends ResourceBase { + type: ResourceType.RenderPipeline; +} +export interface QueryPool extends ResourceBase { + type: ResourceType.QueryPool; + + queryResultOcclusion: (dstOffs: number) => boolean | null; +} +export interface Readback extends ResourceBase { + type: ResourceType.Readback; + + readTexture: ( + t: Texture, + x: number, + y: number, + width: number, + height: number, + dst: ArrayBufferView, + dstOffset?: number, + length?: number, + ) => Promise; + + readTextureSync: ( + t: Texture, + x: number, + y: number, + width: number, + height: number, + dst: ArrayBufferView, + dstOffset?: number, + length?: number, + ) => ArrayBufferView; + + readBuffer: ( + b: Buffer, + srcByteOffset?: number, + dst?: ArrayBufferView, + dstOffset?: number, + length?: number, + ) => Promise; +} +export interface ComputePipeline extends ResourceBase { + type: ResourceType.ComputePipeline; +} + +export type Resource = + | Buffer + | Texture + | RenderTarget + | Sampler + | Program + | Bindings + | InputLayout + | RenderPipeline + | ComputePipeline + | Readback; + +export enum CompareMode { + NEVER = GL.NEVER, + LESS = GL.LESS, + EQUAL = GL.EQUAL, + LEQUAL = GL.LEQUAL, + GREATER = GL.GREATER, + NOTEQUAL = GL.NOTEQUAL, + GEQUAL = GL.GEQUAL, + ALWAYS = GL.ALWAYS, +} + +export enum FrontFace { + CCW = GL.CCW, + CW = GL.CW, +} + +export enum CullMode { + NONE, + FRONT, + BACK, + FRONT_AND_BACK, +} + +/** + * Blend factor RGBA components. + * @see https://www.w3.org/TR/webgpu/#enumdef-gpublendfactor + */ +export enum BlendFactor { + /** + * (0, 0, 0, 0) + */ + ZERO = GL.ZERO, + /** + * (1, 1, 1, 1) + */ + ONE = GL.ONE, + /** + * (Rsrc, Gsrc, Bsrc, Asrc) + */ + SRC = GL.SRC_COLOR, + /** + * (1 - Rsrc, 1 - Gsrc, 1 - Bsrc, 1 - Asrc) + */ + ONE_MINUS_SRC = GL.ONE_MINUS_SRC_COLOR, + /** + * (Rdst, Gdst, Bdst, Adst) + */ + DST = GL.DST_COLOR, + /** + * (1 - Rdst, 1 - Gdst, 1 - Bdst, 1 - Adst) + */ + ONE_MINUS_DST = GL.ONE_MINUS_DST_COLOR, + /** + * (Asrc, Asrc, Asrc, Asrc) + */ + SRC_ALPHA = GL.SRC_ALPHA, + /** + * (1 - Asrc, 1 - Asrc, 1 - Asrc, 1 - Asrc) + */ + ONE_MINUS_SRC_ALPHA = GL.ONE_MINUS_SRC_ALPHA, + /** + * (Adst, Adst, Adst, Adst) + */ + DST_ALPHA = GL.DST_ALPHA, + /** + * (1 - Adst, 1 - Adst, 1 - Adst, 1 - Adst) + */ + ONE_MINUS_DST_ALPHA = GL.ONE_MINUS_DST_ALPHA, + /** + * (Rconst, Gconst, Bconst, Aconst) + */ + CONST = GL.CONSTANT_COLOR, + /** + * (1 - Rconst, 1 - Gconst, 1 - Bconst, 1 - Aconst) + */ + ONE_MINUS_CONSTANT = GL.ONE_MINUS_CONSTANT_COLOR, + /** + * (min(Asrc, 1 - Adst), min(Asrc, 1 - Adst), min(Asrc, 1 - Adst), 1) + */ + SRC_ALPHA_SATURATE = GL.SRC_ALPHA_SATURATE, +} + +/** + * Defines the algorithm used to combine source and destination blend factors. + * @see https://www.w3.org/TR/webgpu/#enumdef-gpublendoperation + */ +export enum BlendMode { + /** + * RGBAsrc × RGBAsrcFactor + RGBAdst × RGBAdstFactor + */ + ADD = GL.FUNC_ADD, + /** + * RGBAsrc × RGBAsrcFactor - RGBAdst × RGBAdstFactor + */ + SUBSTRACT = GL.FUNC_SUBTRACT, + /** + * RGBAdst × RGBAdstFactor - RGBAsrc × RGBAsrcFactor + */ + REVERSE_SUBSTRACT = GL.FUNC_REVERSE_SUBTRACT, + // TODO: WebGL 1 should use ext + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendEquation#parameters + /** + * min(RGBAsrc, RGBAdst) + */ + MIN = GL.MIN, + /** + * max(RGBAsrc, RGBAdst) + */ + MAX = GL.MAX, +} + +export enum WrapMode { + CLAMP, + REPEAT, + MIRROR, +} +export enum TexFilterMode { + POINT, + BILINEAR, +} +export enum MipFilterMode { + NO_MIP, + NEAREST, + LINEAR, +} +export enum PrimitiveTopology { + POINTS, + TRIANGLES, + TRIANGLE_STRIP, + LINES, + LINE_STRIP, +} + +/** + * @see https://www.w3.org/TR/webgpu/#GPUBufferDescriptor + */ +export interface BufferDescriptor { + viewOrSize: ArrayBufferView | number; + usage: BufferUsage; + hint?: BufferFrequencyHint; +} + +/** + * @see https://www.w3.org/TR/webgpu/#buffer-usage + */ +export enum BufferUsage { + MAP_READ = 0x0001, + MAP_WRITE = 0x0002, + COPY_SRC = 0x0004, + COPY_DST = 0x0008, + INDEX = 0x0010, + VERTEX = 0x0020, + UNIFORM = 0x0040, + STORAGE = 0x0080, + INDIRECT = 0x0100, + QUERY_RESOLVE = 0x0200, +} + +export enum BufferFrequencyHint { + STATIC = 0x01, + DYNAMIC = 0x02, +} + +/** + * @see https://www.w3.org/TR/webgpu/#enumdef-gpuvertexstepmode + */ +export enum VertexStepMode { + VERTEX = 0x01, + INSTANCE = 0x02, +} + +export enum TextureEvent { + LOADED = 'loaded', +} + +export enum TextureDimension { + TEXTURE_2D, + TEXTURE_2D_ARRAY, + TEXTURE_3D, + TEXTURE_CUBE_MAP, +} + +export enum TextureUsage { + SAMPLED = 0x01, + RENDER_TARGET = 0x02, +} + +export enum ChannelWriteMask { + NONE = 0x00, + RED = 0x01, + GREEN = 0x02, + BLUE = 0x04, + ALPHA = 0x08, + RGB = 0x07, + ALL = 0x0f, +} + +/** + * @see https://www.w3.org/TR/webgpu/#enumdef-gpustenciloperation + */ +export enum StencilOp { + KEEP = GL.KEEP, + ZERO = GL.ZERO, + REPLACE = GL.REPLACE, + INVERT = GL.INVERT, + INCREMENT_CLAMP = GL.INCR, + DECREMENT_CLAMP = GL.DECR, + INCREMENT_WRAP = GL.INCR_WRAP, + DECREMENT_WRAP = GL.DECR_WRAP, +} + +export interface VertexBufferDescriptor { + buffer: Buffer; + byteOffset?: number; +} + +export type IndexBufferDescriptor = VertexBufferDescriptor; + +export interface VertexAttributeDescriptor { + location: number; + format: Format; + bufferIndex: number; + bufferByteOffset: number; + divisor?: number; +} + +export interface InputLayoutBufferDescriptor { + byteStride: number; + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpuvertexbufferlayout-stepmode + */ + stepMode: VertexStepMode; +} + +export interface TextureDescriptor { + dimension?: TextureDimension; + pixelFormat: Format; + width: number; + height: number; + depth?: number; + numLevels?: number; + usage: TextureUsage; + /** + * @see https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/pixelStorei + */ + pixelStore?: Partial<{ + packAlignment: number; + unpackAlignment: number; + unpackFlipY: boolean; + }>; +} + +export function makeTextureDescriptor2D( + pixelFormat: Format, + width: number, + height: number, + numLevels: number, +): TextureDescriptor { + const dimension = TextureDimension.TEXTURE_2D, + depth = 1; + const usage = TextureUsage.SAMPLED; + return { dimension, pixelFormat, width, height, depth, numLevels, usage }; +} + +export interface SamplerDescriptor { + wrapS: WrapMode; + wrapT: WrapMode; + wrapQ?: WrapMode; + minFilter: TexFilterMode; + magFilter: TexFilterMode; + mipFilter: MipFilterMode; + minLOD?: number; + maxLOD?: number; + maxAnisotropy?: number; + compareMode?: CompareMode; +} + +export interface RenderTargetDescriptor { + pixelFormat: Format; + width: number; + height: number; + sampleCount?: number; + texture?: Texture; +} + +/** + * @see https://www.w3.org/TR/webgpu/#dictdef-gpubindgroupentry + */ +export interface BufferBinding { + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpubindgroupentry-binding + * @example + * @binding(0) @group(0) var params : SimParams; + */ + binding: number; + /** + * @{Buffer} + */ + buffer: Buffer; + /** + * The offset, in bytes, from the beginning of buffer to the beginning of the range exposed to the shader by the buffer binding. + * Defaulting to 0 + * @see https://www.w3.org/TR/webgpu/#dom-gpubufferbinding-offset + */ + offset?: number; + /** + * The size, in bytes, of the buffer binding. If not provided, specifies the range starting at offset and ending at the end of buffer. + * @see https://www.w3.org/TR/webgpu/#dom-gpubufferbinding-size + */ + size?: number; +} + +export interface SamplerBinding { + texture: Texture | null; + sampler: Sampler | null; + dimension?: TextureDimension; + formatKind?: SamplerFormatKind; + comparison?: boolean; +} + +export enum SamplerFormatKind { + Float, + Uint, + Sint, + Depth, +} + +export interface BindingsDescriptor { + // infer from shader module @see https://www.w3.org/TR/webgpu/#dom-gpupipelinebase-getbindgrouplayout + pipeline?: RenderPipeline | ComputePipeline; + uniformBufferBindings?: BufferBinding[]; + samplerBindings?: SamplerBinding[]; + storageBufferBindings?: BufferBinding[]; +} + +/** + * Support the following shaderStage: vertex | fragment | compute. + */ +export interface ProgramDescriptor { + vertex?: { + glsl?: string; + wgsl?: string; + entryPoint?: string; + }; + fragment?: { + glsl?: string; + wgsl?: string; + entryPoint?: string; + }; + compute?: { + wgsl: string; + entryPoint?: string; + }; +} + +export interface ProgramDescriptorSimple { + vert?: string; + frag?: string; + preprocessedVert?: string; + preprocessedFrag?: string; + preprocessedCompute?: string; +} + +export interface InputLayoutDescriptor { + vertexBufferDescriptors: (InputLayoutBufferDescriptor | null)[]; + vertexAttributeDescriptors: VertexAttributeDescriptor[]; + indexBufferFormat: Format | null; + /** + * Read attributes from linked program. + */ + program: Program; +} + +export interface ChannelBlendState { + blendMode: BlendMode; + blendSrcFactor: BlendFactor; + blendDstFactor: BlendFactor; +} + +export interface AttachmentState { + channelWriteMask?: ChannelWriteMask; + rgbBlendState: ChannelBlendState; + alphaBlendState: ChannelBlendState; +} + +export interface MegaStateDescriptor { + attachmentsState: AttachmentState[]; + blendConstant?: Color; + depthCompare?: CompareMode; + depthWrite?: boolean; + stencilCompare?: CompareMode; + stencilWrite?: boolean; + stencilPassOp?: StencilOp; + stencilRef?: number; + cullMode?: CullMode; + frontFace?: FrontFace; + polygonOffset?: boolean; +} + +export interface PipelineDescriptor { + inputLayout: InputLayout | null; + program: Program; +} + +export interface RenderPipelineDescriptor extends PipelineDescriptor { + topology?: PrimitiveTopology; + megaStateDescriptor?: MegaStateDescriptor; + + // Attachment data. + colorAttachmentFormats: (Format | null)[]; + depthStencilAttachmentFormat?: Format | null; + sampleCount?: number; +} + +export type ComputePipelineDescriptor = PipelineDescriptor; + +export interface Color { + r: number; + g: number; + b: number; + a: number; +} + +export interface RenderPassDescriptor { + colorAttachment: (RenderTarget | null)[]; + colorAttachmentLevel?: number[]; + colorClearColor?: (Color | 'load')[]; + colorResolveTo: (Texture | null)[]; + colorResolveToLevel?: number[]; + colorStore?: boolean[]; + depthStencilAttachment?: RenderTarget | null; + depthStencilResolveTo?: Texture | null; + depthStencilStore?: boolean; + depthClearValue?: number | 'load'; + stencilClearValue?: number | 'load'; + occlusionQueryPool?: QueryPool | null; +} + +export interface DeviceLimits { + uniformBufferWordAlignment: number; + uniformBufferMaxPageWordSize: number; + readonly supportedSampleCounts: number[]; + occlusionQueriesRecommended: boolean; + computeShadersSupported: boolean; +} + +export interface DebugGroup { + name: string; + drawCallCount: number; + textureBindCount: number; + bufferUploadCount: number; + triangleCount: number; +} + +export enum ViewportOrigin { + LOWER_LEFT, + UPPER_LEFT, +} + +export enum ClipSpaceNearZ { + NEGATIVE_ONE, + ZERO, +} + +export interface VendorInfo { + readonly platformString: string; + readonly glslVersion: string; + readonly explicitBindingLocations: boolean; + readonly separateSamplerTextures: boolean; + readonly viewportOrigin: ViewportOrigin; + readonly clipSpaceNearZ: ClipSpaceNearZ; + readonly supportMRT: boolean; +} + +export type PlatformFramebuffer = WebGLFramebuffer; + +export interface SwapChain { + // @see https://www.w3.org/TR/webgpu/#canvas-configuration + configureSwapChain: ( + width: number, + height: number, + platformFramebuffer?: PlatformFramebuffer, + ) => void; + getDevice: () => Device; + getCanvas: () => HTMLCanvasElement | OffscreenCanvas; + getOnscreenTexture: () => Texture; +} + +/** + * @see https://www.w3.org/TR/webgpu/#debug-markers + */ +interface DebugCommandsMixin { + pushDebugGroup: (groupLabel: string) => void; + popDebugGroup: () => void; + insertDebugMarker: (markerLabel: string) => void; +} + +export interface RenderPass extends DebugCommandsMixin { + // State management. + setViewport: ( + x: number, + y: number, + w: number, + h: number, + /** + * WebGPU only. + */ + minDepth?: number, + /** + * WebGPU only. + */ + maxDepth?: number, + ) => void; + setScissor: (x: number, y: number, w: number, h: number) => void; + setPipeline: (pipeline: RenderPipeline) => void; + setBindings: (bindings: Bindings, dynamicByteOffsets?: number[]) => void; + setVertexInput: ( + inputLayout: InputLayout | null, + buffers: (VertexBufferDescriptor | null)[] | null, + indexBuffer: IndexBufferDescriptor | null, + ) => void; + setStencilRef: (value: number) => void; + + // Draw commands. + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-draw + */ + draw: ( + vertexCount: number, + instanceCount?: number, + firstVertex?: number, + firstInstance?: number, + ) => void; + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-drawindexed + */ + drawIndexed: ( + indexCount: number, + instanceCount?: number, + firstIndex?: number, + baseVertex?: number, + firstInstance?: number, + ) => void; + /** + * WebGPU only. + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-drawindirect + */ + drawIndirect: (indirectBuffer: Buffer, indirectOffset: number) => void; + + // Query system. + beginOcclusionQuery: (dstOffs: number) => void; + endOcclusionQuery: (dstOffs: number) => void; +} + +/** + * @see https://www.w3.org/TR/webgpu/#compute-passes + */ +export interface ComputePass extends DebugCommandsMixin { + setPipeline: (pipeline: ComputePipeline) => void; + setBindings: (bindings: Bindings, dynamicByteOffsets?: number[]) => void; + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpucomputepassencoder-dispatchworkgroups + */ + dispatchWorkgroups: ( + workgroupCountX: number, + workgroupCountY?: number, + workgroupCountZ?: number, + ) => void; + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpucomputepassencoder-dispatchworkgroupsindirect + */ + dispatchWorkgroupsIndirect: ( + indirectBuffer: Buffer, + indirectOffset: number, + ) => void; +} + +export enum QueryPoolType { + OcclusionConservative, +} +/** + * Device represents a "virtual GPU" + * @see https://www.w3.org/TR/webgpu/#gpu-device + * + * Support following backends: + * * webgl1 CanvasWebGLRenderingContext + * * WebGL2 CanvasWebGL2RenderingContext + * * WebGPU GPUDevice + * + * A bit about the design of this API; all resources are "opaque", meaning you cannot look at the + * implementation details or underlying fields of the resources, and most objects cannot have their + * creation parameters modified after they are created. So, while buffers and textures can have their + * contents changed through data upload passes, they cannot be resized after creation. Create a new object + * and destroy the old one if you wish to "resize" it. + */ +export interface Device { + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpudevice-createbuffer + */ + createBuffer: (descriptor: BufferDescriptor) => Buffer; + createTexture: (descriptor: TextureDescriptor) => Texture; + createSampler: (descriptor: SamplerDescriptor) => Sampler; + createRenderTarget: (descriptor: RenderTargetDescriptor) => RenderTarget; + createRenderTargetFromTexture: (texture: Texture) => RenderTarget; + createProgram: (program: ProgramDescriptor) => Program; + createBindings: (bindingsDescriptor: BindingsDescriptor) => Bindings; + createInputLayout: ( + inputLayoutDescriptor: InputLayoutDescriptor, + ) => InputLayout; + createRenderPipeline: ( + descriptor: RenderPipelineDescriptor, + ) => RenderPipeline; + createComputePipeline: ( + descriptor: ComputePipelineDescriptor, + ) => ComputePipeline; + createReadback: () => Readback; + createQueryPool: (type: QueryPoolType, elemCount: number) => QueryPool; + + createRenderPass: (renderPassDescriptor: RenderPassDescriptor) => RenderPass; + createComputePass: () => ComputePass; + + beginFrame(): void; + endFrame(): void; + submitPass: (pass: RenderPass | ComputePass) => void; + destroy(): void; + + // Render pipeline compilation control. + pipelineQueryReady: (o: RenderPipeline) => boolean; + pipelineForceReady: (o: RenderPipeline) => void; + + copySubTexture2D: ( + dst: Texture, + dstX: number, + dstY: number, + src: Texture, + srcX: number, + srcY: number, + ) => void; + + // Information queries. + queryLimits: () => DeviceLimits; + queryTextureFormatSupported: ( + format: Format, + width: number, + height: number, + ) => boolean; + queryPlatformAvailable: () => boolean; + queryVendorInfo: () => VendorInfo; + queryRenderPass: (o: RenderPass) => Readonly; + queryRenderTarget: (o: RenderTarget) => Readonly; + + // Debugging. + setResourceName: (o: Resource, s: string) => void; + setResourceLeakCheck: (o: Resource, v: boolean) => void; + checkForLeaks: () => void; + programPatched: (o: Program, descriptor: ProgramDescriptor) => void; +} diff --git a/src/api/utils/assert.ts b/src/api/utils/assert.ts new file mode 100644 index 0000000..e1f20c7 --- /dev/null +++ b/src/api/utils/assert.ts @@ -0,0 +1,11 @@ +export function assert(b: boolean, message = ''): asserts b { + if (!b) { + console.error(new Error().stack); + throw new Error(`Assert fail: ${message}`); + } +} + +export function assertExists(v: T | null | undefined): T { + if (v !== undefined && v !== null) return v; + else throw new Error('Missing object'); +} diff --git a/src/api/utils/color.ts b/src/api/utils/color.ts new file mode 100644 index 0000000..8848dc7 --- /dev/null +++ b/src/api/utils/color.ts @@ -0,0 +1,31 @@ +import type { Color } from '../interfaces'; + +export function colorEqual(c0: Readonly, c1: Readonly): boolean { + return c0.r === c1.r && c0.g === c1.g && c0.b === c1.b && c0.a === c1.a; +} + +export function colorCopy(dst: Color, src: Readonly): void { + dst.r = src.r; + dst.g = src.g; + dst.b = src.b; + dst.a = src.a; +} + +export function colorNewCopy(src: Readonly): Color { + const { r, g, b, a } = src; + return { r, g, b, a }; +} + +export function colorNewFromRGBA( + r: number, + g: number, + b: number, + a = 1.0, +): Color { + return { r, g, b, a }; +} + +export const TransparentBlack = colorNewFromRGBA(0, 0, 0, 0); +export const OpaqueBlack = colorNewFromRGBA(0, 0, 0, 1); +export const TransparentWhite = colorNewFromRGBA(1, 1, 1, 0); +export const OpaqueWhite = colorNewFromRGBA(1, 1, 1, 1); diff --git a/src/api/utils/depth.ts b/src/api/utils/depth.ts new file mode 100644 index 0000000..1282f2f --- /dev/null +++ b/src/api/utils/depth.ts @@ -0,0 +1,85 @@ +import type { mat4 } from 'gl-matrix'; +import { CompareMode } from '../interfaces'; + +/** + * @see https://forum.babylonjs.com/t/reverse-depth-buffer-z-buffer/6905/2 + */ +export const IsDepthReversed = true; + +export function reverseDepthForPerspectiveProjectionMatrix( + m: mat4, + isDepthReversed = IsDepthReversed, +): void { + if (isDepthReversed) { + m[10] = -m[10]; + m[14] = -m[14]; + } +} + +export function reverseDepthForOrthographicProjectionMatrix( + m: mat4, + isDepthReversed = IsDepthReversed, +): void { + if (isDepthReversed) { + m[10] = -m[10]; + m[14] = -m[14] + 1; + } +} + +export function reverseDepthForCompareMode( + compareMode: CompareMode, + isDepthReversed = IsDepthReversed, +): CompareMode { + if (isDepthReversed) { + switch (compareMode) { + case CompareMode.LESS: + return CompareMode.GREATER; + case CompareMode.LEQUAL: + return CompareMode.GEQUAL; + case CompareMode.GEQUAL: + return CompareMode.LEQUAL; + case CompareMode.GREATER: + return CompareMode.LESS; + default: + return compareMode; + } + } else { + return compareMode; + } +} + +export function reverseDepthForClearValue( + n: number, + isDepthReversed = IsDepthReversed, +): number { + if (isDepthReversed) { + return 1.0 - n; + } else { + return n; + } +} + +export function reverseDepthForDepthOffset( + n: number, + isDepthReversed = IsDepthReversed, +): number { + if (isDepthReversed) { + return -n; + } else { + return n; + } +} + +export function compareDepthValues( + a: number, + b: number, + op: CompareMode, + isDepthReversed = IsDepthReversed, +): boolean { + op = reverseDepthForCompareMode(op, isDepthReversed); + if (op === CompareMode.LESS) return a < b; + else if (op === CompareMode.LEQUAL) return a <= b; + else if (op === CompareMode.GREATER) return a > b; + else if (op === CompareMode.GEQUAL) return a >= b; + else throw new Error('whoops'); +} diff --git a/src/api/utils/endian.ts b/src/api/utils/endian.ts new file mode 100644 index 0000000..f703d11 --- /dev/null +++ b/src/api/utils/endian.ts @@ -0,0 +1,15 @@ +export enum Endianness { + LITTLE_ENDIAN, + BIG_ENDIAN, +} + +const test: Uint16Array = new Uint16Array([0xfeff]); +const testView: DataView = new DataView(test.buffer); +const systemEndianness: Endianness = + testView.getUint8(0) == 0xff + ? Endianness.LITTLE_ENDIAN + : Endianness.BIG_ENDIAN; + +export function getSystemEndianness(): Endianness { + return systemEndianness; +} diff --git a/src/api/utils/hash.ts b/src/api/utils/hash.ts new file mode 100644 index 0000000..1d79ee5 --- /dev/null +++ b/src/api/utils/hash.ts @@ -0,0 +1,338 @@ +import { isNil } from '@antv/util'; +import type { Format } from '../format'; +import type { + AttachmentState, + BindingsDescriptor, + BufferBinding, + ChannelBlendState, + InputLayoutBufferDescriptor, + InputLayoutDescriptor, + MegaStateDescriptor, + Program, + RenderPipelineDescriptor, + SamplerBinding, + SamplerDescriptor, + VertexAttributeDescriptor, +} from '../interfaces'; +import { colorEqual } from './color'; +import { copyMegaState } from './states'; + +type EqualFunc = (a: K, b: K) => boolean; +export function arrayEqual(a: T[], b: T[], e: EqualFunc): boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) if (!e(a[i], b[i])) return false; + return true; +} + +type CopyFunc = (a: T) => T; +export function arrayCopy(a: T[], copyFunc: CopyFunc): T[] { + const b = Array(a.length); + for (let i = 0; i < a.length; i++) b[i] = copyFunc(a[i]); + return b; +} + +function bufferBindingEquals( + a: Readonly, + b: Readonly, +): boolean { + return ( + a.buffer === b.buffer && + a.size === b.size && + a.binding === b.binding && + a.offset === b.offset + ); +} + +function samplerBindingEquals( + a: Readonly, + b: Readonly, +): boolean { + if (a === null) return b === null; + if (b === null) return false; + return ( + a.sampler === b.sampler && + a.texture === b.texture && + a.dimension === b.dimension && + a.formatKind === b.formatKind && + a.comparison === b.comparison + ); +} + +export function bindingsDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + if (a.samplerBindings?.length !== b.samplerBindings?.length) return false; + if ( + a.samplerBindings && + b.samplerBindings && + !arrayEqual(a.samplerBindings, b.samplerBindings, samplerBindingEquals) + ) + return false; + if ( + a.uniformBufferBindings && + b.uniformBufferBindings && + !arrayEqual( + a.uniformBufferBindings, + b.uniformBufferBindings, + bufferBindingEquals, + ) + ) + return false; + return true; +} + +function channelBlendStateEquals( + a: Readonly, + b: Readonly, +): boolean { + return ( + a.blendMode == b.blendMode && + a.blendSrcFactor === b.blendSrcFactor && + a.blendDstFactor === b.blendDstFactor + ); +} + +function attachmentStateEquals( + a: Readonly, + b: Readonly, +): boolean { + if (!channelBlendStateEquals(a.rgbBlendState, b.rgbBlendState)) return false; + if (!channelBlendStateEquals(a.alphaBlendState, b.alphaBlendState)) + return false; + if (a.channelWriteMask !== b.channelWriteMask) return false; + return true; +} + +function megaStateDescriptorEquals( + a: MegaStateDescriptor, + b: MegaStateDescriptor, +): boolean { + if ( + !arrayEqual(a.attachmentsState, b.attachmentsState, attachmentStateEquals) + ) + return false; + if ( + a.blendConstant && + b.blendConstant && + !colorEqual(a.blendConstant, b.blendConstant) + ) + return false; + + return ( + a.depthCompare === b.depthCompare && + a.depthWrite === b.depthWrite && + a.stencilCompare === b.stencilCompare && + a.stencilWrite === b.stencilWrite && + a.stencilPassOp === b.stencilPassOp && + a.stencilRef === b.stencilRef && + a.cullMode === b.cullMode && + a.frontFace === b.frontFace && + a.polygonOffset === b.polygonOffset + ); +} + +function programEquals(a: Readonly, b: Readonly): boolean { + return a.id === b.id; +} + +function formatEquals(a: Format | null, b: Format | null): boolean { + return a === b; +} + +export function renderPipelineDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + if (a.topology !== b.topology) return false; + if (a.inputLayout !== b.inputLayout) return false; + if (a.sampleCount !== b.sampleCount) return false; + if ( + a.megaStateDescriptor && + b.megaStateDescriptor && + !megaStateDescriptorEquals(a.megaStateDescriptor, b.megaStateDescriptor) + ) + return false; + if (!programEquals(a.program, b.program)) return false; + if ( + !arrayEqual( + a.colorAttachmentFormats, + b.colorAttachmentFormats, + formatEquals, + ) + ) + return false; + if (a.depthStencilAttachmentFormat !== b.depthStencilAttachmentFormat) + return false; + return true; +} + +export function vertexAttributeDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + return ( + a.bufferIndex === b.bufferIndex && + a.bufferByteOffset === b.bufferByteOffset && + a.location === b.location && + a.format === b.format && + a.divisor === b.divisor + ); +} + +export function inputLayoutBufferDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + if (isNil(a)) return isNil(b); + if (isNil(b)) return false; + return a.byteStride === b.byteStride && a.stepMode === b.stepMode; +} + +export function inputLayoutDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + if (a.indexBufferFormat !== b.indexBufferFormat) return false; + if ( + !arrayEqual( + a.vertexBufferDescriptors, + b.vertexBufferDescriptors, + inputLayoutBufferDescriptorEquals, + ) + ) + return false; + if ( + !arrayEqual( + a.vertexAttributeDescriptors, + b.vertexAttributeDescriptors, + vertexAttributeDescriptorEquals, + ) + ) + return false; + if (!programEquals(a.program, b.program)) return false; + return true; +} + +export function samplerDescriptorEquals( + a: Readonly, + b: Readonly, +): boolean { + return ( + a.wrapS === b.wrapS && + a.wrapT === b.wrapT && + a.minFilter === b.minFilter && + a.magFilter === b.magFilter && + a.mipFilter === b.mipFilter && + a.minLOD === b.minLOD && + a.maxLOD === b.maxLOD && + a.maxAnisotropy === b.maxAnisotropy && + a.compareMode === b.compareMode + ); +} + +export function samplerBindingCopy( + a: Readonly, +): SamplerBinding { + const sampler = a.sampler; + const texture = a.texture; + const dimension = a.dimension; + const formatKind = a.formatKind; + const comparison = a.comparison; + return { sampler, texture, dimension, formatKind, comparison }; +} + +export function bufferBindingCopy(a: Readonly): BufferBinding { + const buffer = a.buffer; + const size = a.size; + const binding = a.binding; + const offset = a.offset; + return { binding, buffer, offset, size }; +} + +export function bindingsDescriptorCopy( + a: Readonly, +): BindingsDescriptor { + const samplerBindings = + a.samplerBindings && arrayCopy(a.samplerBindings, samplerBindingCopy); + const uniformBufferBindings = + a.uniformBufferBindings && + arrayCopy(a.uniformBufferBindings, bufferBindingCopy); + return { + samplerBindings, + uniformBufferBindings, + pipeline: a.pipeline, + }; +} + +export function renderPipelineDescriptorCopy( + a: Readonly, +): RenderPipelineDescriptor { + const inputLayout = a.inputLayout; + const program = a.program; + const topology = a.topology; + const megaStateDescriptor = + a.megaStateDescriptor && copyMegaState(a.megaStateDescriptor); + const colorAttachmentFormats = a.colorAttachmentFormats.slice(); + const depthStencilAttachmentFormat = a.depthStencilAttachmentFormat; + const sampleCount = a.sampleCount; + return { + inputLayout, + megaStateDescriptor, + program, + topology, + colorAttachmentFormats, + depthStencilAttachmentFormat, + sampleCount, + }; +} + +export function vertexAttributeDescriptorCopy( + a: Readonly, +): VertexAttributeDescriptor { + const location = a.location; + const format = a.format; + const bufferIndex = a.bufferIndex; + const bufferByteOffset = a.bufferByteOffset; + const divisor = a.divisor; + return { + location, + format, + bufferIndex, + bufferByteOffset, + divisor, + }; +} + +export function inputLayoutBufferDescriptorCopy( + a: Readonly, +): InputLayoutBufferDescriptor | null { + if (!isNil(a)) { + const byteStride = a.byteStride; + const stepMode = a.stepMode; + return { byteStride, stepMode }; + } else { + return a; + } +} + +export function inputLayoutDescriptorCopy( + a: Readonly, +): InputLayoutDescriptor { + const vertexAttributeDescriptors = arrayCopy( + a.vertexAttributeDescriptors, + vertexAttributeDescriptorCopy, + ); + const vertexBufferDescriptors = arrayCopy( + a.vertexBufferDescriptors, + inputLayoutBufferDescriptorCopy, + ); + const indexBufferFormat = a.indexBufferFormat; + const program = a.program; + return { + vertexAttributeDescriptors, + vertexBufferDescriptors, + indexBufferFormat, + program, + }; +} diff --git a/src/api/utils/index.ts b/src/api/utils/index.ts new file mode 100644 index 0000000..6c18c6b --- /dev/null +++ b/src/api/utils/index.ts @@ -0,0 +1,7 @@ +export * from './assert'; +export * from './color'; +export * from './depth'; +export * from './states'; +export * from './hash'; +export * from './endian'; +export * from './uniform'; diff --git a/src/api/utils/states.ts b/src/api/utils/states.ts new file mode 100644 index 0000000..5d76186 --- /dev/null +++ b/src/api/utils/states.ts @@ -0,0 +1,284 @@ +import type { + AttachmentState, + ChannelBlendState, + MegaStateDescriptor, + SamplerBinding, +} from '../interfaces'; +import { + BlendFactor, + BlendMode, + ChannelWriteMask, + CompareMode, + CullMode, + FrontFace, + SamplerFormatKind, + StencilOp, + TextureDimension, +} from '../interfaces'; +import { colorCopy, colorNewCopy, TransparentBlack } from './color'; +// import { reverseDepthForCompareMode } from './depth'; + +export function isPowerOfTwo(n: number): boolean { + return !!(n && (n & (n - 1)) === 0); +} + +export function fallbackUndefined(v: T | null | undefined, fallback: T): T { + return v !== null && v !== undefined ? v : fallback; +} + +export function nullify(v: T | undefined | null): T | null { + return v === undefined ? null : v; +} + +export function fillArray(L: T[], n: number, v: T): void { + L.length = n; + L.fill(v); +} + +export function align(n: number, multiple: number): number { + const mask = multiple - 1; + return (n + mask) & ~mask; +} + +export function alignNonPowerOfTwo(n: number, multiple: number): number { + return (((n + multiple - 1) / multiple) | 0) * multiple; +} + +// @see https://github.com/d3/d3-array#bisectRight +export function bisectRight( + L: T[], + e: T, + compare: (a: T, b: T) => number, +): number { + let lo = 0, + hi = L.length; + while (lo < hi) { + const mid = lo + ((hi - lo) >>> 1); + const cmp = compare(e, L[mid]); + if (cmp < 0) hi = mid; + else lo = mid + 1; + } + + return lo; +} + +export function spliceBisectRight( + L: T[], + e: T, + compare: (a: T, b: T) => number, +): void { + const idx = bisectRight(L, e, compare); + L.splice(idx, 0, e); +} + +export function setBitFlagEnabled( + v: number, + mask: number, + enabled: boolean, +): number { + if (enabled) v |= mask; + else v &= ~mask; + return v; +} + +export function nArray(n: number, c: () => T): T[] { + const d = new Array(n); + for (let i = 0; i < n; i++) d[i] = c(); + return d; +} + +export function prependLineNo(str: string, lineStart = 1) { + const lines = str.split('\n'); + return lines + .map((s, i) => `${leftPad('' + (lineStart + i), 4, ' ')} ${s}`) + .join('\n'); +} + +export function leftPad(S: string, spaces: number, ch = '0'): string { + while (S.length < spaces) S = `${ch}${S}`; + return S; +} + +export function range(start: number, count: number): number[] { + const L: number[] = []; + for (let i = start; i < start + count; i++) L.push(i); + return L; +} + +function copyChannelBlendState( + dst: ChannelBlendState, + src: ChannelBlendState, +): void { + dst.blendDstFactor = src.blendDstFactor; + dst.blendSrcFactor = src.blendSrcFactor; + dst.blendMode = src.blendMode; +} + +export function copyAttachmentState( + dst: AttachmentState | undefined, + src: AttachmentState, +): AttachmentState { + if (dst === undefined) { + dst = { + rgbBlendState: {} as ChannelBlendState, + alphaBlendState: {} as ChannelBlendState, + channelWriteMask: 0, + }; + } + + copyChannelBlendState(dst.rgbBlendState, src.rgbBlendState); + copyChannelBlendState(dst.alphaBlendState, src.alphaBlendState); + dst.channelWriteMask = src.channelWriteMask; + return dst; +} + +function copyAttachmentsState( + dst: AttachmentState[], + src: AttachmentState[], +): void { + if (dst.length !== src.length) dst.length = src.length; + for (let i = 0; i < src.length; i++) + dst[i] = copyAttachmentState(dst[i], src[i]); +} + +export function setMegaStateFlags( + dst: MegaStateDescriptor, + src: Partial, +): void { + if (src.attachmentsState !== undefined) { + copyAttachmentsState(dst.attachmentsState, src.attachmentsState); + } + + if (dst.blendConstant && src.blendConstant) { + colorCopy(dst.blendConstant, src.blendConstant); + } + + dst.depthCompare = fallbackUndefined(src.depthCompare, dst.depthCompare); + dst.depthWrite = fallbackUndefined(src.depthWrite, dst.depthWrite); + dst.stencilCompare = fallbackUndefined( + src.stencilCompare, + dst.stencilCompare, + ); + dst.stencilWrite = fallbackUndefined(src.stencilWrite, dst.stencilWrite); + dst.stencilPassOp = fallbackUndefined(src.stencilPassOp, dst.stencilPassOp); + dst.stencilRef = fallbackUndefined(src.stencilRef, dst.stencilRef); + dst.cullMode = fallbackUndefined(src.cullMode, dst.cullMode); + dst.frontFace = fallbackUndefined(src.frontFace, dst.frontFace); + dst.polygonOffset = fallbackUndefined(src.polygonOffset, dst.polygonOffset); +} + +export function copyMegaState(src: MegaStateDescriptor): MegaStateDescriptor { + const dst = Object.assign({}, src); + // Copy fields that need copying. + dst.attachmentsState = []; + copyAttachmentsState(dst.attachmentsState, src.attachmentsState); + dst.blendConstant = dst.blendConstant && colorNewCopy(dst.blendConstant); + return dst; +} + +export interface AttachmentStateSimple { + channelWriteMask: ChannelWriteMask; + rgbBlendMode?: BlendMode; + alphaBlendMode?: BlendMode; + rgbBlendSrcFactor?: BlendFactor; + alphaBlendSrcFactor?: BlendFactor; + rgbBlendDstFactor?: BlendFactor; + alphaBlendDstFactor?: BlendFactor; +} + +export function copyAttachmentStateFromSimple( + dst: AttachmentState, + src: Partial, +): void { + if (src.channelWriteMask !== undefined) { + dst.channelWriteMask = src.channelWriteMask; + } + + if (src.rgbBlendMode !== undefined) { + dst.rgbBlendState.blendMode = src.rgbBlendMode; + } + + if (src.alphaBlendMode !== undefined) { + dst.alphaBlendState.blendMode = src.alphaBlendMode; + } + + if (src.rgbBlendSrcFactor !== undefined) { + dst.rgbBlendState.blendSrcFactor = src.rgbBlendSrcFactor; + } + if (src.alphaBlendSrcFactor !== undefined) { + dst.alphaBlendState.blendSrcFactor = src.alphaBlendSrcFactor; + } + + if (src.rgbBlendDstFactor !== undefined) { + dst.rgbBlendState.blendDstFactor = src.rgbBlendDstFactor; + } + if (src.alphaBlendDstFactor !== undefined) { + dst.alphaBlendState.blendDstFactor = src.alphaBlendDstFactor; + } +} + +const defaultBlendState: ChannelBlendState = { + blendMode: BlendMode.ADD, + blendSrcFactor: BlendFactor.ONE, + blendDstFactor: BlendFactor.ZERO, +}; + +export const defaultMegaState: MegaStateDescriptor = { + attachmentsState: [ + { + channelWriteMask: ChannelWriteMask.ALL, + rgbBlendState: defaultBlendState, + alphaBlendState: defaultBlendState, + }, + ], + + blendConstant: colorNewCopy(TransparentBlack), + depthWrite: true, + depthCompare: CompareMode.LEQUAL, + // depthCompare: reverseDepthForCompareMode(CompareMode.LessEqual), + // stencilCompare: CompareMode.Never, + stencilCompare: CompareMode.ALWAYS, + stencilWrite: false, + stencilPassOp: StencilOp.KEEP, + stencilRef: 0, + cullMode: CullMode.NONE, + frontFace: FrontFace.CCW, + polygonOffset: false, +}; + +export function makeMegaState( + other: Partial | null = null, + src: MegaStateDescriptor = defaultMegaState, +) { + const dst = copyMegaState(src); + if (other !== null) setMegaStateFlags(dst, other); + return dst; +} + +export const fullscreenMegaState = makeMegaState( + { depthCompare: CompareMode.ALWAYS, depthWrite: false }, + defaultMegaState, +); + +export function setAttachmentStateSimple( + dst: Partial, + simple: Partial, +): Partial { + if (dst.attachmentsState === undefined) { + dst.attachmentsState = []; + copyAttachmentsState( + dst.attachmentsState, + defaultMegaState.attachmentsState, + ); + } + + copyAttachmentStateFromSimple(dst.attachmentsState[0], simple); + return dst; +} + +export const defaultBindingLayoutSamplerDescriptor: SamplerBinding = { + texture: null, + sampler: null, + formatKind: SamplerFormatKind.Float, + dimension: TextureDimension.TEXTURE_2D, +}; diff --git a/src/api/utils/uniform.ts b/src/api/utils/uniform.ts new file mode 100644 index 0000000..afbdf60 --- /dev/null +++ b/src/api/utils/uniform.ts @@ -0,0 +1,376 @@ +/** + * ported from luma.gl + * uniformXXX for WebGL1 according to format + */ +import { GL } from '../constants'; +import { assert } from './assert'; + +// if array name then clean the array brackets +const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/; + +export function parseUniformName(name: string): { + name: string; + isArray: boolean; + length: number; +} { + // Shortcut to avoid redundant or bad matches + if (name[name.length - 1] !== ']') { + return { + name, + length: 1, + isArray: false, + }; + } + + const matches = name.match(UNIFORM_NAME_REGEXP); + if (!matches || matches.length < 2) { + throw new Error(`Failed to parse GLSL uniform name ${name}`); + } + + return { + name: matches[1], + length: Number(matches[2]) || 1, + isArray: Boolean(matches[2]), + }; +} + +function getSamplerSetter() { + let cache = null; + return ( + gl: WebGLRenderingContextBase, + location: WebGLUniformLocation, + // eslint-disable-next-line + value: any, + ) => { + const update = cache !== value; + if (update) { + gl.uniform1i(location, value); + cache = value; + } + + return update; + }; +} + +function getArraySetter(functionName: string, toArray, size, uniformSetter) { + let cache: Float32Array | null = null; + let cacheLength = null; + // eslint-disable-next-line + return (gl: WebGLRenderingContextBase, location: number, value: any) => { + const arrayValue = toArray(value, size); + const length = arrayValue.length; + let update = false; + if (cache === null) { + cache = new Float32Array(length); + cacheLength = length; + update = true; + } else { + assert(cacheLength === length, 'Uniform length cannot change.'); + for (let i = 0; i < length; ++i) { + if (arrayValue[i] !== cache[i]) { + update = true; + break; + } + } + } + if (update) { + uniformSetter(gl, functionName, location, arrayValue); + cache.set(arrayValue); + } + + return update; + }; +} + +function setVectorUniform( + gl: WebGLRenderingContextBase, + functionName: string, + location: number, + // eslint-disable-next-line + value: any, +) { + gl[functionName](location, value); +} + +function setMatrixUniform( + gl: WebGLRenderingContextBase, + functionName: string, + location: number, + // eslint-disable-next-line + value: any, +) { + gl[functionName](location, false, value); +} + +const FLOAT_ARRAY = {}; +const INT_ARRAY = {}; +const UINT_ARRAY = {}; +const array1: number[] = [0]; +type ValueType = boolean | number | number[] | boolean[] | ArrayBufferView; +function toTypedArray( + value: ValueType, + uniformLength: number, + Type: + | Float32ArrayConstructor + | Uint16ArrayConstructor + | Uint32ArrayConstructor + | Int32ArrayConstructor, + // eslint-disable-next-line + cache: Record, +): ArrayBufferView { + // convert boolean uniforms to Number + if (uniformLength === 1 && typeof value === 'boolean') { + value = value ? 1 : 0; + } + if (Number.isFinite(value)) { + array1[0] = value as number; + value = array1; + } + const length = (value as number[]).length; + if (length % uniformLength) { + // log.warn(`Uniform size should be multiples of ${uniformLength}`, value)(); + } + + if (value instanceof Type) { + return value; + } + let result = cache[length]; + if (!result) { + result = new Type(length); + cache[length] = result; + } + for (let i = 0; i < length; i++) { + result[i] = value[i]; + } + return result; +} + +function toFloatArray(value: ValueType, uniformLength: number) { + return toTypedArray(value, uniformLength, Float32Array, FLOAT_ARRAY); +} + +function toIntArray(value: ValueType, uniformLength: number) { + return toTypedArray(value, uniformLength, Int32Array, INT_ARRAY); +} + +function toUIntArray(value: ValueType, uniformLength: number) { + return toTypedArray(value, uniformLength, Uint32Array, UINT_ARRAY); +} + +export const UNIFORM_SETTERS = { + // WEBGL1 + [GL.FLOAT]: getArraySetter.bind( + null, + 'uniform1fv', + toFloatArray, + 1, + setVectorUniform, + ), + [GL.FLOAT_VEC2]: getArraySetter.bind( + null, + 'uniform2fv', + toFloatArray, + 2, + setVectorUniform, + ), + [GL.FLOAT_VEC3]: getArraySetter.bind( + null, + 'uniform3fv', + toFloatArray, + 3, + setVectorUniform, + ), + [GL.FLOAT_VEC4]: getArraySetter.bind( + null, + 'uniform4fv', + toFloatArray, + 4, + setVectorUniform, + ), + + [GL.INT]: getArraySetter.bind( + null, + 'uniform1iv', + toIntArray, + 1, + setVectorUniform, + ), + [GL.INT_VEC2]: getArraySetter.bind( + null, + 'uniform2iv', + toIntArray, + 2, + setVectorUniform, + ), + [GL.INT_VEC3]: getArraySetter.bind( + null, + 'uniform3iv', + toIntArray, + 3, + setVectorUniform, + ), + [GL.INT_VEC4]: getArraySetter.bind( + null, + 'uniform4iv', + toIntArray, + 4, + setVectorUniform, + ), + + [GL.BOOL]: getArraySetter.bind( + null, + 'uniform1iv', + toIntArray, + 1, + setVectorUniform, + ), + [GL.BOOL_VEC2]: getArraySetter.bind( + null, + 'uniform2iv', + toIntArray, + 2, + setVectorUniform, + ), + [GL.BOOL_VEC3]: getArraySetter.bind( + null, + 'uniform3iv', + toIntArray, + 3, + setVectorUniform, + ), + [GL.BOOL_VEC4]: getArraySetter.bind( + null, + 'uniform4iv', + toIntArray, + 4, + setVectorUniform, + ), + + // uniformMatrix(false): don't transpose the matrix + [GL.FLOAT_MAT2]: getArraySetter.bind( + null, + 'uniformMatrix2fv', + toFloatArray, + 4, + setMatrixUniform, + ), + [GL.FLOAT_MAT3]: getArraySetter.bind( + null, + 'uniformMatrix3fv', + toFloatArray, + 9, + setMatrixUniform, + ), + [GL.FLOAT_MAT4]: getArraySetter.bind( + null, + 'uniformMatrix4fv', + toFloatArray, + 16, + setMatrixUniform, + ), + + // WEBGL2 - unsigned integers, irregular matrices, additional texture samplers + + [GL.UNSIGNED_INT]: getArraySetter.bind( + null, + 'uniform1uiv', + toUIntArray, + 1, + setVectorUniform, + ), + [GL.UNSIGNED_INT_VEC2]: getArraySetter.bind( + null, + 'uniform2uiv', + toUIntArray, + 2, + setVectorUniform, + ), + [GL.UNSIGNED_INT_VEC3]: getArraySetter.bind( + null, + 'uniform3uiv', + toUIntArray, + 3, + setVectorUniform, + ), + [GL.UNSIGNED_INT_VEC4]: getArraySetter.bind( + null, + 'uniform4uiv', + toUIntArray, + 4, + setVectorUniform, + ), + + // uniformMatrix(false): don't transpose the matrix + [GL.FLOAT_MAT2x3]: getArraySetter.bind( + null, + 'uniformMatrix2x3fv', + toFloatArray, + 6, + setMatrixUniform, + ), + [GL.FLOAT_MAT2x4]: getArraySetter.bind( + null, + 'uniformMatrix2x4fv', + toFloatArray, + 8, + setMatrixUniform, + ), + [GL.FLOAT_MAT3x2]: getArraySetter.bind( + null, + 'uniformMatrix3x2fv', + toFloatArray, + 6, + setMatrixUniform, + ), + [GL.FLOAT_MAT3x4]: getArraySetter.bind( + null, + 'uniformMatrix3x4fv', + toFloatArray, + 12, + setMatrixUniform, + ), + [GL.FLOAT_MAT4x2]: getArraySetter.bind( + null, + 'uniformMatrix4x2fv', + toFloatArray, + 8, + setMatrixUniform, + ), + [GL.FLOAT_MAT4x3]: getArraySetter.bind( + null, + 'uniformMatrix4x3fv', + toFloatArray, + 12, + setMatrixUniform, + ), + + [GL.SAMPLER_2D]: getSamplerSetter, + [GL.SAMPLER_CUBE]: getSamplerSetter, + + [GL.SAMPLER_3D]: getSamplerSetter, + [GL.SAMPLER_2D_SHADOW]: getSamplerSetter, + [GL.SAMPLER_2D_ARRAY]: getSamplerSetter, + [GL.SAMPLER_2D_ARRAY_SHADOW]: getSamplerSetter, + [GL.SAMPLER_CUBE_SHADOW]: getSamplerSetter, + [GL.INT_SAMPLER_2D]: getSamplerSetter, + [GL.INT_SAMPLER_3D]: getSamplerSetter, + [GL.INT_SAMPLER_CUBE]: getSamplerSetter, + [GL.INT_SAMPLER_2D_ARRAY]: getSamplerSetter, + [GL.UNSIGNED_INT_SAMPLER_2D]: getSamplerSetter, + [GL.UNSIGNED_INT_SAMPLER_3D]: getSamplerSetter, + [GL.UNSIGNED_INT_SAMPLER_CUBE]: getSamplerSetter, + [GL.UNSIGNED_INT_SAMPLER_2D_ARRAY]: getSamplerSetter, +}; + +export function getUniformSetter( + gl: WebGLRenderingContext, + location: WebGLUniformLocation, + info: WebGLActiveInfo, + // eslint-disable-next-line +): any { + const setter = UNIFORM_SETTERS[info.type]; + if (!setter) { + throw new Error(`Unknown GLSL uniform type ${info.type}`); + } + return setter().bind(null, gl, location); +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..9cb5657 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * from './api'; +export { WebGLDeviceContribution } from './webgl/WebGLDeviceContribution'; diff --git a/src/shader/compiler.ts b/src/shader/compiler.ts new file mode 100644 index 0000000..ae904cf --- /dev/null +++ b/src/shader/compiler.ts @@ -0,0 +1,449 @@ +import type { VendorInfo } from '../api'; +import { assert, ClipSpaceNearZ, ViewportOrigin } from '../api'; + +// const ES100_REPLACEMENTS: [RegExp, string][] = [ +// // In GLSL 1.00 ES these functions are provided by an extension +// [/\btexture(2D|2DProj|Cube)Lod\(/g, 'texture$1LodEXT('], + +// // Overloads in GLSL 3.00 map to individual functions. Note that we cannot +// // differentiate 2D,2DProj,Cube without type analysis so we choose the most common variant. +// [/\btexture\(/g, 'texture2D('], +// [/\btextureLod\(/g, 'texture2DLodEXT('], +// ]; + +function defineStr(k: string, v: string): string { + return `#define ${k} ${v}`; +} + +export function getDefines(shader: string): Record { + const defines = {}; + shader.replace(/^\s*#define\s*(\S*)\s*(\S*)\s*$/gm, (_, name, value) => { + const v = Number(value); + defines[name] = isNaN(v) ? value : v; + return ''; + }); + return defines; +} + +export function getAttributeLocations( + vert: string, + defines: Record, +): { location: number; name: string }[] { + const locations = []; + vert.replace( + /^\s*layout\(location\s*=\s*(\S*)\)\s*in\s+\S+\s*(.*);$/gm, + (_, location, name) => { + const l = Number(location); + locations.push({ location: isNaN(l) ? defines[location] : l, name }); + return ''; + }, + ); + return locations; +} + +/** + * struct DirectionalLight { + vec3 direction; + float intensity; + vec3 color; +}; + */ +interface StructInfo { + type: string; + uniforms: { + type: string; + name: string; + }[]; +} +export function getUniforms(vert: string) { + const uniformNames: string[] = []; + const structs: StructInfo[] = []; + + vert.replace( + /\s*struct\s*(.*)\s*{((?:\s*.*\s*)*?)};/g, + (_, type, uniformStr) => { + const uniforms = []; + uniformStr + .trim() + .split('\n') + .forEach((line) => { + const [type, name] = line.trim().split(/\s+/); + uniforms.push({ + type: type.trim(), + name: name.replace(';', '').trim(), + }); + }); + structs.push({ + type: type.trim(), + uniforms, + }); + return ''; + }, + ); + + vert.replace(/\s*uniform\s*.*\s*{((?:\s*.*\s*)*?)};/g, (_, uniforms) => { + uniforms + .trim() + .split('\n') + .forEach((line: string) => { + const result = line.trim().split(' '); + const type = result[0] || ''; + let name = result[1] || ''; + // DirectionalLight directionalLights[ NUM_DIR_LIGHTS ]; + const isArray = name.indexOf('[') > -1; + name = name.replace(';', '').replace('[', '').trim(); + // ignore conditional comments + if (type.startsWith('#')) { + return; + } + + // account for structs + if (type) { + const struct = structs.find((struct) => type === struct.type); + if (struct) { + if (isArray) { + for (let i = 0; i < 5; i++) { + struct.uniforms.forEach((uniform) => { + uniformNames.push(`${name}[${i}].${uniform.name}`); + }); + } + } else { + struct.uniforms.forEach((uniform) => { + uniformNames.push(`${name}.${uniform.name}`); + }); + } + } + } + + if (name) { + uniformNames.push(name); + } + }); + return ''; + }); + + return uniformNames; +} + +function parseBinding(layout: string | undefined): number | null { + if (layout === undefined) return null; + + const g = /binding\s*=\s*(\d+)/.exec(layout); + if (g !== null) { + const bindingNum = parseInt(g[1], 10); + if (!Number.isNaN(bindingNum)) return bindingNum; + } + + return null; +} + +function getSeparateSamplerTypes( + combinedSamplerType: string, +): [string, string] { + let samplerType = ``, + textureType = combinedSamplerType; + if (combinedSamplerType.endsWith(`Shadow`)) { + textureType = textureType.slice(0, -6); + samplerType = `Shadow`; + } + return [textureType, samplerType]; +} + +export function preprocessShader_GLSL( + vendorInfo: VendorInfo, + type: 'vert' | 'frag', + source: string, + defines: Record | null = null, +): string { + const isGLSL100 = vendorInfo.glslVersion === '#version 100'; + // const supportMRT = vendorInfo.supportMRT && !!features.MRT; + const supportMRT = false; + + const lines = source + .split('\n') + .map((n) => { + // Remove comments. + return n.replace(/[/][/].*$/, ''); + }) + .filter((n) => { + // Filter whitespace. + const isEmpty = !n || /^\s+$/.test(n); + return !isEmpty; + }); + + // #define KEY VAR + let definesString = ''; + if (defines !== null) + definesString = Object.keys(defines) + .map((key) => defineStr(key, defines[key])) + .join('\n'); + + let precision = + lines.find((line) => line.startsWith('precision')) || + 'precision mediump float;'; + let rest = lines.filter((line) => !line.startsWith('precision')).join('\n'); + let extraDefines = ''; + + if (vendorInfo.viewportOrigin === ViewportOrigin.UPPER_LEFT) { + extraDefines += `${defineStr(`VIEWPORT_ORIGIN_TL`, `1`)}\n`; + } + if (vendorInfo.clipSpaceNearZ === ClipSpaceNearZ.ZERO) { + extraDefines += `${defineStr(`CLIPSPACE_NEAR_ZERO`, `1`)}\n`; + } + + if (vendorInfo.explicitBindingLocations) { + let set = 0, + implicitBinding = 0, + location = 0; + + rest = rest.replace( + /^(layout\((.*)\))?\s*uniform(.+{)$/gm, + (substr, cap, layout, rest) => { + const layout2 = layout ? `${layout}, ` : ``; + return `layout(${layout2}set = ${set}, binding = ${implicitBinding++}) uniform ${rest}`; + }, + ); + + // XXX(jstpierre): WebGPU now binds UBOs and textures in different sets as a porting hack, hrm... + set++; + implicitBinding = 0; + + assert(vendorInfo.separateSamplerTextures); + rest = rest.replace( + /^(layout\((.*)\))?\s*uniform sampler(\w+) (.*);/gm, + (substr, cap, layout, combinedSamplerType, samplerName) => { + let binding = parseBinding(layout); + if (binding === null) binding = implicitBinding++; + + const [textureType, samplerType] = + getSeparateSamplerTypes(combinedSamplerType); + return type === 'frag' + ? ` +layout(set = ${set}, binding = ${ + binding * 2 + 0 + }) uniform texture${textureType} T_${samplerName}; +layout(set = ${set}, binding = ${ + binding * 2 + 1 + }) uniform sampler${samplerType} S_${samplerName};`.trim() + : ''; + }, + ); + + rest = rest.replace( + type === 'frag' ? /^\b(varying|in)\b/gm : /^\b(varying|out)\b/gm, + (substr, tok) => { + return `layout(location = ${location++}) ${tok}`; + }, + ); + + /** + * @see https://github.com/gfx-rs/naga/issues/1994 + */ + extraDefines += `${defineStr(`gl_VertexID`, `gl_VertexIndex`)}\n`; + extraDefines += `${defineStr(`gl_InstanceID`, `gl_InstanceIndex`)}\n`; + + // Workaround for Naga + // https://github.com/gfx-rs/naga/issues/1353 + precision = precision.replace(/^precision (.*) sampler(.*);$/gm, ''); + } else { + let implicitBinding = 0; + rest = rest.replace( + /^(layout\((.*)\))?\s*uniform sampler(\w+) (.*);/gm, + (substr, cap, layout, combinedSamplerType, samplerName) => { + let binding = parseBinding(layout); + if (binding === null) binding = implicitBinding++; + + return `uniform sampler${combinedSamplerType} ${samplerName}; // BINDING=${binding}`; + }, + ); + } + + if (vendorInfo.separateSamplerTextures) { + rest = rest.replace( + /\bSAMPLER_(\w+)\((.*?)\)/g, + (substr, combinedSamplerType, samplerName) => { + return `sampler${combinedSamplerType}(T_${samplerName}, S_${samplerName})`; + }, + ); + + rest = rest.replace(/\bTEXTURE\((.*?)\)/g, (substr, samplerName) => { + return `T_${samplerName}`; + }); + } else { + const samplerNames: [string, string][] = []; + rest = rest.replace( + /\bSAMPLER_(\w+)\((.*?)\)/g, + (substr, combinedSamplerType, samplerName) => { + samplerNames.push([samplerName, combinedSamplerType]); + return samplerName; + }, + ); + if (isGLSL100) { + samplerNames.forEach(([samplerName, combinedSamplerType]) => { + // texture(u_T) -> texture2D(u_T) or textureCube(u_T) + rest = rest.replace(new RegExp(`texture\\(${samplerName}`, 'g'), () => { + return `texture${combinedSamplerType}(${samplerName}`; + }); + }); + } + + rest = rest.replace(/\bTEXTURE\((.*?)\)/g, (substr, samplerName) => { + return samplerName; + }); + } + + // using #define means we can't use `const in/out` in params + // ${isGLSL100 && type === 'vert' ? '#define in attribute\n#define out varying' : ''} + // ${isGLSL100 && type === 'frag' ? '#define in varying' : ''} + + // headless-gl will throw the following error if we prepend `#version 100`: + // #version directive must occur before anything else, except for comments and white space + let concat = `${isGLSL100 ? '' : vendorInfo.glslVersion} +${isGLSL100 && supportMRT ? '#extension GL_EXT_draw_buffers : require' : ''} +${ + isGLSL100 && type === 'frag' + ? '#extension GL_OES_standard_derivatives : enable' + : '' +} +${precision} +${extraDefines} +${definesString} +${rest} +`.trim(); + + // out vec4 outputColor; -> layout(location = 0) out vec4 outputColor; + if (vendorInfo.explicitBindingLocations && type === 'frag') { + concat = concat.replace(/^\b(out)\b/gm, (substr, tok) => { + return `layout(location = 0) ${tok}`; + }); + } + + // GLSL 300 -> 100 + // @see https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html + if (isGLSL100) { + // in -> varying + if (type === 'frag') { + concat = concat.replace( + /^\s*in\s+(\S+)\s*(.*);$/gm, + (_, dataType, name) => { + return `varying ${dataType} ${name};\n`; + }, + ); + } + if (type === 'vert') { + // out -> varying + concat = concat.replace( + /^\s*out\s+(\S+)\s*(.*);$/gm, + (_, dataType, name) => { + return `varying ${dataType} ${name};\n`; + }, + ); + // in -> attribute + concat = concat.replace( + // /^\s*layout\(location\s*=\s*\d*\)\s*in\s*(.*)\s*(.*);$/gm, + /^\s*layout\(location\s*=\s*\S*\)\s*in\s+(\S+)\s*(.*);$/gm, + (_, dataType, name) => { + return `attribute ${dataType} ${name};\n`; + }, + ); + } + + // interface blocks supported in GLSL ES 3.00 and above only + concat = concat.replace( + /\s*uniform\s*.*\s*{((?:\s*.*\s*)*?)};/g, + (substr, uniforms) => { + return uniforms.trim().replace(/^.*$/gm, (uniform: string) => { + // eg. #ifdef + const trimmed = uniform.trim(); + if (trimmed.startsWith('#')) { + return trimmed; + } + return uniform ? `uniform ${trimmed}` : ''; + }); + }, + ); + + if (type === 'frag') { + let glFragColor: string; + concat = concat.replace( + /^\s*out\s+(\S+)\s*(.*);$/gm, + (_, dataType, name) => { + glFragColor = name; + return `${dataType} ${name};\n`; + }, + ); + + const lastIndexOfMain = concat.lastIndexOf('}'); + concat = + concat.substring(0, lastIndexOfMain) + + ` + gl_FragColor = vec4(${glFragColor}); +` + + concat.substring(lastIndexOfMain); + } + + // MRT + // if (supportMRT) { + // if (type === 'frag') { + // const gBuffers = []; + // concat = concat.replace( + // /^\s*layout\(location\s*=\s*\d*\)\s*out\s+vec4\s*(.*);$/gm, + // (_, buffer) => { + // gBuffers.push(buffer); + // return `vec4 ${buffer};\n`; + // }, + // ); + + // const lastIndexOfMain = concat.lastIndexOf('}'); + // concat = + // concat.substring(0, lastIndexOfMain) + + // ` + // ${gBuffers + // .map( + // (gBuffer, i) => `gl_FragData[${i}] = ${gBuffer}; + // `, + // ) + // .join('\n')}` + + // concat.substring(lastIndexOfMain); + // } + // } + + // remove layout(location = 0) + concat = concat.replace(/^\s*layout\((.*)\)/gm, ''); + + // replace texture with texture2D + // for (const [pattern, replacement] of ES100_REPLACEMENTS) { + // concat = concat.replace(pattern, replacement); + // } + } + + return concat; +} + +export interface ProgramDescriptorSimpleWithOrig { + vert: string; + frag: string; + preprocessedVert: string; + preprocessedFrag: string; +} + +export function preprocessProgram_GLSL( + vendorInfo: VendorInfo, + vert: string, + frag: string, + defines: Record | null = null, +): ProgramDescriptorSimpleWithOrig { + const preprocessedVert = preprocessShader_GLSL( + vendorInfo, + 'vert', + vert, + defines, + ); + const preprocessedFrag = preprocessShader_GLSL( + vendorInfo, + 'frag', + frag, + defines, + ); + return { vert, frag, preprocessedVert, preprocessedFrag }; +} diff --git a/src/shader/index.ts b/src/shader/index.ts new file mode 100644 index 0000000..b2a5775 --- /dev/null +++ b/src/shader/index.ts @@ -0,0 +1 @@ +export * from './compiler'; diff --git a/src/webgl/Bindings.ts b/src/webgl/Bindings.ts new file mode 100644 index 0000000..8504c3d --- /dev/null +++ b/src/webgl/Bindings.ts @@ -0,0 +1,72 @@ +import type { + Bindings, + BindingsDescriptor, + BufferBinding, + SamplerBinding, +} from '../api'; +import { ResourceType } from '../api'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; + +export interface BindingLayoutTable_GL { + firstUniformBuffer: number; + numUniformBuffers: number; + firstSampler: number; + numSamplers: number; +} + +export interface BindingLayouts_GL { + numSamplers: number; + numUniformBuffers: number; + bindingLayoutTables: BindingLayoutTable_GL[]; +} + +export class Bindings_GL extends ResourceBase_GL implements Bindings { + type: ResourceType.Bindings = ResourceType.Bindings; + + uniformBufferBindings: BufferBinding[]; + samplerBindings: (SamplerBinding | null)[]; + bindingLayouts: BindingLayouts_GL; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: BindingsDescriptor; + }) { + super({ id, device }); + + const { uniformBufferBindings, samplerBindings } = descriptor; + this.uniformBufferBindings = uniformBufferBindings || []; + this.samplerBindings = samplerBindings || []; + this.bindingLayouts = this.createBindingLayouts(); + } + + private createBindingLayouts(): BindingLayouts_GL { + let firstUniformBuffer = 0; + let firstSampler = 0; + const bindingLayoutTables: BindingLayoutTable_GL[] = []; + + // Support only 1 bindGroup for now. + const numUniformBuffers = this.uniformBufferBindings.length; + const numSamplers = this.samplerBindings.length; + + bindingLayoutTables.push({ + firstUniformBuffer, + numUniformBuffers, + firstSampler, + numSamplers, + }); + firstUniformBuffer += numUniformBuffers; + firstSampler += numSamplers; + + return { + numUniformBuffers: firstUniformBuffer, + numSamplers: firstSampler, + bindingLayoutTables, + }; + } +} diff --git a/src/webgl/Buffer.ts b/src/webgl/Buffer.ts new file mode 100644 index 0000000..b4ec2f2 --- /dev/null +++ b/src/webgl/Buffer.ts @@ -0,0 +1,201 @@ +import { Buffer, BufferDescriptor, BufferFrequencyHint, align } from '../api'; +import { BufferUsage, ResourceType } from '../api'; +import { isNumber } from '@antv/util'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { + getPlatformBuffer, + isWebGL2, + translateBufferHint, + translateBufferUsageToTarget, +} from './utils'; + +export class Buffer_GL extends ResourceBase_GL implements Buffer { + type: ResourceType.Buffer = ResourceType.Buffer; + + gl_buffer_pages: WebGLBuffer[]; + gl_target: GLenum; + usage: BufferUsage; + byteSize: number; + pageByteSize: number; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: BufferDescriptor; + }) { + super({ id, device }); + + const { viewOrSize, usage, hint = BufferFrequencyHint.STATIC } = descriptor; + const { uniformBufferMaxPageByteSize, gl } = device; + + const isUBO = usage & BufferUsage.UNIFORM; + + if (!isUBO) { + if (isWebGL2(gl)) { + // Temporarily unbind VAO when creating buffers to not stomp on the VAO configuration. + gl.bindVertexArray(null); + } else { + device.OES_vertex_array_object.bindVertexArrayOES(null); + } + } + + // const byteSize = isNumber(viewOrSize) + // ? viewOrSize * 4 + // : viewOrSize.byteLength * 4; + + const byteSize = isNumber(viewOrSize) + ? align(viewOrSize, 4) + : align(viewOrSize.byteLength, 4); + + this.gl_buffer_pages = []; + + let pageByteSize: number; + if (isUBO) { + // assert(byteSize % uniformBufferMaxPageByteSize === 0); + let byteSizeLeft = byteSize; + while (byteSizeLeft > 0) { + this.gl_buffer_pages.push( + this.createBufferPage( + Math.min(byteSizeLeft, uniformBufferMaxPageByteSize), + usage, + hint, + ), + ); + byteSizeLeft -= uniformBufferMaxPageByteSize; + } + + pageByteSize = uniformBufferMaxPageByteSize; + + // TODO: uniform in WebGL1 + } else { + this.gl_buffer_pages.push(this.createBufferPage(byteSize, usage, hint)); + pageByteSize = byteSize; + } + + this.pageByteSize = pageByteSize; + this.byteSize = byteSize; + this.usage = usage; + this.gl_target = translateBufferUsageToTarget(usage); + + // init data + if (!isNumber(viewOrSize)) { + this.setSubData(0, new Uint8Array(viewOrSize.buffer)); + } + + if (!isUBO) { + if (isWebGL2(gl)) { + gl.bindVertexArray(this.device['currentBoundVAO']); + } else { + device.OES_vertex_array_object.bindVertexArrayOES( + this.device['currentBoundVAO'], + ); + } + } + } + + setSubData( + dstByteOffset: number, + data: Uint8Array, + srcByteOffset = 0, + byteSize: number = data.byteLength - srcByteOffset, + ): void { + const gl = this.device.gl; + const { + // gl_target, + // byteSize: dstByteSize, + pageByteSize: dstPageByteSize, + } = this; + // Account for setSubData being called with a dstByteOffset that is beyond the end of the buffer. + // if (isWebGL2(gl) && gl_target === gl.UNIFORM_BUFFER) { + // // Manually check asserts for speed. + // if (!(dstByteOffset % dstPageByteSize === 0)) + // throw new Error( + // `Assert fail: (dstByteOffset [${dstByteOffset}] % dstPageByteSize [${dstPageByteSize}]) === 0`, + // ); + // if (!(byteSize % dstPageByteSize === 0)) + // throw new Error( + // `Assert fail: (byteSize [${byteSize}] % dstPageByteSize [${dstPageByteSize}]) === 0`, + // ); + // } + // if (!(dstByteOffset + byteSize <= dstByteSize)) { + // throw new Error( + // `Assert fail: (dstByteOffset [${dstByteOffset}] + byteSize [${byteSize}]) <= dstByteSize [${dstByteSize}], gl_target ${gl_target}`, + // ); + // // exceed, need to recreate + // } + + const virtBufferByteOffsetEnd = dstByteOffset + byteSize; + let virtBufferByteOffset = dstByteOffset; + let physBufferByteOffset = dstByteOffset % dstPageByteSize; + while (virtBufferByteOffset < virtBufferByteOffsetEnd) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindBuffer#parameters + const target = isWebGL2(gl) ? gl.COPY_WRITE_BUFFER : this.gl_target; + + const buffer = getPlatformBuffer(this, virtBufferByteOffset); + // @ts-ignore + if (buffer.ubo) { + return; + } + gl.bindBuffer(target, buffer); + + // only WebGL2 support srcOffset & length + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferSubData + if (isWebGL2(gl)) { + gl.bufferSubData( + target, + physBufferByteOffset, + data, + srcByteOffset, + Math.min( + virtBufferByteOffsetEnd - virtBufferByteOffset, + dstPageByteSize, + ), + ); + } else { + gl.bufferSubData(target, physBufferByteOffset, data); + } + + virtBufferByteOffset += dstPageByteSize; + physBufferByteOffset = 0; + srcByteOffset += dstPageByteSize; + this.device['debugGroupStatisticsBufferUpload'](); + } + } + + destroy() { + super.destroy(); + for (let i = 0; i < this.gl_buffer_pages.length; i++) { + // no ubo in WebGL1 + // @ts-ignore + if (!this.gl_buffer_pages[i].ubo) { + this.device.gl.deleteBuffer(this.gl_buffer_pages[i]); + } + } + } + + private createBufferPage( + byteSize: number, + usage: BufferUsage, + hint: BufferFrequencyHint, + ): WebGLBuffer { + const gl = this.device.gl; + const isUBO = usage & BufferUsage.UNIFORM; + if (!isWebGL2(gl) && isUBO) { + return { + ubo: true, + }; + } else { + const gl_buffer = this.device.ensureResourceExists(gl.createBuffer()); + const gl_target = translateBufferUsageToTarget(usage); + const gl_hint = translateBufferHint(hint); + gl.bindBuffer(gl_target, gl_buffer); + gl.bufferData(gl_target, byteSize, gl_hint); + return gl_buffer; + } + } +} diff --git a/src/webgl/ComputePass.ts b/src/webgl/ComputePass.ts new file mode 100644 index 0000000..15697e3 --- /dev/null +++ b/src/webgl/ComputePass.ts @@ -0,0 +1,48 @@ +import type { Buffer, Bindings, ComputePass, ComputePipeline } from '../api'; +// import { assert, assertExists } from '../api'; +// import type { ComputePipeline_GL } from './ComputePipeline'; + +export class ComputePass_GL implements ComputePass { + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpucomputepassencoder-dispatch + */ + dispatchWorkgroups( + workgroupCountX: number, + workgroupCountY?: number, + workgroupCountZ?: number, + ) {} + + dispatchWorkgroupsIndirect(indirectBuffer: Buffer, indirectOffset: number) {} + + finish() { + // this.gpuComputePassEncoder.end(); + // this.gpuComputePassEncoder = null; + // return this.commandEncoder.finish(); + } + + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-begincomputepass + */ + beginComputePass(): void { + // assert(this.gpuComputePassEncoder === null); + // this.setComputePassDescriptor(computePassDescriptor); + // this.gpuComputePassEncoder = this.commandEncoder.beginComputePass( + // this.gpuComputePassDescriptor, + // ); + } + + setPipeline(pipeline_: ComputePipeline): void { + // const pipeline = pipeline_ as ComputePipeline_WebGPU; + // const gpuComputePipeline = assertExists(pipeline.gpuComputePipeline); + // this.gpuComputePassEncoder.setPipeline(gpuComputePipeline); + } + + setBindings(bindings_: Bindings): void { + // const bindings = bindings_ as Bindings_WebGPU; + // this.gpuComputePassEncoder.setBindGroup(bindingLayoutIndex, bindings.gpuBindGroup[0]); + } + + pushDebugGroup(name: string) {} + popDebugGroup() {} + insertDebugMarker(markerLabel: string) {} +} diff --git a/src/webgl/ComputePipeline.ts b/src/webgl/ComputePipeline.ts new file mode 100644 index 0000000..f5667fa --- /dev/null +++ b/src/webgl/ComputePipeline.ts @@ -0,0 +1,30 @@ +import type { ComputePipeline, ComputePipelineDescriptor } from '../api'; +import { ResourceType } from '../api'; +// import type { Program_GL } from './Program'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; + +export class ComputePipeline_GL + extends ResourceBase_GL + implements ComputePipeline +{ + type: ResourceType.ComputePipeline = ResourceType.ComputePipeline; + + descriptor: ComputePipelineDescriptor; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: ComputePipelineDescriptor; + }) { + super({ id, device }); + + this.descriptor = descriptor; + + // const program = descriptor.program as Program_GL; + } +} diff --git a/src/webgl/Device.ts b/src/webgl/Device.ts new file mode 100644 index 0000000..952f0c2 --- /dev/null +++ b/src/webgl/Device.ts @@ -0,0 +1,2566 @@ +import { isNil } from '@antv/util'; +import { + AttachmentState, + Bindings, + BindingsDescriptor, + Buffer, + BufferDescriptor, + BufferFrequencyHint, + ComputePass, + ComputePipeline, + ComputePipelineDescriptor, + DebugGroup, + Device, + DeviceLimits, + IndexBufferDescriptor, + InputLayout, + InputLayoutDescriptor, + MegaStateDescriptor, + PlatformFramebuffer, + Program, + ProgramDescriptor, + QueryPool, + QueryPoolType, + Readback, + RenderPass, + RenderPassDescriptor, + RenderPipeline, + RenderPipelineDescriptor, + RenderTarget, + RenderTargetDescriptor, + Resource, + Sampler, + SamplerDescriptor, + SwapChain, + Texture, + TextureDescriptor, + TransparentWhite, + VendorInfo, + VertexBufferDescriptor, + getFormatSamplerKind, +} from '../api'; +import { + assert, + assertExists, + BufferUsage, + ChannelWriteMask, + ClipSpaceNearZ, + colorCopy, + colorEqual, + CompareMode, + copyMegaState, + CullMode, + defaultMegaState, + Format, + FormatCompFlags, + FormatFlags, + FormatTypeFlags, + getFormatCompFlags, + getFormatFlags, + getFormatTypeFlags, + GL, + nullify, + prependLineNo, + PrimitiveTopology, + ResourceType, + SamplerFormatKind, + TextureDimension, + TextureUsage, + VertexStepMode, + ViewportOrigin, +} from '../api'; +import { Bindings_GL } from './Bindings'; +import { Buffer_GL } from './Buffer'; +import { InputLayout_GL } from './InputLayout'; +import type { + BindingLayoutSamplerDescriptor_GL, + EXT_texture_compression_rgtc, + EXT_texture_norm16, + GPlatformWebGL2Config, + KHR_parallel_shader_compile, + OES_draw_buffers_indexed, +} from './interfaces'; +import { ProgramCompileState_GL, Program_GL } from './Program'; +import { QueryPool_GL } from './QueryPool'; +import { Readback_GL } from './Readback'; +import { RenderPipeline_GL } from './RenderPipeline'; +import { RenderTarget_GL } from './RenderTarget'; +import { ComputePipeline_GL } from './ComputePipeline'; +import { ResourceCreationTracker } from './ResourceCreationTracker'; +import { Sampler_GL } from './Sampler'; +import { Texture_GL } from './Texture'; +import { + assignPlatformName, + findall, + getPlatformBuffer, + getPlatformSampler, + getPlatformTexture, + isBlendStateNone, + isBlockCompressSized, + isFormatSizedInteger, + isTextureFormatCompressed, + isWebGL2, +} from './utils'; +import { ComputePass_GL } from './ComputePass'; +import { preprocessShader_GLSL } from '../shader'; + +// This is a workaround for ANGLE not supporting UBOs greater than 64kb (the limit of D3D). +// https://bugs.chromium.org/p/angleproject/issues/detail?id=3388 +const UBO_PAGE_MAX_BYTE_SIZE = 0x10000; + +export class Device_GL implements SwapChain, Device { + // Configuration + private shaderDebug = false; + private contextAttributes: WebGLContextAttributes; + + // GL extensions + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/OES_vertex_array_object + OES_vertex_array_object: OES_vertex_array_object | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/ANGLE_instanced_arrays + ANGLE_instanced_arrays: ANGLE_instanced_arrays | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float + OES_texture_float: OES_texture_float | null = null; + // @see https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/ + OES_draw_buffers_indexed: OES_draw_buffers_indexed | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_draw_buffers + // WEBGL_draw_buffers: WEBGL_draw_buffers | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_depth_texture + WEBGL_depth_texture: WEBGL_depth_texture | null = null; + WEBGL_compressed_texture_s3tc: WEBGL_compressed_texture_s3tc | null = null; + WEBGL_compressed_texture_s3tc_srgb: WEBGL_compressed_texture_s3tc_srgb | null = + null; + EXT_texture_compression_rgtc: EXT_texture_compression_rgtc | null = null; + EXT_texture_filter_anisotropic: EXT_texture_filter_anisotropic | null = null; + KHR_parallel_shader_compile: KHR_parallel_shader_compile | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/EXT_texture_norm16 + EXT_texture_norm16: EXT_texture_norm16 | null = null; + OES_texture_float_linear: OES_texture_float_linear | null = null; + OES_texture_half_float_linear: OES_texture_half_float_linear | null = null; + + // Swap Chain + private scTexture: Texture_GL | null = null; + private scPlatformFramebuffer: WebGLFramebuffer | null = null; + + // Device + private currentActiveTexture: GLenum | null = null; + private currentBoundVAO: WebGLVertexArrayObject | null = null; + private currentProgram: Program_GL | null = null; + + private resourceCreationTracker: ResourceCreationTracker | null = null; + private resourceUniqueId = 0; + + // Cached GL driver state + private currentColorAttachments: (RenderTarget_GL | null)[] = []; + private currentColorAttachmentLevels: number[] = []; + private currentColorResolveTos: (Texture_GL | null)[] = []; + private currentColorResolveToLevels: number[] = []; + private currentDepthStencilAttachment: RenderTarget_GL | null; + private currentDepthStencilResolveTo: Texture_GL | null = null; + private currentSampleCount = -1; + private currentPipeline: RenderPipeline_GL; + private currentIndexBufferByteOffset: number | null = null; + private currentMegaState: MegaStateDescriptor = + copyMegaState(defaultMegaState); + private currentSamplers: (WebGLSampler | null)[] = []; + + private currentTextures: (WebGLTexture | null)[] = []; + + private currentUniformBuffers: Buffer[] = []; + private currentUniformBufferByteOffsets: number[] = []; + private currentUniformBufferByteSizes: number[] = []; + private currentScissorEnabled = false; + private currentStencilRef: number | null = null; + + // Pass Execution + private currentRenderPassDescriptor: RenderPassDescriptor | null = null; + private debugGroupStack: DebugGroup[] = []; + private resolveColorAttachmentsChanged = false; + private resolveColorReadFramebuffer: WebGLFramebuffer; + private resolveColorDrawFramebuffer: WebGLFramebuffer; + private resolveDepthStencilAttachmentsChanged = false; + private resolveDepthStencilReadFramebuffer: WebGLFramebuffer; + private resolveDepthStencilDrawFramebuffer: WebGLFramebuffer; + /** + * use DRAW_FRAMEBUFFER in WebGL2 + */ + private renderPassDrawFramebuffer: WebGLFramebuffer; + private readbackFramebuffer: WebGLFramebuffer; + + private fallbackTexture2D: WebGLTexture; + private fallbackTexture2DDepth: WebGLTexture; + private fallbackTexture2DArray: WebGLTexture; + private fallbackTexture3D: WebGLTexture; + private fallbackTextureCube: WebGLTexture; + private fallbackVertexBuffer: Buffer; + + // VendorInfo + readonly platformString: string; + readonly glslVersion: string; + readonly explicitBindingLocations = false; + readonly separateSamplerTextures = false; + readonly viewportOrigin = ViewportOrigin.LOWER_LEFT; + readonly clipSpaceNearZ = ClipSpaceNearZ.NEGATIVE_ONE; + readonly supportMRT: boolean = false; + + private inBlitRenderPass = false; + private blitRenderPipeline: RenderPipeline; + private blitInputLayout: InputLayout; + private blitVertexBuffer: Buffer; + private blitBindings: Bindings; + private blitProgram: Program_GL; + + // GLimits + /** + * @see https://github.com/shrekshao/MoveWebGL1EngineToWebGL2/blob/master/Move-a-WebGL-1-Engine-To-WebGL-2-Blog-2.md#uniform-buffer + */ + uniformBufferMaxPageByteSize: number; + uniformBufferWordAlignment: number; + uniformBufferMaxPageWordSize: number; + supportedSampleCounts: number[] = []; + maxVertexAttribs: number; + occlusionQueriesRecommended = false; + computeShadersSupported = false; + + gl: WebGLRenderingContext | WebGL2RenderingContext; + + constructor( + gl: WebGLRenderingContext | WebGL2RenderingContext, + configuration: GPlatformWebGL2Config, + ) { + this.gl = gl; + this.contextAttributes = assertExists(gl.getContextAttributes()); + + if (!isWebGL2(gl)) { + this.OES_vertex_array_object = gl.getExtension('OES_vertex_array_object'); + // TODO: when ANGLE_instanced_arrays unavailable... + this.ANGLE_instanced_arrays = gl.getExtension('ANGLE_instanced_arrays'); + this.OES_texture_float = gl.getExtension('OES_texture_float'); + // this.WEBGL_draw_buffers = gl.getExtension('WEBGL_draw_buffers'); + // @see https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_depth_texture + // this.WEBGL_depth_texture = gl.getExtension('WEBGL_depth_texture'); + // @see https://developer.mozilla.org/en-US/docs/Web/API/EXT_frag_depth + gl.getExtension('EXT_frag_depth'); + // @see https://developer.mozilla.org/en-US/docs/Web/API/OES_element_index_uint + gl.getExtension('OES_element_index_uint'); + // @see https://developer.mozilla.org/en-US/docs/Web/API/OES_standard_derivatives + gl.getExtension('OES_standard_derivatives'); + + // won't use MRT anymore... + // if (this.WEBGL_draw_buffers) { + // this.supportMRT = true; + // } + } else { + this.EXT_texture_norm16 = gl.getExtension('EXT_texture_norm16'); + // this.supportMRT = true; + } + + this.WEBGL_compressed_texture_s3tc = gl.getExtension( + 'WEBGL_compressed_texture_s3tc', + ); + this.WEBGL_compressed_texture_s3tc_srgb = gl.getExtension( + 'WEBGL_compressed_texture_s3tc_srgb', + ); + this.EXT_texture_compression_rgtc = gl.getExtension( + 'EXT_texture_compression_rgtc', + ); + this.EXT_texture_filter_anisotropic = gl.getExtension( + 'EXT_texture_filter_anisotropic', + ); + this.EXT_texture_norm16 = gl.getExtension('EXT_texture_norm16'); + this.OES_texture_float_linear = gl.getExtension('OES_texture_float_linear'); + this.OES_texture_half_float_linear = gl.getExtension( + 'OES_texture_half_float_linear', + ); + this.KHR_parallel_shader_compile = gl.getExtension( + 'KHR_parallel_shader_compile', + ); + // this.OES_draw_buffers_indexed = gl.getExtension('OES_draw_buffers_indexed'); + + if (isWebGL2(gl)) { + this.platformString = 'WebGL2'; + this.glslVersion = '#version 300 es'; + } else { + this.platformString = 'WebGL1'; + this.glslVersion = '#version 100'; // 100 es not supported + } + + // Create our fake swap-chain texture. + this.scTexture = new Texture_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor: { + width: 0, + height: 0, + depth: 1, + dimension: TextureDimension.TEXTURE_2D, + numLevels: 1, + usage: TextureUsage.RENDER_TARGET, + pixelFormat: + this.contextAttributes.alpha === false + ? Format.U8_RGB_RT + : Format.U8_RGBA_RT, + }, + fake: true, + }); + this.scTexture.formatKind = SamplerFormatKind.Float; + this.scTexture.gl_target = null; + this.scTexture.gl_texture = null; + + this.resolveColorReadFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + this.resolveColorDrawFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + this.resolveDepthStencilReadFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + this.resolveDepthStencilDrawFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + this.renderPassDrawFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + this.readbackFramebuffer = this.ensureResourceExists( + gl.createFramebuffer(), + ); + + this.fallbackTexture2D = this.createFallbackTexture( + TextureDimension.TEXTURE_2D, + SamplerFormatKind.Float, + ); + this.fallbackTexture2DDepth = this.createFallbackTexture( + TextureDimension.TEXTURE_2D, + SamplerFormatKind.Depth, + ); + this.fallbackVertexBuffer = this.createBuffer({ + viewOrSize: 1, + usage: BufferUsage.VERTEX, + hint: BufferFrequencyHint.STATIC, + }); + + if (isWebGL2(gl)) { + // this.fallbackTexture2DArray = this.createFallbackTexture( + // TextureDimension.n2DArray, + // SamplerFormatKind.Float, + // ); + // this.fallbackTexture3D = this.createFallbackTexture( + // TextureDimension.n3D, + // SamplerFormatKind.Float, + // ); + // this.fallbackTextureCube = this.createFallbackTexture( + // TextureDimension.Cube, + // SamplerFormatKind.Float, + // ); + } + + // Adjust for GL defaults. + this.currentMegaState.depthCompare = CompareMode.LESS; + this.currentMegaState.depthWrite = false; + this.currentMegaState.attachmentsState[0].channelWriteMask = + ChannelWriteMask.ALL; + + // always have depth test enabled. + gl.enable(gl.DEPTH_TEST); + gl.enable(gl.STENCIL_TEST); + + this.checkLimits(); + + if (configuration.shaderDebug) { + this.shaderDebug = true; + } + + if (configuration.trackResources) { + this.resourceCreationTracker = new ResourceCreationTracker(); + } + } + + destroy() { + if (this.blitBindings) { + this.blitBindings.destroy(); + } + if (this.blitInputLayout) { + this.blitInputLayout.destroy(); + } + if (this.blitRenderPipeline) { + this.blitRenderPipeline.destroy(); + } + if (this.blitVertexBuffer) { + this.blitVertexBuffer.destroy(); + } + if (this.blitProgram) { + this.blitProgram.destroy(); + } + } + + private createFallbackTexture( + dimension: TextureDimension, + formatKind: SamplerFormatKind, + ): WebGLTexture { + const depth = dimension === TextureDimension.TEXTURE_CUBE_MAP ? 6 : 1; + // const supportDepthTexture = + // isWebGL2(this.gl) || (!isWebGL2(this.gl) && !!this.WEBGL_depth_texture); + const pixelFormat = + formatKind === SamplerFormatKind.Depth + ? Format.D32F + : Format.U8_RGBA_NORM; + + const texture = this.createTexture({ + dimension, + pixelFormat, + usage: TextureUsage.SAMPLED, + width: 1, + height: 1, + depth, + numLevels: 1, + }); + + // this.blackTexture = this.ensureResourceExists(gl.createTexture()); + // gl.bindTexture(GL.TEXTURE_2D, this.blackTexture); + // gl.texImage2D( + // GL.TEXTURE_2D, + // 0, + // isWebGL2(gl) ? gl.RGBA8 : gl.RGBA, + // 1, + // 1, + // 0, + // gl.RGBA, + // gl.UNSIGNED_BYTE, + // new Uint8Array(4), + // ) + + if (formatKind === SamplerFormatKind.Float) { + texture.setImageData([new Uint8Array(4 * depth)]); + } + return getPlatformTexture(texture); + } + + private getNextUniqueId(): number { + return ++this.resourceUniqueId; + } + + private checkLimits(): void { + const gl = this.gl; + + this.maxVertexAttribs = gl.getParameter(GL.MAX_VERTEX_ATTRIBS); + + if (isWebGL2(gl)) { + this.uniformBufferMaxPageByteSize = Math.min( + gl.getParameter(GL.MAX_UNIFORM_BLOCK_SIZE), + UBO_PAGE_MAX_BYTE_SIZE, + ); + this.uniformBufferWordAlignment = + gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT) / 4; + + const supportedSampleCounts = gl.getInternalformatParameter( + gl.RENDERBUFFER, + gl.DEPTH32F_STENCIL8, + gl.SAMPLES, + ); + this.supportedSampleCounts = supportedSampleCounts + ? [...supportedSampleCounts] + : []; + this.occlusionQueriesRecommended = true; + } else { + // mock ubo in WebGL1 + this.uniformBufferWordAlignment = 64; + this.uniformBufferMaxPageByteSize = UBO_PAGE_MAX_BYTE_SIZE; + } + + this.uniformBufferMaxPageWordSize = this.uniformBufferMaxPageByteSize / 4; + + if (!this.supportedSampleCounts.includes(1)) { + this.supportedSampleCounts.push(1); + } + this.supportedSampleCounts.sort((a, b) => a - b); + } + + //#region SwapChain + configureSwapChain( + width: number, + height: number, + platformFramebuffer?: PlatformFramebuffer, + ): void { + const texture = this.scTexture as Texture_GL; + texture.width = width; + texture.height = height; + this.scPlatformFramebuffer = nullify(platformFramebuffer); + } + + getDevice(): Device { + return this; + } + + getCanvas(): HTMLCanvasElement | OffscreenCanvas { + return this.gl.canvas; + } + + getOnscreenTexture(): Texture { + return this.scTexture; + } + + beginFrame(): void {} + + endFrame(): void {} + //#endregion + + //#region Device + // @see https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html + translateTextureInternalFormat( + fmt: Format, + isRenderbufferStorage = false, + ): GLenum { + switch (fmt) { + case Format.ALPHA: + return GL.ALPHA; + case Format.F16_R: + return GL.R16F; + case Format.F16_RG: + return GL.RG16F; + case Format.F16_RGB: + return GL.RGB16F; + case Format.F16_RGBA: + return GL.RGBA16F; + case Format.F32_R: + return GL.R32F; + case Format.F32_RG: + return GL.RG32F; + case Format.F32_RGB: + return GL.RGB32F; + case Format.F32_RGBA: + return GL.RGBA32F; + case Format.U8_R_NORM: + return GL.R8; + case Format.U8_RG_NORM: + return GL.RG8; + case Format.U8_RGB_NORM: + case Format.U8_RGB_RT: + return GL.RGB8; + case Format.U8_RGB_SRGB: + return GL.SRGB8; + case Format.U8_RGBA_NORM: + case Format.U8_RGBA_RT: + // WebGL1 renderbuffer only support RGBA4 RGB565 RGB5_A1 + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/renderbufferStorage#parameters + // But texImage2D allows RGBA + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + return isWebGL2(this.gl) + ? GL.RGBA8 + : isRenderbufferStorage + ? GL.RGBA4 + : GL.RGBA; + case Format.U8_RGBA_SRGB: + case Format.U8_RGBA_RT_SRGB: + return GL.SRGB8_ALPHA8; + case Format.U16_R: + return GL.R16UI; + case Format.U16_R_NORM: + return this.EXT_texture_norm16.R16_EXT; + case Format.U16_RG_NORM: + return this.EXT_texture_norm16.RG16_EXT; + case Format.U16_RGBA_NORM: + return this.EXT_texture_norm16.RGBA16_EXT; + case Format.U16_RGBA_5551: + return GL.RGB5_A1; + case Format.U16_RGB_565: + return GL.RGB565; + case Format.U32_R: + return GL.R32UI; + case Format.S8_RGBA_NORM: + return GL.RGBA8_SNORM; + case Format.S8_RG_NORM: + return GL.RG8_SNORM; + case Format.BC1: + return this.WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT1_EXT; + case Format.BC1_SRGB: + return this.WEBGL_compressed_texture_s3tc_srgb + .COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + case Format.BC2: + return this.WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT; + case Format.BC2_SRGB: + return this.WEBGL_compressed_texture_s3tc_srgb + .COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + case Format.BC3: + return this.WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT; + case Format.BC3_SRGB: + return this.WEBGL_compressed_texture_s3tc_srgb + .COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + case Format.BC4_UNORM: + return this.EXT_texture_compression_rgtc!.COMPRESSED_RED_RGTC1_EXT; + case Format.BC4_SNORM: + return this.EXT_texture_compression_rgtc + .COMPRESSED_SIGNED_RED_RGTC1_EXT; + case Format.BC5_UNORM: + return this.EXT_texture_compression_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT; + case Format.BC5_SNORM: + return this.EXT_texture_compression_rgtc + .COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; + case Format.D32F_S8: + return isWebGL2(this.gl) + ? GL.DEPTH32F_STENCIL8 + : this.WEBGL_depth_texture + ? GL.DEPTH_STENCIL + : GL.DEPTH_COMPONENT16; + case Format.D24_S8: + return isWebGL2(this.gl) + ? GL.DEPTH24_STENCIL8 + : this.WEBGL_depth_texture + ? GL.DEPTH_STENCIL + : GL.DEPTH_COMPONENT16; + case Format.D32F: + return isWebGL2(this.gl) + ? GL.DEPTH_COMPONENT32F + : this.WEBGL_depth_texture + ? GL.DEPTH_COMPONENT + : GL.DEPTH_COMPONENT16; + case Format.D24: + return isWebGL2(this.gl) + ? GL.DEPTH_COMPONENT24 + : this.WEBGL_depth_texture + ? GL.DEPTH_COMPONENT + : GL.DEPTH_COMPONENT16; + default: + throw new Error('whoops'); + } + } + + translateTextureType(fmt: Format): GLenum { + const typeFlags: FormatTypeFlags = getFormatTypeFlags(fmt); + switch (typeFlags) { + case FormatTypeFlags.U8: + return GL.UNSIGNED_BYTE; + case FormatTypeFlags.U16: + return GL.UNSIGNED_SHORT; + case FormatTypeFlags.U32: + return GL.UNSIGNED_INT; + case FormatTypeFlags.S8: + return GL.BYTE; + case FormatTypeFlags.F16: + return GL.HALF_FLOAT; + case FormatTypeFlags.F32: + return GL.FLOAT; + case FormatTypeFlags.U16_PACKED_5551: + return GL.UNSIGNED_SHORT_5_5_5_1; + case FormatTypeFlags.D32F: + return isWebGL2(this.gl) + ? GL.FLOAT + : this.WEBGL_depth_texture + ? GL.UNSIGNED_INT + : GL.UNSIGNED_BYTE; + case FormatTypeFlags.D24: + return isWebGL2(this.gl) + ? GL.UNSIGNED_INT_24_8 + : this.WEBGL_depth_texture + ? GL.UNSIGNED_SHORT + : GL.UNSIGNED_BYTE; + case FormatTypeFlags.D24S8: + // @see https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_depth_texture + return isWebGL2(this.gl) + ? GL.UNSIGNED_INT_24_8 + : this.WEBGL_depth_texture + ? GL.UNSIGNED_INT_24_8_WEBGL + : GL.UNSIGNED_BYTE; + case FormatTypeFlags.D32FS8: + return GL.FLOAT_32_UNSIGNED_INT_24_8_REV; + default: + throw new Error('whoops'); + } + } + + translateTextureFormat(fmt: Format): GLenum { + if (isTextureFormatCompressed(fmt)) { + return this.translateTextureInternalFormat(fmt); + } + + // @see https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_depth_texture + const supportDepthTexture = + isWebGL2(this.gl) || (!isWebGL2(this.gl) && !!this.WEBGL_depth_texture); + + switch (fmt) { + case Format.D24_S8: + case Format.D32F_S8: + return supportDepthTexture ? GL.DEPTH_STENCIL : GL.RGBA; + case Format.D24: + case Format.D32F: + return supportDepthTexture ? GL.DEPTH_COMPONENT : GL.RGBA; + default: + break; + } + + const isInteger = isFormatSizedInteger(fmt); + + const compFlags: FormatCompFlags = getFormatCompFlags(fmt); + switch (compFlags) { + case FormatCompFlags.A: + return GL.ALPHA; + case FormatCompFlags.R: + return isInteger ? GL.RED_INTEGER : GL.RED; + case FormatCompFlags.RG: + return isInteger ? GL.RG_INTEGER : GL.RG; + case FormatCompFlags.RGB: + return isInteger ? GL.RGB_INTEGER : GL.RGB; + case FormatCompFlags.RGBA: + // TODO: Chrome throw error when readPixels RGBA_INTEGER and UNSIGNED_BYTE + // @see https://github.com/KhronosGroup/WebGL/issues/2747 + // return isInteger ? GL.RGBA_INTEGER : GL.RGBA; + return GL.RGBA; + } + } + + setActiveTexture(texture: GLenum): void { + if (this.currentActiveTexture !== texture) { + this.gl.activeTexture(texture); + this.currentActiveTexture = texture; + } + } + + private bindVAO(vao: WebGLVertexArrayObject | null): void { + if (this.currentBoundVAO !== vao) { + if (isWebGL2(this.gl)) { + this.gl.bindVertexArray(vao); + } else { + this.OES_vertex_array_object.bindVertexArrayOES(vao); + } + this.currentBoundVAO = vao; + } + } + + private programCompiled(program: Program_GL): void { + assert(program.compileState !== ProgramCompileState_GL.NeedsCompile); + + if (program.compileState === ProgramCompileState_GL.Compiling) { + program.compileState = ProgramCompileState_GL.NeedsBind; + + if (this.shaderDebug) { + this.checkProgramCompilationForErrors(program); + } + } + } + + private useProgram(program: Program_GL): void { + if (this.currentProgram === program) return; + + this.programCompiled(program); + this.gl.useProgram(program.gl_program); + this.currentProgram = program; + } + + ensureResourceExists(resource: T | null): T { + if (resource === null) { + const error = this.gl.getError(); + throw new Error( + `Created resource is null; GL error encountered: ${error}`, + ); + } else { + return resource; + } + } + + createBuffer(descriptor: BufferDescriptor): Buffer { + return new Buffer_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createTexture(descriptor: TextureDescriptor): Texture { + return new Texture_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createSampler(descriptor: SamplerDescriptor): Sampler { + return new Sampler_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createRenderTarget(descriptor: RenderTargetDescriptor): RenderTarget { + return new RenderTarget_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createRenderTargetFromTexture(texture: Texture): RenderTarget { + const { pixelFormat, width, height, numLevels } = texture as Texture_GL; + // Render targets cannot have a mip chain currently. + assert(numLevels === 1); + + return this.createRenderTarget({ + pixelFormat, + width, + height, + sampleCount: 1, + texture, + }) as RenderTarget_GL; + } + + createProgram(descriptor: ProgramDescriptor): Program_GL { + const rawVertexGLSL = descriptor.vertex?.glsl; + // preprocess GLSL first + if (descriptor.vertex.glsl) { + descriptor.vertex.glsl = preprocessShader_GLSL( + this.queryVendorInfo(), + 'vert', + descriptor.vertex.glsl, + ); + } + if (descriptor.fragment.glsl) { + descriptor.fragment.glsl = preprocessShader_GLSL( + this.queryVendorInfo(), + 'frag', + descriptor.fragment.glsl, + ); + } + return this.createProgramSimple(descriptor, rawVertexGLSL); + } + + private createProgramSimple( + descriptor: ProgramDescriptor, + rawVertexGLSL: string, + ): Program_GL { + const program = new Program_GL( + { + id: this.getNextUniqueId(), + device: this, + descriptor, + }, + rawVertexGLSL, + ); + return program; + } + + createBindings(descriptor: BindingsDescriptor): Bindings { + return new Bindings_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createInputLayout(descriptor: InputLayoutDescriptor): InputLayout { + return new InputLayout_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createRenderPipeline(descriptor: RenderPipelineDescriptor): RenderPipeline { + return new RenderPipeline_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createComputePass(): ComputePass { + return new ComputePass_GL(); + } + + createComputePipeline( + descriptor: ComputePipelineDescriptor, + ): ComputePipeline { + return new ComputePipeline_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor, + }); + } + + createReadback(): Readback { + return new Readback_GL({ + id: this.getNextUniqueId(), + device: this, + }); + } + + createQueryPool(type: QueryPoolType, elemCount: number): QueryPool { + return new QueryPool_GL({ + id: this.getNextUniqueId(), + device: this, + descriptor: { + type, + elemCount, + }, + }); + } + + private formatRenderPassDescriptor(descriptor: RenderPassDescriptor) { + const { colorAttachment } = descriptor; + + descriptor.depthClearValue = descriptor.depthClearValue ?? 'load'; + descriptor.stencilClearValue = descriptor.stencilClearValue ?? 'load'; + + for (let i = 0; i < colorAttachment.length; i++) { + if (!descriptor.colorAttachmentLevel) { + descriptor.colorAttachmentLevel = []; + } + descriptor.colorAttachmentLevel[i] = + descriptor.colorAttachmentLevel[i] ?? 0; + + if (!descriptor.colorResolveToLevel) { + descriptor.colorResolveToLevel = []; + } + descriptor.colorResolveToLevel[i] = + descriptor.colorResolveToLevel[i] ?? 0; + + if (!descriptor.colorClearColor) { + descriptor.colorClearColor = []; + } + descriptor.colorClearColor[i] = descriptor.colorClearColor[i] ?? 'load'; + + if (!descriptor.colorStore) { + descriptor.colorStore = []; + } + descriptor.colorStore[i] = descriptor.colorStore[i] ?? false; + } + } + + createRenderPass(descriptor: RenderPassDescriptor): RenderPass { + assert(this.currentRenderPassDescriptor === null); + this.currentRenderPassDescriptor = descriptor; + + // Format renderpass descriptor + this.formatRenderPassDescriptor(descriptor); + + const { + colorAttachment, + colorAttachmentLevel, + colorClearColor, + colorResolveTo, + colorResolveToLevel, + depthStencilAttachment, + depthClearValue, + stencilClearValue, + depthStencilResolveTo, + } = descriptor; + this.setRenderPassParametersBegin(colorAttachment.length); + for (let i = 0; i < colorAttachment.length; i++) { + this.setRenderPassParametersColor( + i, + colorAttachment[i] as RenderTarget_GL | null, + colorAttachmentLevel[i], + colorResolveTo[i] as Texture_GL | null, + colorResolveToLevel[i], + ); + } + this.setRenderPassParametersDepthStencil( + depthStencilAttachment as RenderTarget_GL | null, + depthStencilResolveTo as Texture_GL | null, + ); + this.validateCurrentAttachments(); + for (let i = 0; i < colorAttachment.length; i++) { + const clearColor = colorClearColor[i]; + if (clearColor === 'load') continue; + this.setRenderPassParametersClearColor( + i, + clearColor.r, + clearColor.g, + clearColor.b, + clearColor.a, + ); + } + this.setRenderPassParametersClearDepthStencil( + depthClearValue, + stencilClearValue, + ); + return this; + } + + submitPass(pass: RenderPass): void { + assert(this.currentRenderPassDescriptor !== null); + this.endPass(); + this.currentRenderPassDescriptor = null; + } + + copySubTexture2D( + dst_: Texture, + dstX: number, + dstY: number, + src_: Texture, + srcX: number, + srcY: number, + ): void { + const gl = this.gl; + + const dst = dst_ as Texture_GL; + const src = src_ as Texture_GL; + assert(src.numLevels === 1); + assert(dst.numLevels === 1); + + if (isWebGL2(gl)) { + if (dst === this.scTexture) { + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.scPlatformFramebuffer); + } else { + gl.bindFramebuffer( + gl.DRAW_FRAMEBUFFER, + this.resolveColorDrawFramebuffer, + ); + this.bindFramebufferAttachment( + gl.DRAW_FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + dst, + 0, + ); + } + + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.resolveColorReadFramebuffer); + this.bindFramebufferAttachment( + gl.READ_FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + src, + 0, + ); + + gl.blitFramebuffer( + srcX, + srcY, + srcX + src.width, + srcY + src.height, + dstX, + dstY, + dstX + src.width, + dstY + src.height, + gl.COLOR_BUFFER_BIT, + gl.LINEAR, + ); + + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null); + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); + } + } + + queryLimits(): DeviceLimits { + return this; + } + + queryTextureFormatSupported( + format: Format, + width: number, + height: number, + ): boolean { + switch (format) { + case Format.BC1_SRGB: + case Format.BC2_SRGB: + case Format.BC3_SRGB: + if (this.WEBGL_compressed_texture_s3tc_srgb !== null) + return isBlockCompressSized(width, height, 4, 4); + return false; + case Format.BC1: + case Format.BC2: + case Format.BC3: + if (this.WEBGL_compressed_texture_s3tc !== null) + return isBlockCompressSized(width, height, 4, 4); + return false; + case Format.BC4_UNORM: + case Format.BC4_SNORM: + case Format.BC5_UNORM: + case Format.BC5_SNORM: + if (this.EXT_texture_compression_rgtc !== null) + return isBlockCompressSized(width, height, 4, 4); + return false; + case Format.U16_R_NORM: + case Format.U16_RG_NORM: + case Format.U16_RGBA_NORM: + return this.EXT_texture_norm16 !== null; + case Format.F32_R: + case Format.F32_RG: + case Format.F32_RGB: + case Format.F32_RGBA: + return this.OES_texture_float_linear !== null; + case Format.F16_R: + case Format.F16_RG: + case Format.F16_RGB: + case Format.F16_RGBA: + return this.OES_texture_half_float_linear !== null; + default: + return true; + } + } + + private queryProgramReady(program: Program_GL): boolean { + const gl = this.gl; + + if (program.compileState === ProgramCompileState_GL.NeedsCompile) { + // This should not happen. + throw new Error('whoops'); + } + if (program.compileState === ProgramCompileState_GL.Compiling) { + let complete: boolean; + + if (this.KHR_parallel_shader_compile !== null) { + complete = gl.getProgramParameter( + program.gl_program, + this.KHR_parallel_shader_compile.COMPLETION_STATUS_KHR, + ); + } else { + // If we don't have async shader compilation, assume all compilation is done immediately :/ + complete = true; + } + + if (complete) { + this.programCompiled(program); + } + + return complete; + } + + return ( + program.compileState === ProgramCompileState_GL.NeedsBind || + program.compileState === ProgramCompileState_GL.ReadyToUse + ); + } + + queryPlatformAvailable(): boolean { + return this.gl.isContextLost(); + } + + queryVendorInfo(): VendorInfo { + return this; + } + + queryRenderPass(o: RenderPass): Readonly { + return this.currentRenderPassDescriptor; + } + + queryRenderTarget(o: RenderTarget): Readonly { + const renderTarget = o as RenderTarget_GL; + return renderTarget; + } + //#endregion + + //#region Debugging + + setResourceName(o: Resource, name: string): void { + o.name = name; + + if (o.type === ResourceType.Buffer) { + const { gl_buffer_pages } = o as Buffer_GL; + for (let i = 0; i < gl_buffer_pages.length; i++) + assignPlatformName(gl_buffer_pages[i], `${name} Page ${i}`); + } else if (o.type === ResourceType.Texture) { + assignPlatformName(getPlatformTexture(o), name); + } else if (o.type === ResourceType.Sampler) { + assignPlatformName(getPlatformSampler(o), name); + } else if (o.type === ResourceType.RenderTarget) { + const { gl_renderbuffer } = o as RenderTarget_GL; + if (gl_renderbuffer !== null) assignPlatformName(gl_renderbuffer, name); + } else if (o.type === ResourceType.InputLayout) { + assignPlatformName((o as InputLayout_GL).vao, name); + } + } + + setResourceLeakCheck(o: Resource, v: boolean): void { + if (this.resourceCreationTracker !== null) + this.resourceCreationTracker.setResourceLeakCheck(o, v); + } + + checkForLeaks(): void { + if (this.resourceCreationTracker !== null) + this.resourceCreationTracker.checkForLeaks(); + } + + pushDebugGroup(name: string): void {} + + popDebugGroup(): void {} + + insertDebugMarker(markerLabel: string) {} + + // pushDebugGroup(debugGroup: DebugGroup): void { + // this.debugGroupStack.push(debugGroup); + // } + + // popDebugGroup(): void { + // this.debugGroupStack.pop(); + // } + + programPatched(o: Program, descriptor: ProgramDescriptor): void { + assert(this.shaderDebug); + + // const program = o as Program_GL; + // const gl = this.gl; + // gl.deleteProgram(program.gl_program); + // program.descriptor = descriptor; + // program.gl_program = this.ensureResourceExists(gl.createProgram()); + // program.compileState = ProgramCompileState_GL.NeedsCompile; + // this.tryCompileProgram(program); + // this.checkProgramCompilationForErrors(program); + } + + getBufferData( + buffer: Buffer, + dstBuffer: ArrayBufferView, + wordOffset = 0, + ): void { + const gl = this.gl; + + if (isWebGL2(gl)) { + gl.bindBuffer( + gl.COPY_READ_BUFFER, + getPlatformBuffer(buffer, wordOffset * 4), + ); + gl.getBufferSubData(gl.COPY_READ_BUFFER, wordOffset * 4, dstBuffer); + } else { + } + } + //#endregion + + private debugGroupStatisticsDrawCall(count = 1): void { + for (let i = this.debugGroupStack.length - 1; i >= 0; i--) + this.debugGroupStack[i].drawCallCount += count; + } + + private debugGroupStatisticsBufferUpload(count = 1): void { + for (let i = this.debugGroupStack.length - 1; i >= 0; i--) + this.debugGroupStack[i].bufferUploadCount += count; + } + + private debugGroupStatisticsTextureBind(count = 1): void { + for (let i = this.debugGroupStack.length - 1; i >= 0; i--) + this.debugGroupStack[i].textureBindCount += count; + } + + private debugGroupStatisticsTriangles(count: number): void { + for (let i = this.debugGroupStack.length - 1; i >= 0; i--) + this.debugGroupStack[i].triangleCount += count; + } + + private reportShaderError(shader: WebGLShader, str: string): boolean { + const gl = this.gl; + const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (!status) { + console.error(prependLineNo(str)); + const debug_shaders = gl.getExtension('WEBGL_debug_shaders'); + if (debug_shaders) + console.error(debug_shaders.getTranslatedShaderSource(shader)); + console.error(gl.getShaderInfoLog(shader)); + } + return status; + } + + private checkProgramCompilationForErrors(program: Program_GL): void { + const gl = this.gl; + + const prog = program.gl_program!; + if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { + const descriptor = program.descriptor; + + if ( + !this.reportShaderError(program.gl_shader_vert, descriptor.vertex.glsl) + ) + return; + + if ( + !this.reportShaderError( + program.gl_shader_frag, + descriptor.fragment.glsl, + ) + ) + return; + + // Neither shader had an error, report the program info log. + console.error(gl.getProgramInfoLog(program.gl_program)); + } + } + + private bindFramebufferAttachment( + framebuffer: GLenum, + binding: GLenum, + attachment: RenderTarget_GL | Texture_GL | null, + level: number, + ): void { + const gl = this.gl; + + if (attachment === null) { + gl.framebufferRenderbuffer(framebuffer, binding, gl.RENDERBUFFER, null); + } else if (attachment.type === ResourceType.RenderTarget) { + if ((attachment as RenderTarget_GL).gl_renderbuffer !== null) { + gl.framebufferRenderbuffer( + framebuffer, + binding, + gl.RENDERBUFFER, + (attachment as RenderTarget_GL).gl_renderbuffer, + ); + } else if ((attachment as RenderTarget_GL).texture !== null) { + gl.framebufferTexture2D( + framebuffer, + binding, + GL.TEXTURE_2D, + getPlatformTexture((attachment as RenderTarget_GL).texture), + level, + ); + } + } else if (attachment.type === ResourceType.Texture) { + // TODO: use Tex2D array with gl.framebufferTextureLayer + gl.framebufferTexture2D( + framebuffer, + binding, + GL.TEXTURE_2D, + getPlatformTexture(attachment as Texture_GL), + level, + ); + } + } + + private bindFramebufferDepthStencilAttachment( + framebuffer: GLenum, + attachment: RenderTarget_GL | Texture_GL | null, + ): void { + const gl = this.gl; + + const flags = + attachment !== null + ? getFormatFlags(attachment.pixelFormat) + : FormatFlags.Depth | FormatFlags.Stencil; + const depth = !!(flags & FormatFlags.Depth); + const stencil = !!(flags & FormatFlags.Stencil); + + if (depth && stencil) { + const supportDepthTexture = + isWebGL2(this.gl) || (!isWebGL2(this.gl) && !!this.WEBGL_depth_texture); + if (supportDepthTexture) { + this.bindFramebufferAttachment( + framebuffer, + gl.DEPTH_STENCIL_ATTACHMENT, + attachment, + 0, + ); + } else { + this.bindFramebufferAttachment( + framebuffer, + gl.DEPTH_ATTACHMENT, + attachment, + 0, + ); + } + } else if (depth) { + this.bindFramebufferAttachment( + framebuffer, + gl.DEPTH_ATTACHMENT, + attachment, + 0, + ); + this.bindFramebufferAttachment( + framebuffer, + gl.STENCIL_ATTACHMENT, + null, + 0, + ); + } else if (stencil) { + this.bindFramebufferAttachment( + framebuffer, + gl.STENCIL_ATTACHMENT, + attachment, + 0, + ); + this.bindFramebufferAttachment(framebuffer, gl.DEPTH_ATTACHMENT, null, 0); + } + } + + private validateCurrentAttachments(): void { + let sampleCount = -1, + width = -1, + height = -1; + + for (let i = 0; i < this.currentColorAttachments.length; i++) { + const attachment = this.currentColorAttachments[i]; + + if (attachment === null) continue; + + if (sampleCount === -1) { + sampleCount = attachment.sampleCount; + width = attachment.width; + height = attachment.height; + } else { + assert(sampleCount === attachment.sampleCount); + assert(width === attachment.width); + assert(height === attachment.height); + } + } + + if (this.currentDepthStencilAttachment) { + if (sampleCount === -1) { + sampleCount = this.currentDepthStencilAttachment.sampleCount; + width = this.currentDepthStencilAttachment.width; + height = this.currentDepthStencilAttachment.height; + } else { + assert(sampleCount === this.currentDepthStencilAttachment.sampleCount); + assert(width === this.currentDepthStencilAttachment.width); + assert(height === this.currentDepthStencilAttachment.height); + } + } + + this.currentSampleCount = sampleCount; + } + + private setRenderPassParametersBegin(numColorAttachments: number): void { + const gl = this.gl; + if (isWebGL2(gl)) { + gl.bindFramebuffer(GL.DRAW_FRAMEBUFFER, this.renderPassDrawFramebuffer); + } else { + if (!this.inBlitRenderPass) { + gl.bindFramebuffer(GL.FRAMEBUFFER, this.renderPassDrawFramebuffer); + } + } + + if (!this.inBlitRenderPass) { + for ( + let i = numColorAttachments; + i < this.currentColorAttachments.length; + i++ + ) { + const target = isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER; + const attachment = isWebGL2(gl) + ? GL.COLOR_ATTACHMENT0 + : GL.COLOR_ATTACHMENT0_WEBGL; + + gl.framebufferRenderbuffer( + target, + attachment + i, + GL.RENDERBUFFER, + null, + ); + gl.framebufferTexture2D(target, attachment + i, GL.TEXTURE_2D, null, 0); + } + } + this.currentColorAttachments.length = numColorAttachments; + + // if (isWebGL2(gl)) { + // gl.drawBuffers([ + // GL.COLOR_ATTACHMENT0, + // GL.COLOR_ATTACHMENT1, + // GL.COLOR_ATTACHMENT2, + // GL.COLOR_ATTACHMENT3, + // ]); + // } else { + // if (!this.inBlitRenderPass) { + // // MRT @see https://github.com/shrekshao/MoveWebGL1EngineToWebGL2/blob/master/Move-a-WebGL-1-Engine-To-WebGL-2-Blog-1.md#multiple-render-targets + // this.WEBGL_draw_buffers.drawBuffersWEBGL([ + // GL.COLOR_ATTACHMENT0_WEBGL, // gl_FragData[0] + // GL.COLOR_ATTACHMENT1_WEBGL, // gl_FragData[1] + // GL.COLOR_ATTACHMENT2_WEBGL, // gl_FragData[2] + // GL.COLOR_ATTACHMENT3_WEBGL, // gl_FragData[3] + // ]); + // } + // } + } + + private setRenderPassParametersColor( + i: number, + colorAttachment: RenderTarget_GL | null, + attachmentLevel: number, + colorResolveTo: Texture_GL | null, + resolveToLevel: number, + ): void { + const gl = this.gl; + + if ( + this.currentColorAttachments[i] !== colorAttachment || + this.currentColorAttachmentLevels[i] !== attachmentLevel + ) { + this.currentColorAttachments[i] = colorAttachment; + this.currentColorAttachmentLevels[i] = attachmentLevel; + + // disable MRT in WebGL1 + if (isWebGL2(gl) || i === 0) { + this.bindFramebufferAttachment( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + (isWebGL2(gl) ? GL.COLOR_ATTACHMENT0 : GL.COLOR_ATTACHMENT0_WEBGL) + + i, + colorAttachment, + attachmentLevel, + ); + } + + this.resolveColorAttachmentsChanged = true; + } + + if ( + this.currentColorResolveTos[i] !== colorResolveTo || + this.currentColorResolveToLevels[i] !== resolveToLevel + ) { + this.currentColorResolveTos[i] = colorResolveTo; + this.currentColorResolveToLevels[i] = resolveToLevel; + + if (colorResolveTo !== null) { + this.resolveColorAttachmentsChanged = true; + } + } + } + + private setRenderPassParametersDepthStencil( + depthStencilAttachment: RenderTarget | null, + depthStencilResolveTo: Texture | null, + ): void { + const gl = this.gl; + + if (this.currentDepthStencilAttachment !== depthStencilAttachment) { + this.currentDepthStencilAttachment = + depthStencilAttachment as RenderTarget_GL | null; + + if (!this.inBlitRenderPass) { + this.bindFramebufferDepthStencilAttachment( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + this.currentDepthStencilAttachment, + ); + } + this.resolveDepthStencilAttachmentsChanged = true; + } + + if (this.currentDepthStencilResolveTo !== depthStencilResolveTo) { + this.currentDepthStencilResolveTo = depthStencilResolveTo as Texture_GL; + + if (depthStencilResolveTo) { + this.resolveDepthStencilAttachmentsChanged = true; + } + } + } + + private setRenderPassParametersClearColor( + slot: number, + r: number, + g: number, + b: number, + a: number, + ): void { + const gl = this.gl; + + if (this.OES_draw_buffers_indexed !== null) { + const attachment = this.currentMegaState.attachmentsState[slot]; + if (attachment && attachment.channelWriteMask !== ChannelWriteMask.ALL) { + this.OES_draw_buffers_indexed.colorMaskiOES( + slot, + true, + true, + true, + true, + ); + attachment.channelWriteMask = ChannelWriteMask.ALL; + } + } else { + const attachment = this.currentMegaState.attachmentsState[0]; + if (attachment && attachment.channelWriteMask !== ChannelWriteMask.ALL) { + gl.colorMask(true, true, true, true); + attachment.channelWriteMask = ChannelWriteMask.ALL; + } + } + + this.setScissorEnabled(false); + + if (isWebGL2(gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/clearBuffer + gl.clearBufferfv(gl.COLOR, slot, [r, g, b, a]); + } else { + gl.clearColor(r, g, b, a); + gl.clear(gl.COLOR_BUFFER_BIT); + } + } + + private setRenderPassParametersClearDepthStencil( + depthClearValue: number | 'load' = 'load', + stencilClearValue: number | 'load' = 'load', + ): void { + const gl = this.gl; + + if (depthClearValue !== 'load') { + assert(!!this.currentDepthStencilAttachment); + // GL clears obey the masks... bad API or worst API? + if (!this.currentMegaState.depthWrite) { + gl.depthMask(true); + this.currentMegaState.depthWrite = true; + } + if (isWebGL2(gl)) { + gl.clearBufferfv(gl.DEPTH, 0, [depthClearValue]); + } else { + gl.clearDepth(depthClearValue); + gl.clear(gl.DEPTH_BUFFER_BIT); + } + } + if (stencilClearValue !== 'load') { + assert(!!this.currentDepthStencilAttachment); + if (!this.currentMegaState.stencilWrite) { + gl.enable(gl.STENCIL_TEST); + gl.stencilMask(0xff); + this.currentMegaState.stencilWrite = true; + } + if (isWebGL2(gl)) { + gl.clearBufferiv(gl.STENCIL, 0, [stencilClearValue]); + } else { + gl.clearStencil(stencilClearValue); + gl.clear(gl.STENCIL_BUFFER_BIT); + } + } + } + + setBindings(bindings_: Bindings, dynamicByteOffsets: number[] = [0]): void { + const gl = this.gl; + + const { uniformBufferBindings, samplerBindings, bindingLayouts } = + bindings_ as Bindings_GL; + assert(0 < bindingLayouts.bindingLayoutTables.length); + const bindingLayoutTable = bindingLayouts.bindingLayoutTables[0]; + // Ignore extra bindings. + assert( + uniformBufferBindings.length >= bindingLayoutTable.numUniformBuffers, + ); + assert(samplerBindings.length >= bindingLayoutTable.numSamplers); + assert(dynamicByteOffsets.length >= uniformBufferBindings.length); + + for (let i = 0; i < uniformBufferBindings.length; i++) { + const binding = uniformBufferBindings[i]; + if (binding.size === 0) continue; + const index = bindingLayoutTable.firstUniformBuffer + i; + const buffer = binding.buffer as Buffer_GL; + const byteOffset = dynamicByteOffsets[i]; + const byteSize = binding.size; + if ( + buffer !== this.currentUniformBuffers[index] || + byteOffset !== this.currentUniformBufferByteOffsets[index] || + byteSize !== this.currentUniformBufferByteSizes[index] + ) { + const platformBufferByteOffset = byteOffset % buffer.pageByteSize; + const platformBuffer = + buffer.gl_buffer_pages[(byteOffset / buffer.pageByteSize) | 0]; + assert(platformBufferByteOffset + byteSize <= buffer.pageByteSize); + + if (isWebGL2(gl)) { + gl.bindBufferRange( + gl.UNIFORM_BUFFER, + index, + platformBuffer, + platformBufferByteOffset, + byteSize, + ); + } else { + // TODO: WebGL1 uniform + } + this.currentUniformBuffers[index] = buffer; + this.currentUniformBufferByteOffsets[index] = byteOffset; + this.currentUniformBufferByteSizes[index] = byteSize; + } + } + + for (let i = 0; i < bindingLayoutTable.numSamplers; i++) { + const binding = samplerBindings[i]; + const samplerIndex = bindingLayoutTable.firstSampler + i; + const gl_sampler = + binding !== null && binding.sampler !== null + ? getPlatformSampler(binding.sampler) + : null; + const gl_texture = + binding !== null && binding.texture !== null + ? getPlatformTexture(binding.texture) + : null; + + if (this.currentSamplers[samplerIndex] !== gl_sampler) { + if (isWebGL2(gl)) { + gl.bindSampler(samplerIndex, gl_sampler); + } + this.currentSamplers[samplerIndex] = gl_sampler; + } + + if (this.currentTextures[samplerIndex] !== gl_texture) { + this.setActiveTexture(gl.TEXTURE0 + samplerIndex); + const { gl_target, width, height, pixelFormat } = assertExists(binding) + .texture as Texture_GL; + if (gl_texture !== null) { + // update index + (binding.texture as Texture_GL).textureIndex = samplerIndex; + gl.bindTexture(gl_target, gl_texture); + + // In WebGL1 set tex's parameters @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texParameter + if (!isWebGL2(gl)) { + (binding.sampler as Sampler_GL)?.setTextureParameters( + gl_target, + width, + height, + ); + } + + this.debugGroupStatisticsTextureBind(); + } else { + gl.bindTexture( + gl_target, + this.getFallbackTexture({ + gl_target, + formatKind: getFormatSamplerKind(pixelFormat), + }), + ); + } + this.currentTextures[samplerIndex] = gl_texture; + } + } + } + + setViewport(x: number, y: number, w: number, h: number): void { + const gl = this.gl; + gl.viewport(x, y, w, h); + } + + setScissor(x: number, y: number, w: number, h: number): void { + const gl = this.gl; + this.setScissorEnabled(true); + gl.scissor(x, y, w, h); + } + + private applyAttachmentStateIndexed( + i: number, + currentAttachmentState: AttachmentState, + newAttachmentState: AttachmentState, + ): void { + const gl = this.gl; + const dbi = this.OES_draw_buffers_indexed!; + + if ( + currentAttachmentState.channelWriteMask !== + newAttachmentState.channelWriteMask + ) { + dbi.colorMaskiOES( + i, + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.RED), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.GREEN), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.BLUE), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.ALPHA), + ); + currentAttachmentState.channelWriteMask = + newAttachmentState.channelWriteMask; + } + + const blendModeChanged = + currentAttachmentState.rgbBlendState.blendMode !== + newAttachmentState.rgbBlendState.blendMode || + currentAttachmentState.alphaBlendState.blendMode !== + newAttachmentState.alphaBlendState.blendMode; + const blendFuncChanged = + currentAttachmentState.rgbBlendState.blendSrcFactor !== + newAttachmentState.rgbBlendState.blendSrcFactor || + currentAttachmentState.alphaBlendState.blendSrcFactor !== + newAttachmentState.alphaBlendState.blendSrcFactor || + currentAttachmentState.rgbBlendState.blendDstFactor !== + newAttachmentState.rgbBlendState.blendDstFactor || + currentAttachmentState.alphaBlendState.blendDstFactor !== + newAttachmentState.alphaBlendState.blendDstFactor; + + if (blendFuncChanged || blendModeChanged) { + if ( + isBlendStateNone(currentAttachmentState.rgbBlendState) && + isBlendStateNone(currentAttachmentState.alphaBlendState) + ) + dbi.enableiOES(i, gl.BLEND); + else if ( + isBlendStateNone(newAttachmentState.rgbBlendState) && + isBlendStateNone(newAttachmentState.alphaBlendState) + ) + dbi.disableiOES(i, gl.BLEND); + } + + if (blendModeChanged) { + dbi.blendEquationSeparateiOES( + i, + newAttachmentState.rgbBlendState.blendMode, + newAttachmentState.alphaBlendState.blendMode, + ); + currentAttachmentState.rgbBlendState.blendMode = + newAttachmentState.rgbBlendState.blendMode; + currentAttachmentState.alphaBlendState.blendMode = + newAttachmentState.alphaBlendState.blendMode; + } + + if (blendFuncChanged) { + dbi.blendFuncSeparateiOES( + i, + newAttachmentState.rgbBlendState.blendSrcFactor, + newAttachmentState.rgbBlendState.blendDstFactor, + newAttachmentState.alphaBlendState.blendSrcFactor, + newAttachmentState.alphaBlendState.blendDstFactor, + ); + currentAttachmentState.rgbBlendState.blendSrcFactor = + newAttachmentState.rgbBlendState.blendSrcFactor; + currentAttachmentState.alphaBlendState.blendSrcFactor = + newAttachmentState.alphaBlendState.blendSrcFactor; + currentAttachmentState.rgbBlendState.blendDstFactor = + newAttachmentState.rgbBlendState.blendDstFactor; + currentAttachmentState.alphaBlendState.blendDstFactor = + newAttachmentState.alphaBlendState.blendDstFactor; + } + } + + private applyAttachmentState( + currentAttachmentState: AttachmentState, + newAttachmentState: AttachmentState, + ): void { + const gl = this.gl; + + if ( + currentAttachmentState.channelWriteMask !== + newAttachmentState.channelWriteMask + ) { + gl.colorMask( + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.RED), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.GREEN), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.BLUE), + !!(newAttachmentState.channelWriteMask & ChannelWriteMask.ALPHA), + ); + currentAttachmentState.channelWriteMask = + newAttachmentState.channelWriteMask; + } + + const blendModeChanged = + currentAttachmentState.rgbBlendState.blendMode !== + newAttachmentState.rgbBlendState.blendMode || + currentAttachmentState.alphaBlendState.blendMode !== + newAttachmentState.alphaBlendState.blendMode; + const blendFuncChanged = + currentAttachmentState.rgbBlendState.blendSrcFactor !== + newAttachmentState.rgbBlendState.blendSrcFactor || + currentAttachmentState.alphaBlendState.blendSrcFactor !== + newAttachmentState.alphaBlendState.blendSrcFactor || + currentAttachmentState.rgbBlendState.blendDstFactor !== + newAttachmentState.rgbBlendState.blendDstFactor || + currentAttachmentState.alphaBlendState.blendDstFactor !== + newAttachmentState.alphaBlendState.blendDstFactor; + + if (blendFuncChanged || blendModeChanged) { + if ( + isBlendStateNone(currentAttachmentState.rgbBlendState) && + isBlendStateNone(currentAttachmentState.alphaBlendState) + ) { + gl.enable(gl.BLEND); + } else if ( + isBlendStateNone(newAttachmentState.rgbBlendState) && + isBlendStateNone(newAttachmentState.alphaBlendState) + ) { + gl.disable(gl.BLEND); + } + } + + if (blendModeChanged) { + gl.blendEquationSeparate( + newAttachmentState.rgbBlendState.blendMode, + newAttachmentState.alphaBlendState.blendMode, + ); + currentAttachmentState.rgbBlendState.blendMode = + newAttachmentState.rgbBlendState.blendMode; + currentAttachmentState.alphaBlendState.blendMode = + newAttachmentState.alphaBlendState.blendMode; + } + + if (blendFuncChanged) { + gl.blendFuncSeparate( + newAttachmentState.rgbBlendState.blendSrcFactor, + newAttachmentState.rgbBlendState.blendDstFactor, + newAttachmentState.alphaBlendState.blendSrcFactor, + newAttachmentState.alphaBlendState.blendDstFactor, + ); + currentAttachmentState.rgbBlendState.blendSrcFactor = + newAttachmentState.rgbBlendState.blendSrcFactor; + currentAttachmentState.alphaBlendState.blendSrcFactor = + newAttachmentState.alphaBlendState.blendSrcFactor; + currentAttachmentState.rgbBlendState.blendDstFactor = + newAttachmentState.rgbBlendState.blendDstFactor; + currentAttachmentState.alphaBlendState.blendDstFactor = + newAttachmentState.alphaBlendState.blendDstFactor; + } + } + + private setMegaState(newMegaState: MegaStateDescriptor): void { + const gl = this.gl; + const currentMegaState = this.currentMegaState; + + if (this.OES_draw_buffers_indexed !== null) { + for (let i = 0; i < newMegaState.attachmentsState.length; i++) + this.applyAttachmentStateIndexed( + i, + currentMegaState.attachmentsState[0], + newMegaState.attachmentsState[0], + ); + } else { + assert(newMegaState.attachmentsState.length === 1); + this.applyAttachmentState( + currentMegaState.attachmentsState[0], + newMegaState.attachmentsState[0], + ); + } + + if ( + !colorEqual(currentMegaState.blendConstant, newMegaState.blendConstant) + ) { + gl.blendColor( + newMegaState.blendConstant.r, + newMegaState.blendConstant.g, + newMegaState.blendConstant.b, + newMegaState.blendConstant.a, + ); + colorCopy(currentMegaState.blendConstant, newMegaState.blendConstant); + } + + if (currentMegaState.depthCompare !== newMegaState.depthCompare) { + gl.depthFunc(newMegaState.depthCompare); + currentMegaState.depthCompare = newMegaState.depthCompare; + } + + if (!!currentMegaState.depthWrite !== !!newMegaState.depthWrite) { + gl.depthMask(newMegaState.depthWrite); + currentMegaState.depthWrite = newMegaState.depthWrite; + } + + if (!!currentMegaState.stencilWrite !== !!newMegaState.stencilWrite) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/stencilMask + gl.stencilMask(newMegaState.stencilWrite ? 0xff : 0x00); + currentMegaState.stencilWrite = newMegaState.stencilWrite; + } + + if (currentMegaState.stencilPassOp !== newMegaState.stencilPassOp) { + gl.stencilOp(gl.KEEP, gl.KEEP, newMegaState.stencilPassOp); + currentMegaState.stencilPassOp = newMegaState.stencilPassOp; + } + + if ( + currentMegaState.stencilRef !== newMegaState.stencilRef || + currentMegaState.stencilCompare !== newMegaState.stencilCompare + ) { + currentMegaState.stencilCompare = newMegaState.stencilCompare; + this.setStencilRef(newMegaState.stencilRef); + } + + if (currentMegaState.cullMode !== newMegaState.cullMode) { + if (currentMegaState.cullMode === CullMode.NONE) { + gl.enable(gl.CULL_FACE); + } else if (newMegaState.cullMode === CullMode.NONE) { + gl.disable(gl.CULL_FACE); + } + + if (newMegaState.cullMode === CullMode.BACK) { + gl.cullFace(gl.BACK); + } else if (newMegaState.cullMode === CullMode.FRONT) { + gl.cullFace(gl.FRONT); + } else if (newMegaState.cullMode === CullMode.FRONT_AND_BACK) { + gl.cullFace(gl.FRONT_AND_BACK); + } + currentMegaState.cullMode = newMegaState.cullMode; + } + + if (currentMegaState.frontFace !== newMegaState.frontFace) { + gl.frontFace(newMegaState.frontFace); + currentMegaState.frontFace = newMegaState.frontFace; + } + + if (currentMegaState.polygonOffset !== newMegaState.polygonOffset) { + if (newMegaState.polygonOffset) { + gl.polygonOffset(1, 1); + gl.enable(gl.POLYGON_OFFSET_FILL); + } else { + gl.disable(gl.POLYGON_OFFSET_FILL); + } + currentMegaState.polygonOffset = newMegaState.polygonOffset; + } + } + + private validatePipelineFormats(pipeline: RenderPipeline_GL): void { + for (let i = 0; i < this.currentColorAttachments.length; i++) { + const attachment = this.currentColorAttachments[i]; + if (attachment === null) continue; + assert(attachment.pixelFormat === pipeline.colorAttachmentFormats[i]); + } + + if (this.currentDepthStencilAttachment) { + assert( + this.currentDepthStencilAttachment.pixelFormat === + pipeline.depthStencilAttachmentFormat, + ); + } + + if (this.currentSampleCount !== -1) { + assert(this.currentSampleCount === pipeline.sampleCount); + } + } + + setPipeline(o: RenderPipeline): void { + this.currentPipeline = o as RenderPipeline_GL; + this.validatePipelineFormats(this.currentPipeline); + + // We allow users to use "non-ready" pipelines for emergencies. In this case, there can be a bit of stuttering. + // assert(this.queryPipelineReady(this.currentPipeline)); + + this.setMegaState(this.currentPipeline.megaState); + + const program = this.currentPipeline.program; + this.useProgram(program); + + if (program.compileState === ProgramCompileState_GL.NeedsBind) { + const gl = this.gl; + const prog = program.gl_program!; + const deviceProgram = program.descriptor; + + const uniformBlocks = findall( + deviceProgram.vertex.glsl, + /uniform (\w+) {([^]*?)}/g, + ); + + if (isWebGL2(gl)) { + for (let i = 0; i < uniformBlocks.length; i++) { + const [, blockName] = uniformBlocks[i]; + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/getUniformBlockIndex + const blockIdx = gl.getUniformBlockIndex(prog, blockName); + if (blockIdx !== -1 && blockIdx !== 0xffffffff) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/uniformBlockBinding + gl.uniformBlockBinding(prog, blockIdx, i); + } + } + } + + const samplers = findall( + deviceProgram.vertex.glsl, + /^uniform .*sampler\S+ (\w+);\s* \/\/ BINDING=(\d+)$/gm, + ); + for (let i = 0; i < samplers.length; i++) { + const [, name, location] = samplers[i]; + const samplerUniformLocation = gl.getUniformLocation(prog, name); + gl.uniform1i(samplerUniformLocation, parseInt(location)); + } + + program.compileState = ProgramCompileState_GL.ReadyToUse; + } + } + + setVertexInput( + inputLayout_: InputLayout | null, + vertexBuffers: (VertexBufferDescriptor | null)[] | null, + indexBuffer: IndexBufferDescriptor | null, + ): void { + if (inputLayout_ !== null) { + assert(this.currentPipeline.inputLayout === inputLayout_); + const inputLayout = inputLayout_ as InputLayout_GL; + + this.bindVAO(inputLayout.vao); + + const gl = this.gl; + for (let i = 0; i < inputLayout.vertexAttributeDescriptors.length; i++) { + const attr = inputLayout.vertexAttributeDescriptors[i]; + + // find location by name in WebGL1 + const location = isWebGL2(gl) + ? attr.location + : inputLayout.program.attributes[attr.location]?.location; + + if (!isNil(location)) { + const vertexBuffer = vertexBuffers![attr.bufferIndex]; + + if (vertexBuffer === null) continue; + + const format = inputLayout.vertexBufferFormats[i]; + + gl.bindBuffer( + gl.ARRAY_BUFFER, + getPlatformBuffer(vertexBuffer.buffer), + ); + + const bufferOffset = + (vertexBuffer.byteOffset || 0) + attr.bufferByteOffset; + + const inputLayoutBuffer = + inputLayout.vertexBufferDescriptors[attr.bufferIndex]!; + gl.vertexAttribPointer( + location, + format.size, + format.type, + format.normalized, + inputLayoutBuffer.byteStride, + bufferOffset, + ); + } + } + + assert( + (indexBuffer !== null) === (inputLayout.indexBufferFormat !== null), + ); + if (indexBuffer !== null) { + const buffer = indexBuffer.buffer as Buffer_GL; + assert(buffer.usage === BufferUsage.INDEX); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, getPlatformBuffer(buffer)); + this.currentIndexBufferByteOffset = indexBuffer.byteOffset; + } else { + this.currentIndexBufferByteOffset = null; + } + } else { + assert(this.currentPipeline.inputLayout === null); + assert(indexBuffer === null); + this.bindVAO(null); + this.currentIndexBufferByteOffset = 0; + } + } + + setStencilRef(value: number): void { + if (this.currentStencilRef === value) { + return; + } + this.currentStencilRef = value; + this.applyStencil(); + } + + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-draw + */ + draw( + vertexCount: number, + instanceCount?: number, + firstVertex?: number, + firstInstance?: number, + ) { + const gl = this.gl; + const pipeline = this.currentPipeline; + if (instanceCount) { + const params: [number, number, number, number] = [ + pipeline.drawMode, + firstVertex || 0, + vertexCount, + instanceCount, + ]; + if (isWebGL2(gl)) { + gl.drawArraysInstanced(...params); + } else { + this.ANGLE_instanced_arrays.drawArraysInstancedANGLE(...params); + } + } else { + gl.drawArrays(pipeline.drawMode, firstVertex, vertexCount); + } + + this.debugGroupStatisticsDrawCall(); + this.debugGroupStatisticsTriangles( + (vertexCount / 3) * Math.max(instanceCount, 1), + ); + } + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-drawindexed + */ + drawIndexed( + indexCount: number, + instanceCount?: number, + firstIndex?: number, + baseVertex?: number, + firstInstance?: number, + ) { + const gl = this.gl; + const pipeline = this.currentPipeline, + inputLayout = assertExists(pipeline.inputLayout); + const byteOffset = + assertExists(this.currentIndexBufferByteOffset) + + firstIndex * inputLayout.indexBufferCompByteSize!; + if (instanceCount) { + const params: [number, number, number, number, number] = [ + pipeline.drawMode, + indexCount, + inputLayout.indexBufferType!, + byteOffset, + instanceCount, + ]; + if (isWebGL2(gl)) { + gl.drawElementsInstanced(...params); + } else { + this.ANGLE_instanced_arrays.drawElementsInstancedANGLE(...params); + } + } else { + gl.drawElements( + pipeline.drawMode, + indexCount, + inputLayout.indexBufferType!, + byteOffset, + ); + } + + this.debugGroupStatisticsDrawCall(); + this.debugGroupStatisticsTriangles( + (indexCount / 3) * Math.max(instanceCount, 1), + ); + } + /** + * @see https://www.w3.org/TR/webgpu/#dom-gpurendercommandsmixin-drawindirect + */ + drawIndirect(indirectBuffer: Buffer, indirectOffset: number) { + // TODO + } + + beginOcclusionQuery(dstOffs: number): void { + const gl = this.gl; + if (isWebGL2(gl)) { + const queryPool = this.currentRenderPassDescriptor + .occlusionQueryPool as QueryPool_GL; + gl.beginQuery(queryPool.gl_query_type, queryPool.gl_query[dstOffs]); + } + } + + endOcclusionQuery(dstOffs: number): void { + const gl = this.gl; + if (isWebGL2(gl)) { + const queryPool = this.currentRenderPassDescriptor! + .occlusionQueryPool as QueryPool_GL; + gl.endQuery(queryPool.gl_query_type); + } + } + + pipelineQueryReady(o: RenderPipeline): boolean { + const pipeline = o as RenderPipeline_GL; + return this.queryProgramReady(pipeline.program); + } + + pipelineForceReady(o: RenderPipeline): void { + // No need to do anything; it will be forced to compile when used naturally. + } + + private endPass(): void { + const gl = this.gl; + + let didUnbindDraw = false; + + for (let i = 0; i < this.currentColorAttachments.length; i++) { + const colorResolveFrom = this.currentColorAttachments[i]; + + if (colorResolveFrom !== null) { + const colorResolveTo = this.currentColorResolveTos[i]; + let didBindRead = false; + + if (colorResolveTo !== null) { + assert( + colorResolveFrom.width === colorResolveTo.width && + colorResolveFrom.height === colorResolveTo.height, + ); + assert(colorResolveFrom.pixelFormat === colorResolveTo.pixelFormat); + + this.setScissorEnabled(false); + if (isWebGL2(gl)) { + gl.bindFramebuffer( + gl.READ_FRAMEBUFFER, + this.resolveColorReadFramebuffer, + ); + } + if (this.resolveColorAttachmentsChanged) { + if (isWebGL2(gl)) { + this.bindFramebufferAttachment( + gl.READ_FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + colorResolveFrom, + this.currentColorAttachmentLevels[i], + ); + } + } + didBindRead = true; + + // Special case: Blitting to the on-screen. + if (colorResolveTo === this.scTexture) { + gl.bindFramebuffer( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + this.scPlatformFramebuffer, + ); + } else { + gl.bindFramebuffer( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + this.resolveColorDrawFramebuffer, + ); + if (this.resolveColorAttachmentsChanged) + gl.framebufferTexture2D( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + colorResolveTo.gl_texture, + this.currentColorResolveToLevels[i], + ); + } + + if (isWebGL2(gl)) { + gl.blitFramebuffer( + 0, + 0, + colorResolveFrom.width, + colorResolveFrom.height, + 0, + 0, + colorResolveTo.width, + colorResolveTo.height, + gl.COLOR_BUFFER_BIT, + gl.LINEAR, + ); + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); + } else { + // need an extra render pass in WebGL1 + this.submitBlitRenderPass(colorResolveFrom, colorResolveTo); + } + didUnbindDraw = true; + } + + if (!this.currentRenderPassDescriptor.colorStore[i]) { + if (!didBindRead) { + gl.bindFramebuffer( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + this.resolveColorReadFramebuffer, + ); + if (this.resolveColorAttachmentsChanged) + this.bindFramebufferAttachment( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + colorResolveFrom, + this.currentColorAttachmentLevels[i], + ); + } + + if (isWebGL2(gl)) { + gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, [ + gl.COLOR_ATTACHMENT0, + ]); + } + } + + gl.bindFramebuffer( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + null, + ); + } + } + + this.resolveColorAttachmentsChanged = false; + + const depthStencilResolveFrom = this.currentDepthStencilAttachment; + if (depthStencilResolveFrom) { + const depthStencilResolveTo = this.currentDepthStencilResolveTo; + let didBindRead = false; + + if (depthStencilResolveTo) { + assert( + depthStencilResolveFrom.width === depthStencilResolveTo.width && + depthStencilResolveFrom.height === depthStencilResolveTo.height, + ); + + this.setScissorEnabled(false); + + gl.bindFramebuffer( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + this.resolveDepthStencilReadFramebuffer, + ); + gl.bindFramebuffer( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + this.resolveDepthStencilDrawFramebuffer, + ); + if (this.resolveDepthStencilAttachmentsChanged) { + this.bindFramebufferDepthStencilAttachment( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + depthStencilResolveFrom, + ); + this.bindFramebufferDepthStencilAttachment( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + depthStencilResolveTo, + ); + } + didBindRead = true; + + if (isWebGL2(gl)) { + gl.blitFramebuffer( + 0, + 0, + depthStencilResolveFrom.width, + depthStencilResolveFrom.height, + 0, + 0, + depthStencilResolveTo.width, + depthStencilResolveTo.height, + gl.DEPTH_BUFFER_BIT, + gl.NEAREST, + ); + } else { + } + gl.bindFramebuffer( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + null, + ); + didUnbindDraw = true; + } + + if (!this.currentRenderPassDescriptor!.depthStencilStore) { + if (!didBindRead) { + gl.bindFramebuffer( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + this.resolveDepthStencilReadFramebuffer, + ); + if (this.resolveDepthStencilAttachmentsChanged) + this.bindFramebufferDepthStencilAttachment( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + depthStencilResolveFrom, + ); + didBindRead = true; + } + + if (isWebGL2(gl)) { + gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, [ + gl.DEPTH_STENCIL_ATTACHMENT, + ]); + } + } + + if (didBindRead) + gl.bindFramebuffer( + isWebGL2(gl) ? GL.READ_FRAMEBUFFER : GL.FRAMEBUFFER, + null, + ); + + this.resolveDepthStencilAttachmentsChanged = false; + } + + if (!didUnbindDraw) { + // If we did not unbind from a resolve, then we need to unbind our render pass draw FBO here. + gl.bindFramebuffer( + isWebGL2(gl) ? GL.DRAW_FRAMEBUFFER : GL.FRAMEBUFFER, + null, + ); + } + } + + private setScissorEnabled(v: boolean): void { + if (this.currentScissorEnabled === v) { + return; + } + + const gl = this.gl; + if (v) { + gl.enable(gl.SCISSOR_TEST); + } else { + gl.disable(gl.SCISSOR_TEST); + } + this.currentScissorEnabled = v; + } + + private applyStencil(): void { + if (isNil(this.currentStencilRef)) { + return; + } + this.gl.stencilFunc( + this.currentMegaState.stencilCompare, + this.currentStencilRef, + 0xff, + ); + } + + private getFallbackTexture( + samplerEntry: BindingLayoutSamplerDescriptor_GL, + ): WebGLTexture { + const gl_target = samplerEntry.gl_target, + formatKind = samplerEntry.formatKind; + if (gl_target === GL.TEXTURE_2D) + return formatKind === SamplerFormatKind.Depth + ? this.fallbackTexture2DDepth + : this.fallbackTexture2D; + else if (gl_target === GL.TEXTURE_2D_ARRAY) + return this.fallbackTexture2DArray; + else if (gl_target === GL.TEXTURE_3D) return this.fallbackTexture3D; + else if (gl_target === GL.TEXTURE_CUBE_MAP) return this.fallbackTextureCube; + else throw new Error('whoops'); + } + + private submitBlitRenderPass( + resolveFrom: RenderTarget_GL, + resolveTo: Texture_GL, + ) { + if (!this.blitRenderPipeline) { + this.blitProgram = this.createProgram({ + vertex: { + glsl: `layout(location = 0) in vec2 a_Position; +out vec2 v_TexCoord; +void main() { + v_TexCoord = 0.5 * (a_Position + 1.0); + gl_Position = vec4(a_Position, 0., 1.); + + #ifdef VIEWPORT_ORIGIN_TL + v_TexCoord.y = 1.0 - v_TexCoord.y; + #endif +}`, + }, + fragment: { + glsl: `uniform sampler2D u_Texture; +in vec2 v_TexCoord; +out vec4 outputColor; +void main() { + outputColor = texture(SAMPLER_2D(u_Texture), v_TexCoord); +}`, + }, + }); + this.blitVertexBuffer = this.createBuffer({ + usage: BufferUsage.VERTEX | BufferUsage.COPY_DST, + viewOrSize: new Float32Array([-4, -4, 4, -4, 0, 4]), + }); + this.blitInputLayout = this.createInputLayout({ + vertexBufferDescriptors: [ + { byteStride: 4 * 2, stepMode: VertexStepMode.VERTEX }, + ], + vertexAttributeDescriptors: [ + { + format: Format.F32_RG, + bufferIndex: 0, + bufferByteOffset: 4 * 0, + location: 0, + }, + ], + indexBufferFormat: null, + program: this.blitProgram, + }); + this.blitRenderPipeline = this.createRenderPipeline({ + topology: PrimitiveTopology.TRIANGLES, + sampleCount: 1, + program: this.blitProgram, + colorAttachmentFormats: [Format.U8_RGBA_RT], + depthStencilAttachmentFormat: null, + inputLayout: this.blitInputLayout, + megaStateDescriptor: copyMegaState(defaultMegaState), + }); + + this.blitBindings = this.createBindings({ + samplerBindings: [ + { + sampler: null, + texture: resolveFrom.texture, + }, + ], + uniformBufferBindings: [], + }); + + this.blitProgram.setUniformsLegacy({ + u_Texture: resolveFrom, + }); + } + + // save currentRenderPassDescriptor since we're already in a render pass + const currentRenderPassDescriptor = this.currentRenderPassDescriptor; + this.currentRenderPassDescriptor = null; + + this.inBlitRenderPass = true; + + const blitRenderPass = this.createRenderPass({ + colorAttachment: [resolveFrom], + colorResolveTo: [resolveTo], + colorClearColor: [TransparentWhite], + }); + + const { width, height } = this.getCanvas() as HTMLCanvasElement; + blitRenderPass.setPipeline(this.blitRenderPipeline); + blitRenderPass.setBindings(this.blitBindings); + blitRenderPass.setVertexInput( + this.blitInputLayout, + [{ buffer: this.blitVertexBuffer }], + null, + ); + blitRenderPass.setViewport(0, 0, width, height); + + // disable blending for blit + this.gl.disable(this.gl.BLEND); + blitRenderPass.draw(3, 0); + this.gl.enable(this.gl.BLEND); + + // restore + this.currentRenderPassDescriptor = currentRenderPassDescriptor; + this.inBlitRenderPass = false; + } +} diff --git a/src/webgl/InputLayout.ts b/src/webgl/InputLayout.ts new file mode 100644 index 0000000..7707a5b --- /dev/null +++ b/src/webgl/InputLayout.ts @@ -0,0 +1,160 @@ +import { + Format, + ResourceType, + VertexStepMode, + assert, + assertExists, + getFormatCompByteSize, +} from '../api'; +import type { + InputLayout, + InputLayoutBufferDescriptor, + InputLayoutDescriptor, + VertexAttributeDescriptor, +} from '../api'; +import { isNil } from '@antv/util'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { + getPlatformBuffer, + isFormatSizedInteger, + isWebGL2, + translateIndexFormat, + translateVertexFormat, +} from './utils'; +import { Program_GL } from './Program'; + +export class InputLayout_GL extends ResourceBase_GL implements InputLayout { + type: ResourceType.InputLayout = ResourceType.InputLayout; + + vertexAttributeDescriptors: VertexAttributeDescriptor[]; + vertexBufferDescriptors: (InputLayoutBufferDescriptor | null)[]; + vertexBufferFormats: ReturnType[]; + indexBufferFormat: Format | null; + indexBufferType: GLenum | null; + indexBufferCompByteSize: number | null; + vao: WebGLVertexArrayObject; + program: Program_GL; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: InputLayoutDescriptor; + }) { + super({ id, device }); + + const { + vertexAttributeDescriptors, + vertexBufferDescriptors, + indexBufferFormat, + program, + } = descriptor; + assert( + indexBufferFormat === Format.U16_R || + indexBufferFormat === Format.U32_R || + indexBufferFormat === null, + ); + const indexBufferType = + indexBufferFormat !== null + ? translateIndexFormat(indexBufferFormat) + : null; + const indexBufferCompByteSize = + indexBufferFormat !== null + ? getFormatCompByteSize(indexBufferFormat) + : null; + + const gl = this.device.gl; + const vao = this.device.ensureResourceExists( + isWebGL2(gl) + ? gl.createVertexArray() + : device.OES_vertex_array_object.createVertexArrayOES(), + ); + if (isWebGL2(gl)) { + gl.bindVertexArray(vao); + } else { + device.OES_vertex_array_object.bindVertexArrayOES(vao); + } + + gl.bindBuffer( + gl.ARRAY_BUFFER, + getPlatformBuffer(this.device['fallbackVertexBuffer']), + ); + + const vertexBufferFormats = []; + for (let i = 0; i < vertexAttributeDescriptors.length; i++) { + const attr = vertexAttributeDescriptors[i]; + + const { format, divisor = 1, bufferIndex } = attr; + // find location by name in WebGL1 + const location = isWebGL2(gl) + ? attr.location + : (program as Program_GL).attributes[attr.location]?.location; + + const vertexFormat = translateVertexFormat(format); + vertexBufferFormats.push(vertexFormat); + + if (!isNil(location)) { + if (isFormatSizedInteger(format)) { + // See https://groups.google.com/d/msg/angleproject/yQb5DaCzcWg/Ova0E3wcAQAJ for more info. + // console.warn("Vertex format uses sized integer types; this will cause a shader recompile on ANGLE platforms"); + // debugger; + } + + const { size, type, normalized } = vertexFormat; + + const inputLayoutBuffer = assertExists( + vertexBufferDescriptors[bufferIndex], + ); + + gl.vertexAttribPointer(location, size, type, normalized, 0, 0); + + if (inputLayoutBuffer.stepMode === VertexStepMode.INSTANCE) { + if (isWebGL2(gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/vertexAttribDivisor + gl.vertexAttribDivisor(location, divisor); + } else { + device.ANGLE_instanced_arrays.vertexAttribDivisorANGLE( + location, + divisor, + ); + } + } + + gl.enableVertexAttribArray(location); + } + } + + if (isWebGL2(gl)) { + gl.bindVertexArray(null); + } else { + device.OES_vertex_array_object.bindVertexArrayOES(null); + } + + this.vertexAttributeDescriptors = vertexAttributeDescriptors; + this.vertexBufferDescriptors = vertexBufferDescriptors; + this.vao = vao; + this.vertexBufferFormats = vertexBufferFormats; + this.indexBufferFormat = indexBufferFormat; + this.indexBufferType = indexBufferType; + this.indexBufferCompByteSize = indexBufferCompByteSize; + this.program = program as Program_GL; + } + + destroy() { + super.destroy(); + if (this.device['currentBoundVAO'] === this.vao) { + if (isWebGL2(this.device.gl)) { + this.device.gl.bindVertexArray(null); + this.device.gl.deleteVertexArray(this.vao); + } else { + this.device.OES_vertex_array_object.bindVertexArrayOES(null); + this.device.OES_vertex_array_object.deleteVertexArrayOES(this.vao); + } + this.device['currentBoundVAO'] = null; + } + } +} diff --git a/src/webgl/Program.ts b/src/webgl/Program.ts new file mode 100644 index 0000000..7d4b37c --- /dev/null +++ b/src/webgl/Program.ts @@ -0,0 +1,219 @@ +import type { Program, ProgramDescriptor } from '../api'; +import { + assert, + getUniformSetter, + parseUniformName, + ResourceType, +} from '../api'; +import { getAttributeLocations, getDefines } from '../shader'; +import { isNil } from '@antv/util'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { Texture_GL } from './Texture'; +import { isWebGL2 } from './utils'; + +// const quadVert = ` +// layout(location = 0) in vec2 a_Position; + +// out vec2 v_TexCoord; + +// void main() { +// v_TexCoord = 0.5 * (a_Position + 1.0); +// gl_Position = vec4(a_Position, 0., 1.); + +// #ifdef VIEWPORT_ORIGIN_TL +// v_TexCoord.y = 1.0 - v_TexCoord.y; +// #endif +// } +// `; + +export enum ProgramCompileState_GL { + NeedsCompile, + Compiling, + NeedsBind, + ReadyToUse, +} + +export class Program_GL extends ResourceBase_GL implements Program { + type: ResourceType.Program = ResourceType.Program; + + gl_program: WebGLProgram; + gl_shader_vert: WebGLShader | null; + gl_shader_frag: WebGLShader | null; + compileState: ProgramCompileState_GL; + descriptor: ProgramDescriptor; + + // eslint-disable-next-line + uniformSetters: Record = {}; + attributes: { + name: string; + location: number; // getAttribLocation() + type: number; + size: number; + }[] = []; + + constructor( + { + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: ProgramDescriptor; + }, + private rawVertexGLSL: string, + ) { + super({ id, device }); + + const gl = this.device.gl; + + this.descriptor = descriptor; + this.gl_program = this.device.ensureResourceExists(gl.createProgram()); + this.gl_shader_vert = null; + this.gl_shader_frag = null; + this.compileState = ProgramCompileState_GL.NeedsCompile; + + this.tryCompileProgram(); + } + + destroy() { + super.destroy(); + this.device.gl.deleteProgram(this.gl_program); + this.device.gl.deleteShader(this.gl_shader_vert); + this.device.gl.deleteShader(this.gl_shader_frag); + } + + private tryCompileProgram(): void { + assert(this.compileState === ProgramCompileState_GL.NeedsCompile); + + const descriptor = this.descriptor; + + const gl = this.device.gl; + if (this.gl_shader_vert !== null) gl.deleteShader(this.gl_shader_vert); + if (this.gl_shader_frag !== null) gl.deleteShader(this.gl_shader_frag); + + // if (descriptor.compute) { + // this.gl_shader_vert = this.compileShader( + // preprocessShader_GLSL(this.device.queryVendorInfo(), 'vert', quadVert), + // gl.VERTEX_SHADER, + // ); + // this.gl_shader_frag = this.compileShader( + // descriptor.preprocessedCompute, + // gl.FRAGMENT_SHADER, + // ); + // } else { + this.gl_shader_vert = this.compileShader( + descriptor.vertex.glsl, + gl.VERTEX_SHADER, + ); + this.gl_shader_frag = this.compileShader( + descriptor.fragment.glsl, + gl.FRAGMENT_SHADER, + ); + // } + + gl.attachShader(this.gl_program, this.gl_shader_vert); + gl.attachShader(this.gl_program, this.gl_shader_frag); + gl.linkProgram(this.gl_program); + + this.compileState = ProgramCompileState_GL.Compiling; + + if (!isWebGL2(gl)) { + // extract uniforms + this.readUniformLocationsFromLinkedProgram(); + // extract attributes + this.readAttributesFromLinkedProgram(); + } + } + + private readAttributesFromLinkedProgram() { + const gl = this.device.gl; + const count = gl.getProgramParameter(this.gl_program, gl.ACTIVE_ATTRIBUTES); + + const defines = getDefines(this.descriptor.vertex.glsl); + const locations = getAttributeLocations( + // Use raw GLSL + this.rawVertexGLSL, + defines, + ); + for (let index = 0; index < count; index++) { + const { name, type, size } = gl.getActiveAttrib(this.gl_program, index); + const location = gl.getAttribLocation(this.gl_program, name); + + const definedLocation = locations.find((l) => l.name === name)?.location; + // Add only user provided attributes, for built-in attributes like + // `gl_InstanceID` locaiton will be < 0 + if (location >= 0 && !isNil(definedLocation)) { + this.attributes[definedLocation] = { + name, + location, + type, + size, + }; + } + } + } + + private readUniformLocationsFromLinkedProgram() { + const gl = this.device.gl; + const numUniforms = gl.getProgramParameter( + this.gl_program, + gl.ACTIVE_UNIFORMS, + ); + + for (let i = 0; i < numUniforms; i++) { + const info = gl.getActiveUniform(this.gl_program, i); + const { name } = parseUniformName(info.name); + let location = gl.getUniformLocation(this.gl_program, name); + this.uniformSetters[name] = getUniformSetter(gl, location, info); + if (info && info.size > 1) { + for (let l = 0; l < info.size; l++) { + location = gl.getUniformLocation(this.gl_program, `${name}[${l}]`); + this.uniformSetters[`${name}[${l}]`] = getUniformSetter( + gl, + location, + info, + ); + } + } + } + } + + private compileShader(contents: string, type: GLenum): WebGLShader { + const gl = this.device.gl; + const shader: WebGLShader = this.device.ensureResourceExists( + gl.createShader(type), + ); + gl.shaderSource(shader, contents); + gl.compileShader(shader); + return shader; + } + + // eslint-disable-next-line + setUniformsLegacy(uniforms: Record = {}) { + const gl = this.device.gl; + + if (!isWebGL2(gl)) { + let programUsed = false; + for (const uniformName in uniforms) { + if (!programUsed) { + gl.useProgram(this.gl_program); + programUsed = true; + } + + const uniform = uniforms[uniformName]; + const uniformSetter = this.uniformSetters[uniformName]; + if (uniformSetter) { + let value = uniform; + if (value instanceof Texture_GL) { + value = value.textureIndex; + } + uniformSetter(value); + } + } + } + + return this; + } +} diff --git a/src/webgl/QueryPool.ts b/src/webgl/QueryPool.ts new file mode 100644 index 0000000..b22541f --- /dev/null +++ b/src/webgl/QueryPool.ts @@ -0,0 +1,60 @@ +import type { QueryPool, QueryPoolType } from '../api'; +import { ResourceType, nArray } from '../api'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { isWebGL2, translateQueryPoolType } from './utils'; + +export class QueryPool_GL extends ResourceBase_GL implements QueryPool { + type: ResourceType.QueryPool = ResourceType.QueryPool; + + gl_query_type: number; + gl_query: WebGLQuery[]; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: { + elemCount: number; + type: QueryPoolType; + }; + }) { + super({ id, device }); + + const gl = this.device.gl; + + if (isWebGL2(gl)) { + const { elemCount, type } = descriptor; + this.gl_query = nArray(elemCount, () => + this.device.ensureResourceExists(gl.createQuery()), + ); + this.gl_query_type = translateQueryPoolType(type); + } + } + + queryResultOcclusion(dstOffs: number): boolean | null { + const gl = this.device.gl; + if (isWebGL2(gl)) { + const gl_query = this.gl_query[dstOffs]; + + if (!gl.getQueryParameter(gl_query, gl.QUERY_RESULT_AVAILABLE)) { + return null; + } + return !!gl.getQueryParameter(gl_query, gl.QUERY_RESULT); + } + return null; + } + + destroy() { + super.destroy(); + const gl = this.device.gl; + if (isWebGL2(gl)) { + for (let i = 0; i < this.gl_query.length; i++) { + gl.deleteQuery(this.gl_query[i]); + } + } + } +} diff --git a/src/webgl/Readback.ts b/src/webgl/Readback.ts new file mode 100644 index 0000000..a551f23 --- /dev/null +++ b/src/webgl/Readback.ts @@ -0,0 +1,215 @@ +import { Buffer, Readback, Texture, getFormatByteSize } from '../api'; +import { GL, ResourceType } from '../api'; +import { clamp } from '@antv/util'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import type { Texture_GL } from './Texture'; +import { getPlatformBuffer, isWebGL2 } from './utils'; + +export class Readback_GL extends ResourceBase_GL implements Readback { + type: ResourceType.Readback = ResourceType.Readback; + + gl_pbo: WebGLBuffer | null = null; + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLSync + gl_sync: WebGLSync | null = null; + + constructor({ id, device }: { id: number; device: Device_GL }) { + super({ id, device }); + } + + private clientWaitAsync( + sync: WebGLSync, + flags = 0, + interval_ms = 10, + ): Promise { + const gl = this.device.gl as WebGL2RenderingContext; + return new Promise((resolve, reject) => { + function test() { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/clientWaitSync + const res = gl.clientWaitSync(sync, flags, 0); + if (res == gl.WAIT_FAILED) { + reject(); + return; + } + if (res == gl.TIMEOUT_EXPIRED) { + setTimeout( + test, + clamp(interval_ms, 0, gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL), + ); + return; + } + resolve(); + } + test(); + }); + } + + private async getBufferSubDataAsync( + target: number, + buffer: WebGLBuffer, + srcByteOffset: number, + dstBuffer: ArrayBufferView, + dstOffset = 0, + length = dstBuffer.byteLength || 0, + ) { + const gl = this.device.gl; + if (isWebGL2(gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/fenceSync + this.gl_sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + + await this.clientWaitAsync(this.gl_sync, 0, 10); + + gl.bindBuffer(target, buffer); + gl.getBufferSubData(target, srcByteOffset, dstBuffer, dstOffset, length); + gl.bindBuffer(target, null); + + return dstBuffer; + } + } + + /** + * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_non-blocking_async_data_readback + */ + async readTexture( + t: Texture, + x: number, + y: number, + width: number, + height: number, + dstBuffer: ArrayBufferView, + dstOffset = 0, + length = dstBuffer.byteLength || 0, + ): Promise { + const gl = this.device.gl; + + const texture = t as Texture_GL; + const gl_format = this.device.translateTextureFormat(texture.pixelFormat); + const gl_type = this.device.translateTextureType(texture.pixelFormat); + const formatByteSize = getFormatByteSize(texture.pixelFormat); + + if (isWebGL2(gl)) { + this.gl_pbo = this.device.ensureResourceExists(gl.createBuffer()); + // PIXEL_PACK_BUFFER: Buffer used for pixel transfer operations + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindBuffer + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); + // STREAM_READ: The contents are intended to be specified once by reading data from WebGL, and queried at most a few times by the application + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData + gl.bufferData(gl.PIXEL_PACK_BUFFER, length, gl.STREAM_READ); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + + gl.bindFramebuffer( + GL.READ_FRAMEBUFFER, + this.device['readbackFramebuffer'], + ); + gl.framebufferTexture2D( + GL.READ_FRAMEBUFFER, + GL.COLOR_ATTACHMENT0, + GL.TEXTURE_2D, + texture.gl_texture, + 0, + ); + + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); + gl.readPixels( + x, + y, + width, + height, + gl_format, + gl_type, + dstOffset * formatByteSize, + ); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + + return this.getBufferSubDataAsync( + gl.PIXEL_PACK_BUFFER, + this.gl_pbo, + 0, + dstBuffer, + dstOffset, + length, + ); + } else { + gl.bindFramebuffer(GL.FRAMEBUFFER, this.device['readbackFramebuffer']); + gl.framebufferTexture2D( + GL.FRAMEBUFFER, + GL.COLOR_ATTACHMENT0, + GL.TEXTURE_2D, + texture.gl_texture, + 0, + ); + // slow requires roundtrip to GPU + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/pixelStorei + gl.pixelStorei(gl.PACK_ALIGNMENT, 4); + gl.readPixels(x, y, width, height, gl.RGBA, gl_type, dstBuffer); + return dstBuffer; + } + } + + readTextureSync( + t: Texture, + x: number, + y: number, + width: number, + height: number, + dstBuffer: ArrayBufferView, + dstOffset = 0, + length = dstBuffer.byteLength || 0, + ): ArrayBufferView { + const gl = this.device.gl; + + const texture = t as Texture_GL; + const gl_type = this.device.translateTextureType(texture.pixelFormat); + + gl.bindFramebuffer(GL.FRAMEBUFFER, this.device['readbackFramebuffer']); + gl.framebufferTexture2D( + GL.FRAMEBUFFER, + GL.COLOR_ATTACHMENT0, + GL.TEXTURE_2D, + texture.gl_texture, + 0, + ); + // slow requires roundtrip to GPU + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/pixelStorei + gl.pixelStorei(gl.PACK_ALIGNMENT, 4); + gl.readPixels(x, y, width, height, gl.RGBA, gl_type, dstBuffer); + return dstBuffer; + } + + async readBuffer( + b: Buffer, + srcByteOffset: number, + dstBuffer: ArrayBufferView, + dstOffset?: number, + length?: number, + ): Promise { + const gl = this.device.gl; + if (isWebGL2(gl)) { + return this.getBufferSubDataAsync( + gl.ARRAY_BUFFER, + getPlatformBuffer(b, srcByteOffset), + srcByteOffset, + dstBuffer, + dstOffset, + length, + ); + } + + // TODO: WebGL1 + return Promise.reject(); + } + + destroy() { + super.destroy(); + if (isWebGL2(this.device.gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/deleteSync + if (this.gl_sync !== null) { + this.device.gl.deleteSync(this.gl_sync); + } + if (this.gl_pbo !== null) { + this.device.gl.deleteBuffer(this.gl_pbo); + } + } + } +} diff --git a/src/webgl/RenderPipeline.ts b/src/webgl/RenderPipeline.ts new file mode 100644 index 0000000..00682cc --- /dev/null +++ b/src/webgl/RenderPipeline.ts @@ -0,0 +1,60 @@ +import type { + Format, + MegaStateDescriptor, + RenderPipeline, + RenderPipelineDescriptor, +} from '../api'; +import { + ResourceType, + PrimitiveTopology, + defaultMegaState, + copyMegaState, +} from '../api'; +import type { Device_GL } from './Device'; +import type { InputLayout_GL } from './InputLayout'; +import type { Program_GL } from './Program'; +import { ResourceBase_GL } from './ResourceBase'; +import { translatePrimitiveTopology } from './utils'; +export class RenderPipeline_GL + extends ResourceBase_GL + implements RenderPipeline +{ + type: ResourceType.RenderPipeline = ResourceType.RenderPipeline; + + program: Program_GL; + drawMode: GLenum; + megaState: MegaStateDescriptor; + inputLayout: InputLayout_GL | null; + + // Attachment data. + colorAttachmentFormats: (Format | null)[]; + depthStencilAttachmentFormat: Format | null; + sampleCount: number; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: RenderPipelineDescriptor; + }) { + super({ id, device }); + + this.drawMode = translatePrimitiveTopology( + descriptor.topology ?? PrimitiveTopology.TRIANGLES, + ); + this.program = descriptor.program as Program_GL; + this.inputLayout = descriptor.inputLayout as InputLayout_GL | null; + + this.megaState = { + ...copyMegaState(defaultMegaState), + ...descriptor.megaStateDescriptor, + }; + + this.colorAttachmentFormats = descriptor.colorAttachmentFormats.slice(); + this.depthStencilAttachmentFormat = descriptor.depthStencilAttachmentFormat; + this.sampleCount = descriptor.sampleCount ?? 1; + } +} diff --git a/src/webgl/RenderTarget.ts b/src/webgl/RenderTarget.ts new file mode 100644 index 0000000..953668d --- /dev/null +++ b/src/webgl/RenderTarget.ts @@ -0,0 +1,86 @@ +import { GL, ResourceType } from '../api'; +import { Format, RenderTarget, RenderTargetDescriptor, Texture } from '../api'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { isWebGL2 } from './utils'; + +export class RenderTarget_GL extends ResourceBase_GL implements RenderTarget { + type: ResourceType.RenderTarget = ResourceType.RenderTarget; + gl_renderbuffer: WebGLRenderbuffer | null = null; + texture: Texture | null = null; + pixelFormat: Format; + width: number; + height: number; + sampleCount: number; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: RenderTargetDescriptor; + }) { + super({ id, device }); + + const gl = this.device.gl; + + const { pixelFormat, width, height, sampleCount = 1, texture } = descriptor; + + let useRenderbuffer = false; + // @see https://blog.tojicode.com/2012/07/using-webgldepthtexture.html + if ( + (pixelFormat === Format.D32F || pixelFormat === Format.D24_S8) && + texture && + !isWebGL2(gl) && + !device.WEBGL_depth_texture + ) { + texture.destroy(); + this.texture = null; + useRenderbuffer = true; + } + + if (!useRenderbuffer && texture) { + this.texture = texture; + } else { + this.gl_renderbuffer = this.device.ensureResourceExists( + gl.createRenderbuffer(), + ); + gl.bindRenderbuffer(gl.RENDERBUFFER, this.gl_renderbuffer); + + const gl_format = this.device.translateTextureInternalFormat( + pixelFormat, + true, + ); + + if (isWebGL2(gl)) { + // @see https://github.com/shrekshao/MoveWebGL1EngineToWebGL2/blob/master/Move-a-WebGL-1-Engine-To-WebGL-2-Blog-2.md#multisampled-renderbuffers + gl.renderbufferStorageMultisample( + GL.RENDERBUFFER, + sampleCount, + gl_format, + width, + height, + ); + } else { + // WebGL1 can only use FXAA or other post-processing methods + gl.renderbufferStorage(GL.RENDERBUFFER, gl_format, width, height); + } + } + this.pixelFormat = pixelFormat; + this.width = width; + this.height = height; + this.sampleCount = sampleCount; + } + + destroy() { + super.destroy(); + if (this.gl_renderbuffer !== null) { + this.device.gl.deleteRenderbuffer(this.gl_renderbuffer); + } + if (this.texture) { + this.texture.destroy(); + } + } +} diff --git a/src/webgl/ResourceBase.ts b/src/webgl/ResourceBase.ts new file mode 100644 index 0000000..bda5f53 --- /dev/null +++ b/src/webgl/ResourceBase.ts @@ -0,0 +1,35 @@ +import type { Disposable, Resource, ResourceBase } from '../api'; +import EventEmitter from 'eventemitter3'; +import type { Device_GL } from './Device'; + +export class ResourceBase_GL + extends EventEmitter + implements ResourceBase, Disposable +{ + id: number; + + name: string; + + device: Device_GL; + + constructor({ id, device }: { id: number; device: Device_GL }) { + super(); + + this.id = id; + this.device = device; + + if (this.device['resourceCreationTracker'] !== null) { + this.device['resourceCreationTracker'].trackResourceCreated( + this as unknown as Resource, + ); + } + } + + destroy() { + if (this.device['resourceCreationTracker'] !== null) { + this.device['resourceCreationTracker'].trackResourceDestroyed( + this as unknown as Resource, + ); + } + } +} diff --git a/src/webgl/ResourceCreationTracker.ts b/src/webgl/ResourceCreationTracker.ts new file mode 100644 index 0000000..acc8a29 --- /dev/null +++ b/src/webgl/ResourceCreationTracker.ts @@ -0,0 +1,46 @@ +import type { Resource } from '../api'; + +export class ResourceCreationTracker { + liveObjects = new Set(); + creationStacks = new Map(); + deletionStacks = new Map(); + + trackResourceCreated(o: Resource): void { + this.creationStacks.set(o, new Error().stack!); + this.liveObjects.add(o); + } + + trackResourceDestroyed(o: Resource): void { + if (this.deletionStacks.has(o)) + console.warn( + `Object double freed:`, + o, + `\n\nCreation stack: `, + this.creationStacks.get(o), + `\n\nDeletion stack: `, + this.deletionStacks.get(o), + `\n\nThis stack: `, + new Error().stack!, + ); + this.deletionStacks.set(o, new Error().stack!); + this.liveObjects.delete(o); + } + + checkForLeaks(): void { + for (const o of this.liveObjects.values()) + console.warn( + 'Object leaked:', + o, + 'Creation stack:', + this.creationStacks.get(o), + ); + } + + setResourceLeakCheck(o: Resource, v: boolean): void { + if (v) { + this.liveObjects.add(o); + } else { + this.liveObjects.delete(o); + } + } +} diff --git a/src/webgl/Sampler.ts b/src/webgl/Sampler.ts new file mode 100644 index 0000000..35c9bd6 --- /dev/null +++ b/src/webgl/Sampler.ts @@ -0,0 +1,180 @@ +import { + GL, + MipFilterMode, + ResourceType, + TexFilterMode, + assert, + isPowerOfTwo, +} from '../api'; +import type { Sampler, SamplerDescriptor } from '../api'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { + getPlatformSampler, + isWebGL2, + translateFilterMode, + translateWrapMode, +} from './utils'; + +/** + * In WebGL 1 texture image data and sampling information are both stored in texture objects + * @see https://github.com/shrekshao/MoveWebGL1EngineToWebGL2/blob/master/Move-a-WebGL-1-Engine-To-WebGL-2-Blog-2.md#sampler-objects + */ +export class Sampler_GL extends ResourceBase_GL implements Sampler { + type: ResourceType.Sampler = ResourceType.Sampler; + + gl_sampler: WebGLSampler; + descriptor: SamplerDescriptor; + + constructor({ + id, + device, + descriptor, + }: { + id: number; + device: Device_GL; + descriptor: SamplerDescriptor; + }) { + super({ id, device }); + + const gl = this.device.gl; + + if (isWebGL2(gl)) { + const gl_sampler = this.device.ensureResourceExists(gl.createSampler()); + gl.samplerParameteri( + gl_sampler, + GL.TEXTURE_WRAP_S, + translateWrapMode(descriptor.wrapS), + ); + gl.samplerParameteri( + gl_sampler, + GL.TEXTURE_WRAP_T, + translateWrapMode(descriptor.wrapT), + ); + gl.samplerParameteri( + gl_sampler, + GL.TEXTURE_WRAP_R, + translateWrapMode(descriptor.wrapQ ?? descriptor.wrapS), + ); + gl.samplerParameteri( + gl_sampler, + GL.TEXTURE_MIN_FILTER, + translateFilterMode(descriptor.minFilter, descriptor.mipFilter), + ); + gl.samplerParameteri( + gl_sampler, + GL.TEXTURE_MAG_FILTER, + translateFilterMode(descriptor.magFilter, MipFilterMode.NO_MIP), + ); + + if (descriptor.minLOD !== undefined) { + gl.samplerParameterf(gl_sampler, GL.TEXTURE_MIN_LOD, descriptor.minLOD); + } + if (descriptor.maxLOD !== undefined) { + gl.samplerParameterf(gl_sampler, GL.TEXTURE_MAX_LOD, descriptor.maxLOD); + } + if (descriptor.compareMode !== undefined) { + gl.samplerParameteri( + gl_sampler, + gl.TEXTURE_COMPARE_MODE, + gl.COMPARE_REF_TO_TEXTURE, + ); + gl.samplerParameteri( + gl_sampler, + gl.TEXTURE_COMPARE_FUNC, + descriptor.compareMode, + ); + } + + const maxAnisotropy = descriptor.maxAnisotropy ?? 1; + if ( + maxAnisotropy > 1 && + this.device.EXT_texture_filter_anisotropic !== null + ) { + assert( + descriptor.minFilter === TexFilterMode.BILINEAR && + descriptor.magFilter === TexFilterMode.BILINEAR && + descriptor.mipFilter === MipFilterMode.LINEAR, + ); + gl.samplerParameterf( + gl_sampler, + this.device.EXT_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT, + maxAnisotropy, + ); + } + + this.gl_sampler = gl_sampler; + } else { + // use later in WebGL1 + this.descriptor = descriptor; + } + } + + setTextureParameters(gl_target: number, width: number, height: number): void { + const gl = this.device.gl; + const descriptor = this.descriptor; + + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL#%E9%9D%9E2%E7%9A%84%E5%B9%82%E7%BA%B9%E7%90%86 + if (this.isNPOT(width, height)) { + gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR); + } else { + gl.texParameteri( + gl_target, + GL.TEXTURE_MIN_FILTER, + translateFilterMode(descriptor.minFilter, descriptor.mipFilter), + ); + } + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_WRAP_S, + translateWrapMode(descriptor.wrapS), + ); + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_WRAP_T, + translateWrapMode(descriptor.wrapT), + ); + + gl.texParameteri( + gl_target, + GL.TEXTURE_MAG_FILTER, + translateFilterMode(descriptor.magFilter, MipFilterMode.NO_MIP), + ); + + // if (descriptor.minLOD !== undefined) { + // gl.texParameterf(gl_target, GL.TEXTURE_MIN_LOD, descriptor.minLOD); + // } + // if (descriptor.maxLOD !== undefined) { + // gl.texParameterf(gl_target, GL.TEXTURE_MAX_LOD, descriptor.maxLOD); + // } + + const maxAnisotropy = descriptor.maxAnisotropy ?? 1; + if ( + maxAnisotropy > 1 && + this.device.EXT_texture_filter_anisotropic !== null + ) { + assert( + descriptor.minFilter === TexFilterMode.BILINEAR && + descriptor.magFilter === TexFilterMode.BILINEAR && + descriptor.mipFilter === MipFilterMode.LINEAR, + ); + gl.texParameteri( + gl_target, + this.device.EXT_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT, + maxAnisotropy, + ); + } + } + + destroy() { + super.destroy(); + + if (isWebGL2(this.device.gl)) { + this.device.gl.deleteSampler(getPlatformSampler(this)); + } + } + + isNPOT(width: number, height: number): boolean { + return !isPowerOfTwo(width) || !isPowerOfTwo(height); + } +} diff --git a/src/webgl/Texture.ts b/src/webgl/Texture.ts new file mode 100644 index 0000000..9bd5df5 --- /dev/null +++ b/src/webgl/Texture.ts @@ -0,0 +1,403 @@ +import { + Format, + FormatTypeFlags, + GL, + ResourceType, + SamplerFormatKind, + Texture, + TextureDescriptor, + TextureDimension, + TextureUsage, + assert, + getFormatSamplerKind, + getFormatTypeFlags, + isPowerOfTwo, +} from '../api'; +import type { Device_GL } from './Device'; +import { ResourceBase_GL } from './ResourceBase'; +import { + getPlatformTexture, + isTextureFormatCompressed, + // isTextureFormatCompressed, + isWebGL2, +} from './utils'; + +export class Texture_GL extends ResourceBase_GL implements Texture { + type: ResourceType.Texture = ResourceType.Texture; + gl_texture: WebGLTexture; + gl_target: GLenum; + pixelFormat: Format; + width: number; + height: number; + depth: number; + numLevels: number; + immutable: boolean; + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/pixelStorei + pixelStore: Partial<{ + packAlignment: number; + unpackAlignment: number; + unpackFlipY: boolean; + }>; + mipmaps: boolean; + formatKind: SamplerFormatKind; + textureIndex: number; // used in WebGL1 + + constructor({ + id, + device, + descriptor, + fake, + }: { + id: number; + device: Device_GL; + descriptor: TextureDescriptor; + fake?: boolean; + }) { + super({ id, device }); + + // Default values. + descriptor = { + dimension: TextureDimension.TEXTURE_2D, + depth: 1, + numLevels: 1, + ...descriptor, + }; + + const gl = this.device.gl; + let gl_target: GLenum; + let gl_texture: WebGLTexture; + const numLevels = this.clampNumLevels(descriptor); + this.immutable = descriptor.usage === TextureUsage.RENDER_TARGET; + this.pixelStore = descriptor.pixelStore; + this.pixelFormat = descriptor.pixelFormat; + this.formatKind = getFormatSamplerKind(descriptor.pixelFormat); + this.width = descriptor.width; + this.height = descriptor.height; + this.depth = descriptor.depth; + this.mipmaps = numLevels >= 1; + + if (!fake) { + gl_texture = this.device.ensureResourceExists(gl.createTexture()); + const gl_type = this.device.translateTextureType(descriptor.pixelFormat); + + const internalformat = this.device.translateTextureInternalFormat( + descriptor.pixelFormat, + ); + this.device.setActiveTexture(gl.TEXTURE0); + this.device['currentTextures'][0] = null; + + this.preprocessImage(); + + if (descriptor.dimension === TextureDimension.TEXTURE_2D) { + gl_target = GL.TEXTURE_2D; + gl.bindTexture(gl_target, gl_texture); + if (this.immutable) { + if (isWebGL2(gl)) { + // texStorage2D will create an immutable texture(fixed size) + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texStorage2D + // @see https://github.com/visgl/luma.gl/issues/193 + // @see https://github.com/WebGLSamples/WebGL2Samples/blob/master/samples/texture_immutable.html + gl.texStorage2D( + gl_target, + numLevels, + internalformat, + descriptor.width, + descriptor.height, + ); + } else { + // texImage2D: level must be 0 for DEPTH_COMPONENT format + // const level = internalformat === GL.DEPTH_COMPONENT || this.isNPOT() ? 0 : numLevels; + const level = + internalformat === GL.DEPTH_COMPONENT || this.isNPOT() ? 0 : 0; + + if ( + (this.pixelFormat === Format.D32F || + this.pixelFormat === Format.D24_S8) && + !isWebGL2(gl) && + !device.WEBGL_depth_texture + ) { + } else { + // if (!isWebGL2(gl)) { + // if (internalformat === GL.RGBA4) { + // internalformat = GL.RGBA; + // } + // } + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + gl.texImage2D( + gl_target, + level, + internalformat, + descriptor.width, + descriptor.height, + 0, + internalformat, + gl_type, + null, + ); + + // @see https://stackoverflow.com/questions/21954036/dartweb-gl-render-warning-texture-bound-to-texture-unit-0-is-not-renderable + // [.WebGL-0x106ad0400]RENDER WARNING: texture bound to texture unit 0 is not renderable. It might be non-power-of-2 or have incompatible texture filtering (maybe)? + if (this.mipmaps && this.isNPOT()) { + this.mipmaps = false; + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_MIN_FILTER, + GL.LINEAR, + ); + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_WRAP_S, + GL.CLAMP_TO_EDGE, + ); + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_WRAP_T, + GL.CLAMP_TO_EDGE, + ); + } + } + } + } + + assert(descriptor.depth === 1); + } else if (descriptor.dimension === TextureDimension.TEXTURE_2D_ARRAY) { + gl_target = GL.TEXTURE_2D_ARRAY; + gl.bindTexture(gl_target, gl_texture); + if (this.immutable) { + if (isWebGL2(gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texStorage3D + gl.texStorage3D( + gl_target, + numLevels, + internalformat, + descriptor.width, + descriptor.height, + descriptor.depth, + ); + } + } + } else if (descriptor.dimension === TextureDimension.TEXTURE_3D) { + gl_target = GL.TEXTURE_3D; + gl.bindTexture(gl_target, gl_texture); + if (this.immutable) { + if (isWebGL2(gl)) { + gl.texStorage3D( + gl_target, + numLevels, + internalformat, + descriptor.width, + descriptor.height, + descriptor.depth, + ); + } + } + } else if (descriptor.dimension === TextureDimension.TEXTURE_CUBE_MAP) { + gl_target = GL.TEXTURE_CUBE_MAP; + gl.bindTexture(gl_target, gl_texture); + if (this.immutable) { + if (isWebGL2(gl)) { + gl.texStorage2D( + gl_target, + numLevels, + internalformat, + descriptor.width, + descriptor.height, + ); + } + } + assert(descriptor.depth === 6); + } else { + throw new Error('whoops'); + } + } + + this.gl_texture = gl_texture; + this.gl_target = gl_target; + this.numLevels = numLevels; + } + + setImageData(levelDatas: (TexImageSource | ArrayBufferView)[], lod = 0) { + const gl = this.device.gl; + const isCompressed = isTextureFormatCompressed(this.pixelFormat); + // const is3D = + // this.gl_target === GL.TEXTURE_3D || + // this.gl_target === GL.TEXTURE_2D_ARRAY; + const isCube = this.gl_target === GL.TEXTURE_CUBE_MAP; + // @ts-ignore + const isTypedArray = levelDatas[0].buffer; + + this.device.setActiveTexture(gl.TEXTURE0); + this.device['currentTextures'][0] = null; + + const data = levelDatas[0]; + + let width: number; + let height: number; + if (isTypedArray) { + width = this.width; + height = this.height; + } else { + // FIXME: Property 'width' does not exist on type 'TexImageSource'. + // Property 'width' does not exist on type 'VideoFrame'. + // @ts-ignore + width = (data as TexImageSource).width; + // @ts-ignore + height = (data as TexImageSource).height; + // update size + this.width = width; + this.height = height; + } + + gl.bindTexture(this.gl_target, this.gl_texture); + + const gl_format = this.device.translateTextureFormat(this.pixelFormat); + const gl_type = this.device.translateTextureType(this.pixelFormat); + + this.preprocessImage(); + + for (let z = 0; z < this.depth; z++) { + const levelData = levelDatas[z]; + let gl_target = this.gl_target; + + if (isCube) { + gl_target = GL.TEXTURE_CUBE_MAP_POSITIVE_X + (z % 6); + } + + if (this.immutable) { + if (isCompressed) { + // TODO: gl.compressedTexSubImage2D() + } + // must use texSubImage2D instead of texImage2D, since texture is immutable + // @see https://stackoverflow.com/questions/56123201/unity-plugin-texture-is-immutable?rq=1 + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texSubImage2D + gl.texSubImage2D( + gl_target, + lod, + 0, + 0, + width, + height, + gl_format, + gl_type, + levelData as ArrayBufferView, + ); + } else { + if (isWebGL2(gl)) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + gl.texImage2D( + gl_target, + lod, + gl_format, + width, + height, + 0, // border must be 0 + gl_format, // TODO: can be different with gl_format + gl_type, + levelData as ArrayBufferView, + ); + } else { + // WebGL1: upload Array & Image separately + if (isTypedArray) { + (gl as WebGLRenderingContext).texImage2D( + gl_target, + lod, + gl_format, + width, + height, + 0, + gl_format, + gl_type, + levelData as ArrayBufferView, + ); + } else { + (gl as WebGLRenderingContext).texImage2D( + gl_target, + lod, + gl_format, + gl_format, + gl_type, + levelData as TexImageSource, + ); + } + } + } + } + + if (this.mipmaps) { + this.generateMipmap(); + } + } + + destroy() { + super.destroy(); + this.device.gl.deleteTexture(getPlatformTexture(this)); + } + + private clampNumLevels(descriptor: TextureDescriptor): number { + if ( + descriptor.dimension === TextureDimension.TEXTURE_2D_ARRAY && + descriptor.depth > 1 + ) { + const typeFlags: FormatTypeFlags = getFormatTypeFlags( + descriptor.pixelFormat, + ); + if (typeFlags === FormatTypeFlags.BC1) { + // Chrome/ANGLE seems to have issues with compressed miplevels of size 1/2, so clamp before they arrive... + // https://bugs.chromium.org/p/angleproject/issues/detail?id=4056 + let w = descriptor.width, + h = descriptor.height; + for (let i = 0; i < descriptor.numLevels; i++) { + if (w <= 2 || h <= 2) return i - 1; + + w = Math.max((w / 2) | 0, 1); + h = Math.max((h / 2) | 0, 1); + } + } + } + + return descriptor.numLevels; + } + + private preprocessImage() { + const gl = this.device.gl; + if (this.pixelStore) { + if (this.pixelStore.unpackFlipY) { + gl.pixelStorei(GL.UNPACK_FLIP_Y_WEBGL, true); + } + if (this.pixelStore.packAlignment) { + gl.pixelStorei(GL.PACK_ALIGNMENT, this.pixelStore.packAlignment); + } + if (this.pixelStore.unpackAlignment) { + gl.pixelStorei(GL.UNPACK_ALIGNMENT, this.pixelStore.unpackAlignment); + } + } + } + + private generateMipmap(): this { + const gl = this.device.gl; + if (!isWebGL2(gl) && this.isNPOT()) { + return this; + } + + if (this.gl_texture && this.gl_target) { + gl.bindTexture(this.gl_target, this.gl_texture); + gl.generateMipmap(this.gl_target); + gl.texParameteri( + GL.TEXTURE_2D, + GL.TEXTURE_MIN_FILTER, + GL.NEAREST_MIPMAP_LINEAR, + ); + gl.bindTexture(this.gl_target, null); + } + return this; + } + + private isNPOT(): boolean { + const gl = this.device.gl; + if (isWebGL2(gl)) { + // NPOT restriction is only for WebGL1 + return false; + } + return !isPowerOfTwo(this.width) || !isPowerOfTwo(this.height); + } +} diff --git a/src/webgl/WebGLDeviceContribution.ts b/src/webgl/WebGLDeviceContribution.ts new file mode 100644 index 0000000..f0645a6 --- /dev/null +++ b/src/webgl/WebGLDeviceContribution.ts @@ -0,0 +1,77 @@ +import { DeviceContribution } from '../api'; +import { Device_GL } from './Device'; + +export interface WebGLRendererPluginOptions { + targets: ('webgl1' | 'webgl2')[]; + onContextCreationError: (e: Event) => void; + onContextLost: (e: Event) => void; + onContextRestored: (e: Event) => void; +} + +export class WebGLDeviceContribution implements DeviceContribution { + constructor(private pluginOptions: Partial) {} + + async createSwapChain($canvas: HTMLCanvasElement) { + const options: WebGLContextAttributes = { + // alpha: true, + antialias: false, + // @see https://stackoverflow.com/questions/27746091/preservedrawingbuffer-false-is-it-worth-the-effort + preserveDrawingBuffer: false, + // @see https://webglfundamentals.org/webgl/lessons/webgl-qna-how-to-use-the-stencil-buffer.html + stencil: true, + // @see https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html + premultipliedAlpha: true, + }; + this.handleContextEvents($canvas); + + const { targets } = this.pluginOptions; + + let gl: WebGLRenderingContext | WebGL2RenderingContext; + if (targets.includes('webgl2')) { + gl = + $canvas.getContext('webgl2', options) || + ($canvas.getContext( + 'experimental-webgl2', + options, + ) as WebGL2RenderingContext); + } + + if (!gl && targets.includes('webgl1')) { + gl = + $canvas.getContext('webgl', options) || + ($canvas.getContext( + 'experimental-webgl', + options, + ) as WebGLRenderingContext); + } + + return new Device_GL(gl as WebGLRenderingContext | WebGL2RenderingContext, { + shaderDebug: true, + trackResources: true, + }); + } + + private handleContextEvents($canvas: HTMLCanvasElement) { + const { onContextLost, onContextRestored, onContextCreationError } = + this.pluginOptions; + // bind context event listeners + if (onContextCreationError) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/webglcontextcreationerror_event + $canvas.addEventListener( + 'webglcontextcreationerror', + onContextCreationError, + false, + ); + } + if (onContextLost) { + $canvas.addEventListener('webglcontextlost', onContextLost, false); + } + if (onContextRestored) { + $canvas.addEventListener( + 'webglcontextrestored', + onContextRestored, + false, + ); + } + } +} diff --git a/src/webgl/interfaces.ts b/src/webgl/interfaces.ts new file mode 100644 index 0000000..884d301 --- /dev/null +++ b/src/webgl/interfaces.ts @@ -0,0 +1,59 @@ +import type { SamplerFormatKind } from '../api'; + +export interface EXT_texture_compression_rgtc { + COMPRESSED_RED_RGTC1_EXT: GLenum; + COMPRESSED_SIGNED_RED_RGTC1_EXT: GLenum; + COMPRESSED_RED_GREEN_RGTC2_EXT: GLenum; + COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: GLenum; +} + +export interface OES_draw_buffers_indexed { + enableiOES: (target: GLuint, index: GLuint) => void; + disableiOES: (target: GLenum, index: GLuint) => void; + blendEquationiOES: (buf: GLuint, mode: GLenum) => void; + blendEquationSeparateiOES: ( + buf: GLuint, + modeRGB: GLenum, + modeAlpha: GLenum, + ) => void; + blendFunciOES: (buf: GLuint, src: GLenum, dst: GLenum) => void; + blendFuncSeparateiOES: ( + buf: GLuint, + srcRGB: GLenum, + dstRGB: GLenum, + srcAlpha: GLenum, + dstAlpha: GLenum, + ) => void; + colorMaskiOES: ( + buf: GLuint, + r: GLboolean, + g: GLboolean, + b: GLboolean, + a: GLboolean, + ) => void; +} + +export interface KHR_parallel_shader_compile { + COMPLETION_STATUS_KHR: number; +} + +export interface EXT_texture_norm16 { + R16_EXT: GLenum; + RG16_EXT: GLenum; + RGB16_EXT: GLenum; + RGBA16_EXT: GLenum; + R16_SNORM_EXT: GLenum; + RG16_SNORM_EXT: GLenum; + RGB16_SNORM_EXT: GLenum; + RGBA16_SNORM_EXT: GLenum; +} + +export class GPlatformWebGL2Config { + public trackResources = false; + public shaderDebug = false; +} + +export interface BindingLayoutSamplerDescriptor_GL { + gl_target: GLenum; + formatKind: SamplerFormatKind; +} diff --git a/src/webgl/utils.ts b/src/webgl/utils.ts new file mode 100644 index 0000000..6be164d --- /dev/null +++ b/src/webgl/utils.ts @@ -0,0 +1,292 @@ +import { + GL, + FormatCompFlags, + FormatFlags, + FormatTypeFlags, + getFormatCompFlags, + getFormatFlags, + getFormatTypeFlags, + Format, + BlendFactor, + BlendMode, + BufferFrequencyHint, + BufferUsage, + MipFilterMode, + PrimitiveTopology, + QueryPoolType, + TexFilterMode, + TextureDimension, + WrapMode, +} from '../api'; +import type { Buffer, ChannelBlendState, Sampler, Texture } from '../api'; +import type { Buffer_GL } from './Buffer'; +import type { Sampler_GL } from './Sampler'; +import type { Texture_GL } from './Texture'; + +// @see https://github.com/visgl/luma.gl/blob/30a1039573576d73641de7c1ba222e8992eb526e/modules/gltools/src/utils/webgl-checks.ts#L22 +export function isWebGL2( + gl: WebGL2RenderingContext | WebGLRenderingContext, +): gl is WebGL2RenderingContext { + if ( + typeof WebGL2RenderingContext !== 'undefined' && + gl instanceof WebGL2RenderingContext + ) { + return true; + } + // Look for debug contexts, headless gl etc + // @ts-ignore + return Boolean(gl && gl._version === 2); +} + +export function isTextureFormatCompressed(fmt: Format): boolean { + const typeFlags: FormatTypeFlags = getFormatTypeFlags(fmt); + switch (typeFlags) { + case FormatTypeFlags.BC1: + case FormatTypeFlags.BC2: + case FormatTypeFlags.BC3: + case FormatTypeFlags.BC4_UNORM: + case FormatTypeFlags.BC4_SNORM: + case FormatTypeFlags.BC5_UNORM: + case FormatTypeFlags.BC5_SNORM: + return true; + default: + return false; + } +} + +export function isFormatSizedInteger(fmt: Format): boolean { + const flags = getFormatFlags(fmt); + if (flags & FormatFlags.Normalized) return false; + + const typeFlags = getFormatTypeFlags(fmt); + // Check for integer types. + if ( + typeFlags === FormatTypeFlags.S8 || + typeFlags === FormatTypeFlags.S16 || + typeFlags === FormatTypeFlags.S32 + ) + return true; + if ( + typeFlags === FormatTypeFlags.U8 || + typeFlags === FormatTypeFlags.U16 || + typeFlags === FormatTypeFlags.U32 + ) + return true; + + return false; +} + +export function translateBufferHint(hint: BufferFrequencyHint): GLenum { + switch (hint) { + case BufferFrequencyHint.STATIC: + return GL.STATIC_DRAW; + case BufferFrequencyHint.DYNAMIC: + return GL.DYNAMIC_DRAW; + } +} + +export function translateBufferUsageToTarget(usage: BufferUsage): GLenum { + if (usage & BufferUsage.INDEX) { + return GL.ELEMENT_ARRAY_BUFFER; + } else if (usage & BufferUsage.VERTEX) { + return GL.ARRAY_BUFFER; + } else if (usage & BufferUsage.UNIFORM) { + return GL.UNIFORM_BUFFER; + } +} + +export function translatePrimitiveTopology( + topology: PrimitiveTopology, +): GLenum { + switch (topology) { + case PrimitiveTopology.TRIANGLES: + return GL.TRIANGLES; + case PrimitiveTopology.POINTS: + return GL.POINTS; + case PrimitiveTopology.TRIANGLE_STRIP: + return GL.TRIANGLE_STRIP; + case PrimitiveTopology.LINES: + return GL.LINES; + case PrimitiveTopology.LINE_STRIP: + return GL.LINE_STRIP; + default: + throw new Error('Unknown primitive topology mode'); + } +} + +function translateType(flags: FormatTypeFlags): GLenum { + switch (flags) { + case FormatTypeFlags.U8: + return GL.UNSIGNED_BYTE; + case FormatTypeFlags.U16: + return GL.UNSIGNED_SHORT; + case FormatTypeFlags.U32: + return GL.UNSIGNED_INT; + case FormatTypeFlags.S8: + return GL.BYTE; + case FormatTypeFlags.S16: + return GL.SHORT; + case FormatTypeFlags.S32: + return GL.INT; + case FormatTypeFlags.F16: + return GL.HALF_FLOAT; + case FormatTypeFlags.F32: + return GL.FLOAT; + default: + throw new Error('whoops'); + } +} +function translateSize(flags: FormatCompFlags): number { + switch (flags) { + case FormatCompFlags.R: + return 1; + case FormatCompFlags.RG: + return 2; + case FormatCompFlags.RGB: + return 3; + case FormatCompFlags.RGBA: + return 4; + default: + return 1; + } +} +export function translateVertexFormat(fmt: Format): { + size: number; + type: GLenum; + normalized: boolean; +} { + const typeFlags = getFormatTypeFlags(fmt); + const compFlags = getFormatCompFlags(fmt); + const flags = getFormatFlags(fmt); + + const type = translateType(typeFlags); + const size = translateSize(compFlags); + const normalized = !!(flags & FormatFlags.Normalized); + return { size, type, normalized }; +} + +export function translateIndexFormat(format: Format): GLenum { + switch (format) { + case Format.U8_R: + return GL.UNSIGNED_BYTE; + case Format.U16_R: + return GL.UNSIGNED_SHORT; + case Format.U32_R: + return GL.UNSIGNED_INT; + default: + throw new Error('whoops'); + } +} + +export function translateWrapMode(wrapMode: WrapMode): GLenum { + switch (wrapMode) { + case WrapMode.CLAMP: + return GL.CLAMP_TO_EDGE; + case WrapMode.REPEAT: + return GL.REPEAT; + case WrapMode.MIRROR: + return GL.MIRRORED_REPEAT; + default: + throw new Error('whoops'); + } +} + +export function translateFilterMode( + filter: TexFilterMode, + mipFilter: MipFilterMode, +): GLenum { + if (mipFilter === MipFilterMode.LINEAR && filter === TexFilterMode.BILINEAR) { + return GL.LINEAR_MIPMAP_LINEAR; + } + if (mipFilter === MipFilterMode.LINEAR && filter === TexFilterMode.POINT) { + return GL.NEAREST_MIPMAP_LINEAR; + } + if ( + mipFilter === MipFilterMode.NEAREST && + filter === TexFilterMode.BILINEAR + ) { + return GL.LINEAR_MIPMAP_NEAREST; + } + if (mipFilter === MipFilterMode.NEAREST && filter === TexFilterMode.POINT) { + return GL.NEAREST_MIPMAP_NEAREST; + } + if (mipFilter === MipFilterMode.NO_MIP && filter === TexFilterMode.BILINEAR) { + return GL.LINEAR; + } + if (mipFilter === MipFilterMode.NO_MIP && filter === TexFilterMode.POINT) { + return GL.NEAREST; + } + throw new Error('Unknown texture filter mode'); +} + +export function getPlatformBuffer( + buffer_: Buffer, + byteOffset = 0, +): WebGLBuffer { + const buffer = buffer_ as Buffer_GL; + return buffer.gl_buffer_pages[(byteOffset / buffer.pageByteSize) | 0]; +} + +export function getPlatformTexture(texture_: Texture): WebGLTexture { + const texture = texture_ as Texture_GL; + return texture.gl_texture; +} + +export function getPlatformSampler(sampler_: Sampler): WebGLSampler { + const sampler = sampler_ as Sampler_GL; + return sampler.gl_sampler; +} + +// eslint-disable-next-line +export function assignPlatformName(o: any, name: string): void { + o.name = name; + o.__SPECTOR_Metadata = { name }; +} + +export function findall(haystack: string, needle: RegExp): RegExpExecArray[] { + const results: RegExpExecArray[] = []; + while (true) { + const result = needle.exec(haystack); + if (!result) break; + results.push(result); + } + return results; +} + +export function isBlendStateNone(blendState: ChannelBlendState): boolean { + return ( + blendState.blendMode == BlendMode.ADD && + blendState.blendSrcFactor == BlendFactor.ONE && + blendState.blendDstFactor === BlendFactor.ZERO + ); +} + +export function translateQueryPoolType(type: QueryPoolType): GLenum { + switch (type) { + case QueryPoolType.OcclusionConservative: + return GL.ANY_SAMPLES_PASSED_CONSERVATIVE; + default: + throw new Error('whoops'); + } +} + +export function translateTextureDimension(dimension: TextureDimension): GLenum { + if (dimension === TextureDimension.TEXTURE_2D) return GL.TEXTURE_2D; + else if (dimension === TextureDimension.TEXTURE_2D_ARRAY) + return GL.TEXTURE_2D_ARRAY; + else if (dimension === TextureDimension.TEXTURE_CUBE_MAP) + return GL.TEXTURE_CUBE_MAP; + else if (dimension === TextureDimension.TEXTURE_3D) return GL.TEXTURE_3D; + else throw new Error('whoops'); +} + +export function isBlockCompressSized( + w: number, + h: number, + bw: number, + bh: number, +): boolean { + if (w % bw !== 0) return false; + if (h % bh !== 0) return false; + return true; +} diff --git a/test/demos/index.ts b/test/demos/index.ts new file mode 100644 index 0000000..c41589d --- /dev/null +++ b/test/demos/index.ts @@ -0,0 +1 @@ +// export { chartSpec } from "./chart-spec"; diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..dcaa0e0 --- /dev/null +++ b/test/index.html @@ -0,0 +1,3 @@ + + + diff --git a/test/main.ts b/test/main.ts new file mode 100644 index 0000000..7fd9279 --- /dev/null +++ b/test/main.ts @@ -0,0 +1,36 @@ +import * as demos from "./demos"; + +const select = document.createElement("select"); +select.style.margin = "1em"; +select.onchange = onChange; +select.style.display = "block"; +document.body.append(select); + +const options = Object.keys(demos).map((d) => { + const option = document.createElement("option"); + option.textContent = d; + option.value = d; + return option; +}); +options.forEach((d) => select.append(d)); + +const initialValue = new URL(location as any).searchParams.get( + "name" +) as string; +if (demos[initialValue]) select.value = initialValue; + +let node; +render(); + +function render() { + if (node) node.remove(); + const demo = demos[select.value]; + node = demo(); + document.body.append(node); +} + +function onChange() { + const { value } = select; + history.pushState({ value }, "", `?name=${value}`); + render(); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..98600e8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "outDir": "./", + "module": "ESNext", + "target": "es5", + "jsx": "react", + "moduleResolution": "node", + "experimentalDecorators": true, + "declaration": true, + "sourceMap": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "isolatedModules": true, + "pretty": true, + "lib": ["dom", "esnext"], + "skipLibCheck": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "importHelpers": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "lib", "es"] +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..609bfe3 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import path from "path"; + +export default defineConfig({ + root: path.resolve("./test"), + server: { port: 8080, open: "/" }, +});