removed socket io and extracted lobby form

This commit is contained in:
shrt 2025-03-27 19:21:34 +01:00
parent cc1a27e1c9
commit a00116a61d
19 changed files with 138 additions and 712 deletions

View File

@ -5,6 +5,10 @@
import "./src/env.js"; import "./src/env.js";
/** @type {import("next").NextConfig} */ /** @type {import("next").NextConfig} */
const config = {}; const config = {
eslint: {
ignoreDuringBuilds: true,
},
};
export default config; export default config;

View File

@ -1,6 +0,0 @@
{
"watch": ["src/server/socket"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "pnpm tsx ./src/server/socket/server.ts"
}

View File

@ -4,11 +4,9 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "./start-database.sh && concurrently \"pnpm next dev --turbo\" \"pnpm dev:socket\"", "dev": "./start-database.sh && pnpm next dev --turbo",
"dev:socket": "pnpm nodemon ./src/server/socket/server.ts",
"start:socket": "node ./dist/src/server/socket/server.js",
"start": "next start",
"build": "next build", "build": "next build",
"start": "next start",
"check": "next lint && tsc --noEmit", "check": "next lint && tsc --noEmit",
"db:generate": "drizzle-kit generate", "db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate", "db:migrate": "drizzle-kit migrate",
@ -40,7 +38,6 @@
"@types/express": "^5.0.1", "@types/express": "^5.0.1",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"concurrently": "^9.1.2",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"drizzle-orm": "^0.41.0", "drizzle-orm": "^0.41.0",
"express": "^4.21.2", "express": "^4.21.2",
@ -49,14 +46,11 @@
"next": "^15.2.3", "next": "^15.2.3",
"next-auth": "5.0.0-beta.25", "next-auth": "5.0.0-beta.25",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nodemon": "^3.1.9",
"postgres": "^3.4.5", "postgres": "^3.4.5",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.54.2", "react-hook-form": "^7.54.2",
"server-only": "^0.0.1", "server-only": "^0.0.1",
"socket.io": "^4.8.1",
"socket.io-client": "^4.8.1",
"sonner": "^2.0.1", "sonner": "^2.0.1",
"superjson": "^2.2.1", "superjson": "^2.2.1",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",

451
pnpm-lock.yaml generated
View File

@ -62,9 +62,6 @@ importers:
clsx: clsx:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.1.1 version: 2.1.1
concurrently:
specifier: ^9.1.2
version: 9.1.2
dotenv: dotenv:
specifier: ^16.4.7 specifier: ^16.4.7
version: 16.4.7 version: 16.4.7
@ -89,9 +86,6 @@ importers:
next-themes: next-themes:
specifier: ^0.4.6 specifier: ^0.4.6
version: 0.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 0.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
nodemon:
specifier: ^3.1.9
version: 3.1.9
postgres: postgres:
specifier: ^3.4.5 specifier: ^3.4.5
version: 3.4.5 version: 3.4.5
@ -107,12 +101,6 @@ importers:
server-only: server-only:
specifier: ^0.0.1 specifier: ^0.0.1
version: 0.0.1 version: 0.0.1
socket.io:
specifier: ^4.8.1
version: 4.8.1
socket.io-client:
specifier: ^4.8.1
version: 4.8.1
sonner: sonner:
specifier: ^2.0.1 specifier: ^2.0.1
version: 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -1252,9 +1240,6 @@ packages:
'@rushstack/eslint-patch@1.11.0': '@rushstack/eslint-patch@1.11.0':
resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==}
'@socket.io/component-emitter@3.1.2':
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
'@standard-schema/utils@0.3.0': '@standard-schema/utils@0.3.0':
resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
@ -1409,9 +1394,6 @@ packages:
'@types/cookie@0.6.0': '@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
'@types/cors@2.8.17':
resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
'@types/estree@1.0.7': '@types/estree@1.0.7':
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
@ -1575,18 +1557,10 @@ packages:
ajv@6.12.6: ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-styles@4.3.0: ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'} engines: {node: '>=8'}
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
argparse@2.0.1: argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@ -1659,14 +1633,6 @@ packages:
balanced-match@1.0.2: balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
base64id@2.0.0:
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
engines: {node: ^4.5.0 || >= 5.9}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
body-parser@1.20.3: body-parser@1.20.3:
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@ -1715,20 +1681,12 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'} engines: {node: '>=10'}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
class-variance-authority@0.7.1: class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
client-only@0.0.1: client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
clsx@2.1.1: clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -1750,11 +1708,6 @@ packages:
concat-map@0.0.1: concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
concurrently@9.1.2:
resolution: {integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==}
engines: {node: '>=18'}
hasBin: true
content-disposition@0.5.4: content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -1770,18 +1723,10 @@ packages:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
copy-anything@3.0.5: copy-anything@3.0.5:
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
engines: {node: '>=12.13'} engines: {node: '>=12.13'}
cors@2.8.5:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
cross-spawn@7.0.6: cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -1820,15 +1765,6 @@ packages:
supports-color: supports-color:
optional: true optional: true
debug@4.3.7:
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
debug@4.4.0: debug@4.4.0:
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -1976,9 +1912,6 @@ packages:
ee-first@1.1.1: ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2: emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
@ -1990,17 +1923,6 @@ packages:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
engine.io-client@6.6.3:
resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==}
engine.io-parser@5.2.3:
resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
engines: {node: '>=10.0.0'}
engine.io@6.6.4:
resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==}
engines: {node: '>=10.2.0'}
enhanced-resolve@5.18.1: enhanced-resolve@5.18.1:
resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
@ -2061,10 +1983,6 @@ packages:
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
escape-html@1.0.3: escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@ -2287,10 +2205,6 @@ packages:
generate-function@2.3.1: generate-function@2.3.1:
resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.3.0: get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2340,10 +2254,6 @@ packages:
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
has-flag@4.0.0: has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2379,9 +2289,6 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
ignore-by-default@1.0.1:
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
ignore@5.3.2: ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
@ -2420,10 +2327,6 @@ packages:
resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-boolean-object@1.2.2: is-boolean-object@1.2.2:
resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2455,10 +2358,6 @@ packages:
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-generator-function@1.1.0: is-generator-function@1.1.0:
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2655,9 +2554,6 @@ packages:
lodash.merge@4.6.2: lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
long@5.3.1: long@5.3.1:
resolution: {integrity: sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==} resolution: {integrity: sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==}
@ -2793,15 +2689,6 @@ packages:
sass: sass:
optional: true optional: true
nodemon@3.1.9:
resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==}
engines: {node: '>=10'}
hasBin: true
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
oauth4webapi@3.3.1: oauth4webapi@3.3.1:
resolution: {integrity: sha512-ZwX7UqYrP3Lr+Glhca3a1/nF2jqf7VVyJfhGuW5JtrfDUxt0u+IoBPzFjZ2dd7PJGkdM6CFPVVYzuDYKHv101A==} resolution: {integrity: sha512-ZwX7UqYrP3Lr+Glhca3a1/nF2jqf7VVyJfhGuW5JtrfDUxt0u+IoBPzFjZ2dd7PJGkdM6CFPVVYzuDYKHv101A==}
@ -2996,9 +2883,6 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
pstree.remy@1.1.8:
resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
punycode@2.3.1: punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -3066,10 +2950,6 @@ packages:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
reflect.getprototypeof@1.0.10: reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3078,10 +2958,6 @@ packages:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
resolve-from@4.0.0: resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -3108,9 +2984,6 @@ packages:
run-parallel@1.2.0: run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
safe-array-concat@1.1.3: safe-array-concat@1.1.3:
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
engines: {node: '>=0.4'} engines: {node: '>=0.4'}
@ -3205,25 +3078,6 @@ packages:
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
simple-update-notifier@2.0.0:
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
engines: {node: '>=10'}
socket.io-adapter@2.5.5:
resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==}
socket.io-client@4.8.1:
resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==}
engines: {node: '>=10.0.0'}
socket.io-parser@4.2.4:
resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==}
engines: {node: '>=10.0.0'}
socket.io@4.8.1:
resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==}
engines: {node: '>=10.2.0'}
sonner@2.0.1: sonner@2.0.1:
resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==} resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==}
peerDependencies: peerDependencies:
@ -3256,10 +3110,6 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string.prototype.includes@2.0.1: string.prototype.includes@2.0.1:
resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3283,10 +3133,6 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-bom@3.0.0: strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -3312,18 +3158,10 @@ packages:
resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
engines: {node: '>=16'} engines: {node: '>=16'}
supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
supports-color@7.2.0: supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'} engines: {node: '>=8'}
supports-color@8.1.1:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
supports-preserve-symlinks-flag@1.0.0: supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3350,14 +3188,6 @@ packages:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'} engines: {node: '>=0.6'}
touch@3.1.1:
resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
hasBin: true
tree-kill@1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
ts-api-utils@2.1.0: ts-api-utils@2.1.0:
resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
engines: {node: '>=18.12'} engines: {node: '>=18.12'}
@ -3418,9 +3248,6 @@ packages:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
undefsafe@2.0.5:
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
undici-types@6.19.8: undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
@ -3489,38 +3316,6 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
ws@8.17.1:
resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
xmlhttprequest-ssl@2.1.2:
resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==}
engines: {node: '>=0.4.0'}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
yocto-queue@0.1.0: yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3806,7 +3601,7 @@ snapshots:
'@eslint/config-array@0.19.2': '@eslint/config-array@0.19.2':
dependencies: dependencies:
'@eslint/object-schema': 2.1.6 '@eslint/object-schema': 2.1.6
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
minimatch: 3.1.2 minimatch: 3.1.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -3820,7 +3615,7 @@ snapshots:
'@eslint/eslintrc@3.3.1': '@eslint/eslintrc@3.3.1':
dependencies: dependencies:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
espree: 10.3.0 espree: 10.3.0
globals: 14.0.0 globals: 14.0.0
ignore: 5.3.2 ignore: 5.3.2
@ -4327,8 +4122,6 @@ snapshots:
'@rushstack/eslint-patch@1.11.0': {} '@rushstack/eslint-patch@1.11.0': {}
'@socket.io/component-emitter@3.1.2': {}
'@standard-schema/utils@0.3.0': {} '@standard-schema/utils@0.3.0': {}
'@swc/counter@0.1.3': {} '@swc/counter@0.1.3': {}
@ -4452,10 +4245,6 @@ snapshots:
'@types/cookie@0.6.0': {} '@types/cookie@0.6.0': {}
'@types/cors@2.8.17':
dependencies:
'@types/node': 20.17.27
'@types/estree@1.0.7': {} '@types/estree@1.0.7': {}
'@types/express-serve-static-core@5.0.6': '@types/express-serve-static-core@5.0.6':
@ -4529,7 +4318,7 @@ snapshots:
'@typescript-eslint/types': 8.28.0 '@typescript-eslint/types': 8.28.0
'@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2)
'@typescript-eslint/visitor-keys': 8.28.0 '@typescript-eslint/visitor-keys': 8.28.0
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
eslint: 9.23.0(jiti@2.4.2) eslint: 9.23.0(jiti@2.4.2)
typescript: 5.8.2 typescript: 5.8.2
transitivePeerDependencies: transitivePeerDependencies:
@ -4544,7 +4333,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2)
'@typescript-eslint/utils': 8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) '@typescript-eslint/utils': 8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
eslint: 9.23.0(jiti@2.4.2) eslint: 9.23.0(jiti@2.4.2)
ts-api-utils: 2.1.0(typescript@5.8.2) ts-api-utils: 2.1.0(typescript@5.8.2)
typescript: 5.8.2 typescript: 5.8.2
@ -4557,7 +4346,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 8.28.0 '@typescript-eslint/types': 8.28.0
'@typescript-eslint/visitor-keys': 8.28.0 '@typescript-eslint/visitor-keys': 8.28.0
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
fast-glob: 3.3.3 fast-glob: 3.3.3
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.5 minimatch: 9.0.5
@ -4636,17 +4425,10 @@ snapshots:
json-schema-traverse: 0.4.1 json-schema-traverse: 0.4.1
uri-js: 4.4.1 uri-js: 4.4.1
ansi-regex@5.0.1: {}
ansi-styles@4.3.0: ansi-styles@4.3.0:
dependencies: dependencies:
color-convert: 2.0.1 color-convert: 2.0.1
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
argparse@2.0.1: {} argparse@2.0.1: {}
aria-hidden@1.2.4: aria-hidden@1.2.4:
@ -4738,10 +4520,6 @@ snapshots:
balanced-match@1.0.2: {} balanced-match@1.0.2: {}
base64id@2.0.0: {}
binary-extensions@2.3.0: {}
body-parser@1.20.3: body-parser@1.20.3:
dependencies: dependencies:
bytes: 3.1.2 bytes: 3.1.2
@ -4806,30 +4584,12 @@ snapshots:
ansi-styles: 4.3.0 ansi-styles: 4.3.0
supports-color: 7.2.0 supports-color: 7.2.0
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
class-variance-authority@0.7.1: class-variance-authority@0.7.1:
dependencies: dependencies:
clsx: 2.1.1 clsx: 2.1.1
client-only@0.0.1: {} client-only@0.0.1: {}
cliui@8.0.1:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
clsx@2.1.1: {} clsx@2.1.1: {}
color-convert@2.0.1: color-convert@2.0.1:
@ -4852,16 +4612,6 @@ snapshots:
concat-map@0.0.1: {} concat-map@0.0.1: {}
concurrently@9.1.2:
dependencies:
chalk: 4.1.2
lodash: 4.17.21
rxjs: 7.8.2
shell-quote: 1.8.2
supports-color: 8.1.1
tree-kill: 1.2.2
yargs: 17.7.2
content-disposition@0.5.4: content-disposition@0.5.4:
dependencies: dependencies:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -4872,17 +4622,10 @@ snapshots:
cookie@0.7.1: {} cookie@0.7.1: {}
cookie@0.7.2: {}
copy-anything@3.0.5: copy-anything@3.0.5:
dependencies: dependencies:
is-what: 4.1.16 is-what: 4.1.16
cors@2.8.5:
dependencies:
object-assign: 4.1.1
vary: 1.1.2
cross-spawn@7.0.6: cross-spawn@7.0.6:
dependencies: dependencies:
path-key: 3.1.1 path-key: 3.1.1
@ -4919,16 +4662,10 @@ snapshots:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
debug@4.3.7: debug@4.4.0:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
debug@4.4.0(supports-color@5.5.0):
dependencies:
ms: 2.1.3
optionalDependencies:
supports-color: 5.5.0
deep-is@0.1.4: {} deep-is@0.1.4: {}
define-data-property@1.1.4: define-data-property@1.1.4:
@ -4983,44 +4720,12 @@ snapshots:
ee-first@1.1.1: {} ee-first@1.1.1: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {} emoji-regex@9.2.2: {}
encodeurl@1.0.2: {} encodeurl@1.0.2: {}
encodeurl@2.0.0: {} encodeurl@2.0.0: {}
engine.io-client@6.6.3:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.3.7
engine.io-parser: 5.2.3
ws: 8.17.1
xmlhttprequest-ssl: 2.1.2
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
engine.io-parser@5.2.3: {}
engine.io@6.6.4:
dependencies:
'@types/cors': 2.8.17
'@types/node': 20.17.27
accepts: 1.3.8
base64id: 2.0.0
cookie: 0.7.2
cors: 2.8.5
debug: 4.3.7
engine.io-parser: 5.2.3
ws: 8.17.1
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
enhanced-resolve@5.18.1: enhanced-resolve@5.18.1:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@ -5128,7 +4833,7 @@ snapshots:
esbuild-register@3.6.0(esbuild@0.19.12): esbuild-register@3.6.0(esbuild@0.19.12):
dependencies: dependencies:
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
esbuild: 0.19.12 esbuild: 0.19.12
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -5212,8 +4917,6 @@ snapshots:
'@esbuild/win32-ia32': 0.25.1 '@esbuild/win32-ia32': 0.25.1
'@esbuild/win32-x64': 0.25.1 '@esbuild/win32-x64': 0.25.1
escalade@3.2.0: {}
escape-html@1.0.3: {} escape-html@1.0.3: {}
escape-string-regexp@4.0.0: {} escape-string-regexp@4.0.0: {}
@ -5249,7 +4952,7 @@ snapshots:
eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)): eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)):
dependencies: dependencies:
'@nolyfill/is-core-module': 1.0.39 '@nolyfill/is-core-module': 1.0.39
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
eslint: 9.23.0(jiti@2.4.2) eslint: 9.23.0(jiti@2.4.2)
get-tsconfig: 4.10.0 get-tsconfig: 4.10.0
is-bun-module: 1.3.0 is-bun-module: 1.3.0
@ -5377,7 +5080,7 @@ snapshots:
ajv: 6.12.6 ajv: 6.12.6
chalk: 4.1.2 chalk: 4.1.2
cross-spawn: 7.0.6 cross-spawn: 7.0.6
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
escape-string-regexp: 4.0.0 escape-string-regexp: 4.0.0
eslint-scope: 8.3.0 eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0 eslint-visitor-keys: 4.2.0
@ -5546,7 +5249,7 @@ snapshots:
gel@2.0.1: gel@2.0.1:
dependencies: dependencies:
'@petamoriken/float16': 3.9.2 '@petamoriken/float16': 3.9.2
debug: 4.4.0(supports-color@5.5.0) debug: 4.4.0
env-paths: 3.0.0 env-paths: 3.0.0
semver: 7.7.1 semver: 7.7.1
shell-quote: 1.8.2 shell-quote: 1.8.2
@ -5558,8 +5261,6 @@ snapshots:
dependencies: dependencies:
is-property: 1.0.2 is-property: 1.0.2
get-caller-file@2.0.5: {}
get-intrinsic@1.3.0: get-intrinsic@1.3.0:
dependencies: dependencies:
call-bind-apply-helpers: 1.0.2 call-bind-apply-helpers: 1.0.2
@ -5613,8 +5314,6 @@ snapshots:
has-bigints@1.1.0: {} has-bigints@1.1.0: {}
has-flag@3.0.0: {}
has-flag@4.0.0: {} has-flag@4.0.0: {}
has-property-descriptors@1.0.2: has-property-descriptors@1.0.2:
@ -5651,8 +5350,6 @@ snapshots:
dependencies: dependencies:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
ignore-by-default@1.0.1: {}
ignore@5.3.2: {} ignore@5.3.2: {}
import-fresh@3.3.1: import-fresh@3.3.1:
@ -5693,10 +5390,6 @@ snapshots:
dependencies: dependencies:
has-bigints: 1.1.0 has-bigints: 1.1.0
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-boolean-object@1.2.2: is-boolean-object@1.2.2:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
@ -5729,8 +5422,6 @@ snapshots:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
is-fullwidth-code-point@3.0.0: {}
is-generator-function@1.1.0: is-generator-function@1.1.0:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
@ -5904,8 +5595,6 @@ snapshots:
lodash.merge@4.6.2: {} lodash.merge@4.6.2: {}
lodash@4.17.21: {}
long@5.3.1: {} long@5.3.1: {}
loose-envify@1.4.0: loose-envify@1.4.0:
@ -6015,21 +5704,6 @@ snapshots:
- '@babel/core' - '@babel/core'
- babel-plugin-macros - babel-plugin-macros
nodemon@3.1.9:
dependencies:
chokidar: 3.6.0
debug: 4.4.0(supports-color@5.5.0)
ignore-by-default: 1.0.1
minimatch: 3.1.2
pstree.remy: 1.1.8
semver: 7.7.1
simple-update-notifier: 2.0.0
supports-color: 5.5.0
touch: 3.1.1
undefsafe: 2.0.5
normalize-path@3.0.0: {}
oauth4webapi@3.3.1: {} oauth4webapi@3.3.1: {}
object-assign@4.1.1: {} object-assign@4.1.1: {}
@ -6171,8 +5845,6 @@ snapshots:
forwarded: 0.2.0 forwarded: 0.2.0
ipaddr.js: 1.9.1 ipaddr.js: 1.9.1
pstree.remy@1.1.8: {}
punycode@2.3.1: {} punycode@2.3.1: {}
qs@6.13.0: qs@6.13.0:
@ -6230,10 +5902,6 @@ snapshots:
react@19.0.0: {} react@19.0.0: {}
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
reflect.getprototypeof@1.0.10: reflect.getprototypeof@1.0.10:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -6254,8 +5922,6 @@ snapshots:
gopd: 1.2.0 gopd: 1.2.0
set-function-name: 2.0.2 set-function-name: 2.0.2
require-directory@2.1.1: {}
resolve-from@4.0.0: {} resolve-from@4.0.0: {}
resolve-pkg-maps@1.0.0: {} resolve-pkg-maps@1.0.0: {}
@ -6292,10 +5958,6 @@ snapshots:
dependencies: dependencies:
queue-microtask: 1.2.3 queue-microtask: 1.2.3
rxjs@7.8.2:
dependencies:
tslib: 2.8.1
safe-array-concat@1.1.3: safe-array-concat@1.1.3:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -6448,51 +6110,6 @@ snapshots:
is-arrayish: 0.3.2 is-arrayish: 0.3.2
optional: true optional: true
simple-update-notifier@2.0.0:
dependencies:
semver: 7.7.1
socket.io-adapter@2.5.5:
dependencies:
debug: 4.3.7
ws: 8.17.1
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
socket.io-client@4.8.1:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.3.7
engine.io-client: 6.6.3
socket.io-parser: 4.2.4
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
socket.io-parser@4.2.4:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.3.7
transitivePeerDependencies:
- supports-color
socket.io@4.8.1:
dependencies:
accepts: 1.3.8
base64id: 2.0.0
cors: 2.8.5
debug: 4.3.7
engine.io: 6.6.4
socket.io-adapter: 2.5.5
socket.io-parser: 4.2.4
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
sonner@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): sonner@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
@ -6515,12 +6132,6 @@ snapshots:
streamsearch@1.1.0: {} streamsearch@1.1.0: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string.prototype.includes@2.0.1: string.prototype.includes@2.0.1:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -6571,10 +6182,6 @@ snapshots:
define-properties: 1.2.1 define-properties: 1.2.1
es-object-atoms: 1.1.1 es-object-atoms: 1.1.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-bom@3.0.0: {} strip-bom@3.0.0: {}
strip-json-comments@3.1.1: {} strip-json-comments@3.1.1: {}
@ -6588,18 +6195,10 @@ snapshots:
dependencies: dependencies:
copy-anything: 3.0.5 copy-anything: 3.0.5
supports-color@5.5.0:
dependencies:
has-flag: 3.0.0
supports-color@7.2.0: supports-color@7.2.0:
dependencies: dependencies:
has-flag: 4.0.0 has-flag: 4.0.0
supports-color@8.1.1:
dependencies:
has-flag: 4.0.0
supports-preserve-symlinks-flag@1.0.0: {} supports-preserve-symlinks-flag@1.0.0: {}
tailwind-merge@3.0.2: {} tailwind-merge@3.0.2: {}
@ -6619,10 +6218,6 @@ snapshots:
toidentifier@1.0.1: {} toidentifier@1.0.1: {}
touch@3.1.1: {}
tree-kill@1.2.2: {}
ts-api-utils@2.1.0(typescript@5.8.2): ts-api-utils@2.1.0(typescript@5.8.2):
dependencies: dependencies:
typescript: 5.8.2 typescript: 5.8.2
@ -6706,8 +6301,6 @@ snapshots:
has-symbols: 1.1.0 has-symbols: 1.1.0
which-boxed-primitive: 1.1.1 which-boxed-primitive: 1.1.1
undefsafe@2.0.5: {}
undici-types@6.19.8: {} undici-types@6.19.8: {}
unpipe@1.0.0: {} unpipe@1.0.0: {}
@ -6786,30 +6379,6 @@ snapshots:
word-wrap@1.2.5: {} word-wrap@1.2.5: {}
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
ws@8.17.1: {}
xmlhttprequest-ssl@2.1.2: {}
y18n@5.0.8: {}
yargs-parser@21.1.1: {}
yargs@17.7.2:
dependencies:
cliui: 8.0.1
escalade: 3.2.0
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
zod@3.24.2: {} zod@3.24.2: {}

