react-os-shell 1.5.0 → 2.0.0

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.
Files changed (49) hide show
  1. package/README.md +8 -9
  2. package/dist/{Browser-MYVYM7YM.js → Browser-WXHEE7GC.js} +4 -4
  3. package/dist/{Browser-MYVYM7YM.js.map → Browser-WXHEE7GC.js.map} +1 -1
  4. package/dist/{Documents-SLODLCU4.js → Documents-DRKELHI6.js} +148 -11
  5. package/dist/Documents-DRKELHI6.js.map +1 -0
  6. package/dist/{Files-NE4YZTRX.js → Files-TJTUA2LV.js} +7 -7
  7. package/dist/{Files-NE4YZTRX.js.map → Files-TJTUA2LV.js.map} +1 -1
  8. package/dist/{Notepad-F3TLHMWJ.js → Notepad-H6LI3MUZ.js} +3 -3
  9. package/dist/{Notepad-F3TLHMWJ.js.map → Notepad-H6LI3MUZ.js.map} +1 -1
  10. package/dist/Preview-J63FQ336.js +9 -0
  11. package/dist/{Preview-HFGTMXE7.js.map → Preview-J63FQ336.js.map} +1 -1
  12. package/dist/{Spreadsheet-WF34DA44.js → Spreadsheet-Q5VPXFJK.js} +4 -4
  13. package/dist/{Spreadsheet-WF34DA44.js.map → Spreadsheet-Q5VPXFJK.js.map} +1 -1
  14. package/dist/apps/index.d.ts +1 -20
  15. package/dist/apps/index.js +13 -28
  16. package/dist/apps/index.js.map +1 -1
  17. package/dist/{chunk-W5ARJ7PU.js → chunk-2N4EEBHF.js} +5 -5
  18. package/dist/{chunk-W5ARJ7PU.js.map → chunk-2N4EEBHF.js.map} +1 -1
  19. package/dist/{chunk-PTRHYPXO.js → chunk-7FNPV6CE.js} +3 -3
  20. package/dist/{chunk-PTRHYPXO.js.map → chunk-7FNPV6CE.js.map} +1 -1
  21. package/dist/{chunk-RE2FEWBE.js → chunk-DOSYYJSP.js} +4 -4
  22. package/dist/{chunk-RE2FEWBE.js.map → chunk-DOSYYJSP.js.map} +1 -1
  23. package/dist/{chunk-XHBHCL5I.js → chunk-HMYEAOUF.js} +3 -3
  24. package/dist/{chunk-XHBHCL5I.js.map → chunk-HMYEAOUF.js.map} +1 -1
  25. package/dist/{chunk-F6NIGZTF.js → chunk-OMY5HWY2.js} +4 -4
  26. package/dist/{chunk-F6NIGZTF.js.map → chunk-OMY5HWY2.js.map} +1 -1
  27. package/dist/{chunk-IJ5Y4EGQ.js → chunk-ROSSX5DN.js} +3 -3
  28. package/dist/{chunk-IJ5Y4EGQ.js.map → chunk-ROSSX5DN.js.map} +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +35 -9
  31. package/dist/index.js.map +1 -1
  32. package/dist/styles.css +12 -0
  33. package/package.json +1 -1
  34. package/dist/Checkers-MIAHIKJH.js +0 -214
  35. package/dist/Checkers-MIAHIKJH.js.map +0 -1
  36. package/dist/Chess-C5BY45NA.js +0 -190
  37. package/dist/Chess-C5BY45NA.js.map +0 -1
  38. package/dist/Documents-SLODLCU4.js.map +0 -1
  39. package/dist/Game2048-3RH3ELRD.js +0 -191
  40. package/dist/Game2048-3RH3ELRD.js.map +0 -1
  41. package/dist/Minesweeper-OXRRSCVF.js +0 -271
  42. package/dist/Minesweeper-OXRRSCVF.js.map +0 -1
  43. package/dist/Preview-HFGTMXE7.js +0 -9
  44. package/dist/Sudoku-XHLYCEVT.js +0 -197
  45. package/dist/Sudoku-XHLYCEVT.js.map +0 -1
  46. package/dist/Tetris-ZHCZYL24.js +0 -243
  47. package/dist/Tetris-ZHCZYL24.js.map +0 -1
  48. package/dist/chunk-Y4QYGQKS.js +0 -31
  49. package/dist/chunk-Y4QYGQKS.js.map +0 -1
