{"id":6671,"date":"2026-10-02T15:30:22","date_gmt":"2026-10-02T13:30:22","guid":{"rendered":"https:\/\/science.knu.ua\/new\/?page_id=6671"},"modified":"2026-10-02T15:33:48","modified_gmt":"2026-10-02T13:33:48","slug":"%e2%9a%99%ef%b8%8f-programa-generator-imennyh-kartok","status":"publish","type":"page","link":"https:\/\/science.knu.ua\/new\/?page_id=6671","title":{"rendered":"\u2699\ufe0f \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0430. \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0456\u043c\u0435\u043d\u043d\u0438\u0445 \u043a\u0430\u0440\u0442\u043e\u043a"},"content":{"rendered":"<!-- Montserrat Font & \u0421\u0442\u0430\u0431\u0456\u043b\u044c\u043d\u0456 CDN \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 -->\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;500;600;700;800;900&display=swap\" rel=\"stylesheet\">\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/lucide@0.479.0\/dist\/umd\/lucide.min.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/pptxgenjs@3.12.0\/dist\/pptxgen.bundle.js\"><\/script>\r\n<div id=\"card-generator-app\">\r\n    <style>\r\n        #card-generator-app {\r\n            --primary: #b80000;\r\n            --primary-hover: #8a0000;\r\n            --dark-blue: #0A1B3F;\r\n            --dark-blue-hover: #061127;\r\n            --success: #2e7d32;\r\n            --bg-color: #f5f6f8;\r\n            --border-color: #d1d5db;\r\n            --text-main: #1f2937;\r\n            --sidebar-width: 495px;\r\n            font-family: 'Montserrat', sans-serif;\r\n            background-color: var(--bg-color);\r\n            color: var(--text-main);\r\n            display: flex;\r\n            height: 88vh;\r\n            min-height: 660px;\r\n            max-height: 940px;\r\n            width: 100%;\r\n            margin: 1rem auto;\r\n            border-radius: 12px;\r\n            border: 1px solid var(--border-color);\r\n            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);\r\n            overflow: hidden;\r\n            position: relative;\r\n            box-sizing: border-box;\r\n        }\r\n        #card-generator-app * {\r\n            box-sizing: border-box;\r\n        }\r\n        \/* --- \u041b\u0406\u0412\u0410 \u041f\u0410\u041d\u0415\u041b\u042c \u041a\u0415\u0420\u0423\u0412\u0410\u041d\u041d\u042f --- *\/\r\n        #card-generator-app .left-panel {\r\n            width: var(--sidebar-width);\r\n            background-color: #ffffff;\r\n            box-shadow: 4px 0 20px rgba(0, 0, 0, 0.04);\r\n            display: flex;\r\n            flex-direction: column;\r\n            border-right: 1px solid var(--border-color);\r\n            z-index: 10;\r\n            overflow-y: auto;\r\n            padding: 12px 16px;\r\n            gap: 8px;\r\n        }\r\n        #card-generator-app .header-title {\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 10px;\r\n            margin-bottom: 1px;\r\n        }\r\n        #card-generator-app .header-title h2 {\r\n            margin: 0;\r\n            font-size: 15px;\r\n            font-weight: 800;\r\n            color: var(--primary);\r\n            line-height: 1.2;\r\n        }\r\n        \/* \u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u0447 \u043c\u043e\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0443 *\/\r\n        #card-generator-app .lang-mode-bar {\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: space-between;\r\n            background: #f1f5f9;\r\n            padding: 4px;\r\n            border-radius: 9px;\r\n            gap: 6px;\r\n            border: 1px solid #e2e8f0;\r\n        }\r\n        #card-generator-app .lang-flag-svg {\r\n            width: 24px;\r\n            height: 16px;\r\n            border-radius: 3px;\r\n            box-shadow: 0 1px 3px rgba(0,0,0,0.2);\r\n            flex-shrink: 0;\r\n            vertical-align: middle;\r\n        }\r\n        #card-generator-app .lang-pill {\r\n            flex: 1;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 8px;\r\n            padding: 6px 10px;\r\n            font-size: 11px;\r\n            font-weight: 700;\r\n            border: 2px solid transparent;\r\n            border-radius: 7px;\r\n            background: #ffffff;\r\n            color: #64748b;\r\n            cursor: pointer;\r\n            transition: all 0.2s ease;\r\n        }\r\n        #card-generator-app .lang-pill:hover {\r\n            background: #f8fafc;\r\n            transform: translateY(-1px);\r\n        }\r\n        #card-generator-app .lang-pill-ua.active {\r\n            background: #f0f7ff;\r\n            border-color: #0057B7;\r\n            color: #003e8a;\r\n            box-shadow: 0 2px 8px rgba(0, 87, 183, 0.25), inset 0 -2px 0 0 #FFD700;\r\n        }\r\n        #card-generator-app .lang-pill-en.active {\r\n            background: #fff8f8;\r\n            border-color: #C8102E;\r\n            color: #012169;\r\n            box-shadow: 0 2px 8px rgba(200, 16, 46, 0.25), inset 0 -2px 0 0 #012169;\r\n        }\r\n        \/* \u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0430 \u0433\u0430\u0440\u044f\u0447\u0438\u0445 \u043a\u043b\u0430\u0432\u0456\u0448 *\/\r\n        #card-generator-app .shortcut-badge-bar {\r\n            display: flex;\r\n            flex-wrap: wrap;\r\n            gap: 4px;\r\n            background: #f8fafc;\r\n            border: 1px solid #e2e8f0;\r\n            padding: 3px 6px;\r\n            border-radius: 6px;\r\n            font-size: 9px;\r\n            color: #64748b;\r\n        }\r\n        #card-generator-app .kbd-tag {\r\n            background: #ffffff;\r\n            border: 1px solid #cbd5e1;\r\n            padding: 1px 3px;\r\n            border-radius: 3px;\r\n            font-weight: 700;\r\n            color: var(--dark-blue);\r\n            font-family: monospace;\r\n        }\r\n        \/* \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 *\/\r\n        #card-generator-app .stats-panel {\r\n            display: flex;\r\n            gap: 6px;\r\n        }\r\n        #card-generator-app .stat-box {\r\n            flex: 1;\r\n            padding: 4px;\r\n            border-radius: 6px;\r\n            text-align: center;\r\n            display: flex;\r\n            flex-direction: column;\r\n            justify-content: center;\r\n            border: 1px solid var(--border-color);\r\n            background: #ffffff;\r\n        }\r\n        #card-generator-app .stat-box.highlight {\r\n            border-color: var(--dark-blue);\r\n            color: var(--dark-blue);\r\n            background: #f8faff;\r\n        }\r\n        #card-generator-app .stat-box.success {\r\n            border-color: var(--success);\r\n            color: var(--success);\r\n            background: #f6fdf7;\r\n        }\r\n        #card-generator-app .stat-value {\r\n            font-size: 13px;\r\n            font-weight: 800;\r\n        }\r\n        #card-generator-app .stat-label {\r\n            font-size: 8px;\r\n            font-weight: 600;\r\n            opacity: 0.85;\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.3px;\r\n        }\r\n        \/* \u0424\u043e\u0440\u043c\u0438 \u0442\u0430 \u0431\u043b\u043e\u043a\u0438 *\/\r\n        #card-generator-app .form-group {\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 3px;\r\n        }\r\n        #card-generator-app .form-group label {\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            font-weight: 700;\r\n            color: var(--dark-blue);\r\n            font-size: 10px;\r\n            letter-spacing: 0.2px;\r\n        }\r\n        #card-generator-app .form-row {\r\n            display: flex;\r\n            gap: 6px;\r\n        }\r\n        #card-generator-app select {\r\n            width: 100%;\r\n            padding: 4px 8px;\r\n            border-radius: 6px;\r\n            border: 1px solid var(--border-color);\r\n            font-family: 'Montserrat', sans-serif;\r\n            font-size: 10.5px;\r\n            color: var(--text-main);\r\n            background-color: #fff;\r\n            outline: none;\r\n            height: 30px;\r\n        }\r\n        #card-generator-app select:focus,\r\n        #card-generator-app input:focus {\r\n            border-color: var(--primary);\r\n            box-shadow: 0 0 0 2px rgba(184, 0, 0, 0.12);\r\n        }\r\n        \/* --- \u0406\u041d\u041f\u0423\u0422-\u0422\u0410\u0411\u041b\u0418\u0426\u042f \u0423 \u041b\u0406\u0412\u0406\u0419 \u041f\u0410\u041d\u0415\u041b\u0406 --- *\/\r\n        #card-generator-app .grid-input-container {\r\n            border: 1.5px solid var(--border-color);\r\n            border-radius: 8px;\r\n            background: #ffffff;\r\n            height: 220px;\r\n            overflow-y: auto;\r\n            overflow-x: auto;\r\n            position: relative;\r\n            box-shadow: inset 0 1px 3px rgba(0,0,0,0.03);\r\n            display: flex;\r\n            flex-direction: column;\r\n        }\r\n        #card-generator-app .live-grid-table {\r\n            width: 100%;\r\n            border-collapse: collapse;\r\n            font-size: 10.5px;\r\n            min-width: 100%;\r\n        }\r\n        #card-generator-app .live-grid-table th {\r\n            position: sticky;\r\n            top: 0;\r\n            background: #f1f5f9;\r\n            color: var(--dark-blue);\r\n            font-weight: 700;\r\n            padding: 5px 6px;\r\n            border-bottom: 1.5px solid var(--border-color);\r\n            z-index: 2;\r\n            text-align: left;\r\n            font-size: 9.5px;\r\n            letter-spacing: 0.2px;\r\n            white-space: nowrap;\r\n        }\r\n        #card-generator-app .live-grid-table td {\r\n            padding: 2px 4px;\r\n            border-bottom: 1px solid #edf2f7;\r\n            vertical-align: middle;\r\n        }\r\n        #card-generator-app .live-grid-table tr:hover td {\r\n            background-color: #fafbfc;\r\n        }\r\n        #card-generator-app .live-grid-table tr.active-preview-row td {\r\n            background-color: #eff6ff;\r\n            border-bottom-color: #bfdbfe;\r\n        }\r\n        #card-generator-app .cell-input {\r\n            width: 100%;\r\n            border: 1px solid transparent;\r\n            background: transparent;\r\n            padding: 4px 5px;\r\n            border-radius: 4px;\r\n            font-family: 'Montserrat', sans-serif;\r\n            font-size: 10px;\r\n            color: var(--text-main);\r\n            outline: none;\r\n            transition: all 0.15s;\r\n            height: 24px;\r\n        }\r\n        #card-generator-app .cell-input:hover {\r\n            border-color: #cbd5e1;\r\n            background: #ffffff;\r\n        }\r\n        #card-generator-app .cell-input:focus {\r\n            border-color: var(--primary);\r\n            background: #ffffff;\r\n            box-shadow: 0 0 0 2px rgba(184, 0, 0, 0.12);\r\n        }\r\n        #card-generator-app .grid-actions-btn {\r\n            background: transparent;\r\n            border: none;\r\n            cursor: pointer;\r\n            padding: 3px;\r\n            border-radius: 4px;\r\n            color: #94a3b8;\r\n            display: inline-flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n        }\r\n        #card-generator-app .grid-actions-btn:hover {\r\n            color: var(--primary);\r\n            background: #fee2e2;\r\n        }\r\n        #card-generator-app .col-toggle-btn {\r\n            background: transparent;\r\n            border: 1px solid #cbd5e1;\r\n            cursor: pointer;\r\n            padding: 1px 4px;\r\n            border-radius: 4px;\r\n            color: #64748b;\r\n            font-size: 9px;\r\n            display: inline-flex;\r\n            align-items: center;\r\n            gap: 3px;\r\n        }\r\n        #card-generator-app .col-toggle-btn:hover {\r\n            color: var(--dark-blue);\r\n            background: #e2e8f0;\r\n        }\r\n        #card-generator-app .col-toggle-btn.active-hidden {\r\n            background: #fee2e2;\r\n            color: var(--primary);\r\n            border-color: #fca5a5;\r\n        }\r\n        \/* \u041a\u043d\u043e\u043f\u043a\u0438 \u0434\u0456\u0439 *\/\r\n        #card-generator-app .btn {\r\n            font-family: 'Montserrat', sans-serif;\r\n            font-weight: 700;\r\n            border: none;\r\n            border-radius: 6px;\r\n            cursor: pointer;\r\n            transition: all 0.2s;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 5px;\r\n            height: 30px;\r\n            font-size: 10.5px;\r\n        }\r\n        #card-generator-app .btn-primary {\r\n            background-color: var(--primary);\r\n            color: #ffffff;\r\n        }\r\n        #card-generator-app .btn-primary:hover:not(:disabled) {\r\n            background-color: var(--primary-hover);\r\n            transform: translateY(-1px);\r\n        }\r\n        #card-generator-app .btn-dark {\r\n            background-color: var(--dark-blue);\r\n            color: #ffffff;\r\n        }\r\n        #card-generator-app .btn-dark:hover:not(:disabled) {\r\n            background-color: var(--dark-blue-hover);\r\n            transform: translateY(-1px);\r\n        }\r\n        #card-generator-app .btn-secondary {\r\n            background-color: #ffffff;\r\n            color: var(--dark-blue);\r\n            border: 1px solid var(--border-color);\r\n        }\r\n        #card-generator-app .btn-secondary:hover:not(:disabled) {\r\n            border-color: var(--dark-blue);\r\n            background: #fdfdfd;\r\n        }\r\n        #card-generator-app .btn-clear {\r\n            background-color: #ffffff;\r\n            color: var(--primary);\r\n            border: 1px solid var(--primary);\r\n        }\r\n        #card-generator-app .btn-clear:hover {\r\n            background-color: var(--primary);\r\n            color: #ffffff;\r\n        }\r\n        #card-generator-app svg {\r\n            width: 14px !important;\r\n            height: 14px !important;\r\n            vertical-align: middle;\r\n            flex-shrink: 0;\r\n        }\r\n        \/* --- \u041f\u0420\u0410\u0412\u0410 \u041f\u0410\u041d\u0415\u041b\u042c --- *\/\r\n        #card-generator-app .right-panel {\r\n            flex: 1;\r\n            display: flex;\r\n            flex-direction: column;\r\n            background-color: var(--bg-color);\r\n            overflow: hidden;\r\n        }\r\n        #card-generator-app .preview-header {\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            background: #ffffff;\r\n            padding: 8px 16px;\r\n            border-bottom: 1px solid var(--border-color);\r\n            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\r\n            z-index: 5;\r\n            flex-wrap: wrap;\r\n            gap: 8px;\r\n        }\r\n        #card-generator-app .view-tabs {\r\n            display: flex;\r\n            background: #ebeef2;\r\n            padding: 3px;\r\n            border-radius: 8px;\r\n            gap: 4px;\r\n        }\r\n        #card-generator-app .tab-btn {\r\n            background: transparent;\r\n            border: none;\r\n            padding: 5px 12px;\r\n            border-radius: 6px;\r\n            font-size: 11px;\r\n            font-weight: 700;\r\n            color: #6b7280;\r\n            cursor: pointer;\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 6px;\r\n            transition: 0.2s;\r\n        }\r\n        #card-generator-app .tab-btn.active {\r\n            background: #ffffff;\r\n            color: var(--dark-blue);\r\n            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);\r\n        }\r\n        #card-generator-app .preview-viewport {\r\n            flex: 1;\r\n            overflow: auto;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            padding: 20px;\r\n            background-color: #e5e7eb;\r\n            position: relative;\r\n        }\r\n        #card-generator-app .sheet-a4 {\r\n            width: 100%;\r\n            max-width: 660px;\r\n            aspect-ratio: 1.414 \/ 1;\r\n            background: #ffffff;\r\n            border-radius: 6px;\r\n            box-shadow: 0 12px 35px rgba(0, 0, 0, 0.15);\r\n            display: flex;\r\n            flex-direction: column;\r\n            position: relative;\r\n            overflow: hidden;\r\n            border: 1px solid #d1d5db;\r\n            user-select: none;\r\n        }\r\n        \/* \u0417\u0430\u043a\u0440\u0456\u043f\u043b\u0435\u043d\u0456 \u043e\u0434\u043d\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u0456 \u0456\u043c\u0435\u043d\u0430 (EN \u0437\u0432\u0435\u0440\u0445\u0443, UA \u0437\u043d\u0438\u0437\u0443) *\/\r\n        #card-generator-app .sheet-half {\r\n            flex: 1;\r\n            display: flex;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            justify-content: flex-start;\r\n            padding: 24px 22px 10px 22px;\r\n            position: relative;\r\n            text-align: center;\r\n            box-sizing: border-box;\r\n            overflow: hidden;\r\n        }\r\n        #card-generator-app .sheet-half.top-mirrored {\r\n            transform: rotate(180deg);\r\n            border-bottom: 1px dashed #9ca3af;\r\n        }\r\n        #card-generator-app .sheet-name-en {\r\n            font-weight: 800;\r\n            line-height: 1.15;\r\n            margin-bottom: 16px;\r\n            white-space: nowrap;\r\n            overflow: hidden;\r\n            text-overflow: ellipsis;\r\n            width: 100%;\r\n            max-width: 96%;\r\n            flex-shrink: 0;\r\n            display: none;\r\n        }\r\n        #card-generator-app .sheet-name-ua {\r\n            font-weight: 800;\r\n            line-height: 1.15;\r\n            margin-bottom: 6px;\r\n            white-space: nowrap;\r\n            overflow: hidden;\r\n            text-overflow: ellipsis;\r\n            width: 100%;\r\n            max-width: 96%;\r\n            flex-shrink: 0;\r\n        }\r\n        #card-generator-app .sheet-pos {\r\n            font-weight: 500;\r\n            color: #4b5563;\r\n            max-width: 92%;\r\n            line-height: 1.35;\r\n            word-break: break-word;\r\n            transition: font-size 0.15s ease;\r\n        }\r\n        #card-generator-app .fold-line-badge {\r\n            position: absolute;\r\n            top: 50%;\r\n            left: 50%;\r\n            transform: translate(-50%, -50%);\r\n            background: #ffffff;\r\n            border: 1px dashed #9ca3af;\r\n            color: #6b7280;\r\n            font-size: 8.5px;\r\n            font-weight: 700;\r\n            padding: 2px 8px;\r\n            border-radius: 10px;\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 4px;\r\n            pointer-events: none;\r\n            z-index: 2;\r\n        }\r\n        #card-generator-app .table-container {\r\n            flex: 1;\r\n            overflow-y: auto;\r\n            padding: 15px;\r\n            background: #ffffff;\r\n            display: none;\r\n        }\r\n        #card-generator-app table.full-list-table {\r\n            width: 100%;\r\n            border-collapse: collapse;\r\n            font-size: 11px;\r\n        }\r\n        #card-generator-app table.full-list-table th {\r\n            background-color: #f8fafc;\r\n            color: var(--dark-blue);\r\n            text-align: left;\r\n            padding: 8px 10px;\r\n            border-bottom: 2px solid var(--border-color);\r\n            font-weight: 700;\r\n            white-space: nowrap;\r\n        }\r\n        #card-generator-app table.full-list-table td {\r\n            padding: 6px 10px;\r\n            border-bottom: 1px solid var(--border-color);\r\n            vertical-align: middle;\r\n        }\r\n        #card-generator-app .toast {\r\n            position: absolute;\r\n            bottom: 20px;\r\n            right: 20px;\r\n            background: #ffffff;\r\n            border-left: 5px solid var(--primary);\r\n            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);\r\n            padding: 8px 14px;\r\n            border-radius: 6px;\r\n            font-size: 11px;\r\n            font-weight: 600;\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 8px;\r\n            z-index: 100;\r\n            opacity: 0;\r\n            transform: translateY(15px);\r\n            transition: all 0.25s ease;\r\n            pointer-events: none;\r\n        }\r\n        #card-generator-app .toast.show {\r\n            opacity: 1;\r\n            transform: translateY(0);\r\n            pointer-events: auto;\r\n        }\r\n        #card-generator-app .toast.toast-success {\r\n            border-left-color: var(--success);\r\n            color: var(--success);\r\n        }\r\n        #card-generator-app .toast.toast-error {\r\n            border-left-color: var(--primary);\r\n            color: var(--primary);\r\n        }\r\n        #card-generator-app .modal-overlay {\r\n            position: absolute;\r\n            inset: 0;\r\n            background: rgba(10, 27, 63, 0.5);\r\n            backdrop-filter: blur(2px);\r\n            display: none;\r\n            align-items: center;\r\n            justify-content: center;\r\n            z-index: 200;\r\n            padding: 20px;\r\n        }\r\n        #card-generator-app .modal-card {\r\n            background: #ffffff;\r\n            border-radius: 10px;\r\n            width: 100%;\r\n            max-width: 500px;\r\n            box-shadow: 0 15px 35px rgba(0,0,0,0.2);\r\n            padding: 16px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 10px;\r\n        }\r\n        @media (max-width: 900px) {\r\n            #card-generator-app {\r\n                flex-direction: column;\r\n                height: auto;\r\n                max-height: none;\r\n            }\r\n            #card-generator-app .left-panel {\r\n                width: 100%;\r\n                border-right: none;\r\n                border-bottom: 1px solid var(--border-color);\r\n            }\r\n        }\r\n    <\/style>\r\n    <!-- \u041b\u0406\u0412\u0410 \u041f\u0410\u041d\u0415\u041b\u042c -->\r\n    <div class=\"left-panel\">\r\n        <div class=\"header-title\">\r\n            <i data-lucide=\"presentation\" style=\"color: var(--primary); width: 20px !important; height: 20px !important;\"><\/i>\r\n            <div>\r\n                <h2>\u041d\u0430\u0441\u0442\u0456\u043b\u044c\u043d\u0456 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0438<\/h2>\r\n                <div style=\"font-size: 9.5px; color: #6b7280; font-weight: 500;\">\u0414\u0432\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0456 \u043a\u0430\u0440\u0442\u043a\u0438 \u043d\u0430 \u0441\u0442\u0456\u043b \u0437 \u043b\u0456\u043d\u0456\u0454\u044e \u0437\u0433\u0438\u043d\u0443 (\u04104)<\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u0447 \u043c\u043e\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0443 (\u041f\u0440\u0430\u043f\u043e\u0440\u0438 UA \u0442\u0430 UK) -->\r\n        <div class=\"lang-mode-bar\">\r\n            <button type=\"button\" class=\"lang-pill lang-pill-ua active\" id=\"btnModeSingle\" onclick=\"setBilingualMode(false)\" title=\"\u0420\u0435\u0436\u0438\u043c \u043e\u0434\u043d\u0456\u0454\u0457 \u043c\u043e\u0432\u0438 (\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430)\">\r\n                <svg class=\"lang-flag-svg\" viewBox=\"0 0 30 20\">\r\n                    <rect width=\"30\" height=\"10\" fill=\"#0057B7\"\/>\r\n                    <rect y=\"10\" width=\"30\" height=\"10\" fill=\"#FFD700\"\/>\r\n                <\/svg>\r\n                <span>UA (1 \u043c\u043e\u0432\u0430)<\/span>\r\n            <\/button>\r\n            <button type=\"button\" class=\"lang-pill lang-pill-en\" id=\"btnModeBi\" onclick=\"setBilingualMode(true)\" title=\"\u041c\u0456\u0436\u043d\u0430\u0440\u043e\u0434\u043d\u0438\u0439 \u0434\u0432\u043e\u043c\u043e\u0432\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c (English + \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430)\">\r\n                <svg class=\"lang-flag-svg\" viewBox=\"0 0 60 30\">\r\n                    <clipPath id=\"uk-clip\"><path d=\"M0,0 v30 h60 v-30 z\"\/><\/clipPath>\r\n                    <clipPath id=\"uk-diag\"><path d=\"M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z\"\/><\/clipPath>\r\n                    <g clip-path=\"url(#uk-clip)\">\r\n                        <path d=\"M0,0 v30 h60 v-30 z\" fill=\"#012169\"\/>\r\n                        <path d=\"M0,0 L60,30 M60,0 L0,30\" stroke=\"#fff\" stroke-width=\"6\"\/>\r\n                        <path d=\"M0,0 L60,30 M60,0 L0,30\" clip-path=\"url(#uk-diag)\" stroke=\"#C8102E\" stroke-width=\"4\"\/>\r\n                        <path d=\"M30,0 v30 M0,15 h60\" stroke=\"#fff\" stroke-width=\"10\"\/>\r\n                        <path d=\"M30,0 v30 M0,15 h60\" stroke=\"#C8102E\" stroke-width=\"6\"\/>\r\n                    <\/g>\r\n                <\/svg>\r\n                <span>EN + UA (2 \u043c\u043e\u0432\u0438)<\/span>\r\n            <\/button>\r\n        <\/div>\r\n        <!-- \u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0430 \u0433\u0430\u0440\u044f\u0447\u0438\u0445 \u043a\u043b\u0430\u0432\u0456\u0448 -->\r\n        <div class=\"shortcut-badge-bar\">\r\n            <span><span class=\"kbd-tag\">Tab<\/span>\/<span class=\"kbd-tag\">Enter<\/span> \u043a\u043b\u0456\u0442\u0438\u043d\u043a\u0438<\/span>\r\n            <span><span class=\"kbd-tag\">Ctrl+V<\/span> \u0432\u0441\u0442\u0430\u0432\u043a\u0430<\/span>\r\n            <span><span class=\"kbd-tag\">Ctrl+Z\/Y<\/span> \u0456\u0441\u0442\u043e\u0440\u0456\u044f<\/span>\r\n            <span><span class=\"kbd-tag\">\u2190<\/span>\/<span class=\"kbd-tag\">\u2192<\/span> \u0440\u0435\u0436\u0438\u043c<\/span>\r\n            <span><span class=\"kbd-tag\">\u2191<\/span>\/<span class=\"kbd-tag\">\u2193<\/span> \u043a\u0430\u0440\u0442\u043a\u0430<\/span>\r\n        <\/div>\r\n        <!-- \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 -->\r\n        <div class=\"stats-panel\">\r\n            <div class=\"stat-box highlight\">\r\n                <div class=\"stat-value\" id=\"stat-total\">0<\/div>\r\n                <div class=\"stat-label\">\u0412\u0441\u044c\u043e\u0433\u043e \u043e\u0441\u0456\u0431<\/div>\r\n            <\/div>\r\n            <div class=\"stat-box success\">\r\n                <div class=\"stat-value\" id=\"stat-selected\">0<\/div>\r\n                <div class=\"stat-label\">\u041e\u0431\u0440\u0430\u043d\u043e<\/div>\r\n            <\/div>\r\n            <div class=\"stat-box\">\r\n                <div class=\"stat-value\" id=\"stat-pages\">0<\/div>\r\n                <div class=\"stat-label\">\u0421\u0442\u043e\u0440\u0456\u043d\u043e\u043a \u04104<\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u0416\u0418\u0412\u0410 \u0406\u041d\u041f\u0423\u0422-\u0422\u0410\u0411\u041b\u0418\u0426\u042f -->\r\n        <div class=\"form-group\">\r\n            <label>\r\n                <span><i data-lucide=\"table-properties\" style=\"margin-right: 4px;\"><\/i>\u0422\u0430\u0431\u043b\u0438\u0446\u044f \u0434\u0430\u043d\u0438\u0445<\/span>\r\n                <span id=\"counter-hint\" style=\"font-size: 9.5px; font-weight: 600; color: #6b7280;\">0 \u043e\u0441\u0456\u0431<\/span>\r\n            <\/label>\r\n            <div class=\"grid-input-container\" id=\"gridContainer\" tabindex=\"0\">\r\n                <table class=\"live-grid-table\" id=\"liveGridTable\">\r\n                    <thead>\r\n                        <tr id=\"gridHeaderRow\">\r\n                            <!-- \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u0443\u044e\u0442\u044c\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u043e -->\r\n                        <\/tr>\r\n                    <\/thead>\r\n                    <tbody id=\"gridTbody\">\r\n                        <!-- \u0406\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u0456 \u043a\u043b\u0456\u0442\u0438\u043d\u043a\u0438 -->\r\n                    <\/tbody>\r\n                <\/table>\r\n            <\/div>\r\n            <!-- \u0422\u0443\u043b\u0431\u0430\u0440 \u0434\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0456 -->\r\n            <div style=\"display: flex; gap: 4px; margin-top: 2px;\">\r\n                <button class=\"btn btn-dark\" style=\"flex: 1; height: 28px; font-size: 10px;\" onclick=\"addNewEmptyRow(true)\" title=\"\u0414\u043e\u0434\u0430\u0442\u0438 \u043d\u043e\u0432\u0438\u0439 \u0440\u044f\u0434\u043e\u043a (Tab\/Enter)\">\r\n                    <i data-lucide=\"plus\"><\/i> + \u0420\u044f\u0434\u043e\u043a\r\n                <\/button>\r\n                <button class=\"btn btn-secondary\" style=\"flex: 1.1; height: 28px; font-size: 10px;\" onclick=\"openPasteModal()\" title=\"\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0442\u0435\u043a\u0441\u0442 \u0441\u043f\u0438\u0441\u043a\u043e\u043c (Ctrl+V)\">\r\n                    <i data-lucide=\"clipboard-paste\"><\/i> \u0412\u0441\u0442\u0430\u0432\u0438\u0442\u0438\r\n                <\/button>\r\n                <button class=\"btn btn-secondary\" id=\"btnTogglePosCol\" style=\"flex: 1; height: 28px; font-size: 10px; padding: 0 4px;\" onclick=\"togglePositionColumn()\" title=\"\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u043e\u0441\u0430\u0434\u0443\">\r\n                    <i data-lucide=\"eye\"><\/i> <span>\u041f\u043e\u0441\u0430\u0434\u0430<\/span>\r\n                <\/button>\r\n                <button class=\"btn btn-secondary\" style=\"flex: 1; height: 28px; font-size: 10px; padding: 0 4px;\" onclick=\"loadDemoData()\" title=\"\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0437\u0440\u0430\u0437\u043e\u043a \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432\">\r\n                    <i data-lucide=\"sparkles\"><\/i> <span>\u0417\u0440\u0430\u0437\u043e\u043a<\/span>\r\n                <\/button>\r\n                <button class=\"btn btn-clear\" style=\"height: 28px; font-size: 10px; padding: 0 6px;\" onclick=\"clearAllData()\" title=\"\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044e\">\r\n                    <i data-lucide=\"trash-2\"><\/i>\r\n                <\/button>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u0413\u043d\u0443\u0447\u043a\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0456\u043c\u0435\u043d\u0456 -->\r\n        <div class=\"form-group\">\r\n            <label><i data-lucide=\"type\" style=\"margin-right: 4px;\"><\/i>\u0424\u043e\u0440\u043c\u0430\u0442 \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u041f\u0406\u0411<\/label>\r\n            <select id=\"nameFormatSelect\" onchange=\"renderCurrentView()\">\r\n                <optgroup label=\"\u0421\u0443\u0447\u0430\u0441\u043d\u0456 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438 (\u0406\u043c'\u044f + \u041f\u0420\u0406\u0417\u0412\u0418\u0429\u0415)\">\r\n                    <option value=\"first_LAST\" selected>\u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \/ Oleksandr KOVALCHUK<\/option>\r\n                    <option value=\"LAST_first\">\u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \/ KOVALCHUK Oleksandr<\/option>\r\n                    <option value=\"first_middle_LAST\">\u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0406\u0432\u0430\u043d\u043e\u0432\u0438\u0447 \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a<\/option>\r\n                    <option value=\"LAST_first_middle\">\u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0406\u0432\u0430\u043d\u043e\u0432\u0438\u0447 (\u041e\u0444\u0456\u0446\u0456\u0439\u043d\u0438\u0439)<\/option>\r\n                <\/optgroup>\r\n                <optgroup label=\"\u0424\u043e\u0440\u043c\u0430\u0442\u0438 \u0437 \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0430\u043c\u0438\">\r\n                    <option value=\"initials_LAST\">\u041e. \u0406. \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \/ O. KOVALCHUK<\/option>\r\n                    <option value=\"initial_dot_LAST\">\u041e. \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \/ O. KOVALCHUK<\/option>\r\n                    <option value=\"LAST_initials\">\u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \u041e. \u0406. \/ KOVALCHUK O.<\/option>\r\n                    <option value=\"LAST_initial\">\u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \u041e.<\/option>\r\n                    <option value=\"initials_space_last\">\u041e. \u0406. \u041a\u043e\u0432\u0430\u043b\u044c\u0447\u0443\u043a \/ O. Kovalchuk<\/option>\r\n                    <option value=\"last_initials_title\">\u041a\u043e\u0432\u0430\u043b\u044c\u0447\u0443\u043a \u041e. \u0406. \/ Kovalchuk O.<\/option>\r\n                <\/optgroup>\r\n                <optgroup label=\"\u0406\u043d\u0448\u0456 \u0441\u0442\u0438\u043b\u0456\">\r\n                    <option value=\"title_case\">\u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u041a\u043e\u0432\u0430\u043b\u044c\u0447\u0443\u043a \/ Oleksandr Kovalchuk<\/option>\r\n                    <option value=\"all_caps\">\u041e\u041b\u0415\u041a\u0421\u0410\u041d\u0414\u0420 \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a \/ OLEKSANDR KOVALCHUK<\/option>\r\n                    <option value=\"as_is\">\u042f\u043a \u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0456 (\u0411\u0435\u0437 \u0437\u043c\u0456\u043d)<\/option>\r\n                <\/optgroup>\r\n            <\/select>\r\n        <\/div>\r\n        <!-- \u0421\u0442\u0438\u043b\u044c \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f: \u041a\u043e\u043b\u0456\u0440 (\u0437 \u0447\u0435\u0440\u0432\u043e\u043d\u0438\u043c EN \/ \u0447\u043e\u0440\u043d\u0438\u043c UA) + \u0420\u043e\u0437\u043c\u0456\u0440 \u0448\u0440\u0438\u0444\u0442\u0443 -->\r\n        <div class=\"form-row\">\r\n            <div class=\"form-group\" style=\"flex: 1;\">\r\n                <label>\u041a\u043e\u043b\u0456\u0440 \u0442\u0435\u043a\u0441\u0442\u0443<\/label>\r\n                <select id=\"themeColorSelect\" onchange=\"renderCurrentView()\">\r\n                    <option value=\"classic\" selected>\u041a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0439 \u0447\u043e\u0440\u043d\u0438\u0439<\/option>\r\n                    <option value=\"duo_crimson_black\">\u0427\u0435\u0440\u0432\u043e\u043d\u0438\u0439 EN + \u0427\u043e\u0440\u043d\u0438\u0439 UA (#B80000 \/ #000)<\/option>\r\n                    <option value=\"corporate\">\u0422\u0435\u043c\u043d\u043e-\u0441\u0438\u043d\u0456\u0439 (#0A1B3F)<\/option>\r\n                    <option value=\"crimson\">\u0411\u043e\u0440\u0434\u043e\u0432\u0438\u0439 (#B80000)<\/option>\r\n                <\/select>\r\n            <\/div>\r\n            <div class=\"form-group\" style=\"flex: 1.25;\">\r\n                <label>\r\n                    <span>\u0420\u043e\u0437\u043c\u0456\u0440 \u0448\u0440\u0438\u0444\u0442\u0443<\/span>\r\n                    <span id=\"fontHint\" style=\"font-size: 8.5px; font-weight: 600; color: #64748b;\">(\u0430\u0432\u0442\u043e)<\/span>\r\n                <\/label>\r\n                <div style=\"display: flex; gap: 4px; align-items: center;\">\r\n                    <select id=\"fontSizeSelect\" onchange=\"handleFontSizeSelectChange()\" style=\"flex: 1;\">\r\n                        <option value=\"auto\" selected>\u0410\u0432\u0442\u043e (\u041d\u0430\u0439\u0431\u0456\u043b\u044c\u0448\u0456)<\/option>\r\n                        <option value=\"large\">\u0412\u0435\u043b\u0438\u043a\u0438\u0439 (85%)<\/option>\r\n                        <option value=\"medium\">\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 (70%)<\/option>\r\n                        <option value=\"small\">\u0414\u0440\u0456\u0431\u043d\u0438\u0439 (55%)<\/option>\r\n                        <option value=\"custom\">\u0412\u043b\u0430\u0441\u043d\u0438\u0439<\/option>\r\n                    <\/select>\r\n                    <div style=\"display: flex; align-items: center; background: #fff; border: 1px solid var(--border-color); border-radius: 6px; padding: 0 4px; height: 30px; width: 62px; flex-shrink: 0;\" title=\"\u0420\u043e\u0437\u043c\u0456\u0440 \u0448\u0440\u0438\u0444\u0442\u0443 \u0432 \u043f\u0443\u043d\u043a\u0442\u0430\u0445 (pt)\">\r\n                        <input type=\"number\" id=\"fontSizeNumber\" min=\"14\" max=\"75\" step=\"1\" value=\"54\" \r\n                            oninput=\"handleFontSizeNumberInput(this.value)\" \r\n                            style=\"width: 100%; border: none; outline: none; font-size: 11px; font-weight: 700; font-family: 'Montserrat', sans-serif; text-align: center; padding: 0; color: #000000; background: transparent;\">\r\n                        <span style=\"font-size: 8.5px; font-weight: 700; color: #94a3b8; user-select: none;\">pt<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u0413\u043e\u043b\u043e\u0432\u043d\u0456 \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u0456\u0457 -->\r\n        <div style=\"display: flex; flex-direction: column; gap: 6px; margin-top: 4px;\">\r\n            <button class=\"btn btn-primary\" onclick=\"generatePPTX()\" style=\"height: 38px; font-size: 12px;\">\r\n                <i data-lucide=\"download\"><\/i> \u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0438 (.PPTX)\r\n            <\/button>\r\n            <button class=\"btn btn-secondary\" onclick=\"printBrowserCards()\" style=\"height: 32px;\">\r\n                <i data-lucide=\"printer\"><\/i> \u0428\u0432\u0438\u0434\u043a\u0438\u0439 \u0434\u0440\u0443\u043a \/ PDF\r\n            <\/button>\r\n        <\/div>\r\n    <\/div>\r\n    <!-- \u041f\u0420\u0410\u0412\u0410 \u041f\u0410\u041d\u0415\u041b\u042c -->\r\n    <div class=\"right-panel\">\r\n        <div class=\"preview-header\">\r\n            <div class=\"view-tabs\">\r\n                <button class=\"tab-btn active\" id=\"tabBtnPreview\" onclick=\"switchTab('preview')\">\r\n                    <i data-lucide=\"layout\"><\/i> \u041c\u0430\u043a\u0435\u0442 \u043a\u0430\u0440\u0442\u043a\u0438 [\u2190]\r\n                <\/button>\r\n                <button class=\"tab-btn\" id=\"tabBtnTable\" onclick=\"switchTab('table')\">\r\n                    <i data-lucide=\"table\"><\/i> \u0420\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044f [\u2192] (<span id=\"tabCount\">0<\/span>)\r\n                <\/button>\r\n            <\/div>\r\n            <!-- \u041d\u0430\u0432\u0456\u0433\u0430\u0446\u0456\u044f \u043c\u0456\u0436 \u043a\u0430\u0440\u0442\u043a\u0430\u043c\u0438 -->\r\n            <div id=\"navControls\" style=\"display: flex; align-items: center; gap: 6px;\">\r\n                <button class=\"btn btn-secondary\" style=\"height: 28px; width: 28px; padding: 0;\" onclick=\"prevCard()\" title=\"\u041f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u044f \u043a\u0430\u0440\u0442\u043a\u0430 [\u2191]\">\r\n                    <i data-lucide=\"chevron-left\"><\/i>\r\n                <\/button>\r\n                <span id=\"navCounter\" style=\"font-size: 11px; font-weight: 700; min-width: 55px; text-align: center;\">0 \/ 0<\/span>\r\n                <button class=\"btn btn-secondary\" style=\"height: 28px; width: 28px; padding: 0;\" onclick=\"nextCard()\" title=\"\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0430 \u043a\u0430\u0440\u0442\u043a\u0430 [\u2193]\">\r\n                    <i data-lucide=\"chevron-right\"><\/i>\r\n                <\/button>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u0412\u043a\u043b\u0430\u0434\u043a\u0430 1: \u041c\u0430\u043a\u0435\u0442 \u043a\u0430\u0440\u0442\u043a\u0438 (EN \u043f\u0435\u0440\u0448\u0430, UA \u0434\u0440\u0443\u0433\u0430, \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u0439 \u0440\u044f\u0434\u043e\u043a \u043c\u0456\u0436 \u043d\u0438\u043c\u0438) -->\r\n        <div class=\"preview-viewport\" id=\"previewViewport\">\r\n            <div class=\"sheet-a4\" id=\"sheetA4\">\r\n                <div class=\"sheet-half top-mirrored\">\r\n                    <div class=\"sheet-name-en\" id=\"previewNameEnTop\">Valerii KOPIIKA<\/div>\r\n                    <div class=\"sheet-name-ua\" id=\"previewNameUaTop\">\u0412\u0430\u043b\u0435\u0440\u0456\u0439 \u041a\u041e\u041f\u0406\u0419\u041a\u0410<\/div>\r\n                    <div class=\"sheet-pos\" id=\"previewPosTop\">\u0412.\u043e. \u0440\u0435\u043a\u0442\u043e\u0440\u0430, \u0434\u043e\u043a\u0442\u043e\u0440 \u043f\u043e\u043b\u0456\u0442\u0438\u0447\u043d\u0438\u0445 \u043d\u0430\u0443\u043a, \u043f\u0440\u043e\u0444\u0435\u0441\u043e\u0440<\/div>\r\n                <\/div>\r\n                <div class=\"fold-line-badge\">\r\n                    <i data-lucide=\"scissors\" style=\"width: 10px !important; height: 10px !important;\"><\/i> \u041b\u0456\u043d\u0456\u044f \u0437\u0433\u0438\u043d\u0443 (\u0446\u0435\u043d\u0442\u0440 \u043b\u0438\u0441\u0442\u0430 \u04104)\r\n                <\/div>\r\n                <div class=\"sheet-half\">\r\n                    <div class=\"sheet-name-en\" id=\"previewNameEnBottom\">Valerii KOPIIKA<\/div>\r\n                    <div class=\"sheet-name-ua\" id=\"previewNameUaBottom\">\u0412\u0430\u043b\u0435\u0440\u0456\u0439 \u041a\u041e\u041f\u0406\u0419\u041a\u0410<\/div>\r\n                    <div class=\"sheet-pos\" id=\"previewPosBottom\">\u0412.\u043e. \u0440\u0435\u043a\u0442\u043e\u0440\u0430, \u0434\u043e\u043a\u0442\u043e\u0440 \u043f\u043e\u043b\u0456\u0442\u0438\u0447\u043d\u0438\u0445 \u043d\u0430\u0443\u043a, \u043f\u0440\u043e\u0444\u0435\u0441\u043e\u0440<\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <!-- \u0412\u043a\u043b\u0430\u0434\u043a\u0430 2: \u0420\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044f (\u0437 \u043a\u043d\u043e\u043f\u043a\u043e\u044e \u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u043e\u0441\u0430\u0434\u0438 \u0443 \u0448\u0430\u043f\u0446\u0456 \u0442\u0430 \u043f\u0430\u043d\u0435\u043b\u0456) -->\r\n        <div class=\"table-container\" id=\"tableContainer\">\r\n            <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; gap: 8px; flex-wrap: wrap;\">\r\n                <input type=\"text\" id=\"tableSearch\" placeholder=\"\u0428\u0443\u043a\u0430\u0442\u0438 \u0443 \u0441\u043f\u0438\u0441\u043a\u0443...\" oninput=\"renderExpandedTable()\" style=\"max-width: 250px; height: 30px; font-size: 11px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--border-color);\">\r\n                <div style=\"display: flex; gap: 6px;\">\r\n                    <button class=\"btn btn-secondary\" id=\"btnTogglePosColExp\" style=\"height: 30px; font-size: 11px;\" onclick=\"togglePositionColumn()\" title=\"\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\">\r\n                        <i data-lucide=\"eye\"><\/i> <span>\u041f\u043e\u0441\u0430\u0434\u0430<\/span>\r\n                    <\/button>\r\n                    <button class=\"btn btn-secondary\" style=\"height: 30px; font-size: 11px;\" onclick=\"toggleSelectAll()\">\r\n                        <i data-lucide=\"check-square\"><\/i> \u041e\u0431\u0440\u0430\u0442\u0438\/\u0437\u043d\u044f\u0442\u0438 \u0432\u0441\u0456\r\n                    <\/button>\r\n                <\/div>\r\n            <\/div>\r\n            <table class=\"full-list-table\">\r\n                <thead>\r\n                    <tr id=\"expandedHeaderRow\">\r\n                        <!-- \u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u043e -->\r\n                    <\/tr>\r\n                <\/thead>\r\n                <tbody id=\"expandedTableBody\">\r\n                    <!-- \u0417\u0430\u043f\u043e\u0432\u043d\u044e\u0454\u0442\u044c\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u043e -->\r\n                <\/tbody>\r\n            <\/table>\r\n        <\/div>\r\n    <\/div>\r\n    <!-- \u041c\u043e\u0434\u0430\u043b\u044c\u043d\u0435 \u0432\u0456\u043a\u043d\u043e \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0443 -->\r\n    <div id=\"pasteModal\" class=\"modal-overlay\">\r\n        <div class=\"modal-card\">\r\n            <div style=\"display: flex; justify-content: space-between; align-items: center;\">\r\n                <span style=\"font-weight: 700; font-size: 13px; color: var(--dark-blue);\"><i data-lucide=\"clipboard-paste\" style=\"margin-right: 4px;\"><\/i>\u0412\u0441\u0442\u0430\u0432\u043a\u0430 \u0441\u043f\u0438\u0441\u043a\u0443 (Excel, Word, \u0422\u0435\u043a\u0441\u0442)<\/span>\r\n                <button class=\"grid-actions-btn\" onclick=\"closePasteModal()\"><i data-lucide=\"x\"><\/i><\/button>\r\n            <\/div>\r\n            <textarea id=\"modalPasteArea\" style=\"width: 100%; height: 160px; font-family: 'Montserrat', sans-serif; font-size: 11px; padding: 8px; border: 1px solid var(--border-color); border-radius: 6px; outline: none; resize: vertical;\" placeholder=\"\u0412\u0441\u0442\u0430\u0432\u0442\u0435 \u0441\u043a\u043e\u043f\u0456\u0439\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0435\u043a\u0441\u0442 \u0441\u044e\u0434\u0438...&#10;&#10;\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0432\u0430\u043d\u0456 \u0444\u043e\u0440\u043c\u0430\u0442\u0438 \u0437 Excel:&#10;1) \u0414\u0432\u043e\u043c\u043e\u0432\u043d\u0438\u0439: \u041f\u0406\u0411 (EN) [Tab] \u041f\u0406\u0411 (UA)&#10;2) \u041f\u043e\u0432\u043d\u0438\u0439: \u041f\u0406\u0411 (EN) [Tab] \u041f\u0406\u0411 (UA) [Tab] \u041f\u043e\u0441\u0430\u0434\u0430&#10;3) \u0417\u0432\u0438\u0447\u0430\u0439\u043d\u0438\u0439: \u041f\u0406\u0411 [Tab] \u041f\u043e\u0441\u0430\u0434\u0430\"><\/textarea>\r\n            <div style=\"display: flex; justify-content: flex-end; gap: 8px;\">\r\n                <button class=\"btn btn-secondary\" onclick=\"closePasteModal()\">\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438<\/button>\r\n                <button class=\"btn btn-primary\" onclick=\"applyModalPaste()\">\u041e\u0431\u0440\u043e\u0431\u0438\u0442\u0438 \u0442\u0430 \u0437\u0430\u043f\u043e\u0432\u043d\u0438\u0442\u0438<\/button>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n    <!-- Toast \u043e\u0432\u0435\u0440\u043b\u0435\u0439 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c -->\r\n    <div id=\"cgToast\" class=\"toast\">\r\n        <i data-lucide=\"info\" id=\"toastIcon\"><\/i>\r\n        <span id=\"toastMsg\">\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f<\/span>\r\n    <\/div>\r\n<\/div>\r\n<script>\r\n    \/\/ --- \u0421\u0422\u0410\u041d \u0414\u041e\u0414\u0410\u0422\u041a\u0423 ---\r\n    let peopleList = [];\r\n    let currentIndex = 0;\r\n    let isBilingual = false; \/\/ \u0420\u0435\u0436\u0438\u043c: false = 1 \u043c\u043e\u0432\u0430 (UA), true = 2 \u043c\u043e\u0432\u0438 (EN + UA)\r\n    let isPositionHidden = false; \/\/ \u0412\u0438\u0434\u0438\u043c\u0456\u0441\u0442\u044c \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u043f\u043e\u0441\u0430\u0434\u0438\r\n    const undoStack = [];\r\n    const redoStack = [];\r\n    const MAX_HISTORY = 40;\r\n    \/\/ \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0456\u0439\u043d\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a: \u041f\u0435\u0440\u0448\u0456 7 \u043f\u0440\u043e\u0432\u0456\u0434\u043d\u0438\u0445 \u043a\u0435\u0440\u0456\u0432\u043d\u0438\u0445 \u043f\u043e\u0441\u0430\u0434\r\n    const demoPersons = [\r\n        { nameEn: \"Kopiika Valerii\", name: \"\u041a\u043e\u043f\u0456\u0439\u043a\u0430 \u0412\u0430\u043b\u0435\u0440\u0456\u0439 \u0412\u043e\u043b\u043e\u0434\u0438\u043c\u0438\u0440\u043e\u0432\u0438\u0447\", position: \"\u0412.\u043e. \u0440\u0435\u043a\u0442\u043e\u0440\u0430, \u0434\u043e\u043a\u0442\u043e\u0440 \u043f\u043e\u043b\u0456\u0442\u0438\u0447\u043d\u0438\u0445 \u043d\u0430\u0443\u043a, \u043f\u0440\u043e\u0444\u0435\u0441\u043e\u0440\" },\r\n        { nameEn: \"Pohoretskyi Mykola\", name: \"\u041f\u043e\u0433\u043e\u0440\u0435\u0446\u044c\u043a\u0438\u0439 \u041c\u0438\u043a\u043e\u043b\u0430 \u0410\u043d\u0430\u0442\u043e\u043b\u0456\u0439\u043e\u0432\u0438\u0447\", position: \"\u041f\u0435\u0440\u0448\u0438\u0439 \u043f\u0440\u043e\u0440\u0435\u043a\u0442\u043e\u0440, \u0434\u043e\u043a\u0442\u043e\u0440 \u044e\u0440\u0438\u0434\u0438\u0447\u043d\u0438\u0445 \u043d\u0430\u0443\u043a, \u043f\u0440\u043e\u0444\u0435\u0441\u043e\u0440\" },\r\n        { nameEn: \"Zhylinska Oksana\", name: \"\u0416\u0438\u043b\u0456\u043d\u0441\u044c\u043a\u0430 \u041e\u043a\u0441\u0430\u043d\u0430 \u0406\u0432\u0430\u043d\u0456\u0432\u043d\u0430\", position: \"\u041f\u0440\u043e\u0440\u0435\u043a\u0442\u043e\u0440\u043a\u0430 \u0437 \u043d\u0430\u0443\u043a\u043e\u0432\u043e\u0457 \u0440\u043e\u0431\u043e\u0442\u0438\" },\r\n        { nameEn: \"Hozhyk Andrii\", name: \"\u0413\u043e\u0436\u0438\u043a \u0410\u043d\u0434\u0440\u0456\u0439 \u041f\u0435\u0442\u0440\u043e\u0432\u0438\u0447\", position: \"\u041f\u0440\u043e\u0440\u0435\u043a\u0442\u043e\u0440 \u0437 \u043d\u0430\u0443\u043a\u043e\u0432\u043e-\u043f\u0435\u0434\u0430\u0433\u043e\u0433\u0456\u0447\u043d\u043e\u0457 \u0440\u043e\u0431\u043e\u0442\u0438\" },\r\n        { nameEn: \"Rozhko Oleksandr\", name: \"\u0420\u043e\u0436\u043a\u043e \u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0414\u043c\u0438\u0442\u0440\u043e\u0432\u0438\u0447\", position: \"\u041f\u0440\u043e\u0440\u0435\u043a\u0442\u043e\u0440 \u0437 \u043d\u0430\u0443\u043a\u043e\u0432\u043e-\u043f\u0435\u0434\u0430\u0433\u043e\u0433\u0456\u0447\u043d\u043e\u0457 \u0440\u043e\u0431\u043e\u0442\u0438 (\u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u043d\u0438\u0439 \u0440\u043e\u0437\u0432\u0438\u0442\u043e\u043a)\" },\r\n        { nameEn: \"Popko Vadym\", name: \"\u041f\u043e\u043f\u043a\u043e \u0412\u0430\u0434\u0438\u043c \u0412\u0456\u043a\u0442\u043e\u0440\u043e\u0432\u0438\u0447\", position: \"\u041f\u0440\u043e\u0440\u0435\u043a\u0442\u043e\u0440 \u0437 \u043d\u0430\u0443\u043a\u043e\u0432\u043e-\u043f\u0435\u0434\u0430\u0433\u043e\u0433\u0456\u0447\u043d\u043e\u0457 \u0440\u043e\u0431\u043e\u0442\u0438 (\u043c\u0456\u0436\u043d\u0430\u0440\u043e\u0434\u043d\u0456 \u0437\u0432'\u044f\u0437\u043a\u0438)\" },\r\n        { nameEn: \"Diachenko Svitlana\", name: \"\u0414\u044f\u0447\u0435\u043d\u043a\u043e \u0421\u0432\u0456\u0442\u043b\u0430\u043d\u0430 \u0406\u0432\u0430\u043d\u0456\u0432\u043d\u0430\", position: \"\u0423\u0447\u0435\u043d\u0438\u0439 \u0441\u0435\u043a\u0440\u0435\u0442\u0430\u0440 \u0412\u0447\u0435\u043d\u043e\u0457 \u0440\u0430\u0434\u0438 \u0423\u043d\u0456\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0443\" }\r\n    ];\r\n    \/\/ \u0422\u0440\u0430\u043d\u0441\u043b\u0456\u0442\u0435\u0440\u0430\u0446\u0456\u044f \u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0438\u0445 \u043b\u0456\u0442\u0435\u0440 \u0437\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u041a\u041c\u0423 (\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0430 \u211655)\r\n    function transliterateUkr(text) {\r\n        if (!text) return \"\";\r\n        const rules = {\r\n            '\u0410': 'A', '\u0430': 'a', '\u0411': 'B', '\u0431': 'b', '\u0412': 'V', '\u0432': 'v',\r\n            '\u0413': 'H', '\u0433': 'h', '\u0490': 'G', '\u0491': 'g', '\u0414': 'D', '\u0434': 'd',\r\n            '\u0415': 'E', '\u0435': 'e', '\u0404': 'Ye', '\u0454': 'ie', '\u0416': 'Zh', '\u0436': 'zh',\r\n            '\u0417': 'Z', '\u0437': 'z', '\u0418': 'Y', '\u0438': 'y', '\u0406': 'I', '\u0456': 'i',\r\n            '\u0407': 'Yi', '\u0457': 'i', '\u0419': 'Y', '\u0439': 'i', '\u041a': 'K', '\u043a': 'k',\r\n            '\u041b': 'L', '\u043b': 'l', '\u041c': 'M', '\u043c': 'm', '\u041d': 'N', '\u043d': 'n',\r\n            '\u041e': 'O', '\u043e': 'o', '\u041f': 'P', '\u043f': 'p', '\u0420': 'R', '\u0440': 'r',\r\n            '\u0421': 'S', '\u0441': 's', '\u0422': 'T', '\u0442': 't', '\u0423': 'U', '\u0443': 'u',\r\n            '\u0424': 'F', '\u0444': 'f', '\u0425': 'Kh', '\u0445': 'kh', '\u0426': 'Ts', '\u0446': 'ts',\r\n            '\u0427': 'Ch', '\u0447': 'ch', '\u0428': 'Sh', '\u0448': 'sh', '\u0429': 'Shch', '\u0449': 'shch',\r\n            '\u042e': 'Yu', '\u044e': 'iu', '\u042f': 'Ya', '\u044f': 'ia', '\u044c': '', '\u042c': '', \"'\": '', \"\u2019\": '', \"`\": ''\r\n        };\r\n        return text.split(' ').map(word => {\r\n            let res = '';\r\n            for (let i = 0; i < word.length; i++) {\r\n                let char = word[i];\r\n                if (i === 0) {\r\n                    if (char === '\u0404') res += 'Ye';\r\n                    else if (char === '\u0454') res += 'ye';\r\n                    else if (char === '\u0407') res += 'Yi';\r\n                    else if (char === '\u0457') res += 'yi';\r\n                    else if (char === '\u0419') res += 'Y';\r\n                    else if (char === '\u0439') res += 'y';\r\n                    else if (char === '\u042e') res += 'Yu';\r\n                    else if (char === '\u044e') res += 'yu';\r\n                    else if (char === '\u042f') res += 'Ya';\r\n                    else if (char === '\u044f') res += 'ya';\r\n                    else res += rules[char] !== undefined ? rules[char] : char;\r\n                } else {\r\n                    res += rules[char] !== undefined ? rules[char] : char;\r\n                }\r\n            }\r\n            return res;\r\n        }).join(' ');\r\n    }\r\n    \/\/ --- \u0415\u0421\u0422\u0415\u0422\u0418\u0427\u041d\u0415 \u0424\u041e\u0420\u041c\u0410\u0422\u0423\u0412\u0410\u041d\u041d\u042f \u041f\u041e\u0421\u0410\u0414\u0418 (\u0410\u0412\u0422\u041e\u041c\u0410\u0422\u0418\u0427\u041d\u0415 \u041f\u0415\u0420\u0415\u041d\u0415\u0421\u0415\u041d\u041d\u042f \u0414\u0423\u0416\u041e\u041a) ---\r\n    function formatPositionText(rawPos, forHtml = false) {\r\n        if (!rawPos) return \"\";\r\n        const pos = rawPos.trim();\r\n        if (pos.includes('\\n') || (forHtml && pos.includes('<br'))) {\r\n            return pos;\r\n        }\r\n        \/\/ \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u044f\u0454\u043c\u043e \u0447\u0438 \u0454 \u043d\u0430\u043f\u0440\u0438\u043a\u0456\u043d\u0446\u0456 \u043f\u043e\u0441\u0430\u0434\u0438 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u043d\u044f \u0443 \u043a\u0440\u0443\u0433\u043b\u0438\u0445 (...) \u0430\u0431\u043e \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u0438\u0445 [...] \u0434\u0443\u0436\u043a\u0430\u0445\r\n        const match = pos.match(\/^(.*?)\\s*([(\\[][^)\\]]+[)\\]])$\/);\r\n        if (match) {\r\n            const mainPart = match[1].trim();\r\n            const bracedPart = match[2].trim();\r\n            \/\/ \u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u0434\u043e\u0432\u0448\u0438\u0439 \u0437\u0430 38 \u0441\u0438\u043c\u0432\u043e\u043b\u0456\u0432, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c\u043e \u0434\u0443\u0436\u043a\u0438 \u043d\u0430 \u043d\u043e\u0432\u0438\u0439 \u0440\u044f\u0434\u043e\u043a \u044f\u043a \u0454\u0434\u0438\u043d\u0435 \u0446\u0456\u043b\u0435\r\n            if (pos.length > 38) {\r\n                return forHtml \r\n                    ? `${escapeHtml(mainPart)}<br>${escapeHtml(bracedPart)}` \r\n                    : `${mainPart}\\n${bracedPart}`;\r\n            }\r\n        }\r\n        return forHtml ? escapeHtml(pos) : pos;\r\n    }\r\n    \/\/ --- \u041f\u0415\u0420\u0415\u041c\u0418\u041a\u0410\u041d\u041d\u042f \u0420\u0415\u0416\u0418\u041c\u0406\u0412 (1 \u041c\u041e\u0412\u0410 \/ 2 \u041c\u041e\u0412\u0418 \u0422\u0410 \u041f\u0420\u0418\u0425\u041e\u0412\u0423\u0412\u0410\u041d\u041d\u042f \u041f\u041e\u0421\u0410\u0414\u0418) ---\r\n    function setBilingualMode(enabled) {\r\n        if (isBilingual === enabled) return;\r\n        saveHistory();\r\n        isBilingual = enabled;\r\n        \/\/ \u0412 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u043c\u0443 \u0440\u0435\u0436\u0438\u043c\u0456 \u043f\u043e\u0441\u0430\u0434\u0430 \u0437\u0430 \u0437\u0430\u043c\u043e\u0432\u0447\u0443\u0432\u0430\u043d\u043d\u044f\u043c \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u0430\r\n        isPositionHidden = enabled ? true : false;\r\n        if (isBilingual) {\r\n            peopleList.forEach(p => {\r\n                if (!p.nameEn && p.name) {\r\n                    p.nameEn = transliterateUkr(p.name);\r\n                }\r\n            });\r\n        }\r\n        document.getElementById('btnModeSingle').classList.toggle('active', !isBilingual);\r\n        document.getElementById('btnModeBi').classList.toggle('active', isBilingual);\r\n        renderAll();\r\n        showToast(isBilingual ? \"\u0414\u0432\u043e\u043c\u043e\u0432\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c: EN (\u0437\u0432\u0435\u0440\u0445\u0443) + UA. \u041f\u043e\u0441\u0430\u0434\u0443 \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u043e.\" : \"\u0417\u0432\u0438\u0447\u0430\u0439\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c: UA (1 \u043c\u043e\u0432\u0430)\", \"info\");\r\n    }\r\n    function togglePositionColumn() {\r\n        saveHistory();\r\n        isPositionHidden = !isPositionHidden;\r\n        renderAll();\r\n        showToast(isPositionHidden ? \"\u041a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438 \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u043e\" : \"\u041a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e\", \"info\");\r\n    }\r\n    \/\/ --- \u0406\u0421\u0422\u041e\u0420\u0406\u042f (UNDO \/ REDO) ---\r\n    function saveHistory() {\r\n        undoStack.push(JSON.parse(JSON.stringify(peopleList)));\r\n        if (undoStack.length > MAX_HISTORY) undoStack.shift();\r\n        redoStack.length = 0;\r\n    }\r\n    function undo() {\r\n        if (undoStack.length === 0) {\r\n            showToast(\"\u041d\u0435\u043c\u0430\u0454 \u0434\u0456\u0439 \u0434\u043b\u044f \u0441\u043a\u0430\u0441\u0443\u0432\u0430\u043d\u043d\u044f\", \"info\");\r\n            return;\r\n        }\r\n        redoStack.push(JSON.parse(JSON.stringify(peopleList)));\r\n        peopleList = undoStack.pop();\r\n        if (currentIndex >= peopleList.length) currentIndex = Math.max(0, peopleList.length - 1);\r\n        renderAll();\r\n        showToast(\"\u0421\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u043e (Undo)\", \"info\");\r\n    }\r\n    function redo() {\r\n        if (redoStack.length === 0) {\r\n            showToast(\"\u041d\u0435\u043c\u0430\u0454 \u0434\u0456\u0439 \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u043d\u044f\", \"info\");\r\n            return;\r\n        }\r\n        undoStack.push(JSON.parse(JSON.stringify(peopleList)));\r\n        peopleList = redoStack.pop();\r\n        if (currentIndex >= peopleList.length) currentIndex = Math.max(0, peopleList.length - 1);\r\n        renderAll();\r\n        showToast(\"\u041f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u043e (Redo)\", \"info\");\r\n    }\r\n    function showToast(message, type = 'info') {\r\n        const toast = document.getElementById('cgToast');\r\n        const msgEl = document.getElementById('toastMsg');\r\n        const iconEl = document.getElementById('toastIcon');\r\n        if (!toast) return;\r\n        toast.className = 'toast ' + (type === 'success' ? 'toast-success' : (type === 'error' ? 'toast-error' : ''));\r\n        msgEl.innerText = message;\r\n        iconEl.setAttribute('data-lucide', type === 'error' ? 'alert-triangle' : (type === 'success' ? 'check-circle' : 'info'));\r\n        lucide.createIcons({ root: toast });\r\n        toast.classList.add('show');\r\n        clearTimeout(toast._timeout);\r\n        toast._timeout = setTimeout(() => toast.classList.remove('show'), 2800);\r\n    }\r\n    \/\/ --- \u0420\u041e\u0417\u0423\u041c\u041d\u0418\u0419 \u041f\u0410\u0420\u0421\u0415\u0420 \u0422\u0415\u041a\u0421\u0422\u0423 \/ EXCEL ---\r\n    function parsePastedText(rawText) {\r\n        if (!rawText || !rawText.trim()) return [];\r\n        const lines = rawText.split(\/\\r?\\n\/).map(l => l.trim()).filter(l => l.length > 0);\r\n        const results = [];\r\n        lines.forEach(line => {\r\n            if (\/^(\u043f\u0456\u0431|\u043f\u0440\u0456\u0437\u0432\u0438\u0449\u0435|\u0456\u043c'\u044f|\u0456\u043c`\u044f|name|\u043f\u043e\u0441\u0430\u0434\u0430|position)\/i.test(line) && (line.includes('\\t') || line.includes(';'))) {\r\n                return;\r\n            }\r\n            let nameEn = \"\";\r\n            let nameUa = \"\";\r\n            let position = \"\";\r\n            if (line.includes('\\t')) {\r\n                const cols = line.split('\\t').map(c => c.trim()).filter(c => c.length > 0);\r\n                if (cols.length >= 3) {\r\n                    nameEn = cols[0];\r\n                    nameUa = cols[1];\r\n                    position = cols.slice(2).join(\" \u2014 \");\r\n                } else if (cols.length === 2) {\r\n                    if (isBilingual && isPositionHidden) {\r\n                        nameEn = cols[0];\r\n                        nameUa = cols[1];\r\n                    } else if (\/[a-zA-Z]\/.test(cols[0]) && \/[\u0430-\u044f\u0410-\u042f\u0456\u0457\u0454\u0491\u0406\u0407\u0404\u0490]\/.test(cols[1])) {\r\n                        nameEn = cols[0];\r\n                        nameUa = cols[1];\r\n                    } else {\r\n                        nameUa = cols[0];\r\n                        position = cols[1];\r\n                    }\r\n                } else {\r\n                    nameUa = cols[0];\r\n                }\r\n            } else if (line.includes(' \u2014 ') || line.includes(' - ')) {\r\n                const sep = line.includes(' \u2014 ') ? ' \u2014 ' : ' - ';\r\n                const parts = line.split(sep);\r\n                nameUa = parts[0].trim();\r\n                position = parts.slice(1).join(sep).trim();\r\n            } else {\r\n                nameUa = line;\r\n            }\r\n            nameUa = nameUa.replace(\/^\\d+[\\.\\)]\\s*\/, '').trim();\r\n            nameEn = nameEn.replace(\/^\\d+[\\.\\)]\\s*\/, '').trim();\r\n            if (!nameEn && nameUa) {\r\n                nameEn = transliterateUkr(nameUa);\r\n            }\r\n            if (nameUa.length > 0 || nameEn.length > 0) {\r\n                results.push({\r\n                    id: 'id_' + Math.random().toString(36).substring(2, 9),\r\n                    nameEn: nameEn,\r\n                    name: nameUa,\r\n                    position: position,\r\n                    selected: true\r\n                });\r\n            }\r\n        });\r\n        return results;\r\n    }\r\n    \/\/ --- \u0420\u041e\u0417\u0411\u0406\u0420 \u0422\u0410 \u0424\u041e\u0420\u041c\u0410\u0422\u0423\u0412\u0410\u041d\u041d\u042f \u0421\u041a\u041b\u0410\u0414\u041e\u0412\u0418\u0425 \u0406\u041c\u0415\u041d\u0406 (UA & EN) ---\r\n    function makeInitial(str) {\r\n        if (!str) return '';\r\n        const s = str.trim();\r\n        if (s.includes('.')) return s.endsWith('.') ? s : s + '.';\r\n        return s.charAt(0).toUpperCase() + '.';\r\n    }\r\n    function makeTitleCase(str) {\r\n        if (!str) return '';\r\n        const s = str.trim();\r\n        if (s.includes('.')) return s.toUpperCase();\r\n        return s.split('-').map(part => {\r\n            if (!part) return '';\r\n            return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();\r\n        }).join('-');\r\n    }\r\n    function isAllCapsWord(w) {\r\n        if (!w || w.length < 2) return false;\r\n        return \/^[^a-z\u0430-\u044f\u0456\u0457\u0454\u0491]+$\/.test(w) && \/[A-Z\u0410-\u042f\u0406\u0407\u0404\u0490]\/.test(w);\r\n    }\r\n    \/\/ \u0406\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f \u041f\u0440\u0456\u0437\u0432\u0438\u0449\u0430 \u0442\u0430 \u0406\u043c\u0435\u043d\u0456 \u0437 \u043e\u0434\u043d\u0430\u043a\u043e\u0432\u043e\u044e \u043b\u043e\u0433\u0456\u043a\u043e\u044e\r\n    function parseNameComponents(rawName) {\r\n        if (!rawName) return { last: '', first: '', middle: '', raw: '' };\r\n        let n = rawName.trim().replace(\/^\\d+[\\.\\)]\\s*\/, '').replace(\/\\s+\/g, ' ');\r\n        if (!n) return { last: '', first: '', middle: '', raw: '' };\r\n        n = n.replace(\/([\u0410-\u042f\u0401\u0406\u0407\u0404A-Z])\\.([\u0410-\u042f\u0401\u0406\u0407\u0404A-Z])\\.\/g, '$1. $2.');\r\n        const parts = n.split(' ');\r\n        if (parts.length === 1) {\r\n            return { last: parts[0], first: '', middle: '', raw: n };\r\n        }\r\n        let last = '', first = '', middle = '';\r\n        if (parts[0].includes('.')) {\r\n            first = parts[0];\r\n            if (parts.length >= 3 && parts[1].includes('.')) {\r\n                middle = parts[1];\r\n                last = parts.slice(2).join(' ');\r\n            } else {\r\n                last = parts.slice(1).join(' ');\r\n            }\r\n        } else if (parts[parts.length - 1].includes('.')) {\r\n            last = parts[0];\r\n            first = parts[1] || '';\r\n            middle = parts.slice(2).join(' ');\r\n        } else if (parts.length === 2 && isAllCapsWord(parts[1]) && !isAllCapsWord(parts[0])) {\r\n            first = parts[0];\r\n            last = parts[1];\r\n        } else if (parts.length === 2 && isAllCapsWord(parts[0]) && !isAllCapsWord(parts[1])) {\r\n            last = parts[0];\r\n            first = parts[1];\r\n        } else {\r\n            last = parts[0];\r\n            first = parts[1] || '';\r\n            middle = parts.slice(2).join(' ');\r\n        }\r\n        return { last: last.trim(), first: first.trim(), middle: middle.trim(), raw: n };\r\n    }\r\n    function formatPersonName(rawName, formatMode) {\r\n        if (!rawName) return '';\r\n        if (formatMode === 'as_is') return rawName.trim();\r\n        const c = parseNameComponents(rawName);\r\n        if (!c.last) return rawName.trim();\r\n        const lastUpper = c.last.toUpperCase();\r\n        const lastTitle = makeTitleCase(c.last);\r\n        const firstTitle = makeTitleCase(c.first);\r\n        const midTitle = makeTitleCase(c.middle);\r\n        const fInit = makeInitial(c.first);\r\n        const mInit = makeInitial(c.middle);\r\n        switch (formatMode) {\r\n            case 'first_LAST':\r\n                return firstTitle ? `${firstTitle} ${lastUpper}` : lastUpper;\r\n            case 'LAST_first':\r\n                return firstTitle ? `${lastUpper} ${firstTitle}` : lastUpper;\r\n            case 'LAST_first_middle':\r\n                return [lastUpper, firstTitle, midTitle].filter(Boolean).join(' ');\r\n            case 'first_middle_LAST':\r\n                return [firstTitle, midTitle, lastUpper].filter(Boolean).join(' ');\r\n            case 'initials_LAST':\r\n                return [fInit, mInit, lastUpper].filter(Boolean).join(' ');\r\n            case 'initial_dot_LAST':\r\n                return fInit ? `${fInit} ${lastUpper}` : lastUpper;\r\n            case 'LAST_initials':\r\n                return [lastUpper, fInit, mInit].filter(Boolean).join(' ');\r\n            case 'LAST_initial':\r\n                return fInit ? `${lastUpper} ${fInit}` : lastUpper;\r\n            case 'initials_space_last':\r\n                return [fInit, mInit, lastTitle].filter(Boolean).join(' ');\r\n            case 'last_initials_title':\r\n                return [lastTitle, fInit, mInit].filter(Boolean).join(' ');\r\n            case 'title_case':\r\n                return firstTitle ? `${firstTitle} ${lastTitle}` : lastTitle;\r\n            case 'all_caps':\r\n                return [c.first, c.middle, c.last].filter(Boolean).join(' ').toUpperCase();\r\n            default:\r\n                return firstTitle ? `${firstTitle} ${lastUpper}` : lastUpper;\r\n        }\r\n    }\r\n    \/\/ --- \u0420\u041e\u0417\u0420\u0410\u0425\u0423\u041d\u041e\u041a \u0422\u0410 \u0414\u0418\u041d\u0410\u041c\u0406\u0427\u041d\u0410 \u0417\u0410\u041b\u0415\u0416\u041d\u0406\u0421\u0422\u042c \u0420\u041e\u0417\u041c\u0406\u0420\u0406\u0412 \u0428\u0420\u0418\u0424\u0422\u0406\u0412 ---\r\n    function getLongestFormattedName() {\r\n        const formatMode = document.getElementById('nameFormatSelect').value;\r\n        const validList = peopleList.filter(p => p.selected && (p.name?.trim() || p.nameEn?.trim()));\r\n        const listToScan = validList.length > 0 ? validList : peopleList;\r\n        if (listToScan.length === 0) return \"\u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a\";\r\n        let longest = \"\";\r\n        listToScan.forEach(p => {\r\n            const formattedUa = p.name ? formatPersonName(p.name, formatMode) : \"\";\r\n            const formattedEn = p.nameEn ? formatPersonName(p.nameEn, formatMode) : \"\";\r\n            if (formattedUa.length > longest.length) longest = formattedUa;\r\n            if (formattedEn.length > longest.length) longest = formattedEn;\r\n        });\r\n        return longest || \"\u041e\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u041a\u041e\u0412\u0410\u041b\u042c\u0427\u0423\u041a\";\r\n    }\r\n    function calculateAutoFontSize() {\r\n        const longest = getLongestFormattedName();\r\n        const len = Math.max(8, longest.length);\r\n        let base, maxLimit;\r\n        if (isBilingual) {\r\n            base = isPositionHidden ? 1040 : 920;\r\n            maxLimit = isPositionHidden ? 56 : 48;\r\n        } else {\r\n            base = isPositionHidden ? 1120 : 1000;\r\n            maxLimit = isPositionHidden ? 60 : 54;\r\n        }\r\n        let size = Math.round(base \/ len);\r\n        if (size > maxLimit) size = maxLimit;\r\n        if (size < 20) size = 20;\r\n        return size;\r\n    }\r\n    \/\/ \u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0456 \u043f\u0440\u0435\u0441\u0435\u0442\u0438: \u0412\u0435\u043b\u0438\u043a\u0438\u0439 (85%), \u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 (70%), \u0414\u0440\u0456\u0431\u043d\u0438\u0439 (55%) \u0441\u0443\u0432\u043e\u0440\u043e \u0432\u0456\u0434 \u0410\u0432\u0442\u043e\r\n    function updateFontSizePresets() {\r\n        const autoSize = calculateAutoFontSize();\r\n        const presets = {\r\n            auto: autoSize,\r\n            large: Math.max(18, Math.round(autoSize * 0.85)),\r\n            medium: Math.max(16, Math.round(autoSize * 0.70)),\r\n            small: Math.max(14, Math.round(autoSize * 0.55))\r\n        };\r\n        const select = document.getElementById('fontSizeSelect');\r\n        const numInput = document.getElementById('fontSizeNumber');\r\n        const optAuto = select.querySelector('option[value=\"auto\"]');\r\n        const optLarge = select.querySelector('option[value=\"large\"]');\r\n        const optMedium = select.querySelector('option[value=\"medium\"]');\r\n        const optSmall = select.querySelector('option[value=\"small\"]');\r\n        if (optAuto) optAuto.text = `\u0410\u0432\u0442\u043e (\u041d\u0430\u0439\u0431\u0456\u043b\u044c\u0448\u0456): ${presets.auto} pt`;\r\n        if (optLarge) optLarge.text = `\u0412\u0435\u043b\u0438\u043a\u0438\u0439 (85%): ${presets.large} pt`;\r\n        if (optMedium) optMedium.text = `\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 (70%): ${presets.medium} pt`;\r\n        if (optSmall) optSmall.text = `\u0414\u0440\u0456\u0431\u043d\u0438\u0439 (55%): ${presets.small} pt`;\r\n        const currentMode = select.value;\r\n        if (currentMode === 'auto') {\r\n            numInput.value = presets.auto;\r\n        } else if (currentMode === 'large') {\r\n            numInput.value = presets.large;\r\n        } else if (currentMode === 'medium') {\r\n            numInput.value = presets.medium;\r\n        } else if (currentMode === 'small') {\r\n            numInput.value = presets.small;\r\n        }\r\n        const fontHint = document.getElementById('fontHint');\r\n        if (fontHint) {\r\n            if (currentMode === 'auto') fontHint.innerText = `(\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c: ${presets.auto}pt)`;\r\n            else if (currentMode === 'custom') fontHint.innerText = `(\u0432\u0440\u0443\u0447\u043d\u0443)`;\r\n            else fontHint.innerText = `(${presets[currentMode]}pt)`;\r\n        }\r\n        return presets;\r\n    }\r\n    function getEffectiveFontSize() {\r\n        const numInput = document.getElementById('fontSizeNumber');\r\n        const val = parseInt(numInput ? numInput.value : 54, 10);\r\n        return isNaN(val) || val <= 0 ? 54 : val;\r\n    }\r\n    function handleFontSizeSelectChange() {\r\n        const select = document.getElementById('fontSizeSelect');\r\n        const numInput = document.getElementById('fontSizeNumber');\r\n        const mode = select.value;\r\n        const autoSize = calculateAutoFontSize();\r\n        if (mode === 'auto') {\r\n            numInput.value = autoSize;\r\n        } else if (mode === 'large') {\r\n            numInput.value = Math.max(18, Math.round(autoSize * 0.85));\r\n        } else if (mode === 'medium') {\r\n            numInput.value = Math.max(16, Math.round(autoSize * 0.70));\r\n        } else if (mode === 'small') {\r\n            numInput.value = Math.max(14, Math.round(autoSize * 0.55));\r\n        } else if (mode === 'custom') {\r\n            numInput.focus();\r\n            numInput.select();\r\n        }\r\n        renderCurrentView();\r\n    }\r\n    function handleFontSizeNumberInput(val) {\r\n        let num = parseInt(val, 10);\r\n        if (isNaN(num)) return;\r\n        if (num > 75) num = 75;\r\n        if (num < 14) num = 14;\r\n        const select = document.getElementById('fontSizeSelect');\r\n        select.value = 'custom';\r\n        renderCurrentView();\r\n    }\r\n    \/\/ \u041a\u043e\u043b\u044c\u043e\u0440\u043e\u0432\u0456 \u0441\u0445\u0435\u043c\u0438\r\n    function getThemeColors() {\r\n        const theme = document.getElementById('themeColorSelect').value;\r\n        let enColor = '#000000';\r\n        let uaColor = '#000000';\r\n        let posColor = '#4B5563';\r\n        if (theme === 'duo_crimson_black') {\r\n            enColor = '#b80000';\r\n            uaColor = '#000000';\r\n            posColor = '#4B5563';\r\n        } else if (theme === 'corporate') {\r\n            enColor = '#0A1B3F';\r\n            uaColor = '#0A1B3F';\r\n            posColor = '#4B5563';\r\n        } else if (theme === 'crimson') {\r\n            enColor = '#b80000';\r\n            uaColor = '#b80000';\r\n            posColor = '#333333';\r\n        } else {\r\n            enColor = '#000000';\r\n            uaColor = '#000000';\r\n            posColor = '#4B5563';\r\n        }\r\n        return { enColor, uaColor, posColor };\r\n    }\r\n    \/\/ --- \u0421\u0418\u041d\u0425\u0420\u041e\u041d\u0406\u0417\u0410\u0426\u0406\u042f \u041d\u0410 \u041b\u042c\u041e\u0422\u0423 \u0422\u0410 \u0420\u0415\u041d\u0414\u0415\u0420\u0418\u041d\u0413 \u0412\u0421\u0406\u0425 \u0415\u041b\u0415\u041c\u0415\u041d\u0422\u0406\u0412 ---\r\n    function renderAll() {\r\n        renderGrid();\r\n        renderExpandedTable();\r\n        updateStats();\r\n        updateToolbarButton();\r\n        renderCurrentView();\r\n    }\r\n    \/\/ \u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0435 \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\r\n    function updateToolbarButton() {\r\n        const btn = document.getElementById('btnTogglePosCol');\r\n        if (btn) {\r\n            btn.innerHTML = `<i data-lucide=\"${isPositionHidden ? 'eye-off' : 'eye'}\"><\/i> <span>\u041f\u043e\u0441\u0430\u0434\u0430<\/span>`;\r\n            btn.classList.toggle('active-hidden', isPositionHidden);\r\n            lucide.createIcons({ root: btn });\r\n        }\r\n        const btnExp = document.getElementById('btnTogglePosColExp');\r\n        if (btnExp) {\r\n            btnExp.innerHTML = `<i data-lucide=\"${isPositionHidden ? 'eye-off' : 'eye'}\"><\/i> <span>\u041f\u043e\u0441\u0430\u0434\u0430<\/span>`;\r\n            btnExp.classList.toggle('active-hidden', isPositionHidden);\r\n            lucide.createIcons({ root: btnExp });\r\n        }\r\n    }\r\n    \/\/ \u0412\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0456\u0434\u0440\u0430\u0445\u0443\u043d\u043e\u043a \u0442\u0430 \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0433\u0430\u043b\u043e\u0447\u043a\u0438 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0443\r\n    function updateStats() {\r\n        const filled = peopleList.filter(p => (p.name && p.name.trim()) || (p.nameEn && p.nameEn.trim())).length;\r\n        const selected = peopleList.filter(p => p.selected && ((p.name && p.name.trim()) || (p.nameEn && p.nameEn.trim()))).length;\r\n        const totalRows = peopleList.length;\r\n        document.getElementById('stat-total').innerText = filled > 0 ? filled : (peopleList[0]?.name ? totalRows : 0);\r\n        document.getElementById('stat-selected').innerText = selected;\r\n        document.getElementById('stat-pages').innerText = selected;\r\n        document.getElementById('tabCount').innerText = filled > 0 ? filled : totalRows;\r\n        document.getElementById('counter-hint').innerText = `${filled > 0 ? filled : (peopleList[0]?.name ? totalRows : 0)} \u043e\u0441\u0456\u0431`;\r\n        const masterCbs = document.querySelectorAll('#masterCheckbox, #masterCheckboxExp');\r\n        masterCbs.forEach(cb => {\r\n            if (cb) {\r\n                cb.checked = totalRows > 0 && selected === totalRows;\r\n                cb.indeterminate = selected > 0 && selected < totalRows;\r\n            }\r\n        });\r\n    }\r\n    function updatePersonValue(id, field, value, sourceInput = null) {\r\n        const item = peopleList.find(p => p.id === id);\r\n        if (!item) return;\r\n        item[field] = value;\r\n        const mirrorInputs = document.querySelectorAll(`input[data-person-id=\"${id}\"][data-field=\"${field}\"]`);\r\n        mirrorInputs.forEach(input => {\r\n            if (input !== sourceInput && input.value !== value) {\r\n                input.value = value;\r\n            }\r\n        });\r\n        updateStats();\r\n        renderCurrentView();\r\n    }\r\n    \/\/ \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043b\u0456\u0432\u043e\u0457 \u0456\u043d\u043f\u0443\u0442-\u0442\u0430\u0431\u043b\u0438\u0446\u0456\r\n    function renderGrid() {\r\n        const headerRow = document.getElementById('gridHeaderRow');\r\n        const tbody = document.getElementById('gridTbody');\r\n        tbody.innerHTML = '';\r\n        if (peopleList.length === 0) {\r\n            peopleList.push({\r\n                id: 'id_' + Math.random().toString(36).substring(2, 9),\r\n                nameEn: '',\r\n                name: '',\r\n                position: '',\r\n                selected: true\r\n            });\r\n        }\r\n        headerRow.innerHTML = `\r\n            <th style=\"width: 24px; text-align: center;\">\r\n                <input type=\"checkbox\" id=\"masterCheckbox\" onchange=\"handleSelectAllChange(this)\" title=\"\u041e\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0456\">\r\n            <\/th>\r\n            <th style=\"width: 20px; text-align: center;\">#<\/th>\r\n            ${isBilingual ? '<th style=\"width: 32%;\">\u041f\u0406\u0411 (EN)<\/th>' : ''}\r\n            <th style=\"${isBilingual ? 'width: 32%;' : 'width: 48%;'}\">\u041f\u0406\u0411 (UA)<\/th>\r\n            ${!isPositionHidden ? `\r\n                <th>\r\n                    <div style=\"display:flex; justify-content:space-between; align-items:center;\">\r\n                        <span>\u041f\u043e\u0441\u0430\u0434\u0430<\/span>\r\n                        <button class=\"col-toggle-btn\" onclick=\"togglePositionColumn()\" title=\"\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\">\r\n                            <i data-lucide=\"eye\"><\/i>\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/th>` : `\r\n                <th style=\"width: 28px; text-align: center;\">\r\n                    <button class=\"col-toggle-btn active-hidden\" onclick=\"togglePositionColumn()\" title=\"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\">\r\n                        <i data-lucide=\"eye-off\"><\/i>\r\n                    <\/button>\r\n                <\/th>`\r\n            }\r\n            <th style=\"width: 28px; text-align: center;\"><\/th>\r\n        `;\r\n        peopleList.forEach((person, idx) => {\r\n            const tr = document.createElement('tr');\r\n            if (idx === currentIndex) tr.classList.add('active-preview-row');\r\n            tr.innerHTML = `\r\n                <td style=\"text-align: center;\">\r\n                    <input type=\"checkbox\" data-person-id=\"${person.id}\" ${person.selected ? 'checked' : ''} onchange=\"toggleSelectPerson('${person.id}', this)\">\r\n                <\/td>\r\n                <td style=\"text-align: center; color: #94a3b8; font-weight: 600; font-size: 9.5px;\">${idx + 1}<\/td>\r\n                ${isBilingual ? `\r\n                <td>\r\n                    <input type=\"text\" class=\"cell-input name-en-cell\" value=\"${escapeHtml(person.nameEn || '')}\" \r\n                        placeholder=\"Name Surname...\"\r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"nameEn\" \r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'nameEn', this.value, this)\">\r\n                <\/td>` : ''}\r\n                <td>\r\n                    <input type=\"text\" class=\"cell-input name-cell\" value=\"${escapeHtml(person.name || '')}\" \r\n                        placeholder=\"\u041f\u0406\u0411...\"\r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"name\" \r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'name', this.value, this)\">\r\n                <\/td>\r\n                ${!isPositionHidden ? `\r\n                <td>\r\n                    <input type=\"text\" class=\"cell-input pos-cell\" value=\"${escapeHtml(person.position || '')}\" \r\n                        placeholder=\"\u041f\u043e\u0441\u0430\u0434\u0430...\"\r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"position\" \r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'position', this.value, this)\">\r\n                <\/td>` : '<td style=\"text-align:center; color:#cbd5e1; font-size:9px;\">\u2014<\/td>'}\r\n                <td style=\"text-align: center;\">\r\n                    <button class=\"grid-actions-btn\" onclick=\"deletePerson('${person.id}')\" title=\"\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438\">\r\n                        <i data-lucide=\"trash-2\"><\/i>\r\n                    <\/button>\r\n                <\/td>\r\n            `;\r\n            tbody.appendChild(tr);\r\n        });\r\n        lucide.createIcons({ root: headerRow });\r\n        lucide.createIcons({ root: tbody });\r\n    }\r\n    \/\/ \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u0440\u0430\u0432\u043e\u0457 \u0440\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u043e\u0457 \u0442\u0430\u0431\u043b\u0438\u0446\u0456 (\u0437 \u043a\u043d\u043e\u043f\u043a\u043e\u044e \u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u043e\u0441\u0430\u0434\u0438 \u0443 \u0448\u0430\u043f\u0446\u0456)\r\n    function renderExpandedTable() {\r\n        const headerRow = document.getElementById('expandedHeaderRow');\r\n        const tbody = document.getElementById('expandedTableBody');\r\n        if (!tbody || !headerRow) return;\r\n        const query = (document.getElementById('tableSearch')?.value || '').toLowerCase().trim();\r\n        tbody.innerHTML = '';\r\n        headerRow.innerHTML = `\r\n            <th style=\"width: 30px; text-align: center;\">\r\n                <input type=\"checkbox\" id=\"masterCheckboxExp\" onchange=\"handleSelectAllChange(this)\" title=\"\u041e\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0456\">\r\n            <\/th>\r\n            <th style=\"width: 35px;\">\u2116<\/th>\r\n            ${isBilingual ? '<th style=\"width: 25%;\">\u041f\u0406\u0411 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u044e (EN)<\/th>' : ''}\r\n            <th style=\"${isBilingual ? 'width: 25%;' : 'width: 40%;'}\">\u041f\u0406\u0411 \u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u043e\u044e (UA)<\/th>\r\n            ${!isPositionHidden ? `\r\n                <th>\r\n                    <div style=\"display:flex; justify-content:space-between; align-items:center;\">\r\n                        <span>\u041f\u043e\u0441\u0430\u0434\u0430 \/ \u041f\u0456\u0434\u0440\u043e\u0437\u0434\u0456\u043b<\/span>\r\n                        <button class=\"col-toggle-btn\" onclick=\"togglePositionColumn()\" title=\"\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\">\r\n                            <i data-lucide=\"eye\"><\/i>\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/th>` : `\r\n                <th style=\"width: 85px; text-align: center;\">\r\n                    <div style=\"display:flex; justify-content:center; align-items:center; gap:4px;\">\r\n                        <span style=\"color:#94a3b8; font-size:10px;\">\u041f\u043e\u0441\u0430\u0434\u0430<\/span>\r\n                        <button class=\"col-toggle-btn active-hidden\" onclick=\"togglePositionColumn()\" title=\"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u043f\u043e\u0441\u0430\u0434\u0438\">\r\n                            <i data-lucide=\"eye-off\"><\/i>\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/th>`\r\n            }\r\n            <th style=\"width: 40px; text-align: center;\">\u0414\u0456\u044f<\/th>\r\n        `;\r\n        peopleList.forEach((person, idx) => {\r\n            if (query && !person.name?.toLowerCase().includes(query) && !person.nameEn?.toLowerCase().includes(query) && !person.position?.toLowerCase().includes(query)) {\r\n                return;\r\n            }\r\n            const tr = document.createElement('tr');\r\n            tr.innerHTML = `\r\n                <td style=\"text-align: center;\">\r\n                    <input type=\"checkbox\" data-person-id=\"${person.id}\" ${person.selected ? 'checked' : ''} onchange=\"toggleSelectPerson('${person.id}', this)\">\r\n                <\/td>\r\n                <td style=\"color: #6b7280; font-weight: 600;\">${idx + 1}<\/td>\r\n                ${isBilingual ? `\r\n                <td>\r\n                    <input type=\"text\" value=\"${escapeHtml(person.nameEn || '')}\" class=\"cell-input\" style=\"border: 1px solid #e2e8f0; background: #fff;\" \r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"nameEn\"\r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'nameEn', this.value, this)\">\r\n                <\/td>` : ''}\r\n                <td>\r\n                    <input type=\"text\" value=\"${escapeHtml(person.name || '')}\" class=\"cell-input\" style=\"border: 1px solid #e2e8f0; background: #fff;\" \r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"name\"\r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'name', this.value, this)\">\r\n                <\/td>\r\n                ${!isPositionHidden ? `\r\n                <td>\r\n                    <input type=\"text\" value=\"${escapeHtml(person.position || '')}\" class=\"cell-input\" style=\"border: 1px solid #e2e8f0; background: #fff;\" \r\n                        data-person-id=\"${person.id}\" data-row-idx=\"${idx}\" data-field=\"position\"\r\n                        onfocus=\"setCurrentPreview(${idx})\"\r\n                        oninput=\"updatePersonValue('${person.id}', 'position', this.value, this)\">\r\n                <\/td>` : '<td style=\"text-align:center; color:#94a3b8; font-size:10px;\">\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u043e<\/td>'}\r\n                <td style=\"text-align: center;\">\r\n                    <button class=\"grid-actions-btn\" onclick=\"deletePerson('${person.id}')\" title=\"\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438\">\r\n                        <i data-lucide=\"trash-2\"><\/i>\r\n                    <\/button>\r\n                <\/td>\r\n            `;\r\n            tbody.appendChild(tr);\r\n        });\r\n        lucide.createIcons({ root: headerRow });\r\n        lucide.createIcons({ root: tbody });\r\n    }\r\n    \/\/ \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043c\u0430\u043a\u0435\u0442\u0430 \u043a\u0430\u0440\u0442\u043a\u0438 (\u041f\u0440\u0435\u0432'\u044e)\r\n    function renderCurrentView() {\r\n        const formatMode = document.getElementById('nameFormatSelect').value;\r\n        updateFontSizePresets();\r\n        const effectivePt = getEffectiveFontSize();\r\n        const colors = getThemeColors();\r\n        const navCounter = document.getElementById('navCounter');\r\n        const nameEnTop = document.getElementById('previewNameEnTop');\r\n        const nameUaTop = document.getElementById('previewNameUaTop');\r\n        const posTop = document.getElementById('previewPosTop');\r\n        const nameEnBottom = document.getElementById('previewNameEnBottom');\r\n        const nameUaBottom = document.getElementById('previewNameUaBottom');\r\n        const posBottom = document.getElementById('previewPosBottom');\r\n        nameEnTop.style.color = colors.enColor;\r\n        nameEnBottom.style.color = colors.enColor;\r\n        nameUaTop.style.color = colors.uaColor;\r\n        nameUaBottom.style.color = colors.uaColor;\r\n        posTop.style.color = colors.posColor;\r\n        posBottom.style.color = colors.posColor;\r\n        nameEnTop.style.display = isBilingual ? 'block' : 'none';\r\n        nameEnBottom.style.display = isBilingual ? 'block' : 'none';\r\n        posTop.style.display = !isPositionHidden ? 'block' : 'none';\r\n        posBottom.style.display = !isPositionHidden ? 'block' : 'none';\r\n        const filledPeople = peopleList.filter(p => (p.name && p.name.trim()) || (p.nameEn && p.nameEn.trim()));\r\n        if (filledPeople.length === 0) {\r\n            navCounter.innerText = \"0 \/ 0\";\r\n            nameEnTop.innerText = \"Name SURNAME\";\r\n            nameUaTop.innerText = \"\u0406\u043c'\u044f \u041f\u0420\u0406\u0417\u0412\u0418\u0429\u0415\";\r\n            posTop.innerHTML = \"\u041f\u043e\u0441\u0430\u0434\u0430 \u0430\u0431\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\";\r\n            nameEnBottom.innerText = \"Name SURNAME\";\r\n            nameUaBottom.innerText = \"\u0406\u043c'\u044f \u041f\u0420\u0406\u0417\u0412\u0418\u0429\u0415\";\r\n            posBottom.innerHTML = \"\u041f\u043e\u0441\u0430\u0434\u0430 \u0430\u0431\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\";\r\n        } else {\r\n            if (currentIndex >= peopleList.length) currentIndex = peopleList.length - 1;\r\n            if (currentIndex < 0) currentIndex = 0;\r\n            navCounter.innerText = `${currentIndex + 1} \/ ${peopleList.length}`;\r\n            const person = peopleList[currentIndex];\r\n            const formattedUa = person.name ? formatPersonName(person.name, formatMode) : \"\";\r\n            const formattedEn = person.nameEn ? formatPersonName(person.nameEn, formatMode) : formattedUa;\r\n            nameEnTop.innerText = formattedEn || formattedUa;\r\n            nameUaTop.innerText = formattedUa || formattedEn;\r\n            \/\/ \u0415\u0441\u0442\u0435\u0442\u0438\u0447\u043d\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u043e\u0441\u0430\u0434\u0438 \u0437 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u043c \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u044f\u043c \u0434\u0443\u0436\u043e\u043a\r\n            const formattedPosHtml = formatPositionText(person.position || \"\", true);\r\n            posTop.innerHTML = formattedPosHtml;\r\n            nameEnBottom.innerText = formattedEn || formattedUa;\r\n            nameUaBottom.innerText = formattedUa || formattedEn;\r\n            posBottom.innerHTML = formattedPosHtml;\r\n        }\r\n        \/\/ \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u043e\u0437\u043c\u0456\u0440\u0443 \u0448\u0440\u0438\u0444\u0442\u0443 \u043d\u0430 \u043a\u0430\u0440\u0442\u0446\u0456\r\n        const sheet = document.getElementById('sheetA4');\r\n        const sheetWidth = sheet ? sheet.offsetWidth : 660;\r\n        const scale = sheetWidth \/ 842;\r\n        const pxSize = Math.max(14, Math.round(effectivePt * scale));\r\n        const pxSizeUa = isBilingual ? Math.max(12, Math.round(pxSize * 0.90)) : pxSize;\r\n        const posPxSize = Math.max(9, Math.round(pxSize * 0.38));\r\n        nameEnTop.style.fontSize = pxSize + 'px';\r\n        nameEnBottom.style.fontSize = pxSize + 'px';\r\n        nameUaTop.style.fontSize = pxSizeUa + 'px';\r\n        nameUaBottom.style.fontSize = pxSizeUa + 'px';\r\n        posTop.style.fontSize = posPxSize + 'px';\r\n        posBottom.style.fontSize = posPxSize + 'px';\r\n        if (isBilingual) {\r\n            const emptyLineGap = Math.max(12, Math.round(pxSize * 0.72));\r\n            nameEnTop.style.marginBottom = emptyLineGap + 'px';\r\n            nameEnBottom.style.marginBottom = emptyLineGap + 'px';\r\n        } else {\r\n            nameEnTop.style.marginBottom = '';\r\n            nameEnBottom.style.marginBottom = '';\r\n        }\r\n        document.querySelectorAll('#gridTbody tr').forEach((tr, i) => {\r\n            if (i === currentIndex) tr.classList.add('active-preview-row');\r\n            else tr.classList.remove('active-preview-row');\r\n        });\r\n    }\r\n    function escapeHtml(str) {\r\n        if (!str) return '';\r\n        return str.replace(\/&\/g, \"&amp;\").replace(\/<\/g, \"&lt;\").replace(\/>\/g, \"&gt;\").replace(\/\"\/g, \"&quot;\");\r\n    }\r\n    \/\/ --- \u0414\u0406\u0407 \u0417 \u0420\u042f\u0414\u041a\u0410\u041c\u0418 \u0422\u0410 \u0414\u0410\u041d\u0418\u041c\u0418 ---\r\n    function setCurrentPreview(idx) {\r\n        currentIndex = idx;\r\n        renderCurrentView();\r\n    }\r\n    function addNewEmptyRow(autoFocus = false) {\r\n        saveHistory();\r\n        const newObj = {\r\n            id: 'id_' + Math.random().toString(36).substring(2, 9),\r\n            nameEn: '',\r\n            name: '',\r\n            position: '',\r\n            selected: true\r\n        };\r\n        peopleList.push(newObj);\r\n        currentIndex = peopleList.length - 1;\r\n        renderAll();\r\n        if (autoFocus) {\r\n            setTimeout(() => {\r\n                const targetClass = isBilingual ? '.name-en-cell' : '.name-cell';\r\n                const inputs = document.querySelectorAll(targetClass);\r\n                if (inputs.length > 0) {\r\n                    inputs[inputs.length - 1].focus();\r\n                }\r\n            }, 50);\r\n        }\r\n    }\r\n    function deletePerson(id) {\r\n        saveHistory();\r\n        if (peopleList.length === 1) {\r\n            peopleList[0].nameEn = '';\r\n            peopleList[0].name = '';\r\n            peopleList[0].position = '';\r\n        } else {\r\n            peopleList = peopleList.filter(p => p.id !== id);\r\n        }\r\n        if (currentIndex >= peopleList.length) currentIndex = Math.max(0, peopleList.length - 1);\r\n        renderAll();\r\n    }\r\n    function toggleSelectPerson(id, sourceCb = null) {\r\n        const item = peopleList.find(p => p.id === id);\r\n        if (item) {\r\n            if (sourceCb) item.selected = sourceCb.checked;\r\n            else item.selected = !item.selected;\r\n            document.querySelectorAll(`input[type=\"checkbox\"][data-person-id=\"${id}\"]`).forEach(cb => {\r\n                if (cb !== sourceCb) cb.checked = item.selected;\r\n            });\r\n            updateStats();\r\n            renderCurrentView();\r\n        }\r\n    }\r\n    function toggleSelectAll(forceState = null) {\r\n        const anyUnselected = peopleList.some(p => !p.selected);\r\n        const newState = forceState !== null ? forceState : anyUnselected;\r\n        peopleList.forEach(p => p.selected = newState);\r\n        renderAll();\r\n    }\r\n    function handleSelectAllChange(cb) {\r\n        const targetState = cb.checked;\r\n        peopleList.forEach(p => p.selected = targetState);\r\n        renderAll();\r\n    }\r\n    function clearAllData() {\r\n        saveHistory();\r\n        peopleList = [{\r\n            id: 'id_' + Math.random().toString(36).substring(2, 9),\r\n            nameEn: '',\r\n            name: '',\r\n            position: '',\r\n            selected: true\r\n        }];\r\n        currentIndex = 0;\r\n        renderAll();\r\n        showToast(\"\u0422\u0430\u0431\u043b\u0438\u0446\u044e \u043e\u0447\u0438\u0449\u0435\u043d\u043e (\u043f\u043e\u043b\u044f \u0433\u043e\u0442\u043e\u0432\u0456 \u0434\u043e \u0432\u0432\u043e\u0434\u0443)\");\r\n    }\r\n    function loadDemoData() {\r\n        saveHistory();\r\n        peopleList = demoPersons.map(d => ({\r\n            id: 'id_' + Math.random().toString(36).substring(2, 9),\r\n            nameEn: d.nameEn,\r\n            name: d.name,\r\n            position: d.position,\r\n            selected: true\r\n        }));\r\n        currentIndex = 0;\r\n        renderAll();\r\n        showToast(\"\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e 7 \u043f\u0440\u043e\u0432\u0456\u0434\u043d\u0438\u0445 \u043f\u043e\u0441\u0430\u0434 \u0443\u043d\u0456\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0443!\", \"success\");\r\n    }\r\n    \/\/ --- \u041c\u041e\u0414\u0410\u041b\u042c\u041d\u0415 \u0412\u0406\u041a\u041d\u041e \u0412\u0421\u0422\u0410\u0412\u041a\u0418 ---\r\n    function openPasteModal() {\r\n        const modal = document.getElementById('pasteModal');\r\n        const area = document.getElementById('modalPasteArea');\r\n        modal.style.display = 'flex';\r\n        area.value = '';\r\n        setTimeout(() => area.focus(), 50);\r\n    }\r\n    function closePasteModal() {\r\n        document.getElementById('pasteModal').style.display = 'none';\r\n    }\r\n    function applyModalPaste() {\r\n        const val = document.getElementById('modalPasteArea').value;\r\n        const parsed = parsePastedText(val);\r\n        if (parsed.length === 0) {\r\n            showToast(\"\u041d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0456\u0432 \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438\", \"error\");\r\n            return;\r\n        }\r\n        saveHistory();\r\n        peopleList = parsed;\r\n        currentIndex = 0;\r\n        renderAll();\r\n        closePasteModal();\r\n        showToast(`\u0423\u0441\u043f\u0456\u0448\u043d\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e ${parsed.length} \u043e\u0441\u0456\u0431!`, \"success\");\r\n    }\r\n    \/\/ --- \u041d\u0410\u0412\u0406\u0413\u0410\u0426\u0406\u042f \u0422\u0410 \u0412\u041a\u041b\u0410\u0414\u041a\u0418 ---\r\n    function prevCard() {\r\n        if (peopleList.length === 0) return;\r\n        currentIndex = (currentIndex - 1 + peopleList.length) % peopleList.length;\r\n        renderCurrentView();\r\n        scrollToActiveGridRow();\r\n    }\r\n    function nextCard() {\r\n        if (peopleList.length === 0) return;\r\n        currentIndex = (currentIndex + 1) % peopleList.length;\r\n        renderCurrentView();\r\n        scrollToActiveGridRow();\r\n    }\r\n    function scrollToActiveGridRow() {\r\n        const activeTr = document.querySelector('#gridTbody tr.active-preview-row');\r\n        if (activeTr) activeTr.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\r\n    }\r\n    function switchTab(tab) {\r\n        const preview = document.getElementById('previewViewport');\r\n        const table = document.getElementById('tableContainer');\r\n        const tabBtnPreview = document.getElementById('tabBtnPreview');\r\n        const tabBtnTable = document.getElementById('tabBtnTable');\r\n        const nav = document.getElementById('navControls');\r\n        if (tab === 'preview') {\r\n            preview.style.display = 'flex';\r\n            table.style.display = 'none';\r\n            tabBtnPreview.classList.add('active');\r\n            tabBtnTable.classList.remove('active');\r\n            nav.style.display = 'flex';\r\n            renderCurrentView();\r\n        } else {\r\n            preview.style.display = 'none';\r\n            table.style.display = 'block';\r\n            tabBtnPreview.classList.remove('active');\r\n            tabBtnTable.classList.add('active');\r\n            nav.style.display = 'none';\r\n            renderExpandedTable();\r\n        }\r\n    }\r\n    \/\/ --- \u041a\u041b\u0410\u0412\u0406\u0410\u0422\u0423\u0420\u041d\u0406 \u0421\u041a\u041e\u0420\u041e\u0427\u0415\u041d\u041d\u042f (HOTKEYS) ---\r\n    document.addEventListener('keydown', (e) => {\r\n        const isCtrl = e.ctrlKey || e.metaKey;\r\n        const target = e.target;\r\n        const isTextInput = (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'number' || !target.type)) || target.tagName === 'TEXTAREA';\r\n        if (isCtrl && (e.key === 'z' || e.key === 'Z')) {\r\n            if (e.shiftKey) { e.preventDefault(); redo(); }\r\n            else { e.preventDefault(); undo(); }\r\n            return;\r\n        }\r\n        if (isCtrl && (e.key === 'y' || e.key === 'Y')) {\r\n            e.preventDefault();\r\n            redo();\r\n            return;\r\n        }\r\n        if (isCtrl && (e.key === 'a' || e.key === 'A') && !isTextInput) {\r\n            e.preventDefault();\r\n            toggleSelectAll(true);\r\n            showToast(\"\u0412\u0438\u0434\u0456\u043b\u0435\u043d\u043e \u0432\u0441\u0456 \u043a\u0430\u0440\u0442\u043a\u0438\", \"info\");\r\n            return;\r\n        }\r\n        if (isCtrl && (e.key === 'c' || e.key === 'C')) {\r\n            if (!isTextInput || window.getSelection().toString() === '') {\r\n                const selected = peopleList.filter(p => p.selected && (p.name || p.nameEn));\r\n                if (selected.length > 0) {\r\n                    const tsv = isBilingual\r\n                        ? selected.map(p => `${p.nameEn || ''}\\t${p.name || ''}\\t${p.position || ''}`).join('\\n')\r\n                        : selected.map(p => `${p.name || ''}\\t${p.position || ''}`).join('\\n');\r\n                    navigator.clipboard.writeText(tsv).then(() => {\r\n                        showToast(`\u0421\u043a\u043e\u043f\u0456\u0439\u043e\u0432\u0430\u043d\u043e ${selected.length} \u043e\u0441\u0456\u0431 \u0434\u043e \u0431\u0443\u0444\u0435\u0440\u0430!`, \"success\");\r\n                    }).catch(() => {});\r\n                    if (!isTextInput) e.preventDefault();\r\n                }\r\n            }\r\n        }\r\n        if (e.key === 'Tab' && isTextInput && target.classList.contains('cell-input')) {\r\n            const rowIdx = parseInt(target.getAttribute('data-row-idx'));\r\n            const field = target.getAttribute('data-field');\r\n            const isLastField = isPositionHidden ? (field === 'name') : (field === 'position');\r\n            if (!e.shiftKey && isLastField && rowIdx === peopleList.length - 1) {\r\n                e.preventDefault();\r\n                addNewEmptyRow(true);\r\n                return;\r\n            }\r\n        }\r\n        if (e.key === 'Enter' && isTextInput && target.classList.contains('cell-input')) {\r\n            e.preventDefault();\r\n            const rowIdx = parseInt(target.getAttribute('data-row-idx'));\r\n            const field = target.getAttribute('data-field');\r\n            if (rowIdx === peopleList.length - 1) {\r\n                addNewEmptyRow(true);\r\n            } else {\r\n                const nextRowInput = document.querySelector(`.cell-input[data-row-idx=\"${rowIdx + 1}\"][data-field=\"${field}\"]`);\r\n                if (nextRowInput) {\r\n                    nextRowInput.focus();\r\n                    nextRowInput.select();\r\n                }\r\n            }\r\n            return;\r\n        }\r\n        if ((!isTextInput && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) || (e.altKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight'))) {\r\n            e.preventDefault();\r\n            if (e.key === 'ArrowLeft') switchTab('preview');\r\n            else switchTab('table');\r\n            return;\r\n        }\r\n        if ((!isTextInput && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) || (e.altKey && (e.key === 'ArrowUp' || e.key === 'ArrowDown'))) {\r\n            e.preventDefault();\r\n            if (e.key === 'ArrowUp') prevCard();\r\n            else nextCard();\r\n            return;\r\n        }\r\n        if (e.key === 'Escape') {\r\n            if (document.getElementById('pasteModal').style.display === 'flex') {\r\n                closePasteModal();\r\n            } else if (isTextInput) {\r\n                target.blur();\r\n            }\r\n        }\r\n    });\r\n    window.addEventListener('paste', (e) => {\r\n        const clipboardData = e.clipboardData || window.clipboardData;\r\n        if (!clipboardData) return;\r\n        const pastedText = clipboardData.getData('text');\r\n        if (!pastedText) return;\r\n        const isMultiLine = pastedText.includes('\\n');\r\n        const hasTabs = pastedText.includes('\\t');\r\n        const target = e.target;\r\n        const isSingleCell = target && target.classList && target.classList.contains('cell-input');\r\n        if (isMultiLine || hasTabs || !isSingleCell) {\r\n            const parsed = parsePastedText(pastedText);\r\n            if (parsed.length > 0) {\r\n                e.preventDefault();\r\n                saveHistory();\r\n                if (isSingleCell) {\r\n                    const rowIdx = parseInt(target.getAttribute('data-row-idx'));\r\n                    peopleList.splice(rowIdx, 1, ...parsed);\r\n                    currentIndex = rowIdx;\r\n                } else if (peopleList.length === 1 && !peopleList[0].name && !peopleList[0].nameEn) {\r\n                    peopleList = parsed;\r\n                    currentIndex = 0;\r\n                } else {\r\n                    peopleList.push(...parsed);\r\n                }\r\n                renderAll();\r\n                showToast(`\u0412\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e ${parsed.length} \u0437\u0430\u043f\u0438\u0441\u0456\u0432!`, \"success\");\r\n            }\r\n        }\r\n    });\r\n    window.addEventListener('resize', () => {\r\n        renderCurrentView();\r\n    });\r\n    \/\/ --- \u0415\u041a\u0421\u041f\u041e\u0420\u0422 \u0423 POWERPOINT (.PPTX) ---\r\n    function generatePPTX() {\r\n        if (typeof PptxGenJS === 'undefined') {\r\n            showToast(\"\u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430 PowerPoint \u0449\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f...\", \"error\");\r\n            return;\r\n        }\r\n        const targets = peopleList.filter(p => p.selected && (p.name?.trim() || p.nameEn?.trim()));\r\n        if (targets.length === 0) {\r\n            showToast(\"\u041d\u0435\u043c\u0430\u0454 \u043e\u0431\u0440\u0430\u043d\u0438\u0445 \u043e\u0441\u0456\u0431 \u0434\u043b\u044f \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u043a\u0430\u0440\u0442\u043e\u043a!\", \"error\");\r\n            return;\r\n        }\r\n        const formatMode = document.getElementById('nameFormatSelect').value;\r\n        const effectiveFontSize = getEffectiveFontSize();\r\n        const uaFontSize = isBilingual ? Math.max(16, Math.round(effectiveFontSize * 0.90)) : effectiveFontSize;\r\n        const posFontSize = Math.max(12, Math.min(22, Math.round(effectiveFontSize * 0.38)));\r\n        const colors = getThemeColors();\r\n        const pptxEnColor = colors.enColor.replace('#', '');\r\n        const pptxUaColor = colors.uaColor.replace('#', '');\r\n        const pptxPosColor = colors.posColor.replace('#', '');\r\n        const pptx = new PptxGenJS();\r\n        pptx.defineLayout({ name: 'A4_Landscape', width: 11.69, height: 8.27 });\r\n        pptx.layout = 'A4_Landscape';\r\n        targets.forEach(person => {\r\n            const displayUa = person.name ? formatPersonName(person.name, formatMode) : \"\";\r\n            const displayEn = person.nameEn ? formatPersonName(person.nameEn, formatMode) : displayUa;\r\n            \/\/ \u0415\u0441\u0442\u0435\u0442\u0438\u0447\u043d\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u044f \u0434\u0443\u0436\u043e\u043a \u0434\u043b\u044f PPTX\r\n            const position = (!isPositionHidden && person.position) \r\n                ? formatPositionText(person.position, false) \r\n                : \"\";\r\n            const slide = pptx.addSlide();\r\n            slide.addShape(pptx.ShapeType.line, {\r\n                x: 0.5, y: 4.135, w: 10.69, h: 0,\r\n                line: { color: 'B0B0B0', width: 0.75, dashType: 'dash' }\r\n            });\r\n            if (isBilingual) {\r\n                \/\/ \u0414\u0412\u041e\u041c\u041e\u0412\u041d\u0418\u0419 \u0420\u0415\u0416\u0418\u041c (EN \u0437\u0432\u0435\u0440\u0445\u0443, UA \u0437\u043d\u0438\u0437\u0443)\r\n                slide.addText(displayEn, {\r\n                    x: 0.5, y: 3.10, w: 10.69, h: 0.75,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: effectiveFontSize, bold: true, fontFace: 'Montserrat', color: pptxEnColor,\r\n                    rotate: 180, wrap: false\r\n                });\r\n                slide.addText(displayUa, {\r\n                    x: 0.5, y: 1.88, w: 10.69, h: 0.75,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: uaFontSize, bold: true, fontFace: 'Montserrat', color: pptxUaColor,\r\n                    rotate: 180, wrap: false\r\n                });\r\n                if (position) {\r\n                    slide.addText(position, {\r\n                        x: 0.5, y: 0.45, w: 10.69, h: 1.3,\r\n                        align: 'center', valign: 'top',\r\n                        fontSize: posFontSize, fontFace: 'Montserrat', color: pptxPosColor,\r\n                        rotate: 180, wrap: true\r\n                    });\r\n                }\r\n                \/\/ \u041d\u0438\u0436\u043d\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430\r\n                slide.addText(displayEn, {\r\n                    x: 0.5, y: 4.45, w: 10.69, h: 0.75,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: effectiveFontSize, bold: true, fontFace: 'Montserrat', color: pptxEnColor,\r\n                    wrap: false\r\n                });\r\n                slide.addText(displayUa, {\r\n                    x: 0.5, y: 5.67, w: 10.69, h: 0.75,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: uaFontSize, bold: true, fontFace: 'Montserrat', color: pptxUaColor,\r\n                    wrap: false\r\n                });\r\n                if (position) {\r\n                    slide.addText(position, {\r\n                        x: 0.5, y: 6.6, w: 10.69, h: 1.3,\r\n                        align: 'center', valign: 'top',\r\n                        fontSize: posFontSize, fontFace: 'Montserrat', color: pptxPosColor,\r\n                        wrap: true\r\n                    });\r\n                }\r\n            } else {\r\n                \/\/ \u0417\u0412\u0418\u0427\u0410\u0419\u041d\u0418\u0419 \u0420\u0415\u0416\u0418\u041c (1 \u043c\u043e\u0432\u0430 UA)\r\n                slide.addText(displayUa, {\r\n                    x: 0.5, y: 2.52, w: 10.69, h: 0.9,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: effectiveFontSize, bold: true, fontFace: 'Montserrat', color: pptxUaColor,\r\n                    rotate: 180, wrap: false\r\n                });\r\n                if (position) {\r\n                    slide.addText(position, {\r\n                        x: 0.5, y: 0.52, w: 10.69, h: 1.9,\r\n                        align: 'center', valign: 'top',\r\n                        fontSize: posFontSize, fontFace: 'Montserrat', color: pptxPosColor,\r\n                        rotate: 180, wrap: true\r\n                    });\r\n                }\r\n                slide.addText(displayUa, {\r\n                    x: 0.5, y: 4.85, w: 10.69, h: 0.9,\r\n                    align: 'center', valign: 'middle',\r\n                    fontSize: effectiveFontSize, bold: true, fontFace: 'Montserrat', color: pptxUaColor,\r\n                    wrap: false\r\n                });\r\n                if (position) {\r\n                    slide.addText(position, {\r\n                        x: 0.5, y: 5.85, w: 10.69, h: 1.9,\r\n                        align: 'center', valign: 'top',\r\n                        fontSize: posFontSize, fontFace: 'Montserrat', color: pptxPosColor,\r\n                        wrap: true\r\n                    });\r\n                }\r\n            }\r\n        });\r\n        const dateStr = new Date().toLocaleDateString('uk-UA').replace(\/\\.\/g, '_');\r\n        pptx.writeFile({ fileName: `Tablychky_${isBilingual ? 'EN_UA_' : ''}A4_${dateStr}.pptx` });\r\n        showToast(`\u0421\u0444\u043e\u0440\u043c\u043e\u0432\u0430\u043d\u043e \u0444\u0430\u0439\u043b \u0434\u043b\u044f ${targets.length} \u043a\u0430\u0440\u0442\u043e\u043a!`, \"success\");\r\n    }\r\n    \/\/ --- \u0428\u0412\u0418\u0414\u041a\u0418\u0419 \u0414\u0420\u0423\u041a \/ PDF ---\r\n    function printBrowserCards() {\r\n        const targets = peopleList.filter(p => p.selected && (p.name?.trim() || p.nameEn?.trim()));\r\n        if (targets.length === 0) {\r\n            showToast(\"\u041d\u0435\u043c\u0430\u0454 \u043e\u0431\u0440\u0430\u043d\u0438\u0445 \u043e\u0441\u0456\u0431 \u0434\u043b\u044f \u0434\u0440\u0443\u043a\u0443!\", \"error\");\r\n            return;\r\n        }\r\n        const formatMode = document.getElementById('nameFormatSelect').value;\r\n        const effectiveFontSize = getEffectiveFontSize();\r\n        const uaFontSize = isBilingual ? Math.max(14, Math.round(effectiveFontSize * 0.90)) : effectiveFontSize;\r\n        const posFontSize = Math.max(10, Math.round(effectiveFontSize * 0.38));\r\n        const colors = getThemeColors();\r\n        let pagesHtml = '';\r\n        targets.forEach(person => {\r\n            const displayUa = person.name ? formatPersonName(person.name, formatMode) : \"\";\r\n            const displayEn = person.nameEn ? formatPersonName(person.nameEn, formatMode) : displayUa;\r\n            const position = (!isPositionHidden && person.position) \r\n                ? formatPositionText(person.position, true) \r\n                : '';\r\n            pagesHtml += `\r\n                <div class=\"print-page\">\r\n                    <div class=\"print-half top\">\r\n                        ${isBilingual ? `<div class=\"p-name-en\">${displayEn}<\/div>` : ''}\r\n                        <div class=\"p-name-ua\">${displayUa}<\/div>\r\n                        ${position ? `<div class=\"p-pos\">${position}<\/div>` : ''}\r\n                    <\/div>\r\n                    <div class=\"print-fold-line\"><\/div>\r\n                    <div class=\"print-half bottom\">\r\n                        ${isBilingual ? `<div class=\"p-name-en\">${displayEn}<\/div>` : ''}\r\n                        <div class=\"p-name-ua\">${displayUa}<\/div>\r\n                        ${position ? `<div class=\"p-pos\">${position}<\/div>` : ''}\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        });\r\n        const printWin = window.open('', '_blank');\r\n        printWin.document.write(`\r\n            <!DOCTYPE html>\r\n            <html>\r\n            <head>\r\n                <title>\u0414\u0440\u0443\u043a \u043d\u0430\u0441\u0442\u0456\u043b\u044c\u043d\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0447\u043e\u043a \u04104<\/title>\r\n                <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@600;800&display=swap\" rel=\"stylesheet\">\r\n                <style>\r\n                    @page { size: A4 landscape; margin: 0; }\r\n                    body { margin: 0; padding: 0; font-family: 'Montserrat', sans-serif; -webkit-print-color-adjust: exact; }\r\n                    .print-page {\r\n                        width: 297mm; height: 210mm;\r\n                        page-break-after: always;\r\n                        display: flex; flex-direction: column;\r\n                        box-sizing: border-box; position: relative;\r\n                    }\r\n                    .print-half {\r\n                        height: 105mm; width: 100%;\r\n                        display: flex; flex-direction: column;\r\n                        align-items: center; justify-content: flex-start;\r\n                        padding-top: 15mm;\r\n                        padding-left: 15mm;\r\n                        padding-right: 15mm;\r\n                        padding-bottom: 8mm;\r\n                        box-sizing: border-box; text-align: center;\r\n                        overflow: hidden;\r\n                    }\r\n                    .print-half.top { transform: rotate(180deg); }\r\n                    .print-fold-line {\r\n                        position: absolute; top: 105mm; left: 0; width: 100%;\r\n                        border-top: 1px dashed #bbb;\r\n                    }\r\n                    .p-name-en {\r\n                        font-size: ${effectiveFontSize}pt;\r\n                        font-weight: 800;\r\n                        color: ${colors.enColor};\r\n                        line-height: 1.15;\r\n                        margin-bottom: 7.5mm;\r\n                        white-space: nowrap;\r\n                        overflow: hidden;\r\n                        text-overflow: ellipsis;\r\n                        width: 100%;\r\n                    }\r\n                    .p-name-ua {\r\n                        font-size: ${uaFontSize}pt;\r\n                        font-weight: 800;\r\n                        color: ${colors.uaColor};\r\n                        line-height: 1.15;\r\n                        margin-bottom: 3.5mm;\r\n                        white-space: nowrap;\r\n                        overflow: hidden;\r\n                        text-overflow: ellipsis;\r\n                        width: 100%;\r\n                    }\r\n                    .p-pos {\r\n                        font-size: ${posFontSize}pt;\r\n                        font-weight: 600;\r\n                        color: ${colors.posColor};\r\n                        line-height: 1.35;\r\n                        max-width: 90%;\r\n                        word-break: break-word;\r\n                    }\r\n                <\/style>\r\n            <\/head>\r\n            <body>\r\n                ${pagesHtml}\r\n                <script>\r\n                    window.onload = function() {\r\n                        setTimeout(function() { window.print(); window.close(); }, 400);\r\n                    };\r\n                <\\\/script>\r\n            <\/body>\r\n            <\/html>\r\n        `);\r\n        printWin.document.close();\r\n    }\r\n    \/\/ --- \u0421\u0422\u0410\u0420\u0422 \u0414\u041e\u0414\u0410\u0422\u041a\u0423 ---\r\n    document.addEventListener('DOMContentLoaded', () => {\r\n        lucide.createIcons();\r\n        loadDemoData();\r\n    });\r\n    setTimeout(() => lucide.createIcons(), 250);\r\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":4,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6671","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/pages\/6671","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6671"}],"version-history":[{"count":1,"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/pages\/6671\/revisions"}],"predecessor-version":[{"id":6672,"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=\/wp\/v2\/pages\/6671\/revisions\/6672"}],"wp:attachment":[{"href":"https:\/\/science.knu.ua\/new\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}