@yassirbenmoussa/aicommerce-sdk 1.8.0 → 1.9.0

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.
@@ -1,5 +1,5 @@
1
1
  var AICommerceWidget=(function(exports){'use strict';/*! AI Commerce Widget v1.0.0 | MIT License | https://aicommerce.dev */
2
- var L=class i{constructor(r){this.sessionToken=null;this.products={create:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(r)}),batchUpsert:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:r})}),list:async r=>{let e=new URLSearchParams;r?.page&&e.set("page",String(r.page)),r?.perPage&&e.set("perPage",String(r.perPage)),r?.search&&e.set("search",r.search),r?.categoryId&&e.set("categoryId",r.categoryId),r?.isActive!==void 0&&e.set("isActive",String(r.isActive));let s=e.toString();return this.request(`/api/v1/products${s?`?${s}`:""}`)},get:async r=>this.request(`/api/v1/products/${r}`),update:async(r,e)=>this.request(`/api/v1/products/${r}`,{method:"PUT",body:JSON.stringify(e)}),delete:async r=>this.request(`/api/v1/products/${r}`,{method:"DELETE"})};if(!r.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=r.apiKey,this.storeId=r.storeId,this.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let r=document.querySelector("script[data-aicommerce-url]");if(r)return r.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let s=`${this.baseUrl}${r}`,b=new AbortController,a=setTimeout(()=>b.abort(),this.timeout);try{let p=await fetch(s,{...e,signal:b.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(a),!p.ok){let T=await p.json().catch(()=>({})),f={code:T.code||"UNKNOWN_ERROR",message:T.message||T.error||`HTTP ${p.status}`,status:p.status};throw new P(f.message,f.code,f.status)}return p.json()}catch(p){throw clearTimeout(a),p instanceof P?p:p instanceof Error&&p.name==="AbortError"?new P("Request timeout","TIMEOUT",408):new P(p instanceof Error?p.message:"Unknown error","NETWORK_ERROR",0)}}async chat(r,e){let s=typeof r=="string"?{message:r,context:e,sessionToken:this.sessionToken||void 0}:{...r,sessionToken:r.sessionToken||this.sessionToken||void 0},b=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return b.sessionToken&&(this.sessionToken=b.sessionToken),b}async chatWithAudio(r,e){let s=await r.arrayBuffer(),a={audioBase64:btoa(new Uint8Array(s).reduce((T,f)=>T+String.fromCharCode(f),"")),audioMimeType:r.type||"audio/webm",context:e,sessionToken:this.sessionToken||void 0},p=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(a)});return p.sessionToken&&(this.sessionToken=p.sessionToken),p}async createSession(){let r=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=r.session.token,r.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(r){this.sessionToken=r;}async upload(r,e){let s=new FormData;s.append("file",r),e?.folder&&s.append("folder",e.folder),e?.productId&&s.append("productId",e.productId),e?.isPrimary&&s.append("isPrimary","true");let b=`${this.baseUrl}/api/v1/upload`,a=await fetch(b,{method:"POST",headers:{"X-API-Key":this.apiKey},body:s});if(!a.ok){let p=await a.json().catch(()=>({}));throw new P(p.message||p.error||`HTTP ${a.status}`,p.code||"UPLOAD_ERROR",a.status)}return a.json()}static async quickChat(r){return new i({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},P=class i extends Error{constructor(r,e,s){super(r),this.name="AICommerceError",this.code=e,this.status=s,Object.setPrototypeOf(this,i.prototype);}};function G(i){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(i);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:99,g:102,b:241}}function q(i){let r=i.primaryColor,e=G(r),s=i.position==="bottom-left";return `
2
+ var R=class i{constructor(r){this.sessionToken=null;this.products={create:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(r)}),batchUpsert:async r=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:r})}),list:async r=>{let e=new URLSearchParams;r?.page&&e.set("page",String(r.page)),r?.perPage&&e.set("perPage",String(r.perPage)),r?.search&&e.set("search",r.search),r?.categoryId&&e.set("categoryId",r.categoryId),r?.isActive!==void 0&&e.set("isActive",String(r.isActive));let d=e.toString();return this.request(`/api/v1/products${d?`?${d}`:""}`)},get:async r=>this.request(`/api/v1/products/${r}`),update:async(r,e)=>this.request(`/api/v1/products/${r}`,{method:"PUT",body:JSON.stringify(e)}),delete:async r=>this.request(`/api/v1/products/${r}`,{method:"DELETE"})};if(!r.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=r.apiKey,this.storeId=r.storeId,this.baseUrl=this.normalizeUrl(r.baseUrl||this.detectBaseUrl()),this.timeout=r.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let r=document.querySelector("script[data-aicommerce-url]");if(r)return r.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(r){return r.replace(/\/$/,"")}async request(r,e={}){let d=`${this.baseUrl}${r}`,y=new AbortController,s=setTimeout(()=>y.abort(),this.timeout);try{let g=await fetch(d,{...e,signal:y.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...e.headers}});if(clearTimeout(s),!g.ok){let A=await g.json().catch(()=>({})),w={code:A.code||"UNKNOWN_ERROR",message:A.message||A.error||`HTTP ${g.status}`,status:g.status};throw new S(w.message,w.code,w.status)}return g.json()}catch(g){throw clearTimeout(s),g instanceof S?g:g instanceof Error&&g.name==="AbortError"?new S("Request timeout","TIMEOUT",408):new S(g instanceof Error?g.message:"Unknown error","NETWORK_ERROR",0)}}async chat(r,e){let d=typeof r=="string"?{message:r,context:e,sessionToken:this.sessionToken||void 0}:{...r,sessionToken:r.sessionToken||this.sessionToken||void 0},y=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(d)});return y.sessionToken&&(this.sessionToken=y.sessionToken),y}async chatWithAudio(r,e){let d=await r.arrayBuffer(),s={audioBase64:btoa(new Uint8Array(d).reduce((A,w)=>A+String.fromCharCode(w),"")),audioMimeType:r.type||"audio/webm",context:e,sessionToken:this.sessionToken||void 0},g=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return g.sessionToken&&(this.sessionToken=g.sessionToken),g}async createSession(){let r=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=r.session.token,r.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(r){this.sessionToken=r;}async upload(r,e){let d=new FormData;d.append("file",r),e?.folder&&d.append("folder",e.folder),e?.productId&&d.append("productId",e.productId),e?.isPrimary&&d.append("isPrimary","true");let y=`${this.baseUrl}/api/v1/upload`,s=await fetch(y,{method:"POST",headers:{"X-API-Key":this.apiKey},body:d});if(!s.ok){let g=await s.json().catch(()=>({}));throw new S(g.message||g.error||`HTTP ${s.status}`,g.code||"UPLOAD_ERROR",s.status)}return s.json()}static async quickChat(r){return new i({apiKey:r.apiKey,baseUrl:r.baseUrl}).chat(r.message,r.context)}},S=class i extends Error{constructor(r,e,d){super(r),this.name="AICommerceError",this.code=e,this.status=d,Object.setPrototypeOf(this,i.prototype);}};function Z(i){let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(i);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:99,g:102,b:241}}function O(i){let r=i.primaryColor,e=Z(r),d=i.position==="bottom-left";return `
3
3
  /* AI Commerce Widget Styles */
4
4
  #aicommerce-widget {
5
5
  --aic-primary: ${r};
@@ -20,7 +20,7 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
20
20
  line-height: 1.5;
21
21
  position: fixed;
22
22
  bottom: 20px;
23
- ${s?"left: 20px;":"right: 20px;"}
23
+ ${d?"left: 20px;":"right: 20px;"}
24
24
  z-index: var(--aic-z-index);
25
25
  }
26
26
 
@@ -74,7 +74,7 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
74
74
  .aicommerce-chat {
75
75
  position: absolute;
76
76
  bottom: 0;
77
- ${s?"left: 0;":"right: 0;"}
77
+ ${d?"left: 0;":"right: 0;"}
78
78
  width: 380px;
79
79
  max-width: calc(100vw - 40px);
80
80
  height: 600px;
@@ -86,7 +86,7 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
86
86
  flex-direction: column;
87
87
  overflow: hidden;
88
88
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
89
- transform-origin: bottom ${s?"left":"right"};
89
+ transform-origin: bottom ${d?"left":"right"};
90
90
  }
91
91
 
92
92
  .aicommerce-chat.aicommerce-closed {
@@ -515,7 +515,7 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
515
515
  @media (max-width: 420px) {
516
516
  #aicommerce-widget {
517
517
  bottom: 16px;
518
- ${s?"left: 16px;":"right: 16px;"}
518
+ ${d?"left: 16px;":"right: 16px;"}
519
519
  }
520
520
 
521
521
  .aicommerce-chat {
@@ -549,17 +549,21 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
549
549
  }
550
550
 
551
551
  /* ============================================
552
- Embedded Mode Styles
552
+ Embedded Mode Styles - ChatGPT Style
553
553
  ============================================ */
554
554
 
555
- /* Embedded container - position relative, inline flow */
555
+ /* Embedded container - fit content with max height */
556
556
  #aicommerce-widget.aicommerce-embedded {
557
557
  position: relative;
558
558
  bottom: auto;
559
559
  left: auto;
560
560
  right: auto;
561
561
  width: 100%;
562
- height: var(--aic-height, 500px);
562
+ height: auto;
563
+ max-height: var(--aic-max-height, 600px);
564
+ display: flex;
565
+ flex-direction: column;
566
+ background: transparent;
563
567
  }
564
568
 
565
569
  /* Embedded mode: hide launcher button */
@@ -567,17 +571,30 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
567
571
  display: none !important;
568
572
  }
569
573
 
570
- /* Embedded mode: chat is always visible and fills container */
574
+ /* Embedded mode: hide the header completely */
575
+ .aicommerce-embedded .aicommerce-header {
576
+ display: none !important;
577
+ }
578
+
579
+ /* Embedded mode: hide close button */
580
+ .aicommerce-embedded .aicommerce-close {
581
+ display: none !important;
582
+ }
583
+
584
+ /* Embedded mode: chat fills container with transparent background */
571
585
  .aicommerce-embedded .aicommerce-chat {
572
586
  position: relative;
573
587
  width: 100%;
574
- height: 100%;
588
+ height: auto;
575
589
  max-width: 100%;
576
- max-height: 100%;
577
- border-radius: var(--aic-radius);
590
+ border-radius: 0;
591
+ background: transparent;
592
+ box-shadow: none;
578
593
  transform: none !important;
579
594
  opacity: 1 !important;
580
595
  pointer-events: auto !important;
596
+ display: flex;
597
+ flex-direction: column;
581
598
  }
582
599
 
583
600
  /* Embedded mode: no open/close animations */
@@ -587,62 +604,324 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
587
604
  pointer-events: auto !important;
588
605
  }
