(schism): started separating backend from frontend

This commit is contained in:
apetitco 2025-12-16 14:09:02 +01:00
parent 117b535962
commit fb49ba4ee9
13 changed files with 1214 additions and 163 deletions

114
.idea/workspace.xml generated Normal file
View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="8218e5ba-3b12-4bf2-94a6-d6e732938beb" name="Changes" comment="(schism): started separating backend from frontend" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitHubPullRequestSearchHistory">{
&quot;lastFilter&quot;: {
&quot;state&quot;: &quot;OPEN&quot;,
&quot;assignee&quot;: &quot;RepentedAlex&quot;
}
}</component>
<component name="GithubPullRequestsUISettings">{
&quot;selectedUrlAndAccountId&quot;: {
&quot;url&quot;: &quot;https://github.com/Maix0/ft_deadge.git&quot;,
&quot;accountId&quot;: &quot;05fe7ff5-d360-4ad3-b17e-66daa92a5dbb&quot;
}
}</component>
<component name="ProblemsViewState">
<option name="selectedTabId" value="CurrentFile" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 2
}</component>
<component name="ProjectId" id="36vR6giruhZAXAb7dgLdVVcQIAs" />
<component name="ProjectViewState">
<option name="autoscrollFromSource" value="true" />
<option name="autoscrollToSource" value="true" />
<option name="hideEmptyMiddlePackages" value="true" />
<option name="openDirectoriesWithSingleClick" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"git-widget-placeholder": "Alex/hell",
"javascript.preferred.runtime.type.id": "node",
"kotlin-language-version-configured": "true",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.standard": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.standard": "",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "pnpm",
"settings.editor.selected.configurable": "settings.javascript.runtime",
"ts.external.directory.path": "/Applications/IntelliJ IDEA.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-30f59d01ecdd-cffe25b9f5b3-intellij.indexing.shared.core-IU-253.28294.334" />
<option value="bundled-js-predefined-d6986cc7102b-c7e53b3be11b-JavaScript-IU-253.28294.334" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="8218e5ba-3b12-4bf2-94a6-d6e732938beb" name="Changes" comment="" />
<created>1765884886075</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1765884886075</updated>
<workItem from="1765884888641" duration="1507000" />
<workItem from="1765886413897" duration="6289000" />
</task>
<task id="LOCAL-00001" summary="(schism): started separating backend from frontend">
<option name="closed" value="true" />
<created>1765890545228</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1765890545228</updated>
</task>
<option name="localTasksCounter" value="2" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="(schism): started separating backend from frontend" />
<option name="LAST_COMMIT_MESSAGE" value="(schism): started separating backend from frontend" />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
</component>
</project>

View file

@ -67,6 +67,32 @@ services:
gelf-address: "udp://127.0.0.1:12201" gelf-address: "udp://127.0.0.1:12201"
tag: "{{.Name}}" 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: chat:
build: build:
context: ./src/ context: ./src/

295
frontend/pnpm-lock.yaml generated
View file

