UNPKG

@empirica/core

Version:
748 lines (737 loc) 26.4 kB
import { Consent, Finished, Loading, NoGames, PlayerCreate, useConsent, useGlobal, usePartConnected, useParticipantContext, usePlayerID, useTajribaConnected } from "./chunk-UMPSA52E.js"; import { error, warn } from "./chunk-TIKLWCJI.js"; // src/player/classic/react/EmpiricaContext.tsx import React3 from "react"; // src/player/classic/react/Lobby.tsx import React from "react"; // src/player/classic/react/hooks.ts import { useEffect, useRef, useState } from "react"; function usePlayer() { return usePartModeCtxKey( "player" ); } function useGame() { return usePartModeCtxKey("game"); } function useRound() { return usePartModeCtxKey( "round" ); } function useStage() { return usePartModeCtxKey( "stage" ); } function useStageTimer() { const stage = useStage(); const [val, setVal] = useState({ tick: stage?.timer?.current }); const timerSubscription = useRef(null); useEffect(() => { if (!stage || !stage.timer) { return; } if (timerSubscription.current === null) { timerSubscription.current = stage.timer.obs().subscribe({ next(val2) { setVal({ tick: val2 }); } }); } return () => { timerSubscription?.current?.unsubscribe.bind(timerSubscription.current); timerSubscription.current = null; }; }, [stage?.timer]); return val.tick; } function usePlayers() { return usePartModeCtxKey( "players" ); } function usePartModeCtx() { const ctx = useParticipantContext(); const [mode, setMode] = useState({ data: ctx?.mode?.getValue() }); useEffect(() => { if (!ctx || !ctx.mode) { return; } const sub = ctx.mode.subscribe({ next(m) { setMode({ data: m }); } }); return sub.unsubscribe.bind(sub); }, [ctx]); return mode.data; } function usePartModeCtxKey(name) { const mode = usePartModeCtx(); const iniVal = mode && mode[name]; const [val, setVal] = useState({ data: iniVal?.getValue() }); useEffect(() => { if (!mode) { return; } const obs = mode[name]; const sub = obs.subscribe({ next(val2) { setVal({ data: val2 }); } }); return sub.unsubscribe.bind(sub); }, [mode]); return val.data; } // src/player/classic/react/Lobby.tsx function Lobby() { const player = usePlayer(); if (!player) { return /* @__PURE__ */ React.createElement(Loading, null); } const treatment = player.get("treatment"); if (!treatment || !treatment.playerCount) { warn("lobby: no treatment found on player"); return /* @__PURE__ */ React.createElement(Loading, null); } return /* @__PURE__ */ React.createElement("div", { className: "flex h-full items-center justify-center" }, /* @__PURE__ */ React.createElement("div", { className: "text-center" }, /* @__PURE__ */ React.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 640 512", className: "mx-auto h-12 w-12 text-gray-400", stroke: "none", fill: "currentColor", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { d: "M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-128c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM320 256c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-192c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80zm244 192h-40c-15.2 0-29.3 4.8-41.1 12.9 9.4 6.4 17.9 13.9 25.4 22.4 4.9-2.1 10.2-3.3 15.7-3.3h40c24.2 0 44 21.5 44 48 0 8.8 7.2 16 16 16s16-7.2 16-16c0-44.1-34.1-80-76-80zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-128c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm304.1 180c-33.4 0-41.7 12-80.1 12-38.4 0-46.7-12-80.1-12-36.3 0-71.6 16.2-92.3 46.9-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM480 432c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16v-44.8c0-16.6 4.9-32.7 14.1-46.4 13.8-20.5 38.4-32.8 65.7-32.8 27.4 0 37.2 12 80.2 12s52.8-12 80.1-12c27.3 0 51.9 12.3 65.7 32.8 9.2 13.7 14.1 29.8 14.1 46.4V432zM157.1 268.9c-11.9-8.1-26-12.9-41.1-12.9H76c-41.9 0-76 35.9-76 80 0 8.8 7.2 16 16 16s16-7.2 16-16c0-26.5 19.8-48 44-48h40c5.5 0 10.8 1.2 15.7 3.3 7.5-8.5 16.1-16 25.4-22.4z" }) ), /* @__PURE__ */ React.createElement("h3", { className: "mt-2 text-sm font-medium text-gray-900" }, treatment.playerCount > 1 ? "Waiting for other players" : "Game loading"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-gray-500" }, "Please wait for the game to be ready."))); } // src/player/classic/react/Steps.tsx import React2, { useEffect as useEffect2, useState as useState2 } from "react"; function Steps({ steps, progressKey, doneKey, object, children }) { let obj; const game = useGame(); const player = usePlayer(); const [stps, setStps] = useState2([]); const [stpsSet, setStpsSet] = useState2(false); useEffect2(() => { let s; if (typeof steps === "function") { s = steps({ game, player }); } else { s = steps; } setStps(s); setStpsSet(true); }, [steps]); useEffect2(() => { if (obj && !obj.get(doneKey) && stpsSet && (!stps || stps.length === 0)) { obj.set(doneKey, true); } }, [stps]); if (object) { obj = object; } else if (player) { obj = player; } else { error("no receiver and no player in Steps"); return /* @__PURE__ */ React2.createElement("div", null, "Missing attribute"); } if (obj.get(doneKey)) { return /* @__PURE__ */ React2.createElement(React2.Fragment, null, children); } const index = obj.get(progressKey) || 0; const next = () => { if (index + 1 >= stps.length) { obj.set(doneKey, true); } else { obj.set(progressKey, index + 1); } }; const previous = () => { if (index > 0) { obj.set(progressKey, index - 1); } }; const Step2 = stps[index]; if (!Step2) { return /* @__PURE__ */ React2.createElement(React2.Fragment, null); } return /* @__PURE__ */ React2.createElement(Step2, { index, previous, next }); } // src/player/classic/react/EmpiricaContext.tsx function EmpiricaContext({ noGames: NoGamesComp = NoGames, consent: ConsentComp = Consent, playerCreate: PlayerCreateForm = PlayerCreate, introSteps = [], lobby = Lobby, exitSteps = [], finished = Finished, loading: LoadingComp = Loading, connecting: ConnectingComp = Loading, unmanagedGame = false, unmanagedAssignment = false, disableConsent = false, disableNoGames = false, disableURLParamsCapture = false, children }) { const tajribaConnected = useTajribaConnected(); const participantConnected = usePartConnected(); const globals = useGlobal(); const player = usePlayer(); const game = useGame(); const [connecting, hasPlayer, onPlayerID] = usePlayerID(); const [consented, onConsent] = useConsent(); if (!tajribaConnected || connecting) { return /* @__PURE__ */ React3.createElement(ConnectingComp, null); } if (player && player.get("ended")) { return /* @__PURE__ */ React3.createElement(Exit, { exitSteps, finished }); } if (!globals || hasPlayer && (!participantConnected || !player || game === void 0)) { return /* @__PURE__ */ React3.createElement(LoadingComp, null); } if (!disableNoGames && !globals.get("experimentOpen") && (!hasPlayer || !player?.get("gameID"))) { return /* @__PURE__ */ React3.createElement(NoGamesComp, null); } if (!disableConsent && !consented) { return /* @__PURE__ */ React3.createElement(ConsentComp, { onConsent }); } if (!hasPlayer) { return /* @__PURE__ */ React3.createElement(PlayerCreateForm, { onPlayerID, connecting }); } if (!player || !unmanagedGame && !game) { return /* @__PURE__ */ React3.createElement(LoadingComp, null); } if (!disableURLParamsCapture && !player.get("urlParams")) { const urlParams = new URLSearchParams(window.location.search); player.set("urlParams", Object.fromEntries(urlParams.entries())); } if (unmanagedAssignment) { return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children); } if (game && game.hasEnded) { if (!player.get("ended")) { return /* @__PURE__ */ React3.createElement(LoadingComp, null); } return /* @__PURE__ */ React3.createElement(Exit, { exitSteps, finished }); } return /* @__PURE__ */ React3.createElement(Steps, { progressKey: "intro", doneKey: "introDone", steps: introSteps }, /* @__PURE__ */ React3.createElement( EmpiricaInnerContext, { exitSteps, lobby, finished, loading: LoadingComp, unmanagedGame }, children )); } function EmpiricaInnerContext({ children, lobby: Lobby2, finished, exitSteps, loading: LoadingComp, unmanagedGame = false }) { const player = usePlayer(); const game = useGame(); const allReady = useAllReady(); if (!game) { if (unmanagedGame) { return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children); } else { return /* @__PURE__ */ React3.createElement(LoadingComp, null); } } if (!Boolean(game.get("status"))) { return /* @__PURE__ */ React3.createElement(Lobby2, null); } if (game.hasEnded) { if (!player?.get("ended")) { return /* @__PURE__ */ React3.createElement(LoadingComp, null); } return /* @__PURE__ */ React3.createElement(Exit, { exitSteps, finished }); } if (unmanagedGame || allReady) { return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children); } return /* @__PURE__ */ React3.createElement(LoadingComp, null); } function Exit({ exitSteps, finished: Finished2 }) { const gameReady = useGameReady(); if (!gameReady) { return /* @__PURE__ */ React3.createElement(Loading, null); } return /* @__PURE__ */ React3.createElement(Steps, { progressKey: "exitStep", doneKey: "exitStepDone", steps: exitSteps }, /* @__PURE__ */ React3.createElement(Finished2, null)); } function useAllReady() { const player = usePlayer(); const players = usePlayers(); const game = useGame(); const stage = useStage(); const round = useRound(); if (!player || !players || !stage || !round || !game || !player.game || !player.round || !player.stage) { return false; } const playerCount = game.get("actualPlayerCount"); if (playerCount !== void 0 && players.length < playerCount) { return false; } for (const p of players) { if (!p.game || !p.round || !p.stage) { return false; } } return true; } function useGameReady() { const player = usePlayer(); const players = usePlayers(); const game = useGame(); if (player && !player.get("gameID")) { return true; } if (player && game && !game.get("start")) { return true; } if (!player || !players || !game || !player.game) { return false; } const playerCount = game.get("actualPlayerCount"); if (playerCount !== void 0 && players.length < playerCount) { return false; } for (const p of players) { if (!p.game) { return false; } } return true; } // src/player/classic/react/Quiz.tsx import React4, { useState as useState3 } from "react"; function Quiz({ next }) { const labelClassName = "block text-sm font-medium text-gray-700 mb-2"; const inputClassName = "appearance-none block px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-empirica-500 focus:border-empirica-500 sm:text-sm"; const [sum, setSum] = useState3(""); const [horse, setHorse] = useState3(""); function handleSubmit(e) { e.preventDefault(); if (sum !== "4" || horse !== "white") { alert("Incorrect! Read the instructions and please try again."); } else { next(); } } return /* @__PURE__ */ React4.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React4.createElement("div", { className: "mt-6 sm:mt-24" }, /* @__PURE__ */ React4.createElement("h3", { className: "text-2xl font-semi-bold text-gray-900" }, "Quiz"), /* @__PURE__ */ React4.createElement("form", { className: "mt-4", onSubmit: handleSubmit }, /* @__PURE__ */ React4.createElement("p", { className: "mb-5" }, /* @__PURE__ */ React4.createElement("label", { className: labelClassName }, "What is 2+2?"), /* @__PURE__ */ React4.createElement( "input", { className: inputClassName, type: "text", dir: "auto", id: "sum", name: "sum", placeholder: "e.g. 3", value: sum, onChange: (e) => setSum(e.target.value), autoComplete: "off", autoFocus: true, required: true } )), /* @__PURE__ */ React4.createElement("p", { className: "mb-5" }, /* @__PURE__ */ React4.createElement("label", { className: labelClassName }, "What color was Napoleon's white horse?"), /* @__PURE__ */ React4.createElement( "input", { className: inputClassName, type: "text", dir: "auto", id: "horse", name: "horse", placeholder: "brown", value: horse, onChange: (e) => setHorse(e.target.value), autoComplete: "off", required: true } )), /* @__PURE__ */ React4.createElement( "button", { type: "submit", className: "inline-flex items-center px-4 py-2 border text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-empirica-500" }, "Submit" )))); } // src/player/classic/react/Slider.tsx import React5, { useRef as useRef2 } from "react"; function Slider({ value, onChange, min = 0, max = 100, stepSize = 1, disabled = false }) { const noVal = value === null || value === void 0; const val = noVal ? (max - min) / 2 : value; const cls = noVal ? "slider-thumb-zero" : "slider-thumb"; const ref = useRef2(null); if (value !== null && ref.current) { const nmin = min ? min : 0; const nmax = max ? max : 100; const newVal = Number((value - nmin) * 100 / (nmax - nmin)); ref.current.style.left = `calc(${newVal}% + (${8 - newVal * 0.15}px))`; } return /* @__PURE__ */ React5.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React5.createElement( "input", { className: cls, type: "range", min, max, step: stepSize, value: val, onChange, disabled } ), noVal ? "" : /* @__PURE__ */ React5.createElement( "output", { ref, className: "font-mono absolute w-12 h-7 flex items-center justify-center left-1/2 bottom-7 rounded transform -translate-x-1/2 bg-gray-200" }, value )); } // src/player/classic/react/chat/Chat.tsx import React6, { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react"; function Chat({ scope, attribute = "messages", loading: LoadingComp = Loading }) { const player = usePlayer(); if (!scope || !player) { return /* @__PURE__ */ React6.createElement(LoadingComp, null); } const handleNewMessage = (text) => { scope.append(attribute, { text, sender: { id: player.id, name: player.get("name") || player.id, avatar: player.get("avatar") } }); }; const msgs = scope.getAttribute(attribute)?.items || []; return /* @__PURE__ */ React6.createElement("div", { className: "h-full w-full flex flex-col" }, /* @__PURE__ */ React6.createElement(Messages, { msgs }), /* @__PURE__ */ React6.createElement(Input, { onNewMessage: handleNewMessage })); } function Messages(props) { const { msgs } = props; const scroller = useRef3(null); const [msgCount, setMsgCount] = useState4(0); useEffect3(() => { if (!scroller.current) { return; } if (msgCount !== msgs.length) { setMsgCount(msgs.length); scroller.current.scrollTop = scroller.current.scrollHeight; } }, [scroller, props, msgCount]); if (msgs.length === 0) { return /* @__PURE__ */ React6.createElement("div", { className: "h-full w-full flex justify-center items-center" }, /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col justify-center items-center w-2/3 space-y-2" }, /* @__PURE__ */ React6.createElement("div", { className: "w-24 h-24 text-gray-200" }, /* @__PURE__ */ React6.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-full w-full fill-current", viewBox: "0 0 512 512" }, /* @__PURE__ */ React6.createElement("path", { d: "M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9c.1-.2 .2-.3 .3-.5z" }) )), /* @__PURE__ */ React6.createElement("h4", { className: "text-gray-700 font-semibold" }, "No chat yet"), /* @__PURE__ */ React6.createElement("p", { className: "text-gray-500 text-center" }, "Send a message to start the conversation."))); } return /* @__PURE__ */ React6.createElement("div", { className: "h-full overflow-auto pl-2 pr-4 pb-2", ref: scroller }, msgs.map((msg) => /* @__PURE__ */ React6.createElement(MessageComp, { key: msg.id, attribute: msg }))); } function MessageComp({ attribute }) { const msg = attribute.value; const ts = attribute.createdAt; let avatar = msg.sender.avatar; if (!avatar) { avatar = `https://avatars.dicebear.com/api/identicon/${msg.sender.id}.svg`; } let avatarImage = /* @__PURE__ */ React6.createElement( "img", { className: "inline-block h-9 w-9 rounded-full", src: avatar, alt: msg.sender.id } ); if (!avatar.startsWith("http")) { avatarImage = /* @__PURE__ */ React6.createElement("div", { className: "inline-block h-9 w-9 rounded-full" }, avatar); } return /* @__PURE__ */ React6.createElement("div", { className: "flex items-start my-2" }, /* @__PURE__ */ React6.createElement("div", { className: "flex-shrink-0" }, avatarImage), /* @__PURE__ */ React6.createElement("div", { className: "ml-3 text-sm" }, /* @__PURE__ */ React6.createElement("p", null, /* @__PURE__ */ React6.createElement("span", { className: "font-semibold text-gray-900 group-hover:text-gray-800" }, msg.sender.name), /* @__PURE__ */ React6.createElement("span", { className: "pl-2 text-gray-400" }, ts && relTime(ts))), /* @__PURE__ */ React6.createElement("p", { className: "text-gray-900 group-hover:text-gray-800" }, msg.text))); } function Input({ onNewMessage }) { const [text, setText] = useState4(""); const resize = (e) => { const target = e.target; target.style.height = "inherit"; target.style.height = `${Math.min(target.scrollHeight, 200)}px`; }; const handleSubmit = (e) => { e.preventDefault(); const txt = text.trim(); if (txt === "") { return; } if (txt.length > 1024) { e.preventDefault(); alert("Max message length is 1024"); return; } onNewMessage(txt); setText(""); }; const handleKeyDown = (e) => { if (e.key === "Enter" && e.shiftKey === false) { handleSubmit(e); resize(e); } }; const handleKeyUp = (e) => { resize(e); }; return /* @__PURE__ */ React6.createElement( "form", { className: "p-2 flex items-strech gap-2 border-t", onSubmit: handleSubmit }, /* @__PURE__ */ React6.createElement( "textarea", { name: "message", id: "message", rows: 1, className: "peer resize-none bg-transparent block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-200 placeholder:text-gray-300 focus:ring-2 focus:ring-inset focus:ring-empirica-500 sm:text-sm sm:leading-6", placeholder: "Say something", onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, value: text, onChange: (e) => setText(e.target.value) } ), /* @__PURE__ */ React6.createElement( "button", { type: "button", className: "rounded-md bg-gray-100 w-9 h-9 p-2 text-sm font-semibold text-gray-500 shadow-sm hover:bg-gray-200 hover:text-empirica-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-empirica-500", onClick: handleSubmit }, /* @__PURE__ */ React6.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-full w-full fill-current", viewBox: "0 0 512 512" }, /* @__PURE__ */ React6.createElement("path", { d: "M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480V396.4c0-4 1.5-7.8 4.2-10.7L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" }) ) ) ); } function relTime(date) { const difference = ((/* @__PURE__ */ new Date()).getTime() - date.getTime()) / 1e3; if (difference < 60) { return `now`; } else if (difference < 3600) { return `${Math.floor(difference / 60)}m`; } else if (difference < 86400) { return `${Math.floor(difference / 3600)}h`; } else if (difference < 2620800) { return `${Math.floor(difference / 86400)} days ago`; } else if (difference < 31449600) { return `${Math.floor(difference / 2620800)} months ago`; } else { return `${Math.floor(difference / 31449600)} years ago`; } } // src/player/classic/react/examples/Sweeper.tsx import React7, { useEffect as useEffect4 } from "react"; var buttonStyle = { width: 40, height: 40, backgroundColor: "#888", color: "black", verticalAlign: "top", fontSize: "32px", borderLeft: "5px solid rgb(220,220,220)", borderTop: "5px solid rgb(220,220,220)", borderBottom: "5px solid #333", borderRight: "5px solid #333", display: "inline-block" }; var visitStyle = { width: 40, height: 40, itemsAlign: "center", backgroundColor: "#555", color: "white", fontWeight: "bold", border: "1px solid black", verticalAlign: "top", fontSize: "24px", display: "inline-block" }; function Sweeper() { const round = useRound(); if (!round) { return null; } const player = usePlayer(); if (!player) { return null; } const visited = round.get("visited"); const bombs = round.get("bombs"); const lost = round.get("lost"); useEffect4(function() { generateBombs(); }, []); function generateBombs() { if (bombs || !round) { return; } let bombArr = new Array(10).fill(0).map(() => new Array(10).fill(0)); for (let i = 0; i < bombArr.length; i++) { let bombPos = Math.floor(Math.random() * 10); bombArr[i][bombPos] = "X"; } for (let i = 0; i < bombArr.length; i++) { for (let j = 0; j < bombArr[i].length; j++) { if (bombArr[i][j] !== "X") { let sum = 0; if (i > 0 && bombArr[i - 1][j] == "X") sum++; if (i < bombArr.length - 1 && bombArr[i + 1][j] == "X") sum++; if (j < bombArr.length - 1 && bombArr[i][j + 1] == "X") sum++; if (j > 0 && bombArr[i][j - 1] == "X") sum++; if (i < bombArr.length - 1 && j > 0 && bombArr[i + 1][j - 1] == "X") sum++; if (i < bombArr.length - 1 && j < bombArr.length - 1 && bombArr[i + 1][j + 1] == "X") sum++; if (i > 0 && j > 0 && bombArr[i - 1][j - 1] == "X") sum++; if (i > 0 && j < bombArr.length - 1 && bombArr[i - 1][j + 1] == "X") sum++; bombArr[i][j] = sum; } } } round.set("bombs", bombArr); let cover = Array(10).fill(0).map(() => Array(10).fill(0)); round.set("visited", cover); } const visitCell = (i, j) => { if (lost || !bombs || !visited) { return; } if (bombs[i][j] === "X") { round.set("lost", true); } dfsCells(i, j); visited[i][j] = 1; round.set("visited", [...visited]); }; function dfsCells(i, j) { if (!round || !bombs || !visited) { return; } if (i < 0 || i > visited.length - 1 || j < 0 || j > visited[0].length - 1 || visited[i][j] == 1 || bombs[i][j] == "X") return; visited[i][j] = 1; round.set("visited", [...visited]); const cell = bombs[i][j]; if (typeof cell === "number" && cell < 1) { dfsCells(i + 1, j); dfsCells(i - 1, j); dfsCells(i, j + 1); dfsCells(i, j - 1); } } if (!bombs) { return null; } return /* @__PURE__ */ React7.createElement("div", { className: "text-sm relative" }, lost ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("div", { className: "absolute h-full w-full flex items-center justify-center text-6xl white font-black bg-opacity-50 bg-gray-300" }, "YOU LOST"), /* @__PURE__ */ React7.createElement("div", { className: "absolute h-full w-full flex items-center justify-center text-6xl white font-black mt-1 ml-1 text-white" }, "YOU LOST")) : "", bombs.map((arr, index) => /* @__PURE__ */ React7.createElement("div", { key: index }, arr.map((_, i) => /* @__PURE__ */ React7.createElement( "div", { key: i, onClick: () => visitCell(index, i), style: visited[index][i] == 0 ? buttonStyle : visitStyle }, /* @__PURE__ */ React7.createElement("div", { className: "h-full w-full flex items-center justify-center" }, visited[index][i] == 0 ? null : bombs[index][i] == 0 ? "" : bombs[index][i]) ))))); } export { usePlayer, useGame, useRound, useStage, useStageTimer, usePlayers, usePartModeCtx, usePartModeCtxKey, Lobby, EmpiricaContext, Quiz, Slider, Chat, Sweeper }; //# sourceMappingURL=chunk-J6LPACOK.js.map