├── .github ├── dependabot.yml └── workflows │ └── build-test.yml ├── .gitignore ├── LICENSE ├── README.md ├── build └── build-bundle.js ├── client ├── MyOther.client.ts ├── client.ts └── tsconfig.json ├── fxmanifest.lua ├── package.json ├── server ├── MyOther.server.ts ├── server.ts └── tsconfig.json └── yarn.lock /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "npm" 5 | directory: / 6 | schedule: 7 | interval: "daily" 8 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build Test 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | build-test: 6 | name: Build Test 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | - name: Use Node.js 12 | uses: actions/setup-node@v2 13 | with: 14 | node-version: '16.x' 15 | cache: 'yarn' 16 | - name: Install dependencies NUI 17 | run: yarn install --frozen-lockfile 18 | - name: Build Bundles 19 | run: yarn build 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | dist 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Project Error 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Material-UI logo 3 |
4 |

FiveM TypeScript Resource Boilerplate

5 | 6 |
7 | This is a simple boilerplate for getting started with TypeScript game-scripts, in FiveM. 8 |
9 | 10 |
11 | 12 | [![Depfu](https://badges.depfu.com/badges/d269ca2d36b5d4cf247e66c6400c216d/count.svg)](https://depfu.com/github/project-error/fivem-typescript-boilerplate?project_id=33035) 13 | [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/project-error/pe-utils/master/LICENSE) 14 | ![Discord](https://img.shields.io/discord/791854454760013827?label=Our%20Discord) 15 |
16 | 17 | This repository is a basic boilerplate for getting started 18 | with TypeScript resources in FiveM. This boilerplate only comes with 19 | development dependencies needed for FiveM-centered TypeScript transpilation, the rest 20 | is up to you. 21 | 22 | *Note: This boilerplate is targeting TypeScript in context of game-scripts, 23 | if you wish to use TypeScript in NUI, take a look at our other [boilerplate](https://github.com/project-error/fivem-react-boilerplate-lua)* 24 | 25 | ## Foreword 26 | 27 | This boilerplate was originally based off a previous popular TypeScript boilerplate, 28 | made by [d0p3t](https://github.com/d0p3t/fivem-ts-boilerplate). He heartbeakingly passed 29 | in 2021, leaving the original unmaintained. This boilerplate was an up-to-date alternative. 30 | 31 | Since then, this boilerplate has been updated to take advantage of tooling progress made 32 | in the greater NPM ecosystem. 33 | 34 | ## Requirements 35 | * Node > v16 36 | * Yarn 37 | 38 | ## Getting Started 39 | 40 | First clone the repository or use the template option 41 | and place it within your `resources` folder 42 | 43 | **Install Dependencies** 44 | 45 | Navigate into the newly cloned folder and execute 46 | the following command, to install dependencies. 47 | 48 | ```sh 49 | npm i 50 | ``` 51 | 52 | ## Development 53 | 54 | ### Hot Building 55 | 56 | While developing your resource, this boilerplate offers 57 | a `watch` script that will automatically hot rebuild on any 58 | change within the `client` or `server` directories. 59 | 60 | ```sh 61 | npm run watch 62 | ``` 63 | *This script still requires you restart the resource for the 64 | changes to be reflected in-game* 65 | 66 | ### Entry Points 67 | **Client** - `./client/client.ts` 68 | 69 | **Server** - `./server/server.ts` 70 | 71 | ## Production Build 72 | Once you have completed the development phase of your resource, 73 | you must create an optimized & minimized production build, using 74 | the `build` script. 75 | 76 | ```sh 77 | npm run build 78 | ``` 79 | 80 | ## Version < 2.0.0 81 | 82 | Version 2.0.0 introduced ESBuild as the primary bundler, removing 83 | the option for automatic builds through the embedded FXServer webpack builder. 84 | 85 | This documentation is preserved for legacy purposes. 86 | 87 | ### Automatic Builds (Optional) 88 | 89 | *This is not recommended as the embedded version of yarn is 90 | ocassionally prone to performance and environment problems. We 91 | highly recomend, you manually run the build script* 92 | 93 | If desired, the `fxmanifest.lua` can be setup to allow for 94 | FXServer to automatically build on resource start. This utilizes 95 | the embedded `yarn` & `webpack` default resources. 96 | 97 | To enable this, add the following to your `fxmanifest.lua` 98 | 99 | ```lua 100 | dependency { 101 | 'yarn', 102 | 'webpack' 103 | } 104 | 105 | webpack_config 'webpack.config.js' 106 | ``` 107 | 108 | ### Additional Notes 109 | 110 | Need further support? Join our [Discord](https://discord.com/invite/HYwBjTbAY5)! -------------------------------------------------------------------------------- /build/build-bundle.js: -------------------------------------------------------------------------------- 1 | const esbuild = require("esbuild"); 2 | 3 | const IS_WATCH_MODE = process.env.IS_WATCH_MODE; 4 | 5 | const TARGET_ENTRIES = [ 6 | { 7 | target: "node16", 8 | entryPoints: ["server/server.ts"], 9 | platform: "node", 10 | outfile: "./dist/server/server.js", 11 | }, 12 | { 13 | target: "es2020", 14 | entryPoints: ["client/client.ts"], 15 | outfile: "./dist/client/client.js", 16 | }, 17 | ]; 18 | 19 | const buildBundle = async () => { 20 | try { 21 | const baseOptions = { 22 | logLevel: "info", 23 | bundle: true, 24 | charset: "utf8", 25 | minifyWhitespace: true, 26 | absWorkingDir: process.cwd(), 27 | }; 28 | 29 | for (const targetOpts of TARGET_ENTRIES) { 30 | const mergedOpts = { ...baseOptions, ...targetOpts }; 31 | 32 | if (IS_WATCH_MODE) { 33 | mergedOpts.watch = { 34 | onRebuild(error) { 35 | if (error) 36 | console.error( 37 | `[ESBuild Watch] (${targetOpts.entryPoints[0]}) Failed to rebuild bundle` 38 | ); 39 | else 40 | console.log( 41 | `[ESBuild Watch] (${targetOpts.entryPoints[0]}) Sucessfully rebuilt bundle` 42 | ); 43 | }, 44 | }; 45 | } 46 | 47 | const { errors } = await esbuild.build(mergedOpts); 48 | 49 | if (errors.length) { 50 | console.error(`[ESBuild] Bundle failed with ${errors.length} errors`); 51 | process.exit(1); 52 | } 53 | } 54 | } catch (e) { 55 | console.log("[ESBuild] Build failed with error"); 56 | console.error(e); 57 | process.exit(1); 58 | } 59 | }; 60 | 61 | buildBundle().catch(() => process.exit(1)); 62 | -------------------------------------------------------------------------------- /client/MyOther.client.ts: -------------------------------------------------------------------------------- 1 | // We can still use a multifile format, 2 | // while utilizing ESM import syntax. 3 | export const myRandomData = { 4 | randomStuff: true 5 | } -------------------------------------------------------------------------------- /client/client.ts: -------------------------------------------------------------------------------- 1 | import { myRandomData } from "./MyOther.client"; 2 | 3 | on('onResourceStart', (resName: string) => { 4 | if (resName === GetCurrentResourceName()) { 5 | console.log(myRandomData) 6 | console.log('TypeScript boilerplate started!') 7 | } 8 | }) -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "strict": true, 5 | "esModuleInterop": true, 6 | "allowSyntheticDefaultImports": true, 7 | "module": "CommonJS", 8 | "types": ["@citizenfx/client", "@types/node"], 9 | "lib": ["ES2020"] 10 | }, 11 | "include": ["./**/*"], 12 | "exclude": ["**/node_modules", "**/__tests__/*"] 13 | } -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | name 'FiveM TypeScript Boilerplate' 3 | author 'Project Error' 4 | game 'gta5' 5 | 6 | server_script 'dist/server/**/*.js' 7 | client_script 'dist/client/**/*.js' 8 | 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fivem-ts-boilerplate", 3 | "version": "2.0.0", 4 | "description": "A boilerplate for TypeScript in FiveM", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "npm run clearbuild && npm run typecheck && node build/build-bundle.js", 8 | "clearbuild": "rimraf ./dist", 9 | "typecheck": "tsc --noEmit -p client/tsconfig.json && tsc --noEmit -p server/tsconfig.json", 10 | "watch": "npm run clearbuild && cross-env IS_WATCH_MODE=1 node build/build-bundle.js" 11 | }, 12 | "author": "Project Error", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@citizenfx/client": "^2.0.6063-1", 16 | "@citizenfx/server": "^2.0.6063-1", 17 | "@types/node": "^20.10.5", 18 | "cross-env": "^7.0.3", 19 | "esbuild": "^0.19.10", 20 | "rimraf": "^5.0.1", 21 | "typescript": "^5.3.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server/MyOther.server.ts: -------------------------------------------------------------------------------- 1 | // We can still use a multifile format, while utilizing ESM import syntax. 2 | 3 | export const myRandomData = { 4 | randomStuff: true 5 | } -------------------------------------------------------------------------------- /server/server.ts: -------------------------------------------------------------------------------- 1 | import { myRandomData } from "./MyOther.server"; 2 | 3 | on("onResourceStart", (resName: string) => { 4 | if (resName === GetCurrentResourceName()) { 5 | console.log("TypeScript boilerplate started!"); 6 | console.log(myRandomData); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "strict": true, 5 | "esModuleInterop": true, 6 | "allowSyntheticDefaultImports": true, 7 | "module": "CommonJS", 8 | "types": ["@citizenfx/server", "@types/node"], 9 | "lib": ["ES2020"] 10 | }, 11 | "include": ["./**/*"], 12 | "exclude": ["**/node_modules", "**/__tests__/*"] 13 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@citizenfx/client@^2.0.6063-1": 6 | version "2.0.6063-1" 7 | resolved "https://registry.yarnpkg.com/@citizenfx/client/-/client-2.0.6063-1.tgz#ccab550a8792787e3a94691a0333c66ae4023c83" 8 | integrity sha512-GoorPVQ7M9OhEP/QarknzaTo/bGTWzakA3nBsOloXaGz1avkdwkrCAdaECdrO/0RaPCOPHKnUn98P+q2ODR/6w== 9 | 10 | "@citizenfx/server@^2.0.6063-1": 11 | version "2.0.6063-1" 12 | resolved "https://registry.yarnpkg.com/@citizenfx/server/-/server-2.0.6063-1.tgz#9ef764941a683df48757cca4718ce598224c9440" 13 | integrity sha512-nirVP4Q2axhmEltlfyQbGs1t3WIW0Gkbd3aw54aXSEarlhFH9Ig/rVqzSgikrcU7oGpSTt7wpirW3nOdl+bolA== 14 | 15 | "@esbuild/aix-ppc64@0.19.10": 16 | version "0.19.10" 17 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz#fb3922a0183d27446de00cf60d4f7baaadf98d84" 18 | integrity sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q== 19 | 20 | "@esbuild/android-arm64@0.19.10": 21 | version "0.19.10" 22 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz#ef31015416dd79398082409b77aaaa2ade4d531a" 23 | integrity sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q== 24 | 25 | "@esbuild/android-arm@0.19.10": 26 | version "0.19.10" 27 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.10.tgz#1c23c7e75473aae9fb323be5d9db225142f47f52" 28 | integrity sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w== 29 | 30 | "@esbuild/android-x64@0.19.10": 31 | version "0.19.10" 32 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.10.tgz#df6a4e6d6eb8da5595cfce16d4e3f6bc24464707" 33 | integrity sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw== 34 | 35 | "@esbuild/darwin-arm64@0.19.10": 36 | version "0.19.10" 37 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz#8462a55db07c1b2fad61c8244ce04469ef1043be" 38 | integrity sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA== 39 | 40 | "@esbuild/darwin-x64@0.19.10": 41 | version "0.19.10" 42 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz#d1de20bfd41bb75b955ba86a6b1004539e8218c1" 43 | integrity sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA== 44 | 45 | "@esbuild/freebsd-arm64@0.19.10": 46 | version "0.19.10" 47 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz#16904879e34c53a2e039d1284695d2db3e664d57" 48 | integrity sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg== 49 | 50 | "@esbuild/freebsd-x64@0.19.10": 51 | version "0.19.10" 52 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz#8ad9e5ca9786ca3f1ef1411bfd10b08dcd9d4cef" 53 | integrity sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag== 54 | 55 | "@esbuild/linux-arm64@0.19.10": 56 | version "0.19.10" 57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz#d82cf2c590faece82d28bbf1cfbe36f22ae25bd2" 58 | integrity sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ== 59 | 60 | "@esbuild/linux-arm@0.19.10": 61 | version "0.19.10" 62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz#477b8e7c7bcd34369717b04dd9ee6972c84f4029" 63 | integrity sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg== 64 | 65 | "@esbuild/linux-ia32@0.19.10": 66 | version "0.19.10" 67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz#d55ff822cf5b0252a57112f86857ff23be6cab0e" 68 | integrity sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg== 69 | 70 | "@esbuild/linux-loong64@0.19.10": 71 | version "0.19.10" 72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz#a9ad057d7e48d6c9f62ff50f6f208e331c4543c7" 73 | integrity sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA== 74 | 75 | "@esbuild/linux-mips64el@0.19.10": 76 | version "0.19.10" 77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz#b011a96924773d60ebab396fbd7a08de66668179" 78 | integrity sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A== 79 | 80 | "@esbuild/linux-ppc64@0.19.10": 81 | version "0.19.10" 82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz#5d8b59929c029811e473f2544790ea11d588d4dd" 83 | integrity sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ== 84 | 85 | "@esbuild/linux-riscv64@0.19.10": 86 | version "0.19.10" 87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz#292b06978375b271bd8bc0a554e0822957508d22" 88 | integrity sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA== 89 | 90 | "@esbuild/linux-s390x@0.19.10": 91 | version "0.19.10" 92 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz#d30af63530f8d4fa96930374c9dd0d62bf59e069" 93 | integrity sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA== 94 | 95 | "@esbuild/linux-x64@0.19.10": 96 | version "0.19.10" 97 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz#898c72eeb74d9f2fb43acf316125b475548b75ce" 98 | integrity sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA== 99 | 100 | "@esbuild/netbsd-x64@0.19.10": 101 | version "0.19.10" 102 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz#fd473a5ae261b43eab6dad4dbd5a3155906e6c91" 103 | integrity sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q== 104 | 105 | "@esbuild/openbsd-x64@0.19.10": 106 | version "0.19.10" 107 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz#96eb8992e526717b5272321eaad3e21f3a608e46" 108 | integrity sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg== 109 | 110 | "@esbuild/sunos-x64@0.19.10": 111 | version "0.19.10" 112 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz#c16ee1c167f903eaaa6acf7372bee42d5a89c9bc" 113 | integrity sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA== 114 | 115 | "@esbuild/win32-arm64@0.19.10": 116 | version "0.19.10" 117 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz#7e417d1971dbc7e469b4eceb6a5d1d667b5e3dcc" 118 | integrity sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw== 119 | 120 | "@esbuild/win32-ia32@0.19.10": 121 | version "0.19.10" 122 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz#2b52dfec6cd061ecb36171c13bae554888b439e5" 123 | integrity sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ== 124 | 125 | "@esbuild/win32-x64@0.19.10": 126 | version "0.19.10" 127 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz#bd123a74f243d2f3a1f046447bb9b363ee25d072" 128 | integrity sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA== 129 | 130 | "@isaacs/cliui@^8.0.2": 131 | version "8.0.2" 132 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 133 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 134 | dependencies: 135 | string-width "^5.1.2" 136 | string-width-cjs "npm:string-width@^4.2.0" 137 | strip-ansi "^7.0.1" 138 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 139 | wrap-ansi "^8.1.0" 140 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 141 | 142 | "@pkgjs/parseargs@^0.11.0": 143 | version "0.11.0" 144 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 145 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 146 | 147 | "@types/node@^20.10.5": 148 | version "20.10.5" 149 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.5.tgz#47ad460b514096b7ed63a1dae26fad0914ed3ab2" 150 | integrity sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw== 151 | dependencies: 152 | undici-types "~5.26.4" 153 | 154 | ansi-regex@^5.0.1: 155 | version "5.0.1" 156 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 157 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 158 | 159 | ansi-regex@^6.0.1: 160 | version "6.0.1" 161 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 162 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 163 | 164 | ansi-styles@^4.0.0: 165 | version "4.3.0" 166 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 167 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 168 | dependencies: 169 | color-convert "^2.0.1" 170 | 171 | ansi-styles@^6.1.0: 172 | version "6.2.1" 173 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 174 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 175 | 176 | balanced-match@^1.0.0: 177 | version "1.0.2" 178 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 179 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 180 | 181 | brace-expansion@^2.0.1: 182 | version "2.0.1" 183 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 184 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 185 | dependencies: 186 | balanced-match "^1.0.0" 187 | 188 | color-convert@^2.0.1: 189 | version "2.0.1" 190 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 191 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 192 | dependencies: 193 | color-name "~1.1.4" 194 | 195 | color-name@~1.1.4: 196 | version "1.1.4" 197 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 198 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 199 | 200 | cross-env@^7.0.3: 201 | version "7.0.3" 202 | resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" 203 | integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== 204 | dependencies: 205 | cross-spawn "^7.0.1" 206 | 207 | cross-spawn@^7.0.0, cross-spawn@^7.0.1: 208 | version "7.0.3" 209 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 210 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 211 | dependencies: 212 | path-key "^3.1.0" 213 | shebang-command "^2.0.0" 214 | which "^2.0.1" 215 | 216 | eastasianwidth@^0.2.0: 217 | version "0.2.0" 218 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 219 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 220 | 221 | emoji-regex@^8.0.0: 222 | version "8.0.0" 223 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 224 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 225 | 226 | emoji-regex@^9.2.2: 227 | version "9.2.2" 228 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 229 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 230 | 231 | esbuild@^0.19.10: 232 | version "0.19.10" 233 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.10.tgz#55e83e4a6b702e3498b9f872d84bfb4ebcb6d16e" 234 | integrity sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA== 235 | optionalDependencies: 236 | "@esbuild/aix-ppc64" "0.19.10" 237 | "@esbuild/android-arm" "0.19.10" 238 | "@esbuild/android-arm64" "0.19.10" 239 | "@esbuild/android-x64" "0.19.10" 240 | "@esbuild/darwin-arm64" "0.19.10" 241 | "@esbuild/darwin-x64" "0.19.10" 242 | "@esbuild/freebsd-arm64" "0.19.10" 243 | "@esbuild/freebsd-x64" "0.19.10" 244 | "@esbuild/linux-arm" "0.19.10" 245 | "@esbuild/linux-arm64" "0.19.10" 246 | "@esbuild/linux-ia32" "0.19.10" 247 | "@esbuild/linux-loong64" "0.19.10" 248 | "@esbuild/linux-mips64el" "0.19.10" 249 | "@esbuild/linux-ppc64" "0.19.10" 250 | "@esbuild/linux-riscv64" "0.19.10" 251 | "@esbuild/linux-s390x" "0.19.10" 252 | "@esbuild/linux-x64" "0.19.10" 253 | "@esbuild/netbsd-x64" "0.19.10" 254 | "@esbuild/openbsd-x64" "0.19.10" 255 | "@esbuild/sunos-x64" "0.19.10" 256 | "@esbuild/win32-arm64" "0.19.10" 257 | "@esbuild/win32-ia32" "0.19.10" 258 | "@esbuild/win32-x64" "0.19.10" 259 | 260 | foreground-child@^3.1.0: 261 | version "3.1.1" 262 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" 263 | integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== 264 | dependencies: 265 | cross-spawn "^7.0.0" 266 | signal-exit "^4.0.1" 267 | 268 | glob@^10.2.5: 269 | version "10.3.6" 270 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.6.tgz#c30553fe51dc19da30423c92cfcf15e433336058" 271 | integrity sha512-mEfImdc/fiYHEcF6pHFfD2b/KrdFB1qH9mRe5vI5HROF8G51SWxQJ2V56Ezl6ZL9y86gsxQ1Lgo2S746KGUPSQ== 272 | dependencies: 273 | foreground-child "^3.1.0" 274 | jackspeak "^2.0.3" 275 | minimatch "^9.0.1" 276 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 277 | path-scurry "^1.10.1" 278 | 279 | is-fullwidth-code-point@^3.0.0: 280 | version "3.0.0" 281 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 282 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 283 | 284 | isexe@^2.0.0: 285 | version "2.0.0" 286 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 287 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 288 | 289 | jackspeak@^2.0.3: 290 | version "2.3.3" 291 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.3.tgz#95e4cbcc03b3eb357bf6bcce14a903fb3d1151e1" 292 | integrity sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg== 293 | dependencies: 294 | "@isaacs/cliui" "^8.0.2" 295 | optionalDependencies: 296 | "@pkgjs/parseargs" "^0.11.0" 297 | 298 | "lru-cache@^9.1.1 || ^10.0.0": 299 | version "10.0.1" 300 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" 301 | integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== 302 | 303 | minimatch@^9.0.1: 304 | version "9.0.3" 305 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" 306 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== 307 | dependencies: 308 | brace-expansion "^2.0.1" 309 | 310 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": 311 | version "7.0.3" 312 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.3.tgz#05ea638da44e475037ed94d1c7efcc76a25e1974" 313 | integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== 314 | 315 | path-key@^3.1.0: 316 | version "3.1.1" 317 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 318 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 319 | 320 | path-scurry@^1.10.1: 321 | version "1.10.1" 322 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" 323 | integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== 324 | dependencies: 325 | lru-cache "^9.1.1 || ^10.0.0" 326 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 327 | 328 | rimraf@^5.0.1: 329 | version "5.0.1" 330 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" 331 | integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== 332 | dependencies: 333 | glob "^10.2.5" 334 | 335 | shebang-command@^2.0.0: 336 | version "2.0.0" 337 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 338 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 339 | dependencies: 340 | shebang-regex "^3.0.0" 341 | 342 | shebang-regex@^3.0.0: 343 | version "3.0.0" 344 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 345 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 346 | 347 | signal-exit@^4.0.1: 348 | version "4.1.0" 349 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 350 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 351 | 352 | "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: 353 | name string-width-cjs 354 | version "4.2.3" 355 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 356 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 357 | dependencies: 358 | emoji-regex "^8.0.0" 359 | is-fullwidth-code-point "^3.0.0" 360 | strip-ansi "^6.0.1" 361 | 362 | string-width@^5.0.1, string-width@^5.1.2: 363 | version "5.1.2" 364 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 365 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 366 | dependencies: 367 | eastasianwidth "^0.2.0" 368 | emoji-regex "^9.2.2" 369 | strip-ansi "^7.0.1" 370 | 371 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: 372 | name strip-ansi-cjs 373 | version "6.0.1" 374 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 375 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 376 | dependencies: 377 | ansi-regex "^5.0.1" 378 | 379 | strip-ansi@^7.0.1: 380 | version "7.1.0" 381 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 382 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 383 | dependencies: 384 | ansi-regex "^6.0.1" 385 | 386 | typescript@^5.3.3: 387 | version "5.3.3" 388 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" 389 | integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== 390 | 391 | undici-types@~5.26.4: 392 | version "5.26.5" 393 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 394 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 395 | 396 | which@^2.0.1: 397 | version "2.0.2" 398 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 399 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 400 | dependencies: 401 | isexe "^2.0.0" 402 | 403 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 404 | version "7.0.0" 405 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 406 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 407 | dependencies: 408 | ansi-styles "^4.0.0" 409 | string-width "^4.1.0" 410 | strip-ansi "^6.0.0" 411 | 412 | wrap-ansi@^8.1.0: 413 | version "8.1.0" 414 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 415 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 416 | dependencies: 417 | ansi-styles "^6.1.0" 418 | string-width "^5.0.1" 419 | strip-ansi "^7.0.1" 420 | --------------------------------------------------------------------------------