PageSourceSearch

https://www.hamdard.edu.pk/wp-content/plugins/hamdard-chatbot/chatbot-widget.js?ver=1790317607

js hamdard.edu.pk collected 2026-09-25 07:08:29 UTC 36,294 bytes, 617 lines download raw bytes

1// Hamdard University Chatbot - WordPress Integration
2// Ultra Premium UI/UX Version
3(function() {
4    'use strict';
5
6    const CHATBOT_CONFIG = {
7        title: 'Hamdard University',
8        subtitle: 'Admissions & AI Assistant',
9        primaryColor: '#059669', // Emerald-600
10        secondaryColor: '#047857', // Emerald-700
11    };
12
13    const QUICK_REPLIES = [
14        "Admission Process",
15        "Fee Structure", 
16        "Courses Offered",
17        "Scholarships",
18        "Contact Information"
19    ];
20
21    class WordPressChatbot {
22        constructor() {
23            this.messages = [];
24            this.isOpen = false;
25            this.isTyping = false;
26            this.init();
27        }
28
29        init() {
30            this.createChatbotHTML();
31            this.attachEventListeners();
32            this.addWelcomeMessage();
33        }
34
35        createChatbotHTML() {
36            const chatbotHTML = `
37                <div id="hamdard-chatbot" class="hamdard-chatbot-container">
38                    <div id="hamdard-chat-button" class="hamdard-chat-button">
39                        <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
40                            <path d="M8 12H16M8 8H16M8 16H12M21 12C21 16.9706 16.9706 21 12 21C10.2 21 8.5 20.5 7 19.6L3 21L4.4 17C3.5 15.5 3 13.8 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
41                        </svg>
42                    </div>
43
44                    <div id="hamdard-chat-window" class="hamdard-chat-window">
45                        <div class="hamdard-chat-header">
46                            <div class="hamdard-chat-header-info">
47                                <div class="hamdard-chat-avatar">
48                                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2L13.09 8.26L20 9L13.09 9.74L12 16L10.91 9.74L4 9L10.91 8.26L12 2Z" fill="currentColor"/></svg>
49                                </div>
50                                <div class="hamdard-header-text">
51                                    <h3 style="margin: 0; font-size: 16px; font-weight: 700; letter-spacing: 0.3px; color: white;">${CHATBOT_CONFIG.title}</h3>
52                                    <div class="hamdard-status">
53                                        <div class="hamdard-status-dot"></div>
54                                        <span>${CHATBOT_CONFIG.subtitle}</span>
55                                    </div>
56                                </div>
57                            </div>
58                            <button id="hamdard-chat-close" class="hamdard-chat-close">
59                                <svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
60                            </button>
61                        </div>
62                        <div class="hamdard-quick-contact">
63                            <span style="display: flex; align-items: center; gap: 4px;"><svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"></path></svg> 021-111-102-030</span>
64                            <span class="hamdard-divider">|</span>
65                            <span style="display: flex; align-items: center; gap: 4px;"><svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg> [email protected]</span>
66                        </div>
67                        <div id="hamdard-chat-messages" class="hamdard-chat-messages"></div>
68                        <div id="hamdard-quick-replies" class="hamdard-quick-replies"></div>
69                        <div class="hamdard-chat-input">
70                            <input type="text" id="hamdard-message-input" placeholder="Type your message... / اپنا پیغام لکھیں" autocomplete="off" />
71                            <button id="hamdard-send-button">
72                                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
73                            </button>
74                        </div>
75                    </div>
76                </div>
77            `;
78            document.body.insertAdjacentHTML('beforeend', chatbotHTML);
79            this.loadStyles();
80        }
81
82        loadStyles() {
83            const styles = `
84                @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap');
85                
86                <style id="hamdard-chatbot-premium-styles">
87                /* Base Reset */
88                .hamdard-chatbot-container * { box-sizing: border-box; }
89                .hamdard-chatbot-container { 
90                    position: fixed; bottom: 24px; right: 24px; 
91                    z-index: 999999 !important; 
92                    font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 
93                }
94                
95                /* Floating Button */
96                .hamdard-chat-button { 
97                    width: 64px; height: 64px; 
98                    background: linear-gradient(135deg, ${CHATBOT_CONFIG.primaryColor}, ${CHATBOT_CONFIG.secondaryColor}); 
99                    border-radius: 50%; display: flex; align-items: center; justify-content: center; 
100                    color: white; cursor: pointer; 
101                    box-shadow: 0 8px 24px rgba(5, 150, 105, 0.4); 
102                    transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.3s; 
103                    animation: hamdardPulse 2.5s infinite; 
104                    position: relative; z-index: 1000000 !important; 
105                }
106                .hamdard-chat-button:hover { 
107                    transform: scale(1.1) translateY(-4px); 
108                    box-shadow: 0 12px 28px rgba(5, 150, 105, 0.5);
109                }
110                @keyframes hamdardPulse { 
111                    0% { box-shadow: 0 0 0 0 rgba(5, 150, 105, 0.4); } 
112                    70% { box-shadow: 0 0 0 15px rgba(5, 150, 105, 0); } 
113                    100% { box-shadow: 0 0 0 0 rgba(5, 150, 105, 0); } 
114                }
115
116                /* Chat Window - Premium Glassmorphism */
117                .hamdard-chat-window { 
118                    width: 400px; height: 680px; max-height: calc(100vh - 120px);
119                    background: rgba(255, 255, 255, 0.98); 
120                    backdrop-filter: blur(20px);
121                    border-radius: 20px; 
122                    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0,0,0,0.05); 
123                    display: none; flex-direction: column; overflow: hidden; 
124                    position: absolute; bottom: 84px; right: 0; 
125                    transform-origin: bottom right;
126                }
127                .hamdard-chat-window.open { 
128                    display: flex; 
129                    animation: scaleIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards; 
130                }
131                @keyframes scaleIn { 
132                    from { opacity: 0; transform: scale(0.9) translateY(20px); } 
133                    to { opacity: 1; transform: scale(1) translateY(0); } 
134                }
135
136                /* Header */
137                .hamdard-chat-header { 
138                    background: linear-gradient(135deg, ${CHATBOT_CONFIG.primaryColor} 0%, ${CHATBOT_CONFIG.secondaryColor} 100%), url("data:image/svg+xml,%3Csvg width='60' height='60' viewB
138ox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); 
139                    color: white; padding: 20px; 
140                    display: flex; align-items: center; justify-content: space-between; 
141                    border-top-left-radius: 20px; border-top-right-radius: 20px;
142                    border-bottom: 1px solid rgba(0,0,0,0.05);
143                }
144                .hamdard-chat-header-info { display: flex; align-items: center; gap: 14px; }
145                .hamdard-chat-avatar { 
146                    width: 44px; height: 44px; 
147                    background: rgba(255, 255, 255, 0.2); 
148                    border-radius: 50%; display: flex; align-items: center; justify-content: center; 
149                    box-shadow: 0 4px 10px rgba(0,0,0,0.1); 
150                    backdrop-filter: blur(4px);
151                    border: 2px solid rgba(255,255,255,0.4);
152                }
153                .hamdard-status { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
154                .hamdard-status-dot { width: 8px; height: 8px; background: #34d399; border-radius: 50%; box-shadow: 0 0 8px rgba(52, 211, 153, 0.8); animation: blink 2s infinite; }
155                @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
156                .hamdard-status span { font-size: 13px; opacity: 0.95; font-weight: 500; color: white;}
157                
158                .hamdard-chat-close { 
159                    background: rgba(255, 255, 255, 0.1); border: none; color: white; 
160                    cursor: pointer; padding: 8px; border-radius: 50%; 
161                    transition: all 0.2s; display: flex; align-items: center; justify-content: center;
162                }
163                .hamdard-chat-close:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); }
164
165                /* Contact Bar */
166                .hamdard-quick-contact { 
167                    background: #f0fdf4; padding: 10px 20px; 
168                    display: flex; justify-content: center; gap: 12px; align-items: center;
169                    font-size: 12px; color: ${CHATBOT_CONFIG.secondaryColor}; 
170                    border-bottom: 1px solid rgba(5, 150, 105, 0.1); font-weight: 600;
171                }
172                .hamdard-divider { opacity: 0.3; }
173
174                /* Messages Area */
175                .hamdard-chat-messages { 
176                    flex: 1; overflow-y: auto; padding: 20px; 
177                    background: #f8fafc; display: flex; flex-direction: column; 
178                    scroll-behavior: smooth;
179                }
180                
181                /* Custom Scrollbar */
182                .hamdard-chat-messages::-webkit-scrollbar { width: 6px; }
183                .hamdard-chat-messages::-webkit-scrollbar-track { background: transparent; }
184                .hamdard-chat-messages::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
185                .hamdard-chat-messages::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
186
187                /* Message Bubbles */
188                .hamdard-message { margin-bottom: 20px; display: flex; align-items: flex-end; gap: 10px; opacity: 0; animation: msgFadeIn 0.3s ease-out forwards; }
189                @keyframes msgFadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
190                .hamdard-message.user { flex-direction: row-reverse; }
191                
192                .hamdard-message-avatar { 
193                    width: 32px; height: 32px; border-radius: 50%; 
194                    display: flex; align-items: center; justify-content: center; flex-shrink: 0; 
195                }
196                .hamdard-message.bot .hamdard-message-avatar { 
197                    background: white; color: ${CHATBOT_CONFIG.primaryColor}; 
198                    box-shadow: 0 4px 10px rgba(0,0,0,0.08); 
199                    border: 1px solid rgba(0,0,0,0.04);
200                }
201                .hamdard-message.user .hamdard-message-avatar { display: none; }
202                
203                .hamdard-message-content { 
204                    max-width: 85%; padding: 14px 18px; font-size: 14.5px; 
205                    line-height: 1.6; word-wrap: break-word; letter-spacing: 0.1px; 
206                }
207                
208                /* Advanced Message Tails and Shadows */
209                .hamdard-message.bot .hamdard-message-content { 
210                    background: white; color: #334155; 
211                    border-radius: 20px 20px 20px 4px; border: 1px solid rgba(0,0,0,0.04);
212                    box-shadow: 0 4px 15px rgba(0,0,0,0.04); 
213                }
214                .hamdard-message.user .hamdard-message-content { 
215                    background: linear-gradient(135deg, ${CHATBOT_CONFIG.primaryColor}, ${CHATBOT_CONFIG.secondaryColor}); 
216                    color: white; border-radius: 20px 20px 4px 20px; 
217                    box-shadow: 0 4px 15px rgba(5, 150, 105, 0.25); 
218                }
219                
220                .hamdard-message-time { font-size: 11px; opacity: 0.6; margin-top: 8px; text-align: right; font-weight: 500;}
221                .hamdard-message.user .hamdard-message-time { color: rgba(255,255,255,0.9); }
222
223                /* Quick Replies */
224                .hamdard-quick-replies { 
225                    padding: 12px 20px; background: white; 
226                    border-top: 1px solid rgba(0,0,0,0.05); display: flex; flex-wrap: wrap; gap: 8px; 
227                }
228                .hamdard-quick-reply { 
229                    background: white; color: ${CHATBOT_CONFIG.primaryColor}; border: 1px solid #a7f3d0; 
230                    padding: 8px 14px; border-radius: 20px; font-size: 13px; font-weight: 600; 
231                    cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
232                    box-shadow: 0 2px 4px rgba(5, 150, 105, 0.05);
233                    font-family: inherit;
234                }
235                .hamdard-quick-reply:hover { 
236                    background: #ecfdf5; transform: translateY(-2px); 
237                    box-shadow: 0 4px 10px rgba(5, 150, 105, 0.15);
238                }
239
240                /* Input Area */
241                .hamdard-chat-input { 
242                    padding: 16px 20px; background: white; 
243                    border-top: 1px solid rgba(0,0,0,0.05); display: flex; gap: 10px; align-items: center; 
244                }
245                .hamdard-chat-input input { 
246                    flex: 1; border: 1px solid #e2e8f0; border-radius: 24px; 
247                    padding: 14px 20px; font-size: 15px; outline: none; 
248                    transition: all 0.3s ease; background: #f8fafc; color: #1e293b;
249                    font-family: inherit;
250                }
251                .hamdard-chat-input input:focus { 
252                    background: white; border-color: ${CHATBOT_CONFIG.primaryColor}; 
253                    box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.15); 
254                }
255                .hamdard-chat-input input::placeholder { color: #94a3b8; }
256                
257                .hamdard-chat-input button { 
258                    background: ${CHATBOT_CONFIG.primaryColor}; color: white; 
259                    border: none; border-radius: 50%; width: 48px; height: 48px; 
260                    display: flex; align-items: center; justify-content: center; 
261                    cursor: pointer; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
262                    box-shadow: 0 4px 12px rgba(5, 150, 105, 0.25);
263                }
264                .hamdard-chat-input button:hover:not(:disabled) { 
265                    background: ${CHATBOT_CONFIG.secondaryColor}; transform: scale(1.1); 
266                    box-shadow: 0 6px 16px rgba(5, 150, 105, 0.35);
267                }
268                .hamdard-chat-input button:disabled { 
269                    background: #cbd5e1;
269 cursor: not-allowed; box-shadow: none; transform: none; 
270                }
271                
272                /* Typing Indicator */
273                .hamdard-typing { display: flex; gap: 6px; padding: 6px 4px; }
274                .hamdard-typing-dot { 
275                    width: 8px; height: 8px; background: #94a3b8; border-radius: 50%; 
276                    animation: bounce 1.4s infinite ease-in-out both; 
277                }
278                .hamdard-typing-dot:nth-child(1) { animation-delay: -0.32s; }
279                .hamdard-typing-dot:nth-child(2) { animation-delay: -0.16s; }
280                @keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
281                
282                /* Form Inputs Focus */
283                .hamdard-lead-input:focus { border-color: ${CHATBOT_CONFIG.primaryColor} !important; box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.15) !important; }
284                .hamdard-lead-submit:hover:not(:disabled) { background: ${CHATBOT_CONFIG.secondaryColor} !important; transform: translateY(-1px); }
285                .hamdard-lead-submit:active:not(:disabled) { transform: translateY(1px); }
286
287                /* Markdown Content Styles */
288                .hamdard-markdown-content { font-size: 14.5px; line-height: 1.6; color: inherit; }
289                .hamdard-markdown-content h4, .hamdard-markdown-content h3, .hamdard-markdown-content h2 { background: #f0fdf4; color: #047857; padding: 10px 14px; border-radius: 8px; border-left: 4px solid #059669; font-size: 15px; margin: 16px 0 8px 0; font-weight: 700; }
290                .hamdard-markdown-content p { margin: 0 0 10px 0; }
291                .hamdard-markdown-content strong { color: #0f172a; font-weight: 700; }
292                .hamdard-markdown-content a { color: #059669; text-decoration: underline; font-weight: 600; }
293                .hamdard-markdown-content ul, .hamdard-markdown-content ol { margin: 0 0 12px 0; padding-left: 24px; }
294                .hamdard-markdown-content li { margin-bottom: 6px; }
295                .hamdard-markdown-content li::marker { color: #059669; font-weight: 700; }
296                .hamdard-markdown-content table { width: 100%; border-collapse: collapse; margin-bottom: 10px; font-size: 13px; }
297                .hamdard-markdown-content th, .hamdard-markdown-content td { padding: 8px; border: 1px solid rgba(0,0,0,0.1); text-align: left; }
298                .hamdard-markdown-content th { background: rgba(5,150,105,0.05); color: #059669; font-weight: 600; }
299                
300                /* Mobile Responsiveness */
301                @media (max-width: 480px) { 
302                    .hamdard-chat-window { 
303                        position: fixed; bottom: 0; right: 0; width: 100vw; height: 100vh; max-height: 100vh;
304                        border-radius: 0; z-index: 9999999; animation: slideUp 0.3s forwards;
305                    } 
306                    .hamdard-chat-header { border-radius: 0; }
307                    @keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
308                }
309                </style>
310            `;
311            document.head.insertAdjacentHTML('beforeend', styles);
312        }
313
314        attachEventListeners() {
315            document.addEventListener('click', (e) => {
316                const chatBtn = e.target.closest('#hamdard-chat-button');
317                if (chatBtn) this.toggleChat();
318
319                const closeBtn = e.target.closest('#hamdard-chat-close');
320                if (closeBtn) this.closeChat();
321
322                const sendBtn = e.target.closest('#hamdard-send-button');
323                if (sendBtn && !this.isTyping) this.sendMessage();
324                
325                const quickReplyBtn = e.target.closest('.hamdard-quick-reply');
326                if (quickReplyBtn && !this.isTyping) this.sendMessage(quickReplyBtn.getAttribute('data-val'));
327
328                // Handle Form Submissions within Chat
329                const leadSubmitBtn = e.target.closest('.hamdard-lead-submit');
330                if (leadSubmitBtn && !this.isTyping) {
331                    const msgId = leadSubmitBtn.getAttribute('data-msgid');
332                    const nameInput = document.getElementById(`lead-name-${msgId}`);
333                    const phoneInput = document.getElementById(`lead-phone-${msgId}`);
334                    const programInput = document.getElementById(`lead-program-${msgId}`);
335                    
336                    if (nameInput && phoneInput) {
337                        const name = nameInput.value.trim();
338                        const phone = phoneInput.value.trim();
339                        const program = programInput ? programInput.value.trim() : '';
340                        
341                        if (!name || !phone) {
342                            if (!name) { nameInput.style.borderColor = '#ef4444'; nameInput.style.backgroundColor = '#fef2f2'; }
343                            if (!phone) { phoneInput.style.borderColor = '#ef4444'; phoneInput.style.backgroundColor = '#fef2f2'; }
344                            setTimeout(() => {
345                                if (nameInput) { nameInput.style.borderColor = '#cbd5e1'; nameInput.style.backgroundColor = 'white'; }
346                                if (phoneInput) { phoneInput.style.borderColor = '#cbd5e1'; phoneInput.style.backgroundColor = 'white'; }
347                            }, 2000);
348                            return;
349                        }
350                        
351                        let text = `My name is ${name}, my WhatsApp number is ${phone}.`;
352                        if (program) text += ` I am interested in ${program}.`;
353                        
354                        nameInput.disabled = true;
355                        phoneInput.disabled = true;
356                        if(programInput) programInput.disabled = true;
357                        leadSubmitBtn.innerHTML = 'Submitted ✔️';
358                        leadSubmitBtn.style.background = '#10b981';
359                        leadSubmitBtn.style.boxShadow = 'none';
360                        leadSubmitBtn.disabled = true;
361                        
362                        this.sendMessage(text);
363                    }
364                }
365            });
366            
367            document.addEventListener('keypress', (e) => {
368                const inputElement = e.target.closest('#hamdard-message-input');
369                if (e.key === 'Enter' && inputElement && !this.isTyping) {
370                    e.preventDefault();
371                    this.sendMessage();
372                }
373            });
374
375            this.renderQuickReplies();
376        }
377
378        toggleChat() {
379            const chatWindow = document.getElementById('hamdard-chat-window');
380            if (this.isOpen) {
381                this.closeChat();
382            } else {
383                chatWindow.classList.add('open');
384                this.isOpen = true;
385                this.scrollToBottom();
386            }
387        }
388
389        closeChat() {
390            const chatWindow = document.getElementById('hamdard-chat-window');
391            chatWindow.classList.remove('open');
392            this.isOpen = false;
393        }
394
395        addWelcomeMessage() {
396            this.addMessage(
397                "السلام علیکم! Welcome to Hamdard University!\n\nI'm your Premium AI Assistant here to help you with:\n- Admission Process / داخلے کا طریقہ\n- Fee Structure / فیس کی تفصیلات\n- Courses & Programs / کورسز\n- Scholarships / وظائف\n- Contact Information / رابطے کی معلومات\n\nHow can I assist you today? آپ کو کیا جاننا ہے؟",
398                true
399            );
400        }
401
402        async sendMessage(messageText) {
403            const input = document.getElementById('hamdard-message-input');
404            const text = messageText || input.value.trim();
405            
406            if (!text || this.isTyping) return;
407
408            this.addMessage(text, false);
409            input.value = '';
410            this.showTyping();
411
412            try {
413                if (typeof window.hamdard_ajax === 'undefined') throw new Error("WP AJAX config not found");
414
415                const formData = new FormData();
416                formData.append('action', 'hamdard_chatbot_message');
417                formData.append('nonce', window.hamdard_ajax.nonce);
418                formData.append('message', text);
419
420                const response = await fetch(window.hamdard_ajax.ajax_url, { method: 'POST', body: formData });
421                const result = await response.json();
422                
423                this.hideTyping();
424                
425                if (result.success && result.data) {
426                    this.addMessage(result.data.content || "I have received your query.", true);
427                    if (result.data.suggestions) this.renderQuickRepliesArray(result.data.suggestions);
428                } else {
429                    this.addMessage("Sorry, the chat system encountered an issue connecting to our servers.", true);
430                }
431            } catch (error) {
432                console.error("Chatbot Plugin Fetch Error:", error);
433                this.hideTyping();
434                this.addMessage("Sorry, I could not reach our core automation servers right now. Please try again later.", true);
435            }
436        }
437
438        addMessage(content, isBot) {
439            const messagesContainer = document.getElementById('hamdard-chat-messages');
440            if (!messagesContainer) return;
441
442            const messageId = Date.now();
443            const messageHTML = `
444                <div class="hamdard-message ${isBot ? 'bot' : 'user'}" id="message-${messageId}">
445                    <div class="hamdard-message-avatar">
446                        ${isBot ? '<svg width="16" height="16" viewB
446ox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2L13.09 8.26L20 9L13.09 9.74L12 16L10.91 9.74L4 9L10.91 8.26L12 2Z" fill="currentColor"/></svg>' : ''}
447                    </div>
448                    <div class="hamdard-message-content">
449                        ${isBot ? this.formatMessage(content, messageId) : content}
450                        <div class="hamdard-message-time">${new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div>
451                    </div>
452                </div>
453            `;
454            messagesContainer.insertAdjacentHTML('beforeend', messageHTML);
455            
456            // SMART SCROLLING ALGORITHM 
457            this.scrollToMessage(messageId, isBot);
458        }
459
460        scrollToMessage(messageId, isBot) {
461            const messagesContainer = document.getElementById('hamdard-chat-messages');
462            const newMessage = document.getElementById(`message-${messageId}`);
463            if (!messagesContainer || !newMessage) return;
464
465            // Give the browser a tiny rendering tick to compute the actual DOM height of the new message
466            setTimeout(() => {
467                if (isBot) {
468                    // Check if the message is tall (more than 40% of the screen)
469                    const isTallMessage = newMessage.clientHeight > messagesContainer.clientHeight * 0.4;
470                    if (isTallMessage) {
471                        // Scroll to the top of the NEW message, with a slight 15px top-margin padding 
472                        messagesContainer.scrollTo({
473                            top: newMessage.offsetTop - 15,
474                            behavior: 'smooth'
475                        });
476                        return;
477                    }
478                }
479                // Fallback: scroll to bottom
480                messagesContainer.scrollTo({
481                    top: messagesContainer.scrollHeight,
482                    behavior: 'smooth'
483                });
484            }, 10);
485        }
486
487        scrollToBottom() {
488            const messagesContainer = document.getElementById('hamdard-chat-messages');
489            if (messagesContainer) {
490                messagesContainer.scrollTo({ top: messagesContainer.scrollHeight, behavior: 'smooth' });
491            }
492        }
493
494        formatMessage(content, messageId) {
495            if (!content) return '';
496            let html = content.replace(/\r\n/g, '\n');
497
498            // 1. LEAD CAPTURE DETECTION
499            const textLower = html.toLowerCase();
500            const isLeadRequest = (textLower.includes("whatsapp") && (textLower.includes("naam") || textLower.includes("name")));
501
502            // Remove JSON blocks
503            html = html.replace(/`{3}json([\s\S]*?)`{3}/g, '');
504
505            // Robust Markdown to HTML Converter
506            // Headings
507            html = html.replace(/^### (.*$)/gim, '<h4>$1</h4>');
508            html = html.replace(/^## (.*$)/gim, '<h3>$1</h3>');
509            html = html.replace(/^# (.*$)/gim, '<h2>$1</h2>');
510            
511            // Bold & Italic
512            html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
513            html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
514            
515            // Links
516            html = html.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" target="_blank">$1</a>');
517            html = html.replace(/(https?:\/\/[^\s\)]+)/g, '<a href="$1" target="_blank">$1</a>'); 
518
519            // Lists
520            html = html.replace(/^(\d+)\.\s+(.*$)/gim, '<li class="num-list" data-num="$1">$2</li>');
521            html = html.replace(/^[-•*]\s+(.*$)/gim, '<li class="bullet-list">$1</li>');
522
523            html = html.replace(/(<li class="bullet-list">.*<\/li>\n?)+/g, match => `<ul>\n${match}</ul>\n`);
524            html = html.replace(/(<li class="num-list".*<\/li>\n?)+/g, match => `<ol>\n${match}</ol>\n`);
525
526            // Line Breaks handling
527            html = html.split('\n').map(line => {
528                if(line.trim() === '') return '';
529                if(line.startsWith('<ul') || line.startsWith('</ul') || line.startsWith('<ol') || line.startsWith('</ol') || line.startsWith('<li') || line.startsWith('<h') || line.startsWith('<table')) return line;
530                return `<p>${line}</p>`;
531            }).filter(line => line !== '').join('');
532
533            // Wrap in styling container
534            html = `<div class="hamdard-markdown-content">${html}</div>`;
535
536            // 2. APPLY LEAD CAPTURE CARD FORMATTING IF DETECTED
537            if (isLeadRequest) {
538                html = `
539                <div style="background: linear-gradient(135deg, #ffffff 0%, #f0fdf4 100%); border: 1px solid #10b981; border-radius: 16px; padding: 18px; margin: 12px 0; box-shadow: 0 6px 16px rgba(16,185,129,0.12); position: relative; overflow: hidden;">
540                    <div style="position: absolute; right: -15px; top: -15px; font-size: 80px; opacity: 0.04;">📋</div>
541                    <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 14px; position: relative; z-index: 1;">
542                        <div style="background: #059669; color: white; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 16px; box-shadow: 0 4px 10px rgba(5,150,105,0.3);">📋</div>
543                        <strong style="color: #065f46; font-size: 16px; font-weight: 700; letter-spacing: 0.2px;">Action Required</strong>
544                    </div>
545                    <div style="color: #334155; font-size: 15px; line-height: 1.6; margin-bottom: 16px; position: relative; z-index: 1;">
546                        ${html}
547                    </div>
548                    <div class="hamdard-lead-form" style="margin-top: 16px; display: flex; flex-direction: column; gap: 10px; position: relative; z-index: 1;">
549                        <input type="text" class="hamdard-lead-input" id="lead-name-${messageId}" placeholder="Full Name *" style="width: 100%; padding: 12px 14px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.2s, box-shadow 0.2s;" required />
550                        <input type="tel" class="hamdard-lead-input" id="lead-phone-${messageId}" placeholder="WhatsApp Number *" style="width: 100%; padding: 12px 14px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.2s, box-shadow 0.2s;" required />
551                        <input type="text" class="hamdard-lead-input" id="lead-program-${messageId}" placeholder="Interested Program (Optional)" style="width: 100%; padding: 12px 14px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.2s, box-shadow 0.2s;" />
552                        <button class="hamdard-lead-submit" data-msgid="${messageId}" style="width: 100%; padding: 12px; margin-top: 4px; background: #059669; color: white; border: none; border-radius: 8px; font-size: 14.5px; font-weight: 600; cursor: pointer; transition: background 0.2s, transform 0.1s; display: flex; justify-content: center; align-items: center; gap: 8px; font-family: inherit; box-shadow: 0 4px 10px rgba(5,150,105,0.2);">
553                            Submit Details
554                            <svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
555                        </button>
556                    </div>
557                </div>`;
558            }
559
560            return html;
561        }
562
563        showTyping() {
564            this.isTyping = true;
565            document.getElementById('hamdard-send-button').disabled = true;
566            document.getElementById('hamdard-message-input').disabled = true;
567
568            const messagesContainer = document.getElementById('hamdard-chat-messages');
569            const typingHTML = `
570                <div id="hamdard-typing-indicator" class="hamdard-message bot">
571                    <div class="hamdard-message-avatar"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2L13.09 8.26L20 9L13.09 9.74L12 16L10.91 9.74L4 9L10.91 8.26L12 2Z" fill="currentColor"/></svg></div>
572                    <div class="hamdard-message-content" style="padding: 14px 20px;">
573                        <div class="hamdard-typing"><div class="hamdard-typing-dot"></div><div class="hamdard-typing-dot"></div><div class="hamdard-typing-dot"></div></div>
574                    </div>
575                </div>
576            `;
577            messagesContainer.insertAdjacentHTML('beforeend', typingHTML);
578            this.scrollToBottom();
579        }
580
581        hideTyping() {
582            this.isTyping = false;
583            document.getElementById('hamdard-send-button').disabled = false;
584            document.getElementById('hamdard-message-input').disabled = false;
585            document.getElementById('hamdard-message-input').focus();
586            
587            const typingIndicator = document.getElementById('hamdard-typing-indicator');
588            if (typingIndicator) typingIndicator.remove();
589        }
590
591        renderQuickReplies() {
592            this.renderQuickRepliesArray(QUICK_REPLIES);
593        }
594
595        renderQuickRepliesArray(repliesArray) {
596            const quickRepliesContainer = document.getElementById('hamdard-quick-replies');
597            if (!quickRepliesContainer) return;
598
599            if (!repliesArray || repliesArray.length === 0) {
600                quickRepliesContainer.innerHTML = '';
601                return;
602            }
603            
604            const repliesHTML = repliesArray.slice(0, 3).map(reply => 
605                `<button class="hamdard-quick-reply" data-val="${reply.split(' / ')[0]}">${reply.split(' / ')[0]}</button>`
606            ).join('');
607            
608            quickRepliesContainer.innerHTML = repliesHTML;
609        }
610    }
611
612    if (document.readyState === 'loading') {
613        document.addEventListener('DOMContentLoaded', () => window.hamdardChatbot = new WordPressChatbot());
614    } else {
615        window.hamdardChatbot = new WordPressChatbot();
616    }
617})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.