cevvo-widget 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/widget.js +53 -34
- package/package.json +1 -1
package/dist/widget.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){"use strict";(function(){const p="https://prod-backend-api.cevvo.ai/api/v1",b={projectId:"",apiKey:"",apiUrl:p,projectName:"AI Assistant",projectColor:"#2563eb",buttonText:"Ask AI",buttonBgColor:"#2563eb",buttonTextColor:"#ffffff",buttonPosition:"bottom-right",buttonOffsetX:"20px",buttonOffsetY:"20px",modalTitle:"AI Assistant",modalSubtitle:"Ask me anything",modalPlaceholder:"Ask a question...",modalExampleQuestions:[],modalWidth:"420px",modalHeight:"600px",mode:"chat",theme:"light",welcomeMessage:"Hi! How can I help you?"},
|
|
1
|
+
(function(){"use strict";(function(){const p="https://prod-backend-api.cevvo.ai/api/v1",b={projectId:"",apiKey:"",apiUrl:p,projectName:"AI Assistant",projectColor:"#2563eb",buttonText:"Ask AI",buttonBgColor:"#2563eb",buttonTextColor:"#ffffff",buttonPosition:"bottom-right",buttonOffsetX:"20px",buttonOffsetY:"20px",modalTitle:"AI Assistant",modalSubtitle:"Ask me anything",modalPlaceholder:"Ask a question...",modalExampleQuestions:[],modalWidth:"420px",modalHeight:"600px",mode:"chat",theme:"light",welcomeMessage:"Hi! How can I help you?",disclaimer:"AI responses may be inaccurate or incomplete. Please verify important information from original sources."},n={cevvoLogo:`<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32 32">
|
|
2
2
|
<ellipse cx="13" cy="16" rx="8" ry="10" fill="#21244A" transform="rotate(-15 13 16)"/>
|
|
3
3
|
<ellipse cx="19" cy="16" rx="8" ry="10" fill="#F69F06" transform="rotate(15 19 16)" opacity="0.85"/>
|
|
4
4
|
</svg>`,close:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" fill="currentColor">
|
|
@@ -465,8 +465,12 @@
|
|
|
465
465
|
border: 1px solid #e4e4e7;
|
|
466
466
|
border-radius: 10px;
|
|
467
467
|
font-size: 14px;
|
|
468
|
+
line-height: 1.5;
|
|
468
469
|
outline: none;
|
|
469
470
|
background: #fff;
|
|
471
|
+
box-sizing: border-box;
|
|
472
|
+
width: 100%;
|
|
473
|
+
min-width: 0;
|
|
470
474
|
transition: border-color 0.15s ease;
|
|
471
475
|
}
|
|
472
476
|
|
|
@@ -501,6 +505,15 @@
|
|
|
501
505
|
opacity: 0.85;
|
|
502
506
|
}
|
|
503
507
|
|
|
508
|
+
.cevvo-disclaimer {
|
|
509
|
+
text-align: center;
|
|
510
|
+
font-size: 9px;
|
|
511
|
+
line-height: 1.4;
|
|
512
|
+
color: #a1a1aa;
|
|
513
|
+
margin: 0 0 8px;
|
|
514
|
+
padding: 0 12px;
|
|
515
|
+
}
|
|
516
|
+
|
|
504
517
|
.cevvo-powered {
|
|
505
518
|
text-align: center;
|
|
506
519
|
font-size: 11px;
|
|
@@ -579,18 +592,22 @@
|
|
|
579
592
|
.cevvo-modal-overlay.mode-modal .cevvo-input-wrapper {
|
|
580
593
|
display: flex;
|
|
581
594
|
flex-direction: column;
|
|
582
|
-
gap:
|
|
583
|
-
padding: 16px;
|
|
595
|
+
gap: 10px;
|
|
596
|
+
padding: 14px 16px;
|
|
584
597
|
border: 1px solid #e4e4e7;
|
|
585
598
|
border-radius: 14px;
|
|
586
599
|
background: #fff;
|
|
600
|
+
box-sizing: border-box;
|
|
587
601
|
}
|
|
588
602
|
|
|
589
603
|
.cevvo-modal-overlay.mode-modal .cevvo-input {
|
|
590
604
|
border: none;
|
|
591
|
-
padding: 0;
|
|
605
|
+
padding: 4px 0;
|
|
592
606
|
font-size: 15px;
|
|
607
|
+
line-height: 1.5;
|
|
593
608
|
background: transparent;
|
|
609
|
+
width: 100%;
|
|
610
|
+
box-sizing: border-box;
|
|
594
611
|
}
|
|
595
612
|
|
|
596
613
|
.cevvo-modal-overlay.mode-modal .cevvo-input:focus {
|
|
@@ -819,48 +836,49 @@
|
|
|
819
836
|
border-color: #38383a;
|
|
820
837
|
color: #e5e5ea;
|
|
821
838
|
}
|
|
822
|
-
`;class h{constructor(e={}){this.config={...b,...e},this.isOpen=!1,this.messages=[],this.threadId=null,this.isLoading=!1;const o=()=>{this.injectStyles(),this.createElements(),this.bindEvents()};document.body?o():document.addEventListener("DOMContentLoaded",o)}injectStyles(){if(document.getElementById("cevvo-widget-styles"))return;const e=document.createElement("style");e.id="cevvo-widget-styles",e.textContent=f,document.head.appendChild(e)}resolveTheme(){return this.config.theme==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":this.config.theme||"light"}createElements(){this.container=document.createElement("div");const e=this.resolveTheme()==="dark"?"cevvo-dark":"";this.container.className=`cevvo-widget ${e}`.trim(),this.container.style.setProperty("--cevvo-accent",this.config.projectColor),this.button=document.createElement("button"),this.button.className=`cevvo-widget-btn ${this.config.buttonPosition}`,this.button.style.background=this.config.buttonBgColor,this.button.style.color=this.config.buttonTextColor,this.button.innerHTML=`${
|
|
839
|
+
`;class h{constructor(e={}){this.config={...b,...e},this.isOpen=!1,this.messages=[],this.threadId=null,this.isLoading=!1;const o=()=>{this.injectStyles(),this.createElements(),this.bindEvents()};document.body?o():document.addEventListener("DOMContentLoaded",o)}injectStyles(){if(document.getElementById("cevvo-widget-styles"))return;const e=document.createElement("style");e.id="cevvo-widget-styles",e.textContent=f,document.head.appendChild(e)}resolveTheme(){return this.config.theme==="auto"?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":this.config.theme||"light"}createElements(){this.container=document.createElement("div");const e=this.resolveTheme()==="dark"?"cevvo-dark":"";this.container.className=`cevvo-widget ${e}`.trim(),this.container.style.setProperty("--cevvo-accent",this.config.projectColor),this.button=document.createElement("button"),this.button.className=`cevvo-widget-btn ${this.config.buttonPosition}`,this.button.style.background=this.config.buttonBgColor,this.button.style.color=this.config.buttonTextColor,this.button.innerHTML=`${n.cevvoLogo}<span>${this.config.buttonText}</span>`,this.overlay=document.createElement("div"),this.overlay.className=`cevvo-modal-overlay ${this.config.mode==="modal"?"mode-modal":""}`,this.overlay.innerHTML=this.config.mode==="modal"?this.renderModalMode():this.renderModal(),this.container.appendChild(this.button),this.container.appendChild(this.overlay),document.body.appendChild(this.container),this.modal=this.overlay.querySelector(".cevvo-modal"),this.messagesContainer=this.overlay.querySelector(".cevvo-modal-body"),this.input=this.overlay.querySelector(".cevvo-input"),this.form=this.overlay.querySelector(".cevvo-input-form"),this.clearBtn=this.overlay.querySelector(".cevvo-clear-btn"),this.closeBtn=this.overlay.querySelector(".cevvo-close-btn")}renderModal(){const e=this.config.modalExampleQuestions.map(o=>`<button class="cevvo-example-btn">${this.escapeHtml(o)}</button>`).join("");return`
|
|
823
840
|
<div class="cevvo-modal">
|
|
824
841
|
<div class="cevvo-modal-header">
|
|
825
842
|
<div class="cevvo-header-info">
|
|
826
|
-
<div class="cevvo-header-logo">${
|
|
843
|
+
<div class="cevvo-header-logo">${n.cevvoLogo}</div>
|
|
827
844
|
<div class="cevvo-header-text">
|
|
828
845
|
<h2>${this.escapeHtml(this.config.modalTitle)}</h2>
|
|
829
846
|
<p>${this.escapeHtml(this.config.modalSubtitle)}</p>
|
|
830
847
|
</div>
|
|
831
848
|
</div>
|
|
832
849
|
<div class="cevvo-header-actions">
|
|
833
|
-
<button class="cevvo-clear-btn" title="Clear chat" style="display:none;">${
|
|
834
|
-
<button class="cevvo-close-btn" title="Close">${
|
|
850
|
+
<button class="cevvo-clear-btn" title="Clear chat" style="display:none;">${n.trash}</button>
|
|
851
|
+
<button class="cevvo-close-btn" title="Close">${n.close}</button>
|
|
835
852
|
</div>
|
|
836
853
|
</div>
|
|
837
854
|
<div class="cevvo-modal-body">
|
|
838
855
|
<div class="cevvo-empty-state">
|
|
839
|
-
<div class="cevvo-empty-icon">${
|
|
856
|
+
<div class="cevvo-empty-icon">${n.sparkle}</div>
|
|
840
857
|
<h3>${this.escapeHtml(this.config.welcomeMessage)}</h3>
|
|
841
858
|
${e?`<div class="cevvo-example-questions">${e}</div>`:""}
|
|
842
859
|
</div>
|
|
843
860
|
</div>
|
|
844
861
|
<div class="cevvo-modal-footer">
|
|
862
|
+
${this.config.disclaimer?`<p class="cevvo-disclaimer">${this.escapeHtml(this.config.disclaimer)}</p>`:""}
|
|
845
863
|
<form class="cevvo-input-form">
|
|
846
864
|
<input type="text" class="cevvo-input" placeholder="${this.escapeHtml(this.config.modalPlaceholder)}" />
|
|
847
|
-
<button type="submit" class="cevvo-send-btn" disabled>${
|
|
865
|
+
<button type="submit" class="cevvo-send-btn" disabled>${n.send}</button>
|
|
848
866
|
</form>
|
|
849
867
|
<p class="cevvo-powered">Powered by <a href="https://cevvo.ai" target="_blank" rel="noopener">Cevvo</a></p>
|
|
850
868
|
</div>
|
|
851
869
|
</div>
|
|
852
|
-
`}renderModalMode(){const e=this.config.modalDescription||
|
|
870
|
+
`}renderModalMode(){const e=this.config.modalDescription||this.config.modalSubtitle||"Ask me anything about the documentation.";return`
|
|
853
871
|
<div class="cevvo-modal">
|
|
854
872
|
<div class="cevvo-modal-header">
|
|
855
873
|
<div class="cevvo-header-info">
|
|
856
|
-
<div class="cevvo-header-logo">${
|
|
874
|
+
<div class="cevvo-header-logo">${n.cevvoLogo}</div>
|
|
857
875
|
<div class="cevvo-header-text">
|
|
858
876
|
<h2>${this.escapeHtml(this.config.modalTitle)}</h2>
|
|
859
877
|
</div>
|
|
860
878
|
</div>
|
|
861
879
|
<div class="cevvo-header-actions">
|
|
862
|
-
<button class="cevvo-clear-btn" title="Clear chat" style="display:none;">${
|
|
863
|
-
<button class="cevvo-close-btn" title="Close">${
|
|
880
|
+
<button class="cevvo-clear-btn" title="Clear chat" style="display:none;">${n.trash}</button>
|
|
881
|
+
<button class="cevvo-close-btn" title="Close">${n.close}</button>
|
|
864
882
|
</div>
|
|
865
883
|
</div>
|
|
866
884
|
<div class="cevvo-modal-description" style="padding: 0 24px;">
|
|
@@ -869,6 +887,7 @@
|
|
|
869
887
|
<div class="cevvo-modal-body">
|
|
870
888
|
</div>
|
|
871
889
|
<div class="cevvo-modal-footer">
|
|
890
|
+
${this.config.disclaimer?`<p class="cevvo-disclaimer">${this.escapeHtml(this.config.disclaimer)}</p>`:""}
|
|
872
891
|
<div class="cevvo-input-wrapper">
|
|
873
892
|
<form class="cevvo-input-form" style="gap: 0;">
|
|
874
893
|
<input type="text" class="cevvo-input" placeholder="${this.escapeHtml(this.config.modalPlaceholder)}" />
|
|
@@ -879,26 +898,26 @@
|
|
|
879
898
|
For harder questions. Searches longer across all sources. Takes up to ~1 minute.
|
|
880
899
|
</div>
|
|
881
900
|
<button type="button" class="cevvo-deep-thinking-btn">
|
|
882
|
-
${
|
|
901
|
+
${n.brain}
|
|
883
902
|
<span>Deep thinking</span>
|
|
884
903
|
</button>
|
|
885
904
|
</div>
|
|
886
|
-
<button type="submit" class="cevvo-send-btn" disabled>${
|
|
905
|
+
<button type="submit" class="cevvo-send-btn" disabled>${n.arrowUp}</button>
|
|
887
906
|
</div>
|
|
888
907
|
</div>
|
|
889
908
|
<div class="cevvo-powered">
|
|
890
909
|
<div class="cevvo-powered-left">
|
|
891
910
|
<span>Powered by</span>
|
|
892
|
-
${
|
|
911
|
+
${n.cevvoLogo}
|
|
893
912
|
<a href="https://cevvo.ai" target="_blank" rel="noopener">cevvo.ai</a>
|
|
894
913
|
</div>
|
|
895
914
|
</div>
|
|
896
915
|
</div>
|
|
897
916
|
</div>
|
|
898
|
-
`}bindEvents(){this.button.addEventListener("click",()=>this.toggle()),this.overlay.addEventListener("click",o=>{o.target===this.overlay&&this.close()}),this.closeBtn.addEventListener("click",()=>this.close()),this.clearBtn.addEventListener("click",()=>this.clearMessages()),this.form.addEventListener("submit",o=>{o.preventDefault(),this.sendMessage()}),this.overlay.querySelector(".cevvo-send-btn").addEventListener("click",o=>{o.preventDefault(),this.sendMessage()}),this.input.addEventListener("input",()=>{const o=this.overlay.querySelector(".cevvo-send-btn");o.disabled=!this.input.value.trim()||this.isLoading}),this.input.addEventListener("keydown",o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),this.sendMessage())}),this.overlay.addEventListener("click",o=>{o.target.classList.contains("cevvo-example-btn")&&(this.input.value=o.target.textContent,this.sendMessage())}),this.messagesContainer.addEventListener("click",o=>{const a=o.target.closest("button");if(!a)return;const s=a.closest(".cevvo-actions");if(!s)return;const
|
|
899
|
-
`);for(const m of w)if(m.startsWith("data: ")){const u=m.slice(6);if(u==="[DONE]")continue;try{const v=JSON.parse(u);v.thread_id&&(this.threadId=v.thread_id),v.token&&(
|
|
917
|
+
`}bindEvents(){this.button.addEventListener("click",()=>this.toggle()),this.overlay.addEventListener("click",o=>{o.target===this.overlay&&this.close()}),this.closeBtn.addEventListener("click",()=>this.close()),this.clearBtn.addEventListener("click",()=>this.clearMessages()),this.form.addEventListener("submit",o=>{o.preventDefault(),this.sendMessage()}),this.overlay.querySelector(".cevvo-send-btn").addEventListener("click",o=>{o.preventDefault(),this.sendMessage()}),this.input.addEventListener("input",()=>{const o=this.overlay.querySelector(".cevvo-send-btn");o.disabled=!this.input.value.trim()||this.isLoading}),this.input.addEventListener("keydown",o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),this.sendMessage())}),this.overlay.addEventListener("click",o=>{o.target.classList.contains("cevvo-example-btn")&&(this.input.value=o.target.textContent,this.sendMessage())}),this.messagesContainer.addEventListener("click",o=>{const a=o.target.closest("button");if(!a)return;const s=a.closest(".cevvo-actions");if(!s)return;const i=s.dataset.messageId,r=a.closest(".cevvo-message"),d=r==null?void 0:r.dataset.msgId,c=this.messages.find(l=>l.id===d);if(a.classList.contains("cevvo-copy-btn")&&(c!=null&&c.content)&&(navigator.clipboard.writeText(c.content),a.innerHTML=n.check,setTimeout(()=>{a.innerHTML=n.copy},2e3)),a.classList.contains("cevvo-thumbs-up")&&i){const l=(c==null?void 0:c.feedback)==="positive"?null:"positive";c&&(c.feedback=l),this.submitFeedback(parseInt(i),5),this.renderMessages()}if(a.classList.contains("cevvo-thumbs-down")&&i){const l=(c==null?void 0:c.feedback)==="negative"?null:"negative";c&&(c.feedback=l),this.submitFeedback(parseInt(i),1),this.renderMessages()}}),document.addEventListener("keydown",o=>{(o.metaKey||o.ctrlKey)&&o.key==="k"&&(o.preventDefault(),this.toggle()),o.key==="Escape"&&this.isOpen&&this.close()})}toggle(){this.isOpen?this.close():this.open()}open(){this.isOpen=!0,this.overlay.classList.add("is-open"),this.button.style.display="none",setTimeout(()=>this.input.focus(),100)}close(){this.isOpen=!1,this.overlay.classList.remove("is-open"),this.button.style.display="flex"}updateModalState(){this.config.mode==="modal"&&(this.messages.length>0?this.overlay.classList.add("has-messages"):this.overlay.classList.remove("has-messages"))}async sendMessage(){const e=this.input.value.trim();if(!e||this.isLoading)return;if(!this.config.projectId||!this.config.apiKey){this.addMessage({role:"assistant",content:'Widget not configured. Please set Project ID and API Key, then click "Apply Changes".'});return}this.input.value="",this.overlay.querySelector(".cevvo-send-btn").disabled=!0,this.addMessage({role:"user",content:e});const o=this.addMessage({role:"assistant",content:"",isLoading:!0});this.isLoading=!0;try{const a={"Content-Type":"application/json","X-API-Key":this.config.apiKey},s=await fetch(`${this.config.apiUrl}/widget/chat/stream`,{method:"POST",headers:a,body:JSON.stringify({message:e,thread_id:this.threadId,project_id:this.config.projectId})});if(!s.ok)throw new Error("Failed to send message");const i=s.body.getReader(),r=new TextDecoder;let d="",c=[],l=null;for(;;){const{done:x,value:y}=await i.read();if(x)break;const w=r.decode(y,{stream:!0}).split(`
|
|
918
|
+
`);for(const m of w)if(m.startsWith("data: ")){const u=m.slice(6);if(u==="[DONE]")continue;try{const v=JSON.parse(u);v.thread_id&&(this.threadId=v.thread_id),v.token&&(d+=v.token,this.updateMessage(o,{content:d,isLoading:!1})),v.sources&&(c=v.sources),v.question_answer_id&&(l=v.question_answer_id)}catch{}}}this.updateMessage(o,{content:d||"I'm sorry, I couldn't generate a response.",sources:c,messageId:l,isLoading:!1})}catch(a){console.error("Chat error:",a),this.updateMessage(o,{content:"Sorry, something went wrong. Please try again.",isLoading:!1})}finally{this.isLoading=!1}}addMessage(e){const o=Date.now().toString();return this.messages.push({id:o,...e}),this.renderMessages(),this.clearBtn.style.display="flex",this.updateModalState(),o}updateMessage(e,o){const a=this.messages.find(s=>s.id===e);a&&(Object.assign(a,o),this.renderMessages())}clearMessages(){this.messages=[],this.threadId=null,this.clearBtn.style.display="none",this.renderMessages(),this.updateModalState()}renderMessages(){if(this.messages.length===0){this.messagesContainer.innerHTML=`
|
|
900
919
|
<div class="cevvo-empty-state">
|
|
901
|
-
<div class="cevvo-empty-icon">${
|
|
920
|
+
<div class="cevvo-empty-icon">${n.sparkle}</div>
|
|
902
921
|
<h3>${this.escapeHtml(this.config.welcomeMessage)}</h3>
|
|
903
922
|
${this.config.modalExampleQuestions.length?`
|
|
904
923
|
<div class="cevvo-example-questions">
|
|
@@ -910,22 +929,22 @@
|
|
|
910
929
|
<div class="cevvo-messages">
|
|
911
930
|
${this.messages.map(e=>this.renderMessage(e)).join("")}
|
|
912
931
|
</div>
|
|
913
|
-
`,this.messagesContainer.scrollTop=this.messagesContainer.scrollHeight}renderMessage(e){var
|
|
932
|
+
`,this.messagesContainer.scrollTop=this.messagesContainer.scrollHeight}renderMessage(e){var d;const o=e.role==="assistant"?n.cevvoLogo:n.user,a=e.isLoading?'<div class="cevvo-typing"><span></span><span></span><span></span></div>':this.formatContent(e.content),s=(d=e.sources)!=null&&d.length?`
|
|
914
933
|
<div class="cevvo-sources">
|
|
915
|
-
<div class="cevvo-sources-header">${
|
|
916
|
-
${e.sources.map((
|
|
917
|
-
<a href="${this.escapeHtml(
|
|
918
|
-
<span class="cevvo-source-num">${
|
|
919
|
-
<span class="cevvo-source-title">${this.escapeHtml(
|
|
920
|
-
${
|
|
934
|
+
<div class="cevvo-sources-header">${n.link} Sources</div>
|
|
935
|
+
${e.sources.map((c,l)=>`
|
|
936
|
+
<a href="${this.escapeHtml(c.source_url||c.url||"#")}" target="_blank" rel="noopener" class="cevvo-source-link">
|
|
937
|
+
<span class="cevvo-source-num">${l+1}</span>
|
|
938
|
+
<span class="cevvo-source-title">${this.escapeHtml(c.title||"Source")}</span>
|
|
939
|
+
${n.link}
|
|
921
940
|
</a>
|
|
922
941
|
`).join("")}
|
|
923
942
|
</div>
|
|
924
|
-
`:"",
|
|
925
|
-
<div class="cevvo-actions ${
|
|
926
|
-
<button class="cevvo-copy-btn" title="Copy">${
|
|
927
|
-
<button class="cevvo-thumbs-up ${e.feedback==="positive"?"active":""}" title="Helpful">${
|
|
928
|
-
<button class="cevvo-thumbs-down ${e.feedback==="negative"?"active":""}" title="Not helpful">${
|
|
943
|
+
`:"",i=e.feedback==="positive"?"feedback-positive":e.feedback==="negative"?"feedback-negative":"",r=e.role==="assistant"&&e.content&&!e.isLoading?`
|
|
944
|
+
<div class="cevvo-actions ${i}" data-message-id="${e.messageId||""}">
|
|
945
|
+
<button class="cevvo-copy-btn" title="Copy">${n.copy}</button>
|
|
946
|
+
<button class="cevvo-thumbs-up ${e.feedback==="positive"?"active":""}" title="Helpful">${n.thumbsUp}</button>
|
|
947
|
+
<button class="cevvo-thumbs-down ${e.feedback==="negative"?"active":""}" title="Not helpful">${n.thumbsDown}</button>
|
|
929
948
|
</div>
|
|
930
949
|
`:"";return`
|
|
931
950
|
<div class="cevvo-message ${e.role}" data-msg-id="${e.id}">
|
|
@@ -933,7 +952,7 @@
|
|
|
933
952
|
<div class="cevvo-message-content">
|
|
934
953
|
<div class="cevvo-bubble ${e.role}">${a}</div>
|
|
935
954
|
${s}
|
|
936
|
-
${
|
|
955
|
+
${r}
|
|
937
956
|
</div>
|
|
938
957
|
</div>
|
|
939
|
-
`}async submitFeedback(e,o){if(e)try{await fetch(`${this.config.apiUrl}/widget/feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:JSON.stringify({message_id:e,rating:o,project_id:this.config.projectId})})}catch(a){console.error("Feedback error:",a)}}formatContent(e){return this.escapeHtml(e).replace(/\n/g,"<br>").replace(/\*\*(.*?)\*\*/g,"<strong>$1</strong>").replace(/\*(.*?)\*/g,"<em>$1</em>").replace(/`(.*?)`/g,"<code>$1</code>")}escapeHtml(e){const o=document.createElement("div");return o.textContent=e,o.innerHTML}}async function g(t,e,o){const a=o||p;try{const s=await fetch(`${a}/widget/config?project_id=${encodeURIComponent(t)}`,{method:"GET",headers:{"X-API-Key":e}});if(!s.ok)return console.warn("[CevvoWidget] Failed to fetch config:",s.status),null;const
|
|
958
|
+
`}async submitFeedback(e,o){if(e)try{await fetch(`${this.config.apiUrl}/widget/feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:JSON.stringify({message_id:e,rating:o,project_id:this.config.projectId})})}catch(a){console.error("Feedback error:",a)}}formatContent(e){return this.escapeHtml(e).replace(/\n/g,"<br>").replace(/\*\*(.*?)\*\*/g,"<strong>$1</strong>").replace(/\*(.*?)\*/g,"<em>$1</em>").replace(/`(.*?)`/g,"<code>$1</code>")}escapeHtml(e){const o=document.createElement("div");return o.textContent=e,o.innerHTML}}async function g(t,e,o){const a=o||p;try{const s=await fetch(`${a}/widget/config?project_id=${encodeURIComponent(t)}`,{method:"GET",headers:{"X-API-Key":e}});if(!s.ok)return console.warn("[CevvoWidget] Failed to fetch config:",s.status),null;const i=await s.json();return{mode:i.mode,buttonText:i.buttonText,buttonPosition:i.position,projectColor:i.primaryColor,buttonBgColor:i.primaryColor,theme:i.theme||"light",modalTitle:i.modalTitle,modalSubtitle:i.modalSubtitle,modalExampleQuestions:i.exampleQuestions||[],welcomeMessage:i.welcomeMessage}}catch(s){return console.warn("[CevvoWidget] Error fetching config:",s.message),null}}window.CevvoWidget={init:async(t={})=>{if(t.projectId&&t.apiKey){const e=await g(t.projectId,t.apiKey,t.apiUrl);if(e)for(const[o,a]of Object.entries(e))a!=null&&a!==""&&(t[o]=a)}return new h(t)},initWithRemoteConfig:async(t,e,o)=>{const a=await g(t,e,o),s={};if(a)for(const[r,d]of Object.entries(a))d!=null&&d!==""&&(s[r]=d);const i={projectId:t,apiKey:e,apiUrl:o,...s};return new h(i)},testCredentials:async(t,e,o)=>{const a=o||p;try{const s=await fetch(`${a}/widget/config?project_id=${encodeURIComponent(t)}`,{method:"GET",headers:{"X-API-Key":e}});return{success:s.ok,status:s.status,data:s.ok?await s.json():null}}catch(s){return{success:!1,status:0,error:s.message}}}},document.addEventListener("DOMContentLoaded",async()=>{const t=document.querySelector("script[data-cevvo-project-id]");if(t){const e=t.getAttribute("data-cevvo-project-id")||"",o=t.getAttribute("data-cevvo-api-key")||"",a=t.getAttribute("data-cevvo-api-url")||void 0;let s=null;e&&o&&(s=await g(e,o,a));const i={projectId:e,apiKey:o,apiUrl:a,...s,...t.getAttribute("data-cevvo-project-name")&&{projectName:t.getAttribute("data-cevvo-project-name")},...t.getAttribute("data-cevvo-project-color")&&{projectColor:t.getAttribute("data-cevvo-project-color")},...t.getAttribute("data-cevvo-button-text")&&{buttonText:t.getAttribute("data-cevvo-button-text")},...t.getAttribute("data-cevvo-button-bg-color")&&{buttonBgColor:t.getAttribute("data-cevvo-button-bg-color")},...t.getAttribute("data-cevvo-modal-title")&&{modalTitle:t.getAttribute("data-cevvo-modal-title")},...t.getAttribute("data-cevvo-modal-placeholder")&&{modalPlaceholder:t.getAttribute("data-cevvo-modal-placeholder")}},r=t.getAttribute("data-cevvo-example-questions");if(r)try{i.modalExampleQuestions=JSON.parse(r)}catch{}new h(i)}})})()})();
|