@mblinkov/whats-missing 20.0.19 → 20.0.21
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/dist/whats-missing.cjs.js +6 -14
- package/dist/whats-missing.es.js +263 -160
- package/package.json +2 -1
- package/src/Game.styles.ts +7 -3
- package/src/Game.tsx +578 -360
package/dist/whats-missing.es.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx as t, jsxs as
|
|
2
|
-
import { useRef as
|
|
3
|
-
const
|
|
4
|
-
src: `${
|
|
1
|
+
import { jsx as t, jsxs as c, Fragment as ue } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as te, useEffect as P, useState as d, useMemo as he, useLayoutEffect as fe } from "react";
|
|
3
|
+
const pe = window.origin + "/cloud/speakid/games/whatsmissing/", V = (l, g) => l.map(([m, o]) => ({
|
|
4
|
+
src: `${pe}${g}/${o.replace(/\s/g, "%20")}.png`,
|
|
5
5
|
name: o
|
|
6
|
-
})),
|
|
6
|
+
})), ye = [
|
|
7
7
|
["apple", "apple"],
|
|
8
8
|
["banana", "banana"],
|
|
9
9
|
["bread", "bread"],
|
|
@@ -69,11 +69,11 @@ const ye = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (l, d) => l
|
|
|
69
69
|
["teddy_bear", "teddy bear"],
|
|
70
70
|
["yo-yo", "yo-yo"],
|
|
71
71
|
["crayons", "crayons"]
|
|
72
|
-
],
|
|
73
|
-
food:
|
|
74
|
-
animals:
|
|
75
|
-
toys:
|
|
76
|
-
},
|
|
72
|
+
], ee = {
|
|
73
|
+
food: V(ye, "food"),
|
|
74
|
+
animals: V(be, "animals"),
|
|
75
|
+
toys: V(we, "toys")
|
|
76
|
+
}, xe = `
|
|
77
77
|
@keyframes spin {
|
|
78
78
|
from { transform: rotate(0deg); }
|
|
79
79
|
to { transform: rotate(360deg); }
|
|
@@ -81,15 +81,17 @@ const ye = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (l, d) => l
|
|
|
81
81
|
`;
|
|
82
82
|
if (typeof document < "u" && !document.getElementById("spin-keyframes")) {
|
|
83
83
|
const l = document.createElement("style");
|
|
84
|
-
l.id = "spin-keyframes", l.innerHTML =
|
|
84
|
+
l.id = "spin-keyframes", l.innerHTML = xe, document.head.appendChild(l);
|
|
85
85
|
}
|
|
86
|
-
const
|
|
86
|
+
const ve = {
|
|
87
87
|
animation: "spin 1.4s linear infinite"
|
|
88
88
|
}, n = {
|
|
89
89
|
gmCenterScreen: {
|
|
90
90
|
position: "relative",
|
|
91
91
|
zIndex: 1,
|
|
92
|
-
|
|
92
|
+
// use percent so the component fits inside the centered square container
|
|
93
|
+
// (100vh caused overflow on tablets because it measured the viewport, not the container)
|
|
94
|
+
minHeight: "100%",
|
|
93
95
|
width: "100%",
|
|
94
96
|
display: "flex",
|
|
95
97
|
flexDirection: "column",
|
|
@@ -144,7 +146,8 @@ const ke = {
|
|
|
144
146
|
position: "relative",
|
|
145
147
|
width: "100%",
|
|
146
148
|
maxWidth: "600px",
|
|
147
|
-
|
|
149
|
+
// should fill the parent square, not the full viewport
|
|
150
|
+
minHeight: "100%",
|
|
148
151
|
display: "flex",
|
|
149
152
|
flexDirection: "column",
|
|
150
153
|
alignItems: "center",
|
|
@@ -233,125 +236,159 @@ const ke = {
|
|
|
233
236
|
},
|
|
234
237
|
gmHourglass: {
|
|
235
238
|
fontSize: "42px",
|
|
236
|
-
...
|
|
239
|
+
...ve
|
|
237
240
|
}
|
|
238
|
-
},
|
|
241
|
+
}, ke = () => {
|
|
239
242
|
const l = document.createElement("style");
|
|
240
243
|
l.textContent = `
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
#whats-missing-root img {
|
|
246
|
-
max-width: 100%;
|
|
247
|
-
height: auto;
|
|
248
|
-
display: block;
|
|
249
|
-
user-select: none;
|
|
250
|
-
}
|
|
251
|
-
html, body { margin: 0; padding: 0; }
|
|
244
|
+
/* scope only inside game root */
|
|
245
|
+
#whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
|
|
246
|
+
#whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
|
|
252
247
|
`, document.head.appendChild(l);
|
|
253
|
-
},
|
|
254
|
-
const m = Array.from({ length: l.length + 1 }, () => Array(
|
|
248
|
+
}, ze = (l, g) => {
|
|
249
|
+
const m = Array.from({ length: l.length + 1 }, () => Array(g.length + 1).fill(0));
|
|
255
250
|
for (let o = 0; o <= l.length; o++) m[o][0] = o;
|
|
256
|
-
for (let o = 0; o <=
|
|
251
|
+
for (let o = 0; o <= g.length; o++) m[0][o] = o;
|
|
257
252
|
for (let o = 1; o <= l.length; o++)
|
|
258
|
-
for (let
|
|
259
|
-
m[o][
|
|
260
|
-
return m[l.length][
|
|
253
|
+
for (let u = 1; u <= g.length; u++)
|
|
254
|
+
m[o][u] = l[o - 1] === g[u - 1] ? m[o - 1][u - 1] : Math.min(m[o - 1][u - 1], m[o][u - 1], m[o - 1][u]) + 1;
|
|
255
|
+
return m[l.length][g.length];
|
|
261
256
|
};
|
|
262
|
-
function
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const [d, m] = r(null), [o, g] = r([]), [C, oe] = r(4), [v, D] = r(!1), [S, P] = r(1), [x, ie] = r(null), [u, z] = r("ready"), [O, U] = r(3), [H, B] = r(10), [A, V] = r(20), [re, L] = r(0), [T, j] = r(!1), [M, q] = r(""), [w, F] = r(!1), [W, _] = r(!1), [K, k] = r(null), [se, E] = r([]), [ae, Z] = r([]), [h, le] = r(!1), [R, X] = r(null), [b, G] = r(1);
|
|
268
|
-
N(() => {
|
|
269
|
-
const e = () => {
|
|
270
|
-
const a = window.innerWidth < 768;
|
|
271
|
-
if (le(a), a) {
|
|
272
|
-
X(null);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const f = 0.97, p = 1e3, y = Math.min(window.innerWidth, window.innerHeight), I = Math.max(360, Math.round(y * f)), te = Math.min(I, p);
|
|
276
|
-
X(te);
|
|
277
|
-
}, i = () => {
|
|
257
|
+
function Ce(l, g = { minDesktopWidth: 1200, forceResize: !1 }) {
|
|
258
|
+
const m = te(null), o = g.minDesktopWidth ?? 1200, u = !!g.forceResize;
|
|
259
|
+
fe(() => {
|
|
260
|
+
if (typeof window > "u" || !l || !l.current) return;
|
|
261
|
+
const s = l.current, F = () => {
|
|
278
262
|
try {
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if ($ && !isNaN($)) {
|
|
290
|
-
G($);
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
263
|
+
const i = document.body, a = getComputedStyle(i), y = parseFloat(i.style && i.style.zoom || "");
|
|
264
|
+
if (y && !isNaN(y) && y > 0) return y;
|
|
265
|
+
const k = parseFloat(a.zoom || "");
|
|
266
|
+
if (k && !isNaN(k) && k > 0) return k;
|
|
267
|
+
const S = a.transform || a.webkitTransform || a.mozTransform;
|
|
268
|
+
if (S && S !== "none") {
|
|
269
|
+
const T = S.match(/matrix\(([^)]+)\)/);
|
|
270
|
+
if (T) {
|
|
271
|
+
const z = T[1].split(",").map((E) => parseFloat(E))[0];
|
|
272
|
+
if (z && !isNaN(z)) return z;
|
|
293
273
|
}
|
|
294
274
|
}
|
|
295
275
|
} catch {
|
|
296
276
|
}
|
|
297
|
-
|
|
277
|
+
return 1;
|
|
278
|
+
}, x = () => {
|
|
279
|
+
if (o && window.innerWidth < o) {
|
|
280
|
+
C();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const i = F();
|
|
284
|
+
if (!i || i === 1) {
|
|
285
|
+
C();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
m.current || (m.current = {
|
|
289
|
+
transform: s.style.transform || null,
|
|
290
|
+
transformOrigin: s.style.transformOrigin || null,
|
|
291
|
+
width: s.style.width || null,
|
|
292
|
+
height: s.style.height || null,
|
|
293
|
+
willChange: s.style.willChange || null
|
|
294
|
+
});
|
|
295
|
+
const a = 1 / i;
|
|
296
|
+
u && (s.style.width = `${i * 100}%`, s.style.height = `${i * 100}%`), s.style.transform = `scale(${a})`, s.style.transformOrigin = "top left", s.style.willChange = "transform", typeof process < "u" && process.env && process.env.NODE_ENV === "development" && console.debug("[useNeutralizeBodyZoom] applied scale:", { scale: i, inv: a, forceResize: u });
|
|
297
|
+
}, C = () => {
|
|
298
|
+
if (!m.current) return;
|
|
299
|
+
const i = m.current;
|
|
300
|
+
i.transform === null ? s.style.removeProperty("transform") : s.style.transform = i.transform, i.transformOrigin === null ? s.style.removeProperty("transform-origin") : s.style.transformOrigin = i.transformOrigin, i.width === null ? s.style.removeProperty("width") : s.style.width = i.width, i.height === null ? s.style.removeProperty("height") : s.style.height = i.height, i.willChange === null ? s.style.removeProperty("will-change") : s.style.willChange = i.willChange, m.current = null, process.env.NODE_ENV === "development" && console.debug("[useNeutralizeBodyZoom] restored original styles");
|
|
298
301
|
};
|
|
299
|
-
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
302
|
+
let w = 0;
|
|
303
|
+
const v = () => {
|
|
304
|
+
cancelAnimationFrame(w), w = requestAnimationFrame(x);
|
|
305
|
+
}, p = new MutationObserver((i) => {
|
|
306
|
+
for (const a of i)
|
|
307
|
+
if (a.type === "attributes" && (a.attributeName === "style" || a.attributeName === "class")) {
|
|
308
|
+
v();
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
return p.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), window.addEventListener("resize", v), v(), () => {
|
|
313
|
+
cancelAnimationFrame(w), p.disconnect(), window.removeEventListener("resize", v), C();
|
|
314
|
+
};
|
|
315
|
+
}, [l, o, u]);
|
|
316
|
+
}
|
|
317
|
+
function Me() {
|
|
318
|
+
const l = te(null);
|
|
319
|
+
Ce(l, { minDesktopWidth: 1200, forceResize: !1 }), P(() => (ke(), () => {
|
|
320
|
+
document.body.style.overflow = "";
|
|
321
|
+
}), []);
|
|
322
|
+
const [g, m] = d(null), [o, u] = d([]), [s, F] = d(4), [x, C] = d(!1), [w, v] = d(1), [p, i] = d(null), [a, y] = d("ready"), [k, S] = d(3), [T, B] = d(10), [z, E] = d(20), [ne, W] = d(0), [A, N] = d(!1), [H, Y] = d(""), [R, j] = d(!1), [D, $] = d(!1), [q, L] = d(null), [oe, G] = d([]), [re, Z] = d([]), [b, ie] = d(!1), [Se, _] = d(1), [U, K] = d(null);
|
|
323
|
+
P(() => {
|
|
324
|
+
const e = () => {
|
|
325
|
+
const h = window.visualViewport, f = h ? Math.round(h.width) : window.innerWidth, I = h ? Math.round(h.height) : window.innerHeight, M = f < 768;
|
|
326
|
+
if (ie(M), M)
|
|
327
|
+
K(null), _(1);
|
|
328
|
+
else {
|
|
329
|
+
const ce = Math.min(f, I), me = Math.max(360, Math.round(ce * 0.97)), ge = Math.min(me, 1e3);
|
|
330
|
+
K(ge), _(1);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
e(), window.addEventListener("resize", e);
|
|
334
|
+
const r = window.visualViewport;
|
|
335
|
+
return r && typeof r.addEventListener == "function" && (r.addEventListener("resize", e), r.addEventListener("scroll", e)), () => {
|
|
336
|
+
window.removeEventListener("resize", e), r && typeof r.removeEventListener == "function" && (r.removeEventListener("resize", e), r.removeEventListener("scroll", e));
|
|
303
337
|
};
|
|
304
338
|
}, []);
|
|
305
|
-
const
|
|
306
|
-
if (!
|
|
307
|
-
const e =
|
|
308
|
-
|
|
309
|
-
},
|
|
310
|
-
const
|
|
311
|
-
let
|
|
312
|
-
for (;
|
|
313
|
-
|
|
314
|
-
|
|
339
|
+
const X = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), J = () => {
|
|
340
|
+
if (!g) return;
|
|
341
|
+
const e = X(ee[g]);
|
|
342
|
+
u(e), C(!0), N(!1), v(1), W(0), G([]), Z([]), Q(e, [], !0);
|
|
343
|
+
}, Q = (e = o, r = re, h = !1) => {
|
|
344
|
+
const f = X(e.length ? e : ee[g]);
|
|
345
|
+
let I = Math.floor(Math.random() * f.length), M = f[I].name, O = 0;
|
|
346
|
+
for (; r.includes(M) && O < 20; )
|
|
347
|
+
I = Math.floor(Math.random() * f.length), M = f[I].name, O++;
|
|
348
|
+
u(f), i(I), Z([...r, M]), j(!1), Y(""), E(20), L(null), h ? (y("ready"), S(3), B(10)) : (y("memorize"), B(10));
|
|
315
349
|
};
|
|
316
|
-
|
|
317
|
-
if (!(!
|
|
318
|
-
if (
|
|
319
|
-
if (
|
|
350
|
+
P(() => {
|
|
351
|
+
if (!(!x || A || R)) {
|
|
352
|
+
if (a === "ready")
|
|
353
|
+
if (k <= 0) y("memorize");
|
|
320
354
|
else {
|
|
321
|
-
const e = setTimeout(() =>
|
|
355
|
+
const e = setTimeout(() => S((r) => r - 1), 1e3);
|
|
322
356
|
return () => clearTimeout(e);
|
|
323
357
|
}
|
|
324
|
-
if (
|
|
325
|
-
if (
|
|
358
|
+
if (a === "memorize")
|
|
359
|
+
if (T <= 0) y("guess");
|
|
326
360
|
else {
|
|
327
|
-
const e = setTimeout(() => B((
|
|
361
|
+
const e = setTimeout(() => B((r) => r - 1), 1e3);
|
|
328
362
|
return () => clearTimeout(e);
|
|
329
363
|
}
|
|
330
|
-
if (
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
|
|
364
|
+
if (a === "guess") {
|
|
365
|
+
if (z <= 0) {
|
|
366
|
+
j(!0), L("wrong");
|
|
367
|
+
const r = o[p].name;
|
|
368
|
+
G((h) => [
|
|
369
|
+
...h,
|
|
370
|
+
{ round: w, answer: H, correct: r, result: "wrong" }
|
|
371
|
+
]);
|
|
335
372
|
return;
|
|
336
373
|
}
|
|
337
|
-
const e = setTimeout(() =>
|
|
374
|
+
const e = setTimeout(() => E((r) => r - 1), 1e3);
|
|
338
375
|
return () => clearTimeout(e);
|
|
339
376
|
}
|
|
340
377
|
}
|
|
341
|
-
}, [
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
const e = o[
|
|
345
|
-
let
|
|
346
|
-
|
|
347
|
-
|
|
378
|
+
}, [a, k, T, z, x, A, R, o, p, w, H]);
|
|
379
|
+
const se = () => {
|
|
380
|
+
if (p === null || D) return;
|
|
381
|
+
const e = o[p].name, r = H.toLowerCase().trim();
|
|
382
|
+
let h = "wrong";
|
|
383
|
+
r === e ? (W((f) => f + 1), L("correct"), h = "correct") : ze(r, e) === 1 ? (W((f) => f + 0.5), L("almost"), h = "almost") : (L("wrong"), h = "wrong"), G((f) => [...f, { round: w, answer: r, correct: e, result: h }]), $(!0), setTimeout(() => {
|
|
384
|
+
$(!1), j(!0);
|
|
348
385
|
}, 600);
|
|
349
|
-
},
|
|
350
|
-
|
|
351
|
-
},
|
|
386
|
+
}, le = () => w < s ? (v((e) => e + 1), Q()) : N(!0), ae = () => {
|
|
387
|
+
C(!1), N(!1), m(null);
|
|
388
|
+
}, de = he(
|
|
352
389
|
() => (
|
|
353
390
|
// ensure logo is positioned inside the square container
|
|
354
|
-
/* @__PURE__ */ t("div", { style: { ...n.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */
|
|
391
|
+
/* @__PURE__ */ t("div", { style: { ...n.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ c("picture", { children: [
|
|
355
392
|
/* @__PURE__ */ t("source", { srcSet: window.origin + "/cloud/speakid/games/whatsmissing/logo.svg", type: "image/svg+xml" }),
|
|
356
393
|
/* @__PURE__ */ t("img", { src: window.origin + "/cloud/speakid/games/whatsmissing/logo.png", alt: "SPEAKID Logo", style: n.gmLogoImg, loading: "lazy" })
|
|
357
394
|
] }) })
|
|
@@ -376,115 +413,181 @@ function Me() {
|
|
|
376
413
|
"div",
|
|
377
414
|
{
|
|
378
415
|
style: {
|
|
379
|
-
width:
|
|
380
|
-
height:
|
|
416
|
+
width: b ? "100%" : U || 1e3,
|
|
417
|
+
height: b ? "100%" : U || 1e3,
|
|
381
418
|
display: "flex",
|
|
382
419
|
justifyContent: "center",
|
|
383
420
|
alignItems: "center",
|
|
384
421
|
overflow: "hidden",
|
|
385
|
-
borderRadius:
|
|
422
|
+
borderRadius: b ? 0 : "20px",
|
|
386
423
|
background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
|
|
387
|
-
boxShadow:
|
|
388
|
-
margin:
|
|
424
|
+
boxShadow: b ? "none" : "0 0 40px rgba(0,0,0,0.1)",
|
|
425
|
+
margin: b ? "0 auto" : "unset",
|
|
389
426
|
position: "relative"
|
|
427
|
+
// needed so absolute logo is inside the square
|
|
390
428
|
},
|
|
391
429
|
children: /* @__PURE__ */ t(
|
|
392
430
|
"div",
|
|
393
431
|
{
|
|
394
432
|
style: {
|
|
395
|
-
transform:
|
|
396
|
-
transformOrigin: "top left",
|
|
433
|
+
transform: "none",
|
|
397
434
|
width: "100%",
|
|
398
435
|
height: "100%",
|
|
399
436
|
display: "flex",
|
|
400
437
|
justifyContent: "center",
|
|
401
438
|
alignItems: "center"
|
|
402
439
|
},
|
|
403
|
-
children: /* @__PURE__ */
|
|
404
|
-
!
|
|
405
|
-
!
|
|
440
|
+
children: /* @__PURE__ */ c("div", { id: "whats-missing-root", children: [
|
|
441
|
+
!b && de,
|
|
442
|
+
!g && !x && /* @__PURE__ */ c("div", { style: n.gmCenterScreen, children: [
|
|
406
443
|
/* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "WHAT'S MISSING?" }),
|
|
407
444
|
/* @__PURE__ */ t("p", { style: n.gmBodyM, children: "Select a theme:" }),
|
|
408
445
|
/* @__PURE__ */ t("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ t("button", { style: n.gmButton, onClick: () => m(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
|
|
409
|
-
/* @__PURE__ */
|
|
446
|
+
/* @__PURE__ */ c("div", { style: { marginTop: 24 }, children: [
|
|
410
447
|
/* @__PURE__ */ t("p", { style: n.gmBodyS, children: "Choose number of rounds:" }),
|
|
411
448
|
/* @__PURE__ */ t("div", { style: { display: "flex", gap: 12, marginTop: 8 }, children: [3, 4, 5].map((e) => /* @__PURE__ */ t(
|
|
412
449
|
"button",
|
|
413
450
|
{
|
|
414
|
-
style: {
|
|
415
|
-
|
|
451
|
+
style: {
|
|
452
|
+
...n.gmButton,
|
|
453
|
+
...s === e ? n.gmButtonActive : {}
|
|
454
|
+
},
|
|
455
|
+
onClick: () => F(e),
|
|
416
456
|
children: e
|
|
417
457
|
},
|
|
418
458
|
e
|
|
419
459
|
)) })
|
|
420
460
|
] })
|
|
421
461
|
] }),
|
|
422
|
-
|
|
423
|
-
/* @__PURE__ */
|
|
462
|
+
g && !x && /* @__PURE__ */ c("div", { style: n.gmCenterScreen, children: [
|
|
463
|
+
/* @__PURE__ */ c("h1", { style: n.gmHeadline1, children: [
|
|
424
464
|
"Theme selected: ",
|
|
425
|
-
|
|
465
|
+
g
|
|
426
466
|
] }),
|
|
427
|
-
/* @__PURE__ */
|
|
467
|
+
/* @__PURE__ */ c("p", { style: n.gmBodyM, children: [
|
|
428
468
|
"Rounds: ",
|
|
429
|
-
|
|
469
|
+
s
|
|
430
470
|
] }),
|
|
431
|
-
/* @__PURE__ */ t("button", { style: n.gmButton, onClick:
|
|
471
|
+
/* @__PURE__ */ t("button", { style: n.gmButton, onClick: J, children: "▶ Start game" })
|
|
432
472
|
] }),
|
|
433
|
-
|
|
473
|
+
A && /* @__PURE__ */ c("div", { style: n.gmCenterScreen, children: [
|
|
434
474
|
/* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "Results" }),
|
|
435
|
-
/* @__PURE__ */
|
|
475
|
+
/* @__PURE__ */ c("h2", { style: n.gmHeadline3, children: [
|
|
436
476
|
"Your score: ",
|
|
437
|
-
|
|
477
|
+
ne,
|
|
438
478
|
" / ",
|
|
439
|
-
|
|
479
|
+
s
|
|
440
480
|
] }),
|
|
441
481
|
/* @__PURE__ */ t("p", { style: { ...n.gmBodyM, color: "#10b981", marginTop: 12 }, children: "Yahoo! You did it! 🍬✨" }),
|
|
442
|
-
/* @__PURE__ */
|
|
443
|
-
/* @__PURE__ */ t("thead", { children: /* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ c("table", { style: n.gmTable, children: [
|
|
483
|
+
/* @__PURE__ */ t("thead", { children: /* @__PURE__ */ c("tr", { children: [
|
|
444
484
|
/* @__PURE__ */ t("th", { children: "Round" }),
|
|
445
485
|
/* @__PURE__ */ t("th", { children: "Your Answer" }),
|
|
446
486
|
/* @__PURE__ */ t("th", { children: "Correct" }),
|
|
447
487
|
/* @__PURE__ */ t("th", { children: "Result" })
|
|
448
488
|
] }) }),
|
|
449
|
-
/* @__PURE__ */ t("tbody", { children:
|
|
489
|
+
/* @__PURE__ */ t("tbody", { children: oe.map((e, r) => /* @__PURE__ */ c("tr", { children: [
|
|
450
490
|
/* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.round }),
|
|
451
491
|
/* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.answer || "—" }),
|
|
452
492
|
/* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.correct }),
|
|
453
493
|
/* @__PURE__ */ t("td", { style: n.gmTableCell, children: e.result === "correct" ? "✔ Correct" : e.result === "almost" ? "◐ Almost (0.5)" : "✘ Wrong" })
|
|
454
|
-
] },
|
|
494
|
+
] }, r)) })
|
|
455
495
|
] }),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
/* @__PURE__ */ t("button", { style: n.gmButton, onClick:
|
|
458
|
-
/* @__PURE__ */ t("button", { style: n.gmButton, onClick:
|
|
496
|
+
/* @__PURE__ */ c("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
|
|
497
|
+
/* @__PURE__ */ t("button", { style: n.gmButton, onClick: J, children: "🔁 Play again" }),
|
|
498
|
+
/* @__PURE__ */ t("button", { style: n.gmButton, onClick: ae, children: "⬅️ Choose theme" })
|
|
459
499
|
] })
|
|
460
500
|
] }),
|
|
461
|
-
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
501
|
+
x && !A && /* @__PURE__ */ c("div", { style: n.gmGameLayout, children: [
|
|
502
|
+
/* @__PURE__ */ c(
|
|
503
|
+
"div",
|
|
504
|
+
{
|
|
505
|
+
style: {
|
|
506
|
+
minHeight: 160,
|
|
507
|
+
display: "flex",
|
|
508
|
+
flexDirection: "column",
|
|
509
|
+
justifyContent: "center",
|
|
510
|
+
alignItems: "center"
|
|
511
|
+
},
|
|
512
|
+
children: [
|
|
513
|
+
a === "ready" && /* @__PURE__ */ c(ue, { children: [
|
|
514
|
+
/* @__PURE__ */ t("h1", { style: { ...n.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
|
|
515
|
+
/* @__PURE__ */ t("div", { style: n.gmHourglass, children: "⏳" })
|
|
516
|
+
] }),
|
|
517
|
+
a === "memorize" && /* @__PURE__ */ c("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
|
|
518
|
+
"MEMORIZE (",
|
|
519
|
+
T,
|
|
520
|
+
")"
|
|
521
|
+
] }),
|
|
522
|
+
a === "guess" && !R && /* @__PURE__ */ c("p", { style: n.gmBodyM, children: [
|
|
523
|
+
"⏳ Time left: ",
|
|
524
|
+
z,
|
|
525
|
+
"s"
|
|
526
|
+
] })
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
),
|
|
530
|
+
a !== "ready" && /* @__PURE__ */ t(
|
|
531
|
+
"div",
|
|
532
|
+
{
|
|
533
|
+
style: {
|
|
534
|
+
...n.gmGrid,
|
|
535
|
+
gridTemplateColumns: b ? "repeat(2, 1fr)" : "repeat(3, 210px)",
|
|
536
|
+
gridAutoRows: b ? "150px" : "210px",
|
|
537
|
+
gap: b ? "12px" : "20px",
|
|
538
|
+
justifyItems: "center"
|
|
539
|
+
},
|
|
540
|
+
children: o.map((e, r) => {
|
|
541
|
+
const h = p === r && a === "guess" && !R;
|
|
542
|
+
return /* @__PURE__ */ t(
|
|
543
|
+
"div",
|
|
544
|
+
{
|
|
545
|
+
style: {
|
|
546
|
+
...n.gmCard,
|
|
547
|
+
...q === "correct" && p === r ? n.gmCorrect : {},
|
|
548
|
+
...q === "wrong" && p === r ? n.gmWrong : {}
|
|
549
|
+
},
|
|
550
|
+
children: !h && /* @__PURE__ */ t(
|
|
551
|
+
"img",
|
|
552
|
+
{
|
|
553
|
+
src: e.src,
|
|
554
|
+
alt: e.name,
|
|
555
|
+
style: {
|
|
556
|
+
width: "100%",
|
|
557
|
+
height: "100%",
|
|
558
|
+
objectFit: "cover"
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
},
|
|
563
|
+
r
|
|
564
|
+
);
|
|
565
|
+
})
|
|
566
|
+
}
|
|
567
|
+
),
|
|
568
|
+
/* @__PURE__ */ c("div", { style: { marginTop: 16, height: 80 }, children: [
|
|
569
|
+
a === "guess" && !R && /* @__PURE__ */ c("div", { children: [
|
|
570
|
+
/* @__PURE__ */ t(
|
|
571
|
+
"input",
|
|
572
|
+
{
|
|
573
|
+
type: "text",
|
|
574
|
+
placeholder: "Type the missing word",
|
|
575
|
+
value: H,
|
|
576
|
+
onChange: (e) => Y(e.target.value),
|
|
577
|
+
style: n.gmInput
|
|
578
|
+
}
|
|
579
|
+
),
|
|
580
|
+
/* @__PURE__ */ t(
|
|
581
|
+
"button",
|
|
582
|
+
{
|
|
583
|
+
style: { ...n.gmButton, marginLeft: 8 },
|
|
584
|
+
onClick: se,
|
|
585
|
+
disabled: D,
|
|
586
|
+
children: D ? "..." : "Check"
|
|
587
|
+
}
|
|
588
|
+
)
|
|
486
589
|
] }),
|
|
487
|
-
|
|
590
|
+
R && /* @__PURE__ */ t("button", { type: "button", style: n.gmButton, onClick: le, children: "Next round" })
|
|
488
591
|
] })
|
|
489
592
|
] })
|
|
490
593
|
] })
|
|
@@ -497,5 +600,5 @@ function Me() {
|
|
|
497
600
|
}
|
|
498
601
|
export {
|
|
499
602
|
Me as Game,
|
|
500
|
-
|
|
603
|
+
ee as themes
|
|
501
604
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mblinkov/whats-missing",
|
|
3
|
-
"version": "20.0.
|
|
3
|
+
"version": "20.0.21",
|
|
4
4
|
"main": "dist/whats-missing.umd.js",
|
|
5
5
|
"module": "dist/whats-missing.es.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"preview": "vite preview"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@types/node": "^24.7.2",
|
|
17
18
|
"@types/react": "^19.2.2",
|
|
18
19
|
"@types/react-dom": "^19.2.1",
|
|
19
20
|
"@vitejs/plugin-react": "^5.0.4",
|
package/src/Game.styles.ts
CHANGED
|
@@ -25,7 +25,9 @@ export const styles: Record<string, CSSProperties> = {
|
|
|
25
25
|
gmCenterScreen: {
|
|
26
26
|
position: "relative",
|
|
27
27
|
zIndex: 1,
|
|
28
|
-
|
|
28
|
+
// use percent so the component fits inside the centered square container
|
|
29
|
+
// (100vh caused overflow on tablets because it measured the viewport, not the container)
|
|
30
|
+
minHeight: "100%",
|
|
29
31
|
width: "100%",
|
|
30
32
|
display: "flex",
|
|
31
33
|
flexDirection: "column",
|
|
@@ -100,7 +102,8 @@ export const styles: Record<string, CSSProperties> = {
|
|
|
100
102
|
position: "relative",
|
|
101
103
|
width: "100%",
|
|
102
104
|
maxWidth: "600px",
|
|
103
|
-
|
|
105
|
+
// should fill the parent square, not the full viewport
|
|
106
|
+
minHeight: "100%",
|
|
104
107
|
display: "flex",
|
|
105
108
|
flexDirection: "column",
|
|
106
109
|
alignItems: "center",
|
|
@@ -203,7 +206,8 @@ export const styles: Record<string, CSSProperties> = {
|
|
|
203
206
|
flexDirection: "column",
|
|
204
207
|
alignItems: "center",
|
|
205
208
|
justifyContent: "center",
|
|
206
|
-
|
|
209
|
+
// use percent so the wrapper scales with the container square
|
|
210
|
+
height: "60%",
|
|
207
211
|
gap: "16px",
|
|
208
212
|
},
|
|
209
213
|
|