PageSourceSearch

https://statelife.com.pk/chatbot/public/chatbot/widget.js?v=20261001175917

js statelife.com.pk collected 2026-10-01 12:59:38 UTC 104,487 bytes, 1,696 lines download raw bytes

1(function() {
2    const scriptSrc = (document.currentScript && document.currentScript.src) || window.CHATBOT_ASSET_BASE || '';
3    let APP_BASE = '';
4    let ASSET_BASE = '';
5    try {
6        if (window.CHATBOT_ASSET_BASE) {
7             const provided = String(window.CHATBOT_ASSET_BASE || '').replace(/\/+$/, '');
8             APP_BASE = provided;
9             ASSET_BASE = provided.endsWith('/chatbot') ? provided : (provided + '/chatbot');
10        } else if (scriptSrc) {
11             ASSET_BASE = new URL('.', scriptSrc).href;
12             APP_BASE = new URL('..', ASSET_BASE).href;
13        }
14    } catch (e) { }
15    
16    // Ensure no trailing slash for consistent appending
17    APP_BASE = APP_BASE.replace(/\/+$/, '');
18    ASSET_BASE = ASSET_BASE.replace(/\/+$/, '');
19
20    if (!APP_BASE) {
21        APP_BASE = window.location.origin.replace(/\/+$/, '');
22    }
23    if (!ASSET_BASE) {
24        ASSET_BASE = APP_BASE + '/chatbot';
25    }
26
27    const STATIC_REPLIES = {};
28    const JSON_INTENTS = [];
29
30    function registerJsonEntries(data) {
31        if (!data) return;
32        const entries = Array.isArray(data.entries)
33            ? data.entries
34            : Array.isArray(data.recommendations)
35            ? data.recommendations
36            : Array.isArray(data.plans_recommendations)
37            ? data.plans_recommendations
38            : Array.isArray(data.careersAndRecruitment)
39            ? data.careersAndRecruitment
40            : null;
41        if (!entries) return;
42        for (const entry of entries) {
43            const id = entry.id;
44            const patterns = (entry.patterns || []).map((p) => {
45                try {
46                    return new RegExp(p, 'i');
47                } catch (e) {
48                    return null;
49                }
50            }).filter(Boolean);
51
52            let responses = Array.isArray(entry.responses) ? entry.responses : [];
53            if (!responses.length && entry) {
54                const parts = [];
55                if (entry.question) {
56                    parts.push("Q: " + entry.question);
57                }
58                if (entry.myth) {
59                    parts.push(entry.myth);
60                }
61                if (entry.reality) {
62                    parts.push(entry.reality);
63                }
64                if (entry.shortAnswer) {
65                    parts.push(entry.shortAnswer);
66                }
67                if (entry.detailedAnswer) {
68                    parts.push(entry.detailedAnswer);
69                }
70                if (entry.explanation) {
71                    parts.push(entry.explanation);
72                }
73                const text = parts.join("\n\n");
74                if (text) {
75                    responses = [{ text: text, weight: 100 }];
76                }
77            }
78
79            JSON_INTENTS.push({
80                id,
81                intent: entry.intent || null,
82                priority: entry.priority || 'medium',
83                patterns,
84                responses,
85                fallbackToAPI: !!entry.fallbackToAPI
86            });
87            if (id && responses.length) {
88                STATIC_REPLIES[id] = responses.map(r => r.text);
89            }
90        }
91    }
92
93    (async function loadStaticReplies() {
94        const paths = [
95            'static_replies/greetings.json',
96            'static_replies/company-info.json',
97            'static_replies/premium-payment.json',
98            'static_replies/whole-life.json',
99            'static_replies/policies.json',
100            'static_replies/faqs-comprehensive.json',
101            'static_replies/faq_multiple_policies.json',
102            'static_replies/common-insurnace-question.json',
103            'static_replies/recommendations.json',
104            'static_replies/Careers.json'
105        ];
106        for (const path of paths) {
107            try {
108                const res = await fetch(`${ASSET_BASE}/${path}`);
109                if (!res.ok) continue;
110                const data = await res.json();
111                registerJsonEntries(data);
112            } catch (e) { }
113        }
114    })();
115
116    // ========================================
117    // BASIC QUERIES CAROUSEL
118    // ========================================
119    const BASIC_QUERIES = [
120        { label: "About State Life", query: "Tell me about State Life" },
121        { label: "Why Choose Us?", query: "Why choose State Life?" },
122        { label: "Govt Guarantee", query: "What is the government guarantee?" },
123        { label: "Product Plans", query: "What insurance plans do you offer?" },
124        { label: "How to Buy", query: "How to buy insurance?" },
125        { label: "File a Claim", query: "How do I file a claim?" },
126        { label: "Pay Premium", query: "How can I pay my premium?" },
127        { label: "Contact Support", query: "How can I contact support?" }
128    ];
129
130    function renderBasicQueriesCarousel() {
131        const carouselContainer = document.createElement('div');
132        carouselContainer.className = 'chatbot-carousel';
133        
134        const carouselContent = document.createElement('div');
135        carouselContent.className = 'carousel-track';
136        
137        // Helper to create buttons
138        const createBtn = (item) => {
139            const button = document.createElement('button');
140            button.className = 'carousel-item';
141            button.textContent = item.label;
142            button.onclick = () => {
143                const textarea = document.getElementById('chatbot-textarea');
144                const sendBtn = document.getElementById('chatbot-send-btn');
145                if (textarea && sendBtn) {
146                    textarea.value = item.query;
147                    sendBtn.click();
148                }
149            };
150            return button;
151        };
152
153        // Add original items
154        BASIC_QUERIES.forEach(item => {
155            carouselContent.appendChild(createBtn(item));
156        });
157
158        // Add duplicate items for seamless scrolling
159        BASIC_QUERIES.forEach(item => {
160            carouselContent.appendChild(createBtn(item));
161        });
162        
163        carouselContainer.appendChild(carouselContent);
164        return carouselContainer;
165    }
166
167    let toggler = document.getElementById('chatbot-toggler');
168
169    if (!toggler) {
170        const html = `
171        <button id="chatbot-toggler">
172            <img src="${APP_BASE}/image/bot-icon.png" alt="Chat" style="width: 100%; height: 100%; object-fit: contain;">
173        </button>
174        <div class="chatbot-container">
175            <div class="chatbot-header">
176                <div class="header-content">
177                    <div class="avatar-container">
178                        <img src="${APP_BASE}/image/slic-main.png" alt="Bot Avatar" class="bot-avatar">
179                        <span class="online-status"></span>
180                    </div>
181                    <div class="header-info">
182                        <h4 style='font-size: 15px; font-weight: 700;'>State Life Insurance Corporation of Pakistan</h4>
183                        <p style='font-size: 12px; font-weight: 400;' >We’re online—available 24/7 to assist you.</p>
184                    </div>
185                    <div class="header-controls">
186                        <!-- <button class="header-btn">⋮</button> -->
187                        <button class="chatbot-close-btn" aria-label="Close chat">
188                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
189                                <polyline points="6 9 12 15 18 9"></polyline>
190                            </svg>
191                        </button>
192                    </div>
193                </div>
194                <div class="header-wave">
195                    <svg viewBox="0 0 1440 320" preserveAspectRatio="none">
196                        <path fill="#e7f0fa" fill-opacity="1" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,112C672,96,768,96,864,112C960,128,1056,160,1152,160C1248,160,1344,128,1392,112L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path>
197                    </svg>
198                </div>
199            </div>
200            <div class="chatbot-body" id="chatbot-body">
201                <div class="chat-message bot">
202                    <div class="message-content">Welcome to State Life Insurance’s chatbot! I’m your digital assistant, here to make insurance simple and accessible. How may I assist you today?</div>
203                    <div class="message-time">Just now</div>
204                </div>
205            </div>
206            <div class="chatbot-rating" id="chatbot-rating" style="display: none;">
207                <div class="rating-label">How was your experience?</div>
208                <div class="rating-emojis">
209                    <button class="rating-emoji" data-rating="1" aria-label="Very bad">😡</button>
210                    <button class="rating-emoji" data-rating="2" aria-label="Bad">😕</button>
211                    <button class="rating-emoji" data-rating="3" aria-label="Okay">😐</button>
212                    <button class="rating-emoji" data-rating="4" aria-label="Good">🙂</button>
213                    <button class="rating-emoji" data-rating="5" aria-label="Excellent">🤩</button>
214                </div>
215                <div class="rating-caption" id="chatbot-rating-caption">Tap an emoji to rate your chat</div>
216            </div>
217            <div class="chatbot-input">
218                <textarea id="chatbot-textarea" placeholder="Type a message..."></textarea>
219                <button id="chatbot-send-btn">
220                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
220<line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
221                </button>
222            </div>
223            <div class="chatbot-disclaimer">
224                AI Chatbot can make mistakes. Please double-check responses.
225            </div>
226        </div>
227    `;
228        
229        const wrapper = document.createElement('div');
230        wrapper.innerHTML = html;
231        document.body.appendChild(wrapper);
232
233        toggler = document.getElementById('chatbot-toggler');
234    }
235
236    const chatContainer = document.querySelector('.chatbot-container');
237    const closeBtn = document.querySelector('.chatbot-close-btn');
238    const chatBody = document.getElementById('chatbot-body');
239    const ratingBar = document.getElementById('chatbot-rating');
240
241    // Append carousel if not already present
242    if (chatBody && !document.querySelector('.chatbot-carousel')) {
243        const carousel = renderBasicQueriesCarousel();
244        // Insert after chatBody, before ratingBar
245        if (ratingBar) {
246            ratingBar.parentNode.insertBefore(carousel, ratingBar);
247        } else {
248            chatBody.parentNode.appendChild(carousel);
249        }
250    }
251
252    const textarea = document.getElementById('chatbot-textarea');
253    const sendBtn = document.getElementById('chatbot-send-btn');
254    const ratingCaption = document.getElementById('chatbot-rating-caption');
255    const ratingButtons = ratingBar ? Array.from(ratingBar.querySelectorAll('.rating-emoji')) : [];
256    let userMessageCount = 0;
257    let greetingCount = 0;
258    let lastGreetingResponse = null;
259
260    const MIN_TYPING_MS = 700;
261    const DELAY_JITTER_MS = 600;
262    function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
263    function randomDelay() { return MIN_TYPING_MS + Math.floor(Math.random() * DELAY_JITTER_MS); }
264
265    function uniqueStrings(arr) {
266        const out = [];
267        const seen = new Set();
268        for (const v of arr) {
269            const s = String(v || '').trim();
270            if (!s) continue;
271            if (seen.has(s)) continue;
272            seen.add(s);
273            out.push(s);
274        }
275        return out;
276    }
277
278    function pickOne(arr) {
279        return arr[Math.floor(Math.random() * arr.length)];
280    }
281
282    function getApiUrlCandidates() {
283        const candidates = [];
284        try { candidates.push(new URL('api/chatbot', window.location.href).href); } catch (e) { }
285        if (APP_BASE) candidates.push(`${APP_BASE}/api/chatbot`);
286        if (APP_BASE && /\/public$/i.test(APP_BASE)) candidates.push(`${APP_BASE.replace(/\/public$/i, '')}/api/chatbot`);
287        if (ASSET_BASE) {
288            try { candidates.push(new URL('../api/chatbot', ASSET_BASE + '/').href); } catch (e) { }
289            if (/\/public\/chatbot$/i.test(ASSET_BASE)) candidates.push(ASSET_BASE.replace(/\/public\/chatbot$/i, '/api/chatbot'));
290        }
291        candidates.push('/api/chatbot');
292        return uniqueStrings(candidates);
293    }
294
295    async function parseJsonOrText(response) {
296        const contentType = (response.headers.get('content-type') || '').toLowerCase();
297        const raw = await response.text();
298        if (contentType.includes('application/json')) {
299            try { return JSON.parse(raw); } catch (e) { }
300        }
301        try { return JSON.parse(raw); } catch (e) { }
302        return { answer: raw, source: 'system', context: [] };
303    }
304
305    function isRouteNotFoundPayload(payload) {
306        const msg = typeof payload === 'string'
307            ? payload
308            : (payload && typeof payload === 'object' && typeof payload.message === 'string')
309            ? payload.message
310            : (payload && typeof payload === 'object' && typeof payload.answer === 'string')
311            ? payload.answer
312            : '';
313        return /the route .* could not be found/i.test(msg) || /could not be found/i.test(msg);
314    }
315
316    function buildSmartRouteFallback() {
317        const starters = [
318            "I didn’t reach the server route from here. Ask your question directly and I’ll answer.",
319            "Looks like I can’t connect to the chat endpoint right now. Tell me what you need and I’ll guide you.",
320            "I’m having trouble reaching the chatbot service. Please ask your question clearly and I’ll help."
321        ];
322
323        const examples = [
324            "How can I pay my premium?",
325            "How do I file a claim?",
326            "How do I check my policy status?",
327            "How can I check bonus statement?",
328            "Which plan is best for me?",
329            "What is the grace period?"
330        ];
331
332        const sample = uniqueStrings([
333            pickOne(examples),
334            pickOne(examples),
335            pickOne(examples),
336            pickOne(examples)
337        ]).slice(0, 4);
338
339        const first = `${pickOne(starters)}\n\nTry one of these:\n• ${sample.join('\n• ')}`;
340
341        const supportVariants = [
342            [
343                "Official support options:",
344                "• Helpline: 051-111-777-542",
345                "• Support page: https://statelife.com.pk/en/support",
346                "• Email: [email protected]",
347                "• Nearest office: https://statelife.com.pk/en/page/contacts-us"
348            ],
349            [
350                "Need a human agent?",
351                "• Call: 051-111-777-542",
352                "• Support: https://statelife.com.pk/en/support",
353                "• Email: [email protected]",
354                "• Offices: https://statelife.com.pk/en/page/contacts-us"
355            ],
356            [
357                "You can also reach State Life here:",
358                "• 051-111-777-542",
359                "• https://statelife.com.pk/en/support",
360                "• [email protected]",
361                "• https://statelife.com.pk/en/page/contacts-us"
362            ]
363        ];
364
365        const second = pickOne(supportVariants).join('\n');
366        return [first, second];
367    }
368
369    function detectApiIssueType(status, payload) {
370        const s = typeof status === 'number' ? status : null;
371        if (s === 401 || s === 403) return 'auth';
372        if (s === 429) return 'rate';
373        if (s === 404 && isRouteNotFoundPayload(payload)) return 'route';
374        if (s && s >= 500) return 'server';
375        if (s === 0 || s === null) return 'network';
376
377        const text = typeof payload === 'string'
378            ? payload
379            : (payload && typeof payload === 'object' && (payload.answer || payload.message || payload.error))
380            ? String(payload.answer || payload.message || payload.error)
381            : '';
382        const t = text.toLowerCase();
383        if (t.includes('invalid api key') || t.includes('unauthorized') || t.includes('forbidden')) return 'auth';
384        if (t.includes('rate limit') || t.includes('too many requests')) return 'rate';
385        if (t.includes('route') && t.includes('could not be found')) return 'route';
386        if (t.includes('server error') || t.includes('service unavailable')) return 'server';
387        return 'unknown';
388    }
389
390    function buildSmartApiFallback(issueType, userMessage) {
391        const msg = String(userMessage || '').toLowerCase();
392        const buckets = {
393            premium: ["How can I pay my premium?", "What is the grace period for premium payment?", "Where can I pay premium online?"],
394            claim: ["How do I file a claim?", "What documents are required for a claim?", "How long does a claim take?"],
395            policy: ["How do I check my policy status?", "How can I check my bonus statement?", "How can I update nominee/beneficiary?"],
396            plan: ["Which plan is best for me?", "What insurance plans do you offer?", "What is Golden Endowment Plan?"],
397        };
398
399        let pool = [
400            "How can I pay my premium?",
401            "How do I file a claim?",
402            "How do I check my policy status?",
403            "How can I check my bonus statement?",
404            "Which plan is best for me?",
405            "What is the grace period for premium payment?",
406        ];
407
408        if (/(premium|pay|payment|epay|jazzcash|bank)/.test(msg)) pool = [...buckets.premium, ...pool];
409        else if (/(claim|death|maturity|documents|hospital)/.test(msg)) pool = [...buckets.claim, ...pool];
410        else if (/(policy|status|bonus|nominee|beneficiary|loan|lapse)/.test(msg)) pool = [...buckets.policy, ...pool];
411        else if (/(plan|recommend|best|buy|takaful|endowment|pension)/.test(msg)) pool = [...buckets.plan, ...pool];
412
413        const picked = uniqueStrings([
414            pickOne(pool),
415            pickOne(pool),
416            pickOne(pool),
417            pickOne(pool),
418        ]).slice(0, 4);
419
420        const intros = {
421            auth: [
422                "I can’t access the AI service right now. Please ask your question directly and I’ll guide you.",
423                "The answer service needs a quick refresh on the server side. Ask your question clearly and I’ll help.",
424                "I’m temporarily unable to fetch an AI answer. Tell me what you need and I’ll guide you."
425            ],
426            rate: [
427                "We’re getting a lot of questions at once. Ask your question directly and I’ll try to help while things cool down.",
428                "I’m a bit busy right now due to high traffic. Ask your question clearly and I’ll guide you.",
429                "Too many requests at the moment. Ask your question directly and I’ll help with the best available info."
430            ],
431            server: [
432                "Something went wrong on the server while answering. Ask your question again and I’ll guide you.",
433                "I hit a temporary issue while generating the answer. Ask your question directly and I’ll help.",
434                "The service is temporarily unavailable. Tell me what you need and I’ll guide you."
435            ],
436            network: [
437                "I can’t reach the server right now. Ask your question directly and I’ll guide you.",
438                "Looks like there’s a connection issue. Tell me what you need and I’ll help.",
439                "I’m having trouble connecting. Ask your question clearly and I’ll help."
440            ],
441            route: [
442                "I didn’t reach the server route from here. Ask your question directly and I’ll answer.",
443                "Looks like I can’t connect to the chat endpoint right now. Tell me what you need and I’ll guide you.",
444                "I’m having trouble reaching the chatbot service. Please ask your question clearly and I’ll help."
445            ],
446            unknown: [
447                "I couldn’t fetch an answer right now. Ask your question directly and I’ll guide you.",
448                "I’m having a temporary issue answering. Tell me what you need and I’ll help.",
449                "Something interrupted my response. Ask your question clearly and I’ll help."
450            ]
451        };
452
453        const first = `${pickOne(intros[issueType] || intros.unknown)}\n\nExamples:\n• ${picked.join('\n• ')}`;
454
455        const supportVariants = [
456            [
457                "If you prefer official support:",
458                "• Helpline: 051-111-777-542",
459                "• Website: https://statelife.com.pk/en/support",
460                "• Email: [email protected]",
461                "• Nearest office: https://statelife.com.pk/en/page/contacts-us"
462            ],
463            [
464                "Need a human agent?",
465                "• Call: 051-111-777-542",
466                "• Support: https://statelife.com.pk/en/support",
467                "• Email: [email protected]",
468                "• Offices: https://statelife.com.pk/en/page/contacts-us"
469            ]
470        ];
471
472        const second = pickOne(supportVariants).join('\n');
473        return [first, second];
474    }
475
476    function injectExampleButtons(escapedHtml, rawText) {
477        const trigger = /(^|\n)\s*(Examples:|Try one of these:)\s*(\n|$)/i;
478        if (!trigger.test(String(rawText || ''))) return escapedHtml;
479
480        const rawLines = String(rawText || '').split('\n');
481        const htmlLines = String(escapedHtml || '').split('\n');
482        const suggestions = [];
483
484        let inBlock = false;
485        let collected = false;
486        let insertAt = null;
487
488        for (let i = 0; i < rawLines.length && i < htmlLines.length; i++) {
489            const line = rawLines[i] || '';
490            const trimmed = line.trim();
491
492            if (!inBlock && /^(Examples:|Try one of these:)\s*$/i.test(trimmed)) {
493                inBlock = true;
494                collected = false;
495                continue;
496            }
497
498            if (!inBlock) continue;
499
500            if (trimmed === '') {
501                htmlLines[i] = '';
502                if (collected) {
503                    inBlock = false;
504                }
505                continue;
506            }
507
508            if (/^\s*•\s+/.test(line)) {
509                const suggestion = line.replace(/^\s*•\s+/, '').trim();
510                if (suggestion) {
511                    const label = (htmlLines[i] || '').replace(/^\s*•\s+/, '').trim();
512                    suggestions.push({ suggestion, label });
513                    htmlLines[i] = '';
514                    if (insertAt === null) {
515                        insertAt = i;
516                    }
517                    collected = true;
518                }
519                continue;
520            }
521
522            if (collected) {
523                inBlock = false;
524            }
525        }
526
527        if (!suggestions.length || insertAt === null) {
528            return htmlLines.join('\n');
529        }
530
531        htmlLines[insertAt] = '__SUGGEST_BLOCK__';
532
533        let out = htmlLines.join('\n');
534        out = out.replace('__SUGGEST_BLOCK__', () => {
535            const buttons = suggestions.map((item) => {
536                const encoded = encodeURIComponent(item.suggestion);
537                return `<button type="button" class="chat-suggestion" data-suggest="${encoded}"><span class="chat-suggestion-text">${item.label}</span><span class="chat-suggestion-icon">⤿</span></button>`;
538            }).join('');
539            return `<div class="chat-suggestions">${buttons}</div>`;
540        });
541
542        return out;
543    }
544
545    const ratingLabels = {
546        1: "We're sorry about this experience. We'll work to improve.",
547        2: "Thanks for the feedback. We'll try to do better.",
548        3: "Thanks! We'll keep improving.",
549        4: "Great! We're glad it was helpful.",
550        5: "Amazing! Thank you for the excellent rating."
551    };
552
553    function collapseRating() {
554        if (ratingBar) {
555            ratingBar.classList.add('collapsed');
556        }
557    }
558
559    function expandRating() {
560        if (ratingBar) {
561            ratingBar.classList.remove('collapsed');
562        }
563    }
564
565    function hasActiveRating() {
566        return ratingButtons.some(btn => btn.classList.contains('active'));
567    }
568
569    function updateRating(value) {
570        if (!ratingButtons.length) return;
571        ratingButtons.forEach(btn => {
572            const v = parseInt(btn.getAttribute('data-rating'), 10);
573            if (v <= value) {
574                btn.classList.add('active');
575            } else {
576                btn.classList.remove('active');
577            }
578        });
579        const label = ratingLabels[value] || "Thank you for your rating.";
580        if (ratingCaption) {
581            ratingCaption.textContent = label;
582        }
583        try {
584            localStorage.setItem('chatbot_last_rating', String(value));
585        } catch (e) {}
586        collapseRating();
587    }
588
589    if (ratingButtons.length) {
590        ratingButtons.forEach(btn => {
591            btn.addEventListener('click', () => {
592                const val = parseInt(btn.getAttribute('data-rating'), 10);
593                if (!isNaN(val)) {
594                    updateRating(val);
595                }
596            });
597        });
598        try {
599            const stored = parseInt(localStorage.getItem('chatbot_last_rating') || '', 10);
600            if (!isNaN(stored) && stored >= 1 && stored <= 5) {
601                updateRating(stored);
602            }
603        } catch (e) {}
604    }
605
606    if (ratingBar) {
607        const ratingLabelEl = ratingBar.querySelector('.rating-label');
608        const toggleTargets = [ratingLabelEl, ratingCaption].filter(Boolean);
609        toggleTargets.forEach(el => {
610            el.addEventListener('click', () => {
611                if (!hasActiveRating()) return;
612                if (ratingBar.classList.contains('collapsed')) {
613                    expandRating();
614                } else {
615                    collapseRating();
616                }
617            });
618        });
619    }
620
621    function maybeShowRatingBar() {
622        if (!ratingBar) return;
623        if (ratingBar.style.display !== 'none') return;
624        if (userMessageCount < 3) return;
625        ratingBar.style.display = 'flex';
626        collapseRating();
627    }
628
629// ========================================
630// ENHANCED STATIC KNOWLEDGE BASE
631// Covers 90%+ of common State Life queries
632// ========================================
633
634const STATIC_KNOWLEDGE = {
635
636  /* =============================================
637     SECTION 1: GREETINGS & CONVERSATIONAL
638     Coverage: Common pleasantries
639  ============================================= */
640  greetings: {
641  patterns: [
642    /^(hi|hello|hey|yo|sup|hiya|heya|howdy|hlo|hlw|greetings|aoa|Sallam)$/i,
643    /\b(assalam(\s*o\s*alaikum)?|salam|asalaam|assalamu\s*alaikum|peace\s*be\s*upon\s*you)\b/i,
644    /\b(good\s*(morning|afternoon|evening|night))\b/i,
645    /\b(hi\s*there|hello\s*there|hey\s*there)\b/i,
646    /\b(👋|🙌|🤝|✋|🤗)\b/i
647  ],
648  responses: [
649    "Hello! 👋 Welcome to State Life Insurance. I'm here to help you with:\n\n• Policy information\n• Premium payment\n• Claims process\n• Product recommendations\n• General inquiries\n\nWhat would you like to know today?",
650    "Assalam o Alaikum! 🌟 Welcome to State Life - Pakistan's most trusted insurer since 1972.\n\nHow may I assist you today?",
651    "Hi there! I can help you with State Life insurance queries. What brings you here today?"
652  ]
653},
654
655farewells: {
656  patterns: [
657    /^(bye|goodbye|see\s*you|see\s*ya|later|take\s*care|catch\s*you\s*later)$/i,
658    /\b(khuda\s*hafiz|allah\s*hafiz|fi\s*amanillah|ma\s*salama)\b/i,
659    /\b(farewell|until\s*next\s*time|talk\s*to\s*you\s*soon)\b/i,
660    /\b(cya|ttyl|gn|good\s*night)\b/i,
661    /\b(👋|🙏|😊|🙌)\b/i
662  ],
663  response: "Thank you for contacting State Life Insurance! 🙏\n\n📞 Need help? Call our helpline: 051-111-777-542\n🌐 Visit: www.statelife.com.pk\n\nTake care and have a great day! 😊"
664},
665
666thanks: {
667  patterns: [
668    /^(thanks|thank\s*you|thx|thanx|ty|thank\s*u)$/i,
669    /\b(shukriya|jazakallah|jazak\s*allah\s*khair|much\s*appreciated|grateful|appreciate\s*it)\b/i,
670    /\b(thankful|many\s*thanks|big\s*thanks)\b/i,
671    /\b(🙏|😊|🙌|❤️)\b/i
672  ],
673  response: "You're most welcome! 😊 Feel free to ask if you have any more questions about State Life insurance.\n\n📞 Helpline: 051-111-777-542 (available 24/7)"
674},
675
676
677  /* =============================================
678     SECTION 2: COMPANY INFORMATION
679     Coverage: About State Life, trust factors
680  ============================================= */
681 aboutStateLife: {
682  patterns: [
683    /\bwhat(\s+is|'s)?\s+(state\s+life|state\s+life\s+insurance)\b/i,
684    /\btell\s+(me\s+)?about\s+(state\s+life|state\s+life\s+insurance)\b/i,
685    /\b(state\s+life|state\s+life\s+insurance)\b/i,
686    /\bwho(\s+is|'s)?\s+(state\s+life|state\s+life\s+insurance)\b/i,
687    /\binfo(?:rmation)?\s+on\s+(state\s+life|state\s+life\s+insurance)\b/i,
688    /\bdetails?\s+about\s+(state\s+life|state\s+life\s+insurance)\b/i
689  ],
690  response: "🏛️ **State Life Insurance Corporation - Pakistan's Most Trusted Insurer**\n\n✅ **Established:** 1972 (50+ years of trust)\n✅ **Ownership:** 100% Government of Pakistan\n✅ **Market Leader:** 70%+ market share\n✅ **Coverage:** 180+ million Pakistanis\n✅ **Rating:** AAA (Highest in Pakistan)\n✅ **Assets:** PKR 1.93+ trillion\n✅ **Network:** 15,000+ offices nationwide\n\n🔒 **Why Choose State Life?**\n• Government guarantee on all policies\n• 50+ years of claim settlement record\n• Largest network - accessible everywhere\n• Shariah-compliant options (Takaful)\n• Affordable premiums with bonuses\n\n📞 **Contact:** 051-111-777-542\n🌐 **Website:** www.statelife.com.pk"
691},
692
693whyStateLife: {
694  patterns: [
695    /\bwhy\s+(choose|pick|select|go\s+with)\s+(state\s+life|state\s+life\s+insurance)\b/i,
696    /\bbenefits?\s+(of|with)\s+(state\s+life|state\s+life\s+insurance)\b/i,
697    /\bwhy\s+buy\s+(from\s+)?(state\s+life|state\s+life\s+insurance)\b/i,
698    /\b(state\s+life|state\s+life\s+insurance)\s+(vs|versus|compared\s+to)\b/i,
699    /\badvantages?\s+(of|with)\s+(state\s+life|state\s+life\s+insurance)\b/i,
700    /\b(state\s+life|state\s+life\s+insurance)\s+better\s+than\b/i
701  ],
702  response: "💎 **Why State Life is Pakistan's #1 Choice:**\n\n🏆 **TRUST & SECURITY**\n✅ Government-owned (100% backed by Pakistan)\n✅ AAA rating (only insurer with highest rating)\n✅ 50+ years, never defaulted on a claim\n✅ PKR 1.93 trillion in assets\n\n💰 **VALUE FOR MONEY**\n✅ Lower premiums (no profit focus like private insurers)\n✅ Bonus participation (share in company profits)\n✅ Best return on investment\n✅ Tax benefits on premiums\n\n🌍 **ACCESSIBILITY**\n✅ 15,000+ offices (urban + rural coverage)\n✅ Online payment (E-PAY portal)\n✅ JazzCash, Bank Alfalah payment options\n✅ Agent network everywhere\n\n📦 **PRODUCT RANGE**\n✅ 60+ insurance plans for every need\n✅ Life, health, child education, retirement\n✅ Shariah-compliant Takaful options\n✅ Group insurance for employees\n\n⚡ **FAST SERVICE**\n✅ Claims settled in 15-30 days\n✅ Online premium payment (instant)\n✅ 24/7 helpline: 051-111-777-542\n\n**Bottom Line:** State Life = Maximum security + Best value + Widest reach"
703},
704
705
706  governmentGuarantee: {
707    patterns: [
708      /government\s+guarantee/i,
709      /is\s+state\s+life\s+safe/i,
710      /can\s+state\s+life\s+bankrupt/i,
711      /policy\s+security/i
712    ],
713    response: "🔒 **Your Policy is 100% Secure with Government Guarantee**\n\n✅ **What This Means:**\nEvery State Life policy is backed by the Government of Pakistan under the Life Insurance (Nationalization) Act 1972. Even if State Life faces financial difficulties (highly unlikely), the government is legally obligated to pay all claims.\n\n🛡️ **Security Layers:**\n1️⃣ Government ownership (100%)\n2️⃣ Government guarantee (legal obligation)\n3️⃣ AAA rating (highest financial strength)\n4️⃣ PKR 1.93 trillion assets backing policies\n5️⃣ SECP regulation (Securities & E
713xchange Commission)\n6️⃣ 50+ years track record (never defaulted)\n\n💡 **Comparison:**\nPrivate insurers: Only company assets back policies\nState Life: Company assets + Government guarantee\n\n**Your policy is as secure as the Government of Pakistan itself!**\n\n📞 Questions? Call: 051-111-777-542"
714  },
715
716  /* =============================================
717     SECTION 3: ELIGIBILITY & GETTING STARTED
718     Coverage: Who can buy, how to start
719  ============================================= */
720  eligibility: {
721    patterns: [
722      /who\s+can\s+buy/i,
723      /eligibility/i,
724      /can\s+i\s+(buy|get|purchase)/i,
725      /age\s+limit/i,
726      /requirements/i
727    ],
728    response: "✅ **Who Can Buy State Life Insurance?**\n\n**BASIC ELIGIBILITY:**\n• Pakistani citizen\n• Age 18+ years\n• Legally able to sign contracts\n• Valid CNIC (National Identity Card)\n\n**AGE RANGES BY PLAN TYPE:**\n📌 **Life Insurance:** 18-65 years (varies by plan)\n📌 **Health Insurance:** 18-64 years\n📌 **Child Plans:** Child 6 months-15 years (parent buys)\n📌 **Retirement Plans:** 18-60 years\n\n**SPECIAL CASES:**\n✅ You CAN insure: Spouse, children, parents\n✅ Non-working spouse: Yes (via Jeevan Saathi plan)\n✅ Multiple policies: Yes, no limit\n✅ Medical exam: Required above certain age/amount\n\n**DOCUMENTS NEEDED:**\n1. CNIC (original + copy)\n2. Age proof (CNIC usually sufficient)\n3. Income proof (for large coverage)\n4. Medical reports (if required)\n\n📞 **Check Your Eligibility:** 051-111-777-542\n🌐 **Apply Online:** www.statelife.com.pk"
729  },
730
731  howToBuy: {
732    patterns: [
733      /how\s+to\s+buy/i,
734      /purchase\s+process/i,
735      /how\s+do\s+i\s+get/i,
736      /buying\s+process/i,
737      /application/i
738    ],
739    response: "📝 **How to Buy State Life Insurance (3 Easy Ways)**\n\n**METHOD 1: THROUGH AGENT (Most Popular)** 👤\n1. Find agent: Call 051-111-777-542 for nearest agent\n2. Agent visits you at home/office\n3. Discuss your needs, get recommendations\n4. Fill application form with agent's help\n5. Submit documents (CNIC, photos, medical if needed)\n6. Pay first premium\n7. Policy issued in 7-15 days\n\n**METHOD 2: VISIT OFFICE** 🏢\n1. Find nearest zonal office: www.statelife.com.pk/contact-us\n2. Walk in during office hours (Mon-Fri 9 AM-5 PM)\n3. Meet insurance advisor\n4. Choose plan, fill application\n5. Submit documents and premium\n6. Policy issued\n\n**METHOD 3: ONLINE (Select Plans)** 💻\n1. Visit: www.statelife.com.pk\n2. Select digital insurance products (Sinf-e-Aahan, Mahfooz)\n3. Fill online form\n4. Upload documents\n5. Pay online via E-PAY\n6. Instant policy issuance\n\n**DOCUMENTS REQUIRED:**\n✅ CNIC (both sides copy)\n✅ 4 passport photos\n✅ Bank account details\n✅ Medical reports (if sum assured > PKR 1 million)\n\n**PROCESSING TIME:** 7-15 days typically\n\n📞 **Need Help?** Call: 051-111-777-542"
740  },
741
742  /* =============================================
743     SECTION 4: PRODUCT RECOMMENDATIONS
744     Coverage: Plan suggestions for common needs
745  ============================================= */
746
747  planGoldenEndowment: {
748    patterns: [
749      /\bgolden\s+endowment\b/i,
750      /what\s+is\s+(the\s+)?golden\s+endowment\s+plan\b/i,
751      /\bgolden\s+endowment\s+plan\s+(details?|benefits?|information)\b/i,
752      /(benefits?|features?|details?)\s+of\s+golden\s+endowment/i
753    ],
754    response: "📘 **Golden Endowment Plan – Pay 7 years, covered 20 years**\n\n• Type: Limited payment endowment (with‑profits)\n• Coverage term: 20 years\n• Premiums: First 7 years only, then no further payments\n• Bonuses: Earned for all 20 years on the full sum assured\n• Maturity benefit: Sum assured + 20 years of accumulated bonuses\n• Death benefit: Sum assured + bonuses accumulated up to date of death\n• Best for: Long‑term savers who want to finish premiums early while keeping full protection and bonus growth for the full term.\n\nFor children’s future needs, consider the **Child Education & Marriage Plan** instead."
755  },
756
757  planJeevanSaathi: {
758    patterns: [
759      /\bjeevan\s+saathi\b/i,
760      /what\s+is\s+(the\s+)?jeevan\s+saathi\s+plan\b/i,
761      /(joint\s+life|married\s+couple).*(plan|policy)/i,
762      /(plan|policy)\s+for\s+married\s+couples/i
763    ],
764    response: "👫 **Jeevan Saathi Plan – Joint life for married couples**\n\n• Type: Joint life assurance (with‑profits)\n• Lives covered: Husband and wife under one policy\n• Key feature: After first spouse’s death, **future premiums are waived**, but coverage for the survivor continues until maturity with bonuses\n• Payouts:\n  1. First payout at first death (full sum assured)\n  2. Second payout at maturity (sum assured + accumulated bonuses)\n• Best for: Couples who want mutual protection, premium waiver after first death, and strong survivor benef
764its.\n\nThis is usually better for married couples than a basic joint life endowment because of the premium‑waiver and two‑payout structure."
765  },
766
767  planPersonalPension: {
768    patterns: [
769      /\bpersonal\s+pension\b/i,
770      /what\s+is\s+(the\s+)?personal\s+pension\s+scheme\b/i,
771      /(pension\s+scheme|retirement\s+income\s+plan)/i
772    ],
773    response: "🏖️ **Personal Pension Scheme – One‑time payment, long‑term pension**\n\n• Type: Single‑contribution pension / annuity plan\n• Payment: One‑time lump sum contribution (minimum around PKR 50,000)\n• Benefit: Guaranteed pension for 25 years, then continued pension for the rest of life\n• Features:\n  • Built‑in annual increases to help against inflation\n  • Option to withdraw / surrender after around 6 years (subject to rules)\n• Best for: People focused on **retirement income**, not just a one‑time maturity lump sum.\n\nThis is different from Endowment plans, which pay a lump sum at maturity or death instead of monthly pension."
774  },
775
776  planPlatinumPlus: {
777    patterns: [
778      /\bplatinum\s+plus\b/i,
779      /what\s+is\s+(the\s+)?platinum\s+plus\s+plan\b/i,
780      /(bonus\s+enhanced|high\s+bonus).*(plan|policy)/i
781    ],
782    response: "💎 **Platinum Plus Plan – Pay 3 years, covered 10 years**\n\n• Type: Limited‑payment endowment with **bonus enhancement**\n• Coverage term: 10 years\n• Premium payment: Only first 3 years (shortest premium term among these plans)\n• Bonus feature: About **50% higher bonuses** than a standard 10‑year endowment (exact rates depend on annual declarations)\n• Entry age: Roughly 1–65 years (can be used for children with parent as policyholder)\n• Best for: Medium‑term goals where you want to finish premiums very quickly but still enjoy strong bonus‑driven growth."
783  },
784
785  planChildEducationMarriage: {
786    patterns: [
787      /\bchild\s+education\s+(&|and)\s+marriage\b/i,
788      /\bchild\s+education\s+and\s+marriage\s+plan\b/i,
789      /(plan|policy)\s+for\s+child(ren)?\s+(education|marriage)/i,
790      /(save|saving).*(child|children).*(education|marriage)/i
791    ],
792    response: "🎓 **Child Education & Marriage Plan – Secure your child’s future**\n\n• Type: Child‑focused endowment with premium waiver\n• Ages: Child 1–15 years; parent usually 20–60 years\n• Feature if parent dies:\n  • All future premiums are **waived**\n  • Policy continues for the child\n  • Child still receives full benefit at maturity\n• Maturity: Benefit can be timed for age 18, 21, or 25 (education, marriage, or business start‑up)\n• Options: Lump‑sum payout or instalments, depending on variant\n• Best for: Parents or grandparents who want to guarantee funds for education and marriage even if something happens to the breadwinner."
793  },
794
795  planEndowmentTable03: {
796    patterns: [
797      /\bendowment\s+plan\b/i,
798      /\bendowment\s+plan\s*\(table[-\s]*03\)/i,
799      /\btable[-\s]*03\b/i,
800      /what\s+is\s+(the\s+)?endowment\s+plan\b/i
801    ],
802    response: "📗 **Endowment Plan (Table‑03) – Single premium endowment**\n\n• Type: Single‑premium endowment (with‑profits)\n• Payment: One‑time lump sum at the start – no recurring premiums\n• Coverage term: Flexible 10–50 years (subject to maximum maturity age rules)\n• Entry age: Roughly 10–65 years\n• Benefits:\n  • Life cover for the full chosen term\n  • Sum assured plus accumulated bonuses at maturity\n  • Death during term: Sum assured + bonuses to beneficiaries\n• Best for: Investors who prefer to pay once and keep long‑term life coverage plus savings, instead of paying yearly premiums."
803  },
804
805  planHaari: {
806    patterns: [
807      /\bhaari\s+plan\b/i,
808      /what\s+is\s+(the\s+)?haari\s+plan\b/i,
809      /(rural|farmer|agricultural).*(plan|policy)/i,
810      /(life\s+and\s+health|life\s*\+\s*health).*(plan|policy)/i
811    ],
812    response: "🌾 **Haari Plan – Life + Health for rural and working families**\n\n• Type: Combined life insurance and health insurance\n• Life benefit: Sum assured + bonuses at maturity or death\n• Health benefit: Hospital
812ization coverage with cashless treatment at State Life network hospitals\n• Accident benefit: 3× sum assured for general accidental death; 5× sum assured for agricultural accident death\n• Best for: Farmers, rural families and anyone who wants one plan that covers both life protection and major medical expenses."
813  },
814
815  planSaharaFamilyHealth: {
816    patterns: [
817      /\bsahara\s+family\s+health\b/i,
818      /what\s+is\s+(the\s+)?sahara\s+family\s+health\s+plan\b/i,
819      /(family\s+health|family\s+medical).*(plan|policy)/i
820    ],
821    response: "🏥 **Sahara Family Health – Hospitalization cover for the whole family**\n\n• Type: Pure health insurance (no life cover)\n• Who it covers: One policy for adults (18–64) and children (about 2 months–17 years)\n• Benefits: Inpatient hospitalization, day‑care surgeries, pre/post‑hospitalization costs and ambulance services\n• Cashless: Treatment at State Life network hospitals without paying upfront (State Life settles eligible bills directly)\n• Best for: Families who already have life insurance but want strong medical protection for all members under one plan."
822  },
823
824  planSehatZindagi: {
825    patterns: [
826      /\bsehat\s+zindagi\b/i,
827      /what\s+is\s+(the\s+)?sehat\s+zindagi\s+plan\b/i,
828      /(individual\s+health|personal\s+health).*(plan|policy)/i
829    ],
830    response: "💊 **Sehat Zindagi – Individual inpatient health insurance**\n\n• Type: Pure health insurance for one person\n• Coverage: Inpatient hospitalization and related medical expenses with cashless access at network hospitals\n• Age focus: Typically adults 18–64 who want their own medical cover\n• Best for: Individuals (especially salaried or self‑employed) who want a dedicated health policy separate from employer benefits or family plans."
831  },
832
833  planSinfEAahan: {
834    patterns: [
835      /\bsinf[-\s]*e[-\s]*aahan\b/i,
836      /(women|ladies|female).*(cancer|breast\s+cancer).*(plan|policy|coverage)/i,
837      /\bcancer\s+protection\b/i
838    ],
839    response: "💗 **Sinf‑e‑Aahan – Cancer protection plan for women**\n\n• Type: Specialized cancer insurance for Pakistani women\n• Benefit: 100% of sum assured paid on confirmed diagnosis of a covered cancer (such as breast, ovarian and other major cancers)\n• Use of payout: Can be used for treatment, income replacement or any purpose\n• Ages: Women roughly 18–64 years\n• Best for: Women who want targeted financial protection against the high cost of cancer treatment."
840  },
841
842  planMahfoozHealth: {
843    patterns: [
844      /\bmahfooz\b/i,
845      /mahfooz\s+(plan|policy)/i,
846      /(digital|online).*(plan|policy)/i
847    ],
848    response: "📱 **Mahfooz Plan – Simple digital protection**\n\n• Type: Digital life/health protection product\n• Channel: Designed to be bought and managed online with minimal paperwork\n• Benefits: Basic life and/or health coverage with straightforward terms\n• Best for: People who prefer quick, app or web‑based insurance without long forms, often as an entry‑level protection plan."
849  },
850
851  planTakafulOverview: {
852    patterns: [
853      /\btakaful\b/i,
854      /shariah[-\s]*compliant\s+(plan|policy|insurance)/i,
855      /(islamic|shariah).*(insurance|plan|policy)/i
856    ],
857    response: "🕋 **Takaful – Shariah‑compliant Islamic insurance**\n\n• Concept: Participants contribute to a common risk pool based on mutual cooperation (Tabarru), not interest or gambling\n• Oversight: Guided by a Shariah Board to ensure compliance with Islamic principles\n• Coverage: Life, health and group solutions structured on Takaful models\n• Who it suits: Customers who want protection and savings that align with Islamic finance principles while still benefiting from State Life’s financial strength."
858  },
859
860  planBancassuranceOverview: {
861    patterns: [
862      /\bbancassurance\b/i,
863      /insurance\s+through\s+banks/i,
864      /(three\s+payment|sadabahar).*(bank|bancassurance)/i
865    ],
866    response: "🏦 **Bancassurance Plans – Buy insurance through your bank**\n\n• Channel: Life insurance plans sold via partner bank branches\n• Main plans:\n  • **Three Payment Plan:** 25% of sum assured paid at 1/3 and 2/3 of term, 50% + bonuses at maturity, with full protection throughout\n  • **Sadabah
866ar Plan:** Anticipated endowment with built‑in accidental death benefit; periodic lump‑sum payouts plus extra cover for accidental death\n  • **Endowment via bank:** Traditional endowment for goals like children’s education or retirement\n• Best for: Customers who prefer to handle insurance and banking at the same place, with simple savings‑plus‑protection products."
867  },
868
869  planWholeLifeEmpower: {
870    patterns: [
871      /whole\s+life\b/i,
872      /table[-\s]*01\b/i,
873      /empower\s+your\s+life.*whole\s+life/i
874    ],
875    response: "🛡️ **Whole Life – Empower Your Life series**\n\n• Type: Permanent life insurance from Empower Your Life range\n• Coverage duration: Up to about age 85\n• Premiums: Regular premiums throughout life (or limited‑pay options in Table‑02 variant)\n• Benefits: Sum assured + long‑term bonuses paid at death or at age 85, whichever comes first\n• Best for: People who want lifelong protection and are comfortable paying premiums over a long period or for a fixed limited‑pay period."
876  },
877
878  planRuralLifeEmpower: {
879    patterns: [
880      /\brural\s+life\b/i,
881      /rural\s+life\s+insurance/i,
882      /empower\s+your\s+life.*rural/i
883    ],
884    response: "🌱 **Rural Life Insurance – Empower Your Life range**\n\n• Type: Life insurance tailored for rural communities\n• Focus: Simple eligibility, affordable premiums and savings with bonus participation\n• Purpose: Provide basic life cover and long‑term savings to farmers and rural households who may not access complex urban products\n• Best for: Rural families who want government‑backed life insurance with straightforward features."
885  },
886
887  recommendationEducation: {
888    patterns: [
889      /(child|children).*(education|school|university|study)/i,
890      /(education|university).*(plan|insurance|fund)/i,
891      /(save|saving).*(child|children).*education/i
892    ],
893    response: "🎓 **Best Plans for Child's Education:**\n\n**TOP RECOMMENDATION:**\n\n**1. Child Education & Marriage Plan (Table-76)** ⭐\n💰 **Premium Waiver:** If parent dies, premiums stop but policy continues\n📅 **Maturity:** Child gets money at 18, 21, or 25 (your choice)\n💵 **Payout Options:** Lump sum OR 5 annual installments\n🎯 **Perfect for:** University fees, higher education\n\n**2. Shehnai Plan (Table-77)**\n📈 **Inflation Protection:** Coverage increases 6% annually\n💰 **Example:** PKR 1M grows to PKR 4.8M over 20 years\n🎯 **Perfect for:** Long-term education planning (10-20 years)\n\n**3. Endowment Plan (Table-03)**\n💵 **Single Premium:** Pay once, forget it\n⏰ **Flexible Terms:** 10-50 years\n🎯 **Perfect for:** Lump sum investment for education\n\n**CALCULATION EXAMPLE:**\nChild age: 5 years\nTarget: University at 18 (13 years)\nEducation cost: PKR 2 million\n\n**Plan:** Child Education (13-year term)\n**Premium:** ~PKR 120,000/year for 10 years\n**At Maturity:** PKR 2M + bonuses = ~PKR 2.5M\n\n📞 **Get Personalized Quote:** 051-111-777-542"
894  },
895
896  recommendationRetirement: {
897    patterns: [
898      /retirement/i,
899      /pension/i,
900      /(old\s+age|after\s+retirement)/i,
901      /monthly\s+income/i
902    ],
903    response: "🏖️ **Best Plans for Retirement Income:**\n\n**TOP RECOMMENDATIONS:**\n\n**1. Personal Pension Scheme** ⭐⭐⭐\n💰 **One-Time Payment:** Minimum PKR 50,000\n📅 **Guaranteed Pension:** 25 years + lifetime after\n📈 **Annual Increases:** Built-in inflation protection\n✅ **Withdrawal Option:** After 6 years if needed\n\n**Example:**\nContribution: PKR 1,000,000 (one-time)\nMonthly Pension: ~PKR 12,000-15,000 for 25 years\nAfter 25 years: Continue for life\n\n**2. Whole Life Policy (Table-01)**\n💼 **Lifelong Coverage:** Protection until age 85\n💰 **Fixed Premiums:** Pay until retirement, then stop\n📦 **Maturity Benefit:** Lump sum + bonuses at 85\n🎯 **Perfect for:** Leaving legacy + retirement fund\n\n**3. Anticipated Endowment (Table-05)**\n💵 **Survival Benefits:** Get 25% at 1/3 and 2/3 of term\n📅 **Maturity:** Remaining 50% + bonuses\n🎯 **Perfect for:** Regular income during retirement\n\n**PLANNING TIP:**\nAge 40 → Target retirement 60 (20 years)\nDesired monthly income: PKR 50,000\nRequired capital: PKR 6-8 million\n\n**Strategy:** Endowment plan 20-year term\nPremium: PKR 300,000/year\nAt 60: Receive PKR 8M+ (lump sum or convert to pension)\n\n📞 **Retirement Planning:** 051-111-777-542"
904  },
905
906  recommendationFamily: {
907    patterns: [
908      /family\s+protection/i,
909      /protect\s+family/i,
910      /breadwinner/i,
911      /income\s+protection/i,
912      /if\s+i\s+die/i
913    ],
914    response: "👨‍👩‍👧‍👦 **Best Plans for Family Protection:**\n\n**TOP RECOMMENDATIONS:**\n\n**1. Muhafiz Plus (Table-78)** ⭐⭐⭐\n💀 **Death Benefit:** Sum assured + bonuses\n🚗 **Accidental Death:** 2× sum assured\n💰 **Family Income:** 15 years of monthly payments\n🎯 **Perfect for:** Maximum family protection\n\n**Example:**\nSum Assured: PKR 5 million\nNormal death: Family gets PKR 5M + bonuses\nAccidental death: PKR 10M + 15 years income\n\n**2. Family Pension Plan (Table-12)**\n💵 **Survival Benefits:** You get 25% at intervals while alive\n💰 **Death Benefit:** Family gets guaranteed monthly income\n🎯 **Perfect for:** Regular income to family if you die\n\n**3. Jeevan Saathi (Table-19)** - For Married Couples\n👫 **Joint Coverage:** Covers both spouses\n🎁 **First Death:** Survivor gets sum assured + premiums w
914aived\n💰 **Second Death:** Another sum assured + bonuses\n🎯 **Perfect for:** Spousal protection\n\n**COVERAGE CALCULATION:**\nFamily monthly expenses: PKR 80,000\nYears until youngest child 18: 15 years\nRequired coverage: PKR 80,000 × 12 × 15 = PKR 14.4M\n\n**Recommended:** Muhafiz Plus with PKR 15M sum assured\n\n📞 **Get Family Protection Quote:** 051-111-777-542"
915  },
916
917  recommendationHealth: {
918    patterns: [
919      /health\s+insurance/i,
920      /medical\s+insurance/i,
921      /hospitalization/i,
922      /hospital\s+bills/i
923    ],
924    response: "🏥 **Best Health Insurance Plans:**\n\n**FOR INDIVIDUALS:**\n\n**Sehat Zindagi** ⭐\n🏥 **Coverage:** Inpatient hospitalization + day care\n💳 **Cashless:** At State Life network hospitals\n💰 **Pre/Post Hospitalization:** Covered\n🚑 **Ambulance:** Emergency coverage\n👤 **Ages:** 18-64 years\n\n**FOR FAMILIES:**\n\n**Sahara Family Health** ⭐⭐⭐\n👨‍👩‍👧 **Coverage:** Parents + children (up to 17 years)\n🏥 **All Benefits:** Inpatient, day care, pre/post hospital\n💳 **Cashless:** Network hospitals\n💵 **One Premium:** Entire family covered\n👶 **Children:** From 2 months old\n\n**SPECIALIZED:**\n\n**Sinf-e-Aahan (Cancer Protection - Women Only)** 💗\n💰 **Payout:** 100% of sum assured on cancer diagnosis\n🎯 **Use Anywhere:** Not limited to specific hospitals\n✅ **Ages:** 18-64 years (Pakistani women)\n📱 **Digital:** Buy online instantly\n\n**Haari Plan (Rural Health + Life)**\n🌾 **For:** Farmers, rural population\n💼 **Combined:** Life insurance + health coverage\n⚡ **Accident Coverage:** 5× for agricultural accidents\n\n**RECOMMENDATION BY FAMILY:**\n• Single person → Sehat Zindagi\n• Married with kids → Sahara Family Health\n• Woman 30+ → Add Sinf-e-Aahan for cancer protection\n• Rural/farmer → Haari Plan\n\n📞 **Health Insurance Quote:** 051-111-777-542\n🌐 **Network Hospitals:** www.statelife.com.pk"
925  },
926
927  /* =============================================
928     SECTION 5: POLICY BASICS (KEY CONCEPTS)
929     Coverage: Essential insurance terms explained
930  ============================================= */
931  wholeLifeVsEndowment: {
932    patterns: [
933      /whole\s+life\s+(vs|versus|or|compared)/i,
934      /difference.*whole.*endowment/i,
935      /endowment\s+(vs|versus|or)/i
936    ],
937    response: "📊 **Whole Life vs Endowment - Simple Comparison:**\n\n**WHOLE LIFE INSURANCE (Table-01)**\n⏰ **Duration:** Until age 85 (lifetime)\n💰 **Premiums:** Pay forever (until maturity)\n🎯 **Purpose:** Permanent protection\n📦 **Payout:** Only if you die OR at age 85\n💵 **Best for:** Leaving inheritance, long-term security\n\n**Example:**\nBuy at 30, pay till 85 = 55 years of premiums\nIf die at 50: Family gets sum assured + 20 years bonuses\nIf reach 85: You get sum assured + 55 years bonuses\n\n---\n\n**ENDOWMENT INSURANCE (Table-03)**\n⏰ **Duration:** Fixed term (10-50 years, you choose)\n💰 **Premiums:** Only during term\n🎯 **Purpose:** Goal-based savings + protection\n📦 **Payout:** At maturity OR death (whichever first)\n💵 **Best for:** Specific goals (education, house, retirement)\n\n**Example:**\nBuy at 30, 20-year term = pay till 50\nIf die at 40: Family gets sum assured + 10 years bonuses\nIf reach 50: YOU get sum assured + 20 years bonuses\n\n---\n\n**QUICK DECISION GUIDE:**\n\n❓ **Want lifelong protection?** → Whole Life\n❓ **Saving for specific goal?** → Endowment\n❓ **Want money back at maturity?** → Endowment\n❓ **Want to leave maximum inheritance?** → Whole Life\n❓ **Lower premium for same coverage?** → Endowment (shorter term)\n\n📞 **Not Sure?** Call for advice: 051-111-777-542"
938  },
939
940  bonusExplained: {
941    patterns: [
942      /what\s+(is|are)\s+bonus/i,
943      /bonus\s+in\s+insurance/i,
944      /how.*bonus.*work/i,
945      /bonus\s+calculation/i
946    ],
947    response: "💰 **Insurance Bonus - Simple Explanation:**\n\n**WHAT IS BONUS?**\nBonus = Your share of State Life's profits!\n\nState Life invests your premiums and earns profits. By law, 97.5% of profits are distributed to policyholders as bonuses.\n\n**HOW BONUS WORKS:**\n\n1️⃣ **Declared Annually:** State Life announces bonus rate each year (e.g., PKR 40 per PKR 1,000 of sum assured)\n\n2️⃣ **Added to Policy:** Bonus credited to your policy value\
947n\n3️⃣ **Paid at Maturity/Death:** All accumulated bonuses paid with sum assured\n\n**EXAMPLE CALCULATION:**\n\nSum Assured: PKR 2,000,000\nAnnual Bonus Rate: PKR 40 per thousand\nPolicy Term: 20 years\n\n**Year 1 Bonus:**\n(PKR 40 ÷ 1,000) × PKR 2,000,000 = PKR 80,000\n\n**Total Bonuses (20 years):**\nPKR 80,000 × 20 years = PKR 1,600,000\n\n**At Maturity You Get:**\nSum Assured: PKR 2,000,000\n+ Bonuses: PKR 1,600,000\n= **Total: PKR 3,600,000** 🎉\n\n**BONUS TYPES:**\n\n📌 **Reversionary Bonus:** Added each year\n📌 **Terminal Bonus:** Extra bonus at maturity (surprise gift!)\n\n**IMPORTANT:**\n✅ Bonuses are NOT guaranteed (depend on State Life's profits)\n✅ But State Life's track record: Consistent bonuses for 50+ years\n✅ Bonuses are tax-free\n✅ Government-backed (secure)\n\n📞 **Check Your Policy's Bonuses:** 051-111-777-542"
948  },
949
950  surrenderValue: {
951    patterns: [
952      /surrender\s+value/i,
953      /cancel.*policy/i,
954      /discontinue.*policy/i,
955      /cash.*value/i,
956      /encashment/i
957    ],
958    response: "💵 **Policy Surrender Value Explained:**\n\n**WHAT IS SURRENDER VALUE?**\nThe amount you get if you cancel (surrender) your policy before maturity.\n\n⚠️ **WARNING:** Surrendering early means BIG LOSS!\n\n**WHEN AVAILABLE:**\n✅ Policy must be in force for **2+ years**\n✅ Bonuses included after **3+ years**\n\n**HOW MUCH YOU GET:**\n\n📉 **Approximate Surrender Values:**\n• Year 2-3: 30-40% of premiums paid\n• Year 5: 50-60% of premiums paid\n• Year 10: 70-80% of premiums paid\n• Year 15+: 85-95% of premiums paid + bonuses\n\n**EXAMPLE - THE LOSS:**\n\n20-year Endowment, PKR 3M sum assured\nYou paid PKR 500,000 total (over 5 years)\n\n**If You Surrender at Year 5:**\n• Surrender Value: ~PKR 300,000\n• **Your Loss: PKR 200,000** 😢\n\n**If You Continue to Maturity (Year 20):**\n• You Get: PKR 3M + PKR 1.5M bonuses = PKR 4.5M\n• **Your Gain: PKR 4 million!** 🎉\n\n**BETTER ALTERNATIVES TO SURRENDER:**\n\n1️⃣ **Policy Loan** ✅\n   • Borrow 80% of surrender value\n   • Keep policy active\n   • Continue earning bonuses\n   • Pay back whenever you want\n\n2️⃣ **Paid-Up Policy** ✅\n   • Stop paying premiums\n   • Reduce coverage proportionally\n   • Still get bonuses and maturity benefit\n   • Keep protection active\n\n3️⃣ **Change Premium Mode** ✅\n   • Switch to annual (cheaper than monthly)\n   • Reduce financial burden\n   • Keep policy active\n\n**SURRENDER PROCESS:**\n1. Visit zonal office\n2. Submit surrender form + original policy\n3. Processing: 15-30 days\n4. Payment to bank account\n\n📞 **Before Surrendering, Call:** 051-111-777-542\n(We'll explore better options!)"
959  },
960
961  policyLoan: {
962    patterns: [
963      /policy\s+loan/i,
964      /borrow.*against.*policy/i,
965      /loan.*insurance/i,
966      /need\s+money.*policy/i
967    ],
968    response: "💳 **Policy Loan - Borrow Against Your Insurance:**\n\n**WHAT IS POLICY LOAN?**\nBorrow money using your policy as collateral - you're essentially borrowing your OWN money!\n\n**KEY BENEFITS:**\n✅ No credit check (it's your policy)\n✅ Keep life coverage active\n✅ Continue earning bonuses\n✅ No fixed repayment schedule\n✅ Lower interest than bank loans\n\n**HOW MUCH CAN YOU BORROW?**\n💰 **Up to 80% of surrender value**\n\n**ELIGIBILITY:**\n✅ Policy has surrender value (2+ years old)\n✅ Paid at least 3 premiums\n✅ Policy is active (not lapsed)\n\n**INTEREST RATE:**\n📈 **12.5% per annum** (compounded semi-annually)\n\n**EXAMPLE CALCULATION:**\n\nPolicy surrender value: PKR 400,000\nMaximum loan: 80% = PKR 320,000\n\n**Interest After 1 Year:**\nPrincipal: PKR 320,000\nInterest (12.5% compounded): ~PKR 41,000\n**Total Owed: PKR 361,000**\n\n**LOAN PROCESS:**\n\n1️⃣ **Call/Visit:** Zonal office or call 051-111-777-542\n2️⃣ **Check Eligibility:** Verify surrender value\n3️⃣ **Apply:** Fill loan application form\n4️⃣ **Approval:** Typically 7-15 days\n5️⃣ **Receive Money:** Bank transfer or cheque\n\n**REPAYMENT:**\n\n🔄 **Option 1:** Repay anytime (full or partial)\n🔄 **Option 2:** Never repay (deducted from maturity/death benefit)\n🔄 **Option 3:** Pay interest only (keep principal outstanding)\n\n**IMPACT IF NOT REPAID:**\n\nSum Assured: PKR 3,000,000\nBonuses: PKR 800,000\n**Total Maturity Value: PKR 3,800,000**\n\nOutstanding Loan: PKR 361,000\n**You Receive: PKR 3,439,000**\n\n**CAUTION:**\n
968If loan + interest exceeds surrender value → Policy LAPSES!\n\n💡 **RECOMMENDATION:**\nRepay or pay interest periodically to maximize maturity benefit.\n\n📞 **Apply for Loan:** 051-111-777-542"
969  },
970
971  gracePeriodLapse: {
972    patterns: [
973      /grace\s+period/i,
974      /late\s+payment/i,
975      /missed\s+premium/i,
976      /policy\s+lapse/i,
977      /forgot\s+to\s+pay/i
978    ],
979    response: "⏰ **Grace Period & Policy Lapse - CRITICAL INFO:**\n\n**GRACE PERIOD = 31 DAYS** ✅\n\nYou get an extra 31 days after premium due date to pay without penalty.\n\n**EXAMPLE:**\nPremium due: January 10\nGrace period: Until February 10 (31 days)\n✅ Pay by Feb 10 → No problem, no penalty!\n❌ Don't pay by Feb 10 → Policy LAPSES\n\n**DURING GRACE PERIOD:**\n✅ Policy is FULLY ACTIVE\n✅ Life coverage continues\n✅ If you die, claim is paid\n✅ No late fee, no penalty\n✅ Bonuses continue\n\n**AFTER GRACE PERIOD (Day 32):**\n❌ Policy LAPSES (becomes inactive)\n❌ No life coverage\n❌ No claim paid if death occurs\n❌ No bonuses credited\n❌ Cannot take loan\n\n**IF YOUR POLICY LAPSES:**\n\n🔧 **SOLUTION: REVIVAL**\n\n⏱️ **Revival Window:** Within 5 years of lapse\n\n**Revival Process:**\n1️⃣ Contact State Life: 051-111-777-542\n2️⃣ Fill revival form\n3️⃣ Pay all outstanding premiums\n4️⃣ Pay revival interest (~10-12% per year)\n5️⃣ Medical exam (if required)\n6️⃣ Approval & reactivation\n\n**REVIVAL COST EXAMPLE:**\n\nLapsed for 2 years\nOutstanding premiums: PKR 100,000 (2 years)\nRevival interest: PKR 12,000 (2 years @ 12%)\n**Total to Pay: PKR 112,000**\n\nPlus: Medical exam if required (PKR 5,000-10,000)\n\n**AFTE
979R 5 YEARS:**\n❌ Cannot revive (policy permanently dead)\n❌ You lose everything except surrender value\n\n**PREVENTION TIPS:**\n\n📅 Set phone reminder 7 days before due date\n💳 Use E-PAY (online payment, instant)\n🤖 Set up calendar alerts\n📱 Ask agent to remind you\n💵 Pay annually (only once per year to remember)\n\n**EMERGENCY? CAN'T PAY?**\n\n💡 **Better Options Than Lapsing:**\n1. Take policy loan (keep policy active)\n2. Convert to paid-up (reduce coverage, stop premiums)\n3. Change to annual mode (lower per-payment amount)\n\n📞 **Policy Lapsed? Call NOW:** 051-111-777-542\n(Sooner you revive, cheaper it is!)"
980  },
981
982  /* =============================================
983     SECTION 6: PREMIUM PAYMENT (PRACTICAL GUIDE)
984     Coverage: How to pay, methods, troubleshooting
985  ============================================= */
986  howToPayPremium: {
987    patterns: [
988      /how.*pay.*premium/i,
989      /payment.*method/i,
990      /pay.*online/i,
991      /premium.*payment/i,
992      /where.*pay/i
993    ],
994    response: "💳 **5 Easy Ways to Pay Your Premium:**\n\n**1. E-PAY (ONLINE) - FASTEST** 🌐 ⭐⭐⭐\n✅ Pay from home (24/7)\n✅ Debit/credit card or internet banking\n✅ Instant confirmation\n✅ No queues!\n🔗 **Link:** epay.statelife.com.pk\n\n**How to Use E-PAY:**\n1. Go to epay.statelife.com.pk\n2. Enter policy number + CNIC\n3. Verify premium amount\n4. Pay with card/internet banking\n5. Get instant receipt (email + SMS)\n⏱️ **Time:** 2 minutes\n\n---\n\n**2. JAZZCASH (MOBILE)** 📱\n✅ Pay via phone (no computer needed)\n✅ JazzCash app or dial *786#\n✅ Instant payment\n\n**3. BANK ALFALAH** 🏦\n✅ Visit any Bank Alfalah branch\n✅ Cash or cheque accepted\n\n**4. STATE LIFE OFFICE** 🏢\n✅ Visit any State Life zonal office\n✅ Pay cash or cheque\n\n**5. THROUGH AGENT** 👤\n✅ Your agent collects from you\n\n📞 **Payment Help:** 051-111-777-542\n🌐 **E-PAY:** epay.statelife.com.pk"
995  },
996
997  /* =============================================
998     SECTION 7: CLAIMS PROCESS (STEP-BY-STEP)
999     Coverage: Maturity, death, survival benefit claims
1000  ============================================= */
1001  maturityClaim: {
1002    patterns: [
1003      /maturity\s+claim/i,
1004      /policy.*matured/i,
1005      /how.*claim.*maturity/i,
1006      /policy.*completed/i
1007    ],
1008    response: "🎉 **Maturity Claim - Get Your Payout!**\n\n**CONGRATULATIONS! Your policy has matured!**\n\nYou'll receive: **Sum Assured + All Bonuses** 💰\n\n**DOCUMENTS REQUIRED:**\n1️⃣ Original policy document\n2️⃣ CNIC copy (both sides)\n3️⃣ Bank-verified maturity discharge voucher\n4️⃣ 3 specimen signatures (if signature changed)\n\n**STEP-BY-STEP PROCESS:**\n\n**STEP 1: GET MATURITY DISCHARGE VOUCHER**\n📥 Download from: www.statelife.com.pk/downloads\nOR get from zonal office\n\n**STEP 2: BANK VERIFICATION**\n• Take voucher to YOUR bank\n• Bank verifies your account details\n• Bank stamps and signs voucher\n\n**STEP 3: SUBMIT TO STATE LIFE**\n• Visit your servicing zonal office\n• Submit all documents\n• Get acknowledgment receipt\n• Note down claim reference number\n\n**STEP 4: PROCESSING**\n⏱️ State Life verifies and processes\n⏰ **Timeline:** 15-30 days typically\n\n**STEP 5: PAYMENT**\n💸 Amount credited to your bank account\n📧 SMS/email notification sent\n📄 Tax certificate provided (if applicable)\n\n**EXAMPLE PAYOUT:**\n\nSum Assured: PKR 2,000,000\n20-year policy bonuses: PKR 1,600,000\nTerminal bonus: PKR 300,000\n**Total You Receive: PKR 3,900,000** 🎊\n\n**PROCESSING TIME:**\n✅ Complete docs: 15-30 days\n⏰ Incomplete docs: 30-60 days (delays)\n🚀 Peak season (Dec-Mar): May take 30-45 days\n\n**TRACKING YOUR CLAIM:**\n📞 Call helpline: 051-111-777-542\n💬 Provide: Policy number + claim reference\n\n**WHAT IF POLICY DOCUMENT LOST?**\nDon't worry!\n1. Apply for duplicate policy first\n2. Publish newspaper ad (formal
1008ity)\n3. Submit indemnity bond\n4. Pay duplicate fee\n5. Then proceed with maturity claim\n⏱️ **Extra Time:** 30 days for duplicate\n\n📞 **Maturity Claim Help:** 051-111-777-542\n🌐 **Download Forms:** www.statelife.com.pk"
1009  },
1010
1011  deathClaim: {
1012    patterns: [
1013      /death\s+claim/i,
1014      /claim.*after.*death/i,
1015      /beneficiary.*claim/i,
1016      /insured.*died/i
1017    ],
1018    response: "🙏 **Death Claim Process - Supporting Your Family**\n\n**We understand this is a difficult time. State Life is here to help.**\n\n**WHO CAN CLAIM?**\n1️⃣ **Nominee** (person named in policy)\n2️⃣ **Assignee** (if policy was assigned)\n3️⃣ **Legal Heirs** (with succession certificate)\n\n**IMMEDIATE ACTIONS:**\n\n📞 **Step 1: Notify State Life (Within 7 Days)**\nCall: 051-111-777-542\nProvide: Policy number, deceased name, death date\n\n**DOCUMENTS REQUIRED:**\n\n✅ Death certificate (NADRA or Union Council)\n✅ Original policy document\n✅ CNIC copies (deceased + claimant)\n✅ Claim form (State Life provides)\n✅ Nominee/legal heir documents\n✅ Bank-verified discharge voucher\n\n**ADDITIONAL DOCUMENTS (If Applicable):**\n\n**Natural Death:**\n• Last doctor's statement\n• Hospital records (if hospitalized)\n\n**Accidental Death:**\n• FIR (police report)\n• Post-mortem report\n• Accident investigation report\n\n**Death Abroad:**\n• Death certificate attested by Pakistan Embassy\n• Translation (if not in Urdu/English)\n\n**CLAIM PROCESS:**\n\n**STEP 1: INITIAL NOTIFICATION**\n• Send written intimation to zonal office\n• State Life reviews policy status\n\n**STEP 2: DOCUMENT SUBMISSION**\n• Collect all required documents\n• Submit to servicing zonal office\n• Get acknowledgment receipt with claim number\n\n**STEP 3: VERIFICATION**\n• State Life verifies documents\n• May conduct investigation (for claims within 2-3 years of policy)\n• May request additional documents\n\n**STEP 4: APPROVAL**\n• Claim approved\n• Approval letter issued\n\n**STEP 5: PAYMENT**\n• Death benefit paid to beneficiary's bank\n• SMS/email notification\n\n**PROCESSING TIME:**\n\n✅ **With Nomination:** 15-30 days\n⏰ **Without Nomination:** 60-90 days (need succession certificate)\n🔍 **Recent Policy (<3 years):** 30-45 days (investigation)\n🚗 **Accidental Death:** 30-45 days (police reports needed)\n\n**DEATH BENEFIT AMOUNT:**\n\nSum Assured: PKR 3,000,000\nBonuses (15 years): PKR 1,200,000\n**Total: PKR 4,200,000**\n\n**If Accidental Death + ADB Rider:**\nBase: PKR 4,200,000\nADB (2×): PKR 6,000,000\n**Total: PKR 10,200,000**\n\n**NOMINATION IMPORTANCE:**\n\n✅ **With Nomination:** Fast claim (15-30 days)\n❌ **Without Nomination:** Slow (60-90 days + succession certificate cost PKR 50,000-150,000)\n\n💡 **TIP:** Always maintain updated nomination!\n\n**IF CLAIM REJECTED:**\n1. Request written reason\n2. Appeal to Principal Office\n3. Approach Insurance Ombudsman\n4. Legal action (as last resort)\n\n**SUPPORT CONTACTS:**\n\n📞 **Death Claim Helpline:** 051-111-777-542\n📧 **Email:** [support email]\n🏢 **Visit:** Nearest zonal office\n\n**State Life is committed to supporting your family during this difficult time.**"
1019  },
1020
1021  /* =============================================
1022     SECTION 8: CONTACT & SUPPORT
1023     Coverage: How to reach State Life
1024  ============================================= */
1025  contact: {
1026    patterns: [
1027      /contact/i,
1028      /helpline/i,
1029      /phone\s+number/i,
1030      /call/i,
1031      /email/i,
1032      /office/i
1033    ],
1034    response: "📞 **State Life Contact Information:**\n\n**HELPLINE (TOLL-FREE):**\n📱 **051-111-777-542**\n\n**ONLINE:**\n🌐 **Website:** www.statelife.com.pk\n💳 **E-PAY Portal:** epay.statelife.com.pk\n\n**HEAD OFFICES:**\n\n🏛️ **Corporate HQ (Islamabad):**\nState Life Building, Blue Area\nIslamabad, Pakistan\n\n🏢 **Principal Office (Karachi):**\nState Life Building No. 9\nDr. Ziauddin Ahmed Road\nKarachi-75530\n\n**FIND NEAREST OFFICE:**\n📍 www.statelife.com.pk/contact-us/zonal-offices\n\n**ZONAL OFFICES:**\n✅ 100+ offices across Pakistan\n✅ All major cities (Karachi, Lahore, Islamabad, Peshawar, Quetta, Multan, Faisalabad, etc.)\n✅ Office Hours: Mon-Fri 9 AM-5 PM\n\n**COMPLAINT REGISTRATION:**\n🔗 https://statelife.com.pk/en/registercomplaint\n\n**SOCIAL MEDIA:**\n📘 Facebook: https://www.facebook.com/slicpakistanofficial\n🐦 Linkedin: https://www.linkedin.com/company/statelifeofficial/\n📸 Instagram: https://www.instagram.com/statelifeofficialpakistan\n\n**FOR SPECIFIC QUERIES:**\n• Premium Payment: E-PAY or helpline\n• Claims: Zonal office or helpline\n• New Policy: Find agent via helpline\n• Complaints: Complaint cell\n• General Info: Helpline or website\n\n📞 **Call Now:** 051-111-777-542"
1035  },
1036
1037  /* =============================================
1038     SECTION 9: COMMON QUESTIONS (MISCELLANEOUS)
1039     Coverage: Frequently asked queries
1040  ============================================= */
1041  taxBenefits: {
1042    patterns: [
1043      /tax.*benefit/i,
1044      /tax.*deduction/i,
1045      /tax.*saving/i,
1046      /tax.*rebate/i
1047    ],
1048    response: "💰 **Tax Benefits on Life Insurance:**\n\n**IMPORTANT:** Tax laws change; consult tax advisor for current rules.\n\n**TYPICAL TAX BENEFITS IN PAKISTAN:**\n\n**1. PREMIUM PAYMENTS:**\n✅ Life insurance premiums may be tax-deductible\n✅ [Current limit and percentage needed from FBR]\n\n**2. MATURITY PROCEEDS:**\n✅ Typically tax-free (not treated as income)\n✅ [Verify current tax treatment]\n\n**3. DEATH BENEFITS:**\n✅ Usually tax-free to beneficiaries\n✅ [Verify current rules]\n\n**EXAMPLE (Hypothetical):**\nAnnual Income: PKR 2,000,000\nInsurance Premium: PKR 200,000\n\nTax Saving: [Calculation based on current tax laws]\n\n**DOCUMENTATION FOR TAX:**\n📄 Keep all premium payment receipts\n📄 Annual policy statement\n📄 Maturity/death claim tax certificate\n\n**FOR ACCURATE INFO:**\n📞 Call State Life: 051-111-777-542\n🌐 Visit: FBR (Federal Board of Revenue) website\n👔 Consult: Tax advisor/CA\n\n**State Life provides tax certificates upon request.**"
1049  },
1050
1051  nominationImportance: {
1052    patterns: [
1053      /nomination/i,
1054      /nominee/i,
1055      /beneficiary/i,
1056      /who.*gets.*money/i
1057    ],
1058    response: "🎯 **Nomination - CRITICAL for Fast Claims!**\n\n**WHAT IS NOMINATION?**\nNaming the person(s) who will receive policy benefits if you die.\n\n**WHY IT'S CRITICAL:**\n\n✅ **With Nomination:**\n• Claim paid in 15-30 days\n• Simple process\n• No court involvement\n• Low cost\n\n❌ **Without Nomination:**\n• Claim takes 60-90+ days\n• Need succession certificate from court\n• Court process: 6-12 months + PKR 50,000-150,000\n• Family suffers during wait\n\n**WHO CAN BE NOMINEE?**\n✅ Spouse\n✅ Children\n✅ Parents\n✅ Siblings\n✅ Anyone with insurable interest\n\n**MULTIPLE NOMINEES:**\nYes! Split percentage:\n• Wife: 50%\n• Son: 25%\n• Daughter: 25%\n\n**NOMINATION vs ASSIGNMENT:**\n\n**Nomination:** Beneficiary designation (can be changed anytime)\n**Assignment:** Transfer of policy ownership (permanent, cancels nomination)\n\n**HOW TO MAKE NOMINATION:**\n\n**New Policy:**\n✅ Fill nomination section in application form\n\n**Existing Policy:**\n1. Visit zonal office\n2. Fill nomination form\n3. Submit with CNIC copies (yours + n
1058ominee's)\n4. State Life endorses policy\n\n**HOW TO CHANGE NOMINATION:**\n\n1. Visit zonal office (can change anytime)\n2. Fill change of nomination form\n3. Provide new nominee's details + CNIC\n4. Updated in policy records\n\n**IMPORTANT SITUATIONS:**\n\n🔄 **Nominee Dies Before You:**\n• Update nomination immediately\n• Otherwise claim goes to nominee's heirs (not your choice)\n\n💍 **Got Married/Divorced:**\n• Update nomination\n• Add/remove spouse\n\n👶 **Child Born:**\n• Add child as nominee\n\n**NOMINATION CHECK:**\nCall 051-111-777-542 and verify:\n• Who is your current nominee?\n• Is information up to date?\n• Do you want to change?\n\n**DO IT TODAY - It Takes 5 Minutes, Saves Family Months of Hassle!**\n\n📞 **Update Nomination:** 051-111-777-542\n🏢 **Visit:** Any State Life zonal office"
1059  },
1060
1061  /* =============================================
1062     SECTION 10: PRODUCT COMPARISONS
1063     Coverage: Helping users choose between plans
1064  ============================================= */
1065  bestPlanForMe: {
1066    patterns: [
1067      /which\s+plan/i,
1068      /best\s+plan/i,
1069      /recommend/i,
1070      /suggest.*plan/i,
1071      /what.*should.*buy/i
1072    ],
1073    response: "🎯 **Finding the Best Plan for YOU:**\n\n**QUICK QUESTIONS TO DECIDE:**\n\n**1️⃣ WHAT'S YOUR PRIMARY GOAL?**\n\n💼 **Family Protection** (if I die, family secure)\n→ Muhafiz Plus, Family Pension, Whole Life\n\n🎓 **Child's Education** (save for university)\n→ Child Education Plan, Shehnai Plan\n\n🏖️ **Retirement Income** (monthly pension after 60)\n→ Personal Pension Scheme, Anticipated Endowment\n\n💰 **Savings + Protection** (grow money + coverage)\n→ Endowment Plan, Three Payment Plan\n\n🏥 **Health Coverage** (hospital bills)\n→ Sahara Family Health, Sehat Zindagi\n\n---\n\n**2️⃣ HOW LONG CAN YOU PAY PREMIUMS?**\n\n⚡ **Pay Once, Done** → Personal Pension, Endowment Table-03\n⏱️ **Pay 3 Years** → Platinum Plus\n📅 **Pay 7 Years** → Golden Endowment\n🔄 **Pay Throughout** → Whole Life, Regular Endowment\n\n---\n\n**3️⃣ WHAT'S YOUR AGE?**\n\n👶 **Under 18:** Can't buy yourself (parent buys Child Plans)\n👨 **18-35:** Any plan works; lock in low premiums now!\n👨‍💼 **35-50:** Focus on family protection + retirement\n👴 **50-65:** Limited options; focus on retirement/pension\n👵 **65+:** Very limited; mainly health insurance\n\n---\n\n**4️⃣ WHAT'S YOUR BUDGET?**\n\n💵 **Tight Budget (<PKR 50K/year):**\n→ Whole Life (lower premium, lifetime coverage)\n→ Health insurance only\n\n💰 **Moderate (PKR 50K-200K/year):**\n→ Endowment 15-20 year term\n→ Child Education Plan\n\n💎 **Comfortable (PKR 200K+/year):**\n→ Comprehensive family protection\n→ Multiple policies (life + health + child)\n\n---\n\n**5️⃣ FAMILY SITUATION?**\n\n👤 **Single:** Whole Life or Endowment (build wealth)\n💑 **Married, No Kids:** Jeevan Saathi (joint coverage)\n👨‍👩‍👧 **Married with Kids:** Muhafiz Plus + Child Plan + Health\n👴 **Retired:** Personal Pension (monthly income)\n\n---\n\n**TOP 3 PLANS FOR MOST PEOPLE:**\n\n🥇 **1. Endowment Plan** (Most Popular)\n✅ Flexible terms (10-50 years)\n✅ Savings + protection\n✅ Suitable for any goal\n\n🥈 **2. Muhafiz Plus** (Best Protection)\n✅ Maximum family security\n✅ Accidental death 2×\n✅ 15-year family income\n\n🥉 **3. Sahara Family Health** (Essential)\n✅ Covers entire family\n✅ Cashless hospital
1073ization\n✅ Affordable premiums\n\n---\n\n**STILL CONFUSED?** 🤔\n\n📞 **FREE CONSULTATION:** 051-111-777-542\n\nTell them:\n• Your age\n• Family situation\n• Goals (education, retirement, protection)\n• Budget\n\nThey'll recommend the perfect plan for YOU!\n\n**REMEMBER:** Best plan = One that matches YOUR goals + budget + life stage"
1074  },
1075
1076
1077 
1078
1079
1080  /* =============================================
1081     SECTION 11: ISLAMIC/TAKAFUL OPTIONS
1082     Coverage: Shariah-compliant insurance
1083  ============================================= */
1084  takaful: {
1085    patterns: [
1086      /takaful/i,
1087      /islamic.*insurance/i,
1088      /shariah.*compliant/i,
1089      /halal.*insurance/i
1090    ],
1091    response: "☪️ **Takaful - Shariah-Compliant Insurance:**\n\n**WHAT IS TAKAFUL?**\nIslamic alternative to conventional insurance, compliant with Shariah principles.\n\n**KEY DIFFERENCES:**\n\n**Conventional Insurance:**\n• Risk transfer to company\n• Interest-based investments\n• Profit to shareholders\n\n**Takaful:**\n• Risk sharing among participants\n• Shariah-compliant investments (no interest/riba)\n• Surplus shared with participants\n• Supervised by Shariah Board\n\n**STATE LIFE TAKAFUL PRODUCTS:**\n\n📦 **Takaful Savings Plans**\n• Unit-linked plans\n• Shariah-compliant investment funds\n• Death protection + savings\n• Flexible contributions\n\n**WHO CAN BUY TAKAFUL?**\n✅ Anyone! Not just Muslims\n✅ Open to all religions\n✅ Same eligibility as conventional plans\n\n**BENEFITS OF TAKAFUL:**\n\n✅ **Halal:** No interest/riba, compliant with Islamic finance\n✅ **Ethical:** Investments in halal businesses only\n✅ **Transparent:** Clear surplus distribution\n✅ **Supervised:** Shariah Board oversight\n✅ **Competitive:** Similar returns to conventional\n\n**TAKAFUL vs CONVENTIONAL:**\n\n**Protection Level:** Same\n**Coverage:** Same\n**Claims Process:** Same\n**Price:** Slightly higher (Shariah compliance cost)\n**Returns:** Comparable\n\n**EXAMPLE TAKAFUL PLAN:**\n\nAge: 30 years\nContribution: PKR 100,000/year\nTerm: 20 years\n\n**Benefits:**\n• Death: PKR 2M + investment value\n• Maturity: Investment fund value + surplus sharing\n• Shariah-compliant investments throughout\n\n**HOW TO APPLY:**\n\n1. Call: 051-111-777-542\n2. Request Takaful plans information\n3. Agent explains options\n4. Choose plan\n5. Application process same as conventional\n\n**SHARIAH BOARD:**\nState Life's Takaful products supervised by qualified Islamic scholars ensuring Shariah compliance.\n\n📞 **Takaful Inquiries:** 051-111-777-542\n🌐 **More Info:** www.statelife.com.pk/takaful"
1092  },
1093
1094  /* =============================================
1095     SECTION 12: AGENT RECRUITMENT
1096     Coverage: Becoming a State Life agent
1097  ============================================= */
1098  becomeAgent: {
1099    patterns: [
1100      /become.*agent/i,
1101      /agent.*job/i,
1102      /career.*state\s+life/i,
1103      /sales.*representative/i,
1104      /insurance.*agent/i
1105    ],
1106    response: "💼 **Become a State Life Insurance Agent:**\n\n**WHY JOIN AS AGENT?**\n\n✅ **Unlimited Earnings:** Commission-based, no ceiling\n✅ **Flexible Hours:** Be your own boss\n✅ **Career Growth:** Sales Rep → Officer → Manager\n✅ **Stable Company:** 50+ years, government-backed\n✅ **Training Provided:** No experience needed\n✅ **Respect & Purpose:** Help families, earn well\n\n**ELIGIBILITY:**\n\n📋 **Minimum Requirements:**\n✅ Age: 20+ years (no max limit)\n✅ Education: Matriculation (10th grade)\n✅ Citizenship: Pakistani with valid CNIC\n✅ Gender: Men AND women welcome\n✅ Experience: NOT required (training provided)\n\n**EARNINGS POTENTIAL:**\n\n💰 **Commission Structure:** [Rates needed]\n• First-year commission: 15-25% of premium\n• Renewal commission: 3-5% (years 2-5)\n• Performance bonuses\n\n**Income Examples:**\n• New Agent (6 months): PKR 20,000-40,000/month\n• Established Agent (2 years): PKR 50,000-100,000/month\n• Top Agents (5+ years): PKR 100,000-300,000+/month\n\n**CAREER PATH:**\n\n**Level 1: Sales Representative (0-2 years)**\n• Entry level\n• Sell policies, build relationships\n• Earn commissions\n\n**Level 2: Sales Officer (2-5 years)**\n• Higher commission rates\n• Medical benefits\n• Office facilities\n• Supervise new agents\n\n**Level 3: Sales Manager (5+ years)**\n• Highest commission\n• Full medical benefits\n• Team management\n• Leadership role\n\n**BENEFITS:**\n\n✅ Group insurance (you're covered too!)\n✅ Commission income (unlimited potential)\n✅ Training & support\n✅ Medical benefits (officers/managers)\n✅ Recognition & awards\n\n**HOW TO APPLY:**\n\n**STEP 1:** Find nearest zonal office\n🔍 www.statelife.com.pk/contact-us/zonal-offices\n\n**STEP 2:** Visit in person\n📄 Bring: CNIC, education certificate, photos\n\n**STEP 3:** Interview\n• Meet recruiting officer\n• Discuss role and expectations\n• Assessment\n\n**STEP 4:** Training\n• Product knowledge\n• Sales skills\n• Regulatory compliance\n\n**STEP 5:*
1106* Start Selling!\n• Get agent code\n• Receive sales kit\n• Begin earning\n\n**WHO SUCCEEDS AS AGENT?**\n\n✅ Self-motivated individuals\n✅ Good communicators\n✅ Relationship builders\n✅ Resilient personalities\n✅ Community-oriented\n\n**INVESTMENT REQUIRED:**\n[Clarify if any fees needed]\n\n**WOMEN AGENTS:**\n✅ Equal opportunities\n✅ Flexible hours (family-friendly)\n✅ Women clients prefer women agents\n✅ Same commission structure\n\n📞 **Agent Recruitment:** 051-111-777-542\n🌐 **More Info:** www.statelife.com.pk/become-an-agent\n\n**Turn your people skills into a profitable career with Pakistan's #1 insurer!**"
1107  },
1108
1109  /* =============================================
1110     SECTION 13: FALLBACK & ERROR HANDLING
1111     Coverage: When query not understood
1112  ============================================= */
1113  clarificationNeeded: {
1114    patterns: [
1115      /^.{1,3}$/,  // Very short messages (1-3 characters)
1116      /^\?+$/      // Just question marks
1117    ],
1118    response: "I'd love to help, but I need a bit more information! 😊\n\nCould you please:\n✅ Ask a complete question\n✅ Use more specific words\n✅ Tell me what you're looking for\n\n**COMMON TOPICS:**\n💰 Premium payment\n📋 Policy information\n🏥 Health insurance\n👨‍👩‍👧 Family protection\n📞 Contact details\n💳 Claims process\n\nOr simply ask: \"How can you help me?\"\n\n📞 **Prefer to speak?** Call: 051-111-777-542"
1119  },
1120
1121  /* =============================================
1122     SECTION 14: DEVELOPER CREDITS
1123     Coverage: Who made this?
1124  ============================================= */
1125  developer: { 
1126     patterns: [ 
1127       /Who\s+Developer/i, 
1128       /Developed\s+by/i, 
1129       /who\s+developed\s+this/i, 
1130       /who.*is.*the.*developer.*of.*this.*(Project|Chatbot|bot|site|app)/i,
1131       /who.*made.*this/i,
1132       /who.*created.*this/i,
1133       /developer.*name/i
1134     ], 
1135     response: "👨‍💻 This chatbot is designed and developed by Saif Ali Jogi - State Life IT Team" 
1136   }
1137
1138};
1139
1140// ========================================
1141// INTENT DETECTION SYSTEM
1142// ========================================
1143
1144function detectIntent(userMessage) {
1145  const lowerMessage = userMessage.toLowerCase().trim();
1146  const isGreetingLike = (msg) => {
1147    const m = msg.toLowerCase().trim();
1148    return /^(hi+|hii+|hello+|hey+|heya|hiya|howdy|hlo|hlw|yo+|sup+|greetings)$/.test(m)
1149      || /\b(assal(a|aa)m(u)?\s*(o|u)?\s*alaikum|assalamu\s*alaikum|assalamualaikum|sal(a|aa)m(u)?\s*(o|u)?\s*alaikum|aoa|asa|asak|salam|salaam|slam|slm)\b/.test(m)
1150      || /\b(good\s*(morning|afternoon|evening|night|day))\b/.test(m);
1151  };
1152
1153  const buildGreetingResponse = (msg, candidates) => {
1154    greetingCount += 1;
1155    const m = msg.toLowerCase().trim();
1156    const isIslamic = /\b(assal(a|aa)m(u)?\s*(o|u)?\s*alaikum|assalamu\s*alaikum|assalamualaikum|sal(a|aa)m(u)?\s*(o|u)?\s*alaikum|aoa|asa|asak|salam|salaam|slam|slm)\b/.test(m);
1157
1158    if (greetingCount > 1) {
1159      return isIslamic
1160        ? "Wa Alaikum Assalam. What can I help you with next?\n\n• Pay premium\n• Claims process\n• Policy details / bonus\n• Plan recommendation"
1161        : "Hi again. What would you like to do next?\n\n• Pay premium\n• Claims process\n• Policy details / bonus\n• Plan recommendation";
1162    }
1163
1164    const safeCandidates = Array.isArray(candidates) ? candidates.filter(Boolean) : [];
1165    const nonRepeat = safeCandidates.filter(t => t && t !== lastGreetingResponse);
1166    const pool = nonRepeat.length ? nonRepeat : safeCandidates;
1167    if (pool.length) {
1168      const picked = pool[Math.floor(Math.random() * pool.length)];
1169      lastGreetingResponse = picked;
1170      if (isIslamic && /hello!\s*👋\s*welcome/i.test(picked)) {
1171        return "Assalam o Alaikum! 🌟 Welcome to State Life Insurance.\n\nI can help you with:\n• Policy information\n• Premium payment\n• Claims process\n• Product recommendations\n• General inquiries\n\nWhat would you like to know today?";
1172      }
1173      return picked;
1174    }
1175
1176    return isIslamic
1177      ? "Assalam o Alaikum! How can I help you today (premium, claim, policy, or plan)?"
1178      : "Hello! How can I help you today (premium, claim, policy, or plan)?";
1179  };
1180
1181  // First, check JSON-based intents loaded from static_replies/*.json
1182  if (Array.isArray(JSON_INTENTS) && JSON_INTENTS.length > 0) {
1183    for (const entry of JSON_INTENTS) {
1184      if (!entry.patterns) continue;
1185      for (const pattern of entry.patterns) {
1186        if (pattern.test(lowerMessage)) {
1187          const responses = Array.isArray(entry.responses) ? entry.responses : [];
1188          let resolved = null;
1189          if (responses.length) {
1190            const totalWeight = responses.reduce((sum, r) =>
1190 sum + (r.weight || 1), 0);
1191            let rand = Math.random() * totalWeight;
1192            for (const r of responses) {
1193              const w = r.weight || 1;
1194              if ((rand -= w) <= 0) {
1195                resolved = r.text;
1196                break;
1197              }
1198            }
1199            if (!resolved) {
1200              resolved = responses[0].text;
1201            }
1202          }
1203          if (resolved) {
1204            if ((entry.intent === 'greeting' || entry.id === 'greetings_general') && isGreetingLike(lowerMessage)) {
1205              resolved = buildGreetingResponse(lowerMessage, responses.map(r => r.text));
1206            }
1207            return {
1208              category: entry.id,
1209              confidence: entry.priority === 'high' ? 'high' : 'medium',
1210              response: resolved
1211            };
1212          }
1213        }
1214      }
1215    }
1216  }
1217  
1218  // Check each category for pattern matches
1219  for (const [category, data] of Object.entries(STATIC_KNOWLEDGE)) {
1220    if (category === 'greetings' || category === 'farewells' || category === 'thanks') {
1221      continue;
1222    }
1223    if (data.patterns) {
1224      for (const pattern of data.patterns) {
1225        if (pattern.test(lowerMessage)) {
1226          const resolved = Array.isArray(data.responses)
1227            ? data.responses[Math.floor(Math.random() * data.responses.length)]
1228            : data.response;
1229          return {
1230            category,
1231            confidence: 'high',
1232            response: resolved
1233          };
1234        }
1235      }
1236    }
1237  }
1238  
1239  return null; // No match found
1240}
1241
1242// ========================================
1243// KEYWORD FALLBACK SYSTEM (Layer 2.5)
1244// ========================================
1245
1246const KEYWORD_RESPONSES = {
1247  // Quick keyword matches for common terms
1248  'premium': "💳 **Premium Payment Info:**\n\nPay via:\n• E-PAY (online): epay.statelife.com.pk\n• JazzCash mobile wallet\n• Bank Alfalah branches\n• State Life offices\n• Through your agent\n\n📞 Help: 051-111-777-542\n\nNeed detailed payment guide? Ask: \"How to pay premium\"",
1249  
1250  'claim': "📋 **Claims Information:**\n\nTypes of claims:\n• Maturity claim (policy completed)\n• Death claim (life insured died)\n• Survival benefit claim\n• Health insurance claim\n\nWhich claim are you asking about?\n\n📞 Claims Help: 051-111-777-542",
1251  
1252  'bonus': "💰 **Bonus = Your share of State Life's profits!**\n\nBonuses added annually to your policy, paid at maturity or death.\n\n**Example:** PKR 40 per PKR 1,000 of sum assured\n\nFor detailed explanation, ask: \"How does bonus work\"\n\n📞 051-111-777-542",
1253  
1254  'lapse': "⚠️ **Policy Lapse Alert:**\n\nGrace Period: 31 days to pay premium\nAfter 31 days: Policy lapses (becomes inactive)\n\nSolution: Policy Revival (within 5 years)\n\nFor full details, ask: \"What is grace period\"\n\n📞 Urgent: 051-111-777-542",
1255  
1256  'loan': "💳 **Policy Loan Available:**\n\nBorrow up to 80% of surrender value\nInterest: 12.5% per annum\nNo fixed repayment schedule\nKeep policy active!\n\nFor complete guide, ask: \"How to get policy loan\"\n\n📞 051-111-777-542"
1257};
1258
1259function checkKeywords(userMessage) {
1260  const lowerMessage = userMessage.toLowerCase();
1261  
1262  for (const [keyword, response] of Object.entries(KEYWORD_RESPONSES)) {
1263    if (lowerMessage.includes(keyword)) {
1264      return {
1265        type: 'keyword_match',
1266        confidence: 'medium',
1267        response: response
1268      };
1269    }
1270  }
1271  
1272  return null;
1273}
1274
1275// ========================================
1276// MAIN ROUTER FUNCTION
1277// ========================================
1278
1279function getStaticResponse(userMessage) {
1280  // Layer 1: Intent Detection (Pattern Matching)
1281  const intentMatch = detectIntent(userMessage);
1282  if (intentMatch) {
1283    return {
1284      source: 'intent_detection',
1285      confidence: intentMatch.confidence,
1286      response: intentMatch.response,
1287      useAPI: false
1288    };
1289  }
1290  
1291  // Layer 2: Keyword Fallback
1292  const keywordMatch = checkKeywords(userMessage);
1293  if (keywordMatch) {
1294    return {
1295      source: 'keyword_match',
1296      confidence: keywordMatch.confidence,
1297      response: keywordMatch.response,
1298      useAPI: false
1299    };
1300  }
1301  
1302  // Layer 3: No match - Use RAG API
1303  return {
1304    source: 'needs_api',
1305    confidence: 'none',
1306    response: null,
1307    useAPI: true
1308  };
1309}
1310
1311// ========================================
1312// USAGE IN YOUR CHATBOT
1313// ========================================
1314
1315/*
1316async function handleUserMessage(userMessage) {
1317  // Step 1: Try static knowledge first
1318  const staticResult = getStaticResponse(userMessage);
1319  
1320  if (!staticResult.useAPI) {
1321    // Found in static knowledge - return immediately (FREE)
1322    return {
1323      reply: staticResult.response,
1324      cost: 0,
1325      source: staticResult.source
1326    };
1327  }
1328  
1329  // Step 2: Static knowledge couldn't help - use RAG API (COSTS MONEY)
1330  const apiResponse = await callOpenRouterRAG(userMessage);
1331  
1332  return {
1333    reply: apiResponse,
1334    cost: calculateAPIcost(apiResponse),
1335    source: 'rag_api'
1336  };
1337}
1338*/
1339
1340// ========================================
1341// EXPORT (Node/CommonJS guard)
1342// ========================================
1343
1344if (typeof module !== 'undefined' && module.exports) {
1345  module.exports = {
1346    STATIC_KNOWLEDGE,
1347    detectIntent,
1348    checkKeywords,
1349    getStaticResponse
1350  };
1351}
1352
1353    function normalizeText(t) {
1354        return t.toLowerCase().replace(/[?!.,:;'"`]/g, '').replace(/\s+/g, ' ').trim();
1355    }
1356
1357    function tokens(text) {
1358        return normalizeText(text).split(' ').filter(Boolean);
1359    }
1360
1361    function jaccard(a, b) {
1362        const sa = new Set(a);
1363        const sb = new Set(b);
1364        const inter = new Set([...sa].filter(x => sb.has(x)));
1365        const uni = new Set([...sa, ...sb]);
1366        return uni.size === 0 ? 0 : inter.size / uni.size;
1367    }
1368
1369    function getStaticReply(message) {
1370        const trimmed = message.trim();
1371        if (trimmed === '?') return STATIC_REPLIES['?'];
1372        const norm = normalizeText(trimmed);
1373        if (STATIC_REPLIES[norm]) return STATIC_REPLIES[norm];
1374        let bestKey = null;
1375        let bestScore = 0;
1376        const msgTokens = tokens(norm);
1377        for (const key in STATIC_REPLIES) {
1378            const score = jaccard(msgTokens, tokens(key));
1379            if (score > bestScore) {
1380                bestScore = score;
1381                bestKey = key;
1382            }
1383        }
1384        if (bestScore >= 0.6) return STATIC_REPLIES[bestKey];
1385        return null;
1386    }
1387
1388    // Toggle Chat
1389    toggler.addEventListener('click', () => {
1390        chatContainer.classList.add('show');
1391        toggler.style.display = 'none';
1392        textarea.focus();
1393    });
1394
1395    closeBtn.addEventListener('click', () => {
1396        chatContainer.classList.remove('show');
1397        toggler.style.display = 'flex';
1398    });
1399
1400    const sendMessage = async () => {
1401        const message = textarea.value.trim();
1402        if (!message) return;
1403
1404        appendMessage(message, 'user');
1405        userMessageCount += 1;
1406        maybeShowRatingBar();
1407        textarea.value = '';
1408        textarea.style.height = '40px';
1409
1410        const staticResult = getStaticResponse(message);
1411        if (staticResult && !staticResult.useAPI && staticResult.response) {
1412            const typingId = appendTypingIndicator();
1413            scrollToBottom();
1414            await sleep(randomDelay());
1415            removeMessage(typingId);
1416            appendMessage(staticResult.response, 'bot');
1417            scrollToBottom();
1418            return;
1419        }
1420
1421        const typingId = appendTypingIndicator();
1422        const start = Date.now();
1423        scrollToBottom();
1424
1425        const appendAny = (value, type) => {
1426            if (Array.isArray(value)) {
1427                for (const part of value) {
1428                    if (typeof part === 'string' && part.trim()) {
1429                        appendMessage(part, type);
1430                    }
1431                }
1432                return;
1433            }
1434            if (typeof value === 'string') {
1435                appendMessage(value, type);
1436                return;
1437            }
1438            if (value && typeof value === 'object') {
1439                const msg = value.answer || value.message || value.error;
1440                if (typeof msg === 'string' && msg.trim()) {
1441                    appendMessage(msg, type);
1442                    return;
1443                }
1444            }
1445            appendMessage("Sorry, I encountered an error. Please try again.", type);
1446        };
1447
1448        try {
1449            const candidates = getApiUrlCandidates();
1450            let lastPayload = null;
1451            let lastStatus = null;
1452
1453            for (const url of candidates) {
1454                console.log('[Chatbot] Calling chat API with message:', message, 'url:', url);
1455                const response = await fetch(url, {
1456                    method: 'POST',
1457                    headers: {
1458                        'Content-Type': 'application/json',
1459                        'Accept': 'application/json'
1460                    },
1461                    body: JSON.stringify({ message })
1462                });
1463
1464                const data = await parseJsonOrText(response);
1465                lastPayload = data;
1466                lastStatus = response.status;
1467
1468                if (response.ok) {
1469                    const elapsed = Date.now() - start;
1470                    if (elapsed < MIN_TYPING_MS) {
1471                        await sleep(MIN_TYPING_MS - elapsed);
1472                    }
1473                    removeMessage(typingId);
1474                    appendAny(data.answer, 'bot');
1475                    scrollToBottom();
1476                    return;
1477                }
1478
1479                if (response.status === 404 && isRouteNotFoundPayload(data)) {
1480                    continue;
1481                }
1482
1483                if (Array.isArray(data && data.answer)) {
1484                    const elapsed = Date.now() - start;
1485                    if (elapsed < MIN_TYPING_MS) {
1486                        await sleep(MIN_TYPING_MS - elapsed);
1487                    }
1488                    removeMessage(typingId);
1489                    appendAny(data.answer, 'bot');
1490                    scrollToBottom();
1491                    return;
1492                }
1493
1494                const elapsed = Date.now() - start;
1495                if (elapsed < MIN_TYPING_MS) {
1496                    await sleep(MIN_TYPING_MS - elapsed);
1497                }
1498                removeMessage(typingId);
1499                const issueType = detectApiIssueType(response.status, data);
1500                if (issueType === 'auth' || issueType === 'rate' || issueType === 'server' || issueType === 'network' || issueType === 'unknown') {
1501                    const smart = buildSmartApiFallback(issueType, message);
1502                    appendAny(smart[0], 'bot');
1503                    await sleep(250);
1504                    appendAny(smart[1], 'bot');
1505                } else {
1506                    appendAny(data.answer || data.error || data.message, 'bot error');
1507                }
1508                console.error(data);
1509                scrollToBottom();
1510                return;
1511            }
1512
1513            const elapsed = Date.now() - start;
1514            if (elapsed < MIN_TYPING_MS) {
1515                await sleep(MIN_TYPING_MS - elapsed);
1516            }
1517            removeMessage(typingId);
1518            const issueType = detectApiIssueType(lastStatus, lastPayload);
1519            const smart = buildSmartApiFallback(issueType, message);
1520            appendAny(smart[0], 'bot');
1521            await sleep(250);
1522            appendAny(smart[1], 'bot');
1523            console.error({ status: lastStatus, payload: lastPayload });
1524        } catch (error) {
1525            const elapsed = Date.now() - start;
1526            if (elapsed < MIN_TYPING_MS) {
1527                await sleep(MIN_TYPING_MS - elapsed);
1528            }
1529            removeMessage(typingId);
1530            const smart = buildSmartApiFallback('network', message);
1531            appendAny(smart[0], 'bot');
1532            await sleep(250);
1533            appendAny(smart[1], 'bot');
1534            console.error(error);
1535        }
1536        scrollToBottom();
1537    };
1538
1539    sendBtn.addEventListener('click', sendMessage);
1540    
1541    textarea.addEventListener('keydown', (e) => {
1542        if (e.key === 'Enter' && !e.shiftKey) {
1543            e.preventDefault();
1544            sendMessage();
1545        }
1546    });
1547
1548    if (chatBody) {
1549        chatBody.addEventListener('click', (e) => {
1550            const btn = e.target && e.target.closest ? e.target.closest('.chat-suggestion') : null;
1551            if (!btn) return;
1552            const value = btn.getAttribute('data-suggest') || '';
1553            const suggestion = value ? decodeURIComponent(value) : '';
1554            if (!suggestion) return;
1555            textarea.value = suggestion;
1556            textarea.focus();
1557            sendMessage();
1558        });
1559    }
1560
1561    function appendMessage(text, type) {
1562        const div = document.createElement('div');
1563        div.className = `chat-message ${type}`;
1564        
1565        const contentDiv = document.createElement('div');
1566        contentDiv.className = 'message-content';
1567        
1568        if (type.includes('bot')) {
1569            contentDiv.textContent = text;
1570            let html = contentDiv.innerHTML;
1571
1572            html = html.replace(/\*\*/g, '');
1573            html = html.replace(/`/g, '');
1574            html = injectExampleButtons(html, text);
1575
1576            // 1. Temporarily replace Markdown links with placeholders
1577            const placeholders = [];
1578            html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, text, url) => {
1579                placeholders.push({ text, url });
1580                return `__MD_LINK_${placeholders.length - 1}__`;
1581            });
1582
1583            // 2. Process raw URLs (ignoring placeholders)
1584            const urlRegex = /\b((?:https?:\/\/|www\.)[^\s<>"'`]+|(?:[a-z0-9.-]+\.[a-z]{2,})(?:\/[^\s<>"'`]*)?)/gi;
1585            html = html.replace(urlRegex, (raw) => {
1586                // If it looks like a placeholder, skip
1587                if (raw.includes('__MD_LINK_')) return raw;
1588                
1589                let trailing = '';
1590                const m = raw.match(/[.,;:!?]+$/);
1591                if (m) {
1592                    trailing = m[0];
1593                }
1594                const core = trailing ? raw.slice(0, -trailing.length) : raw;
1595                let href = core;
1596                if (!/^https?:\/\//i.test(href)) {
1597                    href = 'https://' + href;
1598                }
1599                return `<a class="chat-link" href="${href}" target="_blank" rel="noopener noreferrer">${core}</a>` + trailing;
1600            });
1601
1602            // 3. Restore Markdown links as proper <a> tags
1603            html = html.replace(/__MD_LINK_(\d+)__/g, (match, id) => {
1604                const item = placeholders[id];
1605                let href = item.url;
1606                if (!/^https?:\/\//i.test(href)) {
1607                    href = 'https://' + href;
1608                }
1609                return `<a class="chat-link" href="${href}" target="_blank" rel="noopener noreferrer">${item.text}</a>`;
1610            });
1611
1612            const lines = html.split('\n');
1613            const outLines = [];
1614            for (let i = 0; i < lines.length; i++) {
1615                const line = lines[i];
1616                if (
1617                    /^\s*\|.*\|\s*$/.test(line) &&
1618                    i + 1 < lines.length &&
1619                    /^\s*\|(?:\s*:?-{3,}:?\s*\|)+\s*$/.test(lines[i + 1])
1620                ) {
1621                    const headerLine = line.trim();
1622                    i += 2;
1623                    const rows = [];
1624                    while (i < lines.length && /^\s*\|.*\|\s*$/.test(lines[i])) {
1625                        rows.push(lines[i].trim());
1626                        i++;
1627                    }
1628                    i -= 1;
1629                    const headers = headerLine
1630                        .slice(1, -1)
1631                        .split('|')
1632                        .map((c) => c.trim());
1633                    const bodyRows = rows.map((r) =>
1634                        r
1635                            .slice(1, -1)
1636                            .split('|')
1637                            .map((c) => c.trim())
1638                    );
1639                    // Removed escapeCell function as content is already safe/processed
1640                    let table = '<div class="chat-table-wrap"><table class="chat-table"><thead><tr>';
1641                    headers.forEach((h) => {
1642                        table += '<th>' + h + '</th>';
1643                    });
1644                    table += '</tr></thead><tbody>';
1645                    bodyRows.forEach((cols) => {
1646                        table += '<tr>';
1647                        headers.forEach((_, idx) => {
1648                            const cell = cols[idx] || '';
1649                            table += '<td>' + cell + '</td>';
1650                        });
1651                        table += '</tr>';
1652                    });
1653                    table += '</tbody></table></div>';
1654                    outLines.push(table);
1655                } else {
1656                    outLines.push(line);
1657                }
1658            }
1659            html = outLines.join('\n');
1660
1661            html = html.replace(/^##\s+(.+)$/gm, '<span class="chat-heading">$1</span>');
1662
1663            html = html.replace(/[\s\n]+$/g, '');
1664
1665            html = html.replace(/\n/g, '<br>');
1666
1667            contentDiv.innerHTML = html;
1668        } else {
1669            contentDiv.textContent = text;
1670        }
1671
1672        div.appendChild(contentDiv);
1673        chatBody.appendChild(div);
1674        return div;
1675    }
1676
1677    function appendTypingIndicator() {
1678        const id = 'typing-' + Date.now();
1679        const div = document.createElement('div');
1680        div.id = id;
1681        div.className = 'typing-indicator';
1682        div.innerHTML = '<span></span><span></span><span></span>';
1683        chatBody.appendChild(div);
1684        return id;
1685    }
1686
1687    function removeMessage(id) {
1688        const el = document.getElementById(id);
1689        if (el) el.remove();
1690    }
1691
1692    function scrollToBottom() {
1693        chatBody.scrollTop = chatBody.scrollHeight;
1694    }
1695
1696})();

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.