PageSourceSearch

https://www.fctele.com/wp-content/uploads/fctel-chat/english-ai-chat-app-mobile-duty-20260929.js?v=20260929-1

js fctele.com collected 2026-10-06 11:13:29 UTC 82,160 bytes, 572 lines download raw bytes

1(function(){var s=document.createElement("script");s.src="/wp-content/uploads/fctel-chat/presence-site.js?v=20260925-8";s.async=true;(document.head||document.documentElement).appendChild(s);})();
2(function boot() {
3
4  'use strict';
5
6  if (!document.body) {
7
8    document.addEventListener('DOMContentLoaded', boot, {once: true});
9
10    return;
11
12  }
13
14  if (window.__fctelEnglishChat || document.getElementById('fctel-en-chat')) return;
15
16  window.__fctelEnglishChat = true;
17
18
19
20  var API = 'https://crm.fctelerp.cn/website-chat/public/';
21
22  var CONTACT_API = location.origin + '/wp-json/fctel-ai-chat/v1/contact';
23
24  var PAGE = location.origin + location.pathname;
25
26  var STATIC_FALLBACK_AVATAR = 'data:image/webp;base64,UklGRiIJAABXRUJQVlA4IBYJAADQNACdASqJAMAAPlUmkEUjoiGWOkycOAVEsYBqCP2/aew5Bn2b8o/yq7FTmTxVzfaLu0/8B5KvtF/QH+e9wD9Yend5iv2J9YD0e/4j1AP69/ROtE9ADy3fZb/eD0r4vsbVoW2/l+QVFWBwNDLnzmDHH43Tj56HD5sPAjio84snuyov5Nt9iAO+ozJY8L0a72R2FbEqhUX/txzBuAUYYLvNFxjGX50fh029SqIUUFboAvuGaRWEY9nnJ6dMbzSKunurIuEDqA6bTvSr4p3yIBpkB6MRBPtGDUPzM2wjbeBwavmn4Be9asNwWSMSYAt5GrhVAvz61EIpdLDK83neuYEAx/JhLv7IfF6LZ5LWGVmEuEBwXqjMdc+OVogRzhCfkUK1UCL0uIBCOxuNEJV+HGoDVu1K3nFAd5CcdDN/QI1gsmaRYBvvRWIeEeFIr/6yvO/Wkfpmb/e4/GDoLnkPr+mUzPsam4ZZ/3eqlgBkUzzaXdtiLgryp5m+RmRHf3P7o2ajsTc9EzuqeFd8+9NhgIf2vVO9ODxM7SWu+TIeMxlL3xnjMPrMDRYow/O/5txQwAD8yv0+4LHE1S/+fYlCV+ljAz4KruTWR6dXXUk7aqbIIZSKRQZbUZo6liBuc0wYd1+SthXv4agnvYq7jsC5P4wjHClsReqW1RF5MHb63eNjBfFRIL14QFTerHLJK9UfC+xSYfhBOWTq2Qxwv7abWnaAAHbfUUrozGXoHCSCnn/5KKQZNM9tj96loJ2/WokL8DbZheRLKmlm7eDd/hmYXiHXVQ0A7WH/OmCEktwEx5QaTLyRmuSpzP2+ipPYKVELUN8BDEK4nNawRVuO8XARgarYie7uSUZYxTUhZiYFBgrD2nf5+1WL0fI3uCVLhoH/Du/XaHzVpMHBYC8gQ84ljcgXFmhWgVNI2jpqjxUtddxQV7lxr+iRCdk8glqLIIiBRKCEVb3jm9TdMBOMEV5KikznFNnveoxE9T7ziSnsowK4GjqqCrfCOcLKvhmXtIUXZK9uRFb1ZHl6/7nDpJ1B/94YmVr21j7YJf4Ep+N0KH3va3Sg8tFrxBMcRnJS3zqefER869JST5hy8XmVX5IRWwYX5xUIhuDRDlinV5xZa2hJTd+wyq/78R/7Q6QK3jzdpdbVeLsJU8HLM00D2Tfe/4q3hv0vzi3ooF4a/Yqcx47pAW2G0G0E/edLsWhGbd8Ywsp02q5wO4DOZDeE5bOaigk+OAGncrMw3rSdf+bM5ipM6JFeKHfMPtwcpyVS5MexAJ8jEsbR0BNtyXvMVQOINwZPAB10WyQALOoORAEQbN4AYVlH7vGRrMQgnfjKP6B+BS0V3w6EvkZjc4EUXGbhIJiu+rSExOPT4GDHMAVqiHCU0cazT30oySstG5aRB9ipxN1r8u/69jpDcmiS0DzXFj2TsobfC9zIoZ/374PE2xBi2uAPrljEs5IcA53rcTiYTjCqjKlTHJT3GMKGG6CGTShzRbYJytig2r8GRF4xo47VkPsLcDzz66reru2lO6mr4c4VhPbNocKSLCLANzc5/d+bN7zKsj6VCqsK/C7/J5fz9soVLAgPQ1DtmUmGeWnc/jd8FZrYTrDprMJtEzN10Zcj2QTJkRkm6h9MyEqir3jCVrPaXm44EESuuQf7XedtxzCqzeQ/+BkFVvUNA0gJbFqweOmPT8r3/z3M1XyOAdI+OgH9iTTfWb/GjWJLsiRaZZUCu01Vk8OgYR3JA+SMv58g/P/Ij+di3GV38f8AAFv+tEOCf7N95ZI6XY5PbipHKWdWN8VwVrzHVVQCzQxCyboYrZY4Dt3f+WkJxBDDg+zgCw+5WQKQPXtp000s7BGmEUhS1ndl/tY9c7+RbuVloVPi+SP8xBkQC/5c1+rx0nb5iTCrZONmZnq3k+p0j+nCgOFJ2jrBdg58RHjMFANJcQdKtyFtrcgJq1JkECcpIivSH0xjEqwJpO6VEPUTnh8NN7I0a6NjeQzws7o1CpQsvyyiBnZ3ZNPBpfkxGzRkSBn7Ie7UfwOjq401glqq278/HQLFao/wkt5VsSL+2M3mmkg0UGLs08ml2Rdf5NApwk93va8N1nevn024EnZ4IPW80eoP4SkLjQw5AOo47vzHSKQxbszHkpCII+xwAWt2oIz7ok61ugDECUnhesQgl7N9rrWnJp6bOzsKDwg13At7g2J5lIbjRXSx+lsv8WKA5jWQDSeaAt3+Kbap/b1JXvEmaVC3S6e4AUMnmSD8vy3VzY3RjWui+6rPQxmRhCAPnTOL5X2KD5N2q/NIqcXmzRIvBK+LD+BWHXG/ArH4gWfhhwnj9s8DCSM497CAADNwlzDosWHzGXf5OTLzEoEdsPlkTOnRs2aoba/yoYPytqXamWb3mAC+LZNxcULavGk8ZYYiEEpKWsseE2nxSbrsE8UfVJPxanveks9hN3IovUyaMWDJEN5m+8iQcXDvox/AV3GqzW/IClLhq0UVfJYz2DDAc73mpnEuMwNpmVio+XzfJbCmDSD0gtZWY+bmOgGpRP506VTH5GAFr38MQ4tdQZqWXHFfgJ4WlkB9CQk45JWnQ5WJsF8wrcA1R9nT+Gt1+XiRMUQG+UYjJjGQqRGcdpv1k7JdDvC85TZyUJ1JzZk02h2sWMNyccMsx6OdHVDQ7vzF/25oouRw1XJVAITxQ8iT5j1Q4G/IRe3qT7ljTKkIWDG9q+cYzgHeNk/chcP/W2K0XknH6gToRXbF+R777AAy/bizSpkmd804a5f7txldGn+v6775JmmhCUBnwWY+IliykDEsj/hdVZATt0dfBj3QukBr+i4NdnjRqi5DfQ5+lP0fpPXgnslBOG/woqgkcUOW14hswpOgsCzmHYbLWgX6gHFCl2Ew3NTB4s3zTGf76jLv49EkWyW76isVE1/Iq3PkQDd6l5UquGtd1NApZ95kLyGAfRlSXXSL3+j7xuXjReSkZTBD7afBnzVebIj53DpFpY8eYAmJh2idlbGmcnznXUGkpUVVM2ewJRNUpnWfRtHUePkdMSyfcmZt4DBgLW3rmjBRTGgrardVpvvx7q5q/bFMyZARhC+gim5Ml15R5Ud1DIFAAAAA';
27
28  // Paint the embedded portrait immediately; only swap to the duty portrait
29
30  // after it has loaded, so slow or blocked CRM requests never leave a blank icon.
31
32  var DUTY_AVATAR = 'https://crm.fctelerp.cn/website-chat/public/duty-photo?page=' + encodeURIComponent(PAGE);
33
34  // Loading and offline states use the company identity. A staff portrait is
35  // shown only after CRM confirms that the scheduled person is currently online.
36  var FALLBACK_AVATAR = 'https://www.fctele.com/wp-content/uploads/2026/08/fctel-live-themes/feichang8090/images/logo.png?v=1787806619';
37
38  var avatarRequestId = 0;
39
40  var LANG = ((location.pathname.match(/^\/(fr|es|pt|ar|ru|de|ko|it|id|vi|th|tr|ja)(?:\/|$)/i)||[])[1]||'en').toLowerCase();
41
42  var TEXT = {
43
44    en:{launcher:'Online Consultation',launcherSub:'AI answers · Human supp
44ort',support:'FCTEL Online Support',assistantDrag:'AI assistant · Drag this bar to move',loading:'Loading today’s sales contact…',talk:'Talk to a person',fresh:'New conversation',placeholder:'Enter a product model, interface requirements, or application…',hint:'Enter to send · Shift+Enter for a new line',send:'Send',you:'You',sales:'Sales representative',notice:'Service notice',ai:'AI assistant',references:'Reference products',searching:'Searching the product catalogue…',contactFallback:'International sales support is available through this chat.',onDuty:'On-duty international sales: ',whatsapp:'WhatsApp',chatNow:'Chat now',email:'Email',phone:'Phone',qr:'WhatsApp QR code',scan:'Scan to chat on WhatsApp',hello:'Hello! I am the FCTEL AI assistant. Tell me the product model, interface quantity, or application, and I will help you or connect you with the on-duty sales representative.',unavailable:'The service is temporarily unavailable. Please try again shortly.',generic:'I could not verify enough public information for an accurate answer. Please provide the interface type, quantity, or application, or ask the on-duty sales representative for help.',staffOther:'A sales representative sent an earlier message in another language. Please request a reply in your selected language.',humanRequested:'Human support requested',starting:'Starting a new conversation…',sending:'Sending…'},
45
46    fr:{launcher:'Consultation en ligne',launcherSub:'Réponses IA · Assistance humaine',support:'Assistance FCTEL en ligne',assistantDrag:'Assistant IA · Faites glisser cette barre',loading:'Chargement du conseiller de garde…',talk:'Parler à un conseiller',fresh:'Nouvelle conversation',placeholder:'Saisissez un modèle, des interfaces ou une application…',hint:'Entrée pour envoyer · Maj+Entrée pour une nouvelle ligne',send:'Envoyer',you:'Vous',sales:'Conseiller commercial',notice:'Information de service',ai:'Assistant IA',references:'Produits de référence',searching:'Recherche dans le catalogue produits…',contactFallback:'Le service commercial international est disponible via ce chat.',onDuty:'Commercial international de garde : ',whatsapp:'WhatsApp',chatNow:'Discuter',email:'E-mail',phone:'Téléphone',qr:'Code QR WhatsApp',scan:'Scannez pour discuter sur WhatsApp',hello:'Bonjour ! Je suis l’assistant IA de FCTEL. Indiquez le modèle, le nombre d’interfaces ou l’application ; je vous aiderai ou vous mettrai en relation avec le commercial de garde.',unavailable:'Le service est temporairement indisponible. Veuillez réessayer dans un instant.',generic:'Je ne dispose pas d’assez d’informations publiques vérifiées pour répondre précisément. Indiquez le type d’interface, la quantité ou l’application, ou demandez l’aide du commercial de garde.',staffOther:'Un conseiller a envoyé un ancien message dans une autre langue. Demandez une réponse en français.',humanRequested:'Assistance humaine demandée',starting:'Démarrage d’une nouvelle conversation…',sending:'Envoi…'},
47
48    es:{launcher:'Consulta en línea',launcherSub:'Respuestas IA · Asistencia humana',support:'Soporte FCTEL en línea',assistantDrag:'Asistente IA · Arrastre esta barra',loading:'Cargando el asesor de guardia…',talk:'Hablar con una persona',fresh:'Nueva conversación',placeholder:'Introduzca un modelo, interfaces o aplicación…',hint:'Enter para enviar · Mayús+Enter para nueva línea',send:'Enviar',you:'Usted',sales:'Representante de ventas',notice:'Aviso de servicio',ai:'Asistente IA',references:'Productos de referencia',searching:'Buscando en el catálogo de productos…',contactFallback:'El equipo de ventas internacionales está disponible en este chat.',onDuty:'Ventas internacionales de guardia: ',whatsapp:'WhatsApp',chatNow:'Chatear',email:'Correo',phone:'Teléfono',qr:'Código QR de WhatsApp',scan:'Escanee para chatear por WhatsApp',hello:'¡Hola! Soy el asistente de IA de FCTEL. Indique el modelo, la cantidad de interfaces o la aplicación; le ayudaré o le pondré en contacto con el vendedor de guardia.',unavailable:'El servicio no está disponible temporalmente. Inténtelo de nuevo en breve.',generic:'No pude verificar suficie
48nte información pública para responder con precisión. Indique el tipo de interfaz, la cantidad o la aplicación, o solicite ayuda al vendedor de guardia.',staffOther:'Un representante envió un mensaje anterior en otro idioma. Solicite una respuesta en español.',humanRequested:'Asistencia humana solicitada',starting:'Iniciando una nueva conversación…',sending:'Enviando…'},
49
50    pt:{launcher:'Consulta online',launcherSub:'Respostas por IA · Suporte humano',support:'Suporte online FCTEL',assistantDrag:'Assistente de IA · Arraste esta barra',loading:'A carregar o consultor de serviço…',talk:'Falar com uma pessoa',fresh:'Nova conversa',placeholder:'Introduza um modelo, interfaces ou aplicação…',hint:'Enter para enviar · Shift+Enter para nova linha',send:'Enviar',you:'Você',sales:'Representante comercial',notice:'Aviso de serviço',ai:'Assistente de IA',references:'Produtos de referência',searching:'A pesquisar no catálogo de produtos…',contactFallback:'O suporte de vendas internacionais está disponível neste chat.',onDuty:'Vendas internacionais de serviço: ',whatsapp:'WhatsApp',chatNow:'Conversar',email:'E-mail',phone:'Telefone',qr:'Código QR do WhatsApp',scan:'Digitalize para conversar no WhatsApp',hello:'Olá! Sou o assistente de IA da FCTEL. Informe o modelo, a quantidade de interfaces ou a aplicação; ajudarei ou encaminharei para o vendedor de serviço.',unavailable:'O serviço está temporariamente indisponível. Tente novamente em breve.',generic:'Não encontrei informações públicas verificadas suficientes para uma resposta precisa. Informe o tipo de interface, quantidade ou aplicação, ou peça ajuda ao vendedor de serviço.',staffOther:'Um representante enviou uma mensagem anterior noutro idioma. Solicite uma resposta em português.',humanRequested:'Suporte humano solicitado',starting:'A iniciar uma nova conversa…',sending:'A enviar…'},
51
52    de:{launcher:'Online-Beratung',launcherSub:'KI-Antworten · Persönlicher Support',support:'FCTEL Online-Support',assistantDrag:'KI-Assistent · Leiste zum Verschieben ziehen',loading:'Zuständigen Berater laden…',talk:'Mit einem Mitarbeiter sprechen',fresh:'Neues Gespräch',placeholder:'Produktmodell, Schnittstellen oder Anwendung eingeben…',hint:'Enter zum Senden · Umschalt+Enter für neue Zeile',send:'Senden',you:'Sie',sales:'Vertriebsmitarbeiter',notice:'Servicehinweis',ai:'KI-Assistent',references:'Referenzprodukte',searching:'Produktkatalog wird durchsucht…',contactFallback:'Der internationale Vertrieb ist über diesen Chat erreichbar.',onDuty:'Internationaler Vertrieb im Dienst: ',whatsapp:'WhatsApp',chatNow:'Chat starten',email:'E-Mail',phone:'Telefon',qr:'WhatsApp-QR-Code',scan:'Scannen, um über WhatsApp zu chatten',hello:'Hallo! Ich bin der FCTEL KI-Assistent. Nennen Sie Modell, Schnittstellenanzahl oder Anwendung; ich helfe Ihnen oder verbinde Sie mit dem zuständigen Vertrieb.',unavailable:'Der Dienst ist vorübergehend nicht verfügbar. Bitte versuchen Sie es gleich erneut.',generic:'Für eine genaue Antwort liegen nicht genügend verifizierte öffentliche Informationen vor. Bitte nennen Sie Schnittstellentyp, Anzahl oder Anwendung oder fragen Sie den zuständigen Vertrieb.',staffOther:'Ein Mitarbeiter hat zuvor in einer anderen Sprache geantwortet. Bitte bitten Sie um eine Antwort auf Deutsch.',humanRequested:'Persönlicher Support angefordert',starting:'Neues Gespräch wird gestartet…',sending:'Wird gesendet…'},
53
54    it:{launcher:'Consulenza online',launcherSub:'Risposte IA · Assistenza umana',support:'Supporto online FCTEL',assistantDrag:'Assistente IA · Trascina questa barra',loading:'Caricamento del consulente di turno…',talk:'Parla con una persona',fresh:'Nuova conversazione',placeholder:'Inserisci modello, interfacce o applicazione…',hint:'Invio per spedire · Maiusc+Invio per nuova riga',send:'Invia',you:'Tu',sales:'Rappresentante commerciale',notice:'Avviso di servizio',ai:'Assistente IA',references:'Prodotti di riferimento',searching:'Ricerca nel catalogo prodotti…',contactFallback:'Il supporto vendite internazionali è disponibile in questa chat.',onDuty:'Vendite internazionali di turno: ',whatsapp:'WhatsApp',chatNow:'Chatta ora',email:'E-mail',phone:'Telefono',qr:'Codice QR WhatsApp',scan:'Scansiona per chattare su WhatsApp',hello:'Ciao! Sono l’assistente IA di FCTEL. Indica modello, numero di interfacce o a
54pplicazione; ti aiuterò o ti metterò in contatto con il commerciale di turno.',unavailable:'Il servizio è temporaneamente non disponibile. Riprova tra poco.',generic:'Non ho trovato informazioni pubbliche verificate sufficienti per una risposta precisa. Indica tipo di interfaccia, quantità o applicazione, oppure chiedi al commerciale di turno.',staffOther:'Un rappresentante ha inviato un messaggio precedente in un’altra lingua. Richiedi una risposta in italiano.',humanRequested:'Assistenza umana richiesta',starting:'Avvio di una nuova conversazione…',sending:'Invio…'},
55
56    ru:{launcher:'Онлайн-консультация',launcherSub:'Ответы ИИ · Поддержка специалиста',support:'Онлайн-поддержка FCTEL',assistantDrag:'ИИ-ассистент · Перетащите эту панель',loading:'Загрузка дежурного специалиста…',talk:'Связаться со специалистом',fresh:'Новый диалог',placeholder:'Введите модель, интерфейсы или область применения…',hint:'Enter — отправить · Shift+Enter — новая строка',send:'Отправить',you:'Вы',sales:'Менеджер по продажам',notice:'Сервисное сообщение',ai:'ИИ-ассистент',references:'Рекомендуемые продукты',searching:'Поиск по каталогу продукции…',contactFallback:'Международный отдел продаж доступен в этом чате.',onDuty:'Дежурный менеджер международных продаж: ',whatsapp:'WhatsApp',chatNow:'Написать',email:'Эл. почта',phone:'Телефон',qr:'QR-код WhatsApp',scan:'Отсканируйте для чата в WhatsApp',hello:'Здравствуйте! Я ИИ-ассистент FCTEL. Укажите модель, количество интерфейсов или применение — я помогу или свяжу вас с дежурным менеджером.',unavailable:'Сервис временно недоступен. Повторите попытку позже.',generic:'Недостаточно проверенной открытой информации для точного ответа. Укажите тип интерфейса, количество или применение либо обратитесь к дежурному менеджеру.',staffOther:'Предыдущий ответ менеджера был на другом языке. Попросите ответить по-русски.',humanRequested:'Запрошена помощь специалиста',starting:'Начинается новый диалог…',sending:'Отправка…'},
57
58    ar:{launcher:'استشارة عبر الإنترنت',launcherSub:'إجابات بالذكاء الاصطناعي · دعم بشري',support:'دعم FCTEL عبر الإنترنت',assistantDrag:'مساعد ذكي · اسحب هذا الشريط للتحريك',loading:'جارٍ تحميل موظف المبيعات المناوب…',talk:'التحدث مع موظف',fresh:'محادثة جديدة',placeholder:'أدخل طراز المنتج أو الواجهات أو التطبيق…',hint:'Enter للإرسال · Shift+Enter لسطر جديد',send:'إرسال',you:'أنت',sales:'ممثل المبيعات',notice:'إشعار الخدمة',ai:'المساعد الذكي',references:'منتجات مرجعية',searching:'جارٍ البحث في كتالوج المنتجات…',contactFallback:'فريق المبيعات الدولية متاح عبر هذه المحادثة.',onDuty:'موظف المبيعات الدولية المناوب: ',whatsapp:'واتساب',chatNow:'ابدأ المحادثة',email:'البريد الإلكتروني',phone:'الهاتف',qr:'رمز QR لواتساب',scan:'امسح الرمز للمحادثة عبر واتساب',hello:'مرحبًا! أنا مساعد FCTEL الذكي. أخبرني بطراز المنتج أو عدد الواجهات أو التطبيق، وسأساعدك أو أوصلك بموظف المبيعات المناوب.',unavailable:'الخدمة غير متاحة مؤقتًا. يرجى المحاولة بعد قليل.',generic:'لا تتوفر معلومات عامة موثقة كافية لإجابة دقيقة. يرجى تحديد نوع الواجهة والكمية أو التطبيق، أو طلب مساعدة موظف المبيعات المناوب.',staffOther:'أرسل ممثل المبيعات رسالة سابقة بلغة أخرى. يرجى طلب الرد باللغة العربية.',humanRequested:'تم طلب الدعم البشري',starting:'جارٍ بدء محادثة جديدة…',sending:'جارٍ الإرسال…'},
59
60    ko:{launcher:'온라인 상담',launcherSub:'AI 답변 · 상담원 지원',support:'FCTEL 온라인 지원',assistantDrag:'AI 상담원 · 이 막대를 끌어 이동',loading:'당번 영업 담당자 불러오는 중…',talk:'상담원 연결',fresh:'새 대화',placeholder:'제품 모델, 인터페이스 또는 적용 분야를 입력하세요…',hint:'Enter 전송 · Shift+Enter 줄바꿈',send:'전송',you:'고객',sales:'영업 담당자',notice:'서비스 안내',ai:'AI 상담원',references:'참고 제품',searching:'제품 카탈로그 검색 중…',contactFallback:'해외 영업팀이 이 채팅을 통해 지원합니다.',onDuty:'당번 해외 영업 담당자: ',whatsapp:'WhatsApp',chatNow:'채팅 시작',email:'이메일',phone:'전화',qr:'WhatsApp QR 코드',scan:'스캔하여 WhatsApp으로 상담하세요',hello:'안녕하세요! FCTEL AI 상담원입니다. 제품 모델, 인터페이스 수량 또는 적용 분야를 알려주시면 답변하거나 당번 영업 담당자에게 연결해 드립니다.',unavailable:'서비스를 일시적으로 사용할 수 없습니다. 잠시 후 다시 시도하세요.',generic:'정확한 답변을 위한 검증된 공개 정보가 충분하지 않습니다. 인터페이스 종류, 수량 또는 적용 분야를 알려주시거나 당번 영업 담당자에게 문의하세요.',staffOther:'영업 담당자의 이전 메시지가 다른 언어로 작성되었습니다. 한국어 답변을 요청하세요.',humanRequested:'상담원 지원 요청됨',starting:'새 대화를 시작하는 중…',sending:'전송 중…'},
61
62    id:{launcher:'Konsultasi Online',launcherSub:'Jawaban AI · Dukungan manusia',support:'Dukungan Online FCTEL',assistantDrag:'Asisten AI · Seret bilah ini',loading:'Memuat petugas penjualan…',talk:'Bicara dengan petugas',fresh:'Percakapan baru',placeholder:'Masukkan model produk, antarmuka, atau aplikasi…',hint:'Enter untuk kirim · Shift+Enter untuk baris baru',send:'Kirim',you:'Anda',sales:'Staf penjualan',notice:'Pemberitahuan layanan',ai:'Asisten AI',references:'Produk referensi',searching:'Mencari katalog produk…',contactFallback:'Tim penjualan internasional tersedia melalui chat ini.',onDuty:'Petugas penjualan internasional: ',whatsapp:'WhatsApp',chatNow:'Chat sekarang',email:'Email',phone:'Telepon',qr:'Kode QR WhatsApp',scan:'Pindai untuk chat melalui WhatsApp',hello:'Halo! Saya asisten AI FCTEL. Beri tahu model produk, jumlah antarmuka, atau aplikasi; saya akan membantu atau menghubungkan Anda dengan petugas penjualan.',unavailable:'Layanan sementara tidak tersedia. Silakan coba lagi sebentar lagi.',generic:'Informasi publik terverifikasi belum cukup untuk jawaban yang akurat. Beri tahu jenis antarmuka, jumlah, atau aplikasi, atau minta bantuan petugas penjualan.',staffOther:'Staf penjualan mengirim pesan sebelumnya dalam bahasa lain. Mohon minta balasan dalam Bahasa Indonesia.',humanRequested:'Dukungan manusia diminta',starting:'Memulai percakapan baru…',sending:'Mengirim…'}
63,
64    vi:{"launcher": "Tư vấn trực tuyến", "launcherSub": "AI trả lời · Nhân viên hỗ trợ", "support": "Hỗ trợ trực tuyến FCTEL", "assistantDrag": "Trợ lý AI · Kéo thanh này để di chuyển", "loading": "Đang tải thông tin nhân viên kinh doanh…", "talk": "Nói chuyện với nhân viên", "fresh": "Cuộc trò chuyện mới", "placeholder": "Nhập mã sản phẩm, yêu cầu giao diện hoặc ứng dụng…", "hint": "Enter để gửi · Shift+Enter để xuống dòng", "send": "Gửi", "you": "Bạn", "sales": "Nhân viên kinh doanh", "notice": "Thông báo dịch vụ", "ai": "Trợ lý AI", "references": "Sản phẩm tham khảo", "searching": "Đang tìm trong danh mục sản phẩm…", "contactFallback": "Đội ngũ kinh doanh quốc tế sẵn sàng hỗ trợ qua cuộc trò chuyện này.", "onDuty": "Nhân viên kinh doanh quốc tế trực: ", "whatsapp": "WhatsApp", "chatNow": "Trò chuyện ngay", "email": "Email", "phone": "Điện thoại", "qr": "Mã QR WhatsApp", "scan": "Quét để trò chuyện qua WhatsApp", "hello": "Xin chào! Tôi là trợ lý AI của FCTEL. Hãy cho tôi biết mã sản phẩm, số lượng giao diện hoặc ứng dụng;
64 tôi sẽ hỗ trợ bạn hoặc kết nối với nhân viên kinh doanh.", "unavailable": "Dịch vụ tạm thời không khả dụng. Vui lòng thử lại sau.", "generic": "Tôi chưa có đủ thông tin đã xác minh để trả lời chính xác. Vui lòng cung cấp loại giao diện, số lượng hoặc ứng dụng, hoặc liên hệ nhân viên kinh doanh.", "staffOther": "Nhân viên kinh doanh đã gửi tin nhắn trước đó bằng ngôn ngữ khác. Vui lòng yêu cầu họ trả lời bằng tiếng Việt.", "humanRequested": "Đã yêu cầu hỗ trợ từ nhân viên", "starting": "Đang bắt đầu cuộc trò chuyện mới…", "sending": "Đang gửi…"},
65    th:{"launcher": "ปรึกษาออนไลน์", "launcherSub": "คำตอบจาก AI · เจ้าหน้าที่ช่วยเหลือ", "support": "ฝ่ายสนับสนุนออนไลน์ FCTEL", "assistantDrag": "ผู้ช่วย AI · ลากแถบนี้เพื่อย้าย", "loading": "กำลังโหลดข้อมูลพนักงานขาย…", "talk": "คุยกับเจ้าหน้าที่", "fresh": "เริ่มการสนทนาใหม่", "placeholder": "ระบุรุ่นสินค้า ประเภทพอร์ต หรือการใช้งาน…", "hint": "Enter เพื่อส่ง · Shift+Enter เพื่อขึ้นบรรทัดใหม่", "send": "ส่ง", "you": "คุณ", "sales": "พนักงานขาย", "notice": "ประกาศบริการ", "ai": "ผู้ช่วย AI", "references": "สินค้าที่เกี่ยวข้อง", "searching": "กำลังค้นหาแคตตาล็อกสินค้า…", "contactFallback": "ทีมขายต่างประเทศพร้อมให้ความช่วยเหลือผ่านแชตนี้", "onDuty": "พนักงานขายต่างประเทศที่เข้าเวร: ", "whatsapp": "WhatsApp", "chatNow": "แชตเลย", "email": "อีเมล", "phone": "โทรศัพท์", "qr": "คิวอาร์โค้ด WhatsApp", "scan": "สแกนเพื่อแชตผ่าน WhatsApp", "hello": "สวัสดี! ฉันเป็นผู้ช่วย AI ของ FCTEL โปรดแจ้งรุ่นสินค้า จำนวนพอร์ต หรือการใช้งาน ฉันจะช่วยตอบหรือส่งต่อให้พนักงานขาย", "unavailable": "บริการไม่พร้อมใช้งานชั่วคราว โปรดลองอีกครั้งในภายหลัง", "generic": "ฉันยังไม่มีข้อมูลที่ตรวจสอบได้เพียงพอสำหรับคำตอบที่ถูกต้อง โปรดแจ้งประเภทพอร์ต จำนวน หรือการใช้งาน หรือติดต่อพนักงานขาย", "staffOther": "พนักงานขายเคยส่งข้อความเป็นภาษาอื่น โปรดขอให้ตอบเป็นภาษาไทย", "humanRequested": "ขอความช่วยเหลือจากเจ้าหน้าที่แล้ว", "starting": "กำลังเริ่มการสนทนาใหม่…", "sending": "กำลังส่ง…"},
66    tr:{"launcher": "Çevrimiçi danışma", "launcherSub": "Yapay zekâ yanıtları · İnsan desteği", "support": "FCTEL çevrimiçi destek", "assistantDrag": "Yapay zekâ asistanı · Taşımak için sürükleyin", "loading": "Görevli satış temsilcisi yükleniyor…", "talk": "Bir temsilciyle görüş", "fresh": "Yeni görüşme", "placeholder": "Ürün modelini, arayüz gereksinimlerini veya uygulamayı yazın…", "hint": "Göndermek için Enter · Yeni satır için Shift+Enter", "send": "Gönder", "you": "Siz", "sales": "Satış temsilcisi", "notice": "Hizmet bildirimi", "ai": "Yapay zekâ asistanı", "references": "İlgili ürünler", "searching": "Ürün kataloğunda aranıyor…", "contactFallback": "Uluslararası satış ekibimiz bu sohbetten yardımcı olabilir.", "onDuty": "Görevli uluslararası satış temsilcisi: ", "whatsapp": "WhatsApp", "chatNow": "Şimdi sohbet et", "email": "E-posta", "phone": "Telefon", "qr": "WhatsApp QR kodu", "scan": "WhatsApp üzerinden sohbet etmek için tarayın", "hello": "Merhaba! Ben FCTEL yapay zekâ asistanıyım. Ürün modelini, arayüz sayısını veya uygulamanızı belirtin; size yardımcı olayım ya da görevli satış temsilcisine yönlendireyim.", "unavailable": "Hizmet geçici olarak kullanılamıyor. Lütfen biraz sonra tekrar deneyin.", "generic": "Doğru yanıt için yeterli doğrulanmış bilgi bulamadım. Lütfen arayüz türünü, miktarı veya uygulamayı belirtin ya da satış temsilcisinden yardım isteyin.", "staffOther": "Satış temsilcisi önceki bir mesajı başka dilde gönderdi. Lütfen Türkçe yanıt isteyin.", "humanRequested": "İnsan desteği istendi", "starting": "Yeni görüşme başlatılıyor…", "sending": "Gönderiliyor…"},
67    ja:{"launcher": "オンライン相談", "launcherSub": "AIの回答 · 担当者によるサポート", "support": "FCTELオンラインサポート", "assistantDrag": "AIアシスタント · このバーをドラッグして移動", "loading": "担当営業の情報を読み込み中…", "talk": "担当者に相談", "fresh": "新しい会話", "placeholder": "製品型番、インターフェースの要件、用途を入力してください…", "hint": "Enterで送信 · Shift+Enterで改行", "send": "送信", "you": "あなた", "sales": "営業担当者", "notice": "サービスのお知らせ", "ai": "AIアシスタント", "references": "関連製品", "searching": "製品カタログを検索中…", "contactFallback": "海外営業チームがこのチャットで対応ã
67—ます。", "onDuty": "本日の海外営業担当: ", "whatsapp": "WhatsApp", "chatNow": "チャットを開始", "email": "メール", "phone": "電話", "qr": "WhatsAppのQRコード", "scan": "スキャンしてWhatsAppで相談", "hello": "こんにちは。FCTELのAIアシスタントです。製品型番、インターフェースの数、用途をお知らせください。ご案内するか、担当営業につなぎます。", "unavailable": "サービスを一時的に利用できません。しばらくしてから再度お試しください。", "generic": "正確に回答するための確認済み情報が不足しています。インターフェースの種類、数量、用途をお知らせいただくか、担当営業にお問い合わせください。", "staffOther": "営業担当者の以前のメッセージは別の言語です。日本語での返信をご依頼ください。", "humanRequested": "担当者への相談を依頼しました", "starting": "新しい会話を開始しています…", "sending": "送信中…"}
68  };
69
70  var I18N = TEXT[LANG] || TEXT.en;
71
72  function t(key){return I18N[key] || TEXT.en[key] || key;}
73
74  var STORAGE = 'fctel-foreign-chat-v2-' + LANG;
75
76  var conversation = null, open = false, busy = false, timer = null, last = '', staffOnline = false, activeMode = 'ai';
77
78  var invite={closes:0,engaged:false,shown:false},inviteTimer=null;
79
80  try { conversation = JSON.parse(localStorage.getItem(STORAGE) || 'null'); } catch (_) {}
81
82  try { invite=JSON.parse(sessionStorage.getItem('fctel-en-chat-invitation-v1')||'null')||invite; } catch (_) {}
83
84  if (!conversation || !conversation.id || !conversation.token) conversation = null;
85
86
87
88  var host = document.createElement('div');
89
90  host.id = 'fctel-en-chat';
91
92  document.body.appendChild(host);
93
94  var root = host.attachShadow ? host.attachShadow({mode: 'open'}) : host;
95
96  root.innerHTML = '<style>'+
97
98    ':host{all:initial;font-family:Inter,Arial,sans-serif;color:#243746;position:relative;z-index:2147482000}*{box-sizing:border-box}button,textarea,input{font:inherit}button{cursor:pointer}[hidden]{display:none!important}'+
99
100    '.launch{position:fixed;display:flex;align-items:center;gap:10px;width:224px;height:60px;padding:7px 14px 7px 7px;border:1px solid #6da2b2;border-radius:31px;background:linear-gradient(120deg,#254c66,#3c8090);color:#fff;box-shadow:0 10px 30px #17394d45;touch-action:none;user-select:none;cursor:grab;overflow:hidden}.avatar{position:relative;display:block;width:46px;height:46px;min-width:46px;border:2px solid #dff5f3;border-radius:50%;background:#eefbfa;object-fit:cover;pointer-events:none;clip-path:circle(50% at 50% 50%)}.launch-avatar{object-fit:cover;object-position:center 14%;background:transparent}
100.launch-copy{display:block!important;min-width:0;text-align:left}.dock-copy{display:none!important}.launch strong{display:block;font-size:14px;line-height:18px;white-space:nowrap}.launch small{display:block;color:#d8ebef;font-size:10px;line-height:14px;margin-top:1px;white-space:nowrap}.launch[data-dock]{width:224px;height:60px;padding:7px 14px 7px 7px;flex-direction:row;border-radius:31px}.launch[data-dock] .launch-copy{display:block!important}.launch[data-dock] strong{writing-mode:horizontal-tb;text-orientation:mixed;white-space:nowrap}.launch[data-dock] small{display:block;white-space:nowrap}.launch[aria-expanded="false"]{animation:fctelChatPulse 2s ease-in-out infinite}.launch[aria-expanded="false"] .avatar{animation:fctelAvatarGlow 2s ease-in-out infinite}@keyframes fctelChatPulse{0%,100%{box-shadow:0 10px 28px #17394d55,0 0 0 0 rgba(34,211,238,.8);filter:brightness(1) saturate(1)}22%{box-shadow:0 14px 38px #17394d88,0 0 0 15px rgba(34,211,238,0);filter:brightness(1.22) saturate(1.28)}36%{box-shadow:0 11px 30px #17394d66,0 0 0 0 rgba(255,200,64,.75);filter:brightness(1.08) saturate(1.12)}58%{box-shadow:0 15px 40px #17394d88,0 0 0 12px rgba(255,200,64,0);filter:brightness(1.2) saturate(1.25)}}@keyframes fctelAvatarGlow{0%,100%{border-color:#dff5f3;box-shadow:0 0 0 0 rgba(223,245,243,0)}22%{border-color:#fff;box-shadow:0 0 0 7px rgba(34,211,238,.28)}58%{border-color:#fff5b8;box-shadow:0 0 0 6px rgba(255,200,64,.24)}}'+
101
102    '.launch[data-dock="left"],.launch[data-dock="right"]{width:56px;height:132px;padding:3px 1px;display:block;border-radius:0 14px 14px 0}.launch[data-dock="right"]{border-radius:14px 0 0 14px}.launch[data-dock="left"] .avatar,.launch[data-dock="right"] .avatar{position:absolute;top:5px;left:50%;width:30px;height:30px;min-width:30px;transform:translateX(-50%)}.launch[data-dock="left"] .launch-copy,.launch[data-dock="right"] .launch-copy{display:none!important}.launch[data-dock="left"] .dock-copy,.launch[data-dock="right"] .dock-copy{position:absolute;top:40px;bottom:4px;left:0;width:100%;display:grid!important;grid-template-columns:19px 17px;justify-content:center;align-items:start;gap:2px;text-align:center}.launch[data-dock="left"] .dock-primary,.launch[data-dock="right"] .dock-primary{display:block;writing-mode:vertical-rl;text-orientation:mixed;letter-spacing:0;line-height:19px;font-size:9px;white-space:nowrap}.launch[data-dock="left"] .dock-secondary,.launch[data-dock="right"] .dock-secondary{display:block;writing-mode:vertical-rl;text-orientation:mixed;letter-spacing:0;line-height:17px;font-size:8px;font-weight:700;color:#e4f5f7;white-space:nowrap;margin:0}.launch[data-dock="left"] .dock-secondary::first-letter,.launch[data-dock="right"] .dock-secondary::first-letter{font-weight:900}.launch[data-dock="left"][aria-expanded="false"],.launch[data-dock="right"][aria-expanded="false"]{animation:fctelDockPulse 2.6s ease-in-out infinite;box-shadow:0 8px 22px rgba(23,57,77,.35)}.launch[data-dock="left"][aria-expanded="false"] .avatar,.launch[data-dock="right"][aria-expanded="false"] .avatar{animation:fctelAvatarGlow 2.6s ease-in-out infinite}@keyframes fctelDockPulse{0%,100%{background:linear-gradient(120deg,#254c66,#3c8090);box-shadow:0 8px 22px rgba(23,57,77,.35),0 0 0 0 rgba(34,211,238,.5);filter:brightness(1)}35%{background:linear-gradient(120deg,#286a82,#25a3af);box-shadow:0 11px 30px rgba(23,57,77,.5),0 0 0 7px rgba(34,211,238,0);filter:brightness(1.18)}65%{background:linear-gradient(120deg,#315b70,#418b91);box-shadow:0 9px 26px rgba(23,57,77,.42),0 0 0 5px rgba(255,200,64,0);filter:brightness(1.08)}}' +
103
104    '.panel{position:fixed;right:18px;bottom:88px;width:430px;height:620px;min-width:340px;min-height:430px;max-width:calc(100vw - 24px);max-height:calc(100vh - 105px);display:flex;flex-direction:column;background:#fff;border:1px solid #d8e5eb;border-radius:19px;box-shadow:0 22px 70px #16354b35;overflow:visible;font-size:14px}'+
105
106    'header{position:relative;display:flex;align-items:center;gap:10px;min-height:76px;padding:12px 14px 12px 108px;background:linear-gradient(110deg,#233d51,#356476);color:#fff;cursor:move;touch-action:none;user-select:none;border-radius:19px 19px 0 0}header .avatar{position:absolute;
106left:18px;top:-18px;width:82px;height:82px;min-width:82px;border-width:3px;box-shadow:0 7px 18px #17394d55;object-fit:cover;object-position:center 10%;clip-path:circle(50% at 50% 50%)}header div{flex:1}header strong{display:block;font-size:15px}header small{color:#dce9ed}.close{width:30px;height:30px;border:1px solid #ffffff45;border-radius:50%;background:#ffffff12;color:#fff;font-size:22px;line-height:1}'+
107
108    '.contact{padding:9px 14px;background:#edf6f7;border-bottom:1px solid #dcebee;color:#315e76;font-size:12px;line-height:1.45}.contact strong{display:block;color:#244f64;white-space:nowrap}.contact-line{display:flex;align-items:center;flex-wrap:wrap;column-gap:14px;row-gap:4px;margin-top:3px}.contact-item{display:inline-flex;align-items:center;gap:4px;min-width:0}.contact-label{color:#526f7f;font-size:10px;font-weight:600}.contact a,.qr-toggle{display:inline-flex;align-items:center;gap:5px;color:#1c6783;font-weight:700;text-decoration:none;border:0;background:none;padding:0;font-size:11px;white-space:nowrap}.contact a:hover,.qr-toggle:hover{text-decoration:underline}.qr-icon{width:14px;height:14px;flex:0 0 14px;fill:currentColor}.qr-card{display:none;margin-top:8px;padding:9px;background:#fff;border:1px solid #d7e6eb;border-radius:10px;text-align:center}.qr-card.show{display:block}.qr-card img{display:block;width:150px;height:150px;object-fit:contain;margin:0 auto 5px}.qr-card span{font-size:11px;color:#526b79}'+
109
110    '.mode-tabs{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;padding:9px 12px;background:#fff;border-bottom:1px solid #e2ebef}.mode-tabs button{padding:8px 5px;border:1px solid #cbdde6;border-radius:9px;background:#fff;color:#315e76;font-size:11px;font-weight:700}.mode-tabs button.active{background:#2e657d;color:#fff;border-color:#2e657d}.mode-tabs button[hidden]{display:none}.chat-view{display:flex;flex:1;min-height:0;flex-direction:column}.messages{flex:1;overflow:auto;padding:14px;background:linear-gradient(160deg,#f5f8fb,#f5f7f7)}.msg{max-width:94%;margin:0 0 12px;padding:11px 13px;border:1px solid #e0e9ee;border-radius:13px;background:#fff;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}.msg.user{margin-left:auto;background:#95ec69;border-color:#85d75f;color:#1f2e1c}.msg.user b{color:#365b2a}.msg.system{font-size:12px;color:#627784}.msg b{display:block;margin-bottom:5px;font-size:11px;color:#527485}.msg a{color:#176989;font-weight:700}.sources{margin-top:10px;padding-top:9px;border-top:1px dashed #cfdee5;white-space:normal}.sources-title{font-size:11px;color:#718795;margin-bottom:5px}.sources a{display:block;position:relative;padding:4px 24px 4px 17px;border-radius:7px;text-decoration:none;line-height:1.35}.sources a:before{content:"•";position:absolute;left:4px}.sources a:after{content:"↗";position:absolute;right:6px}.sources a:hover{background:#edf6f8;text-decoration:underline}.inquiry-view{flex:1;overflow:auto;padding:15px;background:#f7fafb}.inquiry-intro{margin:0 0 12px;color:#526b79;font-size:12px;line-height:1.5}.inquiry-form{padding:0}.field{display:block;margin:0 0 10px}.field span{display:block;margin-bottom:4px;color:#294b5c;font-size:11px;font-weight:700}.field input,.field textarea{width:100%;padding:9px 10px;border:1px solid #cddbe3;border-radius:9px;background:#fff;outline:0}.field textarea{height:88px}.field input:focus,.field textarea:focus{border-color:#5389a1;box-shadow:0 0 0 3px #5389a118}.inquiry-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 9px}.inquiry-submit{width:100%;padding:10px;border:0;border-radius:9px;background:#cf202b;color:#fff;font-weight:800}.inquiry-note{margin:8px 0 0;color:#71828c;font-size:10px}.inquiry-success{padding:18px;border:1px solid #bde4d3;border-radius:12px;background:#effaf5;color:#25634a;line-height:1.6}.resize-handle{position:absolute;z-index:5;display:block;background:transparent}.resize-right{top:80px;right:-6px;bottom:14px;width:12px;cursor:ew-resize}.resize-bottom{left:14px;right:14px;bottom:-6px;height:12px;cursor:ns-resize}.resize-corner{right:-8px;bottom:-8px;width:22px;height:22px;cursor:nwse-resize}.resize-corner:after{content:"";position:absolute;right:5px;bottom:5px;width:8px;height:8px;border-right:2px solid #6c93a3;border-bottom:2px solid #6c93a3}'+
111
112    '.tools{display:flex;gap:8px;padding:8px 14px;border-top:1px solid #e5edf1}.tools button{padding:6px 12px;border:1px solid #cbdde6;border-radius:20px;background:#fff;color:#315e76;font-size:12px}.tools .human{display:none}.status{min-height:18px;padding:0 14px;color:#87602f;font-size:11px}.chat-form{padding:5px 14px 12px}.chat-input{width:100%;height:66px;padding:10px 11px;resize:vertical;border:1px solid #cddbe3;border-radius:12px;outline:0}.chat-input:focus{border-color:#5389a1;box-shadow:0 0 0 3px #5389a118}.sendrow{display:flex;align-items:center;gap:8px;margin-top:7px}.sendrow small{flex:1;color:#75838c;font-size:9px}.send{padding:8px 18px;border:0;border-radius:9px;background:linear-gradient(120deg,#315f79,#438297);color:#fff;font-weight:700}button:disabled{opacity:.55;cursor:wait}'+
113
114    '@media(max-width:520px){.panel{inset:34px 8px 8px;width:auto;height:auto;min-width:0;min-height:0;max-width:none;max-height:none;border-radius:14px}header{padding-left:92px;min-height:64px}header .avatar{left:12px;top:-14px;width:72px;height:72px;min-width:72px}.resize-handle{display:none}.launch{width:174px;height:52px;padding:5px 10px 5px 5px;gap:7px}.launch .avatar{width:40px;height:40px;min-width:40px}.launch strong{font-size:12px;line-height:15px}.launch small{font-size:9px;line-height:11px}.launch[data-dock="left"],.launch[data-dock="right"]{width:54px;height:128px;padding:3px 1px;border-radius:0 14px 14px 0;overflow:hidden}.launch[data-dock="right"]{border-radius:14px 0 0 14px}.launch[data-dock="left"] .avatar,.launch[data-dock="right"] .avatar{top:5px;width:30px;height:30px;min-width:30px}.launch[data-dock="left"] .dock-copy,.launch[data-dock="right"] .dock-copy{top:39px;bottom:4px;grid-template-columns:18px 16px;gap:2px}.launch[data-dock="left"] .dock-primary,.launch[data-dock="right"] .dock-primary{font-size:9px;line-height:18px}.launch[data-dock="left"] .dock-secondary,.launch[data-dock="right"] .dock-secondary{font-size:8px;line-height:16px}}@media(prefers-reduced-motion:reduce){.launch[aria-expanded="false"],.launch[aria-expanded="false"] .avatar{animation:none!important}}' +
115
116    '</style><button class="launch" type="button" aria-expanded="false" title="Click to chat. Drag to dock on any edge."><img class="avatar launch-avatar" src="'+FALLBACK_AVATAR+'" alt="On-duty sales representative"><span class="launch-copy"><strong>Online Consultation</strong><small>
116AI answers · Human support</small></span><span class="dock-copy" aria-hidden="true"><strong class="dock-primary">Online Chat</strong><small class="dock-secondary">AI + Human</small></span></button>'+
117
118    '<section class="panel" hidden role="dialog" aria-label="FCTEL online customer service"><header><img class="avatar panel-avatar" src="'+FALLBACK_AVATAR+'" alt="On-duty sales representative"><div><strong>FCTEL Online Support</strong><small>AI assistant · Drag this bar to move</small></div><button class="close" type="button" aria-label="Close">×</button></header><div class="contact">Loading today\'s sales contact…</div><div class="mode-tabs"><button class="mode-human" type="button">Chat with sales</button><button class="mode-inquiry" type="button">Leave a message</button><button class="mode-ai" type="button">Ask AI</button></div><div class="chat-view"><div class="messages" role="log" aria-live="polite"></div><div class="tools"><button class="human" type="button">Talk to a person</button><button class="fresh" type="button">New conversation</button></div><div class="status" role="status"></div><form class="chat-form"><textarea class="chat-input" maxlength="2000" required aria-label="Your question" placeholder="Enter a product model, interface requirements, or application…"></textarea><div class="sendrow"><small>Enter to send · Shift+Enter for a new line</small><button class="send" type="submit">Send</button></div></form></div><div class="inquiry-view" hidden><p class="inquiry-intro">Leave your contact details and requirements. Our sales team will reply by email or phone.</p><form class="inquiry-form"><div class="inquiry-grid"><label class="field"><span>Name *</span><input name="name" maxlength="100" required autocomplete="name"></label><label class="field"><span>Email *</span><input name="email" type="email" maxlength="200" required autocomplete="email"></label></div><div class="inquiry-grid"><label class="field"><span>WhatsApp / Phone</span><input name="phone" maxlength="80" autocomplete="tel"></label><label class="field"><span>Product</span><input name="product" maxlength="200"></label></div><label class="field"><span>Project requirements *</span><textarea name="requirements" maxlength="1500" minlength="5" required placeholder="Interfaces, quantity, application, delivery country or other requirements"></textarea></label><button class="inquiry-submit" type="submit">Send inquiry</button><p class="inquiry-note">We use your information only to respond to this inquiry.</p><div class="inquiry-status" role="status"></div></form><div class="inquiry-success" hidden><strong>Thank you. Your inquiry has been sent.</strong><br>Our international sales team will contact you using the details provided.</div></div><i class="resize-handle resize-right" data-resize="right" title="Drag to resize width"></i><i class="resize-handle resize-bottom" data-resize="bottom" title="Drag to resize height"></i><i class="resize-handle resize-corner" data-resize="corner" title="Drag to resize width and height"></i></section>';
119
120
121
122  var DOCK_TEXT={en:['Chat Now','AI + Human'],fr:['Chat','IA + Humain'],es:['Chat','IA + Humano'],pt:['Chat','IA + Humano'],de:['Chat','KI + Mensch'],it:['Chat','IA + Umano'],ru:['Чат','ИИ + Агент'],ar:['دردشة','AI + موظف'],ko:['상담','AI + 상담원'],id:['Chat','AI + Staf'],vi:['Trò chuyện','AI + nhân viên'],th:['แชต','AI + เจ้าหน้าที่'],tr:['Sohbet','AI + temsilci'],ja:['チャット','AI+担当者']};
123
124  function $(selector) { return root.querySelector(selector); }
125
126  function localizeUi(){
127
128    var panel=$('.panel');if(panel)panel.dir=LANG==='ar'?'rtl':'ltr';
129
130    $('.launch strong').textContent=t('launcher');$('.launch small').textContent=t('launcherSub');var dockText=DOCK_TEXT[LANG]||DOCK_TEXT.en;$('.dock-primary').textContent=dockText[0];$('.dock-secondary').textContent=dockText[1];
131
132    $('header strong').textContent=t('support');$('header small').textContent=t('assistantDrag');
133
134    $('.contact').textContent=t('loading');$('.human').textContent=t('talk');$('.fresh').textContent=t('fresh');
135
136    $('.chat-input').placeholder=t('placeholder');$('.sendrow small').textContent=t('hint');$('.send').textContent=t('send');
137
138  }
139
140  localizeUi();
141
142  function status(text) { $('.status').textContent = text || ''; }
143
144  function pageProductLabel(){
145    var model=document.querySelector('.fctel-product-model-value,[class*="product-model"]'),heading=document.querySelector('h1');
146    var value=(model&&model.textContent||'').replace(/^\s*(?:model|型号)\s*[::]?\s*/i,'').trim();
147    if(!value)value=(heading&&heading.textContent||document.title||'').replace(/\s+/g,' ').trim();
148    return value.slice(0,200);
149  }
150
151  function setMode(mode){
152    activeMode=mode;
153    var inquiry=mode==='inquiry';
154    $('.chat-view').hidden=inquiry;$('.inquiry-view').hidden=!inquiry;
155    root.querySelectorAll('.mode-tabs button').forEach(function(button){button.classList.toggle('active',button.classList.contains('mode-'+mode));});
156    if(mode==='human')$('.chat-input').placeholder='Tell our sales team the product, quantity, application, or quotation you need…';
157    else if(mode==='ai')$('.chat-input').placeholder=t('placeholder');
158    if(!inquiry)setTimeout(function(){$('.chat-input').focus();}
158,0);
159  }
160
161  function applyAvailability(contact){
162    staffOnline=contact.staff_online===true;
163    $('.mode-human').hidden=!staffOnline;
164    setMode(staffOnline?'human':'inquiry');
165  }
166
167  function englishError(text) {
168
169    text = String(text || '');
170
171    return /[\u3400-\u9fff\ufffd]/.test(text) ? t('unavailable') : text;
172
173  }
174
175  function escapeHtml(text) { var d=document.createElement('div');d.textContent=text||'';return d.innerHTML; }
176
177  function safeRich(text) {
178
179    var html=escapeHtml(text).replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>');
180
181    return html.replace(/\[([^\]]+)\]\((https:\/\/(?:www\.)?fctele\.com\/[^\s)]+)\)/gi,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');
182
183  }
184
185  function englishMessage(message) {
186
187    var text=String(message.body||'');
188
189    if(message.role==='system')return t('hello');
190
191    if(LANG==='ja'&&/[\u3040-\u30ff]/.test(text))return text;
192
193    if(!/[\u3400-\u9fff]/.test(text))return text;
194
195    if(message.role==='ai')return t('generic');
196
197    if(message.role==='staff')return t('staffOther');
198
199    return text;
200
201  }
202
203  var translationCache={};
204
205  function translateChunk(text){
206
207    if(LANG==='en'||!text)return Promise.resolve(text);
208
209    var key=LANG+'|'+text;if(translationCache[key])return Promise.resolve(translationCache[key]);
210
211    var url='https://api.mymemory.translated.net/get?q='+encodeURIComponent(text)+'&langpair=en|'+encodeURIComponent(LANG);
212
213    return fetch(url,{credentials:'omit'}).then(function(r){if(!r.ok)throw new Error('translate');return r.json();}).then(function(data){var out=data&&data.responseData&&data.responseData.translatedText;if(!out||Number(data.responseStatus)!==200||/MYMEMORY WARNING|DAILY LIMIT/i.test(out))throw new Error('translate');translationCache[key]=out;return out;});
214
215  }
216
217  function translateAi(text){
218
219    if(LANG==='en'||!text)return Promise.resolve(text);
220
221    // The CRM may already honor the requested locale. Do not translate that
222    // answer a second time, particularly for Japanese and Thai.
223    var targetScript={vi:/[ăâđêôơưạảãẹẻẽịỉĩọỏõụủũỵỷỹ]/i,th:/[\u0e00-\u0e7f]/,tr:/[çğıöşü]/i,ja:/[\u3040-\u30ff]/,ru:/[\u0400-\u04ff]/,ar:/[\u0600-\u06ff]/,ko:/[\uac00-\ud7af]/};
224    if(targetScript[LANG]&&targetScript[LANG].test(String(text).slice(0,240)))return Promise.resolve(text);
225
226    // The translation endpoint rejects long requests. Split the AI reply into
227    // short clauses while keeping whitespace, so a long technical answer does
228    // not fall back to English merely because one paragraph exceeds its limit.
229    var pieces=String(text).split(/(\n\s*\n)/),short=[];
230    pieces.forEach(function(piece){
231      if(!piece.trim()){short.push(piece);return;}
232      while(piece.length>400){
233        var cut=Math.max(piece.lastIndexOf('. ',400),piece.lastIndexOf('。',400),piece.lastIndexOf('! ',400),piece.lastIndexOf('? ',400),piece.lastIndexOf(' ',400));
234        if(cut<180)cut=400;
235        short.push(piece.slice(0,cut+1));piece=piece.slice(cut+1);
236      }
237      if(piece)short.push(piece);
238    });
239    var jobs=short.map(function(piece){return !piece.trim()?Promise.resolve(piece):translateChunk(piece);});
240
241    return Promise.all(jobs).then(function(parts){return parts.join('');});
242
243  }
244
245  function currentJapaneseProduct(question){
246    if(LANG!=='ja'||!/\/ja\/[^/]+\/[^/]+\/$/.test(location.pathname))return null;
247    var heading=document.querySelector('h1');
248    var title=heading&&heading.textContent.replace(/\s+/g,'').trim();
249    var asked=String(question||'').replace(/\s+/g,'').trim();
250    if(!title||asked.length<10||!(title.indexOf(asked)>=0||asked===title))return null;
251    var modelNode=document.querySelector('.fctel-product-model-value');
252    var modelText=modelNode?modelNode.textContent:'';
253    if(!modelText)document.querySelectorAll('dd').forEach(function(node){if(!modelText&&/\b(?:FC|FCP)-[A-Z0-9-]+\b/i.test(node.textContent))modelText=node.textContent;});
254    var model=(modelText.match(/\b(?:FC|FCP)-[A-Z0-9-]+\b/i)||[])[0]||'';
255    return {title:heading.textContent.trim(),model:model,url:PAGE};
256  }
257
258  function normalizedTechnicalText(value){return String(value||'').toLowerCase().replace(/\bv\s*[.\-\/]?\s*(11|24|28|35|36)\b/g,'v$1').replace(/\bx\s*[.\-\/]?\s*(21|25)\b/g,'x$1').replace(/rs\s*[-\/]?\s*(232|422|485)/g,'rs$1').replace(/([0-9]+)\s*[-x*×]?\s*(?:ports?|channels?|ch)\b/g,'$1ch').replace(/[_|,;:()\[\]]/g,' ').replace(/\s+/g,' ').trim();}
259
260  function productIntent(question){
261
262    var q=normalizedTechnicalText(question),terms=[],required=[],excluded=[];
263
264    ['rs232','rs422','rs485','v11','v24','v28','v35','v36','x21','x25','usb','ethernet','e1','can','hdmi','s
264di','cvbs','vga','audio','modbus','profibus','profinet','fiber','fibre','serial'].forEach(function(term){if(new RegExp('(^|\\W)'+term+'($|\\W)','i').test(q)){terms.push(term);required.push(term);}});
265
266    if(/\b(?:hub|repeater)\b/.test(q))terms.push('hub');
267
268    if(/\b(?:converter|convert|adapter)\b/.test(q))terms.push('converter');
269
270    if(/\b(?:isolat|isolation|isolated)\w*/.test(q)){terms.push('isolation');required.push('isolat');}
271
272    if(/\b(?:dry\s*contact|dido|di\s*[\/+&-]\s*do|digital\s+(?:input|output))\b/.test(q)){terms.push('dry contact');required.push('dry contact');}
273
274    var count=q.match(/\b(\d+)ch\b/);if(!count)count=q.match(/\b(\d+)\s*(?:port|channel)s?\b/);if(count){terms.push(count[1]+' channel');required.push(count[1]+'ch');}
275
276    var model=q.match(/\b(?:fc[ptc]?|fct)[- ]?[a-z0-9]+(?:[-/][a-z0-9]+)*\b/i);if(model){terms.unshift(model[0]);required.unshift(model[0].replace(/\s/g,''));}
277
278    if(/\b(?:no|without|exclude|excluding)\s+(?:a\s+)?usb\b/.test(q))excluded.push('usb');
279
280    var stop={we:1,need:1,needs:1,want:1,looking:1,for:1,the:1,a:1,an:1,to:1,of:1,and:1,with:1,please:1,product:1,products:1,device:1,devices:1,converter:1,convert:1,adapter:1};
281
282    (q.match(/[a-z0-9]+/g)||[]).forEach(function(word){if(word.length>2&&!stop[word]&&terms.indexOf(word)<0)terms.push(word);});
283
284    var searchTerms=terms.filter(function(term){return !/^\d+\s*(?:ch|channel)$/.test(term)&&term!=='isolation'&&term!=='isolat';});
285
286    if(!searchTerms.length)searchTerms=terms;
287
288    var primary=required.filter(function(term){return /^(?:v(?:11|24|28|35|36)|x(?:21|25))$/.test(term);})[0]||'';
289
290    return {raw:q,query:searchTerms.slice(0,6).join(' '),terms:terms,required:required,excluded:excluded,primary:primary};
291
292  }
293
294  function titleHas(text,term){var t=normalizedTechnicalText(text),x=normalizedTechnicalText(term);if(x==='fiber'||x==='fibre')return /\bfib(?:er|re)\b/.test(t);if(x==='isolat')return /\bisolat/.test(t);if(/^\d+ch$/.test(x))return new RegExp('(^|\\D)'+x.slice(0,-2)+'\\s*(?:ch|channels?|ports?)\\b').test(t);return t.indexOf(x)>=0;}
295
296  function sourceMatches(question,title,url,relaxed){
297
298    var intent=productIntent(question),t=normalizedTechnicalText(title),u=String(url||'');
299
300    if(intent.excluded.some(function(x){return titleHas(t,x);}))return false;
301
302    if(relaxed){if(!intent.primary||!titleHas(t,intent.primary))return false;}else if(intent.required.some(function(x){return !titleHas(t,x);}))return false;
303
304    var asksSerial=/\brs(?:232|422|485)\b|\bserial\b/.test(intent.raw),asksIo=/dry contact/.test(intent.required.join(' ')),asksVideo=/\b(?:hdmi|sdi|cvbs|vga|video)\b/.test(intent.raw);
305
306    if(asksSerial&&!asksIo&&/\/digital-input-output\//i.test(u))return false;
307
308    if((asksSerial||asksIo)&&!asksVideo&&/\b(?:hdmi|sdi|cvbs|vga|video)\b/.test(t))return false;
309
310    return true;
311
312  }
313
314  var productSearchCache={};
315
316  function productScore(intent,title,index){
317
318    var t=normalizedTechnicalText(title),score=Math.max(0,30-index);
319
320    intent.terms.forEach(function(term){if(titleHas(t,term))score+=18;});
321
322    intent.required.forEach(function(term){if(titleHas(t,term))score+=32;});
323
324    if(intent.query&&t.indexOf(normalizedTechnicalText(intent.query))>=0)score+=60;
325
326    if(/\bhub\b/.test(intent.raw)&&/\b(?:hub|repeater)\b/.test(t))score+=24;
327
328    if(/\b(?:converter|convert|adapter)\b/.test(intent.raw)&&/\bconverter\b/.test(t))score+=16;
329
330    if(/\bto\b/.test(intent.raw)&&intent.required.length>=2&&intent.required.every(function(term){return titleHas(t,term);}))score+=35;
331
332    return score;
333
334  }
335
336  function legacySearchTerm(term){var match=String(term||'').match(/^([vx])(\d+)$/);return match?match[1].toUpperCase()+'.'+match[2]:term;}
337
338  function searchPublicProducts(question){
339
340    var key=String(question||'').trim().slice(0,220),intent=productIntent(key);if(!key||!intent.query)return Promise.resolve([]);if(productSearchCache[key])return Promise.resolve(productSearchCache[key]);
341
342    var queries=[{value:intent.query,relaxed:false}];if(intent.primary)queries.push({value:legacySearchTerm(intent.primary),relaxed:true});
343
344    return Promise.all(queries.map(function(query){var endpoint=location.origin+'/wp-json/wp/v2/search?type=post&subtype=post&per_page=100&search='+encodeURIComponent(query.value);return fetch(endpoint,{credentials:'same-origin'}).then(function(r){if(!r.ok)throw new Error('search');return r.json();}).then(function(rows){return {rows:rows,relaxed:query.relaxed};});})).then(function(groups){
345
346      var items=[];groups.forEach(function(group,groupIndex){(Array.isArray(group.rows)?group.rows:[]).forEac
346h(function(item,index){var d=document.createElement('textarea');d.innerHTML=item.title||'';var title=d.value.trim().replace(/\s+/g,' '),url=item.url||'';if(!/^https:\/\/(?:www\.)?fctele\.com\//i.test(url)||!sourceMatches(question,title,url,group.relaxed))return;items.push({title:title,url:url,score:productScore(intent,title,index)+(group.relaxed?0:1000)});});});
347
348      items.sort(function(a,b){return b.score-a.score;});var seen={},result=items.filter(function(item){if(seen[item.url])return false;seen[item.url]=1;return true;}).slice(0,4);productSearchCache[key]=result;return result;
349
350    }).catch(function(){return [];});
351
352  }
353
354  function catalogFoundText(){var messages={en:'I found matching products in the FCTEL catalogue. The closest matches are listed below in relevance order.',fr:'J\u2019ai trouv\u00e9 des produits correspondants dans le catalogue FCTEL. Les r\u00e9sultats les plus pertinents sont class\u00e9s ci-dessous.',es:'He encontrado productos coincidentes en el cat\u00e1logo de FCTEL. Las opciones m\u00e1s relevantes aparecen a continuaci\u00f3n.',pt:'Encontrei produtos correspondentes no cat\u00e1logo FCTEL. As op\u00e7\u00f5es mais relevantes est\u00e3o listadas abaixo.',de:'Im FCTEL-Katalog wurden passende Produkte gefunden. Die relevantesten Treffer stehen unten.',it:'Ho trovato prodotti corrispondenti nel catalogo FCTEL. I risultati pi\u00f9 pertinenti sono elencati di seguito.',ru:'\u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 FCTEL \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0442\u043e\u0432\u0430\u0440\u044b. \u041d\u0438\u0436\u0435 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u043e \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u043e\u0441\u0442\u0438.',ar:'\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0645\u0646\u062a\u062c\u0627\u062a \u0645\u0637\u0627\u0628\u0642\u0629 \u0641\u064a \u0643\u062a\u0627\u0644\u0648\u062c FCTEL. \u062a\u0638\u0647\u0631 \u0623\u0643\u062b\u0631 \u0627\u0644\u0646\u062a\u0627\u0626\u062c \u0635\u0644\u0629 \u0623\u062f\u0646\u0627\u0647.',ko:'FCTEL \uc81c\ud488 \uce74\ud0c8\ub85c\uadf8\uc5d0\uc11c \uc77c\uce58\ud558\ub294 \uc81c\ud488\uc744 \ucc3e\uc558\uc2b5\ub2c8\ub2e4. \uad00\ub828\ub3c4\uac00 \ub192\uc740 \uc21c\uc11c\ub85c \uc544\ub798\uc5d0 \ud45c\uc2dc\ub429\ub2c8\ub2e4.',id:'Produk yang sesuai ditemukan dalam katalog FCTEL. Hasil yang paling relevan tercantum di bawah.',vi:'Tôi đã tìm thấy các sản phẩm phù hợp trong danh mục FCTEL. Các kết quả liên quan nhất được liệt kê bên dưới.',th:'พบสินค้าที่ตรงกันในแคตตาล็อก FCTEL โดยเรียงตามความเกี่ยวข้องด้านล่าง',tr:'FCTEL kataloğunda eşleşen ürünler buldum. En ilgili sonuçlar aşağıda listelenmiştir.',ja:'FCTELのカタログで該当する製品が見つかりました。関連性の高い順に以下に表示します。'};return messages[LANG]||messages.en;}
355
356  function appendPublicProducts(row,question,originalBody){searchPublicProducts(question).then(function(items){if(!items.length)return;var body=String(originalBody||'');if(/(?:don['\u2019]?t\s+(?:offer|have)|do\s+not\s+(?:offer|have)|no\s+(?:matching|relevant)|could\s+not\s+(?:find|verify)|can['\u2019]?t\s+(?:find|verify)|\u6682\u672a\u6838\u5b9e|\u6ca1\u6709\u627e\u5230)/i.test(body)){var content=row.children[1];if(content){content.textContent=catalogFoundText();content.classList.add('catalog-confirmed');}}var sources=row.querySelector('.sources');if(!sources){sources=document.createElement('div');sources.className='sources';var heading=document.createElement('div');heading.className='sources-title';heading.textContent=t('references');sources.appendChild(heading);row.appendChild(sources);}var existing={};sources.querySelectorAll('a').forEach(function(a){existing[a.href]=1;});items.forEach(function(item){if(existing[item.url])return;var link=document.createElement('a');link.href=item.url;link.target='_blank';link.rel='noopener noreferrer';link.textContent=item.title;sources.appendChild(link);});});}
357
358  function request(path, method, data) {
359
360    var headers = {'Content-Type':'application/json'};
361
362    if (conversation) headers.Authorization='Bearer '+conversation.token;
363
364    return fetch(API+path,{method:method||'GET',headers:headers,credentials:'omit',body:data===undefined?undefined:JSON.stringify(data)}).then(function(r){return r.json().catch(function(){return {};}).then(function(v){if(!r.ok){var error=new Error(englishError(v.error)||t('unavailable'));error.status=r.status;throw error;}return v;});});
365
366  }
367
368  var publicIpPromise=null,networkConversationId='';
369
370  function publicIp(){
371
372    if(publicIpPromise)return publicIpPromise;
373
374    var controller=typeof AbortController==='function'?new AbortController():null;
375
376    var timer=controller?setTimeout(function(){controller.abort();},2500):null;
377
378    publicIpPromise=fetch('https://api.ipify.org?format=json',{method:'GET',credentials:'omit',cache:'no-store',signal:controller?controller.signal:undefined})
379
380      .then(function(r){if(!r.ok)throw new Error('ip');return r.json();})
381
382      .then(function(data){return String(data.ip||'').trim();})
383
384      .catch(function(){return '';})
385
386      .then(function(value){if(timer)clearTimeout(timer);return value;});
387
388    return publicIpPromise;
389
390  }
391
392  function syncVisitorNetwork(){
393
394    if(!conversation||networkConversationId===conversation.id)return Promise.resolve(conversation);
395
396    return publicIp().then(function(address){
397
398      if(!address)return conversation;
399
400      return request('conversations/'+encodeURIComponent(conversation.id)+'/network','POST',{ip_address:address})
401
402        .then(function(){networkConversationId=conversation.id;return conversation;})
403
404        .catch(function(){return conversation;});
405
406    });
407
408  }
409
410  function clearConversation(){conversation=null;last='';networkConversationId='';try{localStorage.removeItem(STORAGE);}catch(_){}}
411
412  function foreignContext(extra){var data={trade_scope:'foreign',site_scope:'foreign',source_site:'www.fctele.com',language:LANG,locale:LANG,original_language:LANG};Object.keys(extra||{}).forEach(function(key){data[key]=extra[key];});return data;}
413
414  function recoverConversation(){clearConversation();$('.messages').innerHTML='';status(t('starting'));return ensure().then(function(){return request('conversations/'+conversation.id+'/open','POST',foreignContext());}).then(function(){status('');return refresh();});}
415
416
417  // FCTEL-STABLE-VISITOR-IDENTITY-20260925
418  function stableBrowserId(){
419    var key='fctel-browser-identity-v2',id='';
420    try{id=localStorage.getItem(key)||'';}catch(_){}
421    if(!/^[a-zA-Z0-9-]{8,100}$/.test(id)){
422      var bytes=new Uint8Array(16);crypto.getRandomValues(bytes);
423      id='site-'+Array.from(bytes,function(b){return b.toString(16).padStart(2,'0');}).join('');
424      try{localStorage.setItem(key,id);}catch(_){}
425    }
426    return id;
427  }
428  var identitySynced=false;
429  function syncChatIdentity(){
430    if(identitySynced||!conversation||!conversation.id)return;
431    identitySynced=true;
432    request('conversations/'+encodeURIComponent(conversation.id)+'/identify','POST',
433      {browser_id:stableBrowserId(),upgrade_legacy:true}).catch(function(){identitySynced=false;});
434  }
435
436  function ensure() {
437
438    if (conversation) {syncVisitorNetwork();syncChatIdentity();return Promise.resolve(conversation);}
439
440    return request('conversations','POST',foreignContext({page:PAGE,browser_id:stableBrowserId()})).then(function(c){conversation=c;try{localStorage.setItem(STORAGE,JSON.stringify(c));}catch(_){}syncVisitorNetwork();syncChatIdentity();return c;});
441
442  }
443
444  function render(data) {
445
446    var signature=JSON.stringify(data.messages||[])+(data.thinking?'1':'0');if(signature===last)return;last=signature;
447
448    var box=$('.messages');box.innerHTML='';var latestQuestion='',preVisitorNotice=false,visitorSeen=false;
449
450    (data.messages||[]).forEach(function(m){
451
452      if(m.role==='visitor'){latestQuestion=m.body||'';visitorSeen=true;}
453      if(m.role==='system'&&!visitorSeen){if(preVisitorNotice)return;preVisitorNotice=true;}
454
455      var row=document.createElement('div');row.className='msg '+(m.role==='visitor'?'user':m.role==='system'?'system':'');
456
457      var label=document.createElement('b');label.textContent=m.role==='visitor'?t('you'):m.role==='staff'?t('sales'):m.role==='system'?t('notice'):t('ai');row.appendChild(label);
458
459      var content=document.createElement('div'),body=englishMessage(m);
460      var pageProduct=m.role==='ai'?currentJapaneseProduct(latestQuestion):null;
461
462      if(pageProduct){
463
464        content.textContent='はい。このページの製品は'+(pageProduct.model?'型番 '+pageProduct.model+' の':'')+pageProduct.title+'です。製品の詳細は現在のページでご確認いただけます。仕様や接続方法について知りたい点があれば、そのままご質問ください。';
465
466      }else if(m.role==='ai'&&LANG!=='en'){
467
468        content.textContent=t('searching');
469
470        translateAi(String(m.body||'')).then(function(translated){if(!content.classList.contains('catalog-confirmed'))content.innerHTML=safeRich(translated);}).catch(function(){if(!content.classList.contains('catalog-confirmed'))content.innerHTML=safeRich(String(m.body||t('generic')));});
471
472      }else if(m.role==='ai'||m.role==='staff')content.innerHTML=safeRich(body);else content.textContent=body;
473
474      row.appendChild(content);
475
476      if(pageProduct){var pageSource=document.createElement('div');pageSource.className='sources';var pageSourceTitle=document.createElement('div');pageSourceTitle.className='sources-title';pageSourceTitle.textContent=t('references');var pageLink=document.createElement('a');pageLink.href=pageProduct.url;pageLink.target='_blank';pageLink.rel='noopener noreferrer';pageLink.textContent=pageProduct.title;pageSource.appendChild(pageSourceTitle);pageSource.appendChild(pageLink);row.appendChild(pageSource);}
477
478      if((m.role==='ai'||m.role==='staff')&&m.sources&&m.sources.length){var sources=document.createElement('div');sources.className='sources';var heading=document.createElement('div');heading.className='sources-title';heading.textContent=t('references');sources.appendChild(heading);
478m.sources.forEach(function(source){if(!/^https:\/\/(?:www\.)?fctele\.com\//i.test(source.url||'')||!sourceMatches(latestQuestion,source.title,source.url))return;var link=document.createElement('a');link.href=source.url;link.target='_blank';link.rel='noopener noreferrer';link.textContent=source.title;sources.appendChild(link);});if(sources.querySelector('a'))row.appendChild(sources);}
479
480      box.appendChild(row);
481
482      if(m.role==='ai'&&!/https?:\/\/(?:www\.)?fctele\.com\//i.test(latestQuestion))appendPublicProducts(row,latestQuestion,m.body);
483
484    });
485
486    if(data.thinking){var thinking=document.createElement('div');thinking.className='msg system';thinking.textContent=t('searching');box.appendChild(thinking);}
487
488    $('.human').disabled=data.state!=='ai'||data.human_requested;$('.human').textContent=data.human_requested?t('humanRequested'):t('talk');box.scrollTop=box.scrollHeight;
489
490  }
491
492  function refresh(){if(!open||!conversation)return;request('conversations/'+encodeURIComponent(conversation.id)).then(render).catch(function(e){if(e.status===401||e.status===403)return recoverConversation().catch(function(err){status(err.message);});status(e.message);});}
493
494  function setAvatar(photo,name){
495
496    var requestId=++avatarRequestId,imgs=root.querySelectorAll('.launch-avatar,.panel-avatar');
497
498    imgs.forEach(function(img){
499
500      img.alt=name||'On-duty sales representative';
501
502      img.onerror=function(){if(img.src!==STATIC_FALLBACK_AVATAR)img.src=STATIC_FALLBACK_AVATAR;};
503
504      if(!img.complete||!img.naturalWidth)img.src=STATIC_FALLBACK_AVATAR;
505
506    });
507
508    if(!photo||photo===STATIC_FALLBACK_AVATAR)return;
509
510    var preview=new Image(),timeout=setTimeout(function(){preview.onload=preview.onerror=null;},5000);
511
512    preview.onload=function(){clearTimeout(timeout);if(requestId!==avatarRequestId)return;imgs.forEach(function(img){img.src=photo;});};
513
514    preview.onerror=function(){clearTimeout(timeout);};
515
516    preview.src=photo;
517
518  }
519
520  function contactJsonp(query){return new Promise(function(resolve,reject){var callback='__fctelContact'+Date.now()+Math.random().toString(36).slice(2),script=document.createElement('script'),done=false;function finish(error,value){if(done)return;done=true;clearTimeout(timer);delete window[callback];script.remove();error?reject(error):resolve(value);}window[callback]=function(value){finish(null,value);};script.src=API+'contact'+query+'&callback='+encodeURIComponent(callback)+'&_='+Date.now();script.async=true;script.onerror=function(){finish(new Error('Contact unavailable'));};var timer=setTimeout(function(){finish(new Error('Contact timeout'));},8000);(document.head||document.documentElement).appendChild(script);});}
521  function contactRequest(){var query='?page='+encodeURIComponent(PAGE)+'&language='+encodeURIComponent(LANG),controller=typeof AbortController==='function'?new AbortController():null;var timeout=setTimeout(function(){if(controller)controller.abort();},8000);return fetch(API+'contact'+query,{credentials:'omit',cache:'no-store',signal:controller?controller.signal:undefined}).then(function(r){if(!r.ok)throw new Error('Contact unavailable');return r.json();}).finally(function(){clearTimeout(timeout);}).catch(function(){return contactJsonp(query);}).catch(function(){return fetch(CONTACT_API+query+'&_='+Date.now(),{credentials:'omit',cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('Local contact unavailable');return r.json();});});}
522  function loadContact(){setAvatar(FALLBACK_AVATAR,'International Sales');return contactRequest().then(function(c){var el=$('.contact'),showDuty=!!c.duty_online,name=showDuty?(c.sales_name||'International Sales'):(c.supervisor_online?'Foreign Trade Supervisor':'International Sales'),photo=showDuty?(c.sales_photo_url||FALLBACK_AVATAR):FALLBACK_AVATAR,links='',qr='';if(!showDuty){c.sales_email='[email protected]';c.sales_phone='+86-18758069661';c.sales_whatsapp='+86-18758069661';c.sales_qr_url='';}setAvatar(photo,name);if(c.sales_whatsapp){links+='<span class="contact-item"><span class="contact-label">'+t('whatsapp')+'</span><a href="https://wa.me/'+encodeURIComponent(c.sales_whatsapp.replace(/\D/g,''))+'" target="_blank" rel="noopener noreferrer">'+t('chatNow')+'</a></span>';}if(c.sales_email){links+='<span class="contact-item"><span class="contact-label">'+t('email')+'</span><a href="mailto:'+escapeHtml(c.sales_email)+'">'+escapeHtml(c.sales_email)+'</a></span>';}if(c.sales_phone){links+='<span class="contact-item"><span class="contact-label">'+t('phone')+'</span><a href="tel:'+escapeHtml(c.sales_phone)+'">'+escapeHtml(c.sales_phone)+'</a></span>';}if(c.sales_qr_url){links+='<span class="contact-item"><button class="qr-toggle" type="button">
522'+t('qr')+' <svg class="qr-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 3h7v7H3V3zm2 2v3h3V5H5zm9-2h7v7h-7V3zm2 2v3h3V5h-3zM3 14h7v7H3v-7zm2 2v3h3v-3H5zm9-2h3v3h-3v-3zm4 0h3v3h-3v-3zm-4 4h3v3h-3v-3zm4 0h1v1h2v2h-4v-3z"/></svg></button></span>';qr='<div class="qr-card"><img src="'+escapeHtml(c.sales_qr_url)+'" alt="'+t('qr')+'"><span>'+t('scan')+'</span></div>';}var availability=c.staff_online?'<span style="color:#177a53">● Online now</span>':'<span style="color:#8a6531">● Offline · Leave a message for a reply</span>';el.innerHTML='<strong>'+availability+' · '+escapeHtml(name)+'</strong><div class="contact-line">'+links+'</div>'+qr;applyAvailability(c);var q=$('.qr-toggle');if(q)q.onclick=function(){$('.qr-card').classList.toggle('show');};return c;}).catch(function(){setAvatar(FALLBACK_AVATAR,'International Sales');$('.contact').textContent=t('contactFallback');applyAvailability({staff_online:false});});}
523
524  function installLauncherDock(){var button=$('.launch'),saved={dock:'corner',x:1,y:1},drag=null,suppress=0;try{var old=JSON.parse(localStorage.getItem('fctel-en-launcher-position-v2')||'null');if(old&&typeof old.x==='number'&&typeof old.y==='number')saved=old;}catch(_){}function vp(){return {w:document.documentElement.clientWidth||innerWidth,h:innerHeight};}function size(dock){return /^(left|right)$/.test(dock)?(vp().w<=520?{w:54,h:128}:{w:56,h:132}):(vp().w<=520?{w:174,h:52}:{w:224,h:60});}function place(){if(drag)return;var v=vp(),dock=saved.dock||'free',s=size(dock),x=Math.max(0,Math.min(v.w-s.w,saved.x*v.w-s.w/2)),y=Math.max(0,Math.min(v.h-s.h,saved.y*v.h-s.h/2));if(dock==='corner'){x=Math.max(0,v.w-s.w-(v.w<=520?12:Math.max(20,Math.min(120,Math.round(v.w*.06)))));y=Math.max(0,v.h-s.h-(v.w<=520?16:48));}if(dock==='left')x=0;if(dock==='right')x=v.w-s.w;if(dock==='top')y=0;if(dock==='bottom')y=v.h-s.h;button.dataset.dock=dock;button.style.left=x+'px';button.style.top=y+'px';}function point(e){var p=e.touches&&e.touches[0]||e;return {x:p.clientX,y:p.clientY};}function down(e){if(e.button!==undefined&&e.button!==0)return;var p=point(e),r=button.getBoundingClientRect();drag={dx:p.x-r.left,dy:p.y-r.top,last:p,moved:false};}function move(e){if(!drag)return;var p=point(e),v=vp(),s=size('free');
524if(!drag.moved&&Math.abs(p.x-drag.last.x)+Math.abs(p.y-drag.last.y)<7)return;drag.moved=true;drag.last=p;button.dataset.dock='free';button.style.left=Math.max(0,Math.min(v.w-s.w,p.x-drag.dx))+'px';button.style.top=Math.max(0,Math.min(v.h-s.h,p.y-drag.dy))+'px';e.preventDefault();}function up(){if(!drag)return;var d=drag;drag=null;if(d.moved){var v=vp(),r=button.getBoundingClientRect(),cx=r.left+r.width/2,cy=r.top+r.height/2,threshold=18,dock='free';if(r.left<=threshold)dock='left';else if(v.w-r.right<=threshold)dock='right';else if(r.top<=threshold)dock='top';else if(v.h-r.bottom<=threshold)dock='bottom';saved={dock:dock,x:Math.max(0,Math.min(1,cx/v.w)),y:Math.max(0,Math.min(1,cy/v.h))};try{localStorage.setItem('fctel-en-launcher-position-v2',JSON.stringify(saved));}catch(_){}suppress=Date.now()+450;}place();}button.addEventListener('mousedown',down);button.addEventListener('touchstart',down,{passive:true});document.addEventListener('mousemove',move);document.addEventListener('touchmove',move,{passive:false});document.addEventListener('mouseup',up);document.addEventListener('touchend',up);button.addEventListener('click',function(e){if(Date.now()<suppress){e.preventDefault();e.stopImmediatePropagation();}},true);addEventListener('resize',place);place();}
525
526  function installPanelDrag(){var bar=$('header'),panel=$('.panel'),drag=null;bar.addEventListener('pointerdown',function(e){if(e.target.closest('button')||innerWidth<521)return;var r=panel.getBoundingClientRect();drag={x:e.clientX,y:e.clientY,left:r.left,top:r.top,id:e.pointerId};bar.setPointerCapture(e.pointerId);});bar.addEventListener('pointermove',function(e){if(!drag||e.pointerId!==drag.id)return;panel.style.left=Math.max(0,Math.min(innerWidth-panel.offsetWidth,drag.left+e.clientX-drag.x))+'px';panel.style.top=Math.max(0,Math.min(innerHeight-panel.offsetHeight,drag.top+e.clientY-drag.y))+'px';panel.style.right='auto';panel.style.bottom='auto';});function stop(e){if(drag&&(!e||e.pointerId===drag.id))drag=null;}bar.addEventListener('pointerup',stop);bar.addEventListener('pointercancel',stop);}
527
528  function installPanelResize(){var panel=$('.panel'),resizing=null;root.querySelectorAll('[data-resize]').forEach(function(handle){handle.addEventListener('pointerdown',function(e){if(innerWidth<521)return;var r=panel.getBoundingClientRect();panel.style.left=r.left+'px';panel.style.top=r.top+'px';panel.style.right='auto';panel.style.bottom='auto';panel.style.width=r.width+'px';panel.style.height=r.height+'px';resizing={x:e.clientX,y:e.clientY,w:r.width,h:r.height,mode:handle.dataset.resize,id:e.pointerId};handle.setPointerCapture(e.pointerId);e.preventDefault();});handle.addEventListener('pointermove',function(e){if(!resizing||e.pointerId!==resizing.id)return;var dx=e.clientX-resizing.x,dy=e.clientY-resizing.y;if(resizing.mode!=='bottom')panel.style.width=Math.max(340,Math.min(innerWidth-panel.offsetLeft-4,resizing.w+dx))+'px';if(resizing.mode!=='right')panel.style.height=Math.max(430,Math.min(innerHeight-panel.offsetTop-4,resizing.h+dy))+'px';});function stop(e){if(resizing&&e.pointerId===resizing.id)resizing=null;}handle.addEventListener('pointerup',stop);handle.addEventListener('pointercancel',stop);});}
529
530  function saveInvite(){try{sessionStorage.setItem('fctel-en-chat-invitation-v1',JSON.stringify(invite));}catch(_){}}
531
532  function scheduleInvite(delay){clearTimeout(inviteTimer);inviteTimer=setTimeout(function(){if(!open&&!invite.engaged&&invite.closes<2&&!document.hidden)setOpen(true,true);},delay);}
533
534  function setOpen(value,automatic){if(value===open)return;open=value;$('.panel').hidden=!value;$('.launch').hidden=value;$('.launch').setAttribute('aria-expanded',String(value));if(value){clearTimeout(inviteTimer);invite.shown=true;if(!automatic)invite.engaged=true;saveInvite();loadContact();ensure().then(function(){return request('conversations/'+conversation.id+'/open','POST',foreignContext());}).then(refresh).catch(function(e){if(e.status===401||e.status===403)return recoverConversation().catch(function(err){status(err.message);});status(e.message);});timer=timer||setInterval(refresh,3000);$('.panel textarea').focus();}else{invite.closes++;invite.shown=true;saveInvite();if(invite.closes<2&&!invite.engaged)scheduleInvite(90000);$('.launch').focus();}}
535
536  $('.launch').onclick=function(){setOpen(true,false);};$('.close').onclick=function(){setOpen(false,false);};
537
538  $('.fresh').onclick=function(){recoverConversation().catch(function(e){status(e.message);});};
539
540  $('.human').onclick=function(){if(busy)return;invite.engaged=true;saveInvite();busy=true;ensure().then(function(){return request('conversations/'+conversation.id+'/human','POST',foreignContext());}).then(refresh).catch(function(e){status(e.message);}).finally(function(){busy=false;});};
541
542  $('.mode-human').onclick=function(){setMode('human');$('.human').click();};
543  $('.mode-inquiry').onclick=function(){setMode('inquiry');};
544  $('.mode-ai').onclick=function(){setMode('ai');};
545
546  $('.chat-form').onsubmit=function(e){e.preventDefault();var input=$('.chat-input'),text=input.value.trim();if(!text||busy)return;invite.engaged=true;saveInvite();busy=true;$('.send').disabled=true;status(t('sending'));ensure().then(function(){if(activeMode==='human'&&staffOnline)return request('conversations/'+conversation.id+'/human','POST',foreignContext());}).then(function(){return request('conversations/'+conversation.id+'/messages','POST',foreignContext({body:text,client_id:'foreign-'+LANG+'-'+Date.now()+'-'+Math.random().toString(36).slice(2)}));}).then(function(){input.value='';status('');refresh();}).catch(function(err){status(err.message);}).finally(function(){busy=false;$('.send').disabled=false;});};
547
548  $('.inquiry-form').onsubmit=function(e){
549    e.preventDefault();if(busy)return;
550    var form=e.currentTarget,data={},button=$('.inquiry-submit'),message=$('.inquiry-status');
551    ['name','email','phone','product','requirements'].forEach(function(key){data[key]=(form.elements[key].value||'').trim();});
552    busy=true;button.disabled=true;message.textContent='Sending your inquiry…';
553    ensure().then(function(){return request('conversations/'+conversation.id+'/inquiry','POST',foreignContext(data));}).then(function(){
554      form.hidden=true;$('.inquiry-success').hidden=false;message.textContent='';invite.engaged=true;saveInvite();refresh();
555    }).catch(function(err){message.textContent=err.message;}).finally(function(){busy=false;button.disabled=false;});
556  };
557
558  $('.chat-input').onkeydown=function(e){if(e.key==='Enter'&&!e.shiftKey&&!e.isComposing){e.preventDefault();if($('.chat-form').requestSubmit)$('.chat-form').requestSubmit();else $('.send').click();}};
559
560  $('.inquiry-form').elements.product.value=pageProductLabel();
561
562  installLauncherDock();installPanelDrag();installPanelResize();loadContact();
563  // FCTEL-LIVE-PRESENCE-20260924
564  import('https://crm.fctelerp.cn/static/website_chat/presence-visitor.js?v=20260924-2').then(function(module){module.installEnglishSite();}).catch(function(){});
565  
566
567  if(!invite.shown&&!invite.engaged)scheduleInvite(15000);
568
569  addEventListener('scroll',function(){var max=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight)-innerHeight;if(max>0&&(pageYOffset||document.documentElement.scrollTop)/max>=.25&&!invite.shown&&!invite.engaged)setOpen(true,true);},{passive:true});
570
571})();
572

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.