589
606
 
590
- /* Embedded mode: messages area adjusts to container */
607
+ /* Embedded mode: messages area - messages start from bottom, grow upward */
591
608
  .aicommerce-embedded .aicommerce-messages {
609
+ display: flex;
610
+ flex-direction: column;
611
+ justify-content: flex-end;
612
+ overflow-y: auto;
613
+ max-height: calc(var(--aic-max-height, 600px) - 100px);
614
+ padding: 16px;
615
+ max-width: 700px;
616
+ margin: 0 auto;
617
+ width: 100%;
618
+ background: transparent;
619
+ gap: 12px;
620
+ scrollbar-width: thin;
621
+ scrollbar-color: var(--aic-border) transparent;
622
+ }
623
+
624
+ /* Embedded mode: custom scrollbar for webkit browsers */
625
+ .aicommerce-embedded .aicommerce-messages::-webkit-scrollbar {
626
+ width: 6px;
627
+ }
628
+
629
+ .aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-track {
630
+ background: transparent;
631
+ }
632
+
633
+ .aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb {
634
+ background-color: var(--aic-border);
635
+ border-radius: 3px;
636
+ }
637
+
638
+ .aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb:hover {
639
+ background-color: var(--aic-text-secondary);
640
+ }
641
+
642
+ /* Embedded mode: messages have different styling */
643
+ .aicommerce-embedded .aicommerce-message {
644
+ max-width: 100%;
645
+ }
646
+
647
+ .aicommerce-embedded .aicommerce-message-content {
648
+ background: var(--aic-bg);
649
+ border: 1px solid var(--aic-border);
650
+ border-radius: 12px;
651
+ padding: 12px 16px;
652
+ }
653
+
654
+ .aicommerce-embedded .aicommerce-user .aicommerce-message-content {
655
+ background: var(--aic-primary);
656
+ color: white;
657
+ border-color: var(--aic-primary);
658
+ }
659
+
660
+ /* Embedded mode: input container wrapper - always at bottom */
661
+ .aicommerce-embedded .aicommerce-input-wrapper {
662
+ width: 100%;
663
+ display: flex;
664
+ flex-direction: column;
665
+ align-items: center;
666
+ padding: 16px;
667
+ flex-shrink: 0;
668
+ }
669
+
670
+ /* Embedded mode: input container styled like ChatGPT */
671
+ .aicommerce-embedded .aicommerce-input-container {
672
+ width: 100%;
673
+ max-width: 700px;
674
+ background: var(--aic-bg);
675
+ border: 1px solid var(--aic-border);
676
+ border-radius: 24px;
677
+ padding: 8px 12px;
678
+ display: flex;
679
+ align-items: flex-end;
680
+ gap: 8px;
681
+ }
682
+
683
+ /* Embedded mode: textarea field styling - auto-grow */
684
+ .aicommerce-embedded .aicommerce-input {
592
685
  flex: 1;
593
- min-height: 0;
686
+ min-width: 0;
687
+ border: none;
688
+ background: transparent;
689
+ padding: 8px 4px;
690
+ font-size: 16px;
691
+ font-family: inherit;
692
+ color: var(--aic-text);
693
+ outline: none;
694
+ resize: none;
695
+ min-height: 24px;
696
+ max-height: 150px;
697
+ line-height: 1.5;
698
+ overflow-y: auto;
594
699
  }
