{"id":7851,"date":"2026-01-25T13:45:18","date_gmt":"2026-01-25T06:45:18","guid":{"rendered":"https:\/\/tokuteigino.vn\/?page_id=7851"},"modified":"2026-02-25T02:46:15","modified_gmt":"2026-02-24T19:46:15","slug":"de-thi-nong-nghiep-gino2","status":"publish","type":"page","link":"https:\/\/tokuteigino.vn\/vi\/de-thi-nong-nghiep-gino2\/","title":{"rendered":"\u0110\u1ec1 thi n\u00f4ng nghi\u1ec7p gino2"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"vi\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Danh s\u00e1ch \u0111\u1ec1 thi n\u00f4ng nghi\u1ec7p tokutei gino2<\/title>\n    <style>\n          \/* Th\u00eam c\u00e1c style ch\u1ed1ng sao ch\u00e9p *\/\n          body {\n            -webkit-user-select: none; \/* Chrome\/Safari *\/\n            -moz-user-select: none; \/* Firefox *\/\n            -ms-user-select: none; \/* IE10+ *\/\n            user-select: none;\n            -webkit-touch-callout: none; \/* iOS Safari *\/\n        }\n        \n        \/* \u1ea8n c\u00e1c ph\u1ea7n t\u1eed khi in *\/\n        @media print {\n            body * {\n                visibility: hidden;\n            }\n        }\n        .test-container * {\n            box-sizing: border-box;\n            margin: 0;\n            padding: 0;\n            font-family: 'Roboto', Arial, sans-serif;\n        }\n        \n        .test-container {\n            background-color: #f5f5f5;\n            color: #333;\n            position: relative;\n        }\n        \n        .test-container .popup {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.7);\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            z-index: 1000;\n        }\n        \n        .test-container .popup-content {\n            background: white;\n            padding: 25px;\n            border-radius: 10px;\n            width: 90%;\n            max-width: 500px;\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);\n        }\n        \n        .test-container .popup-content h3 {\n            color: #10291a;\n            margin-bottom: 20px;\n            text-align: center;\n        }\n        \n        .test-container .popup-content input {\n            width: 100%;\n            padding: 12px;\n            margin-bottom: 15px;\n            border: 1px solid #ddd;\n            border-radius: 5px;\n            font-size: 16px;\n        }\n        \n        .test-container .popup-content button {\n            width: 100%;\n            padding: 12px;\n            background-color: #10291a;\n            color: white;\n            border: none;\n            border-radius: 5px;\n            font-size: 16px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n        }\n        \n        .test-container .popup-content button:hover {\n            background-color: #003366;\n        }\n        \n        .test-container .container {\n            display: flex;\n            height: 100vh;\n            overflow: hidden; \n        }\n        \n        .test-container .sidebar {\n            width: 280px;\n            background-color: #fff;\n            border-right: 1px solid #ddd;\n            box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);\n            overflow-y: auto;\n            transition: transform 0.3s ease;\n            min-height: 100vh;         \n            flex-shrink: 0;\n        }\n        \n        .test-container .sidebar-header {\n            padding: 20px;\n            background-color: #10291a;\n            color: white;\n            text-align: center;\n            font-weight: bold;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n        \n        .test-container .exam-list {\n            padding: 10px;\n            padding-bottom: 80px;\n        }\n        \n        .test-container .exam-item {\n            padding: 10px;\n            margin-bottom: 5px;\n            cursor: pointer;\n            border-radius: 5px;\n            transition: all 0.2s;\n            background: #f5f5f5;               \n            box-shadow: 0 1px 3px rgba(12, 12, 12, 0.05); \n        }\n        \n        .test-container .exam-item:hover {\n            background-color: #f0f0f0;\n        }\n        \n        .test-container .exam-item.active {\n            background-color: #fae6e6;\n            color: #10291a;\n        }\n        \n        .test-container .content {\n            flex: 1;\n            padding: 0;\n            height: 100vh;\n            overflow-y: auto;\n            position: relative;\n        }\n        \n        .test-container .header {\n            width:100%;  \n            z-index: 9;\n            display: flex;\n            justify-content: space-between;     \n            align-items: center; \n            padding: 10px 15px;\n        }\n\n        .test-container .header-left {\n            display: flex;\n            align-items: center;\n            gap: 15px;\n            z-index: 1000;\n        }\n        \n        .test-container .timer-container {\n            background-color: #10291a;\n            color: white;\n            padding: 5px 10px;\n            border-radius: 20px;\n            font-size: 15px;\n            white-space: nowrap;\n        }\n        \n        .test-container .header-right {\n            display: flex;\n            align-items: center;\n        }\n     \n        .test-container .submit-button {\n            padding: 5px 15px;\n            background-color: #e5efd7;\n            color: #10291a;\n            border: none;\n            border-radius: 20px;\n            font-size: 15px;\n            cursor: pointer;\n            transition: all 0.3s;\n            border-bottom: 1px solid #28a745;\n        }\n        \n        .test-container .submit-button:hover {\n            background-color: #218838;\n            color: white;\n        }\n        \n        .test-container .question-group {\n            background-color: white;\n            border-radius: 5px;\n            margin-bottom: 20px;\n            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\n        }\n        \n        .test-container .group-header {\n            padding: 10px;\n            background-color: #f8f9fa;\n            border-bottom: 1px solid #eee;\n            border-radius: 5px 5px 0 0;\n        }\n        \n        .test-container .group-title {\n            font-weight: normal;\n            color: #10291a;\n        }\n        \n        .test-container .group-subtitle {\n            color: #666;\n            font-size: 14px;\n            margin-top: 5px;\n        }\n        \n        .test-container .question {\n            padding: 15px;\n            font-weight: normal;\n            border-bottom: 2px solid #eee;\n        }\n        .test-container .question-container {\n            display: none;\n        }\n        .test-container .question-container.show-questions {\n            display: block;\n        }\n        \n        .test-container .question-text {\n            margin-bottom: 15px;\n            font-weight: normal;\n        }\n        \n        .test-container .question-image {\n            max-width: 100%;\n            height: auto;\n            margin: 10px 0;\n            border-radius: 5px;\n        }\n        \n        .test-container .question-option {\n            display: block;\n            padding: 10px;\n            margin: 5px 0;\n            border-radius: 5px;\n            transition: all 0.2s;\n            font-weight: normal;\n        }\n        \n        .test-container .question-option:hover {\n            background-color: #f0f7ff;\n        }\n        \n        .test-container .question-option input {\n            margin-right: 10px;\n        }\n        \n        .test-container .explanation {\n            display: none;\n            background-color: #e6f7ff;\n            padding: 10px;\n            margin-top: 10px;\n            border-radius: 5px;\n            border-left: 4px solid #10291a;\n            font-size: 14px;\n            font-weight: normal;\n        }\n        \n        .test-container .start-popup {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.7);\n            display: none;\n            justify-content: center;\n            align-items: center;\n            z-index: 1000;\n        }\n        \n        .test-container .start-popup-content {\n            background: white;\n            padding: 30px;\n            border-radius: 10px;\n            text-align: center;\n            max-width: 400px;\n        }\n        \n        .test-container .start-popup button {\n            padding: 10px 20px;\n            background-color: #10291a;\n            color: white;\n            border: none;\n            border-radius: 5px;\n            margin-top: 20px;\n            cursor: pointer;\n        }\n        \n        .test-container .no-exam-message {\n            text-align: center;\n            padding: 50px;\n            font-size: 18px;\n            color: #dc3545;\n        }\n\n        \/* ======= TH\u00d4NG B\u00c1O KH\u00d3A H\u1eccC K\u1ebeT TH\u00daC ======= *\/\n        .test-container .course-ended-message {\n            text-align: center;\n            padding: 50px 20px;\n            font-size: 18px;\n            color: #dc3545;\n        }\n        .test-container .course-ended-message .box {\n            background: #fff;\n            max-width: 600px;\n            margin: 0 auto;\n            padding: 22px;\n            border-radius: 10px;\n            box-shadow: 0 5px 15px rgba(0,0,0,0.08);\n            border: 1px solid #f1caca;\n        }\n        .test-container .course-ended-message h2 {\n            margin-bottom: 10px;\n            font-size: 20px;\n            color: #b91c1c;\n        }\n        .test-container .course-ended-message p {\n            color: #7f1d1d;\n            line-height: 1.5;\n        }\n\n        \/* Menu toggle button *\/\n        .test-container .menu-toggle {\n            display: none;\n            background: none;\n            border: none;\n            color: #10291a;\n            font-size: 22px;\n            cursor: pointer;\n            padding: 4px;\n            margin-right: 15px;\n            border-radius: 50%;\n            width: 40px;\n            height: 40px;\n            align-items: center;\n            justify-content: center;\n            transition: all 0.3s ease;\n        }\n\n        .test-container .menu-toggle:hover {\n            background-color: white;\n            transform: scale(1.1);\n        }\n\n        .test-container .menu-toggle#closeMenu {\n            color: white;\n            background-color: transparent;\n            box-shadow: none;\n            font-size: 22px;\n            margin-right: 0;\n        }\n\n        .test-container .menu-toggle#closeMenu:hover {\n            color: #f0f0f0;\n        }\n\n        .test-container .result-popup {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.7);\n            display: none;\n            justify-content: center;\n            align-items: center;\n            z-index: 99999;\n        }\n        \n        .test-container .result-popup-content {\n            background: white;\n            padding: 30px;\n            border-radius: 10px;\n            width: 90%;\n            max-width: 450px;\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);\n            text-align: center;\n        }\n        \n        .test-container .result-popup h3 {\n            color: #10291a;\n            margin-bottom: 20px;\n        }\n        \n        .test-container .result-details {\n            text-align: left;\n            margin: 20px 0;\n            line-height: 1.8;\n        }\n        \n        .test-container .result-row {\n            display: flex;\n            justify-content: space-between;\n            margin-bottom: 10px;\n        }\n        \n        .test-container .result-label {\n            font-weight: bold;\n            color: #555;\n        }\n        \n        .test-container .result-value {\n            color: #10291a;\n            font-weight: bold;\n        }\n        \n        .test-container .result-popup button {\n            padding: 10px 20px;\n            background-color: #10291a;\n            color: white;\n            border: none;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n        }\n        \n        .test-container .result-popup button:hover {\n            background-color: #003366;\n        }\n\n        .answer-correct { color: #28a745; font-weight: bold; margin-left: 6px; }\n        .answer-wrong { color: #dc3545; font-weight: bold; margin-left: 6px; }\n\n        .test-container .question-list-item.active-question {\n            background: #fae6e6;\n            color: #10291a;\n            border-color: #28a745;\n        }\n        .test-container .question-list-item.active-question.answered-question {\n            background: #fae6e6;\n            color: #10291a;\n            border-color: #28a745;\n        }\n\n        @media (min-width: 769px) {\n          .test-container .header-right {\n            position: absolute;\n            left: 40%;\n            transform: translateX(-50%);\n          }\n        }\n\n        @media (max-width: 768px) {\n            .test-container .container { flex-direction: column; }\n            .test-container .sidebar {\n                position: fixed;\n                top: 0;\n                left: 0;\n                height: 100vh;\n                width: 280px;\n                z-index: 9999;\n                transform: translateX(-100%);\n            }\n            .test-container .sidebar.visible { transform: translateX(0); }\n            .test-container .content {\n                margin-left: 0;\n                padding-top: 60px;\n                padding-bottom: 150px;\n            }\n            .test-container .menu-toggle {\n                display: block;\n                z-index: 10000;\n                position: relative; \n            }\n            .test-container .header {\n                position: fixed;\n                left: 0;\n                bottom: 0;\n                width: 100%;\n                z-index: 9999;\n                justify-content: space-between;\n                background:#fff; \n            }\n        }\n\n        .exam-done-check { color: #28a745; font-weight: bold; font-size: 18px; margin-left: 6px; }\n\n        @media (min-width: 1024px) {\n            .test-container .header {\n                width:100%;  \n                display: flex;\n                justify-content: space-between;\n                align-items: center;\n                padding: 10px 15px;\n            }\n            .test-container .question-layout {\n                display: flex;\n                padding: 15px;\n                padding-top: 10px;\n            }\n            .test-container .question-list {\n                width: 260px;\n                margin-right: 15px;\n                background: #fff;\n                border-radius: 5px;\n                border: 1px solid #ddd;\n                padding: 10px;\n                padding-bottom: 50px;\n                display: flex;\n                flex-wrap: wrap;\n                gap: 8px;\n                align-content: flex-start;\n                max-height: calc(100vh - 120px);\n                overflow-y: auto;\n            }\n            .test-container .question-list-item {\n                flex: 0 0 calc(50% - 8px);\n                text-align: center;\n                padding: 6px 4px;\n                border-radius: 4px;\n                background: #f5f5f5;\n                border: 1px solid #ddd;\n                cursor: pointer;\n                font-size: 13px;\n                user-select: none;\n            }\n            .test-container .question-list-item.active-question {\n                background: #fae6e6;\n                color: #10291a;\n                border-color: #28a745;\n            }\n            .test-container .question-list-item.answered-question {\n                background: #e5efd7;\n                color: #10291a;\n                border-color: #28a745;\n            }\n            .test-container .question-container-wrapper {\n                flex: 1;\n                overflow-y: auto;\n                max-height: calc(100vh - 80px);\n            }\n            .test-container .question { display: none; }\n            .test-container .question.active-question { display: block; }\n        }\n        .course-ended-message {\n        position: fixed;\n        inset: 0;\n        background: rgba(0,0,0,0.6);\n        display: none;\n        justify-content: center;\n        align-items: center;\n        z-index: 99999;\n        }\n\n        .course-ended-message .box {\n        background: #fff3cd;\n        border: 1px solid #ffeeba;\n        border-radius: 12px;\n        padding: 30px;\n        text-align: center;\n        max-width: 450px;\n        width: 90%;\n        box-shadow: 0 10px 25px rgba(0,0,0,0.15);\n        }\n\n        .course-ended-message h2 {\n        color: #856404;\n        margin-bottom: 15px;\n        }\n\n        .course-ended-message p {\n        color: #856404;\n        margin-bottom: 20px;\n        }\n\n        .contact-btn {\n        padding: 10px 20px;\n        background: #10291a;\n        color: #fff;\n        border: none;\n        border-radius: 6px;\n        font-weight: bold;\n        cursor: pointer;\n        transition: background 0.3s ease;\n        }\n\n        .contact-btn:hover {\n        background: #0c1f14;\n        }\n\n    <\/style>\n<\/head>\n<body>\n    <div class=\"test-container\">\n\n    <!-- TH\u00d4NG B\u00c1O KH\u00d3A H\u1eccC K\u1ebeT TH\u00daC -->\n    <div id=\"courseEndedMessage\" class=\"course-ended-message\" style=\"display:none;\">\n    <div class=\"box\">\n        <h2>Kh\u00f3a h\u1ecdc c\u1ee7a b\u1ea1n c\u1ea7n \u0111\u01b0\u1ee3c h\u1ed7 tr\u1ee3<\/h2>\n        <p>Vui l\u00f2ng li\u00ean h\u1ec7 Thanh Mai Yokohama<\/p>\n        <button onclick=\"openContactLink()\" class=\"contact-btn\">\n        Li\u00ean h\u1ec7\n        <\/button>\n    <\/div>\n    <\/div>\n\n    <div id=\"loginPopup\" class=\"popup\" style=\"display:none;\">\n      <div class=\"popup-content\">\n        <h3>\u0110\u0102NG NH\u1eacP H\u1ec6 TH\u1ed0NG<\/h3>\n        <input id=\"loginUserId\" placeholder=\"Email\" \/>\n        <div style=\"position:relative;\">\n          <input id=\"loginPassword\" type=\"password\" placeholder=\"M\u1eadt kh\u1ea9u\" \/>\n          <span id=\"togglePwd\"\n            onclick=\"togglePassword()\"\n            style=\"\n              position:absolute;\n              right:12px;\n              top:50%;\n              transform:translateY(-50%);\n              cursor:pointer;\n              user-select:none;\n            \">\n            <svg id=\"eyeIcon\"\n                width=\"22\" height=\"22\"\n                viewBox=\"0 0 24 24\"\n                fill=\"none\"\n                stroke=\"#000\"\n                stroke-width=\"2\"\n                stroke-linecap=\"round\"\n                stroke-linejoin=\"round\">\n              <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"><\/path>\n              <circle cx=\"12\" cy=\"12\" r=\"3\"><\/circle>\n            <\/svg>\n          <\/span>\n        <\/div>\n        <button id=\"loginButton\" onclick=\"loginUser()\">\u0110\u0103ng nh\u1eadp<\/button>\n      <\/div>\n    <\/div>\n\n    <!-- Main Container -->\n    <div class=\"container\" id=\"mainContainer\" style=\"display:none;\">\n        <div class=\"sidebar\" id=\"sidebar\">\n            <div class=\"sidebar-header\">\n                Danh s\u00e1ch \u0111\u1ec1 thi\n                <button class=\"menu-toggle\" id=\"closeMenu\">\u00d7<\/button>\n            <\/div>\n            <div class=\"exam-list\" id=\"examList\"><\/div>\n        <\/div>        \n        <div class=\"content\" id=\"contentArea\"><\/div>\n    <\/div>\n    \n    <!-- Start Quiz Popup -->\n    <div id=\"startQuizPopup\" class=\"start-popup\">\n        <div class=\"start-popup-content\">\n            <p>B\u1ea1n \u0111\u00e3 s\u1eb5n s\u00e0ng \u0111\u1ec3 l\u00e0m b\u00e0i?<\/p>\n            <button onclick=\"startTimer()\">B\u1eaft \u0111\u1ea7u<\/button>\n        <\/div>\n    <\/div>\n\n    <!-- No Exam Message -->\n    <div id=\"noExamMessage\" class=\"no-exam-message\" style=\"display:none;\">\n        <h2 style=\"color:#10291a;\">Kh\u00f4ng c\u00f3 b\u00e0i t\u1eadp n\u00e0o \u0111\u01b0\u1ee3c hi\u1ec3n th\u1ecb<\/h2>\n        <p>Hi\u1ec7n t\u1ea1i kh\u00f4ng c\u00f3 b\u00e0i t\u1eadp n\u00e0o s\u1eb5n s\u00e0ng. Vui l\u00f2ng quay l\u1ea1i sau.<\/p>\n    <\/div>\n\n    <div id=\"resultPopup\" class=\"result-popup\">\n        <div class=\"result-popup-content\">\n            <h3>K\u1ebeT QU\u1ea2 B\u00c0I L\u00c0M<\/h3>\n            <div class=\"result-details\" id=\"resultDetails\"><\/div>\n            <button onclick=\"closeResultPopup()\">\u0110\u00f3ng<\/button>\n        <\/div>\n    <\/div>\n\n    <\/div>\n\n    <script>\n        \/* ======================================================\n        CONFIG + GLOBALS\n        ====================================================== *\/\n        const scriptUrl = \"https:\/\/script.google.com\/macros\/s\/AKfycbw9xXdWXgzpubRqpYTOLUJvfJOQg9S9_nhgdta6Z0sZnUeoBSGuZ9vE8ke0ykCqDOFR\/exec\";\n\n        let timeLeft = 0;\n        let timerInterval = null;\n\n        let correctAnswers = [];\n        let questionScores = [];\n        let totalQuestions = 0;\n\n        let allExamsData = {};\n        let preloadQueue = [];\n        let isPreloading = false;\n        let examDuration = 10;\n        let currentExamId = null;\n        let sessionInterval = null;\n\n        let isDesktopMode = () => window.innerWidth >= 1024;\n\n        \/* ======================================================\n        COURSE END CHECK (START + 180 DAYS)\n        - ch\u1ea1y ngay l\u00fac load trang \/ sau login\n        ====================================================== *\/\n        function parseDDMMYYYY(str) {\n          \/\/ \"dd\/MM\/yyyy\"\n          if (!str || typeof str !== \"string\") return null;\n          const parts = str.split(\"\/\");\n          if (parts.length !== 3) return null;\n          const d = parseInt(parts[0], 10);\n          const m = parseInt(parts[1], 10);\n          const y = parseInt(parts[2], 10);\n          if (!d || !m || !y) return null;\n          return new Date(y, m - 1, d, 0, 0, 0, 0);\n        }\n\n        function getEarliestStartDateForUser() {\n          const tmy_userName = (localStorage.getItem(\"tmy_userName\") || \"\").toLowerCase();\n          const isAdmin = tmy_userName === \"admin\";\n          if (isAdmin) return null; \/\/ admin b\u1ecf qua\n\n          const classIds = JSON.parse(localStorage.getItem(\"tmy_classIds\") || \"[]\");\n          const map = JSON.parse(localStorage.getItem(\"tmy_courseStartDates\") || \"{}\");\n\n          if (!Array.isArray(classIds) || classIds.length === 0) return null;\n\n          let earliest = null;\n          classIds.forEach(cid => {\n            const startStr = map?.[cid];\n            const dt = parseDDMMYYYY(startStr);\n            if (dt) {\n              if (!earliest || dt.getTime() < earliest.getTime()) earliest = dt;\n            }\n          });\n\n          return earliest; \/\/ c\u00f3 th\u1ec3 null n\u1ebfu kh\u00f4ng c\u00f3 startAt\n        }\n\n        function isCourseEnded180Days() {\n          const startDate = getEarliestStartDateForUser();\n          if (!startDate) return false; \/\/ kh\u00f4ng c\u00f3 startAt -> kh\u00f4ng ch\u1eb7n\n\n          const endTime = startDate.getTime() + 180 * 24 * 60 * 60 * 1000;\n          const now = new Date();\n\n          return now.getTime() > endTime;\n        }\n\n        function showCourseEndedBlock() {\n          document.getElementById(\"loginPopup\").style.display = \"none\";\n          document.getElementById(\"mainContainer\").style.display = \"none\";\n          document.getElementById(\"noExamMessage\").style.display = \"none\";\n          document.getElementById(\"courseEndedMessage\").style.display = \"block\";\n        }\n\n        function checkCourseEndedOnLoadAndBlockIfNeeded() {\n          const tmy_userName = (localStorage.getItem(\"tmy_userName\") || \"\").toLowerCase();\n          const isAdmin = tmy_userName === \"admin\";\n          if (isAdmin) return false;\n\n          if (isCourseEnded180Days()) {\n            showCourseEndedBlock();\n            return true;\n          }\n          \/\/ hide message if not ended\n          document.getElementById(\"courseEndedMessage\").style.display = \"none\";\n          return false;\n        }\n\n        \/* ======================================================\n        SESSION MONITOR\n        ====================================================== *\/\n        function startSessionMonitor() {\n            if (sessionInterval) clearInterval(sessionInterval);\n            \/*sessionInterval = setInterval(() => {\n                checkSessionAlive();\n            }, 60000);*\/\n        }\n\n        function clearUserSessionAndReload() {\n          localStorage.removeItem(\"tmy_userId\");\n          localStorage.removeItem(\"tmy_userName\");\n          localStorage.removeItem(\"tmy_classIds\");\n          localStorage.removeItem(\"tmy_classId\");\n          localStorage.removeItem(\"tmy_courseStartDates\");\n          localStorage.removeItem(\"tmy_studentStatus\");\n          location.reload();\n        }\n\n        function checkSessionAlive() {\n        const tmy_userId = localStorage.getItem(\"tmy_userId\");\n        const deviceId = localStorage.getItem(\"deviceId\");\n        if (!tmy_userId || !deviceId) return;\n\n        fetch(\n            `${scriptUrl}?action=checkSession`\n            + `&tmy_userId=${encodeURIComponent(tmy_userId)}`\n            + `&deviceId=${encodeURIComponent(deviceId)}`\n        )\n            .then(res => res.json())\n            .then(result => {\n            if (!result.valid) {\n                alert(\"T\u00e0i kho\u1ea3n c\u1ee7a b\u1ea1n s\u1ebd b\u1ecb \u0111\u0103ng xu\u1ea5t v\u00ec \u0111\u00e3 \u0111\u0103ng nh\u1eadp tr\u00ean thi\u1ebft b\u1ecb kh\u00e1c.\\n \u0110\u0103ng nh\u1eadp tr\u00ean nhi\u1ec1u thi\u1ebft b\u1ecb s\u1ebd khi\u1ebfn t\u00e0i kho\u1ea3n c\u1ee7a b\u1ea1n b\u1ecb kh\u00f3a!\");\n                localStorage.removeItem(\"tmy_userId\");\n                localStorage.removeItem(\"tmy_userName\");\n                localStorage.removeItem(\"tmy_classIds\");\n                localStorage.removeItem(\"tmy_classId\");\n                localStorage.removeItem(\"tmy_courseStartDates\");\n                localStorage.removeItem(\"tmy_studentStatus\");\n                location.reload();\n                return;\n            }\n\n            \/\/ \u2705 refresh localStorage th\u01b0\u1eddng xuy\u00ean\n            if (result.tmy_courseStartDates && typeof result.tmy_courseStartDates === \"object\") {\n                localStorage.setItem(\"tmy_courseStartDates\", JSON.stringify(result.tmy_courseStartDates));\n            }\n            if (typeof result.tmy_studentStatus === \"string\") {\n                localStorage.setItem(\"tmy_studentStatus\", result.tmy_studentStatus);\n            }\n\n            \/\/ \u2705 check h\u1ebft h\u1ea1n 180 ng\u00e0y ngay c\u1ea3 khi user kh\u00f4ng login l\u1ea1i\n            applyCourseExpiredUI();\n            })\n            .catch(() => {\n            \/\/ im l\u1eb7ng \u2013 kh\u00f4ng ph\u00e1 flow\n            });\n        }\n\n\n        \/* ======================================================\n        SECURITY \/ ANTI COPY (GI\u1eee NGUY\u00caN)\n        ====================================================== *\/\n        function disableCopyPaste() {\n          const userIdInput = document.getElementById('tmy_userId');\n          if (userIdInput) {\n              userIdInput.onpaste = function (e) { return true; };\n          }\n\n          document.addEventListener('contextmenu', function (e) {\n              e.preventDefault();\n              return false;\n          });\n\n          document.addEventListener('dragstart', function (e) {\n              e.preventDefault();\n              return false;\n          });\n\n          document.addEventListener('keydown', function (e) {\n              if (e.ctrlKey && (e.keyCode === 65 || e.keyCode === 67 || e.keyCode === 86 || e.keyCode === 88)) {\n                e.preventDefault();\n                return false;\n              }\n              if (e.keyCode === 123) {\n                e.preventDefault();\n                return false;\n              }\n          });\n        }\n        disableCopyPaste();\n\n        \/* ======================================================\n        EXAM STATUS (LOCAL STORAGE)\n        ====================================================== *\/\n        function saveExamStatus(examId, percentage) {\n          const key = \"tmy_exam_status\";\n          const data = JSON.parse(localStorage.getItem(key) || \"{}\");\n          data[examId] = { done: true, percentage: Number(percentage) || 0 };\n          localStorage.setItem(key, JSON.stringify(data));\n        }\n\n        function getExamStatus(examId) {\n          const data = JSON.parse(localStorage.getItem(\"tmy_exam_status\") || \"{}\");\n          return data[examId] || null;\n        }\n\n        \/* ======================================================\n        PRELOAD OTHER EXAMS\n        ====================================================== *\/\n        function startPreloadOtherExams(currentExamId) {\n          if (isPreloading) return;\n\n          preloadQueue = Object.keys(allExamsData)\n              .filter(id => id !== currentExamId && !allExamsData[id].questions);\n\n          if (preloadQueue.length === 0) return;\n\n          isPreloading = true;\n          preloadNextExam();\n        }\n\n        function preloadNextExam() {\n          if (preloadQueue.length === 0) {\n              isPreloading = false;\n              return;\n          }\n\n          const examId = preloadQueue.shift();\n          if (!examId || allExamsData[examId].questions) {\n              preloadNextExam();\n              return;\n          }\n\n          loadExamData(examId)\n              .then(questions => {\n                allExamsData[examId].questions = questions;\n              })\n              .catch(err => {\n                console.warn(\"Preload failed:\", examId, err.message);\n              })\n              .finally(() => {\n                setTimeout(preloadNextExam, 300);\n              });\n        }\n\n        \/* ======================================================\n        PRIORITY EXAM\n        ====================================================== *\/\n        function findPriorityExam(exams) {\n          const statusMap = JSON.parse(localStorage.getItem(\"tmy_exam_status\") || \"{}\");\n\n          const list = (exams || []).filter(e => {\n              const s = statusMap[e.id];\n              return (!s) || (Number(s.percentage) < 80);\n          });\n\n          list.sort((a, b) => (Number(a.displayOrder) || 999999) - (Number(b.displayOrder) || 999999));\n          return list[0] || null;\n        }\n\n        \/* ======================================================\n        DOM READY\n        ====================================================== *\/\n        document.addEventListener('DOMContentLoaded', () => {\n          const tmy_userId = localStorage.getItem('tmy_userId');\n          const tmy_userName = (localStorage.getItem('tmy_userName') || \"\").toLowerCase();\n          const tmy_classIds = JSON.parse(localStorage.getItem('tmy_classIds') || \"[]\");\n          const deviceId = localStorage.getItem('deviceId');\n\n          const isAdmin = tmy_userName === \"admin\";\n\n          \/\/ N\u1ebfu \u0111\u00e3 login -> check kh\u00f3a h\u1ecdc k\u1ebft th\u00fac tr\u01b0\u1edbc khi v\u00e0o\n          if (tmy_userId && tmy_userName && (isAdmin || tmy_classIds.length > 0)) {\n              if (!deviceId) localStorage.setItem('deviceId', generateRandomID());\n\n              if (checkCourseEndedOnLoadAndBlockIfNeeded()) return;\n\n              document.getElementById('loginPopup').style.display = 'none';\n              document.getElementById('mainContainer').style.display = 'flex';\n              loadExams(true);\n          } else {\n              document.getElementById('loginPopup').style.display = 'flex';\n          }\n\n          document.getElementById('closeMenu').addEventListener('click', () => {\n              document.getElementById('sidebar').classList.remove('visible');\n          });\n        });\n\n        \/* ======================================================\n        MENU\n        ====================================================== *\/\n        function toggleMenu() {\n          const sidebar = document.getElementById('sidebar');\n          sidebar.classList.toggle('visible');\n        }\n\n        \/* ======================================================\n        LOGIN (C\u1eacP NH\u1eacT: l\u01b0u tmy_studentStatus + tmy_courseStartDates)\n        ====================================================== *\/\n        function loginUser() {\n          const tmy_userId = document.getElementById('loginUserId').value.trim();\n          const password  = document.getElementById('loginPassword').value.trim();\n          const btn = document.getElementById('loginButton');\n\n          if (!tmy_userId || !password) {\n              alert('Vui l\u00f2ng nh\u1eadp email v\u00e0 m\u1eadt kh\u1ea9u!');\n              return;\n          }\n\n          btn.disabled = true;\n          btn.textContent = '\u0110ang ki\u1ec3m tra...';\n\n          \/\/ \ud83d\udd11 T\u1ea0O DEVICE ID M\u1edaI KHI LOGIN L\u1ea0I\n          const newDeviceId = generateRandomID();\n          localStorage.setItem('deviceId', newDeviceId);\n\n          const url =\n              `${scriptUrl}?action=checkUserId`\n              + `&tmy_userId=${encodeURIComponent(tmy_userId)}`\n              + `&password=${encodeURIComponent(password)}`\n              + `&deviceId=${encodeURIComponent(newDeviceId)}`;\n\n          fetch(url)\n              .then(res => res.json())\n              .then(result => {\n                if (!result.exists) {\n                    alert('Sai t\u00e0i kho\u1ea3n ho\u1eb7c m\u1eadt kh\u1ea9u!');\n                    return;\n                }\n\n                \/\/ \u2705 L\u01afU SESSION\n                localStorage.setItem('tmy_userId', tmy_userId);\n                localStorage.setItem('tmy_userName', result.tmy_userName || \"\");\n                localStorage.setItem('tmy_classIds', JSON.stringify(result.tmy_classIds || []));\n                localStorage.setItem('tmy_classId', result.tmy_classIds?.[0] || \"\");\n\n                \/\/ \u2705 L\u01afU TH\u00caM TR\u1ea0NG TH\u00c1I + NG\u00c0Y B\u1eaeT \u0110\u1ea6U (NEW)\n                localStorage.setItem('tmy_studentStatus', result.tmy_studentStatus || \"\");\n                localStorage.setItem('tmy_courseStartDates', JSON.stringify(result.tmy_courseStartDates || {}));\n\n                \/\/ \u2705 CHECK KH\u00d3A H\u1eccC K\u1ebeT TH\u00daC NGAY SAU LOGIN\n                if (checkCourseEndedOnLoadAndBlockIfNeeded()) return;\n\n                \/\/ \u2705 \u1ea8N POPUP \u2192 LOAD L\u1ea0I \u0110\u1ec0\n                document.getElementById('loginPopup').style.display = 'none';\n                document.getElementById('mainContainer').style.display = 'flex';\n\n                \/\/startSessionMonitor();\n                loadExams(true);\n              })\n              .catch(err => {\n                alert('L\u1ed7i \u0111\u0103ng nh\u1eadp: ' + err.message);\n              })\n              .finally(() => {\n                btn.disabled = false;\n                btn.textContent = '\u0110\u0103ng nh\u1eadp';\n              });\n        }\n\n        \/* ======================================================\n        LOAD EXAMS\n        ====================================================== *\/\n        function loadExams(autoOpenPriority = false) {\n          \/\/ ch\u1eb7n n\u1ebfu kh\u00f3a h\u1ecdc h\u1ebft h\u1ea1n\n          if (checkCourseEndedOnLoadAndBlockIfNeeded()) return;\n\n          const tmy_classIds = JSON.parse(localStorage.getItem('tmy_classIds') || \"[]\");\n          const tmy_userName = (localStorage.getItem('tmy_userName') || \"\").toLowerCase();\n          const isAdmin = tmy_userName === \"admin\";\n\n          const url = isAdmin\n              ? `${scriptUrl}?action=fetchExams`\n              : `${scriptUrl}?action=fetchExams&tmy_classIds=${encodeURIComponent(JSON.stringify(tmy_classIds))}`;\n\n          fetch(url)\n              .then(res => res.json())\n              .then(result => {\n                if (result.error) throw new Error(result.error);\n\n                if (!result.exams || result.exams.length === 0) {\n                    document.getElementById('mainContainer').style.display = 'none';\n                    document.getElementById('noExamMessage').style.display = 'block';\n                    return;\n                }\n\n                document.getElementById('mainContainer').style.display = 'flex';\n                document.getElementById('noExamMessage').style.display = 'none';\n\n                const examList = document.getElementById('examList');\n                examList.innerHTML = '';\n                allExamsData = {};\n\n                result.exams.forEach(exam => {\n                    allExamsData[exam.id] = {\n                      id: exam.id,\n                      labelName: exam.labelName,\n                      testName: exam.testName,\n                      duration: exam.duration,\n                      displayOrder: Number(exam.displayOrder) || 999999,\n                      questions: null\n                    };\n                });\n\n                result.exams.forEach(exam => {\n                    const examItem = document.createElement('div');\n                    examItem.className = 'exam-item';\n                    examItem.dataset.examId = exam.id;\n\n                    const status = getExamStatus(exam.id);\n                    let icon = \"\";\n                    if (status) {\n                      if (Number(status.percentage) >= 80) {\n                          icon = `<span class=\"exam-done-check\">\u2714<\/span>`;\n                      } else {\n                          icon = `<span style=\"color:#dc3545;font-weight:bold;margin-left:6px;\">\u2718<\/span>`;\n                      }\n                    }\n\n                    examItem.innerHTML = `${exam.labelName} ${icon}`;\n\n                    examItem.onclick = () => {\n                      showExam(exam.id);\n                      document.getElementById('sidebar').classList.remove('visible');\n                    };\n\n                    examList.appendChild(examItem);\n                });\n\n                document.getElementById('contentArea').innerHTML = `\n                    <div class=\"header\">\n                      <div class=\"header-left\">\n                        <button class=\"menu-toggle\" onclick=\"toggleMenu()\">\u2630<\/button>\n                        <div class=\"timer-container\">\n                          <span id=\"timer\">${formatTime(timeLeft)}<\/span>\n                        <\/div>\n                      <\/div>\n                      <div class=\"header-right\">\n                        <button class=\"submit-button\" id=\"submitButton\" onclick=\"submitQuiz()\">N\u1ed9p b\u00e0i<\/button>\n                      <\/div>\n                    <\/div>\n                `;\n\n                if (autoOpenPriority) {\n                    const priority = findPriorityExam(result.exams);\n                    if (priority && priority.id) {\n                      setTimeout(() => showExam(priority.id), 500);\n                    }\n                }\n              })\n              .catch(err => {\n                console.error(err);\n                alert(\"L\u1ed7i t\u1ea3i danh s\u00e1ch \u0111\u1ec1: \" + err.message);\n              });\n        }\n\n        \/* ======================================================\n        LOAD QUESTIONS (ON DEMAND)\n        ====================================================== *\/\n        function loadExamData(examId) {\n          return fetch(`${scriptUrl}?action=fetchQuestions&examId=${encodeURIComponent(examId)}`)\n              .then(response => {\n                if (!response.ok) throw new Error('Network response was not ok');\n                return response.json();\n              })\n              .then(data => {\n                if (data.error) throw new Error(data.error);\n                return data;\n              });\n        }\n\n        \/* ======================================================\n        SHOW EXAM\n        ====================================================== *\/\n        function showExam(examId) {\n          \/\/ ch\u1eb7n n\u1ebfu kh\u00f3a h\u1ecdc h\u1ebft h\u1ea1n\n          if (checkCourseEndedOnLoadAndBlockIfNeeded()) return;\n\n          const examItems = document.querySelectorAll('.exam-item');\n          examItems.forEach(item => {\n              item.classList.remove('active');\n              if (item.dataset.examId === examId) item.classList.add('active');\n          });\n\n          const examMeta = allExamsData[examId];\n          if (!examMeta) {\n              alert('Kh\u00f4ng th\u1ec3 t\u1ea3i d\u1eef li\u1ec7u b\u00e0i t\u1eadp. Vui l\u00f2ng th\u1eed l\u1ea1i.');\n              return;\n          }\n\n          if (!examMeta.questions) {\n              loadExamData(examId)\n                .then(questions => {\n                  allExamsData[examId].questions = questions;\n                  renderExam(examId);\n                  setTimeout(() => startPreloadOtherExams(examId), 800);\n                })\n                .catch(err => {\n                  console.error(err);\n                  alert('Kh\u00f4ng th\u1ec3 t\u1ea3i d\u1eef li\u1ec7u b\u00e0i t\u1eadp. Vui l\u00f2ng th\u1eed l\u1ea1i.');\n                });\n              return;\n          }\n\n          renderExam(examId);\n        }\n\n        \/* ======================================================\n        RENDER EXAM\n        ====================================================== *\/\n        function renderExam(examId) {\n          const examData = allExamsData[examId];\n          if (!examData || !examData.questions) {\n              alert('Kh\u00f4ng th\u1ec3 t\u1ea3i d\u1eef li\u1ec7u b\u00e0i t\u1eadp. Vui l\u00f2ng th\u1eed l\u1ea1i.');\n              return;\n          }\n\n          currentExamId = examId;\n          examDuration = examData.duration || 10;\n          timeLeft = examDuration * 60;\n\n          const contentArea = document.getElementById('contentArea');\n\n          if (isDesktopMode()) {\n              contentArea.innerHTML = `\n              <div class=\"header\">\n                  <div class=\"header-left\">\n                    <button class=\"menu-toggle\" onclick=\"toggleMenu()\">\u2630<\/button>\n                    <div class=\"timer-container\">\n                      <span id=\"timer\">${formatTime(timeLeft)}<\/span>\n                    <\/div>\n                  <\/div>\n                  <div class=\"header-right\">\n                    <button class=\"submit-button\" id=\"submitButton\" onclick=\"submitQuiz()\">N\u1ed9p b\u00e0i<\/button>\n                  <\/div>\n              <\/div>\n              <div class=\"question-layout\">\n                  <div id=\"questionList\" class=\"question-list\"><\/div>\n                  <div class=\"question-container-wrapper\">\n                    <div id=\"questionContainer\" class=\"question-container\"><\/div>\n                  <\/div>\n              <\/div>\n              `;\n          } else {\n              contentArea.innerHTML = `\n              <div class=\"header\">\n                  <div class=\"header-left\">\n                    <button class=\"menu-toggle\" onclick=\"toggleMenu()\">\u2630<\/button>\n                    <div class=\"timer-container\">\n                      <span id=\"timer\">${formatTime(timeLeft)}<\/span>\n                    <\/div>\n                  <\/div>\n                  <div class=\"header-right\">\n                    <button class=\"submit-button\" id=\"submitButton\" onclick=\"submitQuiz()\">N\u1ed9p b\u00e0i<\/button>\n                  <\/div>\n              <\/div>\n              <div id=\"questionContainer\" class=\"question-container\"><\/div>\n              `;\n          }\n\n          displayQuestions(examData.questions);\n\n          document.getElementById('startQuizPopup').style.display = 'flex';\n\n          if (timerInterval) {\n              clearInterval(timerInterval);\n              timerInterval = null;\n          }\n        }\n\n        \/* ======================================================\n        TIMER\n        ====================================================== *\/\n        function formatTime(seconds) {\n          const mins = Math.floor(Math.max(seconds, 0) \/ 60);\n          const secs = Math.max(seconds, 0) % 60;\n          return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n        }\n\n        function startTimer() {\n          \/\/startSessionMonitor();\n          document.getElementById('startQuizPopup').style.display = 'none';\n          document.querySelector('.question-container')?.classList.add('show-questions');\n          if (!timerInterval) timerInterval = setInterval(updateTimer, 1000);\n        }\n\n        function updateTimer() {\n          const timerElement = document.getElementById('timer');\n          timeLeft--;\n          if (timerElement) timerElement.textContent = formatTime(timeLeft);\n\n          if (timeLeft < 0) {\n              clearInterval(timerInterval);\n              timerInterval = null;\n              endQuiz();\n          }\n        }\n\n        \/* ======================================================\n        DISPLAY QUESTIONS (GI\u1eee NGUY\u00caN)\n        ====================================================== *\/\n        function displayQuestions(questions) {\n          const container = document.getElementById('questionContainer');\n          container.innerHTML = '';\n\n          if (!questions || questions.length === 0) {\n              container.innerHTML = '<p>Kh\u00f4ng c\u00f3 c\u00e2u h\u1ecfi n\u00e0o trong \u0111\u1ec1 n\u00e0y.<\/p>';\n              return;\n          }\n\n          const groupedQuestions = [];\n          let currentGroup = null;\n\n          questions.forEach(question => {\n              if (question.groupTitle) {\n                currentGroup = {\n                  title: question.groupTitle,\n                  subtitle: question.groupSubtitle,\n                  image: question.groupImage,\n                  questions: []\n                };\n                groupedQuestions.push(currentGroup);\n              }\n\n              if (currentGroup) currentGroup.questions.push(question);\n              else {\n                currentGroup = { title: 'Ungrouped', subtitle: '', image: '', questions: [question] };\n                groupedQuestions.push(currentGroup);\n              }\n          });\n\n          let globalQuestionIndex = 0;\n          correctAnswers = [];\n          questionScores = [];\n\n          groupedQuestions.forEach((group, groupIndex) => {\n              let groupHTML = '';\n\n              if (group.title !== 'Ungrouped') {\n                groupHTML += `\n                  <div class=\"group-header\">\n                    <div class=\"group-title\">Ph\u1ea7n ${groupIndex + 1}: ${group.title}<\/div>\n                    ${group.subtitle ? `<div class=\"group-subtitle\">${group.subtitle}<\/div>` : ''}\n                    ${group.image ? `<img decoding=\"async\" class=\"question-image\" src=\"${group.image}\">` : ''}\n                  <\/div>\n                `;\n              }\n\n              group.questions.forEach(question => {\n                const questionIndex = globalQuestionIndex;\n\n                correctAnswers.push(question.correctAnswer);\n                questionScores.push(parseFloat(question.questionScore) || 1);\n\n                groupHTML += `\n                  <div class=\"question\" id=\"question-${questionIndex}\">\n                    <div class=\"question-text\">${question.questionText}<\/div>\n                    ${question.questionImage ? `<img decoding=\"async\" class=\"question-image\" src=\"${question.questionImage}\">` : ''}\n\n                    <label class=\"question-option\">\n                      <input type=\"radio\" name=\"question${questionIndex}\" value=\"A\">\n                      ${question.optionA || 'N\/A'}\n                    <\/label>\n\n                    <label class=\"question-option\">\n                      <input type=\"radio\" name=\"question${questionIndex}\" value=\"B\">\n                      ${question.optionB || 'N\/A'}\n                    <\/label>\n\n                    ${question.optionC ? `\n                      <label class=\"question-option\">\n                        <input type=\"radio\" name=\"question${questionIndex}\" value=\"C\">\n                        ${question.optionC}\n                      <\/label>\n                    ` : ''}\n\n                    ${question.optionD ? `\n                      <label class=\"question-option\">\n                        <input type=\"radio\" name=\"question${questionIndex}\" value=\"D\">\n                        ${question.optionD}\n                      <\/label>\n                    ` : ''}\n\n                    ${question.explanation ? `\n                      <div class=\"explanation\" id=\"explanation-${questionIndex}\">\n                        <strong>Gi\u1ea3i th\u00edch:<\/strong> ${question.explanation}\n                      <\/div>\n                    ` : ''}\n                  <\/div>\n                `;\n\n                globalQuestionIndex++;\n              });\n\n              container.innerHTML += `<div class=\"question-group\">${groupHTML}<\/div>`;\n          });\n\n          totalQuestions = globalQuestionIndex;\n          window.totalQuestions = totalQuestions;\n\n          setupAnswerSelection();\n\n          if (isDesktopMode()) {\n              buildDesktopQuestionList(totalQuestions);\n              setActiveQuestionDesktop(0);\n              document.querySelector('.question-container')?.classList.add('show-questions');\n          } else {\n              document.querySelector('.question-container')?.classList.add('show-questions');\n          }\n        }\n\n        \/* ======================================================\n        DESKTOP QUESTION LIST\n        ====================================================== *\/\n        function buildDesktopQuestionList(total) {\n          const list = document.getElementById('questionList');\n          if (!list) return;\n          list.innerHTML = '';\n\n          for (let i = 0; i < total; i++) {\n              const item = document.createElement('div');\n              item.className = 'question-list-item';\n              item.dataset.index = i;\n              item.textContent = `C\u00e2u ${i + 1}`;\n              item.addEventListener('click', () => setActiveQuestionDesktop(i));\n              list.appendChild(item);\n          }\n        }\n\n        function setActiveQuestionDesktop(index) {\n          const questions = document.querySelectorAll('.question');\n          questions.forEach((q, i) => {\n              q.classList.toggle('active-question', i === index);\n          });\n\n          const list = document.getElementById('questionList');\n          if (!list) return;\n\n          const items = list.querySelectorAll('.question-list-item');\n          items.forEach((item, i) => {\n              if (i === index) item.classList.add('active-question');\n              else item.classList.remove('active-question');\n          });\n        }\n\n        \/* ======================================================\n        ANSWER SELECTION\n        ====================================================== *\/\n        function setupAnswerSelection() {\n          const radioButtons = document.querySelectorAll('input[type=\"radio\"]');\n          radioButtons.forEach(radio => {\n              radio.addEventListener('change', function () {\n                const questionDiv = this.closest('.question');\n                const labels = questionDiv.querySelectorAll('.question-option');\n\n                labels.forEach(label => {\n                    label.style.backgroundColor = '';\n                    label.style.color = '';\n                });\n\n                this.closest('.question-option').style.backgroundColor = '#e6f7ff';\n\n                if (isDesktopMode()) {\n                    const questions = Array.from(document.querySelectorAll('.question'));\n                    const index = questions.indexOf(questionDiv);\n                    if (index !== -1) {\n                      const list = document.getElementById('questionList');\n                      if (list) {\n                          const item = list.querySelector(`.question-list-item[data-index=\"${index}\"]`);\n                          if (item) item.classList.add('answered-question');\n                      }\n                    }\n                }\n              });\n          });\n        }\n\n        \/* ======================================================\n        SUBMIT QUIZ (GI\u1eee NGUY\u00caN)\n        ====================================================== *\/\n        function submitQuiz() {\n          if (!confirm(\"B\u1ea1n c\u00f3 ch\u1eafc ch\u1eafn mu\u1ed1n n\u1ed9p b\u00e0i thi n\u00e0y?\")) return;\n\n          if (timerInterval) {\n              clearInterval(timerInterval);\n              timerInterval = null;\n          }\n\n          const submitBtn = document.getElementById(\"submitButton\");\n          if (submitBtn) submitBtn.disabled = true;\n\n          document.querySelectorAll('input[type=\"radio\"]').forEach(r => r.disabled = true);\n\n          if (!currentExamId || !allExamsData[currentExamId]) {\n              alert(\"Kh\u00f4ng x\u00e1c \u0111\u1ecbnh \u0111\u01b0\u1ee3c \u0111\u1ec1 thi hi\u1ec7n t\u1ea1i.\");\n              return;\n          }\n\n          const testName = allExamsData[currentExamId].testName;\n          const name = localStorage.getItem(\"tmy_userName\") || \"\";\n          const email = localStorage.getItem(\"tmy_userId\") || \"\";\n          const deviceId = localStorage.getItem(\"deviceId\") || generateRandomID();\n\n          const totalTime = examDuration * 60;\n          const timeSpent = totalTime - timeLeft;\n          const minutes = Math.floor(Math.max(timeSpent, 0) \/ 60);\n\n          let correctCount = 0;\n          let totalScore = 0;\n\n          for (let i = 0; i < totalQuestions; i++) {\n              const selected = document.querySelector(`input[name=\"question${i}\"]:checked`);\n              const answer = selected ? selected.value : \"N\/A\";\n\n              if (answer === correctAnswers[i]) {\n                  correctCount++;\n                  totalScore += (Number(questionScores[i]) || 1);\n              }\n\n              const questionDiv = document.getElementById(`question-${i}`);\n              if (!questionDiv) continue;\n\n              const options = questionDiv.querySelectorAll('.question-option');\n\n              options.forEach(option => {\n                  const input = option.querySelector(\"input\");\n                  if (!input) return;\n\n                  const value = input.value;\n\n                  const oldIcon = option.querySelector(\".answer-correct, .answer-wrong\");\n                  if (oldIcon) oldIcon.remove();\n\n                  if (!selected) return;\n\n                  if (value === correctAnswers[i]) {\n                      const icon = document.createElement(\"span\");\n                      icon.className = \"answer-correct\";\n                      icon.textContent = \"\u2714\";\n                      option.appendChild(icon);\n                  }\n\n                  if (value === answer && answer !== correctAnswers[i]) {\n                      const icon = document.createElement(\"span\");\n                      icon.className = \"answer-wrong\";\n                      icon.textContent = \"\u2718\";\n                      option.appendChild(icon);\n                  }\n              });\n\n              if (selected) {\n                  const exp = document.getElementById(`explanation-${i}`);\n                  if (exp) exp.style.display = 'block';\n              }\n          }\n\n          const percentage = totalQuestions > 0 ? (correctCount \/ totalQuestions) * 100 : 0;\n          const ketqua = (percentage >= 80) ? \"\u0110\u1ed7\" : \"Tr\u01b0\u1ee3t\";\n\n          saveExamStatus(currentExamId, percentage);\n          updateExamIconInSidebar(currentExamId);\n\n          fetch(scriptUrl, {\n              method: \"POST\",\n              mode: \"no-cors\",\n              headers: { \"Content-Type\": \"application\/json\" },\n              body: JSON.stringify({\n                action: \"submitQuiz\",\n                testName: testName,\n                name: name,\n                email: email,\n                correctCount: correctCount,\n                totalQuestions: totalQuestions,\n                minutes: minutes,\n                deviceId: deviceId,\n                percentage: percentage,\n                ketqua: ketqua\n              })\n          })\n              .then(() => {\n                showResultPopup({\n                    totalQuestions,\n                    correctCount,\n                    totalScore,\n                    minutes,\n                    seconds: Math.max(timeSpent, 0) % 60,\n                    ketqua\n                });\n              })\n              .catch(err => {\n                alert(\"L\u1ed7i n\u1ed9p b\u00e0i: \" + err.message);\n              });\n        }\n\n        function updateExamIconInSidebar(examId) {\n          const item = document.querySelector(`.exam-item[data-exam-id=\"${examId}\"]`);\n          if (!item) return;\n\n          const exam = allExamsData[examId];\n          const status = getExamStatus(examId);\n\n          let icon = \"\";\n          if (status) {\n              if (Number(status.percentage) >= 80) icon = `<span class=\"exam-done-check\">\u2714<\/span>`;\n              else icon = `<span style=\"color:#dc3545;font-weight:bold;margin-left:6px;\">\u2718<\/span>`;\n          }\n\n          const label = exam?.labelName || item.textContent.trim();\n          item.innerHTML = `${label} ${icon}`;\n        }\n\n        \/* ======================================================\n        RESULT POPUP\n        ====================================================== *\/\n        function showResultPopup(results) {\n          const resultDetails = document.getElementById('resultDetails');\n          const correctPercentage = results.totalQuestions > 0\n              ? (results.correctCount \/ results.totalQuestions) * 100\n              : 0;\n\n          resultDetails.innerHTML = `\n              <div class=\"result-row\">\n                <span class=\"result-label\">S\u1ed1 c\u00e2u \u0111\u00fang:<\/span>\n                <span class=\"result-value\">\n                  ${results.correctCount}\/${results.totalQuestions} (${correctPercentage.toFixed(0)}%)\n                <\/span>\n              <\/div>\n              <div class=\"result-row\">\n                <span class=\"result-label\">Th\u1eddi gian l\u00e0m b\u00e0i:<\/span>\n                <span class=\"result-value\">\n                  ${results.minutes} ph\u00fat ${results.seconds} gi\u00e2y\n                <\/span>\n              <\/div>\n          `;\n\n          let imageUrl = \"\";\n          if (correctPercentage <= 30) imageUrl = \"https:\/\/tokuteigino.vn\/wp-content\/uploads\/2025\/01\/0-30-1.png\";\n          else if (correctPercentage <= 55) imageUrl = \"https:\/\/tokuteigino.vn\/wp-content\/uploads\/2025\/01\/30-55.png\";\n          else if (correctPercentage <= 75) imageUrl = \"https:\/\/tokuteigino.vn\/wp-content\/uploads\/2025\/01\/55-75.png\";\n          else if (correctPercentage <= 90) imageUrl = \"https:\/\/tokuteigino.vn\/wp-content\/uploads\/2025\/01\/75-90-1.png\";\n          else imageUrl = \"https:\/\/tokuteigino.vn\/wp-content\/uploads\/2025\/01\/90-100-2.png\";\n\n          resultDetails.innerHTML += `\n              <div style=\"text-align:center; margin-top:15px;\">\n                <img decoding=\"async\" src=\"${imageUrl}\" style=\"max-width:100%; border-radius:8px;\">\n              <\/div>\n          `;\n\n          document.getElementById('resultPopup').style.display = 'flex';\n        }\n\n        function closeResultPopup() {\n          document.getElementById('resultPopup').style.display = 'none';\n        }\n        function openContactLink() {\n        const contactUrl = \"https:\/\/zalo.me\/1143640521456481728\";\n        window.open(contactUrl, \"_blank\");\n        }\n\n        \/* ======================================================\n        END QUIZ\n        ====================================================== *\/\n        function endQuiz() {\n          document.querySelectorAll('input[type=\"radio\"]').forEach(r => r.disabled = true);\n          alert(\"Th\u1eddi gian l\u00e0m b\u00e0i \u0111\u00e3 h\u1ebft! H\u1ec7 th\u1ed1ng s\u1ebd t\u1ef1 \u0111\u1ed9ng n\u1ed9p b\u00e0i.\");\n          submitQuiz();\n        }\n\n        \/* ======================================================\n        HELPERS\n        ====================================================== *\/\n        function generateRandomID() {\n          return Math.random().toString(36).substr(2, 9);\n        }\n\n        function togglePassword() {\n          const input = document.getElementById(\"loginPassword\");\n          const iconWrap = document.getElementById(\"togglePwd\");\n\n          if (input.type === \"password\") {\n              input.type = \"text\";\n              iconWrap.innerHTML = `\n              <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\"\n                  fill=\"none\" stroke=\"#000\" stroke-width=\"2\"\n                  stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <path d=\"M17.94 17.94A10.94 10.94 0 0 1 12 19\n                          c-7 0-11-7-11-7a21.81 21.81 0 0 1 5.06-5.94\"><\/path>\n                  <path d=\"M1 1l22 22\"><\/path>\n                  <path d=\"M9.53 9.53A3 3 0 0 0 12 15\n                          a3 3 0 0 0 2.47-5.47\"><\/path>\n              <\/svg>\n              `;\n          } else {\n              input.type = \"password\";\n              iconWrap.innerHTML = `\n              <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\"\n                  fill=\"none\" stroke=\"#000\" stroke-width=\"2\"\n                  stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"><\/path>\n                  <circle cx=\"12\" cy=\"12\" r=\"3\"><\/circle>\n              <\/svg>\n              `;\n          }\n        }\n    <\/script>\n\n<\/body>\n<\/html>\n\n","protected":false},"excerpt":{"rendered":"<p>Danh s\u00e1ch \u0111\u1ec1 thi n\u00f4ng nghi\u1ec7p tokutei gino2 Kh\u00f3a h\u1ecdc c\u1ee7a b\u1ea1n c\u1ea7n \u0111\u01b0\u1ee3c h\u1ed7 tr\u1ee3 Vui l\u00f2ng li\u00ean h\u1ec7 Thanh Mai Yokohama Li\u00ean h\u1ec7 \u0110\u0102NG NH\u1eacP H\u1ec6 TH\u1ed0NG \u0110\u0103ng nh\u1eadp Danh s\u00e1ch \u0111\u1ec1 thi \u00d7 B\u1ea1n \u0111\u00e3 s\u1eb5n s\u00e0ng \u0111\u1ec3 l\u00e0m b\u00e0i? B\u1eaft \u0111\u1ea7u Kh\u00f4ng c\u00f3 b\u00e0i t\u1eadp n\u00e0o \u0111\u01b0\u1ee3c hi\u1ec3n th\u1ecb Hi\u1ec7n t\u1ea1i [&#8230;]\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-7851","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/pages\/7851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/comments?post=7851"}],"version-history":[{"count":8,"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/pages\/7851\/revisions"}],"predecessor-version":[{"id":8131,"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/pages\/7851\/revisions\/8131"}],"wp:attachment":[{"href":"https:\/\/tokuteigino.vn\/vi\/wp-json\/wp\/v2\/media?parent=7851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}