{"id":18301,"date":"2026-02-05T11:43:25","date_gmt":"2026-02-05T04:43:25","guid":{"rendered":"https:\/\/www.ivecr5.ac.th\/web2020\/?page_id=18301"},"modified":"2026-02-23T10:22:37","modified_gmt":"2026-02-23T03:22:37","slug":"%e0%b8%a8%e0%b8%b4%e0%b8%a9%e0%b8%a2%e0%b9%8c%e0%b9%80%e0%b8%81%e0%b9%88%e0%b8%b2","status":"publish","type":"page","link":"https:\/\/www.ivecr5.ac.th\/web2020\/%e0%b8%a8%e0%b8%b4%e0%b8%a9%e0%b8%a2%e0%b9%8c%e0%b9%80%e0%b8%81%e0%b9%88%e0%b8%b2\/","title":{"rendered":"\u0e28\u0e34\u0e29\u0e22\u0e4c\u0e40\u0e01\u0e48\u0e32"},"content":{"rendered":"<div class=\"vce-row-container\" data-vce-boxed-width=\"true\"><div class=\"vce-row vce-row--col-gap-30 vce-row-equal-height vce-row-content--top\" id=\"el-d102a26a\" data-vce-do-apply=\"all el-d102a26a\"><div class=\"vce-row-content\" data-vce-element-content=\"true\"><div class=\"vce-col vce-col--md-auto vce-col--xs-1 vce-col--xs-last vce-col--xs-first vce-col--sm-last vce-col--sm-first vce-col--md-last vce-col--lg-last vce-col--xl-last vce-col--md-first vce-col--lg-first vce-col--xl-first\" id=\"el-8f371d82\"><div class=\"vce-col-inner\" data-vce-do-apply=\"border margin background  el-8f371d82\"><div class=\"vce-col-content\" data-vce-element-content=\"true\" data-vce-do-apply=\"padding el-8f371d82\"><div class=\"vce-raw-html\"><div class=\"vce-raw-html-wrapper\" id=\"el-7b2246cc\" data-vce-do-apply=\"all el-7b2246cc\">\n\n\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32<\/title>\n    <!-- Import Font Kanit -->\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin=\"\">\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Kanit:wght@200;300;400;500;600;700&amp;display=swap\" rel=\"stylesheet\">\n    \n    <style>\n        \/* Scoped Styles for Visual Composer Compatibility *\/\n        #alumni-widget-container {\n            font-family: 'Kanit', sans-serif !important;\n            color: #333;\n            background-color: #fff;\n            padding: 20px;\n            border-radius: 8px;\n            box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n            max-width: 100%;\n            overflow: hidden; \/* Prevent container overflow *\/\n        }\n\n        #alumni-widget-container * {\n            box-sizing: border-box;\n            font-family: 'Kanit', sans-serif !important;\n        }\n\n        \/* Header Section *\/\n        .alumni-header {\n            display: flex;\n            flex-wrap: wrap;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 20px;\n            gap: 15px;\n        }\n\n        .alumni-title h2 {\n            margin: 0;\n            color: #7f1d1d; \/* Dark Red *\/\n            font-size: 24px;\n            font-weight: 600;\n            display: flex;\n            align-items: center;\n            gap: 10px;\n        }\n\n        .alumni-controls {\n            display: flex;\n            gap: 10px;\n            flex-wrap: wrap;\n        }\n\n        .alumni-search-box {\n            position: relative;\n        }\n\n        .alumni-search-box input {\n            padding: 8px 15px 8px 35px;\n            border: 1px solid #ddd;\n            border-radius: 6px;\n            font-size: 14px;\n            width: 250px;\n            outline: none;\n            transition: border-color 0.2s;\n        }\n\n        .alumni-search-box input:focus {\n            border-color: #7f1d1d;\n        }\n\n        \/* Search Icon (Pure CSS) *\/\n        .search-icon {\n            position: absolute;\n            left: 10px;\n            top: 50%;\n            transform: translateY(-50%);\n            width: 14px;\n            height: 14px;\n            border: 2px solid #999;\n            border-radius: 50%;\n        }\n        .search-icon::after {\n            content: '';\n            position: absolute;\n            right: -5px;\n            bottom: -5px;\n            width: 6px;\n            height: 2px;\n            background: #999;\n            transform: rotate(45deg);\n        }\n\n        .btn-refresh {\n            background-color: #991b1b;\n            color: white;\n            border: none;\n            padding: 8px 15px;\n            border-radius: 6px;\n            cursor: pointer;\n            font-size: 14px;\n            display: flex;\n            align-items: center;\n            gap: 5px;\n            transition: background-color 0.2s;\n        }\n\n        .btn-refresh:hover {\n            background-color: #7f1d1d;\n        }\n\n        \/* Table Styles *\/\n        .table-responsive {\n            overflow-x: auto;\n            border: 1px solid #e5e7eb;\n            border-radius: 8px;\n            \/* \u0e40\u0e1e\u0e34\u0e48\u0e21 Scroll Bar \u0e2a\u0e27\u0e22\u0e46 *\/\n            scrollbar-width: thin;\n            scrollbar-color: #cbd5e1 #f1f5f9;\n        }\n        \n        \/* Webkit scrollbar styles *\/\n        .table-responsive::-webkit-scrollbar {\n            height: 8px;\n        }\n        .table-responsive::-webkit-scrollbar-track {\n            background: #f1f5f9;\n        }\n        .table-responsive::-webkit-scrollbar-thumb {\n            background-color: #cbd5e1;\n            border-radius: 4px;\n        }\n\n        #alumni-table {\n            width: 100%;\n            \/* \u0e25\u0e1a min-width \u0e2d\u0e2d\u0e01\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49 flex \u0e15\u0e32\u0e21 content \u0e43\u0e19\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d \u0e41\u0e15\u0e48\u0e22\u0e31\u0e07 scroll \u0e44\u0e14\u0e49 *\/\n            border-collapse: separate; \/* \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19 separate \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49 sticky \u0e17\u0e33\u0e07\u0e32\u0e19\u0e2a\u0e21\u0e1a\u0e39\u0e23\u0e13\u0e4c\u0e01\u0e31\u0e1a border *\/\n            border-spacing: 0;\n            font-size: 14px;\n        }\n\n        #alumni-table th {\n            background-color: #991b1b; \/* Red 800 *\/\n            color: white;\n            padding: 12px 8px;\n            font-weight: 500;\n            text-align: center;\n            border: 1px solid #7f1d1d;\n            white-space: nowrap; \/* \u0e2b\u0e49\u0e32\u0e21\u0e15\u0e31\u0e14\u0e04\u0e33\u0e2b\u0e31\u0e27\u0e15\u0e32\u0e23\u0e32\u0e07 *\/\n        }\n\n        \/* Sticky Column Header *\/\n        #alumni-table th.col-major {\n            text-align: left;\n            padding-left: 15px;\n            position: sticky;\n            left: 0;\n            z-index: 20;\n            min-width: 300px;\n            border-right: 2px solid #7f1d1d;\n        }\n\n        #alumni-table td {\n            padding: 10px 8px;\n            border-bottom: 1px solid #e5e7eb;\n            border-right: 1px solid #e5e7eb;\n            text-align: center;\n            color: #4b5563;\n        }\n\n        \/* Sticky Column Body *\/\n        #alumni-table td.col-major {\n            text-align: left;\n            padding-left: 20px;\n            position: sticky;\n            left: 0;\n            background-color: #fff; \/* \u0e15\u0e49\u0e2d\u0e07\u0e21\u0e35\u0e2a\u0e35\u0e1e\u0e37\u0e49\u0e19\u0e2b\u0e25\u0e31\u0e07 \u0e44\u0e21\u0e48\u0e07\u0e31\u0e49\u0e19\u0e08\u0e30\u0e42\u0e1b\u0e23\u0e48\u0e07\u0e43\u0e2a\u0e40\u0e2b\u0e47\u0e19 text \u0e0b\u0e49\u0e2d\u0e19 *\/\n            z-index: 10;\n            border-right: 2px solid #e5e7eb;\n            font-weight: 400;\n            \/* \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e07\u0e32\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e2b\u0e49\u0e23\u0e39\u0e49\u0e27\u0e48\u0e32\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\u0e25\u0e2d\u0e22 *\/\n            box-shadow: 2px 0 5px rgba(0,0,0,0.05);\n        }\n\n        \/* Row Styling *\/\n        .college-header-row td {\n            background-color: #f3f4f6;\n            font-weight: 600;\n            text-align: left;\n            padding-left: 15px;\n            color: #1f2937;\n            position: sticky;\n            left: 0;\n            z-index: 5;\n        }\n\n        .data-row:hover td {\n            background-color: #fef2f2; \/* Light red hover *\/\n        }\n        \/* Fix hover for sticky column *\/\n        .data-row:hover td.col-major {\n            background-color: #fef2f2;\n        }\n\n        \/* Total Column Header *\/\n        #alumni-table th.col-total {\n            background-color: #7f1d1d; \/* \u0e2a\u0e35\u0e41\u0e14\u0e07\u0e40\u0e02\u0e49\u0e21\u0e01\u0e27\u0e48\u0e32\u0e1b\u0e01\u0e15\u0e34 (Red 900) *\/\n            border-left: 2px solid #ef4444;\n            font-weight: 700;\n        }\n\n        \/* Total Column Body *\/\n        .col-total {\n            font-weight: 700 !important;\n            color: #991b1b !important;\n            background-color: #fef2f2 !important;\n            border-left: 1px solid #fecaca !important;\n        }\n\n        \/* Grand Total Row *\/\n        .grand-total-row td {\n            background-color: #fee2e2 !important;\n            color: #7f1d1d;\n            font-weight: 700;\n            border-top: 2px solid #f87171;\n        }\n        \n        \/* Sticky Grand Total Label *\/\n        .grand-total-row td.col-major {\n            background-color: #fee2e2 !important;\n            z-index: 15; \/* \u0e2a\u0e39\u0e07\u0e01\u0e27\u0e48\u0e32 row \u0e1b\u0e01\u0e15\u0e34 *\/\n        }\n\n        \/* Loading & Empty State *\/\n        .state-message {\n            text-align: center;\n            padding: 40px;\n            color: #6b7280;\n        }\n        \n        \/* Spinner *\/\n        .spinner {\n            border: 4px solid #f3f3f3;\n            border-top: 4px solid #991b1b;\n            border-radius: 50%;\n            width: 30px;\n            height: 30px;\n            animation: spin 1s linear infinite;\n            margin: 0 auto 10px;\n        }\n\n        @keyframes spin {\n            0% { transform: rotate(0deg); }\n            100% { transform: rotate(360deg); }\n        }\n\n        \/* Mobile Adjustments (Responsive) *\/\n        @media (max-width: 768px) {\n            .alumni-header {\n                flex-direction: column;\n                align-items: stretch;\n            }\n            .alumni-search-box input {\n                width: 100%;\n            }\n\n            \/* \u0e1b\u0e23\u0e31\u0e1a\u0e15\u0e32\u0e23\u0e32\u0e07\u0e43\u0e19\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d *\/\n            #alumni-table th.col-major,\n            #alumni-table td.col-major {\n                min-width: 160px; \/* \u0e25\u0e14\u0e04\u0e27\u0e32\u0e21\u0e01\u0e27\u0e49\u0e32\u0e07\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e32\u0e02\u0e32\u0e43\u0e19\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d *\/\n                max-width: 160px;\n                padding-left: 8px;\n                font-size: 12px;\n                white-space: normal; \/* \u0e43\u0e2b\u0e49\u0e15\u0e31\u0e14\u0e04\u0e33\u0e25\u0e07\u0e1a\u0e23\u0e23\u0e17\u0e31\u0e14\u0e43\u0e2b\u0e21\u0e48\u0e44\u0e14\u0e49 *\/\n                line-height: 1.4;\n            }\n\n            #alumni-table th, \n            #alumni-table td {\n                padding: 8px 4px; \/* \u0e25\u0e14 padding *\/\n                font-size: 13px;\n                min-width: 60px; \/* \u0e04\u0e27\u0e32\u0e21\u0e01\u0e27\u0e49\u0e32\u0e07\u0e02\u0e31\u0e49\u0e19\u0e15\u0e48\u0e33\u0e02\u0e2d\u0e07\u0e0a\u0e48\u0e2d\u0e07\u0e1b\u0e35 *\/\n            }\n\n            \/* \u0e1b\u0e23\u0e31\u0e1a\u0e2b\u0e31\u0e27\u0e02\u0e49\u0e2d \"\u0e23\u0e27\u0e21\" \u0e43\u0e19\u0e21\u0e37\u0e2d\u0e16\u0e37\u0e2d *\/\n            #alumni-table th.col-total {\n                min-width: 70px;\n            }\n        }\n    <\/style>\n\n\n\n<!-- Main Widget Container -->\n<div id=\"alumni-widget-container\">\n    \n    <!-- Header & Controls -->\n    <div class=\"alumni-header\">\n        <div class=\"alumni-title\">\n            <h2>\n                <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                    <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"><\/path>\n                    <polyline points=\"14 2 14 8 20 8\"><\/polyline>\n                    <path d=\"M8 13h8\"><\/path>\n                    <path d=\"M8 17h8\"><\/path>\n                    <path d=\"M10 9h4\"><\/path>\n                <\/svg>\n                \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32\n            <\/h2>\n        <\/div>\n        \n        <div class=\"alumni-controls\">\n            <div class=\"alumni-search-box\">\n                <span class=\"search-icon\"><\/span>\n                <input type=\"text\" id=\"searchInput\" placeholder=\"\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e2a\u0e32\u0e02\u0e32 \u0e2b\u0e23\u0e37\u0e2d \u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22...\">\n            <\/div>\n            <button class=\"btn-refresh\" id=\"refreshBtn\">\n                <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n                    <path d=\"M23 4v6h-6\"><\/path>\n                    <path d=\"M1 20v-6h6\"><\/path>\n                    <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"><\/path>\n                <\/svg>\n                \u0e23\u0e35\u0e40\u0e1f\u0e23\u0e0a\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <!-- Table Container -->\n    <div class=\"table-responsive\">\n        <table id=\"alumni-table\">\n            <thead id=\"tableHead\"><\/thead>\n            <tbody id=\"tableBody\"><\/tbody>\n        <\/table>\n    <\/div>\n\n    <!-- Info Section -->\n    <div style=\"margin-top: 20px; padding: 10px; background-color: #eff6ff; border: 1px solid #dbeafe; color: #1e40af; border-radius: 6px; font-size: 12px; display: flex; gap: 10px; flex-wrap: wrap;\">\n        <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" style=\"flex-shrink:0;\"><circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line><\/svg>\n        <div>\n            <b>\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e2b\u0e15\u0e38:<\/b> \u0e40\u0e25\u0e37\u0e48\u0e2d\u0e19\u0e15\u0e32\u0e23\u0e32\u0e07\u0e44\u0e1b\u0e17\u0e32\u0e07\u0e0b\u0e49\u0e32\u0e22-\u0e02\u0e27\u0e32\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e14\u0e39\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1b\u0e35\u0e2d\u0e37\u0e48\u0e19\u0e46 \u0e23\u0e30\u0e1a\u0e1a\u0e08\u0e30\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34\u0e17\u0e38\u0e01 5 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35\n        <\/div>\n    <\/div>\n\n<\/div>\n\n<script>\n    (function() {\n        \/\/ --- CONFIGURATION ---\n        \/\/ \u0e43\u0e2a\u0e48 Link CSV \u0e08\u0e32\u0e01 Google Sheet (File > Share > Publish to web > CSV) \u0e17\u0e35\u0e48\u0e19\u0e35\u0e48\n        const GOOGLE_SHEET_CSV_URL = \"https:\/\/docs.google.com\/spreadsheets\/d\/e\/2PACX-1vSR7Ta2oksF_7ULXy87XjQSlP_SUo5sy-rsqhOuQlUR_OCj1c0MJerYB5fY4yGo_L62C2biqwI0NnRF\/pub?output=csv\"; \n        const REFRESH_INTERVAL_MS = 5000; \/\/ 5 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35\n\n        \/\/ --- MOCK DATA (\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07) ---\n        const MOCK_DATA = [\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e2a\u0e21\u0e38\u0e17\u0e23\u0e2a\u0e32\u0e04\u0e23\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e2a\u0e32\u0e23\u0e2a\u0e19\u0e40\u0e17\u0e28\", y2558: 9, y2559: 10, y2560: 7, y2561: 9, y2562: 5, y2563: 10, y2564: 4, y2565: 8, y2566: 14, y2567: 10 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e2a\u0e21\u0e38\u0e17\u0e23\u0e2a\u0e32\u0e04\u0e23\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e40\u0e21\u0e04\u0e32\u0e17\u0e23\u0e2d\u0e19\u0e34\u0e01\u0e2a\u0e4c\u0e41\u0e25\u0e30\u0e2b\u0e38\u0e48\u0e19\u0e22\u0e19\u0e15\u0e4c\", y2558: 0, y2559: 0, y2560: 0, y2561: 0, y2562: 0, y2563: 0, y2564: 0, y2565: 0, y2566: 8, y2567: 5 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e2a\u0e21\u0e38\u0e17\u0e23\u0e2a\u0e07\u0e04\u0e23\u0e32\u0e21\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e41\u0e21\u0e48\u0e1e\u0e34\u0e21\u0e1e\u0e4c\", y2558: 0, y2559: 24, y2560: 16, y2561: 7, y2562: 29, y2563: 7, y2564: 11, y2565: 25, y2566: 10, y2567: 9 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e2a\u0e21\u0e38\u0e17\u0e23\u0e2a\u0e07\u0e04\u0e23\u0e32\u0e21\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08\u0e14\u0e34\u0e08\u0e34\u0e17\u0e31\u0e25 (\u0e04\u0e2d\u0e21\u0e1e\u0e34\u0e27\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08)\", y2558: 0, y2559: 0, y2560: 11, y2561: 1, y2562: 12, y2563: 10, y2564: 11, y2565: 14, y2566: 18, y2567: 3 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e44\u0e1f\u0e1f\u0e49\u0e32\", y2558: 16, y2559: 10, y2560: 6, y2561: 17, y2562: 18, y2563: 0, y2564: 18, y2565: 18, y2566: 15, y2567: 9 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e01\u0e25 (\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e22\u0e32\u0e19\u0e22\u0e19\u0e15\u0e4c)\", y2558: 0, y2559: 0, y2560: 11, y2561: 9, y2562: 0, y2563: 0, y2564: 4, y2565: 4, y2566: 8, y2567: 0 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e2d\u0e34\u0e40\u0e25\u0e47\u0e01\u0e17\u0e23\u0e2d\u0e19\u0e34\u0e01\u0e2a\u0e4c\", y2558: 0, y2559: 0, y2560: 15, y2561: 6, y2562: 17, y2563: 12, y2564: 14, y2565: 24, y2566: 9, y2567: 7 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e2d\u0e32\u0e0a\u0e35\u0e27\u0e28\u0e36\u0e01\u0e29\u0e32\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e01\u0e32\u0e23\u0e42\u0e23\u0e07\u0e41\u0e23\u0e21\", y2558: 0, y2559: 17, y2560: 10, y2561: 12, y2562: 10, y2563: 16, y2564: 14, y2565: 9, y2566: 16, y2567: 6 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e2d\u0e32\u0e0a\u0e35\u0e27\u0e28\u0e36\u0e01\u0e29\u0e32\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08\u0e14\u0e34\u0e08\u0e34\u0e17\u0e31\u0e25 (\u0e04\u0e2d\u0e21\u0e1e\u0e34\u0e27\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08)\", y2558: 0, y2559: 0, y2560: 15, y2561: 25, y2562: 19, y2563: 29, y2564: 19, y2565: 21, y2566: 22, y2567: 14 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e2d\u0e32\u0e0a\u0e35\u0e27\u0e28\u0e36\u0e01\u0e29\u0e32\u0e40\u0e1e\u0e0a\u0e23\u0e1a\u0e38\u0e23\u0e35\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e01\u0e32\u0e23\u0e15\u0e25\u0e32\u0e14\", y2558: 0, y2559: 0, y2560: 0, y2561: 0, y2562: 0, y2563: 0, y2564: 0, y2565: 12, y2566: 18, y2567: 11 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e1b\u0e23\u0e30\u0e08\u0e27\u0e1a\u0e04\u0e35\u0e23\u0e35\u0e02\u0e31\u0e19\u0e18\u0e4c\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e22\u0e32\u0e19\u0e22\u0e19\u0e15\u0e4c\", y2558: 21, y2559: 15, y2560: 14, y2561: 17, y2562: 17, y2563: 20, y2564: 14, y2565: 17, y2566: 19, y2567: 16 },\n            { college: \"\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22\u0e40\u0e17\u0e04\u0e19\u0e34\u0e04\u0e1b\u0e23\u0e30\u0e08\u0e27\u0e1a\u0e04\u0e35\u0e23\u0e35\u0e02\u0e31\u0e19\u0e18\u0e4c\", major: \"\u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32\u0e40\u0e17\u0e04\u0e42\u0e19\u0e42\u0e25\u0e22\u0e35\u0e01\u0e32\u0e23\u0e1c\u0e25\u0e34\u0e15\", y2558: 0, y2559: 0, y2560: 0, y2561: 0, y2562: 0, y2563: 0, y2564: 0, y2565: 16, y2566: 6, y2567: 19 }\n        ];\n\n        \/\/ --- STATE & UTILS ---\n        let allData = [];\n        let years = []; \n        let isFetching = false;\n\n        \/\/ CSV Parser\n        function parseCSV(text) {\n            const lines = text.split('\\n').filter(line => line.trim() !== '');\n            const headers = lines[0].split(',').map(h => h.trim().replace(\/\"\/g, ''));\n            return lines.slice(1).map(line => {\n                const values = line.match(\/(\".*?\"|[^\",\\s]+)(?=\\s*,|\\s*$)\/g) || [];\n                const rowData = values.length > 0 ? values : line.split(',');\n                return headers.reduce((obj, header, index) => {\n                    let val = rowData[index] ? rowData[index].replace(\/\"\/g, '').trim() : '';\n                    obj[header] = val;\n                    return obj;\n                }, {});\n            });\n        }\n\n        function updateYearsFromData(data) {\n            if (!data || data.length === 0) return;\n            const keys = Object.keys(data[0]);\n            years = keys.filter(k => \n                k.toLowerCase() !== 'college' && \n                k.toLowerCase() !== 'major'\n            ).sort(); \n        }\n\n        function processData(rawData) {\n            return rawData.map(row => {\n                let total = 0;\n                years.forEach(year => {\n                    total += Number(row[year]) || 0;\n                });\n                return { ...row, total };\n            });\n        }\n\n        \/\/ isBackground = true \u0e08\u0e30\u0e44\u0e21\u0e48\u0e42\u0e0a\u0e27\u0e4c\u0e44\u0e2d\u0e04\u0e2d\u0e19\u0e2b\u0e21\u0e38\u0e19\u0e42\u0e2b\u0e25\u0e14 (\u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e01\u0e32\u0e23\u0e01\u0e23\u0e30\u0e1e\u0e23\u0e34\u0e1a)\n        async function loadData(isBackground = false) {\n            if (isFetching) return; \/\/ \u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e01\u0e32\u0e23\u0e14\u0e36\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e0b\u0e49\u0e2d\u0e19\u0e17\u0e31\u0e1a\u0e01\u0e31\u0e19\n            isFetching = true;\n\n            const tableBody = document.getElementById('tableBody');\n            \n            \/\/ \u0e42\u0e0a\u0e27\u0e4c Loading \u0e40\u0e09\u0e1e\u0e32\u0e30\u0e15\u0e2d\u0e19\u0e42\u0e2b\u0e25\u0e14\u0e04\u0e23\u0e31\u0e49\u0e07\u0e41\u0e23\u0e01\u0e2a\u0e38\u0e14 \u0e2b\u0e23\u0e37\u0e2d\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21\u0e23\u0e35\u0e40\u0e1f\u0e23\u0e0a\u0e40\u0e2d\u0e07\n            if (!isBackground && allData.length === 0) {\n                tableBody.innerHTML = '<tr><td colspan=\"100%\" class=\"state-message\"><div class=\"spinner\"><\/div>\u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25...<\/td><\/tr>';\n            }\n            \n            let jsonData = [];\n\n            try {\n                if (GOOGLE_SHEET_CSV_URL) {\n                    const response = await fetch(GOOGLE_SHEET_CSV_URL, { cache: 'no-store' }); \/\/ \u0e1a\u0e31\u0e07\u0e04\u0e31\u0e1a\u0e44\u0e21\u0e48\u0e43\u0e2b\u0e49\u0e15\u0e34\u0e14 cache\n                    const text = await response.text();\n                    jsonData = parseCSV(text);\n                } else {\n                    await new Promise(r => setTimeout(r, 600));\n                    jsonData = MOCK_DATA;\n                }\n\n                updateYearsFromData(jsonData);\n                allData = processData(jsonData);\n                \n                \/\/ \u0e01\u0e23\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e14\u0e49\u0e27\u0e22\u0e04\u0e33\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19 (\u0e16\u0e49\u0e32\u0e21\u0e35) \u0e01\u0e48\u0e2d\u0e19\u0e27\u0e32\u0e14\u0e15\u0e32\u0e23\u0e32\u0e07\n                filterAndRender();\n\n            } catch (error) {\n                console.error(\"Fetch Error:\", error);\n                if (!isBackground) {\n                    setTimeout(() => {\n                        updateYearsFromData(MOCK_DATA);\n                        allData = processData(MOCK_DATA);\n                        filterAndRender();\n                    }, 1000);\n                }\n            } finally {\n                isFetching = false;\n            }\n        }\n\n        \/\/ \u0e14\u0e36\u0e07\u0e04\u0e33\u0e04\u0e49\u0e19\u0e2b\u0e32\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\u0e41\u0e25\u0e30\u0e19\u0e33\u0e44\u0e1b Render\n        function filterAndRender() {\n            const term = document.getElementById('searchInput').value.toLowerCase();\n            let filtered = allData;\n            \n            if (term) {\n                filtered = allData.filter(item => \n                    (item.college && item.college.toLowerCase().includes(term)) || \n                    (item.major && item.major.toLowerCase().includes(term))\n                );\n            }\n            renderTable(filtered);\n        }\n\n        \/\/ \u0e27\u0e34\u0e18\u0e35\u0e43\u0e2b\u0e21\u0e48\u0e15\u0e48\u0e2d String HTML \u0e41\u0e17\u0e19\u0e01\u0e32\u0e23 appendChild \u0e17\u0e35\u0e25\u0e30\u0e2a\u0e48\u0e27\u0e19 \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e44\u0e21\u0e48\u0e43\u0e2b\u0e49\u0e40\u0e01\u0e34\u0e14\u0e2d\u0e32\u0e01\u0e32\u0e23\u0e08\u0e2d\u0e01\u0e23\u0e30\u0e1e\u0e23\u0e34\u0e1a\n        function renderTable(dataToRender) {\n            const tableBody = document.getElementById('tableBody');\n            const tableHead = document.getElementById('tableHead');\n            \n            if (dataToRender.length === 0) {\n                tableBody.innerHTML = '<tr><td colspan=\"100%\" class=\"state-message\">\u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e35\u0e48\u0e04\u0e49\u0e19\u0e2b\u0e32<\/td><\/tr>';\n                return;\n            }\n\n            \/\/ --- 1. \u0e2a\u0e23\u0e49\u0e32\u0e07 HTML \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a Header ---\n            let headHtml = '<tr><th class=\"col-major\">\u0e27\u0e34\u0e17\u0e22\u0e32\u0e25\u0e31\u0e22 \/ \u0e2a\u0e32\u0e02\u0e32\u0e27\u0e34\u0e0a\u0e32<\/th>';\n            years.forEach(year => {\n                const label = year.startsWith('y') ? '\u0e1b\u0e35 ' + year.substring(1) : year;\n                headHtml += `<th>${label}<\/th>`;\n            });\n            headHtml += '<th class=\"col-total\">\u0e23\u0e27\u0e21<\/th><\/tr>';\n\n            \/\/ --- 2. \u0e08\u0e31\u0e14\u0e01\u0e25\u0e38\u0e48\u0e21\u0e41\u0e25\u0e30\u0e2a\u0e23\u0e49\u0e32\u0e07 HTML \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a Body ---\n            const groups = {};\n            dataToRender.forEach(item => {\n                if (!groups[item.college]) groups[item.college] = [];\n                groups[item.college].push(item);\n            });\n\n            const grandTotals = {};\n            years.forEach(y => grandTotals[y] = 0);\n            grandTotals.all = 0;\n\n            let bodyHtml = '';\n\n            Object.keys(groups).forEach(college => {\n                const colSpanCount = 1 + years.length + 1;\n                bodyHtml += `<tr class=\"college-header-row\"><td colspan=\"${colSpanCount}\">${college}<\/td><\/tr>`;\n\n                groups[college].forEach(item => {\n                    years.forEach(y => grandTotals[y] += (Number(item[y]) || 0));\n                    grandTotals.all += item.total;\n                    \n                    bodyHtml += `<tr class=\"data-row\"><td class=\"col-major\">${item.major}<\/td>`;\n                    years.forEach(y => {\n                        const val = Number(item[y]) || 0;\n                        bodyHtml += `<td>${val === 0 ? '-' : val}<\/td>`;\n                    });\n                    bodyHtml += `<td class=\"col-total\">${item.total}<\/td><\/tr>`;\n                });\n            });\n\n            \/\/ Grand Total Row\n            bodyHtml += `<tr class=\"grand-total-row\"><td class=\"col-major\" style=\"text-align:center;\">\u0e23\u0e27\u0e21\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14<\/td>`;\n            years.forEach(y => {\n                bodyHtml += `<td>${grandTotals[y]}<\/td>`;\n            });\n            bodyHtml += `<td class=\"col-total\">${grandTotals.all}<\/td><\/tr>`;\n\n            \/\/ --- 3. \u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15 DOM \u0e23\u0e27\u0e14\u0e40\u0e14\u0e35\u0e22\u0e27 (\u0e44\u0e21\u0e48\u0e21\u0e35\u0e01\u0e23\u0e30\u0e1e\u0e23\u0e34\u0e1a\u0e02\u0e32\u0e27) ---\n            tableHead.innerHTML = headHtml;\n            tableBody.innerHTML = bodyHtml;\n        }\n\n        \/\/ --- EVENT LISTENERS ---\n        document.getElementById('searchInput').addEventListener('input', filterAndRender);\n        document.getElementById('refreshBtn').addEventListener('click', function() {\n            \/\/ \u0e40\u0e21\u0e37\u0e48\u0e2d\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21\u0e14\u0e49\u0e27\u0e22\u0e15\u0e31\u0e27\u0e40\u0e2d\u0e07 \u0e43\u0e2b\u0e49\u0e1a\u0e31\u0e07\u0e04\u0e31\u0e1a\u0e42\u0e2b\u0e25\u0e14\u0e43\u0e2b\u0e21\u0e48\n            loadData(false);\n        });\n\n        \/\/ \u0e42\u0e2b\u0e25\u0e14\u0e04\u0e23\u0e31\u0e49\u0e07\u0e41\u0e23\u0e01\n        loadData(false);\n\n        \/\/ --- \u0e15\u0e31\u0e49\u0e07\u0e40\u0e27\u0e25\u0e32 Auto Refresh \u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e2b\u0e25\u0e31\u0e07 ---\n        setInterval(() => {\n            loadData(true); \/\/ true = \u0e42\u0e2b\u0e25\u0e14\u0e40\u0e1a\u0e37\u0e49\u0e2d\u0e07\u0e2b\u0e25\u0e31\u0e07\u0e41\u0e1a\u0e1a\u0e44\u0e21\u0e48\u0e42\u0e0a\u0e27\u0e4c Spinner\n        }, REFRESH_INTERVAL_MS);\n\n    })();\n<\/script>\n\n\n<\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>\n<p>Views: 118<\/p>","protected":false},"excerpt":{"rendered":"<p>\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32 \u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e1c\u0e39\u0e49\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32 \u0e23\u0e35\u0e40\u0e1f\u0e23\u0e0a  [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"class_list":["post-18301","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/pages\/18301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/comments?post=18301"}],"version-history":[{"count":6,"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/pages\/18301\/revisions"}],"predecessor-version":[{"id":18332,"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/pages\/18301\/revisions\/18332"}],"wp:attachment":[{"href":"https:\/\/www.ivecr5.ac.th\/web2020\/wp-json\/wp\/v2\/media?parent=18301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}