pull/56/head
Pierre Ferreira 11 months ago
commit 5ff26df06f

@ -17,6 +17,8 @@
"@testing-library/user-event": "^13.5.0",
"@types/lodash": "^4.14.200",
"bootstrap": "^5.3.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
@ -26,7 +28,33 @@
"react-intl": "^6.5.2",
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
<<<<<<< HEAD
<<<<<<< HEAD
"react-switch": "^7.0.0",
=======
=======
>>>>>>> 7e44c5e (ajout de dépendances pour un switch et stub dans les params de jeu :package:)
<<<<<<< HEAD
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
=======
"react-switch": "^7.0.0",
<<<<<<< HEAD
>>>>>>> 3d3d620 (ajout de dépendances pour un switch et stub dans les params de jeu :package:)
<<<<<<< HEAD
>>>>>>> 65f2cb6 (ajout de dépendances pour un switch et stub dans les params de jeu :package:)
=======
=======
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
>>>>>>> 2ba7efc (Début du serveur)
<<<<<<< HEAD
>>>>>>> 6399f16 (Début du serveur)
=======
=======
"react-switch": "^7.0.0",
>>>>>>> 3d3d620 (ajout de dépendances pour un switch et stub dans les params de jeu :package:)
>>>>>>> 7e44c5e (ajout de dépendances pour un switch et stub dans les params de jeu :package:)
"typescript": "^5.2.2",
"vis-network": "^9.1.9",
"web-vitals": "^2.1.4"
@ -3788,6 +3816,11 @@
"@sinonjs/commons": "^1.7.0"
}
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
@ -4208,6 +4241,19 @@
"@types/node": "*"
}
},
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
},
"node_modules/@types/cors": {
"version": "2.8.16",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.16.tgz",
"integrity": "sha512-Trx5or1Nyg1Fq138PCuWqoApzvoSLWzZ25ORBiHMbbUT42g578lH1GT4TwYDbiUOLFuDsCkfLneT2105fsFWGg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/eslint": {
"version": "8.44.7",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz",
@ -5652,6 +5698,14 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
"engines": {
"node": "^4.5.0 || >= 5.9"
}
},
"node_modules/batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@ -6381,6 +6435,18 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
@ -7251,6 +7317,94 @@
"node": ">= 0.8"
}
},
"node_modules/engine.io": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
"integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
"dependencies": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/engine.io-client": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-client/node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/engine.io-parser": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
"integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/engine.io/node_modules/cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/engine.io/node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
@ -15614,6 +15768,77 @@
"node": ">=8"
}
},
"node_modules/socket.io": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz",
"integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.2.0"
}
},
"node_modules/socket.io-adapter": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
"integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
"dependencies": {
"ws": "~8.11.0"
}
},
"node_modules/socket.io-adapter/node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/socket.io-client": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
"integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/sockjs": {
"version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@ -17930,6 +18155,14 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

@ -11,6 +11,8 @@
"@testing-library/user-event": "^13.5.0",
"@types/lodash": "^4.14.200",
"bootstrap": "^5.3.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
@ -21,6 +23,11 @@
"react-router-dom": "^6.18.0",
"react-scripts": "5.0.1",
"react-switch": "^7.0.0",
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
"react-switch": "^7.0.0",
"typescript": "^5.2.2",
"vis-network": "^9.1.9",
"web-vitals": "^2.1.4"

@ -0,0 +1,79 @@
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const cors = require('cors');
const app = express();
const server = http.createServer(app);
const io = socketIO(server, {
cors: {
origin: ["http://localhost:3000", "http://localhost:3001"], // Remplacez par l'URL de votre application React
methods: ["GET", "POST"],
credentials: true
}
});
const map = new Map()
// ... le reste de votre configuration du serveur
server.listen(3002, () => {
console.log('Serveur Socket.IO écoutant sur le port 3001');
});
io.on('connection', (socket) => {
console.log(socket.id);
socket.on('network created', (network, person, indices, room) =>{
io.to(room).emit("game created", network, person, indices, Math.floor(Math.random() * map.get(room).length))
});
socket.on("lobby joined", (room, name) =>{
socket.join(room)
if (map.get(room) == undefined){
map.set(room, [{id: socket.id, name: name}])
}
else{
const tab = map.get(room)
for(let i = 0; i<tab.length; i++){
if (tab[i].id === socket.id){
tab.splice(i, 1)
}
}
map.get(room).push({id: socket.id, name: name})
}
io.to(room).emit("new player", map.get(room))
})
socket.on("lobby created", () =>{
io.to(socket.id).emit("lobby created", 134)
})
socket.on("already asked", (nodeId, askingPlayer, askedPlayer) =>{
io.to(askingPlayer.id).emit("already asked", nodeId, askedPlayer)
})
socket.on("ask player", (nodeId, playerId, askingPlayer) =>{
io.to(playerId).emit("asked", nodeId, askingPlayer)
})
socket.on("disconnect", () =>{
for (const k of map.keys()){
const tab = map.get(k)
for (let i = 0; i<tab.length; i++){
if (tab[i].id === socket.id){
tab.splice(i, 1)
}
}
}
})
socket.on("node checked", (id, works, color, room, playerIndex) =>{
console.log(playerIndex)
io.to(room).emit("node checked", id, works, color, playerIndex)
})
});

@ -2,6 +2,7 @@
import React from 'react';
import { useState } from 'react';
import { IntlProvider } from 'react-intl';
import { GameProvider } from './Contexts/GameContext';
/* Page */
import Home from './Pages/Home';
@ -61,26 +62,28 @@ function App() {
// <img src={logo} className="App-logo" alt="logo" />
// </header>
// </div>
//@ts-ignore
<IntlProvider locale={locale} messages={messages[locale]}>
<ThemeProvider>
<BrowserRouter>
{/* <AppNavbar changeLocale={changeLocale} /> */}
{hasNavbarVisible && <AppNavbar changeLocale={changeLocale} />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<Play/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale} />} />
<Route path="/info" element={<InfoPage/>} />
</Routes>
</BrowserRouter>
</ThemeProvider>
</IntlProvider>
<GameProvider>
{/*@ts-ignore*/}
<IntlProvider locale={locale} messages={messages[locale]}>
<ThemeProvider>
<BrowserRouter>
{hasNavbarVisible && <AppNavbar changeLocale={changeLocale} />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<Play/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale}/>} />
<Route path="/info" element={<InfoPage/>} />
</Routes>
</BrowserRouter>
</ThemeProvider>
</IntlProvider>
</GameProvider>
);
}

