{"id":1342,"date":"2025-12-26T00:35:58","date_gmt":"2025-12-25T15:35:58","guid":{"rendered":"https:\/\/huongvietjp.com\/?page_id=1342"},"modified":"2025-12-26T00:35:58","modified_gmt":"2025-12-25T15:35:58","slug":"dat-ban","status":"publish","type":"page","link":"https:\/\/banhangnhat.com\/vi\/dat-ban\/","title":{"rendered":"\u0110\u1eb7t B\u00e0n"},"content":{"rendered":"        <div id=\"hv-booking-widget\"\n             class=\"hv-booking-section\"\n             data-redirect-url=\"\"\n             data-redirect-delay=\"0\">\n            <div class=\"hv-booking-header\">\n                <h1>\u0110\u1eb7t b\u00e0n \/ \u4e88\u7d04<\/h1>\n                <p>Ch\u1ecdn chi nh\u00e1nh, kh\u00e1ch, gi\u1edd. Ch\u1ea1m ng\u00e0y, ch\u1ecdn gi\u1edd, r\u1ed3i nh\u1eadp th\u00f4ng tin.<br>\u5e97\u30fb\u4eba\u6570\u30fb\u6642\u9593\u3092\u9078\u3073\u3001\u65e5\u4ed8\u3068\u6642\u9593\u3092\u30bf\u30c3\u30d7\u3057\u3066\u5165\u529b\u3057\u307e\u3059\u3002<\/p>\n                <div class=\"hv-pro-badges\"><span>Pro+<\/span><span>Mini<\/span><span>Touch<\/span><span>Fast<\/span><\/div>\n            <\/div>\n\n            <div id=\"hv_booking_form_wrap\" class=\"hv-booking-form-wrap\">\n                <form id=\"hv-booking-form\" class=\"hv-booking-form\">\n                    <div class=\"hv-booking-grid hv-booking-grid-2col\">\n                        <div class=\"hv-column hv-column-left\">\n                            <div class=\"hv-top-filters\">\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_restaurant_id\">Chi nh\u00e1nh \/ \u5e97<\/label>\n                                    <select id=\"hv_restaurant_id\" name=\"restaurant_id\" required>\n                                                                                    <option value=\"2\">\n                                                HUONGVIET\u8c4a\u6a4b\u652f\u5e97 \/ HUONGVIET Chi Nh\u00e1nh Toyohashi                                            <\/option>\n                                                                                    <option value=\"1\">\n                                                HUONGVIET\u77e5\u7acb\u652f\u5e97 \/ HUONGVIET Chi Nh\u00e1nh Chiryu                                            <\/option>\n                                                                            <\/select>\n                                <\/div>\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_party_size\">Kh\u00e1ch \/ \u4eba<\/label>\n                                    <input type=\"number\" id=\"hv_party_size\" name=\"party_size\" min=\"1\" max=\"40\" value=\"2\" required>\n                                <\/div>\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_hour\">B\u1eaft \u0111\u1ea7u \/ \u958b\u59cb<\/label>\n                                    <div class=\"hv-time-row\">\n                                        <select id=\"hv_hour\" class=\"hv-time-hour\">\n                                                                                            <option value=\"00\" >00<\/option>\n                                                                                            <option value=\"01\" >01<\/option>\n                                                                                            <option value=\"02\" >02<\/option>\n                                                                                            <option value=\"03\" >03<\/option>\n                                                                                            <option value=\"04\" >04<\/option>\n                                                                                            <option value=\"05\" >05<\/option>\n                                                                                            <option value=\"06\" >06<\/option>\n                                                                                            <option value=\"07\" >07<\/option>\n                                                                                            <option value=\"08\" >08<\/option>\n                                                                                            <option value=\"09\" >09<\/option>\n                                                                                            <option value=\"10\"  selected='selected'>10<\/option>\n                                                                                            <option value=\"11\" >11<\/option>\n                                                                                            <option value=\"12\" >12<\/option>\n                                                                                            <option value=\"13\" >13<\/option>\n                                                                                            <option value=\"14\" >14<\/option>\n                                                                                            <option value=\"15\" >15<\/option>\n                                                                                            <option value=\"16\" >16<\/option>\n                                                                                            <option value=\"17\" >17<\/option>\n                                                                                            <option value=\"18\" >18<\/option>\n                                                                                            <option value=\"19\" >19<\/option>\n                                                                                            <option value=\"20\" >20<\/option>\n                                                                                            <option value=\"21\" >21<\/option>\n                                                                                            <option value=\"22\" >22<\/option>\n                                                                                            <option value=\"23\" >23<\/option>\n                                                                                    <\/select>\n                                        <select id=\"hv_minute\" class=\"hv-time-minute\">\n                                            <option value=\"00\">00<\/option>\n                                            <option value=\"15\">15<\/option>\n                                            <option value=\"30\">30<\/option>\n                                            <option value=\"45\">45<\/option>\n                                        <\/select>\n                                    <\/div>\n                                <\/div>\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_hour_to\">K\u1ebft th\u00fac \/ \u7d42\u4e86<\/label>\n                                    <div class=\"hv-time-row\">\n                                        <select id=\"hv_hour_to\" class=\"hv-time-hour\">\n                                                                                            <option value=\"00\" >00<\/option>\n                                                                                            <option value=\"01\" >01<\/option>\n                                                                                            <option value=\"02\" >02<\/option>\n                                                                                            <option value=\"03\" >03<\/option>\n                                                                                            <option value=\"04\" >04<\/option>\n                                                                                            <option value=\"05\" >05<\/option>\n                                                                                            <option value=\"06\" >06<\/option>\n                                                                                            <option value=\"07\" >07<\/option>\n                                                                                            <option value=\"08\" >08<\/option>\n                                                                                            <option value=\"09\" >09<\/option>\n                                                                                            <option value=\"10\" >10<\/option>\n                                                                                            <option value=\"11\" >11<\/option>\n                                                                                            <option value=\"12\"  selected='selected'>12<\/option>\n                                                                                            <option value=\"13\" >13<\/option>\n                                                                                            <option value=\"14\" >14<\/option>\n                                                                                            <option value=\"15\" >15<\/option>\n                                                                                            <option value=\"16\" >16<\/option>\n                                                                                            <option value=\"17\" >17<\/option>\n                                                                                            <option value=\"18\" >18<\/option>\n                                                                                            <option value=\"19\" >19<\/option>\n                                                                                            <option value=\"20\" >20<\/option>\n                                                                                            <option value=\"21\" >21<\/option>\n                                                                                            <option value=\"22\" >22<\/option>\n                                                                                            <option value=\"23\" >23<\/option>\n                                                                                    <\/select>\n                                        <select id=\"hv_minute_to\" class=\"hv-time-minute\">\n                                            <option value=\"00\">00<\/option>\n                                            <option value=\"15\">15<\/option>\n                                            <option value=\"30\">30<\/option>\n                                            <option value=\"45\">45<\/option>\n                                        <\/select>\n                                    <\/div>\n                                <\/div>\n                            <\/div>\n\n                            <div class=\"hv-filter-help\">1. Ch\u1ecdn chi nh\u00e1nh, kh\u00e1ch, gi\u1edd. 2. Ch\u1ea1m ng\u00e0y. 3. Ch\u1ecdn gi\u1edd r\u1ed3i nh\u1eadp.<\/div>\n\n                            <div class=\"hv-recommend-card\" id=\"hv_recommend_card\">\n                                <div class=\"hv-recommend-head\">\n                                    <strong>G\u1ee3i \u00fd \/ \u63a8\u5968<\/strong>\n                                    <span class=\"hv-recommend-badge\">AUTO<\/span>\n                                <\/div>\n                                <div class=\"hv-recommend-body\">\n                                    <div class=\"hv-recommend-line\"><span>Ng\u00e0y \/ \u65e5<\/span><strong id=\"hv_best_day\">\u0110ang t\u1ea3i...<\/strong><\/div>\n                                    <div class=\"hv-recommend-line\"><span>Gi\u1edd \/ \u6642\u9593<\/span><strong id=\"hv_best_time\">-<\/strong><\/div>\n                                    <div class=\"hv-recommend-line\"><span>Tr\u1ed1ng \/ \u7a7a<\/span><strong id=\"hv_best_tables\">-<\/strong><\/div>\n                                <\/div>\n                                <div class=\"hv-recommend-actions\">\n                                    <button type=\"button\" id=\"hv_apply_best\" class=\"hv-button-secondary\">\u00c1p d\u1ee5ng<\/button>\n                                    <span id=\"hv_recommend_note\" class=\"hv-quick-note\">\u01afu ti\u00ean gi\u1edd d\u1ec5 \u0111\u1eb7t.<\/span>\n                                <\/div>\n                            <\/div>\n\n                            <input type=\"hidden\" id=\"hv_date\" name=\"date\" required>\n                            <input type=\"hidden\" id=\"hv_time\" name=\"time_from\">\n                            <input type=\"hidden\" id=\"hv_time_to\" name=\"time_to\">\n\n                            <div class=\"hv-calendar-card\">\n                                <div class=\"hv-calendar-toolbar\">\n                                    <button type=\"button\" id=\"hv_prev_month\" class=\"hv-icon-btn hv-icon-btn-nav\" aria-label=\"Th\u00e1ng tr\u01b0\u1edbc\"><span class=\"hv-icon-arrow\">\u25c0<\/span><span class=\"hv-icon-text\">Tr\u01b0\u1edbc<\/span><\/button>\n                                    <div>\n                                        <div id=\"hv_calendar_title\" class=\"hv-calendar-title\"><\/div>\n                                        <div id=\"hv_calendar_subtitle\" class=\"hv-calendar-subtitle\">\u0110\u00e3 l\u1ecdc theo chi nh\u00e1nh, kh\u00e1ch, gi\u1edd.<\/div>\n                                    <\/div>\n                                    <button type=\"button\" id=\"hv_next_month\" class=\"hv-icon-btn hv-icon-btn-nav\" aria-label=\"Th\u00e1ng sau\"><span class=\"hv-icon-text\">Sau<\/span><span class=\"hv-icon-arrow\">\u25b6<\/span><\/button>\n                                <\/div>\n                                <div class=\"hv-calendar-weekdays\">\n                                    <span>Mon<\/span><span>Tue<\/span><span>Wed<\/span><span>Thu<\/span><span>Fri<\/span><span>Sat<\/span><span>Sun<\/span>\n                                <\/div>\n                                <div id=\"hv_calendar_grid\" class=\"hv-calendar-grid\"><\/div>\n                                <div class=\"hv-calendar-legend\">\n                                    <span><i class=\"hv-dot hv-dot-ok\"><\/i> Tr\u1ed1ng \/ \u7a7a<\/span>\n                                    <span><i class=\"hv-dot hv-dot-req\"><\/i> \u00cdt \/ \u5c11<\/span>\n                                    <span><i class=\"hv-dot hv-dot-no\"><\/i> H\u1ebft \/ \u6e80<\/span>\n                                    <span><i class=\"hv-dot hv-dot-closed\"><\/i> Ngh\u1ec9 \/ \u4f11<\/span>\n                                <\/div>\n                                <div class=\"hv-calendar-tip\">Ch\u1ea1m ng\u00e0y c\u00f2n ch\u1ed7 \u0111\u1ec3 \u0111\u1eb7t.<\/div>\n                            <\/div>\n\n                            <div class=\"hv-timeslots-card\">\n                                <div class=\"hv-timeslots-head\">\n                                    <strong>Gi\u1edd \/ \u6642<\/strong>\n                                    <span id=\"hv_selected_date_label\">Ch\u01b0a ch\u1ecdn \/ \u672a\u9078\u629e<\/span>\n                                <\/div>\n                                <div id=\"hv_timeslot_list\" class=\"hv-timeslot-list\">\n                                    <div class=\"hv-placeholder\">Ch\u1ecdn ng\u00e0y \u0111\u1ec3 xem gi\u1edd.<\/div>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n\n                        <div class=\"hv-column hv-column-right\">\n                            <div class=\"hv-side-card\">\n                                <div class=\"hv-side-summary\">\n                                    <div class=\"hv-side-summary-row\"><span>Chi nh\u00e1nh \/ \u5e97<\/span><strong id=\"hv_summary_branch\">-<\/strong><\/div>\n                                    <div class=\"hv-side-summary-row\"><span>Ng\u00e0y \/ \u65e5<\/span><strong id=\"hv_summary_date\">-<\/strong><\/div>\n                                    <div class=\"hv-side-summary-row\"><span>Gi\u1edd \/ \u6642<\/span><strong id=\"hv_summary_time\">-<\/strong><\/div>\n                                    <div class=\"hv-side-summary-row\"><span>Kh\u00e1ch \/ \u4eba<\/span><strong id=\"hv_summary_party\">2<\/strong><\/div>\n                                <\/div>\n\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_floor\">T\u1ea7ng \/ \u968e<\/label>\n                                    <select id=\"hv_floor\" name=\"floor_id\" required>\n                                        <option value=\"\">Ch\u1ecdn t\u1ea7ng \/ \u968e<\/option>\n                                    <\/select>\n                                <\/div>\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_table\">B\u00e0n \/ \u5e2d<\/label>\n                                    <select id=\"hv_table\" name=\"table_id\" required>\n                                        <option value=\"\">Ch\u1ecdn b\u00e0n \/ \u5e2d<\/option>\n                                    <\/select>\n                                    <div id=\"hv_table_quick_status\" class=\"hv-quick-note\">Ch\u1ecdn ng\u00e0y gi\u1edd \u0111\u1ec3 g\u1ee3i \u00fd t\u1ea7ng \/ b\u00e0n.<\/div>\n                                <\/div>\n\n                                <hr class=\"hv-separator\">\n\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_name\">T\u00ean \/ \u540d\u524d<\/label>\n                                    <input type=\"text\" id=\"hv_name\" name=\"customer_name\" value=\"\" required>\n                                <\/div>\n\n                                <div class=\"hv-field hv-field-inline hv-field-inline-2\">\n                                    <div class=\"hv-field\">\n                                        <label for=\"hv_phone\">\u0110T \/ TEL<\/label>\n                                        <input type=\"text\" id=\"hv_phone\" name=\"customer_phone\">\n                                    <\/div>\n                                    <div class=\"hv-field\">\n                                        <label for=\"hv_email\">Email<\/label>\n                                        <input type=\"email\" id=\"hv_email\" name=\"customer_email\" value=\"\">\n                                    <\/div>\n                                <\/div>\n\n                                <div class=\"hv-field hv-postal\">\n                                    <label for=\"hv_postal_code\">\u90f5\u4fbf\u756a\u53f7 \/ M\u00e3 b\u01b0u \u0111i\u1ec7n<\/label>\n                                    <div class=\"hv-postal-row\">\n                                        <input type=\"text\" id=\"hv_postal_code\" name=\"postal_code\" placeholder=\"100-0001\">\n                                        <button type=\"button\" id=\"hv_postal_lookup\" class=\"hv-button-secondary\">T\u00ecm \u0111\u1ecba ch\u1ec9 \/ \u691c\u7d22<\/button>\n                                    <\/div>\n                                    <div id=\"hv_postal_status\" class=\"hv-postal-status\"><\/div>\n                                <\/div>\n\n                                <div class=\"hv-field hv-field-inline hv-field-inline-2\">\n                                    <div class=\"hv-field\">\n                                        <label for=\"hv_prefecture\">\u90fd\u9053\u5e9c\u770c \/ T\u1ec9nh<\/label>\n                                        <input type=\"text\" id=\"hv_prefecture\" name=\"prefecture\">\n                                    <\/div>\n                                    <div class=\"hv-field\">\n                                        <label for=\"hv_city\">\u5e02\u533a\u753a\u6751 \/ Th\u00e0nh ph\u1ed1<\/label>\n                                        <input type=\"text\" id=\"hv_city\" name=\"city\">\n                                    <\/div>\n                                <\/div>\n\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_address_line\">\u4f4f\u6240 \/ \u0110\u1ecba ch\u1ec9 chi ti\u1ebft<\/label>\n                                    <input type=\"text\" id=\"hv_address_line\" name=\"address_line\">\n                                <\/div>\n\n                                <div class=\"hv-field\">\n                                    <label for=\"hv_note\">Ghi ch\u00fa \/ \u5099\u8003<\/label>\n                                    <textarea id=\"hv_note\" name=\"note\" rows=\"3\"><\/textarea>\n                                <\/div>\n\n                                <div class=\"hv-actions\">\n                                    <button type=\"submit\" id=\"hv_submit\" class=\"hv-button-primary\">\u0110\u1eb7t b\u00e0n \/ \u4e88\u7d04<\/button>\n                                <\/div>\n\n                                <p id=\"hv_booking_message\" class=\"hv-booking-message\" aria-live=\"polite\"><\/p>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                <\/form>\n            <\/div>\n\n            <div id=\"hv_booking_success_wrap\" class=\"hv-booking-success\" style=\"display:none;\">\n                <h2>\u0110\u1eb6T B\u00c0N TH\u00c0NH C\u00d4NG \/ \u3054\u4e88\u7d04\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f<\/h2>\n                <p class=\"hv-booking-success-text\">C\u1ea3m \u01a1n Qu\u00fd kh\u00e1ch \u0111\u00e3 \u0111\u1eb7t b\u00e0n t\u1ea1i HUONGVIET.<br>\u3054\u4e88\u7d04\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\u3002<\/p>\n                <ul class=\"hv-booking-success-summary\">\n                    <li><strong>Chi nh\u00e1nh \/ \u5e97:<\/strong> <span id=\"hv_success_restaurant\"><\/span><\/li>\n                    <li><strong>Ng\u00e0y gi\u1edd \/ \u65e5\u6642:<\/strong> <span id=\"hv_success_datetime\"><\/span><\/li>\n                    <li><strong>Kh\u00e1ch \/ \u4eba:<\/strong> <span id=\"hv_success_party\"><\/span><\/li>\n                    <li><strong>T\u1ea7ng \/ B\u00e0n:<\/strong> <span id=\"hv_success_table\"><\/span><\/li>\n                <\/ul>\n                <p id=\"hv_booking_success_message\" class=\"hv-booking-message\" aria-live=\"polite\"><\/p>\n            <\/div>\n        <\/div>\n\n        <style>\n            .hv-booking-section {\n                max-width: 1200px;\n                margin: 24px auto 40px;\n                padding: 24px 20px 28px;\n                background: #ffffff;\n                border-radius: 18px;\n                box-shadow: 0 10px 25px rgba(0,0,0,0.06);\n                border: 1px solid #e7dfd0;\n            }\n            .hv-booking-header h1 {\n                font-size: clamp(1.8rem, 2.8vw, 2.6rem);\n                margin-bottom: 8px;\n                line-height: 1.15;\n            }\n            .hv-booking-header p {\n                font-size: 0.98rem;\n                color: #666;\n                margin-bottom: 20px;\n            }\n            .hv-pro-badges { display:flex; flex-wrap:wrap; gap:6px; margin-top:-6px; margin-bottom:22px; }\n            .hv-pro-badges span { background: linear-gradient(135deg,#1d1d1d,#7a5c3a); color:#fff; border-radius:999px; padding:6px 10px; font-size:0.78rem; letter-spacing:.02em; box-shadow:0 8px 24px rgba(0,0,0,0.08); }\n            .hv-filter-help { margin: 0 0 12px; padding: 8px 10px; border-radius: 12px; background: linear-gradient(135deg,#fbf7f0,#f5ede3); border:1px solid #eadfce; color:#6b5640; font-size:0.82rem; }\n            .hv-recommend-card { padding: 8px 10px; border-radius: 14px; margin-bottom: 8px; }\n            .hv-recommend-head { margin-bottom: 8px; }\n            .hv-recommend-head strong { font-size: 0.9rem; }\n            .hv-recommend-badge { font-size: 0.72rem; padding: 5px 10px; }\n            .hv-recommend-body { gap: 8px; }\n            .hv-recommend-line { padding: 7px 9px; border-radius: 10px; }\n            .hv-recommend-line span { font-size: 0.76rem; }\n            .hv-recommend-line strong { font-size: 0.86rem; }\n            .hv-recommend-actions { gap: 8px; margin-top: 8px; }\n            .hv-quick-note { font-size: 0.78rem; line-height: 1.25; }\n\n            .hv-top-filters { position: sticky; top: 10px; z-index: 2; background: linear-gradient(180deg,#fff 0%,#fbf8f4 100%); }\n            .hv-field input:focus, .hv-field select:focus, .hv-field textarea:focus { outline:none; border-color:#9c7a52; box-shadow:0 0 0 4px rgba(156,122,82,0.12); }\n            .hv-calendar-card { background: linear-gradient(180deg,#fff 0%,#fcfaf6 100%); }\n            .hv-booking-header p { margin-bottom: 10px; line-height: 1.45; }\n            .hv-icon-btn:hover { border-color:#9c7a52; transform: translateY(-1px); box-shadow:0 10px 18px rgba(0,0,0,0.08); }\n            .hv-calendar-day { position:relative; overflow:hidden; }\n            .hv-calendar-day::after { content:\"\"; position:absolute; inset:auto 0 0 0; height:3px; opacity:.95; }\n            .hv-calendar-day .hv-calendar-day-meta { font-size:0.62rem; color:#7a6d60; margin-top:0; line-height:1.05; }\n            .hv-status-ok { background:linear-gradient(180deg,#ffffff 0%,#f1fbf5 100%); }\n            .hv-status-ok::after { background:#2fb163; }\n            .hv-status-req { background:linear-gradient(180deg,#ffffff 0%,#fff8e8 100%); }\n            .hv-status-req::after { background:#e2a11a; }\n            .hv-status-no { background:linear-gradient(180deg,#ffffff 0%,#fff1ee 100%); }\n            .hv-status-no::after { background:#dd5a48; }\n            .hv-status-closed { background:linear-gradient(180deg,#fff8f8 0%,#f6eeee 100%); }\n            .hv-status-past { background:linear-gradient(180deg,#ffffff 0%,#f3f3f3 100%); }\n            .hv-status-closed::after { background:#8b0000; }\n            .hv-status-past::after { background:#999; }\n            .hv-calendar-day.is-past { opacity:.62; }\n            .hv-status-past .hv-calendar-day-status { color:#7a7a7a; }\n            .hv-calendar-day.is-best { border-color:#2fb163; box-shadow:0 0 0 2px rgba(47,177,99,0.12); }\n            .hv-calendar-day.is-best .hv-calendar-day-num::before { content:\"\u2605 \"; color:#2fb163; font-size:0.82rem; }\n            .hv-timeslot-list { gap:10px; }\n            .hv-timeslot-btn { transition:.18s ease; }\n            .hv-timeslot-btn:hover { transform: translateY(-1px); border-color:#9c7a52; }\n            .hv-timeslot-btn.is-recommended { border-color:#2fb163; box-shadow:0 0 0 3px rgba(47,177,99,0.10); }\n            .hv-timeslot-btn.is-disabled { background:#f7f7f7; text-decoration:line-through; }\n            .hv-side-card { position: sticky; top: 10px; background: linear-gradient(180deg,#fff 0%,#fcfaf7 100%); }\n            .hv-side-summary-row strong { text-align:right; }\n            .hv-booking-section { background: linear-gradient(180deg,#ffffff 0%,#faf7f2 100%); }\n            .hv-booking-header h1 { letter-spacing:.01em; }\n            .hv-quick-note { margin-top:10px; color:#746657; font-size:.9rem; }\n            .hv-recommend-card { margin-bottom:14px; background: radial-gradient(circle at top right,#fff8ed 0%,#fff 42%,#fbf7f0 100%); border:1px solid #e9d8bf; border-radius:16px; padding:12px; box-shadow:0 6px 18px rgba(122,92,58,0.08); position:relative; overflow:hidden; }\n            .hv-recommend-card::before { content:\"\"; position:absolute; inset:-40% auto auto 55%; width:180px; height:180px; background:radial-gradient(circle, rgba(255,214,153,.32), rgba(255,214,153,0)); pointer-events:none; }\n            .hv-recommend-head { display:flex; align-items:center; justify-content:space-between; gap:6px; margin-bottom:8px; position:relative; z-index:1; }\n            .hv-recommend-badge { display:inline-flex; align-items:center; justify-content:center; border-radius:999px; padding:6px 10px; background:linear-gradient(135deg,#111,#8b6b46); color:#fff; font-size:.75rem; letter-spacing:.08em; }\n            .hv-recommend-body { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:6px; position:relative; z-index:1; }\n            .hv-recommend-line { padding:8px 10px; border-radius:12px; background:rgba(255,255,255,.8); border:1px solid #efe2d2; }\n            .hv-recommend-line span { display:block; font-size:.76rem; color:#7a6a58; margin-bottom:3px; }\n            .hv-recommend-line strong { display:block; font-size:.92rem; color:#2d241b; line-height:1.2; }\n            .hv-recommend-actions { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px; position:relative; z-index:1; }\n            .hv-availability-pill { display:inline-flex; align-items:center; gap:6px; padding:8px 12px; border-radius:999px; background:#f7f2ea; border:1px solid #eadfce; color:#5f513f; font-size:.88rem; }\n            .hv-booking-grid-2col {\n                display: grid;\n                grid-template-columns: minmax(0, 1.8fr) minmax(320px, 1fr);\n                gap: 20px;\n                align-items: start;\n            }\n            .hv-top-filters,\n            .hv-side-card,\n            .hv-calendar-card,\n            .hv-timeslots-card {\n                background: #fff;\n                border: 1px solid #e9e2d7;\n                border-radius: 16px;\n                padding: 14px;\n                box-shadow: 0 4px 14px rgba(0,0,0,0.03);\n            }\n            .hv-top-filters {\n                display: grid;\n                grid-template-columns: repeat(4, minmax(0, 1fr));\n                gap: 8px;\n                margin-bottom: 8px;\n            }\n            .hv-field { margin-bottom: 9px; }\n            .hv-field label {\n                display: block;\n                font-weight: 600;\n                margin-bottom: 4px;\n                font-size: 0.88rem;\n                color: #5b4730;\n            }\n            .hv-field input,\n            .hv-field select,\n            .hv-field textarea {\n                width: 100%;\n                padding: 8px 10px;\n                border-radius: 10px;\n                border: 1px solid #d7d2ca;\n                font-size: 0.92rem;\n                box-sizing: border-box;\n                background: #fff;\n            }\n            .hv-time-row { display:flex; gap:6px; }\n            .hv-time-row select { flex:1; min-width:0; }\n            .hv-field-inline-2 {\n                display: grid;\n                grid-template-columns: repeat(2, minmax(0, 1fr));\n                gap: 12px;\n            }\n            .hv-calendar-toolbar {\n                display: flex;\n                justify-content: space-between;\n                align-items: center;\n                gap: 8px;\n                margin-bottom: 8px;\n            }\n            .hv-calendar-title { font-size: 1.1rem; font-weight: 700; color: #2d2d2d; line-height:1.1; }\n            .hv-calendar-subtitle { font-size: 0.74rem; color: #777; line-height:1.2; }\n            .hv-icon-btn {\n                width: 40px; height: 40px; border-radius: 12px; border: 1px solid #d7d2ca;\n                background: #fff; cursor: pointer; font-size: 16px;\n            }\n            .hv-icon-btn-nav {\n                width: auto;\n                min-width: 96px;\n                height: 38px;\n                padding: 0 10px;\n                display: inline-flex;\n                align-items: center;\n                justify-content: center;\n                gap: 8px;\n                font-size: 13px;\n                font-weight: 600;\n                color: #5f4d39;\n                white-space: nowrap;\n            }\n            .hv-icon-btn-nav .hv-icon-arrow {\n                font-size: 15px;\n                line-height: 1;\n            }\n            .hv-icon-btn-nav .hv-icon-text {\n                line-height: 1;\n            }\n            .hv-calendar-weekdays,\n            .hv-calendar-grid {\n                contain: layout paint;\n                display: grid;\n                grid-template-columns: repeat(7, minmax(0, 1fr));\n                gap: 6px;\n            }\n            .hv-calendar-weekdays {\n                margin-bottom: 6px;\n                color: #7b6d5c;\n                font-size: 0.8rem;\n                text-align: center;\n            }\n            .hv-calendar-day {\n                min-height: 26px;\n                border-radius: 10px;\n                border: 1px solid #e4ddd2;\n                background: #fff;\n                padding: 3px 4px;\n                text-align: left;\n                cursor: pointer;\n                display: flex;\n                flex-direction: column;\n                justify-content: flex-start;\n                gap: 1px;\n                transition: .18s ease;\n                line-height: 1.15;\n            }\n            .hv-calendar-day:hover { transform: translateY(-1px); box-shadow: 0 6px 15px rgba(0,0,0,0.05); }\n            .hv-calendar-day.is-empty { visibility: hidden; }\n            .hv-calendar-day.is-disabled { cursor: not-allowed; opacity: .58; }\n            .hv-calendar-day.is-selected { border-color: #111; box-shadow: 0 0 0 2px rgba(0,0,0,0.06); }\n            .hv-calendar-day-num { font-weight: 700; font-size: 0.8rem; color: #2b2b2b; line-height:1; }\n            .hv-calendar-day-status { font-size: 0.58rem; font-weight: 700; line-height:1; }\n            .hv-status-ok .hv-calendar-day-status { color: #1f8c4c; }\n            .hv-status-req .hv-calendar-day-status { color: #c48a00; }\n            .hv-status-no .hv-calendar-day-status { color: #d6513d; }\n            .hv-status-closed .hv-calendar-day-status { color: #8b0000; font-weight: 800; }\n            .hv-calendar-legend {\n                display:flex; flex-wrap:wrap; gap:8px; margin-top:8px; font-size:0.76rem; color:#5f5f5f;\n            }\n            .hv-dot { display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:6px; vertical-align:middle; }\n            .hv-dot-ok { background:#34b566; }\n            .hv-dot-req { background:#f2b233; }\n            .hv-dot-no { background:#e15b49; }\n            .hv-dot-closed { background:#9b9b9b; }\n            .hv-calendar-tip { margin-top: 5px; font-size: 0.72rem; color: #6d6257; }\n            .hv-timeslots-head { display:flex; justify-content:space-between; align-items:center; gap:6px; margin-bottom:8px; }\n            .hv-selected-date-label, #hv_selected_date_label { color:#6e6257; font-size:0.84rem; }\n            .hv-timeslot-list { display:flex; flex-wrap:wrap; gap:6px; }\n            .hv-timeslot-btn {\n                padding: 6px 10px; border-radius: 999px; border:1px solid #d7d2ca; background:#fff; cursor:pointer; font-size:0.82rem;\n            }\n            .hv-timeslot-btn.is-active { background:#111; color:#fff; border-color:#111; }\n            .hv-timeslot-btn.is-disabled { opacity:.48; cursor:not-allowed; }\n            .hv-placeholder { color:#7a7a7a; font-size:0.95rem; }\n            .hv-side-summary {\n                padding: 10px; border-radius: 12px; background: #f9f6f1; border: 1px solid #ece2d3; margin-bottom: 10px;\n            }\n            .hv-side-summary-row {\n                display:flex; justify-content:space-between; gap:10px; font-size:0.84rem; padding:3px 0;\n            }\n            .hv-postal-row { display:flex; gap:6px; align-items:center; }\n            .hv-postal-row input { flex:1 1 auto; min-width:0; }\n            .hv-button-primary,\n            .hv-button-secondary {\n                display: inline-block; padding: 8px 12px; border-radius: 10px; border: none; cursor: pointer; font-size: 0.84rem; text-decoration: none;\n            }\n            .hv-button-primary { background: #111; color: #fff; width: 100%; }\n            .hv-button-primary:disabled { opacity: 0.6; cursor: wait; }\n            .hv-button-secondary { background: #f5f5f5; color: #333; border: 1px solid #ddd; white-space: nowrap; }\n            .hv-actions { margin-top: 12px; }\n            .hv-booking-message { margin-top: 8px; font-size: 0.84rem; }\n            .hv-booking-success { text-align: center; padding-top: 10px; }\n            .hv-booking-success-summary { list-style: none; padding: 0; margin: 16px auto; text-align: left; display: inline-block; }\n            .hv-booking-success-summary li { margin-bottom: 4px; }\n            .hv-separator { border: 0; border-top: 1px dashed #ddd; margin: 14px 0; }\n            @media (max-width: 980px) {\n                .hv-booking-grid-2col { grid-template-columns: 1fr; }\n                .hv-top-filters, .hv-side-card { position: static; }\n            }\n            @media (max-width: 768px) {\n                .hv-booking-section { padding: 12px 8px 16px; border-radius: 14px; }\n                .hv-top-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n                .hv-calendar-day { min-height: 22px; padding: 2px 3px; border-radius: 9px; }\n                .hv-calendar-day-num { font-size: 0.74rem; }\n                .hv-calendar-day-status { font-size: 0.54rem; }\n                .hv-calendar-day .hv-calendar-day-meta { font-size: 0.56rem; }\n                .hv-field-inline-2 { grid-template-columns: 1fr; }\n                .hv-recommend-body { grid-template-columns: 1fr; }\n                .hv-recommend-actions { flex-direction: column; align-items: flex-start; }\n            }\n            @media (max-width: 520px) {\n                .hv-top-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); gap:6px; }\n                .hv-field label { font-size: 0.8rem; }\n                .hv-field input, .hv-field select, .hv-field textarea { font-size: 0.84rem; padding: 8px 9px; }\n                .hv-pro-badges { gap:5px; }\n                .hv-pro-badges span { font-size:0.7rem; padding:5px 8px; }\n                .hv-calendar-weekdays, .hv-calendar-grid { gap: 4px; }\n                .hv-calendar-weekdays { font-size: 0.7rem; margin-bottom: 4px; }\n                .hv-calendar-day { min-height: 18px; padding: 2px 2px; border-radius: 8px; gap: 0; }\n                .hv-calendar-day-num { font-size: 0.68rem; }\n                .hv-calendar-day-status { font-size: 0.5rem; }\n                .hv-calendar-day .hv-calendar-day-meta { font-size: 0.5rem; }\n                .hv-calendar-title { font-size: 0.96rem; }\n                .hv-calendar-subtitle, .hv-filter-help, .hv-calendar-tip, .hv-quick-note { font-size: 0.68rem; }\n                .hv-icon-text { font-size: 0.72rem; }\n                .hv-postal-row { flex-direction: column; align-items: stretch; }\n                .hv-recommend-card { padding:10px; }\n                .hv-timeslot-btn { font-size:0.74rem; padding:5px 8px; }\n            }\n        <\/style>\n\n        <script>\n        (function() {\n            var hvStaticStructure = {\"floors\":[{\"id\":1,\"restaurant_id\":1,\"floor_code\":\"1F\",\"name_ja\":\"1\\u968e T\\u1ea7ng 1\",\"name_vi\":\"1\\u968e T\\u1ea7ng 1\",\"is_active\":1},{\"id\":2,\"restaurant_id\":2,\"floor_code\":\"1F\",\"name_ja\":\"1\\u968e-T\\u1ea7ng 1\",\"name_vi\":\"1\\u968e-T\\u1ea7ng 1\",\"is_active\":1},{\"id\":3,\"restaurant_id\":2,\"floor_code\":\"2F\",\"name_ja\":\"2\\u968e-T\\u1ea7ng 2\",\"name_vi\":\"2\\u968e-T\\u1ea7ng 2\",\"is_active\":1},{\"id\":4,\"restaurant_id\":2,\"floor_code\":\"3F\",\"name_ja\":\"3\\u968e-T\\u1ea7ng 3\",\"name_vi\":\"3\\u968e-T\\u1ea7ng 3\",\"is_active\":1},{\"id\":5,\"restaurant_id\":2,\"floor_code\":\"4F\",\"name_ja\":\"4\\u968e-T\\u1ea7ng 4(C\\u01b0\\u1edbi, ti\\u1ec7c)\",\"name_vi\":\"4\\u968e-T\\u1ea7ng 4(C\\u01b0\\u1edbi, ti\\u1ec7c)\",\"is_active\":1},{\"id\":6,\"restaurant_id\":2,\"floor_code\":\"4F\",\"name_ja\":\"4\\u968e-T\\u1ea7ng 4(S\\u1ef1 Ki\\u1ec7n)\",\"name_vi\":\"4\\u968e-T\\u1ea7ng 4(S\\u1ef1 Ki\\u1ec7n)\",\"is_active\":1}],\"tables\":[{\"id\":1,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-01\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 1\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 1\",\"min_seats\":2,\"max_seats\":6,\"status\":\"active\"},{\"id\":2,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-02\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 2\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 2\",\"min_seats\":2,\"max_seats\":6,\"status\":\"active\"},{\"id\":3,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-03\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 3\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 3\",\"min_seats\":2,\"max_seats\":6,\"status\":\"active\"},{\"id\":4,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-04\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 4\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 4\",\"min_seats\":2,\"max_seats\":6,\"status\":\"active\"},{\"id\":5,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-05\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 5\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 5\",\"min_seats\":1,\"max_seats\":2,\"status\":\"active\"},{\"id\":6,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-06\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 6\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 6\",\"min_seats\":1,\"max_seats\":2,\"status\":\"active\"},{\"id\":7,\"restaurant_id\":1,\"floor_id\":1,\"table_code\":\"T-07\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 7\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 7\",\"min_seats\":1,\"max_seats\":2,\"status\":\"active\"},{\"id\":8,\"restaurant_id\":2,\"floor_id\":5,\"table_code\":\"T\\u1ea6NG 4\",\"name_ja\":\"\\u5927\\u30db\\u30fc\\u30eb-Ph\\u00f2ng L\\u1edbn\",\"name_vi\":\"\\u5927\\u30db\\u30fc\\u30eb-Ph\\u00f2ng L\\u1edbn\",\"min_seats\":10,\"max_seats\":80,\"status\":\"active\"},{\"id\":9,\"restaurant_id\":2,\"floor_id\":4,\"table_code\":\"T-301\",\"name_ja\":\"BIDA VIP-\\u30d3\\u30ea\\u30e4\\u30fc\\u30c9VIP\",\"name_vi\":\"BIDA VIP-\\u30d3\\u30ea\\u30e4\\u30fc\\u30c9VIP\",\"min_seats\":1,\"max_seats\":6,\"status\":\"active\"},{\"id\":10,\"restaurant_id\":2,\"floor_id\":4,\"table_code\":\"T302\",\"name_ja\":\"BIDA -\\u30d3\\u30ea\\u30e4\\u30fc\\u30c9\",\"name_vi\":\"BIDA -\\u30d3\\u30ea\\u30e4\\u30fc\\u30c9\",\"min_seats\":1,\"max_seats\":6,\"status\":\"active\"},{\"id\":11,\"restaurant_id\":2,\"floor_id\":3,\"table_code\":\"VIP\",\"name_ja\":\"KARAOKE VIP\",\"name_vi\":\"KARAOKE VIP\",\"min_seats\":1,\"max_seats\":10,\"status\":\"active\"},{\"id\":12,\"restaurant_id\":2,\"floor_id\":3,\"table_code\":\"VIP MAX\",\"name_ja\":\"KARAOKE VIP MAX\",\"name_vi\":\"KARAOKE VIP MAX\",\"min_seats\":1,\"max_seats\":30,\"status\":\"active\"},{\"id\":13,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-01\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 1\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 1\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":14,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-02\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 2\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 2\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":15,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-03\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 3\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 3\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":16,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-04\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 4\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":17,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-05\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 5\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 5\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":18,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-06\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 6\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 6\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":19,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-07\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 7\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 7\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":20,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-08\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 8\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 8\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":21,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-09\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 9\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 9\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":22,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-10\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 10\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 10\",\"min_seats\":4,\"max_seats\":6,\"status\":\"active\"},{\"id\":23,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-11\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 11\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 11\",\"min_seats\":4,\"max_seats\":6,\"status\":\"active\"},{\"id\":24,\"restaurant_id\":2,\"floor_id\":2,\"table_code\":\"T-12\",\"name_ja\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 12\",\"name_vi\":\"\\u30c6\\u30fc\\u30d6\\u30eb-B\\u00e0n 12\",\"min_seats\":4,\"max_seats\":6,\"status\":\"active\"},{\"id\":25,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"B\\u00e0n 1\",\"name_ja\":\"B\\u00e0n 1 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 1 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":26,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"B\\u00e0n 402\",\"name_ja\":\"B\\u00e0n 2 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 2 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":27,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"B\\u00e0n 403\",\"name_ja\":\"B\\u00e0n 3 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 3 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":28,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"B\\u00e0n 404\",\"name_ja\":\"B\\u00e0n 4 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 4 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":29,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"B\\u00e0n 405\",\"name_ja\":\"B\\u00e0n 5 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 5 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":30,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"406\",\"name_ja\":\"B\\u00e0n 6 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 6 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":31,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"407\",\"name_ja\":\"B\\u00e0n 7 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 7 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":32,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"408\",\"name_ja\":\"B\\u00e0n 8 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 8 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":33,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"409\",\"name_ja\":\"B\\u00e0n 9 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 9 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":34,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"410\",\"name_ja\":\"B\\u00e0n 10 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 10 t\\u1ea7ng 4\",\"min_seats\":1,\"max_seats\":4,\"status\":\"active\"},{\"id\":35,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"411\",\"name_ja\":\"B\\u00e0n 11 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 11 t\\u1ea7ng 4\",\"min_seats\":4,\"max_seats\":6,\"status\":\"active\"},{\"id\":36,\"restaurant_id\":2,\"floor_id\":6,\"table_code\":\"412\",\"name_ja\":\"B\\u00e0n 12 t\\u1ea7ng 4\",\"name_vi\":\"B\\u00e0n 12 t\\u1ea7ng 4\",\"min_seats\":4,\"max_seats\":6,\"status\":\"active\"}]};\n            const apiBase = \"https:\\\/\\\/banhangnhat.com\\\/vi\\\/wp-json\\\/hv-booking\\\/v1\";\n            let availabilityCache = null;\n            const monthCache = {};\n            const dayCache = {};\n            const PREFETCH_TTL = 180000;\n            let renderCalendarToken = 0;\n            let loadDaySlotsToken = 0;\n            let calendarRefreshTimer = null;\n            let selectedDay = null;\n            let calendarMonth = null;\n            let calendarYear = null;\n            let calendarDayData = {};\n            let suppressSlotReload = false;\n            let autoMonthJumpDone = false;\n            let bestSuggestion = null;\n            let autoApplyBestPending = true;\n            function primeCache(bucket, key, data) {\n                bucket[key] = { ts: Date.now(), data: data };\n            }\n            function readCache(bucket, key) {\n                const item = bucket[key] || null;\n                if (!item) return null;\n                if ((Date.now() - item.ts) > PREFETCH_TTL) { delete bucket[key]; return null; }\n                return item.data;\n            }\n            function monthKeyFor(y, m, rid, party, tf, tt) {\n                return [y, m, rid || '', party || 0, tf || '', tt || ''].join('|');\n            }\n            function prefetchMonth(y, m) {\n                const rid = $('hv_restaurant_id') ? $('hv_restaurant_id').value : '';\n                const party = $('hv_party_size') ? parseInt($('hv_party_size').value || '0', 10) : 0;\n                if (!rid || !party || m < 1 || m > 12) return;\n                const key = monthKeyFor(y, m, rid, party, preferredTimeFrom(), preferredTimeTo());\n                if (readCache(monthCache, key)) return;\n                const url = apiBase + '\/availability-month?restaurant_id=' + encodeURIComponent(rid) + '&year=' + encodeURIComponent(y) + '&month=' + encodeURIComponent(m) + '&party_size=' + encodeURIComponent(party) + '&time_from=' + encodeURIComponent(preferredTimeFrom()) + '&time_to=' + encodeURIComponent(preferredTimeTo());\n                fetch(url, { headers: { 'Accept': 'application\/json' } }).then(function(res){ return res.ok ? res.json() : null; }).then(function(data){ if (data) primeCache(monthCache, key, data); }).catch(function(){});\n            }\n            function prefetchNearbyMonths() {\n                let prevY = calendarYear, prevM = calendarMonth - 1;\n                let nextY = calendarYear, nextM = calendarMonth + 1;\n                if (prevM < 1) { prevM = 12; prevY -= 1; }\n                if (nextM > 12) { nextM = 1; nextY += 1; }\n                prefetchMonth(prevY, prevM);\n                prefetchMonth(nextY, nextM);\n            }\n            function prefetchAroundSelectedDay() {\n                if (!selectedDay) return;\n                const rid = $('hv_restaurant_id') ? $('hv_restaurant_id').value : '';\n                const party = $('hv_party_size') ? parseInt($('hv_party_size').value || '0', 10) : 0;\n                if (!rid || !party) return;\n                [-1, 1].forEach(function(offset){\n                    const d = new Date(selectedDay + 'T00:00:00');\n                    d.setDate(d.getDate() + offset);\n                    const dateStr = d.getFullYear() + '-' + pad2(d.getMonth()+1) + '-' + pad2(d.getDate());\n                    const key = [dateStr, rid || '', party || 0, preferredTimeFrom() || '', preferredTimeTo() || ''].join('|');\n                    if (readCache(dayCache, key)) return;\n                    const url = apiBase + '\/availability-day?restaurant_id=' + encodeURIComponent(rid) + '&date=' + encodeURIComponent(dateStr) + '&party_size=' + encodeURIComponent(party) + '&preferred_time_from=' + encodeURIComponent(preferredTimeFrom()) + '&preferred_time_to=' + encodeURIComponent(preferredTimeTo());\n                    fetch(url, { headers: { 'Accept': 'application\/json' } }).then(function(res){ return res.ok ? res.json() : null; }).then(function(data){ if (data) primeCache(dayCache, key, data); }).catch(function(){});\n                });\n            }\n\n\n            function $(id) { return document.getElementById(id); }\n            function pad2(n) { return String(n).padStart(2, '0'); }\n            function todayLocalStr() {\n                const now = new Date();\n                return now.getFullYear() + '-' + pad2(now.getMonth() + 1) + '-' + pad2(now.getDate());\n            }\n            function isPastDate(dateStr) {\n                return dateStr < todayLocalStr();\n            }\n            function cacheKeyMonth() {\n                return [($('hv_restaurant_id') ? $('hv_restaurant_id').value : ''), calendarYear, calendarMonth, ($('hv_party_size') ? $('hv_party_size').value : ''), preferredTimeFrom(), preferredTimeTo()].join('|');\n            }\n            function cacheKeyDay() {\n                return [($('hv_restaurant_id') ? $('hv_restaurant_id').value : ''), selectedDay || '', ($('hv_party_size') ? $('hv_party_size').value : ''), preferredTimeFrom(), preferredTimeTo()].join('|');\n            }\n            function invalidateAvailabilityCaches() {\n                Object.keys(monthCache).forEach(function(k){ delete monthCache[k]; });\n                Object.keys(dayCache).forEach(function(k){ delete dayCache[k]; });\n            }\n            function scheduleCalendarRefresh(delay) {\n                if (calendarRefreshTimer) clearTimeout(calendarRefreshTimer);\n                calendarRefreshTimer = setTimeout(function(){ renderCalendar(); }, typeof delay === 'number' ? delay : 120);\n            }\n            function countSelectableDays(dayMap) {\n                return Object.keys(dayMap || {}).filter(function(key) {\n                    const meta = dayMap[key] || {};\n                    return !isPastDate(key) && meta.key !== 'closed' && meta.key !== 'no' && meta.key !== 'past';\n                }).length;\n            }\n            function findBestDay(dayMap) {\n                const keys = Object.keys(dayMap || {}).sort();\n                for (let i = 0; i < keys.length; i++) {\n                    const key = keys[i];\n                    const meta = dayMap[key] || {};\n                    if (!isPastDate(key) && meta.key === 'ok') return key;\n                }\n                for (let i = 0; i < keys.length; i++) {\n                    const key = keys[i];\n                    const meta = dayMap[key] || {};\n                    if (!isPastDate(key) && meta.key === 'req') return key;\n                }\n                return null;\n            }\n            function maybeJumpToNextAvailableMonth(dayMap) {\n                if (selectedDay || autoMonthJumpDone) return false;\n                const selectable = countSelectableDays(dayMap);\n                if (selectable > 0) return false;\n                autoMonthJumpDone = true;\n                calendarMonth++;\n                if (calendarMonth > 12) { calendarMonth = 1; calendarYear++; }\n                renderCalendar(true);\n                return true;\n            }\n            function syncTimeFields() {\n                const h = $('hv_hour') ? $('hv_hour').value : '10';\n                const m = $('hv_minute') ? $('hv_minute').value : '00';\n                const h2 = $('hv_hour_to') ? $('hv_hour_to').value : '12';\n                const m2 = $('hv_minute_to') ? $('hv_minute_to').value : '00';\n                if ($('hv_time')) $('hv_time').value = h + ':' + m;\n                if ($('hv_time_to')) $('hv_time_to').value = h2 + ':' + m2;\n            }\n            function preferredTimeFrom(){ return $('hv_time') ? $('hv_time').value : ''; }\n            function preferredTimeTo(){ return $('hv_time_to') ? $('hv_time_to').value : ''; }\n            function humanDate(dateStr){ if(!dateStr) return '-'; const d=new Date(dateStr + 'T00:00:00'); if (isNaN(d.getTime())) return dateStr; return d.toLocaleDateString('ja-JP',{year:'numeric',month:'2-digit',day:'2-digit', weekday:'short'}); }\n            function updateBestSuggestionUi(){\n                if ($('hv_best_day')) $('hv_best_day').textContent = bestSuggestion && bestSuggestion.date ? humanDate(bestSuggestion.date) : 'Ch\u01b0a c\u00f3';\n                if ($('hv_best_time')) $('hv_best_time').textContent = bestSuggestion && bestSuggestion.time_from ? (bestSuggestion.time_from + ' \u2192 ' + bestSuggestion.time_to) : (preferredTimeFrom() && preferredTimeTo() ? preferredTimeFrom() + ' \u2192 ' + preferredTimeTo() : '-');\n                if ($('hv_best_tables')) $('hv_best_tables').textContent = bestSuggestion && typeof bestSuggestion.free_tables !== 'undefined' ? (bestSuggestion.free_tables + ' b\u00e0n') : '-';\n                if ($('hv_recommend_note')) $('hv_recommend_note').textContent = bestSuggestion && bestSuggestion.note ? bestSuggestion.note : '\u01afu ti\u00ean ng\u00e0y, gi\u1edd d\u1ec5 \u0111\u1eb7t h\u01a1n.';\n            }\n            function applyBestSuggestion(){\n                if (!bestSuggestion || !bestSuggestion.date) return;\n                if (bestSuggestion.time_from && bestSuggestion.time_to) {\n                    const tf = String(bestSuggestion.time_from).slice(0,5).split(':');\n                    const tt = String(bestSuggestion.time_to).slice(0,5).split(':');\n                    if ($('hv_hour')) $('hv_hour').value = tf[0];\n                    if ($('hv_minute')) $('hv_minute').value = tf[1];\n                    if ($('hv_hour_to')) $('hv_hour_to').value = tt[0];\n                    if ($('hv_minute_to')) $('hv_minute_to').value = tt[1];\n                    syncTimeFields();\n                }\n                if (bestSuggestion.date) {\n                    const parts = String(bestSuggestion.date).split('-');\n                    if (parts.length === 3) { calendarYear = parseInt(parts[0],10); calendarMonth = parseInt(parts[1],10); }\n                    selectedDay = null;\n                    renderCalendar().then(function(){ setSelectedDate(bestSuggestion.date); });\n                }\n                updateSummary();\n            }\n            function updateSummary() {\n                const branchSelect = $('hv_restaurant_id');\n                const branchText = branchSelect && branchSelect.options[branchSelect.selectedIndex] ? branchSelect.options[branchSelect.selectedIndex].textContent : '-';\n                if ($('hv_summary_branch')) $('hv_summary_branch').textContent = branchText || '-';\n                if ($('hv_summary_date')) $('hv_summary_date').textContent = selectedDay || '-';\n                if ($('hv_summary_time')) $('hv_summary_time').textContent = ($('hv_time') ? $('hv_time').value : '-') + ' \u2192 ' + ($('hv_time_to') ? $('hv_time_to').value : '-');\n                if ($('hv_summary_party')) $('hv_summary_party').textContent = $('hv_party_size') ? $('hv_party_size').value : '2';\n            }\n            function setSelectedDate(dateStr) {\n                selectedDay = dateStr || null;\n                if ($('hv_date')) $('hv_date').value = selectedDay || '';\n                if ($('hv_selected_date_label')) $('hv_selected_date_label').textContent = selectedDay || 'Ch\u01b0a ch\u1ecdn ng\u00e0y';\n                document.querySelectorAll('.hv-calendar-day').forEach(function(btn) {\n                    btn.classList.toggle('is-selected', btn.dataset.date === selectedDay);\n                });\n                updateSummary();\n                updateAvailability();\n                loadDaySlots();\n            }\n            async function lookupPostalFallback(postal, msgEl) {\n                try {\n                    const res = await fetch('https:\/\/zipcloud.ibsnet.co.jp\/api\/search?zipcode=' + encodeURIComponent(postal));\n                    if (!res.ok) throw new Error('ZipCloud HTTP error');\n                    const data = await res.json();\n                    if (!data || data.status !== 200 || !data.results || !data.results[0]) {\n                        msgEl.style.color = 'red';\n                        msgEl.textContent = 'Kh\u00f4ng t\u00ecm th\u1ea5y \u0111\u1ecba ch\u1ec9 t\u1eeb m\u00e3 b\u01b0u \u0111i\u1ec7n n\u00e0y.';\n                        return;\n                    }\n                    const r = data.results[0];\n                    if ($('hv_prefecture')) $('hv_prefecture').value = r.address1 || '';\n                    if ($('hv_city')) $('hv_city').value = ((r.address2 || '') + ' ' + (r.address3 || '')).trim();\n                    if ($('hv_address_line') && !$('hv_address_line').value) $('hv_address_line').value = ((r.address2 || '') + ' ' + (r.address3 || '')).trim();\n                    msgEl.style.color = 'green';\n                    msgEl.textContent = '\u0110\u00e3 t\u1ef1 \u0111\u1ed9ng \u0111i\u1ec1n \u0111\u1ecba ch\u1ec9 (ZipCloud).';\n                } catch (e) {\n                    console.error(e);\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = 'Kh\u00f4ng th\u1ec3 tra m\u00e3 b\u01b0u \u0111i\u1ec7n. Vui l\u00f2ng nh\u1eadp tay.';\n                }\n            }\n            async function lookupPostal() {\n                const postalEl = $('hv_postal_code');\n                const msgEl = $('hv_postal_status') || $('hv_booking_message');\n                if (!postalEl || !msgEl) return;\n                const postal = (postalEl.value || '').replace(\/[^0-9]\/g, '');\n                if (postal.length < 7) {\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = 'M\u00e3 b\u01b0u \u0111i\u1ec7n kh\u00f4ng h\u1ee3p l\u1ec7.';\n                    return;\n                }\n                msgEl.style.color = '#333';\n                msgEl.textContent = '\u0110ang tra c\u1ee9u \u0111\u1ecba ch\u1ec9...';\n                try {\n                    const res = await fetch(apiBase + '\/address-lookup?postal_code=' + encodeURIComponent(postal), { method:'GET', headers:{'Accept':'application\/json'} });\n                    if (!res.ok) throw new Error('HTTP error');\n                    const data = await res.json();\n                    if (data && data.success) {\n                        if ($('hv_prefecture')) $('hv_prefecture').value = data.prefecture || '';\n                        if ($('hv_city')) $('hv_city').value = data.city || '';\n                        if ($('hv_address_line') && !$('hv_address_line').value) $('hv_address_line').value = data.address_line || '';\n                        msgEl.style.color = 'green';\n                        msgEl.textContent = data.message || '\u0110\u00e3 t\u1ef1 \u0111\u1ed9ng \u0111i\u1ec1n \u0111\u1ecba ch\u1ec9.';\n                        return;\n                    }\n                    await lookupPostalFallback(postal, msgEl);\n                } catch (e) {\n                    console.error(e);\n                    await lookupPostalFallback(postal, msgEl);\n                }\n            }\n            async function renderCalendar(fromAutoJump) {\n                const rid = $('hv_restaurant_id') ? $('hv_restaurant_id').value : '';\n                const party = $('hv_party_size') ? parseInt($('hv_party_size').value || '0', 10) : 0;\n                const grid = $('hv_calendar_grid');\n                const token = ++renderCalendarToken;\n                if (!grid) return;\n                grid.innerHTML = '<div class=\"hv-placeholder\" style=\"grid-column:1 \/ -1;\">\u0110ang t\u1ea3i l\u1ecbch...<\/div>';\n                if (!rid || !party || !calendarYear || !calendarMonth) {\n                    grid.innerHTML = '<div class=\"hv-placeholder\" style=\"grid-column:1 \/ -1;\">Vui l\u00f2ng ch\u1ecdn chi nh\u00e1nh v\u00e0 s\u1ed1 kh\u00e1ch.<\/div>';\n                    return;\n                }\n                try {\n                    const key = cacheKeyMonth();\n                    let data = readCache(monthCache, key);\n                    if (!data) {\n                        const url = apiBase + '\/availability-month?restaurant_id=' + encodeURIComponent(rid) + '&year=' + encodeURIComponent(calendarYear) + '&month=' + encodeURIComponent(calendarMonth) + '&party_size=' + encodeURIComponent(party) + '&time_from=' + encodeURIComponent(preferredTimeFrom()) + '&time_to=' + encodeURIComponent(preferredTimeTo());\n                        const res = await fetch(url, { headers: { 'Accept': 'application\/json' } });\n                        data = res.ok ? await res.json() : { success:false, days:{} };\n                        primeCache(monthCache, key, data);\n                    }\n                    if (token !== renderCalendarToken) return;\n                    calendarDayData = (data && data.days) ? data.days : {};\n                    bestSuggestion = (data && data.best_suggestion) ? data.best_suggestion : null;\n                    updateBestSuggestionUi();\n                    if (data && data.message && $('hv_calendar_subtitle')) $('hv_calendar_subtitle').textContent = data.message;\n                    prefetchNearbyMonths();\n                } catch (e) {\n                    console.error(e);\n                    calendarDayData = {};\n                }\n                const first = new Date(calendarYear, calendarMonth - 1, 1);\n                const daysInMonth = new Date(calendarYear, calendarMonth, 0).getDate();\n                const jsFirst = first.getDay();\n                const mondayFirstOffset = (jsFirst + 6) % 7;\n                if ($('hv_calendar_title')) $('hv_calendar_title').textContent = pad2(calendarMonth) + '\/' + calendarYear;\n                if (!fromAutoJump && maybeJumpToNextAvailableMonth(calendarDayData)) { return; }\n                const bestDay = findBestDay(calendarDayData);\n                grid.innerHTML = '';\n                for (let i = 0; i < mondayFirstOffset; i++) {\n                    const empty = document.createElement('div');\n                    empty.className = 'hv-calendar-day is-empty';\n                    grid.appendChild(empty);\n                }\n                for (let day = 1; day <= daysInMonth; day++) {\n                    const dateStr = calendarYear + '-' + pad2(calendarMonth) + '-' + pad2(day);\n                    const rawMeta = calendarDayData[dateStr] || { key:'closed', symbol:'-' };\n                    const meta = Object.assign({}, rawMeta);\n                    if (isPastDate(dateStr)) { meta.key = 'past'; meta.symbol = 'Qua'; }\n                    else if (meta.key === 'closed') { meta.symbol = meta.symbol || 'Ngh\u1ec9'; }\n                    const btn = document.createElement('button');\n                    btn.type = 'button';\n                    btn.className = 'hv-calendar-day hv-status-' + (meta.key || 'closed');\n                    btn.dataset.date = dateStr;\n                    const slotMeta = (typeof meta.free_tables !== 'undefined') ? ('<span class=\"hv-calendar-day-meta\">' + meta.free_tables + ' b\u00e0n<\/span>') : ((typeof meta.free_slots !== 'undefined' && typeof meta.total_slots !== 'undefined') ? ('<span class=\"hv-calendar-day-meta\">' + meta.free_slots + '\/' + meta.total_slots + ' ca<\/span>') : '');\n                    btn.innerHTML = '<span class=\"hv-calendar-day-num\">' + day + '<\/span><span class=\"hv-calendar-day-status\">' + (meta.symbol || '-') + '<\/span>' + slotMeta;\n                    if (meta.key === 'no' || meta.key === 'closed' || meta.key === 'past') btn.classList.add('is-disabled');\n                    if (meta.key === 'past') btn.classList.add('is-past');\n                    if (bestDay && bestDay === dateStr) btn.classList.add('is-best');\n                    if (selectedDay === dateStr) btn.classList.add('is-selected');\n                    btn.addEventListener('click', function() {\n                        if (btn.classList.contains('is-disabled')) return;\n                        setSelectedDate(dateStr);\n                    });\n                    grid.appendChild(btn);\n                }\n                if (autoApplyBestPending && !selectedDay && bestSuggestion && bestSuggestion.date && bestSuggestion.date.indexOf(calendarYear + '-' + pad2(calendarMonth)) === 0) {\n                    autoApplyBestPending = false;\n                    setTimeout(function(){ applyBestSuggestion(); }, 120);\n                }\n            }\n            async function loadDaySlots() {\n                const box = $('hv_timeslot_list');\n                if (!box) return;\n                const rid = $('hv_restaurant_id') ? $('hv_restaurant_id').value : '';\n                const party = $('hv_party_size') ? parseInt($('hv_party_size').value || '0', 10) : 0;\n                const token = ++loadDaySlotsToken;\n                if (!rid || !party || !selectedDay) {\n                    box.innerHTML = '<div class=\"hv-placeholder\">Ch\u1ecdn ng\u00e0y \u0111\u1ec3 xem gi\u1edd.<\/div>';\n                    return;\n                }\n                if (suppressSlotReload) return;\n                box.innerHTML = '<div class=\"hv-placeholder\">\u0110ang t\u1ea3i gi\u1edd...<\/div>';\n                prefetchAroundSelectedDay();\n                try {\n                    const key = cacheKeyDay();\n                    let data = readCache(dayCache, key);\n                    if (!data) {\n                        const url = apiBase + '\/availability-day?restaurant_id=' + encodeURIComponent(rid) + '&date=' + encodeURIComponent(selectedDay) + '&party_size=' + encodeURIComponent(party) + '&preferred_time_from=' + encodeURIComponent(preferredTimeFrom()) + '&preferred_time_to=' + encodeURIComponent(preferredTimeTo());\n                        const res = await fetch(url, { headers: { 'Accept': 'application\/json' } });\n                        data = res.ok ? await res.json() : { success:false, times:[] };\n                        primeCache(dayCache, key, data);\n                    }\n                    if (token !== loadDaySlotsToken) return;\n                    const times = (data && data.times) ? data.times : [];\n                    if (data && data.best_suggestion) { bestSuggestion = data.best_suggestion; updateBestSuggestionUi(); }\n                    if (!times.length) {\n                        box.innerHTML = '<div class=\"hv-placeholder\">Ng\u00e0y n\u00e0y hi\u1ec7n ch\u01b0a c\u00f3 ca ph\u1ee5c v\u1ee5 ho\u1eb7c ch\u01b0a c\u1ea5u h\u00ecnh shift.<\/div>';\n                        return;\n                    }\n                    box.innerHTML = '';\n                    let firstAvailableBtn = null;\n                    let matchedBtn = null;\n                    times.forEach(function(slot, index) {\n                        const btn = document.createElement('button');\n                        btn.type = 'button';\n                        btn.className = 'hv-timeslot-btn' + (slot.is_available ? '' : ' is-disabled');\n                        btn.textContent = String(slot.time_from || '').slice(0, 5) + ' \u2192 ' + String(slot.time_to || '').slice(0, 5) + (typeof slot.free_tables !== 'undefined' ? (' \u00b7 ' + slot.free_tables + ' b\u00e0n') : '');\n                        if (slot.is_recommended) btn.classList.add('is-recommended');\n                        if (($('hv_time') && $('hv_time').value === String(slot.time_from || '').slice(0, 5)) && ($('hv_time_to') && $('hv_time_to').value === String(slot.time_to || '').slice(0, 5))) {\n                            btn.classList.add('is-active');\n                            matchedBtn = btn;\n                        }\n                        if (!slot.is_available) {\n                            btn.disabled = true;\n                        } else if (!firstAvailableBtn) {\n                            firstAvailableBtn = btn;\n                        }\n                        btn.addEventListener('click', function() {\n                            suppressSlotReload = true;\n                            const tf = String(slot.time_from || '').slice(0, 5).split(':');\n                            const tt = String(slot.time_to || '').slice(0, 5).split(':');\n                            if ($('hv_hour')) $('hv_hour').value = tf[0];\n                            if ($('hv_minute')) $('hv_minute').value = tf[1];\n                            if ($('hv_hour_to')) $('hv_hour_to').value = tt[0];\n                            if ($('hv_minute_to')) $('hv_minute_to').value = tt[1];\n                            syncTimeFields();\n                            updateSummary();\n                            document.querySelectorAll('.hv-timeslot-btn').forEach(function(x){ x.classList.remove('is-active'); });\n                            btn.classList.add('is-active');\n                            suppressSlotReload = false;\n                            updateAvailability();\n                        });\n                        box.appendChild(btn);\n                    });\n                    if (!matchedBtn && firstAvailableBtn) {\n                        firstAvailableBtn.click();\n                    }\n                } catch (e) {\n                    console.error(e);\n                    box.innerHTML = '<div class=\"hv-placeholder\">Kh\u00f4ng t\u1ea3i \u0111\u01b0\u1ee3c khung gi\u1edd.<\/div>';\n                }\n            }\n            async function updateAvailability() {\n                const form = $('hv-booking-form');\n                if (!form) return;\n                const restaurantId = form.restaurant_id.value;\n                const date = form.date.value;\n                const timeFrom = form.time_from.value;\n                const timeTo = form.time_to.value;\n                const partySize = parseInt(form.party_size.value || '0', 10);\n                if (!restaurantId || !date || !timeFrom || !timeTo || !partySize) {\n                    populateFloors({ floors: [], tables: [] });\n                    return;\n                }\n                let payload = { success:false, floors:[], tables:[], busy_table_ids:[] };\n                try {\n                    const url = apiBase + '\/availability?restaurant_id=' + encodeURIComponent(restaurantId) + '&date=' + encodeURIComponent(date) + '&time_from=' + encodeURIComponent(timeFrom) + '&time_to=' + encodeURIComponent(timeTo) + '&party_size=' + encodeURIComponent(partySize);\n                    const res = await fetch(url, { headers: { 'Accept': 'application\/json' } });\n                    if (res.ok) {\n                        const data = await res.json();\n                        if (data && typeof data === 'object') payload = data;\n                    }\n                } catch (e) {\n                    console.error(e);\n                }\n                try {\n                    const needFallback = !payload.success || !(payload.floors && payload.floors.length) || !(payload.tables && payload.tables.length);\n                    if (needFallback) {\n                        const rid = parseInt(restaurantId, 10);\n                        const allFloors = (hvStaticStructure && hvStaticStructure.floors) ? hvStaticStructure.floors : [];\n                        const allTables = (hvStaticStructure && hvStaticStructure.tables) ? hvStaticStructure.tables : [];\n                        const activeFloors = allFloors.filter(function(f) { return parseInt(f.restaurant_id, 10) === rid && (!f.is_active || parseInt(f.is_active, 10) === 1); });\n                        const busyIds = (payload.busy_table_ids || []).map(function(id) { return parseInt(id, 10); });\n                        const tablesForBranch = allTables.filter(function(t) { return parseInt(t.restaurant_id, 10) === rid && t.status !== 'deleted' && t.status !== 'inactive'; }).map(function(t) {\n                            const isBusy = busyIds.indexOf(parseInt(t.id, 10)) !== -1;\n                            return {\n                                id: t.id, floor_id: t.floor_id, restaurant_id: t.restaurant_id, table_code: t.table_code,\n                                min_seats: t.min_seats, max_seats: t.max_seats,\n                                is_available: !isBusy && (!t.min_seats || parseInt(t.min_seats, 10) <= partySize) && (!t.max_seats || parseInt(t.max_seats, 10) >= partySize),\n                                label: (t.table_code || '') + ' (' + (t.min_seats || 0) + '-' + (t.max_seats || 0) + ')'\n                            };\n                        }).filter(function(t){ return (!t.min_seats || parseInt(t.min_seats, 10) <= partySize) && (!t.max_seats || parseInt(t.max_seats, 10) >= partySize); });\n                        const floorsForBranch = activeFloors.map(function(f) {\n                            const label = (f.name_vi && String(f.name_vi).trim()) ? f.name_vi : ((f.name_ja && String(f.name_ja).trim()) ? f.name_ja : (f.floor_code || ('Floor ' + f.id)));\n                            const clone = {}; for (const k in f) if (Object.prototype.hasOwnProperty.call(f, k)) clone[k] = f[k]; clone.label = label; return clone;\n                        });\n                        payload.floors = floorsForBranch;\n                        payload.tables = tablesForBranch;\n                        payload.success = true;\n                    }\n                } catch (fe) {\n                    console.error('Static floors\/tables build error', fe);\n                }\n                availabilityCache = payload;\n                populateFloors(payload);\n                if ($('hv_table_quick_status')) {\n                    const freeCnt = (payload.tables || []).filter(function(t){ return !!t.is_available; }).length;\n                    $('hv_table_quick_status').textContent = freeCnt > 0 ? ('Hi\u1ec7n c\u00f3 ' + freeCnt + ' b\u00e0n ph\u00f9 h\u1ee3p cho khung gi\u1edd \u0111\u00e3 ch\u1ecdn.') : 'Khung gi\u1edd n\u00e0y hi\u1ec7n ch\u01b0a c\u00f2n b\u00e0n ph\u00f9 h\u1ee3p.';\n                }\n            }\n            function populateFloors(data) {\n                const floorSelect = $('hv_floor');\n                const tableSelect = $('hv_table');\n                if (!floorSelect || !tableSelect) return;\n                floorSelect.innerHTML = '<option value=\"\">Ch\u1ecdn t\u1ea7ng \/ \u968e\u9078\u629e<\/option>';\n                tableSelect.innerHTML = '<option value=\"\">Ch\u1ecdn b\u00e0n \/ \u5e2d\u9078\u629e<\/option>';\n                (data.floors || []).forEach(function(f) {\n                    const opt = document.createElement('option'); opt.value = f.id; opt.textContent = f.label; floorSelect.appendChild(opt);\n                });\n                const firstFloorWithTable = (data.tables || []).find(function(t){ return !!t.is_available; });\n                if (firstFloorWithTable) floorSelect.value = String(firstFloorWithTable.floor_id);\n                updateTablesForFloor();\n            }\n            function updateTablesForFloor() {\n                const floorSelect = $('hv_floor');\n                const tableSelect = $('hv_table');\n                if (!floorSelect || !tableSelect || !availabilityCache) return;\n                const floorId = parseInt(floorSelect.value || '0', 10);\n                tableSelect.innerHTML = '<option value=\"\">Ch\u1ecdn b\u00e0n \/ \u5e2d\u9078\u629e<\/option>';\n                let firstAvailableValue = '';\n                (availabilityCache.tables || []).forEach(function(t) {\n                    if (floorId && parseInt(t.floor_id, 10) !== floorId) return;\n                    const opt = document.createElement('option');\n                    opt.value = t.id;\n                    opt.textContent = t.label + (t.is_available ? '' : ' (\u0110\u00e3 \u0111\u1eb7t \/ \u6e80\u5e2d)');\n                    if (!t.is_available) opt.disabled = true;\n                    if (!firstAvailableValue && t.is_available) firstAvailableValue = String(t.id);\n                    tableSelect.appendChild(opt);\n                });\n                if (firstAvailableValue) tableSelect.value = firstAvailableValue;\n            }\n            async function submitBooking(event) {\n                event.preventDefault();\n                const form = $('hv-booking-form');\n                const msgEl = $('hv_booking_message');\n                const widget = $('hv-booking-widget');\n                const formWrap = $('hv_booking_form_wrap');\n                const successWrap = $('hv_booking_success_wrap');\n                if (!form || !msgEl) return;\n                const payload = {\n                    time_to: form.time_to ? form.time_to.value : '',\n                    restaurant_id: form.restaurant_id.value,\n                    date: form.date.value,\n                    time_from: form.time_from.value,\n                    party_size: parseInt(form.party_size.value || '0', 10),\n                    floor_id: form.floor_id.value,\n                    table_id: form.table_id.value,\n                    customer_name: form.customer_name.value,\n                    customer_phone: form.customer_phone.value,\n                    customer_email: form.customer_email.value,\n                    postal_code: form.postal_code.value,\n                    prefecture: form.prefecture.value,\n                    city: form.city.value,\n                    address_line: form.address_line.value,\n                    note: form.note.value\n                };\n                if (!payload.restaurant_id || !payload.date || !payload.time_from || !payload.time_to || !payload.party_size) {\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = 'Vui l\u00f2ng ch\u1ecdn chi nh\u00e1nh, ng\u00e0y, gi\u1edd \u0111\u1ebfn, gi\u1edd v\u1ec1 v\u00e0 s\u1ed1 kh\u00e1ch.';\n                    return;\n                }\n                if (!payload.floor_id || !payload.table_id) {\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = 'Vui l\u00f2ng ch\u1ecdn t\u1ea7ng v\u00e0 b\u00e0n.';\n                    return;\n                }\n                if (!payload.customer_name) {\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = 'Vui l\u00f2ng nh\u1eadp h\u1ecd t\u00ean kh\u00e1ch h\u00e0ng.';\n                    return;\n                }\n                const submitBtn = $('hv_submit');\n                if (submitBtn) submitBtn.disabled = true;\n                msgEl.style.color = '#333';\n                msgEl.textContent = '\u0110ang g\u1eedi \u0111\u1eb7t b\u00e0n...';\n                try {\n                    const res = await fetch(apiBase + '\/reservations', {\n                        method: 'POST',\n                        headers: { 'Content-Type': 'application\/json', 'Accept': 'application\/json' },\n                        body: JSON.stringify(payload)\n                    });\n                    const data = await res.json();\n                    if (!res.ok || !data || !data.success) {\n                        throw new Error((data && data.message) ? data.message : 'Reservation failed');\n                    }\n                    const branchSelect = form.restaurant_id;\n                    const floorSelect = form.floor_id;\n                    const tableSelect = form.table_id;\n                    const branchText = branchSelect && branchSelect.options[branchSelect.selectedIndex] ? branchSelect.options[branchSelect.selectedIndex].textContent : '';\n                    const floorText = floorSelect && floorSelect.options[floorSelect.selectedIndex] ? floorSelect.options[floorSelect.selectedIndex].textContent : '';\n                    const tableText = tableSelect && tableSelect.options[tableSelect.selectedIndex] ? tableSelect.options[tableSelect.selectedIndex].textContent : '';\n                    const dt = payload.date + ' ' + payload.time_from + ' \u2192 ' + payload.time_to;\n                    if ($('hv_success_restaurant')) $('hv_success_restaurant').textContent = branchText;\n                    if ($('hv_success_datetime')) $('hv_success_datetime').textContent = dt;\n                    if ($('hv_success_party')) $('hv_success_party').textContent = String(payload.party_size);\n                    if ($('hv_success_table')) $('hv_success_table').textContent = floorText + ' \/ ' + tableText;\n                    const successMsg = $('hv_booking_success_message');\n                    if (successMsg) { successMsg.style.color = 'green'; successMsg.textContent = data.message || '\u0110\u1eb7t b\u00e0n th\u00e0nh c\u00f4ng \/ \u4e88\u7d04\u5b8c\u4e86'; }\n                    form.reset();\n                    selectedDay = null;\n                    availabilityCache = null;\n                    autoMonthJumpDone = false;\n                    syncTimeFields();\n                    updateSummary();\n                    renderCalendar();\n                    if (formWrap && successWrap) {\n                        formWrap.style.display = 'none';\n                        successWrap.style.display = 'block';\n                        successWrap.scrollIntoView({ behavior: 'smooth' });\n                    }\n                    if (widget) {\n                        const redirectUrl = widget.dataset.redirectUrl || '';\n                        const redirectDelay = parseInt(widget.dataset.redirectDelay || '0', 10);\n                        if (redirectUrl && redirectDelay > 0) setTimeout(function(){ window.location.href = redirectUrl; }, redirectDelay * 1000);\n                    }\n                } catch (e) {\n                    console.error(e);\n                    msgEl.style.color = 'red';\n                    msgEl.textContent = e && e.message ? e.message : 'C\u00f3 l\u1ed7i khi g\u1eedi \u0111\u1eb7t b\u00e0n. Vui l\u00f2ng th\u1eed l\u1ea1i.';\n                } finally {\n                    if (submitBtn) submitBtn.disabled = false;\n                }\n            }\n            document.addEventListener('DOMContentLoaded', function() {\n                const today = new Date();\n                calendarMonth = today.getMonth() + 1;\n                calendarYear = today.getFullYear();\n                syncTimeFields();\n                updateSummary();\n                updateBestSuggestionUi();\n                autoMonthJumpDone = false;\n                renderCalendar();\n                const form = $('hv-booking-form');\n                if (form) form.addEventListener('submit', submitBooking);\n                ['hv_restaurant_id','hv_party_size'].forEach(function(id){ if ($(id)) $(id).addEventListener('change', function(){ selectedDay = null; bestSuggestion = null; if ($('hv_date')) $('hv_date').value = ''; autoMonthJumpDone = false; autoApplyBestPending = true; updateSummary(); updateBestSuggestionUi(); invalidateAvailabilityCaches(); scheduleCalendarRefresh(80); if ($('hv_timeslot_list')) $('hv_timeslot_list').innerHTML = '<div class=\"hv-placeholder\">Ch\u1ecdn ng\u00e0y \u0111\u1ec3 xem gi\u1edd.<\/div>'; populateFloors({ floors: [], tables: [] }); }); });\n                ['hv_hour','hv_minute','hv_hour_to','hv_minute_to'].forEach(function(id){ if ($(id)) $(id).addEventListener('change', function(){ syncTimeFields(); updateSummary(); autoMonthJumpDone = false; autoApplyBestPending = true; invalidateAvailabilityCaches(); scheduleCalendarRefresh(80); if (selectedDay) { loadDaySlots(); updateAvailability(); } }); });\n                if ($('hv_floor')) $('hv_floor').addEventListener('change', updateTablesForFloor);\n                if ($('hv_postal_lookup')) $('hv_postal_lookup').addEventListener('click', lookupPostal);\n                if ($('hv_prev_month')) $('hv_prev_month').addEventListener('click', function(){ calendarMonth--; if (calendarMonth < 1) { calendarMonth = 12; calendarYear--; } autoApplyBestPending = false; scheduleCalendarRefresh(0); });\n                if ($('hv_next_month')) $('hv_next_month').addEventListener('click', function(){ calendarMonth++; if (calendarMonth > 12) { calendarMonth = 1; calendarYear++; } autoApplyBestPending = false; scheduleCalendarRefresh(0); });\n                if ($('hv_apply_best')) $('hv_apply_best').addEventListener('click', function(){ applyBestSuggestion(); });\n            });\n        })();\n        <\/script>\n        \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1342","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/pages\/1342","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/comments?post=1342"}],"version-history":[{"count":1,"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/pages\/1342\/revisions"}],"predecessor-version":[{"id":1343,"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/pages\/1342\/revisions\/1343"}],"wp:attachment":[{"href":"https:\/\/banhangnhat.com\/vi\/wp-json\/wp\/v2\/media?parent=1342"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}