@a.izzuddin/ai-chat 0.2.17 → 0.2.19

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.
@@ -601,6 +601,16 @@
601
601
  "default": "''",
602
602
  "attribute": "bot-avatar-url"
603
603
  },
604
+ {
605
+ "kind": "field",
606
+ "name": "userAvatarUrl",
607
+ "privacy": "public",
608
+ "type": {
609
+ "text": "string"
610
+ },
611
+ "default": "''",
612
+ "attribute": "user-avatar-url"
613
+ },
604
614
  {
605
615
  "kind": "field",
606
616
  "name": "widgetIconUrl",
@@ -1038,6 +1048,14 @@
1038
1048
  "default": "''",
1039
1049
  "fieldName": "botAvatarUrl"
1040
1050
  },
1051
+ {
1052
+ "name": "user-avatar-url",
1053
+ "type": {
1054
+ "text": "string"
1055
+ },
1056
+ "default": "''",
1057
+ "fieldName": "userAvatarUrl"
1058
+ },
1041
1059
  {
1042
1060
  "name": "widget-icon-url",
1043
1061
  "type": {
package/dist/index.d.mts CHANGED
@@ -66,6 +66,7 @@ declare class AIChat extends LitElement {
66
66
  mode: 'fullscreen' | 'widget';
67
67
  initialMessages: Message[];
68
68
  botAvatarUrl: string;
69
+ userAvatarUrl: string;
69
70
  widgetIconUrl: string;
70
71
  backgroundImageUrl: string;
71
72
  widgetWidth: string;
@@ -111,6 +112,10 @@ declare class AIChat extends LitElement {
111
112
  type: StringConstructor;
112
113
  attribute: string;
113
114
  };
115
+ userAvatarUrl: {
116
+ type: StringConstructor;
117
+ attribute: string;
118
+ };
114
119
  widgetIconUrl: {
115
120
  type: StringConstructor;
116
121
  attribute: string;
package/dist/index.d.ts CHANGED
@@ -66,6 +66,7 @@ declare class AIChat extends LitElement {
66
66
  mode: 'fullscreen' | 'widget';
67
67
  initialMessages: Message[];
68
68
  botAvatarUrl: string;
69
+ userAvatarUrl: string;
69
70
  widgetIconUrl: string;
70
71
  backgroundImageUrl: string;
71
72
  widgetWidth: string;
@@ -111,6 +112,10 @@ declare class AIChat extends LitElement {
111
112
  type: StringConstructor;
112
113
  attribute: string;
113
114
  };
115
+ userAvatarUrl: {
116
+ type: StringConstructor;
117
+ attribute: string;
118
+ };
114
119
  widgetIconUrl: {
115
120
  type: StringConstructor;
116
121
  attribute: string;
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
16
16
  if (kind && result) __defProp(target, key, result);
17
17
  return result;
18
18
  };
19
- var VERSION = "0.2.17";
19
+ var VERSION = "0.2.19";
20
20
  exports.AIChat = class AIChat extends lit.LitElement {
21
21
  constructor() {
22
22
  super();
@@ -27,6 +27,7 @@ exports.AIChat = class AIChat extends lit.LitElement {
27
27
  this.mode = "fullscreen";
28
28
  this.initialMessages = [];
29
29
  this.botAvatarUrl = "";
30
+ this.userAvatarUrl = "";
30
31
  this.widgetIconUrl = "";
31
32
  this.backgroundImageUrl = "";
32
33
  this.widgetWidth = "380px";
@@ -547,7 +548,9 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
547
548
  })}
548
549
  >
549
550
  <div class="avatar">
550
- ${msg.role === "user" ? "U" : this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
551
+ ${msg.role === "user" ? this.userAvatarUrl ? lit.html`<img src="${this.userAvatarUrl}" alt="User" class="avatar-image" />` : lit.html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" style="width: 20px; height: 20px;">
552
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
553
+ </svg>` : this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
551
554
  </div>
552
555
  <div class="message-content">
553
556
  <div class="message-text">${unsafeHtml_js.unsafeHTML(this.formatMessageContent(msg.content))}</div>
@@ -565,7 +568,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
565
568
  ` : ""}
566
569
  ${msg.role === "assistant" && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? lit.html`
567
570
  <div class="faq-section">
568
- <p class="faq-title">Suggested Questions:</p>
571
+ <p class="faq-title">Cadangan Soalan:</p>
569
572
  <ul class="faq-list">
570
573
  ${msg.suggestedQuestions.map((question) => lit.html`
571
574
  <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
@@ -710,6 +713,7 @@ exports.AIChat.styles = lit.css`
710
713
  justify-content: center;
711
714
  box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);
712
715
  transition: transform 0.2s, box-shadow 0.2s;
716
+ overflow: hidden;
713
717
  }
714
718
 
715
719
  .widget-button:hover {
@@ -735,10 +739,8 @@ exports.AIChat.styles = lit.css`
735
739
  }
736
740
 
737
741
  .widget-button-icon {
738
- width: 100%;
739
- height: 100%;
740
- max-width: 60px;
741
- max-height: 60px;
742
+ width: 60px;
743
+ height: 60px;
742
744
  object-fit: contain;
743
745
  border-radius: 50%;
744
746
  }
@@ -1429,6 +1431,7 @@ exports.AIChat.properties = {
1429
1431
  mode: { type: String, reflect: true },
1430
1432
  initialMessages: { type: Array },
1431
1433
  botAvatarUrl: { type: String, attribute: "bot-avatar-url" },
1434
+ userAvatarUrl: { type: String, attribute: "user-avatar-url" },
1432
1435
  widgetIconUrl: { type: String, attribute: "widget-icon-url" },
1433
1436
  backgroundImageUrl: { type: String, attribute: "background-image-url" },
1434
1437
  widgetWidth: { type: String, attribute: "widget-width" },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ai-chat.ts"],"names":["AIChat","LitElement","html","repeat","classMap","unsafeHTML","css","state","customElement"],"mappings":"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AA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA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","file":"index.js","sourcesContent":["import { LitElement, html, css, PropertyValues } from 'lit';\r\nimport { customElement, state } from 'lit/decorators.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\r\n\r\nconst VERSION = '0.2.17';\r\n\r\nexport interface FAQ {\r\n No: string;\r\n Question: string;\r\n}\r\n\r\nexport interface SuggestedQuestion {\r\n id?: number;\r\n question_type?: string;\r\n question_text: string;\r\n category?: string;\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n faqs?: FAQ[];\r\n suggestedQuestions?: SuggestedQuestion[];\r\n}\r\n\r\n/**\r\n * AI Chat Web Component\r\n *\r\n * @fires message-sent - Fired when user sends a message\r\n * @fires response-received - Fired when AI responds\r\n * @fires error - Fired when an error occurs\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\">\r\n * </ai-chat>\r\n *\r\n * <!-- Widget mode with custom size -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * mode=\"widget\"\r\n * widget-width=\"400px\"\r\n * widget-height=\"650px\">\r\n * </ai-chat>\r\n *\r\n * <!-- Custom theme colors -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * primary-color=\"#10B981\"\r\n * primary-color-hover=\"#059669\"\r\n * user-message-bg=\"#D1FAE5\"\r\n * bot-message-bg=\"#F3F4F6\">\r\n * </ai-chat>\r\n * ```\r\n */\r\n@customElement('ai-chat')\r\nexport class AIChat extends LitElement {\r\n static styles = css`\r\n :host {\r\n font-family: system-ui, -apple-system, sans-serif;\r\n color: #09090b;\r\n }\r\n\r\n /* Fullscreen mode (default) */\r\n :host([mode=\"fullscreen\"]) {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n background: #ffffff;\r\n }\r\n\r\n :host([mode=\"fullscreen\"][theme=\"dark\"]) {\r\n background: #000;\r\n color: #fafafa;\r\n }\r\n\r\n /* Widget mode */\r\n :host([mode=\"widget\"]) {\r\n position: fixed;\r\n bottom: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n }\r\n\r\n .widget-container {\r\n position: relative;\r\n }\r\n\r\n .widget-button {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: #3681D3;\r\n border: none;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);\r\n transition: transform 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .widget-button:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 6px 20px rgba(65, 105, 225, 0.4);\r\n }\r\n\r\n .widget-button-no-bg {\r\n background: transparent;\r\n box-shadow: none;\r\n }\r\n\r\n .widget-button-no-bg:hover {\r\n background: transparent;\r\n box-shadow: none;\r\n transform: scale(1.1);\r\n }\r\n\r\n .widget-button svg {\r\n width: 28px;\r\n height: 28px;\r\n color: white;\r\n }\r\n\r\n .widget-button-icon {\r\n width: 100%;\r\n height: 100%;\r\n max-width: 60px;\r\n max-height: 60px;\r\n object-fit: contain;\r\n border-radius: 50%;\r\n }\r\n\r\n .widget-window {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 0;\r\n width: var(--widget-width, 380px);\r\n height: var(--widget-height, 600px);\r\n background: #fff;\r\n border-radius: 16px;\r\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n transition: opacity 0.2s, transform 0.2s;\r\n }\r\n\r\n .widget-window.open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n pointer-events: all;\r\n }\r\n\r\n :host([theme=\"dark\"]) .widget-window {\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n /* Tablet breakpoint */\r\n @media (max-width: 1024px) and (min-width: 769px) {\r\n .widget-window {\r\n width: var(--widget-width, 400px);\r\n height: var(--widget-height, 650px);\r\n }\r\n }\r\n\r\n /* Small tablet breakpoint */\r\n @media (max-width: 768px) and (min-width: 481px) {\r\n .widget-window {\r\n width: var(--widget-width, 360px);\r\n height: var(--widget-height, 550px);\r\n }\r\n }\r\n\r\n /* Mobile portrait */\r\n @media (max-width: 480px) and (orientation: portrait) {\r\n .widget-window {\r\n width: calc(100vw - 40px);\r\n height: 70vh;\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile landscape */\r\n @media (max-width: 900px) and (orientation: landscape) {\r\n .widget-window {\r\n width: var(--widget-width, 500px);\r\n height: calc(100vh - 100px);\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile responsive styles for all modes */\r\n @media (max-width: 768px) {\r\n .header {\r\n padding: 0.875rem 1rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.25rem;\r\n height: 2.25rem;\r\n }\r\n\r\n .title {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 1rem 0.75rem;\r\n }\r\n\r\n .message {\r\n gap: 0.75rem;\r\n }\r\n\r\n .avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n font-size: 0.75rem;\r\n }\r\n\r\n .message-content {\r\n max-width: 100%;\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 3rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.25rem;\r\n padding: 0 1rem;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.8125rem;\r\n padding: 0;\r\n }\r\n\r\n .input-area {\r\n padding: 0.75rem;\r\n }\r\n\r\n .input-form {\r\n gap: 0.5rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.75rem;\r\n padding: 0 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.75rem;\r\n height: 2.75rem;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-icon {\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n }\r\n }\r\n\r\n /* Extra small screens */\r\n @media (max-width: 480px) {\r\n .header {\r\n padding: 0.75rem 0.875rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n }\r\n\r\n .title {\r\n font-size: 1rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 0.75rem 0.5rem;\r\n }\r\n\r\n .message {\r\n gap: 0.5rem;\r\n }\r\n\r\n .avatar {\r\n width: 1.75rem;\r\n height: 1.75rem;\r\n font-size: 0.7rem;\r\n }\r\n\r\n .message-content {\r\n padding: 0.5rem 0.75rem;\r\n font-size: 0.875rem;\r\n border-radius: 0.75rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 2rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .input-area {\r\n padding: 0.625rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.5rem;\r\n padding: 0 0.75rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n }\r\n\r\n .version-tag {\r\n font-size: 0.7rem;\r\n padding: 0.375rem;\r\n }\r\n }\r\n\r\n .header {\r\n background:#3681D3;\r\n padding: 1rem 1.25rem;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n box-shadow: 0 2px 8px rgba(65, 105, 225, 0.2);\r\n }\r\n\r\n :host([theme=\"dark\"]) .header {\r\n background: #3681D3\r\n }\r\n\r\n .header-content {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n width: 100%;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 50%;\r\n background: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n }\r\n\r\n .header-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .title {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #fff;\r\n }\r\n\r\n .messages-area {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 1.5rem 1rem;\r\n position: relative;\r\n background: #ffffff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .messages-area {\r\n background: #000;\r\n }\r\n\r\n .messages-area::before {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background-image: var(--background-image-url);\r\n background-size: 200px auto 60%;\r\n background-position: center center;\r\n background-repeat: no-repeat;\r\n opacity: 0.03;\r\n pointer-events: none;\r\n z-index: 0;\r\n }\r\n\r\n .messages-container {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 1.5rem;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .empty-state {\r\n text-align: center;\r\n margin-top: 5rem;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1.5rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state {\r\n color: #a1a1aa;\r\n }\r\n\r\n .empty-state-avatar {\r\n width: 5rem;\r\n height: 5rem;\r\n border-radius: 50%;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar {\r\n background: #3f3f46;\r\n }\r\n\r\n .empty-state-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .empty-state-avatar svg {\r\n width: 3rem;\r\n height: 3rem;\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar svg {\r\n color: #6b7280;\r\n }\r\n\r\n .empty-state-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.5rem;\r\n }\r\n\r\n .empty-state-message {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #374151;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-message {\r\n color: #f3f4f6;\r\n }\r\n\r\n .empty-state-subtitle {\r\n font-size: 0.9375rem;\r\n margin: 0;\r\n color: #6b7280;\r\n max-width: 24rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-subtitle {\r\n color: #9ca3af;\r\n }\r\n\r\n .message {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .message.user {\r\n flex-direction: row-reverse;\r\n }\r\n\r\n .avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 9999px;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n font-weight: 600;\r\n font-size: 0.875rem;\r\n overflow: hidden;\r\n color: #6B7280;\r\n }\r\n\r\n :host([theme=\"dark\"]) .avatar {\r\n background: #3f3f46;\r\n color: #9ca3af;\r\n }\r\n\r\n .avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .message-content {\r\n max-width: 36rem;\r\n padding: 0.875rem 1.125rem;\r\n border-radius: 1.25rem;\r\n line-height: 1.6;\r\n overflow-wrap: break-word;\r\n word-wrap: break-word;\r\n min-width: 0;\r\n }\r\n\r\n .message.user .message-content {\r\n background: var(--user-message-bg, #D6E4FF);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 0.25rem 1.25rem;\r\n }\r\n\r\n .message.assistant .message-content {\r\n background: var(--bot-message-bg, #F5F5F5);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 1.25rem 0.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.user .message-content {\r\n background: #3D5A99;\r\n color: #fff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.assistant .message-content {\r\n background: #27272a;\r\n color: #fafafa;\r\n }\r\n\r\n .message-text {\r\n white-space: pre-wrap;\r\n margin: 0;\r\n word-wrap: break-word;\r\n overflow-wrap: break-word;\r\n word-break: break-word;\r\n }\r\n\r\n .message-text ul,\r\n .message-text ol {\r\n margin: 0.5rem 0;\r\n padding-left: 1.5rem;\r\n white-space: normal;\r\n list-style-position: outside;\r\n }\r\n\r\n .message-text li {\r\n margin: 0.25rem 0;\r\n white-space: normal;\r\n display: list-item;\r\n }\r\n\r\n .message-text ul {\r\n list-style-type: disc;\r\n }\r\n\r\n .message-text ol {\r\n list-style-type: decimal;\r\n counter-reset: list-counter;\r\n }\r\n\r\n .message-text ol li {\r\n display: list-item;\r\n list-style-type: decimal;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n border-top: 1px solid #d1d5db;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-section {\r\n border-top-color: #3f3f46;\r\n }\r\n\r\n .faq-title {\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n color: var(--primary-color, #3681D3);\r\n margin: 0 0 0.375rem 0;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-title {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n .faq-list {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.375rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.875rem;\r\n color: var(--primary-color, #3681D3);\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: pointer;\r\n transition: background-color 0.2s, color 0.2s;\r\n border: 1px solid transparent;\r\n }\r\n\r\n .faq-item:hover {\r\n background-color: #EEF2FF;\r\n color: var(--primary-color-hover, #3457C7);\r\n border-color: #C7D2FE;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item:hover {\r\n background-color: #1e293b;\r\n color: #93C5FD;\r\n border-color: #3f3f46;\r\n }\r\n\r\n /* FAQ static item styles - commented out for now */\r\n /* .faq-item-static {\r\n font-size: 0.875rem;\r\n color: #6B7280;\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: default;\r\n border: 1px solid transparent;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item-static {\r\n color: #9CA3AF;\r\n } */\r\n\r\n .loading {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .spinner {\r\n display: inline-block;\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border: 2px solid #e4e4e7;\r\n border-top-color: #71717a;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n .input-area {\r\n border-top: 1px solid #e5e7eb;\r\n background: #fff;\r\n padding: 1rem 1.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-area {\r\n border-top-color: #27272a;\r\n background: #18181b;\r\n }\r\n\r\n .input-form {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n gap: 0.75rem;\r\n align-items: center;\r\n }\r\n\r\n .input-field {\r\n flex: 1;\r\n height: 3rem;\r\n padding: 0 1rem;\r\n border: 1px solid #d1d5db;\r\n border-radius: 1.5rem;\r\n font-size: 0.9375rem;\r\n font-family: inherit;\r\n background: #fff;\r\n color: #374151;\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .input-field::placeholder {\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-field {\r\n border-color: #3f3f46;\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n .input-field:focus {\r\n outline: none;\r\n border-color: var(--primary-color, #3681D3);\r\n box-shadow: 0 0 0 3px rgba(65, 105, 225, 0.1);\r\n }\r\n\r\n .input-field:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-button {\r\n width: 3rem;\r\n height: 3rem;\r\n border-radius: 9999px;\r\n border: none;\r\n background: var(--primary-color, #3681D3);\r\n color: #fff;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s, transform 0.1s;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-button:hover:not(:disabled) {\r\n background: var(--primary-color-hover, #3457C7);\r\n transform: scale(1.05);\r\n }\r\n\r\n .send-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-icon {\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n }\r\n\r\n .version-tag {\r\n text-align: center;\r\n padding: 0.5rem;\r\n font-size: 0.75rem;\r\n color: #9ca3af;\r\n border-top: 1px solid #e5e7eb;\r\n }\r\n\r\n :host([theme=\"dark\"]) .version-tag {\r\n color: #6b7280;\r\n border-top-color: #27272a;\r\n }\r\n `;\r\n\r\n declare apiUrl: string;\r\n declare sessionId: string;\r\n declare chatTitle: string;\r\n declare theme: 'light' | 'dark';\r\n declare mode: 'fullscreen' | 'widget';\r\n declare initialMessages: Message[];\r\n declare botAvatarUrl: string;\r\n declare widgetIconUrl: string;\r\n declare backgroundImageUrl: string;\r\n declare widgetWidth: string;\r\n declare widgetHeight: string;\r\n declare primaryColor: string;\r\n declare primaryColorHover: string;\r\n declare userMessageBg: string;\r\n declare botMessageBg: string;\r\n declare welcomeMessage: string;\r\n declare welcomeSubtitle: string;\r\n declare initialQuestionsUrl: string;\r\n declare language: string;\r\n declare showRelatedFaqs: boolean;\r\n declare errorMessage: string;\r\n\r\n @state()\r\n private declare messages: Message[];\r\n\r\n @state()\r\n private declare input: string;\r\n\r\n @state()\r\n private declare isLoading: boolean;\r\n\r\n @state()\r\n private declare isOpen: boolean;\r\n\r\n\r\n static override properties = {\r\n apiUrl: { type: String, attribute: 'api-url' },\r\n sessionId: { type: String, attribute: 'session-id' },\r\n chatTitle: { type: String, attribute: 'title' },\r\n theme: { type: String },\r\n mode: { type: String, reflect: true },\r\n initialMessages: { type: Array },\r\n botAvatarUrl: { type: String, attribute: 'bot-avatar-url' },\r\n widgetIconUrl: { type: String, attribute: 'widget-icon-url' },\r\n backgroundImageUrl: { type: String, attribute: 'background-image-url' },\r\n widgetWidth: { type: String, attribute: 'widget-width' },\r\n widgetHeight: { type: String, attribute: 'widget-height' },\r\n primaryColor: { type: String, attribute: 'primary-color' },\r\n primaryColorHover: { type: String, attribute: 'primary-color-hover' },\r\n userMessageBg: { type: String, attribute: 'user-message-bg' },\r\n botMessageBg: { type: String, attribute: 'bot-message-bg' },\r\n welcomeMessage: { type: String, attribute: 'welcome-message' },\r\n welcomeSubtitle: { type: String, attribute: 'welcome-subtitle' },\r\n initialQuestionsUrl: { type: String, attribute: 'initial-questions-url' },\r\n language: { type: String, attribute: 'language' },\r\n showRelatedFaqs: { type: Boolean, attribute: 'show-related-faqs' },\r\n errorMessage: { type: String, attribute: 'error-message' },\r\n };\r\n\r\n constructor() {\r\n super();\r\n this.apiUrl = '';\r\n this.sessionId = 'default-session';\r\n this.chatTitle = 'My AI Agent';\r\n this.theme = 'light';\r\n this.mode = 'fullscreen';\r\n this.initialMessages = [];\r\n this.botAvatarUrl = '';\r\n this.widgetIconUrl = '';\r\n this.backgroundImageUrl = '';\r\n this.widgetWidth = '380px';\r\n this.widgetHeight = '600px';\r\n this.primaryColor = '#3681D3';\r\n this.primaryColorHover = '#3457C7';\r\n this.userMessageBg = '#D6E4FF';\r\n this.botMessageBg = '#F5F5F5';\r\n this.welcomeMessage = 'How can I help you today?';\r\n this.welcomeSubtitle = '';\r\n this.initialQuestionsUrl = '';\r\n this.language = 'en';\r\n this.showRelatedFaqs = false;\r\n this.errorMessage = 'Maaf, terdapat masalah semasa menghubungi pelayan. Sila cuba lagi.';\r\n this.messages = [];\r\n this.input = '';\r\n this.isLoading = false;\r\n this.isOpen = false;\r\n }\r\n\r\n private toggleWidget() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n /**\r\n * Clear all chat messages and reset to welcome message\r\n * @public\r\n */\r\n public clearChat(): void {\r\n this.clearMessagesFromStorage();\r\n\r\n if (this.welcomeMessage) {\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n }];\r\n } else {\r\n this.messages = [];\r\n }\r\n }\r\n\r\n private lightenColor(hex: string, percent: number = 15): string {\r\n // Remove # if present\r\n hex = hex.replace('#', '');\r\n\r\n // Convert to RGB\r\n const r = parseInt(hex.substring(0, 2), 16);\r\n const g = parseInt(hex.substring(2, 4), 16);\r\n const b = parseInt(hex.substring(4, 6), 16);\r\n\r\n // Lighten\r\n const newR = Math.min(255, Math.round(r + (255 - r) * (percent / 100)));\r\n const newG = Math.min(255, Math.round(g + (255 - g) * (percent / 100)));\r\n const newB = Math.min(255, Math.round(b + (255 - b) * (percent / 100)));\r\n\r\n // Convert back to hex\r\n return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;\r\n }\r\n\r\n private getStorageKey(): string {\r\n return `ai-chat-messages-${this.sessionId}`;\r\n }\r\n\r\n private saveMessagesToStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.setItem(storageKey, JSON.stringify(this.messages));\r\n // Store the current session ID to track session changes\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n } catch (error) {\r\n console.warn('Failed to save messages to sessionStorage:', error);\r\n }\r\n }\r\n\r\n private loadMessagesFromStorage(): Message[] | null {\r\n try {\r\n // Check if session has changed\r\n const lastSessionId = sessionStorage.getItem('ai-chat-last-session-id');\r\n\r\n if (lastSessionId && lastSessionId !== this.sessionId) {\r\n // Session has changed, clear the old session's messages\r\n const oldStorageKey = `ai-chat-messages-${lastSessionId}`;\r\n sessionStorage.removeItem(oldStorageKey);\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n return null; // Don't load any messages for new session\r\n }\r\n\r\n const storageKey = this.getStorageKey();\r\n const saved = sessionStorage.getItem(storageKey);\r\n if (saved) {\r\n return JSON.parse(saved) as Message[];\r\n }\r\n } catch (error) {\r\n console.warn('Failed to load messages from sessionStorage:', error);\r\n }\r\n return null;\r\n }\r\n\r\n private clearMessagesFromStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.removeItem(storageKey);\r\n } catch (error) {\r\n console.warn('Failed to clear messages from sessionStorage:', error);\r\n }\r\n }\r\n\r\n private formatMessageContent(content: string): string {\r\n // Escape HTML to prevent XSS\r\n const escapeHtml = (text: string) => {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n };\r\n\r\n // Add line break before numbered lists that come after any text (not already on new line)\r\n let processedContent = content.replace(/([^\\n])\\s*(\\d+\\.\\s+)/g, '$1\\n$2');\r\n\r\n // First, split inline numbered lists (1. 2. 3. pattern)\r\n processedContent = processedContent.replace(/(\\d+\\.\\s+[^0-9]+?)(?=\\s+\\d+\\.\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split inline bullet lists (- pattern)\r\n processedContent = processedContent.replace(/(-\\s+[^-]+?)(?=\\s+-\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split content by lines\r\n const lines = processedContent.split('\\n');\r\n let formattedContent = '';\r\n let inList = false;\r\n let listType: 'ul' | 'ol' | null = null;\r\n let orderedListCounter = 1; // Track the current numbered list counter\r\n\r\n // Helper function to check if next non-empty line is a list item\r\n const getNextListType = (startIndex: number): 'ul' | 'ol' | null => {\r\n for (let j = startIndex + 1; j < lines.length; j++) {\r\n const nextLine = lines[j].trim();\r\n if (nextLine === '') continue; // Skip blank lines\r\n if (nextLine.match(/^[-*•]\\s+/)) return 'ul';\r\n if (nextLine.match(/^\\d+\\.\\s+/)) return 'ol';\r\n return null; // Found non-list content\r\n }\r\n return null; // End of content\r\n };\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n\r\n // Check for unordered list (-, *, •)\r\n const unorderedMatch = trimmedLine.match(/^[-*•]\\s+(.+)$/);\r\n // Check for ordered list (1., 2., etc.)\r\n const orderedMatch = trimmedLine.match(/^(\\d+)\\.\\s+(.+)$/);\r\n\r\n if (unorderedMatch) {\r\n if (!inList || listType !== 'ul') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n formattedContent += '<ul>';\r\n inList = true;\r\n listType = 'ul';\r\n }\r\n formattedContent += `<li>${escapeHtml(unorderedMatch[1])}</li>`;\r\n } else if (orderedMatch) {\r\n const itemNumber = parseInt(orderedMatch[1], 10);\r\n const itemText = orderedMatch[2];\r\n\r\n if (!inList || listType !== 'ol') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n // Use the start attribute to continue numbering from where we left off\r\n // or reset to 1 if this is a new sequence starting with 1\r\n if (itemNumber === 1) {\r\n orderedListCounter = 1;\r\n formattedContent += '<ol>';\r\n } else {\r\n formattedContent += `<ol start=\"${orderedListCounter}\">`;\r\n }\r\n inList = true;\r\n listType = 'ol';\r\n }\r\n formattedContent += `<li value=\"${itemNumber}\">${escapeHtml(itemText)}</li>`;\r\n orderedListCounter = itemNumber + 1; // Track next number\r\n } else {\r\n // Not a list item\r\n if (trimmedLine === '') {\r\n // Blank line - check if next line continues the same list type\r\n const nextListType = getNextListType(i);\r\n if (inList && nextListType === listType) {\r\n // Keep list open and add spacing within the list\r\n formattedContent += '<li style=\"list-style: none; height: 0.5em;\"></li>';\r\n } else {\r\n // Close list if we're in one\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += '<br>';\r\n }\r\n } else {\r\n // Non-blank, non-list content\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += escapeHtml(line) + '\\n';\r\n }\r\n }\r\n }\r\n\r\n // Close any open list\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n }\r\n\r\n return formattedContent;\r\n }\r\n\r\n async connectedCallback() {\r\n super.connectedCallback();\r\n\r\n // Try to load messages from sessionStorage first\r\n const savedMessages = this.loadMessagesFromStorage();\r\n\r\n if (this.initialMessages && this.initialMessages.length > 0) {\r\n this.messages = [...this.initialMessages];\r\n } else if (savedMessages && savedMessages.length > 0) {\r\n // Restore saved messages from sessionStorage\r\n this.messages = savedMessages;\r\n } else {\r\n // Fetch initial suggested questions if URL is provided\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n let fetchFailed = false;\r\n\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n // Append language parameter to the URL\r\n let fetchUrl = this.initialQuestionsUrl;\r\n if (this.language) {\r\n const separator = fetchUrl.includes('?') ? '&' : '?';\r\n fetchUrl = `${fetchUrl}${separator}language=${this.language}`;\r\n }\r\n\r\n const response = await fetch(fetchUrl);\r\n if (response.ok) {\r\n const data = await response.json();\r\n\r\n // Support various response formats\r\n let questionsArray = data.questions || data.suggested_questions || data;\r\n\r\n // If array contains objects with question_text property, store full objects\r\n if (Array.isArray(questionsArray) && questionsArray.length > 0) {\r\n if (typeof questionsArray[0] === 'object' && questionsArray[0].question_text) {\r\n // Store full question objects with id and question_type\r\n suggestedQuestions = questionsArray.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n } else if (typeof questionsArray[0] === 'string') {\r\n // Legacy format: convert strings to objects\r\n suggestedQuestions = questionsArray.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n }\r\n } else {\r\n fetchFailed = true;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch initial questions:', error);\r\n fetchFailed = true;\r\n }\r\n }\r\n\r\n // If fetch failed, clear session storage\r\n if (fetchFailed) {\r\n this.clearMessagesFromStorage();\r\n }\r\n\r\n // Always show welcome message if available\r\n if (this.welcomeMessage) {\r\n // Add welcome message as initial assistant message\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n suggestedQuestions: suggestedQuestions,\r\n }];\r\n }\r\n }\r\n }\r\n\r\n updated(changedProperties: PropertyValues) {\r\n super.updated(changedProperties);\r\n if (changedProperties.has('messages')) {\r\n this.scrollToBottom();\r\n // Save messages to sessionStorage whenever they change\r\n this.saveMessagesToStorage();\r\n }\r\n }\r\n\r\n private scrollToBottom() {\r\n // Use setTimeout to ensure Lit has finished rendering\r\n setTimeout(() => {\r\n // Find the last user message and scroll to it\r\n const userMessages = this.shadowRoot?.querySelectorAll('.message.user');\r\n if (userMessages && userMessages.length > 0) {\r\n const lastUserMessage = userMessages[userMessages.length - 1] as HTMLElement;\r\n lastUserMessage.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Normalize suggested questions - converts string arrays to SuggestedQuestion objects\r\n */\r\n private normalizeSuggestedQuestions(questions: any): SuggestedQuestion[] | undefined {\r\n if (!questions || !Array.isArray(questions) || questions.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // If already objects with question_text, return as-is\r\n if (typeof questions[0] === 'object' && questions[0].question_text) {\r\n return questions as SuggestedQuestion[];\r\n }\r\n\r\n // If strings, convert to SuggestedQuestion objects\r\n if (typeof questions[0] === 'string') {\r\n return questions.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private handleInput(e: Event) {\r\n this.input = (e.target as HTMLInputElement).value;\r\n }\r\n\r\n private async handleFAQClick(question: SuggestedQuestion) {\r\n if (this.isLoading) return;\r\n\r\n // Check if this is a suggested question with id and question_type\r\n if (question.id && question.question_type) {\r\n // Call the new API endpoint for suggested questions\r\n await this.handleSuggestedQuestionClick(question);\r\n } else {\r\n // Legacy behavior: Set the input and trigger submit\r\n this.input = question.question_text;\r\n\r\n // Create a synthetic submit event\r\n const submitEvent = new Event('submit', { cancelable: true });\r\n this.handleSubmit(submitEvent);\r\n }\r\n }\r\n\r\n private async handleSuggestedQuestionClick(question: SuggestedQuestion) {\r\n if (!question.id || !question.question_type) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: question.question_text,\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n // Call the new endpoint: /api/questions/{id}?question_type={question_type}\r\n // Extract base URL from initialQuestionsUrl (e.g., \"http://example.com:8080/api/questions/first-launch\" -> \"http://example.com:8080\")\r\n let baseUrl = '';\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n const urlObj = new URL(this.initialQuestionsUrl);\r\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\r\n } catch {\r\n // Fallback if URL parsing fails\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n } else {\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n\r\n const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract response text from the API response\r\n let responseText = 'No response from agent';\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object') {\r\n // The API returns { question: { answer_text: \"...\", ... }, related_questions: [...] }\r\n if (data.question && data.question.answer_text) {\r\n responseText = data.question.answer_text;\r\n }\r\n\r\n // Convert related_questions to SuggestedQuestion format\r\n if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {\r\n if (typeof data.related_questions[0] === 'object' && data.related_questions[0].question_text) {\r\n suggestedQuestions = data.related_questions.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n }\r\n }\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Suggested question API failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private async handleSubmit(e: Event) {\r\n e.preventDefault();\r\n\r\n if (!this.input.trim() || this.isLoading || !this.apiUrl) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: this.input.trim(),\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n const questionText = this.input.trim();\r\n this.input = '';\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n const response = await fetch(`${this.apiUrl}/ask`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n session_id: this.sessionId,\r\n question: questionText,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract the response text and suggested questions\r\n let responseText = 'No response from agent';\r\n let faqs: FAQ[] | undefined = undefined;\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object' && data.response && typeof data.response === 'string') {\r\n // Check if data.response contains stringified JSON\r\n const trimmedResponse = data.response.trim();\r\n if (trimmedResponse.startsWith('{') || trimmedResponse.startsWith('[')) {\r\n try {\r\n // First attempt: standard JSON.parse\r\n const innerData = JSON.parse(data.response);\r\n\r\n if (innerData && innerData.response && typeof innerData.response === 'string') {\r\n responseText = innerData.response;\r\n faqs = innerData.faq_used || innerData.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);\r\n } else {\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } catch (parseError) {\r\n // Backend has malformed JSON - extract response text\r\n const responsePattern = /\"response\"\\s*:\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"/s;\r\n const responseMatch = data.response.match(responsePattern);\r\n\r\n if (responseMatch) {\r\n responseText = responseMatch[1]\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\r/g, '\\r')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n } else {\r\n responseText = 'Error: Could not parse response';\r\n }\r\n\r\n // Extract FAQs array (support both faq_used and faqs_used)\r\n const faqsPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const faqsMatch = data.response.match(faqsPattern);\r\n\r\n if (faqsMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMatch[1]);\r\n } catch {\r\n // FAQs might span multiple lines\r\n const faqsMultiPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const faqsMultiMatch = data.response.match(faqsMultiPattern);\r\n if (faqsMultiMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMultiMatch[1]);\r\n } catch {\r\n faqs = undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract suggested questions array\r\n const suggestedPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const suggestedMatch = data.response.match(suggestedPattern);\r\n\r\n if (suggestedMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n const suggestedMultiPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const suggestedMultiMatch = data.response.match(suggestedMultiPattern);\r\n if (suggestedMultiMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n suggestedQuestions = undefined;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // Not JSON, direct text response\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } else if (typeof data === 'string') {\r\n responseText = data;\r\n } else if (data && typeof data === 'object') {\r\n // Fallback for other formats\r\n responseText = data.message || data.answer || 'Error: Unexpected response format';\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n faqs: faqs,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Backend connection failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private renderChatUI() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n return html`\r\n <!-- Header -->\r\n <div class=\"header\" style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <div class=\"header-content\">\r\n <div class=\"header-avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"Bot\" class=\"header-avatar-image\" />`\r\n : html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${this.primaryColor}\" stroke-width=\"2\" style=\"width: 1.5rem; height: 1.5rem;\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>`}\r\n </div>\r\n <h1 class=\"title\">${this.chatTitle}</h1>\r\n </div>\r\n </div>\r\n\r\n <!-- Messages Area -->\r\n <div class=\"messages-area\" style=\"--user-message-bg: ${this.userMessageBg}; --bot-message-bg: ${this.botMessageBg}; --primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover}; ${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}');` : ''}\">\r\n <div class=\"messages-container\">\r\n ${repeat(this.messages, (msg) => msg.id, (msg) => html`\r\n <div\r\n class=${classMap({\r\n message: true,\r\n user: msg.role === 'user',\r\n assistant: msg.role === 'assistant'\r\n })}\r\n >\r\n <div class=\"avatar\">\r\n ${msg.role === 'user'\r\n ? 'U'\r\n : this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"message-text\">${unsafeHTML(this.formatMessageContent(msg.content))}</div>\r\n ${msg.role === 'assistant' && this.showRelatedFaqs && msg.faqs && msg.faqs.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Related FAQs:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.faqs.map(faq => html`\r\n <li class=\"faq-item-static\">\r\n ${faq.Question}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n ${msg.role === 'assistant' && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Suggested Questions:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.suggestedQuestions.map(question => html`\r\n <li class=\"faq-item\" @click=${() => this.handleFAQClick(question)}>\r\n ${question.question_text}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n `)}\r\n\r\n ${this.isLoading ? html`\r\n <div class=\"loading\">\r\n <div class=\"avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"spinner\"></div>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n\r\n <!-- Input Area -->\r\n <div class=\"input-area\" style=\"--primary-color: ${this.primaryColor}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <form class=\"input-form\" @submit=${this.handleSubmit}>\r\n <input\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"Taip mesej anda...\"\r\n .value=${this.input}\r\n @input=${this.handleInput}\r\n ?disabled=${this.isLoading}\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"send-button\"\r\n ?disabled=${this.isLoading || !this.input.trim()}\r\n aria-label=\"Send message\"\r\n >\r\n ${this.isLoading ? html`\r\n <div class=\"spinner\" style=\"border-color: #fff; border-top-color: transparent;\"></div>\r\n ` : html`\r\n <svg class=\"send-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n `}\r\n </button>\r\n </form>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div class=\"version-tag\">v${VERSION}</div>\r\n `;\r\n }\r\n\r\n render() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n if (this.mode === 'widget') {\r\n return html`\r\n <div class=\"widget-container\">\r\n <!-- Chat Window -->\r\n <div\r\n class=${classMap({ 'widget-window': true, 'open': this.isOpen })}\r\n style=\"--widget-width: ${this.widgetWidth}; --widget-height: ${this.widgetHeight};\"\r\n >\r\n ${this.renderChatUI()}\r\n </div>\r\n\r\n <!-- Toggle Button -->\r\n <button\r\n class=${classMap({\r\n 'widget-button': true,\r\n 'widget-button-no-bg': !this.isOpen && !!this.widgetIconUrl\r\n })}\r\n style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};\"\r\n @click=${this.toggleWidget}\r\n aria-label=${this.isOpen ? 'Close chat' : 'Open chat'}\r\n >\r\n ${this.isOpen ? html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n ` : this.widgetIconUrl ? html`\r\n <img src=\"${this.widgetIconUrl}\" alt=\"Chat\" class=\"widget-button-icon\" />\r\n ` : html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>\r\n `}\r\n </button>\r\n </div>\r\n `;\r\n }\r\n\r\n // Fullscreen mode\r\n return this.renderChatUI();\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'ai-chat': AIChat;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/components/ai-chat.ts"],"names":["AIChat","LitElement","html","repeat","classMap","unsafeHTML","css","state","customElement"],"mappings":"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A;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;AADLN,cAAA,CAuxBK,UAAA,GAAa;AAAA,EAC3B,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,SAAA,EAAU;AAAA,EAC7C,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,YAAA,EAAa;AAAA,EACnD,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,OAAA,EAAQ;AAAA,EAC9C,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,EACtB,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,EAAK;AAAA,EACpC,eAAA,EAAiB,EAAE,IAAA,EAAM,KAAA,EAAM;AAAA,EAC/B,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,gBAAA,EAAiB;AAAA,EAC1D,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,kBAAA,EAAoB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,sBAAA,EAAuB;AAAA,EACtE,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,cAAA,EAAe;AAAA,EACvD,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA,EAAgB;AAAA,EACzD,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA,EAAgB;AAAA,EACzD,iBAAA,EAAmB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,qBAAA,EAAsB;AAAA,EACpE,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,gBAAA,EAAiB;AAAA,EAC1D,cAAA,EAAgB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC7D,eAAA,EAAiB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,kBAAA,EAAmB;AAAA,EAC/D,mBAAA,EAAqB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,uBAAA,EAAwB;AAAA,EACxE,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,UAAA,EAAW;AAAA,EAChD,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,mBAAA,EAAoB;AAAA,EACjE,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA;AAC3C,CAAA;AAnCgB,eAAA,CAAA;AAAA,EADfO,mBAAA;AAAM,CAAA,EA1wBIP,cAAA,CA2wBK,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADfO,mBAAA;AAAM,CAAA,EA7wBIP,cAAA,CA8wBK,SAAA,EAAA,OAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADfO,mBAAA;AAAM,CAAA,EAhxBIP,cAAA,CAixBK,SAAA,EAAA,WAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADfO,mBAAA;AAAM,CAAA,EAnxBIP,cAAA,CAoxBK,SAAA,EAAA,QAAA,EAAA,CAAA,CAAA;AApxBLA,cAAA,GAAN,eAAA,CAAA;AAAA,EADNQ,4BAAc,SAAS;AAAA,CAAA,EACXR,cAAA,CAAA","file":"index.js","sourcesContent":["import { LitElement, html, css, PropertyValues } from 'lit';\r\nimport { customElement, state } from 'lit/decorators.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\r\n\r\nconst VERSION = '0.2.19';\r\n\r\nexport interface FAQ {\r\n No: string;\r\n Question: string;\r\n}\r\n\r\nexport interface SuggestedQuestion {\r\n id?: number;\r\n question_type?: string;\r\n question_text: string;\r\n category?: string;\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n faqs?: FAQ[];\r\n suggestedQuestions?: SuggestedQuestion[];\r\n}\r\n\r\n/**\r\n * AI Chat Web Component\r\n *\r\n * @fires message-sent - Fired when user sends a message\r\n * @fires response-received - Fired when AI responds\r\n * @fires error - Fired when an error occurs\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\">\r\n * </ai-chat>\r\n *\r\n * <!-- Widget mode with custom size -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * mode=\"widget\"\r\n * widget-width=\"400px\"\r\n * widget-height=\"650px\">\r\n * </ai-chat>\r\n *\r\n * <!-- Custom theme colors -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * primary-color=\"#10B981\"\r\n * primary-color-hover=\"#059669\"\r\n * user-message-bg=\"#D1FAE5\"\r\n * bot-message-bg=\"#F3F4F6\">\r\n * </ai-chat>\r\n * ```\r\n */\r\n@customElement('ai-chat')\r\nexport class AIChat extends LitElement {\r\n static styles = css`\r\n :host {\r\n font-family: system-ui, -apple-system, sans-serif;\r\n color: #09090b;\r\n }\r\n\r\n /* Fullscreen mode (default) */\r\n :host([mode=\"fullscreen\"]) {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n background: #ffffff;\r\n }\r\n\r\n :host([mode=\"fullscreen\"][theme=\"dark\"]) {\r\n background: #000;\r\n color: #fafafa;\r\n }\r\n\r\n /* Widget mode */\r\n :host([mode=\"widget\"]) {\r\n position: fixed;\r\n bottom: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n }\r\n\r\n .widget-container {\r\n position: relative;\r\n }\r\n\r\n .widget-button {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: #3681D3;\r\n border: none;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);\r\n transition: transform 0.2s, box-shadow 0.2s;\r\n overflow: hidden;\r\n }\r\n\r\n .widget-button:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 6px 20px rgba(65, 105, 225, 0.4);\r\n }\r\n\r\n .widget-button-no-bg {\r\n background: transparent;\r\n box-shadow: none;\r\n }\r\n\r\n .widget-button-no-bg:hover {\r\n background: transparent;\r\n box-shadow: none;\r\n transform: scale(1.1);\r\n }\r\n\r\n .widget-button svg {\r\n width: 28px;\r\n height: 28px;\r\n color: white;\r\n }\r\n\r\n .widget-button-icon {\r\n width: 60px;\r\n height: 60px;\r\n object-fit: contain;\r\n border-radius: 50%;\r\n }\r\n\r\n .widget-window {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 0;\r\n width: var(--widget-width, 380px);\r\n height: var(--widget-height, 600px);\r\n background: #fff;\r\n border-radius: 16px;\r\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n transition: opacity 0.2s, transform 0.2s;\r\n }\r\n\r\n .widget-window.open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n pointer-events: all;\r\n }\r\n\r\n :host([theme=\"dark\"]) .widget-window {\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n /* Tablet breakpoint */\r\n @media (max-width: 1024px) and (min-width: 769px) {\r\n .widget-window {\r\n width: var(--widget-width, 400px);\r\n height: var(--widget-height, 650px);\r\n }\r\n }\r\n\r\n /* Small tablet breakpoint */\r\n @media (max-width: 768px) and (min-width: 481px) {\r\n .widget-window {\r\n width: var(--widget-width, 360px);\r\n height: var(--widget-height, 550px);\r\n }\r\n }\r\n\r\n /* Mobile portrait */\r\n @media (max-width: 480px) and (orientation: portrait) {\r\n .widget-window {\r\n width: calc(100vw - 40px);\r\n height: 70vh;\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile landscape */\r\n @media (max-width: 900px) and (orientation: landscape) {\r\n .widget-window {\r\n width: var(--widget-width, 500px);\r\n height: calc(100vh - 100px);\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile responsive styles for all modes */\r\n @media (max-width: 768px) {\r\n .header {\r\n padding: 0.875rem 1rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.25rem;\r\n height: 2.25rem;\r\n }\r\n\r\n .title {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 1rem 0.75rem;\r\n }\r\n\r\n .message {\r\n gap: 0.75rem;\r\n }\r\n\r\n .avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n font-size: 0.75rem;\r\n }\r\n\r\n .message-content {\r\n max-width: 100%;\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 3rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.25rem;\r\n padding: 0 1rem;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.8125rem;\r\n padding: 0;\r\n }\r\n\r\n .input-area {\r\n padding: 0.75rem;\r\n }\r\n\r\n .input-form {\r\n gap: 0.5rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.75rem;\r\n padding: 0 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.75rem;\r\n height: 2.75rem;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-icon {\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n }\r\n }\r\n\r\n /* Extra small screens */\r\n @media (max-width: 480px) {\r\n .header {\r\n padding: 0.75rem 0.875rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n }\r\n\r\n .title {\r\n font-size: 1rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 0.75rem 0.5rem;\r\n }\r\n\r\n .message {\r\n gap: 0.5rem;\r\n }\r\n\r\n .avatar {\r\n width: 1.75rem;\r\n height: 1.75rem;\r\n font-size: 0.7rem;\r\n }\r\n\r\n .message-content {\r\n padding: 0.5rem 0.75rem;\r\n font-size: 0.875rem;\r\n border-radius: 0.75rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 2rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .input-area {\r\n padding: 0.625rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.5rem;\r\n padding: 0 0.75rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n }\r\n\r\n .version-tag {\r\n font-size: 0.7rem;\r\n padding: 0.375rem;\r\n }\r\n }\r\n\r\n .header {\r\n background:#3681D3;\r\n padding: 1rem 1.25rem;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n box-shadow: 0 2px 8px rgba(65, 105, 225, 0.2);\r\n }\r\n\r\n :host([theme=\"dark\"]) .header {\r\n background: #3681D3\r\n }\r\n\r\n .header-content {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n width: 100%;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 50%;\r\n background: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n }\r\n\r\n .header-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .title {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #fff;\r\n }\r\n\r\n .messages-area {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 1.5rem 1rem;\r\n position: relative;\r\n background: #ffffff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .messages-area {\r\n background: #000;\r\n }\r\n\r\n .messages-area::before {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background-image: var(--background-image-url);\r\n background-size: 200px auto 60%;\r\n background-position: center center;\r\n background-repeat: no-repeat;\r\n opacity: 0.03;\r\n pointer-events: none;\r\n z-index: 0;\r\n }\r\n\r\n .messages-container {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 1.5rem;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .empty-state {\r\n text-align: center;\r\n margin-top: 5rem;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1.5rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state {\r\n color: #a1a1aa;\r\n }\r\n\r\n .empty-state-avatar {\r\n width: 5rem;\r\n height: 5rem;\r\n border-radius: 50%;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar {\r\n background: #3f3f46;\r\n }\r\n\r\n .empty-state-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .empty-state-avatar svg {\r\n width: 3rem;\r\n height: 3rem;\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar svg {\r\n color: #6b7280;\r\n }\r\n\r\n .empty-state-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.5rem;\r\n }\r\n\r\n .empty-state-message {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #374151;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-message {\r\n color: #f3f4f6;\r\n }\r\n\r\n .empty-state-subtitle {\r\n font-size: 0.9375rem;\r\n margin: 0;\r\n color: #6b7280;\r\n max-width: 24rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-subtitle {\r\n color: #9ca3af;\r\n }\r\n\r\n .message {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .message.user {\r\n flex-direction: row-reverse;\r\n }\r\n\r\n .avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 9999px;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n font-weight: 600;\r\n font-size: 0.875rem;\r\n overflow: hidden;\r\n color: #6B7280;\r\n }\r\n\r\n :host([theme=\"dark\"]) .avatar {\r\n background: #3f3f46;\r\n color: #9ca3af;\r\n }\r\n\r\n .avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .message-content {\r\n max-width: 36rem;\r\n padding: 0.875rem 1.125rem;\r\n border-radius: 1.25rem;\r\n line-height: 1.6;\r\n overflow-wrap: break-word;\r\n word-wrap: break-word;\r\n min-width: 0;\r\n }\r\n\r\n .message.user .message-content {\r\n background: var(--user-message-bg, #D6E4FF);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 0.25rem 1.25rem;\r\n }\r\n\r\n .message.assistant .message-content {\r\n background: var(--bot-message-bg, #F5F5F5);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 1.25rem 0.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.user .message-content {\r\n background: #3D5A99;\r\n color: #fff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.assistant .message-content {\r\n background: #27272a;\r\n color: #fafafa;\r\n }\r\n\r\n .message-text {\r\n white-space: pre-wrap;\r\n margin: 0;\r\n word-wrap: break-word;\r\n overflow-wrap: break-word;\r\n word-break: break-word;\r\n }\r\n\r\n .message-text ul,\r\n .message-text ol {\r\n margin: 0.5rem 0;\r\n padding-left: 1.5rem;\r\n white-space: normal;\r\n list-style-position: outside;\r\n }\r\n\r\n .message-text li {\r\n margin: 0.25rem 0;\r\n white-space: normal;\r\n display: list-item;\r\n }\r\n\r\n .message-text ul {\r\n list-style-type: disc;\r\n }\r\n\r\n .message-text ol {\r\n list-style-type: decimal;\r\n counter-reset: list-counter;\r\n }\r\n\r\n .message-text ol li {\r\n display: list-item;\r\n list-style-type: decimal;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n border-top: 1px solid #d1d5db;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-section {\r\n border-top-color: #3f3f46;\r\n }\r\n\r\n .faq-title {\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n color: var(--primary-color, #3681D3);\r\n margin: 0 0 0.375rem 0;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-title {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n .faq-list {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.375rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.875rem;\r\n color: var(--primary-color, #3681D3);\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: pointer;\r\n transition: background-color 0.2s, color 0.2s;\r\n border: 1px solid transparent;\r\n }\r\n\r\n .faq-item:hover {\r\n background-color: #EEF2FF;\r\n color: var(--primary-color-hover, #3457C7);\r\n border-color: #C7D2FE;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item:hover {\r\n background-color: #1e293b;\r\n color: #93C5FD;\r\n border-color: #3f3f46;\r\n }\r\n\r\n /* FAQ static item styles - commented out for now */\r\n /* .faq-item-static {\r\n font-size: 0.875rem;\r\n color: #6B7280;\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: default;\r\n border: 1px solid transparent;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item-static {\r\n color: #9CA3AF;\r\n } */\r\n\r\n .loading {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .spinner {\r\n display: inline-block;\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border: 2px solid #e4e4e7;\r\n border-top-color: #71717a;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n .input-area {\r\n border-top: 1px solid #e5e7eb;\r\n background: #fff;\r\n padding: 1rem 1.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-area {\r\n border-top-color: #27272a;\r\n background: #18181b;\r\n }\r\n\r\n .input-form {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n gap: 0.75rem;\r\n align-items: center;\r\n }\r\n\r\n .input-field {\r\n flex: 1;\r\n height: 3rem;\r\n padding: 0 1rem;\r\n border: 1px solid #d1d5db;\r\n border-radius: 1.5rem;\r\n font-size: 0.9375rem;\r\n font-family: inherit;\r\n background: #fff;\r\n color: #374151;\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .input-field::placeholder {\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-field {\r\n border-color: #3f3f46;\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n .input-field:focus {\r\n outline: none;\r\n border-color: var(--primary-color, #3681D3);\r\n box-shadow: 0 0 0 3px rgba(65, 105, 225, 0.1);\r\n }\r\n\r\n .input-field:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-button {\r\n width: 3rem;\r\n height: 3rem;\r\n border-radius: 9999px;\r\n border: none;\r\n background: var(--primary-color, #3681D3);\r\n color: #fff;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s, transform 0.1s;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-button:hover:not(:disabled) {\r\n background: var(--primary-color-hover, #3457C7);\r\n transform: scale(1.05);\r\n }\r\n\r\n .send-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-icon {\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n }\r\n\r\n .version-tag {\r\n text-align: center;\r\n padding: 0.5rem;\r\n font-size: 0.75rem;\r\n color: #9ca3af;\r\n border-top: 1px solid #e5e7eb;\r\n }\r\n\r\n :host([theme=\"dark\"]) .version-tag {\r\n color: #6b7280;\r\n border-top-color: #27272a;\r\n }\r\n `;\r\n\r\n declare apiUrl: string;\r\n declare sessionId: string;\r\n declare chatTitle: string;\r\n declare theme: 'light' | 'dark';\r\n declare mode: 'fullscreen' | 'widget';\r\n declare initialMessages: Message[];\r\n declare botAvatarUrl: string;\r\n declare userAvatarUrl: string;\r\n declare widgetIconUrl: string;\r\n declare backgroundImageUrl: string;\r\n declare widgetWidth: string;\r\n declare widgetHeight: string;\r\n declare primaryColor: string;\r\n declare primaryColorHover: string;\r\n declare userMessageBg: string;\r\n declare botMessageBg: string;\r\n declare welcomeMessage: string;\r\n declare welcomeSubtitle: string;\r\n declare initialQuestionsUrl: string;\r\n declare language: string;\r\n declare showRelatedFaqs: boolean;\r\n declare errorMessage: string;\r\n\r\n @state()\r\n private declare messages: Message[];\r\n\r\n @state()\r\n private declare input: string;\r\n\r\n @state()\r\n private declare isLoading: boolean;\r\n\r\n @state()\r\n private declare isOpen: boolean;\r\n\r\n\r\n static override properties = {\r\n apiUrl: { type: String, attribute: 'api-url' },\r\n sessionId: { type: String, attribute: 'session-id' },\r\n chatTitle: { type: String, attribute: 'title' },\r\n theme: { type: String },\r\n mode: { type: String, reflect: true },\r\n initialMessages: { type: Array },\r\n botAvatarUrl: { type: String, attribute: 'bot-avatar-url' },\r\n userAvatarUrl: { type: String, attribute: 'user-avatar-url' },\r\n widgetIconUrl: { type: String, attribute: 'widget-icon-url' },\r\n backgroundImageUrl: { type: String, attribute: 'background-image-url' },\r\n widgetWidth: { type: String, attribute: 'widget-width' },\r\n widgetHeight: { type: String, attribute: 'widget-height' },\r\n primaryColor: { type: String, attribute: 'primary-color' },\r\n primaryColorHover: { type: String, attribute: 'primary-color-hover' },\r\n userMessageBg: { type: String, attribute: 'user-message-bg' },\r\n botMessageBg: { type: String, attribute: 'bot-message-bg' },\r\n welcomeMessage: { type: String, attribute: 'welcome-message' },\r\n welcomeSubtitle: { type: String, attribute: 'welcome-subtitle' },\r\n initialQuestionsUrl: { type: String, attribute: 'initial-questions-url' },\r\n language: { type: String, attribute: 'language' },\r\n showRelatedFaqs: { type: Boolean, attribute: 'show-related-faqs' },\r\n errorMessage: { type: String, attribute: 'error-message' },\r\n };\r\n\r\n constructor() {\r\n super();\r\n this.apiUrl = '';\r\n this.sessionId = 'default-session';\r\n this.chatTitle = 'My AI Agent';\r\n this.theme = 'light';\r\n this.mode = 'fullscreen';\r\n this.initialMessages = [];\r\n this.botAvatarUrl = '';\r\n this.userAvatarUrl = '';\r\n this.widgetIconUrl = '';\r\n this.backgroundImageUrl = '';\r\n this.widgetWidth = '380px';\r\n this.widgetHeight = '600px';\r\n this.primaryColor = '#3681D3';\r\n this.primaryColorHover = '#3457C7';\r\n this.userMessageBg = '#D6E4FF';\r\n this.botMessageBg = '#F5F5F5';\r\n this.welcomeMessage = 'How can I help you today?';\r\n this.welcomeSubtitle = '';\r\n this.initialQuestionsUrl = '';\r\n this.language = 'en';\r\n this.showRelatedFaqs = false;\r\n this.errorMessage = 'Maaf, terdapat masalah semasa menghubungi pelayan. Sila cuba lagi.';\r\n this.messages = [];\r\n this.input = '';\r\n this.isLoading = false;\r\n this.isOpen = false;\r\n }\r\n\r\n private toggleWidget() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n /**\r\n * Clear all chat messages and reset to welcome message\r\n * @public\r\n */\r\n public clearChat(): void {\r\n this.clearMessagesFromStorage();\r\n\r\n if (this.welcomeMessage) {\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n }];\r\n } else {\r\n this.messages = [];\r\n }\r\n }\r\n\r\n private lightenColor(hex: string, percent: number = 15): string {\r\n // Remove # if present\r\n hex = hex.replace('#', '');\r\n\r\n // Convert to RGB\r\n const r = parseInt(hex.substring(0, 2), 16);\r\n const g = parseInt(hex.substring(2, 4), 16);\r\n const b = parseInt(hex.substring(4, 6), 16);\r\n\r\n // Lighten\r\n const newR = Math.min(255, Math.round(r + (255 - r) * (percent / 100)));\r\n const newG = Math.min(255, Math.round(g + (255 - g) * (percent / 100)));\r\n const newB = Math.min(255, Math.round(b + (255 - b) * (percent / 100)));\r\n\r\n // Convert back to hex\r\n return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;\r\n }\r\n\r\n private getStorageKey(): string {\r\n return `ai-chat-messages-${this.sessionId}`;\r\n }\r\n\r\n private saveMessagesToStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.setItem(storageKey, JSON.stringify(this.messages));\r\n // Store the current session ID to track session changes\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n } catch (error) {\r\n console.warn('Failed to save messages to sessionStorage:', error);\r\n }\r\n }\r\n\r\n private loadMessagesFromStorage(): Message[] | null {\r\n try {\r\n // Check if session has changed\r\n const lastSessionId = sessionStorage.getItem('ai-chat-last-session-id');\r\n\r\n if (lastSessionId && lastSessionId !== this.sessionId) {\r\n // Session has changed, clear the old session's messages\r\n const oldStorageKey = `ai-chat-messages-${lastSessionId}`;\r\n sessionStorage.removeItem(oldStorageKey);\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n return null; // Don't load any messages for new session\r\n }\r\n\r\n const storageKey = this.getStorageKey();\r\n const saved = sessionStorage.getItem(storageKey);\r\n if (saved) {\r\n return JSON.parse(saved) as Message[];\r\n }\r\n } catch (error) {\r\n console.warn('Failed to load messages from sessionStorage:', error);\r\n }\r\n return null;\r\n }\r\n\r\n private clearMessagesFromStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.removeItem(storageKey);\r\n } catch (error) {\r\n console.warn('Failed to clear messages from sessionStorage:', error);\r\n }\r\n }\r\n\r\n private formatMessageContent(content: string): string {\r\n // Escape HTML to prevent XSS\r\n const escapeHtml = (text: string) => {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n };\r\n\r\n // Add line break before numbered lists that come after any text (not already on new line)\r\n let processedContent = content.replace(/([^\\n])\\s*(\\d+\\.\\s+)/g, '$1\\n$2');\r\n\r\n // First, split inline numbered lists (1. 2. 3. pattern)\r\n processedContent = processedContent.replace(/(\\d+\\.\\s+[^0-9]+?)(?=\\s+\\d+\\.\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split inline bullet lists (- pattern)\r\n processedContent = processedContent.replace(/(-\\s+[^-]+?)(?=\\s+-\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split content by lines\r\n const lines = processedContent.split('\\n');\r\n let formattedContent = '';\r\n let inList = false;\r\n let listType: 'ul' | 'ol' | null = null;\r\n let orderedListCounter = 1; // Track the current numbered list counter\r\n\r\n // Helper function to check if next non-empty line is a list item\r\n const getNextListType = (startIndex: number): 'ul' | 'ol' | null => {\r\n for (let j = startIndex + 1; j < lines.length; j++) {\r\n const nextLine = lines[j].trim();\r\n if (nextLine === '') continue; // Skip blank lines\r\n if (nextLine.match(/^[-*•]\\s+/)) return 'ul';\r\n if (nextLine.match(/^\\d+\\.\\s+/)) return 'ol';\r\n return null; // Found non-list content\r\n }\r\n return null; // End of content\r\n };\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n\r\n // Check for unordered list (-, *, •)\r\n const unorderedMatch = trimmedLine.match(/^[-*•]\\s+(.+)$/);\r\n // Check for ordered list (1., 2., etc.)\r\n const orderedMatch = trimmedLine.match(/^(\\d+)\\.\\s+(.+)$/);\r\n\r\n if (unorderedMatch) {\r\n if (!inList || listType !== 'ul') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n formattedContent += '<ul>';\r\n inList = true;\r\n listType = 'ul';\r\n }\r\n formattedContent += `<li>${escapeHtml(unorderedMatch[1])}</li>`;\r\n } else if (orderedMatch) {\r\n const itemNumber = parseInt(orderedMatch[1], 10);\r\n const itemText = orderedMatch[2];\r\n\r\n if (!inList || listType !== 'ol') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n // Use the start attribute to continue numbering from where we left off\r\n // or reset to 1 if this is a new sequence starting with 1\r\n if (itemNumber === 1) {\r\n orderedListCounter = 1;\r\n formattedContent += '<ol>';\r\n } else {\r\n formattedContent += `<ol start=\"${orderedListCounter}\">`;\r\n }\r\n inList = true;\r\n listType = 'ol';\r\n }\r\n formattedContent += `<li value=\"${itemNumber}\">${escapeHtml(itemText)}</li>`;\r\n orderedListCounter = itemNumber + 1; // Track next number\r\n } else {\r\n // Not a list item\r\n if (trimmedLine === '') {\r\n // Blank line - check if next line continues the same list type\r\n const nextListType = getNextListType(i);\r\n if (inList && nextListType === listType) {\r\n // Keep list open and add spacing within the list\r\n formattedContent += '<li style=\"list-style: none; height: 0.5em;\"></li>';\r\n } else {\r\n // Close list if we're in one\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += '<br>';\r\n }\r\n } else {\r\n // Non-blank, non-list content\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += escapeHtml(line) + '\\n';\r\n }\r\n }\r\n }\r\n\r\n // Close any open list\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n }\r\n\r\n return formattedContent;\r\n }\r\n\r\n async connectedCallback() {\r\n super.connectedCallback();\r\n\r\n // Try to load messages from sessionStorage first\r\n const savedMessages = this.loadMessagesFromStorage();\r\n\r\n if (this.initialMessages && this.initialMessages.length > 0) {\r\n this.messages = [...this.initialMessages];\r\n } else if (savedMessages && savedMessages.length > 0) {\r\n // Restore saved messages from sessionStorage\r\n this.messages = savedMessages;\r\n } else {\r\n // Fetch initial suggested questions if URL is provided\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n let fetchFailed = false;\r\n\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n // Append language parameter to the URL\r\n let fetchUrl = this.initialQuestionsUrl;\r\n if (this.language) {\r\n const separator = fetchUrl.includes('?') ? '&' : '?';\r\n fetchUrl = `${fetchUrl}${separator}language=${this.language}`;\r\n }\r\n\r\n const response = await fetch(fetchUrl);\r\n if (response.ok) {\r\n const data = await response.json();\r\n\r\n // Support various response formats\r\n let questionsArray = data.questions || data.suggested_questions || data;\r\n\r\n // If array contains objects with question_text property, store full objects\r\n if (Array.isArray(questionsArray) && questionsArray.length > 0) {\r\n if (typeof questionsArray[0] === 'object' && questionsArray[0].question_text) {\r\n // Store full question objects with id and question_type\r\n suggestedQuestions = questionsArray.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n } else if (typeof questionsArray[0] === 'string') {\r\n // Legacy format: convert strings to objects\r\n suggestedQuestions = questionsArray.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n }\r\n } else {\r\n fetchFailed = true;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch initial questions:', error);\r\n fetchFailed = true;\r\n }\r\n }\r\n\r\n // If fetch failed, clear session storage\r\n if (fetchFailed) {\r\n this.clearMessagesFromStorage();\r\n }\r\n\r\n // Always show welcome message if available\r\n if (this.welcomeMessage) {\r\n // Add welcome message as initial assistant message\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n suggestedQuestions: suggestedQuestions,\r\n }];\r\n }\r\n }\r\n }\r\n\r\n updated(changedProperties: PropertyValues) {\r\n super.updated(changedProperties);\r\n if (changedProperties.has('messages')) {\r\n this.scrollToBottom();\r\n // Save messages to sessionStorage whenever they change\r\n this.saveMessagesToStorage();\r\n }\r\n }\r\n\r\n private scrollToBottom() {\r\n // Use setTimeout to ensure Lit has finished rendering\r\n setTimeout(() => {\r\n // Find the last user message and scroll to it\r\n const userMessages = this.shadowRoot?.querySelectorAll('.message.user');\r\n if (userMessages && userMessages.length > 0) {\r\n const lastUserMessage = userMessages[userMessages.length - 1] as HTMLElement;\r\n lastUserMessage.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Normalize suggested questions - converts string arrays to SuggestedQuestion objects\r\n */\r\n private normalizeSuggestedQuestions(questions: any): SuggestedQuestion[] | undefined {\r\n if (!questions || !Array.isArray(questions) || questions.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // If already objects with question_text, return as-is\r\n if (typeof questions[0] === 'object' && questions[0].question_text) {\r\n return questions as SuggestedQuestion[];\r\n }\r\n\r\n // If strings, convert to SuggestedQuestion objects\r\n if (typeof questions[0] === 'string') {\r\n return questions.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private handleInput(e: Event) {\r\n this.input = (e.target as HTMLInputElement).value;\r\n }\r\n\r\n private async handleFAQClick(question: SuggestedQuestion) {\r\n if (this.isLoading) return;\r\n\r\n // Check if this is a suggested question with id and question_type\r\n if (question.id && question.question_type) {\r\n // Call the new API endpoint for suggested questions\r\n await this.handleSuggestedQuestionClick(question);\r\n } else {\r\n // Legacy behavior: Set the input and trigger submit\r\n this.input = question.question_text;\r\n\r\n // Create a synthetic submit event\r\n const submitEvent = new Event('submit', { cancelable: true });\r\n this.handleSubmit(submitEvent);\r\n }\r\n }\r\n\r\n private async handleSuggestedQuestionClick(question: SuggestedQuestion) {\r\n if (!question.id || !question.question_type) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: question.question_text,\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n // Call the new endpoint: /api/questions/{id}?question_type={question_type}\r\n // Extract base URL from initialQuestionsUrl (e.g., \"http://example.com:8080/api/questions/first-launch\" -> \"http://example.com:8080\")\r\n let baseUrl = '';\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n const urlObj = new URL(this.initialQuestionsUrl);\r\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\r\n } catch {\r\n // Fallback if URL parsing fails\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n } else {\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n\r\n const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract response text from the API response\r\n let responseText = 'No response from agent';\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object') {\r\n // The API returns { question: { answer_text: \"...\", ... }, related_questions: [...] }\r\n if (data.question && data.question.answer_text) {\r\n responseText = data.question.answer_text;\r\n }\r\n\r\n // Convert related_questions to SuggestedQuestion format\r\n if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {\r\n if (typeof data.related_questions[0] === 'object' && data.related_questions[0].question_text) {\r\n suggestedQuestions = data.related_questions.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n }\r\n }\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Suggested question API failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private async handleSubmit(e: Event) {\r\n e.preventDefault();\r\n\r\n if (!this.input.trim() || this.isLoading || !this.apiUrl) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: this.input.trim(),\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n const questionText = this.input.trim();\r\n this.input = '';\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n const response = await fetch(`${this.apiUrl}/ask`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n session_id: this.sessionId,\r\n question: questionText,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract the response text and suggested questions\r\n let responseText = 'No response from agent';\r\n let faqs: FAQ[] | undefined = undefined;\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object' && data.response && typeof data.response === 'string') {\r\n // Check if data.response contains stringified JSON\r\n const trimmedResponse = data.response.trim();\r\n if (trimmedResponse.startsWith('{') || trimmedResponse.startsWith('[')) {\r\n try {\r\n // First attempt: standard JSON.parse\r\n const innerData = JSON.parse(data.response);\r\n\r\n if (innerData && innerData.response && typeof innerData.response === 'string') {\r\n responseText = innerData.response;\r\n faqs = innerData.faq_used || innerData.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);\r\n } else {\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } catch (parseError) {\r\n // Backend has malformed JSON - extract response text\r\n const responsePattern = /\"response\"\\s*:\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"/s;\r\n const responseMatch = data.response.match(responsePattern);\r\n\r\n if (responseMatch) {\r\n responseText = responseMatch[1]\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\r/g, '\\r')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n } else {\r\n responseText = 'Error: Could not parse response';\r\n }\r\n\r\n // Extract FAQs array (support both faq_used and faqs_used)\r\n const faqsPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const faqsMatch = data.response.match(faqsPattern);\r\n\r\n if (faqsMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMatch[1]);\r\n } catch {\r\n // FAQs might span multiple lines\r\n const faqsMultiPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const faqsMultiMatch = data.response.match(faqsMultiPattern);\r\n if (faqsMultiMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMultiMatch[1]);\r\n } catch {\r\n faqs = undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract suggested questions array\r\n const suggestedPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const suggestedMatch = data.response.match(suggestedPattern);\r\n\r\n if (suggestedMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n const suggestedMultiPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const suggestedMultiMatch = data.response.match(suggestedMultiPattern);\r\n if (suggestedMultiMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n suggestedQuestions = undefined;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // Not JSON, direct text response\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } else if (typeof data === 'string') {\r\n responseText = data;\r\n } else if (data && typeof data === 'object') {\r\n // Fallback for other formats\r\n responseText = data.message || data.answer || 'Error: Unexpected response format';\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n faqs: faqs,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Backend connection failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private renderChatUI() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n return html`\r\n <!-- Header -->\r\n <div class=\"header\" style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <div class=\"header-content\">\r\n <div class=\"header-avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"Bot\" class=\"header-avatar-image\" />`\r\n : html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${this.primaryColor}\" stroke-width=\"2\" style=\"width: 1.5rem; height: 1.5rem;\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>`}\r\n </div>\r\n <h1 class=\"title\">${this.chatTitle}</h1>\r\n </div>\r\n </div>\r\n\r\n <!-- Messages Area -->\r\n <div class=\"messages-area\" style=\"--user-message-bg: ${this.userMessageBg}; --bot-message-bg: ${this.botMessageBg}; --primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover}; ${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}');` : ''}\">\r\n <div class=\"messages-container\">\r\n ${repeat(this.messages, (msg) => msg.id, (msg) => html`\r\n <div\r\n class=${classMap({\r\n message: true,\r\n user: msg.role === 'user',\r\n assistant: msg.role === 'assistant'\r\n })}\r\n >\r\n <div class=\"avatar\">\r\n ${msg.role === 'user'\r\n ? this.userAvatarUrl\r\n ? html`<img src=\"${this.userAvatarUrl}\" alt=\"User\" class=\"avatar-image\" />`\r\n : html`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" style=\"width: 20px; height: 20px;\">\r\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\"/>\r\n </svg>`\r\n : this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"message-text\">${unsafeHTML(this.formatMessageContent(msg.content))}</div>\r\n ${msg.role === 'assistant' && this.showRelatedFaqs && msg.faqs && msg.faqs.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Related FAQs:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.faqs.map(faq => html`\r\n <li class=\"faq-item-static\">\r\n ${faq.Question}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n ${msg.role === 'assistant' && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Cadangan Soalan:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.suggestedQuestions.map(question => html`\r\n <li class=\"faq-item\" @click=${() => this.handleFAQClick(question)}>\r\n ${question.question_text}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n `)}\r\n\r\n ${this.isLoading ? html`\r\n <div class=\"loading\">\r\n <div class=\"avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"spinner\"></div>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n\r\n <!-- Input Area -->\r\n <div class=\"input-area\" style=\"--primary-color: ${this.primaryColor}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <form class=\"input-form\" @submit=${this.handleSubmit}>\r\n <input\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"Taip mesej anda...\"\r\n .value=${this.input}\r\n @input=${this.handleInput}\r\n ?disabled=${this.isLoading}\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"send-button\"\r\n ?disabled=${this.isLoading || !this.input.trim()}\r\n aria-label=\"Send message\"\r\n >\r\n ${this.isLoading ? html`\r\n <div class=\"spinner\" style=\"border-color: #fff; border-top-color: transparent;\"></div>\r\n ` : html`\r\n <svg class=\"send-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n `}\r\n </button>\r\n </form>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div class=\"version-tag\">v${VERSION}</div>\r\n `;\r\n }\r\n\r\n render() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n if (this.mode === 'widget') {\r\n return html`\r\n <div class=\"widget-container\">\r\n <!-- Chat Window -->\r\n <div\r\n class=${classMap({ 'widget-window': true, 'open': this.isOpen })}\r\n style=\"--widget-width: ${this.widgetWidth}; --widget-height: ${this.widgetHeight};\"\r\n >\r\n ${this.renderChatUI()}\r\n </div>\r\n\r\n <!-- Toggle Button -->\r\n <button\r\n class=${classMap({\r\n 'widget-button': true,\r\n 'widget-button-no-bg': !this.isOpen && !!this.widgetIconUrl\r\n })}\r\n style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};\"\r\n @click=${this.toggleWidget}\r\n aria-label=${this.isOpen ? 'Close chat' : 'Open chat'}\r\n >\r\n ${this.isOpen ? html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n ` : this.widgetIconUrl ? html`\r\n <img src=\"${this.widgetIconUrl}\" alt=\"Chat\" class=\"widget-button-icon\" />\r\n ` : html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>\r\n `}\r\n </button>\r\n </div>\r\n `;\r\n }\r\n\r\n // Fullscreen mode\r\n return this.renderChatUI();\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'ai-chat': AIChat;\r\n }\r\n}\r\n"]}
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ var __decorateClass = (decorators, target, key, kind) => {
14
14
  if (kind && result) __defProp(target, key, result);
15
15
  return result;
16
16
  };
17
- var VERSION = "0.2.17";
17
+ var VERSION = "0.2.19";
18
18
  var AIChat = class extends LitElement {
19
19
  constructor() {
20
20
  super();
@@ -25,6 +25,7 @@ var AIChat = class extends LitElement {
25
25
  this.mode = "fullscreen";
26
26
  this.initialMessages = [];
27
27
  this.botAvatarUrl = "";
28
+ this.userAvatarUrl = "";
28
29
  this.widgetIconUrl = "";
29
30
  this.backgroundImageUrl = "";
30
31
  this.widgetWidth = "380px";
@@ -545,7 +546,9 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
545
546
  })}
546
547
  >
547
548
  <div class="avatar">
548
- ${msg.role === "user" ? "U" : this.botAvatarUrl ? html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
549
+ ${msg.role === "user" ? this.userAvatarUrl ? html`<img src="${this.userAvatarUrl}" alt="User" class="avatar-image" />` : html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" style="width: 20px; height: 20px;">
550
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
551
+ </svg>` : this.botAvatarUrl ? html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
549
552
  </div>
550
553
  <div class="message-content">
551
554
  <div class="message-text">${unsafeHTML(this.formatMessageContent(msg.content))}</div>
@@ -563,7 +566,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
563
566
  ` : ""}
564
567
  ${msg.role === "assistant" && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? html`
565
568
  <div class="faq-section">
566
- <p class="faq-title">Suggested Questions:</p>
569
+ <p class="faq-title">Cadangan Soalan:</p>
567
570
  <ul class="faq-list">
568
571
  ${msg.suggestedQuestions.map((question) => html`
569
572
  <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
@@ -708,6 +711,7 @@ AIChat.styles = css`
708
711
  justify-content: center;
709
712
  box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);
710
713
  transition: transform 0.2s, box-shadow 0.2s;
714
+ overflow: hidden;
711
715
  }
712
716
 
713
717
  .widget-button:hover {
@@ -733,10 +737,8 @@ AIChat.styles = css`
733
737
  }
734
738
 
735
739
  .widget-button-icon {
736
- width: 100%;
737
- height: 100%;
738
- max-width: 60px;
739
- max-height: 60px;
740
+ width: 60px;
741
+ height: 60px;
740
742
  object-fit: contain;
741
743
  border-radius: 50%;
742
744
  }
@@ -1427,6 +1429,7 @@ AIChat.properties = {
1427
1429
  mode: { type: String, reflect: true },
1428
1430
  initialMessages: { type: Array },
1429
1431
  botAvatarUrl: { type: String, attribute: "bot-avatar-url" },
1432
+ userAvatarUrl: { type: String, attribute: "user-avatar-url" },
1430
1433
  widgetIconUrl: { type: String, attribute: "widget-icon-url" },
1431
1434
  backgroundImageUrl: { type: String, attribute: "background-image-url" },
1432
1435
  widgetWidth: { type: String, attribute: "widget-width" },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ai-chat.ts"],"names":[],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AA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","file":"index.mjs","sourcesContent":["import { LitElement, html, css, PropertyValues } from 'lit';\r\nimport { customElement, state } from 'lit/decorators.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\r\n\r\nconst VERSION = '0.2.17';\r\n\r\nexport interface FAQ {\r\n No: string;\r\n Question: string;\r\n}\r\n\r\nexport interface SuggestedQuestion {\r\n id?: number;\r\n question_type?: string;\r\n question_text: string;\r\n category?: string;\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n faqs?: FAQ[];\r\n suggestedQuestions?: SuggestedQuestion[];\r\n}\r\n\r\n/**\r\n * AI Chat Web Component\r\n *\r\n * @fires message-sent - Fired when user sends a message\r\n * @fires response-received - Fired when AI responds\r\n * @fires error - Fired when an error occurs\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\">\r\n * </ai-chat>\r\n *\r\n * <!-- Widget mode with custom size -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * mode=\"widget\"\r\n * widget-width=\"400px\"\r\n * widget-height=\"650px\">\r\n * </ai-chat>\r\n *\r\n * <!-- Custom theme colors -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * primary-color=\"#10B981\"\r\n * primary-color-hover=\"#059669\"\r\n * user-message-bg=\"#D1FAE5\"\r\n * bot-message-bg=\"#F3F4F6\">\r\n * </ai-chat>\r\n * ```\r\n */\r\n@customElement('ai-chat')\r\nexport class AIChat extends LitElement {\r\n static styles = css`\r\n :host {\r\n font-family: system-ui, -apple-system, sans-serif;\r\n color: #09090b;\r\n }\r\n\r\n /* Fullscreen mode (default) */\r\n :host([mode=\"fullscreen\"]) {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n background: #ffffff;\r\n }\r\n\r\n :host([mode=\"fullscreen\"][theme=\"dark\"]) {\r\n background: #000;\r\n color: #fafafa;\r\n }\r\n\r\n /* Widget mode */\r\n :host([mode=\"widget\"]) {\r\n position: fixed;\r\n bottom: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n }\r\n\r\n .widget-container {\r\n position: relative;\r\n }\r\n\r\n .widget-button {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: #3681D3;\r\n border: none;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);\r\n transition: transform 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .widget-button:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 6px 20px rgba(65, 105, 225, 0.4);\r\n }\r\n\r\n .widget-button-no-bg {\r\n background: transparent;\r\n box-shadow: none;\r\n }\r\n\r\n .widget-button-no-bg:hover {\r\n background: transparent;\r\n box-shadow: none;\r\n transform: scale(1.1);\r\n }\r\n\r\n .widget-button svg {\r\n width: 28px;\r\n height: 28px;\r\n color: white;\r\n }\r\n\r\n .widget-button-icon {\r\n width: 100%;\r\n height: 100%;\r\n max-width: 60px;\r\n max-height: 60px;\r\n object-fit: contain;\r\n border-radius: 50%;\r\n }\r\n\r\n .widget-window {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 0;\r\n width: var(--widget-width, 380px);\r\n height: var(--widget-height, 600px);\r\n background: #fff;\r\n border-radius: 16px;\r\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n transition: opacity 0.2s, transform 0.2s;\r\n }\r\n\r\n .widget-window.open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n pointer-events: all;\r\n }\r\n\r\n :host([theme=\"dark\"]) .widget-window {\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n /* Tablet breakpoint */\r\n @media (max-width: 1024px) and (min-width: 769px) {\r\n .widget-window {\r\n width: var(--widget-width, 400px);\r\n height: var(--widget-height, 650px);\r\n }\r\n }\r\n\r\n /* Small tablet breakpoint */\r\n @media (max-width: 768px) and (min-width: 481px) {\r\n .widget-window {\r\n width: var(--widget-width, 360px);\r\n height: var(--widget-height, 550px);\r\n }\r\n }\r\n\r\n /* Mobile portrait */\r\n @media (max-width: 480px) and (orientation: portrait) {\r\n .widget-window {\r\n width: calc(100vw - 40px);\r\n height: 70vh;\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile landscape */\r\n @media (max-width: 900px) and (orientation: landscape) {\r\n .widget-window {\r\n width: var(--widget-width, 500px);\r\n height: calc(100vh - 100px);\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile responsive styles for all modes */\r\n @media (max-width: 768px) {\r\n .header {\r\n padding: 0.875rem 1rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.25rem;\r\n height: 2.25rem;\r\n }\r\n\r\n .title {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 1rem 0.75rem;\r\n }\r\n\r\n .message {\r\n gap: 0.75rem;\r\n }\r\n\r\n .avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n font-size: 0.75rem;\r\n }\r\n\r\n .message-content {\r\n max-width: 100%;\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 3rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.25rem;\r\n padding: 0 1rem;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.8125rem;\r\n padding: 0;\r\n }\r\n\r\n .input-area {\r\n padding: 0.75rem;\r\n }\r\n\r\n .input-form {\r\n gap: 0.5rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.75rem;\r\n padding: 0 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.75rem;\r\n height: 2.75rem;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-icon {\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n }\r\n }\r\n\r\n /* Extra small screens */\r\n @media (max-width: 480px) {\r\n .header {\r\n padding: 0.75rem 0.875rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n }\r\n\r\n .title {\r\n font-size: 1rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 0.75rem 0.5rem;\r\n }\r\n\r\n .message {\r\n gap: 0.5rem;\r\n }\r\n\r\n .avatar {\r\n width: 1.75rem;\r\n height: 1.75rem;\r\n font-size: 0.7rem;\r\n }\r\n\r\n .message-content {\r\n padding: 0.5rem 0.75rem;\r\n font-size: 0.875rem;\r\n border-radius: 0.75rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 2rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .input-area {\r\n padding: 0.625rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.5rem;\r\n padding: 0 0.75rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n }\r\n\r\n .version-tag {\r\n font-size: 0.7rem;\r\n padding: 0.375rem;\r\n }\r\n }\r\n\r\n .header {\r\n background:#3681D3;\r\n padding: 1rem 1.25rem;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n box-shadow: 0 2px 8px rgba(65, 105, 225, 0.2);\r\n }\r\n\r\n :host([theme=\"dark\"]) .header {\r\n background: #3681D3\r\n }\r\n\r\n .header-content {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n width: 100%;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 50%;\r\n background: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n }\r\n\r\n .header-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .title {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #fff;\r\n }\r\n\r\n .messages-area {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 1.5rem 1rem;\r\n position: relative;\r\n background: #ffffff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .messages-area {\r\n background: #000;\r\n }\r\n\r\n .messages-area::before {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background-image: var(--background-image-url);\r\n background-size: 200px auto 60%;\r\n background-position: center center;\r\n background-repeat: no-repeat;\r\n opacity: 0.03;\r\n pointer-events: none;\r\n z-index: 0;\r\n }\r\n\r\n .messages-container {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 1.5rem;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .empty-state {\r\n text-align: center;\r\n margin-top: 5rem;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1.5rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state {\r\n color: #a1a1aa;\r\n }\r\n\r\n .empty-state-avatar {\r\n width: 5rem;\r\n height: 5rem;\r\n border-radius: 50%;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar {\r\n background: #3f3f46;\r\n }\r\n\r\n .empty-state-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .empty-state-avatar svg {\r\n width: 3rem;\r\n height: 3rem;\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar svg {\r\n color: #6b7280;\r\n }\r\n\r\n .empty-state-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.5rem;\r\n }\r\n\r\n .empty-state-message {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #374151;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-message {\r\n color: #f3f4f6;\r\n }\r\n\r\n .empty-state-subtitle {\r\n font-size: 0.9375rem;\r\n margin: 0;\r\n color: #6b7280;\r\n max-width: 24rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-subtitle {\r\n color: #9ca3af;\r\n }\r\n\r\n .message {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .message.user {\r\n flex-direction: row-reverse;\r\n }\r\n\r\n .avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 9999px;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n font-weight: 600;\r\n font-size: 0.875rem;\r\n overflow: hidden;\r\n color: #6B7280;\r\n }\r\n\r\n :host([theme=\"dark\"]) .avatar {\r\n background: #3f3f46;\r\n color: #9ca3af;\r\n }\r\n\r\n .avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .message-content {\r\n max-width: 36rem;\r\n padding: 0.875rem 1.125rem;\r\n border-radius: 1.25rem;\r\n line-height: 1.6;\r\n overflow-wrap: break-word;\r\n word-wrap: break-word;\r\n min-width: 0;\r\n }\r\n\r\n .message.user .message-content {\r\n background: var(--user-message-bg, #D6E4FF);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 0.25rem 1.25rem;\r\n }\r\n\r\n .message.assistant .message-content {\r\n background: var(--bot-message-bg, #F5F5F5);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 1.25rem 0.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.user .message-content {\r\n background: #3D5A99;\r\n color: #fff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.assistant .message-content {\r\n background: #27272a;\r\n color: #fafafa;\r\n }\r\n\r\n .message-text {\r\n white-space: pre-wrap;\r\n margin: 0;\r\n word-wrap: break-word;\r\n overflow-wrap: break-word;\r\n word-break: break-word;\r\n }\r\n\r\n .message-text ul,\r\n .message-text ol {\r\n margin: 0.5rem 0;\r\n padding-left: 1.5rem;\r\n white-space: normal;\r\n list-style-position: outside;\r\n }\r\n\r\n .message-text li {\r\n margin: 0.25rem 0;\r\n white-space: normal;\r\n display: list-item;\r\n }\r\n\r\n .message-text ul {\r\n list-style-type: disc;\r\n }\r\n\r\n .message-text ol {\r\n list-style-type: decimal;\r\n counter-reset: list-counter;\r\n }\r\n\r\n .message-text ol li {\r\n display: list-item;\r\n list-style-type: decimal;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n border-top: 1px solid #d1d5db;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-section {\r\n border-top-color: #3f3f46;\r\n }\r\n\r\n .faq-title {\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n color: var(--primary-color, #3681D3);\r\n margin: 0 0 0.375rem 0;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-title {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n .faq-list {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.375rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.875rem;\r\n color: var(--primary-color, #3681D3);\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: pointer;\r\n transition: background-color 0.2s, color 0.2s;\r\n border: 1px solid transparent;\r\n }\r\n\r\n .faq-item:hover {\r\n background-color: #EEF2FF;\r\n color: var(--primary-color-hover, #3457C7);\r\n border-color: #C7D2FE;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item:hover {\r\n background-color: #1e293b;\r\n color: #93C5FD;\r\n border-color: #3f3f46;\r\n }\r\n\r\n /* FAQ static item styles - commented out for now */\r\n /* .faq-item-static {\r\n font-size: 0.875rem;\r\n color: #6B7280;\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: default;\r\n border: 1px solid transparent;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item-static {\r\n color: #9CA3AF;\r\n } */\r\n\r\n .loading {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .spinner {\r\n display: inline-block;\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border: 2px solid #e4e4e7;\r\n border-top-color: #71717a;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n .input-area {\r\n border-top: 1px solid #e5e7eb;\r\n background: #fff;\r\n padding: 1rem 1.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-area {\r\n border-top-color: #27272a;\r\n background: #18181b;\r\n }\r\n\r\n .input-form {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n gap: 0.75rem;\r\n align-items: center;\r\n }\r\n\r\n .input-field {\r\n flex: 1;\r\n height: 3rem;\r\n padding: 0 1rem;\r\n border: 1px solid #d1d5db;\r\n border-radius: 1.5rem;\r\n font-size: 0.9375rem;\r\n font-family: inherit;\r\n background: #fff;\r\n color: #374151;\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .input-field::placeholder {\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-field {\r\n border-color: #3f3f46;\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n .input-field:focus {\r\n outline: none;\r\n border-color: var(--primary-color, #3681D3);\r\n box-shadow: 0 0 0 3px rgba(65, 105, 225, 0.1);\r\n }\r\n\r\n .input-field:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-button {\r\n width: 3rem;\r\n height: 3rem;\r\n border-radius: 9999px;\r\n border: none;\r\n background: var(--primary-color, #3681D3);\r\n color: #fff;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s, transform 0.1s;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-button:hover:not(:disabled) {\r\n background: var(--primary-color-hover, #3457C7);\r\n transform: scale(1.05);\r\n }\r\n\r\n .send-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-icon {\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n }\r\n\r\n .version-tag {\r\n text-align: center;\r\n padding: 0.5rem;\r\n font-size: 0.75rem;\r\n color: #9ca3af;\r\n border-top: 1px solid #e5e7eb;\r\n }\r\n\r\n :host([theme=\"dark\"]) .version-tag {\r\n color: #6b7280;\r\n border-top-color: #27272a;\r\n }\r\n `;\r\n\r\n declare apiUrl: string;\r\n declare sessionId: string;\r\n declare chatTitle: string;\r\n declare theme: 'light' | 'dark';\r\n declare mode: 'fullscreen' | 'widget';\r\n declare initialMessages: Message[];\r\n declare botAvatarUrl: string;\r\n declare widgetIconUrl: string;\r\n declare backgroundImageUrl: string;\r\n declare widgetWidth: string;\r\n declare widgetHeight: string;\r\n declare primaryColor: string;\r\n declare primaryColorHover: string;\r\n declare userMessageBg: string;\r\n declare botMessageBg: string;\r\n declare welcomeMessage: string;\r\n declare welcomeSubtitle: string;\r\n declare initialQuestionsUrl: string;\r\n declare language: string;\r\n declare showRelatedFaqs: boolean;\r\n declare errorMessage: string;\r\n\r\n @state()\r\n private declare messages: Message[];\r\n\r\n @state()\r\n private declare input: string;\r\n\r\n @state()\r\n private declare isLoading: boolean;\r\n\r\n @state()\r\n private declare isOpen: boolean;\r\n\r\n\r\n static override properties = {\r\n apiUrl: { type: String, attribute: 'api-url' },\r\n sessionId: { type: String, attribute: 'session-id' },\r\n chatTitle: { type: String, attribute: 'title' },\r\n theme: { type: String },\r\n mode: { type: String, reflect: true },\r\n initialMessages: { type: Array },\r\n botAvatarUrl: { type: String, attribute: 'bot-avatar-url' },\r\n widgetIconUrl: { type: String, attribute: 'widget-icon-url' },\r\n backgroundImageUrl: { type: String, attribute: 'background-image-url' },\r\n widgetWidth: { type: String, attribute: 'widget-width' },\r\n widgetHeight: { type: String, attribute: 'widget-height' },\r\n primaryColor: { type: String, attribute: 'primary-color' },\r\n primaryColorHover: { type: String, attribute: 'primary-color-hover' },\r\n userMessageBg: { type: String, attribute: 'user-message-bg' },\r\n botMessageBg: { type: String, attribute: 'bot-message-bg' },\r\n welcomeMessage: { type: String, attribute: 'welcome-message' },\r\n welcomeSubtitle: { type: String, attribute: 'welcome-subtitle' },\r\n initialQuestionsUrl: { type: String, attribute: 'initial-questions-url' },\r\n language: { type: String, attribute: 'language' },\r\n showRelatedFaqs: { type: Boolean, attribute: 'show-related-faqs' },\r\n errorMessage: { type: String, attribute: 'error-message' },\r\n };\r\n\r\n constructor() {\r\n super();\r\n this.apiUrl = '';\r\n this.sessionId = 'default-session';\r\n this.chatTitle = 'My AI Agent';\r\n this.theme = 'light';\r\n this.mode = 'fullscreen';\r\n this.initialMessages = [];\r\n this.botAvatarUrl = '';\r\n this.widgetIconUrl = '';\r\n this.backgroundImageUrl = '';\r\n this.widgetWidth = '380px';\r\n this.widgetHeight = '600px';\r\n this.primaryColor = '#3681D3';\r\n this.primaryColorHover = '#3457C7';\r\n this.userMessageBg = '#D6E4FF';\r\n this.botMessageBg = '#F5F5F5';\r\n this.welcomeMessage = 'How can I help you today?';\r\n this.welcomeSubtitle = '';\r\n this.initialQuestionsUrl = '';\r\n this.language = 'en';\r\n this.showRelatedFaqs = false;\r\n this.errorMessage = 'Maaf, terdapat masalah semasa menghubungi pelayan. Sila cuba lagi.';\r\n this.messages = [];\r\n this.input = '';\r\n this.isLoading = false;\r\n this.isOpen = false;\r\n }\r\n\r\n private toggleWidget() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n /**\r\n * Clear all chat messages and reset to welcome message\r\n * @public\r\n */\r\n public clearChat(): void {\r\n this.clearMessagesFromStorage();\r\n\r\n if (this.welcomeMessage) {\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n }];\r\n } else {\r\n this.messages = [];\r\n }\r\n }\r\n\r\n private lightenColor(hex: string, percent: number = 15): string {\r\n // Remove # if present\r\n hex = hex.replace('#', '');\r\n\r\n // Convert to RGB\r\n const r = parseInt(hex.substring(0, 2), 16);\r\n const g = parseInt(hex.substring(2, 4), 16);\r\n const b = parseInt(hex.substring(4, 6), 16);\r\n\r\n // Lighten\r\n const newR = Math.min(255, Math.round(r + (255 - r) * (percent / 100)));\r\n const newG = Math.min(255, Math.round(g + (255 - g) * (percent / 100)));\r\n const newB = Math.min(255, Math.round(b + (255 - b) * (percent / 100)));\r\n\r\n // Convert back to hex\r\n return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;\r\n }\r\n\r\n private getStorageKey(): string {\r\n return `ai-chat-messages-${this.sessionId}`;\r\n }\r\n\r\n private saveMessagesToStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.setItem(storageKey, JSON.stringify(this.messages));\r\n // Store the current session ID to track session changes\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n } catch (error) {\r\n console.warn('Failed to save messages to sessionStorage:', error);\r\n }\r\n }\r\n\r\n private loadMessagesFromStorage(): Message[] | null {\r\n try {\r\n // Check if session has changed\r\n const lastSessionId = sessionStorage.getItem('ai-chat-last-session-id');\r\n\r\n if (lastSessionId && lastSessionId !== this.sessionId) {\r\n // Session has changed, clear the old session's messages\r\n const oldStorageKey = `ai-chat-messages-${lastSessionId}`;\r\n sessionStorage.removeItem(oldStorageKey);\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n return null; // Don't load any messages for new session\r\n }\r\n\r\n const storageKey = this.getStorageKey();\r\n const saved = sessionStorage.getItem(storageKey);\r\n if (saved) {\r\n return JSON.parse(saved) as Message[];\r\n }\r\n } catch (error) {\r\n console.warn('Failed to load messages from sessionStorage:', error);\r\n }\r\n return null;\r\n }\r\n\r\n private clearMessagesFromStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.removeItem(storageKey);\r\n } catch (error) {\r\n console.warn('Failed to clear messages from sessionStorage:', error);\r\n }\r\n }\r\n\r\n private formatMessageContent(content: string): string {\r\n // Escape HTML to prevent XSS\r\n const escapeHtml = (text: string) => {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n };\r\n\r\n // Add line break before numbered lists that come after any text (not already on new line)\r\n let processedContent = content.replace(/([^\\n])\\s*(\\d+\\.\\s+)/g, '$1\\n$2');\r\n\r\n // First, split inline numbered lists (1. 2. 3. pattern)\r\n processedContent = processedContent.replace(/(\\d+\\.\\s+[^0-9]+?)(?=\\s+\\d+\\.\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split inline bullet lists (- pattern)\r\n processedContent = processedContent.replace(/(-\\s+[^-]+?)(?=\\s+-\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split content by lines\r\n const lines = processedContent.split('\\n');\r\n let formattedContent = '';\r\n let inList = false;\r\n let listType: 'ul' | 'ol' | null = null;\r\n let orderedListCounter = 1; // Track the current numbered list counter\r\n\r\n // Helper function to check if next non-empty line is a list item\r\n const getNextListType = (startIndex: number): 'ul' | 'ol' | null => {\r\n for (let j = startIndex + 1; j < lines.length; j++) {\r\n const nextLine = lines[j].trim();\r\n if (nextLine === '') continue; // Skip blank lines\r\n if (nextLine.match(/^[-*•]\\s+/)) return 'ul';\r\n if (nextLine.match(/^\\d+\\.\\s+/)) return 'ol';\r\n return null; // Found non-list content\r\n }\r\n return null; // End of content\r\n };\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n\r\n // Check for unordered list (-, *, •)\r\n const unorderedMatch = trimmedLine.match(/^[-*•]\\s+(.+)$/);\r\n // Check for ordered list (1., 2., etc.)\r\n const orderedMatch = trimmedLine.match(/^(\\d+)\\.\\s+(.+)$/);\r\n\r\n if (unorderedMatch) {\r\n if (!inList || listType !== 'ul') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n formattedContent += '<ul>';\r\n inList = true;\r\n listType = 'ul';\r\n }\r\n formattedContent += `<li>${escapeHtml(unorderedMatch[1])}</li>`;\r\n } else if (orderedMatch) {\r\n const itemNumber = parseInt(orderedMatch[1], 10);\r\n const itemText = orderedMatch[2];\r\n\r\n if (!inList || listType !== 'ol') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n // Use the start attribute to continue numbering from where we left off\r\n // or reset to 1 if this is a new sequence starting with 1\r\n if (itemNumber === 1) {\r\n orderedListCounter = 1;\r\n formattedContent += '<ol>';\r\n } else {\r\n formattedContent += `<ol start=\"${orderedListCounter}\">`;\r\n }\r\n inList = true;\r\n listType = 'ol';\r\n }\r\n formattedContent += `<li value=\"${itemNumber}\">${escapeHtml(itemText)}</li>`;\r\n orderedListCounter = itemNumber + 1; // Track next number\r\n } else {\r\n // Not a list item\r\n if (trimmedLine === '') {\r\n // Blank line - check if next line continues the same list type\r\n const nextListType = getNextListType(i);\r\n if (inList && nextListType === listType) {\r\n // Keep list open and add spacing within the list\r\n formattedContent += '<li style=\"list-style: none; height: 0.5em;\"></li>';\r\n } else {\r\n // Close list if we're in one\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += '<br>';\r\n }\r\n } else {\r\n // Non-blank, non-list content\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += escapeHtml(line) + '\\n';\r\n }\r\n }\r\n }\r\n\r\n // Close any open list\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n }\r\n\r\n return formattedContent;\r\n }\r\n\r\n async connectedCallback() {\r\n super.connectedCallback();\r\n\r\n // Try to load messages from sessionStorage first\r\n const savedMessages = this.loadMessagesFromStorage();\r\n\r\n if (this.initialMessages && this.initialMessages.length > 0) {\r\n this.messages = [...this.initialMessages];\r\n } else if (savedMessages && savedMessages.length > 0) {\r\n // Restore saved messages from sessionStorage\r\n this.messages = savedMessages;\r\n } else {\r\n // Fetch initial suggested questions if URL is provided\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n let fetchFailed = false;\r\n\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n // Append language parameter to the URL\r\n let fetchUrl = this.initialQuestionsUrl;\r\n if (this.language) {\r\n const separator = fetchUrl.includes('?') ? '&' : '?';\r\n fetchUrl = `${fetchUrl}${separator}language=${this.language}`;\r\n }\r\n\r\n const response = await fetch(fetchUrl);\r\n if (response.ok) {\r\n const data = await response.json();\r\n\r\n // Support various response formats\r\n let questionsArray = data.questions || data.suggested_questions || data;\r\n\r\n // If array contains objects with question_text property, store full objects\r\n if (Array.isArray(questionsArray) && questionsArray.length > 0) {\r\n if (typeof questionsArray[0] === 'object' && questionsArray[0].question_text) {\r\n // Store full question objects with id and question_type\r\n suggestedQuestions = questionsArray.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n } else if (typeof questionsArray[0] === 'string') {\r\n // Legacy format: convert strings to objects\r\n suggestedQuestions = questionsArray.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n }\r\n } else {\r\n fetchFailed = true;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch initial questions:', error);\r\n fetchFailed = true;\r\n }\r\n }\r\n\r\n // If fetch failed, clear session storage\r\n if (fetchFailed) {\r\n this.clearMessagesFromStorage();\r\n }\r\n\r\n // Always show welcome message if available\r\n if (this.welcomeMessage) {\r\n // Add welcome message as initial assistant message\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n suggestedQuestions: suggestedQuestions,\r\n }];\r\n }\r\n }\r\n }\r\n\r\n updated(changedProperties: PropertyValues) {\r\n super.updated(changedProperties);\r\n if (changedProperties.has('messages')) {\r\n this.scrollToBottom();\r\n // Save messages to sessionStorage whenever they change\r\n this.saveMessagesToStorage();\r\n }\r\n }\r\n\r\n private scrollToBottom() {\r\n // Use setTimeout to ensure Lit has finished rendering\r\n setTimeout(() => {\r\n // Find the last user message and scroll to it\r\n const userMessages = this.shadowRoot?.querySelectorAll('.message.user');\r\n if (userMessages && userMessages.length > 0) {\r\n const lastUserMessage = userMessages[userMessages.length - 1] as HTMLElement;\r\n lastUserMessage.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Normalize suggested questions - converts string arrays to SuggestedQuestion objects\r\n */\r\n private normalizeSuggestedQuestions(questions: any): SuggestedQuestion[] | undefined {\r\n if (!questions || !Array.isArray(questions) || questions.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // If already objects with question_text, return as-is\r\n if (typeof questions[0] === 'object' && questions[0].question_text) {\r\n return questions as SuggestedQuestion[];\r\n }\r\n\r\n // If strings, convert to SuggestedQuestion objects\r\n if (typeof questions[0] === 'string') {\r\n return questions.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private handleInput(e: Event) {\r\n this.input = (e.target as HTMLInputElement).value;\r\n }\r\n\r\n private async handleFAQClick(question: SuggestedQuestion) {\r\n if (this.isLoading) return;\r\n\r\n // Check if this is a suggested question with id and question_type\r\n if (question.id && question.question_type) {\r\n // Call the new API endpoint for suggested questions\r\n await this.handleSuggestedQuestionClick(question);\r\n } else {\r\n // Legacy behavior: Set the input and trigger submit\r\n this.input = question.question_text;\r\n\r\n // Create a synthetic submit event\r\n const submitEvent = new Event('submit', { cancelable: true });\r\n this.handleSubmit(submitEvent);\r\n }\r\n }\r\n\r\n private async handleSuggestedQuestionClick(question: SuggestedQuestion) {\r\n if (!question.id || !question.question_type) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: question.question_text,\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n // Call the new endpoint: /api/questions/{id}?question_type={question_type}\r\n // Extract base URL from initialQuestionsUrl (e.g., \"http://example.com:8080/api/questions/first-launch\" -> \"http://example.com:8080\")\r\n let baseUrl = '';\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n const urlObj = new URL(this.initialQuestionsUrl);\r\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\r\n } catch {\r\n // Fallback if URL parsing fails\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n } else {\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n\r\n const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract response text from the API response\r\n let responseText = 'No response from agent';\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object') {\r\n // The API returns { question: { answer_text: \"...\", ... }, related_questions: [...] }\r\n if (data.question && data.question.answer_text) {\r\n responseText = data.question.answer_text;\r\n }\r\n\r\n // Convert related_questions to SuggestedQuestion format\r\n if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {\r\n if (typeof data.related_questions[0] === 'object' && data.related_questions[0].question_text) {\r\n suggestedQuestions = data.related_questions.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n }\r\n }\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Suggested question API failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private async handleSubmit(e: Event) {\r\n e.preventDefault();\r\n\r\n if (!this.input.trim() || this.isLoading || !this.apiUrl) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: this.input.trim(),\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n const questionText = this.input.trim();\r\n this.input = '';\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n const response = await fetch(`${this.apiUrl}/ask`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n session_id: this.sessionId,\r\n question: questionText,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract the response text and suggested questions\r\n let responseText = 'No response from agent';\r\n let faqs: FAQ[] | undefined = undefined;\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object' && data.response && typeof data.response === 'string') {\r\n // Check if data.response contains stringified JSON\r\n const trimmedResponse = data.response.trim();\r\n if (trimmedResponse.startsWith('{') || trimmedResponse.startsWith('[')) {\r\n try {\r\n // First attempt: standard JSON.parse\r\n const innerData = JSON.parse(data.response);\r\n\r\n if (innerData && innerData.response && typeof innerData.response === 'string') {\r\n responseText = innerData.response;\r\n faqs = innerData.faq_used || innerData.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);\r\n } else {\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } catch (parseError) {\r\n // Backend has malformed JSON - extract response text\r\n const responsePattern = /\"response\"\\s*:\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"/s;\r\n const responseMatch = data.response.match(responsePattern);\r\n\r\n if (responseMatch) {\r\n responseText = responseMatch[1]\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\r/g, '\\r')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n } else {\r\n responseText = 'Error: Could not parse response';\r\n }\r\n\r\n // Extract FAQs array (support both faq_used and faqs_used)\r\n const faqsPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const faqsMatch = data.response.match(faqsPattern);\r\n\r\n if (faqsMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMatch[1]);\r\n } catch {\r\n // FAQs might span multiple lines\r\n const faqsMultiPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const faqsMultiMatch = data.response.match(faqsMultiPattern);\r\n if (faqsMultiMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMultiMatch[1]);\r\n } catch {\r\n faqs = undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract suggested questions array\r\n const suggestedPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const suggestedMatch = data.response.match(suggestedPattern);\r\n\r\n if (suggestedMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n const suggestedMultiPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const suggestedMultiMatch = data.response.match(suggestedMultiPattern);\r\n if (suggestedMultiMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n suggestedQuestions = undefined;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // Not JSON, direct text response\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } else if (typeof data === 'string') {\r\n responseText = data;\r\n } else if (data && typeof data === 'object') {\r\n // Fallback for other formats\r\n responseText = data.message || data.answer || 'Error: Unexpected response format';\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n faqs: faqs,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Backend connection failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private renderChatUI() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n return html`\r\n <!-- Header -->\r\n <div class=\"header\" style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <div class=\"header-content\">\r\n <div class=\"header-avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"Bot\" class=\"header-avatar-image\" />`\r\n : html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${this.primaryColor}\" stroke-width=\"2\" style=\"width: 1.5rem; height: 1.5rem;\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>`}\r\n </div>\r\n <h1 class=\"title\">${this.chatTitle}</h1>\r\n </div>\r\n </div>\r\n\r\n <!-- Messages Area -->\r\n <div class=\"messages-area\" style=\"--user-message-bg: ${this.userMessageBg}; --bot-message-bg: ${this.botMessageBg}; --primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover}; ${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}');` : ''}\">\r\n <div class=\"messages-container\">\r\n ${repeat(this.messages, (msg) => msg.id, (msg) => html`\r\n <div\r\n class=${classMap({\r\n message: true,\r\n user: msg.role === 'user',\r\n assistant: msg.role === 'assistant'\r\n })}\r\n >\r\n <div class=\"avatar\">\r\n ${msg.role === 'user'\r\n ? 'U'\r\n : this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"message-text\">${unsafeHTML(this.formatMessageContent(msg.content))}</div>\r\n ${msg.role === 'assistant' && this.showRelatedFaqs && msg.faqs && msg.faqs.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Related FAQs:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.faqs.map(faq => html`\r\n <li class=\"faq-item-static\">\r\n ${faq.Question}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n ${msg.role === 'assistant' && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Suggested Questions:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.suggestedQuestions.map(question => html`\r\n <li class=\"faq-item\" @click=${() => this.handleFAQClick(question)}>\r\n ${question.question_text}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n `)}\r\n\r\n ${this.isLoading ? html`\r\n <div class=\"loading\">\r\n <div class=\"avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"spinner\"></div>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n\r\n <!-- Input Area -->\r\n <div class=\"input-area\" style=\"--primary-color: ${this.primaryColor}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <form class=\"input-form\" @submit=${this.handleSubmit}>\r\n <input\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"Taip mesej anda...\"\r\n .value=${this.input}\r\n @input=${this.handleInput}\r\n ?disabled=${this.isLoading}\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"send-button\"\r\n ?disabled=${this.isLoading || !this.input.trim()}\r\n aria-label=\"Send message\"\r\n >\r\n ${this.isLoading ? html`\r\n <div class=\"spinner\" style=\"border-color: #fff; border-top-color: transparent;\"></div>\r\n ` : html`\r\n <svg class=\"send-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n `}\r\n </button>\r\n </form>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div class=\"version-tag\">v${VERSION}</div>\r\n `;\r\n }\r\n\r\n render() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n if (this.mode === 'widget') {\r\n return html`\r\n <div class=\"widget-container\">\r\n <!-- Chat Window -->\r\n <div\r\n class=${classMap({ 'widget-window': true, 'open': this.isOpen })}\r\n style=\"--widget-width: ${this.widgetWidth}; --widget-height: ${this.widgetHeight};\"\r\n >\r\n ${this.renderChatUI()}\r\n </div>\r\n\r\n <!-- Toggle Button -->\r\n <button\r\n class=${classMap({\r\n 'widget-button': true,\r\n 'widget-button-no-bg': !this.isOpen && !!this.widgetIconUrl\r\n })}\r\n style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};\"\r\n @click=${this.toggleWidget}\r\n aria-label=${this.isOpen ? 'Close chat' : 'Open chat'}\r\n >\r\n ${this.isOpen ? html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n ` : this.widgetIconUrl ? html`\r\n <img src=\"${this.widgetIconUrl}\" alt=\"Chat\" class=\"widget-button-icon\" />\r\n ` : html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>\r\n `}\r\n </button>\r\n </div>\r\n `;\r\n }\r\n\r\n // Fullscreen mode\r\n return this.renderChatUI();\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'ai-chat': AIChat;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/components/ai-chat.ts"],"names":[],"mappings":"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A;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;AADL,MAAA,CAuxBK,UAAA,GAAa;AAAA,EAC3B,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,SAAA,EAAU;AAAA,EAC7C,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,YAAA,EAAa;AAAA,EACnD,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,OAAA,EAAQ;AAAA,EAC9C,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,EACtB,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,IAAA,EAAK;AAAA,EACpC,eAAA,EAAiB,EAAE,IAAA,EAAM,KAAA,EAAM;AAAA,EAC/B,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,gBAAA,EAAiB;AAAA,EAC1D,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,kBAAA,EAAoB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,sBAAA,EAAuB;AAAA,EACtE,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,cAAA,EAAe;AAAA,EACvD,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA,EAAgB;AAAA,EACzD,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA,EAAgB;AAAA,EACzD,iBAAA,EAAmB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,qBAAA,EAAsB;AAAA,EACpE,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC5D,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,gBAAA,EAAiB;AAAA,EAC1D,cAAA,EAAgB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,iBAAA,EAAkB;AAAA,EAC7D,eAAA,EAAiB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,kBAAA,EAAmB;AAAA,EAC/D,mBAAA,EAAqB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,uBAAA,EAAwB;AAAA,EACxE,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,UAAA,EAAW;AAAA,EAChD,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,WAAW,mBAAA,EAAoB;AAAA,EACjE,YAAA,EAAc,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW,eAAA;AAC3C,CAAA;AAnCgB,eAAA,CAAA;AAAA,EADf,KAAA;AAAM,CAAA,EA1wBI,MAAA,CA2wBK,SAAA,EAAA,UAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADf,KAAA;AAAM,CAAA,EA7wBI,MAAA,CA8wBK,SAAA,EAAA,OAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADf,KAAA;AAAM,CAAA,EAhxBI,MAAA,CAixBK,SAAA,EAAA,WAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADf,KAAA;AAAM,CAAA,EAnxBI,MAAA,CAoxBK,SAAA,EAAA,QAAA,EAAA,CAAA,CAAA;AApxBL,MAAA,GAAN,eAAA,CAAA;AAAA,EADN,cAAc,SAAS;AAAA,CAAA,EACX,MAAA,CAAA","file":"index.mjs","sourcesContent":["import { LitElement, html, css, PropertyValues } from 'lit';\r\nimport { customElement, state } from 'lit/decorators.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\r\n\r\nconst VERSION = '0.2.19';\r\n\r\nexport interface FAQ {\r\n No: string;\r\n Question: string;\r\n}\r\n\r\nexport interface SuggestedQuestion {\r\n id?: number;\r\n question_type?: string;\r\n question_text: string;\r\n category?: string;\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n faqs?: FAQ[];\r\n suggestedQuestions?: SuggestedQuestion[];\r\n}\r\n\r\n/**\r\n * AI Chat Web Component\r\n *\r\n * @fires message-sent - Fired when user sends a message\r\n * @fires response-received - Fired when AI responds\r\n * @fires error - Fired when an error occurs\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\">\r\n * </ai-chat>\r\n *\r\n * <!-- Widget mode with custom size -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * mode=\"widget\"\r\n * widget-width=\"400px\"\r\n * widget-height=\"650px\">\r\n * </ai-chat>\r\n *\r\n * <!-- Custom theme colors -->\r\n * <ai-chat\r\n * api-url=\"https://api.example.com\"\r\n * session-id=\"user-123\"\r\n * title=\"My AI Assistant\"\r\n * primary-color=\"#10B981\"\r\n * primary-color-hover=\"#059669\"\r\n * user-message-bg=\"#D1FAE5\"\r\n * bot-message-bg=\"#F3F4F6\">\r\n * </ai-chat>\r\n * ```\r\n */\r\n@customElement('ai-chat')\r\nexport class AIChat extends LitElement {\r\n static styles = css`\r\n :host {\r\n font-family: system-ui, -apple-system, sans-serif;\r\n color: #09090b;\r\n }\r\n\r\n /* Fullscreen mode (default) */\r\n :host([mode=\"fullscreen\"]) {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n background: #ffffff;\r\n }\r\n\r\n :host([mode=\"fullscreen\"][theme=\"dark\"]) {\r\n background: #000;\r\n color: #fafafa;\r\n }\r\n\r\n /* Widget mode */\r\n :host([mode=\"widget\"]) {\r\n position: fixed;\r\n bottom: 20px;\r\n right: 20px;\r\n z-index: 9999;\r\n }\r\n\r\n .widget-container {\r\n position: relative;\r\n }\r\n\r\n .widget-button {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: #3681D3;\r\n border: none;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);\r\n transition: transform 0.2s, box-shadow 0.2s;\r\n overflow: hidden;\r\n }\r\n\r\n .widget-button:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 6px 20px rgba(65, 105, 225, 0.4);\r\n }\r\n\r\n .widget-button-no-bg {\r\n background: transparent;\r\n box-shadow: none;\r\n }\r\n\r\n .widget-button-no-bg:hover {\r\n background: transparent;\r\n box-shadow: none;\r\n transform: scale(1.1);\r\n }\r\n\r\n .widget-button svg {\r\n width: 28px;\r\n height: 28px;\r\n color: white;\r\n }\r\n\r\n .widget-button-icon {\r\n width: 60px;\r\n height: 60px;\r\n object-fit: contain;\r\n border-radius: 50%;\r\n }\r\n\r\n .widget-window {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 0;\r\n width: var(--widget-width, 380px);\r\n height: var(--widget-height, 600px);\r\n background: #fff;\r\n border-radius: 16px;\r\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n transition: opacity 0.2s, transform 0.2s;\r\n }\r\n\r\n .widget-window.open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n pointer-events: all;\r\n }\r\n\r\n :host([theme=\"dark\"]) .widget-window {\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n /* Tablet breakpoint */\r\n @media (max-width: 1024px) and (min-width: 769px) {\r\n .widget-window {\r\n width: var(--widget-width, 400px);\r\n height: var(--widget-height, 650px);\r\n }\r\n }\r\n\r\n /* Small tablet breakpoint */\r\n @media (max-width: 768px) and (min-width: 481px) {\r\n .widget-window {\r\n width: var(--widget-width, 360px);\r\n height: var(--widget-height, 550px);\r\n }\r\n }\r\n\r\n /* Mobile portrait */\r\n @media (max-width: 480px) and (orientation: portrait) {\r\n .widget-window {\r\n width: calc(100vw - 40px);\r\n height: 70vh;\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile landscape */\r\n @media (max-width: 900px) and (orientation: landscape) {\r\n .widget-window {\r\n width: var(--widget-width, 500px);\r\n height: calc(100vh - 100px);\r\n bottom: 80px;\r\n right: 0;\r\n }\r\n\r\n .widget-button {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n\r\n .widget-button svg {\r\n width: 24px;\r\n height: 24px;\r\n }\r\n }\r\n\r\n /* Mobile responsive styles for all modes */\r\n @media (max-width: 768px) {\r\n .header {\r\n padding: 0.875rem 1rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.25rem;\r\n height: 2.25rem;\r\n }\r\n\r\n .title {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 1rem 0.75rem;\r\n }\r\n\r\n .message {\r\n gap: 0.75rem;\r\n }\r\n\r\n .avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n font-size: 0.75rem;\r\n }\r\n\r\n .message-content {\r\n max-width: 100%;\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 3rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.25rem;\r\n padding: 0 1rem;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.8125rem;\r\n padding: 0;\r\n }\r\n\r\n .input-area {\r\n padding: 0.75rem;\r\n }\r\n\r\n .input-form {\r\n gap: 0.5rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.75rem;\r\n padding: 0 0.875rem;\r\n font-size: 0.9375rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.75rem;\r\n height: 2.75rem;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-icon {\r\n width: 1.125rem;\r\n height: 1.125rem;\r\n }\r\n }\r\n\r\n /* Extra small screens */\r\n @media (max-width: 480px) {\r\n .header {\r\n padding: 0.75rem 0.875rem;\r\n }\r\n\r\n .header-avatar {\r\n width: 2rem;\r\n height: 2rem;\r\n }\r\n\r\n .title {\r\n font-size: 1rem;\r\n }\r\n\r\n .messages-area {\r\n padding: 0.75rem 0.5rem;\r\n }\r\n\r\n .message {\r\n gap: 0.5rem;\r\n }\r\n\r\n .avatar {\r\n width: 1.75rem;\r\n height: 1.75rem;\r\n font-size: 0.7rem;\r\n }\r\n\r\n .message-content {\r\n padding: 0.5rem 0.75rem;\r\n font-size: 0.875rem;\r\n border-radius: 0.75rem;\r\n }\r\n\r\n .empty-state {\r\n margin-top: 2rem;\r\n }\r\n\r\n .empty-state p {\r\n font-size: 1.125rem;\r\n }\r\n\r\n .input-area {\r\n padding: 0.625rem;\r\n }\r\n\r\n .input-field {\r\n height: 2.5rem;\r\n padding: 0 0.75rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .send-button {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n }\r\n\r\n .version-tag {\r\n font-size: 0.7rem;\r\n padding: 0.375rem;\r\n }\r\n }\r\n\r\n .header {\r\n background:#3681D3;\r\n padding: 1rem 1.25rem;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n box-shadow: 0 2px 8px rgba(65, 105, 225, 0.2);\r\n }\r\n\r\n :host([theme=\"dark\"]) .header {\r\n background: #3681D3\r\n }\r\n\r\n .header-content {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n width: 100%;\r\n }\r\n\r\n .header-avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 50%;\r\n background: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n }\r\n\r\n .header-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .title {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #fff;\r\n }\r\n\r\n .messages-area {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 1.5rem 1rem;\r\n position: relative;\r\n background: #ffffff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .messages-area {\r\n background: #000;\r\n }\r\n\r\n .messages-area::before {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background-image: var(--background-image-url);\r\n background-size: 200px auto 60%;\r\n background-position: center center;\r\n background-repeat: no-repeat;\r\n opacity: 0.03;\r\n pointer-events: none;\r\n z-index: 0;\r\n }\r\n\r\n .messages-container {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 1.5rem;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .empty-state {\r\n text-align: center;\r\n margin-top: 5rem;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1.5rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state {\r\n color: #a1a1aa;\r\n }\r\n\r\n .empty-state-avatar {\r\n width: 5rem;\r\n height: 5rem;\r\n border-radius: 50%;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n overflow: hidden;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar {\r\n background: #3f3f46;\r\n }\r\n\r\n .empty-state-avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .empty-state-avatar svg {\r\n width: 3rem;\r\n height: 3rem;\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-avatar svg {\r\n color: #6b7280;\r\n }\r\n\r\n .empty-state-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.5rem;\r\n }\r\n\r\n .empty-state-message {\r\n font-size: 1.25rem;\r\n font-weight: 600;\r\n margin: 0;\r\n color: #374151;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-message {\r\n color: #f3f4f6;\r\n }\r\n\r\n .empty-state-subtitle {\r\n font-size: 0.9375rem;\r\n margin: 0;\r\n color: #6b7280;\r\n max-width: 24rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .empty-state-subtitle {\r\n color: #9ca3af;\r\n }\r\n\r\n .message {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .message.user {\r\n flex-direction: row-reverse;\r\n }\r\n\r\n .avatar {\r\n width: 2.5rem;\r\n height: 2.5rem;\r\n border-radius: 9999px;\r\n background: #E5E7EB;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n font-weight: 600;\r\n font-size: 0.875rem;\r\n overflow: hidden;\r\n color: #6B7280;\r\n }\r\n\r\n :host([theme=\"dark\"]) .avatar {\r\n background: #3f3f46;\r\n color: #9ca3af;\r\n }\r\n\r\n .avatar-image {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n\r\n .message-content {\r\n max-width: 36rem;\r\n padding: 0.875rem 1.125rem;\r\n border-radius: 1.25rem;\r\n line-height: 1.6;\r\n overflow-wrap: break-word;\r\n word-wrap: break-word;\r\n min-width: 0;\r\n }\r\n\r\n .message.user .message-content {\r\n background: var(--user-message-bg, #D6E4FF);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 0.25rem 1.25rem;\r\n }\r\n\r\n .message.assistant .message-content {\r\n background: var(--bot-message-bg, #F5F5F5);\r\n color: #1a1a1a;\r\n border-radius: 1.25rem 1.25rem 1.25rem 0.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.user .message-content {\r\n background: #3D5A99;\r\n color: #fff;\r\n }\r\n\r\n :host([theme=\"dark\"]) .message.assistant .message-content {\r\n background: #27272a;\r\n color: #fafafa;\r\n }\r\n\r\n .message-text {\r\n white-space: pre-wrap;\r\n margin: 0;\r\n word-wrap: break-word;\r\n overflow-wrap: break-word;\r\n word-break: break-word;\r\n }\r\n\r\n .message-text ul,\r\n .message-text ol {\r\n margin: 0.5rem 0;\r\n padding-left: 1.5rem;\r\n white-space: normal;\r\n list-style-position: outside;\r\n }\r\n\r\n .message-text li {\r\n margin: 0.25rem 0;\r\n white-space: normal;\r\n display: list-item;\r\n }\r\n\r\n .message-text ul {\r\n list-style-type: disc;\r\n }\r\n\r\n .message-text ol {\r\n list-style-type: decimal;\r\n counter-reset: list-counter;\r\n }\r\n\r\n .message-text ol li {\r\n display: list-item;\r\n list-style-type: decimal;\r\n }\r\n\r\n .faq-section {\r\n margin-top: 0.75rem;\r\n padding-top: 0.75rem;\r\n border-top: 1px solid #d1d5db;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-section {\r\n border-top-color: #3f3f46;\r\n }\r\n\r\n .faq-title {\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n color: var(--primary-color, #3681D3);\r\n margin: 0 0 0.375rem 0;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-title {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n .faq-list {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.375rem;\r\n }\r\n\r\n .faq-item {\r\n font-size: 0.875rem;\r\n color: var(--primary-color, #3681D3);\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: pointer;\r\n transition: background-color 0.2s, color 0.2s;\r\n border: 1px solid transparent;\r\n }\r\n\r\n .faq-item:hover {\r\n background-color: #EEF2FF;\r\n color: var(--primary-color-hover, #3457C7);\r\n border-color: #C7D2FE;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item {\r\n color: var(--primary-color-light, #5B7FE8);\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item:hover {\r\n background-color: #1e293b;\r\n color: #93C5FD;\r\n border-color: #3f3f46;\r\n }\r\n\r\n /* FAQ static item styles - commented out for now */\r\n /* .faq-item-static {\r\n font-size: 0.875rem;\r\n color: #6B7280;\r\n padding: 0;\r\n border-radius: 0.5rem;\r\n cursor: default;\r\n border: 1px solid transparent;\r\n }\r\n\r\n :host([theme=\"dark\"]) .faq-item-static {\r\n color: #9CA3AF;\r\n } */\r\n\r\n .loading {\r\n display: flex;\r\n gap: 1rem;\r\n }\r\n\r\n .spinner {\r\n display: inline-block;\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n border: 2px solid #e4e4e7;\r\n border-top-color: #71717a;\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n }\r\n\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n .input-area {\r\n border-top: 1px solid #e5e7eb;\r\n background: #fff;\r\n padding: 1rem 1.25rem;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-area {\r\n border-top-color: #27272a;\r\n background: #18181b;\r\n }\r\n\r\n .input-form {\r\n max-width: 56rem;\r\n margin: 0 auto;\r\n display: flex;\r\n gap: 0.75rem;\r\n align-items: center;\r\n }\r\n\r\n .input-field {\r\n flex: 1;\r\n height: 3rem;\r\n padding: 0 1rem;\r\n border: 1px solid #d1d5db;\r\n border-radius: 1.5rem;\r\n font-size: 0.9375rem;\r\n font-family: inherit;\r\n background: #fff;\r\n color: #374151;\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n }\r\n\r\n .input-field::placeholder {\r\n color: #9ca3af;\r\n }\r\n\r\n :host([theme=\"dark\"]) .input-field {\r\n border-color: #3f3f46;\r\n background: #18181b;\r\n color: #fafafa;\r\n }\r\n\r\n .input-field:focus {\r\n outline: none;\r\n border-color: var(--primary-color, #3681D3);\r\n box-shadow: 0 0 0 3px rgba(65, 105, 225, 0.1);\r\n }\r\n\r\n .input-field:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-button {\r\n width: 3rem;\r\n height: 3rem;\r\n border-radius: 9999px;\r\n border: none;\r\n background: var(--primary-color, #3681D3);\r\n color: #fff;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: background 0.2s, transform 0.1s;\r\n flex-shrink: 0;\r\n }\r\n\r\n .send-button:hover:not(:disabled) {\r\n background: var(--primary-color-hover, #3457C7);\r\n transform: scale(1.05);\r\n }\r\n\r\n .send-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n\r\n .send-icon {\r\n width: 1.25rem;\r\n height: 1.25rem;\r\n }\r\n\r\n .version-tag {\r\n text-align: center;\r\n padding: 0.5rem;\r\n font-size: 0.75rem;\r\n color: #9ca3af;\r\n border-top: 1px solid #e5e7eb;\r\n }\r\n\r\n :host([theme=\"dark\"]) .version-tag {\r\n color: #6b7280;\r\n border-top-color: #27272a;\r\n }\r\n `;\r\n\r\n declare apiUrl: string;\r\n declare sessionId: string;\r\n declare chatTitle: string;\r\n declare theme: 'light' | 'dark';\r\n declare mode: 'fullscreen' | 'widget';\r\n declare initialMessages: Message[];\r\n declare botAvatarUrl: string;\r\n declare userAvatarUrl: string;\r\n declare widgetIconUrl: string;\r\n declare backgroundImageUrl: string;\r\n declare widgetWidth: string;\r\n declare widgetHeight: string;\r\n declare primaryColor: string;\r\n declare primaryColorHover: string;\r\n declare userMessageBg: string;\r\n declare botMessageBg: string;\r\n declare welcomeMessage: string;\r\n declare welcomeSubtitle: string;\r\n declare initialQuestionsUrl: string;\r\n declare language: string;\r\n declare showRelatedFaqs: boolean;\r\n declare errorMessage: string;\r\n\r\n @state()\r\n private declare messages: Message[];\r\n\r\n @state()\r\n private declare input: string;\r\n\r\n @state()\r\n private declare isLoading: boolean;\r\n\r\n @state()\r\n private declare isOpen: boolean;\r\n\r\n\r\n static override properties = {\r\n apiUrl: { type: String, attribute: 'api-url' },\r\n sessionId: { type: String, attribute: 'session-id' },\r\n chatTitle: { type: String, attribute: 'title' },\r\n theme: { type: String },\r\n mode: { type: String, reflect: true },\r\n initialMessages: { type: Array },\r\n botAvatarUrl: { type: String, attribute: 'bot-avatar-url' },\r\n userAvatarUrl: { type: String, attribute: 'user-avatar-url' },\r\n widgetIconUrl: { type: String, attribute: 'widget-icon-url' },\r\n backgroundImageUrl: { type: String, attribute: 'background-image-url' },\r\n widgetWidth: { type: String, attribute: 'widget-width' },\r\n widgetHeight: { type: String, attribute: 'widget-height' },\r\n primaryColor: { type: String, attribute: 'primary-color' },\r\n primaryColorHover: { type: String, attribute: 'primary-color-hover' },\r\n userMessageBg: { type: String, attribute: 'user-message-bg' },\r\n botMessageBg: { type: String, attribute: 'bot-message-bg' },\r\n welcomeMessage: { type: String, attribute: 'welcome-message' },\r\n welcomeSubtitle: { type: String, attribute: 'welcome-subtitle' },\r\n initialQuestionsUrl: { type: String, attribute: 'initial-questions-url' },\r\n language: { type: String, attribute: 'language' },\r\n showRelatedFaqs: { type: Boolean, attribute: 'show-related-faqs' },\r\n errorMessage: { type: String, attribute: 'error-message' },\r\n };\r\n\r\n constructor() {\r\n super();\r\n this.apiUrl = '';\r\n this.sessionId = 'default-session';\r\n this.chatTitle = 'My AI Agent';\r\n this.theme = 'light';\r\n this.mode = 'fullscreen';\r\n this.initialMessages = [];\r\n this.botAvatarUrl = '';\r\n this.userAvatarUrl = '';\r\n this.widgetIconUrl = '';\r\n this.backgroundImageUrl = '';\r\n this.widgetWidth = '380px';\r\n this.widgetHeight = '600px';\r\n this.primaryColor = '#3681D3';\r\n this.primaryColorHover = '#3457C7';\r\n this.userMessageBg = '#D6E4FF';\r\n this.botMessageBg = '#F5F5F5';\r\n this.welcomeMessage = 'How can I help you today?';\r\n this.welcomeSubtitle = '';\r\n this.initialQuestionsUrl = '';\r\n this.language = 'en';\r\n this.showRelatedFaqs = false;\r\n this.errorMessage = 'Maaf, terdapat masalah semasa menghubungi pelayan. Sila cuba lagi.';\r\n this.messages = [];\r\n this.input = '';\r\n this.isLoading = false;\r\n this.isOpen = false;\r\n }\r\n\r\n private toggleWidget() {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n /**\r\n * Clear all chat messages and reset to welcome message\r\n * @public\r\n */\r\n public clearChat(): void {\r\n this.clearMessagesFromStorage();\r\n\r\n if (this.welcomeMessage) {\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n }];\r\n } else {\r\n this.messages = [];\r\n }\r\n }\r\n\r\n private lightenColor(hex: string, percent: number = 15): string {\r\n // Remove # if present\r\n hex = hex.replace('#', '');\r\n\r\n // Convert to RGB\r\n const r = parseInt(hex.substring(0, 2), 16);\r\n const g = parseInt(hex.substring(2, 4), 16);\r\n const b = parseInt(hex.substring(4, 6), 16);\r\n\r\n // Lighten\r\n const newR = Math.min(255, Math.round(r + (255 - r) * (percent / 100)));\r\n const newG = Math.min(255, Math.round(g + (255 - g) * (percent / 100)));\r\n const newB = Math.min(255, Math.round(b + (255 - b) * (percent / 100)));\r\n\r\n // Convert back to hex\r\n return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;\r\n }\r\n\r\n private getStorageKey(): string {\r\n return `ai-chat-messages-${this.sessionId}`;\r\n }\r\n\r\n private saveMessagesToStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.setItem(storageKey, JSON.stringify(this.messages));\r\n // Store the current session ID to track session changes\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n } catch (error) {\r\n console.warn('Failed to save messages to sessionStorage:', error);\r\n }\r\n }\r\n\r\n private loadMessagesFromStorage(): Message[] | null {\r\n try {\r\n // Check if session has changed\r\n const lastSessionId = sessionStorage.getItem('ai-chat-last-session-id');\r\n\r\n if (lastSessionId && lastSessionId !== this.sessionId) {\r\n // Session has changed, clear the old session's messages\r\n const oldStorageKey = `ai-chat-messages-${lastSessionId}`;\r\n sessionStorage.removeItem(oldStorageKey);\r\n sessionStorage.setItem('ai-chat-last-session-id', this.sessionId);\r\n return null; // Don't load any messages for new session\r\n }\r\n\r\n const storageKey = this.getStorageKey();\r\n const saved = sessionStorage.getItem(storageKey);\r\n if (saved) {\r\n return JSON.parse(saved) as Message[];\r\n }\r\n } catch (error) {\r\n console.warn('Failed to load messages from sessionStorage:', error);\r\n }\r\n return null;\r\n }\r\n\r\n private clearMessagesFromStorage(): void {\r\n try {\r\n const storageKey = this.getStorageKey();\r\n sessionStorage.removeItem(storageKey);\r\n } catch (error) {\r\n console.warn('Failed to clear messages from sessionStorage:', error);\r\n }\r\n }\r\n\r\n private formatMessageContent(content: string): string {\r\n // Escape HTML to prevent XSS\r\n const escapeHtml = (text: string) => {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n };\r\n\r\n // Add line break before numbered lists that come after any text (not already on new line)\r\n let processedContent = content.replace(/([^\\n])\\s*(\\d+\\.\\s+)/g, '$1\\n$2');\r\n\r\n // First, split inline numbered lists (1. 2. 3. pattern)\r\n processedContent = processedContent.replace(/(\\d+\\.\\s+[^0-9]+?)(?=\\s+\\d+\\.\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split inline bullet lists (- pattern)\r\n processedContent = processedContent.replace(/(-\\s+[^-]+?)(?=\\s+-\\s+|\\s*$)/g, '$1\\n');\r\n\r\n // Split content by lines\r\n const lines = processedContent.split('\\n');\r\n let formattedContent = '';\r\n let inList = false;\r\n let listType: 'ul' | 'ol' | null = null;\r\n let orderedListCounter = 1; // Track the current numbered list counter\r\n\r\n // Helper function to check if next non-empty line is a list item\r\n const getNextListType = (startIndex: number): 'ul' | 'ol' | null => {\r\n for (let j = startIndex + 1; j < lines.length; j++) {\r\n const nextLine = lines[j].trim();\r\n if (nextLine === '') continue; // Skip blank lines\r\n if (nextLine.match(/^[-*•]\\s+/)) return 'ul';\r\n if (nextLine.match(/^\\d+\\.\\s+/)) return 'ol';\r\n return null; // Found non-list content\r\n }\r\n return null; // End of content\r\n };\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmedLine = line.trim();\r\n\r\n // Check for unordered list (-, *, •)\r\n const unorderedMatch = trimmedLine.match(/^[-*•]\\s+(.+)$/);\r\n // Check for ordered list (1., 2., etc.)\r\n const orderedMatch = trimmedLine.match(/^(\\d+)\\.\\s+(.+)$/);\r\n\r\n if (unorderedMatch) {\r\n if (!inList || listType !== 'ul') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n formattedContent += '<ul>';\r\n inList = true;\r\n listType = 'ul';\r\n }\r\n formattedContent += `<li>${escapeHtml(unorderedMatch[1])}</li>`;\r\n } else if (orderedMatch) {\r\n const itemNumber = parseInt(orderedMatch[1], 10);\r\n const itemText = orderedMatch[2];\r\n\r\n if (!inList || listType !== 'ol') {\r\n if (inList) formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n // Use the start attribute to continue numbering from where we left off\r\n // or reset to 1 if this is a new sequence starting with 1\r\n if (itemNumber === 1) {\r\n orderedListCounter = 1;\r\n formattedContent += '<ol>';\r\n } else {\r\n formattedContent += `<ol start=\"${orderedListCounter}\">`;\r\n }\r\n inList = true;\r\n listType = 'ol';\r\n }\r\n formattedContent += `<li value=\"${itemNumber}\">${escapeHtml(itemText)}</li>`;\r\n orderedListCounter = itemNumber + 1; // Track next number\r\n } else {\r\n // Not a list item\r\n if (trimmedLine === '') {\r\n // Blank line - check if next line continues the same list type\r\n const nextListType = getNextListType(i);\r\n if (inList && nextListType === listType) {\r\n // Keep list open and add spacing within the list\r\n formattedContent += '<li style=\"list-style: none; height: 0.5em;\"></li>';\r\n } else {\r\n // Close list if we're in one\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += '<br>';\r\n }\r\n } else {\r\n // Non-blank, non-list content\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n inList = false;\r\n listType = null;\r\n }\r\n formattedContent += escapeHtml(line) + '\\n';\r\n }\r\n }\r\n }\r\n\r\n // Close any open list\r\n if (inList) {\r\n formattedContent += listType === 'ol' ? '</ol>' : '</ul>';\r\n }\r\n\r\n return formattedContent;\r\n }\r\n\r\n async connectedCallback() {\r\n super.connectedCallback();\r\n\r\n // Try to load messages from sessionStorage first\r\n const savedMessages = this.loadMessagesFromStorage();\r\n\r\n if (this.initialMessages && this.initialMessages.length > 0) {\r\n this.messages = [...this.initialMessages];\r\n } else if (savedMessages && savedMessages.length > 0) {\r\n // Restore saved messages from sessionStorage\r\n this.messages = savedMessages;\r\n } else {\r\n // Fetch initial suggested questions if URL is provided\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n let fetchFailed = false;\r\n\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n // Append language parameter to the URL\r\n let fetchUrl = this.initialQuestionsUrl;\r\n if (this.language) {\r\n const separator = fetchUrl.includes('?') ? '&' : '?';\r\n fetchUrl = `${fetchUrl}${separator}language=${this.language}`;\r\n }\r\n\r\n const response = await fetch(fetchUrl);\r\n if (response.ok) {\r\n const data = await response.json();\r\n\r\n // Support various response formats\r\n let questionsArray = data.questions || data.suggested_questions || data;\r\n\r\n // If array contains objects with question_text property, store full objects\r\n if (Array.isArray(questionsArray) && questionsArray.length > 0) {\r\n if (typeof questionsArray[0] === 'object' && questionsArray[0].question_text) {\r\n // Store full question objects with id and question_type\r\n suggestedQuestions = questionsArray.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n } else if (typeof questionsArray[0] === 'string') {\r\n // Legacy format: convert strings to objects\r\n suggestedQuestions = questionsArray.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n }\r\n } else {\r\n fetchFailed = true;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch initial questions:', error);\r\n fetchFailed = true;\r\n }\r\n }\r\n\r\n // If fetch failed, clear session storage\r\n if (fetchFailed) {\r\n this.clearMessagesFromStorage();\r\n }\r\n\r\n // Always show welcome message if available\r\n if (this.welcomeMessage) {\r\n // Add welcome message as initial assistant message\r\n const welcomeText = this.welcomeSubtitle\r\n ? `${this.welcomeMessage}\\n\\n${this.welcomeSubtitle}`\r\n : this.welcomeMessage;\r\n\r\n this.messages = [{\r\n id: 'welcome-' + Date.now(),\r\n role: 'assistant',\r\n content: welcomeText,\r\n suggestedQuestions: suggestedQuestions,\r\n }];\r\n }\r\n }\r\n }\r\n\r\n updated(changedProperties: PropertyValues) {\r\n super.updated(changedProperties);\r\n if (changedProperties.has('messages')) {\r\n this.scrollToBottom();\r\n // Save messages to sessionStorage whenever they change\r\n this.saveMessagesToStorage();\r\n }\r\n }\r\n\r\n private scrollToBottom() {\r\n // Use setTimeout to ensure Lit has finished rendering\r\n setTimeout(() => {\r\n // Find the last user message and scroll to it\r\n const userMessages = this.shadowRoot?.querySelectorAll('.message.user');\r\n if (userMessages && userMessages.length > 0) {\r\n const lastUserMessage = userMessages[userMessages.length - 1] as HTMLElement;\r\n lastUserMessage.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Normalize suggested questions - converts string arrays to SuggestedQuestion objects\r\n */\r\n private normalizeSuggestedQuestions(questions: any): SuggestedQuestion[] | undefined {\r\n if (!questions || !Array.isArray(questions) || questions.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // If already objects with question_text, return as-is\r\n if (typeof questions[0] === 'object' && questions[0].question_text) {\r\n return questions as SuggestedQuestion[];\r\n }\r\n\r\n // If strings, convert to SuggestedQuestion objects\r\n if (typeof questions[0] === 'string') {\r\n return questions.map((q: string) => ({\r\n question_text: q\r\n }));\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private handleInput(e: Event) {\r\n this.input = (e.target as HTMLInputElement).value;\r\n }\r\n\r\n private async handleFAQClick(question: SuggestedQuestion) {\r\n if (this.isLoading) return;\r\n\r\n // Check if this is a suggested question with id and question_type\r\n if (question.id && question.question_type) {\r\n // Call the new API endpoint for suggested questions\r\n await this.handleSuggestedQuestionClick(question);\r\n } else {\r\n // Legacy behavior: Set the input and trigger submit\r\n this.input = question.question_text;\r\n\r\n // Create a synthetic submit event\r\n const submitEvent = new Event('submit', { cancelable: true });\r\n this.handleSubmit(submitEvent);\r\n }\r\n }\r\n\r\n private async handleSuggestedQuestionClick(question: SuggestedQuestion) {\r\n if (!question.id || !question.question_type) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: question.question_text,\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n // Call the new endpoint: /api/questions/{id}?question_type={question_type}\r\n // Extract base URL from initialQuestionsUrl (e.g., \"http://example.com:8080/api/questions/first-launch\" -> \"http://example.com:8080\")\r\n let baseUrl = '';\r\n if (this.initialQuestionsUrl) {\r\n try {\r\n const urlObj = new URL(this.initialQuestionsUrl);\r\n baseUrl = `${urlObj.protocol}//${urlObj.host}`;\r\n } catch {\r\n // Fallback if URL parsing fails\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n } else {\r\n baseUrl = 'http://43.217.183.120:8080';\r\n }\r\n\r\n const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract response text from the API response\r\n let responseText = 'No response from agent';\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object') {\r\n // The API returns { question: { answer_text: \"...\", ... }, related_questions: [...] }\r\n if (data.question && data.question.answer_text) {\r\n responseText = data.question.answer_text;\r\n }\r\n\r\n // Convert related_questions to SuggestedQuestion format\r\n if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {\r\n if (typeof data.related_questions[0] === 'object' && data.related_questions[0].question_text) {\r\n suggestedQuestions = data.related_questions.map((q: any) => ({\r\n id: q.id,\r\n question_type: q.question_type,\r\n question_text: q.question_text,\r\n category: q.category\r\n }));\r\n }\r\n }\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Suggested question API failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private async handleSubmit(e: Event) {\r\n e.preventDefault();\r\n\r\n if (!this.input.trim() || this.isLoading || !this.apiUrl) return;\r\n\r\n const userMessage: Message = {\r\n id: Date.now().toString(),\r\n role: 'user',\r\n content: this.input.trim(),\r\n };\r\n\r\n this.messages = [...this.messages, userMessage];\r\n const questionText = this.input.trim();\r\n this.input = '';\r\n this.isLoading = true;\r\n\r\n // Dispatch message-sent event\r\n this.dispatchEvent(new CustomEvent('message-sent', {\r\n detail: userMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n\r\n try {\r\n const response = await fetch(`${this.apiUrl}/ask`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n session_id: this.sessionId,\r\n question: questionText,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n throw new Error(`Backend error: ${response.status} ${errorText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Extract the response text and suggested questions\r\n let responseText = 'No response from agent';\r\n let faqs: FAQ[] | undefined = undefined;\r\n let suggestedQuestions: SuggestedQuestion[] | undefined = undefined;\r\n\r\n if (data && typeof data === 'object' && data.response && typeof data.response === 'string') {\r\n // Check if data.response contains stringified JSON\r\n const trimmedResponse = data.response.trim();\r\n if (trimmedResponse.startsWith('{') || trimmedResponse.startsWith('[')) {\r\n try {\r\n // First attempt: standard JSON.parse\r\n const innerData = JSON.parse(data.response);\r\n\r\n if (innerData && innerData.response && typeof innerData.response === 'string') {\r\n responseText = innerData.response;\r\n faqs = innerData.faq_used || innerData.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);\r\n } else {\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } catch (parseError) {\r\n // Backend has malformed JSON - extract response text\r\n const responsePattern = /\"response\"\\s*:\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"/s;\r\n const responseMatch = data.response.match(responsePattern);\r\n\r\n if (responseMatch) {\r\n responseText = responseMatch[1]\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\r/g, '\\r')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n } else {\r\n responseText = 'Error: Could not parse response';\r\n }\r\n\r\n // Extract FAQs array (support both faq_used and faqs_used)\r\n const faqsPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const faqsMatch = data.response.match(faqsPattern);\r\n\r\n if (faqsMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMatch[1]);\r\n } catch {\r\n // FAQs might span multiple lines\r\n const faqsMultiPattern = /\"(?:faq_used|faqs_used)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const faqsMultiMatch = data.response.match(faqsMultiPattern);\r\n if (faqsMultiMatch) {\r\n try {\r\n faqs = JSON.parse(faqsMultiMatch[1]);\r\n } catch {\r\n faqs = undefined;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Extract suggested questions array\r\n const suggestedPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[^\\]]*\\])/s;\r\n const suggestedMatch = data.response.match(suggestedPattern);\r\n\r\n if (suggestedMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n const suggestedMultiPattern = /\"(?:suggested_follow_ups|suggested_questions)\"\\s*:\\s*(\\[[\\s\\S]*?\\n\\s*\\])/;\r\n const suggestedMultiMatch = data.response.match(suggestedMultiPattern);\r\n if (suggestedMultiMatch) {\r\n try {\r\n const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);\r\n suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);\r\n } catch {\r\n suggestedQuestions = undefined;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // Not JSON, direct text response\r\n responseText = data.response;\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n } else if (typeof data === 'string') {\r\n responseText = data;\r\n } else if (data && typeof data === 'object') {\r\n // Fallback for other formats\r\n responseText = data.message || data.answer || 'Error: Unexpected response format';\r\n faqs = data.faq_used || data.faqs_used || undefined;\r\n suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);\r\n }\r\n\r\n const assistantMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: responseText,\r\n faqs: faqs,\r\n suggestedQuestions: suggestedQuestions,\r\n };\r\n\r\n this.messages = [...this.messages, assistantMessage];\r\n\r\n // Dispatch response-received event\r\n this.dispatchEvent(new CustomEvent('response-received', {\r\n detail: assistantMessage,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } catch (err) {\r\n console.error('Backend connection failed:', err);\r\n\r\n const errorMessage: Message = {\r\n id: (Date.now() + 1).toString(),\r\n role: 'assistant',\r\n content: this.errorMessage,\r\n };\r\n\r\n this.messages = [...this.messages, errorMessage];\r\n\r\n // Dispatch error event\r\n this.dispatchEvent(new CustomEvent('error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n } finally {\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n private renderChatUI() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n return html`\r\n <!-- Header -->\r\n <div class=\"header\" style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <div class=\"header-content\">\r\n <div class=\"header-avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"Bot\" class=\"header-avatar-image\" />`\r\n : html`<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${this.primaryColor}\" stroke-width=\"2\" style=\"width: 1.5rem; height: 1.5rem;\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>`}\r\n </div>\r\n <h1 class=\"title\">${this.chatTitle}</h1>\r\n </div>\r\n </div>\r\n\r\n <!-- Messages Area -->\r\n <div class=\"messages-area\" style=\"--user-message-bg: ${this.userMessageBg}; --bot-message-bg: ${this.botMessageBg}; --primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover}; ${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}');` : ''}\">\r\n <div class=\"messages-container\">\r\n ${repeat(this.messages, (msg) => msg.id, (msg) => html`\r\n <div\r\n class=${classMap({\r\n message: true,\r\n user: msg.role === 'user',\r\n assistant: msg.role === 'assistant'\r\n })}\r\n >\r\n <div class=\"avatar\">\r\n ${msg.role === 'user'\r\n ? this.userAvatarUrl\r\n ? html`<img src=\"${this.userAvatarUrl}\" alt=\"User\" class=\"avatar-image\" />`\r\n : html`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" style=\"width: 20px; height: 20px;\">\r\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\"/>\r\n </svg>`\r\n : this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"message-text\">${unsafeHTML(this.formatMessageContent(msg.content))}</div>\r\n ${msg.role === 'assistant' && this.showRelatedFaqs && msg.faqs && msg.faqs.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Related FAQs:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.faqs.map(faq => html`\r\n <li class=\"faq-item-static\">\r\n ${faq.Question}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n ${msg.role === 'assistant' && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? html`\r\n <div class=\"faq-section\">\r\n <p class=\"faq-title\">Cadangan Soalan:</p>\r\n <ul class=\"faq-list\">\r\n ${msg.suggestedQuestions.map(question => html`\r\n <li class=\"faq-item\" @click=${() => this.handleFAQClick(question)}>\r\n ${question.question_text}\r\n </li>\r\n `)}\r\n </ul>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n `)}\r\n\r\n ${this.isLoading ? html`\r\n <div class=\"loading\">\r\n <div class=\"avatar\">\r\n ${this.botAvatarUrl\r\n ? html`<img src=\"${this.botAvatarUrl}\" alt=\"AI\" class=\"avatar-image\" />`\r\n : 'AI'}\r\n </div>\r\n <div class=\"message-content\">\r\n <div class=\"spinner\"></div>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n </div>\r\n\r\n <!-- Input Area -->\r\n <div class=\"input-area\" style=\"--primary-color: ${this.primaryColor}; --primary-color-hover: ${this.primaryColorHover};\">\r\n <form class=\"input-form\" @submit=${this.handleSubmit}>\r\n <input\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"Taip mesej anda...\"\r\n .value=${this.input}\r\n @input=${this.handleInput}\r\n ?disabled=${this.isLoading}\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"send-button\"\r\n ?disabled=${this.isLoading || !this.input.trim()}\r\n aria-label=\"Send message\"\r\n >\r\n ${this.isLoading ? html`\r\n <div class=\"spinner\" style=\"border-color: #fff; border-top-color: transparent;\"></div>\r\n ` : html`\r\n <svg class=\"send-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n `}\r\n </button>\r\n </form>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div class=\"version-tag\">v${VERSION}</div>\r\n `;\r\n }\r\n\r\n render() {\r\n const primaryColorLight = this.lightenColor(this.primaryColor, 15);\r\n\r\n if (this.mode === 'widget') {\r\n return html`\r\n <div class=\"widget-container\">\r\n <!-- Chat Window -->\r\n <div\r\n class=${classMap({ 'widget-window': true, 'open': this.isOpen })}\r\n style=\"--widget-width: ${this.widgetWidth}; --widget-height: ${this.widgetHeight};\"\r\n >\r\n ${this.renderChatUI()}\r\n </div>\r\n\r\n <!-- Toggle Button -->\r\n <button\r\n class=${classMap({\r\n 'widget-button': true,\r\n 'widget-button-no-bg': !this.isOpen && !!this.widgetIconUrl\r\n })}\r\n style=\"--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};\"\r\n @click=${this.toggleWidget}\r\n aria-label=${this.isOpen ? 'Close chat' : 'Open chat'}\r\n >\r\n ${this.isOpen ? html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n ` : this.widgetIconUrl ? html`\r\n <img src=\"${this.widgetIconUrl}\" alt=\"Chat\" class=\"widget-button-icon\" />\r\n ` : html`\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>\r\n </svg>\r\n `}\r\n </button>\r\n </div>\r\n `;\r\n }\r\n\r\n // Fullscreen mode\r\n return this.renderChatUI();\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'ai-chat': AIChat;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a.izzuddin/ai-chat",
3
- "version": "0.2.17",
3
+ "version": "0.2.19",
4
4
  "description": "A framework-agnostic AI chat web component. Works with React, Vue, Svelte, Angular, and vanilla JavaScript.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",