View File

@ -10,10 +10,10 @@ export default async function QuizGameStartPage() {
const session = await auth(); const session = await auth();
return ( return (
<> <>
<div className="mb-8 flex flex-col items-center justify-center gap-2 text-center"> <div className="mb-8 flex flex-col items-center justify-center gap-2 pt-12 text-center">
<Icons.logo className="animate-puls h-10 w-10 text-purple-700" /> <Icons.logo className="animate-puls text-primary h-10 w-10" />
<h1 className="bg-gradient-to-r from-yellow-300 via-pink-400 to-yellow-300 bg-clip-text text-5xl font-extrabold tracking-tight text-transparent uppercase"> <h1 className="from-primary to-secondary bg-gradient-to-b bg-clip-text text-5xl font-black tracking-tight text-transparent uppercase">
{appConfig.name} {appConfig.name}
</h1> </h1>
<p className="text-lg font-medium text-indigo-200"> <p className="text-lg font-medium text-indigo-200">
@ -26,9 +26,14 @@ export default async function QuizGameStartPage() {
{/* Create Lobby Button */} {/* Create Lobby Button */}
<div className="space-y-6"> <div className="space-y-6">
{session ? ( {session ? (
<CreateLobbyDialog className="w-full" /> <CreateLobbyDialog className="text-shadow-primary w-full" />
) : ( ) : (
<Button size={"xxl"} variant={"party"} asChild> <Button
size={"xxl"}
variant={"party"}
asChild
className="text-shadow-primary w-full font-black uppercase"
>
<Link href={"/api/auth/signin"}>Sign-in to create a Lobby</Link> <Link href={"/api/auth/signin"}>Sign-in to create a Lobby</Link>
</Button> </Button>
)} )}
@ -37,7 +42,7 @@ export default async function QuizGameStartPage() {
<Button <Button
size={"xxl"} size={"xxl"}
variant={"party"} variant={"party"}
className="w-full rounded-xl bg-gradient-to-r from-blue-500 to-indigo-600 text-white hover:from-blue-600 hover:to-indigo-700" className="w-full rounded-xl bg-gradient-to-r from-blue-500 via-blue-600 to-indigo-600 text-white hover:from-blue-600 hover:to-indigo-700"
> >
<Users className="mr-2 h-6 w-6" /> <Users className="mr-2 h-6 w-6" />
Join Lobby Join Lobby

View File

@ -1,20 +1,9 @@
"use client"; "use client";
import React from "react"; import React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import { Icons } from "@/components/icons";
Form, import { cn } from "@/lib/utils";
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { lobbyPatchSchema } from "@/lib/validations/lobby";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -23,32 +12,10 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { toast } from "sonner"; import LobbyForm from "./lobby/lobby-form";
import { api } from "@/trpc/react";
import { useRouter } from "next/navigation";
import { Icons } from "@/components/icons";
import { cn } from "@/lib/utils";
function CreateLobbyDialog({ className }: { className?: string }) { function CreateLobbyDialog({ className }: { className?: string }) {
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [loading, setLoading] = React.useState(false);
const { mutateAsync } = api.lobby.create.useMutation();
const router = useRouter();
const form = useForm<z.infer<typeof lobbyPatchSchema>>({
resolver: zodResolver(lobbyPatchSchema),
defaultValues: {
name: "",
},
});
async function onSubmit(lobby: z.infer<typeof lobbyPatchSchema>) {
setLoading(true);
const result = await mutateAsync({ lobby });
setOpen(false);
if (result) router.push(`/lobby/${result.id}`);
else toast.error("Something went wrong.");
setLoading(false);
}
return ( return (
<Dialog open={open} onOpenChange={setOpen}> <Dialog open={open} onOpenChange={setOpen}>
@ -57,7 +24,7 @@ function CreateLobbyDialog({ className }: { className?: string }) {
size={"xxl"} size={"xxl"}
variant={"party"} variant={"party"}
className={cn( className={cn(
"border-green-700 bg-gradient-to-r from-green-500 to-emerald-600 text-white shadow-green-600/30 hover:from-green-600 hover:to-emerald-700", "text-shadow-primary text-primary-foreground font-black",
className, className,
)} )}
> >
@ -68,38 +35,14 @@ function CreateLobbyDialog({ className }: { className?: string }) {
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className="container-bg bg-border/30"> <DialogContent className="container-bg bg-background/10">
<DialogHeader> <DialogHeader>
<DialogTitle>Create a Lobby</DialogTitle> <DialogTitle className="text-shadow-primary text-4xl font-black uppercase">
Create Lobby
</DialogTitle>
<DialogDescription></DialogDescription> <DialogDescription></DialogDescription>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input
className="placeholder:text-white/50"
placeholder="What is you lobbies name?"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
type="submit"
disabled={loading || !form.formState.isDirty}
>
Create Lobby
</Button>
</form>
</Form>
</DialogHeader> </DialogHeader>
<LobbyForm cb={() => setOpen(false)} />
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );

View File

@ -7,11 +7,6 @@ import UserCard from "@/components/user-card";
import DeleteLobbyDialog from "@/app/_components/delete-lobby-dialog"; import DeleteLobbyDialog from "@/app/_components/delete-lobby-dialog";
import LobbyMembershipDialog from "@/app/_components/lobby-membership-dialog"; import LobbyMembershipDialog from "@/app/_components/lobby-membership-dialog";
import { type Session } from "next-auth"; import { type Session } from "next-auth";
import { getSocket } from "@/lib/hooks/use-socket";
import {
LOBBY_USER_PRESENCE_EVENT,
LOBBY_USER_PRESENCE_UPDATE_EVENT,
} from "@/server/socket/event-const";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
function LobbyPage({ function LobbyPage({
@ -27,25 +22,8 @@ function LobbyPage({
const [memberPresence, setMemberPresence] = React.useState<Array<string>>(); const [memberPresence, setMemberPresence] = React.useState<Array<string>>();
const isJoined = members.find((member) => member.id === session?.user.id); const isJoined = members.find((member) => member.id === session?.user.id);
const isOwner = lobby.createdById === session?.user.id; const isOwner = lobby.createdById === session?.user.id;
const socket = session ? getSocket() : undefined;
React.useEffect(() => {
if (!session || !isJoined || !socket) return;
socket.emit(LOBBY_USER_PRESENCE_EVENT, lobby.id, session.user.id, true);
console.log("user joined");
// socket.on(LOBBY_USER_PRESENCE_UPDATE_EVENT, (users) => {
// console.log("presence updated", users);
// setMemberPresence(users);
// });
return () => {
if (!session || !isJoined || !socket) return;
socket.emit(LOBBY_USER_PRESENCE_EVENT, lobby.id, session.user.id, false);
socket.disconnect();
};
}, [socket]);
return ( return (
<div className="container-bg w-full max-w-md space-y-4 p-6"> <div className="container-bg w-full max-w-md space-y-4 p-6">

View File

@ -0,0 +1,81 @@
"use client";
import type { Lobby } from "@/server/db/schema";
import React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { lobbyPatchSchema } from "@/lib/validations/lobby";
import { toast } from "sonner";
import { api } from "@/trpc/react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
function LobbyForm({
server_lobby,
cb,
}: {
server_lobby?: Lobby;
cb?: () => void;
}) {
const [loading, setLoading] = React.useState(false);
const { mutateAsync: createLobby } = api.lobby.create.useMutation();
const { mutateAsync: updateLobby } = api.lobby.update.useMutation();
const router = useRouter();
const form = useForm<z.infer<typeof lobbyPatchSchema>>({
resolver: zodResolver(lobbyPatchSchema),
defaultValues: {
name: "",
},
});
async function onSubmit(lobby: z.infer<typeof lobbyPatchSchema>) {
setLoading(true);
const existingLobby = Boolean(server_lobby?.id?.length);
const result = existingLobby
? await updateLobby({ lobby, lobbyId: server_lobby?.id! })
: await createLobby({ lobby });
cb?.();
if (result) {
if (!existingLobby) router.push(`/lobby/${result.id}`);
} else toast.error("Something went wrong.");
setLoading(false);
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-8">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input
className="placeholder:text-white/50"
placeholder="What is you lobbies name?"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" disabled={loading || !form.formState.isDirty}>
Create Lobby
</Button>
</form>
</Form>
);
}
export default LobbyForm;

View File

@ -3,16 +3,10 @@
import React from "react"; import React from "react";
import { Button } from "./ui/button"; import { Button } from "./ui/button";
import Link from "next/link"; import Link from "next/link";
import { Home } from "lucide-react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function NavLink({ function NavLink({ label, path, className }: NavLink & { className?: string }) {
label,
path,
className,
isLast,
}: NavLink & { className?: string; isLast?: boolean }) {
const active = usePathname() === path; const active = usePathname() === path;
return ( return (
<Button <Button

View File

@ -11,22 +11,19 @@ async function Navbar() {
return ( return (
<nav className="flex w-full items-center justify-center p-4"> <nav className="flex w-full items-center justify-center p-4">
<div className="container-bg flex w-full max-w-sm items-center justify-between gap-2 overflow-hidden rounded-full border-2"> <div className="container-bg flex h-10 w-full max-w-sm items-center justify-between gap-2 overflow-hidden rounded-full border-2">
<menu className="flex h-full items-center"> <menu className="flex items-center">
{appConfig.navigation.map((navLink, idx) => ( {appConfig.navigation.map((navLink, idx) => (
<li key={idx}> <li key={idx}>
<NavLink <NavLink {...navLink} />
isLast={idx === appConfig.navigation.length - 1}
{...navLink}
/>
</li> </li>
))} ))}
</menu> </menu>
{/* Login Button or Profile Avatar */} {/* Login Button or Profile Avatar */}
{session ? ( {session?.user ? (
<UserPopover user={session.user} /> <UserPopover user={session.user} />
) : ( ) : (
<Button asChild className="bg-red-800"> <Button asChild className="bg-primary font-black">
<Link href="/api/auth/signin">Sign In</Link> <Link href="/api/auth/signin">Sign In</Link>
</Button> </Button>
)} )}

View File

@ -21,7 +21,7 @@ const buttonVariants = cva(
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 rounded-full", "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 rounded-full",
link: "text-primary underline-offset-4 hover:underline", link: "text-primary underline-offset-4 hover:underline",
party: party:
"bg-primary text-primary-foreground rounded-xl border-b-4 shadow-lg font-bold hover:translate-y-[0.1rem] hover:border-b-2 ", "bg-gradient-to-r from-secondary via-primary to-secondary text-shadow-primary text-primary-foreground rounded-xl border-b-4 shadow-lg font-bold hover:translate-y-[0.1rem] hover:border-b-2 ",
}, },
size: { size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3", default: "h-9 px-4 py-2 has-[>svg]:px-3",

View File

@ -25,8 +25,6 @@ export const env = createEnv({
* `NEXT_PUBLIC_`. * `NEXT_PUBLIC_`.
*/ */
client: { client: {
NEXT_PUBLIC_SOCKET_URL: z.string().url(),
// NEXT_PUBLIC_CLIENTVAR: z.string(), // NEXT_PUBLIC_CLIENTVAR: z.string(),
}, },
@ -39,7 +37,6 @@ export const env = createEnv({
AUTH_DISCORD_ID: process.env.AUTH_DISCORD_ID, AUTH_DISCORD_ID: process.env.AUTH_DISCORD_ID,
AUTH_DISCORD_SECRET: process.env.AUTH_DISCORD_SECRET, AUTH_DISCORD_SECRET: process.env.AUTH_DISCORD_SECRET,
DATABASE_URL: process.env.DATABASE_URL, DATABASE_URL: process.env.DATABASE_URL,
NEXT_PUBLIC_SOCKET_URL: process.env.NEXT_PUBLIC_SOCKET_URL,
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
}, },
/** /**

View File

@ -1,13 +0,0 @@
"use client";
import { env } from "@/env";
import io, { Socket } from "socket.io-client";
let socket: Socket | null = null;
export const getSocket = () => {
if (!socket) {
socket = io(env.NEXT_PUBLIC_SOCKET_URL);
}
return socket;
};

View File

@ -9,4 +9,5 @@ export const lobbyPatchSchema = z.object({
.max(255, { .max(255, {
message: "Name can only contain up to 255 characters", message: "Name can only contain up to 255 characters",
}), }),
maxPlayers: z.number().default(0),
}); });

View File

@ -16,13 +16,8 @@ export const lobbies = createTable("lobby", (d) => ({
.primaryKey() .primaryKey()
.notNull() .notNull()
.$defaultFn(() => createId()), .$defaultFn(() => createId()),
name: d name: d.varchar({ length: 255 }).notNull(),
.varchar({ length: 255 }) maxPlayers: d.integer().notNull().default(0),
.notNull(),
maxMembers: d
.integer()
.notNull()
.default(0),
createdById: d createdById: d
.varchar({ length: 255 }) .varchar({ length: 255 })
.notNull() .notNull()
@ -57,15 +52,9 @@ export const lobbyMembers = createTable(
.varchar({ length: 255 }) .varchar({ length: 255 })
.notNull() .notNull()
.references(() => lobbies.id, { onDelete: "cascade" }), .references(() => lobbies.id, { onDelete: "cascade" }),
joinedAt: d joinedAt: d.timestamp("created_at", { withTimezone: true }).notNull(),
.timestamp("created_at", { withTimezone: true }) role: d.varchar({ length: 255 }).notNull(),
.notNull(), isReady: d.boolean().notNull(),
role: d
.varchar({ length: 255 })
.notNull(),
isReady: d
.boolean()
.notNull(),
}), }),
(t) => [primaryKey({ columns: [t.lobbyId, t.userId] })], (t) => [primaryKey({ columns: [t.lobbyId, t.userId] })],
); );
@ -81,7 +70,6 @@ export const lobbyMembersRelations = relations(lobbyMembers, ({ one }) => ({
}), }),
})); }));
export const users = createTable("user", (d) => ({ export const users = createTable("user", (d) => ({
id: d id: d
.varchar({ length: 255 }) .varchar({ length: 255 })

View File

@ -1,7 +0,0 @@
export const JOIN_LOBBY_EVENT = "joinLobby";
export const LEAVE_LOBBY_EVENT = "leaveLobby";
export const LOBBY_USER_PRESENCE_EVENT = "lobbyPresence";
export const LOBBY_USER_PRESENCE_UPDATE_EVENT = "lobbyPresenceUpdate";
// export const PLAYER_LOBBY_STATUS = "playerLobbyStatus";

View File

@ -1,65 +0,0 @@
import { type Server as SocketIOServer } from "socket.io";
import {
LOBBY_USER_PRESENCE_EVENT,
JOIN_LOBBY_EVENT,
LEAVE_LOBBY_EVENT,
LOBBY_USER_PRESENCE_UPDATE_EVENT,
} from "./event-const";
import { env } from "@/env";
const log = (message?: any, ...optionalParams: any[]) => {
if (env.NODE_ENV === "development") {
console.log(message, ...optionalParams);
}
};
const lobbyPresenceMap = new Map<string, Array<string>>();
export const initSocketEvents = (io: SocketIOServer) => {
io.on("connection", (socket) => {
log("New client connected:", socket.id);
socket.on(
LOBBY_USER_PRESENCE_EVENT,
(lobbyId: string, userId: string, present: boolean) => {
socket.join(lobbyId);
// if (!lobbyPresenceMap.has(lobbyId)) {
// lobbyPresenceMap.set(lobbyId, []);
// }
// if (present) {
// lobbyPresenceMap.get(lobbyId)?.push(userId);
// } else {
// lobbyPresenceMap
// .get(lobbyId)
// ?.splice(lobbyPresenceMap.get(lobbyId)?.indexOf(userId)!, 1);
// }
// console.log(lobbyPresenceMap);
// socket
// .to(lobbyId)
// .emit(
// LOBBY_USER_PRESENCE_UPDATE_EVENT,
// lobbyPresenceMap.get(lobbyId),
// );
log(
`user ${userId} is (present: ${present}) in lobby room: ${lobbyId}`,
);
},
);
// Comments
// socket.on(DELETE_COMMENT_EVENT, (commentId: string, articleId: string) => {
// log(`Comment deleted: ${commentId} for article: ${articleId}`);
// io.to(articleId).emit(DELETE_COMMENT_EVENT, commentId);
// });
// socket.on(ADD_COMMENT_EVENT, (comment: Comment) => {
// log(`Comment added: ${comment.id} for article: ${comment.articleId}`);
// io.to(comment.articleId).emit(ADD_COMMENT_EVENT, comment);
// });
socket.on("disconnect", () => {
log("Client disconnected:", socket.id);
});
});
};

View File

@ -1,37 +0,0 @@
import "dotenv/config";
import express from "express";
import http from "http";
import { Server } from "socket.io";
import { initSocketEvents } from "./events";
import { env } from "@/env";
declare global {
var io: Server | undefined;
}
const createSocketServer = () => {
const app = express();
const server = http.createServer(app);
const PORT = 4000;
const origin = "http://localhost:" + PORT;
if (!global.io) {
global.io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
initSocketEvents(global.io);
server.listen(PORT, () => {
console.log(`Socket.IO server running on port ${PORT}`);
});
}
return global.io;
};
export const ioServer = createSocketServer();

View File

@ -11,10 +11,10 @@
--card-foreground: oklch(0.145 0 0); --card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0); --popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0); --popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0); --primary: oklch(71.76% 0.2017 349.7);
--primary-foreground: oklch(0.985 0 0); --primary-foreground: oklch(100% 0 349.7);
--secondary: oklch(0.97 0 0); --secondary: oklch(88.93% 0.143 90.13);
--secondary-foreground: oklch(0.205 0 0); --secondary-foreground: oklch(21.76% 0.0197 108.64);
--muted: oklch(0.97 0 0); --muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0); --muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0); --accent: oklch(0.97 0 0);
@ -131,4 +131,7 @@
.gradient-bg { .gradient-bg {
@apply bg-gradient-to-br from-indigo-950 via-purple-900 to-indigo-900; @apply bg-gradient-to-br from-indigo-950 via-purple-900 to-indigo-900;
} }
.text-shadow-primary {
text-shadow: 1px 1px 2px var(--primary);
}
} }