@yassirbenmoussa/aicommerce-sdk 1.8.0 → 1.9.1

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