{"id":9550,"date":"2025-11-30T04:18:05","date_gmt":"2025-11-30T04:18:05","guid":{"rendered":"https:\/\/pawdy.co.th\/?page_id=9550"},"modified":"2026-02-03T05:02:50","modified_gmt":"2026-02-03T05:02:50","slug":"pawdy-ai","status":"publish","type":"page","link":"https:\/\/pawdy.co.th\/en\/pawdy-ai\/","title":{"rendered":"Pawdy AI"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"9550\" class=\"elementor elementor-9550\" wpc-filter-elementor-widget=\"1\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e2351de e-con-full e-flex e-con e-parent\" data-id=\"e2351de\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6e8b20e elementor-widget elementor-widget-html\" data-id=\"6e8b20e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<section id=\"pawsense\" class=\"ps\">\r\n    <header class=\"ps__head\">\r\n        <div class=\"ps__brand\">\r\n            <div>\r\n                <h2 class=\"ps__title\">Pawdy AI<\/h2>\r\n            <\/div>\r\n        <\/div>\r\n        <div class=\"ps__actions\"><\/div>\r\n    <\/header>\r\n\r\n    <main id=\"ps-log\" class=\"ps__log\" aria-live=\"polite\">\r\n        <article class=\"msg msg--bot\">\r\n            <div class=\"msg__avatar\" aria-hidden=\"true\">\ud83d\udc3e<\/div>\r\n            <div class=\"msg__bubble markdown\">\r\n                <p>\r\n                \u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\u0e04\u0e48\u0e30 \u0e09\u0e31\u0e19\u0e04\u0e37\u0e2d\u0e19\u0e49\u0e2d\u0e07\u0e1e\u0e2d\u0e14\u0e35 \ud83d\udc3e<br>\r\n                \u0e1c\u0e39\u0e49\u0e0a\u0e48\u0e27\u0e22\u0e2d\u0e31\u0e08\u0e09\u0e23\u0e34\u0e22\u0e30\u0e08\u0e32\u0e01 Nhamaew Pet AI \u0e17\u0e35\u0e48\u0e08\u0e30\u0e04\u0e2d\u0e22\u0e23\u0e31\u0e1a\u0e1f\u0e31\u0e07\u0e1b\u0e31\u0e0d\u0e2b\u0e32\u0e19\u0e49\u0e2d\u0e07\u0e2b\u0e21\u0e32\u2013\u0e19\u0e49\u0e2d\u0e07\u0e41\u0e21\u0e27<br>\r\n                \u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e43\u0e2b\u0e49\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e17\u0e35\u0e48\u0e40\u0e02\u0e49\u0e32\u0e43\u0e08\u0e07\u0e48\u0e32\u0e22\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a \u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e2d\u0e32\u0e2b\u0e32\u0e23 \u0e2a\u0e38\u0e02\u0e20\u0e32\u0e1e \u0e41\u0e25\u0e30\u0e44\u0e25\u0e1f\u0e4c\u0e2a\u0e44\u0e15\u0e25\u0e4c<br><br>\r\n\r\n                \u0e08\u0e34\u0e49\u0e21 \u0e40\u0e25\u0e37\u0e2d\u0e01\u0e42\u0e2b\u0e21\u0e14\u0e14\u0e49\u0e32\u0e19\u0e25\u0e48\u0e32\u0e07 \u0e41\u0e25\u0e49\u0e27\u0e25\u0e2d\u0e07\u0e04\u0e38\u0e22\u0e01\u0e31\u0e1a\u0e19\u0e49\u0e2d\u0e07\u0e1e\u0e2d\u0e14\u0e35\u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e19\u0e49\u0e32\u0e32\u0e32 \ud83d\udc9a\r\n<\/p>\r\n            <\/div>\r\n        <\/article>\r\n    <\/main>\r\n\r\n    <footer class=\"ps__foot\">\r\n        <div class=\"ps__tools\">\r\n            <button id=\"ps-mode-dog\" class=\"btn btn--mode\" data-mode=\"DOG\">\r\n                \ud83d\udc15 \u0e42\u0e2b\u0e21\u0e14\u0e19\u0e49\u0e2d\u0e07\u0e2b\u0e21\u0e32\r\n            <\/button>\r\n            <button id=\"ps-mode-cat\" class=\"btn btn--mode\" data-mode=\"CAT\">\r\n                \ud83d\udc08 \u0e42\u0e2b\u0e21\u0e14\u0e19\u0e49\u0e2d\u0e07\u0e41\u0e21\u0e27\r\n            <\/button>\r\n            <span class=\"spacer\"><\/span>\r\n            <button id=\"ps-help\" class=\"btn btn--ghost\">\u0e27\u0e34\u0e18\u0e35\u0e43\u0e0a\u0e49\u0e41\u0e25\u0e30\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33<\/button>\r\n            <button id=\"ps-reset\" class=\"btn btn--ghost\">\u21ba \u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48<\/button>\r\n        <\/div>\r\n        <form id=\"ps-form\" class=\"composer\" autocomplete=\"off\">\r\n            <textarea id=\"ps-input\" rows=\"1\" placeholder=\"\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e04\u0e33\u0e16\u0e32\u0e21\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13...\"><\/textarea>\r\n            <button class=\"btn btn--send\" aria-label=\"\u0e2a\u0e48\u0e07\">\r\n                <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" aria-hidden=\"true\" focusable=\"false\">\r\n                    <path d=\"M2 21l21-9L2 3v7l15 2-15 2v7z\" fill=\"currentColor\"\/>\r\n                <\/svg>\r\n            <\/button>\r\n        <\/form>\r\n    <\/footer>\r\n<\/section>\r\n<style>\r\n\r\n:root {\r\n    --bg: #ffffff;\r\n    --fg: #374151;\r\n    --muted: #6b7280;\r\n    --line: rgba(15, 23, 42, .10);\r\n    --bot: #f9f9f9;\r\n    --user: #e9f0ff;\r\n    --radius: 18px;\r\n    --shadow: 0 16px 40px rgba(2, 6, 23, .08);\r\n    --brand1: #9ACA3C;\r\n    --brand2: #9ACA3C;\r\n}\r\n\/* ====== Base Reset ====== *\/\r\n\r\n* { box-sizing: border-box; }\r\n\r\n@media (max-width: 480px) {\r\n    #ps-help,\r\n    #ps-reset {\r\n        font-size: 13px;\r\n        font-weight: 600;\r\n    }\r\n}\r\n\r\n@media (max-width: 380px) {\r\n    #ps-help,\r\n    #ps-reset {\r\n        font-size: 12px;\r\n        font-weight: 600;\r\n    }\r\n}\r\n.ps {\r\n    max-width: 1200px;\r\n    margin: 10px auto;\r\n    border: 1px solid var(--line);\r\n    border-radius: 22px;\r\n    overflow: hidden;\r\n    background:\r\n        radial-gradient(180px 180px at 95% -20%, color-mix(in srgb, var(--brand1) 14%, transparent), transparent 60%),\r\n        radial-gradient(220px 220px at -10% 115%, color-mix(in srgb, var(--brand2) 12%, transparent), transparent 60%),\r\n        var(--bg);\r\n    color: var(--fg);\r\n    font-family: Kanit, system-ui, sans-serif;\r\n    box-shadow: var(--shadow);\r\n}\r\n\r\n\/* ====== Header ====== *\/\r\n\r\n.ps__head {\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    padding: 10px 10px;\r\n    background: linear-gradient(180deg, #9ACA3C, #9ACA3C);\r\n    border-bottom: none;\r\n    position: relative;\r\n}\r\n\r\n.ps__actions {\r\n    position: absolute;\r\n    right: 16px;\r\n}\r\n\r\n.ps__brand {\r\n    text-align: center;\r\n    margin-top: 8px;\r\n}\r\n\r\n@media (max-width: 480px) {\r\n    .ps__head {\r\n        justify-content: center;\r\n    }\r\n\r\n    .ps__brand {\r\n        width: 100%;\r\n        display: flex;\r\n        justify-content: center;\r\n    }\r\n\r\n    .ps__title {\r\n        text-align: center;\r\n        width: 100%;\r\n        margin: 0 auto;\r\n    }\r\n}\r\n.ps__title {\r\n\r\n    margin: 0;\r\n    text-align: center;\r\n    padding-top: 10px;\r\n    font-weight: 700;\r\n    font-size: 48px;\r\n    color: #ffffff;\r\n    text-shadow:\r\n        0 4px 12px rgba(65, 120, 20, 0.45),      \/* \u0e40\u0e02\u0e35\u0e22\u0e27\u0e40\u0e02\u0e49\u0e21 *\/\r\n\r\n        0 2px 4px rgba(75, 140, 30, 0.35);      \/* \u0e40\u0e02\u0e35\u0e22\u0e27\u0e01\u0e25\u0e32\u0e07 *\/\r\n\r\n}\r\n\r\n.ps__sub {\r\n    margin: 3px 0 0;\r\n    color: #ffffff !important;\r\n    font-size: 13px;\r\n    opacity: .95;\r\n}\r\n\r\n\/* ====== Buttons ====== *\/\r\n\r\n.btn {\r\n    border: 1px solid var(--line);\r\n    background: transparent;\r\n    color: var(--muted);\r\n    border-radius: 12px;\r\n    padding: 6px 10px;\r\n    cursor: pointer;\r\n    transition: .2s ease;\r\n    font-family: inherit;\r\n}\r\n\r\n.btn--ghost:hover {\r\n    color: #fff;\r\n\r\n}\r\n\r\n.btn--mode {\r\n    font-weight: 600;\r\n    padding: 8px 14px;\r\n    border-radius: 12px;\r\n    background: linear-gradient(180deg, #fff, #fafafa);\r\n    color: var(--fg);\r\n    opacity: 0.6;\r\n    transition: all .25s ease;\r\n}\r\n\r\n.btn--mode:hover {\r\n    opacity: 0.85;\r\n    transform: translateY(-1px);\r\n    box-shadow: 0 4px 10px rgba(2,6,23,.08);\r\n}\r\n\r\n.btn--mode-active {\r\n    opacity: 1;\r\n    background: #9ACA3C;\r\n    color: #fff;\r\n    border-color: transparent;\r\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.btn--mode-active:hover {\r\n    color: #fff;\r\n    transform: translateY(-1px);\r\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n\/* ====== Chat Log ====== *\/\r\n.ps__log {\r\n    height: min(66vh, 680px);\r\n    padding: 10px 16px;\r\n    overflow: auto;\r\n    -webkit-overflow-scrolling: touch;\r\n    scroll-behavior: smooth;\r\n}\r\n\r\n\/* ====== Message ====== *\/\r\n\r\n.msg {\r\n    display: flex;\r\n    gap: 10px;\r\n    margin: 8px 0;\r\n}\r\n\r\n.msg__avatar {\r\n    min-width: 28px;\r\n    text-align: center;\r\n}\r\n\r\n.msg__bubble {\r\n    max-width: 78% !important;\r\n    background: var(--bot) !important;\r\n    border: 1px solid rgba(15,23,42,.05) !important;\r\n    padding: 12px 16px !important;\r\n    border-radius: 20px !important;\r\n    line-height: 1.6 !important;\r\n    box-shadow: none !important;\r\n    word-break: break-word;\r\n}\r\n\r\n.msg--user {\r\n    justify-content: flex-end;\r\n}\r\n\r\n.msg--user .msg__avatar {\r\n    display: none;\r\n}\r\n\r\n.msg--user .msg__bubble {\r\n    background: var(--user) !important;\r\n    border-color: rgba(99,102,241,.15) !important;\r\n}\r\n\r\n.msg__bubble--choice {\r\n    background: var(--bg) !important;\r\n    border: 1px solid var(--line) !important;\r\n    box-shadow: 0 4px 12px rgba(2,6,23,.08) !important;\r\n}\r\n\r\n\/* ====== Markdown & Chips ====== *\/\r\n\r\n.markdown p { margin: 0 0 4px 0; }\r\n.markdown p:last-child { margin-bottom: 0; }\r\n.markdown strong { font-weight: 800; color: var(--fg); }\r\n.chips {\r\n\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    gap: 6px;\r\n    margin: 8px 0 0;\r\n    padding: 0;\r\n    list-style: none;\r\n}\r\n\r\n.chips li {\r\n    font-size: 12px;\r\n    border: 1px dashed var(--line);\r\n    padding: 5px 9px;\r\n    border-radius: 999px;\r\n    color: var(--muted);\r\n    cursor: pointer;\r\n}\r\n\r\n.chips li:hover {\r\n    border-style: solid;\r\n}\r\n\r\n\/* ====== Footer ====== *\/\r\n\r\n.ps__tools {\r\n    display: flex;\r\n    align-items: center;\r\n    gap: 10px;\r\n    margin: 0 2px;\r\n}\r\n\r\n.spacer { flex: 1; }\r\n\r\n.ps__foot {\r\n    display: grid;\r\n    grid-template-rows: auto auto;\r\n    row-gap: 10px;\r\n    border-top: 1px solid var(--line);\r\n    padding: 10px 12px;\r\n    background: linear-gradient(180deg, transparent, rgba(2,6,23,.03));\r\n\r\n}\r\n\r\n\/* ====== Composer ====== *\/\r\n\r\n.composer {\r\n    display: flex;\r\n    gap: 8px;\r\n    align-items: flex-end;\r\n    border: 1px solid var(--line);\r\n    border-radius: 14px;\r\n    padding: 8px 10px;\r\n    background: linear-gradient(180deg, rgba(2,6,23,.02), rgba(2,6,23,.01));\r\n    margin: 0;\r\n\r\n}\r\n\r\n#ps-input {\r\n    flex: 1;\r\n    resize: none;\r\n    max-height: 180px;\r\n    background: transparent;\r\n    color: var(--fg);\r\n    border: 0;\r\n    outline: none;\r\n    font: inherit;\r\n    line-height: 1.6;\r\n\r\n}\r\n\r\n.btn--send {\r\n    min-width: 46px;\r\n    height: 42px;\r\n    display: grid;\r\n    place-items: center;\r\n    border-radius: 14px;\r\n    background: #fff;\r\n    color: #111827;\r\n    border: 1px solid #e5e7eb;\r\n    box-shadow: 0 6px 16px rgba(2,6,23,.08), inset 0 0 0 1px rgba(255,255,255,.6);\r\n    transition: transform .12s ease, box-shadow .12s ease, filter .12s ease;\r\n}\r\n\r\n.btn--send:hover {\r\n    filter: brightness(.99);\r\n    box-shadow: 0 8px 18px rgba(2,6,23,.10);\r\n}\r\n\r\n.btn--send:active {\r\n    transform: translateY(1px) scale(.99);\r\n}\r\n\r\n\/* ====== Typing Animation ====== *\/\r\n\r\n.typing { display: inline-flex; gap: 5px; align-items: center; }\r\n.typing i {\r\n    width: 6px; height: 6px;\r\n    border-radius: 999px;\r\n    background: var(--muted);\r\n    opacity: .5;\r\n    animation: blink 1.12s infinite;\r\n}\r\n\r\n.typing i:nth-child(2) { animation-delay: .15s; }\r\n.typing i:nth-child(3) { animation-delay: .3s; }\r\n\r\n@keyframes blink { 0%,80%,100% {opacity:.25;} 40%{opacity:1;} }\r\n\r\n\/* ====== Responsive Adjustments ====== *\/\r\n\r\n@media (max-width: 768px) {\r\n    .ps__log {\r\n        height: 60vh;\r\n    }\r\n}\r\n\r\n.chat-link {\r\n    color: #9ACA3C;             \/* \u0e2a\u0e35\u0e19\u0e49\u0e33\u0e40\u0e07\u0e34\u0e19 *\/\r\n    text-decoration: underline; \/* \u0e02\u0e35\u0e14\u0e40\u0e2a\u0e49\u0e19\u0e43\u0e15\u0e49 *\/\r\n    word-break: break-all;      \/* \u0e15\u0e31\u0e14 URL \u0e22\u0e32\u0e27\u0e46 \u0e44\u0e21\u0e48\u0e43\u0e2b\u0e49\u0e40\u0e01\u0e34\u0e19 bubble *\/\r\n    transition: color .2s ease;\r\n}\r\n\r\n.chat-link:hover {\r\n    color: #FBB045;             \/* \u0e2a\u0e35\u0e40\u0e02\u0e49\u0e21\u0e02\u0e36\u0e49\u0e19\u0e15\u0e2d\u0e19 hover *\/\r\n    text-decoration: none;      \/* \u0e0b\u0e48\u0e2d\u0e19\u0e40\u0e2a\u0e49\u0e19\u0e43\u0e15\u0e49\u0e15\u0e2d\u0e19 hover *\/\r\n\r\n}\r\n\r\n@media (max-width: 480px) {\r\n    .ps {\r\n        margin: 0 6px;\r\n        border-radius: 18px;\r\n        box-shadow: none;\r\n    }\r\n    .ps__head {\r\n        flex-direction: column;\r\n        align-items: flex-start;\r\n        padding: 8px 12px;\r\n    }\r\n    .ps__title {\r\n        font-size: 16px;\r\n\r\n    }\r\n\r\n    .ps__sub {\r\n        font-size: 11px;\r\n    }\r\n\r\n    .ps__log {\r\n        height: 58vh;\r\n        padding: 8px 10px;\r\n        font-size: 14px;\r\n        line-height: 1.5;\r\n\r\n    }\r\n\r\n    .msg__bubble {\r\n        max-width: 90% !important;\r\n        font-size: 14px !important;\r\n        padding: 10px 12px !important;\r\n        border-radius: 16px !important;\r\n    }\r\n\r\n    .chips {\r\n        gap: 4px;\r\n    }\r\n\r\n    .chips li {\r\n        font-size: 11px;\r\n        padding: 4px 8px;\r\n    }\r\n\r\n    .ps__tools {\r\n        flex-wrap: wrap;\r\n        gap: 6px;\r\n        justify-content: center;\r\n    }\r\n\r\n    .btn--mode {\r\n        flex: 1 1 45%;\r\n        font-size: 13px;\r\n        padding: 8px 0;\r\n        border-radius: 10px;\r\n        text-align: center;\r\n\r\n    }\r\n\r\n    #ps-reset, #ps-help { \/* \u0e41\u0e01\u0e49\u0e44\u0e02\u0e43\u0e2b\u0e49\u0e04\u0e23\u0e2d\u0e1a\u0e04\u0e25\u0e38\u0e21\u0e1b\u0e38\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e14\u0e49\u0e27\u0e22 *\/\r\n        grid-column: span 1; \/* \u0e43\u0e2b\u0e49\u0e41\u0e15\u0e48\u0e25\u0e30\u0e1b\u0e38\u0e48\u0e21\u0e01\u0e34\u0e19\u0e1e\u0e37\u0e49\u0e19\u0e17\u0e35\u0e48 1 \u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c *\/\r\n        flex: auto; \/* \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01 flex: 1 1 45% \u0e17\u0e35\u0e48\u0e2d\u0e32\u0e08\u0e15\u0e34\u0e14\u0e21\u0e32 *\/\r\n    }\r\n\r\n    .composer {\r\n        flex-direction: row;\r\n        align-items: center;\r\n        padding: 6px 8px;\r\n        gap: 6px;\r\n    }\r\n\r\n    #ps-input {\r\n        font-size: 14px;\r\n        padding: 4px;\r\n        line-height: 1.4;\r\n    }\r\n\r\n    .btn--send {\r\n        min-width: 40px;\r\n        height: 38px;\r\n        border-radius: 12px;\r\n    }\r\n    .msg__bubble .btn--ghost {\r\n        font-size: 11px;\r\n        padding: 4px 8px;\r\n    }\r\n}\r\n\r\n@media (max-width: 380px) {\r\n    .ps__tools {\r\n        display: grid;\r\n        grid-template-columns: 1fr 1fr;\r\n        gap: 6px;\r\n    }\r\n    .spacer { display: none; }\r\n    .btn--mode {\r\n        font-size: 12px;\r\n        padding: 6px 0;\r\n    }\r\n\r\n    \/* \u0e08\u0e31\u0e14\u0e01\u0e32\u0e23\u0e1b\u0e38\u0e48\u0e21 \"\u0e27\u0e34\u0e18\u0e35\u0e43\u0e0a\u0e49\" \u0e41\u0e25\u0e30 \"\u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\" \u0e43\u0e19 mobile layout *\/\r\n\r\n    #ps-help, #ps-reset {\r\n        grid-column: span 1; \/* \u0e43\u0e2b\u0e49\u0e41\u0e15\u0e48\u0e25\u0e30\u0e1b\u0e38\u0e48\u0e21\u0e01\u0e34\u0e19\u0e1e\u0e37\u0e49\u0e19\u0e17\u0e35\u0e48 1 \u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c *\/\r\n        flex: auto; \/* \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01 flex: 1 1 45% \u0e17\u0e35\u0e48\u0e2d\u0e32\u0e08\u0e15\u0e34\u0e14\u0e21\u0e32 *\/\r\n\r\n    }\r\n\r\n}\r\n\/* \u2728 Dynamic Loading Messages - Horizontal Layout *\/\r\n.typing-wrapper {\r\n    display: flex;\r\n    flex-direction: row; \/* \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e41\u0e19\u0e27\u0e19\u0e2d\u0e19 *\/\r\n    gap: 10px;\r\n    align-items: center; \/* \u0e08\u0e31\u0e14\u0e01\u0e25\u0e32\u0e07\u0e41\u0e19\u0e27\u0e15\u0e31\u0e49\u0e07 *\/\r\n}\r\n\r\n.loading-text {\r\n    font-size: 13px;\r\n    color: var(--muted);\r\n    font-weight: 500;\r\n    line-height: 1.6;\r\n    animation: smoothFadeIn 0.6s cubic-bezier(0.22, 1, 0.36, 1);\r\n}\r\n\r\n.typing {\r\n    display: inline-flex;\r\n    gap: 5px;\r\n    align-items: center;\r\n    margin-left: auto; \/* \u0e14\u0e31\u0e19\u0e44\u0e1b\u0e02\u0e27\u0e32\u0e2a\u0e38\u0e14 (\u0e16\u0e49\u0e32\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23) *\/\r\n}\r\n\r\n\/* Smooth modern fade-in *\/\r\n@keyframes smoothFadeIn {\r\n    from {\r\n        opacity: 0;\r\n        transform: translateY(6px) scale(0.98);\r\n    }\r\n    to {\r\n        opacity: 1;\r\n        transform: translateY(0) scale(1);\r\n    }\r\n}\r\n\r\n\/* Subtle continuous animation *\/\r\n@keyframes subtlePulse {\r\n    0%, 100% { \r\n        opacity: 0.75;\r\n    }\r\n    50% { \r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n.loading-text {\r\n    animation: \r\n        smoothFadeIn 0.6s cubic-bezier(0.22, 1, 0.36, 1),\r\n        subtlePulse 2.5s ease-in-out infinite 0.6s;\r\n}\r\n\r\n\/* Responsive *\/\r\n@media (max-width: 480px) {\r\n    .typing-wrapper {\r\n        gap: 8px;\r\n    }\r\n    \r\n    .loading-text {\r\n        font-size: 12px;\r\n        line-height: 1.5;\r\n    }\r\n}\r\n<\/style>\r\n<script>\r\n    \r\n\/\/ ============================================================\r\n\/\/ \ud83d\udd27 KEEP ALIVE SYSTEM\r\n\/\/ ============================================================\r\n\r\nlet keepAliveInterval = null;\r\nlet isPageVisible = true;\r\nlet pendingRequest = null;\r\nlet lastActivityTime = Date.now();\r\n\r\ndocument.addEventListener('visibilitychange', () => {\r\n    isPageVisible = !document.hidden;\r\n    if (isPageVisible) {\r\n        console.log('\u0e01\u0e25\u0e31\u0e1a\u0e21\u0e32\u0e17\u0e35\u0e48\u0e2b\u0e19\u0e49\u0e32\u0e08\u0e2d');\r\n        lastActivityTime = Date.now();\r\n    } else {\r\n        console.log('\u0e2a\u0e25\u0e31\u0e1a\u0e2d\u0e2d\u0e01\u0e08\u0e32\u0e01\u0e2b\u0e19\u0e49\u0e32\u0e08\u0e2d');\r\n    }\r\n});\r\n\r\nfunction startKeepAlive() {\r\n    if (keepAliveInterval) return;\r\n    keepAliveInterval = setInterval(() => {\r\n        const timeSinceActivity = Date.now() - lastActivityTime;\r\n        \r\n        \/\/ \u0e2b\u0e22\u0e38\u0e14 Keep Alive \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e34\u0e19 10 \u0e19\u0e32\u0e17\u0e35 (\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e08\u0e32\u0e01 5 \u0e19\u0e32\u0e17\u0e35)\r\n        if (timeSinceActivity > 10 * 60 * 1000) {\r\n            stopKeepAlive();\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u0e2a\u0e48\u0e07 heartbeat \u0e40\u0e09\u0e1e\u0e32\u0e30\u0e40\u0e21\u0e37\u0e48\u0e2d: visible + \u0e44\u0e21\u0e48\u0e21\u0e35 pending request\r\n        if (isPageVisible && !pendingRequest) {\r\n            fetch('https:\/\/pawdy.co.th\/wp-json\/', {  \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19 URL \u0e43\u0e2b\u0e49\u0e15\u0e23\u0e07\u0e01\u0e31\u0e1a\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\r\n                method: 'HEAD',\r\n                mode: 'no-cors'\r\n            }).catch(() => {\r\n                console.log('Heartbeat failed (\u0e44\u0e21\u0e48\u0e40\u0e1b\u0e47\u0e19\u0e44\u0e23)');\r\n            });\r\n        }\r\n    }, 30000);  \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e08\u0e32\u0e01 25000 \u0e40\u0e1b\u0e47\u0e19 30000 (30 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35)\r\n    console.log('\u0e40\u0e23\u0e34\u0e48\u0e21 Keep Alive');\r\n}\r\n\r\n\r\nfunction stopKeepAlive() {\r\n    if (keepAliveInterval) {\r\n        clearInterval(keepAliveInterval);\r\n        keepAliveInterval = null;\r\n        console.log('\u0e2b\u0e22\u0e38\u0e14 Keep Alive');\r\n    }\r\n}\r\n\r\nfunction trackActivity() {\r\n    lastActivityTime = Date.now();\r\n    startKeepAlive();\r\n}\r\n\r\nasync function fetchWithRetry(url, options, maxRetries = 2, timeout = 600000) {\r\n    const controller = new AbortController();\r\n    const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n    pendingRequest = { url, startTime: Date.now() };\r\n    \r\n    try {\r\n        for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n            try {\r\n                const response = await fetch(url, {\r\n                    ...options,\r\n                    signal: controller.signal,\r\n                    headers: {\r\n                        ...options.headers,\r\n                        'Connection': 'keep-alive',\r\n                        'Keep-Alive': 'timeout=60, max=100'\r\n                    }\r\n                });\r\n                clearTimeout(timeoutId);\r\n                pendingRequest = null;\r\n                trackActivity();\r\n                return response;\r\n            } catch (error) {\r\n                if (attempt === maxRetries) throw error;\r\n                if (error.name === 'TypeError' || error.message.includes('Failed to fetch')) {\r\n                    console.log(`Retry ${attempt + 1}\/${maxRetries}`);\r\n                    await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1)));\r\n                    continue;\r\n                }\r\n                throw error;\r\n            }\r\n        }\r\n    } catch (error) {\r\n        clearTimeout(timeoutId);\r\n        pendingRequest = null;\r\n        throw error;\r\n    }\r\n}\r\n\r\n\/\/ ============================================================\r\n\/\/ \ud83d\udd27 MAIN APPLICATION\r\n\/\/ ============================================================\r\n(()=> {\r\n   const CHAT_ENDPOINT = 'https:\/\/pawdy.co.th\/wp-json\/pawdy\/v1\/chat';\r\n    const MODE_ENDPOINT = 'https:\/\/pawdy.co.th\/wp-json\/pawdy\/v1\/change-mode';\r\n    const SESSION_KEY = 'pawdy_session';\r\n\r\n    const log = document.getElementById('ps-log');\r\n    const form = document.getElementById('ps-form');\r\n    const input = document.getElementById('ps-input');\r\n    const resetBtn = document.getElementById('ps-reset');\r\n    const helpBtn = document.getElementById('ps-help');\r\n    const modeDogBtn = document.getElementById('ps-mode-dog');\r\n    const modeCatBtn = document.getElementById('ps-mode-cat');\r\n\r\nfunction createNewSession() {\r\n    const newSession = {\r\n        userId: 'pawdy-' + (crypto?.randomUUID?.() || String(Date.now())),\r\n        mode: 'DOG',\r\n        createdAt: new Date().toISOString()\r\n    };\r\n    localStorage.setItem(SESSION_KEY, JSON.stringify(newSession));\r\n    console.log('\u0e2a\u0e23\u0e49\u0e32\u0e07 Session \u0e43\u0e2b\u0e21\u0e48 (Page Load):', newSession);\r\n    return newSession;\r\n}\r\n\r\nconst session = createNewSession();\r\nlet userId = session.userId;\r\nlet currentMode = session.mode;\r\n\r\nconsole.log('\ud83d\udc3e User ID:', userId);\r\nconsole.log('\ud83d\udc3e Current Mode:', currentMode);\r\n\r\n    function updateModeButtonState(mode) {\r\n        modeDogBtn.classList.remove('btn--mode-active');\r\n        modeCatBtn.classList.remove('btn--mode-active');\r\n        if (mode === 'DOG') {\r\n            modeDogBtn.classList.add('btn--mode-active');\r\n        } else if (mode === 'CAT') {\r\n            modeCatBtn.classList.add('btn--mode-active');\r\n        }\r\n    }\r\n    updateModeButtonState(currentMode); \r\n    \r\n    let loadingInterval = null;\r\n    let loadingStartTime = null;\r\n\r\n    function getDynamicMessage(elapsedSeconds) {\r\n        if (elapsedSeconds < 30) {\r\n            return '\u0e19\u0e49\u0e2d\u0e07\u0e1e\u0e2d\u0e14\u0e35\u0e01\u0e33\u0e25\u0e31\u0e07\u0e04\u0e34\u0e14\u0e04\u0e33\u0e15\u0e2d\u0e1a.. \u0e01\u0e23\u0e38\u0e13\u0e32\u0e2d\u0e22\u0e48\u0e32\u0e1e\u0e36\u0e48\u0e07\u0e2d\u0e2d\u0e01\u0e08\u0e32\u0e01\u0e2b\u0e19\u0e49\u0e32\u0e19\u0e35\u0e49';\r\n        } else if (elapsedSeconds < 60) {\r\n            return '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e2b\u0e32\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e17\u0e35\u0e48\u0e14\u0e35\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14\u0e43\u0e2b\u0e49\u0e04\u0e38\u0e13...';\r\n        } else if (elapsedSeconds < 90) {\r\n            return '\u0e2d\u0e35\u0e01\u0e2a\u0e31\u0e01\u0e04\u0e23\u0e39\u0e48\u0e19\u0e30\u0e04\u0e30 \u0e43\u0e01\u0e25\u0e49\u0e44\u0e14\u0e49\u0e04\u0e33\u0e15\u0e2d\u0e1a\u0e41\u0e25\u0e49\u0e27...';\r\n        } else {\r\n            return '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e1b\u0e23\u0e30\u0e21\u0e27\u0e25\u0e1c\u0e25\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e23\u0e2d\u0e2a\u0e31\u0e01\u0e04\u0e23\u0e39\u0e48...';\r\n        }\r\n    }\r\n\r\n    function showDynamicTyping() {\r\n        const el = document.createElement('article');\r\n        el.className = 'msg msg--bot';\r\n        el.innerHTML = `\r\n            <div class=\"msg__avatar\" aria-hidden=\"true\">\ud83d\udc3e<\/div>\r\n            <div class=\"msg__bubble\">\r\n                <div class=\"typing-wrapper\">\r\n                    <span class=\"typing\"><i><\/i><i><\/i><i><\/i><\/span>\r\n                    <span class=\"loading-text\"><\/span>\r\n                <\/div>\r\n            <\/div>\r\n        `;\r\n        log.appendChild(el);\r\n        if (atBottom) log.scrollTop = log.scrollHeight;\r\n        \r\n        loadingStartTime = Date.now();\r\n        \r\n        loadingInterval = setInterval(() => {\r\n            const elapsed = Math.floor((Date.now() - loadingStartTime) \/ 1000);\r\n            const textEl = el.querySelector('.loading-text');\r\n            if (textEl) {\r\n                textEl.textContent = getDynamicMessage(elapsed);\r\n            }\r\n        }, 5000);\r\n        \r\n        return el;\r\n    }\r\n\r\n    function clearLoadingInterval() {\r\n        if (loadingInterval) {\r\n            clearInterval(loadingInterval);\r\n            loadingInterval = null;\r\n        }\r\n        loadingStartTime = null;\r\n    }\r\n    \r\n    let atBottom = true;\r\n    let isSessionInitialized = false;\r\n\r\n    function esc(s){\r\n        const str = (s == null ? '' : String(s));\r\n        return str.replace(\/[&<>\"']\/g, ch => ({\r\n            '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#039;'\r\n        }[ch]));\r\n    }\r\n    \r\n    const autoGrow = el => { \r\n        el.style.height='auto'; \r\n        el.style.height=Math.min(el.scrollHeight,180)+'px'; \r\n    };\r\n    \r\nfunction md(text){\r\n    let s = esc(text || '');\r\n    s = s.replace(\/\\((https?:\\\/\\\/[^\\s<)]+)\\)\/g, '$1');\r\n    s = s.replace(\r\n        \/(https?:\\\/\\\/[^\\s<)]+)\/g, \r\n        '<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"chat-link\">$1<\/a>'\r\n    );\r\n    return s.replace(\/\\n\/g, '<br>');\r\n}\r\n\r\n    const addMsg=(role,html,typing=false,isChoice=false)=>{\r\n        const el=document.createElement('article');\r\n        el.className='msg '+(role==='user'?'msg--user':'msg--bot');\r\n        const avatar=role==='user'?'':'<div class=\"msg__avatar\" aria-hidden=\"true\">\ud83d\udc3e<\/div>';\r\n        let bubbleClass = isChoice ? 'msg__bubble msg__bubble--choice' : 'msg__bubble markdown';\r\n        let body=typing\r\n          ?'<div class=\"msg__bubble\"><span class=\"typing\"><i><\/i><i><\/i><i><\/i><\/span><\/div>'\r\n          :'<div class=\"'+bubbleClass+'\">'+html+'<\/div>';\r\n        el.innerHTML=avatar+body;\r\n        log.appendChild(el);\r\n        if(atBottom)log.scrollTop=log.scrollHeight;\r\n        return el;\r\n    };\r\n    \r\n    function replaceTyping(article,html){\r\n        article.innerHTML='<div class=\"msg__avatar\" aria-hidden=\"true\">\ud83d\udc3e<\/div><div class=\"msg__bubble markdown\">'+html+'<\/div>';\r\n        const bubble=article.querySelector('.msg__bubble');\r\n        const btn=document.createElement('button');\r\n        btn.type='button';\r\n        btn.className='btn btn--ghost';\r\n        btn.textContent='\u0e04\u0e31\u0e14\u0e25\u0e2d\u0e01';\r\n        btn.style.marginTop='8px';\r\n        btn.addEventListener('click',()=>{\r\n            const text=bubble.innerText;\r\n            navigator.clipboard.writeText(text).then(()=>{\r\n                const old=btn.textContent;\r\n                btn.textContent='\u0e04\u0e31\u0e14\u0e25\u0e2d\u0e01\u0e41\u0e25\u0e49\u0e27 \u2713';\r\n                setTimeout(()=>btn.textContent=old,1200);\r\n            });\r\n        });\r\n        bubble.appendChild(btn);\r\n        log.scrollTop=log.scrollHeight;\r\n    }\r\n\r\n    function getUserFriendlyError(error) {\r\n        const errorMsg = error.message || String(error);\r\n        \r\n        if (errorMsg.includes('Load failed') || \r\n            errorMsg.includes('Failed to fetch') ||\r\n            errorMsg.includes('NetworkError') ||\r\n            errorMsg.includes('network')) {\r\n            return '\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d\u0e02\u0e31\u0e14\u0e02\u0e49\u0e2d\u0e07 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e16\u0e32\u0e21\u0e04\u0e33\u0e16\u0e32\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e19\u0e30\u0e04\u0e30';\r\n        }\r\n        \r\n        if (errorMsg.includes('timeout') || errorMsg.includes('timed out')) {\r\n            return '\u0e02\u0e13\u0e30\u0e19\u0e35\u0e49\u0e21\u0e35\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e2b\u0e25\u0e32\u0e22\u0e17\u0e48\u0e32\u0e19 \u0e17\u0e33\u0e43\u0e2b\u0e49\u0e40\u0e01\u0e34\u0e14\u0e04\u0e27\u0e32\u0e21\u0e02\u0e31\u0e14\u0e02\u0e49\u0e2d\u0e07\u0e40\u0e25\u0e47\u0e01\u0e19\u0e49\u0e2d\u0e22 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e16\u0e32\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e04\u0e48\u0e30';\r\n        }\r\n        \r\n        if (errorMsg.includes('JSON') || errorMsg.includes('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25')) {\r\n            return '\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e23\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e19\u0e30\u0e04\u0e30';\r\n        }\r\n        \r\n        if (errorMsg.includes('\u0e2b\u0e21\u0e14\u0e25\u0e34\u0e21\u0e34\u0e15') || errorMsg.includes('limit')) {\r\n            return errorMsg;\r\n        }\r\n        \r\n        return errorMsg || '\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e16\u0e32\u0e21\u0e04\u0e33\u0e16\u0e32\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e04\u0e48\u0e30';\r\n    }\r\n\r\n    \/\/ \ud83d\udd27 \u0e41\u0e01\u0e49\u0e44\u0e02: \u0e43\u0e0a\u0e49 fetchWithRetry \u0e41\u0e17\u0e19 fetch\r\n    async function callChatAPI(userText, showUserMessage = true){\r\n        if(showUserMessage && userText !== '[\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e42\u0e2b\u0e21\u0e14]'){\r\n        }\r\n        \r\n        const payload={text:userText, userId, animalType: currentMode}; \r\n        console.log('Chat Payload:', payload);\r\n        \r\n        try {\r\n            const res = await fetchWithRetry(CHAT_ENDPOINT, {\r\n    method: 'POST',\r\n    headers: {'Content-Type': 'application\/json'},\r\n    body: JSON.stringify(payload)\r\n}, 2, 600000);  \/\/ \u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e08\u0e32\u0e01 60000 \u0e40\u0e1b\u0e47\u0e19 300000 (5 \u0e19\u0e32\u0e17\u0e35)\r\n\r\n            let data;\r\n            let bodyText;\r\n\r\n            try {\r\n                bodyText = await res.text();\r\n                data = JSON.parse(bodyText);\r\n            } catch (e) {\r\n                if (!res.ok) {\r\n                    console.error('API Non-JSON Error: HTTP ' + res.status, bodyText);\r\n                    throw new Error('\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d (\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07)');\r\n                }\r\n                throw new Error('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 API \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07 (\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e41\u0e1b\u0e25\u0e07\u0e40\u0e1b\u0e47\u0e19 JSON)');\r\n            }\r\n\r\n            console.log('Chat Response:', data);\r\n\r\n            if (res.ok) {\r\n                isSessionInitialized = true;\r\n            }\r\n\r\n            if(data && typeof data==='object' && data.code){\r\n                switch(data.code){\r\n                    case 'limit_history':\r\n                        throw new Error('\u0e2b\u0e21\u0e14\u0e25\u0e34\u0e21\u0e34\u0e15\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e15\u0e48\u0e2d \u0e01\u0e23\u0e38\u0e13\u0e32\u0e01\u0e14\u0e1b\u0e38\u0e48\u0e21 \u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48\u0e19\u0e30\u0e04\u0e30');\r\n                    case 'limit_per_day':\r\n                        throw new Error('\u0e2b\u0e21\u0e14\u0e25\u0e34\u0e21\u0e34\u0e15\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e15\u0e48\u0e2d\u0e27\u0e31\u0e19 \u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e01\u0e25\u0e31\u0e1a\u0e21\u0e32\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e44\u0e14\u0e49\u0e43\u0e19\u0e27\u0e31\u0e19\u0e1e\u0e23\u0e38\u0e48\u0e07\u0e19\u0e35\u0e49\u0e19\u0e30\u0e04\u0e30');\r\n                    case 'first_message_day':\r\n                        return {requiresConfirmation: true, originalText: userText};\r\n                }\r\n            }\r\n            \r\n            if(!res.ok){\r\n                const errorDetail = data.data || data.message || 'Unknown error';\r\n                throw new Error('\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e40\u0e0a\u0e37\u0e48\u0e2d\u0e21\u0e15\u0e48\u0e2d: ' + errorDetail);\r\n            }\r\n\r\n            const msg=data.data||data.message||data.reply;\r\n            if(typeof msg==='string' && msg.trim())return msg;\r\n            if(typeof data==='string' && data.trim())return data;\r\n            throw new Error('\u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e2d\u0e1a\u0e01\u0e25\u0e31\u0e1a\u0e08\u0e32\u0e01 AI');\r\n            \r\n        } catch (error) {\r\n            console.error('Chat API Error:', error);\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    \/\/ \ud83d\udd27 \u0e41\u0e01\u0e49\u0e44\u0e02: \u0e43\u0e0a\u0e49 fetchWithRetry \u0e41\u0e17\u0e19 fetch\r\n    async function changeModeAPI(newMode){\r\n        const payload={userId, animalType:newMode};\r\n        console.log('Mode Change Payload:', payload);\r\n        \r\n        try {\r\n            const res = await fetchWithRetry(MODE_ENDPOINT, {\r\n                method: 'POST',\r\n                headers: {'Content-Type': 'application\/json'},\r\n                body: JSON.stringify(payload)\r\n            }, 2, 30000);\r\n            \r\n            const data=await res.json().catch(()=>({}));\r\n            console.log('Mode Change Response:', data);\r\n            \r\n            if(res.ok && data.code==='success'){\r\n                isSessionInitialized = true;\r\n                return true;\r\n            } \r\n            throw new Error('\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e42\u0e2b\u0e21\u0e14\u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08: ' + (data.data || data.message || 'Unknown error'));\r\n        } catch (error) {\r\n            console.error('Mode Change API Error:', error);\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    async function handleModeChange(newMode){\r\n        if(newMode===currentMode)return;\r\n        \r\n        modeDogBtn.disabled=true;\r\n        modeCatBtn.disabled=true;\r\n        \r\n        const modeTextRequest = newMode==='DOG'?'\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e42\u0e2b\u0e21\u0e14\u0e19\u0e49\u0e2d\u0e07\u0e2b\u0e21\u0e32':'\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e40\u0e1b\u0e47\u0e19\u0e42\u0e2b\u0e21\u0e14\u0e19\u0e49\u0e2d\u0e07\u0e41\u0e21\u0e27';\r\n        addMsg('user', md(modeTextRequest));\r\n        \r\n        const typingArticle=showDynamicTyping();\r\n        \r\n        try{\r\n            if(!isSessionInitialized){\r\n                console.log(' Session \u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e43\u0e19 Backend, \u0e01\u0e33\u0e25\u0e31\u0e07\u0e2a\u0e23\u0e49\u0e32\u0e07...');\r\n                await callChatAPI('[\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e42\u0e2b\u0e21\u0e14]', false);\r\n                console.log(' \u0e2a\u0e23\u0e49\u0e32\u0e07 Session \u0e43\u0e19 Backend \u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08');\r\n            }\r\n            \r\n            await changeModeAPI(newMode);\r\n            \r\n            currentMode=newMode;\r\n            \r\n            const session = JSON.parse(localStorage.getItem(SESSION_KEY) || '{}');\r\n            session.mode = newMode;\r\n            localStorage.setItem(SESSION_KEY, JSON.stringify(session));\r\n            console.log(' \u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e42\u0e2b\u0e21\u0e14\u0e43\u0e2b\u0e21\u0e48\u0e25\u0e07 localStorage:', newMode);\r\n            \r\n            updateModeButtonState(newMode);\r\n\r\n            const modeText=newMode==='DOG'?'\ud83d\udc15 \u0e19\u0e49\u0e2d\u0e07\u0e2b\u0e21\u0e32':'\ud83d\udc08 \u0e19\u0e49\u0e2d\u0e07\u0e41\u0e21\u0e27';\r\n            replaceTyping(typingArticle,md(`\u0e2a\u0e25\u0e31\u0e1a\u0e42\u0e2b\u0e21\u0e14\u0e40\u0e1b\u0e47\u0e19 ${modeText} \u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08\\n\\n\u0e01\u0e32\u0e23\u0e2a\u0e19\u0e17\u0e19\u0e32\u0e15\u0e48\u0e2d\u0e08\u0e32\u0e01\u0e19\u0e35\u0e49\u0e08\u0e30\u0e40\u0e19\u0e49\u0e19\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a${modeText}\u0e04\u0e48\u0e30`));\r\n        }catch(err){\r\n            if(typingArticle && typingArticle.parentNode){\r\n                typingArticle.remove();\r\n            }\r\n            \r\n            const errorMsg = getUserFriendlyError(err);\r\n            addMsg('bot', md(errorMsg));\r\n            console.error('Mode Change Error:',err);\r\n        }finally{\r\n            clearLoadingInterval();\r\n            modeDogBtn.disabled=false;\r\n            modeCatBtn.disabled=false;\r\n        }\r\n    }\r\n    \r\n    modeDogBtn.addEventListener('click',()=>handleModeChange('DOG'));\r\n    modeCatBtn.addEventListener('click',()=>handleModeChange('CAT'));\r\n\r\n    async function handleHelp(){\r\n        const helpText = '\u0e27\u0e34\u0e18\u0e35\u0e43\u0e0a\u0e49\u0e41\u0e25\u0e30\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33';\r\n        console.log(' Help Button Pressed | User ID:', userId, '| Mode:', currentMode);\r\n        addMsg('user',md(helpText));\r\n        const typingArticle=showDynamicTyping();\r\n        \r\n        try{\r\n            const reply=await callChatAPI(helpText);\r\n\r\n            if(reply && typeof reply === 'object' && reply.requiresConfirmation){\r\n                showConfirmation(typingArticle, reply.originalText);\r\n            } else if(typeof reply === 'string') {\r\n                replaceTyping(typingArticle,md(reply));\r\n            } else {\r\n                throw new Error('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 API \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07');\r\n            }\r\n        }catch(err){\r\n            replaceTyping(typingArticle,md(getUserFriendlyError(err)));\r\n            console.error('Help Error:',err);\r\n        }finally{\r\n            clearLoadingInterval();\r\n        }\r\n    }\r\n    \r\n    helpBtn.addEventListener('click', handleHelp);\r\n\r\nasync function hardReset(){\r\n    console.log('\ud83d\udd04 Reset | User ID:', userId, '| Mode:', currentMode);\r\n    const resetText = '\u0e40\u0e23\u0e34\u0e48\u0e21\u0e04\u0e38\u0e22\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48';\r\n    addMsg('user',md(resetText));\r\n    const typingArticle=showDynamicTyping();\r\n\r\n    try{\r\n        const reply=await callChatAPI(resetText);\r\n\r\n        if(reply && typeof reply === 'object' && reply.requiresConfirmation){\r\n            showConfirmation(typingArticle, reply.originalText);\r\n        } else if(typeof reply === 'string') {\r\n            replaceTyping(typingArticle,md(reply));\r\n        } else {\r\n            throw new Error('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 API \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07');\r\n        }\r\n    }catch(err){\r\n        replaceTyping(typingArticle,md(getUserFriendlyError(err)));\r\n        console.error('Reset Error:',err);\r\n    }finally{\r\n        clearLoadingInterval();\r\n    }\r\n}\r\n    \r\n    resetBtn.addEventListener('click',hardReset);\r\n\r\n    function showConfirmation(typingArticle, originalText){\r\n        const confirmHTML = `\r\n            <p>\u0e02\u0e2d\u0e16\u0e32\u0e21\u0e19\u0e34\u0e14\u0e19\u0e36\u0e07\u0e19\u0e30\u0e04\u0e30 \u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e17\u0e35\u0e48\u0e1e\u0e36\u0e48\u0e07\u0e2a\u0e48\u0e07\u0e21\u0e32 \u0e40\u0e1b\u0e47\u0e19\u0e01\u0e32\u0e23\u0e04\u0e38\u0e22\u0e15\u0e48\u0e2d\u0e08\u0e32\u0e01\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e40\u0e14\u0e34\u0e21\u0e17\u0e35\u0e48\u0e04\u0e38\u0e22\u0e2d\u0e22\u0e39\u0e48\u0e01\u0e48\u0e2d\u0e19\u0e2b\u0e19\u0e49\u0e32 \u0e2b\u0e23\u0e37\u0e2d\u0e40\u0e1b\u0e47\u0e19\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48<\/p>\r\n            <div class=\"choice-buttons\">\r\n                <button class=\"btn-choice\" data-choice=\"old\">\u0e2b\u0e31\u0e27\u0e02\u0e49\u0e2d\u0e40\u0e14\u0e34\u0e21<\/button>\r\n                <button class=\"btn-choice\" data-choice=\"new\">\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48<\/button>\r\n            <\/div>\r\n        `;\r\n        \r\n        typingArticle.innerHTML = '<div class=\"msg__avatar\" aria-hidden=\"true\">\ud83d\udc3e<\/div><div class=\"msg__bubble msg__bubble--choice\">' + confirmHTML + '<\/div>';\r\n        \r\n        const buttons = typingArticle.querySelectorAll('.btn-choice');\r\n        buttons.forEach(btn => {\r\n            btn.addEventListener('click', async ()=>{\r\n                const choice = btn.dataset.choice;\r\n                const prefix = choice === 'new' ? '[\u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e43\u0e2b\u0e21\u0e48]' : '[\u0e2b\u0e31\u0e27\u0e02\u0e49\u0e2d\u0e40\u0e14\u0e34\u0e21]';\r\n                const finalText = prefix + originalText;\r\n                \r\n                buttons.forEach(b => b.disabled = true);\r\n                const newTypingArticle = showDynamicTyping();\r\n                \r\n                try{\r\n                    const reply = await callChatAPI(finalText);\r\n                    if(typeof reply === 'string') {\r\n                        replaceTyping(newTypingArticle, md(reply));\r\n                    } else {\r\n                        throw new Error('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 API \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07');\r\n                    }\r\n                } catch(err){\r\n                    replaceTyping(newTypingArticle, md(getUserFriendlyError(err)));\r\n                    console.error('Confirmation Error:', err);\r\n                }finally{\r\n                    clearLoadingInterval();\r\n                }\r\n            });\r\n        });\r\n    }\r\n\r\n    form.addEventListener('submit',async e=>{\r\n        e.preventDefault();\r\n        const text=(input.value||'').trim();\r\n        if(!text)return;\r\n        \r\n        addMsg('user',md(text));\r\n        input.value='';\r\n        autoGrow(input);\r\n        const typingArticle=showDynamicTyping();\r\n        \r\n        try{\r\n            const reply=await callChatAPI(text);\r\n            \r\n            if(reply && typeof reply === 'object' && reply.requiresConfirmation){\r\n                showConfirmation(typingArticle, reply.originalText);\r\n            } else if(typeof reply === 'string') {\r\n                replaceTyping(typingArticle,md(reply));\r\n            } else {\r\n                throw new Error('\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 API \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07');\r\n            }\r\n        }catch(err){\r\n            replaceTyping(typingArticle,md(getUserFriendlyError(err)));\r\n            console.error('Chat Error:',err);\r\n        }finally{\r\n            clearLoadingInterval();\r\n        }\r\n    });\r\n\r\n    input.addEventListener('keydown',e=>{\r\n        if(e.key==='Enter'&&!e.shiftKey){\r\n            e.preventDefault();\r\n            form.dispatchEvent(new Event('submit',{cancelable:true}));\r\n        }\r\n    });\r\n\r\n    \/\/ \ud83d\udd27 \u0e40\u0e1e\u0e34\u0e48\u0e21: Activity Tracking \u0e41\u0e25\u0e30 Keep Alive\r\n    ['click', 'keydown', 'touchstart', 'scroll'].forEach(event => {\r\n        document.addEventListener(event, trackActivity, { passive: true });\r\n    });\r\n\r\n    startKeepAlive();\r\n    window.addEventListener('beforeunload', stopKeepAlive);\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Pawdy AI \ud83d\udc3e \u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\u0e04\u0e48\u0e30 \u0e09\u0e31\u0e19\u0e04\u0e37\u0e2d\u0e19\u0e49\u0e2d\u0e07\u0e1e\u0e2d\u0e14\u0e35 \ud83d\udc3e \u0e1c\u0e39\u0e49\u0e0a\u0e48\u0e27\u0e22\u0e2d\u0e31\u0e08\u0e09\u0e23\u0e34\u0e22\u0e30\u0e08\u0e32\u0e01 Nhamaew Pet AI \u0e17\u0e35\u0e48\u0e08\u0e30\u0e04\u0e2d\u0e22\u0e23\u0e31\u0e1a\u0e1f\u0e31\u0e07\u0e1b\u0e31\u0e0d\u0e2b\u0e32\u0e19\u0e49\u0e2d\u0e07\u0e2b\u0e21\u0e32\u2013\u0e19\u0e49\u0e2d\u0e07\u0e41\u0e21\u0e27 \u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e43\u0e2b\u0e49\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e17\u0e35\u0e48\u0e40\u0e02\u0e49\u0e32\u0e43\u0e08\u0e07\u0e48\u0e32\u0e22\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a \u0e40\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e2d\u0e32\u0e2b\u0e32\u0e23 \u0e2a\u0e38\u0e02\u0e20\u0e32\u0e1e \u0e41\u0e25\u0e30\u0e44\u0e25\u0e1f\u0e4c\u0e2a\u0e44\u0e15\u0e25\u0e4c \u0e08\u0e34\u0e49\u0e21 \u0e40\u0e25\u0e37\u0e2d\u0e01\u0e42\u0e2b\u0e21\u0e14\u0e14\u0e49\u0e32\u0e19\u0e25\u0e48\u0e32\u0e07 \u0e41\u0e25\u0e49\u0e27\u0e25\u0e2d\u0e07\u0e04\u0e38\u0e22\u0e01\u0e31\u0e1a\u0e19\u0e49\u0e2d\u0e07\u0e1e\u0e2d\u0e14\u0e35\u0e44\u0e14\u0e49\u0e40\u0e25\u0e22\u0e19\u0e49\u0e32\u0e32\u0e32 \ud83d\udc9a \ud83d\udc15 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-9550","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/pages\/9550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/comments?post=9550"}],"version-history":[{"count":95,"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/pages\/9550\/revisions"}],"predecessor-version":[{"id":10026,"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/pages\/9550\/revisions\/10026"}],"wp:attachment":[{"href":"https:\/\/pawdy.co.th\/en\/wp-json\/wp\/v2\/media?parent=9550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}