@ -10,7 +10,11 @@ importers:
dependencies: dependencies:
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: ^4.1.18 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.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': '@types/qrcode':
specifier: ^1.5.6 specifier: ^1.5.6
version: 1.5.6 version: 1.5.6
@ -35,6 +39,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite: vite:
specifier: ^7.3.0 specifier: ^7.3.0
<<<<<<< HEAD
version: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) version: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)
vite-tsconfig-paths: vite-tsconfig-paths:
specifier: ^5.1.4 specifier: ^5.1.4
@ -44,156 +49,292 @@ packages:
'@esbuild/aix-ppc64@0.27.2': '@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} 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'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [aix] os: [aix]
<<<<<<< HEAD
'@esbuild/android-arm64@0.27.2': '@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/android-arm@0.27.2': '@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} 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'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/android-x64@0.27.2': '@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/darwin-arm64@0.27.2': '@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
<<<<<<< HEAD
'@esbuild/darwin-x64@0.27.2': '@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
<<<<<<< HEAD
'@esbuild/freebsd-arm64@0.27.2': '@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
<<<<<<< HEAD
'@esbuild/freebsd-x64@0.27.2': '@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
<<<<<<< HEAD
'@esbuild/linux-arm64@0.27.2': '@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-arm@0.27.2': '@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} 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'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-ia32@0.27.2': '@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} 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'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-loong64@0.27.2': '@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} 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'} engines: {node: '>=18'}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-mips64el@0.27.2': '@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} 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'} engines: {node: '>=18'}
cpu: [mips64el] cpu: [mips64el]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-ppc64@0.27.2': '@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} 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'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-riscv64@0.27.2': '@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} 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'} engines: {node: '>=18'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-s390x@0.27.2': '@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} 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'} engines: {node: '>=18'}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-x64@0.27.2': '@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/netbsd-arm64@0.27.2': '@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [netbsd] os: [netbsd]
<<<<<<< HEAD
'@esbuild/netbsd-x64@0.27.2': '@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [netbsd] os: [netbsd]
<<<<<<< HEAD
'@esbuild/openbsd-arm64@0.27.2': '@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openbsd] os: [openbsd]
<<<<<<< HEAD
'@esbuild/openbsd-x64@0.27.2': '@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [openbsd] os: [openbsd]
<<<<<<< HEAD
'@esbuild/openharmony-arm64@0.27.2': '@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openharmony] os: [openharmony]
<<<<<<< HEAD
'@esbuild/sunos-x64@0.27.2': '@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [sunos] os: [sunos]
<<<<<<< HEAD
'@esbuild/win32-arm64@0.27.2': '@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
<<<<<<< HEAD
'@esbuild/win32-ia32@0.27.2': '@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} 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'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
<<<<<<< HEAD
'@esbuild/win32-x64@0.27.2': '@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -423,8 +564,13 @@ packages:
'@types/js-cookie@3.0.6': '@types/js-cookie@3.0.6':
resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
<<<<<<< HEAD
'@types/node@25.0.3': '@types/node@25.0.3':
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} 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': '@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==} resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
@ -494,8 +640,13 @@ packages:
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
<<<<<<< HEAD
esbuild@0.27.2: esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} 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'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -808,6 +959,7 @@ packages:
snapshots: snapshots:
<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2': '@esbuild/aix-ppc64@0.27.2':
optional: true optional: true
@ -884,6 +1036,84 @@ snapshots:
optional: true optional: true
'@esbuild/win32-x64@0.27.2': '@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 optional: true
'@jridgewell/gen-mapping@0.3.13': '@jridgewell/gen-mapping@0.3.13':
@ -1034,24 +1264,40 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
'@tailwindcss/oxide-win32-x64-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.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: dependencies:
'@tailwindcss/node': 4.1.18 '@tailwindcss/node': 4.1.18
'@tailwindcss/oxide': 4.1.18 '@tailwindcss/oxide': 4.1.18
tailwindcss: 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.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/estree@1.0.8': {}
'@types/js-cookie@3.0.6': {} '@types/js-cookie@3.0.6': {}
<<<<<<< HEAD
'@types/node@25.0.3': '@types/node@25.0.3':
=======
'@types/node@25.0.2':
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies: dependencies:
undici-types: 7.16.0 undici-types: 7.16.0
'@types/qrcode@1.5.6': '@types/qrcode@1.5.6':
dependencies: dependencies:
<<<<<<< HEAD
'@types/node': 25.0.3 '@types/node': 25.0.3
=======
'@types/node': 25.0.2
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
ansi-regex@5.0.1: {} ansi-regex@5.0.1: {}
@ -1108,6 +1354,7 @@ snapshots:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
tapable: 2.3.0 tapable: 2.3.0
<<<<<<< HEAD
esbuild@0.27.2: esbuild@0.27.2:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2 '@esbuild/aix-ppc64': 0.27.2
@ -1136,6 +1383,36 @@ snapshots:
'@esbuild/win32-arm64': 0.27.2 '@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2 '@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 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): fdir@6.5.0(picomatch@4.0.3):
optionalDependencies: optionalDependencies:
@ -1333,27 +1610,45 @@ snapshots:
undici-types@7.16.0: {} 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.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: dependencies:
debug: 4.4.3 debug: 4.4.3
globrex: 0.1.2 globrex: 0.1.2
tsconfck: 3.1.6(typescript@5.9.3) tsconfck: 3.1.6(typescript@5.9.3)
optionalDependencies: 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.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: transitivePeerDependencies:
- supports-color - supports-color
- typescript - typescript
<<<<<<< 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.3)(jiti@2.6.1)(lightningcss@1.30.2):
dependencies: dependencies:
esbuild: 0.27.2 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) fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3 picomatch: 4.0.3
postcss: 8.5.6 postcss: 8.5.6
rollup: 4.53.5 rollup: 4.53.5
tinyglobby: 0.2.15 tinyglobby: 0.2.15
optionalDependencies: optionalDependencies:
<<<<<<< HEAD
'@types/node': 25.0.3 '@types/node': 25.0.3
=======
'@types/node': 25.0.2
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fsevents: 2.3.3 fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.30.2 lightningcss: 1.30.2

