@minicode-dev/chat 0.1.4 → 0.1.6

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 +1 @@
1
- {"version":3,"file":"BattleshipGameCard-CW_A8Nim.js","names":["sameCell","_Fragment","useChatGames","useChatConnectionStatus","createSoundManager","sameUser","GameSoundControls","isTerminalGame","getGameStatus","connect4Sounds","getVerificationLabel","chatSoundUrl","validatePlacement","createBoard","placeShip","FLEET","hasWebGL","AMBIENT","battleshipSounds","name","hidden","playUiSound","scheduleCues","run","keyFor","at","timer","timers","ambientHolders","syncAmbient","holdAmbient","released","CRUISER_ID","sameCell$1","a","b","hitsOn","ship","shots","cell","skip","crossesCruiserAlarm","shot","cruiser","fleet","before","incomingShots","after","launchCues","incoming","impactCues","cues","result","sunk","cruiserAlarm","defeated","won","ROWS","SHIP_NAMES","SCENE_STATUSES","DOUBLE_SELECT_MS","EMPTY_SHOTS","cellLabel","sameCell","isCell","shipName","id","shotAt","shipAt","ships","item","capitalize","text","prefersReducedMotion","call","args","buildBoard","board","first","placed","previewCells","size","anchor","orientation","index","countShots","total","hits","row","SyncControls","sync","connected","onAdoptOffer","onResync","VerificationBadge","label","game","ShieldCheck","TriangleAlert","FallbackGrid","shipCells","preview","view","onHover","col","cls","selected","cursor","onSelect","HistorySummary","showStats","iWon","currentUserId","Anchor","status","BattleshipGameCard","state","gameKey","variant","BattleshipPanel","stageRef","useRef","sceneRef","animatingRef","lastSeenShotRef","lastSelectRef","handlersRef","soundTimersRef","lastStatusRef","hintId","useId","sceneStatus","setSceneStatus","useState","viewMode","setViewMode","hovered","setHovered","setCursor","setSelected","setOrientation","activeShipId","setActiveShipId","radar","setRadar","expanded","setExpanded","animating","setAnimating","announcement","setAnnouncement","isHost","isGuest","isParticipant","terminal","placing","battle","myTurn","busy","canFire","canPlace","sceneVisible","sceneReady","myFleet","useMemo","targetShots","ownBoard","placedIds","fleetComplete","currentShip","ownShips","enemyShips","shotCount","hitCount","radarContacts","cells","r","c","mode","buildView","useCallback","viewModeArg","hideCell","announce","fire","placeAt","selectCell","now","last","useEffect","container","disposed","scene","createBattleScene","error","ambient","lastShot","eventId","sunkId","kind","nextMode","impact","cueKey","cancelled","hold","resolve","rotate","value","ready","clicked","action","toggleRadar","handleStageKeyDown","event","moves","dr","dc","base","next","handleCardKeyDown","verification","statusText","sunkCount","jsx","Minimize2","Maximize2","onMinimize","ChevronDown","X","onDismiss","Fragment","Crosshair","Waves","active","i","Check","RotateCw","Shuffle","Radar","LocateFixed","BattleshipGameCard_default","memo"],"sources":["../../src/games/battleship/sound/battleshipSounds.js","../../src/games/battleship/sound/cues.js","../../src/games/battleship/BattleshipGameCard.jsx"],"sourcesContent":["import { createSoundManager } from '../../../audio/createSoundManager.js';\nimport { connect4Sounds } from '../../connect4/connect4Sounds.js';\nimport { chatSoundUrl } from '../../../assets/chatAssets.js';\n\nconst AMBIENT = 'ocean_ambient_loop';\n\n// Files come from the supplied pack; levels even out its loudness (measured\n// mean volume) so impacts stay present and alarms/fly-bys never dominate.\nexport const battleshipSounds = createSoundManager({\n id: 'battleship',\n baseUrl: () => chatSoundUrl('battleship_audio_pack/assets'), // resolved lazily at fetch time\n settingsFrom: connect4Sounds, // one mute/volume preference for every chat game\n sounds: Object.fromEntries([\n 'cannon_fire', 'projectile_flyby', 'water_splash', 'ship_hit', 'ship_heavy_hit', 'ship_sinking',\n 'sonar_ping', 'cruiser_damage_alarm', 'ship_place', 'ship_rotate', 'ui_click', 'victory', 'defeat', AMBIENT,\n ].map((name) => [name, `${name}.ogg`])),\n levels: {\n cannon_fire: 0.7, projectile_flyby: 0.3, water_splash: 0.9, ship_hit: 0.9, ship_heavy_hit: 1,\n ship_sinking: 0.4, sonar_ping: 0.35, cruiser_damage_alarm: 0.3, ship_place: 0.4, ship_rotate: 0.4,\n ui_click: 0.3, victory: 0.55, defeat: 0.4, [AMBIENT]: 0.22,\n },\n});\n\nconst hidden = () => typeof document !== 'undefined' && document.hidden;\n\n/** Immediate feedback for a local UI action (never deduplicated). */\nexport function playUiSound(name) {\n if (!hidden()) battleshipSounds.play(name);\n}\n\n/**\n * Plays timed cues once per key. Pending timers live in `timers` so the panel\n * can cancel them on unmount; a hidden page stays silent.\n */\nexport function scheduleCues(cues, keyFor, timers) {\n cues.forEach(({ name, at }) => {\n const run = () => { if (!hidden()) battleshipSounds.play(name, { key: keyFor(name) }); };\n if (at <= 0) { run(); return; }\n const timer = setTimeout(() => { timers.delete(timer); run(); }, at);\n timers.add(timer);\n });\n}\n\n// Ocean bed: plays while at least one open board holds it and the page is visible.\nlet ambientHolders = 0;\nconst syncAmbient = () => {\n if (ambientHolders > 0 && !hidden()) battleshipSounds.startLoop(AMBIENT);\n else battleshipSounds.stopLoop(AMBIENT);\n};\n\nexport function holdAmbient() {\n ambientHolders += 1;\n if (ambientHolders === 1) document.addEventListener('visibilitychange', syncAmbient);\n syncAmbient();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n ambientHolders -= 1;\n if (ambientHolders === 0) document.removeEventListener('visibilitychange', syncAmbient);\n syncAmbient();\n };\n}\n","// Pure sound choreography for Battleship (no audio, no DOM): what to play and\n// when, relative to the shot animation. Times are milliseconds.\n\nexport const CRUISER_ID = 'cruiser';\nexport const CRUISER_ALARM_HITS = 2;\n\nconst sameCell = (a, b) => a.row === b.row && a.col === b.col;\nconst hitsOn = (ship, shots, skip) => ship.cells\n .filter((cell) => shots?.[cell.row]?.[cell.col] === 'hit' && !(skip && sameCell(cell, skip))).length;\n\n/**\n * True only for the confirmed hit that takes our own cruiser from fewer than two\n * hits to two or more. `incomingShots` already contains `shot`. The enemy cruiser\n * stays hidden until sunk, so only our fleet can raise the alarm.\n */\nexport function crossesCruiserAlarm(fleet, incomingShots, shot) {\n if (shot?.result !== 'hit') return false;\n const cruiser = (fleet || []).find((ship) => ship.id === CRUISER_ID);\n if (!cruiser?.cells?.some((cell) => sameCell(cell, shot))) return false;\n const before = hitsOn(cruiser, incomingShots, shot);\n const after = hitsOn(cruiser, incomingShots);\n return before < CRUISER_ALARM_HITS && after >= CRUISER_ALARM_HITS;\n}\n\n// Launch cues play when the projectile leaves; impact cues when it lands.\nexport function launchCues({ incoming }) {\n return incoming\n ? [{ name: 'projectile_flyby', at: 0 }]\n : [{ name: 'cannon_fire', at: 0 }, { name: 'projectile_flyby', at: 180 }];\n}\n\nexport function impactCues({ result, sunk, defeated, won, cruiserAlarm }) {\n const cues = result === 'hit'\n ? (sunk ? [{ name: 'ship_heavy_hit', at: 0 }, { name: 'ship_sinking', at: 350 }] : [{ name: 'ship_hit', at: 0 }])\n : [{ name: 'water_splash', at: 0 }];\n if (cruiserAlarm) cues.push({ name: 'cruiser_damage_alarm', at: 500 });\n if (defeated) cues.push({ name: won ? 'victory' : 'defeat', at: sunk ? 1600 : 600 });\n return cues;\n}\n","/* eslint-disable react/prop-types */\nimport { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport { ChevronDown, Crosshair, LocateFixed, Maximize2, Minimize2, Radar, RotateCw, Shuffle, Check, Anchor, TriangleAlert, Waves, ShieldCheck, X } from 'lucide-react';\nimport { useChatConnectionStatus } from '../../core/connection/connectionStore.js';\nimport useChatGames from '../shared/useChatGames.js';\nimport { getGameStatus, getVerificationLabel, isTerminalGame, sameUser } from '../shared/gameStatus.js';\nimport { BOARD_SIZE, FLEET, createBoard, placeShip, validatePlacement } from './logic';\nimport { hasWebGL } from './webglSupport';\nimport GameSoundControls from '../shared/GameSoundControls.jsx';\nimport { battleshipSounds, holdAmbient, playUiSound, scheduleCues } from './sound/battleshipSounds';\nimport { crossesCruiserAlarm, impactCues, launchCues } from './sound/cues';\nimport '../connect4/games.css';\nimport './battleship.css';\n\nconst ROWS = 'ABCDEFGHIJ';\nconst SHIP_NAMES = { carrier: 'portaaviones', battleship: 'acorazado', cruiser: 'crucero', submarine: 'submarino', destroyer: 'destructor' };\nconst SCENE_STATUSES = ['placement', 'active', 'won', 'conflict', 'closed'];\nconst DOUBLE_SELECT_MS = 400;\nconst EMPTY_SHOTS = Array.from({ length: BOARD_SIZE }, () => Array(BOARD_SIZE).fill(null));\n\nconst cellLabel = (cell) => (cell ? `${ROWS[cell.row]}${cell.col + 1}` : '—');\nconst sameCell = (a, b) => Boolean(a && b && a.row === b.row && a.col === b.col);\nconst isCell = (cell) => Boolean(cell) && Number.isInteger(cell.row) && Number.isInteger(cell.col)\n && cell.row >= 0 && cell.row < BOARD_SIZE && cell.col >= 0 && cell.col < BOARD_SIZE;\nconst shipName = (id) => SHIP_NAMES[id] || 'barco';\nconst shotAt = (shots, cell) => shots?.[cell.row]?.[cell.col] ?? null;\nconst shipAt = (ships, cell) => ships.find((ship) => ship.cells?.some((item) => sameCell(item, cell)));\nconst capitalize = (text) => text.charAt(0).toUpperCase() + text.slice(1);\n\nconst prefersReducedMotion = () => typeof window !== 'undefined' && Boolean(window.matchMedia?.('(prefers-reduced-motion: reduce)').matches);\n\n// The store owns delivery errors; UI handlers must never leak rejected promises.\nconst call = (name, ...args) => Promise.resolve().then(() => useChatGames.getState()[name]?.(...args)).catch(() => {});\n\nfunction buildBoard(fleet) {\n let board = createBoard();\n for (const ship of fleet || []) {\n const first = ship.cells?.[0];\n if (!first) continue;\n const placed = placeShip(board, { shipId: ship.id, row: first.row, col: first.col, orientation: ship.orientation });\n if (placed.ok) board = placed.board;\n }\n return board;\n}\n\nfunction previewCells(anchor, size, orientation) {\n return Array.from({ length: size }, (_, index) => ({\n row: anchor.row + (orientation === 'vertical' ? index : 0),\n col: anchor.col + (orientation === 'horizontal' ? index : 0),\n })).filter(isCell);\n}\n\nfunction countShots(shots) {\n let total = 0; let hits = 0;\n for (const row of shots || []) for (const shot of row || []) { if (shot) total += 1; if (shot === 'hit') hits += 1; }\n return { total, hits };\n}\n\nfunction SyncControls({ sync, connected, onResync, onAdoptOffer }) {\n if (sync?.status === 'requesting') return <div className=\"chat-game-sync\" role=\"status\">Sincronizando partida…</div>;\n return <div className=\"chat-game-sync\" role=\"alert\">\n {sync?.message && <span>{sync.message}</span>}\n {sync?.status === 'incompatible' && sync.offer && <button type=\"button\" className=\"chat-game-action chat-game-action--primary\" disabled={!connected} onClick={onAdoptOffer}>Usar estado del anfitrión</button>}\n <button type=\"button\" className=\"chat-game-action\" disabled={!connected} onClick={onResync}>Reintentar sincronización</button>\n </div>;\n}\n\nfunction VerificationBadge({ game }) {\n const label = getVerificationLabel(game);\n if (!label) return null;\n return <span className={`bs-badge bs-badge--${game.verification}`}>{game.verification === 'ok' && <ShieldCheck size={12} aria-hidden=\"true\" />}{game.verification === 'mismatch' && <TriangleAlert size={12} aria-hidden=\"true\" />}{label}</span>;\n}\n\n// 2D grid used when WebGL is unavailable: same interaction, no three.js.\nfunction FallbackGrid({ view, selected, cursor, onSelect, onHover }) {\n const shipCells = new Map();\n view.ships.forEach((ship) => ship.cells.forEach((cell) => shipCells.set(`${cell.row}-${cell.col}`, ship)));\n const preview = new Set((view.preview?.cells || []).map((cell) => `${cell.row}-${cell.col}`));\n return <div className=\"bs-grid\" role=\"grid\" aria-label={view.mode === 'target' ? 'Tablero objetivo' : 'Mi flota'} onMouseLeave={() => onHover(null)}>\n {Array.from({ length: BOARD_SIZE }, (_, row) => <div role=\"row\" key={row} className=\"bs-grid__row\">\n {Array.from({ length: BOARD_SIZE }, (_, col) => {\n const id = `${row}-${col}`;\n const ship = shipCells.get(id);\n const shot = view.shots?.[row]?.[col];\n const cls = ['bs-grid__cell', ship && 'is-ship', ship?.sunk && 'is-sunk', shot && `is-${shot}`,\n preview.has(id) && (view.preview.valid ? 'is-preview' : 'is-invalid'),\n sameCell(selected, { row, col }) && 'is-selected', sameCell(cursor, { row, col }) && 'is-cursor'].filter(Boolean).join(' ');\n return <button key={id} type=\"button\" role=\"gridcell\" tabIndex={-1} className={cls} disabled={!view.interactive}\n aria-label={`${ROWS[row]}${col + 1}${shot === 'hit' ? ', impacto' : shot === 'miss' ? ', agua' : ''}${ship ? ', barco' : ''}`}\n onMouseEnter={() => onHover({ row, col })} onClick={() => onSelect({ row, col })} />;\n })}\n </div>)}\n </div>;\n}\n\nfunction HistorySummary({ game, currentUserId, status }) {\n const { total, hits } = countShots(game.targetShots);\n const sunk = game.sunkEnemyShips?.length || 0;\n const showStats = ['active', 'won', 'closed', 'conflict'].includes(game.status) && total > 0;\n const iWon = game.status === 'won' && sameUser(currentUserId, game.winnerId);\n return <section className=\"chat-game-card chat-game-card--history bs-card bs-card--history\" aria-label=\"Partida de Batalla Naval\">\n <header className=\"chat-game-header\">\n <div className=\"chat-game-heading\">\n <span className=\"chat-game-eyebrow\">MINIJUEGOS · 2 JUGADORES</span>\n <h3>Batalla Naval <Anchor size={13} aria-hidden=\"true\" className=\"bs-title-icon\" /></h3>\n </div>\n </header>\n <p className={`chat-game-status${iWon ? ' bs-status--win' : ''}`}>{status}</p>\n {showStats && <p className=\"bs-history-stats\">Disparos {total} · Impactos {hits} · Hundidos {sunk}/{FLEET.length}</p>}\n <VerificationBadge game={game} />\n </section>;\n}\n\nfunction BattleshipGameCard({ gameKey, currentUserId, variant = 'panel', onMinimize, onDismiss }) {\n const game = useChatGames((state) => state.games[gameKey]);\n const connected = useChatConnectionStatus() === 'connected';\n if (!game) return null;\n const status = getGameStatus(game, currentUserId);\n if (variant === 'history') return <HistorySummary game={game} currentUserId={currentUserId} status={status} />;\n return <BattleshipPanel game={game} gameKey={gameKey} currentUserId={currentUserId} connected={connected}\n status={status} variant={variant} onMinimize={onMinimize} onDismiss={onDismiss} />;\n}\n\nfunction BattleshipPanel({ game, gameKey, currentUserId, connected, status, variant, onMinimize, onDismiss }) {\n const stageRef = useRef(null);\n const sceneRef = useRef(null);\n const animatingRef = useRef(false);\n const lastSeenShotRef = useRef(undefined);\n const lastSelectRef = useRef({ cell: null, time: 0 });\n const handlersRef = useRef({});\n const soundTimersRef = useRef(new Set());\n const lastStatusRef = useRef(game.status);\n const hintId = useId();\n const [sceneStatus, setSceneStatus] = useState('idle');\n const [viewMode, setViewMode] = useState('own');\n const [hovered, setHovered] = useState(null);\n const [cursor, setCursor] = useState(null);\n const [selected, setSelected] = useState(null);\n const [orientation, setOrientation] = useState('horizontal');\n const [activeShipId, setActiveShipId] = useState(null);\n const [radar, setRadar] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [animating, setAnimating] = useState(false);\n const [announcement, setAnnouncement] = useState(null);\n\n const isHost = sameUser(currentUserId, game.hostId);\n const isGuest = sameUser(currentUserId, game.guestId);\n const isParticipant = isHost || isGuest;\n const terminal = isTerminalGame(game);\n const placing = game.status === 'placement';\n const battle = game.status === 'active' || game.status === 'won';\n const myTurn = game.status === 'active' && sameUser(currentUserId, game.turnId);\n const busy = !connected || Boolean(game.pending) || Boolean(game.pendingEvent);\n const canFire = myTurn && !game.pendingShot && !busy && !game.error && !animating;\n const canPlace = placing && !game.myReady && !busy;\n const sceneVisible = SCENE_STATUSES.includes(game.status) && (game.status !== 'closed' || (game.myFleet?.length ?? 0) > 0);\n const sceneReady = sceneStatus === 'ready';\n\n const myFleet = useMemo(() => game.myFleet || [], [game.myFleet]);\n const incomingShots = game.incomingShots || EMPTY_SHOTS;\n const targetShots = game.targetShots || EMPTY_SHOTS;\n const ownBoard = useMemo(() => buildBoard(myFleet), [myFleet]);\n const placedIds = useMemo(() => new Set(myFleet.map((ship) => ship.id)), [myFleet]);\n const fleetComplete = FLEET.every((ship) => placedIds.has(ship.id));\n const currentShip = FLEET.find((ship) => ship.id === activeShipId && !placedIds.has(ship.id)) || FLEET.find((ship) => !placedIds.has(ship.id)) || null;\n\n const ownShips = useMemo(() => myFleet.map((ship) => ({ ...ship, sunk: Boolean(ship.cells?.length) && ship.cells.every((cell) => shotAt(incomingShots, cell) === 'hit') })), [myFleet, incomingShots]);\n const enemyShips = useMemo(() => (game.sunkEnemyShips || []).filter((ship) => ship?.cells?.length)\n .map((ship) => ({ ...ship, size: ship.size ?? ship.cells.length, sunk: true })), [game.sunkEnemyShips]);\n const { total: shotCount, hits: hitCount } = useMemo(() => countShots(targetShots), [targetShots]);\n const radarContacts = useMemo(() => {\n const cells = [];\n targetShots.forEach((row, r) => row?.forEach((shot, c) => { if (shot === 'hit') cells.push({ row: r, col: c }); }));\n return cells;\n }, [targetShots]);\n\n const mode = placing ? 'own' : viewMode;\n const anchor = hovered || cursor;\n const preview = useMemo(() => {\n if (!canPlace || !currentShip || !anchor) return null;\n const result = validatePlacement(ownBoard, { shipId: currentShip.id, row: anchor.row, col: anchor.col, orientation });\n return { cells: result.ok ? result.ship.cells : previewCells(anchor, currentShip.size, orientation), valid: result.ok };\n }, [canPlace, currentShip, anchor, ownBoard, orientation]);\n\n const buildView = useCallback((viewModeArg, hideCell) => {\n if (viewModeArg === 'target') {\n const shots = hideCell ? targetShots.map((row, r) => row.map((shot, c) => (r === hideCell.row && c === hideCell.col ? null : shot))) : targetShots;\n const ships = hideCell ? enemyShips.map((ship) => (shipAt([ship], hideCell) ? { ...ship, sunk: false } : ship)) : enemyShips;\n return { mode: 'target', ships, shots, preview: null, interactive: canFire };\n }\n const shots = hideCell ? incomingShots.map((row, r) => row.map((shot, c) => (r === hideCell.row && c === hideCell.col ? null : shot))) : incomingShots;\n const ships = hideCell ? ownShips.map((ship) => (shipAt([ship], hideCell) ? { ...ship, sunk: false } : ship)) : ownShips;\n return { mode: 'own', ships, shots, preview: placing ? preview : null, interactive: canPlace };\n }, [targetShots, enemyShips, incomingShots, ownShips, placing, preview, canFire, canPlace]);\n const view = useMemo(() => buildView(mode), [buildView, mode]);\n\n const announce = useCallback((text, kind = 'info') => setAnnouncement({ text, kind, id: Date.now() }), []);\n\n const fire = useCallback((cell = selected) => {\n if (!canFire || !isCell(cell)) return;\n if (shotAt(targetShots, cell)) { announce(`Ya disparaste en ${cellLabel(cell)}`); return; }\n setSelected(null);\n sceneRef.current?.selectCell?.(null);\n playUiSound('ui_click');\n void call('bsFire', gameKey, { row: cell.row, col: cell.col });\n }, [canFire, selected, targetShots, gameKey, announce]);\n\n const placeAt = useCallback((cell) => {\n if (!canPlace || !isCell(cell)) return;\n const placed = shipAt(myFleet, cell);\n if (placed) {\n setActiveShipId(placed.id);\n if (placed.orientation) setOrientation(placed.orientation);\n playUiSound('ui_click');\n void call('bsRemoveShip', gameKey, placed.id);\n return;\n }\n if (!currentShip) return;\n const result = validatePlacement(ownBoard, { shipId: currentShip.id, row: cell.row, col: cell.col, orientation });\n if (!result.ok) { announce(result.reason === 'overlap' ? 'Se superpone con otro barco' : 'No cabe en esa posición', 'miss'); return; }\n setActiveShipId(null);\n playUiSound('ship_place');\n void call('bsPlaceShip', gameKey, { shipId: currentShip.id, row: cell.row, col: cell.col, orientation });\n }, [canPlace, myFleet, currentShip, ownBoard, orientation, gameKey, announce]);\n\n const selectCell = useCallback((cell) => {\n if (!isCell(cell)) return;\n setCursor(cell);\n if (placing) { placeAt(cell); return; }\n if (mode !== 'target' || !canFire) return;\n const now = Date.now();\n const last = lastSelectRef.current;\n lastSelectRef.current = { cell, time: now };\n if (sameCell(last.cell, cell) && now - last.time < DOUBLE_SELECT_MS) { fire(cell); return; }\n if (shotAt(targetShots, cell)) { announce(`Ya disparaste en ${cellLabel(cell)}`); return; }\n setSelected(cell);\n sceneRef.current?.selectCell?.(cell);\n }, [placing, placeAt, mode, canFire, fire, targetShots, announce]);\n\n handlersRef.current = { selectCell, setHovered };\n\n // One WebGL context per card: created once while the board is visible, disposed on unmount.\n useEffect(() => {\n const container = stageRef.current;\n if (!sceneVisible || !container) return undefined;\n if (!hasWebGL()) { setSceneStatus('fallback'); return undefined; }\n let disposed = false;\n let scene = null;\n setSceneStatus('loading');\n import('./scene/createBattleScene.js')\n .then(({ createBattleScene }) => {\n if (disposed) return;\n scene = createBattleScene(container, {\n quality: 'auto',\n reducedMotion: prefersReducedMotion(),\n onCellHover: (cell) => { if (!disposed) handlersRef.current.setHovered(isCell(cell) ? { row: cell.row, col: cell.col } : null); },\n onCellSelect: (cell) => { if (!disposed) handlersRef.current.selectCell(isCell(cell) ? { row: cell.row, col: cell.col } : null); },\n });\n sceneRef.current = scene;\n setSceneStatus('ready');\n })\n .catch((error) => {\n if (disposed) return;\n console.error('[battleship] No se pudo iniciar la escena', error);\n setSceneStatus('fallback');\n });\n return () => {\n disposed = true;\n sceneRef.current = null;\n try { scene?.dispose(); } catch (error) { console.error('[battleship] Error al liberar la escena', error); }\n };\n }, [sceneVisible]);\n\n useEffect(() => {\n battleshipSounds.preload();\n const timers = soundTimersRef.current;\n return () => { timers.forEach(clearTimeout); timers.clear(); };\n }, []);\n\n // Ocean bed only while this board is open (unmounted when minimized/closed).\n const ambient = sceneVisible && !terminal;\n useEffect(() => (ambient ? holdAmbient() : undefined), [ambient]);\n\n // Both fleets committed: sonar sweep once per game.\n useEffect(() => {\n const before = lastStatusRef.current;\n lastStatusRef.current = game.status;\n if (before === 'placement' && game.status === 'active') scheduleCues([{ name: 'sonar_ping', at: 0 }], () => `${game.gameId}:start`, soundTimersRef.current);\n }, [game.status, game.gameId]);\n\n // Animate each new shot once (never replay history on mount), then show the settled state.\n // Sounds follow the same event id, so RESYNC/replayed frames (no new id) stay silent.\n const lastShot = game.lastShot;\n useEffect(() => {\n if (!sceneReady && sceneStatus !== 'fallback') return;\n const eventId = lastShot?.eventId ?? null;\n if (lastSeenShotRef.current === undefined) { lastSeenShotRef.current = eventId; return; }\n if (!eventId || eventId === lastSeenShotRef.current) return;\n lastSeenShotRef.current = eventId;\n const incoming = !sameUser(lastShot.by, currentUserId);\n const cell = { row: lastShot.row, col: lastShot.col };\n const label = cellLabel(cell);\n const sunkId = typeof lastShot.sunk === 'string' ? lastShot.sunk\n : lastShot.sunk ? shipAt(incoming ? myFleet : (game.sunkEnemyShips || []), cell)?.id : null;\n const text = incoming\n ? (lastShot.sunk ? `Te hundieron el ${shipName(sunkId)}` : lastShot.result === 'hit' ? `El rival impactó en ${label}` : `El rival falló: agua en ${label}`)\n : (lastShot.sunk ? `¡Hundiste el ${shipName(sunkId)}!` : lastShot.result === 'hit' ? `¡Impacto en ${label}!` : `Agua en ${label}`);\n const kind = lastShot.result === 'hit' ? 'hit' : 'miss';\n const nextMode = incoming ? 'own' : 'target';\n // The cruiser alarm is keyed per game: it can sound only once per cruiser.\n const cruiserAlarm = incoming && crossesCruiserAlarm(myFleet, game.incomingShots, lastShot);\n const impact = impactCues({ result: lastShot.result, sunk: Boolean(lastShot.sunk), defeated: Boolean(lastShot.defeated), won: !incoming, cruiserAlarm });\n const cueKey = (name) => (name === 'cruiser_damage_alarm' ? `${game.gameId}:cruiser`\n : name === 'victory' || name === 'defeat' ? `${game.gameId}:end` : eventId);\n const timers = soundTimersRef.current;\n setViewMode(nextMode);\n const scene = sceneRef.current;\n if (!scene?.playShot) { scheduleCues(impact, cueKey, timers); announce(text, kind); return; }\n scheduleCues(launchCues({ incoming }), cueKey, timers);\n animatingRef.current = true;\n setAnimating(true);\n let cancelled = false;\n try { scene.setView(buildView(nextMode, cell)); } catch { /* scene keeps its last view */ }\n const hold = prefersReducedMotion() ? 0 : 600;\n Promise.resolve(scene.playShot({ row: cell.row, col: cell.col, result: lastShot.result, sunk: Boolean(lastShot.sunk), incoming }))\n .catch(() => {})\n .then(() => { scheduleCues(impact, cueKey, timers); if (!cancelled) announce(text, kind); return new Promise((resolve) => setTimeout(resolve, hold)); })\n .then(() => { if (!cancelled) { animatingRef.current = false; setAnimating(false); } });\n return () => { cancelled = true; animatingRef.current = false; setAnimating(false); };\n // Only a new event id may trigger an animation.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [sceneReady, sceneStatus, lastShot?.eventId]);\n\n // Auto-switch: my turn → target, rival turn → my fleet (after any running animation).\n useEffect(() => {\n if (animating || game.status !== 'active') return;\n setViewMode(myTurn ? 'target' : 'own');\n }, [myTurn, game.status, animating]);\n\n useEffect(() => { if (!canFire) setSelected(null); }, [canFire]);\n\n // Push the settled view to the scene unless a shot animation owns it.\n useEffect(() => {\n if (!sceneReady || animatingRef.current) return;\n try { sceneRef.current?.setView(view); } catch (error) { console.error('[battleship] setView', error); }\n }, [sceneReady, view, animating]);\n\n useEffect(() => {\n if (!sceneReady) return;\n sceneRef.current?.selectCell?.(mode === 'target' ? selected : null);\n }, [sceneReady, selected, mode]);\n\n useEffect(() => {\n if (!sceneReady) return;\n const scene = sceneRef.current;\n scene?.setRadarVisible?.(radar && mode === 'target');\n scene?.setRadarContacts?.(radarContacts);\n }, [sceneReady, radar, mode, radarContacts]);\n\n const rotate = () => { playUiSound('ship_rotate'); setOrientation((value) => (value === 'horizontal' ? 'vertical' : 'horizontal')); };\n const ready = () => { if (fleetComplete && canPlace) { playUiSound('ui_click'); void call('bsReady', gameKey); } };\n const clicked = (action) => (...args) => { playUiSound('ui_click'); action(...args); };\n const toggleRadar = () => {\n playUiSound(radar ? 'ui_click' : 'sonar_ping');\n setRadar((value) => !value);\n };\n\n const handleStageKeyDown = (event) => {\n if (event.target !== event.currentTarget || event.altKey || event.ctrlKey || event.metaKey) return;\n const moves = { ArrowUp: [-1, 0], ArrowDown: [1, 0], ArrowLeft: [0, -1], ArrowRight: [0, 1] };\n if (moves[event.key]) {\n event.preventDefault();\n const [dr, dc] = moves[event.key];\n const base = (mode === 'target' ? selected : null) || cursor || hovered;\n const next = base ? { row: Math.min(BOARD_SIZE - 1, Math.max(0, base.row + dr)), col: Math.min(BOARD_SIZE - 1, Math.max(0, base.col + dc)) } : { row: 0, col: 0 };\n setCursor(next);\n setHovered(null);\n if (mode === 'target' && canFire) { setSelected(next); sceneRef.current?.selectCell?.(next); }\n } else if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n if (placing) placeAt(cursor || hovered);\n else fire(selected || cursor);\n }\n };\n\n const handleCardKeyDown = (event) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;\n if (/^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName) || event.target.isContentEditable) return;\n if (event.key === 'r' || event.key === 'R') {\n event.preventDefault();\n if (placing) rotate(); else sceneRef.current?.resetCamera?.();\n } else if (event.key === 'Escape' && expanded) {\n event.preventDefault();\n event.stopPropagation();\n setExpanded(false);\n }\n };\n\n const verification = <VerificationBadge game={game} />;\n const iWon = game.status === 'won' && sameUser(currentUserId, game.winnerId);\n const statusText = !connected && !terminal ? 'Sin conexión · esperando reconexión' : game.pending ? 'Sincronizando…' : status;\n const sunkCount = enemyShips.length;\n\n return (\n <section className={`chat-game-card bs-card${myTurn ? ' chat-game-card--my-turn' : ''}${variant ? ` chat-game-card--${variant}` : ''}${expanded ? ' bs-card--expanded' : ''}`}\n aria-label=\"Partida de Batalla Naval\" onKeyDown={handleCardKeyDown}>\n <header className=\"chat-game-header\">\n <div className=\"chat-game-heading\">\n <span className=\"chat-game-eyebrow\">MINIJUEGOS · 2 JUGADORES</span>\n <h3>Batalla Naval <Anchor size={13} aria-hidden=\"true\" className=\"bs-title-icon\" /></h3>\n </div>\n {variant === 'panel' && <GameSoundControls manager={battleshipSounds} />}\n {sceneVisible && <button className=\"chat-game-close bs-expand\" type=\"button\" aria-pressed={expanded}\n aria-label={expanded ? 'Reducir tablero' : 'Ampliar tablero'} title={expanded ? 'Reducir (Esc)' : 'Ampliar'} onClick={clicked(() => setExpanded((value) => !value))}>\n {expanded ? <Minimize2 size={15} aria-hidden=\"true\" /> : <Maximize2 size={15} aria-hidden=\"true\" />}\n </button>}\n {onMinimize && <button className=\"chat-game-close\" type=\"button\" aria-label=\"Minimizar tablero\" title=\"Minimizar tablero\" onClick={() => { setExpanded(false); onMinimize(); }}><ChevronDown size={16} aria-hidden=\"true\" /></button>}\n {isParticipant && !terminal && (\n <button className=\"chat-game-close\" type=\"button\" aria-label=\"Finalizar partida para ambos jugadores\" title=\"Finalizar partida para ambos\" onClick={() => void call('act', gameKey, 'game_end')} disabled={!connected}><X size={16} aria-hidden=\"true\" /></button>\n )}\n {onDismiss && <button className=\"chat-game-close\" type=\"button\" aria-label=\"Cerrar tablero y volver al chat\" title=\"Cerrar tablero\" onClick={onDismiss}><X size={16} aria-hidden=\"true\" /></button>}\n </header>\n\n <div className=\"bs-statusline\">\n <p className={`chat-game-status${iWon ? ' bs-status--win' : ''}`} role=\"status\">{statusText}</p>\n {verification}\n </div>\n\n {game.status === 'invited' && <div className=\"bs-invite\">\n <p>Coloca 5 barcos en un tablero de 10×10 y hunde la flota rival por turnos.</p>\n {isGuest && <div className=\"chat-game-actions\">\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary\" disabled={busy} onClick={clicked(() => void call('act', gameKey, 'game_accept'))}>Aceptar partida</button>\n <button type=\"button\" className=\"chat-game-action\" disabled={busy} onClick={clicked(() => void call('act', gameKey, 'game_decline'))}>Rechazar</button>\n </div>}\n </div>}\n\n {sceneVisible && <>\n {battle && <div className=\"bs-hud\" role=\"toolbar\" aria-label=\"Vista del tablero\">\n <div className=\"bs-segment\">\n <button type=\"button\" aria-pressed={viewMode === 'target'} onClick={clicked(() => setViewMode('target'))}><Crosshair size={14} aria-hidden=\"true\" />Objetivo</button>\n <button type=\"button\" aria-pressed={viewMode === 'own'} onClick={clicked(() => setViewMode('own'))}><Anchor size={14} aria-hidden=\"true\" />Mi flota</button>\n </div>\n <dl className=\"bs-stats\">\n <div><dt>Disparos</dt><dd>{shotCount}</dd></div>\n <div><dt>Impactos</dt><dd>{hitCount}</dd></div>\n <div><dt>Hundidos</dt><dd>{sunkCount}/{FLEET.length}</dd></div>\n </dl>\n </div>}\n\n <div className=\"bs-stage-wrap\">\n <div ref={stageRef} className={`bs-stage${sceneStatus === 'fallback' ? ' bs-stage--fallback' : ''}`} tabIndex={0} role=\"application\"\n aria-label={placing ? 'Tablero 3D de tu flota. Flechas para mover, Enter para colocar o quitar un barco, R para rotar.' : 'Tablero 3D de Batalla Naval. Flechas para mover la selección, Enter para disparar, R para centrar la cámara.'}\n aria-describedby={hintId} aria-busy={sceneStatus === 'loading'} onKeyDown={handleStageKeyDown}>\n {sceneStatus === 'fallback' && <FallbackGrid view={view} selected={mode === 'target' ? selected : null} cursor={cursor} onSelect={selectCell} onHover={setHovered} />}\n </div>\n {sceneStatus === 'loading' && <div className=\"bs-stage-state\" role=\"status\"><Waves size={16} aria-hidden=\"true\" /> Preparando el océano…</div>}\n {sceneStatus === 'fallback' && <p className=\"bs-fallback-note\"><TriangleAlert size={12} aria-hidden=\"true\" /> Vista 3D no disponible · modo 2D</p>}\n <div className=\"bs-cell-chip\" aria-hidden=\"true\">{placing ? cellLabel(anchor) : mode === 'target' ? cellLabel(selected || hovered) : cellLabel(hovered)}</div>\n <div className=\"bs-live\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement && <span key={announcement.id} className={`bs-toast bs-toast--${announcement.kind}`}>{announcement.text}</span>}\n </div>\n </div>\n <p id={hintId} className=\"bs-hint\">{placing\n ? 'Clic para colocar · clic en un barco para quitarlo · R para rotar'\n : 'Arrastra para rotar · doble clic o Enter para disparar'}</p>\n\n {placing && <div className=\"bs-placement\">\n <ul className=\"bs-fleet\" aria-label=\"Tu flota\">\n {FLEET.map((ship) => {\n const placed = placedIds.has(ship.id);\n const active = currentShip?.id === ship.id;\n return <li key={ship.id}>\n <button type=\"button\" className={`bs-ship${placed ? ' is-placed' : ''}${active ? ' is-active' : ''}`} aria-pressed={active}\n disabled={!canPlace} title={placed ? 'Quitar y volver a colocar' : 'Seleccionar barco'}\n onClick={clicked(() => { if (placed) void call('bsRemoveShip', gameKey, ship.id); setActiveShipId(ship.id); })}>\n <span className=\"bs-ship__name\">{capitalize(shipName(ship.id))}</span>\n <span className=\"bs-ship__pips\" aria-label={`${ship.size} casillas`}>{Array.from({ length: ship.size }, (_, i) => <i key={i} />)}</span>\n {placed && <Check size={13} aria-label=\"colocado\" />}\n </button>\n </li>;\n })}\n </ul>\n <div className=\"chat-game-actions bs-actions\">\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!canPlace} onClick={rotate} title=\"Rotar (R)\">\n <RotateCw size={15} aria-hidden=\"true\" />{orientation === 'horizontal' ? 'Horizontal' : 'Vertical'}\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!canPlace} onClick={() => { playUiSound('ship_place'); void call('bsRandomFleet', gameKey); }}><Shuffle size={15} aria-hidden=\"true\" />Aleatorio</button>\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary bs-btn\" disabled={!canPlace || !fleetComplete} onClick={ready}>\n <Check size={15} aria-hidden=\"true\" />{game.myReady ? 'Flota lista' : `Listo (${placedIds.size}/${FLEET.length})`}\n </button>\n </div>\n {game.myReady && <p className=\"bs-waiting\">{game.opponentReady ? 'Ambas flotas listas · iniciando…' : 'Flota lista. Esperando a que el rival coloque su flota…'}</p>}\n </div>}\n\n {battle && <div className=\"chat-game-actions bs-actions\">\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary bs-btn bs-btn--fire\" disabled={!canFire || !selected || mode !== 'target'} onClick={() => fire()}\n title={selected ? `Disparar en ${cellLabel(selected)} (Enter)` : 'Selecciona una casilla'}>\n <Crosshair size={15} aria-hidden=\"true\" />Disparar{selected ? ` · ${cellLabel(selected)}` : ''}\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" aria-pressed={radar} disabled={mode !== 'target' || !sceneReady} onClick={toggleRadar} title=\"Radar de impactos\">\n <Radar size={15} aria-hidden=\"true\" />Radar\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!sceneReady} onClick={clicked(() => sceneRef.current?.resetCamera?.())} title=\"Centrar cámara (R)\">\n <LocateFixed size={15} aria-hidden=\"true\" /><span className=\"bs-btn-label\">Centrar</span>\n </button>\n </div>}\n </>}\n\n {game.status === 'conflict' && isParticipant && <SyncControls sync={game.sync} connected={connected}\n onResync={() => void call('requestResync', gameKey)} onAdoptOffer={() => void call('adoptResyncOffer', gameKey)} />}\n {game.error && <div className=\"chat-game-error\" role=\"alert\"><span>{game.error}</span>\n {game.pendingEvent && <button type=\"button\" className=\"chat-game-action\" disabled={!connected || game.pending} onClick={() => void call('retry', gameKey)}>Reintentar</button>}\n </div>}\n <footer className=\"chat-game-footer\">{terminal ? 'Puedes seguir conversando o invitar a otra partida.' : 'Hunde los 5 barcos rivales. El chat sigue disponible.'}</footer>\n </section>\n );\n}\n\nexport default memo(BattleshipGameCard);\n"],"mappings":"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"}
1
+ {"version":3,"file":"BattleshipGameCard-S-UdM6rn.js","names":["sameCell","_Fragment","useChatGames","useChatConnectionStatus","createSoundManager","sameUser","GameSoundControls","isTerminalGame","getGameStatus","connect4Sounds","getVerificationLabel","chatSoundUrl","validatePlacement","createBoard","placeShip","FLEET","hasWebGL","AMBIENT","battleshipSounds","name","hidden","playUiSound","scheduleCues","run","keyFor","at","timer","timers","ambientHolders","syncAmbient","holdAmbient","released","CRUISER_ID","sameCell$1","a","b","hitsOn","ship","shots","cell","skip","crossesCruiserAlarm","shot","cruiser","fleet","before","incomingShots","after","launchCues","incoming","impactCues","cues","result","sunk","cruiserAlarm","defeated","won","ROWS","SHIP_NAMES","SCENE_STATUSES","DOUBLE_SELECT_MS","EMPTY_SHOTS","cellLabel","sameCell","isCell","shipName","id","shotAt","shipAt","ships","item","capitalize","text","prefersReducedMotion","call","args","buildBoard","board","first","placed","previewCells","size","anchor","orientation","index","countShots","total","hits","row","SyncControls","sync","connected","onAdoptOffer","onResync","VerificationBadge","label","game","ShieldCheck","TriangleAlert","FallbackGrid","shipCells","preview","view","onHover","col","cls","selected","cursor","onSelect","HistorySummary","showStats","iWon","currentUserId","Anchor","status","BattleshipGameCard","state","gameKey","variant","BattleshipPanel","stageRef","useRef","sceneRef","animatingRef","lastSeenShotRef","lastSelectRef","handlersRef","soundTimersRef","lastStatusRef","hintId","useId","sceneStatus","setSceneStatus","useState","viewMode","setViewMode","hovered","setHovered","setCursor","setSelected","setOrientation","activeShipId","setActiveShipId","radar","setRadar","expanded","setExpanded","animating","setAnimating","announcement","setAnnouncement","isHost","isGuest","isParticipant","terminal","placing","battle","myTurn","busy","canFire","canPlace","sceneVisible","sceneReady","myFleet","useMemo","targetShots","ownBoard","placedIds","fleetComplete","currentShip","ownShips","enemyShips","shotCount","hitCount","radarContacts","cells","r","c","mode","buildView","useCallback","viewModeArg","hideCell","announce","fire","placeAt","selectCell","now","last","useEffect","container","disposed","scene","createBattleScene","error","ambient","lastShot","eventId","sunkId","kind","nextMode","impact","cueKey","cancelled","hold","resolve","rotate","value","ready","clicked","action","toggleRadar","handleStageKeyDown","event","moves","dr","dc","base","next","handleCardKeyDown","verification","statusText","sunkCount","jsx","Minimize2","Maximize2","onMinimize","ChevronDown","X","onDismiss","Fragment","Crosshair","Waves","active","i","Check","RotateCw","Shuffle","Radar","LocateFixed","BattleshipGameCard_default","memo"],"sources":["../../src/games/battleship/sound/battleshipSounds.js","../../src/games/battleship/sound/cues.js","../../src/games/battleship/BattleshipGameCard.jsx"],"sourcesContent":["import { createSoundManager } from '../../../audio/createSoundManager.js';\nimport { connect4Sounds } from '../../connect4/connect4Sounds.js';\nimport { chatSoundUrl } from '../../../assets/chatAssets.js';\n\nconst AMBIENT = 'ocean_ambient_loop';\n\n// Files come from the supplied pack; levels even out its loudness (measured\n// mean volume) so impacts stay present and alarms/fly-bys never dominate.\nexport const battleshipSounds = createSoundManager({\n id: 'battleship',\n baseUrl: () => chatSoundUrl('battleship_audio_pack/assets'), // resolved lazily at fetch time\n settingsFrom: connect4Sounds, // one mute/volume preference for every chat game\n sounds: Object.fromEntries([\n 'cannon_fire', 'projectile_flyby', 'water_splash', 'ship_hit', 'ship_heavy_hit', 'ship_sinking',\n 'sonar_ping', 'cruiser_damage_alarm', 'ship_place', 'ship_rotate', 'ui_click', 'victory', 'defeat', AMBIENT,\n ].map((name) => [name, `${name}.ogg`])),\n levels: {\n cannon_fire: 0.7, projectile_flyby: 0.3, water_splash: 0.9, ship_hit: 0.9, ship_heavy_hit: 1,\n ship_sinking: 0.4, sonar_ping: 0.35, cruiser_damage_alarm: 0.3, ship_place: 0.4, ship_rotate: 0.4,\n ui_click: 0.3, victory: 0.55, defeat: 0.4, [AMBIENT]: 0.22,\n },\n});\n\nconst hidden = () => typeof document !== 'undefined' && document.hidden;\n\n/** Immediate feedback for a local UI action (never deduplicated). */\nexport function playUiSound(name) {\n if (!hidden()) battleshipSounds.play(name);\n}\n\n/**\n * Plays timed cues once per key. Pending timers live in `timers` so the panel\n * can cancel them on unmount; a hidden page stays silent.\n */\nexport function scheduleCues(cues, keyFor, timers) {\n cues.forEach(({ name, at }) => {\n const run = () => { if (!hidden()) battleshipSounds.play(name, { key: keyFor(name) }); };\n if (at <= 0) { run(); return; }\n const timer = setTimeout(() => { timers.delete(timer); run(); }, at);\n timers.add(timer);\n });\n}\n\n// Ocean bed: plays while at least one open board holds it and the page is visible.\nlet ambientHolders = 0;\nconst syncAmbient = () => {\n if (ambientHolders > 0 && !hidden()) battleshipSounds.startLoop(AMBIENT);\n else battleshipSounds.stopLoop(AMBIENT);\n};\n\nexport function holdAmbient() {\n ambientHolders += 1;\n if (ambientHolders === 1) document.addEventListener('visibilitychange', syncAmbient);\n syncAmbient();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n ambientHolders -= 1;\n if (ambientHolders === 0) document.removeEventListener('visibilitychange', syncAmbient);\n syncAmbient();\n };\n}\n","// Pure sound choreography for Battleship (no audio, no DOM): what to play and\n// when, relative to the shot animation. Times are milliseconds.\n\nexport const CRUISER_ID = 'cruiser';\nexport const CRUISER_ALARM_HITS = 2;\n\nconst sameCell = (a, b) => a.row === b.row && a.col === b.col;\nconst hitsOn = (ship, shots, skip) => ship.cells\n .filter((cell) => shots?.[cell.row]?.[cell.col] === 'hit' && !(skip && sameCell(cell, skip))).length;\n\n/**\n * True only for the confirmed hit that takes our own cruiser from fewer than two\n * hits to two or more. `incomingShots` already contains `shot`. The enemy cruiser\n * stays hidden until sunk, so only our fleet can raise the alarm.\n */\nexport function crossesCruiserAlarm(fleet, incomingShots, shot) {\n if (shot?.result !== 'hit') return false;\n const cruiser = (fleet || []).find((ship) => ship.id === CRUISER_ID);\n if (!cruiser?.cells?.some((cell) => sameCell(cell, shot))) return false;\n const before = hitsOn(cruiser, incomingShots, shot);\n const after = hitsOn(cruiser, incomingShots);\n return before < CRUISER_ALARM_HITS && after >= CRUISER_ALARM_HITS;\n}\n\n// Launch cues play when the projectile leaves; impact cues when it lands.\nexport function launchCues({ incoming }) {\n return incoming\n ? [{ name: 'projectile_flyby', at: 0 }]\n : [{ name: 'cannon_fire', at: 0 }, { name: 'projectile_flyby', at: 180 }];\n}\n\nexport function impactCues({ result, sunk, defeated, won, cruiserAlarm }) {\n const cues = result === 'hit'\n ? (sunk ? [{ name: 'ship_heavy_hit', at: 0 }, { name: 'ship_sinking', at: 350 }] : [{ name: 'ship_hit', at: 0 }])\n : [{ name: 'water_splash', at: 0 }];\n if (cruiserAlarm) cues.push({ name: 'cruiser_damage_alarm', at: 500 });\n if (defeated) cues.push({ name: won ? 'victory' : 'defeat', at: sunk ? 1600 : 600 });\n return cues;\n}\n","/* eslint-disable react/prop-types */\nimport { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport { ChevronDown, Crosshair, LocateFixed, Maximize2, Minimize2, Radar, RotateCw, Shuffle, Check, Anchor, TriangleAlert, Waves, ShieldCheck, X } from 'lucide-react';\nimport { useChatConnectionStatus } from '../../core/connection/connectionStore.js';\nimport useChatGames from '../shared/useChatGames.js';\nimport { getGameStatus, getVerificationLabel, isTerminalGame, sameUser } from '../shared/gameStatus.js';\nimport { BOARD_SIZE, FLEET, createBoard, placeShip, validatePlacement } from './logic';\nimport { hasWebGL } from './webglSupport';\nimport GameSoundControls from '../shared/GameSoundControls.jsx';\nimport { battleshipSounds, holdAmbient, playUiSound, scheduleCues } from './sound/battleshipSounds';\nimport { crossesCruiserAlarm, impactCues, launchCues } from './sound/cues';\nimport '../connect4/games.css';\nimport './battleship.css';\n\nconst ROWS = 'ABCDEFGHIJ';\nconst SHIP_NAMES = { carrier: 'portaaviones', battleship: 'acorazado', cruiser: 'crucero', submarine: 'submarino', destroyer: 'destructor' };\nconst SCENE_STATUSES = ['placement', 'active', 'won', 'conflict', 'closed'];\nconst DOUBLE_SELECT_MS = 400;\nconst EMPTY_SHOTS = Array.from({ length: BOARD_SIZE }, () => Array(BOARD_SIZE).fill(null));\n\nconst cellLabel = (cell) => (cell ? `${ROWS[cell.row]}${cell.col + 1}` : '—');\nconst sameCell = (a, b) => Boolean(a && b && a.row === b.row && a.col === b.col);\nconst isCell = (cell) => Boolean(cell) && Number.isInteger(cell.row) && Number.isInteger(cell.col)\n && cell.row >= 0 && cell.row < BOARD_SIZE && cell.col >= 0 && cell.col < BOARD_SIZE;\nconst shipName = (id) => SHIP_NAMES[id] || 'barco';\nconst shotAt = (shots, cell) => shots?.[cell.row]?.[cell.col] ?? null;\nconst shipAt = (ships, cell) => ships.find((ship) => ship.cells?.some((item) => sameCell(item, cell)));\nconst capitalize = (text) => text.charAt(0).toUpperCase() + text.slice(1);\n\nconst prefersReducedMotion = () => typeof window !== 'undefined' && Boolean(window.matchMedia?.('(prefers-reduced-motion: reduce)').matches);\n\n// The store owns delivery errors; UI handlers must never leak rejected promises.\nconst call = (name, ...args) => Promise.resolve().then(() => useChatGames.getState()[name]?.(...args)).catch(() => {});\n\nfunction buildBoard(fleet) {\n let board = createBoard();\n for (const ship of fleet || []) {\n const first = ship.cells?.[0];\n if (!first) continue;\n const placed = placeShip(board, { shipId: ship.id, row: first.row, col: first.col, orientation: ship.orientation });\n if (placed.ok) board = placed.board;\n }\n return board;\n}\n\nfunction previewCells(anchor, size, orientation) {\n return Array.from({ length: size }, (_, index) => ({\n row: anchor.row + (orientation === 'vertical' ? index : 0),\n col: anchor.col + (orientation === 'horizontal' ? index : 0),\n })).filter(isCell);\n}\n\nfunction countShots(shots) {\n let total = 0; let hits = 0;\n for (const row of shots || []) for (const shot of row || []) { if (shot) total += 1; if (shot === 'hit') hits += 1; }\n return { total, hits };\n}\n\nfunction SyncControls({ sync, connected, onResync, onAdoptOffer }) {\n if (sync?.status === 'requesting') return <div className=\"chat-game-sync\" role=\"status\">Sincronizando partida…</div>;\n return <div className=\"chat-game-sync\" role=\"alert\">\n {sync?.message && <span>{sync.message}</span>}\n {sync?.status === 'incompatible' && sync.offer && <button type=\"button\" className=\"chat-game-action chat-game-action--primary\" disabled={!connected} onClick={onAdoptOffer}>Usar estado del anfitrión</button>}\n <button type=\"button\" className=\"chat-game-action\" disabled={!connected} onClick={onResync}>Reintentar sincronización</button>\n </div>;\n}\n\nfunction VerificationBadge({ game }) {\n const label = getVerificationLabel(game);\n if (!label) return null;\n return <span className={`bs-badge bs-badge--${game.verification}`}>{game.verification === 'ok' && <ShieldCheck size={12} aria-hidden=\"true\" />}{game.verification === 'mismatch' && <TriangleAlert size={12} aria-hidden=\"true\" />}{label}</span>;\n}\n\n// 2D grid used when WebGL is unavailable: same interaction, no three.js.\nfunction FallbackGrid({ view, selected, cursor, onSelect, onHover }) {\n const shipCells = new Map();\n view.ships.forEach((ship) => ship.cells.forEach((cell) => shipCells.set(`${cell.row}-${cell.col}`, ship)));\n const preview = new Set((view.preview?.cells || []).map((cell) => `${cell.row}-${cell.col}`));\n return <div className=\"bs-grid\" role=\"grid\" aria-label={view.mode === 'target' ? 'Tablero objetivo' : 'Mi flota'} onMouseLeave={() => onHover(null)}>\n {Array.from({ length: BOARD_SIZE }, (_, row) => <div role=\"row\" key={row} className=\"bs-grid__row\">\n {Array.from({ length: BOARD_SIZE }, (_, col) => {\n const id = `${row}-${col}`;\n const ship = shipCells.get(id);\n const shot = view.shots?.[row]?.[col];\n const cls = ['bs-grid__cell', ship && 'is-ship', ship?.sunk && 'is-sunk', shot && `is-${shot}`,\n preview.has(id) && (view.preview.valid ? 'is-preview' : 'is-invalid'),\n sameCell(selected, { row, col }) && 'is-selected', sameCell(cursor, { row, col }) && 'is-cursor'].filter(Boolean).join(' ');\n return <button key={id} type=\"button\" role=\"gridcell\" tabIndex={-1} className={cls} disabled={!view.interactive}\n aria-label={`${ROWS[row]}${col + 1}${shot === 'hit' ? ', impacto' : shot === 'miss' ? ', agua' : ''}${ship ? ', barco' : ''}`}\n onMouseEnter={() => onHover({ row, col })} onClick={() => onSelect({ row, col })} />;\n })}\n </div>)}\n </div>;\n}\n\nfunction HistorySummary({ game, currentUserId, status }) {\n const { total, hits } = countShots(game.targetShots);\n const sunk = game.sunkEnemyShips?.length || 0;\n const showStats = ['active', 'won', 'closed', 'conflict'].includes(game.status) && total > 0;\n const iWon = game.status === 'won' && sameUser(currentUserId, game.winnerId);\n return <section className=\"chat-game-card chat-game-card--history bs-card bs-card--history\" aria-label=\"Partida de Batalla Naval\">\n <header className=\"chat-game-header\">\n <div className=\"chat-game-heading\">\n <span className=\"chat-game-eyebrow\">MINIJUEGOS · 2 JUGADORES</span>\n <h3>Batalla Naval <Anchor size={13} aria-hidden=\"true\" className=\"bs-title-icon\" /></h3>\n </div>\n </header>\n <p className={`chat-game-status${iWon ? ' bs-status--win' : ''}`}>{status}</p>\n {showStats && <p className=\"bs-history-stats\">Disparos {total} · Impactos {hits} · Hundidos {sunk}/{FLEET.length}</p>}\n <VerificationBadge game={game} />\n </section>;\n}\n\nfunction BattleshipGameCard({ gameKey, currentUserId, variant = 'panel', onMinimize, onDismiss }) {\n const game = useChatGames((state) => state.games[gameKey]);\n const connected = useChatConnectionStatus() === 'connected';\n if (!game) return null;\n const status = getGameStatus(game, currentUserId);\n if (variant === 'history') return <HistorySummary game={game} currentUserId={currentUserId} status={status} />;\n return <BattleshipPanel game={game} gameKey={gameKey} currentUserId={currentUserId} connected={connected}\n status={status} variant={variant} onMinimize={onMinimize} onDismiss={onDismiss} />;\n}\n\nfunction BattleshipPanel({ game, gameKey, currentUserId, connected, status, variant, onMinimize, onDismiss }) {\n const stageRef = useRef(null);\n const sceneRef = useRef(null);\n const animatingRef = useRef(false);\n const lastSeenShotRef = useRef(undefined);\n const lastSelectRef = useRef({ cell: null, time: 0 });\n const handlersRef = useRef({});\n const soundTimersRef = useRef(new Set());\n const lastStatusRef = useRef(game.status);\n const hintId = useId();\n const [sceneStatus, setSceneStatus] = useState('idle');\n const [viewMode, setViewMode] = useState('own');\n const [hovered, setHovered] = useState(null);\n const [cursor, setCursor] = useState(null);\n const [selected, setSelected] = useState(null);\n const [orientation, setOrientation] = useState('horizontal');\n const [activeShipId, setActiveShipId] = useState(null);\n const [radar, setRadar] = useState(false);\n const [expanded, setExpanded] = useState(false);\n const [animating, setAnimating] = useState(false);\n const [announcement, setAnnouncement] = useState(null);\n\n const isHost = sameUser(currentUserId, game.hostId);\n const isGuest = sameUser(currentUserId, game.guestId);\n const isParticipant = isHost || isGuest;\n const terminal = isTerminalGame(game);\n const placing = game.status === 'placement';\n const battle = game.status === 'active' || game.status === 'won';\n const myTurn = game.status === 'active' && sameUser(currentUserId, game.turnId);\n const busy = !connected || Boolean(game.pending) || Boolean(game.pendingEvent);\n const canFire = myTurn && !game.pendingShot && !busy && !game.error && !animating;\n const canPlace = placing && !game.myReady && !busy;\n const sceneVisible = SCENE_STATUSES.includes(game.status) && (game.status !== 'closed' || (game.myFleet?.length ?? 0) > 0);\n const sceneReady = sceneStatus === 'ready';\n\n const myFleet = useMemo(() => game.myFleet || [], [game.myFleet]);\n const incomingShots = game.incomingShots || EMPTY_SHOTS;\n const targetShots = game.targetShots || EMPTY_SHOTS;\n const ownBoard = useMemo(() => buildBoard(myFleet), [myFleet]);\n const placedIds = useMemo(() => new Set(myFleet.map((ship) => ship.id)), [myFleet]);\n const fleetComplete = FLEET.every((ship) => placedIds.has(ship.id));\n const currentShip = FLEET.find((ship) => ship.id === activeShipId && !placedIds.has(ship.id)) || FLEET.find((ship) => !placedIds.has(ship.id)) || null;\n\n const ownShips = useMemo(() => myFleet.map((ship) => ({ ...ship, sunk: Boolean(ship.cells?.length) && ship.cells.every((cell) => shotAt(incomingShots, cell) === 'hit') })), [myFleet, incomingShots]);\n const enemyShips = useMemo(() => (game.sunkEnemyShips || []).filter((ship) => ship?.cells?.length)\n .map((ship) => ({ ...ship, size: ship.size ?? ship.cells.length, sunk: true })), [game.sunkEnemyShips]);\n const { total: shotCount, hits: hitCount } = useMemo(() => countShots(targetShots), [targetShots]);\n const radarContacts = useMemo(() => {\n const cells = [];\n targetShots.forEach((row, r) => row?.forEach((shot, c) => { if (shot === 'hit') cells.push({ row: r, col: c }); }));\n return cells;\n }, [targetShots]);\n\n const mode = placing ? 'own' : viewMode;\n const anchor = hovered || cursor;\n const preview = useMemo(() => {\n if (!canPlace || !currentShip || !anchor) return null;\n const result = validatePlacement(ownBoard, { shipId: currentShip.id, row: anchor.row, col: anchor.col, orientation });\n return { cells: result.ok ? result.ship.cells : previewCells(anchor, currentShip.size, orientation), valid: result.ok };\n }, [canPlace, currentShip, anchor, ownBoard, orientation]);\n\n const buildView = useCallback((viewModeArg, hideCell) => {\n if (viewModeArg === 'target') {\n const shots = hideCell ? targetShots.map((row, r) => row.map((shot, c) => (r === hideCell.row && c === hideCell.col ? null : shot))) : targetShots;\n const ships = hideCell ? enemyShips.map((ship) => (shipAt([ship], hideCell) ? { ...ship, sunk: false } : ship)) : enemyShips;\n return { mode: 'target', ships, shots, preview: null, interactive: canFire };\n }\n const shots = hideCell ? incomingShots.map((row, r) => row.map((shot, c) => (r === hideCell.row && c === hideCell.col ? null : shot))) : incomingShots;\n const ships = hideCell ? ownShips.map((ship) => (shipAt([ship], hideCell) ? { ...ship, sunk: false } : ship)) : ownShips;\n return { mode: 'own', ships, shots, preview: placing ? preview : null, interactive: canPlace };\n }, [targetShots, enemyShips, incomingShots, ownShips, placing, preview, canFire, canPlace]);\n const view = useMemo(() => buildView(mode), [buildView, mode]);\n\n const announce = useCallback((text, kind = 'info') => setAnnouncement({ text, kind, id: Date.now() }), []);\n\n const fire = useCallback((cell = selected) => {\n if (!canFire || !isCell(cell)) return;\n if (shotAt(targetShots, cell)) { announce(`Ya disparaste en ${cellLabel(cell)}`); return; }\n setSelected(null);\n sceneRef.current?.selectCell?.(null);\n playUiSound('ui_click');\n void call('bsFire', gameKey, { row: cell.row, col: cell.col });\n }, [canFire, selected, targetShots, gameKey, announce]);\n\n const placeAt = useCallback((cell) => {\n if (!canPlace || !isCell(cell)) return;\n const placed = shipAt(myFleet, cell);\n if (placed) {\n setActiveShipId(placed.id);\n if (placed.orientation) setOrientation(placed.orientation);\n playUiSound('ui_click');\n void call('bsRemoveShip', gameKey, placed.id);\n return;\n }\n if (!currentShip) return;\n const result = validatePlacement(ownBoard, { shipId: currentShip.id, row: cell.row, col: cell.col, orientation });\n if (!result.ok) { announce(result.reason === 'overlap' ? 'Se superpone con otro barco' : 'No cabe en esa posición', 'miss'); return; }\n setActiveShipId(null);\n playUiSound('ship_place');\n void call('bsPlaceShip', gameKey, { shipId: currentShip.id, row: cell.row, col: cell.col, orientation });\n }, [canPlace, myFleet, currentShip, ownBoard, orientation, gameKey, announce]);\n\n const selectCell = useCallback((cell) => {\n if (!isCell(cell)) return;\n setCursor(cell);\n if (placing) { placeAt(cell); return; }\n if (mode !== 'target' || !canFire) return;\n const now = Date.now();\n const last = lastSelectRef.current;\n lastSelectRef.current = { cell, time: now };\n if (sameCell(last.cell, cell) && now - last.time < DOUBLE_SELECT_MS) { fire(cell); return; }\n if (shotAt(targetShots, cell)) { announce(`Ya disparaste en ${cellLabel(cell)}`); return; }\n setSelected(cell);\n sceneRef.current?.selectCell?.(cell);\n }, [placing, placeAt, mode, canFire, fire, targetShots, announce]);\n\n handlersRef.current = { selectCell, setHovered };\n\n // One WebGL context per card: created once while the board is visible, disposed on unmount.\n useEffect(() => {\n const container = stageRef.current;\n if (!sceneVisible || !container) return undefined;\n if (!hasWebGL()) { setSceneStatus('fallback'); return undefined; }\n let disposed = false;\n let scene = null;\n setSceneStatus('loading');\n import('./scene/createBattleScene.js')\n .then(({ createBattleScene }) => {\n if (disposed) return;\n scene = createBattleScene(container, {\n quality: 'auto',\n reducedMotion: prefersReducedMotion(),\n onCellHover: (cell) => { if (!disposed) handlersRef.current.setHovered(isCell(cell) ? { row: cell.row, col: cell.col } : null); },\n onCellSelect: (cell) => { if (!disposed) handlersRef.current.selectCell(isCell(cell) ? { row: cell.row, col: cell.col } : null); },\n });\n sceneRef.current = scene;\n setSceneStatus('ready');\n })\n .catch((error) => {\n if (disposed) return;\n console.error('[battleship] No se pudo iniciar la escena', error);\n setSceneStatus('fallback');\n });\n return () => {\n disposed = true;\n sceneRef.current = null;\n try { scene?.dispose(); } catch (error) { console.error('[battleship] Error al liberar la escena', error); }\n };\n }, [sceneVisible]);\n\n useEffect(() => {\n battleshipSounds.preload();\n const timers = soundTimersRef.current;\n return () => { timers.forEach(clearTimeout); timers.clear(); };\n }, []);\n\n // Ocean bed only while this board is open (unmounted when minimized/closed).\n const ambient = sceneVisible && !terminal;\n useEffect(() => (ambient ? holdAmbient() : undefined), [ambient]);\n\n // Both fleets committed: sonar sweep once per game.\n useEffect(() => {\n const before = lastStatusRef.current;\n lastStatusRef.current = game.status;\n if (before === 'placement' && game.status === 'active') scheduleCues([{ name: 'sonar_ping', at: 0 }], () => `${game.gameId}:start`, soundTimersRef.current);\n }, [game.status, game.gameId]);\n\n // Animate each new shot once (never replay history on mount), then show the settled state.\n // Sounds follow the same event id, so RESYNC/replayed frames (no new id) stay silent.\n const lastShot = game.lastShot;\n useEffect(() => {\n if (!sceneReady && sceneStatus !== 'fallback') return;\n const eventId = lastShot?.eventId ?? null;\n if (lastSeenShotRef.current === undefined) { lastSeenShotRef.current = eventId; return; }\n if (!eventId || eventId === lastSeenShotRef.current) return;\n lastSeenShotRef.current = eventId;\n const incoming = !sameUser(lastShot.by, currentUserId);\n const cell = { row: lastShot.row, col: lastShot.col };\n const label = cellLabel(cell);\n const sunkId = typeof lastShot.sunk === 'string' ? lastShot.sunk\n : lastShot.sunk ? shipAt(incoming ? myFleet : (game.sunkEnemyShips || []), cell)?.id : null;\n const text = incoming\n ? (lastShot.sunk ? `Te hundieron el ${shipName(sunkId)}` : lastShot.result === 'hit' ? `El rival impactó en ${label}` : `El rival falló: agua en ${label}`)\n : (lastShot.sunk ? `¡Hundiste el ${shipName(sunkId)}!` : lastShot.result === 'hit' ? `¡Impacto en ${label}!` : `Agua en ${label}`);\n const kind = lastShot.result === 'hit' ? 'hit' : 'miss';\n const nextMode = incoming ? 'own' : 'target';\n // The cruiser alarm is keyed per game: it can sound only once per cruiser.\n const cruiserAlarm = incoming && crossesCruiserAlarm(myFleet, game.incomingShots, lastShot);\n const impact = impactCues({ result: lastShot.result, sunk: Boolean(lastShot.sunk), defeated: Boolean(lastShot.defeated), won: !incoming, cruiserAlarm });\n const cueKey = (name) => (name === 'cruiser_damage_alarm' ? `${game.gameId}:cruiser`\n : name === 'victory' || name === 'defeat' ? `${game.gameId}:end` : eventId);\n const timers = soundTimersRef.current;\n setViewMode(nextMode);\n const scene = sceneRef.current;\n if (!scene?.playShot) { scheduleCues(impact, cueKey, timers); announce(text, kind); return; }\n scheduleCues(launchCues({ incoming }), cueKey, timers);\n animatingRef.current = true;\n setAnimating(true);\n let cancelled = false;\n try { scene.setView(buildView(nextMode, cell)); } catch { /* scene keeps its last view */ }\n const hold = prefersReducedMotion() ? 0 : 600;\n Promise.resolve(scene.playShot({ row: cell.row, col: cell.col, result: lastShot.result, sunk: Boolean(lastShot.sunk), incoming }))\n .catch(() => {})\n .then(() => { scheduleCues(impact, cueKey, timers); if (!cancelled) announce(text, kind); return new Promise((resolve) => setTimeout(resolve, hold)); })\n .then(() => { if (!cancelled) { animatingRef.current = false; setAnimating(false); } });\n return () => { cancelled = true; animatingRef.current = false; setAnimating(false); };\n // Only a new event id may trigger an animation.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [sceneReady, sceneStatus, lastShot?.eventId]);\n\n // Auto-switch: my turn → target, rival turn → my fleet (after any running animation).\n useEffect(() => {\n if (animating || game.status !== 'active') return;\n setViewMode(myTurn ? 'target' : 'own');\n }, [myTurn, game.status, animating]);\n\n useEffect(() => { if (!canFire) setSelected(null); }, [canFire]);\n\n // Push the settled view to the scene unless a shot animation owns it.\n useEffect(() => {\n if (!sceneReady || animatingRef.current) return;\n try { sceneRef.current?.setView(view); } catch (error) { console.error('[battleship] setView', error); }\n }, [sceneReady, view, animating]);\n\n useEffect(() => {\n if (!sceneReady) return;\n sceneRef.current?.selectCell?.(mode === 'target' ? selected : null);\n }, [sceneReady, selected, mode]);\n\n useEffect(() => {\n if (!sceneReady) return;\n const scene = sceneRef.current;\n scene?.setRadarVisible?.(radar && mode === 'target');\n scene?.setRadarContacts?.(radarContacts);\n }, [sceneReady, radar, mode, radarContacts]);\n\n const rotate = () => { playUiSound('ship_rotate'); setOrientation((value) => (value === 'horizontal' ? 'vertical' : 'horizontal')); };\n const ready = () => { if (fleetComplete && canPlace) { playUiSound('ui_click'); void call('bsReady', gameKey); } };\n const clicked = (action) => (...args) => { playUiSound('ui_click'); action(...args); };\n const toggleRadar = () => {\n playUiSound(radar ? 'ui_click' : 'sonar_ping');\n setRadar((value) => !value);\n };\n\n const handleStageKeyDown = (event) => {\n if (event.target !== event.currentTarget || event.altKey || event.ctrlKey || event.metaKey) return;\n const moves = { ArrowUp: [-1, 0], ArrowDown: [1, 0], ArrowLeft: [0, -1], ArrowRight: [0, 1] };\n if (moves[event.key]) {\n event.preventDefault();\n const [dr, dc] = moves[event.key];\n const base = (mode === 'target' ? selected : null) || cursor || hovered;\n const next = base ? { row: Math.min(BOARD_SIZE - 1, Math.max(0, base.row + dr)), col: Math.min(BOARD_SIZE - 1, Math.max(0, base.col + dc)) } : { row: 0, col: 0 };\n setCursor(next);\n setHovered(null);\n if (mode === 'target' && canFire) { setSelected(next); sceneRef.current?.selectCell?.(next); }\n } else if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n if (placing) placeAt(cursor || hovered);\n else fire(selected || cursor);\n }\n };\n\n const handleCardKeyDown = (event) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return;\n if (/^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName) || event.target.isContentEditable) return;\n if (event.key === 'r' || event.key === 'R') {\n event.preventDefault();\n if (placing) rotate(); else sceneRef.current?.resetCamera?.();\n } else if (event.key === 'Escape' && expanded) {\n event.preventDefault();\n event.stopPropagation();\n setExpanded(false);\n }\n };\n\n const verification = <VerificationBadge game={game} />;\n const iWon = game.status === 'won' && sameUser(currentUserId, game.winnerId);\n const statusText = !connected && !terminal ? 'Sin conexión · esperando reconexión' : game.pending ? 'Sincronizando…' : status;\n const sunkCount = enemyShips.length;\n\n return (\n <section className={`chat-game-card bs-card${myTurn ? ' chat-game-card--my-turn' : ''}${variant ? ` chat-game-card--${variant}` : ''}${expanded ? ' bs-card--expanded' : ''}`}\n aria-label=\"Partida de Batalla Naval\" onKeyDown={handleCardKeyDown}>\n <header className=\"chat-game-header\">\n <div className=\"chat-game-heading\">\n <span className=\"chat-game-eyebrow\">MINIJUEGOS · 2 JUGADORES</span>\n <h3>Batalla Naval <Anchor size={13} aria-hidden=\"true\" className=\"bs-title-icon\" /></h3>\n </div>\n {variant === 'panel' && <GameSoundControls manager={battleshipSounds} />}\n {sceneVisible && <button className=\"chat-game-close bs-expand\" type=\"button\" aria-pressed={expanded}\n aria-label={expanded ? 'Reducir tablero' : 'Ampliar tablero'} title={expanded ? 'Reducir (Esc)' : 'Ampliar'} onClick={clicked(() => setExpanded((value) => !value))}>\n {expanded ? <Minimize2 size={15} aria-hidden=\"true\" /> : <Maximize2 size={15} aria-hidden=\"true\" />}\n </button>}\n {onMinimize && <button className=\"chat-game-close\" type=\"button\" aria-label=\"Minimizar tablero\" title=\"Minimizar tablero\" onClick={() => { setExpanded(false); onMinimize(); }}><ChevronDown size={16} aria-hidden=\"true\" /></button>}\n {isParticipant && !terminal && (\n <button className=\"chat-game-close\" type=\"button\" aria-label=\"Finalizar partida para ambos jugadores\" title=\"Finalizar partida para ambos\" onClick={() => void call('act', gameKey, 'game_end')} disabled={!connected}><X size={16} aria-hidden=\"true\" /></button>\n )}\n {onDismiss && <button className=\"chat-game-close\" type=\"button\" aria-label=\"Cerrar tablero y volver al chat\" title=\"Cerrar tablero\" onClick={onDismiss}><X size={16} aria-hidden=\"true\" /></button>}\n </header>\n\n <div className=\"bs-statusline\">\n <p className={`chat-game-status${iWon ? ' bs-status--win' : ''}`} role=\"status\">{statusText}</p>\n {verification}\n </div>\n\n {game.status === 'invited' && <div className=\"bs-invite\">\n <p>Coloca 5 barcos en un tablero de 10×10 y hunde la flota rival por turnos.</p>\n {isGuest && <div className=\"chat-game-actions\">\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary\" disabled={busy} onClick={clicked(() => void call('act', gameKey, 'game_accept'))}>Aceptar partida</button>\n <button type=\"button\" className=\"chat-game-action\" disabled={busy} onClick={clicked(() => void call('act', gameKey, 'game_decline'))}>Rechazar</button>\n </div>}\n </div>}\n\n {sceneVisible && <>\n {battle && <div className=\"bs-hud\" role=\"toolbar\" aria-label=\"Vista del tablero\">\n <div className=\"bs-segment\">\n <button type=\"button\" aria-pressed={viewMode === 'target'} onClick={clicked(() => setViewMode('target'))}><Crosshair size={14} aria-hidden=\"true\" />Objetivo</button>\n <button type=\"button\" aria-pressed={viewMode === 'own'} onClick={clicked(() => setViewMode('own'))}><Anchor size={14} aria-hidden=\"true\" />Mi flota</button>\n </div>\n <dl className=\"bs-stats\">\n <div><dt>Disparos</dt><dd>{shotCount}</dd></div>\n <div><dt>Impactos</dt><dd>{hitCount}</dd></div>\n <div><dt>Hundidos</dt><dd>{sunkCount}/{FLEET.length}</dd></div>\n </dl>\n </div>}\n\n <div className=\"bs-stage-wrap\">\n <div ref={stageRef} className={`bs-stage${sceneStatus === 'fallback' ? ' bs-stage--fallback' : ''}`} tabIndex={0} role=\"application\"\n aria-label={placing ? 'Tablero 3D de tu flota. Flechas para mover, Enter para colocar o quitar un barco, R para rotar.' : 'Tablero 3D de Batalla Naval. Flechas para mover la selección, Enter para disparar, R para centrar la cámara.'}\n aria-describedby={hintId} aria-busy={sceneStatus === 'loading'} onKeyDown={handleStageKeyDown}>\n {sceneStatus === 'fallback' && <FallbackGrid view={view} selected={mode === 'target' ? selected : null} cursor={cursor} onSelect={selectCell} onHover={setHovered} />}\n </div>\n {sceneStatus === 'loading' && <div className=\"bs-stage-state\" role=\"status\"><Waves size={16} aria-hidden=\"true\" /> Preparando el océano…</div>}\n {sceneStatus === 'fallback' && <p className=\"bs-fallback-note\"><TriangleAlert size={12} aria-hidden=\"true\" /> Vista 3D no disponible · modo 2D</p>}\n <div className=\"bs-cell-chip\" aria-hidden=\"true\">{placing ? cellLabel(anchor) : mode === 'target' ? cellLabel(selected || hovered) : cellLabel(hovered)}</div>\n <div className=\"bs-live\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcement && <span key={announcement.id} className={`bs-toast bs-toast--${announcement.kind}`}>{announcement.text}</span>}\n </div>\n </div>\n <p id={hintId} className=\"bs-hint\">{placing\n ? 'Clic para colocar · clic en un barco para quitarlo · R para rotar'\n : 'Arrastra para rotar · doble clic o Enter para disparar'}</p>\n\n {placing && <div className=\"bs-placement\">\n <ul className=\"bs-fleet\" aria-label=\"Tu flota\">\n {FLEET.map((ship) => {\n const placed = placedIds.has(ship.id);\n const active = currentShip?.id === ship.id;\n return <li key={ship.id}>\n <button type=\"button\" className={`bs-ship${placed ? ' is-placed' : ''}${active ? ' is-active' : ''}`} aria-pressed={active}\n disabled={!canPlace} title={placed ? 'Quitar y volver a colocar' : 'Seleccionar barco'}\n onClick={clicked(() => { if (placed) void call('bsRemoveShip', gameKey, ship.id); setActiveShipId(ship.id); })}>\n <span className=\"bs-ship__name\">{capitalize(shipName(ship.id))}</span>\n <span className=\"bs-ship__pips\" aria-label={`${ship.size} casillas`}>{Array.from({ length: ship.size }, (_, i) => <i key={i} />)}</span>\n {placed && <Check size={13} aria-label=\"colocado\" />}\n </button>\n </li>;\n })}\n </ul>\n <div className=\"chat-game-actions bs-actions\">\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!canPlace} onClick={rotate} title=\"Rotar (R)\">\n <RotateCw size={15} aria-hidden=\"true\" />{orientation === 'horizontal' ? 'Horizontal' : 'Vertical'}\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!canPlace} onClick={() => { playUiSound('ship_place'); void call('bsRandomFleet', gameKey); }}><Shuffle size={15} aria-hidden=\"true\" />Aleatorio</button>\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary bs-btn\" disabled={!canPlace || !fleetComplete} onClick={ready}>\n <Check size={15} aria-hidden=\"true\" />{game.myReady ? 'Flota lista' : `Listo (${placedIds.size}/${FLEET.length})`}\n </button>\n </div>\n {game.myReady && <p className=\"bs-waiting\">{game.opponentReady ? 'Ambas flotas listas · iniciando…' : 'Flota lista. Esperando a que el rival coloque su flota…'}</p>}\n </div>}\n\n {battle && <div className=\"chat-game-actions bs-actions\">\n <button type=\"button\" className=\"chat-game-action chat-game-action--primary bs-btn bs-btn--fire\" disabled={!canFire || !selected || mode !== 'target'} onClick={() => fire()}\n title={selected ? `Disparar en ${cellLabel(selected)} (Enter)` : 'Selecciona una casilla'}>\n <Crosshair size={15} aria-hidden=\"true\" />Disparar{selected ? ` · ${cellLabel(selected)}` : ''}\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" aria-pressed={radar} disabled={mode !== 'target' || !sceneReady} onClick={toggleRadar} title=\"Radar de impactos\">\n <Radar size={15} aria-hidden=\"true\" />Radar\n </button>\n <button type=\"button\" className=\"chat-game-action bs-btn\" disabled={!sceneReady} onClick={clicked(() => sceneRef.current?.resetCamera?.())} title=\"Centrar cámara (R)\">\n <LocateFixed size={15} aria-hidden=\"true\" /><span className=\"bs-btn-label\">Centrar</span>\n </button>\n </div>}\n </>}\n\n {game.status === 'conflict' && isParticipant && <SyncControls sync={game.sync} connected={connected}\n onResync={() => void call('requestResync', gameKey)} onAdoptOffer={() => void call('adoptResyncOffer', gameKey)} />}\n {game.error && <div className=\"chat-game-error\" role=\"alert\"><span>{game.error}</span>\n {game.pendingEvent && <button type=\"button\" className=\"chat-game-action\" disabled={!connected || game.pending} onClick={() => void call('retry', gameKey)}>Reintentar</button>}\n </div>}\n <footer className=\"chat-game-footer\">{terminal ? 'Puedes seguir conversando o invitar a otra partida.' : 'Hunde los 5 barcos rivales. El chat sigue disponible.'}</footer>\n </section>\n );\n}\n\nexport default memo(BattleshipGameCard);\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { n as e, o as t, r as n, s as r, t as i } from "./battleship-DXKuIZ1I.js";
2
2
  import { t as a } from "./webglSupport-2WjPEPZ_.js";
3
3
  import { useCallback as o, useEffect as s, useId as c, useRef as l, useState as u } from "react";
4
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
5
- import { Crosshair as ee, Gauge as te, LocateFixed as ne, Radar as re, RotateCcw as ie, TriangleAlert as p, Waves as m, X as h } from "lucide-react";
4
+ import { Crosshair as d, Gauge as f, LocateFixed as ee, Radar as te, RotateCcw as ne, TriangleAlert as re, Waves as ie, X as p } from "lucide-react";
5
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
6
6
  // src/games/battleship/BattleshipPrototype.jsx
7
7
  var g = "ABCDEFGHIJ", _ = 10, v = [
8
8
  "auto",
@@ -173,12 +173,12 @@ function O({ onClose: e, compact: t = !1 }) {
173
173
  }, de = (t) => {
174
174
  t.key === "Escape" && !t.defaultPrevented && (t.preventDefault(), t.stopPropagation(), e?.());
175
175
  }, fe = z.shots ? Math.round(z.hits / z.shots * 100) : 0, $ = ae[L];
176
- return /* @__PURE__ */ f("section", {
176
+ return /* @__PURE__ */ h("section", {
177
177
  className: `bs-proto${t ? " bs-proto--compact" : ""}`,
178
178
  "aria-label": "Batalla Naval, vista previa 3D sin rival",
179
179
  onKeyDown: de,
180
180
  children: [
181
- /* @__PURE__ */ d("div", {
181
+ /* @__PURE__ */ m("div", {
182
182
  ref: r,
183
183
  className: "bs-proto__stage",
184
184
  tabIndex: 0,
@@ -188,29 +188,29 @@ function O({ onClose: e, compact: t = !1 }) {
188
188
  "aria-busy": O === "loading",
189
189
  onKeyDown: Q
190
190
  }),
191
- O === "loading" && /* @__PURE__ */ f("div", {
191
+ O === "loading" && /* @__PURE__ */ h("div", {
192
192
  className: "bs-proto__state",
193
193
  role: "status",
194
- children: [/* @__PURE__ */ d("div", {
194
+ children: [/* @__PURE__ */ m("div", {
195
195
  className: "bs-proto__skeleton",
196
196
  "aria-hidden": "true",
197
- children: Array.from({ length: 25 }, (e, t) => /* @__PURE__ */ d("span", {}, t))
198
- }), /* @__PURE__ */ f("p", { children: [/* @__PURE__ */ d(m, {
197
+ children: Array.from({ length: 25 }, (e, t) => /* @__PURE__ */ m("span", {}, t))
198
+ }), /* @__PURE__ */ h("p", { children: [/* @__PURE__ */ m(ie, {
199
199
  size: 16,
200
200
  "aria-hidden": "true"
201
201
  }), " Preparando el océano…"] })]
202
202
  }),
203
- O === "error" && /* @__PURE__ */ f("div", {
203
+ O === "error" && /* @__PURE__ */ h("div", {
204
204
  className: "bs-proto__state bs-proto__state--error",
205
205
  role: "alert",
206
206
  children: [
207
- /* @__PURE__ */ d(p, {
207
+ /* @__PURE__ */ m(re, {
208
208
  size: 28,
209
209
  "aria-hidden": "true"
210
210
  }),
211
- /* @__PURE__ */ d("strong", { children: "Vista 3D no disponible" }),
212
- /* @__PURE__ */ d("p", { children: oe }),
213
- /* @__PURE__ */ d("button", {
211
+ /* @__PURE__ */ m("strong", { children: "Vista 3D no disponible" }),
212
+ /* @__PURE__ */ m("p", { children: oe }),
213
+ /* @__PURE__ */ m("button", {
214
214
  type: "button",
215
215
  className: "bs-proto__btn",
216
216
  onClick: e,
@@ -218,141 +218,141 @@ function O({ onClose: e, compact: t = !1 }) {
218
218
  })
219
219
  ]
220
220
  }),
221
- /* @__PURE__ */ f("header", {
221
+ /* @__PURE__ */ h("header", {
222
222
  className: "bs-proto__top",
223
223
  children: [
224
- /* @__PURE__ */ f("div", {
224
+ /* @__PURE__ */ h("div", {
225
225
  className: "bs-proto__panel bs-proto__brand",
226
- children: [/* @__PURE__ */ f("span", {
226
+ children: [/* @__PURE__ */ h("span", {
227
227
  className: "bs-proto__title",
228
- children: ["Batalla Naval ", /* @__PURE__ */ d("span", {
228
+ children: ["Batalla Naval ", /* @__PURE__ */ m("span", {
229
229
  className: "bs-proto__title-sub",
230
230
  children: "· Sin rival"
231
231
  })]
232
- }), /* @__PURE__ */ d("span", {
232
+ }), /* @__PURE__ */ m("span", {
233
233
  className: "bs-proto__badge",
234
234
  children: "Vista previa 3D"
235
235
  })]
236
236
  }),
237
- Y && /* @__PURE__ */ f("div", {
237
+ Y && /* @__PURE__ */ h("div", {
238
238
  className: "bs-proto__panel bs-proto__info",
239
- children: [/* @__PURE__ */ f("dl", {
239
+ children: [/* @__PURE__ */ h("dl", {
240
240
  className: "bs-proto__cells",
241
- children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", { children: "Objetivo" }), /* @__PURE__ */ d("dd", {
241
+ children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("dt", { children: "Objetivo" }), /* @__PURE__ */ m("dd", {
242
242
  className: "bs-proto__cell-selected",
243
243
  children: y(j)
244
- })] }), /* @__PURE__ */ f("div", {
244
+ })] }), /* @__PURE__ */ h("div", {
245
245
  className: "bs-proto__cells-hover",
246
- children: [/* @__PURE__ */ d("dt", { children: "Cursor" }), /* @__PURE__ */ d("dd", { children: y(N) })]
246
+ children: [/* @__PURE__ */ m("dt", { children: "Cursor" }), /* @__PURE__ */ m("dd", { children: y(N) })]
247
247
  })]
248
- }), /* @__PURE__ */ f("dl", {
248
+ }), /* @__PURE__ */ h("dl", {
249
249
  className: "bs-proto__stats",
250
250
  children: [
251
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", { children: "Disparos" }), /* @__PURE__ */ d("dd", { children: z.shots })] }),
252
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", { children: "Impactos" }), /* @__PURE__ */ d("dd", { children: z.hits })] }),
253
- /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("dt", { children: "Precisión" }), /* @__PURE__ */ f("dd", { children: [fe, "%"] })] })
251
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("dt", { children: "Disparos" }), /* @__PURE__ */ m("dd", { children: z.shots })] }),
252
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("dt", { children: "Impactos" }), /* @__PURE__ */ m("dd", { children: z.hits })] }),
253
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("dt", { children: "Precisión" }), /* @__PURE__ */ h("dd", { children: [fe, "%"] })] })
254
254
  ]
255
255
  })]
256
256
  }),
257
- /* @__PURE__ */ d("button", {
257
+ /* @__PURE__ */ m("button", {
258
258
  type: "button",
259
259
  className: "bs-proto__icon-btn bs-proto__close",
260
260
  onClick: e,
261
261
  "aria-label": "Cerrar Batalla Naval",
262
262
  title: "Cerrar (Esc)",
263
- children: /* @__PURE__ */ d(h, {
263
+ children: /* @__PURE__ */ m(p, {
264
264
  size: 18,
265
265
  "aria-hidden": "true"
266
266
  })
267
267
  })
268
268
  ]
269
269
  }),
270
- /* @__PURE__ */ d("div", {
270
+ /* @__PURE__ */ m("div", {
271
271
  className: "bs-proto__live",
272
272
  "aria-live": "polite",
273
273
  "aria-atomic": "true",
274
- children: V && /* @__PURE__ */ d("span", {
274
+ children: V && /* @__PURE__ */ m("span", {
275
275
  className: `bs-proto__toast bs-proto__toast--${V.kind}${U ? " is-visible" : ""}`,
276
276
  children: V.text
277
277
  }, V.id)
278
278
  }),
279
- /* @__PURE__ */ d("span", {
279
+ /* @__PURE__ */ m("span", {
280
280
  className: "bs-proto__sr",
281
281
  "aria-live": "polite",
282
282
  children: j ? `Casilla seleccionada ${y(j)}` : ""
283
283
  }),
284
- Y && /* @__PURE__ */ f("footer", {
284
+ Y && /* @__PURE__ */ h("footer", {
285
285
  className: "bs-proto__bottom",
286
- children: [/* @__PURE__ */ d("p", {
286
+ children: [/* @__PURE__ */ m("p", {
287
287
  id: _,
288
288
  className: "bs-proto__hint",
289
289
  children: "Arrastra para rotar · Rueda/pellizco para zoom · Clic para apuntar · doble clic para disparar"
290
- }), /* @__PURE__ */ f("div", {
290
+ }), /* @__PURE__ */ h("div", {
291
291
  className: "bs-proto__panel bs-proto__actions",
292
292
  role: "toolbar",
293
293
  "aria-label": "Acciones de Batalla Naval",
294
294
  children: [
295
- /* @__PURE__ */ f("button", {
295
+ /* @__PURE__ */ h("button", {
296
296
  type: "button",
297
297
  className: "bs-proto__btn bs-proto__btn--fire",
298
298
  onClick: () => Z(),
299
299
  disabled: !j,
300
300
  title: j ? `Disparar en ${y(j)} (Enter)` : "Selecciona una casilla para disparar",
301
- children: [/* @__PURE__ */ d(ee, {
301
+ children: [/* @__PURE__ */ m(d, {
302
302
  size: 18,
303
303
  "aria-hidden": "true"
304
- }), /* @__PURE__ */ d("span", { children: "Disparar" })]
304
+ }), /* @__PURE__ */ m("span", { children: "Disparar" })]
305
305
  }),
306
- /* @__PURE__ */ f("button", {
306
+ /* @__PURE__ */ h("button", {
307
307
  type: "button",
308
308
  className: "bs-proto__btn",
309
309
  onClick: ce,
310
310
  "aria-pressed": F,
311
311
  title: "Mostrar u ocultar radar",
312
- children: [/* @__PURE__ */ d(re, {
312
+ children: [/* @__PURE__ */ m(te, {
313
313
  size: 18,
314
314
  "aria-hidden": "true"
315
- }), /* @__PURE__ */ d("span", {
315
+ }), /* @__PURE__ */ m("span", {
316
316
  className: "bs-proto__btn-label",
317
317
  children: "Radar"
318
318
  })]
319
319
  }),
320
- /* @__PURE__ */ f("button", {
320
+ /* @__PURE__ */ h("button", {
321
321
  type: "button",
322
322
  className: "bs-proto__btn",
323
323
  onClick: () => i.current?.resetCamera(),
324
324
  title: "Centrar cámara (R)",
325
- children: [/* @__PURE__ */ d(ne, {
325
+ children: [/* @__PURE__ */ m(ee, {
326
326
  size: 18,
327
327
  "aria-hidden": "true"
328
- }), /* @__PURE__ */ d("span", {
328
+ }), /* @__PURE__ */ m("span", {
329
329
  className: "bs-proto__btn-label",
330
330
  children: "Centrar cámara"
331
331
  })]
332
332
  }),
333
- /* @__PURE__ */ f("button", {
333
+ /* @__PURE__ */ h("button", {
334
334
  type: "button",
335
335
  className: "bs-proto__btn",
336
336
  onClick: le,
337
337
  "aria-label": `Calidad: ${$}. Cambiar calidad`,
338
338
  title: "Cambiar calidad de render",
339
- children: [/* @__PURE__ */ d(te, {
339
+ children: [/* @__PURE__ */ m(f, {
340
340
  size: 18,
341
341
  "aria-hidden": "true"
342
- }), /* @__PURE__ */ f("span", {
342
+ }), /* @__PURE__ */ h("span", {
343
343
  className: "bs-proto__btn-label",
344
344
  children: ["Calidad: ", $]
345
345
  })]
346
346
  }),
347
- /* @__PURE__ */ f("button", {
347
+ /* @__PURE__ */ h("button", {
348
348
  type: "button",
349
349
  className: "bs-proto__btn",
350
350
  onClick: ue,
351
351
  title: "Reiniciar tablero",
352
- children: [/* @__PURE__ */ d(ie, {
352
+ children: [/* @__PURE__ */ m(ne, {
353
353
  size: 18,
354
354
  "aria-hidden": "true"
355
- }), /* @__PURE__ */ d("span", {
355
+ }), /* @__PURE__ */ m("span", {
356
356
  className: "bs-proto__btn-label",
357
357
  children: "Reiniciar"
358
358
  })]
@@ -360,7 +360,7 @@ function O({ onClose: e, compact: t = !1 }) {
360
360
  ]
361
361
  })]
362
362
  }),
363
- !Y && /* @__PURE__ */ d("p", {
363
+ !Y && /* @__PURE__ */ m("p", {
364
364
  id: _,
365
365
  className: "bs-proto__sr",
366
366
  children: "Arrastra para rotar · Rueda/pellizco para zoom · Clic para seleccionar"
@@ -370,4 +370,4 @@ function O({ onClose: e, compact: t = !1 }) {
370
370
  }
371
371
  export { O as default };
372
372
 
373
- //# sourceMappingURL=BattleshipPrototype-Duz-S1JE.js.map
373
+ //# sourceMappingURL=BattleshipPrototype-Dm6U_mCr.js.map