@ -0,0 +1,56 @@
import Player from "./model/Player";
import { socket } from "./SocketConfig";
function positionToColor(pos: number): string{
switch (pos) {
case 0:
return "blue";
case 1:
return "green";
case 2:
return "yellow";
case 3:
return "purple";
case 4:
return "red";
default:
return "brown";
}
}
function colorToEmoji(color: string, works: boolean): string{
if (works){
switch (color) {
case "blue":
return "🔵";
case "green":
return "🟢";
case "yellow":
return "🟡";
case "purple":
return "🟣";
case "red":
return "🔴";
default:
return "🟤";
}
}
else{
switch (color) {
case "blue":
return "🟦";
case "green":
return "🟩";
case "yellow":
return "🟨";
case "purple":
return "🟪";
case "red":
return "🟥";
default:
return "🟫";
}
}
}
export {colorToEmoji, positionToColor}

@ -1,17 +1,61 @@
import React from 'react';
import { useGame } from '../Contexts/GameContext';
import { socket } from '../SocketConfig';
import './ChoiceBar.css';
import { useTheme } from '../Style/ThemeContext';
import IndiceTesterFactory from '../model/Factory/IndiceTesterFactory';
import { positionToColor } from '../ColorHelper';
const ChoiceBar = () => {
const players = ['Player1', 'Player2', 'Player3'];
const { players, nodeId, actualPlayerIndex, personNetwork, indices, room } = useGame();
const theme = useTheme();
function askPlayer(playerId: string){
if (nodeId !== null){
socket.emit("ask player", nodeId, playerId, players.find((p) => p.id === socket.id))
}
}
function askEveryone(){
if (nodeId !== null){
const person = personNetwork?.getPersons().find((p) => p.getId() == nodeId)
if (person != undefined){
const indiceTester = IndiceTesterFactory.Create(indices[actualPlayerIndex])
let nextPlayerIndex = actualPlayerIndex + 1
if (nextPlayerIndex == players.length){
nextPlayerIndex = 0
}
let playerIndex = actualPlayerIndex + 1
if (indiceTester.Works(person)){
socket.emit("node checked", nodeId, true, positionToColor(actualPlayerIndex), room, nextPlayerIndex)
while(playerIndex != actualPlayerIndex){
if (playerIndex == players.length){
playerIndex = 0
}
const tester = IndiceTesterFactory.Create(indices[playerIndex])
const works = tester.Works(person)
socket.emit("node checked", nodeId, works, positionToColor(playerIndex), room, nextPlayerIndex)
if(!works){
return
}
playerIndex ++
}
}
}
}
}
return (
<div className="choice-bar-container">
<h3 className="choice-bar-heading">Quel joueur voulez-vous interroger ?</h3>
<div>
<button className="choice-bar-button" onClick={() => askEveryone()} style={{ backgroundColor: theme.colors.primary }}>Tout le monde</button>
{players.map((player, index) => (
<button key={index} className="choice-bar-button" style={{ backgroundColor: theme.colors.primary }}>
{player}
player.id !== socket.id &&
<button key={index} className="choice-bar-button" onClick={() => askPlayer(player.id)} style={{ backgroundColor: theme.colors.primary }}>
{player.name}
</button>
))}
</div>

@ -11,24 +11,58 @@ import "./GraphContainer.css";
import NodePerson from "../model/Graph/NodePerson";
import IndiceTesterFactory from "../model/Factory/IndiceTesterFactory";
import GameCreator from "../model/GameCreator";
import io from 'socket.io-client';
import JSONParser from "../JSONParser";
import PersonNetwork from "../model/PersonsNetwork";
import Person from "../model/Person";
import Indice from "../model/Indices/Indice";
import { useLocation } from "react-router-dom";
import { useGame } from "../Contexts/GameContext";
import { socket } from "../SocketConfig"
import { colorToEmoji, positionToColor } from "../ColorHelper";
const [networkPerson, choosenPerson, choosenIndices, graph] = GameCreator.CreateGame(3, 30)
console.log(networkPerson)
console.log(graph)
choosenIndices.forEach((indice) =>{
console.log(indice.ToString("fr"))
});
console.log(choosenPerson)
const testIndice = choosenIndices[0]
interface MyGraphComponentProps {
onNodeClick: (shouldShowChoiceBar: boolean) => void;
handleShowTurnBar: (shouldShowTurnBar: boolean) => void
}
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
let lastAskingPlayer = 0
let lastNodeId = -1
let first = true
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar}) => {
const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex } = useGame();
let playerIndex: number = turnPlayerIndex
let index = 0
for (let i=0; i<players.length; i++){
if(players[i].id == socket.id){
index=i
break
}
}
let thisPlayerIndex = index
if (first){
first = false
setActualPlayerIndexData(index)
if (playerIndex == thisPlayerIndex){
handleShowTurnBar(true)
}
indices.forEach(i => {
console.log(i.ToString("en"))
});
}
useEffect(() => {
if (personNetwork == null){
return
}
const graph = GraphCreator.CreateGraph(personNetwork)
const container = document.getElementById('graph-container');
if (!container) {
console.error("Container not found");
@ -58,26 +92,84 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
}
};
const networkData = { nodes: nodes, edges: graph.edges };
const network = new Network(container, networkData, initialOptions);
//TEST POUR MONTRER QU'IL Y EN A QU'UN A CHAQUE FOIS
/*
networkPerson.getPersons().forEach(p => {
socket.on("node checked",(id, works, color, newPlayerIndex) => {
const node = nodes.get().find((n) => id == n.id)
if (node!=undefined){
onNodeClick(false)
playerIndex = newPlayerIndex
networkData.nodes.update({id: id, label: node.label + colorToEmoji(color, works)})
if (playerIndex === thisPlayerIndex){
handleShowTurnBar(true)
}
else{
handleShowTurnBar(false)
console.log("je passe bien ici ?????")
}
}
lastAskingPlayer = 0
lastNodeId = -1
})
socket.on("already asked", (nodeId, askedPlayer) =>{
console.log("player: " + askedPlayer + " already asked on node " + nodeId)
})
socket.on("asked", (nodeId, askingPlayer) => {
if (askingPlayer.id !== lastAskingPlayer || nodeId !== lastNodeId ){
lastAskingPlayer = askingPlayer.id
lastNodeId = nodeId
const pers = personNetwork.getPersons().find((p) => p.getId() == nodeId)
if (pers!=undefined){
if (askedPersons.includes(pers)){
socket.emit("already asked", nodeId, askingPlayer, socket.id)
return
}
else{
askedPersons.push(pers)
const node = nodes.get().find((n) => nodeId == n.id)
if (node != undefined && indice != null){
var tester = IndiceTesterFactory.Create(indice)
playerIndex = playerIndex + 1
if(playerIndex == players.length){
playerIndex = 0
}
if (tester.Works(pers)){
socket.emit("node checked", nodeId, true, positionToColor(thisPlayerIndex), room, playerIndex)
}
else{
socket.emit("node checked", nodeId, false, positionToColor(thisPlayerIndex), room, playerIndex)
}
}
}
}
}
})
personNetwork.getPersons().forEach(p => {
let a = 0
for (let i of choosenIndices){
for (let i of indices){
let tester = IndiceTesterFactory.Create(i)
if (tester.Works(p)){
a++
}
}
if (a==choosenIndices.length){
networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"})
if (a==indices.length){
//networkData.nodes.update({id: p.getId(), label: p.getName() + "\n🔵"})
console.log(p)
}
});
*/
// Gérer le changement entre la physique et le déplacement manuel
network.on("dragging", (params) => {
@ -89,28 +181,17 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
});
network.on("click", (params) => {
if(params.nodes.length > 0){
//TEST POUR VOIR SI ON PEUT RAJOUTER DES TRUCS AU LABEL
const pers = networkPerson.getPersons().find((p) => p.getId() == params.nodes[0])
if (pers!=undefined){
//@ts-ignore
const node = nodes.get().find((n) => params.nodes[0] == n.id)
if (node != undefined){
var tester = IndiceTesterFactory.Create(testIndice)
if (tester.Works(pers)){
networkData.nodes.update({id: params.nodes[0], label: node.label + "🔵"})
}
else{
networkData.nodes.update({id: params.nodes[0], label: node.label + "🟦"})
}
}
}
setNodeIdData(params.nodes[0])
// Renvoyer un true pour afficher la choice bar
onNodeClick(true)
if (thisPlayerIndex == playerIndex){
onNodeClick(true)
}
else{
onNodeClick(false)
}
}
else{
// Renvoyer un false pour cacher la choice bar
@ -124,6 +205,8 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick}) => {
<div id="graph-container"/>
</>
);
};
}
export default MyGraphComponent;