595
700
 
596
- /* Embedded mode responsive */
597
- @media (max-width: 420px) {
598
- #aicommerce-widget.aicommerce-embedded {
599
- height: var(--aic-height, 400px);
701
+ .aicommerce-embedded .aicommerce-input::placeholder {
702
+ color: var(--aic-text-secondary);
703
+ }
704
+
705
+ /* Embedded mode: buttons styling - smaller, no overflow */
706
+ .aicommerce-embedded .aicommerce-mic,
707
+ .aicommerce-embedded .aicommerce-send {
708
+ flex-shrink: 0;
709
+ width: 36px;
710
+ height: 36px;
711
+ min-width: 36px;
712
+ border-radius: 50%;
713
+ background: var(--aic-primary);
714
+ color: white;
715
+ border: none;
716
+ display: flex;
717
+ align-items: center;
718
+ justify-content: center;
719
+ cursor: pointer;
720
+ transition: all 0.2s ease;
721
+ }
722
+
723
+ .aicommerce-embedded .aicommerce-mic:hover,
724
+ .aicommerce-embedded .aicommerce-send:hover {
725
+ opacity: 0.9;
726
+ }
727
+
728
+ .aicommerce-embedded .aicommerce-mic {
729
+ background: transparent;
730
+ color: var(--aic-text-secondary);
731
+ }
732
+
733
+ .aicommerce-embedded .aicommerce-mic:hover {
734
+ background: rgba(0, 0, 0, 0.05);
735
+ color: var(--aic-text);
736
+ }
737
+
738
+ /* Embedded mode: product cards styling */
739
+ .aicommerce-embedded .aicommerce-products {
740
+ display: flex;
741
+ flex-wrap: wrap;
742
+ gap: 12px;
743
+ margin-top: 12px;
744
+ }
745
+
746
+ .aicommerce-embedded .aicommerce-product-card {
747
+ background: var(--aic-bg);
748
+ border: 1px solid var(--aic-border);
749
+ border-radius: 12px;
750
+ max-width: 180px;
751
+ }
752
+
753
+ /* Embedded mode: typing indicator */
754
+ .aicommerce-embedded .aicommerce-typing {
755
+ background: var(--aic-bg);
756
+ border: 1px solid var(--aic-border);
757
+ border-radius: 12px;
758
+ padding: 12px 16px;
759
+ }
760
+
761
+ /* Embedded mode responsive - mobile fixes */
762
+ @media (max-width: 640px) {
763
+ .aicommerce-embedded .aicommerce-input-container {
764
+ padding: 6px 10px;
765
+ gap: 6px;
766
+ border-radius: 20px;
600
767
  }
601
768
 
602
- .aicommerce-embedded .aicommerce-chat {
603
- border-radius: 12px;
769
+ .aicommerce-embedded .aicommerce-mic,
770
+ .aicommerce-embedded .aicommerce-send {
771
+ width: 32px;
772
+ height: 32px;
773
+ min-width: 32px;
774
+ }
775
+
776
+ .aicommerce-embedded .aicommerce-mic svg,
777
+ .aicommerce-embedded .aicommerce-send svg {
778
+ width: 16px;
779
+ height: 16px;
604
780
  }
781
+
782
+ .aicommerce-embedded .aicommerce-input {
783
+ font-size: 16px;
784
+ padding: 6px 4px;
785
+ }
786
+
787
+ .aicommerce-embedded .aicommerce-messages {
788
+ padding: 12px;
789
+ }
790
+
791
+ .aicommerce-embedded .aicommerce-input-wrapper {
792
+ padding: 12px;
793
+ }
794
+ }
795
+
796
+ /* ============================================
797
+ Add to Cart Button Styles
798
+ ============================================ */
799
+
800
+ .aicommerce-add-to-cart {
801
+ width: 100%;
802
+ padding: 8px 12px;
803
+ background: var(--aic-primary);
804
+ color: white;
805
+ border: none;
806
+ border-radius: 6px;
807
+ font-size: 12px;
808
+ font-weight: 500;
809
+ cursor: pointer;
810
+ margin-top: 8px;
811
+ transition: all 0.2s;
812
+ display: flex;
813
+ align-items: center;
814
+ justify-content: center;
815
+ gap: 6px;
816
+ }
817
+
818
+ .aicommerce-add-to-cart:hover {
819
+ opacity: 0.9;
820
+ transform: translateY(-1px);
821
+ }
822
+
823
+ .aicommerce-add-to-cart:active {
824
+ transform: translateY(0);
825
+ }
826
+
827
+ .aicommerce-add-to-cart:disabled {
828
+ opacity: 0.7;
829
+ cursor: not-allowed;
830
+ transform: none;
831
+ }
832
+
833
+ .aicommerce-add-to-cart svg {
834
+ flex-shrink: 0;
605
835
  }
606
- `}function D(i){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=i;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}function Q(i){if(!i.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new L({apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},s=null,b=[],a=null,f=null,l;async function H(){try{let t=i.baseUrl||O(),o=await fetch(`${t}/api/v1/store`,{headers:{"x-api-key":i.apiKey}});return o.ok?(await o.json()).store:null}catch(t){return console.error("Failed to fetch store config:",t),null}}function O(){if(typeof window<"u"){let t=document.querySelector("script[data-aicommerce-url]");if(t)return t.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function j(){e.storeConfig=await H();let t=i.displayMode||"widget",o=t==="embedded";l={apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl||O(),displayMode:t,container:i.container,height:i.height||"500px",position:i.position||"bottom-right",theme:i.theme||"auto",primaryColor:i.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:i.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:i.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:i.zIndex||9999,buttonText:i.buttonText||"\u{1F4AC}",hideLauncher:i.hideLauncher||false,onOpen:i.onOpen,onClose:i.onClose,onProductClick:i.onProductClick,onMessage:i.onMessage};let c=q(l);if(f=D(c),o){let d=null;if(typeof i.container=="string"?d=document.querySelector(i.container):i.container instanceof HTMLElement&&(d=i.container),!d){console.error("[AI Commerce] Embedded mode requires a valid container element or selector");return}a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-embedded aicommerce-theme-${l.theme}`,a.style.setProperty("--aic-height",l.height),d.appendChild(a),e.isOpen=true;}else a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-${l.position} aicommerce-theme-${l.theme}`,document.body.appendChild(a);y(),e.messages.push({role:"assistant",content:l.welcomeMessage}),e.isLoading=false,y();}function y(){if(!a)return;let t=l.displayMode==="embedded",o=`
607
- ${!t&&!l.hideLauncher?`
836
+
837
+ /* Spinner animation for loading state */
838
+ @keyframes aicommerce-spin {
839
+ to { transform: rotate(360deg); }
840
+ }
841
+
842
+ .aicommerce-spinner {
843
+ animation: aicommerce-spin 1s linear infinite;
844
+ }
845
+ `}function W(i){let r=document.createElement("style");r.id="aicommerce-widget-styles",r.textContent=i;let e=document.getElementById("aicommerce-widget-styles");return e&&e.remove(),document.head.appendChild(r),r}function ee(i){if(!i.apiKey)throw new Error("AICommerceWidget: apiKey is required");let r=new R({apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl}),e={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},d=null,y=[],s=null,w=null,m;async function F(){try{let a=i.baseUrl||B(),o=await fetch(`${a}/api/v1/store`,{headers:{"x-api-key":i.apiKey}});return o.ok?(await o.json()).store:null}catch(a){return console.error("Failed to fetch store config:",a),null}}function B(){if(typeof window<"u"){let a=document.querySelector("script[data-aicommerce-url]");if(a)return a.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function K(){e.storeConfig=await F();let a=i.displayMode||"widget",o=a==="embedded";m={apiKey:i.apiKey,storeId:i.storeId,baseUrl:i.baseUrl||B(),displayMode:a,container:i.container,maxHeight:i.maxHeight||"600px",placeholder:i.placeholder||"Ask me anything about our products...",position:i.position||"bottom-right",theme:i.theme||"auto",primaryColor:i.primaryColor||e.storeConfig?.primaryColor||"#6366f1",welcomeMessage:i.welcomeMessage||e.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:i.botName||e.storeConfig?.chatBotName||"Shopping Assistant",zIndex:i.zIndex||9999,buttonText:i.buttonText||"\u{1F4AC}",hideLauncher:i.hideLauncher||false,addToCartText:i.addToCartText,onOpen:i.onOpen,onClose:i.onClose,onProductClick:i.onProductClick,onAddToCart:i.onAddToCart,onMessage:i.onMessage};let c=O(m);if(w=W(c),o){let h=null;if(typeof i.container=="string"?h=document.querySelector(i.container):i.container instanceof HTMLElement&&(h=i.container),!h){console.error("[AI Commerce] Embedded mode requires a valid container element or selector");return}s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-embedded aicommerce-theme-${m.theme}`,s.style.setProperty("--aic-max-height",m.maxHeight),h.appendChild(s),e.isOpen=true;}else s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-${m.position} aicommerce-theme-${m.theme}`,document.body.appendChild(s);k(),o||e.messages.push({role:"assistant",content:m.welcomeMessage}),e.isLoading=false,k();}async function N(a,o=1){if(!(await fetch("/cart/add.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:a,quantity:o})})).ok)throw new Error("Failed to add to cart");document.dispatchEvent(new CustomEvent("cart:refresh"));}function k(){if(!s)return;let a=m.displayMode==="embedded",o=e.messages.some(l=>l.role==="user");a&&(s.classList.remove("aicommerce-no-messages","aicommerce-has-messages"),s.classList.add(o?"aicommerce-has-messages":"aicommerce-no-messages"));let c=m.placeholder||"Ask me anything about our products...",h=`
846
+ <div class="aicommerce-input-container">
847
+ ${a?`
848
+ <textarea
849
+ class="aicommerce-input"
850
+ placeholder="${c}"
851
+ rows="1"
852
+ ${e.isLoading||e.isRecording?"disabled":""}
853
+ ></textarea>
854
+ `:`
855
+ <input
856
+ type="text"
857
+ class="aicommerce-input"
858
+ placeholder="${c}"
859
+ ${e.isLoading||e.isRecording?"disabled":""}
860
+ />
861
+ `}
862
+ <button class="aicommerce-mic ${e.isRecording?"aicommerce-recording":""}" ${e.isLoading?"disabled":""} aria-label="${e.isRecording?"Stop recording":"Voice input"}">
863
+ ${e.isRecording?`
864
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
865
+ <rect x="6" y="6" width="12" height="12" rx="2"/>
866
+ </svg>
867
+ `:`
868
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
869
+ <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
870
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
871
+ <line x1="12" y1="19" x2="12" y2="23"/>
872
+ <line x1="8" y1="23" x2="16" y2="23"/>
873
+ </svg>
874
+ `}
875
+ </button>
876
+ <button class="aicommerce-send" ${e.isLoading||e.isRecording?"disabled":""} aria-label="Send message">
877
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
878
+ <path d="M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13"/>
879
+ </svg>
880
+ </button>
881
+ </div>
882
+ `,u=`
883
+ ${!a&&!m.hideLauncher?`
608
884
  <button class="aicommerce-launcher ${e.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
609
- <span class="aicommerce-launcher-icon">${l.buttonText}</span>
885
+ <span class="aicommerce-launcher-icon">${m.buttonText}</span>
610
886
  </button>
611
887
  `:""}
612
888
 
613
889
  <div class="aicommerce-chat ${e.isOpen?"aicommerce-open":"aicommerce-closed"}">
890
+ ${a?"":`
614
891
  <div class="aicommerce-header">
615
892
  <div class="aicommerce-header-info">
616
893
  <div class="aicommerce-avatar">
617
- ${e.storeConfig?.logo?`<img src="${e.storeConfig.logo}" alt="${l.botName}" />`:"<span>\u{1F916}</span>"}
894
+ ${e.storeConfig?.logo?`<img src="${e.storeConfig.logo}" alt="${m.botName}" />`:"<span>\u{1F916}</span>"}
618
895
  </div>
619
896
  <div class="aicommerce-header-text">
620
- <span class="aicommerce-bot-name">${l.botName}</span>
897
+ <span class="aicommerce-bot-name">${m.botName}</span>
621
898
  <span class="aicommerce-status">Online</span>
622
899
  </div>
623
900
  </div>
624
- ${t?"":'<button class="aicommerce-close" aria-label="Close chat">\u2715</button>'}
901
+ <button class="aicommerce-close" aria-label="Close chat">\u2715</button>
625
902
  </div>
903
+ `}
626
904
 
905
+ ${a&&o?`
627
906
  <div class="aicommerce-messages">
628
- ${e.messages.map((d,u)=>{let C=N(d.content),E=d.role==="user";return `
629
- <div class="aicommerce-message aicommerce-${d.role}">
630
- <div class="aicommerce-message-content ${C?"aicommerce-rtl":"aicommerce-ltr"}">
631
- ${d.audioUrl?z(d,u,E):$(d.content)}
907
+ ${e.messages.map((l,L)=>{let $=j(l.content),n=l.role==="user";return `
908
+ <div class="aicommerce-message aicommerce-${l.role}">
909
+ <div class="aicommerce-message-content ${$?"aicommerce-rtl":"aicommerce-ltr"}">
910
+ ${l.audioUrl?H(l,L,n):T(l.content)}
632
911
  </div>
633
- ${d.products&&d.products.length>0?`
912
+ ${l.products&&l.products.length>0?`
634
913
  <div class="aicommerce-products">
635
- ${d.products.map(g=>`
636
- <div class="aicommerce-product-card" data-product-id="${g.id}">
637
- ${g.image||g.imageUrl?`
638
- <img src="${g.image||g.imageUrl}" alt="${$(g.name)}" class="aicommerce-product-image" />
914
+ ${l.products.map(t=>`
915
+ <div class="aicommerce-product-card" data-product-id="${t.id}">
916
+ ${t.image||t.imageUrl?`
917
+ <img src="${t.image||t.imageUrl}" alt="${T(t.name)}" class="aicommerce-product-image" />
639
918
  `:`
640
919
  <div class="aicommerce-product-placeholder">\u{1F4E6}</div>
641
920
  `}
642
921
  <div class="aicommerce-product-info">
643
- <span class="aicommerce-product-name" title="${$(g.name)}">${$(g.name)}</span>
644
- ${g.description?`<p class="aicommerce-product-desc">${$(g.description)}</p>`:""}
645
- <span class="aicommerce-product-price">${_(g.price,g.currency)}</span>
922
+ <span class="aicommerce-product-name" title="${T(t.name)}">${T(t.name)}</span>
923
+ ${t.description?`<p class="aicommerce-product-desc">${T(t.description)}</p>`:""}
924
+ <span class="aicommerce-product-price">${D(t.price,t.currency)}</span>
646
925
  </div>
647
926
  </div>
648
927
  `).join("")}
@@ -658,52 +937,85 @@ var L=class i{constructor(r){this.sessionToken=null;this.products={create:async
658
937
  </div>
659
938
  `:""}
660
939
  </div>
940
+ `:""}
661
941
 
662
- <div class="aicommerce-input-container">
663
- <input
664
- type="text"
665
- class="aicommerce-input"
666
- placeholder="Type your message..."
667
- ${e.isLoading||e.isRecording?"disabled":""}
668
- />
669
- <button class="aicommerce-mic ${e.isRecording?"aicommerce-recording":""}" ${e.isLoading?"disabled":""} aria-label="${e.isRecording?"Stop recording":"Voice input"}">
670
- ${e.isRecording?`
671
- <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
672
- <rect x="6" y="6" width="12" height="12" rx="2"/>
673
- </svg>
674
- `:`
675
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
676
- <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
677
- <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
678
- <line x1="12" y1="19" x2="12" y2="23"/>
679
- <line x1="8" y1="23" x2="16" y2="23"/>
680
- </svg>
681
- `}
682
- </button>
683
- <button class="aicommerce-send" ${e.isLoading||e.isRecording?"disabled":""} aria-label="Send message">
684
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
685
- <path d="M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13"/>
686
- </svg>
687
- </button>
942
+ ${a?"":`
943
+ <div class="aicommerce-messages">
944
+ ${e.messages.map((l,L)=>{let $=j(l.content),n=l.role==="user";return `
945
+ <div class="aicommerce-message aicommerce-${l.role}">
946
+ <div class="aicommerce-message-content ${$?"aicommerce-rtl":"aicommerce-ltr"}">
947
+ ${l.audioUrl?H(l,L,n):T(l.content)}
948
+ </div>
949
+ ${l.products&&l.products.length>0?`
950
+ <div class="aicommerce-products">
951
+ ${l.products.map(t=>`
952
+ <div class="aicommerce-product-card" data-product-id="${t.id}" data-variant-id="${t.variantId||""}">
953
+ ${t.image||t.imageUrl?`
954
+ <img src="${t.image||t.imageUrl}" alt="${T(t.name)}" class="aicommerce-product-image" />
955
+ `:`
956
+ <div class="aicommerce-product-placeholder">\u{1F4E6}</div>
957
+ `}
958
+ <div class="aicommerce-product-info">
959
+ <span class="aicommerce-product-name" title="${T(t.name)}">${T(t.name)}</span>
960
+ ${t.description?`<p class="aicommerce-product-desc">${T(t.description)}</p>`:""}
961
+ <span class="aicommerce-product-price">${D(t.price,t.currency)}</span>
962
+ <button class="aicommerce-add-to-cart" data-product-id="${t.id}">
963
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
964
+ <circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/>
965
+ <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/>
966
+ </svg>
967
+ ${m.addToCartText||"Add to Cart"}
968
+ </button>
969
+ </div>
970
+ </div>
971
+ `).join("")}
972
+ </div>
973
+ `:""}
974
+ </div>
975
+ `}).join("")}
976
+ ${e.isLoading?`
977
+ <div class="aicommerce-message aicommerce-assistant">
978
+ <div class="aicommerce-typing">
979
+ <span></span><span></span><span></span>
980
+ </div>
981
+ </div>
982
+ `:""}
688
983
  </div>
984
+ `}
985
+
986
+ ${a?`
987
+ <div class="aicommerce-input-wrapper">
988
+ ${h}
989
+ </div>
990
+ `:h}
689
991
  </div>
690
- `;a.innerHTML=o,W();let c=a.querySelector(".aicommerce-messages");c&&(c.scrollTop=c.scrollHeight);}function z(t,o,c){return `
992
+ `;s.innerHTML=u,Y();let E=s.querySelector(".aicommerce-messages");E&&(E.scrollTop=E.scrollHeight);}function H(a,o,c){return `
691
993
  <div class="aicommerce-audio-player" data-message-index="${o}">
692
994
  <button class="aicommerce-audio-btn">
693
995
  <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
694
996
  </button>
695
997
  <div class="aicommerce-audio-waveform">
696
998
  <div class="aicommerce-waveform-bars">
697
- ${(t.waveformBars||Array(40).fill(10)).map(d=>`
698
- <div class="aicommerce-waveform-bar" style="height: ${d}%; background-color: ${c?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
999
+ ${(a.waveformBars||Array(40).fill(10)).map(h=>`
1000
+ <div class="aicommerce-waveform-bar" style="height: ${h}%; background-color: ${c?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
699
1001
  `).join("")}
700
1002
  </div>
701
1003
  <div class="aicommerce-audio-time">
702
1004
  <span class="aicommerce-current-time">0:00</span>
703
- <span>${B(t.audioDuration||0)}</span>
1005
+ <span>${z(a.audioDuration||0)}</span>
704
1006
  </div>
705
1007
  </div>
706
- <audio src="${t.audioUrl}" preload="metadata"></audio>
1008
+ <audio src="${a.audioUrl}" preload="metadata"></audio>
707
1009
  </div>
708
- `}function W(){if(!a)return;let t=a.querySelector(".aicommerce-launcher");t&&t.addEventListener("click",()=>M());let o=a.querySelector(".aicommerce-close");o&&o.addEventListener("click",()=>A());let c=a.querySelector(".aicommerce-input"),d=a.querySelector(".aicommerce-send");c&&c.addEventListener("keypress",n=>{n.key==="Enter"&&c.value.trim()&&(I(c.value.trim()),c.value="");}),d&&c&&d.addEventListener("click",()=>{c.value.trim()&&(I(c.value.trim()),c.value="");});let u=a.querySelector(".aicommerce-mic");u&&u.addEventListener("click",()=>F()),a.querySelectorAll(".aicommerce-product-card").forEach(n=>{n.addEventListener("click",()=>{let m=n.getAttribute("data-product-id"),h=e.messages.flatMap(x=>x.products||[]).find(x=>x.id===m);h&&(l.onProductClick?l.onProductClick(h):h.url&&window.open(h.url,"_blank","noopener,noreferrer"));});}),a.querySelectorAll(".aicommerce-products").forEach(n=>{let m=false,h=0,x=0;n.addEventListener("mousedown",k=>{m=true,n.style.cursor="grabbing",h=k.pageX-n.offsetLeft,x=n.scrollLeft;}),n.addEventListener("mouseleave",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mouseup",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mousemove",k=>{if(!m)return;k.preventDefault();let v=(k.pageX-n.offsetLeft-h)*2;n.scrollLeft=x-v;});}),a.querySelectorAll(".aicommerce-audio-player").forEach(n=>{let m=n.querySelector("audio"),h=n.querySelector(".aicommerce-audio-btn"),x=n.querySelectorAll(".aicommerce-waveform-bar"),k=n.querySelector(".aicommerce-current-time");if(!m||!h)return;h.addEventListener("click",()=>{!m.paused?(m.pause(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(a?.querySelectorAll("audio").forEach(w=>{if(w!==m&&!w.paused){w.pause();let R=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");R&&(R.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),m.play(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),m.addEventListener("timeupdate",()=>{if(k&&(k.textContent=B(m.currentTime)),m.duration){let v=m.currentTime/m.duration*100;x.forEach((w,U)=>{U/x.length*100<=v?w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),m.addEventListener("ended",()=>{h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=n.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),R=(v.clientX-w.left)/w.width;m.duration&&(m.currentTime=R*m.duration);});});}async function F(){if(e.isRecording)s&&s.state!=="inactive"&&s.stop();else try{let t=await navigator.mediaDevices.getUserMedia({audio:!0});b=[],s=new MediaRecorder(t,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),s.ondataavailable=o=>{o.data.size>0&&b.push(o.data);},s.onstop=async()=>{if(t.getTracks().forEach(o=>o.stop()),b.length>0){let o=new Blob(b,{type:s?.mimeType||"audio/webm"});await K(o);}e.isRecording=!1,y();},s.start(),e.isRecording=!0,y();}catch(t){console.error("Failed to start recording:",t),e.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),y();}}async function K(t){let o=URL.createObjectURL(t),c=Array(40).fill(10),d=0;try{c=await Y(t);let u=new Audio(o);await new Promise(C=>{u.onloadedmetadata=()=>{d=u.duration,C();},u.onerror=()=>C();});}catch(u){console.error("Audio analysis failed",u);}e.messages.push({role:"user",content:"Voice message",audioUrl:o,audioDuration:d,waveformBars:c}),e.isLoading=true,y();try{let u=await r.chatWithAudio(t);return e.messages.push({role:"assistant",content:u.reply,products:u.products}),l.onMessage&&l.onMessage("Voice message",u),u}catch(u){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),u}finally{e.isLoading=false,y();}}function N(t){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(t)}function B(t){let o=Math.floor(t/60),c=Math.floor(t%60);return `${o}:${c.toString().padStart(2,"0")}`}async function Y(t){try{let o=new(window.AudioContext||window.webkitAudioContext),c=await t.arrayBuffer(),u=(await o.decodeAudioData(c)).getChannelData(0),C=40,E=Math.floor(u.length/C),g=[];for(let n=0;n<C;n++){let m=n*E,h=m+E,x=0;for(let v=m;v<h;v++)u[v]&&(x+=u[v]*u[v]);let k=Math.sqrt(x/E),S=Math.min(100,Math.max(10,k*400));g.push(S);}return g}catch(o){return console.error("Analysis error",o),Array.from({length:40},()=>20+Math.random()*60)}}async function I(t){e.messages.push({role:"user",content:t}),e.isLoading=true,y();try{let o=await r.chat(t);return e.messages.push({role:"assistant",content:o.reply,products:o.products}),l.onMessage&&l.onMessage(t,o),o}catch(o){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),o}finally{e.isLoading=false,y();}}function M(){e.isOpen=true,y(),l.onOpen?.(),setTimeout(()=>{a?.querySelector(".aicommerce-input")?.focus();},100);}function A(){e.isOpen=false,y(),l.onClose?.();}function J(){e.isOpen?A():M();}function X(){a&&(a.remove(),a=null),f&&(f.remove(),f=null);}function V(t){if(Object.assign(l,t),t.primaryColor){let o=q(l);f&&(f.textContent=o);}y();}function $(t){let o=document.createElement("div");return o.textContent=t,o.innerHTML}function _(t,o){let d={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[o||"USD"]||o||"$";return `${t.toFixed(2)} ${d}`}return j(),{open:M,close:A,toggle:J,destroy:X,sendMessage:I,updateConfig:V}}var Z={init:Q,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=Z);exports.AICommerceWidget=Z;exports.createWidget=Q;return exports;})({});//# sourceMappingURL=widget.min.js.map
1010
+ `}function Y(){if(!s)return;let a=s.querySelector(".aicommerce-launcher");a&&a.addEventListener("click",()=>U());let o=s.querySelector(".aicommerce-close");o&&o.addEventListener("click",()=>q());let c=s.querySelector(".aicommerce-input"),h=s.querySelector(".aicommerce-send");c&&(c.addEventListener("keydown",n=>{let t=n;if(t.key==="Enter"){let p=c instanceof HTMLTextAreaElement;if(p&&t.shiftKey)return;n.preventDefault();let b=c.value.trim();b&&(I(b),c.value="",p&&(c.style.height="auto"));}}),c instanceof HTMLTextAreaElement&&c.addEventListener("input",()=>{c.style.height="auto",c.style.height=Math.min(c.scrollHeight,150)+"px";})),h&&c&&h.addEventListener("click",()=>{let n=c.value.trim();n&&(I(n),c.value="",c instanceof HTMLTextAreaElement&&(c.style.height="auto"));});let u=s.querySelector(".aicommerce-mic");u&&u.addEventListener("click",()=>J()),s.querySelectorAll(".aicommerce-product-card").forEach(n=>{n.addEventListener("click",t=>{if(t.target.closest(".aicommerce-add-to-cart"))return;let p=n.getAttribute("data-product-id"),b=e.messages.flatMap(f=>f.products||[]).find(f=>f.id===p);b&&(m.onProductClick?m.onProductClick(b):b.url&&window.open(b.url,"_blank","noopener,noreferrer"));});}),s.querySelectorAll(".aicommerce-add-to-cart").forEach(n=>{n.addEventListener("click",async t=>{t.stopPropagation();let p=n,b=p.closest(".aicommerce-product-card"),f=b?.getAttribute("data-product-id"),x=b?.getAttribute("data-variant-id"),C=e.messages.flatMap(P=>P.products||[]).find(P=>P.id===f);if(!C)return;let v=p.innerHTML;p.disabled=true,p.innerHTML=`
1011
+ <svg class="aicommerce-spinner" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1012
+ <circle cx="12" cy="12" r="10" stroke-dasharray="32" stroke-dashoffset="32"/>
1013
+ </svg>
1014
+ Adding...
1015
+ `;try{m.onAddToCart?await m.onAddToCart(C):x&&window.Shopify?await N(x):C.url&&window.open(C.url,"_blank","noopener,noreferrer"),p.innerHTML=`
1016
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1017
+ <polyline points="20 6 9 17 4 12"/>
1018
+ </svg>
1019
+ Added!
1020
+ `,setTimeout(()=>{p.innerHTML=v,p.disabled=!1;},2e3);}catch(P){console.error("[AI Commerce] Add to cart failed:",P),p.innerHTML=v,p.disabled=false;}});}),s.querySelectorAll(".aicommerce-products").forEach(n=>{let t=false,p=0,b=0;n.addEventListener("mousedown",f=>{t=true,n.style.cursor="grabbing",p=f.pageX-n.offsetLeft,b=n.scrollLeft;}),n.addEventListener("mouseleave",()=>{t=false,n.style.cursor="grab";}),n.addEventListener("mouseup",()=>{t=false,n.style.cursor="grab";}),n.addEventListener("mousemove",f=>{if(!t)return;f.preventDefault();let C=(f.pageX-n.offsetLeft-p)*2;n.scrollLeft=b-C;});}),s.querySelectorAll(".aicommerce-audio-player").forEach(n=>{let t=n.querySelector("audio"),p=n.querySelector(".aicommerce-audio-btn"),b=n.querySelectorAll(".aicommerce-waveform-bar"),f=n.querySelector(".aicommerce-current-time");if(!t||!p)return;p.addEventListener("click",()=>{!t.paused?(t.pause(),p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(s?.querySelectorAll("audio").forEach(v=>{if(v!==t&&!v.paused){v.pause();let M=v.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");M&&(M.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),t.play(),p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),t.addEventListener("timeupdate",()=>{if(f&&(f.textContent=z(t.currentTime)),t.duration){let C=t.currentTime/t.duration*100;b.forEach((v,P)=>{P/b.length*100<=C?v.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":v.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),t.addEventListener("ended",()=>{p.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let x=n.querySelector(".aicommerce-waveform-bars");x&&x.addEventListener("click",C=>{let v=x.getBoundingClientRect(),M=(C.clientX-v.left)/v.width;t.duration&&(t.currentTime=M*t.duration);});});}async function J(){if(e.isRecording)d&&d.state!=="inactive"&&d.stop();else try{let a=await navigator.mediaDevices.getUserMedia({audio:!0});y=[],d=new MediaRecorder(a,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),d.ondataavailable=o=>{o.data.size>0&&y.push(o.data);},d.onstop=async()=>{if(a.getTracks().forEach(o=>o.stop()),y.length>0){let o=new Blob(y,{type:d?.mimeType||"audio/webm"});await X(o);}e.isRecording=!1,k();},d.start(),e.isRecording=!0,k();}catch(a){console.error("Failed to start recording:",a),e.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),k();}}async function X(a){let o=URL.createObjectURL(a),c=Array(40).fill(10),h=0;try{c=await V(a);let u=new Audio(o);await new Promise(E=>{u.onloadedmetadata=()=>{h=u.duration,E();},u.onerror=()=>E();});}catch(u){console.error("Audio analysis failed",u);}e.messages.push({role:"user",content:"Voice message",audioUrl:o,audioDuration:h,waveformBars:c}),e.isLoading=true,k();try{let u=await r.chatWithAudio(a);return e.messages.push({role:"assistant",content:u.reply,products:u.products}),m.onMessage&&m.onMessage("Voice message",u),u}catch(u){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),u}finally{e.isLoading=false,k();}}function j(a){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(a)}function z(a){let o=Math.floor(a/60),c=Math.floor(a%60);return `${o}:${c.toString().padStart(2,"0")}`}async function V(a){try{let o=new(window.AudioContext||window.webkitAudioContext),c=await a.arrayBuffer(),u=(await o.decodeAudioData(c)).getChannelData(0),E=40,l=Math.floor(u.length/E),L=[];for(let $=0;$<E;$++){let n=$*l,t=n+l,p=0;for(let x=n;x<t;x++)u[x]&&(p+=u[x]*u[x]);let b=Math.sqrt(p/l),f=Math.min(100,Math.max(10,b*400));L.push(f);}return L}catch(o){return console.error("Analysis error",o),Array.from({length:40},()=>20+Math.random()*60)}}async function I(a){e.messages.push({role:"user",content:a}),e.isLoading=true,k();try{let o=await r.chat(a);return e.messages.push({role:"assistant",content:o.reply,products:o.products}),m.onMessage&&m.onMessage(a,o),o}catch(o){throw e.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),o}finally{e.isLoading=false,k();}}function U(){e.isOpen=true,k(),m.onOpen?.(),setTimeout(()=>{s?.querySelector(".aicommerce-input")?.focus();},100);}function q(){e.isOpen=false,k(),m.onClose?.();}function G(){e.isOpen?q():U();}function _(){s&&(s.remove(),s=null),w&&(w.remove(),w=null);}function Q(a){if(Object.assign(m,a),a.primaryColor){let o=O(m);w&&(w.textContent=o);}k();}function T(a){let o=document.createElement("div");return o.textContent=a,o.innerHTML}function D(a,o){let h={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[o||"USD"]||o||"$";return `${a.toFixed(2)} ${h}`}return K(),{open:U,close:q,toggle:G,destroy:_,sendMessage:I,updateConfig:Q}}var re={init:ee,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=re);exports.AICommerceWidget=re;exports.createWidget=ee;return exports;})({});//# sourceMappingURL=widget.min.js.map
709
1021
  //# sourceMappingURL=widget.min.js.map