package/dist/styles.css CHANGED
@@ -275,5 +275,17 @@
275
275
  [data-theme="dark"] ::-webkit-scrollbar-thumb { background: #45475a; border-radius: 4px; }
276
276
  [data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: #585b70; }
277
277
 
278
+ /* Documents app — page content styling. The editor is a bare contenteditable
279
+ and Tailwind's preflight strips list markers and element margins, so
280
+ restore them for anything typed into or imported from a document; images
281
+ are click-to-resize (menu) and never overflow the page. */
282
+ .docs-editor ul { list-style: disc; padding-left: 1.5rem; margin: 0.25rem 0; }
283
+ .docs-editor ul ul { list-style: circle; }
284
+ .docs-editor ol { list-style: decimal; padding-left: 1.5rem; margin: 0.25rem 0; }
285
+ .docs-editor li { margin: 0.125rem 0; }
286
+ .docs-editor p { margin: 0 0 0.5rem; }
287
+ .docs-editor img { max-width: 100%; height: auto; cursor: pointer; }
288
+ .docs-editor img:hover { outline: 2px solid rgba(59, 130, 246, 0.45); outline-offset: 1px; }
289
+
278
290
 
279
291
  /* ═══════════════════════════════════════════════════
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-os-shell",
3
- "version": "1.5.0",
3
+ "version": "2.0.0",
4
4
  "description": "Desktop-style React UI shell — windows, taskbar, start menu, sticky notes, frosted glass theming, and bundled apps.",
5
5
  "license": "MIT",
6
6
  "author": "Victor Y. Mau",
@@ -1,214 +0,0 @@
1
- import { useState, useCallback, useEffect } from 'react';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
-
4
- // src/apps/Checkers.tsx
5
- var DIRS_B = [[-1, -1], [-1, 1]];
6
- var DIRS_R = [[1, -1], [1, 1]];
7
- var ALL = [...DIRS_B, ...DIRS_R];
8
- var initBoard = () => {
9
- const b = Array.from({ length: 8 }, () => Array(8).fill(null));
10
- for (let r = 0; r < 3; r++)
11
- for (let c = 0; c < 8; c++)
12
- if ((r + c) % 2 === 1) b[r][c] = { color: "r", king: false };
13
- for (let r = 5; r < 8; r++)
14
- for (let c = 0; c < 8; c++)
15
- if ((r + c) % 2 === 1) b[r][c] = { color: "b", king: false };
16
- return b;
17
- };
18
- var clone = (b) => b.map((r) => r.map((c) => c ? { ...c } : null));
19
- var inB = (r, c) => r >= 0 && r < 8 && c >= 0 && c < 8;
20
- var getJumps = (b, r, c) => {
21
- const p = b[r][c];
22
- if (!p) return [];
23
- const dirs = p.king ? ALL : p.color === "b" ? DIRS_B : DIRS_R;
24
- const jumps = [];
25
- for (const [dr, dc] of dirs) {
26
- const mr = r + dr, mc = c + dc, tr = r + 2 * dr, tc = c + 2 * dc;
27
- if (inB(tr, tc) && b[mr][mc] && b[mr][mc].color !== p.color && !b[tr][tc])
28
- jumps.push({ to: [tr, tc], cap: [mr, mc] });
29
- }
30
- return jumps;
31
- };
32
- var getMoves = (b, r, c) => {
33
- const p = b[r][c];
34
- if (!p) return [];
35
- const dirs = p.king ? ALL : p.color === "b" ? DIRS_B : DIRS_R;
36
- return dirs.filter(([dr, dc]) => {
37
- const nr = r + dr, nc = c + dc;
38
- return inB(nr, nc) && !b[nr][nc];
39
- }).map(([dr, dc]) => [r + dr, c + dc]);
40
- };
41
- var allMoves = (b, color) => {
42
- const pieces = [];
43
- let hasJump = false;
44
- for (let r = 0; r < 8; r++) for (let c = 0; c < 8; c++) {
45
- if (b[r][c]?.color !== color) continue;
46
- const jumps = getJumps(b, r, c), moves = getMoves(b, r, c);
47
- if (jumps.length) hasJump = true;
48
- if (jumps.length || moves.length) pieces.push({ r, c, jumps, moves });
49
- }
50
- if (hasJump) return pieces.filter((p) => p.jumps.length).map((p) => ({ ...p, moves: [] }));
51
- return pieces;
52
- };
53
- function Checkers() {
54
- const [board, setBoard] = useState(initBoard);
55
- const [turn, setTurn] = useState("b");
56
- const [sel, setSel] = useState(null);
57
- const [valid, setValid] = useState([]);
58
- const [caps, setCaps] = useState({ r: 0, b: 0 });
59
- const [winner, setWinner] = useState(null);
60
- const [jumping, setJumping] = useState(false);
61
- const checkWin = useCallback((b, next) => {
62
- const m = allMoves(b, next);
63
- if (m.length === 0) setWinner(next === "b" ? "Red" : "Black");
64
- }, []);
65
- const handleClick = useCallback((r, c) => {
66
- if (winner || turn !== "b") return;
67
- const moves = allMoves(board, "b");
68
- const mustJump = moves.length > 0 && moves[0].jumps.length > 0;
69
- if (jumping && sel) {
70
- const jumps = getJumps(board, sel[0], sel[1]);
71
- const j = jumps.find((j2) => j2.to[0] === r && j2.to[1] === c);
72
- if (!j) return;
73
- const nb2 = clone(board);
74
- nb2[r][c] = nb2[sel[0]][sel[1]];
75
- nb2[sel[0]][sel[1]] = null;
76
- nb2[j.cap[0]][j.cap[1]] = null;
77
- if (r === 0 && nb2[r][c].color === "b") nb2[r][c].king = true;
78
- setCaps((p) => ({ ...p, r: p.r + 1 }));
79
- const moreJumps = getJumps(nb2, r, c);
80
- if (moreJumps.length && !(r === 0 && !board[sel[0]][sel[1]].king)) {
81
- setBoard(nb2);
82
- setSel([r, c]);
83
- setValid(moreJumps.map((j2) => j2.to));
84
- return;
85
- }
86
- setBoard(nb2);
87
- setSel(null);
88
- setValid([]);
89
- setJumping(false);
90
- setTurn("r");
91
- checkWin(nb2, "r");
92
- return;
93
- }
94
- if (board[r][c]?.color === "b") {
95
- const piece = moves.find((m) => m.r === r && m.c === c);
96
- if (!piece) return;
97
- setSel([r, c]);
98
- setValid(mustJump ? piece.jumps.map((j) => j.to) : piece.moves);
99
- return;
100
- }
101
- if (!sel || !valid.some(([vr, vc]) => vr === r && vc === c)) return;
102
- const nb = clone(board);
103
- if (mustJump) {
104
- const piece = moves.find((m) => m.r === sel[0] && m.c === sel[1]);
105
- const j = piece.jumps.find((j2) => j2.to[0] === r && j2.to[1] === c);
106
- nb[r][c] = nb[sel[0]][sel[1]];
107
- nb[sel[0]][sel[1]] = null;
108
- nb[j.cap[0]][j.cap[1]] = null;
109
- const wasKing = nb[r][c].king;
110
- if (r === 0 && nb[r][c].color === "b") nb[r][c].king = true;
111
- setCaps((p) => ({ ...p, r: p.r + 1 }));
112
- const moreJumps = getJumps(nb, r, c);
113
- if (moreJumps.length && !(r === 0 && !wasKing)) {
114
- setBoard(nb);
115
- setSel([r, c]);
116
- setValid(moreJumps.map((j2) => j2.to));
117
- setJumping(true);
118
- return;
119
- }
120
- } else {
121
- nb[r][c] = nb[sel[0]][sel[1]];
122
- nb[sel[0]][sel[1]] = null;
123
- if (r === 0 && nb[r][c].color === "b") nb[r][c].king = true;
124
- }
125
- setBoard(nb);
126
- setSel(null);
127
- setValid([]);
128
- setTurn("r");
129
- checkWin(nb, "r");
130
- }, [board, turn, sel, valid, winner, jumping, checkWin]);
131
- useEffect(() => {
132
- if (turn !== "r" || winner) return;
133
- const t = setTimeout(() => {
134
- const moves = allMoves(board, "r");
135
- if (moves.length === 0) {
136
- setWinner("Black");
137
- return;
138
- }
139
- const mustJump = moves[0].jumps.length > 0;
140
- const pick = moves[Math.floor(Math.random() * moves.length)];
141
- const nb = clone(board);
142
- let cr = pick.r, cc = pick.c, capCount = 0;
143
- if (mustJump) {
144
- let jumps = pick.jumps;
145
- while (jumps.length) {
146
- const j = jumps[Math.floor(Math.random() * jumps.length)];
147
- nb[j.to[0]][j.to[1]] = nb[cr][cc];
148
- nb[cr][cc] = null;
149
- nb[j.cap[0]][j.cap[1]] = null;
150
- capCount++;
151
- const wasKing = nb[j.to[0]][j.to[1]].king;
152
- if (j.to[0] === 7) nb[j.to[0]][j.to[1]].king = true;
153
- cr = j.to[0];
154
- cc = j.to[1];
155
- if (j.to[0] === 7 && !wasKing) break;
156
- jumps = getJumps(nb, cr, cc);
157
- }
158
- } else {
159
- const m = pick.moves[Math.floor(Math.random() * pick.moves.length)];
160
- nb[m[0]][m[1]] = nb[cr][cc];
161
- nb[cr][cc] = null;
162
- if (m[0] === 7) nb[m[0]][m[1]].king = true;
163
- }
164
- setCaps((p) => ({ ...p, b: p.b + capCount }));
165
- setBoard(nb);
166
- setTurn("b");
167
- checkWin(nb, "b");
168
- }, 400);
169
- return () => clearTimeout(t);
170
- }, [turn, board, winner, checkWin]);
171
- const reset = () => {
172
- setBoard(initBoard());
173
- setTurn("b");
174
- setSel(null);
175
- setValid([]);
176
- setCaps({ r: 0, b: 0 });
177
- setWinner(null);
178
- setJumping(false);
179
- };
180
- const isValid = (r, c) => valid.some(([vr, vc]) => vr === r && vc === c);
181
- const isSel = (r, c) => sel?.[0] === r && sel?.[1] === c;
182
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 p-2", children: [
183
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full max-w-[352px]", children: [
184
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: winner ? `${winner} wins!` : turn === "b" ? "Your turn (Black)" : "Red is thinking..." }),
185
- /* @__PURE__ */ jsx("button", { onClick: reset, className: "px-3 py-1 text-xs bg-gray-700 text-white rounded hover:bg-gray-600", children: "New Game" })
186
- ] }),
187
- /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500 flex gap-4", children: [
188
- /* @__PURE__ */ jsxs("span", { children: [
189
- "Red captured: ",
190
- caps.r
191
- ] }),
192
- /* @__PURE__ */ jsxs("span", { children: [
193
- "Black captured: ",
194
- caps.b
195
- ] })
196
- ] }),
197
- /* @__PURE__ */ jsx("div", { className: "border-2 border-gray-800 inline-block", children: board.map((row, r) => /* @__PURE__ */ jsx("div", { className: "flex", children: row.map((cell, c) => {
198
- const dark = (r + c) % 2 === 1;
199
- return /* @__PURE__ */ jsx(
200
- "div",
201
- {
202
- onClick: () => dark && handleClick(r, c),
203
- className: `w-[41px] h-[41px] flex items-center justify-center ${dark ? "bg-emerald-800" : "bg-amber-100"} ${isValid(r, c) ? "ring-2 ring-inset ring-green-400 bg-green-700/60 cursor-pointer" : ""} ${dark ? "cursor-pointer" : ""}`,
204
- children: cell && /* @__PURE__ */ jsx("div", { className: `w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shadow-md ${cell.color === "r" ? "bg-red-600 border-2 border-red-400" : "bg-gray-900 border-2 border-gray-600"} ${isSel(r, c) ? "ring-2 ring-yellow-400 ring-offset-1" : ""}`, children: cell.king && /* @__PURE__ */ jsx("span", { className: "text-yellow-300 text-sm", children: "\u2655" }) })
205
- },
206
- c
207
- );
208
- }) }, r)) })
209
- ] });
210
- }
211
-
212
- export { Checkers as default };
213
- //# sourceMappingURL=Checkers-MIAHIKJH.js.map
214
- //# sourceMappingURL=Checkers-MIAHIKJH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/Checkers.tsx"],"names":["j","nb"],"mappings":"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","file":"Checkers-MIAHIKJH.js","sourcesContent":["import { useState, useCallback, useEffect } from 'react';\n\ntype Cell = null | { color: 'r' | 'b'; king: boolean };\ntype Pos = [number, number];\n\nconst DIRS_B: Pos[] = [[-1, -1], [-1, 1]]; // black moves up\nconst DIRS_R: Pos[] = [[1, -1], [1, 1]]; // red moves down\nconst ALL: Pos[] = [...DIRS_B, ...DIRS_R];\n\nconst initBoard = (): Cell[][] => {\n const b: Cell[][] = Array.from({ length: 8 }, () => Array(8).fill(null));\n for (let r = 0; r < 3; r++)\n for (let c = 0; c < 8; c++)\n if ((r + c) % 2 === 1) b[r][c] = { color: 'r', king: false };\n for (let r = 5; r < 8; r++)\n for (let c = 0; c < 8; c++)\n if ((r + c) % 2 === 1) b[r][c] = { color: 'b', king: false };\n return b;\n};\n\nconst clone = (b: Cell[][]): Cell[][] => b.map(r => r.map(c => c ? { ...c } : null));\nconst inB = (r: number, c: number) => r >= 0 && r < 8 && c >= 0 && c < 8;\n\nconst getJumps = (b: Cell[][], r: number, c: number): { to: Pos; cap: Pos }[] => {\n const p = b[r][c];\n if (!p) return [];\n const dirs = p.king ? ALL : p.color === 'b' ? DIRS_B : DIRS_R;\n const jumps: { to: Pos; cap: Pos }[] = [];\n for (const [dr, dc] of dirs) {\n const mr = r + dr, mc = c + dc, tr = r + 2 * dr, tc = c + 2 * dc;\n if (inB(tr, tc) && b[mr][mc] && b[mr][mc]!.color !== p.color && !b[tr][tc])\n jumps.push({ to: [tr, tc], cap: [mr, mc] });\n }\n return jumps;\n};\n\nconst getMoves = (b: Cell[][], r: number, c: number): Pos[] => {\n const p = b[r][c];\n if (!p) return [];\n const dirs = p.king ? ALL : p.color === 'b' ? DIRS_B : DIRS_R;\n return dirs.filter(([dr, dc]) => { const nr = r + dr, nc = c + dc; return inB(nr, nc) && !b[nr][nc]; })\n .map(([dr, dc]) => [r + dr, c + dc] as Pos);\n};\n\nconst allMoves = (b: Cell[][], color: 'r' | 'b') => {\n const pieces: { r: number; c: number; jumps: { to: Pos; cap: Pos }[]; moves: Pos[] }[] = [];\n let hasJump = false;\n for (let r = 0; r < 8; r++) for (let c = 0; c < 8; c++) {\n if (b[r][c]?.color !== color) continue;\n const jumps = getJumps(b, r, c), moves = getMoves(b, r, c);\n if (jumps.length) hasJump = true;\n if (jumps.length || moves.length) pieces.push({ r, c, jumps, moves });\n }\n if (hasJump) return pieces.filter(p => p.jumps.length).map(p => ({ ...p, moves: [] as Pos[] }));\n return pieces;\n};\n\nexport default function Checkers() {\n const [board, setBoard] = useState(initBoard);\n const [turn, setTurn] = useState<'b' | 'r'>('b');\n const [sel, setSel] = useState<Pos | null>(null);\n const [valid, setValid] = useState<Pos[]>([]);\n const [caps, setCaps] = useState({ r: 0, b: 0 });\n const [winner, setWinner] = useState<string | null>(null);\n const [jumping, setJumping] = useState(false);\n\n const checkWin = useCallback((b: Cell[][], next: 'r' | 'b') => {\n const m = allMoves(b, next);\n if (m.length === 0) setWinner(next === 'b' ? 'Red' : 'Black');\n }, []);\n\n const handleClick = useCallback((r: number, c: number) => {\n if (winner || turn !== 'b') return;\n const moves = allMoves(board, 'b');\n const mustJump = moves.length > 0 && moves[0].jumps.length > 0;\n\n if (jumping && sel) {\n // mid multi-jump: only allow continuing jump from selected piece\n const jumps = getJumps(board, sel[0], sel[1]);\n const j = jumps.find(j => j.to[0] === r && j.to[1] === c);\n if (!j) return;\n const nb = clone(board);\n nb[r][c] = nb[sel[0]][sel[1]];\n nb[sel[0]][sel[1]] = null;\n nb[j.cap[0]][j.cap[1]] = null;\n if (r === 0 && nb[r][c]!.color === 'b') nb[r][c]!.king = true;\n setCaps(p => ({ ...p, r: p.r + 1 }));\n const moreJumps = getJumps(nb, r, c);\n if (moreJumps.length && !(r === 0 && !board[sel[0]][sel[1]]!.king)) {\n setBoard(nb); setSel([r, c]); setValid(moreJumps.map(j => j.to));\n return;\n }\n setBoard(nb); setSel(null); setValid([]); setJumping(false); setTurn('r');\n checkWin(nb, 'r');\n return;\n }\n\n // selecting a piece\n if (board[r][c]?.color === 'b') {\n const piece = moves.find(m => m.r === r && m.c === c);\n if (!piece) return;\n setSel([r, c]);\n setValid(mustJump ? piece.jumps.map(j => j.to) : piece.moves);\n return;\n }\n\n // moving to a square\n if (!sel || !valid.some(([vr, vc]) => vr === r && vc === c)) return;\n const nb = clone(board);\n if (mustJump) {\n const piece = moves.find(m => m.r === sel[0] && m.c === sel[1])!;\n const j = piece.jumps.find(j => j.to[0] === r && j.to[1] === c)!;\n nb[r][c] = nb[sel[0]][sel[1]]; nb[sel[0]][sel[1]] = null;\n nb[j.cap[0]][j.cap[1]] = null;\n const wasKing = nb[r][c]!.king;\n if (r === 0 && nb[r][c]!.color === 'b') nb[r][c]!.king = true;\n setCaps(p => ({ ...p, r: p.r + 1 }));\n const moreJumps = getJumps(nb, r, c);\n if (moreJumps.length && !(r === 0 && !wasKing)) {\n setBoard(nb); setSel([r, c]); setValid(moreJumps.map(j => j.to)); setJumping(true);\n return;\n }\n } else {\n nb[r][c] = nb[sel[0]][sel[1]]; nb[sel[0]][sel[1]] = null;\n if (r === 0 && nb[r][c]!.color === 'b') nb[r][c]!.king = true;\n }\n setBoard(nb); setSel(null); setValid([]); setTurn('r');\n checkWin(nb, 'r');\n }, [board, turn, sel, valid, winner, jumping, checkWin]);\n\n // AI turn\n useEffect(() => {\n if (turn !== 'r' || winner) return;\n const t = setTimeout(() => {\n const moves = allMoves(board, 'r');\n if (moves.length === 0) { setWinner('Black'); return; }\n const mustJump = moves[0].jumps.length > 0;\n const pick = moves[Math.floor(Math.random() * moves.length)];\n const nb = clone(board);\n let cr = pick.r, cc = pick.c, capCount = 0;\n if (mustJump) {\n let jumps = pick.jumps;\n while (jumps.length) {\n const j = jumps[Math.floor(Math.random() * jumps.length)];\n nb[j.to[0]][j.to[1]] = nb[cr][cc]; nb[cr][cc] = null;\n nb[j.cap[0]][j.cap[1]] = null; capCount++;\n const wasKing = nb[j.to[0]][j.to[1]]!.king;\n if (j.to[0] === 7) nb[j.to[0]][j.to[1]]!.king = true;\n cr = j.to[0]; cc = j.to[1];\n if (j.to[0] === 7 && !wasKing) break;\n jumps = getJumps(nb, cr, cc);\n }\n } else {\n const m = pick.moves[Math.floor(Math.random() * pick.moves.length)];\n nb[m[0]][m[1]] = nb[cr][cc]; nb[cr][cc] = null;\n if (m[0] === 7) nb[m[0]][m[1]]!.king = true;\n }\n setCaps(p => ({ ...p, b: p.b + capCount }));\n setBoard(nb); setTurn('b');\n checkWin(nb, 'b');\n }, 400);\n return () => clearTimeout(t);\n }, [turn, board, winner, checkWin]);\n\n const reset = () => { setBoard(initBoard()); setTurn('b'); setSel(null); setValid([]); setCaps({ r: 0, b: 0 }); setWinner(null); setJumping(false); };\n const isValid = (r: number, c: number) => valid.some(([vr, vc]) => vr === r && vc === c);\n const isSel = (r: number, c: number) => sel?.[0] === r && sel?.[1] === c;\n\n return (\n <div className=\"flex flex-col items-center gap-2 p-2\">\n <div className=\"flex items-center justify-between w-full max-w-[352px]\">\n <span className=\"text-sm font-medium\">{winner ? `${winner} wins!` : turn === 'b' ? 'Your turn (Black)' : 'Red is thinking...'}</span>\n <button onClick={reset} className=\"px-3 py-1 text-xs bg-gray-700 text-white rounded hover:bg-gray-600\">New Game</button>\n </div>\n <div className=\"text-xs text-gray-500 flex gap-4\">\n <span>Red captured: {caps.r}</span><span>Black captured: {caps.b}</span>\n </div>\n <div className=\"border-2 border-gray-800 inline-block\">\n {board.map((row, r) => (\n <div key={r} className=\"flex\">\n {row.map((cell, c) => {\n const dark = (r + c) % 2 === 1;\n return (\n <div key={c} onClick={() => dark && handleClick(r, c)}\n className={`w-[41px] h-[41px] flex items-center justify-center ${dark ? 'bg-emerald-800' : 'bg-amber-100'} ${isValid(r, c) ? 'ring-2 ring-inset ring-green-400 bg-green-700/60 cursor-pointer' : ''} ${dark ? 'cursor-pointer' : ''}`}>\n {cell && (\n <div className={`w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shadow-md ${cell.color === 'r' ? 'bg-red-600 border-2 border-red-400' : 'bg-gray-900 border-2 border-gray-600'} ${isSel(r, c) ? 'ring-2 ring-yellow-400 ring-offset-1' : ''}`}>\n {cell.king && <span className=\"text-yellow-300 text-sm\">&#9813;</span>}\n </div>\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"]}
@@ -1,190 +0,0 @@
1
- import { useState, useCallback } from 'react';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
-
4
- // src/apps/Chess.tsx
5
- var ICONS = {
6
- wK: "\u2654",
7
- wQ: "\u2655",
8
- wR: "\u2656",
9
- wB: "\u2657",
10
- wN: "\u2658",
11
- wP: "\u2659",
12
- bK: "\u265A",
13
- bQ: "\u265B",
14
- bR: "\u265C",
15
- bB: "\u265D",
16
- bN: "\u265E",
17
- bP: "\u265F"
18
- };
19
- var initBoard = () => {
20
- const b = Array.from({ length: 8 }, () => Array(8).fill(null));
21
- const back = ["R", "N", "B", "Q", "K", "B", "N", "R"];
22
- for (let c = 0; c < 8; c++) {
23
- b[0][c] = { type: back[c], color: "b" };
24
- b[1][c] = { type: "P", color: "b" };
25
- b[6][c] = { type: "P", color: "w" };
26
- b[7][c] = { type: back[c], color: "w" };
27
- }
28
- return b;
29
- };
30
- var inBounds = (r, c) => r >= 0 && r < 8 && c >= 0 && c < 8;
31
- function getValidMoves(board, [r, c]) {
32
- const p = board[r][c];
33
- if (!p) return [];
34
- const moves = [];
35
- const add = (nr, nc) => {
36
- if (!inBounds(nr, nc)) return false;
37
- const t = board[nr][nc];
38
- if (t && t.color === p.color) return false;
39
- moves.push([nr, nc]);
40
- return !t;
41
- };
42
- const slide = (dr, dc) => {
43
- for (let i = 1; i < 8; i++) if (!add(r + dr * i, c + dc * i)) break;
44
- };
45
- switch (p.type) {
46
- case "P": {
47
- const dir = p.color === "w" ? -1 : 1;
48
- const start = p.color === "w" ? 6 : 1;
49
- if (inBounds(r + dir, c) && !board[r + dir][c]) {
50
- moves.push([r + dir, c]);
51
- if (r === start && !board[r + 2 * dir][c]) moves.push([r + 2 * dir, c]);
52
- }
53
- for (const dc of [-1, 1]) {
54
- const nr = r + dir, nc = c + dc;
55
- if (inBounds(nr, nc) && board[nr][nc] && board[nr][nc].color !== p.color)
56
- moves.push([nr, nc]);
57
- }
58
- break;
59
- }
60
- case "R":
61
- [[-1, 0], [1, 0], [0, -1], [0, 1]].forEach(([dr, dc]) => slide(dr, dc));
62
- break;
63
- case "B":
64
- [[-1, -1], [-1, 1], [1, -1], [1, 1]].forEach(([dr, dc]) => slide(dr, dc));
65
- break;
66
- case "Q":
67
- [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]].forEach(([dr, dc]) => slide(dr, dc));
68
- break;
69
- case "N":
70
- [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]].forEach(([dr, dc]) => add(r + dr, c + dc));
71
- break;
72
- case "K":
73
- [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]].forEach(([dr, dc]) => add(r + dr, c + dc));
74
- break;
75
- }
76
- return moves;
77
- }
78
- function cloneBoard(b) {
79
- return b.map((row) => row.map((p) => p ? { ...p } : null));
80
- }
81
- function Chess() {
82
- const [board, setBoard] = useState(initBoard);
83
- const [selected, setSelected] = useState(null);
84
- const [validMoves, setValidMoves] = useState([]);
85
- const [turn, setTurn] = useState("w");
86
- const [captured, setCaptured] = useState({ w: [], b: [] });
87
- const [gameOver, setGameOver] = useState(false);
88
- const aiMove = useCallback((b, cap) => {
89
- const allMoves = [];
90
- for (let r = 0; r < 8; r++)
91
- for (let c = 0; c < 8; c++)
92
- if (b[r][c]?.color === "b")
93
- getValidMoves(b, [r, c]).forEach((to) => allMoves.push({ from: [r, c], to }));
94
- if (!allMoves.length) {
95
- setGameOver(true);
96
- return;
97
- }
98
- const m = allMoves[Math.floor(Math.random() * allMoves.length)];
99
- const nb = cloneBoard(b);
100
- const newCap = { w: [...cap.w], b: [...cap.b] };
101
- const target = nb[m.to[0]][m.to[1]];
102
- if (target) newCap.w.push(ICONS[target.color + target.type]);
103
- nb[m.to[0]][m.to[1]] = nb[m.from[0]][m.from[1]];
104
- nb[m.from[0]][m.from[1]] = null;
105
- setBoard(nb);
106
- setCaptured(newCap);
107
- setTurn("w");
108
- }, []);
109
- const handleClick = (r, c) => {
110
- if (gameOver || turn !== "w") return;
111
- if (selected) {
112
- if (validMoves.some(([mr, mc]) => mr === r && mc === c)) {
113
- const nb = cloneBoard(board);
114
- const newCap = { w: [...captured.w], b: [...captured.b] };
115
- const target = nb[r][c];
116
- if (target) newCap.b.push(ICONS[target.color + target.type]);
117
- nb[r][c] = nb[selected[0]][selected[1]];
118
- nb[selected[0]][selected[1]] = null;
119
- setBoard(nb);
120
- setCaptured(newCap);
121
- setSelected(null);
122
- setValidMoves([]);
123
- setTurn("b");
124
- setTimeout(() => aiMove(nb, newCap), 300);
125
- return;
126
- }
127
- if (board[r][c]?.color === "w") {
128
- setSelected([r, c]);
129
- setValidMoves(getValidMoves(board, [r, c]));
130
- return;
131
- }
132
- setSelected(null);
133
- setValidMoves([]);
134
- return;
135
- }
136
- if (board[r][c]?.color === "w") {
137
- setSelected([r, c]);
138
- setValidMoves(getValidMoves(board, [r, c]));
139
- }
140
- };
141
- const reset = () => {
142
- setBoard(initBoard());
143
- setSelected(null);
144
- setValidMoves([]);
145
- setTurn("w");
146
- setCaptured({ w: [], b: [] });
147
- setGameOver(false);
148
- };
149
- const isValid = (r, c) => validMoves.some(([mr, mc]) => mr === r && mc === c);
150
- const isSel = (r, c) => selected?.[0] === r && selected?.[1] === c;
151
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 p-4", children: [
152
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full max-w-md", children: [
153
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-700 dark:text-gray-200", children: gameOver ? "Game Over" : turn === "w" ? "\u2654 White to move" : "\u265A Black thinking..." }),
154
- /* @__PURE__ */ jsx("button", { onClick: reset, className: "px-3 py-1 text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded hover:bg-gray-300 dark:hover:bg-gray-600", children: "New Game" })
155
- ] }),
156
- captured.b.length > 0 && /* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-500 dark:text-gray-400 w-full max-w-md", children: [
157
- "Captured: ",
158
- captured.b.join(" ")
159
- ] }),
160
- /* @__PURE__ */ jsx("div", { className: "border-2 border-gray-700 dark:border-gray-400 rounded overflow-hidden", children: board.map((row, r) => /* @__PURE__ */ jsx("div", { className: "flex", children: row.map((piece, c) => {
161
- const light = (r + c) % 2 === 0;
162
- const sel = isSel(r, c);
163
- const valid = isValid(r, c);
164
- return /* @__PURE__ */ jsxs(
165
- "div",
166
- {
167
- onClick: () => handleClick(r, c),
168
- className: `w-[52px] h-[52px] flex items-center justify-center text-3xl cursor-pointer relative select-none
169
- ${light ? "bg-amber-100 dark:bg-amber-200" : "bg-amber-700 dark:bg-amber-800"}
170
- ${sel ? "ring-2 ring-inset ring-blue-500" : ""}
171
- ${valid && piece ? "ring-2 ring-inset ring-red-400" : ""}
172
- `,
173
- children: [
174
- piece && /* @__PURE__ */ jsx("span", { className: piece.color === "w" ? "text-white drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]" : "text-gray-900 drop-shadow-[0_1px_1px_rgba(255,255,255,0.3)]", children: ICONS[piece.color + piece.type] }),
175
- valid && !piece && /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rounded-full bg-green-500 opacity-60" })
176
- ]
177
- },
178
- c
179
- );
180
- }) }, r)) }),
181
- captured.w.length > 0 && /* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-500 dark:text-gray-400 w-full max-w-md", children: [
182
- "Captured: ",
183
- captured.w.join(" ")
184
- ] })
185
- ] });
186
- }
187
-
188
- export { Chess as default };
189
- //# sourceMappingURL=Chess-C5BY45NA.js.map
190
- //# sourceMappingURL=Chess-C5BY45NA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/Chess.tsx"],"names":[],"mappings":"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","file":"Chess-C5BY45NA.js","sourcesContent":["import { useState, useCallback } from 'react'\n\ntype Piece = { type: string; color: 'w' | 'b' } | null\ntype Board = Piece[][]\ntype Pos = [number, number]\n\nconst ICONS: Record<string, string> = {\n wK: '♔', wQ: '♕', wR: '♖', wB: '♗', wN: '♘', wP: '♙',\n bK: '♚', bQ: '♛', bR: '♜', bB: '♝', bN: '♞', bP: '♟',\n}\n\nconst initBoard = (): Board => {\n const b: Board = Array.from({ length: 8 }, () => Array(8).fill(null))\n const back = ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R']\n for (let c = 0; c < 8; c++) {\n b[0][c] = { type: back[c], color: 'b' }\n b[1][c] = { type: 'P', color: 'b' }\n b[6][c] = { type: 'P', color: 'w' }\n b[7][c] = { type: back[c], color: 'w' }\n }\n return b\n}\n\nconst inBounds = (r: number, c: number) => r >= 0 && r < 8 && c >= 0 && c < 8\n\nfunction getValidMoves(board: Board, [r, c]: Pos): Pos[] {\n const p = board[r][c]\n if (!p) return []\n const moves: Pos[] = []\n const add = (nr: number, nc: number) => {\n if (!inBounds(nr, nc)) return false\n const t = board[nr][nc]\n if (t && t.color === p.color) return false\n moves.push([nr, nc])\n return !t\n }\n const slide = (dr: number, dc: number) => {\n for (let i = 1; i < 8; i++) if (!add(r + dr * i, c + dc * i)) break\n }\n\n switch (p.type) {\n case 'P': {\n const dir = p.color === 'w' ? -1 : 1\n const start = p.color === 'w' ? 6 : 1\n if (inBounds(r + dir, c) && !board[r + dir][c]) {\n moves.push([r + dir, c])\n if (r === start && !board[r + 2 * dir][c]) moves.push([r + 2 * dir, c])\n }\n for (const dc of [-1, 1]) {\n const nr = r + dir, nc = c + dc\n if (inBounds(nr, nc) && board[nr][nc] && board[nr][nc]!.color !== p.color)\n moves.push([nr, nc])\n }\n break\n }\n case 'R': [[-1,0],[1,0],[0,-1],[0,1]].forEach(([dr,dc]) => slide(dr,dc)); break\n case 'B': [[-1,-1],[-1,1],[1,-1],[1,1]].forEach(([dr,dc]) => slide(dr,dc)); break\n case 'Q': [[-1,0],[1,0],[0,-1],[0,1],[-1,-1],[-1,1],[1,-1],[1,1]].forEach(([dr,dc]) => slide(dr,dc)); break\n case 'N': [[-2,-1],[-2,1],[-1,-2],[-1,2],[1,-2],[1,2],[2,-1],[2,1]].forEach(([dr,dc]) => add(r+dr,c+dc)); break\n case 'K': [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]].forEach(([dr,dc]) => add(r+dr,c+dc)); break\n }\n return moves\n}\n\nfunction cloneBoard(b: Board): Board { return b.map(row => row.map(p => p ? { ...p } : null)) }\n\nexport default function Chess() {\n const [board, setBoard] = useState<Board>(initBoard)\n const [selected, setSelected] = useState<Pos | null>(null)\n const [validMoves, setValidMoves] = useState<Pos[]>([])\n const [turn, setTurn] = useState<'w' | 'b'>('w')\n const [captured, setCaptured] = useState<{ w: string[]; b: string[] }>({ w: [], b: [] })\n const [gameOver, setGameOver] = useState(false)\n\n const aiMove = useCallback((b: Board, cap: { w: string[]; b: string[] }) => {\n const allMoves: { from: Pos; to: Pos }[] = []\n for (let r = 0; r < 8; r++)\n for (let c = 0; c < 8; c++)\n if (b[r][c]?.color === 'b')\n getValidMoves(b, [r, c]).forEach(to => allMoves.push({ from: [r, c], to }))\n if (!allMoves.length) { setGameOver(true); return }\n const m = allMoves[Math.floor(Math.random() * allMoves.length)]\n const nb = cloneBoard(b)\n const newCap = { w: [...cap.w], b: [...cap.b] }\n const target = nb[m.to[0]][m.to[1]]\n if (target) newCap.w.push(ICONS[target.color + target.type])\n nb[m.to[0]][m.to[1]] = nb[m.from[0]][m.from[1]]\n nb[m.from[0]][m.from[1]] = null\n setBoard(nb)\n setCaptured(newCap)\n setTurn('w')\n }, [])\n\n const handleClick = (r: number, c: number) => {\n if (gameOver || turn !== 'w') return\n if (selected) {\n if (validMoves.some(([mr, mc]) => mr === r && mc === c)) {\n const nb = cloneBoard(board)\n const newCap = { w: [...captured.w], b: [...captured.b] }\n const target = nb[r][c]\n if (target) newCap.b.push(ICONS[target.color + target.type])\n nb[r][c] = nb[selected[0]][selected[1]]\n nb[selected[0]][selected[1]] = null\n setBoard(nb)\n setCaptured(newCap)\n setSelected(null)\n setValidMoves([])\n setTurn('b')\n setTimeout(() => aiMove(nb, newCap), 300)\n return\n }\n if (board[r][c]?.color === 'w') {\n setSelected([r, c])\n setValidMoves(getValidMoves(board, [r, c]))\n return\n }\n setSelected(null)\n setValidMoves([])\n return\n }\n if (board[r][c]?.color === 'w') {\n setSelected([r, c])\n setValidMoves(getValidMoves(board, [r, c]))\n }\n }\n\n const reset = () => {\n setBoard(initBoard())\n setSelected(null)\n setValidMoves([])\n setTurn('w')\n setCaptured({ w: [], b: [] })\n setGameOver(false)\n }\n\n const isValid = (r: number, c: number) => validMoves.some(([mr, mc]) => mr === r && mc === c)\n const isSel = (r: number, c: number) => selected?.[0] === r && selected?.[1] === c\n\n return (\n <div className=\"flex flex-col items-center gap-3 p-4\">\n <div className=\"flex items-center justify-between w-full max-w-md\">\n <span className=\"text-sm font-semibold text-gray-700 dark:text-gray-200\">\n {gameOver ? 'Game Over' : turn === 'w' ? '♔ White to move' : '♚ Black thinking...'}\n </span>\n <button onClick={reset} className=\"px-3 py-1 text-xs font-medium bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded hover:bg-gray-300 dark:hover:bg-gray-600\">\n New Game\n </button>\n </div>\n\n {captured.b.length > 0 && (\n <div className=\"text-sm text-gray-500 dark:text-gray-400 w-full max-w-md\">\n Captured: {captured.b.join(' ')}\n </div>\n )}\n\n <div className=\"border-2 border-gray-700 dark:border-gray-400 rounded overflow-hidden\">\n {board.map((row, r) => (\n <div key={r} className=\"flex\">\n {row.map((piece, c) => {\n const light = (r + c) % 2 === 0\n const sel = isSel(r, c)\n const valid = isValid(r, c)\n return (\n <div\n key={c}\n onClick={() => handleClick(r, c)}\n className={`w-[52px] h-[52px] flex items-center justify-center text-3xl cursor-pointer relative select-none\n ${light ? 'bg-amber-100 dark:bg-amber-200' : 'bg-amber-700 dark:bg-amber-800'}\n ${sel ? 'ring-2 ring-inset ring-blue-500' : ''}\n ${valid && piece ? 'ring-2 ring-inset ring-red-400' : ''}\n `}\n >\n {piece && <span className={piece.color === 'w' ? 'text-white drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]' : 'text-gray-900 drop-shadow-[0_1px_1px_rgba(255,255,255,0.3)]'}>\n {ICONS[piece.color + piece.type]}\n </span>}\n {valid && !piece && <div className=\"w-3 h-3 rounded-full bg-green-500 opacity-60\" />}\n </div>\n )\n })}\n </div>\n ))}\n </div>\n\n {captured.w.length > 0 && (\n <div className=\"text-sm text-gray-500 dark:text-gray-400 w-full max-w-md\">\n Captured: {captured.w.join(' ')}\n </div>\n )}\n </div>\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/Documents.tsx"],"names":[],"mappings":"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","file":"Documents-SLODLCU4.js","sourcesContent":["/**\n * Documents — windowed viewer / light editor for plain-text and Word\n * documents. TXT-family files (.txt, .md, .csv, .log, .json, .xml,\n * .html, .css, .ts, .tsx, .js, .jsx, .py, .yml, .yaml, .toml, .sh)\n * open in an editable textarea. Word .docx files are converted to\n * read-only HTML via mammoth (an optional peer dep).\n *\n * Open files via the toolbar's Open button or by dragging them onto\n * the window.\n */\nimport { useState, useRef, useEffect } from 'react';\nimport { WindowTitle } from '../shell/Modal';\nimport toast from '../shell/toast';\nimport AboutApp from './_about';\n\nconst TITLE_DISPLAY_MAX = 24;\nfunction truncateForTitle(s: string) {\n return s.length > TITLE_DISPLAY_MAX ? `${s.slice(0, TITLE_DISPLAY_MAX - 1)}…` : s;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, c => ({\n '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;',\n }[c] || c));\n}\n\nconst TEXT_EXTS = new Set([\n 'txt', 'md', 'markdown', 'csv', 'tsv', 'log', 'json', 'xml',\n 'html', 'htm', 'css', 'js', 'jsx', 'ts', 'tsx', 'py', 'rb',\n 'go', 'rs', 'java', 'c', 'h', 'cpp', 'hpp', 'sh', 'bash',\n 'yml', 'yaml', 'toml', 'ini', 'conf', 'env', 'sql',\n]);\nconst DOCX_EXTS = new Set(['docx']);\n\ninterface DocData {\n filename: string;\n kind: 'text' | 'docx';\n content: string;\n /** Original mime / extension hint for the download button. */\n ext: string;\n}\n\nconst BLANK_DOC: DocData = { filename: 'Untitled', kind: 'docx', content: '', ext: 'docx' };\n\nexport default function Documents() {\n // Documents is for editing — open with a blank paper-style canvas so the\n // user can start typing immediately. Loading a file replaces this state.\n const [data, setData] = useState<DocData>(BLANK_DOC);\n const [busy, setBusy] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [edited, setEdited] = useState(false);\n const fileRef = useRef<HTMLInputElement>(null);\n const editorRef = useRef<HTMLDivElement>(null);\n\n // Apply a formatting command to the current selection in the editor.\n const exec = (cmd: string, value?: string) => {\n editorRef.current?.focus();\n document.execCommand(cmd, false, value);\n setEdited(true);\n };\n\n // Pull current HTML out of the editor (for save).\n const getEditorHtml = () => editorRef.current?.innerHTML ?? '';\n const getEditorText = () => editorRef.current?.innerText ?? '';\n\n const ingestFile = async (file: File) => {\n const ext = (file.name.split('.').pop() || '').toLowerCase();\n setBusy(true);\n try {\n if (TEXT_EXTS.has(ext) || (!DOCX_EXTS.has(ext) && file.type.startsWith('text/'))) {\n const text = await file.text();\n // Convert plain text → HTML so the contenteditable shows\n // line breaks correctly. Escape HTML special chars first.\n const html = escapeHtml(text).replace(/\\n/g, '<br>');\n setData({ filename: file.name, kind: 'text', content: html, ext });\n setEdited(false);\n } else if (DOCX_EXTS.has(ext)) {\n try {\n // mammoth is an optional peer dep — convert .docx → HTML.\n const mammoth = await import(/* @vite-ignore */ 'mammoth' as any);\n const buf = await file.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer: buf });\n setData({ filename: file.name, kind: 'docx', content: result.value || '<p><em>(empty document)</em></p>', ext });\n setEdited(false);\n } catch (err) {\n toast.error('Install the optional \"mammoth\" peer dep to read .docx files.');\n }\n } else if (ext === 'doc') {\n toast.error('.doc is the legacy Word binary format — convert to .docx first.');\n } else {\n toast.error(`Unsupported file type: .${ext || 'unknown'}`);\n }\n } finally {\n setBusy(false);\n }\n };\n\n const handlePick = () => fileRef.current?.click();\n const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) ingestFile(file);\n if (fileRef.current) fileRef.current.value = '';\n };\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n const file = e.dataTransfer.files?.[0];\n if (file) ingestFile(file);\n };\n\n const downloadCurrent = () => {\n if (!data) return;\n const html = getEditorHtml();\n if (data.kind === 'text') {\n // If the user added formatting, save as .html alongside; otherwise\n // strip back to plain text so the original .txt round-trips cleanly.\n const hasFormatting = /<(b|strong|i|em|u|font|span style)/i.test(html);\n if (hasFormatting) {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title><body style=\"font-family:ui-monospace,monospace;white-space:pre-wrap\">${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = `${data.filename.replace(/\\.[^.]+$/, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n } else {\n const text = getEditorText();\n const blob = new Blob([text], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a'); a.href = url; a.download = data.filename; a.click();\n URL.revokeObjectURL(url);\n }\n } else {\n const blob = new Blob([`<!doctype html><meta charset=\"utf-8\"><title>${escapeHtml(data.filename)}</title>${html}`], { type: 'text/html' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url; a.download = `${data.filename.replace(/\\.docx$/i, '')}.html`; a.click();\n URL.revokeObjectURL(url);\n }\n };\n\n const titleName = data?.filename ? truncateForTitle(data.filename) : 'Untitled';\n\n return (\n <div\n className=\"relative flex flex-col h-full\"\n onDragOver={(e) => { e.preventDefault(); if (!isDragging) setIsDragging(true); }}\n onDragLeave={(e) => { if (e.currentTarget === e.target) setIsDragging(false); }}\n onDrop={handleDrop}\n >\n <WindowTitle title={`${titleName}${edited ? ' •' : ''} - Documents`} />\n <AboutApp app=\"documents\" />\n\n {/* Toolbar */}\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-gray-200 bg-gray-50 shrink-0\">\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".txt,.md,.csv,.tsv,.log,.json,.xml,.html,.htm,.css,.js,.jsx,.ts,.tsx,.py,.rb,.go,.rs,.java,.c,.h,.cpp,.hpp,.sh,.bash,.yml,.yaml,.toml,.ini,.conf,.env,.sql,.docx,text/*\"\n onChange={handleFile}\n className=\"hidden\"\n />\n <button onClick={handlePick} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors flex items-center gap-1\">\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 00-1.883 2.542l.857 6a2.25 2.25 0 002.227 1.932H19.05a2.25 2.25 0 002.227-1.932l.857-6a2.25 2.25 0 00-1.883-2.542m-16.5 0V6A2.25 2.25 0 016 3.75h3.879a1.5 1.5 0 011.06.44l2.122 2.12a1.5 1.5 0 001.06.44H18A2.25 2.25 0 0120.25 9v.776\" />\n </svg>\n Open\n </button>\n <button onClick={downloadCurrent} className=\"text-xs text-gray-700 hover:text-gray-900 px-2 py-1 rounded hover:bg-gray-200 transition-colors\">\n Save\n </button>\n <span className=\"text-[10px] text-gray-400 ml-1\">TXT · DOCX · Code</span>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <span className=\"text-xs font-medium text-gray-700 truncate max-w-[200px]\" title={data.filename}>\n {data.filename}{edited ? ' •' : ''}\n </span>\n\n {/* Formatting toolbar */}\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <div className=\"flex items-center gap-0.5\">\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('bold')}\n className=\"px-2 py-1 text-xs rounded font-bold text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bold\">B</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('italic')}\n className=\"px-2 py-1 text-xs rounded italic text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Italic\">I</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('underline')}\n className=\"px-2 py-1 text-xs rounded underline text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Underline\">U</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('strikeThrough')}\n className=\"px-2 py-1 text-xs rounded line-through text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Strikethrough\">S</button>\n </div>\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <select onMouseDown={e => e.preventDefault()} onChange={e => { exec('fontSize', e.target.value); e.currentTarget.value = ''; }}\n defaultValue=\"\" className=\"text-xs border border-gray-300 rounded px-1 py-0.5 bg-white\">\n <option value=\"\" disabled>Size</option>\n <option value=\"1\">XS</option>\n <option value=\"2\">S</option>\n <option value=\"3\">M</option>\n <option value=\"4\">L</option>\n <option value=\"5\">XL</option>\n <option value=\"6\">2XL</option>\n </select>\n <input type=\"color\" defaultValue=\"#000000\" onChange={e => exec('foreColor', e.target.value)}\n className=\"w-7 h-6 border border-gray-300 rounded cursor-pointer\" title=\"Text color\" />\n <div className=\"h-4 w-px bg-gray-300 mx-1\" />\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertUnorderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Bulleted list\">• List</button>\n <button onMouseDown={e => e.preventDefault()} onClick={() => exec('insertOrderedList')}\n className=\"px-2 py-1 text-xs rounded text-gray-700 hover:bg-gray-200 transition-colors\" title=\"Numbered list\">1.</button>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 min-h-0 overflow-hidden\">\n {busy ? (\n <div className=\"flex items-center justify-center h-full text-sm text-gray-400\">Loading…</div>\n ) : (\n <div className={`h-full overflow-auto ${data.kind === 'docx' ? 'bg-gray-100 px-12 py-10' : 'bg-white'}`}>\n <div\n ref={editorRef}\n contentEditable\n suppressContentEditableWarning\n spellCheck={false}\n onInput={() => setEdited(true)}\n dangerouslySetInnerHTML={{ __html: data.content }}\n className={\n data.kind === 'docx'\n ? 'mx-auto max-w-[760px] bg-white p-12 shadow text-[14px] leading-relaxed text-gray-800 outline-none focus:ring-2 focus:ring-blue-400/40 prose prose-sm'\n : 'block w-full min-h-full p-4 font-mono text-[13px] leading-relaxed text-gray-800 bg-white outline-none whitespace-pre-wrap'\n }\n />\n </div>\n )}\n </div>\n\n {isDragging && (\n <div className=\"absolute inset-0 bg-blue-500/15 border-4 border-dashed border-blue-500 pointer-events-none flex items-center justify-center z-20\">\n <div className=\"px-4 py-2 rounded-md bg-blue-600 text-white text-sm font-medium shadow-lg\">\n Drop to open\n </div>\n </div>\n )}\n </div>\n );\n}\n\n"]}