From 7e92fdd379d1d7ff4620fdb33f7f5489de8e8d26 Mon Sep 17 00:00:00 2001 From: MeowcaTheoRange Date: Mon, 19 Jun 2023 00:16:00 -0500 Subject: [PATCH] OK, I think that's enough --- .gitignore | 3 + .prettierrc | 17 + .vscode/settings.json | 5 + package-lock.json | 2033 +++++++++++++++++++++++++ package.json | 35 + src/app/api/index.ts | 8 + src/app/api/troll/index.ts | 21 + src/app/api/user/index.ts | 63 + src/app/index.ts | 6 + src/index.ts | 18 + src/lib/db/crud.ts | 54 + src/lib/db/mongodb.ts | 7 + src/lib/trollcall/convert/flair.ts | 11 + src/lib/trollcall/convert/troll.ts | 23 + src/lib/trollcall/convert/user.ts | 38 + src/lib/trollcall/flair.ts | 28 + src/lib/trollcall/troll.ts | 28 + src/lib/trollcall/user.ts | 50 + src/lib/trollcall/utility/merge.ts | 38 + src/types/assist/branding.ts | 16 + src/types/assist/color.ts | 102 ++ src/types/assist/extended_zodiac.ts | 2182 +++++++++++++++++++++++++++ src/types/assist/generics.ts | 6 + src/types/assist/language.ts | 51 + src/types/assist/mongo.ts | 6 + src/types/client/dialoglog.ts | 53 + src/types/client/flair.ts | 26 + src/types/client/quirks.ts | 10 + src/types/client/troll.ts | 236 +++ src/types/client/user.ts | 50 + src/types/dialoglog.ts | 45 + src/types/flair.ts | 11 + src/types/quirks.ts | 87 ++ src/types/troll.ts | 30 + src/types/user.ts | 22 + tsconfig.json | 20 + 36 files changed, 5439 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 .vscode/settings.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/app/api/index.ts create mode 100644 src/app/api/troll/index.ts create mode 100644 src/app/api/user/index.ts create mode 100644 src/app/index.ts create mode 100644 src/index.ts create mode 100644 src/lib/db/crud.ts create mode 100644 src/lib/db/mongodb.ts create mode 100644 src/lib/trollcall/convert/flair.ts create mode 100644 src/lib/trollcall/convert/troll.ts create mode 100644 src/lib/trollcall/convert/user.ts create mode 100644 src/lib/trollcall/flair.ts create mode 100644 src/lib/trollcall/troll.ts create mode 100644 src/lib/trollcall/user.ts create mode 100644 src/lib/trollcall/utility/merge.ts create mode 100644 src/types/assist/branding.ts create mode 100644 src/types/assist/color.ts create mode 100644 src/types/assist/extended_zodiac.ts create mode 100644 src/types/assist/generics.ts create mode 100644 src/types/assist/language.ts create mode 100644 src/types/assist/mongo.ts create mode 100644 src/types/client/dialoglog.ts create mode 100644 src/types/client/flair.ts create mode 100644 src/types/client/quirks.ts create mode 100644 src/types/client/troll.ts create mode 100644 src/types/client/user.ts create mode 100644 src/types/dialoglog.ts create mode 100644 src/types/flair.ts create mode 100644 src/types/quirks.ts create mode 100644 src/types/troll.ts create mode 100644 src/types/user.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cfbfa63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +node_modules/ +dist/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5e17cae --- /dev/null +++ b/.prettierrc @@ -0,0 +1,17 @@ +{ + "trailingComma": "none", + "tabWidth": 4, + "useTabs": false, + "printWidth": 120, + "semi": true, + "singleQuote": false, + "quoteProps": "preserve", + "jsxSingleQuote": false, + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "avoid", + "proseWrap": "never", + "endOfLine": "lf", + "embeddedLanguageFormatting": "auto", + "singleAttributePerLine": true +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1bd74ee --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "editor.tabSize": 4, + "prettier.tabWidth": 4 +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4782095 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2033 @@ +{ + "name": "trollcallquick", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "trollcallquick", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@types/cookie-parser": "^1.4.3", + "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", + "dotenv": "^16.3.0", + "express": "^4.18.2", + "lodash": "^4.17.21", + "mongodb": "^5.6.0", + "nanoid": "^3.3.6", + "tsconfig-paths": "^4.2.0", + "yup": "^1.2.0" + }, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/lodash": "^4.14.195", + "@types/node": "^20.3.1", + "concurrently": "^8.2.0", + "nodemon": "^2.0.22", + "tsc-alias": "^1.8.6", + "typescript": "^5.1.3" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "node_modules/@types/node": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bson": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.3.0.tgz", + "integrity": "sha512-ukmCZMneMlaC5ebPHXIkP8YJzNl5DC41N5MAIvKDqLggdao342t4McltoJBQfQya/nHBWAcSsYRqlXPoQkTJag==", + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concurrently": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.0.tgz", + "integrity": "sha512-nnLMxO2LU492mTUj9qX/az/lESonSZu81UznYDoXtz1IQf996ixVqPAgHXwvHiHCAef/7S8HIK+fTFK7Ifk8YA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.0.tgz", + "integrity": "sha512-tHB+hmf8MRCkT3VVivGiG8kq9HiGTmQ3FzOKgztfpJQH1IWuZTOvKSJmHNnQPowecAmkCJhLrxdPhOr06LLqIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mongodb": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.6.0.tgz", + "integrity": "sha512-z8qVs9NfobHJm6uzK56XBZF8XwM9H294iRnB7wNjF0SnY93si5HPziIJn+qqvUR5QOff/4L0gCD6SShdR/GtVQ==", + "dependencies": { + "bson": "^5.3.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/plimit-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.5.0.tgz", + "integrity": "sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.0" + } + }, + "node_modules/property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-lit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.0.tgz", + "integrity": "sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tsc-alias": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.6.tgz", + "integrity": "sha512-vq+i6VpE83IeMsSJVcFN03ZBofADhr8/gIJXjxpbnTRfN/MFXy0+SBaKG2o7p95QqXBGkeG98HYz3IkOOveFbg==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yup": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", + "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b6140f6 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "devDependencies": { + "@types/express": "^4.17.17", + "@types/lodash": "^4.14.195", + "@types/node": "^20.3.1", + "concurrently": "^8.2.0", + "nodemon": "^2.0.22", + "tsc-alias": "^1.8.6", + "typescript": "^5.1.3" + }, + "name": "trollcallquick", + "version": "0.1.0", + "main": "dist/index.js", + "scripts": { + "build": "npx tsc", + "start": "node dist/index.js", + "dev": "trap \"rm -rf dist/*;fuser -k 3000/tcp\" SIGINT;concurrently \"npx tsc --watch\" \"tsc-alias -w\" \"nodemon -q dist/index.js\"", + "devonce": "npx tsc && tsc-alias -p tsconfig.json;trap \"rm -rf dist/*;fuser -k 3000/tcp\" SIGINT;node dist/index.js" + }, + "author": "MeowcaTheoRange", + "license": "ISC", + "description": "", + "dependencies": { + "@types/cookie-parser": "^1.4.3", + "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", + "dotenv": "^16.3.0", + "express": "^4.18.2", + "lodash": "^4.17.21", + "mongodb": "^5.6.0", + "nanoid": "^3.3.6", + "tsconfig-paths": "^4.2.0", + "yup": "^1.2.0" + } +} diff --git a/src/app/api/index.ts b/src/app/api/index.ts new file mode 100644 index 0000000..753caa0 --- /dev/null +++ b/src/app/api/index.ts @@ -0,0 +1,8 @@ +import { Router } from "express"; +import { trollRouter } from "./troll"; +import { userRouter } from "./user"; + +export const apiRouter = Router(); + +apiRouter.use("/", trollRouter); +apiRouter.use("/", userRouter); diff --git a/src/app/api/troll/index.ts b/src/app/api/troll/index.ts new file mode 100644 index 0000000..abfc99f --- /dev/null +++ b/src/app/api/troll/index.ts @@ -0,0 +1,21 @@ +import { ServerTrollToClientTroll } from "@/lib/trollcall/convert/troll"; +import { getSingleTroll } from "@/lib/trollcall/troll"; +import { getSingleUser } from "@/lib/trollcall/user"; +import { Router } from "express"; + +export const trollRouter = Router(); + +trollRouter.get("/user/:user/troll/:troll", async (req, res, next) => { + const { params } = req; + const user = await getSingleUser({ + name: params.user + }); + if (user == null) return res.sendStatus(404); + const troll = await getSingleTroll({ + "name.0": params.troll, + "owners.0": user._id + }); + if (troll == null) return res.sendStatus(404); + const serverTroll = await ServerTrollToClientTroll(troll); + res.json(serverTroll); +}); diff --git a/src/app/api/user/index.ts b/src/app/api/user/index.ts new file mode 100644 index 0000000..1452fdc --- /dev/null +++ b/src/app/api/user/index.ts @@ -0,0 +1,63 @@ +import { MergeServerUsers, ServerUserToClientUser, SubmitUserToServerUser } from "@/lib/trollcall/convert/user"; +import { changeUser, createUser, getSingleUser } from "@/lib/trollcall/user"; +import { PartialUserSchema, SubmitUser, SubmitUserSchema } from "@/types/client/user"; +import { ServerUser } from "@/types/user"; +import { Router } from "express"; + +export const userRouter = Router(); + +userRouter.get("/user/:user/", async (req, res, next) => { + const { params } = req; + const user = await getSingleUser({ + name: params.user + }); + if (user == null) return res.sendStatus(404); + const serverUser = await ServerUserToClientUser(user); + res.json(serverUser); +}); + +userRouter.post("/user/", async (req, res, next) => { + const { body } = req; + let validatedUser: SubmitUser; + try { + validatedUser = await SubmitUserSchema.validate(body); + } catch (err) { + return res.status(400).send(err); + } + const checkExistingUser = await getSingleUser({ + name: validatedUser.name + }); + if (checkExistingUser != null) return res.sendStatus(409); + // we are sure this object is full, so cast partial + const serverUser = SubmitUserToServerUser(validatedUser) as Omit; + const newUser = await createUser(serverUser); + if (newUser == null) return res.sendStatus(503); + // Give cookies + res.cookie("TROLLCALL_NAME", newUser.name, { maxAge: 31540000 }) + .cookie("TROLLCALL_CODE", newUser.code, { maxAge: 31540000 }) + .json(newUser); +}); + +userRouter.put("/user/:user/", async (req, res, next) => { + const { body, params, cookies } = req; + let validatedUser: Partial; + try { + validatedUser = (await PartialUserSchema.validate(body)) as Partial; + } catch (err) { + return res.status(400).send(err); + } + const checkExistingUser = await getSingleUser({ + name: params.user + }); + if (checkExistingUser == null) return res.sendStatus(404); + if (checkExistingUser.code !== cookies.TROLLCALL_CODE || checkExistingUser.name !== cookies.TROLLCALL_NAME) + return res.sendStatus(403); + const serverUser = SubmitUserToServerUser(validatedUser); + const bothUsers = MergeServerUsers(checkExistingUser, serverUser); + const newUser = await changeUser(bothUsers); + if (newUser == null) return res.sendStatus(503); + // Give cookies, redundant style + res.cookie("TROLLCALL_NAME", newUser.name, { maxAge: 31540000 }) + .cookie("TROLLCALL_CODE", newUser.code, { maxAge: 31540000 }) + .json(newUser); +}); diff --git a/src/app/index.ts b/src/app/index.ts new file mode 100644 index 0000000..d4d90bb --- /dev/null +++ b/src/app/index.ts @@ -0,0 +1,6 @@ +import { Router } from "express"; +import { apiRouter } from "./api/index"; + +export const appRouter = Router(); + +appRouter.use("/api/", apiRouter); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..aaf9d75 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,18 @@ +import dotenv from "dotenv"; +dotenv.config(); + +import express, { Express } from "express"; +import { appRouter } from "./app"; + +import bodyParser from "body-parser"; +import cookieParser from "cookie-parser"; + +const app: Express = express(); +app.use(bodyParser.json()); +app.use(cookieParser()); + +app.use("/", appRouter); + +app.listen(process.env.PORT, () => { + console.log(`⚡️[server]: Server is running at http://localhost:${process.env.PORT}`); +}); diff --git a/src/lib/db/crud.ts b/src/lib/db/crud.ts new file mode 100644 index 0000000..44d21cf --- /dev/null +++ b/src/lib/db/crud.ts @@ -0,0 +1,54 @@ +import { FindCursor, Filter as MDBFilter, ObjectId } from "mongodb"; +import { mainDB } from "./mongodb"; + +// Functionally identical to the MongoDB type functions, but this is here if you want to extend TrollCall to another NoSQL database. + +export type WithId = Omit & { + _id: ObjectId; +}; + +export type Document = { [key: string]: any }; +export type Filter = MDBFilter; + +export async function createOne(collection: string, doc: any) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.insertOne(doc); +} + +export async function readOne(collection: string, find: Filter) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.findOne(find); +} // MongoDB and its finicky type safety + +export function readMany(collection: string, find: Filter) { + const selectedCollection = mainDB.collection(collection); + return selectedCollection.find(find); +} + +export async function countMany(collection: string, find: any) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.countDocuments(find); +} + +export async function replaceOne(collection: string, find: any, update: any) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.replaceOne(find, update); +} + +export async function updateOne(collection: string, find: any, update: any) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.updateOne(find, update); +} + +export async function deleteOne(collection: string, find: any) { + const selectedCollection = mainDB.collection(collection); + return await selectedCollection.findOneAndDelete(find); +} + +export async function cursorToArray(cursor: FindCursor, func: (input: any) => any = x => x) { + let array: T[] = []; + while (await cursor.hasNext()) { + array.push(await func(await cursor.next())); + } + return array; +} diff --git a/src/lib/db/mongodb.ts b/src/lib/db/mongodb.ts new file mode 100644 index 0000000..5ed4e38 --- /dev/null +++ b/src/lib/db/mongodb.ts @@ -0,0 +1,7 @@ +import { MongoClient } from "mongodb"; + +if (process.env.MONGODB_DATABASE == null) process.exit(); + +export const client = new MongoClient(process.env.MONGODB_DATABASE, {}); + +export const mainDB = client.db("trollcall_test"); diff --git a/src/lib/trollcall/convert/flair.ts b/src/lib/trollcall/convert/flair.ts new file mode 100644 index 0000000..5f050fd --- /dev/null +++ b/src/lib/trollcall/convert/flair.ts @@ -0,0 +1,11 @@ +import { ClientFlair, ServerFlair } from "@/types/flair"; +import { sanitize } from "../utility/merge"; + +export async function ServerFlairToClientFlair(serverFlair: ServerFlair): Promise { + const sanitizedFlair = sanitize(serverFlair); + let clientFlair: ClientFlair = { + ...sanitizedFlair + }; + + return clientFlair; +} diff --git a/src/lib/trollcall/convert/troll.ts b/src/lib/trollcall/convert/troll.ts new file mode 100644 index 0000000..ec16573 --- /dev/null +++ b/src/lib/trollcall/convert/troll.ts @@ -0,0 +1,23 @@ +import { Class, TrueSign } from "@/types/assist/extended_zodiac"; +import { ClientTroll, ServerTroll } from "@/types/troll"; +import { getManyFlairs } from "../flair"; +import { getManyUsers } from "../user"; +import { cutArray, sanitize } from "../utility/merge"; +import { ServerFlairToClientFlair } from "./flair"; +import { ServerUserToClientUser } from "./user"; + +export async function ServerTrollToClientTroll(serverTroll: ServerTroll): Promise { + const sanitizedTroll = sanitize(serverTroll); + const owners = await getManyUsers({ _id: { $in: serverTroll.owners } }, ServerUserToClientUser); + const flairs = await getManyFlairs({ _id: { $in: serverTroll.flairs } }, ServerFlairToClientFlair); + let clientTroll: ClientTroll = { + ...sanitizedTroll, + trueSign: TrueSign[serverTroll.trueSign], + falseSign: serverTroll.falseSign != null ? TrueSign[serverTroll.falseSign] : null, + class: Class[serverTroll.class], + owners: cutArray(owners), + flairs: cutArray(flairs) + }; + + return clientTroll; +} diff --git a/src/lib/trollcall/convert/user.ts b/src/lib/trollcall/convert/user.ts new file mode 100644 index 0000000..510b004 --- /dev/null +++ b/src/lib/trollcall/convert/user.ts @@ -0,0 +1,38 @@ +import { TrueSign } from "@/types/assist/extended_zodiac"; +import { SubmitUser } from "@/types/client/user"; +import { ClientUser, ServerUser } from "@/types/user"; +import { nanoid } from "nanoid"; +import { getManyFlairs } from "../flair"; +import { cutArray, cutObject, removeCode, sanitize } from "../utility/merge"; +import { ServerFlairToClientFlair } from "./flair"; + +export async function ServerUserToClientUser(serverUser: ServerUser): Promise { + const sanitizedUser = removeCode(sanitize(serverUser)); + const flairs = await getManyFlairs({ _id: { $in: serverUser.flairs } }, ServerFlairToClientFlair); + let clientUser: ClientUser = { + ...sanitizedUser, + trueSign: TrueSign[serverUser.trueSign], + flairs: cutArray(flairs), + updatedDate: serverUser.updatedDate?.getTime() + }; + return clientUser; +} + +export function SubmitUserToServerUser(submitUser: Partial): Omit, "_id"> { + let serverUser: Omit, "_id"> = { + ...submitUser, + flairs: [], + code: submitUser.code || nanoid(16), + updatedDate: new Date() + }; + return serverUser; +} + +export function MergeServerUsers(submitUser: ServerUser, merge: Partial>): ServerUser { + let serverUser: ServerUser = { + ...submitUser, + ...cutObject(merge), + updatedDate: new Date() + }; + return serverUser; +} diff --git a/src/lib/trollcall/flair.ts b/src/lib/trollcall/flair.ts new file mode 100644 index 0000000..9a3efb4 --- /dev/null +++ b/src/lib/trollcall/flair.ts @@ -0,0 +1,28 @@ +import { ServerFlair } from "@/types/flair"; +import { Filter, cursorToArray, readMany, readOne } from "../db/crud"; + +/** + * A function that returns one ServerFlairs from the database. + * @param query A partial Find query. Can contain an ID. + * @returns A ServerFlair. + */ + +export async function getSingleFlair(query: Filter): Promise { + const flair = (await readOne("flairs", query)) as ServerFlair | null; + return flair; +} + +/** + * A function that returns many ServerFlairs from the database using a FindCursor. + * @param query A partial Find query. Can contain an ID. + * @param func A function to run on every ServerFlairs returned. Helps reduce loops. + * @returns An array of ServerFlairs. + */ + +export async function getManyFlairs( + query: Filter, + func?: (input: any) => any +): Promise<(ServerFlair | null)[]> { + const flair = (await cursorToArray(readMany("flairs", query), func)) as (ServerFlair | null)[]; + return flair; +} diff --git a/src/lib/trollcall/troll.ts b/src/lib/trollcall/troll.ts new file mode 100644 index 0000000..9f68b73 --- /dev/null +++ b/src/lib/trollcall/troll.ts @@ -0,0 +1,28 @@ +import { ServerTroll } from "@/types/troll"; +import { Filter, cursorToArray, readMany, readOne } from "../db/crud"; + +/** + * A function that returns one ServerTrolls from the database. + * @param query A partial Find query. Can contain an ID. + * @returns A ServerTroll. + */ + +export async function getSingleTroll(query: Filter): Promise { + const troll = (await readOne("trolls", query)) as ServerTroll | null; + return troll; +} + +/** + * A function that returns many ServerTrolls from the database using a FindCursor. + * @param query A partial Find query. Can contain an ID. + * @param func A function to run on every ServerTrolls returned. Helps reduce loops. + * @returns An array of ServerTrolls. + */ + +export async function getManyTrolls( + query: Filter, + func?: (input: any) => any +): Promise<(ServerTroll | null)[]> { + const troll = (await cursorToArray(readMany("trolls", query), func)) as (ServerTroll | null)[]; + return troll; +} diff --git a/src/lib/trollcall/user.ts b/src/lib/trollcall/user.ts new file mode 100644 index 0000000..1a13ddd --- /dev/null +++ b/src/lib/trollcall/user.ts @@ -0,0 +1,50 @@ +import { ServerUser } from "@/types/user"; +import { Filter, createOne, cursorToArray, readMany, readOne, replaceOne } from "../db/crud"; + +/** + * A function that returns one ServerUser from the database. + * @param query A partial Find query. Can contain an ID. + * @returns A ServerUser. + */ + +export async function getSingleUser(query: Filter): Promise { + const user = (await readOne("users", query)) as ServerUser | null; + return user; +} + +/** + * A function that returns many ServerUsers from the database using a FindCursor. + * @param query A partial Find query. Can contain an ID. + * @param func A function to run on every ServerUser returned. Helps reduce loops. + * @returns An array of ServerUsers. + */ + +export async function getManyUsers( + query: Filter, + func?: (input: any) => T +): Promise<(Awaited | null)[]> { + const user = (await cursorToArray(readMany("users", query), func)) as (Awaited | null)[]; + return user; +} + +/** + * A function that puts one ServerUser into the database. + * @param user A ServerUser. + * @returns A ServerUser, or null, depending on if the operation succeeded. + */ + +export async function createUser(user: Omit): Promise | null> { + const newUser = await createOne("users", user); + return newUser.acknowledged ? user : null; +} + +/** + * A function that changes one database user with the given params. + * @param user A ServerUser. + * @returns A ServerUser, or null, depending on if the operation succeeded. + */ + +export async function changeUser(user: ServerUser): Promise { + const newUser = await replaceOne("users", { _id: user._id }, user); + return newUser.acknowledged ? user : null; +} diff --git a/src/lib/trollcall/utility/merge.ts b/src/lib/trollcall/utility/merge.ts new file mode 100644 index 0000000..f8b5942 --- /dev/null +++ b/src/lib/trollcall/utility/merge.ts @@ -0,0 +1,38 @@ +import { WithId } from "@/lib/db/crud"; +import _ from "lodash"; + +export function cutArray(array: T[]) { + const cut: any[] = []; + array.forEach((value, i) => { + if (value == null) return; + if (Array.isArray(value)) cut[i] = cutArray(value); + else if (typeof value == "object") cut[i] = cutObject(value); + else cut[i] = value; + }); + return cut as NonNullable[]; +} + +export function cutObject(object: T) { + const keys = Object.keys(object); + let cut: { [key: string]: any } = {}; + keys.forEach(key => { + var val = object[key]; + if (val == null) return; + if (Array.isArray(val)) cut[key] = cutArray(val); + else if (_.isObject(val)) cut[key] = cutObject(val); + else cut[key] = val; + }); + return cut as T; +} + +export function sanitize>(serverType: Type): Omit { + const sanitized: Partial = serverType; + delete sanitized._id; + return sanitized as Omit; +} + +export function removeCode(serverType: Type): Omit { + const sanitized: Partial = serverType; + delete sanitized.code; + return sanitized as Omit; +} diff --git a/src/types/assist/branding.ts b/src/types/assist/branding.ts new file mode 100644 index 0000000..ddca3a4 --- /dev/null +++ b/src/types/assist/branding.ts @@ -0,0 +1,16 @@ +// needlessly complicated branding guide. oh well +// this helps you get the gist of how we represent TrollCall within the site + +export const brand = { + name: "TrollCall", + code: "TrollCallNext", + owner: "MeowcaTheoRange" +}; +export const domain = { + main: "trollcall", + tld: "xyz", + owner: "Redact4K" +}; +export const fullDomain = domain.main + "." + domain.tld; +export const source = "the original Hiveswap Troll Call"; +export const sourceCopyright = "Homestuck and HIVESWAP ©️ Homestuck Inc."; diff --git a/src/types/assist/color.ts b/src/types/assist/color.ts new file mode 100644 index 0000000..8397ea5 --- /dev/null +++ b/src/types/assist/color.ts @@ -0,0 +1,102 @@ +import * as yup from "yup"; + +export type ColorTypes = [number, number, number]; + +export const ColorSchema = yup.tuple([ + yup.number().required().min(0).max(255), + yup.number().required().min(0).max(255), + yup.number().required().min(0).max(255), +]); + +const clamp = (n: number, mi: number, ma: number) => + Math.max(mi, Math.min(n, ma)); + +export class Color3 { + R: number; + G: number; + B: number; + constructor(red: number, green: number, blue: number) { + this.R = red; + this.G = green; + this.B = blue; + } + static clone(color3: Color3) { + return new Color3(color3.R, color3.G, color3.B); + } + static fromRGB(red: number, green: number, blue: number) { + return new Color3(red / 255, green / 255, blue / 255); + } + static fromHex(hex: string) { + // @ts-ignore + const hexSplit: [number, number, number] = ( + hex.match(new RegExp(`[0-9a-f]{1,${hex.length / 3}}`, "gi")) ?? [ + "0", + "0", + "0", + ] + ).map((x) => parseInt(x, 16) / 255); + return new Color3(...hexSplit); + } + static fromInt(int: number) { + return new Color3( + (int & 0xff0000) >> 16, + (int & 0x00ff00) >> 8, + int & 0x0000ff + ); + } + static assumeColor( + value: [number, number, number] | string | number, + rgb?: boolean + ) { + if (Color3.isColor(value)) { + if (Array.isArray(value)) + return rgb ? Color3.fromRGB(...value) : new Color3(...value); + else if (typeof value === "string") return Color3.fromHex(value); + else if (typeof value === "number") return Color3.fromInt(value); + } + throw new Error("Not a valid color type"); + } + static isColor( + value: [number, number, number] | string | number, + rgb?: boolean + ) { + return ( + (Array.isArray(value) && + value.length === 3 && + value.every((x) => typeof x === "number" && !isNaN(x))) || + (typeof value === "string" && !isNaN(parseInt(value, 16))) || + (typeof value === "number" && !isNaN(value)) + ); + } + + toHex() { + return this.toInt().toString(16).padStart(6, "0"); + } + toInt() { + return ( + (Math.round(this.R * 255) << 16) + + (Math.round(this.G * 255) << 8) + + Math.round(this.B * 255) + ); + } + toRGB(): [number, number, number] { + return [this.R * 255, this.G * 255, this.B * 255]; + } + multiply(mult: number) { + return new Color3(this.R * mult, this.G * mult, this.B * mult); + } + lighten(mult: number) { + return new Color3( + clamp(this.R + (mult / 100) * (1 - this.R), 0, 1), + clamp(this.G + (mult / 100) * (1 - this.G), 0, 1), + clamp(this.B + (mult / 100) * (1 - this.B), 0, 1) + ); + } + darken(mult: number) { + return new Color3( + clamp(this.R - (mult / 100) * this.R, 0, 1), + clamp(this.G - (mult / 100) * this.G, 0, 1), + clamp(this.B - (mult / 100) * this.B, 0, 1) + ); + } +} diff --git a/src/types/assist/extended_zodiac.ts b/src/types/assist/extended_zodiac.ts new file mode 100644 index 0000000..5b00139 --- /dev/null +++ b/src/types/assist/extended_zodiac.ts @@ -0,0 +1,2182 @@ +import * as yup from "yup"; +import { ColorSchema, ColorTypes } from "./color"; + +export enum ClassGender { + Male, + Unisex, + Female +} + +export enum ClassDisposition { + Active, + Passive +} + +export const ClassShelfSchema = yup.object({ + name: yup.string().required(), + pair: yup.string().required(), + keyword: yup.string().required() +}); + +export type ClassShelfType = { + name: string; + pair: string; + keyword: string; +}; + +export const ClassShelf: { [key: string]: ClassShelfType } = { + Magician: { + name: "Magician", + pair: "Prophet", + keyword: "Manipulate" + }, + Prophet: { + name: "Prophet", + pair: "Magician", + keyword: "Understand" + }, + Destroyer: { + name: "Destroyer", + pair: "Healer", + keyword: "Destroy" // fucking duh + }, + Healer: { + name: "Healer", + pair: "Destroyer", + keyword: "Create" + }, + Stealer: { + name: "Stealer", + pair: "Warrior", + keyword: "Redistribute" + }, + Warrior: { + name: "Warrior", + pair: "Stealer", + keyword: "Apply" + } +}; + +export const ClassSchema = yup.object({ + name: yup.string().required(), + gender: yup.string().required(), + disposition: yup.string().required(), + pair: yup.string().required(), + inverse: yup.string().required(), + keyword: yup.string().required(), + shelf: ClassShelfSchema.required() +}); + +export type ClassType = { + name: string; + gender: string; // just for "canon check"; this is not actually enforced + disposition: string; + pair: string; + inverse: string; + keyword: string; + shelf: ClassShelfType; +}; + +export const Class: { [key: string]: ClassType } = { + Witch: { + name: "Witch", + gender: "Female", + disposition: "Active", + keyword: "Control", + pair: "Heir", + inverse: "Seer", + shelf: ClassShelf.Magician + }, + Heir: { + name: "Heir", + gender: "Male", + disposition: "Passive", + keyword: "Influence", + pair: "Witch", + inverse: "Mage", + shelf: ClassShelf.Magician + }, + Mage: { + name: "Mage", + gender: "Unisex", + disposition: "Active", + keyword: "Experience", + pair: "Seer", + inverse: "Heir", + shelf: ClassShelf.Prophet + }, + Seer: { + name: "Seer", + gender: "Unisex", + disposition: "Passive", + keyword: "Study", + pair: "Mage", + inverse: "Witch", + shelf: ClassShelf.Prophet + }, + Prince: { + name: "Prince", + gender: "Male", + disposition: "Active", + keyword: "Demolish", + pair: "Bard", + inverse: "Sylph", + shelf: ClassShelf.Destroyer + }, + Bard: { + name: "Bard", + gender: "Male", + disposition: "Passive", + keyword: "Deconstruct", + pair: "Prince", + inverse: "Maid", + shelf: ClassShelf.Destroyer + }, + Maid: { + name: "Maid", + gender: "Female", + disposition: "Active", + keyword: "Generate", + pair: "Sylph", + inverse: "Bard", + shelf: ClassShelf.Healer + }, + Sylph: { + name: "Sylph", + gender: "Female", + disposition: "Passive", + keyword: "Mend", + pair: "Maid", + inverse: "Prince", + shelf: ClassShelf.Healer + }, + Thief: { + name: "Thief", + gender: "Unisex", + disposition: "Active", + keyword: "Take", + pair: "Rogue", + inverse: "Page", + shelf: ClassShelf.Stealer + }, + Rogue: { + name: "Rogue", + gender: "Unisex", + disposition: "Passive", + keyword: "Share", + pair: "Thief", + inverse: "Knight", + shelf: ClassShelf.Stealer + }, + Knight: { + name: "Knight", + gender: "Unisex", + disposition: "Active", + keyword: "Exploit", + pair: "Page", + inverse: "Rogue", + shelf: ClassShelf.Warrior + }, + Page: { + name: "Page", + gender: "Unisex", + disposition: "Passive", + keyword: "Empower", + pair: "Knight", + inverse: "Thief", + shelf: ClassShelf.Warrior + }, + Lord: { + name: "Lord", + gender: "Male", + disposition: "Active", + keyword: "Dominate", + pair: "Muse", + inverse: "Muse", + shelf: ClassShelf.Master + }, + Muse: { + name: "Muse", + gender: "Female", + disposition: "Passive", + keyword: "Inspire", + pair: "Lord", + inverse: "Lord", + shelf: ClassShelf.Master + } +}; + +export const ClassKeys = Object.keys(Class); +export const ClassValues = Object.values(Class); + +export const SwaySchema = yup.object({ + name: yup.string().required(), + description: yup.string().required() +}); + +export type SwayType = { + name: string; + description: string; +}; + +export const Sway: { [key: string]: SwayType } = { + Prospit: { + name: "Prospit", + description: + "Marked by a flexible optimism, the personalities of Prospit Dreamers are reactive and intuitive. They naturally exist in the present, rather than look to the future or obsess over the past. When making decisions Prospit Dreamers tend to rely on gut instinct and whatever emotions they are experiencing at the moment. This makes them quick to act and reliable in a crisis, but it also can make them capricious. They have trouble thinking things through, and their feelings toward specific situations and decisions can change from day to day. They solve problems with creativity rather than cold logic, often seeing multiple options with ease and clarity. Because they generally take things as they come, Prospit Dreamers are less rebellious than they are adaptable-instead of struggling against authority, they will find a way to coexist with it. Possibly because they are so instinctual and flexible, they like having a defined set of rules-a safety net for their passionate lives. Naturally trusting, they have trouble with deception or hiding their true selves, and will often worry about what others think of them. The self they project into the world is often not under their control." + }, + Derse: { + name: "Derse", + description: + "Derse Dreamers have personalities marked by a distinct and restless skepticism. Whatever their waking circumstances, chances are they will live in a state of dissatisfaction. Rebellion is in their blood, manifesting whether they are fighting back against a fascist dictatorship, or the most recent trend in casual footwear. Derse Dreamers are cerebral and self-aware; they have a far better grasp on the landscape of their own minds than on the world around them, which they can find alienating and confusing. But as so much of their identity is built on control, they will do their utmost to hide any insecurities, often with false humility or self-deprecating humor. They may be inflexible and pessimistic, but they are also great problem solvers, facing conflicts head-on with shrewd, calculating minds. They see one true path among an infinite snarl of wrong ones. They tend to be introverted, but if you win their trust Derse Dreamers are extremely powerful allies. However, they find sincere vulnerability difficult and will often keep people at arm's length. Letting go and living in the moment is hard for a Derse Dreamer; they constantly look toward the future and analyze the past." + } +}; + +export const SwayKeys = Object.keys(Sway); +export const SwayValues = Object.values(Sway); + +export const AspectSchema = yup.object({ + name: yup.string().required(), + description: yup.string().required() +}); + +export type AspectType = { + name: string; + description: string; +}; + +export const Aspect: { [key: string]: AspectType } = { + Time: { + name: "Time", + description: + "Those bound to the aspect of Time are fighters, full stop. Their lives are often marked by struggle, not so much because fate has it in for them, but because they are fundamentally incapable of just accepting things as they come. They value action over passive acceptance, even if that may not be the wisest or safest choice. Don't try to tell a Time-bound to sit still and look pretty. They are very goal-focused, and tend to value the destination over the journey, and you won't find them making that journey in any traditional sort of way. To quote cheesy posters found on many a guidance counselor's wall-\"impossible is just a word\". If you need a miracle, they are who you call. At their best, the Time-bound are empathetic and relentless problem-solvers. At their worst they are ruthless, defensive, and impulsive. " + }, + Space: { + name: "Space", + description: + "Those bound to the aspect of Space are, as the name suggests, concerned with the big picture. They are patient, masters of the art of 'wait-and-see', and are inclined to take things as they come. That isn't to say that they're pushovers or willing to let injustice lie-they just choose their battles wisely, understanding that sometimes you have to let something burn to the ground in order to build it back better and stronger than before. To this effect, they tend to be innovators, concerned with creation and redemption. Catch them recycling the old to make the new, the fresh, and the beautiful. For the Space-bound, the journey is as, if not more, important than the destination; how they do something is as important as what they do. At their best, they are steady, impartial, and creative. At their worst, they can be detached, apathetic, and vague. " + }, + Heart: { + name: "Heart", + description: + "Those bound to the aspect of Heart are very concerned with their favorite subject: themselves. It wouldn't be a stretch to call them 'self-obsessed', but not necessarily in a negative way. They simply want to understand the one thing we all are stuck with for our entire lives, i.e. our own minds. Forging an identity is extremely important to the Heart-bound, and every decision and action goes toward building a coherent narrative of their own story. That isn't to say Heart-bound don't care deeply for their friends and allies; they just have a tendency to assume that everyone is as concerned with identity as they are. They are excellent at putting on and taking off masks as the situation calls for them. At their best, they are competent, imaginative, and steady. At their worst they can be overbearing, inflexible, and cold. " + }, + Mind: { + name: "Mind", + description: + "Those bound to the aspect of Mind are-you guessed it-the universe's great thinkers. But don't for a second think that means that they have all the answers. They are very concerned with remaining rational, and they have such a firm hold on the constant conjunction of their thinking that it's easy for them to see the multitudes of the choices laid out before them, which often leaves them frozen and unable to act. That said, when a Mind-bound finally launches into action, they can execute a plan with unbelievable grace and precision. Their identity is fluid-it can change from day-to-day, from thought-to-thought, from interaction-to-interaction. Remaining logical is more important to them than building up a solid foundation of \"self.\" At their best they are great innovators, architects, and creators. At their worst they can be nasty, inflexible, and indecisive. " + }, + Hope: { + name: "Hope", + description: + "Those bound to the aspect of Hope are driven first and foremost by their convictions. They do right for right's sake, and are quick to come to the aid of anyone they deem to be experiencing injustice. That said, their views of the world can be quite black and white, so what they see as the \"right\" thing may not always be the universally accepted view. They put great value in the power of the imagination, the ability to dream up a better and more beautiful future. If anyone could dream a better world into existence, it would be one of the Hope-bound. They may sound like all sunshine and rainbows, but they aren't adverse to a little destruction, especially if they think they can replace it with something better and more just. At their best, Hope-bound are positive, caring, and warm. At their worst they can be narrow-minded and selfish. " + }, + Rage: { + name: "Rage", + description: + "Those bound to the aspect of Rage are bringers of chaos. They posses great contempt for lies or false ideas, including the stability that false ideas can impart. To them, the true is far more important than the good; they would tear down a system just to destabilize it if, by their reckoning, it is built on faulty premises. Often the Rage-bound prefer anarchy to any of the alternate forms of civilization, which they believe to be riddled with lies and foolishness and obedient masses. They are bringers of confusion and doubt, and they can be frustratingly difficult to convince otherwise when they have attached themselves to an idea. If they sound dangerous, they are. The Rage-bound tend to be most volatile and unpredictable of the aspects. At their best they are original, revolutionary, and fearless. At their worst they are cruel, uncompromising, and vicious. " + }, + Light: { + name: "Light", + description: + "Those bound to the aspect of Light are the universe's knowledge-seekers. They are, above all, driven to learn and understand. They are great alchemists, able to take multiple sources of information and synthesize them into something useful. They are scholars and researchers, absolutely dedicated to knowledge for knowledge's sake. They are the ultimate students, and although that might conjure up the image of people sitting around peacefully waiting for knowledge to be brought to them, that couldn't be further from the truth. The Light-bound will go after knowledge with a fierce intensity that others may find distasteful. They aren't overly concerned with laws or norms, either. They often take rules as simple suggestions, instead searching for loopholes or work-arounds. At their best, the Light-bound are resourceful and driven. At their worst they can be fussy, pedantic, and insensitive." + }, + Void: { + name: "Void", + description: + "Those bound to the aspect of Void are the universe's secret-keepers. The unknown doesn't scare them-where others might see emptiness, they see potential. A blank page, an empty canvas, that's what the Void-bound live for. They value mystery and the unexplained, and are not particularly bothered by not having all the answers. Where others might be compelled to go out and seek answers, the Void-bound lean more toward casting doubt on what is already considered fully understood. They don't take much on faith and would rather live in a state of confusion than believe something that might be untrue or bow to intellectual authority. After all, in order for something new to be built, the old, rotting foundation must often be razed. At their best, Void-bound are wise, intuitive, and vibrant. At their worst they can be dismissive, indecisive, and apathetic. " + }, + Breath: { + name: "Breath", + description: + "Those bound to the aspect of Breath are, above all, expansive. Flexible and driven, they leave an impact wherever they go. Like the breeze itself, they are able to sweep others up to carry along in their wake, but also like the breeze, they can be difficult to catch hold of or tie down. Although Breath-bound do make very good leaders, breath tends to be a very personal aspect. Often, heroism comes along as an offshoot of them pursuing their own personal stories. They lead by example, and will routinely be surprised that others look up to or feel inspired by them. They have a tendency to underestimate themselves, and not always out of poor self-esteem. They were just doing their own thing. At their best Breath-bound are motivated, adaptable, and forward thinking, but at their worst they can be volatile, avoidant, and gullible." + }, + Blood: { + name: "Blood", + description: + 'Those bound to the aspect of Blood draw their strength from bonds, from the trust and camaraderie that blooms among a group of people who all share a single vision. Blood-bound are absolutely leaders, but they inhabit more of an inspirational role than a commanding one. They are prophets, rather than generals, giving others the strength and motivation to keep fighting. The Blood-bound can dispense excellent advice even when their own lives and interpersonal relationships are disasters. They can be very "do as I say, not as I do" types. A Blood-bound can often be found on a sinking ship, forcing an endeavor forward with sheer stubborn force of will. No matter how bad things go, a Blood-bound can always count on friends and allies. At their best, they are charismatic, uplifting, and magnetic. At their worst they can be sullen, unkind, and set-in-their-ways. ' + }, + Life: { + name: "Life", + description: + "Those bound to the aspect of Life are the universe's healers. They are concerned with the betterment of themselves and those around them, as well as the onward march of positive progress. Deeply empathetic, they have an intuitive understanding of other's suffering and the best way of righting those wrongs. If you're poisoned, chances are the Life-bound have something for what ails ya. This applies to both physical and mental suffering, though it might not be a cure you'll like. They also have the tendency to put other's needs before their own, which never ends well for anyone, because the Life-bound can grow bitter if they feel their own self-care has had to be shunted aside. At their best, they are great listeners, caretakers, and nurturers. At their worst, the Life-bound are passive aggressive, and pushy-they're certain they know best. " + }, + Doom: { + name: "Doom", + description: + "Those bound to the aspect of Doom are fate's chosen sufferers. It may not sound like an overly pleasant aspect to be aligned with, but it does come along with great wisdom and empathy. The Doom-bound understand that misery loves company, and they are ready and willing to provide said company. The Doom-bound won't fix you; they aren't healers. They are commiserators, aware that sometimes the only thing you can do for a person is let them know that they are not alone in their suffering. They are not the advice friend-they're the friend you go to when you need to vent about a rough day at work. They are not necessarily noble martyrs, either-the Doom-bound can become quite irate about their lot. At their best they are wise, kind, and non-judgemental. At their worst, bitter, resentful, and fatalistic." + } +}; + +export const AspectKeys = Object.keys(Aspect); +export const AspectValues = Object.values(Aspect); + +export const SignColorSchema = yup.object({ + name: yup.string().required(), + description: yup.string().required(), + sign: yup.string().required(), + color: ColorSchema.required(), + dates: yup.tuple([yup.string().required(), yup.string().required()]).required() +}); + +export type SignColorType = { + name: string; + description: string; + sign: string; + color: ColorTypes; + dates: [string, string]; +}; + +export const SignColor: { + [key: string]: SignColorType; +} = { + Rust: { + name: "Rust", + description: + "Adventure motivates Rust Signs more than anything else. They crave new experiences, the wilder and farther-from-home, the better. They are confident and energetic, ready to face the unknown. This dynamism makes them great leaders, but it can also make them foolhardy. Often, they don't posses the level of caution they should for someone so willing to jump into new things. Their willingness to trust can get them into trouble, but they are also incredibly resilient. Their ability to bounce back from trauma and injury leaves them as the toughest sign class on the spectrum. Rust Signs make great friends and traveling companions, but they also can be selfish and quick to anger. If what they deem to be an acceptable level of \"excitement\" isn't happening around them, they have a tendency to try to stir some up. They love the drama. They have incredibly high expectations for themselves and for romantic partners. If someone doesn't live up to these, they may deem them not worth their time. If they aren't careful, Rust Signs can end up in a cycle of excitement, followed by crushed expectations, followed by a quick recovery and new flush of excitement. ", + sign: "Aries", + color: [255, 0, 0], + dates: ["March 21", "April 19"] + }, + Bronze: { + name: "Bronze", + description: + "Bronze Signs have a warm and generous disposition, but you might not accuse them of it the first time you meet. They have a tendency toward being withdrawn and slow to open up with new people. This can make them come off as arrogant and cold, like they think they are too good for everyone, although the reality couldn't be further from the truth. In fact, they crave validation and companionship. They are very open-hearted, but if a Bronze Sign decides to dig their heels in, it can be like talking to a wall. More so than any of the other sign classes, Bronze Signs have a marked love of creature comforts. They crave stability and safety, and if they have the means, their homes will be full of beautiful things. Some might accuse them of being hedonistic; they would probably just claim to know what they like. As lovers they can be quite needy, wanting assurances that the affection they feel is reciprocated. Maybe because of this, they have a particular affinity for animals. Don't try to break a Bronze's Sign's routines-they'll resent you for it, even if oftentimes they are too polite to say so.", + sign: "Taurus", + color: [255, 128, 0], + dates: ["April 20", "May 20"] + }, + Gold: { + name: "Gold", + description: + "Gold Signs are the reigning geniuses of the sign class spectrum, and chances are they know it. Witty and widely read, they enjoy conversation and debate, even when that conversation gets a little one-sided. They can come off as preachy, and they have a tendency to railroad, just driving into their interlocutors with the force of their intellect. Their arguments make perfect sense to themselves, but not always to those around them. Gold Signs are interested in a wide variety of topics, so they tend to be Jacks-of-all-trade, and can have trouble dedicating themselves to just a single hobby or career. They have a tendency to be high-energy, and can stress people out, including themselves. Their anxiety is such that they often need quite a bit of time alone with their projects. They can talk circles around most people, and they aren't afraid to use their intelligence to manipulate others to get what they want. They are good at making money, and also good at spending it. They aren't great financial planners, tending toward impulse purchases. In romance they lean toward partners who can keep up with them, both with their intellect and their energy, which can both be hard to match. ", + sign: "Gemini", + color: [255, 255, 0], + dates: ["May 21", "June 21"] + }, + Lime: { + name: "Lime", + description: + "Lime Signs are tumultuous, bringing great emotion and creativity to their endeavors. They are resolute in their decisions; if they are going to do something, they do it. They have a tendency toward melodrama, especially when they feel passionately about something, and their bad moods are loud and usually difficult to conceal. Hiding their feelings does not come naturally to them, so many Lime Signs cultivate a hard outer shell to hide the passionate, caring person inside. Lime Signs tend to have a large group of friends-they draw people to them with allure and the promise of excitement, and are usually unaware that they are doing it. They tend to focus on their own flaws, rather than their good points. Although they are exceedingly kind and empathetic individuals, many Lime Signs posses a mean streak. If you catch them on a bad day, they can be incredibly vicious. But it they take care to use their power for good, they make very loyal companions. Romance is extremely important to Lime Signs, and when they fall, they fall hard. They don't take rejection well, and a breakup can send them into a tailspin requiring an extended period of recovery.", + sign: "Cancer", + color: [127, 255, 0], + dates: ["June 22", "July 22"] + }, + Olive: { + name: "Olive", + description: + "Olive Signs are, by and large, incredibly agreeable people. They are generous and enthusiastic, ready to offer help to anyone who needs it. Luck plays a large role in their lives; Olive Signs have a knack for being in the right place at the right time. And even in the case that their luck goes bad, they can ride rough patches out without falling too far into depression or hopelessness. That said, Olive Signs are most comfortable with things that they are familiar with; new places and ideas often alarm them, resulting in a dogmatic insistence that their way is the right way. They can be quite bossy and domineering, although that usually comes out of a genuine belief that they know best and can help the ones they care about. They are extremely faithful friends and lovers, ready to drop everything and go into helper mode. However, if their trust is breached, there's no going back. No one can hold a grudge like an Olive Sign, and they aren't afraid to just pick up and leave if they decide something isn't working for them. Romance and companionship are extremely important to them, so even if they get hurt, their hearts remain open.", + sign: "Leo", + color: [0, 255, 0], + dates: ["July 23", "August 22"] + }, + Jade: { + name: "Jade", + description: + "Jade Signs are the zodiac's caretakers. Intelligent and steady, they are excellent organizers and planners. They are detail-oriented, and can tend toward perfectionism, never satisfied with their endeavors. If you hire on a Jade Sign, be prepared for an excellent product, but also no peace until that project is flawless. They are fussy and particular, which can cause friction with those around them, although a Jade Sign holds no one to as high a standard as they hold themselves. Since they are shy with strangers and slow to open up, Jade Signs can often come off as timid or doormats, when really they just prefer to come at conflicts in a less combative way. Naturally loyal and loving, they make wonderful doctors, parents, and caretakers, whether they are taking care of people, pets, or plants. In relationships, they can be slow to open up, and need someone willing to be patient enough to go at their pace. If all of this makes Jade Signs sound soft and nurturing, they are, but keep in mind that they can also be fiercely destructive if those they care about are threatened. It takes a lot to make a Jade Sign snap, but if they do, take cover.", + sign: "Virgo", + color: [0, 255, 127], + dates: ["August 23", "September 22"] + }, + Teal: { + name: "Teal", + description: + "Teal Signs are natural charmers. Social and flirtatious, they are great at parties and public speaking events. Even though they aren't afraid to use their many engaging qualities in both personal and business ventures, they have a strong moral sense. Right and wrong are very obvious to a Teal Sign, and it can frustrate them that others don't see the world the same way they do. Their idealism can make them strong defenders of justice, but it can also result in them being incredibly let down. Their strict adherence to procedure can lead to errors in judgement; they can be gullible and too quick to trust. They have vibrant imaginations, and enjoy fiction and roleplaying, and often those games will resemble the lives they want to be living. Deep down, they often long for a hero, someone they can idolize and count on, with the smarts and charisma to keep up with them. Unfortunately, they have a tendency to get involved with people who are very obviously wrong for them out of a desire not to be alone. Many Teal Signs are better off being single, at least until someone really extraordinary comes along.", + sign: "Libra", + color: [0, 255, 255], + dates: ["September 23", "October 23"] + }, + Blue: { + name: "Blue", + description: + "Let's not mince words: Blue Signs are the ones to watch. Of all the sign classes, they have the potential to do the most good, but also cause the worse harm. They can be incredibly effective, and also incredibly destructive. Tell a Blue Sign this and chances are they would agree with you. They are magnetic and adaptive, able to adjust how they present themselves in any situation. They have a mask for every occasion. They are obsessively dedicated, willing to throw themselves into work, play, and everything in between. Because of this, Blue Signs are highly valuable allies and friends. However, they are very selective when it comes to who they let into their inner circle. You could be best friends with a Blue Sign and still never truly know them. They are powerful and successful, but they also tend toward jealousy. They often resent those they see as more well-positioned than they are. A well-adjusted Blue Sign is fantastically competent and inspiring, but a Blue Sign at their worst is a force for chaos. In love they can find themselves having to choose between their ambitions and their relationships, often with great difficulty.", + sign: "Scorpio", + color: [0, 127, 255], + dates: ["October 24", "November 21"] + }, + Indigo: { + name: "Indigo", + description: + "Indigo Signs are the enthusiasts of the sign classes. Friendly and cheerful, their optimism is contagious. Being around a well-adjusted Indigo Sign is always a good time. It's hard not to be drawn into their excitable orbit, just like they are drawn in by anything and everything that piques their interest. And those interests are liable to change at any time. Indigo Signs will often surprise their friends and family by declaring they are no longer interested in what just last week they were claiming was their jam. If you catch an Indigo Signs in a philosophical mood, they can be unexpectedly poignant and introspective. A downside of all this jovial enthusiasm is that Indigo Signs often don't know their own strength. They are known to be careless, both physically and emotionally, their conversations punctuated by jostling elbows and tactless comments. They don't usually mean to offend, and are often shocked to find out they upset anyone. When this happens, they can dig their heels in and insist they did nothing wrong. In romance, Indigo Signs need partners who can keep up with their expansive personalities, as well as forgive them for the occasional hurt feeling or two.", + sign: "Sagittarius", + color: [0, 0, 255], + dates: ["November 22", "December 21"] + }, + Purple: { + name: "Purple", + description: + "Purple Signs are the workaholics of the sign classes. Ambitious and driven, they have a very specific path in mind to reach the pinnacle of their field, and will work tirelessly toward it. However, if their practical brains convince them that their goal is unrealistic, they may be slow to trust anyone with the secret of their true desires. They are often very funny, their wit veering toward the dryly macabre. Their fatalism can be incredibly humorous or terrible, depending who you ask. Purple Signs are usually the people who will say out loud what everyone else was thinking but was too nervous to mention. They are very stubborn, and once they've made up their mind about something, whether it be a restaurant choice or a political affiliation, it is difficult to change. They have trouble admitting they were mistaken, and also that they are upset. An oft-repeated phrase of the Purple Signs is, \"It's fine, don't worry about it.\" They will let arguments fester rather than face them head on. In love they tend to be strictly monogamous and fiercely devoted, ready to pledge themselves to a person the same way they do their goals-utterly, and without reservation.", + sign: "Capricorn", + color: [127, 0, 255], + dates: ["December 22", "January 19"] + }, + Violet: { + name: "Violet", + description: + "Violet Signs are the universe's eccentrics. Forget marching to their own drummer-Violets built their own drum, and it's probably weird. A good deal of this is natural, but they also have a distinct bent toward contrariness. They are the sorts to give the popular thing a pass. Personable and outlandish, they are ready to make friends with anyone, although if they aren't careful their 'game for anything' attitude can come across as clingy or desperate. When their feelings are reciprocated, however, they are very loyal friends. Politics and humanitarian causes are often very important to Violet Signs, and they will turn their considerable inventive energy into a sort of noblesse oblige, happy to offer their nontraditional approaches to help others. At their very best Violet Signs are artistic and inspired, but they tread the fine line between genius and maniac. Too often their more esoteric interests can come across as perverse or untoward, and they can have a hard time holding their tempers, especially if they feel that they are being belittled or ignored. Intelligence is enormously attractive to Violet Signs, and often an intellectual connection is necessary for them to be attracted to a prospective partner.", + sign: "Aquarius", + color: [255, 0, 255], + dates: ["January 20", "February 18"] + }, + Fuchsia: { + name: "Fuchsia", + description: + "Fuchsia Signs are the final of the sign classes, fittingly, also the most enigmatic. Possessing a strong imagination, they have an otherworldly quality to them that draws others in. Often, it has more to do with what they don't tell you than what they do, giving them an air of mystery that would more than likely perplex a Fuchsia sign if you told them about it. They aren't usually trying to be alluring-they're just lost in thought. Highly emotional, Fuchsia signs are sensitive and anxious, and tend to spend a lot of time worrying-about the world, the future, and what others think of them. They are artistic and talented, but can suffer from crippling bouts of depression, holding themselves to impossibly high standards. They have rich fantasy lives, and can get so caught up in daydreams that they sometimes forget to actually do things. Many Fuchsia Signs have trouble with follow-through, and it can take a lot to kick them out of their inertia. As far as romance goes, they need partners who are willing to put in the time to go at their pace, and who can handle how sensitive and emotional they can be.", + sign: "Pisces", + color: [255, 0, 127], + dates: ["February 19", "March 20"] + } +}; + +export const SignColorKeys = Object.keys(SignColor); +export const SignColorValues = Object.values(SignColor); + +export const TrueSignSchema = yup.object({ + name: yup.string().required(), + aspect: AspectSchema.required(), + sway: SwaySchema.required(), + color: SignColorSchema.required() +}); + +export type TrueSignType = { + name: string; + aspect: AspectType; + sway: SwayType; + color: SignColorType; +}; + +export const TrueSign: { + [key: string]: TrueSignType; +} = { + Aries: { + name: "Aries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arsces: { + name: "Arsces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arrius: { + name: "Arrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Rust + }, + Ariborn: { + name: "Ariborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arittarius: { + name: "Arittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arpia: { + name: "Arpia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arza: { + name: "Arza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arga: { + name: "Arga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Rust + }, + Aro: { + name: "Aro", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arcen: { + name: "Arcen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Rust + }, + Armini: { + name: "Armini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arun: { + name: "Arun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Rust + }, + Arist: { + name: "Arist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arsci: { + name: "Arsci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arnius: { + name: "Arnius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Aricorn: { + name: "Aricorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arittanius: { + name: "Arittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arpio: { + name: "Arpio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arra: { + name: "Arra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Argo: { + name: "Argo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arlo: { + name: "Arlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arcer: { + name: "Arcer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Armino: { + name: "Armino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Arus: { + name: "Arus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Rust + }, + Taurus: { + name: "Taurus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurist: { + name: "Taurist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taursci: { + name: "Taursci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurnius: { + name: "Taurnius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Tauricorn: { + name: "Tauricorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurittanius: { + name: "Taurittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurpio: { + name: "Taurpio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurra: { + name: "Taurra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurgo: { + name: "Taurgo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurlo: { + name: "Taurlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurcer: { + name: "Taurcer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurmino: { + name: "Taurmino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Bronze + }, + Taurun: { + name: "Taurun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Tauries: { + name: "Tauries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taursces: { + name: "Taursces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurrius: { + name: "Taurrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Tauriborn: { + name: "Tauriborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurittarius: { + name: "Taurittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurpia: { + name: "Taurpia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurza: { + name: "Taurza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurga: { + name: "Taurga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Tauro: { + name: "Tauro", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurcen: { + name: "Taurcen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Taurmini: { + name: "Taurmini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Bronze + }, + Gemini: { + name: "Gemini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemun: { + name: "Gemun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemries: { + name: "Gemries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemsces: { + name: "Gemsces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemrius: { + name: "Gemrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemiborn: { + name: "Gemiborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemittarius: { + name: "Gemittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gempia: { + name: "Gempia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemza: { + name: "Gemza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemga: { + name: "Gemga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemo: { + name: "Gemo", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemcen: { + name: "Gemcen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Gold + }, + Gemino: { + name: "Gemino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemus: { + name: "Gemus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemrist: { + name: "Gemrist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemsci: { + name: "Gemsci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemnius: { + name: "Gemnius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemicorn: { + name: "Gemicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemittanius: { + name: "Gemittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gempio: { + name: "Gempio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemra: { + name: "Gemra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemgo: { + name: "Gemgo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemlo: { + name: "Gemlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Gemcer: { + name: "Gemcer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Gold + }, + Cancer: { + name: "Cancer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Camino: { + name: "Camino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canus: { + name: "Canus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canrist: { + name: "Canrist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Cansci: { + name: "Cansci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Cannius: { + name: "Cannius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canicorn: { + name: "Canicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canittanius: { + name: "Canittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canpio: { + name: "Canpio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canra: { + name: "Canra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Cango: { + name: "Cango", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Canlo: { + name: "Canlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Lime + }, + Cancen: { + name: "Cancen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Lime + }, + Camini: { + name: "Camini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canun: { + name: "Canun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canries: { + name: "Canries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Lime + }, + Cansces: { + name: "Cansces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canrius: { + name: "Canrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Lime + }, + Caniborn: { + name: "Caniborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canittarius: { + name: "Canittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canpia: { + name: "Canpia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canza: { + name: "Canza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Lime + }, + Canga: { + name: "Canga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Lime + }, + Cano: { + name: "Cano", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Lime + }, + Leo: { + name: "Leo", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lecen: { + name: "Lecen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lemini: { + name: "Lemini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Olive + }, + Leun: { + name: "Leun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Olive + }, + Leries: { + name: "Leries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lesces: { + name: "Lesces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lerius: { + name: "Lerius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Olive + }, + Leiborn: { + name: "Leiborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Olive + }, + Leittarius: { + name: "Leittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lepia: { + name: "Lepia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Olive + }, + Leza: { + name: "Leza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lega: { + name: "Lega", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Olive + }, + Lelo: { + name: "Lelo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lecer: { + name: "Lecer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lemino: { + name: "Lemino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Leus: { + name: "Leus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lerist: { + name: "Lerist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lesci: { + name: "Lesci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lenius: { + name: "Lenius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Leicorn: { + name: "Leicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Leittanius: { + name: "Leittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lepio: { + name: "Lepio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lera: { + name: "Lera", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Lego: { + name: "Lego", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Olive + }, + Virgo: { + name: "Virgo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virlo: { + name: "Virlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Vircer: { + name: "Vircer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virmino: { + name: "Virmino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virus: { + name: "Virus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virist: { + name: "Virist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virsci: { + name: "Virsci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virnius: { + name: "Virnius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Viricorn: { + name: "Viricorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virittanius: { + name: "Virittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virpio: { + name: "Virpio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virra: { + name: "Virra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Jade + }, + Virga: { + name: "Virga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Jade + }, + Viro: { + name: "Viro", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Jade + }, + Vircen: { + name: "Vircen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virmini: { + name: "Virmini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virun: { + name: "Virun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Jade + }, + Viries: { + name: "Viries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virsces: { + name: "Virsces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virrius: { + name: "Virrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Jade + }, + Viriborn: { + name: "Viriborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virittarius: { + name: "Virittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virpia: { + name: "Virpia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Jade + }, + Virza: { + name: "Virza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Jade + }, + Libra: { + name: "Libra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Ligo: { + name: "Ligo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Liblo: { + name: "Liblo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Licer: { + name: "Licer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Limino: { + name: "Limino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libus: { + name: "Libus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Librist: { + name: "Librist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libsci: { + name: "Libsci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libnius: { + name: "Libnius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libicorn: { + name: "Libicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libittanius: { + name: "Libittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Lipio: { + name: "Lipio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Teal + }, + Libza: { + name: "Libza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Teal + }, + Liga: { + name: "Liga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libo: { + name: "Libo", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Teal + }, + Licen: { + name: "Licen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Teal + }, + Limini: { + name: "Limini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libun: { + name: "Libun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libries: { + name: "Libries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libsces: { + name: "Libsces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Teal + }, + Librius: { + name: "Librius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libiborn: { + name: "Libiborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Teal + }, + Libittarius: { + name: "Libittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Teal + }, + Lipia: { + name: "Lipia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Teal + }, + Scorpio: { + name: "Scorpio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorra: { + name: "Scorra", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorgo: { + name: "Scorgo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorlo: { + name: "Scorlo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorcer: { + name: "Scorcer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scormino: { + name: "Scormino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorus: { + name: "Scorus", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorist: { + name: "Scorist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorsci: { + name: "Scorsci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scornius: { + name: "Scornius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scoricorn: { + name: "Scoricorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorittanius: { + name: "Scorittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Blue + }, + Scorpia: { + name: "Scorpia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorza: { + name: "Scorza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorga: { + name: "Scorga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scoro: { + name: "Scoro", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorcen: { + name: "Scorcen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scormini: { + name: "Scormini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorun: { + name: "Scorun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scories: { + name: "Scories", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorsces: { + name: "Scorsces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorrius: { + name: "Scorrius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scoriborn: { + name: "Scoriborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Blue + }, + Scorittarius: { + name: "Scorittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Blue + }, + Sagittarius: { + name: "Sagittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagipia: { + name: "Sagipia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagiza: { + name: "Sagiza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagiga: { + name: "Sagiga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagio: { + name: "Sagio", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagicen: { + name: "Sagicen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagimini: { + name: "Sagimini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagiun: { + name: "Sagiun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagiries: { + name: "Sagiries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagisces: { + name: "Sagisces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagirius: { + name: "Sagirius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagiborn: { + name: "Sagiborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Indigo + }, + Sagittanius: { + name: "Sagittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagipio: { + name: "Sagipio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagira: { + name: "Sagira", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagigo: { + name: "Sagigo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagilo: { + name: "Sagilo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagicer: { + name: "Sagicer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagimino: { + name: "Sagimino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagius: { + name: "Sagius", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagirist: { + name: "Sagirist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagisci: { + name: "Sagisci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Saginius: { + name: "Saginius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Sagicorn: { + name: "Sagicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Indigo + }, + Capricorn: { + name: "Capricorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprittanius: { + name: "Caprittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Capripio: { + name: "Capripio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprira: { + name: "Caprira", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprigo: { + name: "Caprigo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprilo: { + name: "Caprilo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Capricer: { + name: "Capricer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprimino: { + name: "Caprimino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprius: { + name: "Caprius", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprist: { + name: "Caprist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprisci: { + name: "Caprisci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Caprinius: { + name: "Caprinius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Purple + }, + Capriborn: { + name: "Capriborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Purple + }, + Caprittarius: { + name: "Caprittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capripia: { + name: "Capripia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capriza: { + name: "Capriza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capriga: { + name: "Capriga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Purple + }, + Caprio: { + name: "Caprio", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capricen: { + name: "Capricen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Purple + }, + Caprimini: { + name: "Caprimini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capriun: { + name: "Capriun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capries: { + name: "Capries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Purple + }, + Caprisces: { + name: "Caprisces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Purple + }, + Capririus: { + name: "Capririus", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Purple + }, + Aquarius: { + name: "Aquarius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquiborn: { + name: "Aquiborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquittarius: { + name: "Aquittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquapia: { + name: "Aquapia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquaza: { + name: "Aquaza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquaga: { + name: "Aquaga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquo: { + name: "Aquo", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquacen: { + name: "Aquacen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquamini: { + name: "Aquamini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquiun: { + name: "Aquiun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquaries: { + name: "Aquaries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquasces: { + name: "Aquasces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Violet + }, + Aquanius: { + name: "Aquanius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquicorn: { + name: "Aquicorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquittanius: { + name: "Aquittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquapio: { + name: "Aquapio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquara: { + name: "Aquara", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquago: { + name: "Aquago", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aqualo: { + name: "Aqualo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquacer: { + name: "Aquacer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquamino: { + name: "Aquamino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquius: { + name: "Aquius", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquarist: { + name: "Aquarist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Aquasci: { + name: "Aquasci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Violet + }, + Pisces: { + name: "Pisces", + aspect: Aspect.Life, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pirius: { + name: "Pirius", + aspect: Aspect.Hope, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Piborn: { + name: "Piborn", + aspect: Aspect.Rage, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pittarius: { + name: "Pittarius", + aspect: Aspect.Void, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pipia: { + name: "Pipia", + aspect: Aspect.Light, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Piza: { + name: "Piza", + aspect: Aspect.Mind, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Piga: { + name: "Piga", + aspect: Aspect.Space, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pio: { + name: "Pio", + aspect: Aspect.Heart, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Picen: { + name: "Picen", + aspect: Aspect.Blood, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pimini: { + name: "Pimini", + aspect: Aspect.Doom, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Piun: { + name: "Piun", + aspect: Aspect.Breath, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Piries: { + name: "Piries", + aspect: Aspect.Time, + sway: Sway.Derse, + color: SignColor.Fuchsia + }, + Pisci: { + name: "Pisci", + aspect: Aspect.Life, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pinius: { + name: "Pinius", + aspect: Aspect.Hope, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Picorn: { + name: "Picorn", + aspect: Aspect.Rage, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pittanius: { + name: "Pittanius", + aspect: Aspect.Void, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pipio: { + name: "Pipio", + aspect: Aspect.Light, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pira: { + name: "Pira", + aspect: Aspect.Mind, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pigo: { + name: "Pigo", + aspect: Aspect.Space, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pilo: { + name: "Pilo", + aspect: Aspect.Heart, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Picer: { + name: "Picer", + aspect: Aspect.Blood, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pimino: { + name: "Pimino", + aspect: Aspect.Doom, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pius: { + name: "Pius", + aspect: Aspect.Breath, + sway: Sway.Prospit, + color: SignColor.Fuchsia + }, + Pirist: { + name: "Pirist", + aspect: Aspect.Time, + sway: Sway.Prospit, + color: SignColor.Fuchsia + } +}; + +export const TrueSignKeys = Object.keys(TrueSign); +export const TrueSignValues = Object.values(TrueSign); diff --git a/src/types/assist/generics.ts b/src/types/assist/generics.ts new file mode 100644 index 0000000..e565ef2 --- /dev/null +++ b/src/types/assist/generics.ts @@ -0,0 +1,6 @@ +import * as yup from "yup"; + +export const PolicySchema = yup + .string() + .oneOf(["yes", "ask", "no"]) + .default("no"); diff --git a/src/types/assist/language.ts b/src/types/assist/language.ts new file mode 100644 index 0000000..d2c9c5f --- /dev/null +++ b/src/types/assist/language.ts @@ -0,0 +1,51 @@ +export function AdaptivePossessive(owner: string, possession: string) { + return owner + (owner.endsWith("s") ? "'" : "'s") + " " + possession; +} + +export function PronounGrouper( + pronouns: [string, string, string], + sep?: string, + amount?: number +) { + return pronouns.slice(0, amount ?? 2).join(sep ?? "/"); +} + +export function HeightConverter(inches: number) { + var feetandinches = Math.floor(inches / 12) + "'" + (inches % 12) + '"'; + var meters = Math.floor((inches / 39.37) * 100) / 100 + "m"; + return feetandinches + " (" + meters + ")"; +} + +export function AgeConverter(sweeps: number, years?: boolean) { + return years + ? `${Math.round(sweeps * 2.1667 * 10) / 10} years` + : `${sweeps} sweeps`; +} + +export function Pluralize(stringe: string) { + if (stringe.match(/(?:s|ch|sh|x|z|[^aeiou]o)$/)) return stringe + "es"; + else if (stringe.match(/[aeiou](?:y|o)$/)) return stringe + "s"; + else if (stringe.match(/[^aeiou]y$/)) return stringe.slice(0, -1) + "ies"; + else if (stringe.match(/(?:f|fe)$/)) return stringe.slice(0, -1) + "ves"; + else return stringe + "s"; +} + +export function ArraySample(array: any[]) { + return array[Math.floor(Math.random() * array.length)]; +} + +export function ProperNounCase(string: string) { + return string + .split(" ") + .map((x) => x.charAt(0).toUpperCase() + x.slice(1).toLowerCase()) + .join(" "); +} + +export function PesterchumNameFormatter(string: string) { + return ( + string + + " [" + + string.replace(/^(([a-z])[a-z]+)(([A-Z])[a-z]+)$/, "$2$4").toUpperCase() + + "]" + ); +} diff --git a/src/types/assist/mongo.ts b/src/types/assist/mongo.ts new file mode 100644 index 0000000..d56baed --- /dev/null +++ b/src/types/assist/mongo.ts @@ -0,0 +1,6 @@ +import { ObjectId } from "mongodb"; +import * as yup from "yup"; + +export const ObjectIdSchema = yup.mixed((value): value is ObjectId => + ObjectId.isValid(value) +); diff --git a/src/types/client/dialoglog.ts b/src/types/client/dialoglog.ts new file mode 100644 index 0000000..6c2e550 --- /dev/null +++ b/src/types/client/dialoglog.ts @@ -0,0 +1,53 @@ +import * as yup from "yup"; + +export const SubmitDialogSchema = yup.object({ + owners: yup.array().of(yup.string().required()).required().min(1), + name: yup.string().required().min(3).max(100), + description: yup.string().max(10000).ensure(), + characters: yup + .array() + .of( + yup + .object({ + troll: yup.string().required(), + time: yup.string().ensure() + }) + .required() + ) + .required(), + log: yup + .array() + .of( + yup + .object({ + character: yup.number().notRequired().min(0), + quirk: yup.string().default("default"), + text: yup.string().required().max(2000) + }) + .required() + ) + .required() +}); + +export type SubmitDialog = yup.InferType; + +export const PartialDialogSchema = yup.object({ + owners: yup.array().of(yup.string()).min(1), + name: yup.string().min(3).max(100), + description: yup.string().max(10000), + characters: yup.array().of( + yup.object({ + troll: yup.string(), + time: yup.string() + }) + ), + log: yup.array().of( + yup.object({ + character: yup.number().min(0), + quirk: yup.string().default("default"), + text: yup.string().max(2000) + }) + ) +}); + +export type PartialDialog = yup.InferType; diff --git a/src/types/client/flair.ts b/src/types/client/flair.ts new file mode 100644 index 0000000..8c7f838 --- /dev/null +++ b/src/types/client/flair.ts @@ -0,0 +1,26 @@ +import * as yup from "yup"; +import { ColorSchema } from "../assist/color"; + +export const SubmitFlairSchema = yup + .object({ + name: yup.string().required().min(10).max(50), + alt: yup.string().max(1000), + + color: ColorSchema.required(), + link: yup.string().notRequired().url() + }) + .required(); + +export type SubmitFlair = yup.InferType; + +export const PartialFlairSchema = yup + .object({ + name: yup.string().min(10).max(50), + alt: yup.string().max(1000), + + color: ColorSchema, + link: yup.string().url() + }) + .required(); + +export type PartialFlair = yup.InferType; diff --git a/src/types/client/quirks.ts b/src/types/client/quirks.ts new file mode 100644 index 0000000..48b3bbc --- /dev/null +++ b/src/types/client/quirks.ts @@ -0,0 +1,10 @@ +import * as yup from "yup"; +import { QuirkSchema } from "../quirks"; + +export const SubmitQuirkHolderSchema = yup + .array() + .of(yup.tuple([yup.string().required().lowercase(), QuirkSchema.required()]).required()) + .required() + .test("has-default", 'Needs "default" Quirk Mode', v => v.some(([k, v]) => k === "default" || k === "Default")); + +export type SubmitQuirkHolder = yup.InferType; diff --git a/src/types/client/troll.ts b/src/types/client/troll.ts new file mode 100644 index 0000000..2e68366 --- /dev/null +++ b/src/types/client/troll.ts @@ -0,0 +1,236 @@ +import { ColorSchema } from "@/types/assist/color"; +import * as yup from "yup"; +import { ClassKeys, TrueSignKeys } from "../assist/extended_zodiac"; +import { PolicySchema } from "../assist/generics"; +import { SubmitQuirkHolderSchema } from "./quirks"; + +export const SubmitTrollSchema = yup + .object({ + // Name and identification + name: yup + .tuple([ + yup + .string() + .required() + .matches(/^[A-z]+$/, "Letters only") + .length(6) + .lowercase(), + yup + .string() + .required() + .matches(/^[A-z]+$/, "Letters only") + .length(6) + .lowercase() + ]) + .required(), + description: yup.string().max(10000).ensure(), + pronunciation: yup + .tuple([ + yup + .string() + .required() + .matches(/^[A-z-]+$/, "Letters only") + .lowercase(), + yup + .string() + .required() + .matches(/^[A-z-]+$/, "Letters only") + .lowercase() + ]) + .required(), + pronouns: yup + .array() + .of( + yup + .tuple([ + yup + .string() + .required() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase(), // she, he, they + yup + .string() + .required() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase(), // her, him, them + yup + .string() + .required() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase() // hers, his, theirs + ]) + .required() + ) + .required() + .min(1), + gender: yup + .string() + .required() + .matches(/^[A-z-_]+$/, "Letters only") + .min(3) + .max(30), + + // Personal + preferences: yup + .object({ + love: yup.array().of(yup.string().required().min(5).max(100)).required().min(3).max(10), + hate: yup.array().of(yup.string().required().min(5).max(100)).required().min(3).max(10) + }) + .required(), + facts: yup.array().of(yup.string().required().min(5).max(100)).required().min(3).max(10), + + // Hiveswap identity + trueSign: yup.string().required().oneOf(TrueSignKeys), + falseSign: yup + .string() + .nullable() + .transform(v => { + return v === "" ? null : v; + }) + .oneOf(TrueSignKeys), // "Keelez Bunbat" + class: yup.string().required().oneOf(ClassKeys), + + // Trollian + username: yup + .string() + .required() + .matches(/^(([a-z])[a-z]+)(([A-Z])[a-z]+)$/, "Username must match Pesterchum formatting."), + textColor: ColorSchema.notRequired(), // default to trueSign color if undefined, + quirks: SubmitQuirkHolderSchema.required(), // DO NOT HANDLE RIGHT NOW. + // Handled! :D + + // Physical stuff + species: yup + .string() + .notRequired() + .matches(/^([A-z-]+)|()$/, "Letters only"), // "Troll-*" if defined. Otherwise, just "Troll". + height: yup.number().required().positive(), // Inches + age: yup.number().required().positive(), // Sweeps + image: yup.string().required().url(), + // Meta stuff + policies: yup + .object({ + fanart: PolicySchema.required(), + fanartOthers: PolicySchema.required(), + kinning: PolicySchema.required(), + shipping: PolicySchema.required(), + fanfiction: PolicySchema.required() + }) + .required() + // owners: yup.array().of(yup.string().required()).required().min(1), + // flairs: yup.array().of(yup.mixed()).required().ensure(), + }) + .required(); + +export type SubmitTroll = yup.InferType; + +export const PartialTrollSchema = yup + .object({ + // Name and identification + name: yup.tuple([ + yup + .string() + .matches(/^[A-z]+$/, "Letters only") + .length(6) + .lowercase(), + yup + .string() + .matches(/^[A-z]+$/, "Letters only") + .length(6) + .lowercase() + ]), + description: yup.string().max(10000), + pronunciation: yup.tuple([ + yup + .string() + .matches(/^[A-z-]+$/, "Letters only") + .lowercase(), + yup + .string() + .matches(/^[A-z-]+$/, "Letters only") + .lowercase() + ]), + pronouns: yup + .array() + .of( + yup.tuple([ + yup + .string() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase(), // she, he, they + yup + .string() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase(), // her, him, them + yup + .string() + .matches(/^[A-z]+$/, "Letters only") + .min(1) + .max(10) + .lowercase() // hers, his, theirs + ]) + ) + .min(1), + gender: yup + .string() + .matches(/^[A-z-_]+$/, "Letters only") + .min(3) + .max(30), + + // Personal + preferences: yup.object({ + love: yup.array().of(yup.string().min(5).max(100)).min(3).max(10), + hate: yup.array().of(yup.string().min(5).max(100)).min(3).max(10) + }), + facts: yup.array().of(yup.string().min(5).max(100)).min(3).max(10), + + // Hiveswap identity + trueSign: yup.string().oneOf(TrueSignKeys), + falseSign: yup + .string() + .nullable() + .transform(v => { + return v === "" ? null : v; + }) + .oneOf(TrueSignKeys), // "Keelez Bunbat" + class: yup.string().oneOf(ClassKeys), + + // Trollian + username: yup + .string() + .matches(/^(([a-z])[a-z]+)(([A-Z])[a-z]+)$/, "Username must match Pesterchum formatting."), + textColor: yup.tuple([ + yup.number().min(0).max(255), + yup.number().min(0).max(255), + yup.number().min(0).max(255) + ]), + quirks: SubmitQuirkHolderSchema, // DO NOT HANDLE RIGHT NOW. + // Handled! :D + + // Physical stuff + species: yup.string().matches(/^([A-z-]+)|()$/, "Letters only"), // "Troll-*" if defined. Otherwise, just "Troll". + height: yup.number().positive(), // Inches + age: yup.number().positive(), // Sweeps + image: yup.string().url(), + // Meta stuff + policies: yup.object({ + fanart: PolicySchema, + fanartOthers: PolicySchema, + kinning: PolicySchema, + shipping: PolicySchema, + fanfiction: PolicySchema + }) + }) + .required(); + +export type PartialTroll = yup.InferType; diff --git a/src/types/client/user.ts b/src/types/client/user.ts new file mode 100644 index 0000000..402dab4 --- /dev/null +++ b/src/types/client/user.ts @@ -0,0 +1,50 @@ +import * as yup from "yup"; +import { ColorSchema } from "../assist/color"; +import { TrueSignKeys } from "../assist/extended_zodiac"; + +export const SubmitUserSchema = yup + .object({ + name: yup + .string() + .required() + .matches(/^[\w-]+$/, "No special characters or spaces") + .min(3) + .max(50) + .lowercase(), + description: yup.string().max(10000).ensure(), + url: yup.string().notRequired().url(), + trueSign: yup.string().required().oneOf(TrueSignKeys), + color: ColorSchema.required(), + pfp: yup.string().notRequired().url(), + code: yup.string().notRequired().max(256, "Too secure!!") + // flairs: yup.array().of(ClientFlairSchema).required(), + }) + .required(); + +export type SubmitUser = yup.InferType; + +export const PartialUserSchema = yup + .object({ + name: yup + .string() + .matches(/^[\w-]+$/, "No special characters or spaces") + .min(3) + .max(50) + .lowercase(), + description: yup.string().max(10000), + url: yup.string().url(), + trueSign: yup + .string() + .nullable() + .transform(v => { + return v === "" ? null : v; + }) + .oneOf(TrueSignKeys), + color: yup.tuple([yup.number().min(0).max(255), yup.number().min(0).max(255), yup.number().min(0).max(255)]), + pfp: yup.string().url(), + code: yup.string().max(256, "Too secure!!") + // flairs: yup.array().of(ClientFlairSchema).required(), + }) + .required(); + +export type PartialUser = yup.InferType; diff --git a/src/types/dialoglog.ts b/src/types/dialoglog.ts new file mode 100644 index 0000000..ba582e7 --- /dev/null +++ b/src/types/dialoglog.ts @@ -0,0 +1,45 @@ +import { WithId } from "@/lib/db/crud"; +import * as yup from "yup"; +import { ObjectIdSchema } from "./assist/mongo"; +import { SubmitDialogSchema } from "./client/dialoglog"; +import { ClientTroll, ClientTrollSchema } from "./troll"; +import { ClientUserSchema } from "./user"; + +export const ServerDialogSchema = SubmitDialogSchema.shape({ + owners: yup.array().of(ObjectIdSchema.required()).required().min(1), + characters: yup + .array() + .of( + yup + .object({ + troll: ObjectIdSchema.required(), + time: yup.string().ensure() + }) + .required() + ) + .required() +}); + +export type ServerDialog = WithId>; + +export const ClientDialogSchema = SubmitDialogSchema.shape({ + owners: yup.array().of(ClientUserSchema.required()).required().min(1), + characters: yup + .array() + .of( + yup + .object({ + troll: ClientTrollSchema.required(), + time: yup.string().ensure() + }) + .required() + ) + .required() +}); + +export interface ClientDialog extends yup.InferType { + characters: { + troll: ClientTroll; + time: string; + }[]; +} // [SEARCH: HACK] a hack. thanks, jquense diff --git a/src/types/flair.ts b/src/types/flair.ts new file mode 100644 index 0000000..c1e3e07 --- /dev/null +++ b/src/types/flair.ts @@ -0,0 +1,11 @@ +import { WithId } from "@/lib/db/crud"; +import * as yup from "yup"; +import { SubmitFlairSchema } from "./client/flair"; + +export const ServerFlairSchema = SubmitFlairSchema.shape({}); + +export type ServerFlair = WithId>; + +export const ClientFlairSchema = SubmitFlairSchema.shape({}); + +export type ClientFlair = yup.InferType; diff --git a/src/types/quirks.ts b/src/types/quirks.ts new file mode 100644 index 0000000..a057bdd --- /dev/null +++ b/src/types/quirks.ts @@ -0,0 +1,87 @@ +import * as yup from "yup"; + +// See FlaringK's Quirk Builder for type info. +// https://flaringk.github.io/quirkbuilder/ +// https://discord.com/channels/294616636726444033/1067996841532215337/1111282886038016130 + +export const QuirkSchema = yup + .object({ + quirk: yup + .array() + .of( + yup + .object({ + type: yup + .string() + .oneOf([ + "prefix", + "suffix", + "simple", + "regex", + "case", + "case_simple", + "case_regex", + "case_pos" + ]) + .required(), + find: yup.string().notRequired(), + replace: yup + .array() + .of( + yup + .string() + .required() + .matches(/^([A-z-]+)|()$/, "Letters only") + ) + .required() + .min(1), + condition: yup.string().notRequired() + }) + .required() + ) + .required() + }) + .required(); + +export type Quirk = yup.InferType; + +export const ServerQuirkHolderSchema = yup.mixed(); // cant do SHIT in yup + +export type ServerQuirkHolder = { [key: string]: Quirk }; + +export const QuirkReplacementTypes: { + [key: string]: { find: string | null; replace: string }; +} = { + prefix: { + find: null, + replace: "The text that precedes the main text." + }, + suffix: { + find: null, + replace: "The text that proceeds the main text." + }, + simple: { + find: "Text to find what you want to replace.", + replace: "The text that replaces the found text." + }, + regex: { + find: "A Regular Expresion to find what you want to replace.", + replace: "A replacement expression that replaces the found text." + }, + case: { + find: null, + replace: 'Change the case of all text. "lower" for lowercase. "upper" for uppercase.' + }, + case_simple: { + find: "Text to find what you want to change the case of.", + replace: '"lower" for lowercase. "upper" for uppercase.' + }, + case_regex: { + find: "A Regular Expresion to find what you want to change the case of.", + replace: '"lower" for lowercase. "upper" for uppercase.' + }, + case_pos: { + find: 'A comma-separated array of properties.\n\n1st is number of characters (type "Infinity" for all),\n2nd is start position (start, end),\n3rd is character seperation (like Gamzee for selecting every other character),\n 4th is the union modifier. "true" means the position will affect the entire sentence. "false" or no input means the position will affect each word.\n\nExample: "2, start, 1, false" for words to look like "GrEetings EvErybody".', + replace: '"lower" for lowercase. "upper" for uppercase.' + } +}; diff --git a/src/types/troll.ts b/src/types/troll.ts new file mode 100644 index 0000000..253a858 --- /dev/null +++ b/src/types/troll.ts @@ -0,0 +1,30 @@ +import { WithId } from "@/lib/db/crud"; +import * as yup from "yup"; +import { ClassSchema, TrueSignSchema } from "./assist/extended_zodiac"; +import { ObjectIdSchema } from "./assist/mongo"; +import { SubmitTrollSchema } from "./client/troll"; +import { ClientFlairSchema } from "./flair"; +import { ServerQuirkHolder, ServerQuirkHolderSchema } from "./quirks"; +import { ClientUserSchema } from "./user"; + +export const ServerTrollSchema = SubmitTrollSchema.shape({ + owners: yup.array().of(ObjectIdSchema.required()).required().min(1), + flairs: yup.array().of(ObjectIdSchema.required()).required(), + quirks: ServerQuirkHolderSchema.required(), + updatedDate: yup.date().notRequired() +}); + +export type ServerTroll = WithId>; + +export const ClientTrollSchema = SubmitTrollSchema.shape({ + owners: yup.array().of(ClientUserSchema.required()).required().min(1), + flairs: yup.array().of(ClientFlairSchema.required()).required(), + quirks: ServerQuirkHolderSchema.required(), + trueSign: TrueSignSchema.required(), + falseSign: TrueSignSchema.notRequired(), + class: ClassSchema.required() +}); + +export interface ClientTroll extends yup.InferType { + quirks: ServerQuirkHolder; +} // [SEARCH: HACK] a hack. thanks, jquense diff --git a/src/types/user.ts b/src/types/user.ts new file mode 100644 index 0000000..269064a --- /dev/null +++ b/src/types/user.ts @@ -0,0 +1,22 @@ +import { WithId } from "@/lib/db/crud"; +import * as yup from "yup"; +import { TrueSignSchema } from "./assist/extended_zodiac"; +import { ObjectIdSchema } from "./assist/mongo"; +import { SubmitUserSchema } from "./client/user"; +import { ClientFlairSchema } from "./flair"; + +export const ServerUserSchema = SubmitUserSchema.shape({ + flairs: yup.array().of(ObjectIdSchema.required()).required(), + code: yup.string().required(), + updatedDate: yup.date().notRequired() +}); + +export type ServerUser = WithId>; + +export const ClientUserSchema = SubmitUserSchema.shape({ + flairs: yup.array().of(ClientFlairSchema.required()).required(), + trueSign: TrueSignSchema.required(), + updatedDate: yup.number().notRequired() +}); + +export type ClientUser = yup.InferType; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d0878aa --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2021", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve", + "strict": true, + "skipLibCheck": true, + "noErrorTruncation": true, + "moduleResolution": "node", + "rootDir": "src", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "outDir": "./dist/" + }, + "include": ["src/**/*.d.ts", "src/**/*.ts"] +}