@mblinkov/whats-missing 20.0.22 → 20.0.24

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.
@@ -1,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("react"),pe=window.origin+"/cloud/speakid/games/whatsmissing/",q=(d,f)=>d.map(([g,i])=>({src:`${pe}${f}/${i.replace(/\s/g,"%20")}.png`,name:i})),ye=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],xe=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],be=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],V={food:q(ye,"food"),animals:q(xe,"animals"),toys:q(be,"toys")},we=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("react"),xe=window.origin+"/cloud/speakid/games/whatsmissing/",q=(a,f)=>a.map(([g,i])=>({src:`${xe}${f}/${i.replace(/\s/g,"%20")}.png`,name:i})),be=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],we=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],ve=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],V={food:q(be,"food"),animals:q(we,"animals"),toys:q(ve,"toys")},je=`
2
2
  @keyframes spin {
3
3
  from { transform: rotate(0deg); }
4
4
  to { transform: rotate(360deg); }
5
5
  }
6
- `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const d=document.createElement("style");d.id="spin-keyframes",d.innerHTML=we,document.head.appendChild(d)}const ve={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"600px",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"calc(210px * 3 + 20px * 2)",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...ve}},je=()=>{const d=document.createElement("style");d.textContent=`
6
+ `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const a=document.createElement("style");a.id="spin-keyframes",a.innerHTML=je,document.head.appendChild(a)}const Se={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"600px",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"calc(210px * 3 + 20px * 2)",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...Se}},ze=()=>{const a=document.createElement("style");a.textContent=`
7
7
  /* scope only inside game root */
8
8
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
9
9
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
10
- `,document.head.appendChild(d)},Se=(d,f)=>{const g=Array.from({length:d.length+1},()=>Array(f.length+1).fill(0));for(let i=0;i<=d.length;i++)g[i][0]=i;for(let i=0;i<=f.length;i++)g[0][i]=i;for(let i=1;i<=d.length;i++)for(let m=1;m<=f.length;m++)g[i][m]=d[i-1]===f[m-1]?g[i-1][m-1]:Math.min(g[i-1][m-1],g[i][m-1],g[i-1][m])+1;return g[d.length][f.length]};function ze(d,f={minDesktopWidth:1200,forceResize:!1}){const g=s.useRef(null),i=f.minDesktopWidth??1200,m=!!f.forceResize;s.useLayoutEffect(()=>{if(typeof window>"u"||!d||!d.current)return;const l=d.current,z=()=>{try{const r=document.body,y=getComputedStyle(r),p=parseFloat(r.style&&r.style.zoom||"");if(p&&!isNaN(p)&&p>0)return p;const C=parseFloat(y.zoom||"");if(C&&!isNaN(C)&&C>0)return C;const c=document.createElement("div");c.style.position="absolute",c.style.left="0",c.style.top="0",c.style.width="100px",c.style.height="1px",c.style.visibility="hidden",c.style.pointerEvents="none",document.documentElement.appendChild(c);const S=c.getBoundingClientRect();if(document.documentElement.removeChild(c),S&&S.width>0){const k=S.width/100;if(!isNaN(k)&&k>0)return k}}catch{}return 1},L=()=>{if(i&&window.innerWidth<i){j();return}const r=z();if(!r||r===1){j();return}g.current||(g.current={transform:l.style.transform||null,transformOrigin:l.style.transformOrigin||null,width:l.style.width||null,height:l.style.height||null,willChange:l.style.willChange||null});const y=1/r;m&&(l.style.width=`${r*100}%`,l.style.height=`${r*100}%`),l.style.transformOrigin="50% 50%",l.style.transform=`scale(${y})`,l.style.willChange="transform",typeof process<"u"&&process.env?.NODE_ENV==="development"&&console.debug("[useNeutralizeBodyZoom] applied scale:",{scale:r,inv:y,forceResize:m})},j=()=>{if(!g.current)return;const r=g.current;r.transform===null?l.style.removeProperty("transform"):l.style.transform=r.transform,r.transformOrigin===null?l.style.removeProperty("transform-origin"):l.style.transformOrigin=r.transformOrigin,r.width===null?l.style.removeProperty("width"):l.style.width=r.width,r.height===null?l.style.removeProperty("height"):l.style.height=r.height,r.willChange===null?l.style.removeProperty("will-change"):l.style.willChange=r.willChange,g.current=null,typeof process<"u"&&process.env?.NODE_ENV==="development"&&console.debug("[useNeutralizeBodyZoom] restored original styles")};let M=0;const x=()=>{cancelAnimationFrame(M),M=requestAnimationFrame(L)},T=new MutationObserver(r=>{for(const y of r)if(y.type==="attributes"&&(y.attributeName==="style"||y.attributeName==="class")){x();break}});return T.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",x),x(),()=>{cancelAnimationFrame(M),T.disconnect(),window.removeEventListener("resize",x),j()}},[d,i,m])}function Ce(){const d=s.useRef(null),f=s.useRef(null),[g,i]=s.useState(null);ze(d,{minDesktopWidth:1200,forceResize:!1}),s.useEffect(()=>(je(),()=>{document.body.style.overflow=""}),[]);const[m,l]=s.useState(null),[z,L]=s.useState([]),[j,M]=s.useState(4),[x,T]=s.useState(!1),[r,y]=s.useState(1),[p,C]=s.useState(null),[c,S]=s.useState("ready"),[k,Y]=s.useState(3),[A,W]=s.useState(10),[F,Z]=s.useState(20),[oe,N]=s.useState(0),[H,O]=s.useState(!1),[B,_]=s.useState(""),[R,$]=s.useState(!1),[G,U]=s.useState(!1),[K,E]=s.useState(null),[se,D]=s.useState([]),[ie,J]=s.useState([]),[b,re]=s.useState(!1),[I,Q]=s.useState(null);s.useLayoutEffect(()=>{const t=f.current;if(!t||typeof window>"u")return;let o=null;try{o=new ResizeObserver(u=>{for(const a of u){const h=a.contentRect;i(Math.round(Math.min(h.width,h.height)))}}),o.observe(t),i(Math.round(Math.min(t.clientWidth,t.clientHeight)))}catch{i(Math.round(Math.min(t.clientWidth,t.clientHeight)))}return()=>{o&&o.disconnect()}},[b]),s.useEffect(()=>{const t=()=>{const u=window.visualViewport,a=u?Math.round(u.width):window.innerWidth,h=u?Math.round(u.height):window.innerHeight,w=a<768||a>=768&&a<1200&&h>a;if(re(w),w){Q(null);return}const v=.92,P=1e3,ne=40,me=Math.max(360,a-ne),ue=Math.max(360,h-ne),ge=Math.min(me,ue),he=Math.max(360,Math.round(ge*v)),fe=Math.min(he,P);Q(fe)};t(),window.addEventListener("resize",t);const o=window.visualViewport;return o&&typeof o.addEventListener=="function"&&(o.addEventListener("resize",t),o.addEventListener("scroll",t)),()=>{window.removeEventListener("resize",t),o&&typeof o.removeEventListener=="function"&&(o.removeEventListener("resize",t),o.removeEventListener("scroll",t))}},[]);const X=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),ee=()=>{if(!m)return;const t=X(V[m]);L(t),T(!0),O(!1),y(1),N(0),D([]),J([]),te(t,[],!0)},te=(t=z,o=ie,u=!1)=>{const a=X(t.length?t:V[m]);let h=Math.floor(Math.random()*a.length),w=a[h].name,v=0;for(;o.includes(w)&&v<20;)h=Math.floor(Math.random()*a.length),w=a[h].name,v++;L(a),C(h),J([...o,w]),$(!1),_(""),Z(20),E(null),u?(S("ready"),Y(3),W(10)):(S("memorize"),W(10))};s.useEffect(()=>{if(!(!x||H||R)){if(c==="ready")if(k<=0)S("memorize");else{const t=setTimeout(()=>Y(o=>o-1),1e3);return()=>clearTimeout(t)}if(c==="memorize")if(A<=0)S("guess");else{const t=setTimeout(()=>W(o=>o-1),1e3);return()=>clearTimeout(t)}if(c==="guess"){if(F<=0){$(!0),E("wrong");const o=z[p].name;D(u=>[...u,{round:r,answer:B,correct:o,result:"wrong"}]);return}const t=setTimeout(()=>Z(o=>o-1),1e3);return()=>clearTimeout(t)}}},[c,k,A,F,x,H,R,z,p,r,B]);const le=()=>{if(p===null||G)return;const t=z[p].name,o=B.toLowerCase().trim();let u="wrong";o===t?(N(a=>a+1),E("correct"),u="correct"):Se(o,t)===1?(N(a=>a+.5),E("almost"),u="almost"):(E("wrong"),u="wrong"),D(a=>[...a,{round:r,answer:o,correct:t,result:u}]),U(!0),setTimeout(()=>{U(!1),$(!0)},600)},ae=()=>r<j?(y(t=>t+1),te()):O(!0),de=()=>{T(!1),O(!1),l(null)},ce=s.useMemo(()=>e.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:e.jsxs("picture",{children:[e.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),e.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:d,style:{position:"fixed",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease",overflow:"hidden",zIndex:9999,pointerEvents:"auto"},children:e.jsx("div",{ref:f,style:{width:b?"100%":I?`${I}px`:"1000px",height:b?"100%":I?`${I}px`:"1000px",maxWidth:"calc(100vw - 24px)",maxHeight:"calc(100vh - 24px)",display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:b?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:b?"none":"0 0 40px rgba(0,0,0,0.08)",position:"relative"},children:e.jsx("div",{style:{transform:"none",transformOrigin:"50% 50%",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!b&&ce,!m&&!x&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:n.gmButton,onClick:()=>l(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),e.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(t=>e.jsx("button",{style:{...n.gmButton,...j===t?n.gmButtonActive:{}},onClick:()=>M(t),children:t},t))})]})]}),m&&!x&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",m]}),e.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",j]}),e.jsx("button",{style:n.gmButton,onClick:ee,children:"▶ Start game"})]}),H&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",oe," / ",j]}),e.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:n.gmTable,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Round"}),e.jsx("th",{children:"Your Answer"}),e.jsx("th",{children:"Correct"}),e.jsx("th",{children:"Result"})]})}),e.jsx("tbody",{children:se.map((t,o)=>e.jsxs("tr",{children:[e.jsx("td",{style:n.gmTableCell,children:t.round}),e.jsx("td",{style:n.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:n.gmTableCell,children:t.correct}),e.jsx("td",{style:n.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},o))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:n.gmButton,onClick:ee,children:"🔁 Play again"}),e.jsx("button",{style:n.gmButton,onClick:de,children:"⬅️ Choose theme"})]})]}),x&&!H&&e.jsxs("div",{style:n.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[c==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),c==="memorize"&&e.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",A,")"]}),c==="guess"&&!R&&e.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",F,"s"]})]}),c!=="ready"&&(()=>{const t=b?12:20,o=32,u=g??I??(b?360:1e3),a=b?2:3,h=Math.max(90,Math.floor((u-o-t*(a-1))/a));return e.jsx("div",{style:{...n.gmGrid,gridTemplateColumns:`repeat(${a}, ${h}px)`,gridAutoRows:`${h}px`,gap:`${t}px`,justifyContent:"center",justifyItems:"center",padding:8,boxSizing:"border-box"},children:z.map((w,v)=>{const P=p===v&&c==="guess"&&!R;return e.jsx("div",{style:{...n.gmCard,width:`${h}px`,height:`${h}px`,padding:b?8:10,boxSizing:"border-box",...K==="correct"&&p===v?n.gmCorrect:{},...K==="wrong"&&p===v?n.gmWrong:{}},children:!P&&e.jsx("img",{src:w.src,alt:w.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},v)})})})(),e.jsxs("div",{style:{marginTop:16,height:80},children:[c==="guess"&&!R&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:B,onChange:t=>_(t.target.value),style:n.gmInput}),e.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:le,disabled:G,children:G?"...":"Check"})]}),R&&e.jsx("button",{type:"button",style:n.gmButton,onClick:ae,children:"Next round"})]})]})]})})})})}exports.Game=Ce;exports.themes=V;
10
+ `,document.head.appendChild(a)},Ce=(a,f)=>{const g=Array.from({length:a.length+1},()=>Array(f.length+1).fill(0));for(let i=0;i<=a.length;i++)g[i][0]=i;for(let i=0;i<=f.length;i++)g[0][i]=i;for(let i=1;i<=a.length;i++)for(let u=1;u<=f.length;u++)g[i][u]=a[i-1]===f[u-1]?g[i-1][u-1]:Math.min(g[i-1][u-1],g[i][u-1],g[i-1][u])+1;return g[a.length][f.length]};function ke(a,f={minDesktopWidth:1200,forceResize:!1}){const g=s.useRef(null),i=f.minDesktopWidth??1200,u=!!f.forceResize;s.useLayoutEffect(()=>{if(typeof window>"u"||!a||!a.current)return;const l=a.current,z=()=>{try{const r=document.body,y=getComputedStyle(r),p=parseFloat(r.style&&r.style.zoom||"");if(p&&!isNaN(p)&&p>0)return p;const C=parseFloat(y.zoom||"");if(C&&!isNaN(C)&&C>0)return C;const d=document.createElement("div");d.style.position="absolute",d.style.left="0",d.style.top="0",d.style.width="100px",d.style.height="1px",d.style.visibility="hidden",d.style.pointerEvents="none",document.documentElement.appendChild(d);const j=d.getBoundingClientRect();if(document.documentElement.removeChild(d),j&&j.width>0){const k=j.width/100;if(!isNaN(k)&&k>0)return k}}catch{}return 1},L=()=>{if(i&&window.innerWidth<i){v();return}const r=z();if(!r||r===1){v();return}g.current||(g.current={transform:l.style.transform||null,transformOrigin:l.style.transformOrigin||null,width:l.style.width||null,height:l.style.height||null,willChange:l.style.willChange||null});const y=1/r;u&&(l.style.width=`${r*100}%`,l.style.height=`${r*100}%`),l.style.transformOrigin="50% 50%",l.style.transform=`scale(${y})`,l.style.willChange="transform",typeof process<"u"&&process.env?.NODE_ENV==="development"&&console.debug("[useNeutralizeBodyZoom] applied scale:",{scale:r,inv:y,forceResize:u})},v=()=>{if(!g.current)return;const r=g.current;r.transform===null?l.style.removeProperty("transform"):l.style.transform=r.transform,r.transformOrigin===null?l.style.removeProperty("transform-origin"):l.style.transformOrigin=r.transformOrigin,r.width===null?l.style.removeProperty("width"):l.style.width=r.width,r.height===null?l.style.removeProperty("height"):l.style.height=r.height,r.willChange===null?l.style.removeProperty("will-change"):l.style.willChange=r.willChange,g.current=null,typeof process<"u"&&process.env?.NODE_ENV==="development"&&console.debug("[useNeutralizeBodyZoom] restored original styles")};let R=0;const x=()=>{cancelAnimationFrame(R),R=requestAnimationFrame(L)},M=new MutationObserver(r=>{for(const y of r)if(y.type==="attributes"&&(y.attributeName==="style"||y.attributeName==="class")){x();break}});return M.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",x),x(),()=>{cancelAnimationFrame(R),M.disconnect(),window.removeEventListener("resize",x),v()}},[a,i,u])}function Te(){const a=s.useRef(null),f=s.useRef(null),[g,i]=s.useState(null);ke(a,{minDesktopWidth:1200,forceResize:!1}),s.useEffect(()=>(ze(),()=>{document.body.style.overflow=""}),[]);const[u,l]=s.useState(null),[z,L]=s.useState([]),[v,R]=s.useState(4),[x,M]=s.useState(!1),[r,y]=s.useState(1),[p,C]=s.useState(null),[d,j]=s.useState("ready"),[k,Y]=s.useState(3),[W,N]=s.useState(10),[F,_]=s.useState(20),[oe,O]=s.useState(0),[B,$]=s.useState(!1),[H,Z]=s.useState(""),[T,G]=s.useState(!1),[D,K]=s.useState(!1),[U,E]=s.useState(null),[se,P]=s.useState([]),[ie,J]=s.useState([]),[b,re]=s.useState(!1),[I,Q]=s.useState(null);s.useLayoutEffect(()=>{const t=f.current;if(!t||typeof window>"u")return;let o=null;try{o=new ResizeObserver(m=>{for(const c of m){const h=c.contentRect;i(Math.round(Math.min(h.width,h.height)))}}),o.observe(t),i(Math.round(Math.min(t.clientWidth,t.clientHeight)))}catch{i(Math.round(Math.min(t.clientWidth,t.clientHeight)))}return()=>{o&&o.disconnect()}},[b]),s.useEffect(()=>{const t=()=>{const m=window.visualViewport,c=m?Math.round(m.width):window.innerWidth,h=m?Math.round(m.height):window.innerHeight,S=820,w=typeof navigator<"u"&&(navigator.maxTouchPoints>0||"ontouchstart"in window),A=c<=S||w&&h>c;if(re(A),A){Q(null);return}const ue=.92,me=1e3,ne=40,ge=Math.max(360,c-ne),he=Math.max(360,h-ne),fe=Math.min(ge,he),pe=Math.max(360,Math.round(fe*ue)),ye=Math.min(pe,me);Q(ye)};t(),window.addEventListener("resize",t);const o=window.visualViewport;return o&&typeof o.addEventListener=="function"&&(o.addEventListener("resize",t),o.addEventListener("scroll",t)),()=>{window.removeEventListener("resize",t),o&&typeof o.removeEventListener=="function"&&(o.removeEventListener("resize",t),o.removeEventListener("scroll",t))}},[]);const X=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),ee=()=>{if(!u)return;const t=X(V[u]);L(t),M(!0),$(!1),y(1),O(0),P([]),J([]),te(t,[],!0)},te=(t=z,o=ie,m=!1)=>{const c=X(t.length?t:V[u]);let h=Math.floor(Math.random()*c.length),S=c[h].name,w=0;for(;o.includes(S)&&w<20;)h=Math.floor(Math.random()*c.length),S=c[h].name,w++;L(c),C(h),J([...o,S]),G(!1),Z(""),_(20),E(null),m?(j("ready"),Y(3),N(10)):(j("memorize"),N(10))};s.useEffect(()=>{if(!(!x||B||T)){if(d==="ready")if(k<=0)j("memorize");else{const t=setTimeout(()=>Y(o=>o-1),1e3);return()=>clearTimeout(t)}if(d==="memorize")if(W<=0)j("guess");else{const t=setTimeout(()=>N(o=>o-1),1e3);return()=>clearTimeout(t)}if(d==="guess"){if(F<=0){G(!0),E("wrong");const o=z[p].name;P(m=>[...m,{round:r,answer:H,correct:o,result:"wrong"}]);return}const t=setTimeout(()=>_(o=>o-1),1e3);return()=>clearTimeout(t)}}},[d,k,W,F,x,B,T,z,p,r,H]);const le=()=>{if(p===null||D)return;const t=z[p].name,o=H.toLowerCase().trim();let m="wrong";o===t?(O(c=>c+1),E("correct"),m="correct"):Ce(o,t)===1?(O(c=>c+.5),E("almost"),m="almost"):(E("wrong"),m="wrong"),P(c=>[...c,{round:r,answer:o,correct:t,result:m}]),K(!0),setTimeout(()=>{K(!1),G(!0)},600)},ae=()=>r<v?(y(t=>t+1),te()):$(!0),de=()=>{M(!1),$(!1),l(null)},ce=s.useMemo(()=>e.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:e.jsxs("picture",{children:[e.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),e.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:a,style:{position:"absolute",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease",overflow:"hidden",zIndex:1,pointerEvents:"auto"},children:e.jsx("div",{ref:f,style:{width:b?"100%":I?`${I}px`:"1000px",height:b?"100%":I?`${I}px`:"1000px",maxWidth:"calc(100vw - 24px)",maxHeight:"calc(100vh - 20px)",display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:b?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:b?"none":"0 0 40px rgba(0,0,0,0.08)",position:"relative"},children:e.jsx("div",{style:{transform:"none",transformOrigin:"50% 50%",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!b&&ce,!u&&!x&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:n.gmButton,onClick:()=>l(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),e.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(t=>e.jsx("button",{style:{...n.gmButton,...v===t?n.gmButtonActive:{}},onClick:()=>R(t),children:t},t))})]})]}),u&&!x&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",u]}),e.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",v]}),e.jsx("button",{style:n.gmButton,onClick:ee,children:"▶ Start game"})]}),B&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",oe," / ",v]}),e.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:n.gmTable,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Round"}),e.jsx("th",{children:"Your Answer"}),e.jsx("th",{children:"Correct"}),e.jsx("th",{children:"Result"})]})}),e.jsx("tbody",{children:se.map((t,o)=>e.jsxs("tr",{children:[e.jsx("td",{style:n.gmTableCell,children:t.round}),e.jsx("td",{style:n.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:n.gmTableCell,children:t.correct}),e.jsx("td",{style:n.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},o))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:n.gmButton,onClick:ee,children:"🔁 Play again"}),e.jsx("button",{style:n.gmButton,onClick:de,children:"⬅️ Choose theme"})]})]}),x&&!B&&e.jsxs("div",{style:n.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[d==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),d==="memorize"&&e.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",W,")"]}),d==="guess"&&!T&&e.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",F,"s"]})]}),d!=="ready"&&(()=>{const t=b?12:20,o=32,m=g??I??(b?360:1e3),c=b?2:3,h=Math.max(90,Math.floor((m-o-t*(c-1))/c));return e.jsx("div",{style:{...n.gmGrid,gridTemplateColumns:`repeat(${c}, ${h}px)`,gridAutoRows:`${h}px`,gap:`${t}px`,justifyContent:"center",justifyItems:"center",padding:8,boxSizing:"border-box"},children:z.map((S,w)=>{const A=p===w&&d==="guess"&&!T;return e.jsx("div",{style:{...n.gmCard,width:`${h}px`,height:`${h}px`,padding:b?8:10,boxSizing:"border-box",...U==="correct"&&p===w?n.gmCorrect:{},...U==="wrong"&&p===w?n.gmWrong:{}},children:!A&&e.jsx("img",{src:S.src,alt:S.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},w)})})})(),e.jsxs("div",{style:{marginTop:16,height:80},children:[d==="guess"&&!T&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:H,onChange:t=>Z(t.target.value),style:n.gmInput}),e.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:le,disabled:D,children:D?"...":"Check"})]}),T&&e.jsx("button",{type:"button",style:n.gmButton,onClick:ae,children:"Next round"})]})]})]})})})})}exports.Game=Te;exports.themes=V;
@@ -1,9 +1,9 @@
1
- import { jsx as t, jsxs as m, Fragment as we } from "react/jsx-runtime";
2
- import { useRef as Z, useState as c, useEffect as V, useLayoutEffect as se, useMemo as ve } from "react";
3
- const ze = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (a, f) => a.map(([h, i]) => ({
4
- src: `${ze}${f}/${i.replace(/\s/g, "%20")}.png`,
1
+ import { jsx as t, jsxs as m, Fragment as ze } from "react/jsx-runtime";
2
+ import { useRef as _, useState as c, useEffect as V, useLayoutEffect as se, useMemo as Ce } from "react";
3
+ const ke = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (l, f) => l.map(([h, i]) => ({
4
+ src: `${ke}${f}/${i.replace(/\s/g, "%20")}.png`,
5
5
  name: i
6
- })), Ce = [
6
+ })), Se = [
7
7
  ["apple", "apple"],
8
8
  ["banana", "banana"],
9
9
  ["bread", "bread"],
@@ -29,7 +29,7 @@ const ze = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (a, f) => a
29
29
  ["strawberry", "strawberry"],
30
30
  ["tomato", "tomato"],
31
31
  ["watermelon", "watermelon"]
32
- ], ke = [
32
+ ], Te = [
33
33
  ["bear", "bear"],
34
34
  ["cat", "cat"],
35
35
  ["crocodile", "crocodile"],
@@ -49,7 +49,7 @@ const ze = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (a, f) => a
49
49
  ["tortoise", "tortoise"],
50
50
  ["wolf", "wolf"],
51
51
  ["zebra", "zebra"]
52
- ], Se = [
52
+ ], Me = [
53
53
  ["ball", "ball"],
54
54
  ["balloon", "balloon"],
55
55
  ["blocks", "blocks"],
@@ -70,20 +70,20 @@ const ze = window.origin + "/cloud/speakid/games/whatsmissing/", Y = (a, f) => a
70
70
  ["yo-yo", "yo-yo"],
71
71
  ["crayons", "crayons"]
72
72
  ], re = {
73
- food: Y(Ce, "food"),
74
- animals: Y(ke, "animals"),
75
- toys: Y(Se, "toys")
76
- }, Me = `
73
+ food: Y(Se, "food"),
74
+ animals: Y(Te, "animals"),
75
+ toys: Y(Me, "toys")
76
+ }, Re = `
77
77
  @keyframes spin {
78
78
  from { transform: rotate(0deg); }
79
79
  to { transform: rotate(360deg); }
80
80
  }
81
81
  `;
