diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d120fcb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 120 diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..ddd9dec --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,159 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + parserOptions: { + tsconfigRootDir: __dirname, + project: ["**/tsconfig.json"], + }, + env: { + browser: true, + node: true, + jest: true, + }, + ignorePatterns: [ + '**/{node_modules,libs}', + '*.js', + '*.d.ts', + ], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:promise/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:compat/recommended", + ], + plugins: [ + "@typescript-eslint", + "compat", + ], + rules: { + "arrow-parens": ["error", "as-needed"], + "array-bracket-spacing": ["error", "never"], + "brace-style": ["error", "1tbs", { "allowSingleLine": true }], + "comma-dangle": ["error", "always-multiline"], + "curly": "error", + "generator-star-spacing": ["error", { + "before": false, + "after": true, + "anonymous": "neither", + "method": "neither" + }], + "new-parens": "error", + // TODO:: will be opened + "spaced-comment": "off", + "no-multi-spaces": [ + "error", + { + "ignoreEOLComments": true + } + ], + "no-console": ["error", { "allow": ["info", "warn", "error", "debug", "trace"] }], + "no-inner-declarations": "error", + "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1 }], + "no-trailing-spaces": "error", + "no-void": ["error", { "allowAsStatement": true }], + "padding-line-between-statements": [ + "error", + { "blankLine": "always", "prev": "*", "next": ["return", "break"] }, + { "blankLine": "never", "prev": "*", "next": ["case", "default"] }, + { "blankLine": "always", "prev": ["const", "let", "var"], "next": "*" }, + { "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] } + ], + "promise/always-return": "off", + "promise/catch-or-return": "off", + "prefer-rest-params": "off", + "semi": ["error", "always"], + "space-in-parens": ["error", "never"], + "@typescript-eslint/comma-spacing": "error", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { "vars": "all", "varsIgnorePattern": "^_", "args": "none", "caughtErrors": "all", "caughtErrorsIgnorePattern": "^ignore" } + ], + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": ["error", { "types": { "{}": false, "Function": false, "Object": false } }], + "@typescript-eslint/indent": ["error", 2, { + "SwitchCase": 1, + "ignoredNodes": [ + `ClassBody.body > PropertyDefinition[decorators.length > 0] > .key`, + ], + }], + "@typescript-eslint/keyword-spacing": "error", + // TODO:: will be opened + "@typescript-eslint/no-var-requires": "off", + // TODO:: will be opened + "@typescript-eslint/no-non-null-assertion": "off", + // TODO:: will be opened + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unnecessary-type-constraint": "error", + "@typescript-eslint/no-redundant-type-constituents": "warn", + // TODO:: will be opened + "@typescript-eslint/no-unsafe-return": "off", + // TODO:: will be opened + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-call": "off", + "@typescript-eslint/object-curly-spacing": ["error", "always"], + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-reduce-type-parameter": "error", + "@typescript-eslint/prefer-ts-expect-error": "error", + "@typescript-eslint/return-await": "error", + // TODO:: will be opened + "@typescript-eslint/restrict-plus-operands": "off", + // TODO:: will be opened + "@typescript-eslint/restrict-template-expressions": "off", + "@typescript-eslint/space-infix-ops": ["error", { "int32Hint": false }], + // TODO:: will be "error" + "@typescript-eslint/strict-boolean-expressions": "off", + "@typescript-eslint/no-floating-promises": ["error", { "ignoreVoid": true, "ignoreIIFE": true }], + "@typescript-eslint/quotes": ["error", "single"], + // TODO:: will be opened + "@typescript-eslint/require-await": "off", + "@typescript-eslint/space-before-blocks": "error", + "@typescript-eslint/space-before-function-paren": ["error", "always"], + "@typescript-eslint/type-annotation-spacing": "error", + "@typescript-eslint/unbound-method": "off", + // TODO:: will be opened + "@typescript-eslint/no-misused-promises": "off", + "@typescript-eslint/prefer-regexp-exec": "off", + "@typescript-eslint/semi": "error", + // TODO:: will be opened + "@typescript-eslint/member-delimiter-style": ["error", { + "multiline": { + "delimiter": "comma", + "requireLast": true + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + } + }], + "@typescript-eslint/no-unsafe-enum-comparison": "warn", + "@typescript-eslint/no-base-to-string": "off", + "@typescript-eslint/no-duplicate-enum-values": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + // TODO:: will be opened + "@typescript-eslint/no-unsafe-argument": "off", + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "disallowTypeAnnotations": false, + }, + ], + "compat/compat": "error", + }, + overrides: [ + { + "files": ["**/test/**/*.ts", "**/demo/**/*.ts"], + "rules": { + "compat/compat": "off", + "@typescript-eslint/no-unused-vars": "off" + } + } + ] +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2b7da1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +node_modules +.DS_Store +dist +lib +*.local +*.tgz +.eslintcache +*.tsbuildinfo +.vscode +.idea +.history +.pnpm-debug.log +temp +api +www diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 0000000..31354ec --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..f3c3a7b --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" +PATH=$PATH:/usr/local/bin:/usr/local/sbin +npx commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..99febd2 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" +PATH=$PATH:/usr/local/bin:/usr/local/sbin +npx lint-staged diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 0000000..5c81507 --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,6 @@ +{ + "src/**/*.ts": [ + "eslint --cache --fix", + "sh -c 'tsc -b tsconfig.check.json'" + ] +} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..618365b --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +engine-strict=true +enable-pre-post-scripts=true diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb6039c --- /dev/null +++ b/README.md @@ -0,0 +1,274 @@ +# Galacean Engine Effects + +在 Galacean 环境下加载并渲染 Effects 动效 + +## 使用步骤 + +### 1、安装依赖 + +``` bash +$ npm i @galacean/engine --save +# 安装 Galacean 的 Effects 组件 +$ npm i @galacean/engine-effects --save +``` + +### 1、Galacean 场景初始化 + +在 Galacean 中实现 Effects 首先要创建一个 Galacean 场景(如果你没有创建 Engine 对象的话): + +``` ts +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; + +// 创建一个 canvas +const canvas = document.createElement('canvas'); +// 创建一个 engine 对象,WebGL 版本可选 +const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL2 } }); +const rootEntity = engine.sceneManager.activeScene.createRootEntity(); +const cameraEntity = rootEntity.createChild('camera'); +// 创建一个相机对象 +const camera = cameraEntity.addComponent(Camera); + +engine.canvas.resizeByClientSize(); + +camera.fieldOfView = 60; +camera.nearClipPlane = 0.1; +camera.farClipPlane = 1000; + +camera.enableFrustumCulling = false; +cameraEntity.transform.setPosition(0, 0, 8); +``` + +### 2、实例化 GalaceanDisplayComponent 并加载 Effects 资源 + +#### Effects 在 Galacean Engine 场景中渲染(使用场景如氛围粒子等) + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 创建一个空的 Entity 对象 +const entity = rootEntity.createChild(); +const displayComponent = entity.addComponent(GalaceanDisplayComponent); + +// 初始化时把当前 engine 中的相机传递过去 +displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); +// 加载 Effects 的资源 +const scene = await displayComponent.loadScene('./xxx.json'); +scene.setPosition(0,3,0); +``` + +#### Effects 和编辑器渲染效果同步(使用场景如弹窗、UI 层组件等) + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 创建一个空的 Entity 对象 +const entity = rootEntity.createChild(); +const displayComponent = entity.addComponent(GalaceanDisplayComponent); + +// 初始化不传入 Galacean 相机则默认使用Effects自带相机和编辑器保持同步 +displayComponent.initialize(engine._hardwareRenderer.gl); +// 加载 Effects 的资源 +const scene = await displayComponent.loadScene('./xxx.json'); + +// 调整平移 +scene.setPosition(0,3,0); +``` + +> Tips +> +> - 如果你想创建多个 Effects 只需要重复上述步骤就可以了 +> - 单独暂停 Effects:`displayComponent.pause();` +> - 单独继续播放 Effects:`displayComponent.resume();` +> - 单独销毁操作:在渲染 Effects 中不需要用户关心 Effects 的销毁,如果想强行销毁 Effects 请调用 `displayComponent.dispose(name?)`,其中 `name` 参数可选,销毁指定的 composition,默认全部销毁 + +### 3、执行 Galacean 渲染 + +``` ts +// 当然你也可以先执行渲染,再实例化 Effects +engine.run(); +``` + +## 高级用法 + +### 数据模版支持 + +下面给出如何使用 Effects 中的数据模板: + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 创建一个空的 Entity 对象 +const entity = rootEntity.createChild(); +const displayComponent = entity.addComponent(GalaceanDisplayComponent); + +// 初始化时把当前 engine 中的相机传递过去 +displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); +// 加载 Effects 的资源 +const scene = await displayComponent.loadScene('./xxx.json', { + variables: { + // 动态图片,支持传入图片地址或地址数组 + background: 'https://xxx.png', // 如果图片加载失败,将会触发加载失败 + image_avatar: ['https://xxx.png', 'https://xxx.png'], // 如果第一个加载失败,将尝试使用第二个地址,都失败将会触发加载失败 + }, +}); +``` + +和直接在 `effects-runtime` 中的使用类似,更多使用方法参考 Effects 的开发者文档: + +### 多 DisplayComponent 的播放(不推荐) + +在 `engine-effects` 中允许创建多个 `DisplayComponent`,多个 `DisplayComponent` 也是可以一起播放 Effects 的,下面给出多个 `DisplayComponent` 如何一起播放 Effects: + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-Effects'; + +// 创建一个空的 Entity 对象 +const entity0 = rootEntity.createChild(); +const displayComponent0 = entity.addComponent(GalaceanDisplayComponent); + +// 初始化不传入 Galacean 相机则默认使用Effects自带相机和编辑器保持同步 +displayComponent0.initialize(engine._hardwareRenderer.gl); +// 加载 Effects 的资源 +const scene0 = await displayComponent0.loadScene('./xxx.json'); + +// RTS 调用 +// 以第一个合成为例 +const transform = displayComponent0.compositions[0].rootTransform; +// 调整平移 +transform.position[1] = 5; // transform.setPosition(0,5,0); +// 调整旋转 +transform.setRotation(90,0,0); +// 调整缩放 +transform.scale[0] = 2; // transform.setScale(2,1,1); + +// 播放 Effects 资源 +await displayComponent0.play(scene0); + +const entity1 = rootEntity.createChild(); +const displayComponent1 = entity.addComponent(GalaceanDisplayComponent); + +// 初始化不传入 Galacean 相机则默认使用Effects自带相机和编辑器保持同步 +displayComponent1.initialize(engine._hardwareRenderer.gl); +// 加载 Effects 的资源 +const scene1 = await displayComponent.loadScene('./xxx.json'); + +// 播放 Effects 资源,这样 displayComponent1 中的 Effects 都会置于 displayComponent0 的上层 +await displayComponent1.play(scene, { componentRenderOrder:2 }); +``` + +### 多合成播放 + +下面给出如何使用 Effects 中的多合成播放: + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 创建一个空的 Entity 对象 +const entity = rootEntity.createChild(); +const displayComponent = entity.addComponent(GalaceanDisplayComponent); +const json = [ + './xxx.json', + './xxx.json', + './xxx.json', +] + +// 初始化时把当前 engine 中的相机传递过去 +displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); + +// 加载compositions +const compositions = await Promise.all(json.map(json => displayComponent.loadScene(json))); +``` + +### 交互元素 + +开发和设计约定好交互元素名称后,便可以通过交互回调来监听渲染中的交互元素了,下面给出如何使用 Effects 中的交互元素: + +``` ts +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 创建一个空的 Entity 对象 +const entity = rootEntity.createChild(); +const displayComponent = entity.addComponent(GalaceanDisplayComponent); + +// 初始化时把当前 engine 中的相机传递过去 +displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); +// 加载 effects 的资源 +const composition = await displayComponent.loadScene('./xxx.json'); + +displayComponent.on('message', e => { + console.log(e.name); //设置多个交互元素需要根据 name 判断是否指定元素 + if (e.phrase === spec.MESSAGE_ITEM_PHRASE_BEGIN) { + // 元素创建 + } else if (e.phrase === spec.MESSAGE_ITEM_PHRASE_END) { + // 元素销毁 + } +}); + +displayComponent.interactive = true; +displayComponent.on('click', e => { + // 设置多个元素的点击交互需要根据 name 判断是否指定元素 + console.log('trigger click.') + console.log(e.name); +}); +``` + +和直接在 EffectsPlayer 中的使用类似,更多使用方法参考 Effects 的开发者文档: + +### Spine 插件 + +``` ts +// 引入 spine 插件 +// ES Module +import '@galacean/engine-effects/plugin-spine'; +// 非 ES Module +import '@galacean/engine-effects/dist/plugin-spine'; +``` + +## 注意事项 + +### 蒙版问题 + +默认背景颜色下,蒙版可能会和编辑器上不一致,如果想要和编辑器中效果一致的话,请调整背景颜色为黑色,代码如下: + +``` ts +// 设置背景颜色 +engine.sceneManager.activeScene.background.solidColor.set(0, 0, 0, 1); +``` + +## API 文档 + +``` bash +$ pnpm build:docs +// 生成的 api 目录 +``` + +## 开发 + +### 环境准备 + +- Node.js `>= 16.0.0` +- [Pnpm](https://pnpm.io/) `latest` + - 安装: + - `npm install -g pnpm` + - 升级: + - `pnpm install -g pnpm` + +### 本地开发 + +#### 开始开发 + +``` bash +# 1. 安装依赖(首次) +pnpm install +# 2. demo +pnpm dev +``` + +> 浏览器打开: + +### 低端设备测试 + +``` bash +# demo 的 legacy 版本 +pnpm preview +``` diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..422b194 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-conventional'] }; diff --git a/demo/html/compose.html b/demo/html/compose.html new file mode 100644 index 0000000..9e3aaac --- /dev/null +++ b/demo/html/compose.html @@ -0,0 +1,19 @@ + + + + + + 混合渲染测试 - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/dynamic-image.html b/demo/html/dynamic-image.html new file mode 100644 index 0000000..022be20 --- /dev/null +++ b/demo/html/dynamic-image.html @@ -0,0 +1,19 @@ + + + + + + 动态换图 - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/engine-config.html b/demo/html/engine-config.html new file mode 100644 index 0000000..77e47b7 --- /dev/null +++ b/demo/html/engine-config.html @@ -0,0 +1,20 @@ + + + + + + engine config - Galacean Effects Demo + + + +
保证 Effects 动画不会受引擎相关设置影响
+
+ + + diff --git a/demo/html/inspire/engine-effects.html b/demo/html/inspire/engine-effects.html new file mode 100644 index 0000000..c420e71 --- /dev/null +++ b/demo/html/inspire/engine-effects.html @@ -0,0 +1,17 @@ + + + + + + Engine Effects(use galacean camera) - 灵感对比测试 - Galacean Effects Demo + + + + +
+ + + diff --git a/demo/html/inspire/engine-use-effects-camera.html b/demo/html/inspire/engine-use-effects-camera.html new file mode 100644 index 0000000..4ae2713 --- /dev/null +++ b/demo/html/inspire/engine-use-effects-camera.html @@ -0,0 +1,17 @@ + + + + + + Engine Effects(use effects camera) - 灵感对比测试 - Galacean Effects Demo + + + + +
+ + + diff --git a/demo/html/inspire/index.html b/demo/html/inspire/index.html new file mode 100644 index 0000000..a9f0e2e --- /dev/null +++ b/demo/html/inspire/index.html @@ -0,0 +1,77 @@ + + + + + + 灵感对比测试 - Galacean Effects Demo + + + + + +
+
+
Pre Effects Player
+ +
+
+
Engine Effects(use effects camera)
+ +
+
+
Engine Effects(use galacean engine camera)
+ +
+ +
+
+
+
灵感
+
+ +
+
+
+
+ +
+
+ +
+
+ + + +
+
+ +
+
+
+
+

+

+
+
+
+ + + + diff --git a/demo/html/inspire/pre-effects-player.html b/demo/html/inspire/pre-effects-player.html new file mode 100644 index 0000000..3188b8a --- /dev/null +++ b/demo/html/inspire/pre-effects-player.html @@ -0,0 +1,18 @@ + + + + + + Pre Effects Player - 灵感对比测试 - Galacean Effects Demo + + + + +
+ + + + diff --git a/demo/html/interactive.html b/demo/html/interactive.html new file mode 100644 index 0000000..7a7c012 --- /dev/null +++ b/demo/html/interactive.html @@ -0,0 +1,19 @@ + + + + + + Interactive - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/large-scene.html b/demo/html/large-scene.html new file mode 100644 index 0000000..9ca4439 --- /dev/null +++ b/demo/html/large-scene.html @@ -0,0 +1,16 @@ + + + + + + 大场景测试 - Galacean Effects Demo + + + + + + + diff --git a/demo/html/memory.html b/demo/html/memory.html new file mode 100644 index 0000000..973aca4 --- /dev/null +++ b/demo/html/memory.html @@ -0,0 +1,20 @@ + + + + + + 内存泄漏测试 - Galacean Effects Demo + + + +
测试 Effects 动画是否存在内存泄漏情况
+
+ + + diff --git a/demo/html/multiple-components.html b/demo/html/multiple-components.html new file mode 100644 index 0000000..80dfa74 --- /dev/null +++ b/demo/html/multiple-components.html @@ -0,0 +1,19 @@ + + + + + + 多 DisplayComponent 的加载及播放 - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/multiple-compositions.html b/demo/html/multiple-compositions.html new file mode 100644 index 0000000..d5381fc --- /dev/null +++ b/demo/html/multiple-compositions.html @@ -0,0 +1,19 @@ + + + + + + 多合成加载及播放 - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/multiple-engine.html b/demo/html/multiple-engine.html new file mode 100644 index 0000000..564ae13 --- /dev/null +++ b/demo/html/multiple-engine.html @@ -0,0 +1,26 @@ + + + + + + 多 DisplayComponent 的加载及播放 - Galacean Effects Demo + + + +
+ + +
+ + + diff --git a/demo/html/single.html b/demo/html/single.html new file mode 100644 index 0000000..45f8057 --- /dev/null +++ b/demo/html/single.html @@ -0,0 +1,19 @@ + + + + + + single - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/spine.html b/demo/html/spine.html new file mode 100644 index 0000000..d78ddb1 --- /dev/null +++ b/demo/html/spine.html @@ -0,0 +1,19 @@ + + + + + + Spine - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/text.html b/demo/html/text.html new file mode 100644 index 0000000..d398014 --- /dev/null +++ b/demo/html/text.html @@ -0,0 +1,19 @@ + + + + + + 文字 - Galacean Effects Demo + + + +
+ + + diff --git a/demo/html/use-effects-camera.html b/demo/html/use-effects-camera.html new file mode 100644 index 0000000..9c767aa --- /dev/null +++ b/demo/html/use-effects-camera.html @@ -0,0 +1,19 @@ + + + + + + Use Effects Camera - Galacean Effects Demo + + + +
+ + + diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..d69168d --- /dev/null +++ b/demo/index.html @@ -0,0 +1,37 @@ + + + + +Galacean Effects Demo + + + + + + + + diff --git a/demo/src/assets/inspire-list.ts b/demo/src/assets/inspire-list.ts new file mode 100644 index 0000000..173f421 --- /dev/null +++ b/demo/src/assets/inspire-list.ts @@ -0,0 +1,554 @@ +export default { + wufu2022: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*dnU-SprU5pAAAAAAAAAAAAAADlB4AQ', + name: '2022-集五福氛围', + pass: true, + }, + spring: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*oF1NRJG7GU4AAAAAAAAAAAAADlB4AQ', + name: '春促-主页互动', + pass: true, + }, + butterfly: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*uU2JRIjcLIcAAAAAAAAAAAAADlB4AQ', + name: '塔奇-蝴蝶飞入', + pass: true, + }, + turnplate: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*2rNdR76aFvMAAAAAAAAAAAAADlB4AQ', + name: '抽奖转盘', + pass: true, + }, + // 氛围 + ribbons: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/MNJVBYCSYDWN/1425978492-8d707.json', + name: '彩带下落', + pass: true, + }, + rotate: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/AEFTPXNTAVWO/-79861579-61067.json', + name: '旋转出场', + pass: true, + }, + fallout: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FSYBVXNUVVCV/1680771373-b31b5.json', + name: '辐射粒子', + pass: true, + }, + peach: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RXJVVGVKNJAW/-1815889205-12b86.json', + name: '落花', + pass: true, + }, + star: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RYYAXEAYMIYJ/1314733612-96c0b.json', + name: '流星', + pass: true, + }, + firework2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/DHVCWTJROYJX/536570326-9ed46.json', + name: '双层烟花', + pass: true, + }, + gather: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/QXQUJWNNTDFC/596510881-676d1.json', + name: '光线汇聚', + pass: true, + }, + heart: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/CVVEESIKVATT/199364128-b865e.json', + name: '爱心', + pass: true, + }, + applause: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/TAJIINQOUUKP/-799304223-0ee5d.json', + name: '欢呼', + pass: true, + }, + dreamStar: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/WSWUFGSCPBIQ/-1336712667-9b73e.json', + name: '梦幻星星', + pass: true, + }, + firework3: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*1Az5TrNodIcAAAAAAAAAAAAADlB4AQ', + name: '福满全球烟花', + pass: true, + }, + fire: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/WKIPVUDMSRQV/-520032969-680df.json', + name: '火花', + pass: true, + }, + engeryin: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/CICESMUPIGDA/-934216499-86249.json', + name: '能量汇聚', + pass: true, + }, + engeryout: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/NRTLXMLLHGHJ/-1897932390-84bd1.json', + name: '能量爆炸', + pass: true, + }, + bubble: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/LJIHMEMCJJJC/162217830-338a3.json', + name: '泡泡', + pass: true, + }, + starLight: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/PFCIWGNGTRCW/-901387597-eb15c.json', + name: '流星', + pass: true, + }, + ball: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/NKICJVAEIWDU/-1916559527-63956.json', + name: '能量球', + pass: true, + }, + shakeTT: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FSSXOWDKYEHW/-601276311-59d90.json', + name: '淘特摇一摇', + pass: true, + }, + firework1212: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/QGCXRYCJNXAJ/-618372317-88f17.json', + name: '氛围烟花', + pass: true, + }, + fireworkny: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/SDNRPIJFENBK/-1998534768-39820.json', + name: '新春烟花', + pass: true, + }, + rain: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ABVJKUVBOUHG/114561646-e3e3a.json', + name: '下雨', + pass: true, + }, + egg8t1: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/PQNBQHVEBMQN/-669939334-9fa84.json', + name: '年兽大爆炸——8个彩蛋t1', + pass: true, + }, + egg8t2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FBCJKAAJQJIR/-926322664-a7f0a.json', + name: '年兽大爆炸——8个彩蛋t2', + pass: true, + }, + goldheart: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FAJMDFAXTVDA/-1781794368-96309.json', + name: '金色爱心', + pass: true, + }, + superfirework: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RDVUQUFRBHAH/1662842524-1b11d.json', + name: '超级烟花', + pass: true, + }, + banger1: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ODFCRQAYSTSI/46739595-61d76.json', + name: '年兽炸弹——一级鞭炮', + pass: true, + }, + banger2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FPWGAKNANGWI/47663116-1f2ae.json', + name: '年兽炸弹——二级鞭炮', + pass: true, + }, + banger3: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*1rVkRq_G4SkAAAAAAAAAAAAADlB4AQ', + name: '年兽炸弹——三级鞭炮', + pass: true, + }, + banger4: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*ANjGTJ1pr1wAAAAAAAAAAAAADlB4AQ', + name: '年兽炸弹——四级鞭炮', + pass: true, + }, + banger5: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*jQK1TqKCOrEAAAAAAAAAAAAADlB4AQ', + name: '年兽炸弹——五级鞭炮', + pass: true, + }, + boom1: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/VYTUOBBLQTQV/-1156279393-d2798.json', + name: '年兽炸弹——爆竹爆炸level1', + pass: true, + }, + boom2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/CERGSVICOVOS/-1155355872-80adb.json', + name: '年兽炸弹——爆竹爆炸level2', + pass: true, + }, + boom3: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/LBGBIMBQOABC/-1154432351-de5ec.json', + name: '年兽炸弹——爆竹爆炸level3', + pass: true, + }, + boom4: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/YARUMPIWACMN/-1153508830-f1e30.json', + name: '年兽炸弹——爆竹爆炸level4', + pass: true, + }, + boom5: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ALQOVCPFDMRW/-1152585309-66e3e.json', + name: '年兽炸弹——爆竹爆炸level5', + pass: true, + }, + teacher: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/AMCIGUREGVIN/47663116-cbe63.json', + name: '教师节', + pass: true, + }, + combine: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ILDKKFUFMVJA/1705406034-80896.json', + name: '跨年烟花——烟花组合', + pass: true, + }, + city: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/HRMQQUJTBAVY/-1481002344-3d427.json', + name: '跨年烟花——城市背景', + pass: true, + }, + yellow4: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/OXHAIUJACCID/-887962239-f315c.json', + name: '跨年烟花——黄4', + pass: true, + }, + orange: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/EDTPYJOOGNML/-1090908152-baec0.json', + name: '跨年烟花——橙', + pass: true, + }, + dream: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/UVJAJPDEFJAY/-617826901-dc284.json', + name: '跨年烟花——梦', + pass: true, + }, + orange2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FBNFUWSACRAY/496136531-ca927.json', + name: '跨年烟花—橙烟花2', + pass: true, + }, + tigerHead: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ODJHRLCSFQUF/1912262535-47e13.json', + name: '跨年烟花——虎头', + pass: true, + }, + whiteBlue2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/NBKFNEIAXUIG/-510674142-4ff0d.json', + name: '跨年烟花——白蓝2', + pass: true, + }, + yellow1: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/PLGJTAQNBEIO/-890732802-8d4c4.json', + name: '跨年烟花——黄1', + pass: true, + }, + // 弹窗 + applaud: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*js8iRbOiExAAAAAAAAAAAAAADlB4AQ', + name: '双十一弹窗', + pass: true, + }, + WuFu1: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*7vwwSbbDZfwAAAAAAAAAAAAADlB4AQ', + name: '五福弹窗', + pass: true, + }, + lighting: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/WEPWUNCGNVQI/-1695824449-958ba.json', + name: '闪光弹窗', + pass: true, + }, + countdown: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/YDITHDADWXXM/1601633123-e644d.json', + name: '七夕倒计时', + pass: true, + }, + combineCard: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/BRNUKQWSAIKG/136315478-98a3d.json', + name: '合成卡', + pass: true, + }, + multiPeople: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ETELKDEUCNBC/2073953335-fd050.json', + name: '多人红包', + pass: true, + }, + invest: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/PBVALWIQDUTE/-1454659523-382de.json', + name: '投资大咖', + pass: true, + }, + circle: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/NPLUVQLEKBCM/-1111980630-65fbf.json', + name: '圆形弹窗', + pass: true, + }, + window520: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/BQTEQTNCXEEO/1270328461-009fc.json', + name: '520弹窗', + pass: true, + }, + gameResult: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/JRDNOYBAJKBV/-671130785-4f00d.json', + name: '游戏结果', + pass: true, + }, + giftOpen: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*of92S7KNX4MAAAAAAAAAAAAADlB4AQ', + name: '开启礼盒', + pass: true, + }, + redpackRain: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/WGJWMPCTFYQT/-1604277761-f5fde.json', + name: '红包雨', + pass: true, + }, + redpackCombine: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/JTAVTVCYTJXY/-969476604-6dda2.json', + name: '红包融合', + pass: true, + }, + redpackClick: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*ni_VQpmJjNoAAAAAAAAAAAAADlB4AQ', + name: '红包雨——点击爆炸效果', + pass: true, + }, + + // 组合 + mask: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/HCQBCOWGHRQC/273965510-c5c29.json', + name: '蒙板', + pass: true, + }, + lottery: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*53pIRLuAOpwAAAAAAAAAAAAADlB4AQ', + name: '抽奖机', + pass: true, + }, + calendar: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*2nQIRJBcB7MAAAAAAAAAAAAADlB4AQ', + name: '帧动画', + pass: true, + }, + strongLight: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/SNIHEROYDLUU/684550896-dec89.json', + name: '强光', + pass: true, + }, + fan: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/UTUGVAUGWSJM/-1083803027-79544.json', + name: '清凉节', + pass: true, + }, + transition: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/WKGETVNPUSBS/-1278184165-7c3ba.json', + name: '发光过渡', + pass: true, + }, + letter: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/DQARMNHMUWGE/1259164160-8203e.json', + name: '开信封', + pass: true, + }, + letter2: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/IMWVMTEUGHGJ/1259164160-42ace.json', + name: '开信封2', + pass: true, + }, + reward: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/ERDUDLGWUKSS/1690095753-96f6c.json', + name: '获奖banner', + pass: true, + }, + upgrade: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*C1Q9S63cSq0AAAAAAAAAAAAADlB4AQ', + name: '福袋升级', + pass: true, + }, + spray1212: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/LPBCDARDRDDW/-1920604196-bc899.json', + name: '1212喷射', + pass: true, + }, + + trafficLight: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/EUNLFQUDKOXM/996889786-e56a2.json', + name: '支付宝2021——红绿灯', + pass: true, + }, + chicken: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/QWCKPTQMCGWG/-1658455025-93111.json', + name: '支付宝2021——小鸡动画', + pass: true, + }, + opening: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/AUEEDPBSBGLP/-505765340-6d3e4.json', + name: '支付宝2021——开场', + pass: true, + }, + running: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/AIPUQVVFLCPA/1548889573-0d943.json', + name: '支付宝2021——跑步', + pass: true, + }, + payment: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/DVHWTIBIRXHY/-788542078-c8fed.json', + name: '支付宝2021——缴费', + pass: true, + }, + autumn: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*cyyfTavfBscAAAAAAAAAAAAADlB4AQ', + name: '天猫中秋大街', + pass: true, + }, + camera: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RNXFNXQAAYSS/-2013243009-ffc7b.json', + name: '镜头动画', + pass: true, + }, + jump: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RCKVUTNWVGUV/-256451064-4757b.json', + name: '跳棋', + pass: true, + }, + forward: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/AEWWEXCODEAX/1652119839-8c239.json', + name: '招财车——点击前动态', + pass: true, + }, + backward: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FMAWDCBIVLJS/2119821889-1fb2a.json', + name: '招财车——点击后车走', + pass: true, + }, + earth: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*UsUiSL2_gUEAAAAAAAAAAAAADlB4AQ', + name: '地下蹦迪——地球上头', + pass: true, + }, + man: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*tck3TKQFucwAAAAAAAAAAAAADlB4AQ', + name: '地下蹦迪——男人迪厅', + pass: true, + }, + woman: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/FMFLEVNSJFJV/673458012-fcec3.json', + name: '地下蹦迪——女人迪厅', + pass: true, + }, + breath: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/OGJPDUCKJHJA/1567377722-6338b.json', + name: '小答案——魔法书呼吸', + pass: true, + }, + bookopen: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/YSTWOGVRJBUX/1199039501-ac91b.json', + name: '小答案——魔法书打开', + pass: true, + }, + book: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/DFFREDHDSYUC/-1491268648-988dc.json', + name: '小答案——开屏', + pass: true, + }, + + superaward: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/MNEWNYFQHECL/-1474199652-725db.json', + name: '超级开大奖', + pass: true, + }, + redRotate: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/DGSXEBEVHHKL/1081587947-5bdd0.json', + name: '超红转转转', + pass: true, + }, + superPack: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/YXBYHDNORIHN/-969476604-bdf38.json', + name: '超级红包', + pass: true, + }, + packRain: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/TEOHTIPEBNDV/-741068679-7c18c.json', + name: '红包雨——可点击', + pass: true, + }, + glory: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/XULQGUYFDLLN/872016110-b6202.json', + name: '王者争霸', + pass: true, + }, + hot: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/HYHBXHFLAVPK/1097553575-e222c.json', + name: '热卖榜单', + pass: true, + }, + fireworkmama: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/CROUPDBJJTAJ/1816913825-29de9.json', + name: '阿里妈妈——烟花', + pass: true, + }, + screenLeft: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/RVVTUBIYHYKX/1717302625-bcbd2.json', + name: '数据大屏——左侧女孩', + pass: true, + }, + screenRight: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/VKYICIAHDXQJ/-1570241290-2edef.json', + name: '数据大屏——右侧男孩', + pass: true, + }, + camera2: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*GSvyQJNgG08AAAAAAAAAAAAADlB4AQ', + name: '交互元素测试', + pass: true, + }, + startPop: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*7-3QS6D7TroAAAAAAAAAAAAADlB4AQ', + name: '星光弹窗', + pass: true, + }, + blackCard: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*Uw1PTbYunfkAAAAAAAAAAAAADlB4AQ', + name: '618黑卡', + pass: true, + }, + advance: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*MVjVR79EnZgAAAAAAAAAAAAADlB4AQ', + name: '场景推进', + pass: true, + }, + suprise: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*J69-TpS3MjoAAAAAAAAAAAAADlB4AQ', + name: '拼手气开奖', + pass: true, + }, + compressed: { + url: 'https://gw.alipayobjects.com/os/public-service/owl/compressed-texture.json', + name: '压缩纹理', + pass: true, + }, + particleFollow: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*gU3-RKGZABcAAAAAAAAAAAAADlB4AQ', + name: '粒子跟随', + pass: true, + }, + parentSprite: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/92179123544955/sprite.json', + name: '直接认父——图层', + pass: true, + }, + parentParticle: { + url: 'https://gw.alipayobjects.com/os/gltf-asset/92178974741421/particle.json', + name: '直接认父——粒子', + pass: true, + }, + multiParent: { + url: 'https://mdn.alipayobjects.com/mars/afts/file/A*XOjkRofsX2QAAAAAAAAAAAAADlB4AQ', + name: '多级父节点', + pass: true, + }, +}; + diff --git a/demo/src/common/galacean-display-component.ts b/demo/src/common/galacean-display-component.ts new file mode 100644 index 0000000..52cb1a8 --- /dev/null +++ b/demo/src/common/galacean-display-component.ts @@ -0,0 +1,113 @@ +import type { TouchEventType } from '@galacean/engine-effects'; +import { GalaceanDisplayComponent, EventSystem, EVENT_TYPE_CLICK, spec } from '@galacean/engine-effects'; +import type { Entity } from '@galacean/engine'; +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; + +export async function createGalaceanPlayer (options: any) { + const { container, renderFramework = 'webgl2', interactive } = options; + const canvas = document.createElement('canvas'); + + canvas.className = container.className; + container.appendChild(canvas); + + const engine = await WebGLEngine.create({ + canvas, + graphicDeviceOptions: { + webGLMode: renderFramework === 'webgl' ? WebGLMode.WebGL1 : WebGLMode.WebGL2, + }, + }); + + engine.canvas.resizeByClientSize(); + + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + const camera = cameraEntity.addComponent(Camera); + + camera.fieldOfView = 60; + camera.nearClipPlane = 0.1; + camera.farClipPlane = 1000; + camera.enableFrustumCulling = false; + cameraEntity.transform.setPosition(0, 0, 8); + engine.sceneManager.activeScene.background.solidColor.set(0, 0, 0, 1); + + return { + engine, + rootEntity, + camera: !options.useEffectsCamera ? camera : undefined, + hasPlayable: false, + interactive, + pause: () => { }, + resume: () => { }, + onItemClicked: (e: any) => { + console.debug(`item ${e.name} has been clicked`); + }, + }; +} + +let sceneName = ''; +let displayComponent: GalaceanDisplayComponent; +let entity: Entity; + +export async function renderByGalaceanDisplayComponent (player: any, json: string) { + const { rootEntity, engine, camera, interactive = false } = player; + + engine.pause(); + + if (entity) { + entity.destroy(); + } + let event; + + entity = (rootEntity as Entity).createChild(); + + displayComponent = entity.addComponent(GalaceanDisplayComponent); + displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); + displayComponent.interactive = interactive; + const scene = await displayComponent.loadScene(json); + + scene.on('end', ({ composition }) => { + console.info(`${composition.name} end.`); + }); + + const currentComposition = displayComponent.compositions[0]; + + // 防止 event 重复创建 + if (currentComposition.name !== sceneName) { + // 注册事件系统 不需要响应点击时可以不进行注册 + event = new EventSystem(engine._hardwareRenderer._webCanvas); + + event.bindListeners(); + event.addEventListener(EVENT_TYPE_CLICK, handleClick); + // @ts-expect-error + currentComposition.event = event; + } + sceneName = currentComposition.name; + + function handleClick (e: TouchEventType) { + const { x, y } = e; + const regions = currentComposition.hitTest(x, y); + + if (regions.length) { + for (let i = 0; i < regions.length; i++) { + const { name, behavior = spec.InteractBehavior.NOTIFY } = regions[i]; + + if (behavior === spec.InteractBehavior.NOTIFY) { + // 或者自定义notify的回调参数 + console.info(`item ${name} has been clicked`); + } else if (behavior === spec.InteractBehavior.RESUME_PLAYER) { + player.resume(); + } + } + } + } + + player.hasPlayable = true; + player.pause = () => { + displayComponent.pause(); + }; + player.resume = () => { + void displayComponent.resume(); + }; + + engine.run(); +} diff --git a/demo/src/compose.ts b/demo/src/compose.ts new file mode 100644 index 0000000..83bc65f --- /dev/null +++ b/demo/src/compose.ts @@ -0,0 +1,64 @@ +import type { GLTFResource } from '@galacean/engine'; +import { Camera, Layer, Logger, WebGLEngine, WebGLMode } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import { OrbitControl } from '@galacean/engine-toolkit-controls'; +import '@galacean/engine-effects/plugin-spine'; + +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*1FxpRKUFeMkAAAAAAAAAAAAADlB4AQ'; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +Logger.enable(); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL2 } }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + const camera = cameraEntity.addComponent(Camera); + + // 设置背景颜色 + engine.sceneManager.activeScene.background.solidColor.set(0, 0, 0, 1); + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + camera.fieldOfView = 60; + camera.nearClipPlane = 0.1; + camera.farClipPlane = 1000; + camera.enableFrustumCulling = false; + cameraEntity.transform.setPosition(0, 0, 18); + cameraEntity.addComponent(OrbitControl); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const gltf = await engine.resourceManager.load('https://mdn.alipayobjects.com/huamei_s9rwo4/afts/file/A*yM8OS7JZq_EAAAAAAAAAAAAADiqKAQ/AlphaBlendModeTest.glb'); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + entity.layer = Layer.Nothing; + rootEntity.addChild(gltf.defaultSceneRoot); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + + // 红包 + const composition1 = await displayComponent.loadScene(json, { billboard: true, autoplay: false }); + // 爱心 + const composition2 = await displayComponent.loadScene('https://mdn.alipayobjects.com/mars/afts/file/A*02UWQ6BvLuAAAAAAAAAAAAAADlB4AQ', { billboard: true }); + // 蝴蝶 + const composition3 = await displayComponent.loadScene('https://mdn.alipayobjects.com/mars/afts/file/A*wvHEQ7NCai8AAAAAAAAAAAAADlB4AQ', { billboard: true }); + + composition1.setPosition(5, 0, -10); + composition2.setPosition(-2, 0, -2); + composition3.setPosition(0, -3, -5); + + setTimeout(() => { + composition1.play(); + }, 1500); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/dynamic-image.ts b/demo/src/dynamic-image.ts new file mode 100644 index 0000000..d1c2d86 --- /dev/null +++ b/demo/src/dynamic-image.ts @@ -0,0 +1,40 @@ +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +// 教师节贺卡 +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*4AcqRZkGmz8AAAAAAAAAAAAADlB4AQ'; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 } }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 8); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + await displayComponent.loadScene(json, { + variables: { + // 动态图片,支持传入图片地址或地址数组 + background: 'https://mdn.alipayobjects.com/huamei_klifp9/afts/img/A*ySrfRJvfvfQAAAAAAAAAAAAADvV6AQ/original', + }, + }); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/engine-config.ts b/demo/src/engine-config.ts new file mode 100644 index 0000000..7988ac6 --- /dev/null +++ b/demo/src/engine-config.ts @@ -0,0 +1,41 @@ +import { Camera, WebGLEngine } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import inspireList from './assets/inspire-list'; + +const json = inspireList.butterfly.url; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + const camera = cameraEntity.addComponent(Camera); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + camera.fieldOfView = 60; + camera.nearClipPlane = 0.1; + camera.farClipPlane = 1000; + camera.enableFrustumCulling = false; + cameraEntity.transform.setPosition(0, 0, 10); + // 引擎垂直同步设置 + engine.vSyncCount = 2; + engine.settings.colorSpace = 1; + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + await displayComponent.loadScene(json); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/inspire/engine-effects.ts b/demo/src/inspire/engine-effects.ts new file mode 100644 index 0000000..cd27e9c --- /dev/null +++ b/demo/src/inspire/engine-effects.ts @@ -0,0 +1,43 @@ +import { registerPlugin, AbstractPlugin, VFXItem, isWebGL2 } from '@galacean/effects-core'; +import { createGalaceanPlayer, renderByGalaceanDisplayComponent } from '../common/galacean-display-component'; + +// 假装注册陀螺仪插件,兼容有陀螺仪的合成报错 +// @ts-expect-error +registerPlugin('orientation-transformer', AbstractPlugin, VFXItem); + +const container = document.getElementById('J-container'); +let player: any; + +window.addEventListener('message', async event => { + const { type, json, playerOptions } = event.data; + + switch (type) { + case 'init': { + player = await createGalaceanPlayer({ + container, + ...playerOptions, + onItemClicked: (item: any) => console.info(`item ${item.name} has been clicked`, item), + }); + + break; + } + case 'play': { + console.debug(`engine-effects 渲染模式:${isWebGL2(player.engine._hardwareRenderer.gl) ? 'webgl2' : 'webgl'}`); + void renderByGalaceanDisplayComponent(player, json); + + break; + } + case 'pause': { + if (player.hasPlayable) { + player.pause(); + } + + break; + } + case 'resume': { + player.resume(); + + break; + } + } +}); diff --git a/demo/src/inspire/engine-use-effects-camera.ts b/demo/src/inspire/engine-use-effects-camera.ts new file mode 100644 index 0000000..cd35e99 --- /dev/null +++ b/demo/src/inspire/engine-use-effects-camera.ts @@ -0,0 +1,44 @@ +import { registerPlugin, AbstractPlugin, VFXItem, isWebGL2 } from '@galacean/effects-core'; +import { createGalaceanPlayer, renderByGalaceanDisplayComponent } from '../common/galacean-display-component'; + +// 假装注册陀螺仪插件,兼容有陀螺仪的合成报错 +// @ts-expect-error +registerPlugin('orientation-transformer', AbstractPlugin, VFXItem); + +const container = document.getElementById('J-container'); +let player: any; + +window.addEventListener('message', async event => { + const { type, json, playerOptions } = event.data; + + switch (type) { + case 'init': { + player = await createGalaceanPlayer({ + container, + ...playerOptions, + onItemClicked: (item: any) => console.info(`item ${item.name} has been clicked`, item), + useEffectsCamera: true, + }); + + break; + } + case 'play': { + console.debug(`engine-effects 渲染模式:${isWebGL2(player.engine._hardwareRenderer.gl) ? 'webgl2' : 'webgl'}`); + void renderByGalaceanDisplayComponent(player, json); + + break; + } + case 'pause': { + if (player.hasPlayable) { + player.pause(); + } + + break; + } + case 'resume': { + player.resume(); + + break; + } + } +}); diff --git a/demo/src/inspire/index.ts b/demo/src/inspire/index.ts new file mode 100644 index 0000000..1e7509e --- /dev/null +++ b/demo/src/inspire/index.ts @@ -0,0 +1,98 @@ +import inspireList from '../assets/inspire-list'; + +const preEffectsPlayerIframe = document.getElementById('J-preEffectsPlayerIframe') as HTMLIFrameElement; +const engineEffectsIframe = document.getElementById('J-engineEffectsIframe') as HTMLIFrameElement; +const engineUseEffectsCameraIframe = document.getElementById('J-engineUseEffectsCameraIframe') as HTMLIFrameElement; +const frameworkEle = document.getElementById('J-framework') as HTMLSelectElement; +const iframeList = [preEffectsPlayerIframe, engineEffectsIframe, engineUseEffectsCameraIframe]; +const renderFramework = frameworkEle.value; +const currentTime = 0; +const speed = 1; +const playerOptions = { + willCaptureImage: true, + pixelRatio: 2, + env: 'editor', + interactive: true, + renderFramework, +}; +let currentInspire = inspireList['ribbons'].url; + +initialSelectList(); +bindEventListeners(); +handleInit(); + +function bindEventListeners () { + document.getElementById('J-start')!.onclick = () => { + handlePause(); + void handlePlay(currentInspire); + }; + document.getElementById('J-pause')!.onclick = handlePause; + // 切换 WebGL/WebGL2 + frameworkEle.onchange = () => { + playerOptions.renderFramework = frameworkEle.value; + iframeList.forEach(iframe => { + iframe.contentWindow?.location.reload(); + }); + handleInit(); + }; +} + +function handleInit () { + iframeList.forEach(iframe => { + iframe.onload = () => { + iframe.contentWindow?.postMessage({ + type: 'init', + playerOptions, + }); + }; + }); +} + +async function handlePlay (animation: string) { + const json = await (await fetch(animation)).json(); + + iframeList.forEach(iframe => { + iframe.contentWindow?.postMessage({ + type: 'play', + json, + currentTime, + speed, + }); + }); +} + +function handleResume () { + iframeList.forEach(iframe => { + iframe.contentWindow?.postMessage({ + type: 'resume', + }); + }); +} + +function handlePause () { + iframeList.forEach(iframe => { + iframe.contentWindow?.postMessage({ + type: 'pause', + }); + }); +} + +function initialSelectList () { + const selectEle = document.getElementById('J-select') as HTMLSelectElement; + const options: string[] = []; + + Object.entries(inspireList).map(([key, object]) => { + options.push( + `` + ); + }); + selectEle.innerHTML = options.join(''); + selectEle.onchange = () => { + const selected = selectEle.value; + + currentInspire = (inspireList as Record)[selected].url; + }; +} + diff --git a/demo/src/inspire/pre-effects-player.ts b/demo/src/inspire/pre-effects-player.ts new file mode 100644 index 0000000..b68058f --- /dev/null +++ b/demo/src/inspire/pre-effects-player.ts @@ -0,0 +1,39 @@ +//@ts-nocheck +const container = document.getElementById('J-container'); +let player; + +window.addEventListener('message', async event => { + const { type, json, playerOptions } = event.data; + + switch (type) { + case 'init': { + player = new window.ge.Player({ + container, + ...playerOptions, + onItemClicked: item => console.info(`item ${item.name} has been clicked`, item), + }); + + break; + } + case 'play': { + player.destroyCurrentCompositions(); + await player.loadScene(json); + + console.debug(`pre-effects-player 渲染模式:${player.renderer.engine.gpuCapability.type}`); + + break; + } + case 'pause': { + if (player.hasPlayable) { + player.pause(); + } + + break; + } + case 'resume': { + player.resume(); + + break; + } + } +}); diff --git a/demo/src/interactive.ts b/demo/src/interactive.ts new file mode 100644 index 0000000..91b9787 --- /dev/null +++ b/demo/src/interactive.ts @@ -0,0 +1,57 @@ +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import { Camera, Logger, WebGLEngine, WebGLMode } from '@galacean/engine'; + +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); +// const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*OEyVTIysJHMAAAAAAAAAAAAADlB4AQ'; +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*2rNdR76aFvMAAAAAAAAAAAAADlB4AQ'; + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 } }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 15); + + Logger.isEnabled = true; + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + + const composition = await displayComponent.loadScene(json); + const item = composition.getItemByName('lotteryBtn'); + + displayComponent.interactive = true; + + displayComponent.on('click', e => { + console.info(`[DisplayComponent click] - item [${e.name}] clicked.`); + }); + + displayComponent.on('message', e => { + console.info(`[DisplayComponent message] - item [${e.name}] trigger message, type [${e.phrase}].`); + }); + + composition.on('end', ({ composition }) => { + console.info(`[Composition end] - [${composition.name}] end.`); + }); + + item?.on('click', e => { + console.info(`[item click] - item [${e.name}] clicked.`); + }); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/large-scene.ts b/demo/src/large-scene.ts new file mode 100644 index 0000000..f054305 --- /dev/null +++ b/demo/src/large-scene.ts @@ -0,0 +1,85 @@ +import { OrbitControl } from '@galacean/engine-toolkit-controls'; +import type { AmbientLight, GLTFResource } from '@galacean/engine'; +import { Animator, AssetType, BackgroundMode, Camera, PrimitiveMesh, SkyBoxMaterial, WebGLEngine, WebGLMode } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import '@galacean/engine-effects/plugin-spine'; + +import inspireList from './assets/inspire-list'; + +const jsons: [url: string, pos: number[], scale?: number, billboard?: boolean][] = [ + [inspireList.multiPeople.url, [0, 5, -7]], + [inspireList.heart.url, [-6, 4, -2]], + [inspireList.redpackRain.url, [0, 5, -10]], + [inspireList.book.url, [0, 75, 0], 10, true], + [inspireList.WuFu1.url, [-15, 5, -2], 1, true], + [inspireList.applaud.url, [0, 6, 3]], + [inspireList.whiteBlue2.url, [3, 0, -2]], + ['https://mdn.alipayobjects.com/mars/afts/file/A*e2PBQa_gAwcAAAAAAAAAAAAADlB4AQ', [0, 3, -2], 1, true], + ['https://mdn.alipayobjects.com/mars/afts/file/A*wvHEQ7NCai8AAAAAAAAAAAAADlB4AQ', [0, 3, 0], 1], + ['https://mdn.alipayobjects.com/mars/afts/file/A*ger1RL7iTAoAAAAAAAAAAAAADlB4AQ', [6, 4, 3], 0.3], +]; + +void WebGLEngine + .create({ canvas: 'J-canvas', graphicDeviceOptions: { webGLMode: WebGLMode.WebGL2 } }) + .then(async engine => { + engine.canvas.resizeByClientSize(); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + const camera = cameraEntity.addComponent(Camera); + + camera.fieldOfView = 60; + camera.nearClipPlane = 0.1; + camera.farClipPlane = 1000; + + camera.enableFrustumCulling = false; + cameraEntity.transform.setPosition(5, 5, 10); + cameraEntity.addComponent(OrbitControl); + + // 1. 加载场景 + const gltf = await engine.resourceManager.load('https://mdn.alipayobjects.com/huamei_s9rwo4/afts/file/A*YgNkS4JVkboAAAAAAAAAAAAADiqKAQ/spacestation_scene_ld.glb'); + // 1.1 获取动画组件 + const { defaultSceneRoot } = gltf; + const animator = defaultSceneRoot.getComponent(Animator); + + rootEntity.addChild(defaultSceneRoot); + // 1.2 播放动画 + animator?.play('Take 01'); + + // 2. Create sky + await createSkyBox(engine); + + // 3. 实例化 DisplayComponent,并添加到主场景中 + await Promise.all(jsons.map(async ([url, pos, scale = 1, billboard = false]) => { + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl, { camera }); + await displayComponent.loadScene(url, { billboard }); + + // 修改 Effects 位置 + displayComponent.entity.transform.setPosition(pos[0], pos[1], pos[2]); + displayComponent.entity.transform.setScale(scale, scale, scale); + })); + + // 4. 运行 + engine.run(); + }); + +async function createSkyBox (engine: WebGLEngine) { + const ambientLight = await engine.resourceManager.load({ + type: AssetType.Env, + url: 'https://gw.alipayobjects.com/os/bmw-prod/89c54544-1184-45a1-b0f5-c0b17e5c3e68.bin', + }); + const scene = engine.sceneManager.activeScene; + const sky = scene.background.sky; + const skyMaterial = new SkyBoxMaterial(engine); + + scene.background.mode = BackgroundMode.Sky; + sky.material = skyMaterial; + sky.mesh = PrimitiveMesh.createCuboid(engine, 1, 1, 1); + scene.ambientLight = ambientLight; + skyMaterial.texture = ambientLight.specularTexture; + skyMaterial.textureDecodeRGBM = true; +} + diff --git a/demo/src/memory.ts b/demo/src/memory.ts new file mode 100644 index 0000000..5e05d43 --- /dev/null +++ b/demo/src/memory.ts @@ -0,0 +1,49 @@ +import { Camera, WebGLEngine } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import '@galacean/engine-effects/plugin-spine'; + +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*5YkqQr81SFYAAAAAAAAAAAAADlB4AQ'; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 10); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + await displayComponent.loadScene(json); + + let t: number; + + setTimeout(async () => { + t = setInterval(async () => { + displayComponent.dispose(); + await displayComponent.loadScene(json); + }, 3000); + }, 10000); + + setTimeout(() => { + displayComponent.destroy(); + window.clearInterval(t); + }, 40000); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/multiple-components.ts b/demo/src/multiple-components.ts new file mode 100644 index 0000000..5eb5192 --- /dev/null +++ b/demo/src/multiple-components.ts @@ -0,0 +1,45 @@ +import { Camera, WebGLEngine } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import inspireList from './assets/inspire-list'; + +const json1 = 'https://mdn.alipayobjects.com/mars/afts/file/A*OEyVTIysJHMAAAAAAAAAAAAADlB4AQ'; +const json2 = inspireList.autumn.url; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 8); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent1 = entity.addComponent(GalaceanDisplayComponent); + const displayComponent2 = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent1.initialize(engine._hardwareRenderer.gl); + await displayComponent1.loadScene(json1); + // @ts-expect-error + displayComponent2.initialize(engine._hardwareRenderer.gl); + await displayComponent2.loadScene(json2); + + displayComponent1.interactive = true; + displayComponent1.on('click', e => { + console.info(`${e.name} clicked.`); + }); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/multiple-compositions.ts b/demo/src/multiple-compositions.ts new file mode 100644 index 0000000..7100f37 --- /dev/null +++ b/demo/src/multiple-compositions.ts @@ -0,0 +1,47 @@ +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import { Camera, WebGLEngine } from '@galacean/engine'; + +const jsons = [ + 'https://mdn.alipayobjects.com/mars/afts/file/A*Xs_jSZVF0uQAAAAAAAAAAAAADlB4AQ', // ship + 'https://mdn.alipayobjects.com/mars/afts/file/A*qW9XQrKm4RAAAAAAAAAAAAAADlB4AQ', + 'https://mdn.alipayobjects.com/mars/afts/file/A*HPKjQJ2RAfAAAAAAAAAAAAAADlB4AQ', + 'https://mdn.alipayobjects.com/mars/afts/file/A*1LmgTaVdB38AAAAAAAAAAAAADlB4AQ', // star start + 'https://mdn.alipayobjects.com/mars/afts/file/A*HpGeQapHLn0AAAAAAAAAAAAADlB4AQ', + 'https://mdn.alipayobjects.com/mars/afts/file/A*wMDtT4lz5cUAAAAAAAAAAAAADlB4AQ', // star end +]; +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 8); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + // 加载 compositions + const compositions = await Promise.all(jsons.map(json => displayComponent.loadScene(json))); + + compositions.forEach(composition => { + composition.on('end', e => { + console.info(`composition ${e.composition.name} end.`); + }); + }); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/multiple-engine.ts b/demo/src/multiple-engine.ts new file mode 100644 index 0000000..829b812 --- /dev/null +++ b/demo/src/multiple-engine.ts @@ -0,0 +1,48 @@ +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; +import type { Composition } from '@galacean/engine-effects'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +const json1 = 'https://mdn.alipayobjects.com/mars/afts/file/A*1FxpRKUFeMkAAAAAAAAAAAAADlB4AQ'; +const json2 = 'https://mdn.alipayobjects.com/mars/afts/file/A*02UWQ6BvLuAAAAAAAAAAAAAADlB4AQ'; +const canvas1 = document.getElementById('J-canvas1') as HTMLCanvasElement; +const canvas2 = document.getElementById('J-canvas2') as HTMLCanvasElement; + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine1 = await WebGLEngine.create({ canvas: canvas1 }); + const rootEntity1 = engine1.sceneManager.activeScene.createRootEntity(); + const cameraEntity1 = rootEntity1.createChild('camera'); + + const engine2 = await WebGLEngine.create({ canvas: canvas2, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 } }); + const rootEntity2 = engine2.sceneManager.activeScene.createRootEntity(); + const cameraEntity2 = rootEntity2.createChild('camera'); + const camera1 = cameraEntity1.addComponent(Camera); + const camera2 = cameraEntity2.addComponent(Camera); + + engine1.canvas.resizeByClientSize(); + engine2.canvas.resizeByClientSize(); + cameraEntity1.transform.setPosition(0, 0, 10); + cameraEntity2.transform.setPosition(0, 0, 30); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity1 = rootEntity1.createChild(); + const displayComponent1 = entity1.addComponent(GalaceanDisplayComponent); + const entity2 = rootEntity2.createChild(); + const displayComponent2 = entity2.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent1.initialize(engine1._hardwareRenderer.gl, { camera: camera1 }); + await displayComponent1.loadScene(json1); + + // @ts-expect-error + displayComponent2.initialize(engine2._hardwareRenderer.gl, { camera: camera2 }); + await displayComponent2.loadScene(json2) as Composition; + + // 3. 执行 Galacean 渲染 + engine1.run(); + engine2.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/single.ts b/demo/src/single.ts new file mode 100644 index 0000000..1977b9c --- /dev/null +++ b/demo/src/single.ts @@ -0,0 +1,47 @@ +import { Camera, WebGLEngine } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; + +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); +// 图层 +// const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*Y8FjQKKWjboAAAAAAAAAAAAADlB4AQ' +// 闪电球 +// const json = 'https://gw.alipayobjects.com/os/gltf-asset/mars-cli/NKICJVAEIWDU/-1916559527-63956.json'; +// 爱心 +// const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*02UWQ6BvLuAAAAAAAAAAAAAADlB4AQ'; +// 场景推进 +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*MVjVR79EnZgAAAAAAAAAAAAADlB4AQ'; +// const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*8m6aSa2wW5IAAAAAAAAAAAAADlB4AQ'; + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 18); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + const composition = await displayComponent.loadScene(json, { autoplay: false }); + + composition.on('end', ({ composition }) => { + console.info(`${composition.name} end.`); + }); + displayComponent.play(); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/spine.ts b/demo/src/spine.ts new file mode 100644 index 0000000..771fbcb --- /dev/null +++ b/demo/src/spine.ts @@ -0,0 +1,36 @@ +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import '@galacean/engine-effects/plugin-spine'; + +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*C_h3QaPSnfYAAAAAAAAAAAAADlB4AQ'; +// 仅蝴蝶 +// const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*wvHEQ7NCai8AAAAAAAAAAAAADlB4AQ'; + +(async () => { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL2 } }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + const camera = cameraEntity.addComponent(Camera); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + camera.fieldOfView = 60; + camera.nearClipPlane = 0.1; + camera.farClipPlane = 1000; + camera.enableFrustumCulling = false; + cameraEntity.transform.setPosition(0, 0, 10); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + await displayComponent.loadScene(json); + + // 3. 执行 Galacean 渲染 + engine.run(); +})(); diff --git a/demo/src/text.ts b/demo/src/text.ts new file mode 100644 index 0000000..b658d36 --- /dev/null +++ b/demo/src/text.ts @@ -0,0 +1,39 @@ +import { Camera, WebGLEngine } from '@galacean/engine'; +import { GalaceanDisplayComponent, GalaceanTextComponent } from '@galacean/engine-effects'; + +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*GpjhQKmxI1MAAAAAAAAAAAAADlB4AQ'; + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 18); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + const composition = await displayComponent.loadScene(json); + + const textItem = composition.getItemByName('text_2'); + const textComponent = textItem?.getComponent(GalaceanTextComponent); + + textComponent?.setTextColor([255, 0, 0, 1]); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/src/use-effects-camera.ts b/demo/src/use-effects-camera.ts new file mode 100644 index 0000000..9e2fb7c --- /dev/null +++ b/demo/src/use-effects-camera.ts @@ -0,0 +1,34 @@ +import { GalaceanDisplayComponent } from '@galacean/engine-effects'; +import { Camera, WebGLEngine, WebGLMode } from '@galacean/engine'; + +const container = document.getElementById('J-container'); +const canvas = document.createElement('canvas'); +const json = 'https://mdn.alipayobjects.com/mars/afts/file/A*MVjVR79EnZgAAAAAAAAAAAAADlB4AQ'; + +(async () => { + try { + // 1. Galacean 场景初始化 + const engine = await WebGLEngine.create({ canvas, graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 } }); + const rootEntity = engine.sceneManager.activeScene.createRootEntity(); + const cameraEntity = rootEntity.createChild('camera'); + + container?.appendChild(canvas); + engine.canvas.resizeByClientSize(); + + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 15); + + // 2. 实例化 GalaceanDisplayComponent 并加载 Effects 资源 + const entity = rootEntity.createChild(); + const displayComponent = entity.addComponent(GalaceanDisplayComponent); + + // @ts-expect-error + displayComponent.initialize(engine._hardwareRenderer.gl); + await displayComponent.loadScene(json); + + // 3. 执行 Galacean 渲染 + engine.run(); + } catch (e) { + console.error('biz', e); + } +})(); diff --git a/demo/tsconfig.json b/demo/tsconfig.json new file mode 100644 index 0000000..902306b --- /dev/null +++ b/demo/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "src" + ] +} diff --git a/docs/dev-notes.md b/docs/dev-notes.md new file mode 100644 index 0000000..91ad209 --- /dev/null +++ b/docs/dev-notes.md @@ -0,0 +1,7 @@ +## 名词说明 + +> 插件代码中不可避免出现变量名等同名问题,为更好的区分,做以下规则,特此说明: + +- `engine`:除函数/构造函数参数使用,其他情形勿直接使用此命名 +- `originalEngine`:[Galacean Engine](https://github.com/galacean/engine) 引擎的实例化对象 +- `galaceanEngine`:本库中的 `galacean-engine.ts` 下 `GalaceanEngine` 类实例化对象 diff --git a/package.json b/package.json new file mode 100644 index 0000000..bc59d25 --- /dev/null +++ b/package.json @@ -0,0 +1,96 @@ +{ + "name": "@galacean/engine-effects", + "version": "1.0.0", + "description": "Galacean Effects runtime of Galacean Engine", + "module": "./dist/index.mjs", + "main": "./dist/index.js", + "brower": "./dist/index.min.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./alipay": { + "import": "./dist/alipay-miniprogram.mjs", + "require": "./dist/alipay-miniprogram.js", + "types": "./dist/index.d.ts" + }, + "./*": { + "import": "./dist/*.mjs", + "require": "./dist/*.js", + "types": "./dist/*.d.ts" + } + }, + "scripts": { + "dev": "vite", + "preview": "concurrently \"vite build\" \"sleep 6 && vite preview\"", + "prebuild": "pnpm clean", + "build": "pnpm build:declaration && pnpm build:module", + "build:module": "rollup -c", + "build:declaration": "tsc -d --emitDeclarationOnly", + "build:docs": "pnpm build && typedoc", + "lint": "eslint --ext .ts .", + "lint:fix": "eslint --fix --ext .ts .", + "check:ts": "tsc -b ./tsconfig.check.json", + "clean": "rimraf dist", + "prepare": "husky install", + "prepublishOnly": "pnpm build" + }, + "browserslist": [ + "iOS 9" + ], + "dependencies": { + "@galacean/effects-core": "2.0.3", + "@galacean/effects-plugin-spine": "2.0.3" + }, + "peerDependencies": { + "@galacean/engine": "1.3.8" + }, + "devDependencies": { + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@galacean/engine-toolkit-controls": "1.3.0", + "@rollup/plugin-commonjs": "^21.1.0", + "@rollup/plugin-inject": "^5.0.5", + "@rollup/plugin-node-resolve": "^13.3.0", + "@swc/core": "^1.4.13", + "@swc/helpers": "^0.5.8", + "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/parser": "^7.10.0", + "@vitejs/plugin-legacy": "^4.1.1", + "concurrently": "^8.2.2", + "eslint": "^8.57.0", + "eslint-plugin-compat": "^4.2.0", + "eslint-plugin-promise": "^6.1.1", + "husky": "^7.0.4", + "lint-staged": "^11.2.6", + "pnpm": "^8.15.8", + "rimraf": "4", + "rollup": "^2.79.1", + "rollup-plugin-swc3": "^0.11.0", + "tslib": "^2.6.2", + "typedoc": "^0.25.12", + "typescript": "^5.4.5", + "vite": "^4.5.3", + "vite-tsconfig-paths": "^4.3.2" + }, + "contributors": [ + { + "name": "云垣" + }, + { + "name": "桐伦" + } + ], + "author": "Ant Group CO., Ltd.", + "license": "MIT", + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..b66cdf3 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4477 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@galacean/effects-core': + specifier: 2.0.3 + version: 2.0.3 + '@galacean/effects-plugin-spine': + specifier: 2.0.3 + version: 2.0.3 + '@galacean/engine': + specifier: 1.3.8 + version: 1.3.8 + +devDependencies: + '@commitlint/cli': + specifier: ^19.3.0 + version: 19.3.0(@types/node@20.14.2)(typescript@5.4.5) + '@commitlint/config-conventional': + specifier: ^19.2.2 + version: 19.2.2 + '@galacean/engine-toolkit-controls': + specifier: 1.3.0 + version: 1.3.0(@galacean/engine@1.3.8) + '@rollup/plugin-commonjs': + specifier: ^21.1.0 + version: 21.1.0(rollup@2.79.1) + '@rollup/plugin-inject': + specifier: ^5.0.5 + version: 5.0.5(rollup@2.79.1) + '@rollup/plugin-node-resolve': + specifier: ^13.3.0 + version: 13.3.0(rollup@2.79.1) + '@swc/core': + specifier: ^1.4.13 + version: 1.6.3(@swc/helpers@0.5.11) + '@swc/helpers': + specifier: ^0.5.8 + version: 0.5.11 + '@typescript-eslint/eslint-plugin': + specifier: ^7.10.0 + version: 7.13.0(@typescript-eslint/parser@7.13.0)(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.10.0 + version: 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@vitejs/plugin-legacy': + specifier: ^4.1.1 + version: 4.1.1(terser@5.31.1)(vite@4.5.3) + concurrently: + specifier: ^8.2.2 + version: 8.2.2 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-plugin-compat: + specifier: ^4.2.0 + version: 4.2.0(eslint@8.57.0) + eslint-plugin-promise: + specifier: ^6.1.1 + version: 6.2.0(eslint@8.57.0) + husky: + specifier: ^7.0.4 + version: 7.0.4 + lint-staged: + specifier: ^11.2.6 + version: 11.2.6 + pnpm: + specifier: ^8.15.8 + version: 8.15.8 + rimraf: + specifier: '4' + version: 4.4.1 + rollup: + specifier: ^2.79.1 + version: 2.79.1 + rollup-plugin-swc3: + specifier: ^0.11.0 + version: 0.11.2(@swc/core@1.6.3)(rollup@2.79.1) + tslib: + specifier: ^2.6.2 + version: 2.6.2 + typedoc: + specifier: ^0.25.12 + version: 0.25.13(typescript@5.4.5) + typescript: + specifier: ^5.4.5 + version: 5.4.5 + vite: + specifier: ^4.5.3 + version: 4.5.3(@types/node@20.14.2)(terser@5.31.1) + vite-tsconfig-paths: + specifier: ^4.3.2 + version: 4.3.2(typescript@5.4.5)(vite@4.5.3) + +packages: + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + dev: true + + /@babel/compat-data@7.24.7: + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.24.7: + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + convert-source-map: 2.0.0 + debug: 4.3.5(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.24.7: + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.24.7: + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.24.7: + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-compilation-targets@7.24.7: + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + browserslist: 4.23.1 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.7): + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + debug: 4.3.5(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.24.7: + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-function-name@7.24.7: + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-hoist-variables@7.24.7: + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-member-expression-to-functions@7.24.7: + resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-imports@7.24.7: + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression@7.24.7: + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-plugin-utils@7.24.7: + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-wrap-function': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access@7.24.7: + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.24.7: + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-split-export-declaration@7.24.7: + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/helper-string-parser@7.24.7: + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.24.7: + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.24.7: + resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers@7.24.7: + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + dev: true + + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + dev: true + + /@babel/parser@7.24.7: + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.7 + dev: true + + /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.7): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.7): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.7): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-classes@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-split-export-declaration': 7.24.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/template': 7.24.7 + dev: true + + /@babel/plugin-transform-destructuring@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) + dev: true + + /@babel/plugin-transform-optional-chaining@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + regenerator-transform: 0.15.2 + dev: true + + /@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + dev: true + + /@babel/preset-env@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/core': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.7) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-classes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-destructuring': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-typeof-symbol': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.7) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.7) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.7) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.7) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.7) + core-js-compat: 3.37.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.7): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/types': 7.24.7 + esutils: 2.0.3 + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.24.7: + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: true + + /@babel/template@7.24.7: + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + dev: true + + /@babel/traverse@7.24.7: + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.5(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.24.7: + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + dev: true + + /@commitlint/cli@19.3.0(@types/node@20.14.2)(typescript@5.4.5): + resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} + engines: {node: '>=v18'} + hasBin: true + dependencies: + '@commitlint/format': 19.3.0 + '@commitlint/lint': 19.2.2 + '@commitlint/load': 19.2.0(@types/node@20.14.2)(typescript@5.4.5) + '@commitlint/read': 19.2.1 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - typescript + dev: true + + /@commitlint/config-conventional@19.2.2: + resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-conventionalcommits: 7.0.2 + dev: true + + /@commitlint/config-validator@19.0.3: + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + ajv: 8.16.0 + dev: true + + /@commitlint/ensure@19.0.3: + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + dev: true + + /@commitlint/execute-rule@19.0.0: + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/format@19.3.0: + resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + dev: true + + /@commitlint/is-ignored@19.2.2: + resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + semver: 7.6.2 + dev: true + + /@commitlint/lint@19.2.2: + resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/is-ignored': 19.2.2 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 + dev: true + + /@commitlint/load@19.2.0(@types/node@20.14.2)(typescript@5.4.5): + resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.1.0 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + cosmiconfig: 9.0.0(typescript@5.4.5) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.2)(cosmiconfig@9.0.0)(typescript@5.4.5) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - '@types/node' + - typescript + dev: true + + /@commitlint/message@19.0.0: + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/parse@19.0.3: + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-angular: 7.0.0 + conventional-commits-parser: 5.0.0 + dev: true + + /@commitlint/read@19.2.1: + resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + dev: true + + /@commitlint/resolve-extends@19.1.0: + resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.1.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + dev: true + + /@commitlint/rules@19.0.3: + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + dev: true + + /@commitlint/to-lines@19.0.0: + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/top-level@19.0.0: + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + engines: {node: '>=v18'} + dependencies: + find-up: 7.0.0 + dev: true + + /@commitlint/types@19.0.3: + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + engines: {node: '>=v18'} + dependencies: + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.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@8.57.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: 8.57.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.1: + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.5(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@esotericsoftware/spine-core@4.2.47: + resolution: {integrity: sha512-jMU4FMTNMjmWC/bRMuplvyVBIXrs4steuiCg/tRaw5y6S215bvT+4pkpoEg9o3vdUQc6vSMEyajAi/i8s7M1rA==} + dev: false + + /@fastify/deepmerge@1.3.0: + resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} + dev: true + + /@galacean/effects-core@2.0.3: + resolution: {integrity: sha512-+mjmQlxTKV0gdVbxZmnI2nHxT8WY51X9K7KVLnJ5uemrN1QOnu/R60W77YvxJ3/lINeq7CD/riro9m27dnWRAg==} + dependencies: + '@galacean/effects-math': 1.1.0 + '@galacean/effects-specification': 2.0.0 + flatbuffers: 24.3.25 + uuid: 9.0.1 + dev: false + + /@galacean/effects-math@1.1.0: + resolution: {integrity: sha512-6b1v0jq7sYYizRXWmXGTOiboeOjwVzu0BQ6HigC0GVn50oW4wVWX8lFfOd3HIYhddGareI5IZvjaJZwj69qAcA==} + engines: {node: '>=10.0.0'} + dev: false + + /@galacean/effects-plugin-spine@2.0.3: + resolution: {integrity: sha512-dJJ0vRo+eRnStTzEBElIDCTgh5iWXaOWq5/lzk9DKIMvKCkOltMvr6SH0WHtRjYuYxJKbB+aZUzW9GveeUoWSQ==} + dependencies: + '@esotericsoftware/spine-core': 4.2.47 + dev: false + + /@galacean/effects-specification@2.0.0: + resolution: {integrity: sha512-7ieZALZYn5fwKLIGAskmYSKGX82ZkLRdDUInG21KsOJ2eQ5+HcI6mJU5tmN8vjZxQUc+RVuUcssExGbiaj2+5w==} + dev: false + + /@galacean/engine-core@1.3.8: + resolution: {integrity: sha512-VJorRHLrE+GRc8fWj3CeuaoyGP6TnVe9tCKZjdSiEfk1cOdYQdYFaQiw6Is/HY/1OPFIJzeJJA0qXYo3+dctYA==} + dependencies: + '@galacean/engine-math': 1.3.8 + + /@galacean/engine-loader@1.3.8: + resolution: {integrity: sha512-JZnZ7x0N26L9sUFTJVfnW7DJdjNlPzWAb1CKmBGQ0LYr7qxz+/WyHsz3qW9EqbLlMBlDmC1F4bzOh9+gHroy4g==} + dependencies: + '@galacean/engine-core': 1.3.8 + '@galacean/engine-math': 1.3.8 + '@galacean/engine-rhi-webgl': 1.3.8 + + /@galacean/engine-math@1.3.8: + resolution: {integrity: sha512-dsm1YySE+tBVC5PSc1Tw3jGoCR6rCg303ftzO3w5122ieXg54v8SnMBwNVnqcVNxzYY6/68le1So85DtQf+lKA==} + + /@galacean/engine-rhi-webgl@1.3.8: + resolution: {integrity: sha512-hwea+pFvGlG73uX34qWdHz+xzQLmwJyYMVhgNZq5hJmqZQ6SIw4SHKIT3RyRStbuz8BAiJe44/YezBDxsnwNEA==} + dependencies: + '@galacean/engine-core': 1.3.8 + '@galacean/engine-math': 1.3.8 + + /@galacean/engine-toolkit-controls@1.3.0(@galacean/engine@1.3.8): + resolution: {integrity: sha512-J++0Hntw+isnYuVR5T+mlXJ10SX2v3MjizB6Pu27UaqcEzf3Hup9Zmx/rerakX8OZfgwbzCuc2Kqe3c+4v3ukw==} + peerDependencies: + '@galacean/engine': ^1.3.0-beta.6 + dependencies: + '@galacean/engine': 1.3.8 + dev: true + + /@galacean/engine@1.3.8: + resolution: {integrity: sha512-2qMkPN+QpEv1cF2vNNpvxsCJaQrVZ49QWnznRb9GHO0KAcCreIGVm/yPduNKS78aleOz2gpfketTKxL993h1zw==} + dependencies: + '@galacean/engine-core': 1.3.8 + '@galacean/engine-loader': 1.3.8 + '@galacean/engine-math': 1.3.8 + '@galacean/engine-rhi-webgl': 1.3.8 + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + dev: true + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.6: + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@mdn/browser-compat-data@5.5.33: + resolution: {integrity: sha512-uO4uIBFn9D4UNyUmaueIWnE/IJhBlSJ7W1rANvDdaawhTX8CSgqUX8tj9/6a+1WjpL9Bgirf67d//S2VwDsfig==} + 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.17.1 + dev: true + + /@rollup/plugin-commonjs@21.1.0(rollup@2.79.1): + resolution: {integrity: sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^2.38.3 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 7.2.3 + is-reference: 1.2.1 + magic-string: 0.25.9 + resolve: 1.22.8 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-inject@5.0.5(rollup@2.79.1): + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + estree-walker: 2.0.2 + magic-string: 0.30.10 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve@13.3.0(rollup@2.79.1): + resolution: {integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^2.42.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + '@types/resolve': 1.17.1 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@3.1.0(rollup@2.79.1): + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@5.1.0(rollup@2.79.1): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@swc/core-darwin-arm64@1.6.3: + resolution: {integrity: sha512-3r7cJf1BcE30iyF1rnOSKrEzIR+cqnyYSZvivrm62TZdXVsIjfXe1xulsKGxZgNeLY5erIu7ukvMvBvPhnQvqA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-darwin-x64@1.6.3: + resolution: {integrity: sha512-8GLZ23IgVpF5xh2SbS5ZW/12/EEBuRU1hFOLB5rKERJU0y1RJ6YhDMf/FuOWhfHQcFM7TeedBwHIzaF+tdKKlw==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm-gnueabihf@1.6.3: + resolution: {integrity: sha512-VQ/bduX7WhLOlGbJLMG7UH0LBehjjx43R4yuk55rjjJLqpvX5fQzMsWhQdIZ5vsc+4ORzdgtEAlpumTv6bsD1A==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-gnu@1.6.3: + resolution: {integrity: sha512-jHIQ/PCwtdDBIF/BiC5DochswuCAIW/T5skJ+eDMbta7+QtEnZCXTZWpT5ORoEY/gtsE2fjpOA4TS6fBBvXqUw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-musl@1.6.3: + resolution: {integrity: sha512-gA6velEUD27Dwu0BlR9hCcFzkWq2YL2pDAU5qbgeuGhaMiUCBssfqTQB+2ctEnV+AZx+hSMJOHvtA+uFZjfRrw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-gnu@1.6.3: + resolution: {integrity: sha512-fy4qoBDr5I8r+ZNCZxs/oZcmu4j/8mtSud6Ka102DaSxEjNg0vfIdo9ITsVIPsofhUTmDKjQsPB2O7YUlJAioQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-musl@1.6.3: + resolution: {integrity: sha512-c/twcMbq/Gpq47G+b3kWgoaCujpXO11aRgJx6am+CprvP4uNeBHEpQkxD+DQmdWFHisZd0i9GB8NG3e7L9Rz9Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-arm64-msvc@1.6.3: + resolution: {integrity: sha512-y6RxMtX45acReQmzkxcEfJscfBXce6QjuNgWQHHs9exA592BZzmolDUwgmAyjyvopz1lWX+KdymdZFKvuDSx4w==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-ia32-msvc@1.6.3: + resolution: {integrity: sha512-41h7z3xgukl1HDDwhquaeOPSP1OWeHl+mWKnJVmmwd3ui/oowUDCO856qa6JagBgPSnAGfyXwv6vthuXwyCcWA==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-x64-msvc@1.6.3: + resolution: {integrity: sha512-//bnwo9b8Vp1ED06eXCHyGZ5xIpdkQgg2fuFDdtd1FITl7r5bdQh2ryRzPiKiGwgXZwZQitUshI4JeEX9IuW+Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core@1.6.3(@swc/helpers@0.5.11): + resolution: {integrity: sha512-mZpei+LqE+AL+nwgERMQey9EJA9/yhHTN6nwbobH5GnSij/lhfTdGfAb1iumOrroqEcXbHUaK//7wOw7DjBGdA==} + engines: {node: '>=10'} + requiresBuild: true + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + dependencies: + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.11 + '@swc/types': 0.1.8 + optionalDependencies: + '@swc/core-darwin-arm64': 1.6.3 + '@swc/core-darwin-x64': 1.6.3 + '@swc/core-linux-arm-gnueabihf': 1.6.3 + '@swc/core-linux-arm64-gnu': 1.6.3 + '@swc/core-linux-arm64-musl': 1.6.3 + '@swc/core-linux-x64-gnu': 1.6.3 + '@swc/core-linux-x64-musl': 1.6.3 + '@swc/core-win32-arm64-msvc': 1.6.3 + '@swc/core-win32-ia32-msvc': 1.6.3 + '@swc/core-win32-x64-msvc': 1.6.3 + dev: true + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: true + + /@swc/helpers@0.5.11: + resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==} + dependencies: + tslib: 2.6.2 + dev: true + + /@swc/types@0.1.8: + resolution: {integrity: sha512-RNFA3+7OJFNYY78x0FYwi1Ow+iF1eF5WvmfY1nXPOEH4R2p/D4Cr1vzje7dNAI2aLFqpv8Wyz4oKSWqIZArpQA==} + dependencies: + '@swc/counter': 0.1.3 + dev: true + + /@types/conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + dependencies: + '@types/node': 20.14.2 + dev: true + + /@types/estree@0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + dev: true + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/node@20.14.2: + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/parse-json@4.0.2: + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + dev: true + + /@types/resolve@1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 20.14.2 + dev: true + + /@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0)(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5(supports-color@8.1.1) + eslint: 8.57.0 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.13.0: + resolution: {integrity: sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + dev: true + + /@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + debug: 4.3.5(supports-color@8.1.1) + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@7.13.0: + resolution: {integrity: sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==} + engines: {node: ^18.18.0 || >=20.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.13.0(typescript@5.4.5): + resolution: {integrity: sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@7.13.0: + resolution: {integrity: sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.13.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /@vitejs/plugin-legacy@4.1.1(terser@5.31.1)(vite@4.5.3): + resolution: {integrity: sha512-um3gbVouD2Q/g19C0qpDfHwveXDCAHzs8OC3e9g6aXpKoD1H14himgs7wkMnhAynBJy7QqUoZNAXDuqN8zLR2g==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + terser: ^5.4.0 + vite: ^4.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/preset-env': 7.24.7(@babel/core@7.24.7) + browserslist: 4.23.1 + core-js: 3.37.1 + magic-string: 0.30.10 + regenerator-runtime: 0.13.11 + systemjs: 6.15.1 + terser: 5.31.1 + vite: 4.5.3(@types/node@20.14.2)(terser@5.31.1) + transitivePeerDependencies: + - supports-color + dev: true + + /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 + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: true + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + 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.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + 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-sequence-parser@1.1.1: + resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} + 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 + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + 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 + + /ast-metadata-inferer@0.8.0: + resolution: {integrity: sha512-jOMKcHht9LxYIEQu+RVd22vtgrPaVCtDRQ/16IGmurdzxvYbDd5ynxjnyrzLnieG96eTcAyaoj/wN/4/1FyyeA==} + dependencies: + '@mdn/browser-compat-data': 5.5.33 + dev: true + + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.7): + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.7): + resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + core-js-compat: 3.37.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.7): + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + 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.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true + + /browserslist@4.23.1: + resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001633 + electron-to-chromium: 1.4.802 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.1) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /caniuse-lite@1.0.30001633: + resolution: {integrity: sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==} + 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 + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + 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@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 + + /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 + + /colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + dev: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concurrently@8.2.2: + resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} + engines: {node: ^14.13.0 || >=16.0.0} + hasBin: true + dependencies: + chalk: 4.1.2 + date-fns: 2.30.0 + lodash: 4.17.21 + rxjs: 7.8.1 + shell-quote: 1.8.1 + spawn-command: 0.0.2 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + dev: true + + /conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /core-js-compat@3.37.1: + resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} + dependencies: + browserslist: 4.23.1 + dev: true + + /core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} + requiresBuild: true + dev: true + + /cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.2)(cosmiconfig@9.0.0)(typescript@5.4.5): + resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + engines: {node: '>=v16'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=8.2' + typescript: '>=4' + dependencies: + '@types/node': 20.14.2 + cosmiconfig: 9.0.0(typescript@5.4.5) + jiti: 1.21.6 + typescript: 5.4.5 + dev: true + + /cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /cosmiconfig@9.0.0(typescript@5.4.5): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.4.5 + 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 + + /dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + dev: true + + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.24.7 + dev: true + + /debug@4.3.5(supports-color@8.1.1): + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 8.1.1 + 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 + + /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@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dependencies: + is-obj: 2.0.0 + dev: true + + /electron-to-chromium@1.4.802: + resolution: {integrity: sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + 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 + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + 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.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + 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@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-plugin-compat@4.2.0(eslint@8.57.0): + resolution: {integrity: sha512-RDKSYD0maWy5r7zb5cWQS+uSPc26mgOzdORJ8hxILmWM7S/Ncwky7BcAtXVY5iRbKjBdHsWU8Yg7hfoZjtkv7w==} + engines: {node: '>=14.x'} + peerDependencies: + eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@mdn/browser-compat-data': 5.5.33 + ast-metadata-inferer: 0.8.0 + browserslist: 4.23.1 + caniuse-lite: 1.0.30001633 + eslint: 8.57.0 + find-up: 5.0.0 + lodash.memoize: 4.1.2 + semver: 7.6.2 + dev: true + + /eslint-plugin-promise@6.2.0(eslint@8.57.0): + resolution: {integrity: sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + dependencies: + eslint: 8.57.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + 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@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + 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.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + 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@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.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 + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + 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.7 + 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.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + 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.2.0 + dev: true + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + 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-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + dev: true + + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flatbuffers@24.3.25: + resolution: {integrity: sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==} + dev: false + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + 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.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + 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-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + 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-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + 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@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.4 + minipass: 4.2.8 + path-scurry: 1.11.1 + dev: true + + /global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + dependencies: + ini: 4.1.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + 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.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + 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 + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /husky@7.0.4: + resolution: {integrity: sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==} + engines: {node: '>=12'} + hasBin: true + dev: true + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + 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-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + 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==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + 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@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 + 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-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + 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-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + dependencies: + '@types/estree': 1.0.5 + dev: true + + /is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + dependencies: + text-extensions: 2.4.0 + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + 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-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.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + 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.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + 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 + + /lint-staged@11.2.6: + resolution: {integrity: sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==} + hasBin: true + dependencies: + cli-truncate: 2.1.0 + colorette: 1.4.0 + commander: 8.3.0 + cosmiconfig: 7.1.0 + debug: 4.3.5(supports-color@8.1.1) + enquirer: 2.4.1 + execa: 5.1.1 + listr2: 3.14.0(enquirer@2.4.1) + micromatch: 4.0.7 + normalize-path: 3.0.0 + please-upgrade-node: 3.2.0 + string-argv: 0.3.1 + stringify-object: 3.3.0 + supports-color: 8.1.1 + 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.4.1 + rxjs: 7.8.1 + through: 2.3.8 + wrap-ansi: 7.0.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 + + /locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: true + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + 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.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + dev: true + + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + dev: true + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + 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 + + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + dev: true + + /magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + dev: true + + /meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + 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.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@8.0.4: + resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + dev: true + + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + 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 + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + 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 + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + 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-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.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-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + 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 + + /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@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + 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-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /please-upgrade-node@3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + dependencies: + semver-compare: 1.0.0 + dev: true + + /pnpm@8.15.8: + resolution: {integrity: sha512-0aAp4aRHrZC8ls1YsPrUhtKZPVMYVjlve6vy2D6xgju4PFo9D8GPZ1stEDIdSesWH+zjb+gTSqWCPs0hX+7Tkg==} + engines: {node: '>=16.14'} + hasBin: true + dev: true + + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.24.7 + dev: true + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + 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 + + /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-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + 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 + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} + engines: {node: '>=14'} + hasBin: true + dependencies: + glob: 9.3.5 + dev: true + + /rollup-plugin-swc3@0.11.2(@swc/core@1.6.3)(rollup@2.79.1): + resolution: {integrity: sha512-o1ih9B806fV2wBSNk46T0cYfTF2eiiKmYXRpWw3K4j/Cp3tCAt10UCVsTqvUhGP58pcB3/GZcAVl5e7TCSKN6Q==} + engines: {node: '>=12'} + peerDependencies: + '@swc/core': '>=1.2.165' + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + dependencies: + '@fastify/deepmerge': 1.3.0 + '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@swc/core': 1.6.3(@swc/helpers@0.5.11) + get-tsconfig: 4.7.5 + rollup: 2.79.1 + rollup-preserve-directives: 1.1.1(rollup@2.79.1) + dev: true + + /rollup-preserve-directives@1.1.1(rollup@2.79.1): + resolution: {integrity: sha512-+eQafbuEfDPfxQ9hQPlwaROfin4yiVRxap8hnrvvvcSGoukv1tTiYpAW9mvm3uR8J+fe4xd8FdVd5rz9q7jZ+Q==} + peerDependencies: + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + dependencies: + magic-string: 0.30.10 + rollup: 2.79.1 + dev: true + + /rollup@2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + 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.6.2 + dev: true + + /semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + 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@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + dev: true + + /shiki@0.14.7: + resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} + dependencies: + ansi-sequence-parser: 1.1.1 + jsonc-parser: 3.2.1 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + 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 + + /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 + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + 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 + + /sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /spawn-command@0.0.2: + resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + dev: true + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: true + + /string-argv@0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + 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 + + /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-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + 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 + + /systemjs@6.15.1: + resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==} + dev: true + + /terser@5.31.1: + resolution: {integrity: sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.11.3 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + 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 + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-api-utils@1.3.0(typescript@5.4.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.4.5 + dev: true + + /tsconfck@3.1.0(typescript@5.4.5): + resolution: {integrity: sha512-CMjc5zMnyAjcS9sPLytrbFmj89st2g+JYtY/c02ug4Q+CZaAtCgbyviI0n1YvjZE/pzoc6FbNsINS13DOL1B9w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.4.5 + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + 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-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 + + /typedoc@0.25.13(typescript@5.4.5): + resolution: {integrity: sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==} + engines: {node: '>= 16'} + hasBin: true + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x + dependencies: + lunr: 2.3.9 + marked: 4.3.0 + minimatch: 9.0.4 + shiki: 0.14.7 + typescript: 5.4.5 + dev: true + + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + dev: true + + /update-browserslist-db@1.0.16(browserslist@4.23.1): + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.1 + escalade: 3.1.2 + picocolors: 1.0.1 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + + /vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@4.5.3): + resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + debug: 4.3.5(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 3.1.0(typescript@5.4.5) + vite: 4.5.3(@types/node@20.14.2)(terser@5.31.1) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /vite@4.5.3(@types/node@20.14.2)(terser@5.31.1): + resolution: {integrity: sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==} + 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: + '@types/node': 20.14.2 + esbuild: 0.18.20 + postcss: 8.4.38 + rollup: 3.29.4 + terser: 5.31.1 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: true + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + 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 + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + 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 + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true diff --git a/rollup.appx.config.js b/rollup.appx.config.js new file mode 100644 index 0000000..2e08da0 --- /dev/null +++ b/rollup.appx.config.js @@ -0,0 +1,59 @@ +/** + * 小程序产物编译配置 + */ +import inject from '@rollup/plugin-inject'; + +const module = '@galacean/engine-miniprogram-adapter'; +const commonAdapterList = [ + 'window', + 'navigator', + 'HTMLElement', + 'HTMLImageElement', + 'HTMLCanvasElement', + 'HTMLVideoElement', + 'document', + 'WebGLRenderingContext', + 'Image', + 'URL', + 'location', + 'XMLHttpRequest', + 'Blob', + 'performance', + 'requestAnimationFrame', + 'cancelAnimationFrame', +]; +const adapterList = { + alipay: [...commonAdapterList], +} +const globals = { + '@galacean/engine': 'Galacean', +}; + +export default [ + 'alipay', +].map(platform => { + const adapterVars = {}; + + adapterList[platform].forEach(name => { + adapterVars[name] = [`${module}`, name]; + }); + + return { + input: `src/index.ts`, + external: ['@galacean/engine'], + output: [{ + globals, + file: `./dist/${platform}-miniprogram.mjs`, + format: 'es', + sourcemap: true, + }, { + globals, + file: `./dist/${platform}-miniprogram.js`, + format: 'cjs', + sourcemap: true, + }], + plugins: [ + inject(adapterVars), + ], + }; +}); diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..247ceb3 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,56 @@ +import { getPlugins } from './scripts/rollup-config-helper'; +import spineConfig from './rollup.spine.config'; +import appxConfig from './rollup.appx.config'; + +const pkg = require('./package.json'); +const banner = `/*! + * Name: ${pkg.name} + * Description: ${pkg.description} + * Author: ${pkg.author} + * Contributors: ${pkg.contributors.map(c => c.name).join(',')} + * Version: v${pkg.version} + */ +`; + +const globals = { + '@galacean/engine': 'Galacean', +}; +const external = Object.keys(globals); +const plugins = getPlugins(pkg); + +export default (commandLineArgs) => { + return [ + { + input: 'src/index.ts', + output: [{ + file: pkg.module, + format: 'es', + banner, + globals, + sourcemap: true, + }, { + file: pkg.main, + format: 'cjs', + banner, + globals, + sourcemap: true, + }], + external, + plugins, + }, { + input: 'src/index.ts', + output: { + file: pkg.brower, + format: 'umd', + name: 'Galacean.effects', + banner, + globals, + sourcemap: true, + }, + external, + plugins: getPlugins(pkg, { min: true }), + }, + ...spineConfig, + ...appxConfig.map(config => ({ ...config, plugins: plugins.concat(config.plugins) })) + ]; +}; diff --git a/rollup.spine.config.js b/rollup.spine.config.js new file mode 100644 index 0000000..21c6f33 --- /dev/null +++ b/rollup.spine.config.js @@ -0,0 +1,28 @@ +import { getPlugins } from './scripts/rollup-config-helper'; + +const pkg = require('./package.json'); +const globals = { + '@galacean/engine-effects': 'Galacean.effects', +}; +const external = ['@galacean/effects']; +const plugins = getPlugins(pkg); +const paths = { '@galacean/effects': '@galacean/engine-effects'}; + +export default [{ + input: 'src/plugin-spine.ts', + output: [{ + file: './dist/plugin-spine.mjs', + format: 'es', + globals, + sourcemap: true, + paths, + }, { + file: './dist/plugin-spine.js', + format: 'cjs', + globals, + sourcemap: true, + paths, + }], + external, + plugins, +}]; diff --git a/scripts/rollup-config-helper.js b/scripts/rollup-config-helper.js new file mode 100644 index 0000000..5550971 --- /dev/null +++ b/scripts/rollup-config-helper.js @@ -0,0 +1,39 @@ +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import { swc, defineRollupSwcOption, minify } from 'rollup-plugin-swc3'; + +export function getPlugins(pkg, options = {}) { + const { min = false, target } = options; + const plugins = [ + getSWCPlugin({ target }), + resolve(), + commonjs(), + ]; + + if (min) { + plugins.push(minify({ sourceMap: true })); + } + + return plugins; +} + +export function getSWCPlugin( + jscOptions = {}, +) { + const jsc = { + loose: true, + externalHelpers: true, + target: 'ES5', + ...jscOptions, + } + const options = { + exclude: [], + jsc, + sourceMaps: true, + }; + + return swc( + defineRollupSwcOption(options), + ); +} + diff --git a/src/engine-instance.ts b/src/engine-instance.ts new file mode 100644 index 0000000..d1aaaa1 --- /dev/null +++ b/src/engine-instance.ts @@ -0,0 +1,49 @@ +import * as ENGINE from '@galacean/engine'; +import type { GalaceanEffectsOptions } from './galacean-display-component'; +import { GalaceanDisplayComponent } from './galacean-display-component'; + +/** + * 设置全局唯一 Engine 对象 + * @param options + */ +export function setEngine (options?: GalaceanEffectsOptions) { + GalaceanDisplayComponent.notifyTouch = !options?.notifyTouch; + /** + * 必须有这个修改,Effects 的 shader 实现和 Galaecan 不同, + * 这里面的修改对于 Effects 没什么用,但是又没方法避开不用 Engine 中的方法 + * 需要引擎修改后可以去除 + */ + hackShaderConvert(); +} + +function hackShaderConvert () { + ENGINE.ShaderFactory.convertTo300 = function (shader: string, isFrag?: boolean) { + /** replace attribute and in */ + shader = shader.replace(/\battribute\b/g, 'in'); + shader = shader.replace(/\bvarying\b/g, isFrag ? 'in' : 'out'); + + /** replace api */ + shader = shader.replace(/\btexture(2D|Cube)\b/g, 'texture'); + shader = shader.replace(/\btexture(2D|Cube)LodEXT\b/g, 'textureLod'); + if (isFrag) { + + const isMRT = /\bgl_FragData\[.+?\]/g.test(shader); + + if (isMRT) { + shader = shader.replace(/\bgl_FragColor\b/g, 'gl_FragData[0]'); + const result = shader.match(/\bgl_FragData\[.+?\]/g); + + // @ts-expect-error + shader = this._replaceMRTShader(shader, result); + } else { + + if (!shader.includes('MARS_RUNTIME') || shader.includes('vDark')) { + shader = shader.replace(/void\s+?main\s*\(/g, 'out vec4 glFragColor;\nvoid main('); + } + shader = shader.replace(/\bgl_FragColor\b/g, 'glFragColor'); + } + } + + return shader; + }; +} diff --git a/src/galacean-composition.ts b/src/galacean-composition.ts new file mode 100644 index 0000000..8583d92 --- /dev/null +++ b/src/galacean-composition.ts @@ -0,0 +1,138 @@ +import type * as ENGINE from '@galacean/engine'; +import type * as EFFECTS from '@galacean/effects-core'; +import type { Scene, MeshRendererOptions, CompositionProps } from '@galacean/effects-core'; +import { Composition } from '@galacean/effects-core'; +import type { GalaceanRenderer } from './galacean-renderer'; +import { GalaceanTexture } from './galacean-texture'; +import type { GalaceanEngine } from './galacean-engine'; +import { GalaceanRenderFrame } from './galacean-render-frame'; + +export interface GalaceanCompositionProps extends CompositionProps { + /** + * 指定合成名字 + */ + compositionName?: string, + /** + * 是否多合成 + */ + multipleCompositions?: boolean, + /** + * 相机参数 + */ + galaceanCamera?: ENGINE.Camera, + /** + * 是否始终朝向相机 + * @since 1.3.0 + */ + billboard?: boolean, +} + +/** + * composition 抽象类的实现 + */ +export class GalaceanComposition extends Composition { + /** + * 发射器形状缓存 map + */ + static shape: Record = {}; + + /** + * composition 开始标志 + */ + started = false; + /** + * 相机参数 + */ + galaceanCamera?: ENGINE.Camera; + engine?: EFFECTS.Engine; + /** + * 是否始终朝向相机 + * @since 1.3.0 + */ + billboard = false; + + constructor (props: GalaceanCompositionProps, scene: Scene) { + super(props, scene); + + const { billboard, galaceanCamera } = props; + + this.billboard = !!billboard; + this.compositionSourceManager.sourceContent?.items.forEach(item => { + // @ts-expect-error + const shape = item.content?.renderer?.shape ?? {}; + + Object.keys(shape).forEach(name => { + const buffer = shape[name]; + + if (!GalaceanComposition.shape[name]) { + GalaceanComposition.shape[name] = 0; + } + GalaceanComposition.shape[name] += buffer.length; + }); + }); + this.galaceanCamera = galaceanCamera; + this.engine = this.renderer.engine; + (this.renderer as GalaceanRenderer).setEffectsCamera(this.camera); + } + + /** + * 更新 video texture 数据 + */ + override updateVideo () { + void this.textures.map(tex => (tex as GalaceanTexture).startVideo()); + } + + override setPosition (x: number, y: number, z: number): void { + (this.renderer.engine as GalaceanEngine).entity.transform.setPosition(x, y, z); + } + + /** + * 开始 + */ + override createRenderFrame () { + this.renderFrame = new GalaceanRenderFrame({ + camera: this.camera, + keepColorBuffer: this.keepColorBuffer, + renderer: this.renderer, + }); + } + + /** + * 获取 render 参数 + * + * @returns + */ + override getRendererOptions (): MeshRendererOptions { + const emptyTexture = GalaceanTexture.createWithData( + this.renderer.engine, + { + data: new Uint8Array(4).fill(255), + width: 1, + height: 1, + }, + ); + + if (!this.rendererOptions) { + this.rendererOptions = { + emptyTexture, + cachePrefix: '-', + }; + } + + return this.rendererOptions; + } + + override prepareRender () { + const frame = this.renderFrame; + + frame._renderPasses[0].meshes.length = 0; + this.postLoaders.length = 0; + this.pluginSystem.plugins.forEach(loader => { + if (loader.prepareRenderFrame(this, frame)) { + this.postLoaders.push(loader); + } + }); + this.gatherRendererComponent(this.rootItem, frame); + this.postLoaders.forEach(loader => loader.postProcessFrame(this, frame)); + } +} diff --git a/src/galacean-display-component.ts b/src/galacean-display-component.ts new file mode 100644 index 0000000..dd7cca0 --- /dev/null +++ b/src/galacean-display-component.ts @@ -0,0 +1,785 @@ +import * as ENGINE from '@galacean/engine'; +import type { + JSONValue, Scene, SceneLoadOptions, TouchEventType, EffectsObject, MessageItem, + Renderer, SceneType, Composition, SceneLoadType, EventEmitterListener, Region, +} from '@galacean/effects-core'; +import { + EVENT_TYPE_CLICK, EventSystem, spec, AssetManager, Ticker, isArray, gpuTimer, isSceneURL, + isSceneWithOptions, Texture, logger, +} from '@galacean/effects-core'; +import { GalaceanComposition } from './galacean-composition'; +import { GalaceanRenderer } from './galacean-renderer'; +import { GalaceanEngine } from './galacean-engine'; + +/** + * 播放器可以绑定的事件 + */ +export type PlayerEvent

= { + /** + * 播放器点击事件 + */ + ['click']: [clickInfo: Region & { + player: P, + compositionId: string, + compositionName: string, + }], + /** + * 播放器消息事件(合成中元素创建/销毁时触发) + */ + ['message']: [messageInfo: MessageItem], + /** + * 播放器暂停事件 + */ + ['pause']: [], + /** + * 播放器更新事件 + */ + ['update']: [updateInfo: { player: P, playing: boolean }], + /** + * 渲染错误事件 + */ + ['rendererror']: [error?: Error], +}; + +/** + * `onItemClicked` 点击回调函数的传入参数 + */ +export interface ItemClickedData { + name: string, + id: number, + displayComponent: GalaceanDisplayComponent, + hitPositions: spec.vec3[], + compositionId: number, +} + +/** + * `displayComponent.play` 的可选参数 + */ +export interface PlayOptions { + /** + * 播放开始时间 + * @default 0 + */ + currentTime?: number, + /** + * 播放第一帧后暂停播放器 + */ + pauseOnFirstFrame?: boolean, + /** + * 合成播放完成后是否需要再使用,是的话生命周期结束后不会 `dispose` + * @default false + */ + reusable?: boolean, + /** + * 播放速度,当速度为负数时,合成倒播 + */ + speed?: number, + /** + * 是否为多合成播放 + * @default false - 会替换当前播放的合成 + */ + multipleCompositions?: boolean, + /** + * 多合成播放时的基础渲染顺序,数字小的先渲染 + */ + baseRenderOrder?: number, + /** + * 多合成播放时的基础渲染顺序,数字小的先渲染,默认多个 component 的 Effects 混合在一起渲染 + * @since 2.0.0 + */ + componentRenderOrder?: number, + /** + * 如果动画配置有多个合成,设置要播放的合成名称 + */ + compositionName?: string, +} +/** + * Effects 组件全局参数 + */ +export interface GalaceanDisplayComponentOptions { + // 宽度 + width?: number, + // 高度 + height?: number, + // 相机对象 + camera?: ENGINE.Camera, + // 是否可交互(仅在使用默认相机时生效,即camera参数为空) + interactive?: boolean, +} + +/** + * Effects 全局参数 + */ +export interface GalaceanEffectsOptions { + /** + * 是否通知 container touchend / mouseup 事件, 默认通知 + */ + notifyTouch?: boolean, +} + +export interface GalaceanSceneLoadOptions extends SceneLoadOptions { + /** + * 是否始终朝向相机 + * @since 1.3.0 + */ + billboard?: boolean, + /** + * 合成的层级 + * @since 2.0.0 - 用于多个合成同时播放时的渲染顺序 + */ + priority?: number, +} + +/** + * + */ +export class GalaceanDisplayComponent extends ENGINE.Script { + static notifyTouch: boolean; + + compositions: GalaceanComposition[] = []; + camera?: ENGINE.Camera; + width: number; + height: number; + event: EventSystem; + renderer: Renderer; + + gl: WebGLRenderingContext | WebGL2RenderingContext; + /** + * GE 使用的计时器 + */ + ticker: Ticker | null; + baseCompositionIndex: any; + assetManagers: AssetManager[] = []; + env: string; + disposed: any; + autoPlaying: boolean; + effectsEngine: GalaceanEngine; + speed = 1; + + private readonly builtinObjects: EffectsObject[] = []; + private resumePending = false; + + /** + * Effects 组件初始化方法 + * @param context - WebGL上下文 + * @param options - 组件参数 + */ + initialize ( + context: WebGLRenderingContext | WebGL2RenderingContext, + options: GalaceanDisplayComponentOptions = {}, + ) { + const { width, height } = this.engine.canvas; + const { camera, interactive = false } = options; + + // @ts-expect-error _webCanvas 为私有属性 + this.event = new EventSystem(this.engine.canvas._webCanvas, GalaceanDisplayComponent.notifyTouch); + this.event.bindListeners(); + this.event.addEventListener(EVENT_TYPE_CLICK, this.handleClick); + this.width = width; + this.height = height; + this.camera = camera; + this.gl = context; + this.effectsEngine = new GalaceanEngine( + context, + this.engine, + { + entity: this.entity, + camera: this.camera, + }, + ); + // 设置 Renderer + this.renderer = new GalaceanRenderer(this.effectsEngine); + // 交互元素需要 engine->renderer->env + this.effectsEngine.renderer = this.renderer; + this.ticker = new Ticker(60); + this.interactive = interactive; + const ticker = this.ticker; + + ticker.add(this.tick.bind(this)); + ticker.start(); + } + + /** + * 元素监听事件 + * @param eventName - 事件名称 + * @param listener - 事件监听器 + * @returns + */ + on> ( + eventName: E, + listener: EventEmitterListener[E]>, + ) { + this._engine.on(eventName, listener); + } + + /** + * 移除事件监听器 + * @param eventName - 事件名称 + * @param listener - 事件监听器 + * @returns + */ + off> ( + eventName: E, + listener: EventEmitterListener[E]>, + ) { + this._engine.off(eventName, listener); + } + + /** + * 一次性监听事件 + * @param eventName - 事件名称 + * @param listener - 事件监听器 + */ + once> ( + eventName: E, + listener: EventEmitterListener[E]>, + ) { + this._engine.once(eventName, listener); + } + + /** + * 触发事件 + * @param eventName - 事件名称 + * @param args - 事件参数 + */ + emit> ( + eventName: E, + ...args: PlayerEvent[E] + ) { + this._engine.dispatch(eventName, ...args); + } + + /** + * display component 在定时器每帧的回调 + * @param dt - 时间差,毫秒 + */ + private tick (dt: number) { + dt = Math.min(dt, 33) * this.speed; + const comps = this.compositions; + let skipRender = false; + const { renderErrors } = this.renderer.engine; + + renderErrors.values().next().value; + + if (renderErrors.size > 0) { + this.emit('rendererror', renderErrors.values().next().value); + // 有渲染错误时暂停播放 + this.ticker?.pause(); + } + comps.sort((a, b) => a.getIndex() - b.getIndex()); + this.compositions = []; + for (let i = 0; i < comps.length; i++) { + const composition = comps[i]; + + if (composition.textureOffloaded) { + skipRender = true; + logger.error(`Composition ${composition.name} texture offloaded, skip render.`); + this.compositions.push(composition); + continue; + } + if (!composition.isDestroyed && composition.renderer) { + composition.update(dt); + } + if (!composition.isDestroyed) { + this.compositions.push(composition); + } + } + this.baseCompositionIndex = this.compositions.length; + if (skipRender) { + this.emit('rendererror', new Error('Play when texture offloaded.')); + + return this.ticker?.pause(); + } + if (!this.pause) { + const { level } = this.effectsEngine.gpuCapability; + const time = level === 2 ? gpuTimer(this.gl as WebGL2RenderingContext) : undefined; + + time?.begin(); + if ( + this.compositions.length || + this.compositions.length < comps.length + ) { + for (let i = 0; i < comps.length; i++) { + !comps[i].renderFrame.isDestroyed && this.renderer.renderRenderFrame(comps[i].renderFrame); + } + } + time?.end(); + time?.getTime() + .then(t => this.reportGPUTime?.(t ?? 0)) + .catch; + if (this.autoPlaying) { + this.emit('update', { + player: this, + playing: true, + }); + } + } + } + + reportGPUTime (arg0: number): any { + throw new Error('Method not implemented.'); + } + + override onUpdate (deltaTime: number): void { + this.lookAtCamera(); + } + + private lookAtCamera () { + if (!this.camera) { + return; + } + + const position = this.camera.entity.transform.position; + + this.compositions.forEach(comp => { + if (comp.billboard && comp.renderer.engine) { + (comp.renderer.engine as GalaceanEngine).entity.transform.lookAt(position); + } + + }); + } + // TODO: 暂时先注释,如果所有galacean业务的诉求都是和设计帧率保持一致,该方法可删除 + // /** + // * Component 的每帧更新函数- + // * @param deltaTime 每帧更新时间 + // * @returns + // */ + // override onUpdate (deltaTime: number) { + + // if (this.paused) { + // return; + // } + + // deltaTime = Math.max(deltaTime, 0.0167); + // const comps = this.compositions; + + // comps.forEach((composition, i) => { + + // if (!composition.started) { + // return; + // } + // if (composition.isDestroyed) { + // composition.dispose(); + // delete comps[i]; + + // return; + // } + // const time = Math.round(deltaTime * 1000); + + // this.compositions = comps; + // if (time) { + // const reverse = time < 0; + // const step = 15; + // let t = Math.abs(time); + + // for (let ss = reverse ? -step : step; t > step; t -= step) { + // composition.update(ss); + // } + // if (t > 0 && !composition.isDestroyed) { + // const ss = reverse ? -t : t; + + // composition.update(ss); + // } + // } + // }); + + // } + + /** + * 获取当前播放合成,如果是多个合成同时播放,返回第一个合成 + */ + get currentComposition (): GalaceanComposition { + return this.compositions?.[0]; + } + + /** + * 播放通过 player 加载好的全部合成 + */ + play () { + this.autoPlaying = true; + this.compositions.map(composition => { + composition.play(); + }); + this.ticker?.start(); + } + + /** + * 加载动画资源 + * @param scene - 一个或一组 URL 或者通过 URL 请求的 JSONObject 或者 Scene 对象 + * @param options - 加载可选参数 + * @returns + */ + async loadScene (scene: SceneLoadType, options?: GalaceanSceneLoadOptions): Promise; + async loadScene (scene: SceneLoadType[], options?: GalaceanSceneLoadOptions): Promise; + async loadScene (scene: SceneLoadType | SceneLoadType[], options?: GalaceanSceneLoadOptions): Promise { + let composition: GalaceanComposition | GalaceanComposition[]; + const baseOrder = this.baseCompositionIndex; + + if (isArray(scene)) { + this.baseCompositionIndex += scene.length; + composition = await Promise.all(scene.map(async (scn, index) => { + const res = await this.createComposition(scn, options); + + res.setIndex(baseOrder + index); + + return res; + })); + } else { + this.baseCompositionIndex += 1; + composition = await this.createComposition(scene, options); + composition.setIndex(baseOrder); + } + + this.ticker?.start(); + + this.entity.addChild(((composition as GalaceanComposition).renderer.engine as GalaceanEngine).entity); + + return composition; + } + + private async createComposition ( + url: SceneLoadType, + options: GalaceanSceneLoadOptions = {}, + ): Promise { + const engine = new GalaceanEngine( + this.gl, + this.engine, + { + entity: this.entity, + camera: this.camera, + }, + ); + + engine.priority = options.priority ?? 0; + engine.createEntity(); + + const renderer = new GalaceanRenderer(engine); + const last = performance.now(); + let opts = { + autoplay: true, + ...options, + }; + let source: SceneType; + + engine.renderer = renderer; + + if (isSceneURL(url)) { + source = url.url; + if (isSceneWithOptions(url)) { + opts = { + ...opts, + ...url.options, + }; + } + } else { + source = url; + } + + const assetManager = new AssetManager(opts); + + // TODO 多 json 之间目前不共用资源,如果后续需要多 json 共用,这边缓存机制需要额外处理 + // 在 assetManager.loadScene 前清除,避免 loadScene 创建的 EffectsObject 对象丢失 + engine.clearResources(); + this.assetManagers.push(assetManager); + const scene = await assetManager.loadScene(source, renderer, { env: this.env }); + + // 加入 json 资产数据 + engine.addPackageDatas(scene); + // 加入内置引擎对象 + for (const effectsObject of this.builtinObjects) { + engine.addInstance(effectsObject); + } + for (let i = 0; i < scene.textureOptions.length; i++) { + scene.textureOptions[i] = + scene.textureOptions[i] instanceof Texture + ? scene.textureOptions[i] + : engine.assetLoader.loadGUID(scene.textureOptions[i].id); + } + + if (engine.database) { + await engine.createVFXItems(scene); + } + + // 加载期间 player 销毁 + if (this.disposed) { + throw new Error('Disposed player can not used to create Composition.'); + } + const composition = new GalaceanComposition({ + ...opts, + renderer: renderer, + width: this.engine.canvas.width, + height: this.engine.canvas.height, + event: this.event, + handleItemMessage: (message: MessageItem) => { + this.emit('message', message); + }, + }, scene); + + // 中低端设备降帧到 30fps + if (this.ticker) { + if (opts.renderLevel === spec.RenderLevel.B) { + this.ticker.setFPS(Math.min(this.ticker.getFPS(), 30)); + } + } + + if (opts.autoplay) { + this.autoPlaying = true; + composition.play(); + } else { + composition.pause(); + } + + const firstFrameTime = performance.now() - last + composition.statistic.loadTime; + + composition.statistic.firstFrameTime = firstFrameTime; + logger.info(`first frame: [${composition.name}]${firstFrameTime.toFixed(4)}ms`); + + this.compositions.push(composition); + + return composition; + } + + private handleClick = (e: TouchEventType) => { + const { x, y } = e; + + this.compositions.forEach(composition => { + if (!composition || !composition.loaderData) { + return; + } + + const regions = composition?.hitTest(x, y); + + if (regions && regions.length) { + for (let i = 0; i < regions.length; i++) { + const behavior = regions[i].behavior || spec.InteractBehavior.NOTIFY; + + if (behavior === spec.InteractBehavior.NOTIFY) { + + this.emit('click', { + ...regions[i], + compositionId: composition.id, + compositionName: composition.name, + player: this, + }); + + composition.emit('click', { + ...regions[i], + compositionId: composition.id, + compositionName: composition.name, + }); + } else if (behavior === spec.InteractBehavior.RESUME_PLAYER) { + void this.resume(); + } + } + } + }); + }; + + /** + * 快进/快退指定时间间隔 + * @param composition - 要快进的合成 + * @param timeInSeconds - 需要快进/快退的时间长度(秒),可正可负 + */ + forwardCompositionTime (composition: Composition, timeInSeconds: number) { + if (timeInSeconds) { + composition?.update(timeInSeconds * 1000); + } + } + + /** + * 获取当前播放的所有合成(请不要修改返回的数组内容) + */ + getCompositions () { + return this.compositions; + } + + /** + * 异步加载动画资源 + * @param url - URL 或者通过 URL 请求的 JSONObject + * @param options - 加载可选参数 + * @since 1.0.0 + * @returns + */ + async loadAsset ( + url: string | JSONValue, + options: GalaceanSceneLoadOptions = {}, + ): Promise { + const assetManager = new AssetManager(options); + const scene = await assetManager.loadScene(url as SceneType); + + return scene; + } + + /** + * 播放器是否已暂停 + */ + get paused () { + return this.ticker?.getPaused(); + } + + /** + * 获取播放器是否可交互 + */ + get interactive () { + return this.event.enabled; + } + + /** + * 设置播放器是否可交互 + */ + set interactive (enable) { + this.event.enabled = enable; + } + + /** + * 跳转全部合成到指定时间后播放 + * @param time - 指定时间, 单位秒 + */ + gotoAndPlay (time: number) { + this.autoPlaying = true; + this.compositions.map(composition => { + composition.gotoAndPlay(time); + }); + if (this.ticker) { + this.ticker.start(); + } else { + this.tick(0); + } + } + + /** + * 跳转全部合成到指定时间并停留 + * @param time - 指定时间, 单位秒 + */ + gotoAndStop (time: number) { + this.autoPlaying = false; + this.compositions.map(composition => { + composition.gotoAndStop(time); + }); + if (!this.ticker || this.ticker?.getPaused()) { + this.tick(0); + } + this.emit('update', { + player: this, + playing: false, + }); + } + + /** + * 顺序播放一组还未开始播放的合成 + * @param compositions - 要播放的合成数组 + */ + playSequence (compositions: Composition[]): void { + for (let i = 0; i < compositions.length - 1; i++) { + compositions[i].on('end', () => { + compositions[i + 1].play(); + }); + } + compositions[0].play(); + this.ticker?.start(); + } + + /** + * 暂停播放器 + * @param options + * @param options.offloadTexture - 是否卸载贴图纹理,减少内存 + * @returns + */ + pause (options?: { offloadTexture?: boolean }) { + if (this.paused) { + return; + } + + this.ticker?.pause(); + this.emit('update', { + player: this, + playing: false, + }); + } + + /** + * 恢复播放器 + * > 如果暂停时卸载了纹理贴图,此函数将自动请求网络重新加载纹理 + * @returns + */ + async resume () { + if (this.resumePending) { + return; + } + if (this.paused) { + this.resumePending = true; + await Promise.all(this.compositions.map(c => c.reloadTexture())); + this.resumePending = false; + this.handleResume(); + } + this.ticker?.resume(); + } + + private handleResume = () => { + this.emit('update', { player: this, playing: true }); + }; + + /** + * 根据名称查找对应的合成(可能找不到,如果有同名的合成,默认返回第一个) + * @example + * ``` ts + * const composition = player.getCompositionByName('新建合成1'); + * ``` + * @param name - 目标合成名称 + */ + getCompositionByName (name: string) { + return this.compositions.find(comp => comp.name === name); + } + + /** + * 销毁 composition + */ + override onDestroy (): void { + this.pause(); + this.ticker?.stop(); + this.ticker = null; + this.event?.dispose(); + this.dispose(); + } + + /** + * 销毁当前播放的所有 Composition + */ + destroyCurrentCompositions () { + this.compositions.forEach(comp => comp.dispose()); + this.compositions.length = 0; + this.baseCompositionIndex = 0; + } + + /** + * Effects 的单独销毁方法 + * @param name - 指定的 `composition` 名称 + */ + dispose (name?: string) { + if (!name) { + this.pause(); + this.compositions.forEach(composition => { + if (composition) { + composition.dispose(); + composition.renderer.engine.dispose(); + } + }); + this.compositions = []; + } else { + let comps = this.compositions; + + comps.forEach(async (comp, i) => { + if (comp && comp.name === name) { + this.pause(); + comp.dispose(); + comp.renderer.engine.dispose(); + delete comps[i]; + + await this.resume(); + } + }); + comps = comps.filter(comp => comp); + this.compositions = comps; + } + } +} diff --git a/src/galacean-engine.ts b/src/galacean-engine.ts new file mode 100644 index 0000000..e20f126 --- /dev/null +++ b/src/galacean-engine.ts @@ -0,0 +1,99 @@ +import * as ENGINE from '@galacean/engine'; +import * as EFFECTS from '@galacean/effects-core'; + +type ScriptProps = { + entity: ENGINE.Entity, + camera?: ENGINE.Camera, +}; + +export class GalaceanEngine extends EFFECTS.Engine { + bufferArray: Set = new Set(); + geometryArray: Set = new Set(); + textureArray: Set = new Set(); + meshArray: Set = new Set(); + materialArray: Set = new Set(); + galaceanCamera?: ENGINE.Camera; + /** + * 用户设置的优先级 + */ + priority = 0; + /** + * 当前合成的最大优先级 + */ + maxPriority = 0; + /** + * 每个合成的根节点 + */ + entity: ENGINE.Entity; + + constructor ( + gl: WebGL2RenderingContext | WebGLRenderingContext, + public originalEngine: ENGINE.Engine, + private scriptProps: ScriptProps, + ) { + super(); + + this.gpuCapability = new EFFECTS.GPUCapability(gl); + this.galaceanCamera = scriptProps.camera; + } + + /** + * 创建根节点 + */ + createEntity () { + this.entity = new ENGINE.Entity(this.originalEngine); + this.scriptProps.entity.addChild(this.entity); + } + + /** + * 添加节点到合成根节点 + * @param entity - 节点对象 + */ + addEntity (entity: ENGINE.Entity) { + this.entity.addChild(entity); + + } + + clearAssets ( + resourceManager: ENGINE.ResourceManager, + asset: ENGINE.MeshRenderer | ENGINE.Texture2D | ENGINE.Buffer | ENGINE.BufferMesh | ENGINE.Shader | ENGINE.Material, + ) { + if (asset.destroy) { + asset.destroy(true); + } + + // @ts-expect-error + resourceManager._deleteAsset(asset); + // @ts-expect-error + resourceManager._deleteContentRestorer(asset); + // @ts-expect-error + resourceManager._deleteReferResource(asset); + // @ts-expect-error + resourceManager._deleteGraphicResource(asset); + } + + override dispose (): void { + const resourceManager = this.originalEngine.resourceManager; + + this.meshArray.forEach(mesh => { + this.clearAssets(resourceManager, mesh); + }); + this.meshArray.clear(); + this.geometryArray.forEach(geo => { + this.clearAssets(resourceManager, geo); + }); + this.geometryArray.clear(); + this.materialArray.forEach(mat => { + this.clearAssets(resourceManager, mat); + }); + this.materialArray.clear(); + this.textureArray.forEach(tex => { + this.clearAssets(resourceManager, tex); + }); + this.textureArray.clear(); + this.bufferArray.forEach(buffer => { + this.clearAssets(resourceManager, buffer); + }); + this.bufferArray.clear(); + } +} diff --git a/src/galacean-geometry.ts b/src/galacean-geometry.ts new file mode 100644 index 0000000..ca9399f --- /dev/null +++ b/src/galacean-geometry.ts @@ -0,0 +1,450 @@ +import * as ENGINE from '@galacean/engine'; +import type { Attribute, GeometryProps, SkinProps, spec } from '@galacean/effects-core'; +import { generateEmptyTypedArray, Geometry, glContext } from '@galacean/effects-core'; +import { GalaceanComposition } from './galacean-composition'; +import type { GalaceanEngine } from './galacean-engine'; + +/** + * Galacean 中 attribute info 接口 + */ +interface GalaceanAttributeWithType { + /** + * Galacean 中 attribute 对象 + */ + vertexElement: ENGINE.VertexElement, + /** + * 共享或单独的 buffer + */ + vertexBufferBinding: ENGINE.VertexBufferBinding, + bufferIndex: number, + /** + * CPU Buffer + */ + rawBuffer: spec.TypedArray, +} + +/** + * Galacean 中的 geometry 的抽象实现类 + */ +export class GalaceanGeometry extends Geometry { + /** + * geometry 对象 + */ + geometry: ENGINE.BufferMesh; + /** + * 记录顶点属性信息用于缓存 + */ + attributes: Record = {}; + elements: ENGINE.VertexElement[] = []; + indexRawArray?: spec.TypedArray; + indexBufferBinding?: ENGINE.IndexBufferBinding; + + /** + * geometry 绘制模式 + */ + readonly mode: GLenum; + + private destroyed = false; + private attributesName: string[] = []; + private bufferIndex = 0; + private readonly originalEngine: ENGINE.Engine; + + /** + * 构造函数 + * + * @param engine - Effects 引擎对象 + * @param props - Geometry 创建参数 + */ + constructor ( + public override engine: GalaceanEngine, + props?: GeometryProps, + ) { + if (!props) { + return; + } + + const { + drawStart = 0, drawCount, indices, mode, + } = props; + + super(engine); + this.originalEngine = engine.originalEngine; + this.mode = mode ?? glContext.TRIANGLES; + + const attributesName: string[] = []; + const attributes: Record = {}; + const geometry = new ENGINE.BufferMesh(this.originalEngine); + + engine.geometryArray.add(geometry); + + Object.keys(props.attributes).forEach(name => { + const attr = props.attributes[name]; + + if (!('dataSource' in attr)) { + this.setAttributeType(name, attr, geometry, attributes, props.maxVertex); + } else { + // 使用AttributeWithType构造的attribute + const { dataSource } = attr; + + if (dataSource) { + if (attributes[dataSource] === undefined) { + this.setAttributeType(dataSource, attr, geometry, attributes, props.maxVertex); + } + const { size, offset } = attr; + const dataSourceAttribute = attributes[dataSource]; + const vertexBufferBinding = dataSourceAttribute.vertexBufferBinding; + let format = ENGINE.VertexElementFormat.Vector3; + + switch (size) { + case 1: + format = ENGINE.VertexElementFormat.Float; + + break; + case 2: + format = ENGINE.VertexElementFormat.Vector2; + + break; + case 3: + format = ENGINE.VertexElementFormat.Vector3; + + break; + case 4: + format = ENGINE.VertexElementFormat.Vector4; + + break; + } + + const vertexElement = new ENGINE.VertexElement(name, (offset ?? 0), + format, dataSourceAttribute.vertexElement.bindingIndex); + + this.elements.push(vertexElement); + attributes[name] = { + vertexBufferBinding, + vertexElement, + rawBuffer: dataSourceAttribute.rawBuffer, + bufferIndex: dataSourceAttribute.bufferIndex, + }; + } + } + + attributesName.push(name); + }); + + if (indices && indices.data) { + const buffer = new ENGINE.Buffer(this.originalEngine, ENGINE.BufferBindFlag.IndexBuffer, indices.data, ENGINE.BufferUsage.Dynamic); + + this.engine.bufferArray.add(buffer); + const indexBufferBinding = new ENGINE.IndexBufferBinding(buffer, ENGINE.IndexFormat.UInt16); + + this.indexBufferBinding = indexBufferBinding; + this.indexRawArray = indices.data; + geometry.setIndexBufferBinding(indexBufferBinding); + } + + geometry.setVertexElements(this.elements); + geometry.addSubMesh(new ENGINE.SubMesh(drawStart, drawCount ?? 0)); + + this.geometry = geometry; + this.attributes = attributes; + this.attributesName = attributesName; + } + + /** + * 获取绘制数量 + */ + get drawCount (): number { + return this.geometry.subMesh!.count; + } + + /** + * 设置绘制数量 + */ + set drawCount (val: number) { + this.geometry.subMesh!.count = val; + + } + + /** + * 设置绘制起点 + */ + override setDrawStart (count: number): void { + this.drawStart = count; + } + + override getSkinProps (): SkinProps { + throw new Error('Method not implemented.'); + } + + /** + * 获取绘制起点 + */ + override getDrawStart (): number { + return this.drawStart; + } + + /** + * 获取绘制起点 + */ + get drawStart (): number { + return this.geometry.subMesh!.start; + } + + /** + * 设置绘制起点 + */ + set drawStart (val: number) { + this.geometry.subMesh!.start = val; + } + + /** + * 获取 attribute 数据 + * + * @param name - attribute 名称 + * @returns 返回 attribute 数据,如果为空返回 undefined + */ + getAttributeData (name: string): spec.TypedArray | undefined { + if (this.attributes[name] == undefined) { + return; + } + + return this.attributes[name].rawBuffer; + } + + /** + * 设置 attribute 数据 + * + * @param name - attribute 名称 + * @param data - attribute 数据 + * @returns + */ + setAttributeData (name: string, data: spec.TypedArray): void { + if (this.attributes[name] == undefined) { + return; + } + + const attribute = this.attributes[name]; + const buffer = new ENGINE.Buffer( + this.originalEngine, + ENGINE.BufferBindFlag.VertexBuffer, + data, + ENGINE.BufferUsage.Dynamic, + ); + + this.engine?.bufferArray.add(buffer); + const vertexBufferBinding = new ENGINE.VertexBufferBinding(buffer, attribute.vertexBufferBinding.stride); + + this.geometry.setVertexBufferBinding(vertexBufferBinding, attribute.bufferIndex); + attribute.vertexBufferBinding = vertexBufferBinding; + } + + /** + * 设置可变的 attribute 数据 + * + * @param name - attribute 名称 + * @param dataOffset - 数据偏移 + * @param data - 数据内容 + * @returns + */ + setAttributeSubData (name: string, dataOffset: number, data: spec.TypedArray): void { + if (this.attributes[name] == undefined) { + return; + } + + const attribute = this.attributes[name]; + + attribute.rawBuffer.set(data, dataOffset); + // hack + attribute.vertexBufferBinding.buffer.setData(attribute.rawBuffer, dataOffset * data.BYTES_PER_ELEMENT, dataOffset, data.length); + } + + /** + * 获取 attribute 数据步长 + * + * @param name - attribute名称 + * @returns 步长值 + */ + getAttributeStride (name: string): number { + const attribute = this.attributes[name]; + + return attribute.vertexBufferBinding.stride; + } + + /** + * 获取用到的所有 attribute 名称 + * @returns 名称数组 + */ + getAttributeNames (): string[] { + return this.attributesName; + } + + /** + * 获取 index attribute 数据 + * @returns 如果为空返回 undefined + */ + getIndexData (): spec.TypedArray | undefined { + return this.indexRawArray; + } + + /** + * 设置 index attribute 数据 + * + * @param data - index 数据 + */ + setIndexData (data?: spec.TypedArray): void { + if ( + data === undefined || + this.indexRawArray === undefined + ) { + return; + } + + if (data.length > this.indexRawArray.length) { + this.indexRawArray = data; + const buffer = new ENGINE.Buffer(this.originalEngine, ENGINE.BufferBindFlag.IndexBuffer, data); + + this.engine?.bufferArray.add(buffer); + this.indexBufferBinding = new ENGINE.IndexBufferBinding(buffer, ENGINE.IndexFormat.UInt16); + this.geometry.setIndexBufferBinding(this.indexBufferBinding); + } else { + this.indexRawArray.set(data); + this.indexBufferBinding?.buffer.setData(this.indexRawArray, 0); + } + } + + /** + * 设置偏移 index 数据 + * + * @param offset - 数据偏移量 + * @param data - 数据内容 + */ + setIndexSubData (offset: number, data: spec.TypedArray): void { + if ( + data === undefined || + this.indexRawArray === undefined + ) { + return; + } + + this.indexRawArray.set(data, offset); + this.indexBufferBinding?.buffer.setData(this.indexRawArray, 0); + } + + /** + * 设置绘制数量 + * + * @param count - 绘制数量 + */ + setDrawCount (count: number): void { + this.drawCount = count; + } + + /** + * 获取绘制数量 + * + * @returns + */ + getDrawCount (): number { + return this.drawCount; + } + + /** + * 销毁方法 + * + * @returns + */ + override dispose (): void { + if (this.destroyed) { + return; + } + + this.geometry.destroy(); + this.drawCount = 0; + + this.drawStart = 0; + this.attributes = {}; + this.attributesName = []; + this.attributes = {}; + this.attributesName = []; + this.bufferIndex = 0; + this.indexRawArray = undefined; + this.indexBufferBinding = undefined; + this.elements = []; + this.destroyed = true; + } + + private setAttributeType ( + name: string, + attr: Attribute, + geometry: ENGINE.BufferMesh, + attributes: Record, + maxCount?: number, + ) { + const { size, offset, type = glContext.FLOAT } = attr; + let { stride, data } = attr as spec.AttributeWithData; + + if (type && !data) { + data = generateEmptyTypedArray(type); + } + + if (!data) { + return; + } + if (name === 'aSprite') { + stride = 12; + } else { + stride = stride ?? 0; + } + + if (maxCount) { + const length = maxCount * stride + (GalaceanComposition.shape[name] ?? 0); + + // 如果传入了data且data.length不为0 使用传入的data 否则根据length新建数组 + if (data.length === 0) { + data = data instanceof Float32Array ? new Float32Array(length) : new Uint16Array(length); + } + } + + let format = ENGINE.VertexElementFormat.Vector3; + + switch (size) { + case 1: + format = ENGINE.VertexElementFormat.Float; + + break; + case 2: + format = ENGINE.VertexElementFormat.Vector2; + + break; + case 3: + format = ENGINE.VertexElementFormat.Vector3; + + break; + case 4: + format = ENGINE.VertexElementFormat.Vector4; + + break; + } + + const buffer = new ENGINE.Buffer( + this.originalEngine, + ENGINE.BufferBindFlag.VertexBuffer, + data, + ENGINE.BufferUsage.Stream, + ); + + this.engine?.bufferArray.add(buffer); + const vertexBufferBinding = new ENGINE.VertexBufferBinding(buffer, stride); + const vertexElement = new ENGINE.VertexElement(name, offset ?? 0, format, this.bufferIndex); + + this.elements.push(vertexElement); + attributes[name] = { + vertexElement, + vertexBufferBinding, + rawBuffer: data, + bufferIndex: this.bufferIndex, + }; + + geometry.setVertexBufferBinding(vertexBufferBinding, this.bufferIndex); + this.bufferIndex++; + } +} diff --git a/src/galacean-mesh.ts b/src/galacean-mesh.ts new file mode 100644 index 0000000..bb1439b --- /dev/null +++ b/src/galacean-mesh.ts @@ -0,0 +1,180 @@ +import * as ENGINE from '@galacean/engine'; +import type { + Geometry, Material, MaterialDestroyOptions, MeshDestroyOptions, GeometryMeshProps, + Sortable, Renderer, +} from '@galacean/effects-core'; +import { Mesh, DestroyOptions, math } from '@galacean/effects-core'; +import type { GalaceanMaterial } from './material'; +import type { GalaceanGeometry } from './galacean-geometry'; +import type { GalaceanEngine } from './galacean-engine'; +import type { GalaceanRenderer } from './galacean-renderer'; + +/** + * mesh 抽象类的 Galacean 实现 + */ +export class GalaceanMesh extends Mesh implements Sortable { + /** + * renderer 对象 + */ + galaceanMesh: ENGINE.MeshRenderer; + geometries: Geometry[]; + started: boolean = false; + + /** + * 构造函数 + * + * @param engine - Effects 引擎对象 + * @param props - mesh 创建参数 + */ + constructor ( + public galaceanEngine: GalaceanEngine, + props?: GeometryMeshProps, + ) { + const { material, geometry, priority = 0 } = props || {}; + const engine = galaceanEngine; + + super(engine, props); + + if (!geometry || !material) { return; } + + this.geometries = [geometry]; + this.material = material; + + const entity = new ENGINE.Entity(engine.originalEngine); + + this.galaceanMesh = entity.addComponent(ENGINE.MeshRenderer); + this.galaceanEngine.meshArray.add(this.galaceanMesh); + this.galaceanMesh.mesh = (geometry as GalaceanGeometry).geometry; + this.galaceanMesh.setMaterial((material as GalaceanMaterial).galaceanMaterial); + this.worldMatrix = entity.transform.worldMatrix as unknown as math.Matrix4; + this.priority = priority; + } + + override render (renderer: Renderer): void { + // 兼容 spine 逻辑 + if (!this.started) { + this.start(); + } + if (this.isDestroyed || !this.getVisible()) { + return; + } + + const { galaceanCamera } = this.engine as GalaceanEngine; + + if (galaceanCamera) { + const tempVPMat = new ENGINE.Matrix(); + + (this.material as GalaceanMaterial).matrices['effects_MatrixV'] = math.Matrix4.fromArray(galaceanCamera.viewMatrix.elements); + ENGINE.Matrix.multiply(galaceanCamera.projectionMatrix, galaceanCamera.viewMatrix, tempVPMat); + (this.material as GalaceanMaterial).matrices['effects_MatrixVP'] = math.Matrix4.fromArray(tempVPMat.elements); + (this.material as GalaceanMaterial).matrices['effects_MatrixInvV'] = math.Matrix4.fromArray(galaceanCamera.entity.transform.worldMatrix.elements); + + } else { + const effectsCamera = (renderer as GalaceanRenderer).effectsCamera; + + this.material.setMatrix('effects_MatrixV', effectsCamera.getViewMatrix()); + this.material.setMatrix('effects_MatrixVP', effectsCamera.getViewProjectionMatrix()); + this.material.setMatrix('effects_MatrixInvV', effectsCamera.getInverseViewMatrix()); + } + + const tempWorld = math.Matrix4.fromArray(this.worldMatrix.elements); + + const effectsObjectToWorld = this.material.getMatrix('effects_ObjectToWorld'); + + // 兼容 spine + if (this.name.includes('Spine') && effectsObjectToWorld) { + tempWorld.multiply(effectsObjectToWorld); + } + const originalM = new math.Matrix4().setFromArray(this.galaceanMesh.entity.transform.worldMatrix.elements); + + this.material.setMatrix('effects_ObjectToWorld', originalM.multiply(tempWorld)); + this.material.use(renderer, renderer.renderingData.currentFrame.globalUniforms); + } + + /** + * 设置 mesh 的渲染顺序 + * + * @param v - 顺序 index + */ + override set priority (v: number) { + if (this.galaceanMesh) { + // some particle is render error + this.galaceanMesh.priority = v + 2; + (this.engine as GalaceanEngine).maxPriority = Math.max(this.galaceanMesh.priority, (this.engine as GalaceanEngine).maxPriority); + + } + } + + /** + * 获取 mesh 的渲染顺序 + */ + override get priority () { + // miniprogram renderer sometime is undefined + return this.galaceanMesh?.priority ?? 0; + } + + /** + * 设置 mesh 可见性 + * + * @param val - 可见性开关 + */ + override setVisible (val: boolean): void { + this.galaceanMesh.enabled = val; + } + + /** + * 获取 mesh 的可见性 + * + * @returns + */ + override getVisible (): boolean { + return this.galaceanMesh.enabled; + } + + /** + * 设置 material + * + * @param material - material 对象 + * @param destroy - 销毁参数 + */ + override setMaterial ( + material: Material, + destroy?: MaterialDestroyOptions | DestroyOptions.keep, + ): void { + if (destroy !== DestroyOptions.keep) { + this.material.dispose(destroy); + } + this.material = material; + this.galaceanMesh.setMaterial((material as GalaceanMaterial).galaceanMaterial); + } + + override start (): void { + super.start(); + // spine error + this.started = true; + (this.engine as GalaceanEngine).addEntity(this.galaceanMesh.entity); + this.galaceanMesh.priority = this.priority / (this.engine as GalaceanEngine).maxPriority + (this.engine as GalaceanEngine).priority; + } + + /** + * 销毁方法 + * + * @param options - 销毁参数 + */ + override dispose (options?: MeshDestroyOptions): void { + if (this.destroyed) { + return; + } + + if (options?.geometries !== DestroyOptions.keep) { + this.geometries.forEach(geometry => geometry.dispose()); + } + const materialDestroyOption = options?.material; + + if (materialDestroyOption !== DestroyOptions.keep) { + this.material.dispose(materialDestroyOption); + } + this.destroyed = true; + this.galaceanMesh.destroy(); + } +} diff --git a/src/galacean-render-frame.ts b/src/galacean-render-frame.ts new file mode 100644 index 0000000..624dacd --- /dev/null +++ b/src/galacean-render-frame.ts @@ -0,0 +1,8 @@ +import type { RendererComponent } from '@galacean/effects-core'; +import { RenderFrame } from '@galacean/effects-core'; + +export class GalaceanRenderFrame extends RenderFrame { + override addMeshToDefaultRenderPass (mesh?: RendererComponent): void { + mesh?.render(this.renderer); + } +} diff --git a/src/galacean-renderer.ts b/src/galacean-renderer.ts new file mode 100644 index 0000000..3107641 --- /dev/null +++ b/src/galacean-renderer.ts @@ -0,0 +1,25 @@ +import type { Camera } from '@galacean/effects-core'; +import { Renderer } from '@galacean/effects-core'; +import type { GalaceanEngine } from './galacean-engine'; + +export class GalaceanRenderer extends Renderer { + // fix env is undefined + override env = ''; + effectsCamera: Camera; + + constructor (engine: GalaceanEngine) { + super(); + + this.engine = engine; + this.renderingData = { + currentFrame: { + // @ts-expect-error + globalUniforms: {}, + }, + }; + } + + setEffectsCamera (camera: Camera): void { + this.effectsCamera = camera; + } +} diff --git a/src/galacean-sprite-component.ts b/src/galacean-sprite-component.ts new file mode 100644 index 0000000..b1916ff --- /dev/null +++ b/src/galacean-sprite-component.ts @@ -0,0 +1,121 @@ +import * as ENGINE from '@galacean/engine'; +import type { Renderer, SpriteItemProps } from '@galacean/effects-core'; +import { SpriteComponent, effectsClass, math, spec } from '@galacean/effects-core'; +import type { GalaceanEngine } from './galacean-engine'; +import type { GalaceanGeometry } from './galacean-geometry'; +import type { GalaceanMaterial } from './material'; +import type { GalaceanRenderer } from './galacean-renderer'; + +@effectsClass(spec.DataType.SpriteComponent) +export class GalaceanSpriteComponent extends SpriteComponent { + galaceanMesh: ENGINE.MeshRenderer; + + constructor (engine: GalaceanEngine, props?: SpriteItemProps) { + super(engine, props); + } + + /** + * 设置 mesh 的渲染顺序 + * + * @param v - 顺序 index + */ + override set priority (v: number) { + if (this.galaceanMesh) { + this.galaceanMesh.priority = v; + (this.engine as GalaceanEngine).maxPriority = Math.max(this.galaceanMesh.priority, (this.engine as GalaceanEngine).maxPriority); + } + } + /** + * 获取 mesh 的渲染顺序 + */ + override get priority () { + return this.galaceanMesh.priority; + } + + override setVisible (visible: boolean): void { + if (this.galaceanMesh) { + this.galaceanMesh.enabled = visible; + } + } + override getVisible (): boolean { + return this.galaceanMesh.enabled; + } + + override start (): void { + super.start(); + if (this.galaceanMesh) { + (this.engine as GalaceanEngine).addEntity(this.galaceanMesh.entity); + this.galaceanMesh.priority = this.priority / (this.engine as GalaceanEngine).maxPriority + (this.engine as GalaceanEngine).priority; + } + } + + override get enabled (): boolean { + return this.galaceanMesh.enabled; + } + override set enabled (value: boolean) { + if (this.galaceanMesh) { + this.galaceanMesh.enabled = value; + } + } + + override render (renderer: Renderer): void { + if (!this.galaceanMesh || !this.isActiveAndEnabled) { return; } + + const engine = this.engine as GalaceanEngine; + const material = this.material as GalaceanMaterial; + const galaceanCamera = engine.galaceanCamera; + + material.setVector2('_Size', this.transform.size); + + if (galaceanCamera) { + const tempVPMat = new ENGINE.Matrix(); + + ENGINE.Matrix.multiply(galaceanCamera.projectionMatrix, galaceanCamera.viewMatrix, tempVPMat); + material.matrices['effects_MatrixVP'] = new math.Matrix4().setFromArray(tempVPMat.elements); + } else { + const effectsCamera = (renderer as GalaceanRenderer).effectsCamera; + + material.setMatrix('effects_MatrixVP', effectsCamera.getViewProjectionMatrix()); + } + + const tempWorld = new math.Matrix4().multiply(this.transform.getWorldMatrix()); + const originalM = new math.Matrix4().setFromArray(this.galaceanMesh.entity.transform.worldMatrix.elements); + + material.setMatrix('effects_ObjectToWorld', originalM.multiply(tempWorld)); + // material.setMatrix('effects_ObjectToWorld', this.transform.getWorldMatrix()); + material.use(renderer, renderer.renderingData.currentFrame.globalUniforms); + } + + /** + * 从数据中初始化 + * + * @param data - 数据 + */ + override fromData (data: SpriteItemProps): void { + super.fromData(data); + + if (this.galaceanMesh) { + return; + } + const engine = this.engine as GalaceanEngine; + const material = this.material as GalaceanMaterial; + const geometry = this.geometry as GalaceanGeometry; + const entity = new ENGINE.Entity(engine.originalEngine); + + this.galaceanMesh = entity.addComponent(ENGINE.MeshRenderer); + this.galaceanMesh.mesh = geometry.geometry; + + material.setMatrix('effects_ObjectToWorld', this.transform.getWorldMatrix()); + const mVP = this.item.composition?.camera.getViewProjectionMatrix() || new math.Matrix4(); + + material.setMatrix('effects_MatrixVP', mVP); + this.galaceanMesh.setMaterial(material.galaceanMaterial); + } + + override dispose (): void { + super.dispose(); + if (this.galaceanMesh) { + this.galaceanMesh.entity?.destroy(); + } + } +} diff --git a/src/galacean-text-component.ts b/src/galacean-text-component.ts new file mode 100644 index 0000000..9889519 --- /dev/null +++ b/src/galacean-text-component.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */ +import type { Engine, SpriteItemProps } from '@galacean/effects-core'; +import { effectsClass, spec, TextComponentBase, applyMixins, canvasPool } from '@galacean/effects-core'; +import { GalaceanSpriteComponent } from './galacean-sprite-component'; +import type { GalaceanEngine } from './galacean-engine'; + +export interface GalaceanTextComponent extends TextComponentBase { } + +/** + * @since 2.0.0 + * @internal + */ +@effectsClass(spec.DataType.TextComponent) +export class GalaceanTextComponent extends GalaceanSpriteComponent { + isDirty = true; + + constructor (engine: Engine, props?: spec.TextContent) { + super(engine as GalaceanEngine, props as unknown as SpriteItemProps); + + this.canvas = canvasPool.getCanvas(); + canvasPool.saveCanvas(this.canvas); + this.context = this.canvas.getContext('2d', { willReadFrequently: true }); + + if (!props) { + return; + } + + const { options } = props; + + this.updateWithOptions(options); + this.updateTexture(false); + } + + override update (dt: number): void { + super.update(dt); + this.updateTexture(false); + } + + override fromData (data: SpriteItemProps): void { + super.fromData(data); + const options = data.options as spec.TextContentOptions; + + this.updateWithOptions(options); + // Text + this.updateTexture(false); + } + + updateWithOptions (options: spec.TextContentOptions) { + // OVERRIDE by mixins + } + + updateTexture (flipY = true) { + // OVERRIDE by mixins + } +} + +applyMixins(GalaceanTextComponent, [TextComponentBase]); diff --git a/src/galacean-texture.ts b/src/galacean-texture.ts new file mode 100644 index 0000000..643144d --- /dev/null +++ b/src/galacean-texture.ts @@ -0,0 +1,217 @@ +import * as ENGINE from '@galacean/engine'; +import type { + Texture2DSourceOptionsData, Texture2DSourceOptionsImage, Texture2DSourceOptionsVideo, + TextureDataType, TextureSourceOptions, spec, +} from '@galacean/effects-core'; +import { glContext, Texture, TextureSourceType, throwDestroyedError } from '@galacean/effects-core'; +import type { GalaceanEngine } from './galacean-engine'; + +/** + * Galacean 抽象纹理类 + */ +export class GalaceanTexture extends Texture { + /** + * Engine 纹理对象 + */ + texture: ENGINE.Texture2D | null; + + video: HTMLVideoElement; + + /** + * 将 WebGL 纹理过滤器枚举类型映射到 Galacean 纹理过滤器枚举类型 + * @param filter - WebGL 纹理过滤器枚举类型 + * @returns Galacean 纹理过滤器枚举类型 + */ + static toGalaceanTextureFilter (filter?: GLenum): ENGINE.TextureFilterMode { + switch (filter) { + case glContext.LINEAR: + return ENGINE.TextureFilterMode.Bilinear; + default: + return ENGINE.TextureFilterMode.Point; + } + } + + /** + * 将 WebGL 纹理环绕方式枚举类型映射到 Galacean 纹理环绕方式枚举类型 + * @param wrap - WebGL 纹理环绕方式枚举类型 + * @returns Galacean 纹理环绕方式枚举类型 + */ + static toGalaceanTextureWrap (wrap?: GLenum): ENGINE.TextureWrapMode { + switch (wrap) { + case glContext.MIRRORED_REPEAT: + return ENGINE.TextureWrapMode.Mirror; + case glContext.REPEAT: + return ENGINE.TextureWrapMode.Repeat; + default: + return ENGINE.TextureWrapMode.Clamp; + } + } + + /** + * 构造函数 + * @param engine - Effects 引擎对象 + * @param data - 纹理数据 + * @param options - 纹理选项 + */ + constructor ( + public override engine: GalaceanEngine, + data?: TextureDataType, + options: TextureSourceOptions = {}, + ) { + super(engine); + + if (data) { + const { width = 1, height = 1 } = data; + + this.texture = this.createTextureByType({ + ...options as Texture2DSourceOptionsData, + sourceType: TextureSourceType.data, + data, + }); + this.width = width; + this.height = height; + } else { + this.texture = this.createTextureByType(options); + } + // 时序问题 + if (this.engine.textureArray) { + this.texture && this.engine.textureArray.add(this.texture); + } + } + + override fromData (data: spec.EffectComponentData) { + this.texture = this.createTextureByType(data as TextureSourceOptions); + this.texture && this.engine.textureArray.add(this.texture); + } + + /** + * 更新纹理数据 + * @param options - 纹理选项 + */ + override updateSource (options: TextureSourceOptions) { + this.texture?.destroy(true); + this.texture = this.createTextureByType(options); + } + + /** + * 开始更新视频数据 + * + */ + async startVideo () { + if (this.sourceType === TextureSourceType.video) { + if (!this.video.paused) { + await this.video.play(); + } + } + } + + /** + * 释放纹理占用的内存 + */ + override dispose () { + if (this.destroyed || !this.texture) { + return; + } + + this.width = 0; + this.height = 0; + this.destroyed = true; + this.initialize = throwDestroyedError; + + this.texture.destroy(); + } + + /** + * 组装纹理选项 + * @param options - 纹理选项 + * @returns 组装后的纹理选项 + */ + override assembleOptions (options: TextureSourceOptions): TextureSourceOptions { + const { target = glContext.TEXTURE_2D } = options; + + if (!options.sourceType) { + if ('image' in options) { + options.sourceType = TextureSourceType.image; + } else if ('data' in options) { + options.sourceType = TextureSourceType.data; + } else if ('video' in options) { + options.sourceType = TextureSourceType.video; + } else { + options.sourceType = TextureSourceType.none; // TextureSourceType.none + } + } + + // @ts-expect-error + return { + target, + ...options, + minFilter: GalaceanTexture.toGalaceanTextureFilter(options.minFilter), + magFilter: GalaceanTexture.toGalaceanTextureFilter(options.magFilter), + wrapS: GalaceanTexture.toGalaceanTextureWrap(options.wrapS), + wrapT: GalaceanTexture.toGalaceanTextureWrap(options.wrapT), + }; + } + + private createTextureByType (options: TextureSourceOptions): ENGINE.Texture2D | null { + const assembleOptions = this.assembleOptions(options); + const { flipY, wrapS, wrapT, magFilter, sourceType } = assembleOptions; + const engine = this.engine.originalEngine; + + // 时序问题 + if (!engine) { + return null; + } + + let texture: ENGINE.Texture2D | undefined = undefined; + // todo map + const galaceanTextureFormat = ENGINE.TextureFormat.R8G8B8A8; + + this.sourceType = sourceType; + + if (sourceType === TextureSourceType.data) { + const { data } = options as Texture2DSourceOptionsData; + + texture = new ENGINE.Texture2D(engine, data.width, data.height, galaceanTextureFormat, false); + texture.setPixelBuffer(data.data); + texture.wrapModeU = wrapS || ENGINE.TextureWrapMode.Clamp; + texture.wrapModeV = wrapT || ENGINE.TextureWrapMode.Clamp; + texture.filterMode = magFilter || ENGINE.TextureFilterMode.Bilinear; + this.width = data.width; + this.height = data.height; + } else if (sourceType === TextureSourceType.image) { + const { image } = options as Texture2DSourceOptionsImage; + + texture = new ENGINE.Texture2D(engine, image.width, image.height, galaceanTextureFormat, false); + texture.setImageSource(image, 0, flipY); + texture.wrapModeU = wrapS || ENGINE.TextureWrapMode.Clamp; + texture.wrapModeV = wrapT || ENGINE.TextureWrapMode.Clamp; + texture.filterMode = magFilter || ENGINE.TextureFilterMode.Bilinear; + this.width = image.width; + this.height = image.height; + } else if (sourceType === TextureSourceType.none) { + const pixel = new Uint8Array(4).fill(255); + + texture = new ENGINE.Texture2D(engine, 1, 1, ENGINE.TextureFormat.R8G8B8A8, true); + texture.setPixelBuffer(pixel); + texture.wrapModeU = ENGINE.TextureWrapMode.Repeat; + texture.wrapModeV = ENGINE.TextureWrapMode.Repeat; + this.width = this.height = 1; + } else if (sourceType === TextureSourceType.video) { + const { video } = options as Texture2DSourceOptionsVideo; + + this.video = video; + + texture = new ENGINE.Texture2D(engine, 1000, 1000, ENGINE.TextureFormat.R8G8B8A8, false); + texture.setImageSource(video); + texture.wrapModeU = ENGINE.TextureWrapMode.Repeat; + texture.wrapModeV = ENGINE.TextureWrapMode.Repeat; + } + + if (texture) { + texture.name = this.name; + + return texture; + } + throw new Error('Create a texture using an unknown data type.'); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..37f94ef --- /dev/null +++ b/src/index.ts @@ -0,0 +1,76 @@ +import type * as EFFECTS from '@galacean/effects-core'; +import type { + GeometryMeshProps, GeometryProps, MaterialProps, TextureDataType, TextureSourceOptions, +} from '@galacean/effects-core'; +import { Texture, Geometry, Material, Mesh } from '@galacean/effects-core'; +import { GalaceanTexture } from './galacean-texture'; +import { GalaceanMaterial } from './material'; +import { GalaceanGeometry } from './galacean-geometry'; +import { GalaceanMesh } from './galacean-mesh'; +import type { GalaceanEngine } from './galacean-engine'; + +export * from './galacean-sprite-component'; +export * from './galacean-text-component'; +export * from '@galacean/effects-core'; + +export * from './galacean-display-component'; +export * from './galacean-texture'; +export * from './material'; +export * from './galacean-composition'; +export * from './engine-instance'; + +/** + * 图片的创建方法 + * + * @param options - 图片创建参数 + * @returns Galacean 中的抽象图片对象 + */ +Texture.create = (engine: EFFECTS.Engine, options?: TextureSourceOptions) => { + return new GalaceanTexture(engine as GalaceanEngine, undefined, options) as Texture; +}; + +/** + * 通过数据创建图片对象 + * + * @param data - 图片数据 + * @param options - 图片创建参数 + * @returns Galacean 中的抽象图片对象 + */ +Texture.createWithData = ( + engine: EFFECTS.Engine, + data?: TextureDataType, + options?: Record, +) => { + return new GalaceanTexture(engine as GalaceanEngine, data, options) as Texture; +}; + +/** + * 材质球创建方法 + * + * @param props - 材质球创建参数 + * @returns Galacean 中的抽象材质球对象 + */ +Material.create = (engine: EFFECTS.Engine, props?: MaterialProps) => { + return new GalaceanMaterial(engine as GalaceanEngine, props); +}; + +/** + * geometry 创建方法 + * + * @param options - geometry 创建参数 + * @returns THREE 中的抽象 geometry 对象 + */ +Geometry.create = (engine: EFFECTS.Engine, options?: GeometryProps) => { + return new GalaceanGeometry(engine as GalaceanEngine, options); +}; + +/** + * mesh 创建方法 + * + * @param props - mesh 创建参数 + * @returns THREE 中的抽象 mesh 对象 + */ +Mesh.create = (engine: EFFECTS.Engine, props?: GeometryMeshProps) => { + return new GalaceanMesh(engine as GalaceanEngine, props); +}; + diff --git a/src/material/galacean-material-util.ts b/src/material/galacean-material-util.ts new file mode 100644 index 0000000..5e66608 --- /dev/null +++ b/src/material/galacean-material-util.ts @@ -0,0 +1,71 @@ +import * as ENGINE from '@galacean/engine'; +import { glContext } from '@galacean/effects-core'; + +/** + * WebGL 中和 blend 相关参数到 Galacean 的常量映射表 + */ +export const CONSTANT_MAP_BLEND: Record = { + [glContext.ONE]: ENGINE.BlendFactor.One, + [glContext.ZERO]: ENGINE.BlendFactor.Zero, + [glContext.SRC_COLOR]: ENGINE.BlendFactor.SourceColor, + [glContext.SRC_ALPHA]: ENGINE.BlendFactor.SourceAlpha, + [glContext.ONE_MINUS_SRC_COLOR]: ENGINE.BlendFactor.OneMinusSourceColor, + [glContext.ONE_MINUS_SRC_ALPHA]: ENGINE.BlendFactor.OneMinusSourceAlpha, + [glContext.DST_COLOR]: ENGINE.BlendFactor.DestinationColor, + [glContext.DST_ALPHA]: ENGINE.BlendFactor.DestinationAlpha, + [glContext.ONE_MINUS_DST_COLOR]: ENGINE.BlendFactor.OneMinusDestinationColor, + [glContext.ONE_MINUS_DST_ALPHA]: ENGINE.BlendFactor.OneMinusDestinationAlpha, +}; + +/** + * WebGL 中和 blend 相关参数到 Galacean 的常量映射表 + */ +export const CONSTANT_MAP_BLEND_OPERARION: Record = { + [glContext.FUNC_ADD]: ENGINE.BlendOperation.Add, + [glContext.MAX]: ENGINE.BlendOperation.Max, + [glContext.MIN]: ENGINE.BlendOperation.Min, + [glContext.FUNC_SUBTRACT]: ENGINE.BlendOperation.Subtract, + [glContext.FUNC_REVERSE_SUBTRACT]: ENGINE.BlendOperation.ReverseSubtract, +}; + +/** + * WebGL 中和 stencil 相关参数到 Galacean 的常量映射表 + */ +export const CONSTANT_MAP_STENCIL_FUNC: Record = { + [glContext.NEVER]: ENGINE.CompareFunction.Never, + [glContext.EQUAL]: ENGINE.CompareFunction.Equal, + [glContext.LESS]: ENGINE.CompareFunction.Less, + [glContext.LEQUAL]: ENGINE.CompareFunction.LessEqual, + [glContext.ALWAYS]: ENGINE.CompareFunction.Always, + [glContext.NOTEQUAL]: ENGINE.CompareFunction.NotEqual, + [glContext.GREATER]: ENGINE.CompareFunction.Greater, + [glContext.GEQUAL]: ENGINE.CompareFunction.GreaterEqual, +}; + +/** + * WebGL 中和 stencil 相关测试结果参数到 Galacean 的常量映射表 + */ +export const CONSTANT_MAP_STENCIL_OP: Record = { + [glContext.KEEP]: ENGINE.StencilOperation.Keep, + [glContext.ZERO]: ENGINE.StencilOperation.Zero, + [glContext.REPLACE]: ENGINE.StencilOperation.Replace, + [glContext.INCR]: ENGINE.StencilOperation.IncrementSaturate, + [glContext.DECR]: ENGINE.StencilOperation.DecrementSaturate, + [glContext.INCR_WRAP]: ENGINE.StencilOperation.IncrementWrap, + [glContext.DECR_WRAP]: ENGINE.StencilOperation.DecrementWrap, + [glContext.INVERT]: ENGINE.StencilOperation.Invert, +}; + +/** + * WebGL 中和 depth 相关参数到 Galacean 的常量映射表 + */ +export const CONSTANT_MAP_DEPTH: Record = { + [glContext.NEVER]: ENGINE.CompareFunction.Never, + [glContext.ALWAYS]: ENGINE.CompareFunction.Always, + [glContext.EQUAL]: ENGINE.CompareFunction.Equal, + [glContext.LESS]: ENGINE.CompareFunction.Less, + [glContext.LEQUAL]: ENGINE.CompareFunction.LessEqual, + [glContext.GREATER]: ENGINE.CompareFunction.Greater, + [glContext.GEQUAL]: ENGINE.CompareFunction.GreaterEqual, + [glContext.NOTEQUAL]: ENGINE.CompareFunction.NotEqual, +}; diff --git a/src/material/galacean-material.ts b/src/material/galacean-material.ts new file mode 100644 index 0000000..b4b879a --- /dev/null +++ b/src/material/galacean-material.ts @@ -0,0 +1,729 @@ +import * as ENGINE from '@galacean/engine'; +import type { + MaterialProps, Texture, MaterialDestroyOptions, UndefinedAble, GlobalUniforms, Renderer, Engine, +} from '@galacean/effects-core'; +import { + ShaderType, ShaderFactory, math, DestroyOptions, Material, spec, throwDestroyedError, + Shader, generateGUID, +} from '@galacean/effects-core'; +import { + CONSTANT_MAP_BLEND_OPERARION, CONSTANT_MAP_STENCIL_FUNC, CONSTANT_MAP_STENCIL_OP, + CONSTANT_MAP_DEPTH, CONSTANT_MAP_BLEND, +} from './galacean-material-util'; +import type { GalaceanTexture } from '../galacean-texture'; +import type { GalaceanEngine } from '../galacean-engine'; + +/** + * Galacean 抽象材质类 + */ +export class GalaceanMaterial extends Material { + + static UUID = 0; + + /** + * 储存浮点数类型的 uniform 值 + */ + floats: Record = {}; + + /** + * 储存整型数类型的 uniform 值 + */ + ints: Record = {}; + + /** + * 储存二维向量类型的 uniform 值 + */ + vector2s: Record = {}; + + /** + * 储存三维向量类型的 uniform 值 + */ + vector3s: Record = {}; + + /** + * 储存四维向量类型的 uniform 值 + */ + vector4s: Record = {}; + + /** + * 储存 4x4 矩阵类型的 uniform 值 + */ + matrices: Record = {}; + + /** + * 储存 4x4 矩阵类型的 uniform 值 + */ + matrice3s: Record = {}; + + /** + * 储存纹理类型的 uniform 值 + */ + textures: Record = {}; + + /** + * 储存浮点数数组类型的 uniform 值 + */ + floatArrays: Record = {}; + + /** + * 储存四维向量数组类型的 uniform 值 + */ + vector4Arrays: Record = {}; + + /** + * 储存 4x4 矩阵数组类型的 uniform 值 + */ + matrixArrays: Record = {}; + + /** + * Galacean 原始着色器材质对象 + */ + galaceanMaterial: ENGINE.Material; + + private colors: Record = {}; + private quaternions: Record = {}; + + private readonly macros: Record = {}; + private readonly originalEngine: ENGINE.Engine; + + /** + * 构造函数 + * + * @param engine - Effects 引擎对象 + * @param props - 材质属性 + */ + constructor ( + engine: GalaceanEngine, + props?: MaterialProps, + ) { + super(engine as unknown as Engine, props); + + if (!props) { return; } + + const shader = props?.shader; + + this.shader = new Shader(engine as unknown as Engine); + this.shader.shaderData = { + ...shader, + id: generateGUID(), + dataType: spec.DataType.Shader, + vertex: shader?.vertex ?? '', + fragment: shader?.fragment ?? '', + }; + const { level } = this.engine.gpuCapability; + const vertexShaderSource = ShaderFactory.genFinalShaderCode({ + level, + shaderType: ShaderType.vertex, + shader: shader?.vertex ?? '', + macros: shader?.macros, + removeVersion: true, + }); + const fragmentShaderSource = ShaderFactory.genFinalShaderCode( + { + level, + shaderType: ShaderType.fragment, + shader: shader?.fragment ?? '', + macros: shader?.macros, + removeVersion: true, + } + ); + + this.originalEngine = engine.originalEngine; + this.galaceanMaterial = new ENGINE.Material( + this.originalEngine, + ENGINE.Shader.create(this.name, vertexShaderSource, fragmentShaderSource), + ); + this.galaceanMaterial.renderState.renderQueueType = ENGINE.RenderQueueType.Transparent; + this.galaceanMaterial.name = 'ge_' + this.name; + this.setMatrix('effects_ObjectToWorld', new math.Matrix4()); + this.setMatrix('effects_MatrixVP', new math.Matrix4()); + this.setMatrix('effects_MatrixInvV', new math.Matrix4()); + this.setMatrix('effects_MatrixV', new math.Matrix4()); + + engine.materialArray.add(this.galaceanMaterial); + } + + override enableMacro (keyword: string, value?: number | boolean): void { + if (!this.isMacroEnabled(keyword) || this.macros[keyword] !== value) { + this.macros[keyword] = value ?? true; + } + } + override disableMacro (keyword: string): void { + if (this.isMacroEnabled(keyword)) { + delete this.macros[keyword]; + } + } + override isMacroEnabled (keyword: string): boolean { + return this.macros[keyword] !== undefined; + } + + /** + * 获取混合模式 + */ + override get blending (): boolean { + return this.galaceanMaterial.renderState.blendState.targetBlendState.enabled; + } + override set blending (blending: UndefinedAble) { + this.galaceanMaterial.renderState.blendState.targetBlendState.enabled = !!blending; + } + + /** + * 获取混合函数 + */ + override get blendFunction () { + const { + sourceColorBlendFactor, destinationColorBlendFactor, + sourceAlphaBlendFactor, destinationAlphaBlendFactor, + } = this.galaceanMaterial.renderState.blendState.targetBlendState; + + return [ + sourceColorBlendFactor, + destinationColorBlendFactor, + sourceAlphaBlendFactor || sourceColorBlendFactor, + destinationAlphaBlendFactor || destinationColorBlendFactor, + ]; + } + override set blendFunction ( + func: UndefinedAble<[blendSrc: number, blendDst: number, blendSrcAlpha: number, blendDstAlpha: number]>, + ) { + if (!func) { + return; + } + + const [blendSrc, blendDst, blendSrcAlpha, blendDstAlpha] = func; + + this.galaceanMaterial.renderState.blendState.targetBlendState.sourceColorBlendFactor = CONSTANT_MAP_BLEND[blendSrc]; + this.galaceanMaterial.renderState.blendState.targetBlendState.destinationColorBlendFactor = CONSTANT_MAP_BLEND[blendDst]; + this.galaceanMaterial.renderState.blendState.targetBlendState.sourceAlphaBlendFactor = CONSTANT_MAP_BLEND[blendSrcAlpha]; + this.galaceanMaterial.renderState.blendState.targetBlendState.destinationAlphaBlendFactor = CONSTANT_MAP_BLEND[blendDstAlpha]; + } + + /** + * 获取混合方程式 + */ + override get blendEquation () { + const { + colorBlendOperation, + alphaBlendOperation, + } = this.galaceanMaterial.renderState.blendState.targetBlendState; + + return [colorBlendOperation, alphaBlendOperation || colorBlendOperation]; + } + override set blendEquation (equation: UndefinedAble<[rgb: number, alpha: number]>) { + if (equation) { + const [rgb, alpha] = equation; + + this.galaceanMaterial.renderState.blendState.targetBlendState.colorBlendOperation = CONSTANT_MAP_BLEND_OPERARION[rgb]; + this.galaceanMaterial.renderState.blendState.targetBlendState.alphaBlendOperation = CONSTANT_MAP_BLEND_OPERARION[alpha]; + } + } + + /** + * 获取深度测试结果 + */ + override get depthTest (): boolean { + return this.galaceanMaterial.renderState.depthState.enabled; + } + override set depthTest (value: UndefinedAble) { + this.galaceanMaterial.renderState.depthState.enabled = !!value; + } + + /** + * 获取深度缓冲区结果 + */ + override get depthMask (): boolean { + return this.galaceanMaterial.renderState.depthState.writeEnabled; + } + override set depthMask (value: UndefinedAble) { + this.galaceanMaterial.renderState.depthState.writeEnabled = !!value; + } + + /** + * 获取深度函数 + */ + override get depthFunc () { + return this.galaceanMaterial.renderState.depthState.compareFunction; + } + override set depthFunc (value: UndefinedAble) { + if (value !== undefined) { + this.galaceanMaterial.renderState.depthState.compareFunction = CONSTANT_MAP_DEPTH[value]; + } + } + + /** + * 获取多边形偏移开关 + */ + override get polygonOffsetFill (): boolean { + return true; + } + override set polygonOffsetFill (value: UndefinedAble) { + } + + /** + * 获取多边形偏移 + */ + override get polygonOffset () { + return [ + this.galaceanMaterial.renderState.rasterState.slopeScaledDepthBias, + this.galaceanMaterial.renderState.rasterState.depthBias, + ]; + } + override set polygonOffset (value: UndefinedAble<[number, number]>) { + if (value) { + const [factor, units] = value; + + this.galaceanMaterial.renderState.rasterState.slopeScaledDepthBias = factor; + this.galaceanMaterial.renderState.rasterState.depthBias = units; + } + } + + /** + * 获取 alpha 抖动 + */ + override get sampleAlphaToCoverage (): boolean { + return this.galaceanMaterial.renderState.blendState.alphaToCoverage; + } + override set sampleAlphaToCoverage (value: UndefinedAble) { + this.galaceanMaterial.renderState.blendState.alphaToCoverage = !!value; + } + + /** + * 获取模板测试开关 + */ + override get stencilTest () { + return this.galaceanMaterial.renderState.stencilState.enabled; + } + override set stencilTest (value: UndefinedAble) { + this.galaceanMaterial.renderState.stencilState.enabled = !!value; + } + + /** + * 获取模板缓冲区 + */ + override get stencilMask () { + return [ + this.galaceanMaterial.renderState.stencilState.writeMask, + this.galaceanMaterial.renderState.stencilState.writeMask, + ]; + } + override set stencilMask (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.writeMask = value[0]; + } + } + + /** + * 获取模板测试参考值 + */ + override get stencilRef () { + return [ + this.galaceanMaterial.renderState.stencilState.referenceValue, + this.galaceanMaterial.renderState.stencilState.referenceValue, + ]; + } + override set stencilRef (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.referenceValue = value[0]; + } + } + + /** + * 获取模版函数 + */ + override get stencilFunc () { + return [ + this.galaceanMaterial.renderState.stencilState.compareFunctionFront, + this.galaceanMaterial.renderState.stencilState.compareFunctionBack, + ]; + } + override set stencilFunc (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.compareFunctionFront = CONSTANT_MAP_STENCIL_FUNC[value[0]]; + this.galaceanMaterial.renderState.stencilState.compareFunctionBack = CONSTANT_MAP_STENCIL_FUNC[value[1]]; + } + } + + /** + * 获取模板测试失败后参数 + */ + override get stencilOpFail () { + return [ + this.galaceanMaterial.renderState.stencilState.failOperationFront, + this.galaceanMaterial.renderState.stencilState.failOperationBack, + ]; + } + override set stencilOpFail (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.failOperationFront = CONSTANT_MAP_STENCIL_OP[value[0]]; + this.galaceanMaterial.renderState.stencilState.failOperationBack = CONSTANT_MAP_STENCIL_OP[value[0]]; + } + } + + /** + * 获取模版测试通过深度测试失败后参数 + */ + override get stencilOpZFail () { + return [ + this.galaceanMaterial.renderState.stencilState.zFailOperationFront, + this.galaceanMaterial.renderState.stencilState.zFailOperationBack, + ]; + } + override set stencilOpZFail (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.zFailOperationFront = CONSTANT_MAP_STENCIL_OP[value[0]]; + this.galaceanMaterial.renderState.stencilState.zFailOperationBack = CONSTANT_MAP_STENCIL_OP[value[1]]; + } + } + + /** + * 获取模版测试通过并设置深度值参数 + */ + override get stencilOpZPass () { + return [ + this.galaceanMaterial.renderState.stencilState.passOperationFront, + this.galaceanMaterial.renderState.stencilState.passOperationBack, + ]; + } + override set stencilOpZPass (value: UndefinedAble<[number, number]>) { + if (value) { + this.galaceanMaterial.renderState.stencilState.passOperationFront = CONSTANT_MAP_STENCIL_OP[value[0]]; + this.galaceanMaterial.renderState.stencilState.passOperationBack = CONSTANT_MAP_STENCIL_OP[value[0]]; + } + } + + /** + * 获取剔除开关 + */ + override get culling () { + return this.galaceanMaterial.renderState.rasterState.cullMode !== ENGINE.CullMode.Off; + } + override set culling (value: UndefinedAble) { + this.galaceanMaterial.renderState.rasterState.cullMode = value ? ENGINE.CullMode.Front : ENGINE.CullMode.Off; + } + + /** + * 获取剔除面 + */ + override get cullFace () { + return this.galaceanMaterial.renderState.rasterState.cullMode; + } + override set cullFace (value: UndefinedAble) { + if (value === spec.SideMode.FRONT) { + this.galaceanMaterial.renderState.rasterState.cullMode = ENGINE.CullMode.Back; + } else if (value === spec.SideMode.BACK) { + this.galaceanMaterial.renderState.rasterState.cullMode = ENGINE.CullMode.Front; + } else { + this.galaceanMaterial.renderState.rasterState.cullMode = ENGINE.CullMode.Off; + } + } + + override cloneUniforms (sourceMaterial: Material): void { + //TODO:暂时不实现 + } + + getTexture (name: string): Texture | null { + return this.textures[name]; + } + setTexture (name: string, texture: Texture): void { + if (this.destroyed) { return; } + + const { texture: engineTexture } = texture as GalaceanTexture; + + engineTexture && this.galaceanMaterial.shaderData.setTexture(name, engineTexture); + this.textures[name] = texture; + } + + getVector4Array (name: string): number[] { + if (this.galaceanMaterial && !this.destroyed) { + return Array.from(this.galaceanMaterial.shaderData.getFloatArray(name)); + } else { + return []; + } + } + setVector4Array (name: string, array: math.Vector4[] | number[]): void { + if (this.destroyed) { return; } + + const value: number[] = []; + + for (const v of array) { + // 兼容 number[] + if (v instanceof math.Vector4) { + value.push(v.x, v.y, v.z, v.w); + } else { + value.push(v); + } + } + this.galaceanMaterial.shaderData.setFloatArray(name, new Float32Array(value)); + this.vector4Arrays[name] = value; + } + + override use (render: Renderer, globalUniforms: GlobalUniforms): void { + let name: string; + + // 检查贴图数据是否初始化。 + for (name in this.textures) { + this.textures[name].initialize(); + } + for (name in this.floats) { + this.setFloat(name, this.floats[name]); + } + for (name in this.ints) { + this.setInt(name, this.ints[name]); + } + for (name in this.floatArrays) { + this.setFloats(name, this.floatArrays[name]); + } + for (name in this.textures) { + this.setTexture(name, this.textures[name]); + } + for (name in this.vector2s) { + this.setVector2(name, this.vector2s[name]); + } + for (name in this.vector3s) { + this.setVector3(name, this.vector3s[name]); + } + for (name in this.vector4s) { + this.setVector4(name, this.vector4s[name]); + } + for (name in this.colors) { + this.setColor(name, this.colors[name]); + } + for (name in this.quaternions) { + this.setQuaternion(name, this.quaternions[name]); + } + for (name in this.matrices) { + this.setMatrix(name, this.matrices[name]); + } + for (name in this.matrice3s) { + this.setMatrix3(name, this.matrice3s[name]); + } + for (name in this.vector4Arrays) { + this.setVector4Array(name, this.vector4Arrays[name]); + } + for (name in this.matrixArrays) { + // @ts-expect-error + this.setMatrixArray(name, this.matrixArrays[name]); + } + } + checkUniform (name: string) { + throw new Error('Method not implemented.'); + } + + getMatrixArray (name: string): number[] | null { + if (this.galaceanMaterial && !this.destroyed) { + return Array.from(this.galaceanMaterial.shaderData.getFloatArray(name)); + } else { + return []; + } + } + setMatrixArray (name: string, array: math.Matrix4[]): void { + if (this.destroyed) { return; } + + const value: number[] = []; + + for (const { elements } of array) { + value.push( + elements[0], + elements[1], + elements[2], + elements[3], + elements[4], + elements[5], + elements[6], + elements[7], + elements[8], + elements[9], + elements[10], + elements[11], + elements[12], + elements[13], + elements[14], + elements[15], + ); + } + this.galaceanMaterial.shaderData.setFloatArray(name, new Float32Array(value)); + this.matrixArrays[name] = value; + } + + getMatrix (name: string): math.Matrix4 | null { + return this.matrices[name]; + } + setMatrix (name: string, value: math.Matrix4): void { + if (this.destroyed) { return; } + + const mat = new ENGINE.Matrix().copyFrom(value as unknown as ENGINE.Matrix); + + this.galaceanMaterial.shaderData.setMatrix(name, mat); + this.matrices[name] = value; + } + + override setMatrix3 (name: string, value: math.Matrix3): void { + if (this.destroyed) { return; } + + const array = value.toArray(); + + this.galaceanMaterial.shaderData.setFloatArray(name, new Float32Array(array)); + this.matrixArrays[name] = array; + } + + override setMatrixNumberArray (name: string, array: number[]): void { + if (this.destroyed) { return; } + const value: number[] = []; + + for (const v of array) { + for (let i = 0; i < 16; i++) { + value.push(v); + } + } + this.galaceanMaterial.shaderData.setFloatArray(name, new Float32Array(value)); + this.matrixArrays[name] = value; + } + + getVector2 (name: string): math.Vector2 | null { + return this.vector2s[name]; + } + setVector2 (name: string, value: math.Vector2): void { + if (this.destroyed) { return; } + const vec = new ENGINE.Vector2(); + + vec.x = value.x; + vec.y = value.y; + + this.galaceanMaterial.shaderData.setVector2(name, vec); + this.vector2s[name] = value; + } + + getVector3 (name: string): math.Vector3 { + return this.vector3s[name]; + } + setVector3 (name: string, value: math.Vector3): void { + if (this.destroyed) { return; } + const vec = new ENGINE.Vector3(); + + vec.x = value.x; + vec.y = value.y; + vec.z = value.z; + + this.galaceanMaterial.shaderData.setVector3(name, vec); + this.vector3s[name] = value; + } + + getVector4 (name: string): math.Vector4 | null { + return this.vector4s[name]; + } + setVector4 (name: string, value: math.Vector4): void { + if (this.destroyed) { return; } + const vec = new ENGINE.Vector4(); + + vec.x = value.x; + vec.y = value.y; + vec.z = value.z; + vec.w = value.w; + + this.galaceanMaterial.shaderData.setVector4(name, vec); + this.vector4s[name] = value; + } + + getFloat (name: string): number | null { + return this.floats[name]; + } + setFloat (name: string, value: number): void { + if (this.destroyed) { return; } + + this.galaceanMaterial.shaderData.setFloat(name, value); + this.floats[name] = value; + } + + getFloats (name: string): number[] | null { + return this.floatArrays[name]; + } + setFloats (name: string, value: number[]): void { + if (this.destroyed) { return; } + + this.galaceanMaterial.shaderData.setFloatArray(name, new Float32Array(value)); + this.floatArrays[name] = value; + } + + getInt (name: string): number | null { + return this.ints[name]; + } + setInt (name: string, value: number): void { + if (this.destroyed) { return; } + this.galaceanMaterial.shaderData.setInt(name, value); + this.ints[name] = value; + } + + hasUniform (name: string): boolean { + const shaderData = this.galaceanMaterial.shaderData; + + return !!( + shaderData.getTexture(name) || + shaderData.getFloat(name) || + shaderData.getInt(name) || + shaderData.getVector2(name) || + shaderData.getVector3(name) || + shaderData.getVector4(name) || + shaderData.getMatrix(name) || + shaderData.getFloatArray(name) || + shaderData.getIntArray(name) + ); + } + + disableKeyword (keyword: string): void { + throw new Error('Method not implemented.'); + } + isKeywordEnabled (keyword: string): boolean { + throw new Error('Method not implemented.'); + } + + override clone (props?: MaterialProps | undefined): Material { + throw new Error('Method not implemented.'); + } + + private clear () { + // @ts-expect-error + this.uniformSemantics = {}; + this.floats = {}; + this.ints = {}; + this.vector2s = {}; + this.vector3s = {}; + this.vector4s = {}; + this.matrices = {}; + this.matrice3s = {}; + this.textures = {}; + this.floatArrays = {}; + this.vector4Arrays = {}; + this.matrixArrays = {}; + this.initialize = throwDestroyedError; + this.destroyed = true; + } + + override getColor (name: string): math.Color | null { + throw new Error('Method not implemented.'); + } + override setColor (name: string, value: math.Color): void { + throw new Error('Method not implemented.'); + } + override getQuaternion (name: string): math.Quaternion | null { + throw new Error('Method not implemented.'); + } + override setQuaternion (name: string, value: math.Quaternion): void { + throw new Error('Method not implemented.'); + } + + override dispose (destroyOptions?: MaterialDestroyOptions): void { + if (this.destroyed) { + return; + } + + if (destroyOptions?.textures !== DestroyOptions.keep) { + for (const texture of Object.values(this.textures)) { + texture.dispose(); + } + } + + this.clear(); + this.galaceanMaterial.destroy(); + + } +} diff --git a/src/material/index.ts b/src/material/index.ts new file mode 100644 index 0000000..4896aae --- /dev/null +++ b/src/material/index.ts @@ -0,0 +1,2 @@ +export * from './galacean-material-util'; +export * from './galacean-material'; diff --git a/src/plugin-spine.ts b/src/plugin-spine.ts new file mode 100644 index 0000000..d74e075 --- /dev/null +++ b/src/plugin-spine.ts @@ -0,0 +1 @@ +export * from '@galacean/effects-plugin-spine'; diff --git a/tsconfig.check.json b/tsconfig.check.json new file mode 100644 index 0000000..763e693 --- /dev/null +++ b/tsconfig.check.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "exclude": ["**/dist/**", "node_modules"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..44c07f6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist", + "allowJs": false, + "resolveJsonModule": true, + "noImplicitOverride": true, + "skipLibCheck": true, + "strictPropertyInitialization": false, + "strict": true, + "noImplicitAny": true, + "noImplicitThis": true, + "downlevelIteration": true, + "esModuleInterop": true, + // "noUnusedLocals": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "module": "ESNext", + "target": "ESNext", + "lib": [ + "DOM", + "ES2015", + "ESNext" + ], + "paths": { + "@galacean/engine-effects": [ + "./src" + ], + "@galacean/engine-effects/*": [ + "./src/*" + ] + } + }, + "include": [ + "src" + ], + "exclude": [ + "dist" + ] +} diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..35be270 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,13 @@ +{ + "name": "Engine Effects API", + "entryPoints": [ + "src/index.ts", + ], + "out": "api", + "includeVersion": true, + "excludeExternals": true, + "navigationLinks": { + "Galacean Effects": "https://galacean.antgroup.com/effects/", + "Source code": "https://github.com/galacean/engine-effects" + } +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..c6bcd5a --- /dev/null +++ b/vite.config.js @@ -0,0 +1,59 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import legacy from '@vitejs/plugin-legacy'; +import { getSWCPlugin } from './scripts/rollup-config-helper'; + +export default defineConfig(({ mode }) => { + return { + base: './', + build: { + rollupOptions: { + input: { + 'index': resolve(__dirname, 'demo/index.html'), + 'compose': resolve(__dirname, 'demo/html/compose.html'), + 'dynamic-image': resolve(__dirname, 'demo/html/dynamic-image.html'), + 'engine-config': resolve(__dirname, 'demo/html/engine-config.html'), + 'interactive': resolve(__dirname, 'demo/html/interactive.html'), + 'large-scene': resolve(__dirname, 'demo/html/large-scene.html'), + 'memory': resolve(__dirname, 'demo/html/memory.html'), + 'multiple-components': resolve(__dirname, 'demo/html/multiple-components.html'), + 'multiple-compositions': resolve(__dirname, 'demo/html/multiple-compositions.html'), + 'multiple-engine': resolve(__dirname, 'demo/html/multiple-engine.html'), + 'single': resolve(__dirname, 'demo/html/single.html'), + 'spine': resolve(__dirname, 'demo/html/spine.html'), + 'text': resolve(__dirname, 'demo/html/text.html'), + 'use-effects-camera': resolve(__dirname, 'demo/html/use-effects-camera.html'), + 'inspire-index': resolve(__dirname, 'demo/html/inspire/index.html'), + 'inspire-engine-effects': resolve(__dirname, 'demo/html/inspire/engine-effects.html'), + 'inspire-engine-use-effects-camera': resolve(__dirname, 'demo/html/inspire/engine-use-effects-camera.html'), + 'inspire-pre-effects-player': resolve(__dirname, 'demo/html/inspire/pre-effects-player.html'), + } + }, + minify: false, // iOS 9 等低版本加载压缩代码报脚本异常 + }, + server: { + host: '0.0.0.0', + port: 8080, + }, + preview: { + host: '0.0.0.0', + port: 8080, + }, + resolve: { + alias: [{ + find: '@galacean/effects', + replacement: '@galacean/effects-core', + }], + }, + plugins: [ + legacy({ + targets: ['iOS >= 9'], + }), + getSWCPlugin({ + target: 'ES6', + }), + tsconfigPaths(), + ], + }; +});