react-os-shell 1.6.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -9
- package/dist/Browser-HGX2YS22.js +7 -0
- package/dist/{Browser-ELO6K7YY.js.map → Browser-HGX2YS22.js.map} +1 -1
- package/dist/{Calculator-X26IEHCN.js → Calculator-JJZMCBIN.js} +4 -4
- package/dist/{Calculator-X26IEHCN.js.map → Calculator-JJZMCBIN.js.map} +1 -1
- package/dist/{CurrencyConverter-5UHIRF2P.js → CurrencyConverter-VCZGTULI.js} +4 -4
- package/dist/{CurrencyConverter-5UHIRF2P.js.map → CurrencyConverter-VCZGTULI.js.map} +1 -1
- package/dist/{Documents-7KYHOORU.js → Documents-W6JNKYE3.js} +4 -4
- package/dist/{Documents-7KYHOORU.js.map → Documents-W6JNKYE3.js.map} +1 -1
- package/dist/Files-232FHLMO.js +13 -0
- package/dist/{Files-3455T525.js.map → Files-232FHLMO.js.map} +1 -1
- package/dist/{Notepad-RLQ4NXJI.js → Notepad-G2UOOZOU.js} +4 -4
- package/dist/{Notepad-RLQ4NXJI.js.map → Notepad-G2UOOZOU.js.map} +1 -1
- package/dist/{PomodoroTimer-PG4J5NNI.js → PomodoroTimer-TEZJH7E6.js} +4 -4
- package/dist/{PomodoroTimer-PG4J5NNI.js.map → PomodoroTimer-TEZJH7E6.js.map} +1 -1
- package/dist/Preview-QXM6YE7A.js +9 -0
- package/dist/{Preview-H5IOBX66.js.map → Preview-QXM6YE7A.js.map} +1 -1
- package/dist/Spreadsheet-7V6GLIIW.js +7 -0
- package/dist/{Spreadsheet-6C6O6BGG.js.map → Spreadsheet-7V6GLIIW.js.map} +1 -1
- package/dist/{Stock-TIJVSHPV.js → Stock-QVTMAGIU.js} +4 -4
- package/dist/{Stock-TIJVSHPV.js.map → Stock-QVTMAGIU.js.map} +1 -1
- package/dist/{Weather-WVDLOH74.js → Weather-PXUZW22T.js} +4 -4
- package/dist/{Weather-WVDLOH74.js.map → Weather-PXUZW22T.js.map} +1 -1
- package/dist/{WorldClock-OV4GU5J3.js → WorldClock-CRESQVKE.js} +4 -4
- package/dist/{WorldClock-OV4GU5J3.js.map → WorldClock-CRESQVKE.js.map} +1 -1
- package/dist/apps/index.d.ts +1 -20
- package/dist/apps/index.js +20 -35
- package/dist/apps/index.js.map +1 -1
- package/dist/{chunk-GWVVILYQ.js → chunk-5FEW4QE5.js} +3 -3
- package/dist/{chunk-GWVVILYQ.js.map → chunk-5FEW4QE5.js.map} +1 -1
- package/dist/{chunk-ISNP6BHR.js → chunk-AYTCQLZ4.js} +3 -3
- package/dist/{chunk-ISNP6BHR.js.map → chunk-AYTCQLZ4.js.map} +1 -1
- package/dist/{chunk-32CXFFKW.js → chunk-JZS5427T.js} +4 -4
- package/dist/{chunk-32CXFFKW.js.map → chunk-JZS5427T.js.map} +1 -1
- package/dist/{chunk-KKEWB6RG.js → chunk-LXCTOIXP.js} +4 -4
- package/dist/{chunk-KKEWB6RG.js.map → chunk-LXCTOIXP.js.map} +1 -1
- package/dist/{chunk-VAMMHJR3.js → chunk-Q4EH3NFS.js} +4 -4
- package/dist/{chunk-VAMMHJR3.js.map → chunk-Q4EH3NFS.js.map} +1 -1
- package/dist/{chunk-4PSDLG2P.js → chunk-QESYOYZS.js} +5 -5
- package/dist/{chunk-4PSDLG2P.js.map → chunk-QESYOYZS.js.map} +1 -1
- package/dist/{chunk-ZIV7JFJ5.js → chunk-XF7JN5E5.js} +4 -4
- package/dist/{chunk-ZIV7JFJ5.js.map → chunk-XF7JN5E5.js.map} +1 -1
- package/dist/{chunk-Q3USVEUR.js → chunk-XO4ZJAUB.js} +4 -4
- package/dist/{chunk-Q3USVEUR.js.map → chunk-XO4ZJAUB.js.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +37 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/Browser-ELO6K7YY.js +0 -7
- package/dist/Checkers-MIAHIKJH.js +0 -214
- package/dist/Checkers-MIAHIKJH.js.map +0 -1
- package/dist/Chess-C5BY45NA.js +0 -190
- package/dist/Chess-C5BY45NA.js.map +0 -1
- package/dist/Files-3455T525.js +0 -13
- package/dist/Game2048-3RH3ELRD.js +0 -191
- package/dist/Game2048-3RH3ELRD.js.map +0 -1
- package/dist/Minesweeper-OXRRSCVF.js +0 -271
- package/dist/Minesweeper-OXRRSCVF.js.map +0 -1
- package/dist/Preview-H5IOBX66.js +0 -9
- package/dist/Spreadsheet-6C6O6BGG.js +0 -7
- package/dist/Sudoku-XHLYCEVT.js +0 -197
- package/dist/Sudoku-XHLYCEVT.js.map +0 -1
- package/dist/Tetris-ZHCZYL24.js +0 -243
- package/dist/Tetris-ZHCZYL24.js.map +0 -1
- package/dist/chunk-Y4QYGQKS.js +0 -31
- package/dist/chunk-Y4QYGQKS.js.map +0 -1
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
// src/apps/Game2048.tsx
|
|
5
|
-
var TILE_COLORS = {
|
|
6
|
-
0: "bg-gray-200",
|
|
7
|
-
2: "bg-gray-100 text-gray-700",
|
|
8
|
-
4: "bg-gray-200 text-gray-700",
|
|
9
|
-
8: "bg-orange-300 text-white",
|
|
10
|
-
16: "bg-orange-400 text-white",
|
|
11
|
-
32: "bg-orange-500 text-white",
|
|
12
|
-
64: "bg-red-500 text-white",
|
|
13
|
-
128: "bg-yellow-300 text-gray-800",
|
|
14
|
-
256: "bg-yellow-400 text-gray-800",
|
|
15
|
-
512: "bg-yellow-500 text-white",
|
|
16
|
-
1024: "bg-yellow-600 text-white",
|
|
17
|
-
2048: "bg-yellow-300 text-gray-800 ring-4 ring-yellow-400"
|
|
18
|
-
};
|
|
19
|
-
var empty = () => Array.from({ length: 4 }, () => Array(4).fill(0));
|
|
20
|
-
function addRandom(b) {
|
|
21
|
-
const cells = [];
|
|
22
|
-
b.forEach((r2, i) => r2.forEach((v, j) => {
|
|
23
|
-
if (!v) cells.push([i, j]);
|
|
24
|
-
}));
|
|
25
|
-
if (!cells.length) return b;
|
|
26
|
-
const [r, c] = cells[Math.floor(Math.random() * cells.length)];
|
|
27
|
-
const nb = b.map((r2) => [...r2]);
|
|
28
|
-
nb[r][c] = Math.random() < 0.9 ? 2 : 4;
|
|
29
|
-
return nb;
|
|
30
|
-
}
|
|
31
|
-
function slideRow(row) {
|
|
32
|
-
const nums = row.filter((v) => v);
|
|
33
|
-
let score = 0;
|
|
34
|
-
const merged = [];
|
|
35
|
-
for (let i = 0; i < nums.length; i++) {
|
|
36
|
-
if (i + 1 < nums.length && nums[i] === nums[i + 1]) {
|
|
37
|
-
merged.push(nums[i] * 2);
|
|
38
|
-
score += nums[i] * 2;
|
|
39
|
-
i++;
|
|
40
|
-
} else merged.push(nums[i]);
|
|
41
|
-
}
|
|
42
|
-
while (merged.length < 4) merged.push(0);
|
|
43
|
-
return { row: merged, score };
|
|
44
|
-
}
|
|
45
|
-
function rotate(b) {
|
|
46
|
-
return b[0].map((_, i) => b.map((r) => r[i]).reverse());
|
|
47
|
-
}
|
|
48
|
-
function move(board, dir) {
|
|
49
|
-
let b = board.map((r) => [...r]);
|
|
50
|
-
const rotations = { left: 0, down: 1, right: 2, up: 3 };
|
|
51
|
-
for (let i = 0; i < rotations[dir]; i++) b = rotate(b);
|
|
52
|
-
let score = 0;
|
|
53
|
-
b = b.map((r) => {
|
|
54
|
-
const res = slideRow(r);
|
|
55
|
-
score += res.score;
|
|
56
|
-
return res.row;
|
|
57
|
-
});
|
|
58
|
-
for (let i = 0; i < (4 - rotations[dir]) % 4; i++) b = rotate(b);
|
|
59
|
-
return { board: b, score };
|
|
60
|
-
}
|
|
61
|
-
function hasValidMoves(b) {
|
|
62
|
-
for (let i = 0; i < 4; i++)
|
|
63
|
-
for (let j = 0; j < 4; j++) {
|
|
64
|
-
if (!b[i][j]) return true;
|
|
65
|
-
if (j < 3 && b[i][j] === b[i][j + 1]) return true;
|
|
66
|
-
if (i < 3 && b[i][j] === b[i + 1][j]) return true;
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
function boardsEqual(a, b) {
|
|
71
|
-
return a.every((r, i) => r.every((v, j) => v === b[i][j]));
|
|
72
|
-
}
|
|
73
|
-
function initBoard() {
|
|
74
|
-
return addRandom(addRandom(empty()));
|
|
75
|
-
}
|
|
76
|
-
function Game2048() {
|
|
77
|
-
const [board, setBoard] = useState(initBoard);
|
|
78
|
-
const [score, setScore] = useState(0);
|
|
79
|
-
const [best, setBest] = useState(() => Number(localStorage.getItem("game2048_best") || 0));
|
|
80
|
-
const [won, setWon] = useState(false);
|
|
81
|
-
const [showWin, setShowWin] = useState(false);
|
|
82
|
-
const [gameOver, setGameOver] = useState(false);
|
|
83
|
-
const handleMove = useCallback((dir) => {
|
|
84
|
-
if (gameOver) return;
|
|
85
|
-
setBoard((prev) => {
|
|
86
|
-
const { board: nb, score: gained } = move(prev, dir);
|
|
87
|
-
if (boardsEqual(prev, nb)) return prev;
|
|
88
|
-
const withNew = addRandom(nb);
|
|
89
|
-
setScore((s) => {
|
|
90
|
-
const ns = s + gained;
|
|
91
|
-
setBest((b) => {
|
|
92
|
-
const nb2 = Math.max(b, ns);
|
|
93
|
-
localStorage.setItem("game2048_best", String(nb2));
|
|
94
|
-
return nb2;
|
|
95
|
-
});
|
|
96
|
-
return ns;
|
|
97
|
-
});
|
|
98
|
-
if (!won && withNew.some((r) => r.some((v) => v >= 2048))) {
|
|
99
|
-
setWon(true);
|
|
100
|
-
setShowWin(true);
|
|
101
|
-
}
|
|
102
|
-
if (!hasValidMoves(withNew)) setGameOver(true);
|
|
103
|
-
return withNew;
|
|
104
|
-
});
|
|
105
|
-
}, [gameOver, won]);
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
const keyMap = {
|
|
108
|
-
ArrowLeft: "left",
|
|
109
|
-
ArrowRight: "right",
|
|
110
|
-
ArrowUp: "up",
|
|
111
|
-
ArrowDown: "down"
|
|
112
|
-
};
|
|
113
|
-
const handler = (e) => {
|
|
114
|
-
const dir = keyMap[e.key];
|
|
115
|
-
if (dir) {
|
|
116
|
-
e.preventDefault();
|
|
117
|
-
handleMove(dir);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
window.addEventListener("keydown", handler);
|
|
121
|
-
return () => window.removeEventListener("keydown", handler);
|
|
122
|
-
}, [handleMove]);
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
let sx = 0, sy = 0;
|
|
125
|
-
const el = document.getElementById("game2048-board");
|
|
126
|
-
if (!el) return;
|
|
127
|
-
const ts = (e) => {
|
|
128
|
-
sx = e.touches[0].clientX;
|
|
129
|
-
sy = e.touches[0].clientY;
|
|
130
|
-
};
|
|
131
|
-
const te = (e) => {
|
|
132
|
-
const dx = e.changedTouches[0].clientX - sx, dy = e.changedTouches[0].clientY - sy;
|
|
133
|
-
if (Math.max(Math.abs(dx), Math.abs(dy)) < 30) return;
|
|
134
|
-
if (Math.abs(dx) > Math.abs(dy)) handleMove(dx > 0 ? "right" : "left");
|
|
135
|
-
else handleMove(dy > 0 ? "down" : "up");
|
|
136
|
-
};
|
|
137
|
-
el.addEventListener("touchstart", ts, { passive: true });
|
|
138
|
-
el.addEventListener("touchend", te, { passive: true });
|
|
139
|
-
return () => {
|
|
140
|
-
el.removeEventListener("touchstart", ts);
|
|
141
|
-
el.removeEventListener("touchend", te);
|
|
142
|
-
};
|
|
143
|
-
}, [handleMove]);
|
|
144
|
-
const newGame = () => {
|
|
145
|
-
setBoard(initBoard());
|
|
146
|
-
setScore(0);
|
|
147
|
-
setWon(false);
|
|
148
|
-
setShowWin(false);
|
|
149
|
-
setGameOver(false);
|
|
150
|
-
};
|
|
151
|
-
const fontSize = (v) => v >= 1024 ? "text-lg" : v >= 128 ? "text-xl" : "text-2xl";
|
|
152
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center select-none", children: [
|
|
153
|
-
/* @__PURE__ */ jsxs("div", { className: "w-full max-w-[340px]", children: [
|
|
154
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
155
|
-
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800", children: "2048" }),
|
|
156
|
-
/* @__PURE__ */ jsx("button", { onClick: newGame, className: "px-4 py-1.5 bg-gray-700 text-white rounded font-semibold text-sm hover:bg-gray-800", children: "New Game" })
|
|
157
|
-
] }),
|
|
158
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 mb-3", children: [
|
|
159
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 bg-gray-700 text-white rounded px-3 py-1 text-center", children: [
|
|
160
|
-
/* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wider opacity-70", children: "Score" }),
|
|
161
|
-
/* @__PURE__ */ jsx("div", { className: "text-lg font-bold", children: score })
|
|
162
|
-
] }),
|
|
163
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 bg-gray-700 text-white rounded px-3 py-1 text-center", children: [
|
|
164
|
-
/* @__PURE__ */ jsx("div", { className: "text-[10px] uppercase tracking-wider opacity-70", children: "Best" }),
|
|
165
|
-
/* @__PURE__ */ jsx("div", { className: "text-lg font-bold", children: best })
|
|
166
|
-
] })
|
|
167
|
-
] }),
|
|
168
|
-
/* @__PURE__ */ jsxs("div", { id: "game2048-board", className: "relative bg-gray-300 rounded-lg p-2 grid grid-cols-4 gap-2", children: [
|
|
169
|
-
board.flat().map((v, i) => /* @__PURE__ */ jsx("div", { className: `aspect-square rounded-md flex items-center justify-center font-bold transition-all duration-100
|
|
170
|
-
${TILE_COLORS[v] || "bg-yellow-200 text-gray-800"} ${fontSize(v)} ${v ? "animate-pop" : ""}`, children: v || "" }, i)),
|
|
171
|
-
showWin && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-yellow-300/80 rounded-lg flex flex-col items-center justify-center gap-3", children: [
|
|
172
|
-
/* @__PURE__ */ jsx("div", { className: "text-4xl font-bold text-gray-800", children: "You Win!" }),
|
|
173
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
174
|
-
/* @__PURE__ */ jsx("button", { onClick: () => setShowWin(false), className: "px-4 py-2 bg-gray-700 text-white rounded font-semibold text-sm", children: "Continue" }),
|
|
175
|
-
/* @__PURE__ */ jsx("button", { onClick: newGame, className: "px-4 py-2 bg-gray-500 text-white rounded font-semibold text-sm", children: "New Game" })
|
|
176
|
-
] })
|
|
177
|
-
] }),
|
|
178
|
-
gameOver && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 bg-gray-800/70 rounded-lg flex flex-col items-center justify-center gap-3", children: [
|
|
179
|
-
/* @__PURE__ */ jsx("div", { className: "text-3xl font-bold text-white", children: "Game Over" }),
|
|
180
|
-
/* @__PURE__ */ jsx("button", { onClick: newGame, className: "px-4 py-2 bg-white text-gray-800 rounded font-semibold text-sm", children: "Try Again" })
|
|
181
|
-
] })
|
|
182
|
-
] }),
|
|
183
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 text-center mt-3", children: "Use arrow keys or swipe to play" })
|
|
184
|
-
] }),
|
|
185
|
-
/* @__PURE__ */ jsx("style", { children: `@keyframes pop{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.animate-pop{animation:pop .15s ease-out}` })
|
|
186
|
-
] });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export { Game2048 as default };
|
|
190
|
-
//# sourceMappingURL=Game2048-3RH3ELRD.js.map
|
|
191
|
-
//# sourceMappingURL=Game2048-3RH3ELRD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/Game2048.tsx"],"names":["r","nb"],"mappings":"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","file":"Game2048-3RH3ELRD.js","sourcesContent":["import { useState, useCallback, useEffect } from 'react';\n\ntype Board = number[][];\n\nconst TILE_COLORS: Record<number, string> = {\n 0: 'bg-gray-200', 2: 'bg-gray-100 text-gray-700', 4: 'bg-gray-200 text-gray-700',\n 8: 'bg-orange-300 text-white', 16: 'bg-orange-400 text-white', 32: 'bg-orange-500 text-white',\n 64: 'bg-red-500 text-white', 128: 'bg-yellow-300 text-gray-800', 256: 'bg-yellow-400 text-gray-800',\n 512: 'bg-yellow-500 text-white', 1024: 'bg-yellow-600 text-white', 2048: 'bg-yellow-300 text-gray-800 ring-4 ring-yellow-400',\n};\n\nconst empty = (): Board => Array.from({ length: 4 }, () => Array(4).fill(0));\n\nfunction addRandom(b: Board): Board {\n const cells: [number, number][] = [];\n b.forEach((r, i) => r.forEach((v, j) => { if (!v) cells.push([i, j]); }));\n if (!cells.length) return b;\n const [r, c] = cells[Math.floor(Math.random() * cells.length)];\n const nb = b.map(r => [...r]);\n nb[r][c] = Math.random() < 0.9 ? 2 : 4;\n return nb;\n}\n\nfunction slideRow(row: number[]): { row: number[]; score: number } {\n const nums = row.filter(v => v);\n let score = 0;\n const merged: number[] = [];\n for (let i = 0; i < nums.length; i++) {\n if (i + 1 < nums.length && nums[i] === nums[i + 1]) {\n merged.push(nums[i] * 2);\n score += nums[i] * 2;\n i++;\n } else merged.push(nums[i]);\n }\n while (merged.length < 4) merged.push(0);\n return { row: merged, score };\n}\n\nfunction rotate(b: Board): Board {\n return b[0].map((_, i) => b.map(r => r[i]).reverse());\n}\n\nfunction move(board: Board, dir: 'left' | 'right' | 'up' | 'down'): { board: Board; score: number } {\n let b = board.map(r => [...r]);\n const rotations = { left: 0, down: 1, right: 2, up: 3 };\n for (let i = 0; i < rotations[dir]; i++) b = rotate(b);\n let score = 0;\n b = b.map(r => { const res = slideRow(r); score += res.score; return res.row; });\n for (let i = 0; i < (4 - rotations[dir]) % 4; i++) b = rotate(b);\n return { board: b, score };\n}\n\nfunction hasValidMoves(b: Board): boolean {\n for (let i = 0; i < 4; i++)\n for (let j = 0; j < 4; j++) {\n if (!b[i][j]) return true;\n if (j < 3 && b[i][j] === b[i][j + 1]) return true;\n if (i < 3 && b[i][j] === b[i + 1][j]) return true;\n }\n return false;\n}\n\nfunction boardsEqual(a: Board, b: Board): boolean {\n return a.every((r, i) => r.every((v, j) => v === b[i][j]));\n}\n\nfunction initBoard(): Board {\n return addRandom(addRandom(empty()));\n}\n\nexport default function Game2048() {\n const [board, setBoard] = useState<Board>(initBoard);\n const [score, setScore] = useState(0);\n const [best, setBest] = useState(() => Number(localStorage.getItem('game2048_best') || 0));\n const [won, setWon] = useState(false);\n const [showWin, setShowWin] = useState(false);\n const [gameOver, setGameOver] = useState(false);\n\n const handleMove = useCallback((dir: 'left' | 'right' | 'up' | 'down') => {\n if (gameOver) return;\n setBoard(prev => {\n const { board: nb, score: gained } = move(prev, dir);\n if (boardsEqual(prev, nb)) return prev;\n const withNew = addRandom(nb);\n setScore(s => {\n const ns = s + gained;\n setBest(b => { const nb = Math.max(b, ns); localStorage.setItem('game2048_best', String(nb)); return nb; });\n return ns;\n });\n if (!won && withNew.some(r => r.some(v => v >= 2048))) { setWon(true); setShowWin(true); }\n if (!hasValidMoves(withNew)) setGameOver(true);\n return withNew;\n });\n }, [gameOver, won]);\n\n useEffect(() => {\n const keyMap: Record<string, 'left' | 'right' | 'up' | 'down'> = {\n ArrowLeft: 'left', ArrowRight: 'right', ArrowUp: 'up', ArrowDown: 'down',\n };\n const handler = (e: KeyboardEvent) => {\n const dir = keyMap[e.key];\n if (dir) { e.preventDefault(); handleMove(dir); }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [handleMove]);\n\n useEffect(() => {\n let sx = 0, sy = 0;\n const el = document.getElementById('game2048-board');\n if (!el) return;\n const ts = (e: TouchEvent) => { sx = e.touches[0].clientX; sy = e.touches[0].clientY; };\n const te = (e: TouchEvent) => {\n const dx = e.changedTouches[0].clientX - sx, dy = e.changedTouches[0].clientY - sy;\n if (Math.max(Math.abs(dx), Math.abs(dy)) < 30) return;\n if (Math.abs(dx) > Math.abs(dy)) handleMove(dx > 0 ? 'right' : 'left');\n else handleMove(dy > 0 ? 'down' : 'up');\n };\n el.addEventListener('touchstart', ts, { passive: true });\n el.addEventListener('touchend', te, { passive: true });\n return () => { el.removeEventListener('touchstart', ts); el.removeEventListener('touchend', te); };\n }, [handleMove]);\n\n const newGame = () => { setBoard(initBoard()); setScore(0); setWon(false); setShowWin(false); setGameOver(false); };\n\n const fontSize = (v: number) => v >= 1024 ? 'text-lg' : v >= 128 ? 'text-xl' : 'text-2xl';\n\n return (\n <div className=\"flex flex-col items-center select-none\">\n <div className=\"w-full max-w-[340px]\">\n <div className=\"flex items-center justify-between mb-3\">\n <h1 className=\"text-3xl font-bold text-gray-800\">2048</h1>\n <button onClick={newGame} className=\"px-4 py-1.5 bg-gray-700 text-white rounded font-semibold text-sm hover:bg-gray-800\">\n New Game\n </button>\n </div>\n <div className=\"flex gap-3 mb-3\">\n <div className=\"flex-1 bg-gray-700 text-white rounded px-3 py-1 text-center\">\n <div className=\"text-[10px] uppercase tracking-wider opacity-70\">Score</div>\n <div className=\"text-lg font-bold\">{score}</div>\n </div>\n <div className=\"flex-1 bg-gray-700 text-white rounded px-3 py-1 text-center\">\n <div className=\"text-[10px] uppercase tracking-wider opacity-70\">Best</div>\n <div className=\"text-lg font-bold\">{best}</div>\n </div>\n </div>\n <div id=\"game2048-board\" className=\"relative bg-gray-300 rounded-lg p-2 grid grid-cols-4 gap-2\">\n {board.flat().map((v, i) => (\n <div key={i} className={`aspect-square rounded-md flex items-center justify-center font-bold transition-all duration-100\n ${TILE_COLORS[v] || 'bg-yellow-200 text-gray-800'} ${fontSize(v)} ${v ? 'animate-pop' : ''}`}>\n {v || ''}\n </div>\n ))}\n {showWin && (\n <div className=\"absolute inset-0 bg-yellow-300/80 rounded-lg flex flex-col items-center justify-center gap-3\">\n <div className=\"text-4xl font-bold text-gray-800\">You Win!</div>\n <div className=\"flex gap-2\">\n <button onClick={() => setShowWin(false)} className=\"px-4 py-2 bg-gray-700 text-white rounded font-semibold text-sm\">\n Continue\n </button>\n <button onClick={newGame} className=\"px-4 py-2 bg-gray-500 text-white rounded font-semibold text-sm\">\n New Game\n </button>\n </div>\n </div>\n )}\n {gameOver && (\n <div className=\"absolute inset-0 bg-gray-800/70 rounded-lg flex flex-col items-center justify-center gap-3\">\n <div className=\"text-3xl font-bold text-white\">Game Over</div>\n <button onClick={newGame} className=\"px-4 py-2 bg-white text-gray-800 rounded font-semibold text-sm\">\n Try Again\n </button>\n </div>\n )}\n </div>\n <p className=\"text-xs text-gray-400 text-center mt-3\">Use arrow keys or swipe to play</p>\n </div>\n <style>{`@keyframes pop{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.animate-pop{animation:pop .15s ease-out}`}</style>\n </div>\n );\n}\n"]}
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import { formatDate } from './chunk-Y4QYGQKS.js';
|
|
2
|
-
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
3
|
-
import { useWindowMenuItem, Modal, client_default } from './chunk-GWVVILYQ.js';
|
|
4
|
-
import './chunk-UBN4IUDE.js';
|
|
5
|
-
import './chunk-ZF6AYO4G.js';
|
|
6
|
-
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
7
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
-
|
|
9
|
-
// src/api/analytics.ts
|
|
10
|
-
var submitGameScore = (data) => client_default.post(`/analytics/games/${data.game}/scores/`, data).then((r) => r.data);
|
|
11
|
-
var getGameLeaderboard = (game) => client_default.get(`/analytics/games/${game}/leaderboard/`).then((r) => r.data);
|
|
12
|
-
var ROWS = 9;
|
|
13
|
-
var COLS = 9;
|
|
14
|
-
var MINES = 10;
|
|
15
|
-
var DIRS = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
|
|
16
|
-
var NUM_COLORS = { 1: "text-blue-700", 2: "text-green-700", 3: "text-red-600", 4: "text-purple-700", 5: "text-red-900", 6: "text-teal-600", 7: "text-black", 8: "text-gray-500" };
|
|
17
|
-
function createBoard() {
|
|
18
|
-
return Array.from({ length: ROWS }, () => Array.from({ length: COLS }, () => ({ mine: false, revealed: false, flagged: false, adjacent: 0 })));
|
|
19
|
-
}
|
|
20
|
-
function placeMines(board, safeR, safeC) {
|
|
21
|
-
const b = board.map((r) => r.map((c) => ({ ...c })));
|
|
22
|
-
let placed = 0;
|
|
23
|
-
while (placed < MINES) {
|
|
24
|
-
const r = Math.floor(Math.random() * ROWS), c = Math.floor(Math.random() * COLS);
|
|
25
|
-
if (b[r][c].mine || Math.abs(r - safeR) <= 1 && Math.abs(c - safeC) <= 1) continue;
|
|
26
|
-
b[r][c].mine = true;
|
|
27
|
-
placed++;
|
|
28
|
-
}
|
|
29
|
-
for (let r = 0; r < ROWS; r++) for (let c = 0; c < COLS; c++) {
|
|
30
|
-
if (b[r][c].mine) continue;
|
|
31
|
-
b[r][c].adjacent = DIRS.reduce((s, [dr, dc]) => {
|
|
32
|
-
const nr = r + dr, nc = c + dc;
|
|
33
|
-
return s + (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && b[nr][nc].mine ? 1 : 0);
|
|
34
|
-
}, 0);
|
|
35
|
-
}
|
|
36
|
-
return b;
|
|
37
|
-
}
|
|
38
|
-
function floodFill(board, r, c) {
|
|
39
|
-
const b = board.map((row) => row.map((cell) => ({ ...cell })));
|
|
40
|
-
const stack = [[r, c]];
|
|
41
|
-
while (stack.length) {
|
|
42
|
-
const [cr, cc] = stack.pop();
|
|
43
|
-
if (cr < 0 || cr >= ROWS || cc < 0 || cc >= COLS || b[cr][cc].revealed || b[cr][cc].flagged || b[cr][cc].mine) continue;
|
|
44
|
-
b[cr][cc].revealed = true;
|
|
45
|
-
if (b[cr][cc].adjacent === 0) DIRS.forEach(([dr, dc]) => stack.push([cr + dr, cc + dc]));
|
|
46
|
-
}
|
|
47
|
-
return b;
|
|
48
|
-
}
|
|
49
|
-
function checkWin(board) {
|
|
50
|
-
return board.every((row) => row.every((c) => c.mine || c.revealed));
|
|
51
|
-
}
|
|
52
|
-
function Minesweeper() {
|
|
53
|
-
const [board, setBoard] = useState(createBoard);
|
|
54
|
-
const [status, setStatus] = useState("playing");
|
|
55
|
-
const [started, setStarted] = useState(false);
|
|
56
|
-
const [time, setTime] = useState(0);
|
|
57
|
-
const timerRef = useRef(null);
|
|
58
|
-
const startTimeRef = useRef(0);
|
|
59
|
-
const [clicks, setClicks] = useState(0);
|
|
60
|
-
const [showLeaderboard, setShowLeaderboard] = useState(false);
|
|
61
|
-
const [leaderboard, setLeaderboard] = useState([]);
|
|
62
|
-
const [loadingLb, setLoadingLb] = useState(false);
|
|
63
|
-
const scoreSubmitted = useRef(false);
|
|
64
|
-
const flagCount = board.reduce((s, r) => s + r.reduce((s2, c) => s2 + (c.flagged ? 1 : 0), 0), 0);
|
|
65
|
-
const timeSeconds = time / 100;
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
if (started && status === "playing") {
|
|
68
|
-
startTimeRef.current = performance.now() - time * 10;
|
|
69
|
-
timerRef.current = setInterval(() => {
|
|
70
|
-
const elapsed = Math.floor((performance.now() - startTimeRef.current) / 10);
|
|
71
|
-
setTime(Math.min(elapsed, 99999));
|
|
72
|
-
}, 10);
|
|
73
|
-
} else if (timerRef.current) {
|
|
74
|
-
clearInterval(timerRef.current);
|
|
75
|
-
timerRef.current = null;
|
|
76
|
-
}
|
|
77
|
-
return () => {
|
|
78
|
-
if (timerRef.current) clearInterval(timerRef.current);
|
|
79
|
-
};
|
|
80
|
-
}, [started, status]);
|
|
81
|
-
const restart = useCallback(() => {
|
|
82
|
-
setBoard(createBoard());
|
|
83
|
-
setStatus("playing");
|
|
84
|
-
setStarted(false);
|
|
85
|
-
setTime(0);
|
|
86
|
-
startTimeRef.current = 0;
|
|
87
|
-
setClicks(0);
|
|
88
|
-
scoreSubmitted.current = false;
|
|
89
|
-
}, []);
|
|
90
|
-
const handleClick = useCallback((r, c) => {
|
|
91
|
-
if (status !== "playing") return;
|
|
92
|
-
setBoard((prev) => {
|
|
93
|
-
let b = prev;
|
|
94
|
-
if (!started) {
|
|
95
|
-
b = placeMines(prev, r, c);
|
|
96
|
-
setStarted(true);
|
|
97
|
-
}
|
|
98
|
-
const cell = b[r][c];
|
|
99
|
-
if (cell.revealed || cell.flagged) return b;
|
|
100
|
-
if (cell.mine) {
|
|
101
|
-
const lost = b.map((row) => row.map((c2) => ({ ...c2, revealed: c2.mine ? true : c2.revealed })));
|
|
102
|
-
lost[r][c] = { ...lost[r][c], revealed: true };
|
|
103
|
-
setStatus("lost");
|
|
104
|
-
return lost;
|
|
105
|
-
}
|
|
106
|
-
const next = floodFill(b, r, c);
|
|
107
|
-
if (checkWin(next)) setStatus("won");
|
|
108
|
-
return next;
|
|
109
|
-
});
|
|
110
|
-
}, [status, started]);
|
|
111
|
-
const handleContext = useCallback((e, r, c) => {
|
|
112
|
-
e.preventDefault();
|
|
113
|
-
if (status !== "playing") return;
|
|
114
|
-
setBoard((prev) => {
|
|
115
|
-
if (prev[r][c].revealed) return prev;
|
|
116
|
-
const b = prev.map((row) => row.map((cell) => ({ ...cell })));
|
|
117
|
-
b[r][c].flagged = !b[r][c].flagged;
|
|
118
|
-
return b;
|
|
119
|
-
});
|
|
120
|
-
}, [status]);
|
|
121
|
-
const handleChord = useCallback((r, c) => {
|
|
122
|
-
if (status !== "playing") return;
|
|
123
|
-
setBoard((prev) => {
|
|
124
|
-
const cell = prev[r][c];
|
|
125
|
-
if (!cell.revealed || cell.adjacent === 0) return prev;
|
|
126
|
-
const adjFlags = DIRS.reduce((s, [dr, dc]) => {
|
|
127
|
-
const nr = r + dr, nc = c + dc;
|
|
128
|
-
return s + (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && prev[nr][nc].flagged ? 1 : 0);
|
|
129
|
-
}, 0);
|
|
130
|
-
if (adjFlags !== cell.adjacent) return prev;
|
|
131
|
-
let b = prev.map((row) => row.map((c2) => ({ ...c2 })));
|
|
132
|
-
let hitMine = false;
|
|
133
|
-
for (const [dr, dc] of DIRS) {
|
|
134
|
-
const nr = r + dr, nc = c + dc;
|
|
135
|
-
if (nr < 0 || nr >= ROWS || nc < 0 || nc >= COLS || b[nr][nc].revealed || b[nr][nc].flagged) continue;
|
|
136
|
-
if (b[nr][nc].mine) {
|
|
137
|
-
hitMine = true;
|
|
138
|
-
b[nr][nc].revealed = true;
|
|
139
|
-
} else b = floodFill(b, nr, nc);
|
|
140
|
-
}
|
|
141
|
-
if (hitMine) {
|
|
142
|
-
b = b.map((row) => row.map((c2) => ({ ...c2, revealed: c2.mine ? true : c2.revealed })));
|
|
143
|
-
setStatus("lost");
|
|
144
|
-
} else if (checkWin(b)) setStatus("won");
|
|
145
|
-
return b;
|
|
146
|
-
});
|
|
147
|
-
}, [status]);
|
|
148
|
-
const buttonsDown = useRef(0);
|
|
149
|
-
const finalTimeRef = useRef(0);
|
|
150
|
-
useEffect(() => {
|
|
151
|
-
if (status === "won" || status === "lost") {
|
|
152
|
-
if (startTimeRef.current > 0) {
|
|
153
|
-
finalTimeRef.current = Math.round((performance.now() - startTimeRef.current) / 10) / 100;
|
|
154
|
-
} else {
|
|
155
|
-
finalTimeRef.current = timeSeconds;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}, [status]);
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
if (status === "won" && !scoreSubmitted.current) {
|
|
161
|
-
scoreSubmitted.current = true;
|
|
162
|
-
const t = finalTimeRef.current || timeSeconds;
|
|
163
|
-
const tFixed = parseFloat(t.toFixed(2));
|
|
164
|
-
submitGameScore({ game: "minesweeper", won: true, time_seconds: tFixed, clicks }).then((res) => {
|
|
165
|
-
toast_default.success(`You won! Rank #${res.rank} with ${tFixed}s and ${clicks} clicks`);
|
|
166
|
-
}).catch(() => {
|
|
167
|
-
toast_default.success(`You won! ${tFixed}s and ${clicks} clicks`);
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}, [status, clicks]);
|
|
171
|
-
const fetchLeaderboard = useCallback(() => {
|
|
172
|
-
setLoadingLb(true);
|
|
173
|
-
getGameLeaderboard("minesweeper").then((res) => setLeaderboard(res.results || [])).catch(() => setLeaderboard([])).finally(() => setLoadingLb(false));
|
|
174
|
-
}, []);
|
|
175
|
-
const openLb = useCallback(() => {
|
|
176
|
-
fetchLeaderboard();
|
|
177
|
-
setShowLeaderboard(true);
|
|
178
|
-
}, [fetchLeaderboard]);
|
|
179
|
-
useWindowMenuItem("Leaderboard", openLb, /* @__PURE__ */ jsx("svg", { className: "h-4 w-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16.5 18.75h-9m9 0a3 3 0 013 3h-15a3 3 0 013-3m9 0v-3.375c0-.621-.503-1.125-1.125-1.125h-.871M7.5 18.75v-3.375c0-.621.504-1.125 1.125-1.125h.872m5.007 0H9.497m5.007 0a7.454 7.454 0 01-.982-3.172M9.497 14.25a7.454 7.454 0 00.981-3.172M5.25 4.236c-.982.143-1.954.317-2.916.52A6.003 6.003 0 007.73 9.728M5.25 4.236V4.5c0 2.108.966 3.99 2.48 5.228M5.25 4.236V2.721C7.456 2.41 9.71 2.25 12 2.25c2.291 0 4.545.16 6.75.47v1.516M18.75 4.236c.982.143 1.954.317 2.916.52A6.003 6.003 0 0016.27 9.728M18.75 4.236V4.5c0 2.108-.966 3.99-2.48 5.228m0 0a6.003 6.003 0 01-2.27.853m0 0h.008v.008h-.008v-.008z" }) }));
|
|
180
|
-
const face = status === "lost" ? "\u{1F635}" : status === "won" ? "\u{1F60E}" : "\u{1F642}";
|
|
181
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center select-none", onContextMenu: (e) => e.preventDefault(), children: [
|
|
182
|
-
/* @__PURE__ */ jsxs("div", { className: "bg-gray-300 border-4 border-t-white border-l-white border-r-gray-500 border-b-gray-500 p-2", children: [
|
|
183
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between bg-gray-300 border-2 border-t-gray-500 border-l-gray-500 border-r-white border-b-white p-1 mb-2", children: [
|
|
184
|
-
/* @__PURE__ */ jsx("div", { className: "bg-black text-red-500 font-mono font-bold text-xl px-1 w-14 text-center tracking-wider", children: String(Math.max(MINES - flagCount, 0)).padStart(3, "0") }),
|
|
185
|
-
/* @__PURE__ */ jsx("button", { onClick: restart, className: "text-xl w-8 h-8 flex items-center justify-center bg-gray-300 border-2 border-t-white border-l-white border-r-gray-500 border-b-gray-500 active:border-t-gray-500 active:border-l-gray-500 active:border-r-white active:border-b-white cursor-pointer", children: face }),
|
|
186
|
-
/* @__PURE__ */ jsx("div", { className: "bg-black text-red-500 font-mono font-bold text-base px-1 w-[70px] text-center tracking-wider", children: timeSeconds.toFixed(2) })
|
|
187
|
-
] }),
|
|
188
|
-
/* @__PURE__ */ jsx("div", { className: "border-2 border-t-gray-500 border-l-gray-500 border-r-white border-b-white", children: board.map((row, r) => /* @__PURE__ */ jsx("div", { className: "flex", children: row.map((cell, c) => {
|
|
189
|
-
const revealed = cell.revealed;
|
|
190
|
-
const base = revealed ? "w-[35px] h-[35px] flex items-center justify-center text-sm font-bold border border-gray-400" : "w-[35px] h-[35px] flex items-center justify-center text-sm font-bold border-2 border-t-white border-l-white border-r-gray-500 border-b-gray-500 cursor-pointer active:border active:border-gray-400";
|
|
191
|
-
const bg = revealed && cell.mine && status === "lost" ? "bg-red-500" : revealed ? "bg-gray-300" : "bg-gray-300";
|
|
192
|
-
let content = null;
|
|
193
|
-
let color = "";
|
|
194
|
-
if (revealed && cell.mine) {
|
|
195
|
-
content = "\u{1F4A3}";
|
|
196
|
-
} else if (revealed && cell.adjacent > 0) {
|
|
197
|
-
content = cell.adjacent;
|
|
198
|
-
color = NUM_COLORS[cell.adjacent] || "";
|
|
199
|
-
} else if (!revealed && cell.flagged) {
|
|
200
|
-
content = "\u{1F6A9}";
|
|
201
|
-
}
|
|
202
|
-
return /* @__PURE__ */ jsx(
|
|
203
|
-
"div",
|
|
204
|
-
{
|
|
205
|
-
className: `${base} ${bg} ${color}`,
|
|
206
|
-
onClick: () => {
|
|
207
|
-
setClicks((n) => n + 1);
|
|
208
|
-
handleClick(r, c);
|
|
209
|
-
},
|
|
210
|
-
onContextMenu: (e) => {
|
|
211
|
-
setClicks((n) => n + 1);
|
|
212
|
-
handleContext(e, r, c);
|
|
213
|
-
},
|
|
214
|
-
onMouseDown: (e) => {
|
|
215
|
-
buttonsDown.current |= 1 << e.button;
|
|
216
|
-
if ((buttonsDown.current & 5) === 5 || (buttonsDown.current & 3) === 3) handleChord(r, c);
|
|
217
|
-
},
|
|
218
|
-
onMouseUp: (e) => {
|
|
219
|
-
buttonsDown.current &= ~(1 << e.button);
|
|
220
|
-
},
|
|
221
|
-
onMouseLeave: () => {
|
|
222
|
-
buttonsDown.current = 0;
|
|
223
|
-
},
|
|
224
|
-
children: content
|
|
225
|
-
},
|
|
226
|
-
c
|
|
227
|
-
);
|
|
228
|
-
}) }, r)) })
|
|
229
|
-
] }),
|
|
230
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full mt-1 px-1", children: [
|
|
231
|
-
/* @__PURE__ */ jsxs("span", { className: "text-[10px] text-gray-400 font-mono", children: [
|
|
232
|
-
clicks,
|
|
233
|
-
" clicks"
|
|
234
|
-
] }),
|
|
235
|
-
/* @__PURE__ */ jsx(
|
|
236
|
-
"button",
|
|
237
|
-
{
|
|
238
|
-
onClick: () => {
|
|
239
|
-
fetchLeaderboard();
|
|
240
|
-
setShowLeaderboard(true);
|
|
241
|
-
},
|
|
242
|
-
className: "text-[10px] text-blue-600 hover:text-blue-800 font-medium",
|
|
243
|
-
children: "Leaderboard"
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
] }),
|
|
247
|
-
showLeaderboard && /* @__PURE__ */ jsx(Modal, { open: true, onClose: () => setShowLeaderboard(false), title: "Minesweeper Leaderboard", size: "md", children: loadingLb ? /* @__PURE__ */ jsx("div", { className: "text-center py-8 text-sm text-gray-400", children: "Loading..." }) : leaderboard.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-center py-8 text-sm text-gray-400", children: "No wins recorded yet. Be the first!" }) : /* @__PURE__ */ jsx("div", { className: "overflow-y-auto max-h-[60vh]", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
248
|
-
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 bg-white", children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-gray-200", children: [
|
|
249
|
-
/* @__PURE__ */ jsx("th", { className: "text-left py-2 px-2 text-xs font-medium text-gray-500 w-12", children: "#" }),
|
|
250
|
-
/* @__PURE__ */ jsx("th", { className: "text-left py-2 px-2 text-xs font-medium text-gray-500", children: "Player" }),
|
|
251
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-2 px-2 text-xs font-medium text-gray-500 w-16", children: "Time" }),
|
|
252
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-2 px-2 text-xs font-medium text-gray-500 w-16", children: "Clicks" }),
|
|
253
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-2 px-2 text-xs font-medium text-gray-500 w-24", children: "Date" })
|
|
254
|
-
] }) }),
|
|
255
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: leaderboard.map((s, i) => /* @__PURE__ */ jsxs("tr", { className: i < 3 ? "bg-yellow-50/50" : "", children: [
|
|
256
|
-
/* @__PURE__ */ jsx("td", { className: "py-1.5 px-2 font-mono text-gray-400", children: s.rank === 1 ? "\u{1F947}" : s.rank === 2 ? "\u{1F948}" : s.rank === 3 ? "\u{1F949}" : s.rank }),
|
|
257
|
-
/* @__PURE__ */ jsx("td", { className: "py-1.5 px-2 font-medium text-gray-900", children: s.player_name }),
|
|
258
|
-
/* @__PURE__ */ jsxs("td", { className: "py-1.5 px-2 text-right font-mono text-gray-700", children: [
|
|
259
|
-
Number(s.time_seconds).toFixed(2),
|
|
260
|
-
"s"
|
|
261
|
-
] }),
|
|
262
|
-
/* @__PURE__ */ jsx("td", { className: "py-1.5 px-2 text-right font-mono text-gray-500", children: s.clicks }),
|
|
263
|
-
/* @__PURE__ */ jsx("td", { className: "py-1.5 px-2 text-right text-xs text-gray-400", children: formatDate(s.played_at) })
|
|
264
|
-
] }, i)) })
|
|
265
|
-
] }) }) })
|
|
266
|
-
] });
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export { Minesweeper as default };
|
|
270
|
-
//# sourceMappingURL=Minesweeper-OXRRSCVF.js.map
|
|
271
|
-
//# sourceMappingURL=Minesweeper-OXRRSCVF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/analytics.ts","../src/apps/Minesweeper.tsx"],"names":["c"],"mappings":"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","file":"Minesweeper-OXRRSCVF.js","sourcesContent":["/** Game analytics — Minesweeper leaderboard routes through the\n * consumer-supplied apiClient (see setShellApiClient). */\nimport apiClient from './client';\nexport const submitGameScore = (data: { game: string; won: boolean; time_seconds: number; clicks: number }) =>\n apiClient.post(`/analytics/games/${data.game}/scores/`, data).then((r: any) => r.data);\nexport const getGameLeaderboard = (game: string) =>\n apiClient.get(`/analytics/games/${game}/leaderboard/`).then((r: any) => r.data);\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { submitGameScore, getGameLeaderboard } from '../api/analytics';\nimport Modal, { useWindowMenuItem } from '../shell/Modal';\nimport toast from '../shell/toast';\nimport { formatDate } from '../utils/date';\n\nconst ROWS = 9, COLS = 9, MINES = 10;\nconst DIRS = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];\nconst NUM_COLORS: Record<number,string> = {1:'text-blue-700',2:'text-green-700',3:'text-red-600',4:'text-purple-700',5:'text-red-900',6:'text-teal-600',7:'text-black',8:'text-gray-500'};\n\ntype Cell = { mine: boolean; revealed: boolean; flagged: boolean; adjacent: number };\ntype Status = 'playing' | 'won' | 'lost';\n\nfunction createBoard(): Cell[][] {\n return Array.from({length:ROWS},()=>Array.from({length:COLS},()=>({mine:false,revealed:false,flagged:false,adjacent:0})));\n}\n\nfunction placeMines(board: Cell[][], safeR: number, safeC: number) {\n const b = board.map(r=>r.map(c=>({...c})));\n let placed = 0;\n while (placed < MINES) {\n const r = Math.floor(Math.random()*ROWS), c = Math.floor(Math.random()*COLS);\n if (b[r][c].mine || (Math.abs(r-safeR)<=1 && Math.abs(c-safeC)<=1)) continue;\n b[r][c].mine = true;\n placed++;\n }\n for (let r=0;r<ROWS;r++) for (let c=0;c<COLS;c++) {\n if (b[r][c].mine) continue;\n b[r][c].adjacent = DIRS.reduce((s,[dr,dc])=>{\n const nr=r+dr,nc=c+dc;\n return s+(nr>=0&&nr<ROWS&&nc>=0&&nc<COLS&&b[nr][nc].mine?1:0);\n },0);\n }\n return b;\n}\n\nfunction floodFill(board: Cell[][], r: number, c: number) {\n const b = board.map(row=>row.map(cell=>({...cell})));\n const stack: [number,number][] = [[r,c]];\n while (stack.length) {\n const [cr,cc] = stack.pop()!;\n if (cr<0||cr>=ROWS||cc<0||cc>=COLS||b[cr][cc].revealed||b[cr][cc].flagged||b[cr][cc].mine) continue;\n b[cr][cc].revealed = true;\n if (b[cr][cc].adjacent === 0) DIRS.forEach(([dr,dc])=>stack.push([cr+dr,cc+dc]));\n }\n return b;\n}\n\nfunction checkWin(board: Cell[][]): boolean {\n return board.every(row=>row.every(c=>c.mine||c.revealed));\n}\n\nexport default function Minesweeper() {\n const [board, setBoard] = useState(createBoard);\n const [status, setStatus] = useState<Status>('playing');\n const [started, setStarted] = useState(false);\n const [time, setTime] = useState(0); // in centiseconds (hundredths)\n const timerRef = useRef<ReturnType<typeof setInterval>|null>(null);\n const startTimeRef = useRef(0);\n const [clicks, setClicks] = useState(0);\n const [showLeaderboard, setShowLeaderboard] = useState(false);\n const [leaderboard, setLeaderboard] = useState<{ rank: number; player_name: string; time_seconds: number; clicks: number; played_at: string }[]>([]);\n const [loadingLb, setLoadingLb] = useState(false);\n const scoreSubmitted = useRef(false);\n\n const flagCount = board.reduce((s,r)=>s+r.reduce((s2,c)=>s2+(c.flagged?1:0),0),0);\n\n const timeSeconds = time / 100; // convert centiseconds to seconds with 2 decimals\n\n useEffect(()=>{\n if (started && status==='playing') {\n startTimeRef.current = performance.now() - time * 10;\n timerRef.current = setInterval(()=>{\n const elapsed = Math.floor((performance.now() - startTimeRef.current) / 10);\n setTime(Math.min(elapsed, 99999));\n }, 10);\n } else if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n return ()=>{if(timerRef.current)clearInterval(timerRef.current)};\n },[started,status]);\n\n const restart = useCallback(()=>{\n setBoard(createBoard());\n setStatus('playing');\n setStarted(false);\n setTime(0);\n startTimeRef.current = 0;\n setClicks(0);\n scoreSubmitted.current = false;\n },[]);\n\n const handleClick = useCallback((r:number,c:number)=>{\n if (status!=='playing') return;\n setBoard(prev=>{\n let b = prev;\n if (!started) {\n b = placeMines(prev,r,c);\n setStarted(true);\n }\n const cell = b[r][c];\n if (cell.revealed||cell.flagged) return b;\n if (cell.mine) {\n const lost = b.map(row=>row.map(c=>({...c,revealed:c.mine?true:c.revealed})));\n lost[r][c] = {...lost[r][c], revealed:true};\n setStatus('lost');\n return lost;\n }\n const next = floodFill(b,r,c);\n if (checkWin(next)) setStatus('won');\n return next;\n });\n },[status,started]);\n\n const handleContext = useCallback((e:React.MouseEvent,r:number,c:number)=>{\n e.preventDefault();\n if (status!=='playing') return;\n setBoard(prev=>{\n if (prev[r][c].revealed) return prev;\n const b = prev.map(row=>row.map(cell=>({...cell})));\n b[r][c].flagged = !b[r][c].flagged;\n return b;\n });\n },[status]);\n\n // Chord click: both buttons on a revealed number — auto-reveal adjacent if flags match\n const handleChord = useCallback((r:number,c:number)=>{\n if (status!=='playing') return;\n setBoard(prev=>{\n const cell = prev[r][c];\n if (!cell.revealed || cell.adjacent === 0) return prev;\n // Count adjacent flags\n const adjFlags = DIRS.reduce((s,[dr,dc])=>{\n const nr=r+dr,nc=c+dc;\n return s+(nr>=0&&nr<ROWS&&nc>=0&&nc<COLS&&prev[nr][nc].flagged?1:0);\n },0);\n if (adjFlags !== cell.adjacent) return prev;\n // Reveal all unflagged adjacent cells\n let b = prev.map(row=>row.map(c=>({...c})));\n let hitMine = false;\n for (const [dr,dc] of DIRS) {\n const nr=r+dr,nc=c+dc;\n if (nr<0||nr>=ROWS||nc<0||nc>=COLS||b[nr][nc].revealed||b[nr][nc].flagged) continue;\n if (b[nr][nc].mine) { hitMine = true; b[nr][nc].revealed = true; }\n else b = floodFill(b,nr,nc);\n }\n if (hitMine) {\n b = b.map(row=>row.map(c=>({...c,revealed:c.mine?true:c.revealed})));\n setStatus('lost');\n } else if (checkWin(b)) setStatus('won');\n return b;\n });\n },[status]);\n\n const buttonsDown = useRef(0);\n\n // Capture precise time on win/loss\n const finalTimeRef = useRef(0);\n useEffect(() => {\n if (status === 'won' || status === 'lost') {\n // Capture the exact elapsed time when game ends\n if (startTimeRef.current > 0) {\n finalTimeRef.current = Math.round((performance.now() - startTimeRef.current) / 10) / 100; // seconds with 2 decimals\n } else {\n finalTimeRef.current = timeSeconds;\n }\n }\n }, [status]);\n\n // Submit score on win\n useEffect(() => {\n if (status === 'won' && !scoreSubmitted.current) {\n scoreSubmitted.current = true;\n const t = finalTimeRef.current || timeSeconds;\n const tFixed = parseFloat(t.toFixed(2));\n submitGameScore({ game: 'minesweeper', won: true, time_seconds: tFixed, clicks })\n .then(res => { toast.success(`You won! Rank #${res.rank} with ${tFixed}s and ${clicks} clicks`); })\n .catch(() => { toast.success(`You won! ${tFixed}s and ${clicks} clicks`); });\n }\n }, [status, clicks]);\n\n // Fetch leaderboard (no-op when apiClient isn't wired)\n const fetchLeaderboard = useCallback(() => {\n setLoadingLb(true);\n getGameLeaderboard('minesweeper')\n .then(res => setLeaderboard(res.results || []))\n .catch(() => setLeaderboard([]))\n .finally(() => setLoadingLb(false));\n }, []);\n\n // Register \"Leaderboard\" in the window title menu\n const openLb = useCallback(() => { fetchLeaderboard(); setShowLeaderboard(true); }, [fetchLeaderboard]);\n useWindowMenuItem('Leaderboard', openLb, <svg className=\"h-4 w-4 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 18.75h-9m9 0a3 3 0 013 3h-15a3 3 0 013-3m9 0v-3.375c0-.621-.503-1.125-1.125-1.125h-.871M7.5 18.75v-3.375c0-.621.504-1.125 1.125-1.125h.872m5.007 0H9.497m5.007 0a7.454 7.454 0 01-.982-3.172M9.497 14.25a7.454 7.454 0 00.981-3.172M5.25 4.236c-.982.143-1.954.317-2.916.52A6.003 6.003 0 007.73 9.728M5.25 4.236V4.5c0 2.108.966 3.99 2.48 5.228M5.25 4.236V2.721C7.456 2.41 9.71 2.25 12 2.25c2.291 0 4.545.16 6.75.47v1.516M18.75 4.236c.982.143 1.954.317 2.916.52A6.003 6.003 0 0016.27 9.728M18.75 4.236V4.5c0 2.108-.966 3.99-2.48 5.228m0 0a6.003 6.003 0 01-2.27.853m0 0h.008v.008h-.008v-.008z\" /></svg>);\n\n const face = status==='lost'?'😵':status==='won'?'😎':'🙂';\n\n return (\n <div className=\"flex flex-col items-center select-none\" onContextMenu={e => e.preventDefault()}>\n <div className=\"bg-gray-300 border-4 border-t-white border-l-white border-r-gray-500 border-b-gray-500 p-2\">\n {/* Header */}\n <div className=\"flex items-center justify-between bg-gray-300 border-2 border-t-gray-500 border-l-gray-500 border-r-white border-b-white p-1 mb-2\">\n <div className=\"bg-black text-red-500 font-mono font-bold text-xl px-1 w-14 text-center tracking-wider\">\n {String(Math.max(MINES-flagCount,0)).padStart(3,'0')}\n </div>\n <button onClick={restart} className=\"text-xl w-8 h-8 flex items-center justify-center bg-gray-300 border-2 border-t-white border-l-white border-r-gray-500 border-b-gray-500 active:border-t-gray-500 active:border-l-gray-500 active:border-r-white active:border-b-white cursor-pointer\">\n {face}\n </button>\n <div className=\"bg-black text-red-500 font-mono font-bold text-base px-1 w-[70px] text-center tracking-wider\">\n {timeSeconds.toFixed(2)}\n </div>\n </div>\n {/* Grid */}\n <div className=\"border-2 border-t-gray-500 border-l-gray-500 border-r-white border-b-white\">\n {board.map((row,r)=>(\n <div key={r} className=\"flex\">\n {row.map((cell,c)=>{\n const revealed = cell.revealed;\n const base = revealed\n ? 'w-[35px] h-[35px] flex items-center justify-center text-sm font-bold border border-gray-400'\n : 'w-[35px] h-[35px] flex items-center justify-center text-sm font-bold border-2 border-t-white border-l-white border-r-gray-500 border-b-gray-500 cursor-pointer active:border active:border-gray-400';\n const bg = revealed && cell.mine && status==='lost' ? 'bg-red-500' : revealed ? 'bg-gray-300' : 'bg-gray-300';\n let content: React.ReactNode = null;\n let color = '';\n if (revealed && cell.mine) { content = '💣'; }\n else if (revealed && cell.adjacent > 0) { content = cell.adjacent; color = NUM_COLORS[cell.adjacent]||''; }\n else if (!revealed && cell.flagged) { content = '🚩'; }\n return (\n <div key={c} className={`${base} ${bg} ${color}`}\n onClick={()=>{setClicks(n=>n+1);handleClick(r,c);}}\n onContextMenu={e=>{setClicks(n=>n+1);handleContext(e,r,c);}}\n onMouseDown={e=>{buttonsDown.current|=(1<<e.button);if((buttonsDown.current&0b101)===0b101||(buttonsDown.current&0b011)===0b011)handleChord(r,c);}}\n onMouseUp={e=>{buttonsDown.current&=~(1<<e.button)}}\n onMouseLeave={()=>{buttonsDown.current=0}}>\n {content}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n\n {/* Stats + Leaderboard button */}\n <div className=\"flex items-center justify-between w-full mt-1 px-1\">\n <span className=\"text-[10px] text-gray-400 font-mono\">{clicks} clicks</span>\n <button onClick={() => { fetchLeaderboard(); setShowLeaderboard(true); }}\n className=\"text-[10px] text-blue-600 hover:text-blue-800 font-medium\">\n Leaderboard\n </button>\n </div>\n\n {/* Leaderboard Modal */}\n {showLeaderboard && (\n <Modal open onClose={() => setShowLeaderboard(false)} title=\"Minesweeper Leaderboard\" size=\"md\">\n {loadingLb ? (\n <div className=\"text-center py-8 text-sm text-gray-400\">Loading...</div>\n ) : leaderboard.length === 0 ? (\n <div className=\"text-center py-8 text-sm text-gray-400\">No wins recorded yet. Be the first!</div>\n ) : (\n <div className=\"overflow-y-auto max-h-[60vh]\">\n <table className=\"w-full text-sm\">\n <thead className=\"sticky top-0 bg-white\">\n <tr className=\"border-b border-gray-200\">\n <th className=\"text-left py-2 px-2 text-xs font-medium text-gray-500 w-12\">#</th>\n <th className=\"text-left py-2 px-2 text-xs font-medium text-gray-500\">Player</th>\n <th className=\"text-right py-2 px-2 text-xs font-medium text-gray-500 w-16\">Time</th>\n <th className=\"text-right py-2 px-2 text-xs font-medium text-gray-500 w-16\">Clicks</th>\n <th className=\"text-right py-2 px-2 text-xs font-medium text-gray-500 w-24\">Date</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {leaderboard.map((s, i) => (\n <tr key={i} className={i < 3 ? 'bg-yellow-50/50' : ''}>\n <td className=\"py-1.5 px-2 font-mono text-gray-400\">\n {s.rank === 1 ? '🥇' : s.rank === 2 ? '🥈' : s.rank === 3 ? '🥉' : s.rank}\n </td>\n <td className=\"py-1.5 px-2 font-medium text-gray-900\">{s.player_name}</td>\n <td className=\"py-1.5 px-2 text-right font-mono text-gray-700\">{Number(s.time_seconds).toFixed(2)}s</td>\n <td className=\"py-1.5 px-2 text-right font-mono text-gray-500\">{s.clicks}</td>\n <td className=\"py-1.5 px-2 text-right text-xs text-gray-400\">\n {formatDate(s.played_at)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </Modal>\n )}\n </div>\n );\n}\n"]}
|
package/dist/Preview-H5IOBX66.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { Preview as default, setPdfPreview } from './chunk-Q3USVEUR.js';
|
|
2
|
-
import './chunk-KUIPWCTJ.js';
|
|
3
|
-
import './chunk-WIJ45SYD.js';
|
|
4
|
-
import './chunk-32CXFFKW.js';
|
|
5
|
-
import './chunk-GWVVILYQ.js';
|
|
6
|
-
import './chunk-UBN4IUDE.js';
|
|
7
|
-
import './chunk-ZF6AYO4G.js';
|
|
8
|
-
//# sourceMappingURL=Preview-H5IOBX66.js.map
|
|
9
|
-
//# sourceMappingURL=Preview-H5IOBX66.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export { Spreadsheet as default, setSpreadsheetPreview } from './chunk-KKEWB6RG.js';
|
|
2
|
-
import './chunk-32CXFFKW.js';
|
|
3
|
-
import './chunk-GWVVILYQ.js';
|
|
4
|
-
import './chunk-UBN4IUDE.js';
|
|
5
|
-
import './chunk-ZF6AYO4G.js';
|
|
6
|
-
//# sourceMappingURL=Spreadsheet-6C6O6BGG.js.map
|
|
7
|
-
//# sourceMappingURL=Spreadsheet-6C6O6BGG.js.map
|