Completed matches scheduling
This commit is contained in:
205
index.js
205
index.js
@@ -19,24 +19,11 @@ const PORT = process.env.PORT || 4000;
|
|||||||
|
|
||||||
const JWT_SECRET = process.env.JWT_SECRET || 'changeme';
|
const JWT_SECRET = process.env.JWT_SECRET || 'changeme';
|
||||||
|
|
||||||
// Serve static files from the React build
|
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
app.get('/api/health', (req, res) => {
|
app.get('/api/health', (req, res) => {
|
||||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve React app for all non-API routes
|
|
||||||
app.get('*', (req, res) => {
|
|
||||||
// Don't serve React app for API routes
|
|
||||||
if (req.path.startsWith('/api/')) {
|
|
||||||
return res.status(404).json({ error: 'API endpoint not found' });
|
|
||||||
}
|
|
||||||
|
|
||||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Player registration
|
// Player registration
|
||||||
app.post('/api/players', async (req, res) => {
|
app.post('/api/players', async (req, res) => {
|
||||||
const { name, email } = req.body;
|
const { name, email } = req.body;
|
||||||
@@ -204,6 +191,177 @@ function generateRoundRobinPairs(teams) {
|
|||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to reorder matches so no team plays two games consecutively
|
||||||
|
function reorderMatchesNoConsecutiveGames(pairs) {
|
||||||
|
const result = [];
|
||||||
|
const used = new Array(pairs.length).fill(false);
|
||||||
|
let lastTeams = new Set();
|
||||||
|
for (let i = 0; i < pairs.length; i++) {
|
||||||
|
let found = false;
|
||||||
|
for (let j = 0; j < pairs.length; j++) {
|
||||||
|
if (used[j]) continue;
|
||||||
|
const [a, b] = pairs[j];
|
||||||
|
if (!lastTeams.has(a.id) && !lastTeams.has(b.id)) {
|
||||||
|
result.push(pairs[j]);
|
||||||
|
used[j] = true;
|
||||||
|
lastTeams = new Set([a.id, b.id]);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// If not possible, just pick the next unused
|
||||||
|
for (let j = 0; j < pairs.length; j++) {
|
||||||
|
if (!used[j]) {
|
||||||
|
result.push(pairs[j]);
|
||||||
|
used[j] = true;
|
||||||
|
lastTeams = new Set([pairs[j][0].id, pairs[j][1].id]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Robust round robin scheduler (circle method)
|
||||||
|
function generateRoundRobinSchedule(pool) {
|
||||||
|
const teams = [...pool];
|
||||||
|
const n = teams.length;
|
||||||
|
const rounds = [];
|
||||||
|
// If odd, add a dummy team (bye)
|
||||||
|
let isOdd = false;
|
||||||
|
if (n % 2 === 1) {
|
||||||
|
teams.push({ id: -1, name: 'BYE' });
|
||||||
|
isOdd = true;
|
||||||
|
}
|
||||||
|
const numRounds = teams.length - 1;
|
||||||
|
const half = teams.length / 2;
|
||||||
|
for (let round = 0; round < numRounds; round++) {
|
||||||
|
const matches = [];
|
||||||
|
for (let i = 0; i < half; i++) {
|
||||||
|
const t1 = teams[i];
|
||||||
|
const t2 = teams[teams.length - 1 - i];
|
||||||
|
if (t1.id !== -1 && t2.id !== -1) {
|
||||||
|
matches.push([t1, t2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rounds.push(matches);
|
||||||
|
// Rotate teams (except the first)
|
||||||
|
teams.splice(1, 0, teams.pop());
|
||||||
|
}
|
||||||
|
return rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interleave matches from rounds to avoid consecutive games for any team
|
||||||
|
function interleaveRounds(rounds) {
|
||||||
|
const interleaved = [];
|
||||||
|
const maxLen = Math.max(...rounds.map(r => r.length));
|
||||||
|
for (let i = 0; i < maxLen; i++) {
|
||||||
|
for (let j = 0; j < rounds.length; j++) {
|
||||||
|
if (rounds[j][i]) {
|
||||||
|
interleaved.push(rounds[j][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return interleaved;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple and working match ordering
|
||||||
|
function orderMatchesNoConsecutiveGames(pairs) {
|
||||||
|
console.log("orderMatchesNoConsecutiveGames called with", pairs.length, "pairs");
|
||||||
|
|
||||||
|
const n = pairs.length;
|
||||||
|
const result = [];
|
||||||
|
const used = new Array(n).fill(false);
|
||||||
|
|
||||||
|
// Keep track of teams that played in the last match
|
||||||
|
let lastMatchTeams = new Set();
|
||||||
|
|
||||||
|
// Simple approach: always pick a match where neither team played in the last match
|
||||||
|
while (result.length < n) {
|
||||||
|
let foundGoodMatch = false;
|
||||||
|
|
||||||
|
// First pass: look for matches with no consecutive games
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
const [team1, team2] = pairs[i];
|
||||||
|
|
||||||
|
// Check if either team played in the last match
|
||||||
|
if (lastMatchTeams.has(team1.id) || lastMatchTeams.has(team2.id)) {
|
||||||
|
continue; // Skip this match
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found a good match
|
||||||
|
used[i] = true;
|
||||||
|
result.push(pairs[i]);
|
||||||
|
lastMatchTeams = new Set([team1.id, team2.id]);
|
||||||
|
foundGoodMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no good match found, pick any available match
|
||||||
|
if (!foundGoodMatch) {
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
used[i] = true;
|
||||||
|
result.push(pairs[i]);
|
||||||
|
const [team1, team2] = pairs[i];
|
||||||
|
lastMatchTeams = new Set([team1.id, team2.id]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("orderMatchesNoConsecutiveGames returning", result.length, "matches");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple greedy ordering for other cases
|
||||||
|
function simpleGreedyOrder(pairs) {
|
||||||
|
const n = pairs.length;
|
||||||
|
const result = [];
|
||||||
|
const used = new Array(n).fill(false);
|
||||||
|
let lastMatchTeams = new Set();
|
||||||
|
|
||||||
|
while (result.length < n) {
|
||||||
|
let foundGoodMatch = false;
|
||||||
|
|
||||||
|
// Look for matches with no consecutive games
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
const [team1, team2] = pairs[i];
|
||||||
|
if (lastMatchTeams.has(team1.id) || lastMatchTeams.has(team2.id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
used[i] = true;
|
||||||
|
result.push(pairs[i]);
|
||||||
|
lastMatchTeams = new Set([team1.id, team2.id]);
|
||||||
|
foundGoodMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no good match found, pick any available match
|
||||||
|
if (!foundGoodMatch) {
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
used[i] = true;
|
||||||
|
result.push(pairs[i]);
|
||||||
|
const [team1, team2] = pairs[i];
|
||||||
|
lastMatchTeams = new Set([team1.id, team2.id]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Admin: Schedule round robin matches (teams)
|
// Admin: Schedule round robin matches (teams)
|
||||||
app.post('/api/admin/schedule/roundrobin', requireAdmin, async (req, res) => {
|
app.post('/api/admin/schedule/roundrobin', requireAdmin, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
@@ -264,8 +422,10 @@ app.post('/api/admin/schedule/roundrobin', requireAdmin, async (req, res) => {
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
let matchesData = [];
|
let matchesData = [];
|
||||||
pools.forEach((pool, poolIdx) => {
|
pools.forEach((pool, poolIdx) => {
|
||||||
const pairs = generateRoundRobinPairs(pool);
|
const rounds = generateRoundRobinSchedule(pool);
|
||||||
matchesData.push(...pairs.map(([t1, t2]) => ({
|
const pairs = rounds.flat();
|
||||||
|
const orderedMatches = orderMatchesNoConsecutiveGames(pairs);
|
||||||
|
matchesData.push(...orderedMatches.map(([t1, t2]) => ({
|
||||||
stageId: stage.id,
|
stageId: stage.id,
|
||||||
team1Id: t1.id,
|
team1Id: t1.id,
|
||||||
team2Id: t2.id,
|
team2Id: t2.id,
|
||||||
@@ -807,8 +967,10 @@ async function createPoolsAutomatically() {
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
let matchesData = [];
|
let matchesData = [];
|
||||||
pools.forEach((pool, poolIdx) => {
|
pools.forEach((pool, poolIdx) => {
|
||||||
const pairs = generateRoundRobinPairs(pool);
|
const rounds = generateRoundRobinSchedule(pool);
|
||||||
matchesData.push(...pairs.map(([t1, t2]) => ({
|
const pairs = rounds.flat();
|
||||||
|
const orderedMatches = orderMatchesNoConsecutiveGames(pairs);
|
||||||
|
matchesData.push(...orderedMatches.map(([t1, t2]) => ({
|
||||||
stageId: stage.id,
|
stageId: stage.id,
|
||||||
team1Id: t1.id,
|
team1Id: t1.id,
|
||||||
team2Id: t2.id,
|
team2Id: t2.id,
|
||||||
@@ -1081,6 +1243,15 @@ app.post('/api/admin/reset-tournament', requireAdmin, async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
app.get('/*', (req, res) => {
|
||||||
|
// Don't serve React app for API routes
|
||||||
|
if (req.path.startsWith('/api/')) {
|
||||||
|
return res.status(404).json({ error: 'API endpoint not found' });
|
||||||
|
}
|
||||||
|
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||||
|
});
|
||||||
|
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
const io = new Server(server, { cors: { origin: '*' } });
|
const io = new Server(server, { cors: { origin: '*' } });
|
||||||
|
|
||||||
|
|||||||
550
package-lock.json
generated
550
package-lock.json
generated
@@ -13,7 +13,7 @@
|
|||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.0",
|
"dotenv": "^17.2.0",
|
||||||
"express": "^5.1.0",
|
"express": "^4.21.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"jspdf-autotable": "^5.0.2",
|
"jspdf-autotable": "^5.0.2",
|
||||||
"multer": "^2.0.1",
|
"multer": "^2.0.1",
|
||||||
@@ -153,13 +153,13 @@
|
|||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "2.0.0",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-types": "^3.0.0",
|
"mime-types": "~2.1.34",
|
||||||
"negotiator": "^1.0.0"
|
"negotiator": "0.6.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -171,6 +171,12 @@
|
|||||||
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/atob": {
|
"node_modules/atob": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
@@ -214,23 +220,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "2.2.0",
|
"version": "1.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||||
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "^3.1.2",
|
"bytes": "3.1.2",
|
||||||
"content-type": "^1.0.5",
|
"content-type": "~1.0.5",
|
||||||
"debug": "^4.4.0",
|
"debug": "2.6.9",
|
||||||
"http-errors": "^2.0.0",
|
"depd": "2.0.0",
|
||||||
"iconv-lite": "^0.6.3",
|
"destroy": "1.2.0",
|
||||||
"on-finished": "^2.4.1",
|
"http-errors": "2.0.0",
|
||||||
"qs": "^6.14.0",
|
"iconv-lite": "0.4.24",
|
||||||
"raw-body": "^3.0.0",
|
"on-finished": "2.4.1",
|
||||||
"type-is": "^2.0.0"
|
"qs": "6.13.0",
|
||||||
|
"raw-body": "2.5.2",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/btoa": {
|
"node_modules/btoa": {
|
||||||
@@ -344,9 +354,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "1.0.0",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
"integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
|
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "5.2.1"
|
"safe-buffer": "5.2.1"
|
||||||
@@ -374,13 +384,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cookie-signature": {
|
"node_modules/cookie-signature": {
|
||||||
"version": "1.2.2",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"engines": {
|
|
||||||
"node": ">=6.6.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/core-js": {
|
"node_modules/core-js": {
|
||||||
"version": "3.44.0",
|
"version": "3.44.0",
|
||||||
@@ -420,22 +427,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.1",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "^2.1.3"
|
"ms": "2.0.0"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"supports-color": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/debug/node_modules/ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
@@ -445,6 +450,16 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/destroy": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "3.2.6",
|
"version": "3.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
|
||||||
@@ -535,19 +550,6 @@
|
|||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io/node_modules/accepts": {
|
|
||||||
"version": "1.3.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
||||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-types": "~2.1.34",
|
|
||||||
"negotiator": "0.6.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/engine.io/node_modules/debug": {
|
"node_modules/engine.io/node_modules/debug": {
|
||||||
"version": "4.3.7",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
@@ -565,36 +567,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io/node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/engine.io/node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/engine.io/node_modules/negotiator": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
@@ -641,47 +613,60 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "5.1.0",
|
"version": "4.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||||
"integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
|
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "^2.0.0",
|
"accepts": "~1.3.8",
|
||||||
"body-parser": "^2.2.0",
|
"array-flatten": "1.1.1",
|
||||||
"content-disposition": "^1.0.0",
|
"body-parser": "1.20.3",
|
||||||
"content-type": "^1.0.5",
|
"content-disposition": "0.5.4",
|
||||||
"cookie": "^0.7.1",
|
"content-type": "~1.0.4",
|
||||||
"cookie-signature": "^1.2.1",
|
"cookie": "0.7.1",
|
||||||
"debug": "^4.4.0",
|
"cookie-signature": "1.0.6",
|
||||||
"encodeurl": "^2.0.0",
|
"debug": "2.6.9",
|
||||||
"escape-html": "^1.0.3",
|
"depd": "2.0.0",
|
||||||
"etag": "^1.8.1",
|
"encodeurl": "~2.0.0",
|
||||||
"finalhandler": "^2.1.0",
|
"escape-html": "~1.0.3",
|
||||||
"fresh": "^2.0.0",
|
"etag": "~1.8.1",
|
||||||
"http-errors": "^2.0.0",
|
"finalhandler": "1.3.1",
|
||||||
"merge-descriptors": "^2.0.0",
|
"fresh": "0.5.2",
|
||||||
"mime-types": "^3.0.0",
|
"http-errors": "2.0.0",
|
||||||
"on-finished": "^2.4.1",
|
"merge-descriptors": "1.0.3",
|
||||||
"once": "^1.4.0",
|
"methods": "~1.1.2",
|
||||||
"parseurl": "^1.3.3",
|
"on-finished": "2.4.1",
|
||||||
"proxy-addr": "^2.0.7",
|
"parseurl": "~1.3.3",
|
||||||
"qs": "^6.14.0",
|
"path-to-regexp": "0.1.12",
|
||||||
"range-parser": "^1.2.1",
|
"proxy-addr": "~2.0.7",
|
||||||
"router": "^2.2.0",
|
"qs": "6.13.0",
|
||||||
"send": "^1.1.0",
|
"range-parser": "~1.2.1",
|
||||||
"serve-static": "^2.2.0",
|
"safe-buffer": "5.2.1",
|
||||||
"statuses": "^2.0.1",
|
"send": "0.19.0",
|
||||||
"type-is": "^2.0.1",
|
"serve-static": "1.16.2",
|
||||||
"vary": "^1.1.2"
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 0.10.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express/node_modules/cookie": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fflate": {
|
"node_modules/fflate": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||||
@@ -690,17 +675,18 @@
|
|||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "2.1.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||||
"integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
|
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.4.0",
|
"debug": "2.6.9",
|
||||||
"encodeurl": "^2.0.0",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"on-finished": "^2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "^1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"statuses": "^2.0.1"
|
"statuses": "2.0.1",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
@@ -716,12 +702,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fresh": {
|
"node_modules/fresh": {
|
||||||
"version": "2.0.0",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
@@ -837,22 +823,13 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/http-errors/node_modules/statuses": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.6.3",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@@ -873,12 +850,6 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-promise": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/jiti": {
|
"node_modules/jiti": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
||||||
@@ -1011,42 +982,60 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "1.1.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "2.0.0",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||||
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mime-db": {
|
"node_modules/mime-db": {
|
||||||
"version": "1.54.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mime-types": {
|
"node_modules/mime-types": {
|
||||||
"version": "3.0.1",
|
"version": "2.1.35",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-db": "^1.54.0"
|
"mime-db": "1.52.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -1097,53 +1086,10 @@
|
|||||||
"node": ">= 10.16.0"
|
"node": ">= 10.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/multer/node_modules/media-typer": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/multer/node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/multer/node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/multer/node_modules/type-is": {
|
|
||||||
"version": "1.6.18",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
|
||||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"media-typer": "0.3.0",
|
|
||||||
"mime-types": "~2.1.24"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/negotiator": {
|
"node_modules/negotiator": {
|
||||||
"version": "1.0.0",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -1203,15 +1149,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parseurl": {
|
"node_modules/parseurl": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
@@ -1222,13 +1159,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "8.2.0",
|
"version": "0.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||||
"integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
|
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/performance-now": {
|
"node_modules/performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -1405,12 +1339,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.1.0"
|
"side-channel": "^1.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
@@ -1440,14 +1374,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/raw-body": {
|
"node_modules/raw-body": {
|
||||||
"version": "3.0.0",
|
"version": "2.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||||
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
|
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "3.1.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"iconv-lite": "0.6.3",
|
"iconv-lite": "0.4.24",
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1487,22 +1421,6 @@
|
|||||||
"node": ">= 0.8.15"
|
"node": ">= 0.8.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/router": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"debug": "^4.4.0",
|
|
||||||
"depd": "^2.0.0",
|
|
||||||
"is-promise": "^4.0.0",
|
|
||||||
"parseurl": "^1.3.3",
|
|
||||||
"path-to-regexp": "^8.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
@@ -1542,40 +1460,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "1.2.0",
|
"version": "0.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||||
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.5",
|
"debug": "2.6.9",
|
||||||
"encodeurl": "^2.0.0",
|
"depd": "2.0.0",
|
||||||
"escape-html": "^1.0.3",
|
"destroy": "1.2.0",
|
||||||
"etag": "^1.8.1",
|
"encodeurl": "~1.0.2",
|
||||||
"fresh": "^2.0.0",
|
"escape-html": "~1.0.3",
|
||||||
"http-errors": "^2.0.0",
|
"etag": "~1.8.1",
|
||||||
"mime-types": "^3.0.1",
|
"fresh": "0.5.2",
|
||||||
"ms": "^2.1.3",
|
"http-errors": "2.0.0",
|
||||||
"on-finished": "^2.4.1",
|
"mime": "1.6.0",
|
||||||
"range-parser": "^1.2.1",
|
"ms": "2.1.3",
|
||||||
"statuses": "^2.0.1"
|
"on-finished": "2.4.1",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"statuses": "2.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/serve-static": {
|
"node_modules/serve-static": {
|
||||||
"version": "2.2.0",
|
"version": "1.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||||
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"encodeurl": "^2.0.0",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"parseurl": "^1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"send": "^1.2.0"
|
"send": "0.19.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/setprototypeof": {
|
"node_modules/setprototypeof": {
|
||||||
@@ -1731,19 +1660,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/socket.io/node_modules/accepts": {
|
|
||||||
"version": "1.3.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
|
||||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-types": "~2.1.34",
|
|
||||||
"negotiator": "0.6.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/socket.io/node_modules/debug": {
|
"node_modules/socket.io/node_modules/debug": {
|
||||||
"version": "4.3.7",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
@@ -1761,36 +1677,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/socket.io/node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/socket.io/node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/socket.io/node_modules/negotiator": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/split2": {
|
"node_modules/split2": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
@@ -1812,9 +1698,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
@@ -1876,14 +1762,13 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "2.0.1",
|
"version": "1.6.18",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"content-type": "^1.0.5",
|
"media-typer": "0.3.0",
|
||||||
"media-typer": "^1.1.0",
|
"mime-types": "~2.1.24"
|
||||||
"mime-types": "^3.0.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -1916,6 +1801,15 @@
|
|||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/utrie": {
|
"node_modules/utrie": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||||
@@ -1960,12 +1854,6 @@
|
|||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.17.1",
|
"version": "8.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.0",
|
"dotenv": "^17.2.0",
|
||||||
"express": "^5.1.0",
|
"express": "^4.21.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"jspdf-autotable": "^5.0.2",
|
"jspdf-autotable": "^5.0.2",
|
||||||
"multer": "^2.0.1",
|
"multer": "^2.0.1",
|
||||||
|
|||||||
26
scripts/clearRoundRobin.js
Normal file
26
scripts/clearRoundRobin.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const { PrismaClient } = require('../generated/prisma');
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
// Find the round robin stage(s)
|
||||||
|
const rrStages = await prisma.tournamentStage.findMany({ where: { type: 'ROUND_ROBIN' } });
|
||||||
|
const rrStageIds = rrStages.map(s => s.id);
|
||||||
|
if (rrStageIds.length === 0) {
|
||||||
|
console.log('No round robin stage found.');
|
||||||
|
await prisma.$disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Find all matches for these stages
|
||||||
|
const rrMatches = await prisma.match.findMany({ where: { stageId: { in: rrStageIds } } });
|
||||||
|
const rrMatchIds = rrMatches.map(m => m.id);
|
||||||
|
// Delete results for these matches
|
||||||
|
await prisma.result.deleteMany({ where: { matchId: { in: rrMatchIds } } });
|
||||||
|
// Delete matches
|
||||||
|
await prisma.match.deleteMany({ where: { id: { in: rrMatchIds } } });
|
||||||
|
// Delete the round robin stages
|
||||||
|
await prisma.tournamentStage.deleteMany({ where: { id: { in: rrStageIds } } });
|
||||||
|
console.log(`Deleted ${rrStages.length} round robin stage(s), ${rrMatches.length} matches, and their results.`);
|
||||||
|
await prisma.$disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(e => { console.error(e); process.exit(1); });
|
||||||
@@ -58,7 +58,7 @@ async function resetTournament() {
|
|||||||
console.log('🏆 Creating new tournament...');
|
console.log('🏆 Creating new tournament...');
|
||||||
const tournament = await prisma.tournament.create({
|
const tournament = await prisma.tournament.create({
|
||||||
data: {
|
data: {
|
||||||
name: 'Championship Tournament',
|
name: 'Spring Championship 2024',
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
location: 'Main Arena'
|
location: 'Main Arena'
|
||||||
}
|
}
|
||||||
|
|||||||
74
scripts/testSchedule.js
Normal file
74
scripts/testSchedule.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
async function testSchedule() {
|
||||||
|
try {
|
||||||
|
console.log('Testing current round robin schedule...\n');
|
||||||
|
|
||||||
|
// Get all matches
|
||||||
|
const matchesRes = await fetch('http://localhost:4000/api/matches');
|
||||||
|
const matches = await matchesRes.json();
|
||||||
|
|
||||||
|
if (!Array.isArray(matches)) {
|
||||||
|
console.log('Failed to fetch matches:', matches);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter round robin matches
|
||||||
|
const roundRobinMatches = matches.filter(match => match.stage.type === 'ROUND_ROBIN');
|
||||||
|
|
||||||
|
if (roundRobinMatches.length === 0) {
|
||||||
|
console.log('No round robin matches found.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group matches by pool
|
||||||
|
const pools = {};
|
||||||
|
roundRobinMatches.forEach(match => {
|
||||||
|
if (!pools[match.pool]) {
|
||||||
|
pools[match.pool] = [];
|
||||||
|
}
|
||||||
|
pools[match.pool].push(match);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check each pool for consecutive games
|
||||||
|
Object.keys(pools).forEach(poolNum => {
|
||||||
|
console.log(`\n=== Pool ${poolNum} ===`);
|
||||||
|
const poolMatches = pools[poolNum];
|
||||||
|
|
||||||
|
let consecutiveGames = 0;
|
||||||
|
|
||||||
|
poolMatches.forEach((match, index) => {
|
||||||
|
const team1Id = match.team1.id;
|
||||||
|
const team2Id = match.team2.id;
|
||||||
|
|
||||||
|
console.log(`Match ${index + 1}: ${match.team1.name} vs ${match.team2.name}`);
|
||||||
|
|
||||||
|
// Check if either team played in the previous match
|
||||||
|
if (index > 0) {
|
||||||
|
const prevMatch = poolMatches[index - 1];
|
||||||
|
const prevTeams = [prevMatch.team1.id, prevMatch.team2.id];
|
||||||
|
|
||||||
|
if (prevTeams.includes(team1Id)) {
|
||||||
|
console.log(` ⚠️ ${match.team1.name} played in previous match!`);
|
||||||
|
consecutiveGames++;
|
||||||
|
}
|
||||||
|
if (prevTeams.includes(team2Id)) {
|
||||||
|
console.log(` ⚠️ ${match.team2.name} played in previous match!`);
|
||||||
|
consecutiveGames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\nPool ${poolNum} consecutive games: ${consecutiveGames}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('\n=== Summary ===');
|
||||||
|
console.log(`Total round robin matches: ${roundRobinMatches.length}`);
|
||||||
|
console.log(`Total pools: ${Object.keys(pools).length}`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error testing schedule:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testSchedule();
|
||||||
@@ -57,11 +57,22 @@ function App() {
|
|||||||
setLoadingTournaments(true);
|
setLoadingTournaments(true);
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/tournaments');
|
const res = await fetch('/api/tournaments');
|
||||||
if (res.ok) {
|
const data = await res.json();
|
||||||
const data = await res.json();
|
if (Array.isArray(data)) {
|
||||||
setTournaments(data);
|
setTournaments(data);
|
||||||
|
// Automatically select the most recent tournament if none is selected
|
||||||
|
const storedName = localStorage.getItem('tournamentName');
|
||||||
|
if ((!storedName || storedName === '') && data.length > 0) {
|
||||||
|
setTournamentName(data[0].name);
|
||||||
|
setTournamentDate(data[0].date);
|
||||||
|
setTournamentLocation(data[0].location);
|
||||||
|
localStorage.setItem('tournamentName', data[0].name);
|
||||||
|
localStorage.setItem('tournamentDate', data[0].date);
|
||||||
|
localStorage.setItem('tournamentLocation', data[0].location);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Failed to load tournaments');
|
setTournaments([]);
|
||||||
|
console.error('API /api/tournaments did not return an array:', data);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading tournaments:', err);
|
console.error('Error loading tournaments:', err);
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import './MatchesSchedule.css';
|
|||||||
import TeamLogo from './TeamLogo';
|
import TeamLogo from './TeamLogo';
|
||||||
|
|
||||||
const poolColors = [
|
const poolColors = [
|
||||||
'#f8fafc', // light blue
|
'#bae6fd', // darker blue
|
||||||
'#fef9c3', // light yellow
|
'#fde68a', // darker yellow
|
||||||
'#fce7f3', // light pink
|
'#f9a8d4', // darker pink
|
||||||
'#d1fae5', // light green
|
'#6ee7b7', // darker green
|
||||||
'#fee2e2', // light red
|
'#fca5a5', // darker red
|
||||||
'#e0e7ff', // light purple
|
'#a5b4fc', // darker purple
|
||||||
];
|
];
|
||||||
|
|
||||||
function groupMatchesByPoolAndRound(matches) {
|
function groupMatchesByPoolAndRound(matches) {
|
||||||
|
|||||||
@@ -2,14 +2,26 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import TeamLogo from './TeamLogo';
|
import TeamLogo from './TeamLogo';
|
||||||
|
|
||||||
const poolColors = [
|
const poolColors = [
|
||||||
'#f8fafc', // light blue
|
'#bae6fd', // darker blue
|
||||||
'#fef9c3', // light yellow
|
'#fde68a', // darker yellow
|
||||||
'#fce7f3', // light pink
|
'#f9a8d4', // darker pink
|
||||||
'#d1fae5', // light green
|
'#6ee7b7', // darker green
|
||||||
'#fee2e2', // light red
|
'#fca5a5', // darker red
|
||||||
'#e0e7ff', // light purple
|
'#a5b4fc', // darker purple
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Helper to convert hex color to rgba with alpha
|
||||||
|
function hexToRgba(hex, alpha) {
|
||||||
|
// Remove # if present
|
||||||
|
hex = hex.replace('#', '');
|
||||||
|
// Parse r, g, b
|
||||||
|
const bigint = parseInt(hex, 16);
|
||||||
|
const r = (bigint >> 16) & 255;
|
||||||
|
const g = (bigint >> 8) & 255;
|
||||||
|
const b = bigint & 255;
|
||||||
|
return `rgba(${r},${g},${b},${alpha})`;
|
||||||
|
}
|
||||||
|
|
||||||
const Pools = ({ token, onTournamentNameChange }) => {
|
const Pools = ({ token, onTournamentNameChange }) => {
|
||||||
const [matches, setMatches] = useState([]);
|
const [matches, setMatches] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@@ -212,8 +224,12 @@ const Pools = ({ token, onTournamentNameChange }) => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{poolMap[pool].map(match => (
|
{poolMap[pool].map((match, rowIdx) => (
|
||||||
<tr key={match.id}>
|
<tr key={match.id} style={{
|
||||||
|
background: rowIdx % 2 === 0
|
||||||
|
? '#fff'
|
||||||
|
: hexToRgba(poolColors[idx % poolColors.length], 0.5)
|
||||||
|
}}>
|
||||||
<td style={{ textAlign: 'center', padding: '8px' }}>
|
<td style={{ textAlign: 'center', padding: '8px' }}>
|
||||||
<TeamLogo team={match.team1} size="small" />
|
<TeamLogo team={match.team1} size="small" />
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const UserMenu = ({ onSelect, token, onResetTournament, tournamentStarted }) =>
|
|||||||
<li onClick={() => handleSelect('profile')}>Login</li>
|
<li onClick={() => handleSelect('profile')}>Login</li>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<li onClick={() => handleSelect('create-tournament')}>Create tournament</li>
|
<li onClick={() => handleSelect('create-tournament')}>Create new tournament</li>
|
||||||
<li onClick={() => handleSelect('load-tournaments')}>Load tournaments</li>
|
<li onClick={() => handleSelect('load-tournaments')}>Load tournaments</li>
|
||||||
<li
|
<li
|
||||||
className={`start-tournament-option${tournamentStarted ? ' disabled' : ''}`}
|
className={`start-tournament-option${tournamentStarted ? ' disabled' : ''}`}
|
||||||
|
|||||||
Reference in New Issue
Block a user