82
82
  if (typeof document < "u" && !document.getElementById("spin-keyframes")) {
83
- const a = document.createElement("style");
84
- a.id = "spin-keyframes", a.innerHTML = Me, document.head.appendChild(a);
83
+ const l = document.createElement("style");
84
+ l.id = "spin-keyframes", l.innerHTML = Re, document.head.appendChild(l);
85
85
  }
86
- const Te = {
86
+ const Ee = {
87
87
  animation: "spin 1.4s linear infinite"
88
88
  }, n = {
89
89
  gmCenterScreen: {
@@ -236,52 +236,52 @@ const Te = {
236
236
  },
237
237
  gmHourglass: {
238
238
  fontSize: "42px",
239
- ...Te
239
+ ...Ee
240
240
  }
241
- }, Re = () => {
242
- const a = document.createElement("style");
243
- a.textContent = `
241
+ }, Ie = () => {
242
+ const l = document.createElement("style");
243
+ l.textContent = `
244
244
  /* scope only inside game root */
245
245
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
246
246
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
247
- `, document.head.appendChild(a);
248
- }, Ee = (a, f) => {
249
- const h = Array.from({ length: a.length + 1 }, () => Array(f.length + 1).fill(0));
250
- for (let i = 0; i <= a.length; i++) h[i][0] = i;
247
+ `, document.head.appendChild(l);
248
+ }, Be = (l, f) => {
249
+ const h = Array.from({ length: l.length + 1 }, () => Array(f.length + 1).fill(0));
250
+ for (let i = 0; i <= l.length; i++) h[i][0] = i;
251
251
  for (let i = 0; i <= f.length; i++) h[0][i] = i;
252
- for (let i = 1; i <= a.length; i++)
252
+ for (let i = 1; i <= l.length; i++)
253
253
  for (let u = 1; u <= f.length; u++)
254
- h[i][u] = a[i - 1] === f[u - 1] ? h[i - 1][u - 1] : Math.min(h[i - 1][u - 1], h[i][u - 1], h[i - 1][u]) + 1;
255
- return h[a.length][f.length];
254
+ h[i][u] = l[i - 1] === f[u - 1] ? h[i - 1][u - 1] : Math.min(h[i - 1][u - 1], h[i][u - 1], h[i - 1][u]) + 1;
255
+ return h[l.length][f.length];
256
256
  };
257
- function Ie(a, f = { minDesktopWidth: 1200, forceResize: !1 }) {
258
- const h = Z(null), i = f.minDesktopWidth ?? 1200, u = !!f.forceResize;
257
+ function Le(l, f = { minDesktopWidth: 1200, forceResize: !1 }) {
258
+ const h = _(null), i = f.minDesktopWidth ?? 1200, u = !!f.forceResize;
259
259
  se(() => {
260
- if (typeof window > "u" || !a || !a.current) return;
261
- const s = a.current, S = () => {
260
+ if (typeof window > "u" || !l || !l.current) return;
261
+ const s = l.current, S = () => {
262
262
  try {
263
263
  const r = document.body, b = getComputedStyle(r), y = parseFloat(r.style && r.style.zoom || "");
264
264
  if (y && !isNaN(y) && y > 0) return y;
265
- const M = parseFloat(b.zoom || "");
266
- if (M && !isNaN(M) && M > 0) return M;
267
- const d = document.createElement("div");
268
- d.style.position = "absolute", d.style.left = "0", d.style.top = "0", d.style.width = "100px", d.style.height = "1px", d.style.visibility = "hidden", d.style.pointerEvents = "none", document.documentElement.appendChild(d);
269
- const k = d.getBoundingClientRect();
270
- if (document.documentElement.removeChild(d), k && k.width > 0) {
271
- const T = k.width / 100;
272
- if (!isNaN(T) && T > 0) return T;
265
+ const T = parseFloat(b.zoom || "");
266
+ if (T && !isNaN(T) && T > 0) return T;
267
+ const a = document.createElement("div");
268
+ a.style.position = "absolute", a.style.left = "0", a.style.top = "0", a.style.width = "100px", a.style.height = "1px", a.style.visibility = "hidden", a.style.pointerEvents = "none", document.documentElement.appendChild(a);
269
+ const C = a.getBoundingClientRect();
270
+ if (document.documentElement.removeChild(a), C && C.width > 0) {
271
+ const M = C.width / 100;
272
+ if (!isNaN(M) && M > 0) return M;
273
273
  }
274
274
  } catch {
275
275
  }
276
276
  return 1;
277
- }, B = () => {
277
+ }, H = () => {
278
278
  if (i && window.innerWidth < i) {
279
- C();
279
+ z();
280
280
  return;
281
281
  }
282
282
  const r = S();
283
283
  if (!r || r === 1) {
284
- C();
284
+ z();
285
285
  return;
286
286
  }
287
287
  h.current || (h.current = {
@@ -293,14 +293,14 @@ function Ie(a, f = { minDesktopWidth: 1200, forceResize: !1 }) {
293
293
  });
294
294
  const b = 1 / r;
295
295
  u && (s.style.width = `${r * 100}%`, s.style.height = `${r * 100}%`), s.style.transformOrigin = "50% 50%", s.style.transform = `scale(${b})`, s.style.willChange = "transform", typeof process < "u" && process.env?.NODE_ENV === "development" && console.debug("[useNeutralizeBodyZoom] applied scale:", { scale: r, inv: b, forceResize: u });
296
- }, C = () => {
296
+ }, z = () => {
297
297
  if (!h.current) return;
298
298
  const r = h.current;
299
299
  r.transform === null ? s.style.removeProperty("transform") : s.style.transform = r.transform, r.transformOrigin === null ? s.style.removeProperty("transform-origin") : s.style.transformOrigin = r.transformOrigin, r.width === null ? s.style.removeProperty("width") : s.style.width = r.width, r.height === null ? s.style.removeProperty("height") : s.style.height = r.height, r.willChange === null ? s.style.removeProperty("will-change") : s.style.willChange = r.willChange, h.current = null, typeof process < "u" && process.env?.NODE_ENV === "development" && console.debug("[useNeutralizeBodyZoom] restored original styles");
300
300
  };
301
301
  let E = 0;
302
302
  const x = () => {
303
- cancelAnimationFrame(E), E = requestAnimationFrame(B);
303
+ cancelAnimationFrame(E), E = requestAnimationFrame(H);
304
304
  }, I = new MutationObserver((r) => {
305
305
  for (const b of r)
306
306
  if (b.type === "attributes" && (b.attributeName === "style" || b.attributeName === "class")) {
@@ -309,24 +309,24 @@ function Ie(a, f = { minDesktopWidth: 1200, forceResize: !1 }) {
309
309
  }
310
310
  });
311
311
  return I.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), window.addEventListener("resize", x), x(), () => {
312
- cancelAnimationFrame(E), I.disconnect(), window.removeEventListener("resize", x), C();
312
+ cancelAnimationFrame(E), I.disconnect(), window.removeEventListener("resize", x), z();
313
313
  };
314
- }, [a, i, u]);
314
+ }, [l, i, u]);
315
315
  }
316
- function Be() {
317
- const a = Z(null), f = Z(null), [h, i] = c(null);
318
- Ie(a, { minDesktopWidth: 1200, forceResize: !1 }), V(() => (Re(), () => {
316
+ function We() {
317
+ const l = _(null), f = _(null), [h, i] = c(null);
318
+ Le(l, { minDesktopWidth: 1200, forceResize: !1 }), V(() => (Ie(), () => {
319
319
  document.body.style.overflow = "";
320
320
  }), []);
321
- const [u, s] = c(null), [S, B] = c([]), [C, E] = c(4), [x, I] = c(!1), [r, b] = c(1), [y, M] = c(null), [d, k] = c("ready"), [T, _] = c(3), [j, F] = c(10), [N, U] = c(20), [le, $] = c(0), [A, O] = c(!1), [W, K] = c(""), [R, G] = c(!1), [D, J] = c(!1), [Q, H] = c(null), [ae, P] = c([]), [de, X] = c([]), [w, ce] = c(!1), [L, ee] = c(null);
321
+ const [u, s] = c(null), [S, H] = c([]), [z, E] = c(4), [x, I] = c(!1), [r, b] = c(1), [y, T] = c(null), [a, C] = c("ready"), [M, Z] = c(3), [j, F] = c(10), [O, K] = c(20), [le, $] = c(0), [A, D] = c(!1), [W, U] = c(""), [R, G] = c(!1), [P, J] = c(!1), [Q, B] = c(null), [ae, q] = c([]), [de, X] = c([]), [w, ce] = c(!1), [L, ee] = c(null);
322
322
  se(() => {
323
323
  const e = f.current;
324
324
  if (!e || typeof window > "u") return;
325
325
  let o = null;
326
326
  try {
327
327
  o = new ResizeObserver((g) => {
328
- for (const l of g) {
329
- const p = l.contentRect;
328
+ for (const d of g) {
329
+ const p = d.contentRect;
330
330
  i(Math.round(Math.min(p.width, p.height)));
331
331
  }
332
332
  }), o.observe(e), i(Math.round(Math.min(e.clientWidth, e.clientHeight)));
@@ -338,13 +338,13 @@ function Be() {
338
338
  };
339
339
  }, [w]), V(() => {
340
340
  const e = () => {
341
- const g = window.visualViewport, l = g ? Math.round(g.width) : window.innerWidth, p = g ? Math.round(g.height) : window.innerHeight, v = l < 768 || l >= 768 && l < 1200 && p > l;
342
- if (ce(v), v) {
341
+ const g = window.visualViewport, d = g ? Math.round(g.width) : window.innerWidth, p = g ? Math.round(g.height) : window.innerHeight, k = 820, v = typeof navigator < "u" && (navigator.maxTouchPoints > 0 || "ontouchstart" in window), N = d <= k || v && p > d;
342
+ if (ce(N), N) {
343
343
  ee(null);
344
344
  return;
345
345
  }
346
- const z = 0.92, q = 1e3, ie = 40, pe = Math.max(360, l - ie), fe = Math.max(360, p - ie), ye = Math.min(pe, fe), be = Math.max(360, Math.round(ye * z)), xe = Math.min(be, q);
347
- ee(xe);
346
+ const pe = 0.92, fe = 1e3, ie = 40, ye = Math.max(360, d - ie), be = Math.max(360, p - ie), xe = Math.min(ye, be), we = Math.max(360, Math.round(xe * pe)), ve = Math.min(we, fe);
347
+ ee(ve);
348
348
  };
349
349
  e(), window.addEventListener("resize", e);
350
350
  const o = window.visualViewport;
@@ -355,53 +355,53 @@ function Be() {
355
355
  const te = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), ne = () => {
356
356
  if (!u) return;
357
357
  const e = te(re[u]);
358
- B(e), I(!0), O(!1), b(1), $(0), P([]), X([]), oe(e, [], !0);
358
+ H(e), I(!0), D(!1), b(1), $(0), q([]), X([]), oe(e, [], !0);
359
359
  }, oe = (e = S, o = de, g = !1) => {
360
- const l = te(e.length ? e : re[u]);
361
- let p = Math.floor(Math.random() * l.length), v = l[p].name, z = 0;
362
- for (; o.includes(v) && z < 20; )
363
- p = Math.floor(Math.random() * l.length), v = l[p].name, z++;
364
- B(l), M(p), X([...o, v]), G(!1), K(""), U(20), H(null), g ? (k("ready"), _(3), F(10)) : (k("memorize"), F(10));
360
+ const d = te(e.length ? e : re[u]);
361
+ let p = Math.floor(Math.random() * d.length), k = d[p].name, v = 0;
362
+ for (; o.includes(k) && v < 20; )
363
+ p = Math.floor(Math.random() * d.length), k = d[p].name, v++;
364
+ H(d), T(p), X([...o, k]), G(!1), U(""), K(20), B(null), g ? (C("ready"), Z(3), F(10)) : (C("memorize"), F(10));
365
365
  };
366
366
  V(() => {
367
367
  if (!(!x || A || R)) {
368
- if (d === "ready")
369
- if (T <= 0) k("memorize");
368
+ if (a === "ready")
369
+ if (M <= 0) C("memorize");
370
370
  else {
371
- const e = setTimeout(() => _((o) => o - 1), 1e3);
371
+ const e = setTimeout(() => Z((o) => o - 1), 1e3);
372
372
  return () => clearTimeout(e);
373
373
  }
374
- if (d === "memorize")
375
- if (j <= 0) k("guess");
374
+ if (a === "memorize")
375
+ if (j <= 0) C("guess");
376
376
  else {
377
377
  const e = setTimeout(() => F((o) => o - 1), 1e3);
378
378
  return () => clearTimeout(e);
379
379
  }
380
- if (d === "guess") {
381
- if (N <= 0) {
382
- G(!0), H("wrong");
380
+ if (a === "guess") {
381
+ if (O <= 0) {
382
+ G(!0), B("wrong");
383
383
  const o = S[y].name;
384
- P((g) => [
384
+ q((g) => [
385
385
  ...g,
386
386
  { round: r, answer: W, correct: o, result: "wrong" }
387
387
  ]);
388
388
  return;
389
389
  }
390
- const e = setTimeout(() => U((o) => o - 1), 1e3);
390
+ const e = setTimeout(() => K((o) => o - 1), 1e3);
391
391
  return () => clearTimeout(e);
392
392
  }
393
393
  }
394
- }, [d, T, j, N, x, A, R, S, y, r, W]);
394
+ }, [a, M, j, O, x, A, R, S, y, r, W]);
395
395
  const me = () => {
396
- if (y === null || D) return;
396
+ if (y === null || P) return;
397
397
  const e = S[y].name, o = W.toLowerCase().trim();
398
398
  let g = "wrong";
399
- o === e ? ($((l) => l + 1), H("correct"), g = "correct") : Ee(o, e) === 1 ? ($((l) => l + 0.5), H("almost"), g = "almost") : (H("wrong"), g = "wrong"), P((l) => [...l, { round: r, answer: o, correct: e, result: g }]), J(!0), setTimeout(() => {
399
+ o === e ? ($((d) => d + 1), B("correct"), g = "correct") : Be(o, e) === 1 ? ($((d) => d + 0.5), B("almost"), g = "almost") : (B("wrong"), g = "wrong"), q((d) => [...d, { round: r, answer: o, correct: e, result: g }]), J(!0), setTimeout(() => {
400
400
  J(!1), G(!0);
401
401
  }, 600);
402
- }, ue = () => r < C ? (b((e) => e + 1), oe()) : O(!0), ge = () => {
403
- I(!1), O(!1), s(null);
404
- }, he = ve(
402
+ }, ue = () => r < z ? (b((e) => e + 1), oe()) : D(!0), ge = () => {
403
+ I(!1), D(!1), s(null);
404
+ }, he = Ce(
405
405
  () => (
406
406
  // ensure logo is positioned inside the square container
407
407
  /* @__PURE__ */ t("div", { style: { ...n.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ m("picture", { children: [
@@ -414,10 +414,10 @@ function Be() {
414
414
  return /* @__PURE__ */ t(
415
415
  "div",
416
416
  {
417
- ref: a,
417
+ ref: l,
418
418
  style: {
419
419
  // center relative to viewport so site layout doesn't push the game off-center
420
- position: "fixed",
420
+ position: "absolute",
421
421
  inset: 0,
422
422
  display: "flex",
423
423
  justifyContent: "center",
@@ -425,7 +425,7 @@ function Be() {
425
425
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
426
426
  transition: "background 0.3s ease",
427
427
  overflow: "hidden",
428
- zIndex: 9999,
428
+ zIndex: 1,
429
429
  pointerEvents: "auto"
430
430
  },
431
431
  children: /* @__PURE__ */ t(
@@ -436,7 +436,7 @@ function Be() {
436
436
  width: w ? "100%" : L ? `${L}px` : "1000px",
437
437
  height: w ? "100%" : L ? `${L}px` : "1000px",
438
438
  maxWidth: "calc(100vw - 24px)",
439
- maxHeight: "calc(100vh - 24px)",
439
+ maxHeight: "calc(100vh - 20px)",
440
440
  display: "flex",
441
441
  justifyContent: "center",
442
442
  alignItems: "center",
@@ -471,7 +471,7 @@ function Be() {
471
471
  {
472
472
  style: {
473
473
  ...n.gmButton,
474
- ...C === e ? n.gmButtonActive : {}
474
+ ...z === e ? n.gmButtonActive : {}
475
475
  },
476
476
  onClick: () => E(e),
477
477
  children: e
@@ -487,7 +487,7 @@ function Be() {
487
487
  ] }),
488
488
  /* @__PURE__ */ m("p", { style: n.gmBodyM, children: [
489
489
  "Rounds: ",
490
- C
490
+ z
491
491
  ] }),
492
492
  /* @__PURE__ */ t("button", { style: n.gmButton, onClick: ne, children: "▶ Start game" })
493
493
  ] }),
@@ -497,7 +497,7 @@ function Be() {
497
497
  "Your score: ",
498
498
  le,
499
499
  " / ",
500
- C
500
+ z
501
501
  ] }),
502
502
  /* @__PURE__ */ t("p", { style: { ...n.gmBodyM, color: "#10b981", marginTop: 12 }, children: "Yahoo! You did it! 🍬✨" }),
503
503
  /* @__PURE__ */ m("table", { style: n.gmTable, children: [
@@ -531,34 +531,34 @@ function Be() {
531
531
  alignItems: "center"
532
532
  },
533
533
  children: [
534
- d === "ready" && /* @__PURE__ */ m(we, { children: [
534
+ a === "ready" && /* @__PURE__ */ m(ze, { children: [
535
535
  /* @__PURE__ */ t("h1", { style: { ...n.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
536
536
  /* @__PURE__ */ t("div", { style: n.gmHourglass, children: "⏳" })
537
537
  ] }),
538
- d === "memorize" && /* @__PURE__ */ m("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
538
+ a === "memorize" && /* @__PURE__ */ m("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
539
539
  "MEMORIZE (",
540
540
  j,
541
541
  ")"
542
542
  ] }),
543
- d === "guess" && !R && /* @__PURE__ */ m("p", { style: n.gmBodyM, children: [
543
+ a === "guess" && !R && /* @__PURE__ */ m("p", { style: n.gmBodyM, children: [
544
544
  "⏳ Time left: ",
545
- N,
545
+ O,
546
546
  "s"
547
547
  ] })
548
548
  ]
549
549
  }
550
550
  ),
551
- d !== "ready" && (() => {
552
- const e = w ? 12 : 20, o = 32, g = h ?? L ?? (w ? 360 : 1e3), l = w ? 2 : 3, p = Math.max(
551
+ a !== "ready" && (() => {
552
+ const e = w ? 12 : 20, o = 32, g = h ?? L ?? (w ? 360 : 1e3), d = w ? 2 : 3, p = Math.max(
553
553
  90,
554
- Math.floor((g - o - e * (l - 1)) / l)
554
+ Math.floor((g - o - e * (d - 1)) / d)
555
555
  );
556
556
  return /* @__PURE__ */ t(
557
557
  "div",
558
558
  {
559
559
  style: {
560
560
  ...n.gmGrid,
561
- gridTemplateColumns: `repeat(${l}, ${p}px)`,
561
+ gridTemplateColumns: `repeat(${d}, ${p}px)`,
562
562
  gridAutoRows: `${p}px`,
563
563
  gap: `${e}px`,
564
564
  justifyContent: "center",
@@ -566,8 +566,8 @@ function Be() {
566
566
  padding: 8,
567
567
  boxSizing: "border-box"
568
568
  },
569
- children: S.map((v, z) => {
570
- const q = y === z && d === "guess" && !R;
569
+ children: S.map((k, v) => {
570
+ const N = y === v && a === "guess" && !R;
571
571
  return /* @__PURE__ */ t(
572
572
  "div",
573
573
  {
@@ -577,33 +577,33 @@ function Be() {
577
577
  height: `${p}px`,
578
578
  padding: w ? 8 : 10,
579
579
  boxSizing: "border-box",
580
- ...Q === "correct" && y === z ? n.gmCorrect : {},
581
- ...Q === "wrong" && y === z ? n.gmWrong : {}
580
+ ...Q === "correct" && y === v ? n.gmCorrect : {},
581
+ ...Q === "wrong" && y === v ? n.gmWrong : {}
582
582
  },
583
- children: !q && /* @__PURE__ */ t(
583
+ children: !N && /* @__PURE__ */ t(
584
584
  "img",
585
585
  {
586
- src: v.src,
587
- alt: v.name,
586
+ src: k.src,
587
+ alt: k.name,
588
588
  style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
589
589
  }
590
590
  )
591
591
  },
592
- z
592
+ v
593
593
  );
594
594
  })
595
595
  }
596
596
  );
597
597
  })(),
598
598
  /* @__PURE__ */ m("div", { style: { marginTop: 16, height: 80 }, children: [
599
- d === "guess" && !R && /* @__PURE__ */ m("div", { children: [
599
+ a === "guess" && !R && /* @__PURE__ */ m("div", { children: [
600
600
  /* @__PURE__ */ t(
601
601
  "input",
602
602
  {
603
603
  type: "text",
604
604
  placeholder: "Type the missing word",
605
605
  value: W,
606
- onChange: (e) => K(e.target.value),
606
+ onChange: (e) => U(e.target.value),
607
607
  style: n.gmInput
608
608
  }
609
609
  ),
@@ -612,8 +612,8 @@ function Be() {
612
612
  {
613
613
  style: { ...n.gmButton, marginLeft: 8 },
614
614
  onClick: me,
615
- disabled: D,
616
- children: D ? "..." : "Check"
615
+ disabled: P,
616
+ children: P ? "..." : "Check"
617
617
  }
618
618
  )
619
619
  ] }),
@@ -629,6 +629,6 @@ function Be() {
629
629
  );
630
630
  }
631
631
  export {
632
- Be as Game,
632
+ We as Game,
633
633
  re as themes
634
634
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblinkov/whats-missing",
3
- "version": "20.0.22",
3
+ "version": "20.0.24",
4
4
  "main": "dist/whats-missing.umd.js",
5
5
  "module": "dist/whats-missing.es.js",
6
6
  "types": "dist/index.d.ts",
package/src/Game.tsx CHANGED
@@ -248,8 +248,14 @@ export default function Game() {
248
248
  const vw = vv ? Math.round(vv.width) : window.innerWidth;
249
249
  const vh = vv ? Math.round(vv.height) : window.innerHeight;
250
250
 
251
- // treat narrow screens as mobile; portrait tablets also considered mobile
252
- const mobile = vw < 768 || (vw >= 768 && vw < 1200 && vh > vw);
251
+ // treat narrow screens as mobile.
252
+ // Also treat portrait tablets (iPad portrait) as mobile:
253
+ // - use a slightly larger mobile breakpoint (820px),
254
+ // - or if device is touch-capable and height > width (portrait).
255
+ const MOBILE_BREAKPOINT = 820;
256
+ const isTouchDevice = typeof navigator !== "undefined" && (navigator.maxTouchPoints > 0 || "ontouchstart" in window);
257
+ const mobile = vw <= MOBILE_BREAKPOINT || (isTouchDevice && vh > vw);
258
+
253
259
  setIsMobile(mobile);
254
260
 
255
261
  if (mobile) {
@@ -425,7 +431,7 @@ export default function Game() {
425
431
  ref={containerRef}
426
432
  style={{
427
433
  // center relative to viewport so site layout doesn't push the game off-center
428
- position: "fixed",
434
+ position: "absolute",
429
435
  inset: 0,
430
436
  display: "flex",
431
437
  justifyContent: "center",
@@ -433,7 +439,7 @@ export default function Game() {
433
439
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
434
440
  transition: "background 0.3s ease",
435
441
  overflow: "hidden",
436
- zIndex: 9999,
442
+ zIndex: 1,
437
443
  pointerEvents: "auto",
438
444
  }}
439
445
  >
@@ -444,7 +450,7 @@ export default function Game() {
444
450
  width: isMobile ? "100%" : containerSize ? `${containerSize}px` : "1000px",
445
451
  height: isMobile ? "100%" : containerSize ? `${containerSize}px` : "1000px",
446
452
  maxWidth: "calc(100vw - 24px)",
447
- maxHeight: "calc(100vh - 24px)",
453
+ maxHeight: "calc(100vh - 20px)",
448
454
  display: "flex",
449
455
  justifyContent: "center",
450
456
  alignItems: "center",