@foisit/react-wrapper 2.1.1 → 2.1.2

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/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './lib/react-wrapper';
2
+ export * from './lib/components/AssistantProvider';
3
+ export * from './lib/components/AssistantActivator';
4
+ export * from './lib/hooks/useAssistant';
5
+ export * from './lib/hooks/useAssistantState';
6
+ export * from './lib/services/AssistantService';
package/index.js ADDED
@@ -0,0 +1,412 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("react/jsx-runtime"),u=require("react"),I={};function E(){return g.jsx("div",{className:I.container,children:g.jsx("h1",{children:"Welcome to ReactWrapper!"})})}class L{constructor(){this.endpoint="https://foisit-ninja.netlify.app/.netlify/functions/intent"}async determineIntent(e,t,s){try{const i=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userInput:e,context:s,commands:t.map(c=>({id:c.id,command:c.command,description:c.description,keywords:c.keywords,parameters:c.parameters}))})});if(!i.ok)throw new Error("Proxy API request failed");return await i.json()}catch(i){return console.error("Foisit AI Error:",i),{type:"unknown"}}}}class M{constructor(e=!0){this.commands=new Map,this.pendingConfirmation=null,this.conversationContext=null,this.enableSmartIntent=!0,this.enableSmartIntent=e,this.aiService=new L}addCommand(e,t){let s;if(typeof e=="string"){if(!t)throw new Error("Action is required when passing a command string.");s={command:e,action:t,id:`cmd_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}else s=e,s.id||(s.id=`cmd_${Date.now()}_${Math.random().toString(36).substr(2,9)}`);const i=s.command.toLowerCase();this.commands.set(i,s)}removeCommand(e){const t=e.toLowerCase();this.commands.has(t)&&this.commands.delete(t)}async executeCommand(e){var c;if(typeof e=="object"&&this.conversationContext){const o=Array.from(this.commands.values()).find(a=>{var n;return a.id===((n=this.conversationContext)==null?void 0:n.commandId)});if(o){const a={...this.conversationContext.params,...e};return this.conversationContext=null,this.runAction(o,a)}}const t=(typeof e=="string"?e:"").toLowerCase().trim();if(this.pendingConfirmation)if(t==="yes"||t==="y"||t==="confirm"){const o=this.pendingConfirmation;return this.pendingConfirmation=null,this.runAction(o)}else return t==="no"||t==="n"||t==="cancel"?(this.pendingConfirmation=null,{type:"success",message:"Action cancelled."}):{type:"ambiguous",message:`Please confirm: Are you sure you want to ${this.pendingConfirmation.description||this.pendingConfirmation.command}?`,options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]};if(!this.conversationContext){const o=this.commands.get(t);if(o){if(!o.parameters||o.parameters.length===0)return o.critical?(this.pendingConfirmation=o,{type:"ambiguous",message:`Are you sure you want to ${o.description||o.command}?`,options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}):this.runAction(o);this.conversationContext={commandId:o.id||"",params:{}};const a=await Promise.all(o.parameters.map(async n=>{let h=n.options;if(n.getOptions)try{h=await n.getOptions()}catch(m){console.error(`Error fetching options for ${n.name}`,m)}return{name:n.name,label:n.name.charAt(0).toUpperCase()+n.name.slice(1),value:"",required:n.required,type:n.type||"string",options:h}}));return{type:"form",message:o.description||`Please fill in the details for ${o.command}:`,fields:a}}}const s=Array.from(this.commands.values());if(this.enableSmartIntent){const o=await this.aiService.determineIntent(t,s,this.conversationContext);if(o.type==="match"&&o.match){const a=s.find(n=>n.id===o.match);if(a){const n={...((c=this.conversationContext)==null?void 0:c.params)||{},...o.params||{}};if(o.incomplete){if(this.conversationContext={commandId:a.id,params:n},a.parameters&&a.parameters.length>0){const h=await Promise.all(a.parameters.map(async m=>{let d=m.options;if(m.getOptions)try{d=await m.getOptions()}catch(f){console.error(`Error fetching options for ${m.name}`,f)}return{name:m.name,label:m.name.charAt(0).toUpperCase()+m.name.slice(1),value:n[m.name]||"",required:m.required,type:m.type||"string",options:d}}));return{type:"form",message:o.message||`Please fill in the details for ${a.command}:`,fields:h}}return{type:"ambiguous",message:o.message||`Need more info for ${a.command}...`}}return this.conversationContext=null,a.critical?(this.pendingConfirmation={...a,action:()=>a.action(n)},{type:"ambiguous",message:`Are you sure you want to ${a.description||a.command}?`,options:[{label:"Yes",value:"yes"},{label:"No",value:"no"}]}):this.runAction(a,n)}}else if(o.type==="ambiguous"&&o.options)return{type:"ambiguous",message:"Did you mean...",options:o.options.map(a=>({label:a.label,value:a.label}))}}return{type:"ambiguous",message:"I'm not sure what you mean. Here is what I can do:",options:s.map(o=>({label:o.command,value:o.command}))}}async runAction(e,t){try{const s=await e.action(t);return typeof s=="string"?{type:"success",message:s}:s&&s.type?s:{type:"success",message:`Executed: ${e.command}`}}catch(s){return{type:"error",message:s.message||"An error occurred during execution."}}}getCommands(){return Array.from(this.commands.keys())}}class k{constructor(){this.synth=window.speechSynthesis}speak(e,t){if(!this.synth){console.error("SpeechSynthesis API is not supported in this browser.");return}const s=new SpeechSynthesisUtterance(e);t&&(s.pitch=t.pitch||1,s.rate=t.rate||1,s.volume=t.volume||1),s.onend=()=>{console.log("Speech finished.")},s.onerror=i=>{console.error("Error during speech synthesis:",i.error)},this.synth.speak(s)}stopSpeaking(){this.synth&&this.synth.cancel()}}class P{constructor(){this.fallbackMessage="Sorry, I didn’t understand that."}setFallbackMessage(e){this.fallbackMessage=e}handleFallback(e){console.log(this.fallbackMessage),new k().speak(this.fallbackMessage)}}class T{constructor(e="en-US"){this.isListening=!1,this.isStoppedSpeechRecog=!1,this.restartAllowed=!0}startListening(e){console.warn("VoiceProcessor: Voice interaction is currently DISABLED.")}stopListening(){if(console.log("VoiceProcessor: Stopping listening..."),this.isStoppedSpeechRecog=!0,this.restartAllowed=!1,!this.isListening){console.warn("VoiceProcessor: Already stopped. Skipping stop...");return}try{this.recognition.stop(),this.isListening=!1,console.log("VoiceProcessor: Listening stopped.")}catch(e){console.error("VoiceProcessor: Failed to stop SpeechRecognition:",e)}}handleResult(e,t){}handleEnd(){console.log("VoiceProcessor: Session ended."),this.isListening=!1,this.restartAllowed&&!this.isStoppedSpeechRecog&&(console.log("VoiceProcessor: Restarting session due to unexpected stop..."),setTimeout(()=>this.startListening(()=>{}),560))}handleError(e){console.error("VoiceProcessor: Error occurred:",e.error),e.error==="no-speech"?console.log("VoiceProcessor: No speech detected."):e.error==="audio-capture"&&console.log("VoiceProcessor: Microphone not detected."),this.isListening=!1}}class B{constructor(){this.lastTap=0}setupDoubleTapListener(e){document.addEventListener("dblclick",()=>{e()}),document.addEventListener("touchend",t=>{const s=new Date().getTime(),i=s-this.lastTap;i<300&&i>0&&e(),this.lastTap=s})}}function D(){if(document.querySelector("#assistant-styles")){console.log("Styles already injected");return}const e=document.createElement("style");e.id="assistant-styles",e.innerHTML=`
2
+ /* Rounded shape with gradient animation */
3
+ .gradient-indicator {
4
+ position: fixed;
5
+ top: 20px;
6
+ right: 20px;
7
+ width: 60px;
8
+ height: 60px;
9
+ border-radius: 50%;
10
+ background: linear-gradient(135deg, #ff6ec4, #7873f5, #5e8cff, #6ed0f6);
11
+ box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
12
+ animation: amoeba 5s infinite ease-in-out;
13
+ z-index: 9999; /* Ensure it's above all other elements */
14
+ }
15
+
16
+ /* Amoeba effect for the borders */
17
+ @keyframes amoeba {
18
+ 0% {
19
+ border-radius: 50%;
20
+ }
21
+ 25% {
22
+ border-radius: 40% 60% 60% 40%;
23
+ }
24
+ 50% {
25
+ border-radius: 60% 40% 40% 60%;
26
+ }
27
+ 75% {
28
+ border-radius: 40% 60% 60% 40%;
29
+ }
30
+ 100% {
31
+ border-radius: 50%;
32
+ }
33
+ }
34
+ `,document.head.appendChild(e),console.log("Gradient styles injected")}function R(){if(document.querySelector("#gradient-indicator"))return;const r=document.createElement("div");r.id="gradient-indicator",D(),r.classList.add("gradient-indicator"),document.body.appendChild(r),console.log("Gradient indicator added to the DOM")}function H(){const r=document.querySelector("#gradient-indicator");r&&(r.remove(),console.log("Gradient indicator removed from the DOM"))}class N{constructor(){this.state="idle",this.subscribers=[]}getState(){return this.state}setState(e){this.state=e,this.notifySubscribers(),console.log("State updated:",e),e==="listening"?R():H()}subscribe(e){this.subscribers.push(e)}notifySubscribers(){this.subscribers.forEach(e=>e(this.state))}}const l=class l{constructor(e){this.isOpen=!1,this.submitCallback=null,this.closeCallback=null,this.chatContainer=null,this.config={},e&&(this.config=e),this.injectStyles(),this.injectOverlay(),this.injectFloatingButton(),this.setupEventListeners(),this.chatContainer=document.getElementById("foisit-chat-history")}destroy(){const e=document.getElementById(l.OVERLAY_ID);e&&e.remove();const t=document.getElementById(l.STYLES_ID);t&&t.remove();const s=document.getElementById("foisit-floating-btn");s&&s.remove(),this.isOpen=!1,this.chatContainer=null,this.submitCallback=null,this.closeCallback=null}registerCallbacks(e,t){this.submitCallback=e,this.closeCallback=t||null}show(e,t){const s=document.getElementById(l.OVERLAY_ID),i=document.getElementById(l.INPUT_ID);this.chatContainer=document.getElementById("foisit-chat-history"),s&&i&&(this.submitCallback=e,this.closeCallback=t||null,s.style.display="flex",setTimeout(()=>{s.classList.add("visible"),i.focus(),i.focus(),i.value="",this.chatContainer&&(this.chatContainer.innerHTML="")},10),this.isOpen=!0)}hide(){const e=document.getElementById(l.OVERLAY_ID);e&&(e.classList.remove("visible"),setTimeout(()=>{e.style.display="none"},300),this.isOpen=!1,this.closeCallback&&this.closeCallback())}toggle(e,t){this.isOpen?this.hide():this.show(e,t)}addMessage(e,t="system"){if(!this.chatContainer)return;const s=document.createElement("div");s.className=`foisit-bubble ${t}`,s.textContent=e,this.chatContainer.appendChild(s),this.scrollToBottom()}addOptions(e){if(!this.chatContainer)return;const t=document.createElement("div");t.className="foisit-options-container",e.forEach(s=>{const i=document.createElement("button");i.className="foisit-option-chip",i.textContent=s.label,i.onclick=()=>{this.addMessage(s.label,"user"),this.submitCallback&&this.submitCallback(s.value)},t.appendChild(i)}),this.chatContainer.appendChild(t),this.scrollToBottom()}injectFloatingButton(){var i,c,o,a;if(((i=this.config.floatingButton)==null?void 0:i.visible)===!1)return;const e=document.getElementById("foisit-floating-btn");e&&e.remove();const t=document.createElement("div");t.id="foisit-floating-btn",t.className="foisit-floating-btn",t.title=((c=this.config.floatingButton)==null?void 0:c.tooltip)||"Open Foisit Assistant";const s=(o=this.config.floatingButton)==null?void 0:o.position;s&&(t.style.bottom=s.bottom,t.style.right=s.right),(a=this.config.floatingButton)!=null&&a.customHtml?t.innerHTML=this.config.floatingButton.customHtml:t.innerHTML=`
35
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
36
+ <path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 4C16.42 4 20 7.58 20 12C20 16.42 16.42 20 12 20C7.58 20 4 16.42 4 12C4 7.58 7.58 4 12 4Z" fill="white" fill-opacity="0.8"/>
37
+ <path d="M12 6C8.69 6 6 8.69 6 12C6 15.31 8.69 18 12 18C15.31 18 18 15.31 18 12C18 8.69 15.31 6 12 6ZM12 16C9.79 16 8 14.21 8 12C8 9.79 9.79 8 12 8C14.21 8 16 9.79 16 12C16 14.21 14.21 16 12 16Z" fill="white"/>
38
+ </svg>
39
+ `,t.onclick=()=>{this.submitCallback&&this.toggle(this.submitCallback,this.closeCallback||void 0)},document.body.appendChild(t)}addForm(e,t,s){if(!this.chatContainer)return;const i=document.createElement("div");i.className="foisit-form-card";const c=document.createElement("div");c.className="foisit-form-message",c.textContent=e,i.appendChild(c);const o={};t.forEach(n=>{var f,w;const h=document.createElement("div");h.className="foisit-field-group";const m=document.createElement("label");m.textContent=n.label,h.appendChild(m);let d;if((n.type==="select"||n.options)&&((f=n.options)!=null&&f.length)&&n.options.length>0){d=document.createElement("select"),d.className="foisit-field-input";const p=document.createElement("option");p.value="",p.textContent=`Select ${n.label}`,p.disabled=!0,p.selected=!n.value,d.appendChild(p),(w=n.options)==null||w.forEach(x=>{const b=document.createElement("option");b.value=x.value,b.textContent=x.label,n.value===x.value&&(b.selected=!0),d.appendChild(b)})}else d=document.createElement("input"),d.className="foisit-field-input",d.placeholder=n.label,d.value=n.value||"",n.type==="date"?d.type="date":n.type==="number"?d.type="number":d.type="text";o[n.name]=d,h.appendChild(d),i.appendChild(h)});const a=document.createElement("button");a.className="foisit-form-submit",a.textContent="Submit",a.onclick=()=>{const n={};Object.keys(o).forEach(h=>{n[h]=o[h].value}),a.disabled=!0,a.textContent="Submitted",i.style.opacity="0.7",i.style.pointerEvents="none",s(n)},i.appendChild(a),this.chatContainer.appendChild(i),this.scrollToBottom()}showLoading(){if(!this.chatContainer||document.getElementById("foisit-loading-bubble"))return;const e=document.createElement("div");e.id="foisit-loading-bubble",e.className="foisit-bubble system loading",e.innerHTML="<span>.</span><span>.</span><span>.</span>",this.chatContainer.appendChild(e),this.scrollToBottom()}hideLoading(){const e=document.getElementById("foisit-loading-bubble");e&&e.remove()}scrollToBottom(){this.chatContainer&&(this.chatContainer.scrollTop=this.chatContainer.scrollHeight)}injectStyles(){if(document.getElementById(l.STYLES_ID))return;const e=document.createElement("style");e.id=l.STYLES_ID,e.innerHTML=`
40
+ #${l.OVERLAY_ID} {
41
+ position: fixed;
42
+ top: 24px;
43
+ right: 24px;
44
+ width: 320px;
45
+ z-index: 99999;
46
+ display: none;
47
+ flex-direction: column;
48
+ opacity: 0;
49
+ transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
50
+ transform: translateY(-10px);
51
+ }
52
+
53
+ #${l.OVERLAY_ID}.visible {
54
+ opacity: 1;
55
+ transform: translateY(0);
56
+ }
57
+
58
+ .foisit-content {
59
+ width: 100%;
60
+ padding: 0;
61
+ border-radius: 16px;
62
+ overflow: hidden;
63
+ /* Stronger Frosted Look (User Provided) */
64
+ background: linear-gradient(
65
+ 135deg,
66
+ rgba(255, 255, 255, 0.25),
67
+ rgba(255, 255, 255, 0.05)
68
+ );
69
+ backdrop-filter: blur(20px);
70
+ -webkit-backdrop-filter: blur(20px);
71
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
72
+ border: 1px solid rgba(255, 255, 255, 0.4);
73
+ display: flex;
74
+ flex-direction: column;
75
+ }
76
+
77
+ #${l.INPUT_ID} {
78
+ width: 100%;
79
+ background: transparent;
80
+ border: none;
81
+ font-size: 16px;
82
+ color: #333;
83
+ padding: 18px 20px 12px 20px;
84
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
85
+ outline: none;
86
+ text-align: left;
87
+ resize: none;
88
+ min-height: 48px;
89
+ max-height: 200px;
90
+ overflow-y: auto;
91
+ }
92
+
93
+ #${l.INPUT_ID}::placeholder {
94
+ color: rgba(60, 60, 67, 0.7);
95
+ font-weight: 500;
96
+ }
97
+
98
+ @media (prefers-color-scheme: dark) {
99
+ .foisit-content {
100
+ background: linear-gradient(
101
+ 135deg,
102
+ rgba(40, 40, 40, 0.65),
103
+ rgba(40, 40, 40, 0.25)
104
+ );
105
+ border: 1px solid rgba(255, 255, 255, 0.1);
106
+ }
107
+ #${l.INPUT_ID} {
108
+ color: white;
109
+ }
110
+ #${l.INPUT_ID}::placeholder {
111
+ color: rgba(235, 235, 245, 0.6);
112
+ }
113
+ .foisit-watermark {
114
+ color: rgba(255, 255, 255, 0.5);
115
+ }
116
+ }
117
+
118
+ .foisit-watermark {
119
+ align-self: flex-end;
120
+ margin: 0 12px 10px auto;
121
+ padding: 4px 8px;
122
+ border-radius: 8px;
123
+
124
+ font-size: 9px;
125
+ font-weight: 600;
126
+ letter-spacing: 0.8px;
127
+ text-transform: capitalize;
128
+
129
+ background: rgba(0, 0, 0, 0.35);
130
+ backdrop-filter: blur(6px);
131
+ -webkit-backdrop-filter: blur(6px);
132
+
133
+ color: rgba(255, 255, 255, 0.85);
134
+ pointer-events: none;
135
+ }
136
+
137
+
138
+ /* Chat UI Styles */
139
+ #foisit-chat-history {
140
+ flex: 1;
141
+ overflow-y: auto;
142
+ padding: 16px;
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 12px;
146
+ max-height: 400px;
147
+ }
148
+
149
+ .foisit-bubble {
150
+ max-width: 85%;
151
+ padding: 8px 12px;
152
+ border-radius: 12px;
153
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
154
+ font-size: 14px;
155
+ line-height: 1.4;
156
+ }
157
+
158
+ .foisit-bubble.user {
159
+ align-self: flex-end;
160
+ background: rgba(0, 0, 0, 0.05); /* Subtle dark for user */
161
+ color: #333;
162
+ border-bottom-right-radius: 4px;
163
+ }
164
+
165
+ .foisit-bubble.system {
166
+ align-self: flex-start;
167
+ background: rgba(255, 255, 255, 0.4); /* Glassy white */
168
+ color: #333;
169
+ border-bottom-left-radius: 4px;
170
+ }
171
+
172
+ .foisit-options-container {
173
+ display: flex;
174
+ flex-wrap: wrap;
175
+ gap: 8px;
176
+ margin-left: 4px;
177
+ }
178
+
179
+ .foisit-option-chip {
180
+ padding: 6px 12px;
181
+ background: rgba(255, 255, 255, 0.5);
182
+ border: 1px solid rgba(0, 0, 0, 0.1);
183
+ border-radius: 20px;
184
+ font-size: 13px;
185
+ color: #333;
186
+ cursor: pointer;
187
+ transition: all 0.2s;
188
+ }
189
+
190
+ .foisit-option-chip:hover {
191
+ background: rgba(255, 255, 255, 0.8);
192
+ transform: translateY(-1px);
193
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
194
+ }
195
+
196
+ @media (prefers-color-scheme: dark) {
197
+ .foisit-bubble.user {
198
+ background: rgba(255, 255, 255, 0.1);
199
+ color: white;
200
+ }
201
+ .foisit-bubble.system {
202
+ background: rgba(255, 255, 255, 0.05);
203
+ color: rgba(255, 255, 255, 0.9);
204
+ }
205
+ .foisit-option-chip {
206
+ background: rgba(255, 255, 255, 0.1);
207
+ border-color: rgba(255, 255, 255, 0.2);
208
+ color: white;
209
+ }
210
+ .foisit-option-chip:hover {
211
+ background: rgba(255, 255, 255, 0.2);
212
+ }
213
+ /* Loading State */
214
+ .foisit-loading-dots {
215
+ display: inline-flex;
216
+ gap: 4px;
217
+ align-items: center;
218
+ padding: 4px 8px;
219
+ background: rgba(255, 255, 255, 0.4);
220
+ border-radius: 12px;
221
+ margin-left: 12px;
222
+ align-self: flex-start;
223
+ }
224
+ .foisit-dot {
225
+ width: 6px;
226
+ height: 6px;
227
+ background: #666;
228
+ border-radius: 50%;
229
+ animation: foisit-bounce 1.4s infinite ease-in-out both;
230
+ }
231
+ .foisit-dot:nth-child(1) { animation-delay: -0.32s; }
232
+ .foisit-dot:nth-child(2) { animation-delay: -0.16s; }
233
+
234
+ @keyframes foisit-bounce {
235
+ 0%, 80%, 100% { transform: scale(0); }
236
+ 40% { transform: scale(1); }
237
+ }
238
+
239
+ /* Floating Trigger Button - Glassmorphism Style */
240
+ .foisit-floating-btn {
241
+ position: fixed;
242
+ bottom: 20px;
243
+ right: 20px;
244
+ width: 52px;
245
+ height: 52px;
246
+ /* Frosted Glass Effect */
247
+ background: linear-gradient(
248
+ 135deg,
249
+ rgba(255, 255, 255, 0.25),
250
+ rgba(255, 255, 255, 0.08)
251
+ );
252
+ backdrop-filter: blur(16px);
253
+ -webkit-backdrop-filter: blur(16px);
254
+ border-radius: 50%;
255
+ display: flex;
256
+ align-items: center;
257
+ justify-content: center;
258
+ cursor: pointer;
259
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
260
+ border: 1px solid rgba(255, 255, 255, 0.35);
261
+ z-index: 9998;
262
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
263
+ }
264
+
265
+ .foisit-floating-btn:hover {
266
+ transform: scale(1.08);
267
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
268
+ }
269
+
270
+ /* Dark mode for floating button */
271
+ @media (prefers-color-scheme: dark) {
272
+ .foisit-floating-btn {
273
+ background: linear-gradient(
274
+ 135deg,
275
+ rgba(60, 60, 60, 0.6),
276
+ rgba(40, 40, 40, 0.35)
277
+ );
278
+ border-color: rgba(255, 255, 255, 0.15);
279
+ }
280
+ }
281
+
282
+ .foisit-floating-btn img {
283
+ width: 100%;
284
+ height: 100%;
285
+ object-fit: cover;
286
+ border-radius: 50%;
287
+ }
288
+
289
+ /* Dark mode support for inputs */
290
+ @media (prefers-color-scheme: dark) {
291
+ .foisit-field-input {
292
+ background: rgba(40, 40, 40, 0.6);
293
+ color: white;
294
+ border-color: rgba(255, 255, 255, 0.1);
295
+ }
296
+ }
297
+ .foisit-watermark {
298
+ color: rgba(255, 255, 255, 0.3);
299
+ }
300
+ }
301
+
302
+ /* Loading Animation */
303
+ .foisit-bubble.loading span {
304
+ animation: foisit-dots 1.4s infinite ease-in-out both;
305
+ font-size: 20px;
306
+ line-height: 10px;
307
+ margin: 0 1px;
308
+ }
309
+
310
+ .foisit-bubble.loading span:nth-child(1) { animation-delay: -0.32s; }
311
+ .foisit-bubble.loading span:nth-child(2) { animation-delay: -0.16s; }
312
+
313
+ @keyframes foisit-dots {
314
+ 0%, 80%, 100% { transform: scale(0); opacity: 0.5; }
315
+ 40% { transform: scale(1); opacity: 1; }
316
+ }
317
+
318
+ /* Form Styles */
319
+ .foisit-form-card {
320
+ align-self: flex-start;
321
+ background: rgba(255, 255, 255, 0.4);
322
+ padding: 16px;
323
+ border-radius: 12px;
324
+ width: 100%;
325
+ box-sizing: border-box;
326
+ border: 1px solid rgba(255, 255, 255, 0.2);
327
+ display: flex;
328
+ flex-direction: column;
329
+ gap: 12px;
330
+ }
331
+
332
+ .foisit-form-message {
333
+ font-family: -apple-system, sans-serif;
334
+ font-size: 14px;
335
+ color: #333;
336
+ margin-bottom: 4px;
337
+ font-weight: 500;
338
+ }
339
+
340
+ .foisit-field-group {
341
+ display: flex;
342
+ flex-direction: column;
343
+ gap: 4px;
344
+ }
345
+
346
+ .foisit-field-group label {
347
+ font-size: 11px;
348
+ font-weight: 600;
349
+ text-transform: uppercase;
350
+ color: rgba(0, 0, 0, 0.5);
351
+ }
352
+
353
+ .foisit-field-input {
354
+ background: rgba(255, 255, 255, 0.6);
355
+ border: 1px solid rgba(0, 0, 0, 0.1);
356
+ border-radius: 8px;
357
+ padding: 8px 12px;
358
+ font-size: 14px;
359
+ color: #333;
360
+ outline: none;
361
+ }
362
+
363
+ .foisit-field-input:focus {
364
+ border-color: rgba(0, 0, 0, 0.3);
365
+ }
366
+
367
+ .foisit-form-submit {
368
+ background: #000;
369
+ color: #fff;
370
+ border: none;
371
+ border-radius: 8px;
372
+ padding: 10px;
373
+ font-size: 14px;
374
+ font-weight: 500;
375
+ cursor: pointer;
376
+ transition: opacity 0.2s;
377
+ margin-top: 4px;
378
+ }
379
+
380
+ .foisit-form-submit:hover {
381
+ opacity: 0.8;
382
+ }
383
+
384
+ @media (prefers-color-scheme: dark) {
385
+ .foisit-form-card {
386
+ background: rgba(255, 255, 255, 0.05);
387
+ color: white;
388
+ }
389
+ .foisit-form-message {
390
+ color: white;
391
+ }
392
+ .foisit-field-group label {
393
+ color: rgba(255, 255, 255, 0.5);
394
+ }
395
+ .foisit-field-input {
396
+ background: rgba(0, 0, 0, 0.2);
397
+ border-color: rgba(255, 255, 255, 0.1);
398
+ color: white;
399
+ }
400
+ .foisit-form-submit {
401
+ background: #fff;
402
+ color: #000;
403
+ }
404
+ }
405
+
406
+ `,document.head.appendChild(e)}injectOverlay(){if(document.getElementById(l.OVERLAY_ID))return;const e=this.config.inputPlaceholder||"How can I help you?",t=document.createElement("div");t.id=l.OVERLAY_ID,t.innerHTML=`
407
+ <div class="foisit-content">
408
+ <div id="foisit-chat-history"></div>
409
+ <textarea id="${l.INPUT_ID}" placeholder="${e}" autocomplete="off" rows="1"></textarea>
410
+ <div class="foisit-watermark">Foisit</div>
411
+ </div>
412
+ `,document.body.appendChild(t)}setupEventListeners(){const e=document.getElementById(l.OVERLAY_ID),t=document.getElementById(l.INPUT_ID);!e||!t||(t.addEventListener("input",()=>{t.style.height="auto",t.style.height=Math.min(t.scrollHeight,200)+"px"}),e.addEventListener("click",s=>{s.target===e&&this.hide()}),t.addEventListener("keydown",s=>{if(s.key==="Enter"&&!s.shiftKey){s.preventDefault();const i=t.value.trim();i&&this.submitCallback&&(this.submitCallback(i),t.value="",t.style.height="auto")}s.key==="Escape"&&this.hide()}))}};l.OVERLAY_ID="foisit-assistant-overlay",l.INPUT_ID="foisit-assistant-input",l.STYLES_ID="foisit-assistant-styles";let v=l;class S{constructor(e){this.config=e,this.isActivated=!1,this.lastProcessedInput="",this.processingLock=!1,this.defaultIntroMessage="How can I help you?",this.commandHandler=new M(this.config.enableSmartIntent!==!1),this.fallbackHandler=new P,this.voiceProcessor=new T,this.textToSpeech=new k,this.stateManager=new N,this.gestureHandler=new B,this.overlayManager=new v({floatingButton:this.config.floatingButton,inputPlaceholder:this.config.inputPlaceholder}),this.config.commands.forEach(t=>this.commandHandler.addCommand(t)),this.config.fallbackResponse&&this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse),this.gestureHandler.setupDoubleTapListener(()=>this.toggle()),this.overlayManager.registerCallbacks(async t=>{this.overlayManager.addMessage(t,"user"),await this.handleCommand(t)},()=>console.log("AssistantService: Overlay closed."))}startListening(){console.log("AssistantService: Starting listening..."),this.voiceProcessor.startListening(async e=>{var i,c;if(this.processingLock)return;const t=e.toLowerCase().trim();if(!t||t.length<3||t===this.lastProcessedInput){console.log("AssistantService: Ignoring irrelevant input.");return}if(this.lastProcessedInput=t,!this.isActivated){await this.processActivation(t);return}t===((i=this.config.fallbackResponse)==null?void 0:i.toLowerCase())||t===((c=this.config.introMessage)==null?void 0:c.toLowerCase())||t===this.defaultIntroMessage.toLowerCase()?console.log("AssistantService: Ignoring fallback or intro message."):await this.handleCommand(t),this.processingLock=!0,setTimeout(()=>this.processingLock=!1,1e3)})}stopListening(){console.log("AssistantService: Stopping listening..."),this.voiceProcessor.stopListening(),this.isActivated=!1}async processActivation(e){var s;const t=(s=this.config.activationCommand)==null?void 0:s.toLowerCase();t&&(e===t?(console.log("AssistantService: Activation matched."),this.isActivated=!0,this.textToSpeech.speak(this.config.introMessage||this.defaultIntroMessage)):console.log("AssistantService: Activation command not recognized."))}async handleCommand(e){this.overlayManager.showLoading();const t=await this.commandHandler.executeCommand(e);this.overlayManager.hideLoading(),t.message&&this.overlayManager.addMessage(t.message,"system"),t.type==="form"&&t.fields?this.overlayManager.addForm(t.message,t.fields,async s=>{this.overlayManager.showLoading();const i=await this.commandHandler.executeCommand(s);this.overlayManager.hideLoading(),this.processResponse(i)}):t.type==="ambiguous"&&t.options?this.overlayManager.addOptions(t.options):t.type==="error"&&this.fallbackHandler.handleFallback(e)}destroy(){this.voiceProcessor.stopListening(),this.overlayManager.destroy()}processResponse(e){e.message&&this.overlayManager.addMessage(e.message,"system"),e.type==="form"&&e.fields?this.overlayManager.addForm(e.message,e.fields,async t=>{this.overlayManager.showLoading();const s=await this.commandHandler.executeCommand(t);this.overlayManager.hideLoading(),this.processResponse(s)}):e.type==="ambiguous"&&e.options&&this.overlayManager.addOptions(e.options)}addCommand(e,t){console.log(typeof e=="string"?`AssistantService: Adding command "${e}".`:`AssistantService: Adding rich command "${e.command}".`),this.commandHandler.addCommand(e,t)}removeCommand(e){console.log(`AssistantService: Removing command "${e}".`),this.commandHandler.removeCommand(e)}getCommands(){return this.commandHandler.getCommands()}toggle(e,t){console.log("AssistantService: Toggling overlay..."),this.overlayManager.toggle(async s=>{this.overlayManager.addMessage(s,"user"),e&&e(s),await this.handleCommand(s)},()=>{console.log("AssistantService: Overlay closed."),t&&t()})}}const C=u.createContext(null);let y=null;const $=({config:r,children:e})=>{const[t,s]=u.useState(null),[i,c]=u.useState(!1);return u.useEffect(()=>{y?console.warn("Multiple AssistantProvider instances detected. Reusing global AssistantService."):(console.log("Initializing global AssistantService..."),y=new S(r));const o=y;return s(o),o.startListening(),c(!0),()=>{var a;console.log("Cleaning up AssistantService..."),(a=o.destroy)==null||a.call(o),y=null}},[r]),!i||!t?g.jsx("div",{children:"Loading Assistant..."}):g.jsx(C.Provider,{value:t,children:e})},A=()=>{const r=u.useContext(C);if(console.log("assistant",r),!r)throw new Error("useAssistant must be used within an AssistantProvider");return r},O=({label:r="Activate Assistant",onActivate:e})=>{const t=A(),s=()=>{e&&e(),t.reactivate()};return g.jsx("button",{onClick:s,className:"assistant-activator",children:r})},F=r=>{const[e,t]=u.useState(r.getState());return u.useEffect(()=>{const s=i=>{t(i)};return r.subscribe(s),()=>{r.subscribe(()=>{})}},[r]),e};exports.AssistantActivator=O;exports.AssistantContext=C;exports.AssistantProvider=$;exports.AssistantService=S;exports.ReactWrapper=E;exports.useAssistant=A;exports.useAssistantState=F;