diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 6878beb..0000000
--- a/.babelrc
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "presets": [
- [
- "@babel/preset-env",
- {
- "targets": {
- "chrome": 52
- },
- "debug": false,
- "useBuiltIns": "usage"
- }
- ]
- ]
-}
diff --git a/.eslintrc.js b/.eslintrc.js
index 1a35f0a..3631f7f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,28 +1,11 @@
module.exports = {
- extends: ['airbnb-base', './scripts/eslint/index.js'],
- plugins: ['import'],
- parser: 'babel-eslint',
+ extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', './scripts/eslint/index.js'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['@typescript-eslint'],
+ root: true,
env: {
browser: true,
- commonjs: true,
es6: true,
node: true,
},
- parserOptions: {
- ecmaVersion: 2017,
- ecmaFeatures: {
- experimentalObjectRestSpread: true,
- },
- sourceType: 'module',
- },
- settings: {
- 'import/resolver': {
- webpack: {
- config: 'webpack.config.js',
- },
- },
- },
- rules: {
- strict: 'error',
- },
};
diff --git a/README.md b/README.md
index 2da346c..9406299 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ const isGameEntity = function isGameEntityFunc(state) {
}
return {
- id: getUUID(),
+ id: uuidv4(),
printInfo,
};
};
diff --git a/config/index.ejs b/config/index.ejs
deleted file mode 100644
index b970eac..0000000
--- a/config/index.ejs
+++ /dev/null
@@ -1,127 +0,0 @@
-<% var item, key %><%
-htmlWebpackPlugin.options.appMountIds = htmlWebpackPlugin.options.appMountIds || [] %><%
-htmlWebpackPlugin.options.lang = htmlWebpackPlugin.options.lang || "en" %><%
-htmlWebpackPlugin.options.links = htmlWebpackPlugin.options.links || [] %><%
-htmlWebpackPlugin.options.meta = htmlWebpackPlugin.options.meta || [] %><%
-htmlWebpackPlugin.options.scripts = htmlWebpackPlugin.options.scripts || []
-%>
- manifest="<%= htmlWebpackPlugin.files.manifest %>"<% } %>>
-
-
- <%
-
- if (htmlWebpackPlugin.options.baseHref) { %>
- <%
- } %><%
-
- if (Array.isArray(htmlWebpackPlugin.options.meta)) { %><%
- for (item of htmlWebpackPlugin.options.meta) { %>
- <%= key %>="<%= item[key] %>"<% } %>><%
- } %><%
- } %><%
-
- %>
- <%= htmlWebpackPlugin.options.title %> <%
-
- if (htmlWebpackPlugin.files.favicon) { %>
- <%
- } %><%
-
- if (htmlWebpackPlugin.options.mobile) { %>
- <%
- } %><%
-
- for (item of htmlWebpackPlugin.options.links) { %><%
- if (typeof item === 'string' || item instanceof String) { item = { href: item, rel: 'stylesheet' } } %>
- <%= key %>="<%= item[key] %>"<% } %> /><%
- } %><%
-
- for (key in htmlWebpackPlugin.files.css) { %><%
- if (htmlWebpackPlugin.files.cssIntegrity) { %>
- <%
- } else { %>
- <%
- } %><%
- } %><%
- if (htmlWebpackPlugin.options.headHtmlSnippet) { %>
- <%= htmlWebpackPlugin.options.headHtmlSnippet %><%
- } %>
-
- <%
- if (htmlWebpackPlugin.options.unsupportedBrowser) { %>
-
-
- Sorry, your browser is not supported. Please upgrade to the latest version or switch your browser to use this
- site. See
outdatedbrowser.com for options.
-
<%
- } %><%
-
- if (htmlWebpackPlugin.options.bodyHtmlSnippet) { %>
- <%= htmlWebpackPlugin.options.bodyHtmlSnippet %><%
- } %><%
-
- if (htmlWebpackPlugin.options.appMountId) { %>
- <%
- if (htmlWebpackPlugin.options.appMountHtmlSnippet) { %>
- <%= htmlWebpackPlugin.options.appMountHtmlSnippet %><%
- } %>
-
<%
- } %><%
-
- for (item of htmlWebpackPlugin.options.appMountIds) { %>
-
<%
- } %><%
-
- if (htmlWebpackPlugin.options.window) { %>
- <%
- } %><%
-
- if (htmlWebpackPlugin.options.inlineManifestWebpackName) { %>
- <%= htmlWebpackPlugin.files[htmlWebpackPlugin.options.inlineManifestWebpackName] %><%
- } %><%
-
- for (item of htmlWebpackPlugin.options.scripts) { %><%
- if (typeof item === 'string' || item instanceof String) { item = { src: item, type: 'text/javascript' } } %>
- <%
- } %><%
-
- for (key in htmlWebpackPlugin.files.chunks) { %><%
- if (htmlWebpackPlugin.files.jsIntegrity) { %>
- <%
- } else { %>
- <%
- } %><%
- } %><%
-
- if (htmlWebpackPlugin.options.devServer) { %>
- <%
- } %><%
-
- if (htmlWebpackPlugin.options.googleAnalytics) { %>
-
- <%
- } %>
-
-
diff --git a/config/webpack.config.base.js b/config/webpack.config.base.js
deleted file mode 100644
index efeeadd..0000000
--- a/config/webpack.config.base.js
+++ /dev/null
@@ -1,115 +0,0 @@
-const webpack = require('webpack');
-const path = require('path');
-const HtmlWebpackPlugin = require('html-webpack-plugin');
-const CopyWebpackPlugin = require('copy-webpack-plugin');
-
-const pkg = require('../package.json');
-
-const PATHS = {
- src: path.join(__dirname, '../src'),
- dist: path.join(__dirname, '../dist'),
-};
-
-module.exports = {
- context: __dirname,
- entry: {
- app: [PATHS.src],
- vendors: Object.keys(pkg.dependencies),
- },
- output: {
- filename: '[name].js',
- path: PATHS.dist,
- publicPath: '/',
- },
- resolve: {
- extensions: ['.js', '.jsx', '.jsm'],
- alias: {
- configs: path.resolve(__dirname, '../src/configs'),
- core: path.resolve(__dirname, '../src/core'),
- styles: path.resolve(__dirname, '../styles'),
- assets: path.resolve(__dirname, '../assets'),
- scenes: path.resolve(__dirname, '../src/scenes'),
- entities: path.resolve(__dirname, '../src/entities'),
- components: path.resolve(__dirname, '../src/components'),
- utils: path.resolve(__dirname, '../src/utils'),
- root: path.resolve(__dirname, '../src'),
- },
- },
- module: {
- rules: [
- {
- test: [/\.vert$/, /\.frag$/],
- use: 'raw-loader',
- },
- {
- test: /\.js$/,
- exclude: /node_modules/,
- use: 'babel-loader',
- },
- {
- test: /\.scss$/,
- use: [
- {
- loader: 'style-loader',
- },
- {
- loader: 'css-loader',
- options: {
- modules: true,
- camelCase: 'dashes',
- localIdentName: '[path][name]__[local]',
- },
- },
- {
- loader: 'resolve-url-loader',
- },
- {
- loader: 'sass-loader',
- },
- ],
- },
- {
- test: /\.(jpg|png|woff)$/,
- use: 'file-loader',
- },
- ],
- },
- plugins: [
- new webpack.DefinePlugin({
- CANVAS_RENDERER: JSON.stringify(true),
- WEBGL_RENDERER: JSON.stringify(true),
- PRODUCTION: JSON.stringify(false),
- }),
- new HtmlWebpackPlugin({
- template: './index.ejs',
- title: 'Boilerplate -- Change me',
- meta: [{ name: 'robots', content: 'noindex,nofollow' }],
- appMountIds: ['game'],
- inject: false,
- minify: {
- collapseWhitespace: true,
- conservativeCollapse: true,
- preserveLineBreaks: true,
- useShortDoctype: true,
- html5: true,
- },
- mobile: true,
- }),
- new webpack.HotModuleReplacementPlugin(),
- new webpack.NamedModulesPlugin(),
- new CopyWebpackPlugin({
- patterns: [
- {
- from: path.join(__dirname, '../assets/images/'),
- to: path.join(PATHS.dist, 'assets/images/'),
- flatten: false,
- },
- {
- from: path.join(__dirname, '../assets/audio/'),
- to: path.join(PATHS.dist, 'assets/audio/'),
- flatten: false,
- },
- ],
- }),
- ],
-};
diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js
deleted file mode 100644
index 9000db1..0000000
--- a/config/webpack.config.dev.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const baseConfig = require('./webpack.config.base');
-const path = require('path');
-const { merge } = require('webpack-merge');
-
-const PATHS = {
- src: path.join(__dirname, '../src'),
- dist: path.join(__dirname, '../dist'),
-};
-
-const PORT = 3000;
-
-module.exports = merge(baseConfig, {
- mode: 'development',
- devtool: 'eval-source-map',
- devServer: {
- contentBase: PATHS.dist,
- compress: true,
- headers: {
- 'X-Content-Type-Options': 'nosniff',
- 'X-Frame-Options': 'DENY',
- },
- open: true,
- overlay: {
- warnings: true,
- errors: true,
- },
- port: PORT,
- publicPath: `http://localhost:${PORT}/`,
- hot: true,
- },
-});
diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js
deleted file mode 100644
index bba5a96..0000000
--- a/config/webpack.config.prod.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const baseConfig = require('./webpack.config.base');
-const { merge } = require('webpack-merge');
-
-module.exports = merge(baseConfig, {
- mode: 'production',
- node: {
- fs: 'empty',
- net: 'empty',
- tls: 'empty',
- },
- optimization: {
- minimize: true,
- },
-});
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..0d9375a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jsconfig.json b/jsconfig.json
deleted file mode 100644
index e865c02..0000000
--- a/jsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "compilerOptions": {
- "baseUrl": ".", // This must be specified if "paths" is.
- "paths": {
- "configs/*": ["src/configs/*"],
- "core/*": ["src/core/*"],
- "styles/*": ["styles/*"],
- "assets/*": ["assets/*"],
- "scenes/*": ["src/scenes/*"],
- "entities/*": ["src/entities/*"],
- "components/*": ["src/components/*"],
- "utils/*": ["src/utils/*"],
- "root/*": ["src/"],
- }
- }
-}
diff --git a/package.json b/package.json
index 8b329b1..93ee05a 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,16 @@
{
"name": "phaser-3-boilerplate",
- "version": "1.2.0",
+ "version": "2.0.0",
"description": "Phaser 3 Boilerplate project for rapid development.",
"author": "Christian Holt (Sidaroth@protonmail.com)",
- "main": "src/index.js",
+ "main": "src/index.ts",
"scripts": {
- "default:start": "npm run clean && webpack --mode development",
- "start": "webpack-dev-server --config config/webpack.config.dev.js",
- "build": "npm run clean && webpack --mode production --config config/webpack.config.prod.js",
- "clean": "rimraf dist"
+ "start": "pnpm run dev",
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview",
+ "lint": "eslint src --ext .ts && tsc",
+ "lint:fix": "eslint src --ext .ts --fix"
},
"license": "MIT",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
@@ -18,42 +20,34 @@
"url": "git+https://github.com/sidaroth/Phaser3.Boilerplate.git"
},
"devDependencies": {
- "@babel/core": "^7.11.1",
- "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
- "@babel/preset-env": "^7.11.0",
- "babel-eslint": "^8.2.6",
- "babel-loader": "^8.1.0",
- "copy-webpack-plugin": "^6.0.3",
- "core-js": "^2.6.11",
- "css-loader": "^1.0.1",
- "eslint": "^4.19.1",
- "eslint-config-airbnb-base": "^12.1.0",
- "eslint-config-standard": "^10.2.1",
- "eslint-import-resolver-webpack": "^0.10.1",
- "eslint-plugin-import": "^2.22.0",
- "eslint-plugin-node": "^4.2.2",
- "eslint-plugin-promise": "^3.8.0",
- "eslint-plugin-standard": "^3.1.0",
- "expose-loader": "^0.7.5",
- "file-loader": "^1.1.11",
- "html-webpack-plugin": "^3.1.0",
- "html-webpack-template": "^6.1.0",
- "mini-css-extract-plugin": "^0.4.5",
- "node-sass": "^4.14.1",
- "raw-loader": "^0.5.1",
- "resolve-url-loader": "^2.3.2",
- "rimraf": "^2.7.1",
- "sass-loader": "^7.3.1",
- "style-loader": "^0.21.0",
- "webpack": "^4.44.1",
- "webpack-cli": "^3.3.12",
- "webpack-dev-server": "^3.11.0"
+ "@types/dat.gui": "^0.7.10",
+ "@types/stats": "^0.16.30",
+ "@types/uuid": "^9.0.4",
+ "@typescript-eslint/eslint-plugin": "^6.7.4",
+ "@typescript-eslint/parser": "^6.7.4",
+ "esbuild": "^0.19.4",
+ "eslint": "^8.50.0",
+ "eslint-config-airbnb-base": "^15.0.0",
+ "eslint-config-airbnb-typescript": "^17.1.0",
+ "eslint-import-resolver-alias": "^1.1.2",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-promise": "^6.1.1",
+ "eslint-plugin-standard": "^5.0.0",
+ "rollup-plugin-strip-code": "^0.2.7",
+ "tslib": "^2.6.2",
+ "typescript": "^5.2.2",
+ "vite": "^4.4.11",
+ "vite-plugin-dts": "^3.6.0",
+ "vite-plugin-eslint": "^1.8.1"
},
"dependencies": {
- "dat.gui": "^0.7.7",
- "immutable": "^3.8.2",
- "phaser": "^3.24.1",
- "stats-js": "^1.0.1",
- "webpack-merge": "^5.1.2"
+ "@types/node": "^20.8.2",
+ "dat.gui": "^0.7.9",
+ "immutable": "^4.3.4",
+ "phaser": "^3.60.0",
+ "sass": "^1.68.0",
+ "stats.js": "^0.17.0",
+ "uuid": "^9.0.1"
}
-}
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..1616688
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,2843 @@
+lockfileVersion: 5.4
+
+specifiers:
+ '@types/dat.gui': ^0.7.10
+ '@types/node': ^20.8.2
+ '@types/stats': ^0.16.30
+ '@types/uuid': ^9.0.4
+ '@typescript-eslint/eslint-plugin': ^6.7.4
+ '@typescript-eslint/parser': ^6.7.4
+ dat.gui: ^0.7.9
+ esbuild: ^0.19.4
+ eslint: ^8.50.0
+ eslint-config-airbnb-base: ^15.0.0
+ eslint-config-airbnb-typescript: ^17.1.0
+ eslint-import-resolver-alias: ^1.1.2
+ eslint-plugin-import: ^2.28.1
+ eslint-plugin-node: ^11.1.0
+ eslint-plugin-promise: ^6.1.1
+ eslint-plugin-standard: ^5.0.0
+ immutable: ^4.3.4
+ phaser: ^3.60.0
+ rollup-plugin-strip-code: ^0.2.7
+ sass: ^1.68.0
+ stats.js: ^0.17.0
+ tslib: ^2.6.2
+ typescript: ^5.2.2
+ uuid: ^9.0.1
+ vite: ^4.4.10
+ vite-plugin-dts: ^3.6.0
+ vite-plugin-eslint: ^1.8.1
+
+dependencies:
+ '@types/node': 20.8.2
+ dat.gui: 0.7.9
+ immutable: 4.3.4
+ phaser: 3.60.0
+ sass: 1.68.0
+ stats.js: 0.17.0
+ uuid: 9.0.1
+
+devDependencies:
+ '@types/dat.gui': 0.7.10
+ '@types/stats': 0.16.30
+ '@types/uuid': 9.0.4
+ '@typescript-eslint/eslint-plugin': 6.7.4_sjhwt3bl5psuxqi3hx6z7r6ola
+ '@typescript-eslint/parser': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ esbuild: 0.19.4
+ eslint: 8.50.0
+ eslint-config-airbnb-base: 15.0.0_mc36sq7crv2v5vtlozlclqwu5e
+ eslint-config-airbnb-typescript: 17.1.0_fwsuazv5pgoz2k7mdjirunpzam
+ eslint-import-resolver-alias: 1.1.2_b6377bcr3argvnmxmq6ha6uyl4
+ eslint-plugin-import: 2.28.1_4nytrgfpfmroylhx7ogxfohaye
+ eslint-plugin-node: 11.1.0_eslint@8.50.0
+ eslint-plugin-promise: 6.1.1_eslint@8.50.0
+ eslint-plugin-standard: 5.0.0_eslint@8.50.0
+ rollup-plugin-strip-code: 0.2.7
+ tslib: 2.6.2
+ typescript: 5.2.2
+ vite: 4.4.10_xw5nuywhrj3t7rakopdrzdmjn4
+ vite-plugin-dts: 3.6.0_c3vqjxdev4cverowl5dawv6nn4
+ vite-plugin-eslint: 1.8.1_eslint@8.50.0+vite@4.4.10
+
+packages:
+
+ /@aashutoshrathi/word-wrap/1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /@babel/helper-string-parser/7.22.5:
+ resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-validator-identifier/7.22.20:
+ resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/parser/7.23.0:
+ resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/types/7.23.0:
+ resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+ dev: 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-arm/0.19.4:
+ resolution: {integrity: sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: 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-arm64/0.19.4:
+ resolution: {integrity: sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ 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/android-x64/0.19.4:
+ resolution: {integrity: sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==}
+ 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-arm64/0.19.4:
+ resolution: {integrity: sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==}
+ 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/darwin-x64/0.19.4:
+ resolution: {integrity: sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==}
+ 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-arm64/0.19.4:
+ resolution: {integrity: sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==}
+ 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/freebsd-x64/0.19.4:
+ resolution: {integrity: sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ 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-arm/0.19.4:
+ resolution: {integrity: sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ 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-arm64/0.19.4:
+ resolution: {integrity: sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ 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-ia32/0.19.4:
+ resolution: {integrity: sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==}
+ 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-loong64/0.19.4:
+ resolution: {integrity: sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==}
+ 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-mips64el/0.19.4:
+ resolution: {integrity: sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==}
+ 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-ppc64/0.19.4:
+ resolution: {integrity: sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==}
+ 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-riscv64/0.19.4:
+ resolution: {integrity: sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==}
+ 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-s390x/0.19.4:
+ resolution: {integrity: sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==}
+ 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/linux-x64/0.19.4:
+ resolution: {integrity: sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==}
+ 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/netbsd-x64/0.19.4:
+ resolution: {integrity: sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==}
+ 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/openbsd-x64/0.19.4:
+ resolution: {integrity: sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==}
+ 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/sunos-x64/0.19.4:
+ resolution: {integrity: sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==}
+ 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-arm64/0.19.4:
+ resolution: {integrity: sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==}
+ 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-ia32/0.19.4:
+ resolution: {integrity: sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==}
+ 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
+
+ /@esbuild/win32-x64/0.19.4:
+ resolution: {integrity: sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@eslint-community/eslint-utils/4.4.0_eslint@8.50.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.50.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@eslint-community/regexpp/4.9.0:
+ resolution: {integrity: sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dev: true
+
+ /@eslint/eslintrc/2.1.2:
+ resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.6.1
+ globals: 13.22.0
+ ignore: 5.2.4
+ 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.50.0:
+ resolution: {integrity: sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@humanwhocodes/config-array/0.11.11:
+ resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/module-importer/1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+ dev: true
+
+ /@humanwhocodes/object-schema/1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ dev: true
+
+ /@microsoft/api-extractor-model/7.28.2_@types+node@20.8.2:
+ resolution: {integrity: sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==}
+ dependencies:
+ '@microsoft/tsdoc': 0.14.2
+ '@microsoft/tsdoc-config': 0.16.2
+ '@rushstack/node-core-library': 3.61.0_@types+node@20.8.2
+ transitivePeerDependencies:
+ - '@types/node'
+ dev: true
+
+ /@microsoft/api-extractor/7.37.3_@types+node@20.8.2:
+ resolution: {integrity: sha512-daC5IKZw/Qg8DYucnQVvagihKsTr5L7Bgf5VJYe/FwQhQuR9VRqKZfr2JkqoszsVqOf8C0KtFNTaqyB7chD/HQ==}
+ hasBin: true
+ dependencies:
+ '@microsoft/api-extractor-model': 7.28.2_@types+node@20.8.2
+ '@microsoft/tsdoc': 0.14.2
+ '@microsoft/tsdoc-config': 0.16.2
+ '@rushstack/node-core-library': 3.61.0_@types+node@20.8.2
+ '@rushstack/rig-package': 0.5.1
+ '@rushstack/ts-command-line': 4.16.1
+ colors: 1.2.5
+ lodash: 4.17.21
+ resolve: 1.22.6
+ semver: 7.5.4
+ source-map: 0.6.1
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - '@types/node'
+ dev: true
+
+ /@microsoft/tsdoc-config/0.16.2:
+ resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==}
+ dependencies:
+ '@microsoft/tsdoc': 0.14.2
+ ajv: 6.12.6
+ jju: 1.4.0
+ resolve: 1.19.0
+ dev: true
+
+ /@microsoft/tsdoc/0.14.2:
+ resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
+ dev: true
+
+ /@nodelib/fs.scandir/2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: true
+
+ /@nodelib/fs.stat/2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /@nodelib/fs.walk/1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.15.0
+ dev: true
+
+ /@rollup/pluginutils/4.2.1:
+ resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
+ engines: {node: '>= 8.0.0'}
+ dependencies:
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /@rollup/pluginutils/5.0.4:
+ resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+ dependencies:
+ '@types/estree': 1.0.2
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /@rushstack/node-core-library/3.61.0_@types+node@20.8.2:
+ resolution: {integrity: sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==}
+ peerDependencies:
+ '@types/node': '*'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ dependencies:
+ '@types/node': 20.8.2
+ colors: 1.2.5
+ fs-extra: 7.0.1
+ import-lazy: 4.0.0
+ jju: 1.4.0
+ resolve: 1.22.6
+ semver: 7.5.4
+ z-schema: 5.0.5
+ dev: true
+
+ /@rushstack/rig-package/0.5.1:
+ resolution: {integrity: sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==}
+ dependencies:
+ resolve: 1.22.6
+ strip-json-comments: 3.1.1
+ dev: true
+
+ /@rushstack/ts-command-line/4.16.1:
+ resolution: {integrity: sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==}
+ dependencies:
+ '@types/argparse': 1.0.38
+ argparse: 1.0.10
+ colors: 1.2.5
+ string-argv: 0.3.2
+ dev: true
+
+ /@types/argparse/1.0.38:
+ resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
+ dev: true
+
+ /@types/dat.gui/0.7.10:
+ resolution: {integrity: sha512-sLifoNrvs4lgJkAUZcTB28dbWy0AM05Yc0BzTqHheK0tRYRVsJHoFLocB5heDbb5amaFLEXna41GOM6IG06oqA==}
+ dev: true
+
+ /@types/eslint/8.44.3:
+ resolution: {integrity: sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==}
+ dependencies:
+ '@types/estree': 1.0.2
+ '@types/json-schema': 7.0.13
+ dev: true
+
+ /@types/estree/1.0.2:
+ resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==}
+ dev: true
+
+ /@types/json-schema/7.0.13:
+ resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==}
+ dev: true
+
+ /@types/json5/0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: true
+
+ /@types/node/20.8.2:
+ resolution: {integrity: sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==}
+
+ /@types/semver/7.5.3:
+ resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==}
+ dev: true
+
+ /@types/stats/0.16.30:
+ resolution: {integrity: sha512-ihuaNKhVjTQ8UNLJu7Kx96ywf0bSBday/K//HHvO9LKha07Ezxdm6HkazOKUIdayp0EmGEIPBQSL7eLxm8rX0w==}
+ dev: true
+
+ /@types/uuid/9.0.4:
+ resolution: {integrity: sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==}
+ dev: true
+
+ /@typescript-eslint/eslint-plugin/6.7.4_sjhwt3bl5psuxqi3hx6z7r6ola:
+ resolution: {integrity: sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.9.0
+ '@typescript-eslint/parser': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ '@typescript-eslint/scope-manager': 6.7.4
+ '@typescript-eslint/type-utils': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ '@typescript-eslint/utils': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ '@typescript-eslint/visitor-keys': 6.7.4
+ debug: 4.3.4
+ eslint: 8.50.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ natural-compare: 1.4.0
+ semver: 7.5.4
+ ts-api-utils: 1.0.3_typescript@5.2.2
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser/6.7.4_jk7qbkaijtltyu4ajmze3dfiwa:
+ resolution: {integrity: sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 6.7.4
+ '@typescript-eslint/types': 6.7.4
+ '@typescript-eslint/typescript-estree': 6.7.4_typescript@5.2.2
+ '@typescript-eslint/visitor-keys': 6.7.4
+ debug: 4.3.4
+ eslint: 8.50.0
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/scope-manager/6.7.4:
+ resolution: {integrity: sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.7.4
+ '@typescript-eslint/visitor-keys': 6.7.4
+ dev: true
+
+ /@typescript-eslint/type-utils/6.7.4_jk7qbkaijtltyu4ajmze3dfiwa:
+ resolution: {integrity: sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 6.7.4_typescript@5.2.2
+ '@typescript-eslint/utils': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ debug: 4.3.4
+ eslint: 8.50.0
+ ts-api-utils: 1.0.3_typescript@5.2.2
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types/6.7.4:
+ resolution: {integrity: sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dev: true
+
+ /@typescript-eslint/typescript-estree/6.7.4_typescript@5.2.2:
+ resolution: {integrity: sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 6.7.4
+ '@typescript-eslint/visitor-keys': 6.7.4
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.4
+ ts-api-utils: 1.0.3_typescript@5.2.2
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/utils/6.7.4_jk7qbkaijtltyu4ajmze3dfiwa:
+ resolution: {integrity: sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0_eslint@8.50.0
+ '@types/json-schema': 7.0.13
+ '@types/semver': 7.5.3
+ '@typescript-eslint/scope-manager': 6.7.4
+ '@typescript-eslint/types': 6.7.4
+ '@typescript-eslint/typescript-estree': 6.7.4_typescript@5.2.2
+ eslint: 8.50.0
+ semver: 7.5.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys/6.7.4:
+ resolution: {integrity: sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.7.4
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@volar/language-core/1.10.1:
+ resolution: {integrity: sha512-JnsM1mIPdfGPxmoOcK1c7HYAsL6YOv0TCJ4aW3AXPZN/Jb4R77epDyMZIVudSGjWMbvv/JfUa+rQ+dGKTmgwBA==}
+ dependencies:
+ '@volar/source-map': 1.10.1
+ dev: true
+
+ /@volar/source-map/1.10.1:
+ resolution: {integrity: sha512-3/S6KQbqa7pGC8CxPrg69qHLpOvkiPHGJtWPkI/1AXCsktkJ6gIk/5z4hyuMp8Anvs6eS/Kvp/GZa3ut3votKA==}
+ dependencies:
+ muggle-string: 0.3.1
+ dev: true
+
+ /@volar/typescript/1.10.1:
+ resolution: {integrity: sha512-+iiO9yUSRHIYjlteT+QcdRq8b44qH19/eiUZtjNtuh6D9ailYM7DVR0zO2sEgJlvCaunw/CF9Ov2KooQBpR4VQ==}
+ dependencies:
+ '@volar/language-core': 1.10.1
+ dev: true
+
+ /@vue/compiler-core/3.3.4:
+ resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
+ dependencies:
+ '@babel/parser': 7.23.0
+ '@vue/shared': 3.3.4
+ estree-walker: 2.0.2
+ source-map-js: 1.0.2
+ dev: true
+
+ /@vue/compiler-dom/3.3.4:
+ resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
+ dependencies:
+ '@vue/compiler-core': 3.3.4
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/language-core/1.8.15_typescript@5.2.2:
+ resolution: {integrity: sha512-zche5Aw8kkvp3YaghuLiOZyVIpoWHjSQ0EfjxGSsqHOPMamdCoa9x3HtbenpR38UMUoKJ88wiWuiOrV3B/Yq+A==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@volar/language-core': 1.10.1
+ '@volar/source-map': 1.10.1
+ '@vue/compiler-dom': 3.3.4
+ '@vue/reactivity': 3.3.4
+ '@vue/shared': 3.3.4
+ minimatch: 9.0.3
+ muggle-string: 0.3.1
+ typescript: 5.2.2
+ vue-template-compiler: 2.7.14
+ dev: true
+
+ /@vue/reactivity/3.3.4:
+ resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
+ dependencies:
+ '@vue/shared': 3.3.4
+ dev: true
+
+ /@vue/shared/3.3.4:
+ resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
+ dev: true
+
+ /@vue/typescript/1.8.15_typescript@5.2.2:
+ resolution: {integrity: sha512-qWyanQKXOsK84S8rP7QBrqsvUdQ0nZABZmTjXMpb3ox4Bp5IbkscREA3OPUrkgl64mAxwwCzIWcOc3BPTCPjQw==}
+ dependencies:
+ '@volar/typescript': 1.10.1
+ '@vue/language-core': 1.8.15_typescript@5.2.2
+ transitivePeerDependencies:
+ - typescript
+ dev: true
+
+ /acorn-jsx/5.3.2_acorn@8.10.0:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.10.0
+ dev: true
+
+ /acorn/8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ 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
+
+ /ansi-regex/5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /ansi-styles/4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+ dev: true
+
+ /anymatch/3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ /argparse/1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+ dependencies:
+ sprintf-js: 1.0.3
+ dev: true
+
+ /argparse/2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ dev: true
+
+ /array-buffer-byte-length/1.0.0:
+ resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
+ dependencies:
+ call-bind: 1.0.2
+ is-array-buffer: 3.0.2
+ dev: true
+
+ /array-includes/3.1.7:
+ resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ get-intrinsic: 1.2.1
+ is-string: 1.0.7
+ dev: true
+
+ /array-union/2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /array.prototype.findlastindex/1.2.3:
+ resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ es-shim-unscopables: 1.0.0
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /array.prototype.flat/1.3.2:
+ resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ es-shim-unscopables: 1.0.0
+ dev: true
+
+ /array.prototype.flatmap/1.3.2:
+ resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ es-shim-unscopables: 1.0.0
+ dev: true
+
+ /arraybuffer.prototype.slice/1.0.2:
+ resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ get-intrinsic: 1.2.1
+ is-array-buffer: 3.0.2
+ is-shared-array-buffer: 1.0.2
+ dev: true
+
+ /available-typed-arrays/1.0.5:
+ resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /balanced-match/1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ dev: true
+
+ /binary-extensions/2.2.0:
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ engines: {node: '>=8'}
+
+ /brace-expansion/1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+ dev: true
+
+ /brace-expansion/2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+ dependencies:
+ balanced-match: 1.0.2
+ dev: true
+
+ /braces/3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+
+ /call-bind/1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /callsites/3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ 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
+
+ /chokidar/3.5.3:
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ /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.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ dev: true
+
+ /colors/1.2.5:
+ resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==}
+ engines: {node: '>=0.1.90'}
+ dev: true
+
+ /commander/9.5.0:
+ resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
+ engines: {node: ^12.20.0 || >=14}
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /concat-map/0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ dev: true
+
+ /confusing-browser-globals/1.0.11:
+ resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
+ 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
+
+ /dat.gui/0.7.9:
+ resolution: {integrity: sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==}
+ dev: false
+
+ /de-indent/1.0.2:
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+ dev: true
+
+ /debug/3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: true
+
+ /debug/4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+ dev: true
+
+ /deep-is/0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ dev: true
+
+ /define-data-property/1.1.0:
+ resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.0
+ dev: true
+
+ /define-properties/1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-data-property: 1.1.0
+ has-property-descriptors: 1.0.0
+ object-keys: 1.1.1
+ dev: true
+
+ /dir-glob/3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: true
+
+ /doctrine/2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /doctrine/3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /es-abstract/1.22.2:
+ resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ arraybuffer.prototype.slice: 1.0.2
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ es-set-tostringtag: 2.0.1
+ es-to-primitive: 1.2.1
+ function.prototype.name: 1.1.6
+ get-intrinsic: 1.2.1
+ get-symbol-description: 1.0.0
+ globalthis: 1.0.3
+ gopd: 1.0.1
+ has: 1.0.3
+ has-property-descriptors: 1.0.0
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.5
+ is-array-buffer: 3.0.2
+ is-callable: 1.2.7
+ is-negative-zero: 2.0.2
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.2
+ is-string: 1.0.7
+ is-typed-array: 1.1.12
+ is-weakref: 1.0.2
+ object-inspect: 1.12.3
+ object-keys: 1.1.1
+ object.assign: 4.1.4
+ regexp.prototype.flags: 1.5.1
+ safe-array-concat: 1.0.1
+ safe-regex-test: 1.0.0
+ string.prototype.trim: 1.2.8
+ string.prototype.trimend: 1.0.7
+ string.prototype.trimstart: 1.0.7
+ typed-array-buffer: 1.0.0
+ typed-array-byte-length: 1.0.0
+ typed-array-byte-offset: 1.0.0
+ typed-array-length: 1.0.4
+ unbox-primitive: 1.0.2
+ which-typed-array: 1.1.11
+ dev: true
+
+ /es-set-tostringtag/2.0.1:
+ resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /es-shim-unscopables/1.0.0:
+ resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
+ dependencies:
+ has: 1.0.3
+ dev: true
+
+ /es-to-primitive/1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+ dev: true
+
+ /esbuild/0.18.20:
+ resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.18.20
+ '@esbuild/android-arm64': 0.18.20
+ '@esbuild/android-x64': 0.18.20
+ '@esbuild/darwin-arm64': 0.18.20
+ '@esbuild/darwin-x64': 0.18.20
+ '@esbuild/freebsd-arm64': 0.18.20
+ '@esbuild/freebsd-x64': 0.18.20
+ '@esbuild/linux-arm': 0.18.20
+ '@esbuild/linux-arm64': 0.18.20
+ '@esbuild/linux-ia32': 0.18.20
+ '@esbuild/linux-loong64': 0.18.20
+ '@esbuild/linux-mips64el': 0.18.20
+ '@esbuild/linux-ppc64': 0.18.20
+ '@esbuild/linux-riscv64': 0.18.20
+ '@esbuild/linux-s390x': 0.18.20
+ '@esbuild/linux-x64': 0.18.20
+ '@esbuild/netbsd-x64': 0.18.20
+ '@esbuild/openbsd-x64': 0.18.20
+ '@esbuild/sunos-x64': 0.18.20
+ '@esbuild/win32-arm64': 0.18.20
+ '@esbuild/win32-ia32': 0.18.20
+ '@esbuild/win32-x64': 0.18.20
+ dev: true
+
+ /esbuild/0.19.4:
+ resolution: {integrity: sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.19.4
+ '@esbuild/android-arm64': 0.19.4
+ '@esbuild/android-x64': 0.19.4
+ '@esbuild/darwin-arm64': 0.19.4
+ '@esbuild/darwin-x64': 0.19.4
+ '@esbuild/freebsd-arm64': 0.19.4
+ '@esbuild/freebsd-x64': 0.19.4
+ '@esbuild/linux-arm': 0.19.4
+ '@esbuild/linux-arm64': 0.19.4
+ '@esbuild/linux-ia32': 0.19.4
+ '@esbuild/linux-loong64': 0.19.4
+ '@esbuild/linux-mips64el': 0.19.4
+ '@esbuild/linux-ppc64': 0.19.4
+ '@esbuild/linux-riscv64': 0.19.4
+ '@esbuild/linux-s390x': 0.19.4
+ '@esbuild/linux-x64': 0.19.4
+ '@esbuild/netbsd-x64': 0.19.4
+ '@esbuild/openbsd-x64': 0.19.4
+ '@esbuild/sunos-x64': 0.19.4
+ '@esbuild/win32-arm64': 0.19.4
+ '@esbuild/win32-ia32': 0.19.4
+ '@esbuild/win32-x64': 0.19.4
+ dev: true
+
+ /escape-string-regexp/4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-config-airbnb-base/15.0.0_mc36sq7crv2v5vtlozlclqwu5e:
+ resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ peerDependencies:
+ eslint: ^7.32.0 || ^8.2.0
+ eslint-plugin-import: ^2.25.2
+ dependencies:
+ confusing-browser-globals: 1.0.11
+ eslint: 8.50.0
+ eslint-plugin-import: 2.28.1_4nytrgfpfmroylhx7ogxfohaye
+ object.assign: 4.1.4
+ object.entries: 1.1.7
+ semver: 6.3.1
+ dev: true
+
+ /eslint-config-airbnb-typescript/17.1.0_fwsuazv5pgoz2k7mdjirunpzam:
+ resolution: {integrity: sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==}
+ peerDependencies:
+ '@typescript-eslint/eslint-plugin': ^5.13.0 || ^6.0.0
+ '@typescript-eslint/parser': ^5.0.0 || ^6.0.0
+ eslint: ^7.32.0 || ^8.2.0
+ eslint-plugin-import: ^2.25.3
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 6.7.4_sjhwt3bl5psuxqi3hx6z7r6ola
+ '@typescript-eslint/parser': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ eslint: 8.50.0
+ eslint-config-airbnb-base: 15.0.0_mc36sq7crv2v5vtlozlclqwu5e
+ eslint-plugin-import: 2.28.1_4nytrgfpfmroylhx7ogxfohaye
+ dev: true
+
+ /eslint-import-resolver-alias/1.1.2_b6377bcr3argvnmxmq6ha6uyl4:
+ resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==}
+ engines: {node: '>= 4'}
+ peerDependencies:
+ eslint-plugin-import: '>=1.4.0'
+ dependencies:
+ eslint-plugin-import: 2.28.1_4nytrgfpfmroylhx7ogxfohaye
+ dev: true
+
+ /eslint-import-resolver-node/0.3.9:
+ resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.13.0
+ resolve: 1.22.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-module-utils/2.8.0_2koj2nlfkn7hmvx3bc24wyffmi:
+ resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ debug: 3.2.7
+ eslint: 8.50.0
+ eslint-import-resolver-node: 0.3.9
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-plugin-es/3.0.1_eslint@8.50.0:
+ resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==}
+ engines: {node: '>=8.10.0'}
+ peerDependencies:
+ eslint: '>=4.19.1'
+ dependencies:
+ eslint: 8.50.0
+ eslint-utils: 2.1.0
+ regexpp: 3.2.0
+ dev: true
+
+ /eslint-plugin-import/2.28.1_4nytrgfpfmroylhx7ogxfohaye:
+ resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 6.7.4_jk7qbkaijtltyu4ajmze3dfiwa
+ array-includes: 3.1.7
+ array.prototype.findlastindex: 1.2.3
+ array.prototype.flat: 1.3.2
+ array.prototype.flatmap: 1.3.2
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.50.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.8.0_2koj2nlfkn7hmvx3bc24wyffmi
+ has: 1.0.3
+ is-core-module: 2.13.0
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.7
+ object.groupby: 1.0.1
+ object.values: 1.1.7
+ semver: 6.3.1
+ tsconfig-paths: 3.14.2
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: true
+
+ /eslint-plugin-node/11.1.0_eslint@8.50.0:
+ resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==}
+ engines: {node: '>=8.10.0'}
+ peerDependencies:
+ eslint: '>=5.16.0'
+ dependencies:
+ eslint: 8.50.0
+ eslint-plugin-es: 3.0.1_eslint@8.50.0
+ eslint-utils: 2.1.0
+ ignore: 5.2.4
+ minimatch: 3.1.2
+ resolve: 1.22.6
+ semver: 6.3.1
+ dev: true
+
+ /eslint-plugin-promise/6.1.1_eslint@8.50.0:
+ resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ eslint: 8.50.0
+ dev: true
+
+ /eslint-plugin-standard/5.0.0_eslint@8.50.0:
+ resolution: {integrity: sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==}
+ deprecated: 'standard 16.0.0 and eslint-config-standard 16.0.0 no longer require the eslint-plugin-standard package. You can remove it from your dependencies with ''npm rm eslint-plugin-standard''. More info here: https://github.com/standard/standard/issues/1316'
+ peerDependencies:
+ eslint: '>=5.0.0'
+ dependencies:
+ eslint: 8.50.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-utils/2.1.0:
+ resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
+ engines: {node: '>=6'}
+ dependencies:
+ eslint-visitor-keys: 1.3.0
+ dev: true
+
+ /eslint-visitor-keys/1.3.0:
+ resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /eslint-visitor-keys/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.50.0:
+ resolution: {integrity: sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0_eslint@8.50.0
+ '@eslint-community/regexpp': 4.9.0
+ '@eslint/eslintrc': 2.1.2
+ '@eslint/js': 8.50.0
+ '@humanwhocodes/config-array': 0.11.11
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ 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.22.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ 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.3
+ 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.10.0
+ acorn-jsx: 5.3.2_acorn@8.10.0
+ 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/0.6.1:
+ resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
+ 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
+
+ /eventemitter3/5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+ dev: false
+
+ /fast-deep-equal/3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ dev: true
+
+ /fast-glob/3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
+ /fast-json-stable-stringify/2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ dev: true
+
+ /fast-levenshtein/2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ dev: true
+
+ /fastq/1.15.0:
+ resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: true
+
+ /file-entry-cache/6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.1.0
+ dev: true
+
+ /fill-range/7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+
+ /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
+
+ /flat-cache/3.1.0:
+ resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ flatted: 3.2.9
+ keyv: 4.5.3
+ rimraf: 3.0.2
+ dev: true
+
+ /flatted/3.2.9:
+ resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
+ dev: true
+
+ /for-each/0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ dependencies:
+ is-callable: 1.2.7
+ dev: true
+
+ /fs-extra/7.0.1:
+ resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
+ engines: {node: '>=6 <7 || >=8'}
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 4.0.0
+ universalify: 0.1.2
+ dev: true
+
+ /fs.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
+ optional: true
+
+ /function-bind/1.1.1:
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ dev: true
+
+ /function.prototype.name/1.1.6:
+ resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ functions-have-names: 1.2.3
+ dev: true
+
+ /functions-have-names/1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: true
+
+ /get-intrinsic/1.2.1:
+ resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ dev: true
+
+ /get-symbol-description/1.0.0:
+ resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /glob-parent/5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /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==}
+ 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
+
+ /globals/13.22.0:
+ resolution: {integrity: sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+ dev: true
+
+ /globalthis/1.0.3:
+ resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-properties: 1.2.1
+ dev: true
+
+ /globby/11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.1
+ ignore: 5.2.4
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: true
+
+ /gopd/1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /graceful-fs/4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ dev: true
+
+ /graphemer/1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ dev: true
+
+ /has-bigints/1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: true
+
+ /has-flag/4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /has-property-descriptors/1.0.0:
+ resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /has-proto/1.0.1:
+ resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-symbols/1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-tostringtag/1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
+ /has/1.0.3:
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ engines: {node: '>= 0.4.0'}
+ dependencies:
+ function-bind: 1.1.1
+ dev: true
+
+ /he/1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+ dev: true
+
+ /ignore/5.2.4:
+ resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+ engines: {node: '>= 4'}
+ dev: true
+
+ /immutable/4.3.4:
+ resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
+
+ /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-lazy/4.0.0:
+ resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /imurmurhash/0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+ dev: true
+
+ /inflight/1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+ dev: true
+
+ /inherits/2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ dev: true
+
+ /internal-slot/1.0.5:
+ resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: true
+
+ /is-array-buffer/3.0.2:
+ resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /is-bigint/1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: true
+
+ /is-binary-path/2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.2.0
+
+ /is-boolean-object/1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-callable/1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /is-core-module/2.13.0:
+ resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
+ dependencies:
+ has: 1.0.3
+ dev: true
+
+ /is-date-object/1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-extglob/2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ /is-glob/4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+
+ /is-negative-zero/2.0.2:
+ resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /is-number-object/1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-number/7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ /is-path-inside/3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /is-regex/1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-shared-array-buffer/1.0.2:
+ resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
+ /is-string/1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-symbol/1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
+ /is-typed-array/1.1.12:
+ resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ which-typed-array: 1.1.11
+ dev: true
+
+ /is-weakref/1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
+ /isarray/2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+ dev: true
+
+ /isexe/2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ dev: true
+
+ /jju/1.4.0:
+ resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
+ dev: true
+
+ /js-yaml/4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /json-buffer/3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ dev: true
+
+ /json-schema-traverse/0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-stable-stringify-without-jsonify/1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ dev: true
+
+ /json5/1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: true
+
+ /jsonfile/4.0.0:
+ resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
+ optionalDependencies:
+ graceful-fs: 4.2.11
+ dev: true
+
+ /keyv/4.5.3:
+ resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==}
+ dependencies:
+ json-buffer: 3.0.1
+ dev: true
+
+ /kolorist/1.8.0:
+ resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+ 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
+
+ /locate-path/6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+ dev: true
+
+ /lodash.get/4.4.2:
+ resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+ dev: true
+
+ /lodash.isequal/4.5.0:
+ resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+ dev: true
+
+ /lodash.merge/4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ dev: true
+
+ /lodash/4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ dev: true
+
+ /lru-cache/6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+ dev: true
+
+ /magic-string/0.25.3:
+ resolution: {integrity: sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==}
+ dependencies:
+ sourcemap-codec: 1.4.8
+ dev: true
+
+ /merge2/1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /micromatch/4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /minimatch/3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+ dev: true
+
+ /minimatch/9.0.3:
+ resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ brace-expansion: 2.0.1
+ dev: true
+
+ /minimist/1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ dev: true
+
+ /ms/2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ dev: true
+
+ /ms/2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ dev: true
+
+ /muggle-string/0.3.1:
+ resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
+ dev: true
+
+ /nanoid/3.3.6:
+ resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+ dev: true
+
+ /natural-compare/1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ dev: true
+
+ /normalize-path/3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ /object-inspect/1.12.3:
+ resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ dev: true
+
+ /object-keys/1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /object.assign/4.1.4:
+ resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: true
+
+ /object.entries/1.1.7:
+ resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /object.fromentries/2.0.7:
+ resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /object.groupby/1.0.1:
+ resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /object.values/1.1.7:
+ resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /once/1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+ dev: true
+
+ /optionator/0.9.3:
+ resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /p-limit/3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.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
+
+ /parent-module/1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
+ /path-exists/4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-is-absolute/1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /path-key/3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-parse/1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ dev: true
+
+ /path-type/4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /phaser/3.60.0:
+ resolution: {integrity: sha512-IKUy35EnoEVcl2EmJ8WOyK4X8OoxHYdlhZLgRGpNrvD1fEagYffhVmwHcapE/tGiLgyrnezmXIo5RrH2NcrTHw==}
+ dependencies:
+ eventemitter3: 5.0.1
+ dev: false
+
+ /picocolors/1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ dev: true
+
+ /picomatch/2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ /postcss/8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.6
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+ dev: true
+
+ /prelude-ls/1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
+ /punycode/2.3.0:
+ resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /queue-microtask/1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: true
+
+ /readdirp/3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.3.1
+
+ /regexp.prototype.flags/1.5.1:
+ resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ set-function-name: 2.0.1
+ dev: true
+
+ /regexpp/3.2.0:
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /resolve-from/4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /resolve/1.19.0:
+ resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
+ dependencies:
+ is-core-module: 2.13.0
+ path-parse: 1.0.7
+ dev: true
+
+ /resolve/1.22.6:
+ resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.13.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+ dev: true
+
+ /reusify/1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: true
+
+ /rimraf/3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+ dev: true
+
+ /rollup-plugin-strip-code/0.2.7:
+ resolution: {integrity: sha512-+5t9u/VrHPSfiRWWKMVin+KOtFwFak337FAZxeTjxYDjB3DDoHBQRkXHQvBn713eAfW81t41mGuysqsMXiuTjw==}
+ dependencies:
+ magic-string: 0.25.3
+ rollup-pluginutils: 2.8.1
+ dev: true
+
+ /rollup-pluginutils/2.8.1:
+ resolution: {integrity: sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==}
+ dependencies:
+ estree-walker: 0.6.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
+
+ /safe-array-concat/1.0.1:
+ resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==}
+ engines: {node: '>=0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ has-symbols: 1.0.3
+ isarray: 2.0.5
+ dev: true
+
+ /safe-regex-test/1.0.0:
+ resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-regex: 1.1.4
+ dev: true
+
+ /sass/1.68.0:
+ resolution: {integrity: sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ immutable: 4.3.4
+ source-map-js: 1.0.2
+
+ /semver/6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+ dev: true
+
+ /semver/7.5.4:
+ resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
+ /set-function-name/2.0.1:
+ resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-data-property: 1.1.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.0
+ dev: true
+
+ /shebang-command/2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+ dev: true
+
+ /shebang-regex/3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /side-channel/1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ object-inspect: 1.12.3
+ dev: true
+
+ /slash/3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /source-map-js/1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ engines: {node: '>=0.10.0'}
+
+ /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
+
+ /sprintf-js/1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+ dev: true
+
+ /stats.js/0.17.0:
+ resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==}
+ dev: false
+
+ /string-argv/0.3.2:
+ resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+ engines: {node: '>=0.6.19'}
+ dev: true
+
+ /string.prototype.trim/1.2.8:
+ resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /string.prototype.trimend/1.0.7:
+ resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /string.prototype.trimstart/1.0.7:
+ resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.1
+ es-abstract: 1.22.2
+ dev: true
+
+ /strip-ansi/6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+ dev: true
+
+ /strip-bom/3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /strip-json-comments/3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+ 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-preserve-symlinks-flag/1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /text-table/0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ 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
+
+ /ts-api-utils/1.0.3_typescript@5.2.2:
+ resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
+ engines: {node: '>=16.13.0'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.2.2
+ dev: true
+
+ /tsconfig-paths/3.14.2:
+ resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+ 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
+
+ /typed-array-buffer/1.0.0:
+ resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-byte-length/1.0.0:
+ resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ has-proto: 1.0.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-byte-offset/1.0.0:
+ resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ has-proto: 1.0.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-length/1.0.4:
+ resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
+ dependencies:
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typescript/5.0.4:
+ resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
+ engines: {node: '>=12.20'}
+ hasBin: true
+ dev: true
+
+ /typescript/5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+ dev: true
+
+ /unbox-primitive/1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ dependencies:
+ call-bind: 1.0.2
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+ dev: true
+
+ /universalify/0.1.2:
+ resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
+ engines: {node: '>= 4.0.0'}
+ dev: true
+
+ /uri-js/4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.3.0
+ dev: true
+
+ /uuid/9.0.1:
+ resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
+ hasBin: true
+ dev: false
+
+ /validator/13.11.0:
+ resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==}
+ engines: {node: '>= 0.10'}
+ dev: true
+
+ /vite-plugin-dts/3.6.0_c3vqjxdev4cverowl5dawv6nn4:
+ resolution: {integrity: sha512-doxhDRFJCZD2sGjIp4V800nm8Y19GvmwckjG5vYPuiqJ7OBjc9NlW1Vp9Gkyh2aXlUs1jTDRH/lxWfcsPLOQHg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ vite: '*'
+ peerDependenciesMeta:
+ vite:
+ optional: true
+ dependencies:
+ '@microsoft/api-extractor': 7.37.3_@types+node@20.8.2
+ '@rollup/pluginutils': 5.0.4
+ '@vue/language-core': 1.8.15_typescript@5.2.2
+ debug: 4.3.4
+ kolorist: 1.8.0
+ typescript: 5.2.2
+ vite: 4.4.10_xw5nuywhrj3t7rakopdrzdmjn4
+ vue-tsc: 1.8.15_typescript@5.2.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - rollup
+ - supports-color
+ dev: true
+
+ /vite-plugin-eslint/1.8.1_eslint@8.50.0+vite@4.4.10:
+ resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==}
+ peerDependencies:
+ eslint: '>=7'
+ vite: '>=2'
+ dependencies:
+ '@rollup/pluginutils': 4.2.1
+ '@types/eslint': 8.44.3
+ eslint: 8.50.0
+ rollup: 2.79.1
+ vite: 4.4.10_xw5nuywhrj3t7rakopdrzdmjn4
+ dev: true
+
+ /vite/4.4.10_xw5nuywhrj3t7rakopdrzdmjn4:
+ resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==}
+ 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.8.2
+ esbuild: 0.18.20
+ postcss: 8.4.31
+ rollup: 3.29.4
+ sass: 1.68.0
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /vue-template-compiler/2.7.14:
+ resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
+ dependencies:
+ de-indent: 1.0.2
+ he: 1.2.0
+ dev: true
+
+ /vue-tsc/1.8.15_typescript@5.2.2:
+ resolution: {integrity: sha512-4DoB3LUj7IToLmggoCxRiFG+QU5lem0nv03m1ocqugXA9rSVoTOEoYYaP8vu8b99Eh+/cCVdYOeIAQ+RsgUYUw==}
+ hasBin: true
+ peerDependencies:
+ typescript: '*'
+ dependencies:
+ '@vue/language-core': 1.8.15_typescript@5.2.2
+ '@vue/typescript': 1.8.15_typescript@5.2.2
+ semver: 7.5.4
+ typescript: 5.2.2
+ dev: true
+
+ /which-boxed-primitive/1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: true
+
+ /which-typed-array/1.1.11:
+ resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /which/2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: true
+
+ /wrappy/1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ dev: true
+
+ /yallist/4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
+
+ /yocto-queue/0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /z-schema/5.0.5:
+ resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==}
+ engines: {node: '>=8.0.0'}
+ hasBin: true
+ dependencies:
+ lodash.get: 4.4.2
+ lodash.isequal: 4.5.0
+ validator: 13.11.0
+ optionalDependencies:
+ commander: 9.5.0
+ dev: true
diff --git a/scripts/eslint/index.js b/scripts/eslint/index.js
index b6220b7..d9cbc8e 100644
--- a/scripts/eslint/index.js
+++ b/scripts/eslint/index.js
@@ -1,92 +1,6 @@
module.exports = {
rules: {
- 'prefer-destructuring': [
- 'warn',
- {
- VariableDeclarator: {
- array: false,
- object: true,
- },
- AssignmentExpression: {
- array: true,
- object: true,
- },
- },
- {
- enforceForRenamedProperties: false,
- },
- ],
- 'no-restricted-syntax': [
- 'warn',
- {
- selector: 'ForInStatement',
- message:
- 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
- },
- {
- selector: 'ForOfStatement',
- message:
- 'iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.',
- },
- {
- selector: 'LabeledStatement',
- message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
- },
- {
- selector: 'WithStatement',
- message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
- },
- ],
- indent: [
- 'error',
- 4,
- {
- SwitchCase: 1,
- VariableDeclarator: 1,
- outerIIFEBody: 1,
- // MemberExpression: null,
- FunctionDeclaration: {
- parameters: 1,
- body: 1,
- },
- FunctionExpression: {
- parameters: 1,
- body: 1,
- },
- CallExpression: {
- arguments: 1,
- },
- ArrayExpression: 1,
- ObjectExpression: 1,
- ImportDeclaration: 1,
- flatTernaryExpressions: false,
- ignoredNodes: ['JSXElement', 'JSXElement *'],
- },
- ],
- 'class-methods-use-this': 'warn',
- 'no-undef': 'warn',
- 'no-unreachable': 'warn',
- 'no-unused-vars': 'warn',
- 'no-underscore-dangle': 'off',
- 'linebreak-style': ['error', 'windows'],
- 'no-mixed-operators': [
- 'off',
- {
- allowSamePrecedence: true,
- },
- ],
- 'sort-imports': 'off',
- 'import/first': 'off',
- // https://blog.javascripting.com/2015/09/07/fine-tuning-airbnbs-eslint-config/
- 'max-len': [1, 200, 2, { ignoreComments: true }],
- 'no-cond-assign': [2, 'except-parens'],
- radix: 0,
- 'no-unused-vars': [1, { vars: 'local', args: 'none' }],
- 'default-case': 0,
- 'no-else-return': 0,
- 'no-param-reassign': ['warn', { props: false }],
- 'no-continue': 'warn',
- 'no-lonely-if': 'warn',
- 'no-console': 'off',
+ "@typescript-eslint/no-explicit-any": "off",
+ // "@typescript-eslint/no-implicit-any": "error",
},
};
diff --git a/src/components/entities/hasTrigger.js b/src/components/entities/hasTrigger.js
deleted file mode 100644
index 19a19c5..0000000
--- a/src/components/entities/hasTrigger.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import Phaser from 'phaser';
-
-const hasTrigger = function hasTriggerFunc(state) {
- let parentScene;
-
- let triggerZone;
- let overlapsWith = [];
- let overlappedEntities = [];
- let x = 0;
- let y = 0;
- let w = 10;
- let h = 10;
-
- function createTriggerZone() {
- triggerZone = new Phaser.GameObjects.Zone(parentScene, x, y, w, h);
- parentScene.physics.add.existing(triggerZone, true);
- }
-
- function init(newParentScene) {
- parentScene = newParentScene;
- createTriggerZone();
- }
-
- function setSize(newW, newH) {
- w = newW;
- h = newH;
- triggerZone.setSize(w, h);
- }
-
- function setPosition(newX, newY) {
- x = newX;
- y = newY;
- triggerZone.setPosition(x, y);
- }
-
- function setOverlaps(bodies) {
- overlapsWith = bodies;
- }
-
- function addOverlapBody(body) {
- overlapsWith.push(body);
- }
-
- function isOverlappedByAny() {
- return overlappedEntities.length > 0;
- }
-
- /**
- * It should be possible to optimize state to avoid a double loop (or is it?).
- */
- function update() {
- const previous = overlappedEntities;
- overlappedEntities = [];
- parentScene.physics.overlap(triggerZone, overlapsWith, (zone, entity) => {
- overlappedEntities.push(entity);
- });
-
- overlappedEntities.forEach((entity) => {
- if (previous.indexOf(entity) === -1) {
- state.onEntityEnteredRange(entity);
- }
- });
-
- // If an entity was overlapped previously, but no longer, we emit an exit event.
- previous.forEach((entity) => {
- if (overlappedEntities.indexOf(entity) === -1) {
- state.onEntityLeftRange(entity);
- }
- });
- }
-
- return {
- // props
- // methods
- init,
- setSize,
- setPosition,
- setOverlaps,
- addOverlapBody,
- isOverlappedByAny,
- update,
- onEntityLeftRange: e => e,
- onEntityEnteredRange: e => e,
- };
-};
-
-export default hasTrigger;
diff --git a/src/components/entities/hasTrigger.ts b/src/components/entities/hasTrigger.ts
new file mode 100644
index 0000000..aa5349a
--- /dev/null
+++ b/src/components/entities/hasTrigger.ts
@@ -0,0 +1,112 @@
+import { Position } from 'components/hasPosition';
+import { Size } from 'components/hasSize';
+import { ExtendedPhaserScene } from 'components/isScene';
+import Phaser from 'phaser';
+
+export interface TriggerComponent {
+ init(parentScene: ExtendedPhaserScene): void;
+ onEntityLeftRange(entity: Phaser.Tilemaps.Tile | Phaser.Types.Physics.Arcade.GameObjectWithBody): void;
+ onEntityEnteredRange(entity: Phaser.Tilemaps.Tile | Phaser.Types.Physics.Arcade.GameObjectWithBody): void;
+ setSize(size: Size): Size;
+ setPosition(pos: Position): Position;
+ setOverlaps(bodies: Array): void;
+ addOverlapBody(body: Phaser.GameObjects.Zone): void;
+ isOverlappedByAny(): boolean;
+ update(): void;
+}
+
+const hasTrigger = function hasTriggerFunc(state: TriggerComponent): TriggerComponent {
+ let parentScene: ExtendedPhaserScene | undefined;
+
+ let triggerZone: Phaser.GameObjects.Zone | undefined;
+ let overlapsWith: Array = [];
+ let overlappedEntities: Array = [];
+ let x = 0;
+ let y = 0;
+ let w = 10;
+ let h = 10;
+
+ function createTriggerZone() {
+ if (parentScene) {
+ triggerZone = new Phaser.GameObjects.Zone(parentScene, x, y, w, h);
+ parentScene.physics.add.existing(triggerZone, true);
+ }
+ }
+
+ function init(newParentScene: ExtendedPhaserScene) {
+ parentScene = newParentScene;
+ createTriggerZone();
+ }
+
+ function setSize(size: Size): Size {
+ w = size.height;
+ h = size.width;
+ if (triggerZone) {
+ triggerZone.setSize(w, h);
+ }
+ return size;
+ }
+
+ function setPosition(pos: Position): Position {
+ x = pos.x;
+ y = pos.y;
+ if (triggerZone) {
+ triggerZone.setPosition(x, y);
+ }
+ return pos;
+ }
+
+ function setOverlaps(bodies: Array) {
+ overlapsWith = bodies;
+ }
+
+ function addOverlapBody(body: Phaser.GameObjects.Zone) {
+ overlapsWith.push(body);
+ }
+
+ function isOverlappedByAny() {
+ return overlappedEntities.length > 0;
+ }
+
+ /**
+ * It should be possible to optimize state to avoid a double loop (or is it?).
+ */
+ function update() {
+ const previous = overlappedEntities;
+ overlappedEntities = [];
+ if (parentScene && triggerZone) {
+ parentScene.physics.overlap(triggerZone, overlapsWith, (zone, entity) => {
+ overlappedEntities.push(entity);
+ });
+ }
+
+ overlappedEntities.forEach((entity) => {
+ if (previous.indexOf(entity) === -1) {
+ state.onEntityEnteredRange(entity);
+ }
+ });
+
+ // If an entity was overlapped previously, but no longer, we emit an exit event.
+ previous.forEach((entity) => {
+ if (overlappedEntities.indexOf(entity) === -1) {
+ state.onEntityLeftRange(entity);
+ }
+ });
+ }
+
+ return {
+ // props
+ // methods
+ init,
+ setSize,
+ setPosition,
+ setOverlaps,
+ addOverlapBody,
+ isOverlappedByAny,
+ update,
+ onEntityLeftRange: e => e,
+ onEntityEnteredRange: e => e,
+ };
+};
+
+export default hasTrigger;
diff --git a/src/components/entities/isGameEntity.js b/src/components/entities/isGameEntity.js
deleted file mode 100644
index 75a8505..0000000
--- a/src/components/entities/isGameEntity.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import getUUID from 'utils/getUUID';
-
-const isGameEntity = function isGameEntityFunc(state) {
- function printInfo() {
- console.log(`id: %c${state.id}`, 'color: yellow');
- }
-
- function update() {}
-
- return {
- // props
- id: getUUID(),
- // methods
- printInfo,
- update,
- };
-};
-
-export default isGameEntity;
diff --git a/src/components/entities/isGameEntity.ts b/src/components/entities/isGameEntity.ts
new file mode 100644
index 0000000..12aed45
--- /dev/null
+++ b/src/components/entities/isGameEntity.ts
@@ -0,0 +1,26 @@
+import { v4 as uuidv4 } from 'uuid';
+
+export interface GameEntityState {
+ id: string;
+
+ printInfo(): void;
+ update(): void;
+}
+
+const isGameEntity = function isGameEntityFunc(state: GameEntityState): GameEntityState {
+ function printInfo() {
+ console.log(`id: %c${state.id}`, 'color: yellow');
+ }
+
+ function update() { }
+
+ return {
+ // props
+ id: uuidv4(),
+ // methods
+ printInfo,
+ update,
+ };
+};
+
+export default isGameEntity;
diff --git a/src/components/events/canEmit.js b/src/components/events/canEmit.js
deleted file mode 100644
index 618f0df..0000000
--- a/src/components/events/canEmit.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import store from 'root/store';
-import Phaser from 'phaser';
-import createListener from 'core/createListener';
-
-const canEmit = function canEmitFunc(state) {
- const localEmitter = new Phaser.Events.EventEmitter();
- const listeners = [];
-
- function emitGlobal(event, data) {
- store.messageBus.emit(event, data);
- }
-
- function emit(event, data) {
- localEmitter.emit(event, data);
- }
-
- function on(event, fn, context) {
- localEmitter.on(event, fn, context);
- const listener = createListener(event, fn, false, state);
- listeners.push(listener);
- return listener;
- }
-
- function once(event, fn, context) {
- localEmitter.once(event, fn, context);
- const listener = createListener(event, fn, true, state);
- listeners.push(listener);
- return listener;
- }
-
- function off(listener) {
- if (listeners.indexOf(listener) >= 0) {
- localEmitter.off(listener.event, listener.fn, listener.once);
- listeners.splice(listeners.indexOf(listener), 1);
- }
- }
-
- function removeAllListeners() {
- if (localEmitter) {
- listeners.forEach((l) => {
- l.drop();
- });
- }
- }
-
- function destroy() {
- if (localEmitter) {
- state.removeAllListeners();
- localEmitter.destroy();
- }
- }
-
- return {
- // props
- // methods
- emitGlobal,
- emit,
- on,
- once,
- off,
- removeAllListeners,
- destroy,
- };
-};
-
-export default canEmit;
diff --git a/src/components/events/canEmit.ts b/src/components/events/canEmit.ts
new file mode 100644
index 0000000..9abcfa8
--- /dev/null
+++ b/src/components/events/canEmit.ts
@@ -0,0 +1,77 @@
+import store from 'root/store';
+import Phaser from 'phaser';
+import createListener, { Listener } from 'core/createListener';
+import { EventData } from 'configs/eventConfig';
+
+export interface EmitComponent {
+ emitGlobal: (event: T, data: EventData[T]) => void;
+ emit: (event: T, data: EventData[T]) => void;
+ on: (event: T, fn: (e: EventData[T]) => void, context: EmitComponent) => Listener;
+ once: (event: T, fn: (e: EventData[T]) => void, context: EmitComponent) => Listener;
+ off: (listener: Listener) => void;
+ removeAllListeners: () => void;
+ destroy: () => void;
+}
+
+function canEmit(state: EmitComponent) {
+ const localEmitter = new Phaser.Events.EventEmitter();
+ const listeners: Array> = [];
+
+ function emitGlobal(event: T, data: EventData[T]) {
+ store.messageBus?.emit(event, data);
+ }
+
+ function emit(event: T, data: EventData[T]) {
+ localEmitter.emit(event, data);
+ }
+
+ function on(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener {
+ localEmitter.on(event, fn, context);
+ const listener = createListener(event, fn, false, state);
+ listeners.push(listener);
+ return listener;
+ }
+
+ function once(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener {
+ localEmitter.once(event, fn, context);
+ const listener = createListener(event, fn, true, state);
+ listeners.push(listener);
+ return listener;
+ }
+
+ function off(listener: Listener) {
+ if (listeners.indexOf(listener) >= 0) {
+ localEmitter.off(listener.event, listener.fn, listener.once);
+ listeners.splice(listeners.indexOf(listener), 1);
+ }
+ }
+
+ function removeAllListeners() {
+ if (localEmitter) {
+ listeners.forEach((l) => {
+ l.drop();
+ });
+ }
+ }
+
+ function destroy() {
+ if (localEmitter) {
+ state.removeAllListeners();
+ localEmitter.destroy();
+ }
+ }
+ const returnState: EmitComponent = {
+ // props
+ // methods
+ emitGlobal,
+ emit,
+ on,
+ once,
+ off,
+ removeAllListeners,
+ destroy,
+ };
+ return returnState;
+}
+
+export default canEmit;
diff --git a/src/components/events/canListen.js b/src/components/events/canListen.js
deleted file mode 100644
index 30b3683..0000000
--- a/src/components/events/canListen.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import store from 'root/store';
-
-const canListen = function canListenFunc(state) {
- const listeners = [];
-
- function listenOn(emitState, event, fn, context) {
- const listener = emitState.on(event, fn, context);
- listeners.push(listener);
- return listener;
- }
-
- function listenOnce(emitState, event, fn, context) {
- const listener = emitState.once(event, fn, context);
- listeners.push(listener);
- return listener;
- }
-
- function listenGlobal(event, fn, context) {
- const listener = store.messageBus.on(event, fn, context);
- listeners.push(listener);
- return listener;
- }
-
- function listenOnceGlobal(event, fn, context) {
- const listener = store.messageBus.once(event, fn, context);
- listeners.push(listener);
- return listener;
- }
-
- function dropListener(listener) {
- listeners.splice(listeners.findIndex(l => l === listener), 1);
- listener.drop();
- }
-
- function destroy() {
- listeners.forEach((l) => {
- l.drop();
- });
- }
-
- return {
- // props
- // methods
- dropListener,
- listenOn,
- listenOnce,
- listenGlobal,
- listenOnceGlobal,
- destroy,
- };
-};
-
-export default canListen;
diff --git a/src/components/events/canListen.ts b/src/components/events/canListen.ts
new file mode 100644
index 0000000..8ffc050
--- /dev/null
+++ b/src/components/events/canListen.ts
@@ -0,0 +1,72 @@
+import store from 'root/store';
+import { EmitComponent } from './canEmit';
+import { EventData } from 'configs/eventConfig';
+import { Listener } from 'core/createListener';
+import { LifeCycle } from 'components/isScene';
+
+export interface ListenComponent extends LifeCycle {
+ dropListener(listener: Listener): void;
+ listenOn(emitState: EmitComponent, event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined;
+ listenOnce(emitState: EmitComponent, event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined;
+ listenGlobal(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined;
+ listenOnceGlobal(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined;
+}
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const canListen = function canListenFunc(state: ListenComponent): ListenComponent {
+ const listeners: Array> = [];
+
+ function listenOn(emitState: EmitComponent, event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener {
+ const listener = emitState.on(event, fn, context);
+ listeners.push(listener);
+ return listener;
+ }
+
+ function listenOnce(emitState: EmitComponent, event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener {
+ const listener = emitState.once(event, fn, context);
+ listeners.push(listener);
+ return listener;
+ }
+
+ function listenGlobal(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined{
+ const listener = store.messageBus?.on(event, fn, context);
+ if(listener) {
+ listeners.push(listener);
+ }
+ return listener;
+ }
+
+ function listenOnceGlobal(event: T, fn: (e: EventData[T]) => void, context: EmitComponent): Listener | undefined {
+ const listener = store.messageBus?.once(event, fn, context);
+ if(listener) {
+ listeners.push(listener);
+ }
+ return listener;
+ }
+
+ function dropListener(listener: Listener) {
+ listeners.splice(listeners.findIndex(l => l === listener), 1);
+ listener.drop();
+ }
+
+ function destroy() {
+ listeners.forEach((l) => {
+ l.drop();
+ });
+ }
+
+ const returnState: ListenComponent = {
+ // props
+ // methods
+ dropListener,
+ listenOn,
+ listenOnce,
+ listenGlobal,
+ listenOnceGlobal,
+ destroy,
+ };
+
+ return returnState;
+};
+
+export default canListen;
diff --git a/src/components/hasAudio.js b/src/components/hasAudio.js
deleted file mode 100644
index c03ffcb..0000000
--- a/src/components/hasAudio.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import store from 'root/store';
-
-const hasAudio = function hasAudioFunc(state) {
- let audioMan = store.audioManager;
-
- function getAudioManager() {
- return audioMan;
- }
-
- function setAudioManager(manager) {
- audioMan = manager;
- }
-
- function playSfx(key) {
- if (!audioMan) return;
-
- audioMan.playSfx(key);
- }
-
- function playMusic(key) {
- if (!audioMan) return;
-
- audioMan.playMusic(key);
- }
-
- return {
- getAudioManager,
- setAudioManager,
- playSfx,
- playMusic,
- };
-};
-
-export default hasAudio;
diff --git a/src/components/hasAudio.ts b/src/components/hasAudio.ts
new file mode 100644
index 0000000..2142352
--- /dev/null
+++ b/src/components/hasAudio.ts
@@ -0,0 +1,43 @@
+import { AudioManager } from 'core/createAudioManager';
+import store from 'root/store';
+
+export interface Audio {
+ getAudioManager(): AudioManager | undefined;
+ setAudioManager(manager: AudioManager): void;
+ playSfx(key: string): void;
+ playMusic(key: string): void;
+}
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+function hasAudio(state: Audio): Audio {
+ let audioMan: AudioManager | undefined = store.audioManager;
+
+ function getAudioManager(): AudioManager | undefined {
+ return audioMan;
+ }
+
+ function setAudioManager(manager: AudioManager) {
+ audioMan = manager;
+ }
+
+ function playSfx(key: string) {
+ if (!audioMan) return;
+
+ audioMan.playSfx(key);
+ }
+
+ function playMusic(key: string) {
+ if (!audioMan) return;
+
+ audioMan.playMusic(key);
+ }
+
+ return {
+ getAudioManager,
+ setAudioManager,
+ playSfx,
+ playMusic,
+ };
+}
+
+export default hasAudio;
diff --git a/src/components/hasCamera.js b/src/components/hasCamera.js
deleted file mode 100644
index 9e6338d..0000000
--- a/src/components/hasCamera.js
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/**
- * Camera abstraction.
- */
-const hasCamera = function hasCameraFunc(state) {
- let camera;
-
- function create() {
- camera = state.scene.cameras.main;
- }
-
- function setMainCamera(cam) {
- camera = cam;
- }
-
- function getCamera() {
- return camera;
- }
-
- function setViewport(x, y, w, h) {
- if (!camera) return;
- camera.setViewport(x, y, w, h);
- }
-
- function setZoom(zoom) {
- if (!camera) return;
- camera.setZoom(zoom);
- }
-
- function setSize(x, y) {
- if (!camera) return;
- camera.setSize(x, y);
- }
-
- return {
- create,
- getCamera,
- setMainCamera,
- setViewport,
- setZoom,
- setSize,
- };
-};
-
-export default hasCamera;
diff --git a/src/components/hasCamera.ts b/src/components/hasCamera.ts
new file mode 100644
index 0000000..f3e4fbb
--- /dev/null
+++ b/src/components/hasCamera.ts
@@ -0,0 +1,54 @@
+import { ExtendedPhaserScene, LifeCycle } from "./isScene";
+
+export interface Camera extends LifeCycle {
+ getCamera: () => Phaser.Cameras.Scene2D.Camera;
+ setMainCamera: (cam: Phaser.Cameras.Scene2D.Camera) => void;
+ setViewport: (x: number, y: number, w: number, h: number) => void;
+ setZoom: (zoom: number) => void;
+ setSize: (x: number, y: number) => void;
+ scene: ExtendedPhaserScene;
+}
+/**
+ * Camera abstraction.
+ */
+const hasCamera = function hasCameraFunc(state: Camera) {
+ let camera: Phaser.Cameras.Scene2D.Camera | undefined;
+
+ function create() {
+ camera = state.scene.cameras.main;
+ }
+
+ function setMainCamera(cam: Phaser.Cameras.Scene2D.Camera) {
+ camera = cam;
+ }
+
+ function getCamera() {
+ return camera;
+ }
+
+ function setViewport(x: number, y: number, w: number, h: number) {
+ if (!camera) return;
+ camera.setViewport(x, y, w, h);
+ }
+
+ function setZoom(zoom: number) {
+ if (!camera) return;
+ camera.setZoom(zoom);
+ }
+
+ function setSize(x: number, y: number) {
+ if (!camera) return;
+ camera.setSize(x, y);
+ }
+
+ return {
+ create,
+ getCamera,
+ setMainCamera,
+ setViewport,
+ setZoom,
+ setSize,
+ };
+};
+
+export default hasCamera;
diff --git a/src/components/hasInput.js b/src/components/hasInput.js
deleted file mode 100644
index de4653b..0000000
--- a/src/components/hasInput.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-
-const hasInput = function hasInputFunc(state) {
- function getKeyboard() {
- return state.scene.manager.getScene(gameConfig.SCENES.GAME).getKeyboard();
- }
-
- return {
- getKeyboard,
- };
-};
-
-export default hasInput;
diff --git a/src/components/hasInput.ts b/src/components/hasInput.ts
new file mode 100644
index 0000000..b15e100
--- /dev/null
+++ b/src/components/hasInput.ts
@@ -0,0 +1,17 @@
+import { SCENES } from 'configs/gameConfig';
+import { SceneComponent } from './isScene';
+
+export interface Input extends SceneComponent {
+}
+
+function hasInput(state: Input) {
+ function getKeyboard() {
+ return state.scene.scene.manager.getScene(SCENES.GAME).input.keyboard;
+ }
+
+ return {
+ getKeyboard,
+ };
+}
+
+export default hasInput;
diff --git a/src/components/hasPosition.js b/src/components/hasPosition.js
deleted file mode 100644
index 7724e1b..0000000
--- a/src/components/hasPosition.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const hasPosition = function hasPositionFunc(state) {
- let x = 0;
- let y = 0;
-
- function setPosition({ x: xp, y: yp }) {
- x = xp;
- y = yp;
- return { x, y };
- }
-
- function setX(xp) {
- state.setPosition({ x: xp, y });
- return xp;
- }
-
- function setY(yp) {
- state.setPosition({ x, y: yp });
- return yp;
- }
-
- function getPosition() {
- return { x, y };
- }
-
- function getX() {
- return x;
- }
-
- function getY() {
- return y;
- }
-
- return {
- // props
- // methods
- setPosition,
- setX,
- setY,
- getPosition,
- getX,
- getY,
- };
-};
-
-export default hasPosition;
diff --git a/src/components/hasPosition.ts b/src/components/hasPosition.ts
new file mode 100644
index 0000000..87df9f9
--- /dev/null
+++ b/src/components/hasPosition.ts
@@ -0,0 +1,65 @@
+export interface Position {
+ x: number;
+ y: number;
+}
+
+export interface PositionComponent {
+ setPosition: (position: Position) => Position;
+ setX: (xp: number) => number;
+ setY: (yp: number) => number;
+ getPosition: () => Position;
+ getX: () => number;
+ getY: () => number;
+}
+
+function hasPosition(state: PositionComponent): PositionComponent {
+ let x = 0;
+ let y = 0;
+
+ function setPosition({ x: xp, y: yp }: Position): Position {
+ x = xp;
+ y = yp;
+ return { x, y };
+ }
+
+ function setX(xp: number): number {
+ state.setPosition({
+ x: xp,
+ y
+ });
+ return xp;
+ }
+
+ function setY(yp: number): number {
+ state.setPosition({
+ x,
+ y: yp
+ });
+ return yp;
+ }
+
+ function getPosition(): Position {
+ return { x, y };
+ }
+
+ function getX(): number {
+ return x;
+ }
+
+ function getY(): number {
+ return y;
+ }
+
+ return {
+ // props
+ // methods
+ setPosition,
+ setX,
+ setY,
+ getPosition,
+ getX,
+ getY,
+ };
+}
+
+export default hasPosition;
diff --git a/src/components/hasSize.js b/src/components/hasSize.js
deleted file mode 100644
index d69aa7a..0000000
--- a/src/components/hasSize.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const hasSize = function hasSizeFunc(state) {
- let width = 0;
- let height = 0;
-
- function setSize({ w: wp, h: hp }) {
- width = wp;
- height = hp;
-
- return { width, height };
- }
-
- function setWidth(wp) {
- state.setSize({ w: wp, h: height });
- return wp;
- }
-
- function setHeight(hp) {
- state.setSize({ w: width, h: hp });
- return hp;
- }
-
- function getSize() {
- return { w: width, h: height };
- }
-
- function getWidth() {
- return width;
- }
-
- function getHeight() {
- return height;
- }
-
- return {
- // props
- // methods
- setSize,
- setWidth,
- setHeight,
- getSize,
- getWidth,
- getHeight,
- };
-};
-
-export default hasSize;
diff --git a/src/components/hasSize.ts b/src/components/hasSize.ts
new file mode 100644
index 0000000..3b4bc79
--- /dev/null
+++ b/src/components/hasSize.ts
@@ -0,0 +1,66 @@
+export interface Size {
+ width: number;
+ height: number;
+}
+
+export interface SizeComponent {
+ setSize: (size: Size) => Size;
+ setWidth: (wp: number) => number;
+ setHeight: (hp: number) => number;
+ getSize: () => Size;
+ getWidth: () => number;
+ getHeight: () => number;
+}
+
+function hasSize(state: SizeComponent): SizeComponent {
+ let width = 0;
+ let height = 0;
+
+ function setSize({ width: wp, height: hp }: Size): Size {
+ width = wp;
+ height = hp;
+
+ return { width, height };
+ }
+
+ function setWidth(wp: number): number {
+ state.setSize({
+ width: wp,
+ height
+ });
+ return wp;
+ }
+
+ function setHeight(hp: number): number {
+ state.setSize({
+ width,
+ height: hp
+ });
+ return hp;
+ }
+
+ function getSize(): Size {
+ return { width, height };
+ }
+
+ function getWidth(): number {
+ return width;
+ }
+
+ function getHeight(): number {
+ return height;
+ }
+
+ return {
+ // props
+ // methods
+ setSize,
+ setWidth,
+ setHeight,
+ getSize,
+ getWidth,
+ getHeight,
+ };
+}
+
+export default hasSize;
diff --git a/src/components/isScene.js b/src/components/isScene.js
deleted file mode 100644
index 846b5a6..0000000
--- a/src/components/isScene.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import Phaser from 'phaser';
-
-/**
- * Phaser.Scene abstraction.
- * Init -> Preload -> Create -> Update -> Destroy
- */
-const isScene = function isSceneFunc(state, sceneKey) {
- if (!sceneKey) {
- throw new Error('Missing sceneKey');
- }
-
- const scene = new Phaser.Scene(sceneKey);
-
- // ------ Hook into phasers scene lifecycle -------
- scene.init = () => {
- // The ScenePlugin/Manager is not ready until init has run internally.
- state.sceneManager = scene.scene;
- if (state.init) state.init();
- };
-
- scene.preload = () => {
- if (state.preload) state.preload();
- };
-
- scene.create = () => {
- if (state.create) state.create();
- };
-
- scene.update = () => {
- if (state.update) state.update();
- };
-
-
- scene.destroy = () => {
- if (state.destroy) state.destroy();
- };
- // --------------------------------------
-
- function addScene(key, sceneRef, autoStart) {
- return state.sceneManager.add(key, sceneRef, autoStart);
- }
-
- function removeScene(sceneRef) {
- state.sceneManager.remove(sceneRef);
- }
-
- function addImage(x, y, key, frame = undefined) {
- return scene.add.image(x, y, key, frame);
- }
-
- function removeChild(key) {
- const child = scene[key];
- if (child) child.destroy();
- }
-
- return {
- sceneManager: undefined,
- scene,
- addScene,
- removeScene,
- addImage,
- removeChild,
- };
-};
-
-export default isScene;
diff --git a/src/components/isScene.ts b/src/components/isScene.ts
new file mode 100644
index 0000000..d681460
--- /dev/null
+++ b/src/components/isScene.ts
@@ -0,0 +1,89 @@
+import { SCENES } from 'configs/gameConfig';
+import Phaser from 'phaser';
+
+export interface LifeCycle {
+ init?: () => void
+ preload?: () => void
+ create?: () => void
+ update?: () => void
+ destroy?: () => void
+}
+
+export type ExtendedPhaserScene = Phaser.Scene & LifeCycle
+
+export interface SceneComponent extends LifeCycle {
+ sceneManager?: Phaser.Scenes.ScenePlugin;
+ scene: ExtendedPhaserScene;
+ addScene: (key: SCENES, sceneRef: ExtendedPhaserScene, autoStart: boolean) => Phaser.Scene | undefined | null;
+ removeScene: (sceneRef: ExtendedPhaserScene) => void;
+ addImage: (x: number, y: number, key: string, frame?: string) => Phaser.GameObjects.Image;
+ removeChild: (key: string) => void;
+}
+
+/**
+ * Phaser.Scene abstraction.
+ * Init -> Preload -> Create -> Update -> Destroy
+ */
+function isScene(state: SceneComponent, sceneKey: SCENES): SceneComponent {
+ if (!sceneKey) {
+ throw new Error('Missing sceneKey');
+ }
+
+
+
+ const scene: ExtendedPhaserScene = new Phaser.Scene(sceneKey) as ExtendedPhaserScene;
+
+ // ------ Hook into phasers scene lifecycle -------
+ scene.init = () => {
+ // The ScenePlugin/Manager is not ready until init has run internally.
+ state.sceneManager = scene.scene;
+ if (state.init) state.init();
+ };
+
+ scene.preload = () => {
+ if (state.preload) state.preload();
+ };
+
+ scene.create = () => {
+ if (state.create) state.create();
+ };
+
+ scene.update = () => {
+ if (state.update) state.update();
+ };
+
+
+ scene.destroy = () => {
+ if (state.destroy) state.destroy();
+ };
+ // --------------------------------------
+
+ function addScene(key: SCENES, sceneRef: ExtendedPhaserScene, autoStart: boolean): Phaser.Scene | null | undefined {
+ return state.sceneManager?.add(key, sceneRef, autoStart);
+ }
+
+ function removeScene(sceneRef: ExtendedPhaserScene) {
+ state.sceneManager?.remove(sceneRef);
+ }
+
+ function addImage(x: number, y: number, key: string, frame?: string) {
+ return scene.add.image(x, y, key, frame);
+ }
+
+ function removeChild(key: string) {
+ const child = scene.children.getByName(key);
+ child?.removedFromScene()
+ if (child) child.destroy();
+ }
+
+ return {
+ sceneManager: undefined,
+ scene,
+ addScene,
+ removeScene,
+ addImage,
+ removeChild,
+ };
+}
+
+export default isScene;
diff --git a/src/configs/audioConfig.js b/src/configs/audioConfig.js
deleted file mode 100644
index 2a10028..0000000
--- a/src/configs/audioConfig.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- MUSIC: {
- BG_SCORE: {
- KEY: 'bg_score',
- PATH: 'assets/audio/Philipp_Weigl_-_06_-_Full_of_Stars.mp3',
- },
- },
- SFX: {
- COIN: {
- KEY: 'coin_sfx',
- PATH: 'assets/audio/coin.wav',
- },
- },
-};
diff --git a/src/configs/audioConfig.ts b/src/configs/audioConfig.ts
new file mode 100644
index 0000000..88c8fc1
--- /dev/null
+++ b/src/configs/audioConfig.ts
@@ -0,0 +1,27 @@
+export interface MusicInfo {
+ KEY: string;
+ PATH: string;
+}
+
+export type Music = { [key: string]: MusicInfo }
+
+export const MUSIC: Music = {
+ BG_SCORE: {
+ KEY: 'bg_score',
+ PATH: 'assets/audio/Philipp_Weigl_-_06_-_Full_of_Stars.mp3',
+ },
+}
+
+export interface SfxInfo {
+ KEY: string;
+ PATH: string;
+}
+
+export type Sfx = { [key: string]: SfxInfo }
+
+export const SFX: Sfx = {
+ COIN: {
+ KEY: 'coin_sfx',
+ PATH: 'assets/audio/coin.wav',
+ },
+}
diff --git a/src/configs/devConfig.js b/src/configs/devConfig.js
deleted file mode 100644
index 2a489d4..0000000
--- a/src/configs/devConfig.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export default {
- COMPOSITION_INFO: {
- ENABLE: false,
- ENABLE_FILTER: false,
- FILTER: [],
- ENABLE_FACTORY_FILTER: false,
- FACTORY_FILTER: ['Note'],
- },
-};
diff --git a/src/configs/devConfig.ts b/src/configs/devConfig.ts
new file mode 100644
index 0000000..1f82723
--- /dev/null
+++ b/src/configs/devConfig.ts
@@ -0,0 +1,7 @@
+export const COMPOSITION_INFO = {
+ ENABLE: false,
+ ENABLE_FILTER: false,
+ FILTER: [],
+ ENABLE_FACTORY_FILTER: false,
+ FACTORY_FILTER: ['Note'],
+};
diff --git a/src/configs/eventConfig.js b/src/configs/eventConfig.js
deleted file mode 100644
index e818780..0000000
--- a/src/configs/eventConfig.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- EVENTS: {
- GAME: {
- STARTED: 'game started',
- },
- },
-};
diff --git a/src/configs/eventConfig.ts b/src/configs/eventConfig.ts
new file mode 100644
index 0000000..0152aaf
--- /dev/null
+++ b/src/configs/eventConfig.ts
@@ -0,0 +1,47 @@
+export const EVENTS = {
+ GAME: {
+ STARTED: 'game_started',
+ },
+ OTHER: {
+ TEST: 'other_event'
+ },
+ KEYBOARD: {
+ KEYDOWN: 'keydown',
+ KEYUP: 'keyup',
+ },
+ BUTTON: {
+ CLICK: 'button_click'
+ }
+} as const;
+
+export interface GameStartedEvent {
+ welcomeMessage: string;
+}
+
+export interface OtherEvent {
+ test: string;
+}
+
+export interface KeyboardKeyUpEvent {
+ key: string;
+ repeat: boolean;
+ keyCode: number;
+}
+
+export interface KeyboardKeyDownEvent {
+ key: string;
+ repeat: boolean;
+ keyCode: number;
+}
+
+export interface ButtonClickEvent {
+ buttonName: string;
+}
+
+export interface EventData {
+ [EVENTS.GAME.STARTED]: GameStartedEvent;
+ [EVENTS.OTHER.TEST]: OtherEvent;
+ [EVENTS.KEYBOARD.KEYDOWN]: KeyboardKeyDownEvent;
+ [EVENTS.KEYBOARD.KEYUP]: KeyboardKeyUpEvent;
+ [EVENTS.BUTTON.CLICK]: ButtonClickEvent;
+}
diff --git a/src/configs/gameConfig.js b/src/configs/gameConfig.js
deleted file mode 100644
index b8cfe45..0000000
--- a/src/configs/gameConfig.js
+++ /dev/null
@@ -1,84 +0,0 @@
-export default {
- GAME: {
- VIEWHEIGHT: 1080,
- VIEWWIDTH: 1920,
- TITLE: 'Replace Me',
- },
- SCENES: {
- BOOT: 'game_boot',
- LOAD: 'game_load',
- GAME: 'game_game',
- UI: 'UI',
- },
- DEFAULT_TEXT_STYLE: {
- font: 'Roboto',
- fontSize: 20,
- fill: '#ffffff',
- smoothed: false,
- },
- UI_DEFAULT: {
- tint: 0xaaaaaa,
- },
- AUDIO: {
- musicKeys: ['bgScore'],
- sfxKeys: ['coinSfx'],
- },
- KEYS: {
- LEFT_ARROW: {
- CODE: 37,
- KEY: '',
- },
- UP_ARROW: {
- CODE: 38,
- KEY: '',
- },
- RIGHT_ARROW: {
- CODE: 39,
- KEY: '',
- },
- DOWN_ARROW: {
- CODE: 40,
- KEY: '',
- },
- Z: {
- CODE: 90,
- KEY: 'Z',
- },
- X: {
- CODE: 88,
- KEY: 'X',
- },
- COMMA: {
- CODE: 188,
- KEY: ',',
- },
- DOT: {
- CODE: 190,
- KEY: '.',
- },
- A: {
- CODE: 65,
- KEY: 'A',
- },
- S: {
- CODE: 83,
- KEY: 'S',
- },
- K: {
- CODE: 75,
- KEY: 'K',
- },
- L: {
- CODE: 76,
- KEY: 'L',
- },
- ENTER: {
- CODE: 13,
- KEY: '',
- },
- ESCAPE: {
- CODE: 27,
- KEY: '',
- },
- },
-};
diff --git a/src/configs/gameConfig.ts b/src/configs/gameConfig.ts
new file mode 100644
index 0000000..1e6b033
--- /dev/null
+++ b/src/configs/gameConfig.ts
@@ -0,0 +1,93 @@
+export enum GAME {
+ VIEWHEIGHT = 1080,
+ VIEWWIDTH = 1920,
+ TITLE = 'Replace Me',
+}
+export enum SCENES {
+ BOOT = 'game_boot',
+ LOAD = 'game_load',
+ GAME = 'game_game',
+ UI = 'UI',
+}
+export const DEFAULT_TEXT_STYLE = {
+ font: 'Roboto',
+ fontSize: 20,
+ fill: '#ffffff',
+ smoothed: false,
+}
+export const UI_DEFAULT = {
+ tint: 0xaaaaaa,
+}
+export const AUDIO = {
+ musicKeys: ['bgScore'],
+ sfxKeys: ['coinSfx'],
+}
+
+export interface KeyInfo {
+ CODE: number;
+ KEY: string;
+}
+
+export type KeyboardKeys = { [KEY in KeyboardKey]: KeyInfo }
+
+type KeyboardKey = "LEFT_ARROW" | "UP_ARROW" | "RIGHT_ARROW" | "DOWN_ARROW" | "Z" | "X" | "COMMA" | "DOT" | "A" | "S" | "K" | "L" | "ENTER" | "ESCAPE"
+
+export const KEYS: KeyboardKeys = {
+ LEFT_ARROW: {
+ CODE: 37,
+ KEY: '',
+ },
+ UP_ARROW: {
+ CODE: 38,
+ KEY: '',
+ },
+ RIGHT_ARROW: {
+ CODE: 39,
+ KEY: '',
+ },
+ DOWN_ARROW: {
+ CODE: 40,
+ KEY: '',
+ },
+ Z: {
+ CODE: 90,
+ KEY: 'Z',
+ },
+ X: {
+ CODE: 88,
+ KEY: 'X',
+ },
+ COMMA: {
+ CODE: 188,
+ KEY: ',',
+ },
+ DOT: {
+ CODE: 190,
+ KEY: '.',
+ },
+ A: {
+ CODE: 65,
+ KEY: 'A',
+ },
+ S: {
+ CODE: 83,
+ KEY: 'S',
+ },
+ K: {
+ CODE: 75,
+ KEY: 'K',
+ },
+ L: {
+ CODE: 76,
+ KEY: 'L',
+ },
+ ENTER: {
+ CODE: 13,
+ KEY: '',
+ },
+ ESCAPE: {
+ CODE: 27,
+ KEY: '',
+ },
+}
+
diff --git a/src/configs/spriteConfig.js b/src/configs/spriteConfig.js
deleted file mode 100644
index ad3e514..0000000
--- a/src/configs/spriteConfig.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- BACKGROUND: {
- KEY: 'background',
- PATH: 'assets/images/background.png',
- },
- SPEAKER: {
- KEY: 'speaker',
- PATH: 'assets/images/speaker.png',
- },
- SPEAKER_OFF: {
- KEY: 'speaker_off',
- PATH: 'assets/images/speaker-off.png',
- },
-};
diff --git a/src/configs/spriteConfig.ts b/src/configs/spriteConfig.ts
new file mode 100644
index 0000000..75841c3
--- /dev/null
+++ b/src/configs/spriteConfig.ts
@@ -0,0 +1,17 @@
+export interface SpriteConfig {
+ KEY: string;
+ PATH: string;
+}
+
+export const BACKGROUND: SpriteConfig = {
+ KEY: 'background',
+ PATH: 'assets/images/background.png',
+}
+export const SPEAKER: SpriteConfig = {
+ KEY: 'speaker',
+ PATH: 'assets/images/speaker.png',
+}
+export const SPEAKER_OFF: SpriteConfig = {
+ KEY: 'speaker_off',
+ PATH: 'assets/images/speaker-off.png',
+}
diff --git a/src/core/createAudioManager.js b/src/core/createAudioManager.js
deleted file mode 100644
index 48695e5..0000000
--- a/src/core/createAudioManager.js
+++ /dev/null
@@ -1,165 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-import spriteConfig from 'configs/spriteConfig';
-import audioConfig from 'configs/audioConfig';
-import createState from 'utils/createState';
-
-const createAudioManager = function createAudioManagerFunc(parentScene) {
- if (!parentScene) throw new Error('A parent scene must be specified.');
-
- const state = {};
-
- let scene = parentScene;
- let muteIcon;
- let currentSong;
-
- const muteIdentifier = `${gameConfig.GAME.TITLE.replace(/ /g, '_')}_isMuted`; // replace all spaces with _ for safety
- const soundEffects = new Map();
- const music = new Map();
- const currentVolume = 0.7;
- const defaultSongKey = audioConfig.MUSIC.BG_SCORE.KEY;
-
- function _updateMute() {
- if (state.isAudioMuted()) {
- muteIcon.setTexture(spriteConfig.SPEAKER_OFF.KEY);
- scene.sound.mute = true;
- } else {
- muteIcon.setTexture(spriteConfig.SPEAKER.KEY);
- scene.sound.mute = false;
- }
- }
-
- function _setupMute() {
- muteIcon = scene.add.image(1850, 1040, spriteConfig.SPEAKER.KEY);
- muteIcon.setScrollFactor(0);
- muteIcon.tint = gameConfig.UI_DEFAULT.tint;
- muteIcon.depth = 3;
- muteIcon.setInteractive();
- muteIcon.on('pointerup', state.toggleMute, state);
-
- _updateMute();
- }
-
- function __constructor() {
- _setupMute();
-
- Object.keys(audioConfig.MUSIC).forEach((objKey) => {
- const MUSIC = audioConfig.MUSIC[objKey];
- music.set(MUSIC.KEY, scene.sound.add(MUSIC.KEY));
- });
-
- Object.keys(audioConfig.SFX).forEach((objKey) => {
- const SFX = audioConfig.SFX[objKey];
- soundEffects.set(SFX.KEY, scene.sound.add(SFX.KEY));
- });
-
- state.setPauseOnBlur(true);
-
- return state;
- }
-
- function setScene(newScene) {
- // TODO move from old to new, if scene is already defined
- scene = newScene;
- return state;
- }
-
- function setPauseOnBlur(pauseOnBlur) {
- if (scene) {
- scene.sound.pauseOnBlur = pauseOnBlur; // Keep audio playing even when losing focus.
- }
- return state;
- }
-
- function playSfx(key) {
- if (soundEffects.has(key)) {
- console.log('playing', key);
- soundEffects.get(key).play();
- }
- }
-
- function pauseMusic() {
- if (currentSong) {
- currentSong.pause();
- }
- state.isMusicPlaying = false;
- }
-
- function playMusic(key = defaultSongKey) {
- if (!state.isMusicPlaying && music.has(key)) {
- currentSong = music.get(key);
- currentSong.volume = currentVolume;
- currentSong.play();
- state.isMusicPlaying = true;
- }
- }
-
- function stopMusic() {
- if (currentSong) {
- currentSong.stop();
- currentSong = null;
- }
- state.isMusicPlaying = false;
- }
-
- function getCurrentVolume() {
- return currentVolume;
- }
-
- function getCurrentSong() {
- return currentSong;
- }
-
- function getAudioContext(key = defaultSongKey) {
- return music.get(key).source.context;
- }
-
- function getAudioSource(key = defaultSongKey) {
- return music.get(key).source;
- }
-
- function isAudioMuted() {
- return localStorage.getItem(muteIdentifier) === 'true';
- }
-
- function toggleMute() {
- const muteStatus = (!state.isAudioMuted()).toString();
- localStorage.setItem(muteIdentifier, muteStatus);
- _updateMute();
- }
-
- function destroy() {
- state.stopMusic();
- muteIcon.destroy();
- soundEffects.destroy();
- music.destroy();
- }
-
- const localState = {
- // props
- isMusicPlaying: false,
- // methods
- __constructor,
- playSfx,
- setScene,
- setPauseOnBlur,
- playMusic,
- pauseMusic,
- stopMusic,
- getAudioContext,
- getCurrentSong,
- getAudioSource,
- getCurrentVolume,
- isAudioMuted,
- toggleMute,
- destroy,
- };
-
- return createState('AudioManager', state, {
- localState,
- });
-};
-
-/**
- * Audio manager instance, there should only be one. Implementation may change.
- */
-export default createAudioManager;
diff --git a/src/core/createAudioManager.ts b/src/core/createAudioManager.ts
new file mode 100644
index 0000000..9016ce7
--- /dev/null
+++ b/src/core/createAudioManager.ts
@@ -0,0 +1,194 @@
+import { GAME, UI_DEFAULT } from 'configs/gameConfig';
+import { SPEAKER, SPEAKER_OFF } from 'configs/spriteConfig';
+import { MUSIC, SFX } from 'configs/audioConfig';
+import createState from 'utils/createState';
+import { ExtendedPhaserScene } from 'components/isScene';
+
+export interface AudioManager {
+ isMusicPlaying: boolean;
+
+ __constructor(): AudioManager,
+ playSfx(key: string): void,
+ setScene(newScene: ExtendedPhaserScene): AudioManager,
+ setPauseOnBlur(pauseOnBlur: boolean): AudioManager,
+ playMusic(key?: string): void,
+ pauseMusic(): void,
+ stopMusic(): void,
+ getAudioContext(key?: string): BaseAudioContext | undefined,
+ getCurrentSong: Phaser.Sound.NoAudioSound | Phaser.Sound.HTML5AudioSound | Phaser.Sound.WebAudioSound | undefined,
+ getAudioSource(key?: string): AudioBufferSourceNode | undefined,
+ getCurrentVolume(): number,
+ isAudioMuted(): boolean,
+ toggleMute(): void,
+ destroy(): void,
+}
+
+function createAudioManager(parentScene: ExtendedPhaserScene): AudioManager {
+ if (!parentScene) throw new Error('A parent scene must be specified.');
+
+ const state = {} as AudioManager;
+
+ let scene = parentScene;
+ let muteIcon: Phaser.GameObjects.Image;
+ let currentSong: Phaser.Sound.NoAudioSound | Phaser.Sound.HTML5AudioSound | Phaser.Sound.WebAudioSound | undefined;
+
+ const muteIdentifier = `${GAME.TITLE.replace(/ /g, '_')}_isMuted`; // replace all spaces with _ for safety
+ const soundEffectsMap = new Map();
+ const musicMap = new Map();
+ const currentVolume = 0.7;
+ const defaultSongKey = MUSIC.BG_SCORE.KEY;
+
+ function _updateMute() {
+ if (state.isAudioMuted()) {
+ muteIcon.setTexture(SPEAKER_OFF.KEY);
+ scene.sound.mute = true;
+ } else {
+ muteIcon.setTexture(SPEAKER.KEY);
+ scene.sound.mute = false;
+ }
+ }
+
+ function _setupMute() {
+ muteIcon = scene.add.image(1850, 1040, SPEAKER.KEY);
+ muteIcon.setScrollFactor(0);
+ muteIcon.tint = UI_DEFAULT.tint;
+ muteIcon.depth = 3;
+ muteIcon.setInteractive();
+ muteIcon.on('pointerup', state.toggleMute, state);
+
+ _updateMute();
+ }
+
+ function __constructor(): AudioManager {
+ _setupMute();
+
+ Object.keys(MUSIC).forEach((objKey) => {
+ const music = MUSIC[objKey];
+ musicMap.set(music.KEY, scene.sound.add(music.KEY));
+ });
+
+ Object.keys(SFX).forEach((objKey) => {
+ const sfx = SFX[objKey];
+ soundEffectsMap.set(sfx.KEY, scene.sound.add(sfx.KEY));
+ });
+
+ state.setPauseOnBlur(true);
+
+ return state;
+ }
+
+ function setScene(newScene: ExtendedPhaserScene): AudioManager {
+ // TODO move from old to new, if scene is already defined
+ scene = newScene;
+ return state;
+ }
+
+ function setPauseOnBlur(pauseOnBlur: boolean): AudioManager {
+ if (scene) {
+ scene.sound.pauseOnBlur = pauseOnBlur; // Keep audio playing even when losing focus.
+ }
+ return state;
+ }
+
+ function playSfx(key: string) {
+ if (soundEffectsMap.has(key)) {
+ console.log('playing', key);
+ const sfx = soundEffectsMap.get(key)
+ if (sfx) sfx.play();
+ }
+ }
+
+ function pauseMusic() {
+ if (currentSong) {
+ currentSong.pause();
+ }
+ state.isMusicPlaying = false;
+ }
+
+ function playMusic(key: string = defaultSongKey) {
+ if (!state.isMusicPlaying && musicMap.has(key)) {
+ currentSong = musicMap.get(key);
+ if (currentSong) {
+ currentSong.volume = currentVolume;
+ currentSong.play();
+ state.isMusicPlaying = true;
+ }
+ }
+ }
+
+ function stopMusic() {
+ if (currentSong) {
+ currentSong.stop();
+ currentSong = undefined;
+ }
+ state.isMusicPlaying = false;
+ }
+
+ function getCurrentVolume() {
+ return currentVolume;
+ }
+
+ function getCurrentSong() {
+ return currentSong;
+ }
+
+ function getAudioContext(key: string = defaultSongKey): BaseAudioContext | undefined {
+ const music = musicMap.get(key)
+ if (music && music instanceof Phaser.Sound.WebAudioSound) {
+ return music.source.context;
+ }
+ }
+
+ function getAudioSource(key: string = defaultSongKey): AudioBufferSourceNode | undefined {
+ const music = musicMap.get(key)
+ if (music && music instanceof Phaser.Sound.WebAudioSound) {
+ return music.source;
+ }
+ }
+
+ function isAudioMuted() {
+ return localStorage.getItem(muteIdentifier) === 'true';
+ }
+
+ function toggleMute() {
+ const muteStatus = (!state.isAudioMuted()).toString();
+ localStorage.setItem(muteIdentifier, muteStatus);
+ _updateMute();
+ }
+
+ function destroy() {
+ state.stopMusic();
+ muteIcon.destroy();
+ // soundEffects.destroy();
+ // music.destroy();
+ }
+
+ const localState = {
+ // props
+ isMusicPlaying: false,
+ // methods
+ __constructor,
+ playSfx,
+ setScene,
+ setPauseOnBlur,
+ playMusic,
+ pauseMusic,
+ stopMusic,
+ getAudioContext,
+ getCurrentSong,
+ getAudioSource,
+ getCurrentVolume,
+ isAudioMuted,
+ toggleMute,
+ destroy,
+ };
+
+ return createState('AudioManager', state, {
+ localState,
+ });
+}
+
+/**
+ * Audio manager instance, there should only be one. Implementation may change.
+ */
+export default createAudioManager;
diff --git a/src/core/createKeyboard.js b/src/core/createKeyboard.js
deleted file mode 100644
index 9b9d6b9..0000000
--- a/src/core/createKeyboard.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import canEmit from 'components/canEmit';
-import eventConfig from 'configs/eventConfig';
-import getFunctionUsage from 'utils/getFunctionUsage';
-
-const createKeyboardInput = function createKeyboardInputFunc() {
- const state = {};
-
- function keyDownFn(e) {
- state.emit(eventConfig.EVENTS.KEYBOARD.KEYDOWN, { key: e.key, repeat: e.repeat, keyCode: e.keyCode });
- }
-
- function keyUpFn(e) {
- state.emit(eventConfig.EVENTS.KEYBOARD.KEYUP, { key: e.key, repeat: e.repeat, keyCode: e.keyCode });
- }
-
- function enable() {
- document.addEventListener('keydown', keyDownFn);
- document.addEventListener('keyup', keyUpFn);
- }
-
- function disable() {
- document.removeEventListener('keydown', keyDownFn);
- document.removeEventListener('keyup', keyUpFn);
- }
-
- const localState = {
- // props
- // methods
- disable,
- enable,
- };
-
- const canEmitState = canEmit(state);
- const states = [{ state, name: 'state' }, { state: localState, name: 'localState' }, { state: canEmitState, name: 'canEmit' }];
- getFunctionUsage(states, 'Keyboard');
- return Object.assign(...states.map(s => s.state), {
- // pipes and overrides
- });
-};
-
-export default createKeyboardInput;
diff --git a/src/core/createKeyboard.ts b/src/core/createKeyboard.ts
new file mode 100644
index 0000000..bdf8ca5
--- /dev/null
+++ b/src/core/createKeyboard.ts
@@ -0,0 +1,44 @@
+import canEmit, { EmitComponent } from 'components/events/canEmit';
+import { EVENTS } from 'configs/eventConfig';
+import createState from 'utils/createState';
+
+export interface KeyboardInput extends EmitComponent {
+ disable: () => void;
+ enable: () => void;
+}
+
+function createKeyboardInput(): KeyboardInput {
+ const state = {} as KeyboardInput;
+
+ function keyDownFn(e: KeyboardEvent) {
+ state.emit(EVENTS.KEYBOARD.KEYDOWN, { key: e.key, repeat: e.repeat, keyCode: e.keyCode });
+ }
+
+ function keyUpFn(e: KeyboardEvent) {
+ state.emit(EVENTS.KEYBOARD.KEYUP, { key: e.key, repeat: e.repeat, keyCode: e.keyCode });
+ }
+
+ function enable() {
+ document.addEventListener(EVENTS.KEYBOARD.KEYDOWN, keyDownFn);
+ document.addEventListener(EVENTS.KEYBOARD.KEYUP, keyUpFn);
+ }
+
+ function disable() {
+ document.removeEventListener(EVENTS.KEYBOARD.KEYDOWN, keyDownFn);
+ document.removeEventListener(EVENTS.KEYBOARD.KEYUP, keyUpFn);
+ }
+
+ const localState = {
+ // props
+ // methods
+ disable,
+ enable,
+ };
+
+ return createState('KeyboardState', state, {
+ localState,
+ canEmit: canEmit(state),
+ });
+}
+
+export default createKeyboardInput;
diff --git a/src/core/createListener.js b/src/core/createListener.js
deleted file mode 100644
index 06e6378..0000000
--- a/src/core/createListener.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import getUUID from 'utils/getUUID';
-
-const createListener = function createListenerFunc(event, fn, once, emitState) {
- const state = {};
-
- function drop() {
- if (state.dropped) return;
- emitState.off(state);
- state.dropped = true;
- }
-
- return Object.assign(state, {
- // props
- id: getUUID(),
- dropped: false,
- once,
- event,
- fn: !once ? fn : (evt) => {
- fn(evt);
- state.drop();
- },
- // methods
- drop,
- });
-};
-
-export default createListener;
diff --git a/src/core/createListener.ts b/src/core/createListener.ts
new file mode 100644
index 0000000..2f73242
--- /dev/null
+++ b/src/core/createListener.ts
@@ -0,0 +1,38 @@
+import { EmitComponent } from 'components/events/canEmit';
+import { EventData } from 'configs/eventConfig';
+import { v4 as uuidv4 } from 'uuid';
+
+export interface Listener {
+ id: any;
+ dropped: boolean;
+ once: boolean;
+ event: string;
+ fn: (event: EventData[T]) => void;
+ drop: () => void;
+}
+
+function createListener(event: T, fn: (event: EventData[T]) => void, once: boolean, emitState: EmitComponent): Listener {
+ const state = {} as Listener;
+
+ function drop() {
+ if (state.dropped) return;
+ emitState.off(state);
+ state.dropped = true;
+ }
+
+ return Object.assign(state, {
+ // props
+ id: uuidv4(),
+ dropped: false,
+ once,
+ event,
+ fn: !once ? fn : (evt: EventData[T]) => {
+ fn(evt);
+ state.drop();
+ },
+ // methods
+ drop,
+ });
+}
+
+export default createListener;
diff --git a/src/core/createLoadingBar.js b/src/core/createLoadingBar.js
deleted file mode 100644
index 60252d2..0000000
--- a/src/core/createLoadingBar.js
+++ /dev/null
@@ -1,112 +0,0 @@
-import hasPosition from 'components/hasPosition';
-import hasSize from 'components/hasSize';
-import pipe from 'utils/pipe';
-
-/**
- * A multipurpose loading bar that can be added to any scene.
- */
-const createLoadingBar = function createLoadingBarFunc(originalScene) {
- const state = {};
- const padding = 2;
- const textPaddingFromBar = 10;
- const parentScene = originalScene;
-
- let loaderBg;
- let progressBar;
- let text;
- let currentProgress = 0;
-
- /**
- * @private
- */
- function updateProgressBar(progress) {
- currentProgress = progress;
- const pos = state.getPosition();
- progressBar.clear();
- progressBar.fillStyle(0xcccccc, 1);
- progressBar.fillRect(
- pos.x - state.getWidth() / 2,
- pos.y - state.getHeight() / 2,
- state.getWidth() * currentProgress,
- state.getHeight(),
- );
- }
-
- function onChange() {
- const pos = state.getPosition();
- loaderBg.clear();
- loaderBg.fillStyle(0x444444, 1);
- loaderBg.fillRect(
- pos.x - state.getWidth() / 2 - padding,
- pos.y - state.getHeight() / 2 - padding,
- state.getWidth() + padding * 2,
- state.getHeight() + padding * 2,
- );
-
- progressBar.clear();
- progressBar.fillStyle(0xcccccc, 1);
- progressBar.fillRect(
- pos.x - state.getWidth() / 2,
- pos.y - state.getHeight() / 2,
- state.getWidth() * currentProgress,
- state.getHeight(),
- );
-
- text.x = pos.x;
- text.y = pos.y - (text.height + textPaddingFromBar);
- }
-
- /**
- * @constructor
- * @private
- */
- function init() {
- const pos = state.getPosition();
- loaderBg = parentScene.add.graphics();
- progressBar = parentScene.add.graphics();
- text = parentScene.add.text(pos.x, pos.y, 'Loading...', {
- font: '16px Arial',
- fill: '#eeeeee',
- align: 'center',
- });
- text.setOrigin(0.5, 1);
- text.y -= text.height + textPaddingFromBar;
-
- parentScene.load.on('progress', updateProgressBar, state);
- }
-
- function destroy() {
- if (loaderBg) loaderBg.destroy();
- if (progressBar) progressBar.destroy();
- if (text) text.destroy();
- }
-
- const hasPositionState = hasPosition(state);
- const hasSizeState = hasSize(state);
- const localState = {
- destroy,
- };
-
- const states = [
- { state, name: 'state' },
- { state: localState, name: 'localState' },
- { state: hasPositionState, name: 'hasPosition' },
- { state: hasSizeState, name: 'hasSize' },
- ];
-
- const returnState = Object.assign(...states.map(s => s.state), {
- // overrides and pipes.
- setPosition: pipe(
- hasPositionState.setPosition,
- onChange,
- ),
- setSize: pipe(
- hasSizeState.setSize,
- onChange,
- ),
- });
-
- init();
- return returnState;
-};
-export default createLoadingBar;
diff --git a/src/core/createLoadingBar.ts b/src/core/createLoadingBar.ts
new file mode 100644
index 0000000..3da965f
--- /dev/null
+++ b/src/core/createLoadingBar.ts
@@ -0,0 +1,123 @@
+import hasPosition, { Position, PositionComponent } from 'components/hasPosition';
+import hasSize, { Size, SizeComponent } from 'components/hasSize';
+import { ExtendedPhaserScene, LifeCycle } from 'components/isScene';
+import createState from 'utils/createState';
+import pipe from 'utils/pipe';
+
+export interface LoadingBar extends PositionComponent, SizeComponent, LifeCycle { }
+
+/**
+ * A multipurpose loading bar that can be added to any scene.
+ */
+const createLoadingBar = function createLoadingBarFunc(originalScene: ExtendedPhaserScene): LoadingBar {
+ const state = {} as LoadingBar;
+ const padding = 2;
+ const textPaddingFromBar = 10;
+ const parentScene = originalScene;
+
+ let loaderBg: Phaser.GameObjects.Graphics | undefined;
+ let progressBar: Phaser.GameObjects.Graphics | undefined;
+ let text: Phaser.GameObjects.Text | undefined;
+ let currentProgress = 0;
+
+ /**
+ * @private
+ */
+ function updateProgressBar(progress: number) {
+ currentProgress = progress;
+ const pos = state.getPosition();
+ if (progressBar) {
+ progressBar.clear();
+ progressBar.fillStyle(0xcccccc, 1);
+ progressBar.fillRect(
+ pos.x - state.getWidth() / 2,
+ pos.y - state.getHeight() / 2,
+ state.getWidth() * currentProgress,
+ state.getHeight(),
+ );
+ }
+ }
+
+ function onChange() {
+ const pos = state.getPosition();
+ if (loaderBg) {
+ loaderBg.clear();
+ loaderBg.fillStyle(0x444444, 1);
+ loaderBg.fillRect(
+ pos.x - state.getWidth() / 2 - padding,
+ pos.y - state.getHeight() / 2 - padding,
+ state.getWidth() + padding * 2,
+ state.getHeight() + padding * 2,
+ );
+ }
+
+ if (progressBar) {
+ progressBar.clear();
+ progressBar.fillStyle(0xcccccc, 1);
+ progressBar.fillRect(
+ pos.x - state.getWidth() / 2,
+ pos.y - state.getHeight() / 2,
+ state.getWidth() * currentProgress,
+ state.getHeight(),
+ );
+ }
+
+ if (text) {
+ text.x = pos.x;
+ text.y = pos.y - (text.height + textPaddingFromBar);
+ }
+ }
+
+ /**
+ * @constructor
+ * @private
+ */
+ function init() {
+ const pos = state.getPosition();
+ loaderBg = parentScene.add.graphics();
+ progressBar = parentScene.add.graphics();
+ text = parentScene.add.text(pos.x, pos.y, 'Loading...', {
+ font: '16px Arial',
+ backgroundColor: '#eeeeee',
+ align: 'center',
+ });
+ text.setOrigin(0.5, 1);
+ text.y -= text.height + textPaddingFromBar;
+
+ parentScene.load.on('progress', updateProgressBar, state);
+ }
+
+ function destroy() {
+ if (loaderBg) loaderBg.destroy();
+ if (progressBar) progressBar.destroy();
+ if (text) text.destroy();
+ }
+
+ const localState = {
+ destroy,
+ setSize: (size: Size): Size => {
+ onChange();
+ return size;
+ },
+ setPosition: (pos: Position): Position => {
+ onChange();
+ return pos;
+ }
+ };
+
+ const hasPositionState = hasPosition(state)
+ const hasSizeState = hasSize(state)
+
+ const returnState = createState('LoadingBar', state, {
+ localState,
+ hasPosition: hasPositionState,
+ hasSize: hasSizeState,
+ }, {
+ setSize: pipe(hasSizeState.setSize, localState.setSize),
+ setPosition: pipe(hasPositionState.setPosition, localState.setPosition),
+ });
+
+ init();
+ return returnState;
+};
+export default createLoadingBar;
diff --git a/src/core/createMessageBus.js b/src/core/createMessageBus.ts
similarity index 55%
rename from src/core/createMessageBus.js
rename to src/core/createMessageBus.ts
index d70572e..113e5f3 100644
--- a/src/core/createMessageBus.js
+++ b/src/core/createMessageBus.ts
@@ -1,8 +1,11 @@
-import canEmit from 'components/events/canEmit';
+import canEmit, { EmitComponent } from 'components/events/canEmit';
import createState from 'utils/createState';
-const createMessageBus = function createMessageBusFunc() {
- const state = {};
+export interface MessageBus extends EmitComponent {
+}
+
+function createMessageBus(): MessageBus {
+ const state = {} as MessageBus;
const localState = {
// props
@@ -13,6 +16,6 @@ const createMessageBus = function createMessageBusFunc() {
localState,
canEmit: canEmit(state),
});
-};
+}
export default createMessageBus;
diff --git a/src/entities/createButton.js b/src/entities/createButton.ts
similarity index 53%
rename from src/entities/createButton.js
rename to src/entities/createButton.ts
index 73bea99..e20b224 100644
--- a/src/entities/createButton.js
+++ b/src/entities/createButton.ts
@@ -1,30 +1,35 @@
-import canEmit from 'components/events/canEmit';
-import hasSize from 'components/hasSize';
-import hasPosition from 'components/hasPosition';
+import canEmit, { EmitComponent } from 'components/events/canEmit';
+import hasSize, { Size, SizeComponent } from 'components/hasSize';
+import hasPosition, { Position, PositionComponent } from 'components/hasPosition';
import pipe from 'utils/pipe';
-import eventConfig from 'configs/eventConfig';
import createState from 'utils/createState';
+import { EVENTS } from 'configs/eventConfig';
-const createButton = function createButtonFunc(parent) {
- const state = {};
+export interface Button extends EmitComponent, PositionComponent, SizeComponent {
+ refresh: () => void;
+ setText: (val: string) => void;
+}
+
+const createButton = function createButtonFunc(parent: Phaser.Scene): Button {
+ const state = {} as Button;
const parentState = parent;
- let background;
- let zone;
+ let background: Phaser.GameObjects.Graphics | undefined;
+ let zone: Phaser.GameObjects.Zone | undefined;
let text = 'My Button';
- let textElem;
+ let textElem: Phaser.GameObjects.Text | undefined;
function init() {
state.refresh();
}
- function setText(val) {
+ function setText(val: string) {
text = val;
state.refresh();
}
- function onClick(e) {
- state.emit(eventConfig.EVENTS.BUTTON.CLICK, e);
+ function onClick(e: any) {
+ state.emit(EVENTS.BUTTON.CLICK, e);
}
function refresh() {
@@ -40,13 +45,13 @@ const createButton = function createButtonFunc(parent) {
background.strokeRect(state.getX(), state.getY(), state.getWidth(), state.getHeight());
background.fillRect(state.getX(), state.getY(), state.getWidth(), state.getHeight());
- zone.input.hitArea.setTo(state.getX(), state.getY(), state.getWidth(), state.getHeight());
- zone.setInteractive();
+ zone?.input?.hitArea.setTo(state.getX(), state.getY(), state.getWidth(), state.getHeight());
+ zone?.setInteractive();
if (!textElem) {
textElem = parent.add.text(0, 0, '', {
font: '64px Arial',
- fill: '#eeeeee',
+ backgroundColor: '#eeeeee',
align: 'center',
});
}
@@ -80,27 +85,34 @@ const createButton = function createButtonFunc(parent) {
setText,
refresh,
destroy,
+ setPosition: (pos: Position): Position => {
+ state.refresh();
+ return pos;
+ },
+ setSize: (size: Size): Size => {
+ state.refresh();
+ return size;
+ }
};
- const states = {
+
+ const hasPositionState = hasPosition(state)
+ const hasSizeState = hasSize(state)
+ return createState('Button', state, {
localState,
canEmit: canEmit(state),
- hasPosition: hasPosition(state),
- hasSize: hasSize(state),
- };
- const overrides = {
- // overrides
- // manual pipe because the functions doesn't have the same name, and order of execution is important
+ hasPosition: hasPositionState,
+ hasSize: hasSizeState,
+ }, {
setPosition: pipe(
- states.hasPosition.setPosition,
- localState.refresh,
+ hasPositionState.setPosition,
+ localState.setPosition
),
setSize: pipe(
- states.hasSize.setSize,
- localState.refresh,
+ hasSizeState.setSize,
+ localState.setSize
),
- };
- return createState('createButton', state, states, overrides);
+ });
};
export default createButton;
diff --git a/src/entities/createPlayer.js b/src/entities/createPlayer.ts
similarity index 58%
rename from src/entities/createPlayer.js
rename to src/entities/createPlayer.ts
index 2efb070..709badd 100644
--- a/src/entities/createPlayer.js
+++ b/src/entities/createPlayer.ts
@@ -1,16 +1,21 @@
-import isGameEntity from 'components/entities/isGameEntity';
-import canEmit from 'components/events/canEmit';
-import hasPosition from 'components/hasPosition';
+import isGameEntity, { GameEntityState } from 'components/entities/isGameEntity';
+import canEmit, { EmitComponent } from 'components/events/canEmit';
+import hasPosition, { PositionComponent } from 'components/hasPosition';
import createState from 'utils/createState';
-import hasAudio from 'components/hasAudio';
-import audioConfig from 'configs/audioConfig';
+import hasAudio, { Audio } from 'components/hasAudio';
+import { SFX } from 'configs/audioConfig';
-const createPlayer = function createPlayerFunc() {
+export interface Player extends PositionComponent, Audio, EmitComponent, GameEntityState {
+ name: string;
+ printInfo: () => void;
+}
+
+const createPlayer = function createPlayerFunc(): Player {
// variables and functions here are private unless listed below in localState.
- const state = {};
+ const state = {} as Player;
function __constructor() {
- state.playSfx(audioConfig.SFX.COIN.KEY);
+ state.playSfx(SFX.COIN.KEY);
}
function printInfo() {
diff --git a/src/entities/createTriggerZone.js b/src/entities/createTriggerZone.js
deleted file mode 100644
index 24e7588..0000000
--- a/src/entities/createTriggerZone.js
+++ /dev/null
@@ -1,92 +0,0 @@
-import Phaser from 'phaser';
-import hasPosition from 'components/hasPosition';
-import hasSize from 'components/hasSize';
-import isGameEntity from 'components/entities/isGameEntity';
-import createState from 'utils/createState';
-
-const createTriggerZone = function createTriggerZoneFunc(originalScene) {
- const state = {};
-
- let parentScene = originalScene;
- let triggerZone = new Phaser.GameObjects.Zone(parentScene, 0, 0, 0, 0);
- const overlapsWith = [];
- const overlappedEntities = [];
-
- function setScene(newScene) {
- parentScene = newScene;
- triggerZone.destroy();
- const { x, y } = state.getPosition();
-
- triggerZone = new Phaser.GameObjects.Zone(parentScene, x, y, state.getWidth(), state.getHeight());
- }
-
- function setSize(size) {
- triggerZone.setSize(size.w, size.h);
- return size;
- }
-
- function setPosition(pos) {
- triggerZone.setPosition(pos.x, pos.y);
- return pos;
- }
-
- function setOverlaps(bodies) {
- overlapsWith.length = 0;
- overlapsWith.splice(0, 0, bodies);
- }
-
- function addOverlapBody(body) {
- overlapsWith.push(body);
- }
-
- function isOverlappedByAny() {
- return overlappedEntities.length > 0;
- }
-
- /**
- * It should be possible to optimize state to avoid a double loop (or is it?).
- */
- function update() {
- const previous = overlappedEntities;
- overlappedEntities.length = 0;
- parentScene.physics.overlap(triggerZone, overlapsWith, (zone, entity) => {
- overlappedEntities.push(entity);
- });
-
- overlappedEntities.forEach((entity) => {
- if (previous.indexOf(entity) === -1) {
- state.onEntityEnteredRange(entity);
- }
- });
-
- // If an entity was overlapped previously, but no longer, we emit an exit event.
- previous.forEach((entity) => {
- if (overlappedEntities.indexOf(entity) === -1) {
- state.onEntityLeftRange(entity);
- }
- });
- }
-
- const localState = {
- // props
- // methods
- setScene,
- setSize,
- setPosition,
- setOverlaps,
- addOverlapBody,
- isOverlappedByAny,
- update,
- onEntityLeftRange: e => e,
- onEntityEnteredRange: e => e,
- };
-
- return createState('createTriggerZone', state, {
- localState,
- isGameEntity: isGameEntity(state),
- hasPosition: hasPosition(state),
- hasSize: hasSize(state),
- });
-};
-
-export default createTriggerZone;
diff --git a/src/fullscreen.js b/src/fullscreen.js
deleted file mode 100644
index 425e1dc..0000000
--- a/src/fullscreen.js
+++ /dev/null
@@ -1,25 +0,0 @@
-document.getElementById('fullscreen_toggle').onclick = () => {
- if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- } else {
- const element = document.getElementById('game');
- // const element = document.getElementsByTagName('canvas')[0];
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- }
- }
-};
diff --git a/src/fullscreen.ts b/src/fullscreen.ts
new file mode 100644
index 0000000..d15f88e
--- /dev/null
+++ b/src/fullscreen.ts
@@ -0,0 +1,30 @@
+const toggle = document?.getElementById('fullscreen_toggle')
+if (toggle) {
+ toggle.onclick = () => {
+ if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen();
+ } else if (document.webkitExitFullscreen) {
+ document.webkitExitFullscreen();
+ } else if (document.msExitFullscreen) {
+ document.msExitFullscreen();
+ }
+ } else {
+ const element = document.getElementById('game');
+ if (element) {
+ // const element = document.getElementsByTagName('canvas')[0];
+ if (element.requestFullscreen) {
+ element.requestFullscreen();
+ } else if (element.mozRequestFullScreen) {
+ element.mozRequestFullScreen();
+ } else if (element.webkitRequestFullscreen) {
+ element.webkitRequestFullscreen();
+ } else if (element.msRequestFullscreen) {
+ element.msRequestFullscreen();
+ }
+ }
+ }
+ };
+}
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 504a842..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import 'styles/main.scss';
-import Phaser from 'phaser';
-import gameConfig from 'configs/gameConfig';
-
-import BootScene from 'scenes/Boot';
-import LoadScene from 'scenes/Load';
-import Game from 'scenes/Game';
-import resizeCanvas from 'utils/resizeCanvas';
-import store from './store';
-import createMessageBus from 'core/createMessageBus';
-
-const phaserConfig = {
- type: Phaser.WEBGL,
- width: gameConfig.GAME.VIEWWIDTH,
- height: gameConfig.GAME.VIEWHEIGHT,
- backgroundColor: '#555555',
- parent: 'game',
- scene: [BootScene().scene, LoadScene().scene, Game().scene],
-};
-
-const game = new Phaser.Game(phaserConfig);
-store.messageBus = createMessageBus();
-store.game = game;
-
-window.addEventListener('resize', resizeCanvas);
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..f63b86e
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,54 @@
+import 'styles/main.scss';
+import Phaser from 'phaser';
+import { GAME } from 'configs/gameConfig';
+
+import BootScene from 'scenes/Boot';
+import LoadScene from 'scenes/Load';
+import Game from 'scenes/Game';
+import resizeCanvas from 'utils/resizeCanvas';
+import store from './store';
+import createMessageBus from 'core/createMessageBus';
+import sayHello from 'utils/sayHello';
+
+declare global {
+ interface Window {
+ }
+ interface Document {
+ msFullscreenElement?: Element;
+ webkitFullscreenElement?: Element;
+ mozFullScreenElement?: Element;
+ webkitExitFullscreen?: () => void;
+ mozCancelFullScreen?: () => void;
+ msExitFullscreen?: () => void;
+ mozRequestFullScreen?: () => void;
+ webkitRequestFullscreen?: () => void;
+ msRequestFullscreen?: () => void;
+ }
+
+ interface Element {
+ mozRequestFullScreen?: () => void;
+ webkitRequestFullscreen?: () => void;
+ msRequestFullscreen?: () => void;
+ }
+
+ export const GAME_BRANCH: string;
+ export const GAME_VERSION: string;
+ export const GAME_TIMESTAMP: string;
+ export const IS_DEV: boolean;
+}
+
+sayHello();
+const phaserConfig = {
+ type: Phaser.WEBGL,
+ width: GAME.VIEWWIDTH,
+ height: GAME.VIEWHEIGHT,
+ backgroundColor: '#555555',
+ parent: 'game',
+ scene: [BootScene().scene, LoadScene().scene, Game().scene],
+};
+
+const game = new Phaser.Game(phaserConfig);
+store.messageBus = createMessageBus();
+store.game = game;
+
+window.addEventListener('resize', resizeCanvas);
diff --git a/src/scenes/Boot.js b/src/scenes/Boot.js
deleted file mode 100644
index 6db624c..0000000
--- a/src/scenes/Boot.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-import resizeCanvas from 'utils/resizeCanvas';
-import isScene from 'components/isScene';
-import createState from 'utils/createState';
-import hasCamera from 'components/hasCamera';
-
-const BootScene = function BootSceneFunc() {
- const state = {};
-
- // hook into phasers scene lifecycle.
- function create() {
- resizeCanvas();
- state.setSize(gameConfig.GAME.VIEWWIDTH, gameConfig.GAME.VIEWHEIGHT);
- state.sceneManager.start(gameConfig.SCENES.LOAD);
- }
-
- const localState = {
- // methods
- create,
- };
-
- return createState('Boot', state, {
- localState,
- isScene: isScene(state, gameConfig.SCENES.BOOT),
- hasCamera: hasCamera(state),
- });
-};
-
-export default BootScene;
diff --git a/src/scenes/Boot.ts b/src/scenes/Boot.ts
new file mode 100644
index 0000000..67992c8
--- /dev/null
+++ b/src/scenes/Boot.ts
@@ -0,0 +1,31 @@
+import { GAME, SCENES } from 'configs/gameConfig';
+import resizeCanvas from 'utils/resizeCanvas';
+import isScene, { LifeCycle, SceneComponent } from 'components/isScene';
+import createState from 'utils/createState';
+import hasCamera, { Camera } from 'components/hasCamera';
+
+export interface BootScene extends SceneComponent, Camera, LifeCycle { }
+
+const BootScene = function BootSceneFunc() {
+ const state: BootScene = {} as BootScene;
+
+ // hook into phasers scene lifecycle.
+ function create() {
+ resizeCanvas();
+ state.setSize(GAME.VIEWWIDTH, GAME.VIEWHEIGHT);
+ state?.sceneManager?.start(SCENES.LOAD);
+ }
+
+ const localState = {
+ // methods
+ create,
+ };
+
+ return createState('Boot', state, {
+ localState,
+ isScene: isScene(state, SCENES.BOOT),
+ hasCamera: hasCamera(state),
+ });
+};
+
+export default BootScene;
diff --git a/src/scenes/Game.js b/src/scenes/Game.js
deleted file mode 100644
index ff4c5c8..0000000
--- a/src/scenes/Game.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-import spriteConfig from 'configs/spriteConfig';
-import AudioManager from 'core/createAudioManager';
-import createPlayer from 'entities/createPlayer';
-import UI from 'scenes/UI';
-import canListen from 'components/events/canListen';
-import isScene from 'components/isScene';
-import createState from 'utils/createState';
-import store from 'root/store';
-import hasCamera from 'components/hasCamera';
-
-/**
- * Responsible for delegating the various levels, holding the various core systems and such.
- */
-const Game = function GameFunc() {
- const state = {};
- let audioManager;
- let UIContainer;
- let background;
-
- function cameraSetup() {
- state.setViewport(0, 0, gameConfig.GAME.VIEWWIDTH, gameConfig.GAME.VIEWHEIGHT);
- state.setZoom(0.8);
- }
-
-
- function init() {
- // After assets are loaded.
- UIContainer = UI();
- state.addScene(gameConfig.SCENES.UI, UIContainer.scene, true);
- audioManager = AudioManager(UIContainer.scene);
- store.audioManager = audioManager;
- }
-
- function create() {
- background = state.addImage(0, 0, spriteConfig.BACKGROUND.KEY);
- background.setOrigin(0, 0);
- audioManager.playMusic();
- cameraSetup();
-
- const player = createPlayer();
- console.log(player);
- }
-
- function update(time, delta) {}
-
- function destroy() {
- if (background) state.removeChild(spriteConfig.BACKGROUND.KEY);
- if (UIContainer) UIContainer.destroy();
- }
-
- const localState = {
- // props
- // methods
- init,
- create,
- update,
- destroy,
- };
-
- return createState('Game', state, {
- localState,
- canListen: canListen(state),
- isScene: isScene(state, gameConfig.SCENES.GAME),
- hasCamera: hasCamera(state),
- });
-};
-
-export default Game;
diff --git a/src/scenes/Game.ts b/src/scenes/Game.ts
new file mode 100644
index 0000000..c8f68c8
--- /dev/null
+++ b/src/scenes/Game.ts
@@ -0,0 +1,70 @@
+import { GAME, SCENES } from 'configs/gameConfig';
+import { BACKGROUND } from 'configs/spriteConfig';
+import createAudioManager, { AudioManager } from 'core/createAudioManager';
+import createPlayer from 'entities/createPlayer';
+import UI, { UIScene } from 'scenes/UI';
+import canListen, { ListenComponent } from 'components/events/canListen';
+import isScene, { SceneComponent } from 'components/isScene';
+import createState from 'utils/createState';
+import store from 'root/store';
+import hasCamera, { Camera } from 'components/hasCamera';
+
+export interface GameScene extends SceneComponent, Camera, ListenComponent { }
+/**
+ * Responsible for delegating the various levels, holding the various core systems and such.
+ */
+function Game(): GameScene {
+ const state = {} as GameScene;
+ let audioManager: AudioManager | undefined;
+ let UIContainer: UIScene | undefined;
+ let background: Phaser.GameObjects.Image | undefined;
+
+ function cameraSetup() {
+ state.setViewport(0, 0, GAME.VIEWWIDTH, GAME.VIEWHEIGHT);
+ state.setZoom(0.8);
+ }
+
+
+ function init() {
+ // After assets are loaded.
+ UIContainer = UI();
+ state.addScene(SCENES.UI, UIContainer.scene, true);
+ audioManager = createAudioManager(UIContainer.scene);
+ store.audioManager = audioManager;
+ }
+
+ function create() {
+ background = state.addImage(0, 0, BACKGROUND.KEY);
+ background.setOrigin(0, 0);
+ audioManager?.playMusic();
+ cameraSetup();
+
+ const player = createPlayer();
+ console.log(player);
+ }
+
+ function update() { }
+
+ function destroy() {
+ if (background) state.removeChild(BACKGROUND.KEY);
+ if (UIContainer && UIContainer.destroy) UIContainer.destroy();
+ }
+
+ const localState = {
+ // props
+ // methods
+ init,
+ create,
+ update,
+ destroy,
+ };
+
+ return createState('Game', state, {
+ localState,
+ canListen: canListen(state),
+ isScene: isScene(state, SCENES.GAME),
+ hasCamera: hasCamera(state),
+ });
+}
+
+export default Game;
diff --git a/src/scenes/Load.js b/src/scenes/Load.js
deleted file mode 100644
index 217536b..0000000
--- a/src/scenes/Load.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-import createLoadingBar from 'core/createLoadingBar';
-import spriteConfig from 'configs/spriteConfig';
-import audioConfig from 'configs/audioConfig';
-import isScene from 'components/isScene';
-import createState from 'utils/createState';
-
-const LoadScene = function LoadSceneFunc() {
- const state = {};
- let loadingBar;
-
- function loadAudio() {
- // load MUSIC
- Object.keys(audioConfig.MUSIC).forEach((objKey) => {
- const AUDIO = audioConfig.MUSIC[objKey];
- state.scene.load.audio(AUDIO.KEY, AUDIO.PATH);
- });
-
- // load SFX
- Object.keys(audioConfig.SFX).forEach((objKey) => {
- const SFX = audioConfig.SFX[objKey];
- state.scene.load.audio(SFX.KEY, SFX.PATH);
- });
- }
-
- function loadSpritesheets() {}
-
- function loadMaps() {}
-
- function loadImages() {
- Object.keys(spriteConfig).forEach((objKey) => {
- const SPRITE = spriteConfig[objKey];
- state.scene.load.image(SPRITE.KEY, SPRITE.PATH);
- });
- }
-
- function loadAssets() {
- loadAudio();
- loadImages();
- loadSpritesheets();
- loadMaps();
- }
-
- // hook into phasers scene lifecycle.
- function preload() {
- loadingBar = createLoadingBar(state.scene);
- loadingBar.setPosition({ x: gameConfig.GAME.VIEWWIDTH / 2, y: gameConfig.GAME.VIEWHEIGHT / 2 });
- loadingBar.setSize({ w: gameConfig.GAME.VIEWWIDTH * 0.4, h: gameConfig.GAME.VIEWHEIGHT * 0.025 });
-
- state.scene.load.on('complete', () => {
- state.sceneManager.start(gameConfig.SCENES.GAME);
- state.scene.destroy();
- });
-
- loadAssets();
- }
-
- function destroy() {
- if (loadingBar) loadingBar.destroy();
- }
-
- const localState = {
- // props
- // methods
- preload,
- destroy,
- };
-
- return createState('LoadState', state, {
- localState,
- isScene: isScene(state, gameConfig.SCENES.LOAD),
- });
-};
-
-export default LoadScene;
diff --git a/src/scenes/Load.ts b/src/scenes/Load.ts
new file mode 100644
index 0000000..7030451
--- /dev/null
+++ b/src/scenes/Load.ts
@@ -0,0 +1,78 @@
+import { GAME, SCENES } from 'configs/gameConfig';
+import createLoadingBar, { LoadingBar } from 'core/createLoadingBar';
+import { MUSIC, SFX } from 'configs/audioConfig';
+import isScene, { SceneComponent } from 'components/isScene';
+import createState from 'utils/createState';
+import { BACKGROUND, SPEAKER, SPEAKER_OFF } from 'configs/spriteConfig';
+
+export interface LoadSceneState extends SceneComponent { }
+
+function LoadScene(): LoadSceneState {
+ const state = {} as LoadSceneState;
+ let loadingBar: LoadingBar | undefined;
+
+ function loadAudio() {
+ // load MUSIC
+ Object.keys(MUSIC).forEach((objKey) => {
+ const audio = MUSIC[objKey];
+ state.scene.load.audio(audio.KEY, audio.PATH);
+ });
+
+ // load SFX
+ Object.keys(SFX).forEach((objKey) => {
+ const sfx = SFX[objKey];
+ state.scene.load.audio(sfx.KEY, sfx.PATH);
+ });
+ }
+
+ function loadSpritesheets() { }
+
+ function loadMaps() { }
+
+ function loadImages() {
+ state.scene.load.image(BACKGROUND.KEY, BACKGROUND.PATH);
+ state.scene.load.image(SPEAKER.KEY, SPEAKER.PATH);
+ state.scene.load.image(SPEAKER_OFF.KEY, SPEAKER_OFF.PATH);
+ }
+
+ function loadAssets() {
+ loadAudio();
+ loadImages();
+ loadSpritesheets();
+ loadMaps();
+ }
+
+ // hook into phasers scene lifecycle.
+ function preload() {
+ loadingBar = createLoadingBar(state.scene);
+ loadingBar.setPosition({ x: GAME.VIEWWIDTH / 2, y: GAME.VIEWHEIGHT / 2 });
+ loadingBar.setSize({ width: GAME.VIEWWIDTH * 0.4, height: GAME.VIEWHEIGHT * 0.025 });
+
+ state.scene.load.on('complete', () => {
+ state.sceneManager?.start(SCENES.GAME);
+ if (state.scene && state.scene.destroy) {
+ state.scene.destroy();
+ }
+ });
+
+ loadAssets();
+ }
+
+ function destroy() {
+ if (loadingBar && loadingBar.destroy) loadingBar.destroy();
+ }
+
+ const localState = {
+ // props
+ // methods
+ preload,
+ destroy,
+ };
+
+ return createState('LoadState', state, {
+ localState,
+ isScene: isScene(state, SCENES.LOAD),
+ });
+}
+
+export default LoadScene;
diff --git a/src/scenes/UI.js b/src/scenes/UI.ts
similarity index 53%
rename from src/scenes/UI.js
rename to src/scenes/UI.ts
index 3cfe330..94cbf9b 100644
--- a/src/scenes/UI.js
+++ b/src/scenes/UI.ts
@@ -1,34 +1,40 @@
-import Stats from 'stats-js';
+import Stats from 'stats.js';
import * as dat from 'dat.gui';
-import gameConfig from 'configs/gameConfig';
-import isScene from 'components/isScene';
+import { SCENES } from 'configs/gameConfig';
+import isScene, { SceneComponent } from 'components/isScene';
import createState from 'utils/createState';
/**
* Layer/Scene for UI elements.
*/
-const UI = function UIFunc() {
- const state = {};
- let gui;
- let stats;
+export interface UIScene extends SceneComponent {
+ guiData: {
+ name: string;
+ };
+}
+
+function UI(): UIScene {
+ const state = {} as UIScene;
+ let gui: dat.GUI | undefined;
+ let stats: Stats | undefined;
function setupPerformanceStats() {
stats = new Stats();
- stats.setMode(0);
+ stats.showPanel(0);
- stats.domElement.style.position = 'absolute';
- stats.domElement.style.left = '0px';
- stats.domElement.style.top = '0px';
+ stats.dom.style.position = 'absolute';
+ stats.dom.style.left = '0px';
+ stats.dom.style.top = '0px';
- document.body.appendChild(stats.domElement);
+ document.body.appendChild(stats.dom);
// TODO cleanup listeners
state.scene.events.on('preupdate', () => {
- stats.begin();
+ stats?.begin();
});
state.scene.events.on('postupdate', () => {
- stats.end();
+ stats?.end();
});
}
@@ -51,12 +57,18 @@ const UI = function UIFunc() {
}
function destroy() {
- gui.destroy();
- stats.end();
- document.body.removeChild(stats);
+ gui?.destroy();
+ stats?.end();
+ if (stats?.dom) {
+ document.body.removeChild(stats.dom);
+ }
}
const localState = {
+ // props
+ guiData: {
+ name: ''
+ },
// methods
create,
destroy,
@@ -64,8 +76,8 @@ const UI = function UIFunc() {
return createState('UIScene', state, {
localState,
- isScene: isScene(state, gameConfig.SCENES.UI),
+ isScene: isScene(state, SCENES.UI),
});
-};
+}
export default UI;
diff --git a/src/store.js b/src/store.js
deleted file mode 100644
index 2342459..0000000
--- a/src/store.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const store = {};
-
-export default store;
diff --git a/src/store.ts b/src/store.ts
new file mode 100644
index 0000000..a58ed75
--- /dev/null
+++ b/src/store.ts
@@ -0,0 +1,12 @@
+import { AudioManager } from "core/createAudioManager";
+import { MessageBus } from "core/createMessageBus";
+
+export interface Store {
+ messageBus?: MessageBus;
+ game?: Phaser.Game;
+ audioManager?: AudioManager;
+}
+
+const store: Store = {};
+
+export default store;
diff --git a/src/utils/createState.js b/src/utils/createState.ts
similarity index 60%
rename from src/utils/createState.js
rename to src/utils/createState.ts
index fe1f33b..960a59f 100644
--- a/src/utils/createState.js
+++ b/src/utils/createState.ts
@@ -1,9 +1,15 @@
import getFunctionUsage from './getFunctionUsage';
import pipe from './pipe';
-const createState = function createStateFunc(className = 'MyClass', mainState = {}, states = {}, overrides = {}) {
- const stateList = [];
- const pipes = {};
+export interface State {
+ state: any;
+ name: string;
+}
+
+function createState(className = 'MyClass', mainState: T & { __constructor?: unknown}, states: { [key: string]: any } = {}, overrides = {}): T {
+ const stateList: Array = [];
+ const pipes: { [key: string]: Array<(a: unknown) => unknown> } = {};
+ const finishedPipes: { [key: string]: (a: unknown) => unknown } = {};
// Loop over all states (components).
Object.keys(states).forEach((stateKey) => {
@@ -13,24 +19,22 @@ const createState = function createStateFunc(className = 'MyClass', mainState =
name: stateKey,
});
- // Loop over all properties on the state object. If functions, store them away for now.
- Object.keys(state).forEach((propKey) => {
+ for(const propKey in state) {
if (typeof state[propKey] === 'function') {
if (!pipes[propKey]) {
pipes[propKey] = [];
}
- pipes[propKey].push(state[propKey]);
+ pipes[propKey].push(state[propKey] as (a: unknown) => unknown);
}
- });
+ }
+ // Loop over all properties on the state object. If functions, store them away for now.
});
// Loop over all functions stored in pipes, check for multiple usages of the same name.
// Automatically set up a pipe() structure for these.
Object.keys(pipes).forEach((propKey) => {
if (pipes[propKey].length > 1) {
- pipes[propKey] = pipe(...pipes[propKey]);
- } else {
- delete pipes[propKey];
+ finishedPipes[propKey] = pipe(...pipes[propKey]);
}
});
@@ -38,9 +42,9 @@ const createState = function createStateFunc(className = 'MyClass', mainState =
// Creates a piped init/constructor that runs each __constructor() function in the different states.
// This allows a created class/state to have a constructor that is ran at create time.
- const init = pipe(...stateList.map(s => s.state.__constructor).filter(c => c));
+ const init = pipe(...stateList.map(s => (s.state.__constructor as (a: unknown) => unknown)).filter(c => c));
- Object.assign(mainState, ...stateList.map(s => s.state), pipes, overrides);
+ Object.assign(mainState, ...stateList.map(s => s.state), finishedPipes, overrides);
// Cleans up any constructor still on the mainstate.
if (mainState.__constructor) {
@@ -48,9 +52,9 @@ const createState = function createStateFunc(className = 'MyClass', mainState =
}
// actually calls the piped init constructor from above.
- init();
+ init(undefined);
- return mainState;
-};
+ return mainState as T;
+}
export default createState;
diff --git a/src/utils/getFunctionUsage.js b/src/utils/getFunctionUsage.ts
similarity index 65%
rename from src/utils/getFunctionUsage.js
rename to src/utils/getFunctionUsage.ts
index 1589326..1764a58 100644
--- a/src/utils/getFunctionUsage.js
+++ b/src/utils/getFunctionUsage.ts
@@ -1,25 +1,26 @@
-import devConfig from 'configs/devConfig';
+import { COMPOSITION_INFO } from 'configs/devConfig';
+import { State } from './createState';
-const alreadyLogged = [];
+const alreadyLogged: Array = [];
/* eslint-disable */
-const updateFunctionUsage = function updateFunctionUsageFunc(name, state, functionMap) {
+const updateFunctionUsage = function updateFunctionUsageFunc(name: string, state: any, functionMap: Map>) {
for (const fun in state) {
if (functionMap.has(fun)) {
- functionMap.get(fun).push({ name });
+ functionMap.get(fun)?.push(name);
} else {
- functionMap.set(fun, [{ name }]);
+ functionMap.set(fun, [name]);
}
}
};
-const isInFilter = function isInFilterFunc(COMPOSITION_INFO, val, source) {
+const isInFilter = function isInFilterFunc(val: Array, source: string) {
let isInFilter = true;
if (COMPOSITION_INFO.ENABLE_FILTER) {
isInFilter = false;
if (COMPOSITION_INFO.FILTER) {
COMPOSITION_INFO.FILTER.every(f => {
- if (val.find(s => s.name === f)) {
+ if (val.find(s => s === f)) {
isInFilter = true;
return false;
}
@@ -37,25 +38,24 @@ const isInFilter = function isInFilterFunc(COMPOSITION_INFO, val, source) {
return isInFilter && inFactoryFilter;
};
-const getFunctionUsage = function getFunctionUsageFunc(states, source) {
+const getFunctionUsage = function getFunctionUsageFunc(states: Array, source: string) {
if (alreadyLogged.find(l => l === source)) {
return;
}
alreadyLogged.push(source);
- if (devConfig && devConfig.COMPOSITION_INFO && devConfig.COMPOSITION_INFO.ENABLE) {
- const { COMPOSITION_INFO } = devConfig;
+ if (COMPOSITION_INFO && COMPOSITION_INFO.ENABLE) {
// map all states
- const functionMap = new Map();
+ const functionMap = new Map>();
states.forEach(s => {
updateFunctionUsage(s.name, s.state, functionMap);
});
// print info
- functionMap.forEach((val, key, map) => {
- let inFilter = isInFilter(COMPOSITION_INFO, val, source);
+ functionMap.forEach((val, key) => {
+ let inFilter = isInFilter(val, source);
if (inFilter && val.length > 1) {
console.log(
- `%c${source} %cneeds to pipe %c${key} %c=>${val.reduce((acc, curr) => `${acc} ${curr.name},`, '')}`,
+ `%c${source} %cneeds to pipe %c${key} %c=>${val.reduce((acc: string, name: string) => `${acc} ${name},`, '')}`,
'color: yellow',
'color: inherits',
'color: yellow',
diff --git a/src/utils/getUUID.js b/src/utils/getUUID.js
deleted file mode 100644
index f30cb75..0000000
--- a/src/utils/getUUID.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* eslint-disable no-bitwise */
-
-/**
- * Taken from: https://stackoverflow.com/a/2117523
- */
-const getUUID = function getUIdFunc() {
- return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
- (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
-};
-/* eslint-enable no-bitwise */
-
-export default getUUID;
diff --git a/src/utils/pipe.js b/src/utils/pipe.ts
similarity index 52%
rename from src/utils/pipe.js
rename to src/utils/pipe.ts
index 2d93968..0b13c27 100644
--- a/src/utils/pipe.js
+++ b/src/utils/pipe.ts
@@ -1,6 +1,6 @@
-const pipe = function pipeFunc(...fns) {
- const emptyFunc = v => v;
+function pipe(...fns: Array<(t: T) => T>): (t: T) => T {
+ const emptyFunc: (t: T) => T = v => v;
return initialVal => fns.reduce((val, fn) => (fn ? fn(val) : emptyFunc(val)), initialVal);
-};
+}
export default pipe;
diff --git a/src/utils/resizeCanvas.js b/src/utils/resizeCanvas.js
deleted file mode 100644
index 3a84bbd..0000000
--- a/src/utils/resizeCanvas.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import gameConfig from 'configs/gameConfig';
-
-const resizeCanvas = function resizeCanvasFunc() {
- const canvas = document.querySelector('#game>canvas');
- const windowWidth = window.innerWidth;
- const windowHeight = window.innerHeight;
- const windowRatio = windowWidth / windowHeight;
- const gameRatio = gameConfig.GAME.VIEWWIDTH / gameConfig.GAME.VIEWHEIGHT;
- if (windowRatio < gameRatio) {
- canvas.style.width = `${windowWidth}px`;
- canvas.style.height = `${windowWidth / gameRatio}px`;
- } else {
- canvas.style.width = `${windowHeight * gameRatio}px`;
- canvas.style.height = `${windowHeight}px`;
- }
-};
-
-export default resizeCanvas;
diff --git a/src/utils/resizeCanvas.ts b/src/utils/resizeCanvas.ts
new file mode 100644
index 0000000..1db340d
--- /dev/null
+++ b/src/utils/resizeCanvas.ts
@@ -0,0 +1,20 @@
+import { GAME } from 'configs/gameConfig';
+
+const resizeCanvas = function resizeCanvasFunc() {
+ const canvas = document.querySelector('#game>canvas') as HTMLCanvasElement;
+ const windowWidth = window.innerWidth;
+ const windowHeight = window.innerHeight;
+ const windowRatio = windowWidth / windowHeight;
+ const gameRatio = GAME.VIEWWIDTH / GAME.VIEWHEIGHT;
+ if (canvas && canvas.style) {
+ if (windowRatio < gameRatio) {
+ canvas.style.width = `${windowWidth}px`;
+ canvas.style.height = `${windowWidth / gameRatio}px`;
+ } else {
+ canvas.style.width = `${windowHeight * gameRatio}px`;
+ canvas.style.height = `${windowHeight}px`;
+ }
+ }
+};
+
+export default resizeCanvas;
diff --git a/src/utils/sayHello.ts b/src/utils/sayHello.ts
new file mode 100644
index 0000000..97073d2
--- /dev/null
+++ b/src/utils/sayHello.ts
@@ -0,0 +1,16 @@
+export default function sayHello() {
+ if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
+ const args = [
+ ` %c %c %c v${GAME_VERSION}; ${GAME_BRANCH} - ${GAME_TIMESTAMP} %c %c`,
+ 'background: #99ddff; padding:5px 0;',
+ 'background: #99ddff; padding:5px 0;',
+ 'color: #99ddff; background: #030307; padding:5px 0;',
+ 'background: #99ddff; padding:5px 0;',
+ 'background: #99ddff; padding:5px 0;',
+ ];
+
+ window.console.log.apply(console, args);
+ } else if (window.console) {
+ window.console.log(`${GAME_VERSION}; ${GAME_BRANCH}; ${GAME_TIMESTAMP}`);
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7462087
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,67 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "target": "esnext",
+ "allowJs": true,
+ "declaration": true,
+ "useDefineForClassFields": true,
+ "outDir": "types",
+ "declarationMap": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "strict": true,
+ "jsx": "preserve",
+ "sourceMap": true,
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "experimentalDecorators": true,
+ "noEmit": true,
+ "skipLibCheck": true,
+ "paths": {
+ "configs*": [
+ "src/configs*"
+ ],
+ "core*": [
+ "src/core*"
+ ],
+ "styles*": [
+ "styles*"
+ ],
+ "assets*": [
+ "assets*"
+ ],
+ "scenes*": [
+ "src/scenes*"
+ ],
+ "entities*": [
+ "src/entities*"
+ ],
+ "components*": [
+ "src/components*"
+ ],
+ "utils*": [
+ "src/utils*"
+ ],
+ "root*": [
+ "src*"
+ ],
+ },
+ "lib": [
+ "esnext",
+ "dom"
+ ]
+ },
+ "include": [
+ "src/**/*",
+ // "test/vitest/**/*",
+ ],
+ "exclude": [
+ "types/**/*",
+ "node_modules/**/*"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..57bf760
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "module": "esnext",
+ "moduleResolution": "node"
+ },
+ "include": [
+ "vite.config.ts"
+ ]
+}
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..0465220
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,82 @@
+
+import { defineConfig, UserConfigFn, UserConfig } from 'vite';
+import stripCode from 'rollup-plugin-strip-code';
+import { resolve } from 'path';
+import { execSync } from 'child_process';
+import dts from 'vite-plugin-dts';
+import { setDefaultResultOrder } from 'dns'
+setDefaultResultOrder('verbatim')
+
+const getConfig: UserConfigFn = ({ mode }) => {
+ const baseConfig: UserConfig = {
+ build: {
+ lib: {
+ entry: resolve(__dirname, 'src/index.ts'),
+ name: 'phaser-boilerplate',
+ formats: ['es'],
+ fileName: (format) => `phaser-boilerplate.${format}.js`,
+ },
+ outDir: 'lib',
+ },
+ base: './',
+ plugins: [
+ dts({
+ tsconfigPath: "./tsconfig.json",
+ copyDtsFiles: true,
+ include: ["src/**/*"]
+ }),
+ ],
+ resolve: {
+ alias: {
+ configs: resolve(__dirname, "./src/configs"),
+ core: resolve(__dirname, "./src/core"),
+ styles: resolve(__dirname, "./styles"),
+ assets: resolve(__dirname, "./assets"),
+ scenes: resolve(__dirname, "./src/scenes"),
+ entities: resolve(__dirname, "./src/entities"),
+ components: resolve(__dirname, "./src/components"),
+ utils: resolve(__dirname, "./src/utils"),
+ root: resolve(__dirname, "./src"),
+ },
+ },
+ // test: {
+ // globals: true,
+ // environment: 'happy-dom',
+ // coverage: {
+ // reporter: ['text', 'json', 'html']
+ // },
+ // exclude: [
+ // ...configDefaults.exclude,
+ // '/test/**/*',
+ // 'scripts/**/*',
+ // ],
+ // },
+ define: {
+ 'IS_DEV': mode === 'development',
+ 'GAME_VERSION': JSON.stringify(process.env.npm_package_version),
+ 'GAME_BRANCH': JSON.stringify(execSync('git rev-parse --abbrev-ref HEAD').toString().trimEnd()),
+ 'GAME_TIMESTAMP': JSON.stringify(new Date().toLocaleString()),
+ },
+ server: {
+ port: 3000,
+ proxy: {
+ },
+ }
+ };
+
+ if (mode === 'production') {
+ return Object.assign(baseConfig, {
+ plugins: [...baseConfig.plugins,
+ stripCode({
+ start_comment: 'develblock:start',
+ end_comment: 'develblock:end',
+ }),
+ ],
+ });
+ }
+
+ return baseConfig;
+}
+
+// https://vitejs.dev/config/
+export default defineConfig(getConfig);
\ No newline at end of file