{"id":206,"date":"2025-05-09T04:40:04","date_gmt":"2025-05-09T04:40:04","guid":{"rendered":"https:\/\/book.filemondr.hu\/?page_id=206"},"modified":"2025-07-05T17:42:46","modified_gmt":"2025-07-05T17:42:46","slug":"memoria-jatek","status":"publish","type":"page","link":"https:\/\/book.filemondr.hu\/index.php\/memoria-jatek\/","title":{"rendered":"Mem\u00f3ria j\u00e1t\u00e9k"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"hu\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Mem\u00f3riaj\u00e1t\u00e9k &#8211; Filemondr Mesek\u00f6nyvek<\/title>\n\n    <!-- Glob\u00e1lis st\u00edluslap \u00e9s bet\u0171t\u00edpusok -->\n    <link rel=\"stylesheet\" href=\"\/egyseges-stilus.css\">\n    <link rel=\"stylesheet\" href=\"\/moderation.css\">\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Comic+Neue&#038;display=swap\" rel=\"stylesheet\">\n\n    <!-- WebView-kompatibilis meta tag-ek a dark mode kik\u00e9nyszer\u00edt\u00e9s\u00e9hez -->\n    <meta name=\"color-scheme\" content=\"dark\">\n    <meta name=\"theme-color\" content=\"#222831\">\n    <meta name=\"msapplication-navbutton-color\" content=\"#222831\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\n\n    <style>\n        \/* Az alap body st\u00edlusokat a glob\u00e1lis CSS kezeli *\/\n        h1 {\n            text-align: center;\n        }\n\n        \/* Mem\u00f3riaj\u00e1t\u00e9k H1 c\u00edm elrejt\u00e9se *\/\n        .header h1 {\n            display: none;\n        }\n\n        \/* Mem\u00f3riaj\u00e1t\u00e9k specifikus st\u00edlusok *\/\n        .memoria-jatek {\n            display: grid;\n            gap: 10px;\n            max-width: 600px;\n            margin: 20px auto;\n        }\n\n        .kartya {\n            position: relative;\n            width: 100%;\n            aspect-ratio: 1 \/ 1;\n            perspective: 1000px;\n            cursor: pointer;\n        }\n\n        .kartya-belso {\n            position: relative;\n            width: 100%;\n            height: 100%;\n            transform-style: preserve-3d;\n            transition: transform 0.5s;\n        }\n\n        .kartya.forditott .kartya-belso {\n            transform: rotateY(180deg);\n        }\n\n        .kartya-elolap,\n        .kartya-hatlap {\n            position: absolute;\n            width: 100%;\n            height: 100%;\n            backface-visibility: hidden;\n            border-radius: 10px;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\n            overflow: hidden;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n        }\n\n        .kartya-hatlap {\n            background-color: var(--accent-color);\n        }\n\n        .kartya-elolap {\n            transform: rotateY(180deg);\n            background-color: #fff;\n        }\n\n        .kep {\n            width: 100%;\n            height: 100%;\n            object-fit: contain;\n            border-radius: 10px;\n        }\n\n        .kartya.talalat .kartya-belso {\n            box-shadow: 0 0 10px 3px rgba(76, 175, 80, 0.7);\n            border-radius: 10px;\n        }\n\n        .status-panel {\n            margin: 15px auto;\n            text-align: center;\n            font-size: 1.2rem;\n            font-weight: bold;\n            color: var(--text-color);\n            display: flex;\n            justify-content: center;\n            gap: 20px;\n            flex-wrap: wrap;\n        }\n\n        .eredmeny-panel {\n            position: fixed;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            background-color: var(--secondary-bg, #333);\n            color: var(--text-color, #f3f3f3);\n            padding: 30px 20px;\n            border-radius: 12px;\n            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);\n            text-align: center;\n            z-index: 100;\n            max-width: 90%;\n            width: 450px;\n            max-height: 80vh;\n            overflow-y: auto;\n        }\n        .eredmeny-panel h2 {\n            color: var(--accent-color);\n        }\n\n        .eredmeny-panel .btn svg {\n            width: 20px;\n            height: 20px;\n        }\n\n        .leaderboard-panel {\n            position: fixed;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            background-color: var(--secondary-bg, #333);\n            color: var(--text-color, #f3f3f3);\n            padding: 20px;\n            border-radius: 12px;\n            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);\n            z-index: 100;\n            max-width: 90%;\n            width: 500px;\n            max-height: 80vh;\n            overflow-y: auto;\n        }\n\n        .leaderboard-panel h3 {\n            color: var(--accent-color);\n            margin-bottom: 15px;\n            text-align: center;\n        }\n\n        .leaderboard-list {\n            list-style: none;\n            padding: 0;\n            margin: 0;\n        }\n\n        .leaderboard-item {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            padding: 8px 12px;\n            margin: 5px 0;\n            background-color: var(--primary-bg, #222);\n            border-radius: 8px;\n            border-left: 4px solid var(--accent-color);\n        }\n\n        .leaderboard-item.top-3 {\n            background-color: var(--highlight-color, #4CAF50);\n            color: #fff;\n        }\n\n        .leaderboard-rank {\n            font-weight: bold;\n            min-width: 30px;\n        }\n\n        .leaderboard-name {\n            flex: 1;\n            margin: 0 10px;\n            text-align: left;\n        }\n\n        .leaderboard-score {\n            font-weight: bold;\n            color: var(--accent-color);\n            text-align: right;\n        }\n\n        .leaderboard-item.top-3 .leaderboard-score {\n            color: #fff;\n        }\n\n        .name-input {\n            width: 100%;\n            padding: 10px;\n            margin: 10px 0;\n            border: 2px solid var(--accent-color);\n            border-radius: 8px;\n            background-color: var(--primary-bg, #222);\n            color: var(--text-color, #f3f3f3);\n            font-size: 1rem;\n        }\n\n        .name-input:focus {\n            outline: none;\n            border-color: var(--highlight-color);\n            box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);\n        }\n\n        .gombok {\n            display: flex;\n            justify-content: center;\n            gap: 15px;\n            margin-top: 20px;\n            flex-wrap: wrap;\n        }\n\n        .jatek-container {\n            max-width: 800px;\n            margin: 0 auto;\n            padding: 20px;\n        }\n\n        .header {\n            text-align: center;\n            margin-bottom: 20px;\n        }\n        .header p {\n            color: var(--text-color);\n            font-size: 1.1em;\n        }\n\n        .footer {\n            text-align: center;\n            margin-top: 30px;\n            font-size: 0.9rem;\n            color: var(--text-color);\n        }\n        .footer a svg {\n            width: 28px;\n            height: 28px;\n            vertical-align: middle;\n        }\n\n        .btn svg {\n            width: 20px;\n            height: 20px;\n        }\n\n        .nehezseg-valaszto {\n            display: flex;\n            justify-content: center;\n            margin-bottom: 20px;\n            gap: 10px;\n            flex-wrap: wrap;\n        }\n\n        .nehezseg-gomb.aktiv {\n            background: var(--highlight-color) !important;\n            color: #fff !important;\n            transform: scale(1.05);\n            box-shadow: 0 6px 18px rgba(0,0,0,0.3) !important;\n        }\n\n        .vezerlo-panel {\n            display: flex;\n            justify-content: center;\n            margin-bottom: 15px;\n            gap: 10px;\n            flex-wrap: wrap;\n        }\n\n        .teljes-kepernyo-ikon {\n            width: 18px;\n            height: 18px;\n        }\n\n        .loading {\n            text-align: center;\n            color: var(--text-color);\n            padding: 20px;\n        }\n\n        .error {\n            color: #ff6b6b;\n            text-align: center;\n            padding: 10px;\n            background-color: rgba(255, 107, 107, 0.1);\n            border-radius: 8px;\n            margin: 10px 0;\n        }\n\n        .validation-error {\n            color: #ff6b6b;\n            font-size: 0.9em;\n            margin-top: 5px;\n            padding: 5px;\n            background-color: rgba(255, 107, 107, 0.1);\n            border-radius: 4px;\n            border-left: 3px solid #ff6b6b;\n        }\n\n        .report-btn {\n            background: none;\n            border: none;\n            cursor: pointer;\n            font-size: 16px;\n            margin-left: 10px;\n            color: var(--text-color);\n        }\n\n        .report-btn:hover {\n            opacity: 0.7;\n        }\n\n        .moderation-notice {\n            margin-top: 15px;\n            padding: 10px;\n            background-color: rgba(255, 193, 7, 0.1);\n            border-radius: 8px;\n            border-left: 3px solid #ffc107;\n        }\n\n        .moderation-notice p {\n            margin: 0;\n            font-size: 0.9em;\n            color: var(--text-color);\n        }\n\n        @media (max-width: 600px) {\n            .memoria-jatek {\n                gap: 8px;\n            }\n            .jatek-container {\n                padding: 10px;\n            }\n            .eredmeny-panel, .leaderboard-panel {\n                padding: 20px 15px;\n                width: auto;\n            }\n            .nehezseg-valaszto .btn {\n                padding: 8px 10px;\n                font-size: 0.85em;\n            }\n            .footer a svg {\n                width: 24px;\n                height: 24px;\n            }\n            .btn svg {\n                width: 18px;\n                height: 18px;\n            }\n            .status-panel {\n                flex-direction: column;\n                gap: 10px;\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"jatek-container\">\n        <div class=\"header\">\n            <h1>Mem\u00f3riaj\u00e1t\u00e9k<\/h1>\n            <p>Ford\u00edtsd fel a k\u00e1rty\u00e1kat \u00e9s tal\u00e1ld meg a p\u00e1rokat!<\/p>\n\n            <div class=\"nehezseg-valaszto\">\n                <button class=\"nehezseg-gomb btn\" data-parok=\"3\">K\u00f6nny\u0171 (3 p\u00e1r)<\/button>\n                <button class=\"nehezseg-gomb btn aktiv\" data-parok=\"4\">K\u00f6zepes (4 p\u00e1r)<\/button>\n                <button class=\"nehezseg-gomb btn\" data-parok=\"5\">Neh\u00e9z (5 p\u00e1r)<\/button>\n                <button class=\"nehezseg-gomb btn\" data-parok=\"6\">Extra (6 p\u00e1r)<\/button>\n                <button class=\"nehezseg-gomb btn\" data-parok=\"7\">Giga (7 p\u00e1r)<\/button>\n            <\/div>\n\n            <div class=\"vezerlo-panel\">\n                <button class=\"teljes-kepernyo-gomb btn\" id=\"teljes-kepernyo-gomb\">\n                    <svg class=\"teljes-kepernyo-ikon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                        <path d=\"M3 3H9V5H5V9H3V3Z\"\/>\n                        <path d=\"M3 21H9V19H5V15H3V21Z\"\/>\n                        <path d=\"M21 3H15V5H19V9H21V3Z\"\/>\n                        <path d=\"M21 21H15V19H19V15H21V21Z\"\/>\n                    <\/svg>\n                    Teljes k\u00e9perny\u0151\n                <\/button>\n                <button class=\"leaderboard-gomb btn\" id=\"leaderboard-gomb\">\n                    <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                        <path d=\"M7 14H5v5h2v-5zm3-7H8v12h2V7zm3 3h-2v9h2v-9zm3-6h-2v15h2V4z\"\/>\n                    <\/svg>\n                    Ranglista\n                <\/button>\n            <\/div>\n        <\/div>\n\n        <div id=\"jatek-container\">\n        <\/div>\n        <div class=\"status-panel\">\n            <div>L\u00e9p\u00e9sek: <span id=\"lepes-szam\">0<\/span><\/div>\n            <div>Id\u0151: <span id=\"ido-szam\">00:00<\/span><\/div>\n        <\/div>\n\n        <div class=\"footer\">\n            <a href=\"https:\/\/book.filemondr.hu\/index.php\/\" aria-label=\"F\u0151oldal\">\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8h5z\"\/>\n                  <path d=\"M0 0h24v24H0z\" fill=\"none\"\/>\n                <\/svg>\n            <\/a>\n        <\/div>\n    <\/div>\n\n    <!-- Firebase Scripts -->\n    <script type=\"module\">\n        import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-app.js\";\n        import { getFirestore, collection, addDoc, query, orderBy, limit, getDocs } from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-firestore.js\";\n        import { getAnalytics } from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-analytics.js\";\n\n        const firebaseConfig = {\n            apiKey: \"AIzaSyDGrQ8PJCvYynEi1Vq-QtPgljUvGUPNba0\",\n            authDomain: \"par-perc-pihi-8ddfc.firebaseapp.com\",\n            projectId: \"par-perc-pihi-8ddfc\",\n            storageBucket: \"par-perc-pihi-8ddfc.firebasestorage.app\",\n            messagingSenderId: \"169472205893\",\n            appId: \"1:169472205893:web:a0f955e2b1662e5f85af2c\",\n            measurementId: \"G-RBWKR6YYQF\"\n        };\n\n        const app = initializeApp(firebaseConfig);\n        const db = getFirestore(app);\n        const analytics = getAnalytics(app);\n\n        \/\/ Make Firebase functions globally available\n        window.firebaseDB = db;\n        window.firebaseUtils = {\n            collection,\n            addDoc,\n            query,\n            orderBy,\n            limit,\n            getDocs\n        };\n\n        \/\/ Firebase inicializ\u00e1l\u00e1s ut\u00e1n jelezz\u00fck, hogy k\u00e9sz\n        window.firebaseReady = true;\n        console.log('Firebase initialized successfully');\n    <\/script>\n\n    <!-- Moder\u00e1l\u00e1si rendszer -->\n    <script>\n        \/\/ V\u00e1rjuk meg a Firebase inicializ\u00e1l\u00e1s\u00e1t\n        function waitForFirebase() {\n            return new Promise((resolve) => {\n                if (window.firebaseReady) {\n                    resolve();\n                } else {\n                    const checkFirebase = setInterval(() => {\n                        if (window.firebaseReady) {\n                            clearInterval(checkFirebase);\n                            resolve();\n                        }\n                    }, 100);\n                }\n            });\n        }\n\n        class ModerationSystem {\n            constructor() {\n                this.bannedWords = [\n                    \/\/ Magyar tr\u00e1g\u00e1r szavak\n                    'fasz', 'szar', 'kurva', 'pina', 'pics\u00e1', 'geci', 'bazmeg', 'bassza', 'szopj',\n                    'buzi', 'ribanc', 'cafka', 'picsa', 'fing', 'szarik', 'szaros', 'rohadt',\n                    'k\u00f6cs\u00f6g', 'seggfej', 'faszfej', 'szarh\u00e1zi', 'pics\u00e1ba', 'francba',\n                    \/\/ Angol tr\u00e1g\u00e1r szavak\n                    'fuck', 'shit', 'bitch', 'damn', 'hell', 'ass', 'crap', 'piss', 'cock',\n                    'dick', 'pussy', 'whore', 'slut', 'bastard', 'motherfucker', 'asshole', 'suck', 'sucks',\n                    \/\/ Egy\u00e9b probl\u00e9m\u00e1s szavak\n                    'hitler', 'nazi', 'fasiszta', 'kommunista'\n                ];\n                this.moderationCollectionName = 'moderation-queue';\n            }\n\n            containsProfanity(text) {\n                if (!text || typeof text !== 'string') return false;\n                \n                const normalizedText = text.toLowerCase()\n                    .replace(\/[\u00e1\u00e0\u00e2\u00e4]\/g, 'a')\n                    .replace(\/[\u00e9\u00e8\u00ea\u00eb]\/g, 'e')\n                    .replace(\/[\u00ed\u00ec\u00ee\u00ef]\/g, 'i')\n                    .replace(\/[\u00f3\u00f2\u00f4\u00f6]\/g, 'o')\n                    .replace(\/[\u00fa\u00f9\u00fb\u00fc]\/g, 'u')\n                    .replace(\/[\u0151]\/g, 'o')\n                    .replace(\/[\u0171]\/g, 'u')\n                    .replace(\/[^a-z0-9]\/g, '');\n\n                return this.bannedWords.some(word => {\n                    const normalizedWord = word.toLowerCase().replace(\/[^a-z0-9]\/g, '');\n                    if (normalizedWord.length >= 3) {\n                        return normalizedText.includes(normalizedWord);\n                    }\n                    return normalizedText === normalizedWord;\n                });\n            }\n\n            validatePlayerName(name) {\n                if (!name) {\n                    return { valid: false, message: 'K\u00e9rlek add meg a neved!' };\n                }\n\n                const trimmedName = name.trim();\n                \n                if (trimmedName.length === 0) {\n                    return { valid: false, message: 'K\u00e9rlek add meg a neved!' };\n                }\n                \n                if (trimmedName.length < 2) {\n                    return { valid: false, message: 'A n\u00e9v legal\u00e1bb 2 karakter hossz\u00fa legyen!' };\n                }\n                \n                if (trimmedName.length > 20) {\n                    return { valid: false, message: 'A n\u00e9v maximum 20 karakter hossz\u00fa lehet!' };\n                }\n                \n                const allowedCharsRegex = \/^[a-zA-Z\u00e1\u00e9\u00ed\u00f3\u00f6\u0151\u00fa\u00fc\u0171\u00c1\u00c9\u00cd\u00d3\u00d6\u0150\u00da\u00dc\u01700-9\\s\\-_.]+$\/;\n                if (!allowedCharsRegex.test(trimmedName)) {\n                    return { valid: false, message: 'A n\u00e9v csak bet\u0171ket, sz\u00e1mokat \u00e9s alapvet\u0151 \u00edr\u00e1sjeleket tartalmazhat!' };\n                }\n                \n                if (this.containsProfanity(trimmedName)) {\n                    return { valid: false, message: 'K\u00e9rlek v\u00e1lassz egy megfelel\u0151 nevet!' };\n                }\n                \n                return { valid: true };\n            }\n\n            async reportEntry(entryId, gameType, reason = 'inappropriate_name') {\n                try {\n                    if (!window.firebaseDB || !window.firebaseUtils) {\n                        console.error('Firebase not available for reporting');\n                        return { success: false, error: 'Firebase not available' };\n                    }\n\n                    await window.firebaseUtils.addDoc(\n                        window.firebaseUtils.collection(window.firebaseDB, this.moderationCollectionName),\n                        {\n                            entryId: entryId,\n                            gameType: gameType,\n                            reason: reason,\n                            timestamp: new Date()\n                        }\n                    );\n                    return { success: true };\n                } catch (error) {\n                    console.error(\"Error reporting entry:\", error);\n                    return { success: false, error: error.message };\n                }\n            }\n\n            addReportButton(entry, gameType) {\n                return `<button class=\"report-btn\" onclick=\"reportEntry('${entry.id}', '${gameType}')\" title=\"Jelent\u00e9s\">\u26a0\ufe0f<\/button>`;\n            }\n\n            addValidationError(parentElement, message) {\n                if (!parentElement) return;\n                \n                this.removeValidationError(parentElement);\n                \n                const errorDiv = document.createElement('div');\n                errorDiv.className = 'validation-error';\n                errorDiv.textContent = message;\n                parentElement.appendChild(errorDiv);\n            }\n\n            removeValidationError(parentElement) {\n                if (!parentElement) return;\n                \n                const errorDiv = parentElement.querySelector('.validation-error');\n                if (errorDiv) {\n                    errorDiv.remove();\n                }\n            }\n        }\n\n        \/\/ Glob\u00e1lis v\u00e1ltoz\u00f3k inicializ\u00e1l\u00e1sa Firebase bet\u00f6lt\u00e9se ut\u00e1n\n        waitForFirebase().then(() => {\n            window.moderationSystem = new ModerationSystem();\n            \n            window.reportEntry = async function(entryId, gameType) {\n                if (confirm('Biztosan jelenteni szeretn\u00e9d ezt a bejegyz\u00e9st?')) {\n                    const result = await window.moderationSystem.reportEntry(entryId, gameType);\n                    if (result.success) {\n                        alert('K\u00f6sz\u00f6nj\u00fck a jelent\u00e9st! Moder\u00e1toraink hamarosan \u00e1tn\u00e9zik.');\n                    } else {\n                        alert('Hiba t\u00f6rt\u00e9nt a jelent\u00e9s sor\u00e1n: ' + (result.error || 'Ismeretlen hiba'));\n                    }\n                }\n            };\n            \n            console.log('Moderation system loaded successfully');\n        });\n    <\/script>\n\n    <script>\n        const kep_max = 60;\n        const HANG_FORDIT = \"https:\/\/book.filemondr.hu\/hangok\/kartyafordit.mp3\";\n        const HANG_EGYEZES = \"https:\/\/book.filemondr.hu\/hangok\/egyezes.mp3\";\n        const HANG_SIKER = \"https:\/\/book.filemondr.hu\/hangok\/siker.mp3\";\n        const HANG_UJJATEK = \"https:\/\/book.filemondr.hu\/hangok\/ujjatek.mp3\";\n        const KEP_PREFIX = \"https:\/\/book.filemondr.hu\/kepek\/\";\n\n        \/\/ Leaderboard Manager\n        class LeaderboardManager {\n            constructor() {\n                this.difficultyNames = {\n                    3: 'k\u00f6nny\u0171',\n                    4: 'k\u00f6zepes', \n                    5: 'neh\u00e9z',\n                    6: 'extra',\n                    7: 'giga'\n                };\n            }\n\n            calculateScore(moves, timeInSeconds, pairs) {\n                \/\/ Lower score is better (like golf scoring)\n                const moveScore = moves * 10;\n                const timeScore = timeInSeconds;\n                const difficultyMultiplier = 1 - (pairs - 3) * 0.05;\n                \n                return Math.round((moveScore + timeScore) * difficultyMultiplier);\n            }\n\n            async saveScore(playerName, moves, timeInSeconds, pairs) {\n                try {\n                    \/\/ V\u00e1rjuk meg a Firebase \u00e9s moder\u00e1l\u00e1si rendszer inicializ\u00e1l\u00e1s\u00e1t\n                    if (!window.firebaseDB || !window.moderationSystem) {\n                        console.error('Firebase or moderation system not ready');\n                        return { success: false, error: 'Rendszer m\u00e9g nem \u00e1ll k\u00e9szen' };\n                    }\n\n                    \/\/ Valid\u00e1l\u00e1s a k\u00f6z\u00f6s moder\u00e1l\u00e1si rendszerrel\n                    const validation = window.moderationSystem.validatePlayerName(playerName);\n                    if (!validation.valid) {\n                        return { success: false, error: validation.message };\n                    }\n\n                    const score = this.calculateScore(moves, timeInSeconds, pairs);\n                    const collectionName = `memoria-leaderboard-${pairs}`;\n                    \n                    console.log('Saving score:', { playerName, moves, timeInSeconds, pairs, score });\n                    \n                    const docRef = await window.firebaseUtils.addDoc(\n                        window.firebaseUtils.collection(window.firebaseDB, collectionName),\n                        {\n                            playerName: playerName.trim(),\n                            moves: moves,\n                            timeInSeconds: timeInSeconds,\n                            score: score,\n                            pairs: pairs,\n                            timestamp: new Date(),\n                            gameType: 'memoria',\n                            moderated: false,\n                            reportCount: 0\n                        }\n                    );\n                    \n                    console.log('Score saved successfully:', docRef.id);\n                    return { success: true, score: score };\n                } catch (error) {\n                    console.error(\"Error saving score:\", error);\n                    return { success: false, error: error.message };\n                }\n            }\n\n            async getLeaderboard(pairs, limitCount = 10) {\n                try {\n                    const collectionName = `memoria-leaderboard-${pairs}`;\n                    const q = window.firebaseUtils.query(\n                        window.firebaseUtils.collection(window.firebaseDB, collectionName),\n                        window.firebaseUtils.orderBy(\"score\", \"asc\"),\n                        window.firebaseUtils.limit(limitCount)\n                    );\n                    \n                    const querySnapshot = await window.firebaseUtils.getDocs(q);\n                    const leaderboard = [];\n                    \n                    querySnapshot.forEach((doc) => {\n                        leaderboard.push({\n                            id: doc.id,\n                            ...doc.data()\n                        });\n                    });\n                    \n                    return leaderboard;\n                } catch (error) {\n                    console.error(\"Error getting leaderboard:\", error);\n                    return [];\n                }\n            }\n\n            formatTime(seconds) {\n                const mins = Math.floor(seconds \/ 60);\n                const secs = seconds % 60;\n                return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n            }\n\n            async showLeaderboard(pairs) {\n                const existingPanel = document.querySelector('.leaderboard-panel');\n                if (existingPanel) {\n                    existingPanel.remove();\n                    return;\n                }\n\n                const panel = document.createElement('div');\n                panel.className = 'leaderboard-panel';\n                panel.innerHTML = `\n                    <h3>Ranglista - ${this.difficultyNames[pairs]} (${pairs} p\u00e1r)<\/h3>\n                    <div class=\"loading\">Bet\u00f6lt\u00e9s...<\/div>\n                    <div class=\"gombok\">\n                        <button id=\"close-leaderboard\" class=\"btn\">Bez\u00e1r\u00e1s<\/button>\n                    <\/div>\n                `;\n\n                document.body.appendChild(panel);\n\n                try {\n                    const leaderboard = await this.getLeaderboard(pairs);\n                    const loadingDiv = panel.querySelector('.loading');\n                    \n                    if (leaderboard.length === 0) {\n                        loadingDiv.innerHTML = '<p>M\u00e9g nincsenek eredm\u00e9nyek ezen a szinten.<\/p>';\n                    } else {\n                        const listHTML = leaderboard.map((entry, index) => {\n                            const rank = index + 1;\n                            const topClass = rank <= 3 ? 'top-3' : '';\n                            return `\n                                <li class=\"leaderboard-item ${topClass}\">\n                                    <span class=\"leaderboard-rank\">${rank}.<\/span>\n                                    <span class=\"leaderboard-name\">${entry.playerName}<\/span>\n                                    <span class=\"leaderboard-score\">\n                                        ${entry.score} pont<br>\n                                        <small>${entry.moves} l\u00e9p\u00e9s, ${this.formatTime(entry.timeInSeconds)}<\/small>\n                                    <\/span>\n                                    ${window.moderationSystem ? window.moderationSystem.addReportButton(entry, 'memoria') : ''}\n                                <\/li>\n                            `;\n                        }).join('');\n                        \n                        loadingDiv.innerHTML = `\n                            <ul class=\"leaderboard-list\">${listHTML}<\/ul>\n                            <div class=\"moderation-notice\">\n                                <p>Nem megfelel\u0151 tartalom eset\u00e9n haszn\u00e1ld a \u26a0\ufe0f gombot!<\/p>\n                            <\/div>\n                        `;\n                    }\n                } catch (error) {\n                    const loadingDiv = panel.querySelector('.loading');\n                    loadingDiv.innerHTML = '<div class=\"error\">Hiba t\u00f6rt\u00e9nt a ranglista bet\u00f6lt\u00e9sekor.<\/div>';\n                }\n\n                panel.querySelector('#close-leaderboard').addEventListener('click', () => {\n                    panel.remove();\n                });\n\n                \/\/ Close on background click\n                panel.addEventListener('click', (e) => {\n                    if (e.target === panel) {\n                        panel.remove();\n                    }\n                });\n            }\n        }\n\n        class MemoriaJatek {\n            constructor(containerId, kepekSzama = 4) {\n                this.gameBoardContainer = document.getElementById(containerId);\n                this.statusPanelContainer = document.querySelector('.jatek-container');\n                this.lepesSzamElem = document.getElementById('lepes-szam');\n                this.idoSzamElem = document.getElementById('ido-szam');\n                this.kepekSzama = Math.min(kepekSzama, kep_max);\n                this.kartyak = [];\n                this.forditottKartyak = [];\n                this.talalatok = 0;\n                this.lepesSzam = 0;\n                this.jatekFut = false;\n                this.startTime = null;\n                this.gameTime = 0;\n                this.timerInterval = null;\n                this.leaderboardManager = new LeaderboardManager();\n                this.hangok = {\n                    fordit: new Audio(HANG_FORDIT),\n                    egyezes: new Audio(HANG_EGYEZES),\n                    siker: new Audio(HANG_SIKER),\n                    ujjatek: new Audio(HANG_UJJATEK)\n                };\n                this.init();\n            }\n\n            init() {\n                this.gameBoardContainer.innerHTML = '';\n                this.kartyak = [];\n                this.forditottKartyak = [];\n                this.talalatok = 0;\n                this.lepesSzam = 0;\n                this.gameTime = 0;\n                this.jatekFut = true;\n                this.startTime = Date.now();\n\n                if (this.lepesSzamElem) {\n                    this.lepesSzamElem.textContent = this.lepesSzam;\n                }\n                if (this.idoSzamElem) {\n                    this.idoSzamElem.textContent = '00:00';\n                }\n\n                \/\/ Start timer\n                this.startTimer();\n\n                const jatekTer = document.createElement('div');\n                jatekTer.className = 'memoria-jatek';\n                this.gameBoardContainer.appendChild(jatekTer);\n\n                this.generalKartyak(jatekTer);\n                this.setGridColumns(jatekTer);\n                window.addEventListener('resize', () => this.setGridColumns(jatekTer));\n            }\n\n            startTimer() {\n                if (this.timerInterval) {\n                    clearInterval(this.timerInterval);\n                }\n                \n                this.timerInterval = setInterval(() => {\n                    if (this.jatekFut) {\n                        this.gameTime = Math.floor((Date.now() - this.startTime) \/ 1000);\n                        if (this.idoSzamElem) {\n                            this.idoSzamElem.textContent = this.leaderboardManager.formatTime(this.gameTime);\n                        }\n                    }\n                }, 1000);\n            }\n\n            stopTimer() {\n                if (this.timerInterval) {\n                    clearInterval(this.timerInterval);\n                    this.timerInterval = null;\n                }\n            }\n\n            setGridColumns(jatekTer) {\n                const parokSzama = this.kepekSzama;\n                let columns = 4;\n\n                if (window.matchMedia(\"(max-width: 500px)\").matches) {\n                    if (parokSzama <= 3) columns = 2;\n                    else if (parokSzama <= 6) columns = 3;\n                    else columns = 4;\n                } else {\n                    if (parokSzama <= 3) columns = 3;\n                    else if (parokSzama <= 5) columns = 4;\n                    else if (parokSzama <= 7) columns = 4;\n                }\n                jatekTer.style.gridTemplateColumns = `repeat(${columns}, 1fr)`;\n            }\n\n            generalKartyak(jatekTer) {\n                const osszesKep = kep_max;\n                const lehetsegesKepIndexek = Array.from({ length: osszesKep }, (_, i) => i + 1);\n                lehetsegesKepIndexek.sort(() => Math.random() - 0.5);\n                const kivalasztottKepIndexek = lehetsegesKepIndexek.slice(0, this.kepekSzama);\n                let parositottKepek = [...kivalasztottKepIndexek, ...kivalasztottKepIndexek];\n                parositottKepek.sort(() => Math.random() - 0.5);\n\n                parositottKepek.forEach((kepSzam, index) => {\n                    const kartya = document.createElement('div');\n                    kartya.className = 'kartya';\n                    kartya.dataset.index = index;\n                    kartya.dataset.kep = kepSzam;\n\n                    const kartyaBelso = document.createElement('div');\n                    kartyaBelso.className = 'kartya-belso';\n\n                    const kartyaHatlap = document.createElement('div');\n                    kartyaHatlap.className = 'kartya-hatlap';\n\n                    const kartyaElolap = document.createElement('div');\n                    kartyaElolap.className = 'kartya-elolap';\n\n                    const kep = document.createElement('img');\n                    kep.className = 'kep';\n                    kep.src = `${KEP_PREFIX}${kepSzam.toString().padStart(2, '0')}.png`;\n                    kep.alt = `K\u00e1rtya ${kepSzam}`;\n                    kep.loading = 'lazy';\n\n                    kartyaElolap.appendChild(kep);\n                    kartyaBelso.appendChild(kartyaHatlap);\n                    kartyaBelso.appendChild(kartyaElolap);\n                    kartya.appendChild(kartyaBelso);\n\n                    kartya.addEventListener('click', () => this.kartyaKattintas(kartya));\n                    jatekTer.appendChild(kartya);\n                    this.kartyak.push(kartya);\n                });\n            }\n\n            kartyaKattintas(kartya) {\n                if (!this.jatekFut || this.forditottKartyak.length >= 2 || kartya.classList.contains('forditott') || kartya.classList.contains('talalat')) {\n                    return;\n                }\n                kartya.classList.add('forditott');\n                setTimeout(() => { this.hangok.fordit.play().catch(e => console.warn(\"Hanglej\u00e1tsz\u00e1si hiba (ford\u00edt):\", e)); }, 50);\n                this.forditottKartyak.push(kartya);\n\n                if (this.forditottKartyak.length === 2) {\n                    this.lepesSzam++;\n                    if (this.lepesSzamElem) this.lepesSzamElem.textContent = this.lepesSzam;\n                    setTimeout(() => this.ellenorizParokat(), 800);\n                }\n            }\n\n            ellenorizParokat() {\n                const [elso, masodik] = this.forditottKartyak;\n                if (elso.dataset.kep === masodik.dataset.kep) {\n                    elso.classList.add('talalat');\n                    masodik.classList.add('talalat');\n                    this.hangok.egyezes.play().catch(e => console.warn(\"Hanglej\u00e1tsz\u00e1si hiba (egyez\u00e9s):\", e));\n                    this.talalatok++;\n                    if (this.talalatok === this.kepekSzama) {\n                        this.jatekVege();\n                    }\n                } else {\n                    setTimeout(() => {\n                        elso.classList.remove('forditott');\n                        masodik.classList.remove('forditott');\n                    }, 500);\n                }\n                this.forditottKartyak = [];\n            }\n\n            async jatekVege() {\n                this.jatekFut = false;\n                this.stopTimer();\n                this.hangok.siker.play().catch(e => console.warn(\"Hanglej\u00e1tsz\u00e1si hiba (siker):\", e));\n\n                const regiPanel = this.statusPanelContainer.querySelector('.eredmeny-panel');\n                if (regiPanel) regiPanel.remove();\n\n                const score = this.leaderboardManager.calculateScore(this.lepesSzam, this.gameTime, this.kepekSzama);\n                const timeFormatted = this.leaderboardManager.formatTime(this.gameTime);\n\n                const eredmenyPanel = document.createElement('div');\n                eredmenyPanel.className = 'eredmeny-panel';\n                eredmenyPanel.innerHTML = `\n                    <h2>Gratul\u00e1lok!<\/h2>\n                    <p>Sikeresen megtal\u00e1ltad az \u00f6sszes p\u00e1rt!<\/p>\n                    <div style=\"margin: 15px 0;\">\n                        <strong>L\u00e9p\u00e9sek:<\/strong> ${this.lepesSzam}<br>\n                        <strong>Id\u0151:<\/strong> ${timeFormatted}<br>\n                        <strong>Pontsz\u00e1m:<\/strong> ${score}\n                    <\/div>\n                    <div id=\"name-input-container\">\n                        <input type=\"text\" id=\"player-name\" class=\"name-input\" placeholder=\"Add meg a neved a ranglist\u00e1hoz\" maxlength=\"20\">\n                    <\/div>\n                    <div class=\"gombok\">\n                        <button id=\"save-score\" class=\"btn\">Ment\u00e9s ranglist\u00e1ra<\/button>\n                        <button id=\"uj-jatek\" class=\"btn\">\u00daj j\u00e1t\u00e9k<\/button>\n                        <button id=\"show-leaderboard\" class=\"btn\">Ranglista<\/button>\n                        <a href=\"https:\/\/book.filemondr.hu\/index.php\/\" class=\"btn\" aria-label=\"F\u0151oldal\">\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                              <path d=\"M0 0h24v24H0z\" fill=\"none\"\/>\n                              <path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"\/>\n                            <\/svg>\n                        <\/a>\n                    <\/div>\n                `;\n                this.statusPanelContainer.appendChild(eredmenyPanel);\n\n                const playerNameInput = document.getElementById('player-name');\n                const saveScoreBtn = document.getElementById('save-score');\n                const ujJatekBtn = document.getElementById('uj-jatek');\n                const showLeaderboardBtn = document.getElementById('show-leaderboard');\n                const nameInputContainer = document.getElementById('name-input-container');\n\n                \/\/ Auto-focus on name input\n                setTimeout(() => playerNameInput.focus(), 100);\n\n                \/\/ Save score functionality\n                saveScoreBtn.addEventListener('click', async () => {\n                    const playerName = playerNameInput.value.trim();\n                    \n                    \/\/ Valid\u00e1l\u00e1s a k\u00f6z\u00f6s moder\u00e1l\u00e1si rendszerrel\n                    if (!window.moderationSystem) {\n                        alert('Moder\u00e1l\u00e1si rendszer m\u00e9g nem \u00e1ll k\u00e9szen. Pr\u00f3b\u00e1ld \u00fajra!');\n                        return;\n                    }\n\n                    const validation = window.moderationSystem.validatePlayerName(playerName);\n                    if (!validation.valid) {\n                        window.moderationSystem.removeValidationError(nameInputContainer);\n                        window.moderationSystem.addValidationError(nameInputContainer, validation.message);\n                        playerNameInput.focus();\n                        return;\n                    }\n\n                    \/\/ Hiba\u00fczenet elt\u00e1vol\u00edt\u00e1sa, ha volt\n                    window.moderationSystem.removeValidationError(nameInputContainer);\n\n                    saveScoreBtn.disabled = true;\n                    saveScoreBtn.textContent = 'Ment\u00e9s...';\n\n                    try {\n                        const result = await this.leaderboardManager.saveScore(\n                            playerName, \n                            this.lepesSzam, \n                            this.gameTime, \n                            this.kepekSzama\n                        );\n\n                        if (result.success) {\n                            saveScoreBtn.textContent = 'Mentve!';\n                            saveScoreBtn.style.backgroundColor = '#4CAF50';\n                            playerNameInput.disabled = true;\n                        } else {\n                            throw new Error(result.error);\n                        }\n                    } catch (error) {\n                        console.error('Error saving score:', error);\n                        alert('Hiba t\u00f6rt\u00e9nt a ment\u00e9s sor\u00e1n: ' + error.message);\n                        saveScoreBtn.disabled = false;\n                        saveScoreBtn.textContent = 'Ment\u00e9s ranglist\u00e1ra';\n                    }\n                });\n\n                \/\/ Enter key to save score\n                playerNameInput.addEventListener('keypress', (e) => {\n                    if (e.key === 'Enter' && !saveScoreBtn.disabled) {\n                        saveScoreBtn.click();\n                    }\n                });\n\n                \/\/ Show leaderboard\n                showLeaderboardBtn.addEventListener('click', () => {\n                    this.leaderboardManager.showLeaderboard(this.kepekSzama);\n                });\n\n                \/\/ New game\n                ujJatekBtn.addEventListener('click', () => {\n                    this.hangok.ujjatek.play().catch(e => console.warn(\"Hanglej\u00e1tsz\u00e1si hiba (\u00faj j\u00e1t\u00e9k):\", e));\n                    eredmenyPanel.remove();\n                    const aktivGomb = document.querySelector('.nehezseg-gomb.aktiv');\n                    let aktualisNehezseg = 4;\n                    if (aktivGomb) {\n                        aktualisNehezseg = parseInt(aktivGomb.dataset.parok);\n                    }\n                    this.kepekSzama = aktualisNehezseg;\n                    this.init();\n                });\n            }\n        }\n\n        document.addEventListener('DOMContentLoaded', function() {\n            let aktualisNehezseg = 4;\n            let memoriaJatekPeldany = new MemoriaJatek('jatek-container', aktualisNehezseg);\n            const leaderboardManager = new LeaderboardManager();\n\n            const nehezsegGombok = document.querySelectorAll('.nehezseg-gomb');\n            nehezsegGombok.forEach(gomb => {\n                gomb.addEventListener('click', function() {\n                    nehezsegGombok.forEach(g => g.classList.remove('aktiv'));\n                    this.classList.add('aktiv');\n                    aktualisNehezseg = parseInt(this.dataset.parok);\n                    const regiPanel = document.querySelector('.eredmeny-panel');\n                    if (regiPanel) regiPanel.remove();\n                    memoriaJatekPeldany = new MemoriaJatek('jatek-container', aktualisNehezseg);\n                });\n            });\n\n            \/\/ Leaderboard button\n            const leaderboardGomb = document.getElementById('leaderboard-gomb');\n            leaderboardGomb.addEventListener('click', () => {\n                leaderboardManager.showLeaderboard(aktualisNehezseg);\n            });\n\n            \/\/ Fullscreen functionality\n            const teljesKepernyoGomb = document.getElementById('teljes-kepernyo-gomb');\n            const teljesKepernyoIkonSVG = {\n                belepes: `\n                    <svg class=\"teljes-kepernyo-ikon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                        <path d=\"M3 3H9V5H5V9H3V3Z\"\/> <path d=\"M3 21H9V19H5V15H3V21Z\"\/>\n                        <path d=\"M21 3H15V5H19V9H21V3Z\"\/> <path d=\"M21 21H15V19H19V15H21V21Z\"\/>\n                    <\/svg> Teljes k\u00e9perny\u0151`,\n                kilepes: `\n                    <svg class=\"teljes-kepernyo-ikon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                        <path d=\"M5 15H3V21H9V19H5V15Z\"\/> <path d=\"M5 5H3V9H9V3H5V5Z\"\/>\n                        <path d=\"M19 15H21V21H15V19H19V15Z\"\/> <path d=\"M19 5H21V9H15V3H19V5Z\"\/>\n                    <\/svg> Kil\u00e9p\u00e9s`\n            };\n\n            function frissitTeljesKepernyoGomb() {\n                if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) {\n                    teljesKepernyoGomb.innerHTML = teljesKepernyoIkonSVG.belepes;\n                } else {\n                    teljesKepernyoGomb.innerHTML = teljesKepernyoIkonSVG.kilepes;\n                }\n            }\n            frissitTeljesKepernyoGomb();\n\n            teljesKepernyoGomb.addEventListener('click', function() {\n                if (!document.fullscreenElement) {\n                    if (document.documentElement.requestFullscreen) document.documentElement.requestFullscreen();\n                    else if (document.documentElement.webkitRequestFullscreen) document.documentElement.webkitRequestFullscreen();\n                    else if (document.documentElement.msRequestFullscreen) document.documentElement.msRequestFullscreen();\n                } else {\n                    if (document.exitFullscreen) document.exitFullscreen();\n                    else if (document.webkitExitFullscreen) document.webkitExitFullscreen();\n                    else if (document.msExitFullscreen) document.msExitFullscreen();\n                }\n            });\n\n            document.addEventListener('fullscreenchange', frissitTeljesKepernyoGomb);\n            document.addEventListener('webkitfullscreenchange', frissitTeljesKepernyoGomb);\n            document.addEventListener('mozfullscreenchange', frissitTeljesKepernyoGomb);\n            document.addEventListener('MSFullscreenChange', frissitTeljesKepernyoGomb);\n        });\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Mem\u00f3riaj\u00e1t\u00e9k &#8211; Filemondr Mesek\u00f6nyvek Mem\u00f3riaj\u00e1t\u00e9k Ford\u00edtsd fel a k\u00e1rty\u00e1kat \u00e9s tal\u00e1ld meg a p\u00e1rokat! K\u00f6nny\u0171 (3 p\u00e1r) K\u00f6zepes (4 p\u00e1r) Neh\u00e9z (5 p\u00e1r) Extra (6 p\u00e1r) Giga (7 p\u00e1r) Teljes k\u00e9perny\u0151 Ranglista L\u00e9p\u00e9sek: 0 Id\u0151: 00:00<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-206","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/pages\/206","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/comments?post=206"}],"version-history":[{"count":42,"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/pages\/206\/revisions"}],"predecessor-version":[{"id":618,"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/pages\/206\/revisions\/618"}],"wp:attachment":[{"href":"https:\/\/book.filemondr.hu\/index.php\/wp-json\/wp\/v2\/media?parent=206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}