@ -30,10 +30,6 @@ function AppNavbar({changeLocale}) {
<Container>
<Navbar.Brand href="/">
<img src={logo} alt="logo" className="logo"/>
{/* <div>
<h2 style={{color:theme.colors.text}}>Cryptide</h2>
<h6 style={{color:theme.colors.text}}>by Crypteam</h6>
</div> */}
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">

@ -9,7 +9,7 @@ import Person from '../res/img/Person.png'
import leave from '../res/img/bot.png'
//@ts-ignore
function PersonStatus({img = Person, state= leave, name = "Dummy"}) {
function PersonStatus({img = Person, state= Person, name = "Dummy"}) {
const theme=useTheme();
return (
<div className='centerDivV'>

@ -0,0 +1,17 @@
import React from "react";
import { useTheme } from "../Style/ThemeContext";
const TurnBar = () => {
const theme = useTheme();
return (
<div className='upperInfo'
style={{
borderColor: theme.colors.secondary
}}>
{/* texte changeable et a traduire */}
<p>Dummy, à vous de jouer !</p>
</div>
);
};
export default TurnBar;

@ -0,0 +1,103 @@
import React, { createContext, useContext, useState, ReactNode } from 'react';
import Indice from '../model/Indices/Indice';
import Person from '../model/Person';
import PersonNetwork from '../model/PersonsNetwork';
import Player from '../model/Player';
interface GameContextProps {
indices: Indice[];
indice: Indice | null
person: Person | null;
personNetwork: PersonNetwork | null;
players: Player[]
nodeId: number | null
askedPersons: Person[];
actualPlayerIndex: number;
turnPlayerIndex: number;
room: string;
setIndicesData: (newIndices: Indice[]) => void;
setIndiceData: (newIndice: Indice) => void;
setPersonData: (newPerson: Person) => void;
setPersonNetworkData: (newPersonNetwork: PersonNetwork) => void;
setPlayersData: (newPlayer: Player[]) => void;
setNodeIdData: (newId: number) => void;
setAskedPersonsData: (newAskedPersons: Person[]) => void;
setActualPlayerIndexData: (newActualPlayerIndex: number) => void;
setTurnPlayerIndexData: (newTurnPlayerIndex: number) => void;
setRoomData: (newRoom: string) => void;
}
const GameContext = createContext<GameContextProps | undefined>(undefined);
interface GameProviderProps {
children: ReactNode;
}
export const GameProvider: React.FC<GameProviderProps> = ({ children }) => {
const [indices, setIndices] = useState<Indice[]>([]);
const [indice, setIndice] = useState<Indice | null>(null);
const [person, setPerson] = useState<Person | null>(null);
const [personNetwork, setPersonNetwork] = useState<PersonNetwork | null>(null);
const [players, setPlayers] = useState<Player[]>([])
const [nodeId, setNodeId] = useState<number | null>(null);
const [askedPersons, setAskedPersons] = useState<Person[]>([])
const [actualPlayerIndex, setActualPlayerIndex] = useState<number>(-1)
const [turnPlayerIndex, setTurnPlayerIndex] = useState<number>(-1)
const [room, setRoom] = useState<string>("")
const setIndicesData = (newIndices: Indice[]) => {
setIndices(newIndices);
};
const setIndiceData = (newIndice: Indice) =>{
setIndice(newIndice)
};
const setPersonData = (newPerson: Person) => {
setPerson(newPerson);
};
const setPersonNetworkData = (newPersonNetwork: PersonNetwork) => {
setPersonNetwork(newPersonNetwork);
};
const setPlayersData = (newPlayers: Player[]) => {
setPlayers(newPlayers);
};
const setNodeIdData = (newId: number) => {
setNodeId(newId);
};
const setAskedPersonsData = (newAskedPerson: Person[]) => {
setAskedPersons(newAskedPerson);
};
const setActualPlayerIndexData = (newActualPlayerIndex: number) =>{
setActualPlayerIndex(newActualPlayerIndex)
}
const setTurnPlayerIndexData = (newTurnPlayerIndex: number) =>{
setTurnPlayerIndex(newTurnPlayerIndex)
}
const setRoomData = (newRoom: string) =>{
setRoom(newRoom)
}
return (
<GameContext.Provider value={{ indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, nodeId, setNodeIdData, askedPersons, setAskedPersonsData, actualPlayerIndex, setActualPlayerIndexData, turnPlayerIndex, setTurnPlayerIndexData, room, setRoomData }}>
{children}
</GameContext.Provider>
);
};
export const useGame = (): GameContextProps => {
const context = useContext(GameContext);
if (!context) {
throw new Error('useGame must be used within an GameProvider');
}
return context;
};

@ -0,0 +1,83 @@
import AgeIndice from "./model/Indices/AgeIndice";
import ColorEdgesIndice from "./model/Indices/ColorEdgesIndice";
import ColorIndice from "./model/Indices/ColorIndice";
import Indice from "./model/Indices/Indice";
import NbEdgesIndice from "./model/Indices/NbEdgesIndice";
import NbSportIndice from "./model/Indices/NbSportIndice";
import SportIndice from "./model/Indices/SportIndice";
import Person from "./model/Person";
import PersonNetwork from "./model/PersonsNetwork";
class JSONParser{
static JSONToNetwork(jsonString: any): PersonNetwork{
const json = JSON.parse(jsonString)
const persons: Person[] = []
const personFriends = new Map<number, number[]>()
json.persons.forEach((personJson: any) => {
persons.push(JSONParser.JSONToPerson(personJson))
personJson.friends.forEach((f: any) => {
if (personFriends.get(personJson.id) == undefined){
personFriends.set(personJson.id, [f.id])
}
else{
personFriends.get(personJson.id)?.push(f.id)
}
});
});
for(const person of persons){
const tab = personFriends.get(person.getId())
if (tab != undefined){
for(const i of tab){
person.addFriend(persons.filter((p) => p.getId() == i)[0])
}
}
}
return new PersonNetwork(persons);
}
static JSONToPerson(json: any): Person {
const person = new Person(
json.id,
json.name,
json.age,
json.color,
json.sports,
[]
);
return person;
}
static JSONToIndice(json: any): Indice{
switch (json.type){
case "AgeIndice":
return new AgeIndice(json.id, json.minimum, json.maximum)
case "ColorEdgesIndice":
return new ColorEdgesIndice(json.id, json.neighborsColors)
case "ColorIndice":
return new ColorIndice(json.id, json.colors)
case "NbEdgesIndice":
return new NbEdgesIndice(json.id, json.nbNeighbors)
case "NbSportIndice":
return new NbSportIndice(json.id, json.nbSport)
case "SportIndice":
return new SportIndice(json.id, json.sports)
default:
throw new Error("PARSER unable to parse indice: " + json.type);
}
}
static JSONToIndices(jsonString: any): Indice[]{
const json = JSON.parse(jsonString)
const tabIndice: Indice[] = []
json.forEach((i: any) => {
tabIndice.push(this.JSONToIndice(i))
});
return tabIndice
}
}
export default JSONParser

@ -32,38 +32,27 @@ import { HiLanguage } from 'react-icons/hi2';
import { Nav, NavDropdown } from 'react-bootstrap';
import { FormattedMessage } from 'react-intl';
import Color from '../model/Color';
import TurnBar from '../Components/TurnBar';
import { useGame } from '../Contexts/GameContext';
//@ts-ignore
const InGame = ({locale, changeLocale}) => {
const players = [
{ state: Replay, name: 'Dummy' },
{ state: Replay, name: 'Boat' },
{ state: Replay, name: 'Bot-tom' },
{ state: Replay, name: 'Dummy' },
{ state: Replay, name: 'Boat' },
{ state: Replay, name: 'Bot-tom' },
{ state: Replay, name: 'Dummy' },
{ state: Replay, name: 'Boat' },
{ state: Replay, name: 'Bot-tom' },
{ state: Replay, name: 'Dummy' },
{ state: Replay, name: 'Boat' },
{ state: Replay, name: 'Bot-tom' },
{ state: Replay, name: 'Dummy' },
{ state: Replay, name: 'Boat' },
{ state: Replay, name: 'Bot-tom' }
// Ajouter d'autres joueurs au besoin
];
const theme = useTheme();
const [showChoiceBar, setShowChoiceBar] = useState(false);
const [showTurnBar, setShowTurnBar] = useState(false);
const handleNodeClick = (shouldShowChoiceBar: boolean) => {
setShowChoiceBar(shouldShowChoiceBar);
};
const handleShowTurnBar = (shouldShowTurnBar: boolean) => {
setShowTurnBar(shouldShowTurnBar);
};
/* offcanvas */
//? faire une fonction pour close et show en fonction de l'etat du canva ?
//? comment faire pour eviter la recopie de tout le code a chaque canvas boostrap ?
@ -114,18 +103,14 @@ const InGame = ({locale, changeLocale}) => {
const [SwitchEnabled, setSwitchEnabled] = useState(false)
const indices = Stub.GenerateIndice()
const { indice, players } = useGame();
return (
<div id="mainDiv">
<div className='upperInfo'
style={{
borderColor: theme.colors.secondary
}}>
{/* texte changeable et a traduire */}
<p>Dummy, à vous de jouer !</p>
</div>
{showTurnBar && <TurnBar/>}
<div id='graphDiv'>
<GraphContainer onNodeClick={handleNodeClick} />
<GraphContainer onNodeClick={handleNodeClick} handleShowTurnBar={handleShowTurnBar} />
</div>
<div className='playerlistDiv'>
@ -211,9 +196,7 @@ const InGame = ({locale, changeLocale}) => {
</Offcanvas.Header>
<Offcanvas.Body>
{/* Possède les cheveux noir <u>ou</u> joue au basket */}
{indices[0].ToString(locale)}<br/>
{indices[1].ToString(locale)}<br/>
{indices[2].ToString(locale)}
{indice?.ToString(locale)}
</Offcanvas.Body>
</Offcanvas>
@ -248,13 +231,14 @@ const InGame = ({locale, changeLocale}) => {
</Offcanvas.Body>
</Offcanvas>
<div id="bottom-container">
{showChoiceBar && <ChoiceBar />}
</div>
<div id="endgamebutton" > {/* tmp */}
{/*
<div id="endgamebutton" > {/* tmp
<ButtonImgNav dest="/endgame" img={Leave} text='endgame'/>
</div>
*/}
</div>
);
};

@ -1,5 +1,4 @@
.lobby-container {
display: flex;
background-color: #fff;

@ -1,23 +1,30 @@
import React from 'react';
import { useState } from 'react';
// import { useId } from 'react';
// import { v4 as uuidv4 } from 'uuid';
/* Style */
import React, { useEffect, useState } from 'react';
import './Lobby.css';
import { useTheme } from '../Style/ThemeContext';
/* res */
import Person from '../res/img/Person.png';
import PlayerItemList from '../Components/PlayerItemList'
import PersonImg from '../res/img/Person.png';
import Bot from '../res/img/bot.png';
import param from '../res/icon/param.png';
import cible from '../res/icon/cible.png';
/* Component */
import ButtonImgNav from '../Components/ButtonImgNav';
import PlayerItemList from '../Components/PlayerItemList'
import { io } from 'socket.io-client';
import { Link } from 'react-router-dom';
import PersonNetwork from '../model/PersonsNetwork';
import Person from '../model/Person';
import GameCreator from '../model/GameCreator';
import { useGame } from '../Contexts/GameContext';
import JSONParser from '../JSONParser';
import Indice from '../model/Indices/Indice';
import { useNavigate } from 'react-router-dom';
import { socket } from "../SocketConfig";
import { random } from 'lodash';
import Player from '../model/Player';
function Lobby() {
const theme=useTheme();
@ -35,6 +42,69 @@ function Lobby() {
players.push({ pdp: Bot, name: "BotAdded", id: players.length + 1 });
}
const navigate = useNavigate();
const { indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, setActualPlayerIndexData, setTurnPlayerIndexData, setRoomData } = useGame();
let first = true
const params = new URLSearchParams(window.location.search);
const room = params.get('room');
useEffect(() => {
if (first){
first = false
socket.emit("lobby joined", room, "test name" + Math.floor(Math.random() * 10))
return () => {
socket.off('game created');
};
}
}, []);
socket.on("game created", (jsonNetwork, jsonPersonString, jsonIndicesString, playerIndex)=> {
const jsonPerson = JSON.parse(jsonPersonString)
const network: PersonNetwork = JSONParser.JSONToNetwork(jsonNetwork)
const choosenOne: Person = network.getPersons().filter((i) => i.getId() == jsonPerson.id)[0]
const choosenIndices : Indice[] = JSONParser.JSONToIndices(jsonIndicesString)
let index = 0
for (let i=0; i<players.length; i++){
if(players[i].id == socket.id){
index=i
break
}
}
if (room != null){
setRoomData(room)
}
setTurnPlayerIndexData(playerIndex)
setActualPlayerIndexData(index)
setIndiceData(choosenIndices[index])
setPersonData(choosenOne)
setPersonNetworkData(network)
setIndicesData(choosenIndices)
first = true
navigate('/game');
});
socket.on("new player", (tab) =>{
const tmpTab: Player[] = []
for (const p of tab){
tmpTab.push(new Player(p.id, p.name))
}
setPlayersData(tab.map((p: any) => new Player(p.id, p.name)))
})
function StartGame(){
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(players.length, 30)
setPersonData(choosenPerson)
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
socket.emit('network created', JSON.stringify(networkPerson, null, 2), JSON.stringify(choosenPerson), JSON.stringify(choosenIndices), room);
}
return (
<div className='lobby-container'>
<div className='left-part'>
@ -49,9 +119,9 @@ function Lobby() {
}
</div>
{/* //! voir pour la gestion avec un liste, utilisateur avec le "+ (vous)" et les pdp avec les lettres grecs (?)*/}
{players.map((player) => (
<PlayerItemList key={player.id} pdp={player.pdp} name={player.name} id={player.id} />
))}
<PlayerItemList pdp={Person} name="Dummy (vous)"/>
<PlayerItemList pdp={Bot} name="Boat"/>
<PlayerItemList pdp={Bot} name="Bot-tom"/>
</div>
</div>
@ -74,12 +144,24 @@ function Lobby() {
//? indice avancé ? ==> négation, voisin du 2e degré etc.
}
</ul>
<center>
<ButtonImgNav dest='/game' img={cible} text=' À la chasse !'/> {/* page de baptiste ici */}
<center >
<button className='buttonNabImg' onClick={StartGame}>
<img src={cible} alt="Button Image" height="50" width="50"/>
<p>{"la chasse !"}</p>
</button>
</center>
</div>
</div>
);
function shuffleArray(array: Indice[]) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
export default Lobby;

@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
/* Style */
import './Play.css';
@ -17,10 +17,46 @@ import Person from '../res/img/Person.png';
import trophy from '../res/icon/trophy.png';
import param from '../res/icon/param.png';
import share from '../res/icon/share.png';
import { socket } from '../SocketConfig';
import { useNavigate } from 'react-router-dom';
function Play() {
const theme=useTheme()
const [room, setRoom] = useState(null);
const navigate = useNavigate();
function createLobby(){
socket.emit("lobby created")
}
useEffect(() => {
const handleLobbyCreated = (newRoom: any) => {
setRoom(newRoom);
};
// Ajouter l'event listener
socket.on('lobby created', handleLobbyCreated);
// Nettoyer l'event listener lors du démontage du composant
return () => {
socket.off('lobby created', handleLobbyCreated);
};
}, []); // Aucune dépendance ici
useEffect(() => {
if (room !== null) {
const nouvelleURL = `/lobby?room=${room}`;
navigate(nouvelleURL);
}
}, [room, navigate]);
return (
<div className="MainContainer">
@ -42,12 +78,10 @@ function Play() {
/>
</div>
<div className='buttonGroupVertical'>
<Link to="/lobby">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Jouer seul </button>
</Link>
<Link to="/">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Créer une partie </button>
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Jouer seul </button>
</Link>
<button onClick={createLobby} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Créer une partie </button>
<Link to="/">
<button className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Rejoindre </button>
</Link>

@ -0,0 +1,6 @@
import { io } from "socket.io-client";
const socket = io("http://localhost:3002");
export {socket}

@ -42,7 +42,7 @@
"and": "and",
"or": "or",
"or_sport": "or",
"or_sport": "and/or",
"age_indice_start": "The suspect is between",

@ -42,7 +42,7 @@
"and": "et",
"or": "ou",
"or_sport": "ou du",
"or_sport": "et/ou du",
"age_indice_start": "Le suspect a entre",
"age_indice_more_start": "Le suspect a ou a plus de",

@ -10,7 +10,7 @@ import PersonNetwork from "./PersonsNetwork";
import Stub from "./Stub";
class GameCreator{
static CreateGame(nbPlayers: number, nbNodes: number): [PersonNetwork, Person, Indice[], GraphPerson]{
static CreateGame(nbPlayers: number, nbNodes: number): [PersonNetwork, Person, Indice[]]{
const edgesCreator = new EdgesCreator()
const chooser = new IndiceChooser()
@ -26,9 +26,7 @@ class GameCreator{
edgesCreator.CreateAllEdges(networkPerson, person, choosenIndices)
const graph = GraphCreator.CreateGraph(networkPerson)
return [networkPerson, person, choosenIndices, graph]
return [networkPerson, person, choosenIndices]
}
}

@ -28,6 +28,15 @@ class AgeIndice extends Indice {
getMaximum(): number{
return this.maximum
}
toJSON() {
return {
type: "AgeIndice",
id: this.id,
minimum: this.minimum,
maximum: this.maximum
};
}
}
export default AgeIndice

@ -29,6 +29,14 @@ class ColorEdgesIndice extends EdgesIndice {
}
return `${string} ${json.color_edges_end}`
}
toJSON() {
return {
type: "ColorEdgesIndice",
id: this.id,
neighborsColors: this.neighborsColors,
};
}
}
export default ColorEdgesIndice

@ -28,6 +28,15 @@ class ColorIndice extends Indice {
getColors(): Color[]{
return this.colors
}
toJSON() {
return {
type: "ColorIndice",
id: this.id,
colors: this.colors,
};
}
}
export default ColorIndice

@ -17,7 +17,8 @@ abstract class Indice {
// Méthode abstraite pour être implémentée par les classes dérivées
abstract ToString(lang: string): string;
abstract toJSON(): any
}
export default Indice

@ -18,6 +18,14 @@ class NbEdgesIndice extends EdgesIndice {
let json = GetJsonFile(lang)
return `${json.nb_friends_indice_start} ${this.nbNeighbors} ${json.nb_friends_indice_end}`;
}
toJSON() {
return {
type: "NbEdgesIndice",
id: this.id,
nbNeighbors: this.nbNeighbors,
};
}
}
export default NbEdgesIndice

@ -18,6 +18,14 @@ class NbSportIndice extends Indice {
let json = GetJsonFile(lang)
return `${json.nb_sports_indice_start} ${this.nbSport} ${json.nb_sports_indice_end}`;
}
toJSON() {
return {
type: "NbSportIndice",
id: this.id,
nbSport: this.nbSport,
};
}
}
export default NbSportIndice

@ -29,6 +29,14 @@ class SportIndice extends Indice {
getSports(): Sport[]{
return this.sports
}
toJSON() {
return {
type: "SportIndice",
id: this.id,
sports: this.sports,
};
}
}
export default SportIndice

@ -78,6 +78,24 @@ class Person {
setFriends(friends: Person[]): void {
this.friends = friends;
}
toJSON() {
return {
id: this.id,
name: this.name,
age: this.age,
color: this.color,
sports: this.sports,
friends: this.friends.map(friend => ({
id: friend.id,
name: friend.name,
age: friend.age,
color: friend.color,
sports: friend.sports,
// Ne pas inclure friends ici pour éviter la boucle infinie
}))
};
}
}
export default Person

@ -0,0 +1,12 @@
class Player{
public id: string
public name: string;
constructor(id: string, name: string){
this.id=id
this.name=name
}
}
export default Player

@ -1869,6 +1869,11 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@socket.io/component-emitter@~3.1.0":
version "3.1.0"
resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz"
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
"@surma/rollup-plugin-off-main-thread@^2.2.3":
version "2.2.3"
resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz"
@ -2126,6 +2131,18 @@
dependencies:
"@types/node" "*"
"@types/cookie@^0.4.1":
version "0.4.1"
resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz"
integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
"@types/cors@^2.8.12":
version "2.8.16"
resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.16.tgz"
integrity sha512-Trx5or1Nyg1Fq138PCuWqoApzvoSLWzZ25ORBiHMbbUT42g578lH1GT4TwYDbiUOLFuDsCkfLneT2105fsFWGg==
dependencies:
"@types/node" "*"
"@types/eslint-scope@^3.7.3":
version "3.7.7"
resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz"
@ -2263,7 +2280,7 @@
dependencies:
"@types/node" "*"
"@types/node@*":
"@types/node@*", "@types/node@>=10.0.0":
version "20.8.10"
resolved "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz"
integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==
@ -3168,6 +3185,11 @@ balanced-match@^1.0.0:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64id@~2.0.0, base64id@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz"
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
batch@0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz"
@ -3630,6 +3652,11 @@ cookie-signature@1.0.6:
resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@~0.4.1:
version "0.4.2"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
@ -3657,6 +3684,14 @@ core-util-is@~1.0.0:
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cors@^2.8.5, cors@~2.8.5:
version "2.8.5"
resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
dependencies:
object-assign "^4"
vary "^1"
cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz"
@ -3924,7 +3959,7 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4:
debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -4256,6 +4291,38 @@ encodeurl@~1.0.2:
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
engine.io-client@~6.5.2:
version "6.5.3"
resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz"
integrity sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
engine.io-parser "~5.2.1"
ws "~8.11.0"
xmlhttprequest-ssl "~2.0.0"
engine.io-parser@~5.2.1:
version "5.2.1"
resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz"
integrity sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==
engine.io@~6.5.2:
version "6.5.4"
resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz"
integrity sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==
dependencies:
"@types/cookie" "^0.4.1"
"@types/cors" "^2.8.12"
"@types/node" ">=10.0.0"
accepts "~1.3.4"
base64id "2.0.0"
cookie "~0.4.1"
cors "~2.8.5"
debug "~4.3.1"
engine.io-parser "~5.2.1"
ws "~8.11.0"
enhanced-resolve@^5.15.0:
version "5.15.0"
resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz"
@ -4779,7 +4846,7 @@ expect@^29.0.0:
jest-message-util "^29.7.0"
jest-util "^29.7.0"
express@^4.17.3:
express@^4.17.3, express@^4.18.2:
version "4.18.2"
resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@ -7022,7 +7089,7 @@ nwsapi@^2.2.0:
resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz"
integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==
object-assign@^4.0.1, object-assign@^4.1.1:
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@ -8825,6 +8892,44 @@ slash@^4.0.0:
resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz"
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
socket.io-adapter@~2.5.2:
version "2.5.2"
resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz"
integrity sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==
dependencies:
ws "~8.11.0"
socket.io-client@^4.7.2:
version "4.7.2"
resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz"
integrity sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.2"
engine.io-client "~6.5.2"
socket.io-parser "~4.2.4"
socket.io-parser@~4.2.4:
version "4.2.4"
resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz"
integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
socket.io@^4.7.2:
version "4.7.2"
resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz"
integrity sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==
dependencies:
accepts "~1.3.4"
base64id "~2.0.0"
cors "~2.8.5"
debug "~4.3.2"
engine.io "~6.5.2"
socket.io-adapter "~2.5.2"
socket.io-parser "~4.2.4"
sockjs@^0.3.24:
version "0.3.24"
resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz"
@ -9663,7 +9768,7 @@ v8-to-istanbul@^8.1.0:
convert-source-map "^1.6.0"
source-map "^0.7.3"
vary@~1.1.2:
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
@ -10173,6 +10278,11 @@ ws@^8.13.0:
resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz"
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
ws@~8.11.0:
version "8.11.0"
resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz"
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz"
@ -10183,6 +10293,11 @@ xmlchars@^2.2.0:
resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xmlhttprequest-ssl@~2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz"
integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"

Loading…
Cancel
Save