speakid-hangman 1.0.2 → 1.0.3

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":"speakid-hangman.cjs.js","sources":["../src/styles/style.ts","../src/components/HangmanLobbyGame.tsx"],"sourcesContent":["import { CSSProperties } from \"react\";\n\n// ===== Стили согласно визуальному гайдлайну: Onest, минималистичный, дружелюбный =====\n// Шрифт: Onest (Regular, Medium, SemiBold)\n// Стиль: Плоский, минималистичный, воздушный, без излишеств\n// Цвета: Мягкий контраст, дружелюбная палитра\n\nexport const styles: Record<string, CSSProperties> = {\n gmCenterScreen: {\n position: \"relative\",\n zIndex: 1,\n minHeight: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n color: \"#1f2937\", // colorTextPrimary\n padding: \"24px 16px\",\n boxSizing: \"border-box\",\n fontFamily: '\"Onest\", system-ui, -apple-system, \"Segoe UI\", Roboto, Arial, sans-serif',\n background: \"transparent\", // Прозрачный по умолчанию, переопределяется в компоненте\n },\n // Desktop: Headline 1 - Onest SemiBold 32px, line-height 110%\n gmHeadline1: {\n fontWeight: 600, // SemiBold\n fontSize: \"clamp(30px, 4vw, 32px)\", // Mobile 30px, Desktop 32px\n lineHeight: \"110%\",\n marginBottom: \"24px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 2 - Onest Medium 24px, line-height 110%\n gmHeadline2: {\n fontWeight: 500, // Medium\n fontSize: \"24px\",\n lineHeight: \"110%\",\n marginBottom: \"16px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 3 - Onest Medium 24px, line-height 110%\n // Mobile: Headline 3 - Onest Medium 16px, line-height 110%\n gmHeadline3: {\n fontWeight: 500, // Medium\n fontSize: \"clamp(16px, 2vw, 24px)\", // Mobile 16px, Desktop 24px\n lineHeight: \"110%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body L - Onest Regular 18px, line-height 120%\n gmBodyL: {\n fontWeight: 400, // Regular\n fontSize: \"18px\",\n lineHeight: \"120%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body M - Onest Regular 16px, line-height 120%\n // Mobile: Body M - Onest Regular 14px, line-height 120%\n gmBodyM: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(14px, 1.5vw, 16px)\", // Mobile 14px, Desktop 16px\n lineHeight: \"120%\",\n marginBottom: \"8px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body S - Onest Regular 14px, line-height 120%\n // Mobile: Body S - Onest Regular 12px, line-height 120%\n gmBodyS: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(12px, 1.5vw, 14px)\", // Mobile 12px, Desktop 14px\n lineHeight: \"120%\",\n color: \"#6b7280\", // colorTextSecondary\n marginBottom: \"8px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Button: Onest Regular 16px, line-height 100%\n gmButton: {\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 400, // Regular\n fontSize: \"16px\",\n lineHeight: \"100%\",\n padding: \"10px 16px\",\n borderRadius: \"8px\", // Более мягкие углы для минималистичного стиля\n border: \"1px solid #e5e7eb\", // colorSeparator\n background: \"#ec4c44\", // colorAccent (Default)\n color: \"#ffffff\", // colorTextContrast\n cursor: \"pointer\",\n boxShadow: \"none\", // Плоский стиль без теней\n transition: \"background-color 0.2s ease, opacity 0.2s ease, transform 0.1s ease\",\n margin: \"4px\",\n },\n gmButtonActive: {\n background: \"#333\", // colorAccent Active\n color: \"#fff\", // colorTextContrast\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonSecondary: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n color: \"#1f2937\", // colorTextPrimary\n border: \"1px solid #e5e7eb\", // colorSeparator\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonGroup: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n justifyContent: \"center\",\n marginBottom: \"24px\",\n },\n gmWordDisplay: {\n fontSize: \"clamp(20px, 5vw, 28px)\",\n fontWeight: 500, // Medium\n letterSpacing: \"6px\",\n margin: \"32px 0\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmGuessedLetters: {\n fontSize: \"clamp(12px, 1.5vw, 16px)\", // Body S / Body M\n color: \"#6b7280\", // colorTextSecondary\n marginTop: \"16px\",\n minHeight: \"24px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmStatusWin: {\n color: \"#10b981\", // colorTextPositive / colorIconPositive\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmStatusLose: {\n color: \"#ec4c44\", // colorTextNegative / colorIconNegative\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmInfoBox: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n border: \"1px solid #e5e7eb\", // colorSeparator\n borderRadius: \"8px\", // Мягкие углы\n padding: \"16px\",\n marginBottom: \"24px\",\n maxWidth: \"500px\",\n width: \"100%\",\n boxShadow: \"none\", // Плоский стиль\n },\n gmSection: {\n marginBottom: \"32px\",\n width: \"100%\",\n maxWidth: \"500px\",\n },\n // ✅ Обновлено только для качества логотипа (размер как в magic-sentence)\n gmLogoFixed: {\n position: \"absolute\",\n top: \"16px\",\n left: \"16px\",\n width: \"auto\",\n zIndex: 10,\n pointerEvents: \"none\",\n background: \"transparent\",\n transform: \"none\",\n willChange: \"auto\",\n },\n gmLogoImg: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n objectFit: \"contain\",\n imageRendering: \"auto\",\n transform: \"translateZ(0)\",\n backfaceVisibility: \"hidden\",\n WebkitFontSmoothing: \"antialiased\",\n display: \"block\",\n },\n gmLogoFallback: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n color: \"#ec4c44\",\n fontSize: \"16px\",\n fontWeight: 700,\n display: \"block\",\n },\n};\n\n// ===== Цветовая палитра для справки =====\n// colorTextPrimary: #1f2937\n// colorTextSecondary: #6b7280\n// colorTextNegative: #ec4c44\n// colorTextPositive: #10b981\n// colorBackgroundAccent: #f9f9f9\n// colorSeparator: #e5e7eb\n// colorAccent (Default): #ec4c44\n// colorAccent (Active): #333\n\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { styles } from \"../styles/style\";\n\n// Компонент визуализации виселицы\nfunction HangmanDrawing({ \n mistakes, \n maxMistakes, \n size = 200 \n}: { \n mistakes: number; \n maxMistakes: number;\n size?: number;\n}) {\n // Адаптивные размеры SVG\n const svgWidth = size;\n const svgHeight = size * 1.25; // Соотношение 200:250\n const strokeWidth = Math.max(2, size / 100); // Адаптивная толщина линий\n \n // Координаты (пропорциональные исходному размеру 200x250)\n const baseX1 = 10 * (svgWidth / 200);\n const baseY = 240 * (svgHeight / 250);\n const baseX2 = 150 * (svgWidth / 200);\n \n const poleX = 80 * (svgWidth / 200);\n const poleY1 = 20 * (svgHeight / 250);\n const poleY2 = 240 * (svgHeight / 250);\n \n const topX1 = 80 * (svgWidth / 200);\n const topY = 20 * (svgHeight / 250);\n const topX2 = 150 * (svgWidth / 200);\n \n const ropeX = 150 * (svgWidth / 200);\n const ropeY1 = 20 * (svgHeight / 250);\n const ropeY2 = 50 * (svgHeight / 250);\n \n const headCX = 150 * (svgWidth / 200);\n const headCY = 70 * (svgHeight / 250);\n const headR = 20 * (svgWidth / 200);\n \n const bodyX = 150 * (svgWidth / 200);\n const bodyY1 = 90 * (svgHeight / 250);\n const bodyY2 = 150 * (svgHeight / 250);\n \n const leftArmX1 = 150 * (svgWidth / 200);\n const leftArmY1 = 110 * (svgHeight / 250);\n const leftArmX2 = 130 * (svgWidth / 200);\n const leftArmY2 = 130 * (svgHeight / 250);\n \n const rightArmX1 = 150 * (svgWidth / 200);\n const rightArmY1 = 110 * (svgHeight / 250);\n const rightArmX2 = 170 * (svgWidth / 200);\n const rightArmY2 = 130 * (svgHeight / 250);\n \n const leftLegX1 = 150 * (svgWidth / 200);\n const leftLegY1 = 150 * (svgHeight / 250);\n const leftLegX2 = 130 * (svgWidth / 200);\n const leftLegY2 = 190 * (svgHeight / 250);\n \n const rightLegX1 = 150 * (svgWidth / 200);\n const rightLegY1 = 150 * (svgHeight / 250);\n const rightLegX2 = 170 * (svgWidth / 200);\n const rightLegY2 = 190 * (svgHeight / 250);\n\n // Цвет в зависимости от количества ошибок\n const getStrokeColor = () => {\n if (mistakes === 0) return \"#1f2937\"; // colorTextPrimary\n if (mistakes <= maxMistakes * 0.5) return \"#1f2937\"; // Окей\n if (mistakes <= maxMistakes * 0.75) return \"#f59e0b\"; // Предупреждение\n return \"#ec4c44\"; // colorTextNegative - опасно\n };\n\n const strokeColor = getStrokeColor();\n\n return (\n <svg \n width={svgWidth} \n height={svgHeight} \n style={{ \n display: \"block\",\n margin: \"0 auto\",\n }}\n >\n {/* Виселица рисуется пошагово с ошибками */}\n {/* 1-я ошибка: Основание */}\n {mistakes > 0 && (\n <line \n x1={baseX1} \n y1={baseY} \n x2={baseX2} \n y2={baseY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 2-я ошибка: Стойка */}\n {mistakes > 1 && (\n <line \n x1={poleX} \n y1={poleY1} \n x2={poleX} \n y2={poleY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 3-я ошибка: Верхняя перекладина */}\n {mistakes > 2 && (\n <line \n x1={topX1} \n y1={topY} \n x2={topX2} \n y2={topY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 4-я ошибка: Веревка */}\n {mistakes > 3 && (\n <line \n x1={ropeX} \n y1={ropeY1} \n x2={ropeX} \n y2={ropeY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 5-я ошибка: Голова */}\n {mistakes > 4 && (\n <circle \n cx={headCX} \n cy={headCY} \n r={headR} \n stroke={strokeColor} \n fill=\"none\" \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* 6-я ошибка: Тело */}\n {mistakes > 5 && (\n <line \n x1={bodyX} \n y1={bodyY1} \n x2={bodyX} \n y2={bodyY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* Дополнительные части (если maxMistakes больше 6) */}\n {mistakes > 6 && (\n <line \n x1={leftArmX1} \n y1={leftArmY1} \n x2={leftArmX2} \n y2={leftArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 7 && (\n <line \n x1={rightArmX1} \n y1={rightArmY1} \n x2={rightArmX2} \n y2={rightArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 8 && (\n <line \n x1={leftLegX1} \n y1={leftLegY1} \n x2={leftLegX2} \n y2={leftLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 9 && (\n <line \n x1={rightLegX1} \n y1={rightLegY1} \n x2={rightLegX2} \n y2={rightLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n </svg>\n );\n}\n\nexport interface HangmanLobbyGameProps {\n gameCubeSize?: number;\n screenHeight?: number;\n screenWidth?: number;\n logoUrl?: string;\n showLogo?: boolean;\n baseURL?: string;\n}\n\nexport default function HangmanLobbyGame({\n gameCubeSize = 400,\n screenHeight = 800,\n screenWidth = 800,\n logoUrl,\n showLogo = true,\n baseURL,\n}: HangmanLobbyGameProps = {}) {\n const categories = {\n Professions: [\"teacher\", \"doctor\", \"nurse\", \"driver\", \"police\", \"firefighter\", \"cook\", \"waiter\", \"farmer\", \"builder\", \"singer\", \"actor\", \"dentist\", \"pilot\", \"vet\", \"artist\", \"cleaner\", \"student\", \"baker\", \"mechanic\"],\n Family: [\"mother\", \"father\", \"sister\", \"brother\", \"grandmother\", \"grandfather\", \"aunt\", \"uncle\", \"cousin\", \"baby\", \"parents\", \"children\", \"wife\", \"husband\", \"son\", \"daughter\", \"family\", \"twins\", \"relatives\"],\n \"Farm animals\": [\"cow\", \"pig\", \"horse\", \"sheep\", \"goat\", \"duck\", \"chicken\", \"rooster\", \"turkey\", \"goose\", \"rabbit\", \"mouse\", \"donkey\", \"bee\", \"hen\", \"lamb\", \"bull\", \"pony\"],\n Food: [\"apple\", \"banana\", \"bread\", \"cheese\", \"milk\", \"egg\", \"rice\", \"soup\", \"fish\", \"meat\", \"potato\", \"carrot\", \"tomato\", \"cucumber\", \"butter\", \"cake\", \"salad\", \"pasta\", \"pizza\", \"juice\"],\n Hobbies: [\"reading\", \"drawing\", \"painting\", \"dancing\", \"singing\", \"cooking\", \"swimming\", \"fishing\", \"running\", \"cycling\", \"skating\", \"writing\", \"camping\", \"photography\", \"hiking\", \"games\"],\n Christmas: [\"tree\", \"present\", \"gift\", \"santa\", \"snow\", \"snowman\", \"bell\", \"star\", \"lights\", \"card\", \"cookies\", \"elf\", \"sleigh\", \"reindeer\", \"candle\", \"stocking\"],\n Halloween: [\"pumpkin\", \"costume\", \"candy\", \"ghost\", \"witch\", \"spider\", \"bat\", \"skeleton\", \"mask\", \"monster\", \"mummy\", \"cat\", \"broom\", \"zombie\", \"trick\", \"treat\", \"candle\", \"night\", \"party\"],\n Sport: [\"football\", \"basketball\", \"tennis\", \"swimming\", \"running\", \"baseball\", \"skiing\", \"skating\", \"volleyball\", \"hockey\", \"golf\", \"boxing\", \"cycling\", \"rugby\", \"karate\", \"yoga\", \"surfing\", \"climbing\", \"dancing\", \"gym\", \"chess\"],\n \"Body parts\": [\"head\", \"hair\", \"eyes\", \"ears\", \"nose\", \"mouth\", \"teeth\", \"tongue\", \"neck\", \"shoulder\", \"arm\", \"hand\", \"finger\", \"leg\", \"knee\", \"foot\", \"toe\", \"back\", \"stomach\", \"heart\", \"legs\", \"nails\", \"chin\", \"beard\"],\n \"School subjects\": [\"math\", \"english\", \"history\", \"geography\", \"art\", \"music\", \"science\", \"biology\", \"chemistry\", \"physics\", \"pe\", \"literature\", \"drama\", \"design\", \"economics\"],\n Animals: [\"cat\", \"dog\", \"rabbit\", \"elephant\", \"lion\", \"tiger\", \"monkey\", \"bear\", \"fox\", \"wolf\", \"giraffe\", \"zebra\", \"crocodile\", \"dolphin\", \"whale\", \"shark\", \"frog\", \"parrot\", \"mouse\", \"penguin\", \"deer\", \"lizard\", \"turtle\", \"snake\"],\n Countries: [\"russia\", \"canada\", \"china\", \"japan\", \"france\", \"germany\", \"italy\", \"spain\", \"brazil\", \"india\", \"australia\", \"america\", \"england\", \"korea\", \"mexico\", \"egypt\", \"turkey\", \"vietnam\", \"norway\", \"finland\", \"thailand\", \"georgia\", \"kazakhstan\"],\n Clothes: [\"shirt\", \"dress\", \"skirt\", \"trousers\", \"jeans\", \"coat\", \"jacket\", \"sweater\", \"socks\", \"shoes\", \"boots\", \"hat\", \"scarf\", \"gloves\", \"shorts\", \"cap\", \"belt\", \"tie\", \"uniform\", \"pants\", \"underwear\"],\n Traveling: [\"ticket\", \"luggage\", \"suitcase\", \"airport\", \"flight\", \"passport\", \"visa\", \"map\", \"guide\", \"hotel\", \"reservation\", \"bus\", \"train\", \"taxi\", \"tourist\", \"sightseeing\", \"backpack\", \"journey\", \"adventure\", \"beach\", \"tour\", \"souvenir\"],\n Environment: [\"tree\", \"forest\", \"air\", \"water\", \"pollution\", \"recycle\", \"nature\", \"clean\", \"waste\", \"plastic\", \"energy\", \"animal\", \"climate\", \"earth\", \"ocean\", \"river\", \"planet\", \"save\", \"green\", \"environment\", \"litter\", \"organic\"],\n Space: [\"planet\", \"star\", \"sun\", \"moon\", \"astronaut\", \"rocket\", \"space\", \"galaxy\", \"universe\", \"telescope\", \"comet\", \"asteroid\", \"orbit\", \"gravity\", \"alien\", \"spaceship\", \"mars\", \"satellite\", \"sky\", \"eclipse\"],\n Devices: [\"computer\", \"laptop\", \"phone\", \"tablet\", \"tv\", \"keyboard\", \"mouse\", \"printer\", \"camera\", \"headphones\", \"charger\", \"screen\", \"watch\", \"microphone\", \"speaker\", \"console\", \"router\", \"battery\", \"cable\", \"remote\"],\n };\n\n const [stage, setStage] = useState<\"lobby\" | \"category\" | \"rounds\" | \"game\" | \"result\">(\"lobby\");\n const [category, setCategory] = useState<keyof typeof categories | \"\">(\"\");\n const [difficulty] = useState<\"Easy\" | \"Normal\" | \"Hard\">(\"Normal\"); // Фиксированная сложность\n const [rounds, setRounds] = useState(0); // 0 означает \"не выбрано\"\n const [currentRound, setCurrentRound] = useState(1);\n const [word, setWord] = useState(\"\");\n const [guessed, setGuessed] = useState<string[]>([]);\n const [mistakes, setMistakes] = useState(0);\n const [wins, setWins] = useState(0);\n const [roundResult, setRoundResult] = useState<\"win\" | \"lose\" | null>(null);\n const [containerSize, setContainerSize] = useState<number | null>(null);\n const [scale, setScale] = useState(1);\n const [usedWords, setUsedWords] = useState<string[]>([]); // Отслеживание использованных слов\n\n const maxMistakes = difficulty === \"Easy\" ? 8 : difficulty === \"Normal\" ? 6 : 4;\n\n // Вычисляем baseURL для изображений\n const imagesBaseURL = baseURL || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman`\n : \"/cloud/speakid/games/hangman\");\n\n // Определение мобильного устройства - используем window напрямую (как в magic-sentence)\n const [isMobile, setIsMobile] = useState(false);\n const [isNestHub, setIsNestHub] = useState(false);\n\n // Адаптивные размеры относительно gameCubeSize согласно визуальному гайдлайну\n // Desktop базовые размеры: Headline 1 - 32px, Headline 2 - 24px, Body M - 16px, Button - 16px\n // Mobile базовые размеры: Headline 1 - 30px, Headline 3 - 16px, Body M - 14px\n const baseFontSize = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400; // базовый размер 400px\n return {\n headline1: isMobile \n ? Math.max(24, Math.min(30, 30 * fontSizeScale)) // Mobile: 30px\n : Math.max(28, Math.min(32, 32 * fontSizeScale)), // Desktop: 32px\n headline2: Math.max(20, Math.min(28, 24 * fontSizeScale)), // Desktop: 24px\n headline3: isMobile\n ? Math.max(14, Math.min(18, 16 * fontSizeScale)) // Mobile: 16px\n : Math.max(20, Math.min(26, 24 * fontSizeScale)), // Desktop: 24px\n bodyL: Math.max(14, Math.min(20, 18 * fontSizeScale)), // Desktop: 18px\n bodyM: isMobile\n ? Math.max(12, Math.min(16, 14 * fontSizeScale)) // Mobile: 14px\n : Math.max(14, Math.min(18, 16 * fontSizeScale)), // Desktop: 16px\n bodyS: isMobile\n ? Math.max(10, Math.min(14, 12 * fontSizeScale)) // Mobile: 12px\n : Math.max(12, Math.min(16, 14 * fontSizeScale)), // Desktop: 14px\n wordDisplay: Math.max(18, Math.min(32, 26 * fontSizeScale)), // Адаптивный размер\n button: Math.max(12, Math.min(18, 16 * fontSizeScale)), // Desktop: 16px\n };\n }, [isMobile, containerSize, gameCubeSize]);\n\n // Адаптивные отступы и размеры (минималистичный стиль - мягкие углы)\n // Специальные настройки для Nest Hub (1024x600)\n const padding = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return isNestHub \n ? Math.max(8, Math.min(12, 10 * fontSizeScale))\n : Math.max(12, Math.min(24, 16 * fontSizeScale));\n }, [isNestHub, containerSize, gameCubeSize]);\n const gap = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return isNestHub\n ? Math.max(3, Math.min(6, 5 * fontSizeScale))\n : Math.max(4, Math.min(12, 8 * fontSizeScale));\n }, [isNestHub, containerSize, gameCubeSize]);\n const borderRadius = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return Math.max(6, Math.min(10, 8 * fontSizeScale));\n }, [containerSize, gameCubeSize]); // Мягкие углы для плоского стиля\n\n // Функции вдохновленные открытым кодом Hangman\n const isWordGuessed = (secretWord: string, lettersGuessed: string[]): boolean => {\n // Проверяем, все ли буквы слова угаданы\n return secretWord.split(\"\").every(letter => lettersGuessed.includes(letter));\n };\n\n const getGuessedWord = (secretWord: string, lettersGuessed: string[]): string => {\n // Возвращает строку с угаданными буквами и подчеркиваниями\n return secretWord\n .split(\"\")\n .map(letter => (lettersGuessed.includes(letter) ? letter : \"_\"))\n .join(\" \");\n };\n\n const getAvailableLetters = (lettersGuessed: string[]): string[] => {\n // Возвращает массив доступных букв (не угаданных)\n const alphabet = \"abcdefghijklmnopqrstuvwxyz\".split(\"\");\n return alphabet.filter(letter => !lettersGuessed.includes(letter));\n };\n\n const pickRandomCategory = (): keyof typeof categories => {\n const categoryKeys = Object.keys(categories) as Array<keyof typeof categories>;\n \n // Используем crypto.getRandomValues для более надежной случайности\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n randomIndex = array[0] % categoryKeys.length;\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * categoryKeys.length);\n }\n \n return categoryKeys[randomIndex];\n };\n\n const pickRandomWord = (cat: keyof typeof categories, avoidWords: string[] = []): string => {\n if (!cat || !categories[cat]) {\n // Fallback если категория пустая или не существует\n const firstCategory = Object.keys(categories)[0] as keyof typeof categories;\n return categories[firstCategory]?.[0] || \"\";\n }\n \n const words = categories[cat];\n if (!words || words.length === 0) {\n // Fallback если слова пустые\n return \"\";\n }\n \n // Если есть доступные слова (не использованные), выбираем из них\n const availableWords = words.filter(w => !avoidWords.includes(w));\n const wordsToChooseFrom = availableWords.length > 0 ? availableWords : words;\n \n if (wordsToChooseFrom.length === 0) {\n return \"\";\n }\n \n // Используем crypto.getRandomValues для более надежной случайности\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n const randomFloat = array[0] / 0xFFFFFFFF;\n randomIndex = Math.floor(randomFloat * wordsToChooseFrom.length);\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * wordsToChooseFrom.length);\n }\n \n return wordsToChooseFrom[randomIndex];\n };\n\n const startGame = () => {\n if (!category) return;\n setUsedWords([]); // Сбрасываем список использованных слов при новой игре\n const randomWord = pickRandomWord(category, []);\n if (!randomWord) {\n // Если не удалось выбрать слово, возвращаемся к выбору категории\n setStage(\"category\");\n return;\n }\n setWord(randomWord);\n setUsedWords([randomWord]); // Запоминаем первое слово\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n };\n\n // Функция для обработки выбора буквы (используется и для клавиатуры, и для кликов)\n const handleLetterSelect = useCallback((letter: string) => {\n if (stage !== \"game\" || roundResult !== null) return;\n \n const lowerLetter = letter.toLowerCase();\n \n // Проверка: только буквы английского алфавита\n if (!/^[a-z]$/.test(lowerLetter)) return;\n \n // Проверяем, была ли буква уже угадана\n setGuessed((prevGuessed) => {\n if (prevGuessed.includes(lowerLetter)) {\n return prevGuessed;\n }\n \n // Добавляем букву в список угаданных\n return [...prevGuessed, lowerLetter];\n });\n \n // Проверяем, есть ли буква в текущем слове (используем функциональное обновление)\n setWord((currentWord) => {\n if (currentWord && !currentWord.includes(lowerLetter)) {\n setMistakes((m) => m + 1);\n }\n return currentWord;\n });\n }, [stage, roundResult]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n handleLetterSelect(e.key);\n }, [handleLetterSelect]);\n\n useEffect(() => {\n if (stage === \"game\") {\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }\n }, [stage, handleKey]);\n\n // Используем функцию из открытого кода\n const masked = word ? getGuessedWord(word, guessed) : \"\";\n const isWin = word ? isWordGuessed(word, guessed) : false;\n // Игра проиграна когда виселица полностью нарисована (10 частей: основание, стойка, перекладина, веревка, голова, тело, левая рука, правая рука, левая нога, правая нога)\n const isLose = mistakes >= 10;\n const availableLetters = getAvailableLetters(guessed);\n\n // Функция для перехода к следующему раунду (вынесена для избежания дублирования)\n const moveToNextRound = useCallback(() => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord];\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n }, [category, currentRound, rounds]);\n\n useEffect(() => {\n if (isWin && roundResult === null) {\n setRoundResult(\"win\");\n setWins((w) => w + 1);\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n \n if (isLose && roundResult === null) {\n setRoundResult(\"lose\");\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n }, [isWin, isLose, roundResult, moveToNextRound]);\n\n const nextRound = () => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord]; // Добавляем новое слово в список использованных\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n };\n\n // ✅ Адаптив под мобилки, планшеты и десктоп (как в magic-sentence)\n useEffect(() => {\n const resize = () => {\n const width = window.innerWidth;\n const height = window.innerHeight;\n const mobile = width < 768 || (width === 926 && height === 428) || (width === 932 && height === 430);\n const isSmallHeight = height < 700;\n const isWideScreen = width / height > 1.8;\n const nestHub = width === 1024 && height === 600;\n \n setIsMobile(mobile);\n setIsNestHub(nestHub);\n\n // ✅ Адаптивные размеры контейнера\n // Если передан gameCubeSize, используем его (но с ограничениями)\n if (gameCubeSize && gameCubeSize >= 320) {\n const minSize = 320;\n const maxSize = 1200;\n const finalSize = Math.max(minSize, Math.min(maxSize, gameCubeSize));\n setContainerSize(finalSize);\n setScale(1);\n } else if (mobile) {\n setContainerSize(null);\n setScale(1);\n } else if (isSmallHeight) {\n setContainerSize(null);\n setScale(1);\n } else if (isWideScreen) {\n // ✅ Широкие экраны: используем стандартный размер но уменьшаем масштаб\n const minSize = 400;\n const maxSize = 1200;\n const finalSize = Math.min(1000, Math.min(width, height) * 0.9);\n setContainerSize(finalSize);\n setScale(0.85);\n } else {\n const minSize = 400;\n const maxSize = 1200;\n const finalSize = Math.min(1000, Math.min(width, height) * 0.9);\n setContainerSize(finalSize);\n setScale(1);\n }\n };\n resize();\n window.addEventListener(\"resize\", resize);\n return () => window.removeEventListener(\"resize\", resize);\n }, [gameCubeSize]);\n\n // SVG с детскими каракулями для фона (более резкие и яркие)\n const kidsDoodlesSvg = `\n <svg width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" style=\"position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0.2;\">\n <!-- Каракули мелками и фломастерами -->\n \n <!-- Сердечко -->\n <path d=\"M 85% 15% Q 85% 10%, 90% 10% Q 95% 10%, 95% 15% Q 95% 20%, 90% 25% Q 85% 30%, 85% 15%\" \n fill=\"none\" stroke=\"#FF69B4\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Звезда -->\n <path d=\"M 10% 85% L 12% 80% L 14% 85% L 18% 85% L 13% 88% L 15% 92% L 10% 89% L 5% 92% L 7% 88% L 2% 85% Z\" \n fill=\"#FFA500\" stroke=\"#FF8C00\" stroke-width=\"1.5\"/>\n \n <!-- Волнистые линии (мелки) -->\n <path d=\"M 20% 25% Q 22% 23%, 24% 25% T 28% 25% T 32% 25%\" \n fill=\"none\" stroke=\"#FF6B6B\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n <path d=\"M 60% 30% Q 62% 28%, 64% 30% T 68% 30% T 72% 30%\" \n fill=\"none\" stroke=\"#4ECDC4\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n \n <!-- Спираль -->\n <path d=\"M 5% 45% Q 8% 42%, 10% 45% Q 12% 48%, 10% 50% Q 8% 52%, 5% 50% Q 3% 48%, 5% 45%\" \n fill=\"none\" stroke=\"#9B59B6\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Зигзаг -->\n <path d=\"M 88% 55% L 92% 50% L 94% 55% L 96% 50% L 98% 55%\" \n fill=\"none\" stroke=\"#E74C3C\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \n <!-- Ромашка -->\n <circle cx=\"25%\" cy=\"70%\" r=\"15\" fill=\"none\" stroke=\"#FFD700\" stroke-width=\"2.5\"/>\n <circle cx=\"25%\" cy=\"70%\" r=\"8\" fill=\"#FFD700\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n \n <!-- Каляки-маляки (случайные линии) -->\n <path d=\"M 40% 20% Q 42% 22%, 40% 24% T 40% 28%\" \n fill=\"none\" stroke=\"#32CD32\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n <path d=\"M 50% 60% L 53% 57% L 55% 60% L 57% 57%\" \n fill=\"none\" stroke=\"#FF1493\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Еще волнистые линии -->\n <path d=\"M 35% 85% Q 37% 83%, 39% 85% T 43% 85% T 47% 85%\" \n fill=\"none\" stroke=\"#FF4500\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n </svg>\n `;\n\n // Адаптивные стили для контента (без фиксированных размеров)\n const containerStyle: React.CSSProperties = {\n ...styles.gmCenterScreen,\n width: \"100%\",\n height: \"100%\",\n padding: `${padding}px`,\n overflow: \"auto\",\n position: \"relative\",\n boxSizing: \"border-box\",\n background: \"transparent\",\n };\n\n // Условие для отображения логотипа (на desktop и планшетах)\n const shouldShowLogo = !isMobile && showLogo;\n\n // Мемоизированный логотип (рендерится вне условных блоков)\n const MemoizedLogo = useMemo(\n () => {\n // Скрываем логотип на мобильных устройствах в landscape режиме и на малых экранах\n const width = window.innerWidth;\n const height = window.innerHeight;\n if ((isMobile && width > height) || height < 700) {\n return null;\n }\n \n if (!shouldShowLogo) {\n return null;\n }\n \n const logoBaseUrl = logoUrl || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman/logo`\n : \"/cloud/speakid/games/hangman/logo\");\n \n return (\n <div style={{ ...styles.gmLogoFixed, position: \"absolute\", top: 16, left: 16, zIndex: 30 }}>\n <picture>\n <source\n srcSet={`${logoBaseUrl}.svg`}\n type=\"image/svg+xml\"\n />\n <img\n src={`${logoBaseUrl}.png`}\n alt=\"SPEAKID Logo\"\n style={styles.gmLogoImg}\n loading=\"lazy\"\n />\n </picture>\n </div>\n );\n },\n [isMobile, shouldShowLogo, logoUrl]\n );\n\n // Общая структура рендеринга (как в magic-sentence)\n const renderContent = () => {\n // Начальный экран лобби\n if (stage === \"lobby\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <h1 style={{ \n ...styles.gmHeadline1, \n fontSize: `${baseFontSize.headline1}px`, \n marginBottom: `${gap * 3}px`,\n position: \"relative\",\n zIndex: 1,\n }}>\n HANGMAN\n </h1>\n <button\n onClick={() => setStage(\"category\")}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500, // Medium для более заметности\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 3}px`,\n borderRadius: `${borderRadius * 1.5}px`,\n position: \"relative\",\n zIndex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#ec4c44\",\n color: \"#ffffff\",\n border: \"none\",\n cursor: \"pointer\",\n transition: \"background 0.2s ease, transform 0.1s ease\",\n boxShadow: \"0 2px 8px rgba(236, 76, 68, 0.2)\",\n minWidth: \"120px\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"#d43a32\";\n e.currentTarget.style.transform = \"translateY(-2px)\";\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(236, 76, 68, 0.3)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"#ec4c44\";\n e.currentTarget.style.transform = \"translateY(0)\";\n e.currentTarget.style.boxShadow = \"0 2px 8px rgba(236, 76, 68, 0.2)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n <svg\n width={`${baseFontSize.button * 1.3}px`}\n height={`${baseFontSize.button * 1.3}px`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ display: \"block\", marginRight: `${gap}px` }}\n >\n <path\n d=\"M8 5V19L19 12L8 5Z\"\n fill=\"#ffffff\"\n stroke=\"none\"\n />\n </svg>\n <span style={{ fontWeight: 500 }}>PLAY</span>\n </button>\n <div style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}>\n <img\n src={`${imagesBaseURL}/sun.png`}\n alt=\"Sun\"\n style={{\n position: \"absolute\",\n left: isMobile ? \"-10%\" : \"5%\",\n top: \"20%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n <img\n src={`${imagesBaseURL}/character.png`}\n alt=\"Hangman character\"\n style={{\n position: \"absolute\",\n right: isMobile ? \"5%\" : \"10%\",\n bottom: \"10%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n </div>\n </>\n );\n }\n\n // Экран выбора категории\n if (stage === \"category\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: `${padding}px`,\n left: `${padding + 100}px`, // ✅ Смещаем правее логотипа\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, marginTop: `${gap * 4}px`, position: \"relative\", zIndex: 1 }}>\n {Object.keys(categories).map((cat) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={cat}\n onClick={() => {\n setCategory(cat as keyof typeof categories);\n setStage(\"rounds\");\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {cat}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Экран выбора количества раундов\n if (stage === \"rounds\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"category\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: `${padding}px`,\n left: `${padding + 100}px`, // ✅ Смещаем правее логотипа\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <h1 style={{ ...styles.gmHeadline1, fontSize: `${baseFontSize.headline1}px`, marginBottom: `${gap * 2}px`, position: \"relative\", zIndex: 1 }}>\n Choose rounds\n </h1>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, position: \"relative\", zIndex: 1 }}>\n {[1, 3, 5].map((r) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={r}\n onClick={() => {\n setRounds(r);\n startGame();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {r}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Игровой экран\n if (stage === \"game\") {\n return (\n <>\n {MemoizedLogo}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${gap * 0.8}px`,\n marginBottom: `${gap * 0.5}px`,\n maxWidth: `${(containerSize || gameCubeSize) * 0.9}px`,\n }}>\n <h3 style={{ ...styles.gmHeadline3, fontSize: `${baseFontSize.headline3}px`, marginBottom: `${gap * 0.5}px` }}>\n Category: {category}\n </h3>\n <p style={{ ...styles.gmBodyM, fontSize: `${baseFontSize.bodyM}px`, marginBottom: `0px` }}>\n Round {currentRound} of {rounds}\n </p>\n </div>\n\n {word && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `${gap}px`,\n }}>\n I am thinking of a word that is <strong>{word.length}</strong> letters long\n </p>\n )}\n\n {/* Визуализация виселицы */}\n <div style={{\n margin: `${gap}px 0`,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}>\n <HangmanDrawing \n mistakes={mistakes} \n maxMistakes={maxMistakes}\n size={isNestHub \n ? Math.max(80, Math.min(110, (containerSize || gameCubeSize) * 0.16))\n : Math.max(100, Math.min(150, (containerSize || gameCubeSize) * 0.2))}\n />\n </div>\n\n <div style={{\n ...styles.gmWordDisplay,\n fontSize: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9))}px`,\n margin: `${gap}px 0`,\n letterSpacing: `${gap * 0.8}px`,\n minHeight: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9)) * 1.2}px`,\n }}>{masked || \"Loading...\"}</div>\n\n {/* Алфавит - вдохновлено getAvailableLetters */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${gap}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n maxWidth: `${(containerSize || gameCubeSize) * 0.95}px`,\n }}>\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginBottom: `${gap}px`,\n fontWeight: 500, // Medium\n }}>\n Available letters:\n </p>\n <div style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: `${gap / 3}px`,\n justifyContent: \"center\",\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n fontFamily: '\"Onest\", system-ui, sans-serif',\n }}>\n {availableLetters.map((letter) => (\n <button\n key={letter}\n onClick={() => handleLetterSelect(letter)}\n disabled={roundResult !== null}\n onMouseEnter={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n onMouseLeave={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n style={{\n padding: `${gap / 4}px ${gap / 3}px`,\n borderRadius: `${borderRadius * 0.5}px`,\n background: \"#f9f9f9\",\n color: \"#1f2937\",\n border: \"1px solid #e5e7eb\",\n minWidth: `${Math.max(gap * 1.5, (containerSize || gameCubeSize) * 0.04)}px`,\n textAlign: \"center\",\n display: \"inline-block\",\n cursor: roundResult === null ? \"pointer\" : \"default\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n transition: \"background-color 0.2s ease\",\n }}\n >\n {letter}\n </button>\n ))}\n </div>\n </div>\n\n {/* Уже угаданные буквы */}\n {guessed.length > 0 && (\n <div style={{\n ...styles.gmGuessedLetters,\n fontSize: `${Math.max(10, Math.min(12, baseFontSize.bodyS * 0.85))}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `2px`,\n }}>\n <span style={{ color: \"#6b7280\" }}>\n Guessed letters: <strong>{guessed.join(\", \")}</strong>\n </span>\n </div>\n )}\n\n {roundResult === \"win\" && (\n <div style={{\n ...styles.gmStatusWin,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n 🎉 You won this round!\n </div>\n )}\n\n {roundResult === \"lose\" && (\n <div style={{\n ...styles.gmStatusLose,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n The hangman is complete! The word was: <strong>{word}</strong>\n </div>\n )}\n\n {roundResult !== null && currentRound < rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={nextRound}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${Math.max(11, Math.min(14, baseFontSize.button * 0.85))}px`,\n padding: `${gap * 0.6}px ${gap * 1.2}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n NEXT\n </button>\n </div>\n )}\n\n {roundResult !== null && currentRound >= rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={() => setStage(\"result\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n View Results →\n </button>\n </div>\n )}\n\n {roundResult === null && guessed.length === 0 && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n }}>\n Type a letter on your keyboard\n </p>\n )}\n </>\n );\n }\n\n // Экран результатов\n if (stage === \"result\") {\n return (\n <>\n {MemoizedLogo}\n <h1 style={{\n ...styles.gmHeadline1,\n fontSize: `${baseFontSize.headline1}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n 🎊 Game Finished!\n </h1>\n <p style={{\n ...styles.gmBodyL,\n fontSize: `${baseFontSize.bodyL}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n You guessed <strong>{wins}</strong> out of <strong>{rounds}</strong> words correctly.\n </p>\n \n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${gap}px`,\n alignItems: \"center\",\n }}>\n <button\n onClick={() => {\n // Сбрасываем состояние и запускаем новую игру с той же категорией и раундами\n if (!category || rounds === 0) {\n setStage(\"lobby\");\n return;\n }\n \n setUsedWords([]);\n const randomWord = pickRandomWord(category as keyof typeof categories, []);\n if (randomWord) {\n setWord(randomWord);\n setUsedWords([randomWord]);\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n }\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Play again\n </button>\n \n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Exit\n </button>\n </div>\n </>\n );\n }\n\n return null;\n };\n\n // Единый return с трехуровневой структурой (как в magic-sentence)\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n background: \"transparent\",\n overflow: \"hidden\",\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n }}\n >\n <div\n style={{\n width: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n height: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n overflow: \"hidden\",\n borderRadius: isMobile ? 0 : \"20px\",\n background: \"#ffffff\",\n boxShadow: isMobile ? \"none\" : \"0 0 40px rgba(0,0,0,0.1)\",\n margin: isMobile ? \"0 auto\" : \"unset\",\n position: \"relative\", // needed so absolute logo is inside the square\n transform: `scale(${scale})`,\n }}\n >\n <div\n style={{\n transform: \"translateZ(0)\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <div style={containerStyle}>\n {renderContent()}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n"],"names":["styles","HangmanDrawing","mistakes","maxMistakes","size","svgWidth","svgHeight","strokeWidth","baseX1","baseY","baseX2","poleX","poleY1","poleY2","topX1","topY","topX2","ropeX","ropeY1","ropeY2","headCX","headCY","headR","bodyX","bodyY1","bodyY2","leftArmX1","leftArmY1","leftArmX2","leftArmY2","rightArmX1","rightArmY1","rightArmX2","rightArmY2","leftLegX1","leftLegY1","leftLegX2","leftLegY2","rightLegX1","rightLegY1","rightLegX2","rightLegY2","strokeColor","jsxs","jsx","HangmanLobbyGame","gameCubeSize","screenHeight","screenWidth","logoUrl","showLogo","baseURL","categories","stage","setStage","useState","category","setCategory","difficulty","rounds","setRounds","currentRound","setCurrentRound","word","setWord","guessed","setGuessed","setMistakes","wins","setWins","roundResult","setRoundResult","containerSize","setContainerSize","scale","setScale","usedWords","setUsedWords","imagesBaseURL","isMobile","setIsMobile","isNestHub","setIsNestHub","baseFontSize","useMemo","fontSizeScale","padding","gap","borderRadius","isWordGuessed","secretWord","lettersGuessed","letter","getGuessedWord","getAvailableLetters","pickRandomWord","cat","avoidWords","firstCategory","_a","words","availableWords","w","wordsToChooseFrom","randomIndex","array","randomFloat","startGame","randomWord","handleLetterSelect","useCallback","lowerLetter","prevGuessed","currentWord","m","handleKey","useEffect","masked","isWin","isLose","availableLetters","moveToNextRound","r","prev","newWord","timer","nextRound","resize","width","height","mobile","isSmallHeight","isWideScreen","nestHub","finalSize","kidsDoodlesSvg","containerStyle","shouldShowLogo","MemoizedLogo","logoBaseUrl","renderContent","Fragment","e"],"mappings":"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"}
1
+ {"version":3,"file":"speakid-hangman.cjs.js","sources":["../src/styles/style.ts","../src/components/HangmanLobbyGame.tsx"],"sourcesContent":["import { CSSProperties } from \"react\";\n\n// ===== Стили согласно визуальному гайдлайну: Onest, минималистичный, дружелюбный =====\n// Шрифт: Onest (Regular, Medium, SemiBold)\n// Стиль: Плоский, минималистичный, воздушный, без излишеств\n// Цвета: Мягкий контраст, дружелюбная палитра\n\nexport const styles: Record<string, CSSProperties> = {\n gmCenterScreen: {\n position: \"relative\",\n zIndex: 1,\n minHeight: \"100%\",\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n textAlign: \"center\",\n color: \"#1f2937\", // colorTextPrimary\n padding: \"24px 16px\",\n boxSizing: \"border-box\",\n fontFamily: '\"Onest\", system-ui, -apple-system, \"Segoe UI\", Roboto, Arial, sans-serif',\n background: \"transparent\", // Прозрачный по умолчанию, переопределяется в компоненте\n },\n // Desktop: Headline 1 - Onest SemiBold 32px, line-height 110%\n gmHeadline1: {\n fontWeight: 600, // SemiBold\n fontSize: \"clamp(30px, 4vw, 32px)\", // Mobile 30px, Desktop 32px\n lineHeight: \"110%\",\n marginBottom: \"24px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 2 - Onest Medium 24px, line-height 110%\n gmHeadline2: {\n fontWeight: 500, // Medium\n fontSize: \"24px\",\n lineHeight: \"110%\",\n marginBottom: \"16px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Headline 3 - Onest Medium 24px, line-height 110%\n // Mobile: Headline 3 - Onest Medium 16px, line-height 110%\n gmHeadline3: {\n fontWeight: 500, // Medium\n fontSize: \"clamp(16px, 2vw, 24px)\", // Mobile 16px, Desktop 24px\n lineHeight: \"110%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body L - Onest Regular 18px, line-height 120%\n gmBodyL: {\n fontWeight: 400, // Regular\n fontSize: \"18px\",\n lineHeight: \"120%\",\n marginBottom: \"12px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body M - Onest Regular 16px, line-height 120%\n // Mobile: Body M - Onest Regular 14px, line-height 120%\n gmBodyM: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(14px, 1.5vw, 16px)\", // Mobile 14px, Desktop 16px\n lineHeight: \"120%\",\n marginBottom: \"8px\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Desktop: Body S - Onest Regular 14px, line-height 120%\n // Mobile: Body S - Onest Regular 12px, line-height 120%\n gmBodyS: {\n fontWeight: 400, // Regular\n fontSize: \"clamp(12px, 1.5vw, 14px)\", // Mobile 12px, Desktop 14px\n lineHeight: \"120%\",\n color: \"#6b7280\", // colorTextSecondary\n marginBottom: \"8px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n // Button: Onest Regular 16px, line-height 100%\n gmButton: {\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 400, // Regular\n fontSize: \"16px\",\n lineHeight: \"100%\",\n padding: \"10px 16px\",\n borderRadius: \"8px\", // Более мягкие углы для минималистичного стиля\n border: \"1px solid #e5e7eb\", // colorSeparator\n background: \"#ec4c44\", // colorAccent (Default)\n color: \"#ffffff\", // colorTextContrast\n cursor: \"pointer\",\n boxShadow: \"none\", // Плоский стиль без теней\n transition: \"background-color 0.2s ease, opacity 0.2s ease, transform 0.1s ease\",\n margin: \"4px\",\n },\n gmButtonActive: {\n background: \"#333\", // colorAccent Active\n color: \"#fff\", // colorTextContrast\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonSecondary: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n color: \"#1f2937\", // colorTextPrimary\n border: \"1px solid #e5e7eb\", // colorSeparator\n boxShadow: \"none\", // Плоский стиль\n },\n gmButtonGroup: {\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n justifyContent: \"center\",\n marginBottom: \"24px\",\n },\n gmWordDisplay: {\n fontSize: \"clamp(20px, 5vw, 28px)\",\n fontWeight: 500, // Medium\n letterSpacing: \"6px\",\n margin: \"32px 0\",\n color: \"#1f2937\", // colorTextPrimary\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmGuessedLetters: {\n fontSize: \"clamp(12px, 1.5vw, 16px)\", // Body S / Body M\n color: \"#6b7280\", // colorTextSecondary\n marginTop: \"16px\",\n minHeight: \"24px\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n lineHeight: \"120%\",\n },\n gmStatusWin: {\n color: \"#10b981\", // colorTextPositive / colorIconPositive\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmStatusLose: {\n color: \"#ec4c44\", // colorTextNegative / colorIconNegative\n fontWeight: 500, // Medium\n fontSize: \"clamp(14px, 1.5vw, 18px)\", // Body M / Body L\n lineHeight: \"120%\",\n margin: \"16px 0\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n },\n gmInfoBox: {\n background: \"#f9f9f9\", // colorBackgroundAccent\n border: \"1px solid #e5e7eb\", // colorSeparator\n borderRadius: \"8px\", // Мягкие углы\n padding: \"16px\",\n marginBottom: \"24px\",\n maxWidth: \"500px\",\n width: \"100%\",\n boxShadow: \"none\", // Плоский стиль\n },\n gmSection: {\n marginBottom: \"32px\",\n width: \"100%\",\n maxWidth: \"500px\",\n },\n // ✅ Обновлено только для качества логотипа (размер как в magic-sentence)\n gmLogoFixed: {\n position: \"absolute\",\n top: \"16px\",\n left: \"16px\",\n width: \"auto\",\n zIndex: 10,\n pointerEvents: \"none\",\n background: \"transparent\",\n transform: \"none\",\n willChange: \"auto\",\n },\n gmLogoImg: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n objectFit: \"contain\",\n imageRendering: \"auto\",\n transform: \"translateZ(0)\",\n backfaceVisibility: \"hidden\",\n WebkitFontSmoothing: \"antialiased\",\n display: \"block\",\n },\n gmLogoFallback: {\n height: \"28px\",\n width: \"auto\",\n background: \"transparent\",\n color: \"#ec4c44\",\n fontSize: \"16px\",\n fontWeight: 700,\n display: \"block\",\n },\n};\n\n// ===== Цветовая палитра для справки =====\n// colorTextPrimary: #1f2937\n// colorTextSecondary: #6b7280\n// colorTextNegative: #ec4c44\n// colorTextPositive: #10b981\n// colorBackgroundAccent: #f9f9f9\n// colorSeparator: #e5e7eb\n// colorAccent (Default): #ec4c44\n// colorAccent (Active): #333\n\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { styles } from \"../styles/style\";\n\n// Компонент визуализации виселицы\nfunction HangmanDrawing({ \n mistakes, \n maxMistakes, \n size = 200 \n}: { \n mistakes: number; \n maxMistakes: number;\n size?: number;\n}) {\n // Адаптивные размеры SVG\n const svgWidth = size;\n const svgHeight = size * 1.25; // Соотношение 200:250\n const strokeWidth = Math.max(2, size / 100); // Адаптивная толщина линий\n \n // Координаты (пропорциональные исходному размеру 200x250)\n const baseX1 = 10 * (svgWidth / 200);\n const baseY = 240 * (svgHeight / 250);\n const baseX2 = 150 * (svgWidth / 200);\n \n const poleX = 80 * (svgWidth / 200);\n const poleY1 = 20 * (svgHeight / 250);\n const poleY2 = 240 * (svgHeight / 250);\n \n const topX1 = 80 * (svgWidth / 200);\n const topY = 20 * (svgHeight / 250);\n const topX2 = 150 * (svgWidth / 200);\n \n const ropeX = 150 * (svgWidth / 200);\n const ropeY1 = 20 * (svgHeight / 250);\n const ropeY2 = 50 * (svgHeight / 250);\n \n const headCX = 150 * (svgWidth / 200);\n const headCY = 70 * (svgHeight / 250);\n const headR = 20 * (svgWidth / 200);\n \n const bodyX = 150 * (svgWidth / 200);\n const bodyY1 = 90 * (svgHeight / 250);\n const bodyY2 = 150 * (svgHeight / 250);\n \n const leftArmX1 = 150 * (svgWidth / 200);\n const leftArmY1 = 110 * (svgHeight / 250);\n const leftArmX2 = 130 * (svgWidth / 200);\n const leftArmY2 = 130 * (svgHeight / 250);\n \n const rightArmX1 = 150 * (svgWidth / 200);\n const rightArmY1 = 110 * (svgHeight / 250);\n const rightArmX2 = 170 * (svgWidth / 200);\n const rightArmY2 = 130 * (svgHeight / 250);\n \n const leftLegX1 = 150 * (svgWidth / 200);\n const leftLegY1 = 150 * (svgHeight / 250);\n const leftLegX2 = 130 * (svgWidth / 200);\n const leftLegY2 = 190 * (svgHeight / 250);\n \n const rightLegX1 = 150 * (svgWidth / 200);\n const rightLegY1 = 150 * (svgHeight / 250);\n const rightLegX2 = 170 * (svgWidth / 200);\n const rightLegY2 = 190 * (svgHeight / 250);\n\n // Цвет в зависимости от количества ошибок\n const getStrokeColor = () => {\n if (mistakes === 0) return \"#1f2937\"; // colorTextPrimary\n if (mistakes <= maxMistakes * 0.5) return \"#1f2937\"; // Окей\n if (mistakes <= maxMistakes * 0.75) return \"#f59e0b\"; // Предупреждение\n return \"#ec4c44\"; // colorTextNegative - опасно\n };\n\n const strokeColor = getStrokeColor();\n\n return (\n <svg \n width={svgWidth} \n height={svgHeight} \n style={{ \n display: \"block\",\n margin: \"0 auto\",\n }}\n >\n {/* Виселица рисуется пошагово с ошибками */}\n {/* 1-я ошибка: Основание */}\n {mistakes > 0 && (\n <line \n x1={baseX1} \n y1={baseY} \n x2={baseX2} \n y2={baseY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 2-я ошибка: Стойка */}\n {mistakes > 1 && (\n <line \n x1={poleX} \n y1={poleY1} \n x2={poleX} \n y2={poleY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 3-я ошибка: Верхняя перекладина */}\n {mistakes > 2 && (\n <line \n x1={topX1} \n y1={topY} \n x2={topX2} \n y2={topY} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 4-я ошибка: Веревка */}\n {mistakes > 3 && (\n <line \n x1={ropeX} \n y1={ropeY1} \n x2={ropeX} \n y2={ropeY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n\n {/* 5-я ошибка: Голова */}\n {mistakes > 4 && (\n <circle \n cx={headCX} \n cy={headCY} \n r={headR} \n stroke={strokeColor} \n fill=\"none\" \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* 6-я ошибка: Тело */}\n {mistakes > 5 && (\n <line \n x1={bodyX} \n y1={bodyY1} \n x2={bodyX} \n y2={bodyY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {/* Дополнительные части (если maxMistakes больше 6) */}\n {mistakes > 6 && (\n <line \n x1={leftArmX1} \n y1={leftArmY1} \n x2={leftArmX2} \n y2={leftArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 7 && (\n <line \n x1={rightArmX1} \n y1={rightArmY1} \n x2={rightArmX2} \n y2={rightArmY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 8 && (\n <line \n x1={leftLegX1} \n y1={leftLegY1} \n x2={leftLegX2} \n y2={leftLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n \n {mistakes > 9 && (\n <line \n x1={rightLegX1} \n y1={rightLegY1} \n x2={rightLegX2} \n y2={rightLegY2} \n stroke={strokeColor} \n strokeWidth={strokeWidth}\n />\n )}\n </svg>\n );\n}\n\nexport interface HangmanLobbyGameProps {\n gameCubeSize?: number;\n screenHeight?: number;\n screenWidth?: number;\n logoUrl?: string;\n showLogo?: boolean;\n baseURL?: string;\n}\n\nexport default function HangmanLobbyGame({\n gameCubeSize = 400,\n screenHeight = 800,\n screenWidth = 800,\n logoUrl,\n showLogo = true,\n baseURL,\n}: HangmanLobbyGameProps = {}) {\n const categories = {\n Professions: [\"teacher\", \"doctor\", \"nurse\", \"driver\", \"police\", \"firefighter\", \"cook\", \"waiter\", \"farmer\", \"builder\", \"singer\", \"actor\", \"dentist\", \"pilot\", \"vet\", \"artist\", \"cleaner\", \"student\", \"baker\", \"mechanic\"],\n Family: [\"mother\", \"father\", \"sister\", \"brother\", \"grandmother\", \"grandfather\", \"aunt\", \"uncle\", \"cousin\", \"baby\", \"parents\", \"children\", \"wife\", \"husband\", \"son\", \"daughter\", \"family\", \"twins\", \"relatives\"],\n \"Farm animals\": [\"cow\", \"pig\", \"horse\", \"sheep\", \"goat\", \"duck\", \"chicken\", \"rooster\", \"turkey\", \"goose\", \"rabbit\", \"mouse\", \"donkey\", \"bee\", \"hen\", \"lamb\", \"bull\", \"pony\"],\n Food: [\"apple\", \"banana\", \"bread\", \"cheese\", \"milk\", \"egg\", \"rice\", \"soup\", \"fish\", \"meat\", \"potato\", \"carrot\", \"tomato\", \"cucumber\", \"butter\", \"cake\", \"salad\", \"pasta\", \"pizza\", \"juice\"],\n Hobbies: [\"reading\", \"drawing\", \"painting\", \"dancing\", \"singing\", \"cooking\", \"swimming\", \"fishing\", \"running\", \"cycling\", \"skating\", \"writing\", \"camping\", \"photography\", \"hiking\", \"games\"],\n Christmas: [\"tree\", \"present\", \"gift\", \"santa\", \"snow\", \"snowman\", \"bell\", \"star\", \"lights\", \"card\", \"cookies\", \"elf\", \"sleigh\", \"reindeer\", \"candle\", \"stocking\"],\n Halloween: [\"pumpkin\", \"costume\", \"candy\", \"ghost\", \"witch\", \"spider\", \"bat\", \"skeleton\", \"mask\", \"monster\", \"mummy\", \"cat\", \"broom\", \"zombie\", \"trick\", \"treat\", \"candle\", \"night\", \"party\"],\n Sport: [\"football\", \"basketball\", \"tennis\", \"swimming\", \"running\", \"baseball\", \"skiing\", \"skating\", \"volleyball\", \"hockey\", \"golf\", \"boxing\", \"cycling\", \"rugby\", \"karate\", \"yoga\", \"surfing\", \"climbing\", \"dancing\", \"gym\", \"chess\"],\n \"Body parts\": [\"head\", \"hair\", \"eyes\", \"ears\", \"nose\", \"mouth\", \"teeth\", \"tongue\", \"neck\", \"shoulder\", \"arm\", \"hand\", \"finger\", \"leg\", \"knee\", \"foot\", \"toe\", \"back\", \"stomach\", \"heart\", \"legs\", \"nails\", \"chin\", \"beard\"],\n \"School subjects\": [\"math\", \"english\", \"history\", \"geography\", \"art\", \"music\", \"science\", \"biology\", \"chemistry\", \"physics\", \"pe\", \"literature\", \"drama\", \"design\", \"economics\"],\n Animals: [\"cat\", \"dog\", \"rabbit\", \"elephant\", \"lion\", \"tiger\", \"monkey\", \"bear\", \"fox\", \"wolf\", \"giraffe\", \"zebra\", \"crocodile\", \"dolphin\", \"whale\", \"shark\", \"frog\", \"parrot\", \"mouse\", \"penguin\", \"deer\", \"lizard\", \"turtle\", \"snake\"],\n Countries: [\"russia\", \"canada\", \"china\", \"japan\", \"france\", \"germany\", \"italy\", \"spain\", \"brazil\", \"india\", \"australia\", \"america\", \"england\", \"korea\", \"mexico\", \"egypt\", \"turkey\", \"vietnam\", \"norway\", \"finland\", \"thailand\", \"georgia\", \"kazakhstan\"],\n Clothes: [\"shirt\", \"dress\", \"skirt\", \"trousers\", \"jeans\", \"coat\", \"jacket\", \"sweater\", \"socks\", \"shoes\", \"boots\", \"hat\", \"scarf\", \"gloves\", \"shorts\", \"cap\", \"belt\", \"tie\", \"uniform\", \"pants\", \"underwear\"],\n Traveling: [\"ticket\", \"luggage\", \"suitcase\", \"airport\", \"flight\", \"passport\", \"visa\", \"map\", \"guide\", \"hotel\", \"reservation\", \"bus\", \"train\", \"taxi\", \"tourist\", \"sightseeing\", \"backpack\", \"journey\", \"adventure\", \"beach\", \"tour\", \"souvenir\"],\n Environment: [\"tree\", \"forest\", \"air\", \"water\", \"pollution\", \"recycle\", \"nature\", \"clean\", \"waste\", \"plastic\", \"energy\", \"animal\", \"climate\", \"earth\", \"ocean\", \"river\", \"planet\", \"save\", \"green\", \"environment\", \"litter\", \"organic\"],\n Space: [\"planet\", \"star\", \"sun\", \"moon\", \"astronaut\", \"rocket\", \"space\", \"galaxy\", \"universe\", \"telescope\", \"comet\", \"asteroid\", \"orbit\", \"gravity\", \"alien\", \"spaceship\", \"mars\", \"satellite\", \"sky\", \"eclipse\"],\n Devices: [\"computer\", \"laptop\", \"phone\", \"tablet\", \"tv\", \"keyboard\", \"mouse\", \"printer\", \"camera\", \"headphones\", \"charger\", \"screen\", \"watch\", \"microphone\", \"speaker\", \"console\", \"router\", \"battery\", \"cable\", \"remote\"],\n };\n\n const [stage, setStage] = useState<\"lobby\" | \"category\" | \"rounds\" | \"game\" | \"result\">(\"lobby\");\n const [category, setCategory] = useState<keyof typeof categories | \"\">(\"\");\n const [difficulty] = useState<\"Easy\" | \"Normal\" | \"Hard\">(\"Normal\"); // Фиксированная сложность\n const [rounds, setRounds] = useState(0); // 0 означает \"не выбрано\"\n const [currentRound, setCurrentRound] = useState(1);\n const [word, setWord] = useState(\"\");\n const [guessed, setGuessed] = useState<string[]>([]);\n const [mistakes, setMistakes] = useState(0);\n const [wins, setWins] = useState(0);\n const [roundResult, setRoundResult] = useState<\"win\" | \"lose\" | null>(null);\n const [containerSize, setContainerSize] = useState<number | null>(null);\n const [scale, setScale] = useState(1);\n const [usedWords, setUsedWords] = useState<string[]>([]); // Отслеживание использованных слов\n\n const maxMistakes = difficulty === \"Easy\" ? 8 : difficulty === \"Normal\" ? 6 : 4;\n\n // Вычисляем baseURL для изображений\n const imagesBaseURL = baseURL || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman`\n : \"/cloud/speakid/games/hangman\");\n\n // Определение мобильного устройства - используем window напрямую (как в magic-sentence)\n const [isMobile, setIsMobile] = useState(false);\n const [isNestHub, setIsNestHub] = useState(false);\n\n // Адаптивные размеры относительно gameCubeSize согласно визуальному гайдлайну\n // Desktop базовые размеры: Headline 1 - 32px, Headline 2 - 24px, Body M - 16px, Button - 16px\n // Mobile базовые размеры: Headline 1 - 30px, Headline 3 - 16px, Body M - 14px\n const baseFontSize = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400; // базовый размер 400px\n return {\n headline1: isMobile \n ? Math.max(24, Math.min(30, 30 * fontSizeScale)) // Mobile: 30px\n : Math.max(28, Math.min(32, 32 * fontSizeScale)), // Desktop: 32px\n headline2: Math.max(20, Math.min(28, 24 * fontSizeScale)), // Desktop: 24px\n headline3: isMobile\n ? Math.max(14, Math.min(18, 16 * fontSizeScale)) // Mobile: 16px\n : Math.max(20, Math.min(26, 24 * fontSizeScale)), // Desktop: 24px\n bodyL: Math.max(14, Math.min(20, 18 * fontSizeScale)), // Desktop: 18px\n bodyM: isMobile\n ? Math.max(12, Math.min(16, 14 * fontSizeScale)) // Mobile: 14px\n : Math.max(14, Math.min(18, 16 * fontSizeScale)), // Desktop: 16px\n bodyS: isMobile\n ? Math.max(10, Math.min(14, 12 * fontSizeScale)) // Mobile: 12px\n : Math.max(12, Math.min(16, 14 * fontSizeScale)), // Desktop: 14px\n wordDisplay: Math.max(18, Math.min(32, 26 * fontSizeScale)), // Адаптивный размер\n button: Math.max(12, Math.min(18, 16 * fontSizeScale)), // Desktop: 16px\n };\n }, [isMobile, containerSize, gameCubeSize]);\n\n // Адаптивные отступы и размеры (минималистичный стиль - мягкие углы)\n // Специальные настройки для Nest Hub (1024x600)\n const padding = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return isNestHub \n ? Math.max(8, Math.min(12, 10 * fontSizeScale))\n : Math.max(12, Math.min(24, 16 * fontSizeScale));\n }, [isNestHub, containerSize, gameCubeSize]);\n const gap = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return isNestHub\n ? Math.max(3, Math.min(6, 5 * fontSizeScale))\n : Math.max(4, Math.min(12, 8 * fontSizeScale));\n }, [isNestHub, containerSize, gameCubeSize]);\n const borderRadius = useMemo(() => {\n const fontSizeScale = (containerSize || gameCubeSize || 1000) / 400;\n return Math.max(6, Math.min(10, 8 * fontSizeScale));\n }, [containerSize, gameCubeSize]); // Мягкие углы для плоского стиля\n\n // Функции вдохновленные открытым кодом Hangman\n const isWordGuessed = (secretWord: string, lettersGuessed: string[]): boolean => {\n // Проверяем, все ли буквы слова угаданы\n return secretWord.split(\"\").every(letter => lettersGuessed.includes(letter));\n };\n\n const getGuessedWord = (secretWord: string, lettersGuessed: string[]): string => {\n // Возвращает строку с угаданными буквами и подчеркиваниями\n return secretWord\n .split(\"\")\n .map(letter => (lettersGuessed.includes(letter) ? letter : \"_\"))\n .join(\" \");\n };\n\n const getAvailableLetters = (lettersGuessed: string[]): string[] => {\n // Возвращает массив доступных букв (не угаданных)\n const alphabet = \"abcdefghijklmnopqrstuvwxyz\".split(\"\");\n return alphabet.filter(letter => !lettersGuessed.includes(letter));\n };\n\n const pickRandomCategory = (): keyof typeof categories => {\n const categoryKeys = Object.keys(categories) as Array<keyof typeof categories>;\n \n // Используем crypto.getRandomValues для более надежной случайности\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n randomIndex = array[0] % categoryKeys.length;\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * categoryKeys.length);\n }\n \n return categoryKeys[randomIndex];\n };\n\n const pickRandomWord = (cat: keyof typeof categories, avoidWords: string[] = []): string => {\n if (!cat || !categories[cat]) {\n // Fallback если категория пустая или не существует\n const firstCategory = Object.keys(categories)[0] as keyof typeof categories;\n return categories[firstCategory]?.[0] || \"\";\n }\n \n const words = categories[cat];\n if (!words || words.length === 0) {\n // Fallback если слова пустые\n return \"\";\n }\n \n // Если есть доступные слова (не использованные), выбираем из них\n const availableWords = words.filter(w => !avoidWords.includes(w));\n const wordsToChooseFrom = availableWords.length > 0 ? availableWords : words;\n \n if (wordsToChooseFrom.length === 0) {\n return \"\";\n }\n \n // Используем crypto.getRandomValues для более надежной случайности\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n let randomIndex: number;\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n // Преобразуем в дробное число от 0 до 1 для равномерного распределения\n const randomFloat = array[0] / 0xFFFFFFFF;\n randomIndex = Math.floor(randomFloat * wordsToChooseFrom.length);\n } else {\n // Fallback на Math.random если crypto недоступен\n randomIndex = Math.floor(Math.random() * wordsToChooseFrom.length);\n }\n \n return wordsToChooseFrom[randomIndex];\n };\n\n const startGame = () => {\n if (!category) return;\n setUsedWords([]); // Сбрасываем список использованных слов при новой игре\n const randomWord = pickRandomWord(category, []);\n if (!randomWord) {\n // Если не удалось выбрать слово, возвращаемся к выбору категории\n setStage(\"category\");\n return;\n }\n setWord(randomWord);\n setUsedWords([randomWord]); // Запоминаем первое слово\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n };\n\n // Функция для обработки выбора буквы (используется и для клавиатуры, и для кликов)\n const handleLetterSelect = useCallback((letter: string) => {\n if (stage !== \"game\" || roundResult !== null) return;\n \n const lowerLetter = letter.toLowerCase();\n \n // Проверка: только буквы английского алфавита\n if (!/^[a-z]$/.test(lowerLetter)) return;\n \n // Проверяем, была ли буква уже угадана\n setGuessed((prevGuessed) => {\n if (prevGuessed.includes(lowerLetter)) {\n return prevGuessed;\n }\n \n // Добавляем букву в список угаданных\n return [...prevGuessed, lowerLetter];\n });\n \n // Проверяем, есть ли буква в текущем слове (используем функциональное обновление)\n setWord((currentWord) => {\n if (currentWord && !currentWord.includes(lowerLetter)) {\n setMistakes((m) => m + 1);\n }\n return currentWord;\n });\n }, [stage, roundResult]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n handleLetterSelect(e.key);\n }, [handleLetterSelect]);\n\n useEffect(() => {\n if (stage === \"game\") {\n window.addEventListener(\"keydown\", handleKey);\n return () => window.removeEventListener(\"keydown\", handleKey);\n }\n }, [stage, handleKey]);\n\n // Используем функцию из открытого кода\n const masked = word ? getGuessedWord(word, guessed) : \"\";\n const isWin = word ? isWordGuessed(word, guessed) : false;\n // Игра проиграна когда виселица полностью нарисована (10 частей: основание, стойка, перекладина, веревка, голова, тело, левая рука, правая рука, левая нога, правая нога)\n const isLose = mistakes >= 10;\n const availableLetters = getAvailableLetters(guessed);\n\n // Функция для перехода к следующему раунду (вынесена для избежания дублирования)\n const moveToNextRound = useCallback(() => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord];\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n }, [category, currentRound, rounds]);\n\n useEffect(() => {\n if (isWin && roundResult === null) {\n setRoundResult(\"win\");\n setWins((w) => w + 1);\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n \n if (isLose && roundResult === null) {\n setRoundResult(\"lose\");\n \n const timer = setTimeout(() => {\n moveToNextRound();\n }, 2000);\n \n return () => clearTimeout(timer);\n }\n }, [isWin, isLose, roundResult, moveToNextRound]);\n\n const nextRound = () => {\n if (!category || currentRound >= rounds) {\n setStage(\"result\");\n return;\n }\n \n setCurrentRound((r) => r + 1);\n setUsedWords((prev) => {\n const newWord = pickRandomWord(category as keyof typeof categories, prev);\n if (newWord) {\n setWord(newWord);\n return [...prev, newWord]; // Добавляем новое слово в список использованных\n }\n return prev;\n });\n setGuessed([]);\n setMistakes(0);\n setRoundResult(null);\n };\n\n // ✅ Адаптив под мобилки, планшеты и десктоп (как в magic-sentence)\n useEffect(() => {\n const resize = () => {\n const width = window.innerWidth;\n const height = window.innerHeight;\n const mobile = width < 768 || (width === 926 && height === 428) || (width === 932 && height === 430);\n const isSmallHeight = height < 700;\n const isWideScreen = width / height > 1.8;\n const nestHub = width === 1024 && height === 600;\n \n setIsMobile(mobile);\n setIsNestHub(nestHub);\n\n // ✅ Адаптивные размеры контейнера\n // Если передан gameCubeSize, используем его (но с ограничениями)\n if (gameCubeSize && gameCubeSize >= 320) {\n const minSize = 320;\n const maxSize = 1200;\n const finalSize = Math.max(minSize, Math.min(maxSize, gameCubeSize));\n setContainerSize(finalSize);\n setScale(1);\n } else if (mobile) {\n setContainerSize(null);\n setScale(1);\n } else if (isSmallHeight) {\n setContainerSize(null);\n setScale(1);\n } else if (isWideScreen) {\n // ✅ Широкие экраны: используем стандартный размер но уменьшаем масштаб\n const minSize = 400;\n const maxSize = 1200;\n const finalSize = Math.min(1000, Math.min(width, height) * 0.9);\n setContainerSize(finalSize);\n setScale(0.85);\n } else {\n const minSize = 400;\n const maxSize = 1200;\n const finalSize = Math.min(1000, Math.min(width, height) * 0.9);\n setContainerSize(finalSize);\n setScale(1);\n }\n };\n resize();\n window.addEventListener(\"resize\", resize);\n return () => window.removeEventListener(\"resize\", resize);\n }, [gameCubeSize]);\n\n // SVG с детскими каракулями для фона (более резкие и яркие)\n const kidsDoodlesSvg = `\n <svg width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" style=\"position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0.2;\">\n <!-- Каракули мелками и фломастерами -->\n \n <!-- Сердечко -->\n <path d=\"M 85% 15% Q 85% 10%, 90% 10% Q 95% 10%, 95% 15% Q 95% 20%, 90% 25% Q 85% 30%, 85% 15%\" \n fill=\"none\" stroke=\"#FF69B4\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Звезда -->\n <path d=\"M 10% 85% L 12% 80% L 14% 85% L 18% 85% L 13% 88% L 15% 92% L 10% 89% L 5% 92% L 7% 88% L 2% 85% Z\" \n fill=\"#FFA500\" stroke=\"#FF8C00\" stroke-width=\"1.5\"/>\n \n <!-- Волнистые линии (мелки) -->\n <path d=\"M 20% 25% Q 22% 23%, 24% 25% T 28% 25% T 32% 25%\" \n fill=\"none\" stroke=\"#FF6B6B\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n <path d=\"M 60% 30% Q 62% 28%, 64% 30% T 68% 30% T 72% 30%\" \n fill=\"none\" stroke=\"#4ECDC4\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n \n <!-- Спираль -->\n <path d=\"M 5% 45% Q 8% 42%, 10% 45% Q 12% 48%, 10% 50% Q 8% 52%, 5% 50% Q 3% 48%, 5% 45%\" \n fill=\"none\" stroke=\"#9B59B6\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Зигзаг -->\n <path d=\"M 88% 55% L 92% 50% L 94% 55% L 96% 50% L 98% 55%\" \n fill=\"none\" stroke=\"#E74C3C\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n \n <!-- Ромашка -->\n <circle cx=\"25%\" cy=\"70%\" r=\"15\" fill=\"none\" stroke=\"#FFD700\" stroke-width=\"2.5\"/>\n <circle cx=\"25%\" cy=\"70%\" r=\"8\" fill=\"#FFD700\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"65%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"22%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n <line x1=\"25%\" y1=\"70%\" x2=\"28%\" y2=\"75%\" stroke=\"#FFFFFF\" stroke-width=\"2.5\"/>\n \n <!-- Каляки-маляки (случайные линии) -->\n <path d=\"M 40% 20% Q 42% 22%, 40% 24% T 40% 28%\" \n fill=\"none\" stroke=\"#32CD32\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n <path d=\"M 50% 60% L 53% 57% L 55% 60% L 57% 57%\" \n fill=\"none\" stroke=\"#FF1493\" stroke-width=\"3\" stroke-linecap=\"round\"/>\n \n <!-- Еще волнистые линии -->\n <path d=\"M 35% 85% Q 37% 83%, 39% 85% T 43% 85% T 47% 85%\" \n fill=\"none\" stroke=\"#FF4500\" stroke-width=\"3.5\" stroke-linecap=\"round\"/>\n </svg>\n `;\n\n // Адаптивные стили для контента (без фиксированных размеров)\n const containerStyle: React.CSSProperties = {\n ...styles.gmCenterScreen,\n width: \"100%\",\n height: \"100%\",\n padding: `${padding}px`,\n overflow: \"auto\",\n position: \"relative\",\n boxSizing: \"border-box\",\n background: \"transparent\",\n };\n\n // Условие для отображения логотипа (на desktop и планшетах)\n const shouldShowLogo = !isMobile && showLogo;\n\n // Мемоизированный логотип (рендерится вне условных блоков)\n const MemoizedLogo = useMemo(\n () => {\n // Скрываем логотип на мобильных устройствах в landscape режиме и на малых экранах\n const width = window.innerWidth;\n const height = window.innerHeight;\n if ((isMobile && width > height) || height < 700) {\n return null;\n }\n \n if (!shouldShowLogo) {\n return null;\n }\n \n const logoBaseUrl = logoUrl || (typeof window !== \"undefined\" && window.origin \n ? `${window.origin}/cloud/speakid/games/hangman/logo`\n : \"/cloud/speakid/games/hangman/logo\");\n \n return (\n <div style={{ ...styles.gmLogoFixed, position: \"absolute\", top: 16, left: 16, zIndex: 30 }}>\n <picture>\n <source\n srcSet={`${logoBaseUrl}.svg`}\n type=\"image/svg+xml\"\n />\n <img\n src={`${logoBaseUrl}.png`}\n alt=\"SPEAKID Logo\"\n style={styles.gmLogoImg}\n loading=\"lazy\"\n />\n </picture>\n </div>\n );\n },\n [isMobile, shouldShowLogo, logoUrl]\n );\n\n // Общая структура рендеринга (как в magic-sentence)\n const renderContent = () => {\n // Начальный экран лобби\n if (stage === \"lobby\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <h1 style={{ \n ...styles.gmHeadline1, \n fontSize: `${baseFontSize.headline1}px`, \n marginBottom: `${gap * 3}px`,\n position: \"relative\",\n zIndex: 1,\n }}>\n HANGMAN\n </h1>\n <button\n onClick={() => setStage(\"category\")}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500, // Medium для более заметности\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 3}px`,\n borderRadius: `${borderRadius * 1.5}px`,\n position: \"relative\",\n zIndex: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#ec4c44\",\n color: \"#ffffff\",\n border: \"none\",\n cursor: \"pointer\",\n transition: \"background 0.2s ease, transform 0.1s ease\",\n boxShadow: \"0 2px 8px rgba(236, 76, 68, 0.2)\",\n minWidth: \"120px\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"#d43a32\";\n e.currentTarget.style.transform = \"translateY(-2px)\";\n e.currentTarget.style.boxShadow = \"0 4px 12px rgba(236, 76, 68, 0.3)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"#ec4c44\";\n e.currentTarget.style.transform = \"translateY(0)\";\n e.currentTarget.style.boxShadow = \"0 2px 8px rgba(236, 76, 68, 0.2)\";\n }}\n onMouseDown={(e) => {\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n <svg\n width={`${baseFontSize.button * 1.3}px`}\n height={`${baseFontSize.button * 1.3}px`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ display: \"block\", marginRight: `${gap}px` }}\n >\n <path\n d=\"M8 5V19L19 12L8 5Z\"\n fill=\"#ffffff\"\n stroke=\"none\"\n />\n </svg>\n <span style={{ fontWeight: 500 }}>PLAY</span>\n </button>\n <div style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}>\n <img\n src={`${imagesBaseURL}/sun.png`}\n alt=\"Sun\"\n style={{\n position: \"absolute\",\n left: isMobile ? \"-10%\" : \"5%\",\n top: \"20%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n <img\n src={`${imagesBaseURL}/character.png`}\n alt=\"Hangman character\"\n style={{\n position: \"absolute\",\n right: isMobile ? \"5%\" : \"10%\",\n bottom: \"10%\",\n width: \"auto\",\n height: isMobile \n ? `${Math.min(window.innerHeight * 0.33, 200)}px`\n : `${Math.min((containerSize || gameCubeSize || 1000) * 0.33, 300)}px`,\n maxHeight: \"33vh\",\n objectFit: \"contain\",\n opacity: 0.6,\n }}\n />\n </div>\n </>\n );\n }\n\n // Экран выбора категории\n if (stage === \"category\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: `${padding}px`,\n left: \"160px\", // ✅ Фиксированное смещение правее логотипа (16px + ~120px логотип + 24px отступ)\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, marginTop: `${gap * 4}px`, position: \"relative\", zIndex: 1 }}>\n {Object.keys(categories).map((cat) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={cat}\n onClick={() => {\n setCategory(cat as keyof typeof categories);\n setStage(\"rounds\");\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {cat}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Экран выбора количества раундов\n if (stage === \"rounds\") {\n return (\n <>\n {MemoizedLogo}\n <div dangerouslySetInnerHTML={{ __html: kidsDoodlesSvg }} />\n <button\n onClick={() => setStage(\"category\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n position: \"absolute\",\n top: `${padding}px`,\n left: \"160px\", // ✅ Фиксированное смещение правее логотипа (16px + ~120px логотип + 24px отступ)\n zIndex: 10,\n }}\n >\n ←\n </button>\n\n <h1 style={{ ...styles.gmHeadline1, fontSize: `${baseFontSize.headline1}px`, marginBottom: `${gap * 2}px`, position: \"relative\", zIndex: 1 }}>\n Choose rounds\n </h1>\n\n <div style={{ ...styles.gmButtonGroup, gap: `${gap}px`, marginBottom: `${gap * 3}px`, position: \"relative\", zIndex: 1 }}>\n {[1, 3, 5].map((r) => {\n // Облачки с border вместо заливки\n return (\n <button\n key={r}\n onClick={() => {\n setRounds(r);\n startGame();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\";\n e.currentTarget.style.borderColor = \"#1f2937\";\n e.currentTarget.style.transform = \"scale(1.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.borderColor = \"#e5e7eb\";\n e.currentTarget.style.transform = \"scale(1)\";\n }}\n style={{\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontWeight: 500,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap * 1.2}px ${gap * 2}px`,\n borderRadius: `${borderRadius * 2}px`, // Более округлые для облачков\n margin: `${gap / 2}px`,\n background: \"transparent\",\n border: \"2px solid #e5e7eb\",\n color: \"#1f2937\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease\",\n boxShadow: \"none\",\n }}\n >\n {r}\n </button>\n );\n })}\n </div>\n </>\n );\n }\n\n // Игровой экран\n if (stage === \"game\") {\n return (\n <>\n {MemoizedLogo}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${gap * 0.8}px`,\n marginBottom: `${gap * 0.5}px`,\n maxWidth: `${(containerSize || gameCubeSize) * 0.9}px`,\n }}>\n <h3 style={{ ...styles.gmHeadline3, fontSize: `${baseFontSize.headline3}px`, marginBottom: `${gap * 0.5}px` }}>\n Category: {category}\n </h3>\n <p style={{ ...styles.gmBodyM, fontSize: `${baseFontSize.bodyM}px`, marginBottom: `0px` }}>\n Round {currentRound} of {rounds}\n </p>\n </div>\n\n {word && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `${gap}px`,\n }}>\n I am thinking of a word that is <strong>{word.length}</strong> letters long\n </p>\n )}\n\n {/* Визуализация виселицы */}\n <div style={{\n margin: `${gap}px 0`,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}>\n <HangmanDrawing \n mistakes={mistakes} \n maxMistakes={maxMistakes}\n size={isNestHub \n ? Math.max(80, Math.min(110, (containerSize || gameCubeSize) * 0.16))\n : Math.max(100, Math.min(150, (containerSize || gameCubeSize) * 0.2))}\n />\n </div>\n\n <div style={{\n ...styles.gmWordDisplay,\n fontSize: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9))}px`,\n margin: `${gap}px 0`,\n letterSpacing: `${gap * 0.8}px`,\n minHeight: `${Math.max(16, Math.min(24, baseFontSize.wordDisplay * 0.9)) * 1.2}px`,\n }}>{masked || \"Loading...\"}</div>\n\n {/* Алфавит - вдохновлено getAvailableLetters */}\n <div style={{\n ...styles.gmInfoBox,\n padding: `${gap}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n maxWidth: `${(containerSize || gameCubeSize) * 0.95}px`,\n }}>\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginBottom: `${gap}px`,\n fontWeight: 500, // Medium\n }}>\n Available letters:\n </p>\n <div style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: `${gap / 3}px`,\n justifyContent: \"center\",\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n fontFamily: '\"Onest\", system-ui, sans-serif',\n }}>\n {availableLetters.map((letter) => (\n <button\n key={letter}\n onClick={() => handleLetterSelect(letter)}\n disabled={roundResult !== null}\n onMouseEnter={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n onMouseLeave={(e) => {\n if (roundResult === null) {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n e.currentTarget.style.cursor = \"pointer\";\n }\n }}\n style={{\n padding: `${gap / 4}px ${gap / 3}px`,\n borderRadius: `${borderRadius * 0.5}px`,\n background: \"#f9f9f9\",\n color: \"#1f2937\",\n border: \"1px solid #e5e7eb\",\n minWidth: `${Math.max(gap * 1.5, (containerSize || gameCubeSize) * 0.04)}px`,\n textAlign: \"center\",\n display: \"inline-block\",\n cursor: roundResult === null ? \"pointer\" : \"default\",\n fontFamily: '\"Onest\", system-ui, sans-serif',\n fontSize: `${Math.max(9, Math.min(12, baseFontSize.bodyS * 0.75))}px`,\n transition: \"background-color 0.2s ease\",\n }}\n >\n {letter}\n </button>\n ))}\n </div>\n </div>\n\n {/* Уже угаданные буквы */}\n {guessed.length > 0 && (\n <div style={{\n ...styles.gmGuessedLetters,\n fontSize: `${Math.max(10, Math.min(12, baseFontSize.bodyS * 0.85))}px`,\n marginTop: `${gap * 0.5}px`,\n marginBottom: `2px`,\n }}>\n <span style={{ color: \"#6b7280\" }}>\n Guessed letters: <strong>{guessed.join(\", \")}</strong>\n </span>\n </div>\n )}\n\n {roundResult === \"win\" && (\n <div style={{\n ...styles.gmStatusWin,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n 🎉 You won this round!\n </div>\n )}\n\n {roundResult === \"lose\" && (\n <div style={{\n ...styles.gmStatusLose,\n fontSize: `${baseFontSize.bodyL}px`,\n margin: `2px 0`,\n }}>\n The hangman is complete! The word was: <strong>{word}</strong>\n </div>\n )}\n\n {roundResult !== null && currentRound < rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={nextRound}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${Math.max(11, Math.min(14, baseFontSize.button * 0.85))}px`,\n padding: `${gap * 0.6}px ${gap * 1.2}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n NEXT\n </button>\n </div>\n )}\n\n {roundResult !== null && currentRound >= rounds && (\n <div style={{ marginTop: `2px`, marginBottom: `${gap}px` }}>\n <button\n onClick={() => setStage(\"result\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n }}\n >\n View Results →\n </button>\n </div>\n )}\n\n {roundResult === null && guessed.length === 0 && (\n <p style={{\n ...styles.gmBodyS,\n fontSize: `${baseFontSize.bodyS}px`,\n marginTop: `${gap}px`,\n marginBottom: `${gap}px`,\n }}>\n Type a letter on your keyboard\n </p>\n )}\n </>\n );\n }\n\n // Экран результатов\n if (stage === \"result\") {\n return (\n <>\n {MemoizedLogo}\n <h1 style={{\n ...styles.gmHeadline1,\n fontSize: `${baseFontSize.headline1}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n 🎊 Game Finished!\n </h1>\n <p style={{\n ...styles.gmBodyL,\n fontSize: `${baseFontSize.bodyL}px`,\n marginBottom: `${gap * 2}px`,\n }}>\n You guessed <strong>{wins}</strong> out of <strong>{rounds}</strong> words correctly.\n </p>\n \n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${gap}px`,\n alignItems: \"center\",\n }}>\n <button\n onClick={() => {\n // Сбрасываем состояние и запускаем новую игру с той же категорией и раундами\n if (!category || rounds === 0) {\n setStage(\"lobby\");\n return;\n }\n \n setUsedWords([]);\n const randomWord = pickRandomWord(category as keyof typeof categories, []);\n if (randomWord) {\n setWord(randomWord);\n setUsedWords([randomWord]);\n setGuessed([]);\n setMistakes(0);\n setCurrentRound(1);\n setWins(0);\n setRoundResult(null);\n setStage(\"game\");\n }\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#d43a32\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#ec4c44\";\n }}\n style={{\n ...styles.gmButton,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Play again\n </button>\n \n <button\n onClick={() => setStage(\"lobby\")}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#e5e7eb\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"#f9f9f9\";\n }}\n style={{\n ...styles.gmButton,\n ...styles.gmButtonSecondary,\n fontSize: `${baseFontSize.button}px`,\n padding: `${gap}px ${gap * 1.5}px`,\n borderRadius: `${borderRadius}px`,\n minWidth: \"200px\",\n }}\n >\n Exit\n </button>\n </div>\n </>\n );\n }\n\n return null;\n };\n\n // Единый return с трехуровневой структурой (как в magic-sentence)\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n background: \"transparent\",\n overflow: \"hidden\",\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n }}\n >\n <div\n style={{\n width: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n height: isMobile ? \"100%\" : (containerSize || gameCubeSize || 1000),\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n overflow: \"hidden\",\n borderRadius: isMobile ? 0 : \"20px\",\n background: \"#ffffff\",\n boxShadow: isMobile ? \"none\" : \"0 0 40px rgba(0,0,0,0.1)\",\n margin: isMobile ? \"0 auto\" : \"unset\",\n position: \"relative\", // needed so absolute logo is inside the square\n transform: `scale(${scale})`,\n }}\n >\n <div\n style={{\n transform: \"translateZ(0)\",\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <div style={containerStyle}>\n {renderContent()}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n"],"names":["styles","HangmanDrawing","mistakes","maxMistakes","size","svgWidth","svgHeight","strokeWidth","baseX1","baseY","baseX2","poleX","poleY1","poleY2","topX1","topY","topX2","ropeX","ropeY1","ropeY2","headCX","headCY","headR","bodyX","bodyY1","bodyY2","leftArmX1","leftArmY1","leftArmX2","leftArmY2","rightArmX1","rightArmY1","rightArmX2","rightArmY2","leftLegX1","leftLegY1","leftLegX2","leftLegY2","rightLegX1","rightLegY1","rightLegX2","rightLegY2","strokeColor","jsxs","jsx","HangmanLobbyGame","gameCubeSize","screenHeight","screenWidth","logoUrl","showLogo","baseURL","categories","stage","setStage","useState","category","setCategory","difficulty","rounds","setRounds","currentRound","setCurrentRound","word","setWord","guessed","setGuessed","setMistakes","wins","setWins","roundResult","setRoundResult","containerSize","setContainerSize","scale","setScale","usedWords","setUsedWords","imagesBaseURL","isMobile","setIsMobile","isNestHub","setIsNestHub","baseFontSize","useMemo","fontSizeScale","padding","gap","borderRadius","isWordGuessed","secretWord","lettersGuessed","letter","getGuessedWord","getAvailableLetters","pickRandomWord","cat","avoidWords","firstCategory","_a","words","availableWords","w","wordsToChooseFrom","randomIndex","array","randomFloat","startGame","randomWord","handleLetterSelect","useCallback","lowerLetter","prevGuessed","currentWord","m","handleKey","useEffect","masked","isWin","isLose","availableLetters","moveToNextRound","r","prev","newWord","timer","nextRound","resize","width","height","mobile","isSmallHeight","isWideScreen","nestHub","finalSize","kidsDoodlesSvg","containerStyle","shouldShowLogo","MemoizedLogo","logoBaseUrl","renderContent","Fragment","e"],"mappings":"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"}
@@ -206,7 +206,7 @@ function ve({
206
206
  maxMistakes: Z,
207
207
  size: G = 200
208
208
  }) {
209
- const l = G, d = G * 1.25, y = Math.max(2, G / 100), T = 10 * (l / 200), b = 240 * (d / 250), f = 150 * (l / 200), x = 80 * (l / 200), K = 20 * (d / 250), Q = 240 * (d / 250), w = 80 * (l / 200), N = 20 * (d / 250), $ = 150 * (l / 200), B = 150 * (l / 200), M = 20 * (d / 250), z = 50 * (d / 250), v = 150 * (l / 200), C = 70 * (d / 250), _ = 20 * (l / 200), S = 150 * (l / 200), q = 90 * (d / 250), Y = 150 * (d / 250), h = 150 * (l / 200), F = 110 * (d / 250), g = 130 * (l / 200), W = 130 * (d / 250), J = 150 * (l / 200), H = 110 * (d / 250), ce = 170 * (l / 200), L = 130 * (d / 250), ee = 150 * (l / 200), V = 150 * (d / 250), p = 130 * (l / 200), te = 190 * (d / 250), I = 150 * (l / 200), ne = 150 * (d / 250), s = 170 * (l / 200), R = 190 * (d / 250), c = r === 0 || r <= Z * 0.5 ? "#1f2937" : r <= Z * 0.75 ? "#f59e0b" : "#ec4c44";
209
+ const l = G, d = G * 1.25, y = Math.max(2, G / 100), T = 10 * (l / 200), b = 240 * (d / 250), f = 150 * (l / 200), x = 80 * (l / 200), K = 20 * (d / 250), Q = 240 * (d / 250), w = 80 * (l / 200), N = 20 * (d / 250), $ = 150 * (l / 200), B = 150 * (l / 200), M = 20 * (d / 250), z = 50 * (d / 250), v = 150 * (l / 200), C = 70 * (d / 250), _ = 20 * (l / 200), S = 150 * (l / 200), q = 90 * (d / 250), E = 150 * (d / 250), h = 150 * (l / 200), F = 110 * (d / 250), g = 130 * (l / 200), W = 130 * (d / 250), J = 150 * (l / 200), H = 110 * (d / 250), ce = 170 * (l / 200), L = 130 * (d / 250), ee = 150 * (l / 200), V = 150 * (d / 250), p = 130 * (l / 200), te = 190 * (d / 250), I = 150 * (l / 200), ne = 150 * (d / 250), s = 170 * (l / 200), Y = 190 * (d / 250), c = r === 0 || r <= Z * 0.5 ? "#1f2937" : r <= Z * 0.75 ? "#f59e0b" : "#ec4c44";
210
210
  return /* @__PURE__ */ u(
211
211
  "svg",
212
212
  {
@@ -278,7 +278,7 @@ function ve({
278
278
  x1: S,
279
279
  y1: q,
280
280
  x2: S,
281
- y2: Y,
281
+ y2: E,
282
282
  stroke: c,
283
283
  strokeWidth: y
284
284
  }
@@ -322,7 +322,7 @@ function ve({
322
322
  x1: I,
323
323
  y1: ne,
324
324
  x2: s,
325
- y2: R,
325
+ y2: Y,
326
326
  stroke: c,
327
327
  strokeWidth: y
328
328
  }
@@ -357,7 +357,7 @@ function Le({
357
357
  Environment: ["tree", "forest", "air", "water", "pollution", "recycle", "nature", "clean", "waste", "plastic", "energy", "animal", "climate", "earth", "ocean", "river", "planet", "save", "green", "environment", "litter", "organic"],
358
358
  Space: ["planet", "star", "sun", "moon", "astronaut", "rocket", "space", "galaxy", "universe", "telescope", "comet", "asteroid", "orbit", "gravity", "alien", "spaceship", "mars", "satellite", "sky", "eclipse"],
359
359
  Devices: ["computer", "laptop", "phone", "tablet", "tv", "keyboard", "mouse", "printer", "camera", "headphones", "charger", "screen", "watch", "microphone", "speaker", "console", "router", "battery", "cable", "remote"]
360
- }, [b, f] = m("lobby"), [x, K] = m(""), [Q] = m("Normal"), [w, N] = m(0), [$, B] = m(1), [M, z] = m(""), [v, C] = m([]), [_, S] = m(0), [q, Y] = m(0), [h, F] = m(null), [g, W] = m(null), [J, H] = m(1), [ce, L] = m([]), ee = Q === "Easy" ? 8 : Q === "Normal" ? 6 : 4, V = y || (typeof window < "u" && window.origin ? `${window.origin}/cloud/speakid/games/hangman` : "/cloud/speakid/games/hangman"), [p, te] = m(!1), [I, ne] = m(!1), s = D(() => {
360
+ }, [b, f] = m("lobby"), [x, K] = m(""), [Q] = m("Normal"), [w, N] = m(0), [$, B] = m(1), [M, z] = m(""), [v, C] = m([]), [_, S] = m(0), [q, E] = m(0), [h, F] = m(null), [g, W] = m(null), [J, H] = m(1), [ce, L] = m([]), ee = Q === "Easy" ? 8 : Q === "Normal" ? 6 : 4, V = y || (typeof window < "u" && window.origin ? `${window.origin}/cloud/speakid/games/hangman` : "/cloud/speakid/games/hangman"), [p, te] = m(!1), [I, ne] = m(!1), s = D(() => {
361
361
  const e = (g || r || 1e3) / 400;
362
362
  return {
363
363
  headline1: p ? Math.max(24, Math.min(30, 30 * e)) : Math.max(28, Math.min(32, 32 * e)),
@@ -377,7 +377,7 @@ function Le({
377
377
  button: Math.max(12, Math.min(18, 16 * e))
378
378
  // Desktop: 16px
379
379
  };
380
- }, [p, g, r]), R = D(() => {
380
+ }, [p, g, r]), Y = D(() => {
381
381
  const e = (g || r || 1e3) / 400;
382
382
  return I ? Math.max(8, Math.min(12, 10 * e)) : Math.max(12, Math.min(24, 16 * e));
383
383
  }, [I, g, r]), o = D(() => {
@@ -395,18 +395,18 @@ function Le({
395
395
  const i = T[e];
396
396
  if (!i || i.length === 0)
397
397
  return "";
398
- const j = i.filter((k) => !t.includes(k)), E = j.length > 0 ? j : i;
399
- if (E.length === 0)
398
+ const R = i.filter((k) => !t.includes(k)), j = R.length > 0 ? R : i;
399
+ if (j.length === 0)
400
400
  return "";
401
401
  let O;
402
402
  if (typeof crypto < "u" && crypto.getRandomValues) {
403
403
  const k = new Uint32Array(1);
404
404
  crypto.getRandomValues(k);
405
405
  const ue = k[0] / 4294967295;
406
- O = Math.floor(ue * E.length);
406
+ O = Math.floor(ue * j.length);
407
407
  } else
408
- O = Math.floor(Math.random() * E.length);
409
- return E[O];
408
+ O = Math.floor(Math.random() * j.length);
409
+ return j[O];
410
410
  }, xe = () => {
411
411
  if (!x) return;
412
412
  L([]);
@@ -415,11 +415,11 @@ function Le({
415
415
  f("category");
416
416
  return;
417
417
  }
418
- z(e), L([e]), C([]), S(0), B(1), Y(0), F(null), f("game");
418
+ z(e), L([e]), C([]), S(0), B(1), E(0), F(null), f("game");
419
419
  }, oe = ae((e) => {
420
420
  if (b !== "game" || h !== null) return;
421
421
  const t = e.toLowerCase();
422
- /^[a-z]$/.test(t) && (C((i) => i.includes(t) ? i : [...i, t]), z((i) => (i && !i.includes(t) && S((j) => j + 1), i)));
422
+ /^[a-z]$/.test(t) && (C((i) => i.includes(t) ? i : [...i, t]), z((i) => (i && !i.includes(t) && S((R) => R + 1), i)));
423
423
  }, [b, h]), re = ae((e) => {
424
424
  oe(e.key);
425
425
  }, [oe]);
@@ -439,7 +439,7 @@ function Le({
439
439
  }, [x, $, w]);
440
440
  le(() => {
441
441
  if (de && h === null) {
442
- F("win"), Y((t) => t + 1);
442
+ F("win"), E((t) => t + 1);
443
443
  const e = setTimeout(() => {
444
444
  ie();
445
445
  }, 2e3);
@@ -465,13 +465,13 @@ function Le({
465
465
  };
466
466
  le(() => {
467
467
  const e = () => {
468
- const t = window.innerWidth, i = window.innerHeight, j = t < 768 || t === 926 && i === 428 || t === 932 && i === 430, E = i < 700, O = t / i > 1.8, U = t === 1024 && i === 600;
469
- if (te(j), ne(U), r && r >= 320) {
468
+ const t = window.innerWidth, i = window.innerHeight, R = t < 768 || t === 926 && i === 428 || t === 932 && i === 430, j = i < 700, O = t / i > 1.8, U = t === 1024 && i === 600;
469
+ if (te(R), ne(U), r && r >= 320) {
470
470
  const $e = Math.max(320, Math.min(1200, r));
471
471
  W($e), H(1);
472
- } else if (j)
472
+ } else if (R)
473
473
  W(null), H(1);
474
- else if (E)
474
+ else if (j)
475
475
  W(null), H(1);
476
476
  else if (O) {
477
477
  const k = Math.min(1e3, Math.min(t, i) * 0.9);
@@ -531,7 +531,7 @@ function Le({
531
531
  ...a.gmCenterScreen,
532
532
  width: "100%",
533
533
  height: "100%",
534
- padding: `${R}px`,
534
+ padding: `${Y}px`,
535
535
  overflow: "auto",
536
536
  position: "relative",
537
537
  boxSizing: "border-box",
@@ -694,9 +694,9 @@ function Le({
694
694
  padding: `${o}px ${o * 1.5}px`,
695
695
  borderRadius: `${c}px`,
696
696
  position: "absolute",
697
- top: `${R}px`,
698
- left: `${R + 100}px`,
699
- // ✅ Смещаем правее логотипа
697
+ top: `${Y}px`,
698
+ left: "160px",
699
+ // ✅ Фиксированное смещение правее логотипа (16px + ~120px логотип + 24px отступ)
700
700
  zIndex: 10
701
701
  },
702
702
  children: "←"
@@ -753,9 +753,9 @@ function Le({
753
753
  padding: `${o}px ${o * 1.5}px`,
754
754
  borderRadius: `${c}px`,
755
755
  position: "absolute",
756
- top: `${R}px`,
757
- left: `${R + 100}px`,
758
- // ✅ Смещаем правее логотипа
756
+ top: `${Y}px`,
757
+ left: "160px",
758
+ // ✅ Фиксированное смещение правее логотипа (16px + ~120px логотип + 24px отступ)
759
759
  zIndex: 10
760
760
  },
761
761
  children: "←"
@@ -993,7 +993,7 @@ function Le({
993
993
  }
994
994
  L([]);
995
995
  const e = P(x, []);
996
- e && (z(e), L([e]), C([]), S(0), B(1), Y(0), F(null), f("game"));
996
+ e && (z(e), L([e]), C([]), S(0), B(1), E(0), F(null), f("game"));
997
997
  },
998
998
  onMouseEnter: (e) => {
999
999
  e.currentTarget.style.backgroundColor = "#d43a32";