View file

@ -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 tttPage from "./ttt.html?raw";
import { showError, showInfo, showSuccess } from "@app/toast"; import { showError, showInfo, showSuccess } from "@app/toast";
import { io, Socket } from "socket.io-client";
// 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;
}
}
// Route handler for the Tic-Tac-Toe page. // Route handler for the Tic-Tac-Toe page.
// Instantiates the game logic and binds UI events. // Instantiates the game logic and binds UI events.
async function handleTTT(): Promise<RouteHandlerReturn> async function handleTTT(): Promise<RouteHandlerReturn> {
{ const socket: Socket = io("http://localhost:80");
// Create a fresh instance for every page load.
let board = new TTC();
return { return {
html: tttPage, html: tttPage,
@ -131,61 +17,49 @@ async function handleTTT(): Promise<RouteHandlerReturn>
const cells = app.querySelectorAll<HTMLDivElement>(".ttt-grid-cell"); const cells = app.querySelectorAll<HTMLDivElement>(".ttt-grid-cell");
const restartBtn = app.querySelector<HTMLButtonElement>("#ttt-restart-btn"); const restartBtn = app.querySelector<HTMLButtonElement>("#ttt-restart-btn");
const grid = app.querySelector('.ttt-grid'); // Not sure about this one
const updateUI = () => { const updateUI = (boardState: (string | null)[]) => {
const board_state = board.getBoard(); boardState.forEach((state, idx) => {
board_state.forEach((cell_state, cell_idx) => { cells[idx].innerText = state || " ";
cells[cell_idx].innerText = cell_state !== null ? cell_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) { cells?.forEach(function (c, idx) {
c.addEventListener('click', () => { c.addEventListener('click', () => {
const result = board.makeMove(idx); socket.emit('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();
}); });
}); });
restartBtn?.addEventListener('click', () => { restartBtn?.addEventListener('click', () => {
board.reset(); socket.emit('resetGame');
// 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');
}); });
} },
} }
} }
addRoute('/ttt', handleTTT);
addRoute('/ttt', handleTTT)

View file

@ -20,7 +20,11 @@
"fastify-plugin": "^5.1.0", "fastify-plugin": "^5.1.0",
"joi": "^18.0.2", "joi": "^18.0.2",
"otp": "^1.1.2", "otp": "^1.1.2",
<<<<<<< HEAD
"typebox": "^1.0.64", "typebox": "^1.0.64",
=======
"typebox": "^1.0.63",
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
"uuidv7": "^1.1.0" "uuidv7": "^1.1.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -27,7 +27,11 @@
"fastify": "^5.6.2", "fastify": "^5.6.2",
"fastify-cli": "^7.4.1", "fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0", "fastify-plugin": "^5.1.0",
<<<<<<< HEAD
"typebox": "^1.0.64" "typebox": "^1.0.64"
=======
"typebox": "^1.0.63"
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.19.3", "@types/node": "^22.19.3",

View file

@ -27,7 +27,11 @@
"fastify": "^5.6.2", "fastify": "^5.6.2",
"fastify-plugin": "^5.1.0", "fastify-plugin": "^5.1.0",
"socket.io": "^4.8.1", "socket.io": "^4.8.1",
<<<<<<< HEAD
"typebox": "^1.0.64" "typebox": "^1.0.64"
=======
"typebox": "^1.0.63"
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.19.3", "@types/node": "^22.19.3",

View file

@ -33,7 +33,11 @@
"vite": "^7.3.0" "vite": "^7.3.0"
}, },
"dependencies": { "dependencies": {
<<<<<<< HEAD
"@redocly/cli": "^2.13.0", "@redocly/cli": "^2.13.0",
=======
"@redocly/cli": "^2.12.7",
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
"bindings": "^1.5.0" "bindings": "^1.5.0"
} }
} }

