diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..0b1cef8
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "lastFilter": {
+ "state": "OPEN",
+ "assignee": "RepentedAlex"
+ }
+}
+ {
+ "selectedUrlAndAccountId": {
+ "url": "https://github.com/Maix0/ft_deadge.git",
+ "accountId": "05fe7ff5-d360-4ad3-b17e-66daa92a5dbb"
+ }
+}
+
+
+
+ {
+ "associatedIndex": 2
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1765884886075
+
+
+ 1765884886075
+
+
+
+
+
+ 1765890545228
+
+
+
+ 1765890545228
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index a3bec84..715d2cc 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -67,6 +67,32 @@ services:
gelf-address: "udp://127.0.0.1:12201"
tag: "{{.Name}}"
+<<<<<<< HEAD
+=======
+ ###############
+ # TIC-TAC-TOE #
+ ###############
+ tic-tac-toe:
+ build:
+ context: ./src/
+ args:
+ - SERVICE=tic-tac-toe
+ - EXTRA_FILES=tic-tac-toe/extra
+ container_name: tic-tac-toe
+ restart: unless-stopped
+ networks:
+ - transcendance-network
+ volumes:
+ - sqlite-volume:/volumes/database
+ - static-volume:/volumes/static
+ environment:
+ - JWT_SECRET=KRUGKIDROVUWG2ZAMJZG653OEBTG66BANJ2W24DTEBXXMZLSEB2GQZJANRQXU6JA
+ - DATABASE_DIR=/volumes/database
+
+ ###############
+ # CHAT #
+ ###############
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
chat:
build:
context: ./src/
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index ec12443..626a9d3 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -10,7 +10,11 @@ importers:
dependencies:
'@tailwindcss/vite':
specifier: ^4.1.18
+<<<<<<< HEAD
version: 4.1.18(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))
+=======
+ version: 4.1.18(vite@7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2))
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
'@types/qrcode':
specifier: ^1.5.6
version: 1.5.6
@@ -35,6 +39,7 @@ importers:
version: 5.9.3
vite:
specifier: ^7.3.0
+<<<<<<< HEAD
version: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)
vite-tsconfig-paths:
specifier: ^5.1.4
@@ -44,156 +49,292 @@ packages:
'@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+=======
+ version: 7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2)
+ vite-tsconfig-paths:
+ specifier: ^5.1.4
+ version: 5.1.4(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2))
+
+packages:
+
+ '@esbuild/aix-ppc64@0.27.1':
+ resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
+<<<<<<< HEAD
'@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+=======
+ '@esbuild/android-arm64@0.27.1':
+ resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+<<<<<<< HEAD
'@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+=======
+ '@esbuild/android-arm@0.27.1':
+ resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+<<<<<<< HEAD
'@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+=======
+ '@esbuild/android-x64@0.27.1':
+ resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+<<<<<<< HEAD
'@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+=======
+ '@esbuild/darwin-arm64@0.27.1':
+ resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+<<<<<<< HEAD
'@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+=======
+ '@esbuild/darwin-x64@0.27.1':
+ resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+<<<<<<< HEAD
'@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+=======
+ '@esbuild/freebsd-arm64@0.27.1':
+ resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+<<<<<<< HEAD
'@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+=======
+ '@esbuild/freebsd-x64@0.27.1':
+ resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+<<<<<<< HEAD
'@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+=======
+ '@esbuild/linux-arm64@0.27.1':
+ resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+=======
+ '@esbuild/linux-arm@0.27.1':
+ resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+=======
+ '@esbuild/linux-ia32@0.27.1':
+ resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+=======
+ '@esbuild/linux-loong64@0.27.1':
+ resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+=======
+ '@esbuild/linux-mips64el@0.27.1':
+ resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+=======
+ '@esbuild/linux-ppc64@0.27.1':
+ resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+=======
+ '@esbuild/linux-riscv64@0.27.1':
+ resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+=======
+ '@esbuild/linux-s390x@0.27.1':
+ resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+=======
+ '@esbuild/linux-x64@0.27.1':
+ resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+=======
+ '@esbuild/netbsd-arm64@0.27.1':
+ resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
+<<<<<<< HEAD
'@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+=======
+ '@esbuild/netbsd-x64@0.27.1':
+ resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
+<<<<<<< HEAD
'@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+=======
+ '@esbuild/openbsd-arm64@0.27.1':
+ resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
+<<<<<<< HEAD
'@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+=======
+ '@esbuild/openbsd-x64@0.27.1':
+ resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+<<<<<<< HEAD
'@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+=======
+ '@esbuild/openharmony-arm64@0.27.1':
+ resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
+<<<<<<< HEAD
'@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+=======
+ '@esbuild/sunos-x64@0.27.1':
+ resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+<<<<<<< HEAD
'@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+=======
+ '@esbuild/win32-arm64@0.27.1':
+ resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+<<<<<<< HEAD
'@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+=======
+ '@esbuild/win32-ia32@0.27.1':
+ resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+<<<<<<< HEAD
'@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+=======
+ '@esbuild/win32-x64@0.27.1':
+ resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -423,8 +564,13 @@ packages:
'@types/js-cookie@3.0.6':
resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
+<<<<<<< HEAD
'@types/node@25.0.3':
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==}
+=======
+ '@types/node@25.0.2':
+ resolution: {integrity: sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
'@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
@@ -494,8 +640,13 @@ packages:
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
engines: {node: '>=10.13.0'}
+<<<<<<< HEAD
esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+=======
+ esbuild@0.27.1:
+ resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
hasBin: true
@@ -808,6 +959,7 @@ packages:
snapshots:
+<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2':
optional: true
@@ -884,6 +1036,84 @@ snapshots:
optional: true
'@esbuild/win32-x64@0.27.2':
+=======
+ '@esbuild/aix-ppc64@0.27.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/android-arm@0.27.1':
+ optional: true
+
+ '@esbuild/android-x64@0.27.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.1':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.1':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
optional: true
'@jridgewell/gen-mapping@0.3.13':
@@ -1034,24 +1264,40 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
'@tailwindcss/oxide-win32-x64-msvc': 4.1.18
+<<<<<<< HEAD
'@tailwindcss/vite@4.1.18(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))':
+=======
+ '@tailwindcss/vite@4.1.18(vite@7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2))':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
'@tailwindcss/node': 4.1.18
'@tailwindcss/oxide': 4.1.18
tailwindcss: 4.1.18
+<<<<<<< HEAD
vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)
+=======
+ vite: 7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
'@types/estree@1.0.8': {}
'@types/js-cookie@3.0.6': {}
+<<<<<<< HEAD
'@types/node@25.0.3':
+=======
+ '@types/node@25.0.2':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
undici-types: 7.16.0
'@types/qrcode@1.5.6':
dependencies:
+<<<<<<< HEAD
'@types/node': 25.0.3
+=======
+ '@types/node': 25.0.2
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
ansi-regex@5.0.1: {}
@@ -1108,6 +1354,7 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.0
+<<<<<<< HEAD
esbuild@0.27.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2
@@ -1136,6 +1383,36 @@ snapshots:
'@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.2
+=======
+ esbuild@0.27.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.1
+ '@esbuild/android-arm': 0.27.1
+ '@esbuild/android-arm64': 0.27.1
+ '@esbuild/android-x64': 0.27.1
+ '@esbuild/darwin-arm64': 0.27.1
+ '@esbuild/darwin-x64': 0.27.1
+ '@esbuild/freebsd-arm64': 0.27.1
+ '@esbuild/freebsd-x64': 0.27.1
+ '@esbuild/linux-arm': 0.27.1
+ '@esbuild/linux-arm64': 0.27.1
+ '@esbuild/linux-ia32': 0.27.1
+ '@esbuild/linux-loong64': 0.27.1
+ '@esbuild/linux-mips64el': 0.27.1
+ '@esbuild/linux-ppc64': 0.27.1
+ '@esbuild/linux-riscv64': 0.27.1
+ '@esbuild/linux-s390x': 0.27.1
+ '@esbuild/linux-x64': 0.27.1
+ '@esbuild/netbsd-arm64': 0.27.1
+ '@esbuild/netbsd-x64': 0.27.1
+ '@esbuild/openbsd-arm64': 0.27.1
+ '@esbuild/openbsd-x64': 0.27.1
+ '@esbuild/openharmony-arm64': 0.27.1
+ '@esbuild/sunos-x64': 0.27.1
+ '@esbuild/win32-arm64': 0.27.1
+ '@esbuild/win32-ia32': 0.27.1
+ '@esbuild/win32-x64': 0.27.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
@@ -1333,27 +1610,45 @@ snapshots:
undici-types@7.16.0: {}
+<<<<<<< HEAD
vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)):
+=======
+ vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2)):
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
debug: 4.4.3
globrex: 0.1.2
tsconfck: 3.1.6(typescript@5.9.3)
optionalDependencies:
+<<<<<<< HEAD
vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)
+=======
+ vite: 7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
transitivePeerDependencies:
- supports-color
- typescript
+<<<<<<< HEAD
vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2):
dependencies:
esbuild: 0.27.2
+=======
+ vite@7.3.0(@types/node@25.0.2)(jiti@2.6.1)(lightningcss@1.30.2):
+ dependencies:
+ esbuild: 0.27.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.53.5
tinyglobby: 0.2.15
optionalDependencies:
+<<<<<<< HEAD
'@types/node': 25.0.3
+=======
+ '@types/node': 25.0.2
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fsevents: 2.3.3
jiti: 2.6.1
lightningcss: 1.30.2
diff --git a/frontend/src/pages/ttt/ttt.ts b/frontend/src/pages/ttt/ttt.ts
index e895914..4875647 100644
--- a/frontend/src/pages/ttt/ttt.ts
+++ b/frontend/src/pages/ttt/ttt.ts
@@ -1,126 +1,12 @@
-import { addRoute, setTitle, type RouteHandlerReturn } from "@app/routing";
+import { addRoute, type RouteHandlerReturn } from "@app/routing";
import tttPage from "./ttt.html?raw";
import { showError, showInfo, showSuccess } from "@app/toast";
-
-// Represents the possible states of a cell on the board.
-// `null` means that the cell is empty.
-type CellState = 'O' | 'X' | null
-
-// Encapsulates the game logic.
-class TTC {
-
- private isGameOver: boolean;
-
- private board: [
- CellState, CellState, CellState,
- CellState, CellState, CellState,
- CellState, CellState, CellState];
- private currentPlayer: 'O' | 'X';
-
- constructor() {
- this.board = [null,null,null,null,null,null,null,null,null];
- this.isGameOver = false;
- this.currentPlayer = 'X';
- }
-
- private changePlayer()
- {
- if (this.currentPlayer === 'X')
- this.currentPlayer = 'O';
- else
- this.currentPlayer = 'X';
- }
-
- // Analyzes the current board to determine if the game has ended.
- private checkState(): 'winX' | 'winO' | 'draw' | 'ongoing'
- {
- const checkRow = (row: number): ('X' | 'O' | null) => {
- if (this.board[row * 3] === null)
- return null;
- if (this.board[row * 3] === this.board[row * 3 + 1] && this.board[row * 3 + 1] === this.board[row * 3 + 2])
- return this.board[row * 3];
- return null;
- }
-
- const checkCol = (col: number): ('X' | 'O' | null) => {
- if (this.board[col] === null) return null;
-
- if (this.board[col] === this.board[col + 3] && this.board[col + 3] === this.board[col + 6])
- return this.board[col];
- return null;
- }
-
- const checkDiag = (): ('X' | 'O' | null) => {
- if (this.board[4] === null) return null
-
- if (this.board[0] === this.board[4] && this.board[4] === this.board[8])
- return this.board[4]
-
- if (this.board[2] === this.board[4] && this.board[4] === this.board[6])
- return this.board[4]
- return null;
- }
-
-
- const row = (checkRow(0) ?? checkRow(1)) ?? checkRow(2);
- const col = (checkCol(0) ?? checkCol(1)) ?? checkCol(2);
- const diag = checkDiag();
-
- if (row !== null) return `win${row}`;
- if (col !== null) return `win${col}`;
- if (diag !== null ) return `win${diag}`;
-
- if (this.board.filter(c => c === null).length === 0)
- return 'draw';
- return 'ongoing';
- }
-
- public reset(): void {
- this.board = [null,null,null,null,null,null,null,null,null];
- this.currentPlayer = 'X';
- this.isGameOver = false;
- };
-
- // Attempts to place the current player's mark on the specified cell.
- // @param idx - The index of the board (0-8) to place the mark.
- // @returns The resulting game state, or `invalidMove` if the move is illegal.
- public makeMove(idx: number): 'winX' | 'winO' | 'draw' | 'ongoing' | 'invalidMove' {
- if (this.isGameOver) {
- return 'invalidMove';
- }
- if (idx < 0 || idx >= this.board.length) {
- return 'invalidMove';
- }
- if (this.board[idx] !== null) {
- return 'invalidMove';
- }
- this.board[idx] = this.currentPlayer;
- this.changePlayer();
-
- const result = this.checkState();
-
- if (result !== 'ongoing') {
- this.isGameOver = true;
- }
-
- return result;
- }
-
- public getBoard(): [
- CellState, CellState, CellState,
- CellState, CellState, CellState,
- CellState, CellState, CellState]
- {
- return this.board;
- }
-}
+import { io, Socket } from "socket.io-client";
// Route handler for the Tic-Tac-Toe page.
// Instantiates the game logic and binds UI events.
-async function handleTTT(): Promise
-{
- // Create a fresh instance for every page load.
- let board = new TTC();
+async function handleTTT(): Promise {
+ const socket: Socket = io("http://localhost:80");
return {
html: tttPage,
@@ -131,61 +17,49 @@ async function handleTTT(): Promise
const cells = app.querySelectorAll(".ttt-grid-cell");
const restartBtn = app.querySelector("#ttt-restart-btn");
+ const grid = app.querySelector('.ttt-grid'); // Not sure about this one
- const updateUI = () => {
- const board_state = board.getBoard();
- board_state.forEach((cell_state, cell_idx) => {
- cells[cell_idx].innerText = cell_state !== null ? cell_state : " ";
- });
+ const updateUI = (boardState: (string | null)[]) => {
+ boardState.forEach((state, idx) => {
+ cells[idx].innerText = state || " ";
+ });
};
- console.log(cells);
+ socket.on('gameState', (data) => {
+ updateUI(data.board);
+
+ if (data.lastResult && data.lastResult !== 'ongoing') {
+ grid?.classList.add('pointer-events-none');
+ if (data.lastResult === 'winX') {
+ showSuccess('X won !');
+ } if (data.lastResult === 'winO') {
+ showSuccess('O won !');
+ } if (data.lastResult === 'draw') {
+ showInfo('Draw !');
+ }
+ }
+
+ if (data.reset) {
+ grid?.classList.remove('pointer-events-none');
+ showInfo('Game Restarted');
+ }
+ });
+
+ socket.on('error', (msg) => {
+ showError(msg);
+ });
cells?.forEach(function (c, idx) {
c.addEventListener('click', () => {
- const result = board.makeMove(idx);
- switch(result)
- {
- case ('draw'): {
- showInfo('Game is a draw');
- break;
- }
- case ('invalidMove'): {
- showError('Move is invalid');
- break;
- }
-
- case ('winX'): {
- showSuccess('X won');
- app?.querySelector('.ttt-grid')?.classList.add('pointer-events-none');
- break;
- }
- case ('winO'): {
- showSuccess('O won');
- app?.querySelector('.ttt-grid')?.classList.add('pointer-events-none');
- break;
- }
- }
-
- // Sync UI with Game State
- const board_state = board.getBoard();
- board_state.forEach( function (cell_state, cell_idx) {
- cells[cell_idx].innerText = cell_state !== null ? cell_state : " ";
- });
-
- updateUI();
+ socket.emit('makeMove', idx);
});
});
+
restartBtn?.addEventListener('click', () => {
- board.reset();
- // Remove pointer-events-none to re-enable the board if it was disabled
- app?.querySelector('.ttt-grid')?.classList.remove('pointer-events-none');
- updateUI();
- showInfo('Game Restarted');
+ socket.emit('resetGame');
});
- }
+ },
}
}
-
-addRoute('/ttt', handleTTT)
\ No newline at end of file
+addRoute('/ttt', handleTTT);
\ No newline at end of file
diff --git a/src/@shared/package.json b/src/@shared/package.json
index 4cdbef0..8e88a53 100644
--- a/src/@shared/package.json
+++ b/src/@shared/package.json
@@ -20,7 +20,11 @@
"fastify-plugin": "^5.1.0",
"joi": "^18.0.2",
"otp": "^1.1.2",
+<<<<<<< HEAD
"typebox": "^1.0.64",
+=======
+ "typebox": "^1.0.63",
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
"uuidv7": "^1.1.0"
},
"devDependencies": {
diff --git a/src/auth/package.json b/src/auth/package.json
index b709575..6e86c50 100644
--- a/src/auth/package.json
+++ b/src/auth/package.json
@@ -27,7 +27,11 @@
"fastify": "^5.6.2",
"fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0",
+<<<<<<< HEAD
"typebox": "^1.0.64"
+=======
+ "typebox": "^1.0.63"
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
},
"devDependencies": {
"@types/node": "^22.19.3",
diff --git a/src/chat/package.json b/src/chat/package.json
index 555055b..74eb62a 100644
--- a/src/chat/package.json
+++ b/src/chat/package.json
@@ -27,7 +27,11 @@
"fastify": "^5.6.2",
"fastify-plugin": "^5.1.0",
"socket.io": "^4.8.1",
+<<<<<<< HEAD
"typebox": "^1.0.64"
+=======
+ "typebox": "^1.0.63"
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
},
"devDependencies": {
"@types/node": "^22.19.3",
diff --git a/src/package.json b/src/package.json
index 3169a11..e05f135 100644
--- a/src/package.json
+++ b/src/package.json
@@ -33,7 +33,11 @@
"vite": "^7.3.0"
},
"dependencies": {
+<<<<<<< HEAD
"@redocly/cli": "^2.13.0",
+=======
+ "@redocly/cli": "^2.12.7",
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
"bindings": "^1.5.0"
}
}
diff --git a/src/pnpm-lock.yaml b/src/pnpm-lock.yaml
index d00e5ab..ef2870f 100644
--- a/src/pnpm-lock.yaml
+++ b/src/pnpm-lock.yaml
@@ -9,8 +9,13 @@ importers:
.:
dependencies:
'@redocly/cli':
+<<<<<<< HEAD
specifier: ^2.13.0
version: 2.13.0(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)
+=======
+ specifier: ^2.12.7
+ version: 2.12.7(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
bindings:
specifier: ^1.5.0
version: 1.5.0
@@ -41,7 +46,11 @@ importers:
version: 8.50.0(eslint@9.39.2)(typescript@5.9.3)
vite:
specifier: ^7.3.0
+<<<<<<< HEAD
version: 7.3.0(@types/node@25.0.3)(yaml@2.8.2)
+=======
+ version: 7.3.0(@types/node@25.0.2)(yaml@2.8.2)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
'@shared':
dependencies:
@@ -79,8 +88,13 @@ importers:
specifier: ^1.1.2
version: 1.1.2
typebox:
+<<<<<<< HEAD
specifier: ^1.0.64
version: 1.0.64
+=======
+ specifier: ^1.0.63
+ version: 1.0.63
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
uuidv7:
specifier: ^1.1.0
version: 1.1.0
@@ -122,8 +136,13 @@ importers:
specifier: ^5.1.0
version: 5.1.0
typebox:
+<<<<<<< HEAD
specifier: ^1.0.64
version: 1.0.64
+=======
+ specifier: ^1.0.63
+ version: 1.0.63
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies:
'@types/node':
specifier: ^22.19.3
@@ -168,8 +187,13 @@ importers:
specifier: ^4.8.1
version: 4.8.1
typebox:
+<<<<<<< HEAD
specifier: ^1.0.64
version: 1.0.64
+=======
+ specifier: ^1.0.63
+ version: 1.0.63
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies:
'@types/node':
specifier: ^22.19.3
@@ -183,6 +207,18 @@ importers:
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4(typescript@5.9.3)(vite@7.3.0(@types/node@22.19.3)(yaml@2.8.2))
+<<<<<<< HEAD
+=======
+
+ tic-tac-toe:
+ dependencies:
+ fastify-socket.io:
+ specifier: ^5.1.0
+ version: 5.1.0(fastify@5.6.2)(socket.io@4.8.1)
+ socket.io:
+ specifier: ^4.8.1
+ version: 4.8.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
user:
dependencies:
@@ -211,8 +247,13 @@ importers:
specifier: ^5.1.0
version: 5.1.0
typebox:
+<<<<<<< HEAD
specifier: ^1.0.64
version: 1.0.64
+=======
+ specifier: ^1.0.63
+ version: 1.0.63
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies:
'@types/node':
specifier: ^22.19.3
@@ -250,158 +291,288 @@ packages:
'@emotion/unitless@0.8.1':
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
+<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+=======
+ '@esbuild/aix-ppc64@0.27.1':
+ resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
+<<<<<<< HEAD
'@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+=======
+ '@esbuild/android-arm64@0.27.1':
+ resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+<<<<<<< HEAD
'@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+=======
+ '@esbuild/android-arm@0.27.1':
+ resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+<<<<<<< HEAD
'@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+=======
+ '@esbuild/android-x64@0.27.1':
+ resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+<<<<<<< HEAD
'@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+=======
+ '@esbuild/darwin-arm64@0.27.1':
+ resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+<<<<<<< HEAD
'@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+=======
+ '@esbuild/darwin-x64@0.27.1':
+ resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+<<<<<<< HEAD
'@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+=======
+ '@esbuild/freebsd-arm64@0.27.1':
+ resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+<<<<<<< HEAD
'@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+=======
+ '@esbuild/freebsd-x64@0.27.1':
+ resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+<<<<<<< HEAD
'@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+=======
+ '@esbuild/linux-arm64@0.27.1':
+ resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+=======
+ '@esbuild/linux-arm@0.27.1':
+ resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+=======
+ '@esbuild/linux-ia32@0.27.1':
+ resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+=======
+ '@esbuild/linux-loong64@0.27.1':
+ resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+=======
+ '@esbuild/linux-mips64el@0.27.1':
+ resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+=======
+ '@esbuild/linux-ppc64@0.27.1':
+ resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+=======
+ '@esbuild/linux-riscv64@0.27.1':
+ resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+=======
+ '@esbuild/linux-s390x@0.27.1':
+ resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+<<<<<<< HEAD
'@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+=======
+ '@esbuild/linux-x64@0.27.1':
+ resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+<<<<<<< HEAD
'@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+=======
+ '@esbuild/netbsd-arm64@0.27.1':
+ resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
+<<<<<<< HEAD
'@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+=======
+ '@esbuild/netbsd-x64@0.27.1':
+ resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
+<<<<<<< HEAD
'@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+=======
+ '@esbuild/openbsd-arm64@0.27.1':
+ resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
+<<<<<<< HEAD
'@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+=======
+ '@esbuild/openbsd-x64@0.27.1':
+ resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+<<<<<<< HEAD
'@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+=======
+ '@esbuild/openharmony-arm64@0.27.1':
+ resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
+<<<<<<< HEAD
'@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+=======
+ '@esbuild/sunos-x64@0.27.1':
+ resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+<<<<<<< HEAD
'@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+=======
+ '@esbuild/win32-arm64@0.27.1':
+ resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+<<<<<<< HEAD
'@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+=======
+ '@esbuild/win32-ia32@0.27.1':
+ resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+<<<<<<< HEAD
'@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+=======
+ '@esbuild/win32-x64@0.27.1':
+ resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -679,8 +850,13 @@ packages:
'@redocly/ajv@8.17.1':
resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==}
+<<<<<<< HEAD
'@redocly/cli@2.13.0':
resolution: {integrity: sha512-VOGh8p5gKy+u94SbvMGaHvDM6TPw668D9iQkNSztoi4T5sj3ZwM7Y8Z3yZnMqC5s5epDcLAMq4jCO8UVn5ZWHg==}
+=======
+ '@redocly/cli@2.12.7':
+ resolution: {integrity: sha512-cevNpojACA3JVUU3fqIzebY1CXipeBl84EMrriAgB4Pi0cHWImf12WkpLN/MCKMlW20/IzBzQ04CVlTyKFXuyw==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
hasBin: true
@@ -694,12 +870,21 @@ packages:
resolution: {integrity: sha512-2+O+riuIUgVSuLl3Lyh5AplWZyVMNuG2F98/o6NrutKJfW4/GTZdPpZlIphS0HGgcOHgmWcCSHj+dWFlZaGSHw==}
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
+<<<<<<< HEAD
'@redocly/openapi-core@2.13.0':
resolution: {integrity: sha512-xQ4z5tsrXbIa4EfCniHv1zZ4etmQ0lpRcxy750iOamV5A/+19mgbPtD+UQCoT18puDAjcnOgpX7x2ha72qKrnw==}
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
'@redocly/respect-core@2.13.0':
resolution: {integrity: sha512-35OidNXWkmmsJiwgX+tFw7FaU8usZVvZ/lFBFNJga65pivEvaDlfiwKxIRTzM4iuNbc2FRvP2q30dlGAztv0tg==}
+=======
+ '@redocly/openapi-core@2.12.7':
+ resolution: {integrity: sha512-b32Pvl4IE2QZFPpPXD7Qciwy1/AZ2EUaYJ++Oyngaz5WlyeGb9HX/fWmf2QO0YvSqNdK7OSY3m8lPBQ+zlNlgw==}
+ engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
+
+ '@redocly/respect-core@2.12.7':
+ resolution: {integrity: sha512-pBm81qeCYkOC0BCAO6lnEDifLChpCUFP6CsBPNXTYgpFa606UjDULYVIcVUOvwZGlqv6euWIHNT8DfkzFGeltQ==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
'@rollup/rollup-android-arm-eabi@4.53.5':
@@ -836,8 +1021,13 @@ packages:
'@types/node@22.19.3':
resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==}
+<<<<<<< HEAD
'@types/node@25.0.3':
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==}
+=======
+ '@types/node@25.0.2':
+ resolution: {integrity: sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
'@types/stylis@4.2.5':
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
@@ -1273,8 +1463,13 @@ packages:
es6-promise@3.3.1:
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
+<<<<<<< HEAD
esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+=======
+ esbuild@0.27.1:
+ resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
engines: {node: '>=18'}
hasBin: true
@@ -1385,9 +1580,18 @@ packages:
resolution: {integrity: sha512-7Jsfj2uLuGWvnxjrGDrHWpSm65+OcVx0ZbTD2wwkz6Wt6KjGm6+ZYwwpdXdwAlzbJYq+LCEMNvDJc4485AQ1vQ==}
hasBin: true
+ fastify-plugin@4.5.1:
+ resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
+
fastify-plugin@5.1.0:
resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==}
+ fastify-socket.io@5.1.0:
+ resolution: {integrity: sha512-GC1gjrxBGeTbMWV779XHF4uw3AtgKwSQJ9MnjGiMp91ZBuPXEdBYa7NnAMDEl3oZPgK9JO4BlNncTV+UAN+1kg==}
+ peerDependencies:
+ fastify: 4.x.x
+ socket.io: '>=4'
+
fastify@5.6.2:
resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==}
@@ -2438,8 +2642,13 @@ packages:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
+<<<<<<< HEAD
typebox@1.0.64:
resolution: {integrity: sha512-U6quDhQMzQRzBX8jvlE5mZlUnlMRTaZrG/QMAhOYVJ0D0rhq1iOXBQVSzBX0JgAh55jXQ7fWIv24i+lVimXcDw==}
+=======
+ typebox@1.0.63:
+ resolution: {integrity: sha512-qqQ1IePTIL3Illa9C5GToVAUM5qRwOaDN4x/V4jBIt4V0S3lqttJbUNIYm+u+QXvvVxOnTddWxa+6hGuujIEwA==}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
typescript-eslint@8.50.0:
resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==}
@@ -2670,6 +2879,7 @@ snapshots:
'@emotion/unitless@0.8.1': {}
+<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2':
optional: true
@@ -2746,6 +2956,84 @@ snapshots:
optional: true
'@esbuild/win32-x64@0.27.2':
+=======
+ '@esbuild/aix-ppc64@0.27.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/android-arm@0.27.1':
+ optional: true
+
+ '@esbuild/android-x64@0.27.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.1':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.1':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.1':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
optional: true
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)':
@@ -3065,14 +3353,23 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
+<<<<<<< HEAD
'@redocly/cli@2.13.0(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)':
+=======
+ '@redocly/cli@2.12.7(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
'@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.34.0
+<<<<<<< HEAD
'@redocly/openapi-core': 2.13.0(ajv@8.17.1)
'@redocly/respect-core': 2.13.0(ajv@8.17.1)
+=======
+ '@redocly/openapi-core': 2.12.7(ajv@8.17.1)
+ '@redocly/respect-core': 2.12.7(ajv@8.17.1)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
abort-controller: 3.0.0
chokidar: 3.6.0
colorette: 1.4.0
@@ -3124,7 +3421,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
+<<<<<<< HEAD
'@redocly/openapi-core@2.13.0(ajv@8.17.1)':
+=======
+ '@redocly/openapi-core@2.12.7(ajv@8.17.1)':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
'@redocly/ajv': 8.17.1
'@redocly/config': 0.41.0
@@ -3138,12 +3439,20 @@ snapshots:
transitivePeerDependencies:
- ajv
+<<<<<<< HEAD
'@redocly/respect-core@2.13.0(ajv@8.17.1)':
+=======
+ '@redocly/respect-core@2.12.7(ajv@8.17.1)':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
'@faker-js/faker': 7.6.0
'@noble/hashes': 1.8.0
'@redocly/ajv': 8.17.1
+<<<<<<< HEAD
'@redocly/openapi-core': 2.13.0(ajv@8.17.1)
+=======
+ '@redocly/openapi-core': 2.12.7(ajv@8.17.1)
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
better-ajv-errors: 1.2.0(ajv@8.17.1)
colorette: 2.0.20
json-pointer: 0.6.2
@@ -3243,7 +3552,11 @@ snapshots:
dependencies:
undici-types: 6.21.0
+<<<<<<< HEAD
'@types/node@25.0.3':
+=======
+ '@types/node@25.0.2':
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies:
undici-types: 7.16.0
@@ -3690,6 +4003,7 @@ snapshots:
es6-promise@3.3.1: {}
+<<<<<<< HEAD
esbuild@0.27.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2
@@ -3718,6 +4032,36 @@ snapshots:
'@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.2
+=======
+ esbuild@0.27.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.1
+ '@esbuild/android-arm': 0.27.1
+ '@esbuild/android-arm64': 0.27.1
+ '@esbuild/android-x64': 0.27.1
+ '@esbuild/darwin-arm64': 0.27.1
+ '@esbuild/darwin-x64': 0.27.1
+ '@esbuild/freebsd-arm64': 0.27.1
+ '@esbuild/freebsd-x64': 0.27.1
+ '@esbuild/linux-arm': 0.27.1
+ '@esbuild/linux-arm64': 0.27.1
+ '@esbuild/linux-ia32': 0.27.1
+ '@esbuild/linux-loong64': 0.27.1
+ '@esbuild/linux-mips64el': 0.27.1
+ '@esbuild/linux-ppc64': 0.27.1
+ '@esbuild/linux-riscv64': 0.27.1
+ '@esbuild/linux-s390x': 0.27.1
+ '@esbuild/linux-x64': 0.27.1
+ '@esbuild/netbsd-arm64': 0.27.1
+ '@esbuild/netbsd-x64': 0.27.1
+ '@esbuild/openbsd-arm64': 0.27.1
+ '@esbuild/openbsd-x64': 0.27.1
+ '@esbuild/openharmony-arm64': 0.27.1
+ '@esbuild/sunos-x64': 0.27.1
+ '@esbuild/win32-arm64': 0.27.1
+ '@esbuild/win32-ia32': 0.27.1
+ '@esbuild/win32-x64': 0.27.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
escalade@3.2.0: {}
@@ -3858,8 +4202,17 @@ snapshots:
semver: 7.7.3
yargs-parser: 22.0.0
+ fastify-plugin@4.5.1: {}
+
fastify-plugin@5.1.0: {}
+ fastify-socket.io@5.1.0(fastify@5.6.2)(socket.io@4.8.1):
+ dependencies:
+ fastify: 5.6.2
+ fastify-plugin: 4.5.1
+ socket.io: 4.8.1
+ tslib: 2.8.1
+
fastify@5.6.2:
dependencies:
'@fastify/ajv-compiler': 4.0.5
@@ -4551,7 +4904,11 @@ snapshots:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
+<<<<<<< HEAD
'@types/node': 25.0.3
+=======
+ '@types/node': 25.0.2
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
long: 5.3.2
pump@3.0.3:
@@ -4966,6 +5323,11 @@ snapshots:
tslib@2.6.2: {}
+<<<<<<< HEAD
+=======
+ tslib@2.8.1: {}
+
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
tunnel-agent@0.6.0:
dependencies:
safe-buffer: 5.2.1
@@ -4980,7 +5342,11 @@ snapshots:
media-typer: 1.1.0
mime-types: 3.0.2
+<<<<<<< HEAD
typebox@1.0.64: {}
+=======
+ typebox@1.0.63: {}
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
typescript-eslint@8.50.0(eslint@9.39.2)(typescript@5.9.3):
dependencies:
@@ -5035,7 +5401,11 @@ snapshots:
vite@7.3.0(@types/node@22.19.3)(yaml@2.8.2):
dependencies:
+<<<<<<< HEAD
esbuild: 0.27.2
+=======
+ esbuild: 0.27.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
@@ -5046,16 +5416,26 @@ snapshots:
fsevents: 2.3.3
yaml: 2.8.2
+<<<<<<< HEAD
vite@7.3.0(@types/node@25.0.3)(yaml@2.8.2):
dependencies:
esbuild: 0.27.2
+=======
+ vite@7.3.0(@types/node@25.0.2)(yaml@2.8.2):
+ dependencies:
+ esbuild: 0.27.1
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.53.5
tinyglobby: 0.2.15
optionalDependencies:
+<<<<<<< HEAD
'@types/node': 25.0.3
+=======
+ '@types/node': 25.0.2
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fsevents: 2.3.3
yaml: 2.8.2
diff --git a/src/tic-tac-toe/package.json b/src/tic-tac-toe/package.json
new file mode 100644
index 0000000..503c4fc
--- /dev/null
+++ b/src/tic-tac-toe/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "tic-tac-toe",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "npm run build && node dist/run.js",
+ "build": "vite build",
+ "build:prod": "vite build --outDir=/dist --minify=true --sourcemap=false",
+ "REMOVEME-build:openapi": "VITE_ENTRYPOINT=src/openapi.ts vite build && node dist/openapi.cjs >openapi.json",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "packageManager": "pnpm@10.24.0",
+ "dependencies": {
+ "fastify-socket.io": "^5.1.0",
+ "socket.io": "^4.8.1"
+ }
+}
diff --git a/src/tic-tac-toe/src/app.ts b/src/tic-tac-toe/src/app.ts
new file mode 100644
index 0000000..896d366
--- /dev/null
+++ b/src/tic-tac-toe/src/app.ts
@@ -0,0 +1,240 @@
+import { FastifyInstance, FastifyPluginAsync } from 'fastify';
+import fastifySocketIO from 'fastify-socket.io';
+import { TTC } from './game';
+
+const app: FastifyPluginAsync = async (fastify: FastifyInstance, opts): Promise => {
+ void opts;
+ await fastify.register(fastifySocketIO, {
+ cors: {
+ origin: '*',
+ methods: ['GET', 'POST'],
+ },
+ });
+
+ const game = new TTC();
+
+ fastify.ready().then(() => {
+ fastify.io.on('connection', (socket) => {
+ fastify.log.info(`Client connected: ${socket.id}`);
+
+ socket.emit('gameState', {
+ board: game.board,
+ turn: game.currentPlayer,
+ gameOver: game.isGameOver,
+ });
+
+ socket.on('makeMove', (idx: number) => {
+ const result = game.makeMove(idx);
+
+ if (result === 'invalidMove') {
+ socket.emit('error', 'Invalid Move');
+ }
+ else {
+ fastify.io.emit('gameState', {
+ board: game.board,
+ turn: game.currentPlayer,
+ lastResult: result,
+ });
+ }
+ });
+
+ socket.on('resetGame', () => {
+ game.reset();
+ fastify.io.emit('gameState', {
+ board: game.board,
+ turn: game.currentPlayer,
+ reset: true,
+ });
+ });
+ });
+ });
+};
+
+export default app;
+
+// // TODO: Import the plugins defined for this microservice
+// // TODO: Import the routes defined for this microservice
+
+// // @brief The microservice app (as a plugin for Fastify), kinda like a main function I guess ???
+// // @param fastify
+// // @param opts
+// export const app: FastifyPluginAsync = async (fastify, opts): Promise => {
+// // Register all the fastify plugins that this app will use
+
+// // Once it is done:
+// fastify.ready((err) => {
+// if (err) {
+// throw err;
+// }
+// // TODO: Supposedly, something should be there I guess
+// });
+// };
+// // Export it as the default for this file.
+// export default app;
+
+// // TODO: Understand what is this for in /src/chat/src/app.ts
+// // declare module 'fastify' {
+// // interface FastifyInstance {
+// // io: Server<{
+// // hello: (message: string) => string;
+// // MsgObjectServer: (data: { message: ClientMessage }) => void;
+// // message: (msg: string) => void;
+// // testend: (sock_id_client: string) => void;
+// // }>;
+// // }
+// // }
+
+// // TODO: Same for this, also in /src/chat/src/app.ts
+// // async function onReady(fastify: FastifyInstance) {
+// // function connectedUser(io?: Server, target?: string): number {
+// // let count = 0;
+// // const seen = new Set();
+// // // <- only log/count unique usernames
+
+// // for (const [socketId, username] of clientChat) {
+// // // Basic sanity checks
+// // if (typeof socketId !== 'string' || socketId.length === 0) {
+// // clientChat.delete(socketId);
+// // continue;
+// // }
+// // if (typeof username !== 'string' || username.length === 0) {
+// // clientChat.delete(socketId);
+// // continue;
+// // }
+
+// // // If we have the io instance, attempt to validate the socket is still connected
+// // if (io && typeof io.sockets?.sockets?.get === 'function') {
+// // const s = io.sockets.sockets.get(socketId) as
+// // | Socket
+// // | undefined;
+// // // If socket not found or disconnected, remove from map and skip
+// // if (!s || s.disconnected) {
+// // clientChat.delete(socketId);
+// // continue;
+// // }
+
+// // // Skip duplicates (DO NOT delete them — just don't count)
+// // if (seen.has(username)) {
+// // continue;
+// // }
+// // // socket exists and is connected
+// // seen.add(username);
+// // count++;
+// // // console.log(color.green,"count: ", count);
+// // console.log(color.yellow, 'Client:', color.reset, username);
+
+// // const targetSocketId = target;
+// // io.to(targetSocketId!).emit('listObj', username);
+
+// // console.log(
+// // color.yellow,
+// // 'Chat Socket ID:',
+// // color.reset,
+// // socketId,
+// // );
+// // continue;
+// // }
+
+// // // If no io provided, assume entries in the map are valid and count them.
+// // count++;
+// // console.log(
+// // color.red,
+// // 'Client (unverified):',
+// // color.reset,
+// // username,
+// // );
+// // console.log(
+// // color.red,
+// // 'Chat Socket ID (unverified):',
+// // color.reset,
+// // socketId,
+// // );
+// // }
+
+// // return count;
+// // }
+
+// // function broadcast(data: ClientMessage, sender?: string) {
+// // fastify.io.fetchSockets().then((sockets) => {
+// // for (const s of sockets) {
+// // if (s.id !== sender) {
+// // // Send REAL JSON object
+// // const clientName = clientChat.get(s.id) || null;
+// // if (clientName !== null) {
+// // s.emit('MsgObjectServer', { message: data });
+// // }
+// // console.log(' Target window socket ID:', s.id);
+// // console.log(' Target window ID:', [...s.rooms]);
+// // console.log(' Sender window ID:', sender ? sender : 'none');
+// // }
+// // }
+// // });
+// // }
+
+// // fastify.io.on('connection', (socket: Socket) => {
+// // socket.on('message', (message: string) => {
+// // console.info(
+// // color.blue,
+// // 'Socket connected!',
+// // color.reset,
+// // socket.id,
+// // );
+// // console.log(
+// // color.blue,
+// // 'Received message from client',
+// // color.reset,
+// // message,
+// // );
+
+// // const obj: ClientMessage = JSON.parse(message) as ClientMessage;
+// // clientChat.set(socket.id, obj.user);
+// // console.log(
+// // color.green,
+// // 'Message from client',
+// // color.reset,
+// // `Sender: login name: "${obj.user}" - windowID "${obj.SenderWindowID}" - text message: "${obj.text}"`,
+// // );
+// // // Send object directly — DO NOT wrap it in a string
+// // broadcast(obj, obj.SenderWindowID);
+// // console.log(
+// // color.red,
+// // 'connected in the Chat :',
+// // connectedUser(fastify.io),
+// // color.reset,
+// // );
+// // });
+
+// // socket.on('testend', (sock_id_cl: string) => {
+// // console.log('testend received from client socket id:', sock_id_cl);
+// // });
+
+// // socket.on('list', () => {
+// // console.log(color.red, 'list activated', color.reset, socket.id);
+// // connectedUser(fastify.io, socket.id);
+// // });
+
+// // socket.on('disconnecting', (reason) => {
+// // const clientName = clientChat.get(socket.id) || null;
+// // console.log(
+// // color.green,
+// // `Client disconnecting: ${clientName} (${socket.id}) reason:`,
+// // reason,
+// // );
+// // if (reason === 'transport error') return;
+
+// // if (clientName !== null) {
+// // const obj = {
+// // type: 'chat',
+// // user: clientName,
+// // token: '',
+// // text: 'LEFT the chat',
+// // timestamp: Date.now(),
+// // SenderWindowID: socket.id,
+// // };
+
+// // broadcast(obj, obj.SenderWindowID);
+// // // clientChat.delete(obj.user);
+// // }
+// // });
+// // });
+// // }
\ No newline at end of file
diff --git a/src/tic-tac-toe/src/game.ts b/src/tic-tac-toe/src/game.ts
new file mode 100644
index 0000000..a08a2e4
--- /dev/null
+++ b/src/tic-tac-toe/src/game.ts
@@ -0,0 +1,81 @@
+// Represents the possible states of a cell on the board.
+// `null` means that the cell is empty.
+type CellState = 'O' | 'X' | null
+
+export class TTC {
+ private isGameOver: boolean = false;
+ public board: CellState[] = Array(9).fill(null);
+ private currentPlayer: 'O' | 'X' = 'X';
+
+ private changePlayer() {
+ this.currentPlayer = this.currentPlayer === 'X' ? 'O' : 'X';
+ }
+
+ // Analyzes the current board to determine if the game has ended.
+ private checkState(): 'winX' | 'winO' | 'draw' | 'ongoing' {
+ const checkRow = (row: number): ('X' | 'O' | null) => {
+ if (this.board[row * 3] === null) {return null;}
+ if (this.board[row * 3] === this.board[row * 3 + 1] && this.board[row * 3 + 1] === this.board[row * 3 + 2]) {return this.board[row * 3];}
+ return null;
+ };
+
+ const checkCol = (col: number): ('X' | 'O' | null) => {
+ if (this.board[col] === null) return null;
+
+ if (this.board[col] === this.board[col + 3] && this.board[col + 3] === this.board[col + 6]) {return this.board[col];}
+ return null;
+ };
+
+ const checkDiag = (): ('X' | 'O' | null) => {
+ if (this.board[4] === null) return null;
+
+ if (this.board[0] === this.board[4] && this.board[4] === this.board[8]) {return this.board[4];}
+
+ if (this.board[2] === this.board[4] && this.board[4] === this.board[6]) {return this.board[4];}
+ return null;
+ };
+
+
+ const row = (checkRow(0) ?? checkRow(1)) ?? checkRow(2);
+ const col = (checkCol(0) ?? checkCol(1)) ?? checkCol(2);
+ const diag = checkDiag();
+
+ if (row !== null) return `win${row}`;
+ if (col !== null) return `win${col}`;
+ if (diag !== null) return `win${diag}`;
+
+ if (this.board.filter(c => c === null).length === 0) {return 'draw';}
+ return 'ongoing';
+ }
+
+ public reset(): void {
+ this.board = [null, null, null, null, null, null, null, null, null];
+ this.currentPlayer = 'X';
+ this.isGameOver = false;
+ };
+
+ // Attempts to place the current player's mark on the specified cell.
+ // @param idx - The index of the board (0-8) to place the mark.
+ // @returns The resulting game state, or `invalidMove` if the move is illegal.
+ public makeMove(idx: number): 'winX' | 'winO' | 'draw' | 'ongoing' | 'invalidMove' {
+ if (this.isGameOver) {
+ return 'invalidMove';
+ }
+ if (idx < 0 || idx >= this.board.length) {
+ return 'invalidMove';
+ }
+ if (this.board[idx] !== null) {
+ return 'invalidMove';
+ }
+ this.board[idx] = this.currentPlayer;
+ this.changePlayer();
+
+ const result = this.checkState();
+
+ if (result !== 'ongoing') {
+ this.isGameOver = true;
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/user/package.json b/src/user/package.json
index 2987bf2..9d85fc9 100644
--- a/src/user/package.json
+++ b/src/user/package.json
@@ -26,7 +26,11 @@
"fastify": "^5.6.2",
"fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0",
+<<<<<<< HEAD
"typebox": "^1.0.64"
+=======
+ "typebox": "^1.0.63"
+>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
},
"devDependencies": {
"@types/node": "^22.19.3",