380
src/pnpm-lock.yaml generated
View file

@ -9,8 +9,13 @@ importers:
.: .:
dependencies: dependencies:
'@redocly/cli': '@redocly/cli':
<<<<<<< HEAD
specifier: ^2.13.0 specifier: ^2.13.0
version: 2.13.0(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.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: bindings:
specifier: ^1.5.0 specifier: ^1.5.0
version: 1.5.0 version: 1.5.0
@ -41,7 +46,11 @@ importers:
version: 8.50.0(eslint@9.39.2)(typescript@5.9.3) version: 8.50.0(eslint@9.39.2)(typescript@5.9.3)
vite: vite:
specifier: ^7.3.0 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.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': '@shared':
dependencies: dependencies:
@ -79,8 +88,13 @@ importers:
specifier: ^1.1.2 specifier: ^1.1.2
version: 1.1.2 version: 1.1.2
typebox: typebox:
<<<<<<< HEAD
specifier: ^1.0.64 specifier: ^1.0.64
version: 1.0.64 version: 1.0.64
=======
specifier: ^1.0.63
version: 1.0.63
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
uuidv7: uuidv7:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0 version: 1.1.0
@ -122,8 +136,13 @@ importers:
specifier: ^5.1.0 specifier: ^5.1.0
version: 5.1.0 version: 5.1.0
typebox: typebox:
<<<<<<< HEAD
specifier: ^1.0.64 specifier: ^1.0.64
version: 1.0.64 version: 1.0.64
=======
specifier: ^1.0.63
version: 1.0.63
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies: devDependencies:
'@types/node': '@types/node':
specifier: ^22.19.3 specifier: ^22.19.3
@ -168,8 +187,13 @@ importers:
specifier: ^4.8.1 specifier: ^4.8.1
version: 4.8.1 version: 4.8.1
typebox: typebox:
<<<<<<< HEAD
specifier: ^1.0.64 specifier: ^1.0.64
version: 1.0.64 version: 1.0.64
=======
specifier: ^1.0.63
version: 1.0.63
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies: devDependencies:
'@types/node': '@types/node':
specifier: ^22.19.3 specifier: ^22.19.3
@ -183,6 +207,18 @@ importers:
vite-tsconfig-paths: vite-tsconfig-paths:
specifier: ^5.1.4 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)) 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: user:
dependencies: dependencies:
@ -211,8 +247,13 @@ importers:
specifier: ^5.1.0 specifier: ^5.1.0
version: 5.1.0 version: 5.1.0
typebox: typebox:
<<<<<<< HEAD
specifier: ^1.0.64 specifier: ^1.0.64
version: 1.0.64 version: 1.0.64
=======
specifier: ^1.0.63
version: 1.0.63
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
devDependencies: devDependencies:
'@types/node': '@types/node':
specifier: ^22.19.3 specifier: ^22.19.3
@ -250,158 +291,288 @@ packages:
'@emotion/unitless@0.8.1': '@emotion/unitless@0.8.1':
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2': '@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} 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'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [aix] os: [aix]
<<<<<<< HEAD
'@esbuild/android-arm64@0.27.2': '@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/android-arm@0.27.2': '@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} 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'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/android-x64@0.27.2': '@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
<<<<<<< HEAD
'@esbuild/darwin-arm64@0.27.2': '@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
<<<<<<< HEAD
'@esbuild/darwin-x64@0.27.2': '@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
<<<<<<< HEAD
'@esbuild/freebsd-arm64@0.27.2': '@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
<<<<<<< HEAD
'@esbuild/freebsd-x64@0.27.2': '@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
<<<<<<< HEAD
'@esbuild/linux-arm64@0.27.2': '@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-arm@0.27.2': '@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} 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'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-ia32@0.27.2': '@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} 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'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-loong64@0.27.2': '@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} 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'} engines: {node: '>=18'}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-mips64el@0.27.2': '@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} 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'} engines: {node: '>=18'}
cpu: [mips64el] cpu: [mips64el]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-ppc64@0.27.2': '@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} 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'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-riscv64@0.27.2': '@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} 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'} engines: {node: '>=18'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-s390x@0.27.2': '@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} 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'} engines: {node: '>=18'}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/linux-x64@0.27.2': '@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
<<<<<<< HEAD
'@esbuild/netbsd-arm64@0.27.2': '@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [netbsd] os: [netbsd]
<<<<<<< HEAD
'@esbuild/netbsd-x64@0.27.2': '@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [netbsd] os: [netbsd]
<<<<<<< HEAD
'@esbuild/openbsd-arm64@0.27.2': '@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openbsd] os: [openbsd]
<<<<<<< HEAD
'@esbuild/openbsd-x64@0.27.2': '@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [openbsd] os: [openbsd]
<<<<<<< HEAD
'@esbuild/openharmony-arm64@0.27.2': '@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openharmony] os: [openharmony]
<<<<<<< HEAD
'@esbuild/sunos-x64@0.27.2': '@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [sunos] os: [sunos]
<<<<<<< HEAD
'@esbuild/win32-arm64@0.27.2': '@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} 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'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
<<<<<<< HEAD
'@esbuild/win32-ia32@0.27.2': '@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} 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'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
<<<<<<< HEAD
'@esbuild/win32-x64@0.27.2': '@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} 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'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@ -679,8 +850,13 @@ packages:
'@redocly/ajv@8.17.1': '@redocly/ajv@8.17.1':
resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==} resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==}
<<<<<<< HEAD
'@redocly/cli@2.13.0': '@redocly/cli@2.13.0':
resolution: {integrity: sha512-VOGh8p5gKy+u94SbvMGaHvDM6TPw668D9iQkNSztoi4T5sj3ZwM7Y8Z3yZnMqC5s5epDcLAMq4jCO8UVn5ZWHg==} 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'} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
hasBin: true hasBin: true
@ -694,12 +870,21 @@ packages:
resolution: {integrity: sha512-2+O+riuIUgVSuLl3Lyh5AplWZyVMNuG2F98/o6NrutKJfW4/GTZdPpZlIphS0HGgcOHgmWcCSHj+dWFlZaGSHw==} resolution: {integrity: sha512-2+O+riuIUgVSuLl3Lyh5AplWZyVMNuG2F98/o6NrutKJfW4/GTZdPpZlIphS0HGgcOHgmWcCSHj+dWFlZaGSHw==}
engines: {node: '>=18.17.0', npm: '>=9.5.0'} engines: {node: '>=18.17.0', npm: '>=9.5.0'}
<<<<<<< HEAD
'@redocly/openapi-core@2.13.0': '@redocly/openapi-core@2.13.0':
resolution: {integrity: sha512-xQ4z5tsrXbIa4EfCniHv1zZ4etmQ0lpRcxy750iOamV5A/+19mgbPtD+UQCoT18puDAjcnOgpX7x2ha72qKrnw==} resolution: {integrity: sha512-xQ4z5tsrXbIa4EfCniHv1zZ4etmQ0lpRcxy750iOamV5A/+19mgbPtD+UQCoT18puDAjcnOgpX7x2ha72qKrnw==}
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
'@redocly/respect-core@2.13.0': '@redocly/respect-core@2.13.0':
resolution: {integrity: sha512-35OidNXWkmmsJiwgX+tFw7FaU8usZVvZ/lFBFNJga65pivEvaDlfiwKxIRTzM4iuNbc2FRvP2q30dlGAztv0tg==} 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'} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
'@rollup/rollup-android-arm-eabi@4.53.5': '@rollup/rollup-android-arm-eabi@4.53.5':
@ -836,8 +1021,13 @@ packages:
'@types/node@22.19.3': '@types/node@22.19.3':
resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==}
<<<<<<< HEAD
'@types/node@25.0.3': '@types/node@25.0.3':
resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} 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': '@types/stylis@4.2.5':
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==} resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
@ -1273,8 +1463,13 @@ packages:
es6-promise@3.3.1: es6-promise@3.3.1:
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
<<<<<<< HEAD
esbuild@0.27.2: esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} 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'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -1385,9 +1580,18 @@ packages:
resolution: {integrity: sha512-7Jsfj2uLuGWvnxjrGDrHWpSm65+OcVx0ZbTD2wwkz6Wt6KjGm6+ZYwwpdXdwAlzbJYq+LCEMNvDJc4485AQ1vQ==} resolution: {integrity: sha512-7Jsfj2uLuGWvnxjrGDrHWpSm65+OcVx0ZbTD2wwkz6Wt6KjGm6+ZYwwpdXdwAlzbJYq+LCEMNvDJc4485AQ1vQ==}
hasBin: true hasBin: true
fastify-plugin@4.5.1:
resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
fastify-plugin@5.1.0: fastify-plugin@5.1.0:
resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} 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: fastify@5.6.2:
resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==} resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==}
@ -2438,8 +2642,13 @@ packages:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
<<<<<<< HEAD
typebox@1.0.64: typebox@1.0.64:
resolution: {integrity: sha512-U6quDhQMzQRzBX8jvlE5mZlUnlMRTaZrG/QMAhOYVJ0D0rhq1iOXBQVSzBX0JgAh55jXQ7fWIv24i+lVimXcDw==} 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: typescript-eslint@8.50.0:
resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==} resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==}
@ -2670,6 +2879,7 @@ snapshots:
'@emotion/unitless@0.8.1': {} '@emotion/unitless@0.8.1': {}
<<<<<<< HEAD
'@esbuild/aix-ppc64@0.27.2': '@esbuild/aix-ppc64@0.27.2':
optional: true optional: true
@ -2746,6 +2956,84 @@ snapshots:
optional: true optional: true
'@esbuild/win32-x64@0.27.2': '@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 optional: true
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)':
@ -3065,14 +3353,23 @@ snapshots:
json-schema-traverse: 1.0.0 json-schema-traverse: 1.0.0
require-from-string: 2.0.2 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.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: dependencies:
'@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 2.0.1(@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/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.34.0 '@opentelemetry/semantic-conventions': 1.34.0
<<<<<<< HEAD
'@redocly/openapi-core': 2.13.0(ajv@8.17.1) '@redocly/openapi-core': 2.13.0(ajv@8.17.1)
'@redocly/respect-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 abort-controller: 3.0.0
chokidar: 3.6.0 chokidar: 3.6.0
colorette: 1.4.0 colorette: 1.4.0
@ -3124,7 +3421,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
<<<<<<< HEAD
'@redocly/openapi-core@2.13.0(ajv@8.17.1)': '@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: dependencies:
'@redocly/ajv': 8.17.1 '@redocly/ajv': 8.17.1
'@redocly/config': 0.41.0 '@redocly/config': 0.41.0
@ -3138,12 +3439,20 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- ajv - ajv
<<<<<<< HEAD
'@redocly/respect-core@2.13.0(ajv@8.17.1)': '@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: dependencies:
'@faker-js/faker': 7.6.0 '@faker-js/faker': 7.6.0
'@noble/hashes': 1.8.0 '@noble/hashes': 1.8.0
'@redocly/ajv': 8.17.1 '@redocly/ajv': 8.17.1
<<<<<<< HEAD
'@redocly/openapi-core': 2.13.0(ajv@8.17.1) '@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) better-ajv-errors: 1.2.0(ajv@8.17.1)
colorette: 2.0.20 colorette: 2.0.20
json-pointer: 0.6.2 json-pointer: 0.6.2
@ -3243,7 +3552,11 @@ snapshots:
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
<<<<<<< HEAD
'@types/node@25.0.3': '@types/node@25.0.3':
=======
'@types/node@25.0.2':
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
dependencies: dependencies:
undici-types: 7.16.0 undici-types: 7.16.0
@ -3690,6 +4003,7 @@ snapshots:
es6-promise@3.3.1: {} es6-promise@3.3.1: {}
<<<<<<< HEAD
esbuild@0.27.2: esbuild@0.27.2:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2 '@esbuild/aix-ppc64': 0.27.2
@ -3718,6 +4032,36 @@ snapshots:
'@esbuild/win32-arm64': 0.27.2 '@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2 '@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 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: {} escalade@3.2.0: {}
@ -3858,8 +4202,17 @@ snapshots:
semver: 7.7.3 semver: 7.7.3
yargs-parser: 22.0.0 yargs-parser: 22.0.0
fastify-plugin@4.5.1: {}
fastify-plugin@5.1.0: {} 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: fastify@5.6.2:
dependencies: dependencies:
'@fastify/ajv-compiler': 4.0.5 '@fastify/ajv-compiler': 4.0.5
@ -4551,7 +4904,11 @@ snapshots:
'@protobufjs/path': 1.1.2 '@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0 '@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0 '@protobufjs/utf8': 1.1.0
<<<<<<< HEAD
'@types/node': 25.0.3 '@types/node': 25.0.3
=======
'@types/node': 25.0.2
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
long: 5.3.2 long: 5.3.2
pump@3.0.3: pump@3.0.3:
@ -4966,6 +5323,11 @@ snapshots:
tslib@2.6.2: {} tslib@2.6.2: {}
<<<<<<< HEAD
=======
tslib@2.8.1: {}
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
tunnel-agent@0.6.0: tunnel-agent@0.6.0:
dependencies: dependencies:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -4980,7 +5342,11 @@ snapshots:
media-typer: 1.1.0 media-typer: 1.1.0
mime-types: 3.0.2 mime-types: 3.0.2
<<<<<<< HEAD
typebox@1.0.64: {} 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): typescript-eslint@8.50.0(eslint@9.39.2)(typescript@5.9.3):
dependencies: dependencies:
@ -5035,7 +5401,11 @@ snapshots:
vite@7.3.0(@types/node@22.19.3)(yaml@2.8.2): vite@7.3.0(@types/node@22.19.3)(yaml@2.8.2):
dependencies: dependencies:
<<<<<<< HEAD
esbuild: 0.27.2 esbuild: 0.27.2
=======
esbuild: 0.27.1
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3 picomatch: 4.0.3
postcss: 8.5.6 postcss: 8.5.6
@ -5046,16 +5416,26 @@ snapshots:
fsevents: 2.3.3 fsevents: 2.3.3
yaml: 2.8.2 yaml: 2.8.2
<<<<<<< HEAD
vite@7.3.0(@types/node@25.0.3)(yaml@2.8.2): vite@7.3.0(@types/node@25.0.3)(yaml@2.8.2):
dependencies: dependencies:
esbuild: 0.27.2 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) fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3 picomatch: 4.0.3
postcss: 8.5.6 postcss: 8.5.6
rollup: 4.53.5 rollup: 4.53.5
tinyglobby: 0.2.15 tinyglobby: 0.2.15
optionalDependencies: optionalDependencies:
<<<<<<< HEAD
'@types/node': 25.0.3 '@types/node': 25.0.3
=======
'@types/node': 25.0.2
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
fsevents: 2.3.3 fsevents: 2.3.3
yaml: 2.8.2 yaml: 2.8.2

View file

@ -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"
}
}

240
src/tic-tac-toe/src/app.ts Normal file
View file

@ -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> => {
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<void> => {
// // 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<string>();
// // // <- 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);
// // }
// // });
// // });
// // }

View file

@ -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;
}
}

View file

@ -26,7 +26,11 @@
"fastify": "^5.6.2", "fastify": "^5.6.2",
"fastify-cli": "^7.4.1", "fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0", "fastify-plugin": "^5.1.0",
<<<<<<< HEAD
"typebox": "^1.0.64" "typebox": "^1.0.64"
=======
"typebox": "^1.0.63"
>>>>>>> 16e6ae0 ((schism): started separating backend from frontend)
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.19.3", "@types/node": "^22.19.3",