ocwi-core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,722 @@
1
+ var OCWI=function(){"use strict";function t(t="m"){if("undefined"!=typeof crypto&&"randomUUID"in crypto)return`${t}_${crypto.randomUUID()}`;const e=Math.random().toString(36).slice(2);return`${t}_${Date.now().toString(36)}${e}`}function e(t){if(null===t||"object"!=typeof t)return t;if(Array.isArray(t))return t.map(t=>e(t));const i={};for(const n of Object.keys(t))i[n]=e(t[n]);return i}function i(t,n,s=[]){const o=Array.isArray(t)?[]:{},r=s.length>=2&&"i18n"===s[s.length-2]&&"dictionary"===s[s.length-1];if(Array.isArray(t)){const i=Array.isArray(n)?n:[];return e(i.length?i:t)}const a=n??{},c=r?Array.from(new Set([...Object.keys(t),...Object.keys(a)])):Object.keys(t);for(const n of c){const r=t[n],c=a[n];o[n]=null===r||"object"!=typeof r||Array.isArray(r)?e(void 0!==c?c:r):i(r,c??{},[...s,n])}return o}const n={en:{send:"Send",stop:"Stop",copy:"Copy",edit:"Edit",refresh:"Refresh",confirm:"Confirm",cancel:"Cancel",generationStopped:"Generation stopped",loading:"Loading…",reconnect:"Try reconnecting",reconnectFailed:"Connection failed",errorDanaUnavailable:"The AI service is temporarily unavailable.",errorDanaTimeout:"The request timed out. Please try again.",errorProxyError:"A connection error occurred.",errorNetwork:"Network error. Please check your connection.",errorOffline:"You are offline. Please check your internet connection.",errorUnknown:"An unexpected error occurred.",errorDanaLlmUnavailable:"The AI model is temporarily unreachable.",errorDanaLlmAuth:"AI service authentication failed. Please contact support.",errorDanaLlmTimeout:"The AI model took too long to respond.",errorDanaInternal:"An internal server error occurred. Please try again.",showDetails:"Show technical details",hideDetails:"Hide technical details",statusDanaOnline:"Dana: Online",statusDanaConnecting:"Dana: Connecting…",statusDanaOffline:"Dana: Offline",statusDanaMock:"Dana: Demo mode",statusLumaOnline:"Luma: Online",statusLumaConnecting:"Luma: Connecting…",statusLumaOffline:"Luma: Offline",statusLumaError:"Luma: Server error",statusLumaNotFound:"Luma: Configuration not found",statusLumaUnknown:"Luma: Unknown"},cs:{send:"Odeslat",stop:"Zastavit",copy:"Kopírovat",edit:"Upravit",refresh:"Obnovit",confirm:"Potvrdit",cancel:"Zrušit",generationStopped:"Generování zastaveno",loading:"Načítání…",reconnect:"Zkusit znovu",reconnectFailed:"Připojení selhalo",errorDanaUnavailable:"Služba AI je dočasně nedostupná.",errorDanaTimeout:"Požadavek vypršel. Zkuste to znovu.",errorProxyError:"Chyba připojení.",errorNetwork:"Chyba sítě. Zkontrolujte připojení.",errorOffline:"Jste offline. Zkontrolujte připojení k internetu.",errorUnknown:"Nastala neočekávaná chyba.",errorDanaLlmUnavailable:"AI model je dočasně nedostupný.",errorDanaLlmAuth:"Chyba ověření AI služby. Kontaktujte podporu.",errorDanaLlmTimeout:"AI model příliš dlouho neodpovídaný.",errorDanaInternal:"Interní chyba serveru. Zkuste to znovu.",showDetails:"Zobrazit technické detaily",hideDetails:"Skrýt technické detaily",statusDanaOnline:"Dana: Online",statusDanaConnecting:"Dana: Připojování…",statusDanaOffline:"Dana: Offline",statusDanaMock:"Dana: Demo režim",statusLumaOnline:"Luma: Online",statusLumaConnecting:"Luma: Připojování…",statusLumaOffline:"Luma: Offline",statusLumaError:"Luma: Chyba serveru",statusLumaNotFound:"Luma: Konfigurace nenalezena",statusLumaUnknown:"Luma: Neznámý stav"},de:{send:"Senden",stop:"Stopp",copy:"Kopieren",edit:"Bearbeiten",refresh:"Neu generieren",confirm:"Bestätigen",cancel:"Abbrechen",generationStopped:"Generierung gestoppt",loading:"Laden…",reconnect:"Erneut versuchen",reconnectFailed:"Verbindung fehlgeschlagen",errorDanaUnavailable:"Der KI-Dienst ist vorübergehend nicht verfügbar.",errorDanaTimeout:"Anfrage abgelaufen. Bitte erneut versuchen.",errorProxyError:"Ein Verbindungsfehler ist aufgetreten.",errorNetwork:"Netzwerkfehler. Bitte Verbindung prüfen.",errorOffline:"Sie sind offline. Bitte Internetverbindung prüfen.",errorUnknown:"Ein unerwarteter Fehler ist aufgetreten.",errorDanaLlmUnavailable:"Das KI-Modell ist vorübergehend nicht erreichbar.",errorDanaLlmAuth:"KI-Dienst-Authentifizierung fehlgeschlagen. Support kontaktieren.",errorDanaLlmTimeout:"Das KI-Modell hat zu lange nicht geantwortet.",errorDanaInternal:"Interner Serverfehler. Bitte erneut versuchen.",showDetails:"Details anzeigen",hideDetails:"Details ausblenden",statusDanaOnline:"Dana: Online",statusDanaConnecting:"Dana: Verbinden…",statusDanaOffline:"Dana: Offline",statusDanaMock:"Dana: Demo-Modus",statusLumaOnline:"Luma: Online",statusLumaConnecting:"Luma: Verbinden…",statusLumaOffline:"Luma: Offline",statusLumaError:"Luma: Serverfehler",statusLumaNotFound:"Luma: Konfiguration nicht gefunden",statusLumaUnknown:"Luma: Unbekannt"}},s={locale:void 0,api:{danaUrl:void 0,lumaUrl:void 0,timeoutMs:3e4},i18n:{lang:"en",dictionary:n},theme:{primary:"#2563eb",ocwiZIndex:"2147480000",ocwiWidth:"320px",ocwiHeight:"480px",ocwiRadius:"12px",ocwiSpacing:"8px",ocwiBg:"#ffffff",ocwiInputPlaceholder:"#6b7280",ocwiBorder:"#e5e7eb",ocwiHeaderBg:"#2b6cb0",ocwiHeaderText:"#ffffff",ocwiBubbleUserBg:"var(--ocwi-primary, #2563eb)",ocwiBubbleUserText:"#ffffff",ocwiBubbleAssistantBg:"#f3f4f6",ocwiBubbleAssistantText:"#1f2937",ocwiInputBg:"#ffffff",ocwiInputText:"#111111",ocwiInputRows:1,ocwiSendBg:"#2563eb",ocwiSendText:"#ffffff",ocwiBubbleMaxWidth:"92%",ocwiFabBg:"var(--ocwi-primary, #2563eb)",ocwiFabText:"#ffffff"},ui:{name:"Dana",avatarUrl:"https://i.pravatar.cc/200?img=5",placeholder:"Type a message...",introductionMessage:"How can I help you?",errorMessage:void 0,sendLabel:void 0,keybindForSend:"Enter",position:"bottom-right",initialState:"expanded",fontSize:"auto"},features:{minimize:!0,close:!0,serverStatus:!0,languageSelector:!0,avatarDisplay:!0,nameDisplay:!0,messageRefresh:!0,messageCopy:!0,messageEdit:!0,messageDelete:!0,messageCache:!1,sendButton:!0,stopButton:!0,watermark:!0,placeholder:!0,authentication:!0},watermark:{imageUrl:"https://www.amca.cz/Amca/media/system/img/header-logo.png",repeatMode:"none",position:"top-right",scale:1}};function o(t,n){if(!n)return t;const s=function(t){return t?e(t):t}(n)||{};return i(t,s)}async function r(t,e=6e3){if(!t)return{config:{},status:"ok"};const i=new AbortController,n=setTimeout(()=>i.abort(),e);try{const e=await fetch(t,{signal:i.signal});if(e.ok){try{const t=await e.json();if(t&&"object"==typeof t)return{config:t,status:"ok"}}catch{}return{config:{},status:"ok"}}return 404===e.status?(console.warn("[OCWI] Luma config not found (404). Check lumaUrl."),{config:{},status:"not_found"}):e.status>=500?(console.warn(`[OCWI] Luma server error (${e.status}).`),{config:{},status:"server_error"}):(console.warn(`[OCWI] Luma config fetch returned ${e.status}.`),{config:{},status:"network_error"})}catch(t){return"AbortError"===t?.name?(console.warn("[OCWI] Luma config fetch timed out."),{config:{},status:"timeout"}):(console.warn("[OCWI] Luma config fetch error",t),{config:{},status:"network_error"})}finally{clearTimeout(n)}}function a(t){return`ocwi_luma_cfg_${function(t){let e=5381;for(let i=0;i<t.length;i++)e=33*e^t.charCodeAt(i);return(e>>>0).toString(36)}(String(t||"").trim())}`}function c(t,e,i=14){const n=String(t||"").trim();if(!n)return;const s=a(n),o={v:1,ts:Date.now(),config:e||{}};let r="";try{r=JSON.stringify(o)}catch{return}r.length>3800||function(t,e,i){if("undefined"==typeof document)return;const n=Math.max(0,Math.floor(24*i*60*60));document.cookie=`${t}=${e}; Max-Age=${n}; Path=/; SameSite=Lax`}(s,encodeURIComponent(r),i)}function l(t,e,i,n){if("a"===i&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!n:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?n:"a"===i?n.call(t):n?n.value:e.get(t)}"function"==typeof SuppressedError&&SuppressedError;const h=globalThis,d=h.ShadowRoot&&(void 0===h.ShadyCSS||h.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,u=Symbol(),p=new WeakMap;let m=class{constructor(t,e,i){if(this._$cssResult$=!0,i!==u)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const e=this.t;if(d&&void 0===t){const i=void 0!==e&&1===e.length;i&&(t=p.get(e)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),i&&p.set(e,t))}return t}toString(){return this.cssText}};const f=d?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new m("string"==typeof t?t:t+"",void 0,u))(e)})(t):t,{is:g,defineProperty:b,getOwnPropertyDescriptor:w,getOwnPropertyNames:v,getOwnPropertySymbols:y,getPrototypeOf:x}=Object,$=globalThis,S=$.trustedTypes,A=S?S.emptyScript:"",_=$.reactiveElementPolyfillSupport,k=(t,e)=>t,E={toAttribute(t,e){switch(e){case Boolean:t=t?A:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},C=(t,e)=>!g(t,e),M={attribute:!0,type:String,converter:E,reflect:!1,useDefault:!1,hasChanged:C};Symbol.metadata??=Symbol("metadata"),$.litPropertyMetadata??=new WeakMap;let I=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=M){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(t,i,e);void 0!==n&&b(this.prototype,t,n)}}static getPropertyDescriptor(t,e,i){const{get:n,set:s}=w(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:n,set(e){const o=n?.call(this);s?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??M}static _$Ei(){if(this.hasOwnProperty(k("elementProperties")))return;const t=x(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(k("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(k("properties"))){const t=this.properties,e=[...v(t),...y(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(f(t))}else void 0!==t&&e.push(f(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,e)=>{if(d)t.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const i of e){const e=document.createElement("style"),n=h.litNonce;void 0!==n&&e.setAttribute("nonce",n),e.textContent=i.cssText,t.appendChild(e)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),n=this.constructor._$Eu(t,i);if(void 0!==n&&!0===i.reflect){const s=(void 0!==i.converter?.toAttribute?i.converter:E).toAttribute(e,i.type);this._$Em=t,null==s?this.removeAttribute(n):this.setAttribute(n,s),this._$Em=null}}_$AK(t,e){const i=this.constructor,n=i._$Eh.get(t);if(void 0!==n&&this._$Em!==n){const t=i.getPropertyOptions(n),s="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:E;this._$Em=n;const o=s.fromAttribute(e,t.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(t,e,i){if(void 0!==t){const n=this.constructor,s=this[t];if(i??=n.getPropertyOptions(t),!((i.hasChanged??C)(s,e)||i.useDefault&&i.reflect&&s===this._$Ej?.get(t)&&!this.hasAttribute(n._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:n,wrapped:s},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==s||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===n&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,n=this[e];!0!==t||this._$AL.has(e)||void 0===n||this.C(e,void 0,i,n)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};I.elementStyles=[],I.shadowRootOptions={mode:"open"},I[k("elementProperties")]=new Map,I[k("finalized")]=new Map,_?.({ReactiveElement:I}),($.reactiveElementVersions??=[]).push("2.1.1");const D=globalThis,T=D.trustedTypes,L=T?T.createPolicy("lit-html",{createHTML:t=>t}):void 0,O="$lit$",R=`lit$${Math.random().toFixed(9).slice(2)}$`,U="?"+R,N=`<${U}>`,P=document,z=()=>P.createComment(""),B=t=>null===t||"object"!=typeof t&&"function"!=typeof t,H=Array.isArray,j="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,W=/-->/g,K=/>/g,V=RegExp(`>|${j}(?:([^\\s"'>=/]+)(${j}*=${j}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),q=/'/g,Z=/"/g,J=/^(?:script|style|textarea|title)$/i,Y=(t,...e)=>({_$litType$:1,strings:t,values:e}),G=Symbol.for("lit-noChange"),X=Symbol.for("lit-nothing"),Q=new WeakMap,tt=P.createTreeWalker(P,129);function et(t,e){if(!H(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==L?L.createHTML(e):e}const it=(t,e)=>{const i=t.length-1,n=[];let s,o=2===e?"<svg>":3===e?"<math>":"",r=F;for(let e=0;e<i;e++){const i=t[e];let a,c,l=-1,h=0;for(;h<i.length&&(r.lastIndex=h,c=r.exec(i),null!==c);)h=r.lastIndex,r===F?"!--"===c[1]?r=W:void 0!==c[1]?r=K:void 0!==c[2]?(J.test(c[2])&&(s=RegExp("</"+c[2],"g")),r=V):void 0!==c[3]&&(r=V):r===V?">"===c[0]?(r=s??F,l=-1):void 0===c[1]?l=-2:(l=r.lastIndex-c[2].length,a=c[1],r=void 0===c[3]?V:'"'===c[3]?Z:q):r===Z||r===q?r=V:r===W||r===K?r=F:(r=V,s=void 0);const d=r===V&&t[e+1].startsWith("/>")?" ":"";o+=r===F?i+N:l>=0?(n.push(a),i.slice(0,l)+O+i.slice(l)+R+d):i+R+(-2===l?e:d)}return[et(t,o+(t[i]||"<?>")+(2===e?"</svg>":3===e?"</math>":"")),n]};class nt{constructor({strings:t,_$litType$:e},i){let n;this.parts=[];let s=0,o=0;const r=t.length-1,a=this.parts,[c,l]=it(t,e);if(this.el=nt.createElement(c,i),tt.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(n=tt.nextNode())&&a.length<r;){if(1===n.nodeType){if(n.hasAttributes())for(const t of n.getAttributeNames())if(t.endsWith(O)){const e=l[o++],i=n.getAttribute(t).split(R),r=/([.?@])?(.*)/.exec(e);a.push({type:1,index:s,name:r[2],strings:i,ctor:"."===r[1]?ct:"?"===r[1]?lt:"@"===r[1]?ht:at}),n.removeAttribute(t)}else t.startsWith(R)&&(a.push({type:6,index:s}),n.removeAttribute(t));if(J.test(n.tagName)){const t=n.textContent.split(R),e=t.length-1;if(e>0){n.textContent=T?T.emptyScript:"";for(let i=0;i<e;i++)n.append(t[i],z()),tt.nextNode(),a.push({type:2,index:++s});n.append(t[e],z())}}}else if(8===n.nodeType)if(n.data===U)a.push({type:2,index:s});else{let t=-1;for(;-1!==(t=n.data.indexOf(R,t+1));)a.push({type:7,index:s}),t+=R.length-1}s++}}static createElement(t,e){const i=P.createElement("template");return i.innerHTML=t,i}}function st(t,e,i=t,n){if(e===G)return e;let s=void 0!==n?i._$Co?.[n]:i._$Cl;const o=B(e)?void 0:e._$litDirective$;return s?.constructor!==o&&(s?._$AO?.(!1),void 0===o?s=void 0:(s=new o(t),s._$AT(t,i,n)),void 0!==n?(i._$Co??=[])[n]=s:i._$Cl=s),void 0!==s&&(e=st(t,s._$AS(t,e.values),s,n)),e}class ot{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:e},parts:i}=this._$AD,n=(t?.creationScope??P).importNode(e,!0);tt.currentNode=n;let s=tt.nextNode(),o=0,r=0,a=i[0];for(;void 0!==a;){if(o===a.index){let e;2===a.type?e=new rt(s,s.nextSibling,this,t):1===a.type?e=new a.ctor(s,a.name,a.strings,this,t):6===a.type&&(e=new dt(s,this,t)),this._$AV.push(e),a=i[++r]}o!==a?.index&&(s=tt.nextNode(),o++)}return tt.currentNode=P,n}p(t){let e=0;for(const i of this._$AV)void 0!==i&&(void 0!==i.strings?(i._$AI(t,i,e),e+=i.strings.length-2):i._$AI(t[e])),e++}}class rt{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,i,n){this.type=2,this._$AH=X,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=i,this.options=n,this._$Cv=n?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const e=this._$AM;return void 0!==e&&11===t?.nodeType&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=st(this,t,e),B(t)?t===X||null==t||""===t?(this._$AH!==X&&this._$AR(),this._$AH=X):t!==this._$AH&&t!==G&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):(t=>H(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==X&&B(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,n="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=nt.createElement(et(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(e);else{const t=new ot(n,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=Q.get(t.strings);return void 0===e&&Q.set(t.strings,e=new nt(t)),e}k(t){H(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,n=0;for(const s of t)n===e.length?e.push(i=new rt(this.O(z()),this.O(z()),this,this.options)):i=e[n],i._$AI(s),n++;n<e.length&&(this._$AR(i&&i._$AB.nextSibling,n),e.length=n)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){const e=t.nextSibling;t.remove(),t=e}}setConnected(t){void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t))}}class at{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,i,n,s){this.type=1,this._$AH=X,this._$AN=void 0,this.element=t,this.name=e,this._$AM=n,this.options=s,i.length>2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=X}_$AI(t,e=this,i,n){const s=this.strings;let o=!1;if(void 0===s)t=st(this,t,e,0),o=!B(t)||t!==this._$AH&&t!==G,o&&(this._$AH=t);else{const n=t;let r,a;for(t=s[0],r=0;r<s.length-1;r++)a=st(this,n[i+r],e,r),a===G&&(a=this._$AH[r]),o||=!B(a)||a!==this._$AH[r],a===X?t=X:t!==X&&(t+=(a??"")+s[r+1]),this._$AH[r]=a}o&&!n&&this.j(t)}j(t){t===X?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}}class ct extends at{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===X?void 0:t}}class lt extends at{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==X)}}class ht extends at{constructor(t,e,i,n,s){super(t,e,i,n,s),this.type=5}_$AI(t,e=this){if((t=st(this,t,e,0)??X)===G)return;const i=this._$AH,n=t===X&&i!==X||t.capture!==i.capture||t.once!==i.once||t.passive!==i.passive,s=t!==X&&(i===X||n);n&&this.element.removeEventListener(this.name,this,i),s&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class dt{constructor(t,e,i){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=i}get _$AU(){return this._$AM._$AU}_$AI(t){st(this,t)}}const ut=D.litHtmlPolyfillSupport;ut?.(nt,rt),(D.litHtmlVersions??=[]).push("3.3.1");const pt=globalThis;let mt=class extends I{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=((t,e,i)=>{const n=i?.renderBefore??e;let s=n._$litPart$;if(void 0===s){const t=i?.renderBefore??null;n._$litPart$=s=new rt(e.insertBefore(z(),t),t,void 0,i??{})}return s._$AI(t),s})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return G}};mt._$litElement$=!0,mt.finalized=!0,pt.litElementHydrateSupport?.({LitElement:mt});const ft=pt.litElementPolyfillSupport;ft?.({LitElement:mt}),(pt.litElementVersions??=[]).push("4.2.1");const gt=((t,...e)=>{const i=1===t.length?t[0]:e.reduce((e,i,n)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[n+1],t[0]);return new m(i,t,u)})`
2
+ :host {
3
+ all: initial;
4
+ box-sizing: border-box;
5
+ contain: content;
6
+ position: fixed;
7
+ inset: auto 16px 16px auto;
8
+ z-index: var(--ocwi-z-index, 2147480000);
9
+ font-family:
10
+ system-ui,
11
+ -apple-system,
12
+ Segoe UI,
13
+ Roboto,
14
+ Helvetica,
15
+ Arial,
16
+ 'Apple Color Emoji',
17
+ 'Segoe UI Emoji';
18
+
19
+ /* Single source of truth for viewport edge gap.
20
+ All max-width / max-height / mobile layout derive from this.
21
+ Override --ocwi-edge in media queries, everything recalculates. */
22
+ --ocwi-edge: 16px;
23
+
24
+ --ocwi-safe-top: env(safe-area-inset-top, 0px);
25
+ --ocwi-safe-bottom: env(safe-area-inset-bottom, 0px);
26
+ --ocwi-safe-left: env(safe-area-inset-left, 0px);
27
+ --ocwi-safe-right: env(safe-area-inset-right, 0px);
28
+ }
29
+ :host *,
30
+ :host *::before,
31
+ :host *::after {
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ .wrap {
36
+ box-sizing: border-box;
37
+ /* Both axes: subtract edge gap from BOTH sides (2 * --ocwi-edge).
38
+ This prevents overflow on the opposite side regardless of position config. */
39
+ width: min(var(--ocwi-width, 320px), calc(100vw - 2 * var(--ocwi-edge)));
40
+ height: min(
41
+ var(--ocwi-height, 480px),
42
+ calc(100svh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top) - var(--ocwi-safe-bottom))
43
+ );
44
+ max-width: calc(100vw - 2 * var(--ocwi-edge));
45
+ max-height: calc(
46
+ 100svh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top) - var(--ocwi-safe-bottom)
47
+ );
48
+ background: var(--ocwi-bg, #ffffff);
49
+ border: 1px solid var(--ocwi-border, #e5e7eb);
50
+ border-radius: var(--ocwi-radius, 12px);
51
+ display: grid;
52
+ grid-template-rows: auto 1fr auto;
53
+ overflow: hidden;
54
+ box-shadow:
55
+ 0 10px 15px -3px rgba(0, 0, 0, 0.1),
56
+ 0 4px 6px -2px rgba(0, 0, 0, 0.05);
57
+ }
58
+ @supports not (height: 1svh) {
59
+ .wrap {
60
+ height: min(
61
+ var(--ocwi-height, 480px),
62
+ calc(100vh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top) - var(--ocwi-safe-bottom))
63
+ );
64
+ max-height: calc(
65
+ 100vh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top) - var(--ocwi-safe-bottom)
66
+ );
67
+ }
68
+ }
69
+ .wrap.minimized {
70
+ height: auto;
71
+ grid-template-rows: auto;
72
+ }
73
+
74
+ header {
75
+ background: var(--ocwi-header-bg, var(--ocwi-bg, #ffffff));
76
+ color: var(--ocwi-header-text, #111);
77
+ padding: calc(var(--ocwi-spacing, 8px) * 1) calc(var(--ocwi-spacing, 8px) * 1.5);
78
+ font-weight: 500;
79
+ font-size: 14px;
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: space-between;
83
+ gap: 12px;
84
+ border-bottom: 1px solid var(--ocwi-border, #e5e7eb);
85
+ min-width: 0;
86
+ flex-wrap: nowrap;
87
+ }
88
+ .header-left {
89
+ display: flex;
90
+ align-items: center;
91
+ gap: 12px;
92
+ min-width: 0;
93
+ flex: 1 1 auto;
94
+ overflow: hidden;
95
+ }
96
+ .header-actions {
97
+ display: flex;
98
+ align-items: center;
99
+ gap: 8px;
100
+ flex: 0 0 auto;
101
+ flex-wrap: nowrap;
102
+ }
103
+
104
+ /* ─── Status dot ─────────────────────────────────────────
105
+ Diagonal split: left half = luma, right half = dana.
106
+ Colors injected via inline style --luma-clr / --dana-clr.
107
+ When no lumaUrl: both halves same (solid dot).
108
+ ────────────────────────────────────────────────────────── */
109
+ .status-dot {
110
+ width: 12px;
111
+ height: 12px;
112
+ border-radius: 9999px;
113
+ flex-shrink: 0;
114
+ background: linear-gradient(90deg, var(--luma-clr, #22c55e) 50%, var(--dana-clr, #22c55e) 50%);
115
+ cursor: help;
116
+ }
117
+ .status-dot.is-pulsing {
118
+ animation: ocwi-pulse 1s infinite ease-in-out;
119
+ }
120
+ @keyframes ocwi-pulse {
121
+ 0%,
122
+ 100% {
123
+ opacity: 1;
124
+ transform: scale(1);
125
+ }
126
+ 50% {
127
+ opacity: 0.5;
128
+ transform: scale(0.82);
129
+ }
130
+ }
131
+
132
+ .avatar {
133
+ width: 32px;
134
+ height: 32px;
135
+ border-radius: 9999px;
136
+ object-fit: cover;
137
+ }
138
+ .name {
139
+ font-weight: 500;
140
+ white-space: nowrap;
141
+ overflow: hidden;
142
+ text-overflow: ellipsis;
143
+ min-width: 0;
144
+ flex: 1 1 auto;
145
+ }
146
+
147
+ .lang-select {
148
+ margin-left: 4px;
149
+ font-size: 13px;
150
+ height: 36px;
151
+ line-height: 16px;
152
+ padding: 4px 10px;
153
+ border-radius: 6px;
154
+ border: 1px solid color-mix(in oklch, var(--ocwi-header-text, #111) 20%, transparent);
155
+ background: transparent;
156
+ color: var(--ocwi-header-text, #111);
157
+ appearance: none;
158
+ -webkit-appearance: none;
159
+ cursor: pointer;
160
+ flex-shrink: 0;
161
+ }
162
+ .lang-select:hover {
163
+ background: color-mix(in oklch, var(--ocwi-header-text, #111) 12%, transparent);
164
+ }
165
+ .lang-select::-ms-expand {
166
+ display: none;
167
+ }
168
+
169
+ .icon-btn.header-btn {
170
+ padding: 6px;
171
+ border: 1px solid color-mix(in oklch, var(--ocwi-header-text, #111) 20%, transparent);
172
+ border-radius: 6px;
173
+ background: transparent;
174
+ color: var(--ocwi-header-text, #111);
175
+ flex-shrink: 0;
176
+ }
177
+ .icon-btn.header-btn:hover {
178
+ background: color-mix(in oklch, var(--ocwi-header-text, #111) 12%, transparent);
179
+ }
180
+
181
+ .messages {
182
+ padding: calc(var(--ocwi-spacing, 8px) * 1.5);
183
+ overflow-y: auto;
184
+ overflow-x: hidden;
185
+ background-color: var(--ocwi-bg, #ffffff);
186
+ background-image: var(--ocwi-watermark-image, none);
187
+ background-repeat: var(--ocwi-watermark-repeat, no-repeat);
188
+ background-position: var(--ocwi-watermark-position, right 1rem bottom 1rem);
189
+ background-size: var(--ocwi-watermark-size, 200px auto);
190
+ background-attachment: local;
191
+ position: relative;
192
+ }
193
+ .empty {
194
+ color: var(--ocwi-input-placeholder, #6b7280);
195
+ font-size: 12px;
196
+ text-align: center;
197
+ margin-top: 16px;
198
+ position: relative;
199
+ z-index: 1;
200
+ }
201
+
202
+ .bubble {
203
+ max-width: var(--ocwi-bubble-max-width, 80%);
204
+ display: inline-block;
205
+ padding: calc(var(--ocwi-spacing, 8px) * 1) calc(var(--ocwi-spacing, 8px) * 1.5);
206
+ border-radius: 16px;
207
+ margin: 4px 0;
208
+ line-height: 1.4;
209
+ word-wrap: break-word;
210
+ font-size: var(--ocwi-message-font, clamp(14px, calc(var(--ocwi-width, 320px) / 20), 16px));
211
+ position: relative;
212
+ z-index: 1;
213
+ }
214
+ .user {
215
+ background: var(--ocwi-bubble-user-bg, var(--ocwi-primary, #2563eb));
216
+ color: var(--ocwi-bubble-user-text, #ffffff);
217
+ align-self: end;
218
+ justify-self: end;
219
+ border-bottom-right-radius: 0;
220
+ }
221
+ .assistant {
222
+ background: var(--ocwi-bubble-assistant-bg, #f3f4f6);
223
+ color: var(--ocwi-bubble-assistant-text, #1f2937);
224
+ align-self: start;
225
+ justify-self: start;
226
+ border-bottom-left-radius: 0;
227
+ }
228
+
229
+ /* ─── Error bubble ───────────────────────────────────────
230
+ Distinct from system/assistant — reddish tint.
231
+ ────────────────────────────────────────────────────────── */
232
+ .bubble.error {
233
+ background: #fff1f2;
234
+ color: #9f1239;
235
+ border: 1px solid #fecdd3;
236
+ border-bottom-left-radius: 0;
237
+ }
238
+ .error-details {
239
+ margin-top: 6px;
240
+ border-top: 1px solid color-mix(in oklch, currentColor 15%, transparent);
241
+ padding-top: 6px;
242
+ }
243
+ .error-details-toggle {
244
+ all: unset;
245
+ font-size: 11px;
246
+ font-weight: 500;
247
+ color: currentColor;
248
+ opacity: 0.7;
249
+ cursor: pointer;
250
+ text-decoration: underline dotted;
251
+ text-underline-offset: 2px;
252
+ display: block;
253
+ }
254
+ .error-details-toggle:hover {
255
+ opacity: 1;
256
+ }
257
+ .error-details-content {
258
+ margin-top: 6px;
259
+ font-size: 11px;
260
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
261
+ opacity: 0.75;
262
+ word-break: break-all;
263
+ white-space: pre-wrap;
264
+ background: color-mix(in oklch, currentColor 6%, transparent);
265
+ padding: 4px 6px;
266
+ border-radius: 4px;
267
+ }
268
+
269
+ .bubble-text {
270
+ overflow-wrap: anywhere;
271
+ word-break: break-word;
272
+ hyphens: auto;
273
+ font-size: var(--ocwi-message-font, clamp(14px, calc(var(--ocwi-width, 320px) / 20), 16px));
274
+ }
275
+
276
+ .typing-dots {
277
+ display: inline-flex;
278
+ gap: 5px;
279
+ align-items: center;
280
+ height: 1em;
281
+ }
282
+ .typing-dots span {
283
+ width: 6px;
284
+ height: 6px;
285
+ border-radius: 9999px;
286
+ background: currentColor;
287
+ opacity: 0.35;
288
+ animation: ocwi-typing 1.2s infinite ease-in-out;
289
+ }
290
+ .typing-dots span:nth-child(2) {
291
+ animation-delay: 0.15s;
292
+ }
293
+ .typing-dots span:nth-child(3) {
294
+ animation-delay: 0.3s;
295
+ }
296
+ @keyframes ocwi-typing {
297
+ 0%,
298
+ 80%,
299
+ 100% {
300
+ opacity: 0.35;
301
+ transform: translateY(0);
302
+ }
303
+ 40% {
304
+ opacity: 1;
305
+ transform: translateY(-1px);
306
+ }
307
+ }
308
+
309
+ .edit-textarea {
310
+ width: 100%;
311
+ min-height: 36px;
312
+ padding: 8px 10px;
313
+ border: 1px solid color-mix(in oklch, currentColor 20%, transparent);
314
+ border-radius: 10px;
315
+ outline: none;
316
+ font-family: inherit;
317
+ font-size: inherit;
318
+ line-height: 1.4;
319
+ resize: vertical;
320
+ background: color-mix(in oklch, #fff 70%, transparent);
321
+ color: inherit;
322
+ }
323
+ .edit-actions {
324
+ margin-top: 8px;
325
+ display: flex;
326
+ gap: 6px;
327
+ justify-content: end;
328
+ }
329
+
330
+ form {
331
+ display: grid;
332
+ grid-template-columns: 1fr auto;
333
+ gap: var(--ocwi-spacing, 8px);
334
+ padding: var(--ocwi-spacing, 8px);
335
+ border-top: 1px solid var(--ocwi-border, #e5e7eb);
336
+ background: var(--ocwi-input-bg, #ffffff);
337
+ align-items: end;
338
+ }
339
+ form.no-send {
340
+ grid-template-columns: 1fr;
341
+ gap: 0;
342
+ }
343
+
344
+ textarea {
345
+ width: 100%;
346
+ min-height: 36px;
347
+ max-height: var(--ocwi-composer-max-height, min(calc(36px * 3), 30svh));
348
+ padding: 8px calc(var(--ocwi-spacing, 8px) * 1);
349
+ border: 1px solid var(--ocwi-border, #e5e7eb);
350
+ border-radius: 8px;
351
+ outline: none;
352
+ color: var(--ocwi-input-text, #111111);
353
+ background: var(--ocwi-input-bg, #ffffff);
354
+ font-size: 14px;
355
+ font-family: inherit;
356
+ line-height: 1.4;
357
+ resize: none;
358
+ overflow-y: auto;
359
+ }
360
+ @supports not (height: 1svh) {
361
+ textarea {
362
+ max-height: var(--ocwi-composer-max-height, calc(36px * 3));
363
+ }
364
+ }
365
+ textarea::placeholder {
366
+ color: var(--ocwi-input-placeholder, #6b7280);
367
+ }
368
+ textarea:disabled {
369
+ opacity: 0.7;
370
+ cursor: not-allowed;
371
+ }
372
+
373
+ button {
374
+ height: 36px;
375
+ padding: 0 12px;
376
+ border: none;
377
+ border-radius: 8px;
378
+ background: var(--ocwi-send-bg, var(--ocwi-primary, #2563eb));
379
+ color: var(--ocwi-send-text, #ffffff);
380
+ font-weight: 600;
381
+ font-size: 14px;
382
+ cursor: pointer;
383
+ display: flex;
384
+ align-items: center;
385
+ justify-content: center;
386
+ gap: 6px;
387
+ }
388
+ button[disabled] {
389
+ opacity: 0.6;
390
+ cursor: not-allowed;
391
+ }
392
+ .send-label {
393
+ font-size: 14px;
394
+ font-weight: 600;
395
+ line-height: 1;
396
+ }
397
+
398
+ .icon-btn {
399
+ background: transparent;
400
+ border: none;
401
+ padding: 4px;
402
+ border-radius: 6px;
403
+ display: inline-grid;
404
+ place-items: center;
405
+ cursor: pointer;
406
+ color: inherit;
407
+ }
408
+ .icon-btn:hover {
409
+ background: color-mix(in oklch, currentColor 10%, transparent);
410
+ }
411
+ .icon-btn svg {
412
+ width: 16px;
413
+ height: 16px;
414
+ }
415
+
416
+ .bubble .icon-btn.chip {
417
+ padding: 2px 6px;
418
+ border-radius: 6px;
419
+ background: transparent;
420
+ border: 1px solid color-mix(in oklch, currentColor 20%, transparent);
421
+ }
422
+ .bubble .icon-btn.chip:hover {
423
+ background: color-mix(in oklch, currentColor 12%, transparent);
424
+ }
425
+
426
+ .bubble-actions {
427
+ position: absolute;
428
+ top: -8px;
429
+ right: 4px;
430
+ display: flex;
431
+ gap: 4px;
432
+ opacity: 0;
433
+ visibility: hidden;
434
+ pointer-events: none;
435
+ transition:
436
+ opacity 0.15s ease,
437
+ visibility 0.15s ease;
438
+ }
439
+ .bubble.actions-open .bubble-actions,
440
+ .bubble:focus-within .bubble-actions {
441
+ opacity: 1;
442
+ visibility: visible;
443
+ pointer-events: auto;
444
+ }
445
+ .bubble .more-btn {
446
+ position: absolute;
447
+ right: 0;
448
+ top: 0;
449
+ background: transparent;
450
+ touch-action: manipulation;
451
+ }
452
+ .bubble.actions-open .more-btn {
453
+ display: none;
454
+ }
455
+
456
+ @media (hover: hover) and (pointer: fine) {
457
+ .bubble:hover .bubble-actions,
458
+ .bubble:focus-within .bubble-actions {
459
+ opacity: 1;
460
+ visibility: visible;
461
+ pointer-events: auto;
462
+ }
463
+ .bubble .more-btn {
464
+ display: none;
465
+ }
466
+ }
467
+ @media (hover: none) {
468
+ .bubble .more-btn {
469
+ display: inline-grid;
470
+ }
471
+ }
472
+
473
+ .floating-btn {
474
+ width: 77px;
475
+ height: 77px;
476
+ padding: 0;
477
+ border-radius: 9999px;
478
+ display: inline-grid;
479
+ place-items: center;
480
+ background: var(--ocwi-fab-bg, var(--ocwi-primary, #2563eb));
481
+ color: var(--ocwi-fab-text, #ffffff);
482
+ box-shadow:
483
+ 0 10px 15px -3px rgba(0, 0, 0, 0.1),
484
+ 0 4px 6px -2px rgba(0, 0, 0, 0.05);
485
+ touch-action: manipulation;
486
+ }
487
+ .floating-btn:focus-visible {
488
+ outline: 2px solid color-mix(in oklch, currentColor 40%, transparent);
489
+ outline-offset: 2px;
490
+ }
491
+
492
+ .list {
493
+ display: grid;
494
+ grid-auto-rows: max-content;
495
+ row-gap: 12px;
496
+ align-content: start;
497
+ position: relative;
498
+ z-index: 1;
499
+ }
500
+ .row {
501
+ display: grid;
502
+ }
503
+ .row.right {
504
+ justify-items: end;
505
+ }
506
+ .row.left {
507
+ justify-items: start;
508
+ }
509
+ .row.center {
510
+ justify-items: center;
511
+ }
512
+
513
+ .reconnect-block {
514
+ display: flex;
515
+ flex-direction: column;
516
+ align-items: center;
517
+ gap: 8px;
518
+ padding: 12px 16px;
519
+ margin: 4px 0;
520
+ border-radius: 12px;
521
+ background: color-mix(in oklch, var(--ocwi-border, #e5e7eb) 50%, transparent);
522
+ text-align: center;
523
+ }
524
+ .reconnect-label {
525
+ font-size: 12px;
526
+ color: var(--ocwi-input-placeholder, #6b7280);
527
+ font-weight: 500;
528
+ }
529
+ .reconnect-btn {
530
+ height: auto;
531
+ padding: 8px 18px;
532
+ border-radius: 20px;
533
+ background: transparent;
534
+ border: 1.5px solid var(--ocwi-border, #e5e7eb);
535
+ color: var(--ocwi-header-text, #111);
536
+ font-size: 13px;
537
+ font-weight: 500;
538
+ gap: 6px;
539
+ cursor: pointer;
540
+ display: inline-flex;
541
+ align-items: center;
542
+ white-space: nowrap;
543
+ }
544
+ .reconnect-btn:hover {
545
+ background: color-mix(in oklch, currentColor 8%, transparent);
546
+ }
547
+ .reconnect-btn svg {
548
+ width: 14px;
549
+ height: 14px;
550
+ }
551
+
552
+ /* ─── Mobile ≤480px ───────────────────────────────────── */
553
+ @media (max-width: 480px) {
554
+ /* Override --ocwi-edge to 6px — all .wrap width/height/max-* recalculate automatically */
555
+ :host {
556
+ --ocwi-edge: 6px;
557
+ inset: var(--ocwi-safe-top, 0px) var(--ocwi-edge) var(--ocwi-edge) var(--ocwi-edge) !important;
558
+ transform: none !important;
559
+ }
560
+ .wrap.open {
561
+ width: calc(100vw - 2 * var(--ocwi-edge));
562
+ max-width: calc(100vw - 2 * var(--ocwi-edge));
563
+ height: calc(
564
+ 100svh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top, 0px) - var(--ocwi-safe-bottom, 0px)
565
+ );
566
+ border-radius: 16px 16px 10px 10px;
567
+ }
568
+ @supports not (height: 1svh) {
569
+ .wrap.open {
570
+ height: calc(
571
+ 100vh - 2 * var(--ocwi-edge) - var(--ocwi-safe-top, 0px) - var(--ocwi-safe-bottom, 0px)
572
+ );
573
+ }
574
+ }
575
+ .wrap.minimized {
576
+ width: min(var(--ocwi-width, 320px), calc(100vw - 2 * var(--ocwi-edge)));
577
+ height: auto;
578
+ border-radius: var(--ocwi-radius, 12px);
579
+ }
580
+ }
581
+ `;class bt{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}class wt extends bt{constructor(t){if(super(t),this.it=X,2!==t.type)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(t){if(t===X||null==t)return this._t=void 0,this.it=t;if(t===G)return t;if("string"!=typeof t)throw Error(this.constructor.directiveName+"() called with a non-string value");if(t===this.it)return this._t;this.it=t;const e=[t];return e.raw=e,this._t={_$litType$:this.constructor.resultType,strings:e,values:[]}}}wt.directiveName="unsafeHTML",wt.resultType=1;class vt extends wt{}vt.directiveName="unsafeSVG",vt.resultType=2;const yt=(t=>(...e)=>({_$litDirective$:t,values:e}))(vt);function xt(t){return Object.entries(t).filter(([,t])=>null!=t).map(([t,e])=>` ${t}="${String(e)}"`).join("")}function $t(t,e=20,i=2){return yt(function(t,e=20,i=2){const n={xmlns:"http://www.w3.org/2000/svg",width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":i,"stroke-linecap":"round","stroke-linejoin":"round",class:"lucide",focusable:"false","aria-hidden":"true"},s=t.map(([t,e])=>`<${t}${xt(e)}></${t}>`).join("");return`<svg${xt(n)}>${s}</svg>`}(t,e,i))}const St={closed:$t([["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"}],["path",{d:"M8 12h.01"}],["path",{d:"M12 12h.01"}],["path",{d:"M16 12h.01"}]],36),minimize:$t([["path",{d:"m14 10 7-7"}],["path",{d:"M20 10h-6V4"}],["path",{d:"m3 21 7-7"}],["path",{d:"M4 14h6v6"}]],16),maximize:$t([["path",{d:"M15 3h6v6"}],["path",{d:"m21 3-7 7"}],["path",{d:"m3 21 7-7"}],["path",{d:"M9 21H3v-6"}]],16),close:$t([["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]],16),send:$t([["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}],["path",{d:"m21.854 2.147-10.94 10.939"}]],20),stop:$t([["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2"}]],20),refresh:$t([["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"}],["path",{d:"M21 3v5h-5"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"}],["path",{d:"M8 16H3v5"}]],16),copy:$t([["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"}]],16),edit:$t([["path",{d:"M13 21h8"}],["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"}]],16),login:$t([["path",{d:"m10 17 5-5-5-5"}],["path",{d:"M15 12H3"}],["path",{d:"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"}]],16),logout:$t([["path",{d:"m16 17 5-5-5-5"}],["path",{d:"M21 12H9"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"}]],16),more:$t([["circle",{cx:"12",cy:"12",r:"1"}],["circle",{cx:"12",cy:"5",r:"1"}],["circle",{cx:"12",cy:"19",r:"1"}]],16)};function At(t,e,i,n,s="menuitem"){return t?Y`<button
582
+ type="button"
583
+ class="icon-btn chip"
584
+ title=${i}
585
+ aria-label=${i}
586
+ role=${s}
587
+ @click=${n}
588
+ >
589
+ ${e}
590
+ </button>`:null}function _t(t){const e=String(t||"").trim();return e?/^https?:\/\//i.test(e)?e:`https://${e}`:e}function kt(t){return String(t||"").replace(/\/+$/,"")}function Et(t){const e=kt(_t(t)),i=e.indexOf("?"),n=e.indexOf("#"),s=i>=0&&n>=0?Math.min(i,n):i>=0?i:n;return(s>=0?e.slice(0,s):e).replace(/\/api\/chat$/i,"")}function Ct(e){return{id:String(e?.id||t("m")),role:(i=e?.role,"user"===i||"assistant"===i||"system"===i?i:"assistant"),text:String(e?.text??e?.message??e?.content??"").trim(),timestamp:Number.isFinite(Number(e?.timestamp))?Number(e.timestamp):Date.now(),metadata:e?.metadata&&"object"==typeof e.metadata?e.metadata:void 0};var i}function Mt(t){const e=t.match(/data:\s*\{[^}]*"error"\s*:\s*"([^"]+)"[^}]*\}/);return e?e[1]:null}function It(t,e){return e?"OFFLINE":/DANA .unavailable/i.test(t)?"DANA_UNAVAILABLE":/DANA timeout/i.test(t)?"DANA_TIMEOUT":/Proxy error/i.test(t)?"PROXY_ERROR":/DANA_LLM_UNAVAILABLE/i.test(t)?"DANA_LLM_UNAVAILABLE":/DANA_LLM_AUTH/i.test(t)?"DANA_LLM_AUTH":/DANA_LLM_TIMEOUT/i.test(t)?"DANA_LLM_TIMEOUT":/DANA_INTERNAL/i.test(t)?"DANA_INTERNAL":/Failed to fetch|NetworkError|net::ERR/i.test(t)?"NETWORK_ERROR":"UNKNOWN"}class Dt{constructor(t){this.config=t,this.activeController=null}stop(){try{this.activeController?.abort()}catch{}}async getMessages(t){const e=this.config.api||{},i=kt(_t(e.danaUrl||""));if(!i)return[];const n=`${Et(i)}/api/conversations/${encodeURIComponent(t)}/messages`,s=new AbortController,o=setTimeout(()=>s.abort(),e.timeoutMs&&e.timeoutMs>0?e.timeoutMs:3e4);try{const t=await fetch(n,{method:"GET",headers:{accept:"application/json"},signal:s.signal});if(!t.ok)throw new Error(`HTTP ${t.status}`);const e=await t.json().catch(()=>({}));return(Array.isArray(e?.messages)?e.messages:Array.isArray(e)?e:[]).map(Ct)}finally{clearTimeout(o)}}async resetChat(t){const e=this.config.api||{},i=kt(_t(e.danaUrl||""));if(!i)return{};const n=Et(i),s=t?`${n}/api/conversations/${encodeURIComponent(t)}/reset`:`${n}/api/conversations/reset`,o=new AbortController,r=setTimeout(()=>o.abort(),e.timeoutMs&&e.timeoutMs>0?e.timeoutMs:3e4);try{const t=await fetch(s,{method:"POST",headers:{accept:"application/json"},signal:o.signal});if(!t.ok)throw new Error(`HTTP ${t.status}`);const e=await t.json().catch(()=>({})),i=String(e?.conversationId||e?.sessionId||"").trim();return i?{conversationId:i}:{}}finally{clearTimeout(r)}}async sendMessageStream(e,i){const n=this.config.api||{},s=kt(_t(n.danaUrl||""));if(!s)return{assistant:{id:t("e"),role:"system",text:"Error: danaUrl is not configured",timestamp:Date.now()},stopped:!1};try{this.activeController?.abort()}catch{}const o=new AbortController;this.activeController=o;const r=o?setTimeout(()=>o.abort(),n.timeoutMs&&n.timeoutMs>0?n.timeoutMs:3e4):null;try{const n=function(t){const e=_t(String(t||"").trim());if(!e)return"";const i=e.indexOf("?"),n=e.indexOf("#"),s=i>=0&&n>=0?Math.min(i,n):i>=0?i:n,o=s>=0?e.slice(0,s):e,r=s>=0?e.slice(s):"",a=kt(o);return/\/api\/chat$/i.test(a)?`${a}${r}`:`${/\/api$/i.test(a)?`${a}/chat`:`${a}/api/chat`}${r}`}(s),r=await fetch(n,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({prompt:e.prompt,conversationId:e.conversationId,clientMessageId:e.clientMessageId,rewriteFromMessageId:e.rewriteFromMessageId}),signal:o.signal});if(!r.ok)throw new Error(`HTTP ${r.status}`);const a={conversationId:r.headers.get("x-conversation-id")||void 0,userMessageId:r.headers.get("x-user-message-id")||void 0,assistantMessageId:r.headers.get("x-assistant-message-id")||void 0};i?.onMeta?.(a);const c=r.body?.getReader?.(),l=new TextDecoder;let h="",d="";if(c)for(;;){const{value:e,done:n}=await c.read();if(n)break;const s=l.decode(e,{stream:!0});if(!s)continue;d+=s,d.length>1024&&(d=d.slice(-512));const o=Mt(d);if(o){try{c.cancel()}catch{}throw{id:t("e"),role:"system",text:o,timestamp:Date.now(),metadata:{isError:!0,errorCode:It(o,!1),technicalDetail:o}}}h+=s,i?.onChunk?.(s)}else{h=await r.text();const e=Mt(h);if(e)throw{id:t("e"),role:"system",text:e,timestamp:Date.now(),metadata:{isError:!0,errorCode:It(e,!1),technicalDetail:e}}}return{meta:a,assistant:{id:a.assistantMessageId||t("a"),role:"assistant",text:String(h||""),timestamp:Date.now()},stopped:!1}}catch(e){if("AbortError"===e?.name)return{assistant:{id:t("a"),role:"assistant",text:"",timestamp:Date.now(),metadata:{stopped:!0}},stopped:!0};const i=e?.text||e?.message||String(e||"Network error");if(e?.metadata?.isError)throw e;throw{id:t("e"),role:"system",text:i,timestamp:Date.now(),metadata:{isError:!0,errorCode:It(i,!1),technicalDetail:i}}}finally{r&&clearTimeout(r),this.activeController===o&&(this.activeController=null)}}}const Tt="ocwi_mock_conversations_v1";function Lt(t){if("undefined"!=typeof localStorage)try{localStorage.setItem(Tt,JSON.stringify(t))}catch{}}const Ot="undefined"==typeof localStorage?{}:function(t){if(t)try{return JSON.parse(t)}catch{return}}(localStorage.getItem(Tt))??{};function Rt(t){return new Promise(e=>setTimeout(e,t))}class Ut{constructor(){this.delayMsPerChunk=50,this.activeController=null}async getMessages(t){const e=String(t||"").trim();return e?(Ot[e]||[]).map(t=>({...t,metadata:t.metadata?{...t.metadata}:void 0})):[]}async resetChat(e){const i=t("c");return Ot[i]=[],Lt(Ot),{conversationId:i}}stop(){try{this.activeController?.abort()}catch{}}async sendMessageStream(e,i){const n=String(e.prompt||"");let s=String(e.conversationId||"").trim();s||(s=t("c"),Ot[s]=Ot[s]||[]);const o=Ot[s]||[];Ot[s]=o;const r=(e.clientMessageId||"").trim(),a=(e.rewriteFromMessageId||"").trim();if(a){const t=o.findIndex(t=>t.id===a);t>=0&&o.splice(t+1)}let c=r||t("u");const l=r?o.findIndex(t=>t.id===r):-1;if(l>=0&&"user"===o[l]?.role)o[l]={...o[l],text:n,timestamp:Date.now()};else{const t={id:c,role:"user",text:n,timestamp:Date.now()};o.push(t)}const h=t("a"),d={conversationId:s,userMessageId:c,assistantMessageId:h};i?.onMeta?.(d);const u=n.trim(),p=function(t){const e=[],i=/(\s+|[^\s]+)/g;let n;for(;n=i.exec(t);)e.push(n[0]);return e.length?e:[t]}(u?`You said: "${u}". This is a mock response streamed by chunks.`:"This is a mock response streamed by chunks."),m=new AbortController;this.activeController=m;let f="",g=!1;try{for(const t of p){if(m.signal.aborted){g=!0;break}f+=t,i?.onChunk?.(t),await Rt(this.delayMsPerChunk)}}finally{this.activeController===m&&(this.activeController=null)}const b={id:h,role:"assistant",text:f,timestamp:Date.now(),metadata:g?{stopped:!0}:void 0};return o.push(b),Lt(Ot),{meta:d,assistant:b,stopped:g}}}var Nt,Pt,zt,Bt,Ht,jt,Ft,Wt,Kt,Vt,qt,Zt,Jt,Yt,Gt,Xt,Qt,te,ee,ie,ne,se,oe,re,ae,ce,le,he,de,ue,pe,me,fe,ge,be,we,ve,ye,xe,$e,Se,Ae,_e,ke,Ee,Ce,Me,Ie;function De(t){switch(t){case"ok":return"online";case"not_found":return"not_found";case"server_error":return"server_error";case"timeout":case"network_error":return"offline"}}const Te={mock:"#009FE3",online:"#22c55e",connecting:"#fbbf24",offline:"#ef4444"},Le={unknown:"#9ca3af",online:"#22c55e",connecting:"#fbbf24",offline:"#ef4444",server_error:"#f97316",not_found:"#a855f7"},Oe=["connecting"],Re=["connecting"],Ue=[1e3,2e3,4e3,8e3,16e3,32e3];class Ne extends mt{constructor(){super(),Nt.add(this),this.config=s,this.bus=function(){const t=new Map;return{on:function(e,i){let n=t.get(e);return n||(n=new Set,t.set(e,n)),n.add(i),()=>{n.delete(i)}},emit:function(e,i){const n=t.get(e);if(n&&0!==n.size)for(const t of n)try{t(i)}catch(t){console.error("[OCWI] Event listener error",t)}},clear:function(){t.clear()}}}(),this.i18n=function(t,e="en"){let i={...t},n=e||"en";return{t:function(t){return(i[n]||{})[t]??(i.en||{})[t]??t},setLanguage:function(t){n=t||"en"},getLanguage:function(){return n},mergeDictionary:function(t){for(const[e,n]of Object.entries(t||{}))i[e]={...i[e]||{},...n}}}}(n,this.config.i18n?.lang||"en"),this.api=new Ut,this._userChangedWindowState=!1,this._apiKey="",this._danaReconnectTimer=null,this._danaReconnectAbort=null,this._lumaReconnectTimer=null,this._onHostClick=t=>{if(!this.store.getState().openActionsMessageId)return;const e=(t.composedPath?.()||[]).some(t=>t instanceof HTMLElement&&t.classList?.contains("bubble")&&t.classList?.contains("actions-open"));e||this.store.setState({openActionsMessageId:null})},this._onWindowResize=()=>{"open"===this.store.getState().windowState&&l(this,Nt,"m",_e).call(this)},this._onOnline=()=>{console.info("[OCWI] navigator: online");const{danaReconnectAttempt:t,lumaReconnectAttempt:e}=this.store.getState();l(this,Nt,"m",Pt).call(this)&&(l(this,Nt,"m",Wt).call(this),l(this,Nt,"m",jt).call(this,t)),l(this,Nt,"m",zt).call(this)&&(l(this,Nt,"m",Zt).call(this),l(this,Nt,"m",Vt).call(this,e))},this._onOffline=()=>{console.info("[OCWI] navigator: offline"),l(this,Nt,"m",Pt).call(this)&&(l(this,Nt,"m",Wt).call(this),this.store.setState({danaStatus:"offline",danaReconnectAttempt:0}),l(this,Nt,"m",jt).call(this,0)),l(this,Nt,"m",zt).call(this)&&(l(this,Nt,"m",Zt).call(this),this.store.setState({lumaStatus:"offline",lumaReconnectAttempt:0}),l(this,Nt,"m",Vt).call(this,0)),"open"===this.store.getState().windowState&&l(this,Nt,"m",Yt).call(this,"OFFLINE")},this.store=function(){let t={messages:[],status:"idle",windowState:"closed",loggedIn:!1,openActionsMessageId:null,expandedErrorIds:[],conversationId:null,isStreaming:!1,danaStatus:"mock",lumaStatus:"unknown",danaReconnectAttempt:0,lumaReconnectAttempt:0,editingMessageId:null,editDraft:""};const e=new Set;function i(){return t}return{getState:i,setState:function(n){t=Object.assign({},t,n);for(const t of e)try{t(i())}catch(t){console.error("[OCWI] Store listener error",t)}},subscribe:function(t){e.add(t);try{t(i())}catch{}return()=>{e.delete(t)}}}}()}connectedCallback(){super.connectedCallback(),l(this,Nt,"m",ie).call(this),l(this,Nt,"m",ne).call(this),l(this,Nt,"m",se).call(this),l(this,Nt,"m",oe).call(this),this.i18n.setLanguage(this.config.locale||this.config.i18n?.lang||"en"),this.config.i18n?.dictionary&&this.i18n.mergeDictionary(this.config.i18n.dictionary),l(this,Nt,"m",Gt).call(this),l(this,Nt,"m",he).call(this),this.addEventListener("click",this._onHostClick),"undefined"!=typeof window&&(window.addEventListener("resize",this._onWindowResize),window.visualViewport?.addEventListener("resize",this._onWindowResize),window.addEventListener("online",this._onOnline),window.addEventListener("offline",this._onOffline),navigator.onLine||setTimeout(()=>this._onOffline(),0)),this.unsubscribeStore=this.store.subscribe(()=>{this.requestUpdate(),this.updateComplete.then(()=>{const t=this.renderRoot.querySelector(".messages");t&&(t.scrollTop=t.scrollHeight),l(this,Nt,"m",_e).call(this)})})}disconnectedCallback(){l(this,Nt,"m",Wt).call(this),l(this,Nt,"m",Zt).call(this);try{this.unsubscribeStore?.()}catch{}if(this.unsubscribeStore=void 0,"undefined"!=typeof window){try{window.removeEventListener("resize",this._onWindowResize)}catch{}try{window.visualViewport?.removeEventListener("resize",this._onWindowResize)}catch{}try{window.removeEventListener("online",this._onOnline)}catch{}try{window.removeEventListener("offline",this._onOffline)}catch{}}try{this.removeEventListener("click",this._onHostClick)}catch{}super.disconnectedCallback()}firstUpdated(){l(this,Nt,"m",_e).call(this)}updated(){"open"===this.store.getState().windowState&&l(this,Nt,"m",_e).call(this)}updateConfig(t){const e=JSON.stringify(this.config.api||{}),i=this.config.locale||this.config.i18n?.lang||"en";this.config=o(this.config,t),JSON.stringify(this.config.api||{})!==e&&l(this,Nt,"m",Gt).call(this);const n=t.locale??this.config.locale??this.config.i18n?.lang??"en";t.i18n?.dictionary&&this.i18n.mergeDictionary(t.i18n.dictionary),i!==n&&this.i18n.setLanguage(n),l(this,Nt,"m",ie).call(this),l(this,Nt,"m",ne).call(this),l(this,Nt,"m",se).call(this),l(this,Nt,"m",oe).call(this),l(this,Nt,"m",he).call(this)}setInitialLumaStatus(t){const e=De(t);this.store.setState({lumaStatus:e}),"online"!==e&&l(this,Nt,"m",zt).call(this)&&l(this,Nt,"m",Vt).call(this,0)}getState(){return this.store.getState()}destroy(){l(this,Nt,"m",Wt).call(this),l(this,Nt,"m",Zt).call(this);try{this.unsubscribeStore?.()}catch{}this.remove(),this.bus.clear()}renderHeaderBlock(t){const e=this.config.features||{},i=this.config.ui?.avatarUrl,n=(this.config.ui?.name??"").trim(),s=n.split(" ")[0]||"Assistant",o=(this.config.locale||this.config.i18n?.lang||"en").trim(),r="minimized"===this.store.getState().windowState,a=this.store.getState().loggedIn;return Y` <header>
591
+ <div class="header-left">
592
+ ${e.avatarDisplay&&i?Y`<img class="avatar" src=${i} alt=${s} />`:null}
593
+ ${e.serverStatus?l(this,Nt,"m",re).call(this):null}
594
+ ${e.nameDisplay?Y`<div class="name" title=${n}>${n}</div>`:null}
595
+ </div>
596
+ <div class="header-actions">
597
+ ${!t&&e.authentication?Y` <button
598
+ class="icon-btn header-btn"
599
+ @click=${l(this,Nt,"m",de).bind(this)}
600
+ aria-label=${a?"Logout":"Login"}
601
+ title=${a?"Logout":"Login"}
602
+ >
603
+ ${a?St.logout:St.login}
604
+ </button>`:null}
605
+ ${!t&&e.languageSelector?Y` <select
606
+ class="lang-select"
607
+ @change=${l(this,Nt,"m",ue).bind(this)}
608
+ .value=${o}
609
+ >
610
+ <option value="cs">🇨🇿</option>
611
+ <option value="en">🇬🇧</option>
612
+ <option value="de">🇩🇪</option>
613
+ </select>`:null}
614
+ ${e.minimize?Y` <button
615
+ class="icon-btn header-btn"
616
+ @click=${l(this,Nt,"m",ae).bind(this)}
617
+ aria-label=${r?"Maximize":"Minimize"}
618
+ title=${r?"Maximize":"Minimize"}
619
+ >
620
+ ${r?St.maximize:St.minimize}
621
+ </button>`:null}
622
+ ${e.close?Y` <button
623
+ class="icon-btn header-btn"
624
+ @click=${l(this,Nt,"m",ce).bind(this)}
625
+ aria-label="Close chat"
626
+ title="Close chat"
627
+ >
628
+ ${St.close}
629
+ </button>`:null}
630
+ </div>
631
+ </header>`}renderFloatingButton(t){return Y`<button class="floating-btn" @click=${t} aria-label="Open chat">
632
+ ${St.closed}
633
+ </button>`}renderMinimizedWindow(){return Y`<div class="wrap minimized">${this.renderHeaderBlock(!0)}</div>`}renderOpenWindow(t,e,i,n){const s=this.store.getState(),o=!1!==this.config.features?.sendButton,r=!1!==this.config.features?.stopButton,a=l(this,Nt,"m",Se).call(this),c=this.config.ui?.sendLabel??this.i18n.t("send"),h=this.i18n.t("stop"),d=!!l(this,Nt,"m",Pt).call(this)&&s.danaReconnectAttempt>=Ue.length;return Y` <div class="wrap open">
634
+ ${this.renderHeaderBlock(!1)}
635
+ <div class="messages">
636
+ ${function(t,e,i){const n=e?.trim(),s=i.labels||{};return Y` <div class="list">
637
+ ${n?Y` <div class="row left">
638
+ <div class="bubble assistant"><div class="bubble-text">${n}</div></div>
639
+ </div>`:null}
640
+ ${(t??[]).map(t=>{const e=t.metadata,n="assistant"===t.role||"system"===t.role,o=!n&&i.editingMessageId===t.id,r=Boolean(e?.isError),a=e?.technicalDetail,c=r&&(i.expandedErrorIds??[]).includes(t.id),l=!o&&!r&&(n?i.assistantRefresh||i.assistantCopy:i.userCopy||i.userEdit),h=l&&i.openActionsMessageId===t.id,d=e=>{e.preventDefault(),e.stopPropagation(),i.onAction?.("copy",t)},u=t.text?.trim()??"",p=Boolean(e?.streaming);return Y` <div class="row ${n?"left":"right"}">
641
+ <div
642
+ class="bubble ${n?"assistant":"user"} ${r?"error":""} ${h?"actions-open":""}"
643
+ >
644
+ <div class="bubble-text">
645
+ ${o?Y`<textarea
646
+ class="edit-textarea"
647
+ .value=${i.editDraft??t.text??""}
648
+ @input=${e=>{const n=e.currentTarget;i.onEditDraftChange?.(t,n?.value??"")}}
649
+ aria-label="Edit message"
650
+ ></textarea>`:n&&p&&!u?Y`<span class="typing-dots" aria-label="Typing"
651
+ ><span></span><span></span><span></span
652
+ ></span>`:u}
653
+ </div>
654
+
655
+ ${o?Y` <div class="edit-actions" role="group" aria-label="Edit actions">
656
+ <button type="button" class="icon-btn chip" @click=${e=>{e.preventDefault(),e.stopPropagation(),i.onEditCancel?.(t)}}>
657
+ ${s.cancel??"Cancel"}
658
+ </button>
659
+ <button type="button" class="icon-btn chip" @click=${e=>{e.preventDefault(),e.stopPropagation(),i.onEditConfirm?.(t,i.editDraft??t.text??"")}}>
660
+ ${s.confirm??"Confirm"}
661
+ </button>
662
+ </div>`:r&&a?Y` <div class="error-details">
663
+ <button type="button" class="error-details-toggle" @click=${e=>{e.preventDefault(),e.stopPropagation(),i.onToggleErrorDetails?.(t.id)}}>
664
+ ${c?s.hideDetails??"Hide details":s.showDetails??"Show details"}
665
+ </button>
666
+ ${c?Y`<div class="error-details-content">${a}</div>`:null}
667
+ </div>`:l?Y` <div class="bubble-actions" role="menu" aria-label="Message actions">
668
+ ${n?Y` ${At(i.assistantRefresh,St.refresh,s.refresh??"Refresh",e=>{e.preventDefault(),e.stopPropagation(),i.onAction?.("refresh",t)})}
669
+ ${At(i.assistantCopy,St.copy,s.copy??"Copy",d)}`:Y` ${At(i.userCopy,St.copy,s.copy??"Copy",d)}
670
+ ${At(i.userEdit,St.edit,s.edit??"Edit",e=>{e.preventDefault(),e.stopPropagation(),i.onAction?.("edit",t)})}`}
671
+ </div>
672
+ <button
673
+ type="button"
674
+ class="icon-btn more-btn"
675
+ title="More actions"
676
+ aria-label="More actions"
677
+ aria-haspopup="menu"
678
+ aria-expanded=${h?"true":"false"}
679
+ @click=${e=>{e.preventDefault(),e.stopPropagation(),i.onToggleActions?.(t)}}
680
+ >
681
+ ${St.more}
682
+ </button>`:null}
683
+ </div>
684
+ </div>`})}
685
+ ${i.reconnectFailed?Y` <div class="row center">
686
+ <div class="reconnect-block">
687
+ <span class="reconnect-label">${s.reconnectFailed??"Connection failed"}</span>
688
+ <button
689
+ type="button"
690
+ class="reconnect-btn"
691
+ @click=${t=>{t.preventDefault(),i.onReconnect?.()}}
692
+ >
693
+ ${St.refresh} ${s.reconnect??"Try reconnecting"}
694
+ </button>
695
+ </div>
696
+ </div>`:null}
697
+ </div>`}(t,this.config.ui?.introductionMessage??"",{assistantRefresh:!!this.config.features?.messageRefresh,assistantCopy:!!this.config.features?.messageCopy,userCopy:!!this.config.features?.messageCopy,userEdit:!!this.config.features?.messageEdit,openActionsMessageId:s.openActionsMessageId,onToggleActions:t=>l(this,Nt,"m",pe).call(this,t.id),onAction:async(t,e)=>{if(l(this,Nt,"m",me).call(this),"copy"!==t)if("edit"!==t){if("refresh"===t){const t=l(this,Nt,"m",Ie).call(this,this.store.getState().messages,e.id);if(!t)return;const i=this.store.getState().messages.findIndex(e=>e.id===t.id);if(i<0)return;this.store.setState({messages:this.store.getState().messages.slice(0,i+1)}),await l(this,Nt,"m",ye).call(this,t.text,{appendUser:!1,userMessageId:t.id,rewriteFromMessageId:t.id})}}else l(this,Nt,"m",Ce).call(this,e);else await l(this,Nt,"m",be).call(this,e.text??"")},editingMessageId:s.editingMessageId,editDraft:s.editDraft,onEditDraftChange:(t,e)=>this.store.setState({editDraft:e}),onEditCancel:()=>this.store.setState({editingMessageId:null,editDraft:""}),onEditConfirm:(t,e)=>{l(this,Nt,"m",Me).call(this,t,e)},expandedErrorIds:s.expandedErrorIds,onToggleErrorDetails:t=>l(this,Nt,"m",ge).call(this,t),reconnectFailed:d,onReconnect:()=>l(this,Nt,"m",Kt).call(this),labels:{refresh:this.i18n.t("refresh"),copy:this.i18n.t("copy"),edit:this.i18n.t("edit"),confirm:this.i18n.t("confirm"),cancel:this.i18n.t("cancel"),reconnect:this.i18n.t("reconnect"),reconnectFailed:this.i18n.t("reconnectFailed"),showDetails:this.i18n.t("showDetails"),hideDetails:this.i18n.t("hideDetails")}})}
698
+ </div>
699
+ <form class=${o?"":"no-send"} @submit=${i}>
700
+ <textarea
701
+ .rows=${a}
702
+ placeholder=${this.config.features?.placeholder&&this.config.ui?.placeholder||""}
703
+ aria-label=${this.config.ui?.placeholder||""}
704
+ ?disabled=${Boolean(e)}
705
+ @keydown=${n}
706
+ @input=${l(this,Nt,"m",ke).bind(this)}
707
+ ></textarea>
708
+ ${o?e&&r?Y`<button type="button" aria-label=${h} @click=${l(this,Nt,"m",$e).bind(this)}>
709
+ <span class="send-label">${h}</span>${St.stop}
710
+ </button>`:Y`<button type="submit" aria-label=${c} ?disabled=${Boolean(e)}>
711
+ ${c?Y`<span class="send-label">${c}</span>`:null}
712
+ ${St.send}
713
+ </button>`:null}
714
+ </form>
715
+ </div>`}render(){const t=this.store.getState();return"closed"===t.windowState?this.renderFloatingButton(l(this,Nt,"m",ae).bind(this)):"minimized"===t.windowState?this.renderMinimizedWindow():this.renderOpenWindow(t.messages,t.isStreaming,l(this,Nt,"m",xe).bind(this),l(this,Nt,"m",Ee).bind(this))}}return Nt=new WeakSet,Pt=function(){return String(this.config.api?.danaUrl||"").trim()},zt=function(){return String(this.config.api?.lumaUrl||"").trim()},Bt=function(t){this.store.getState().danaStatus!==t&&this.store.setState({danaStatus:t}),"offline"===t&&l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Ht).call(this),"online"===t&&(l(this,Nt,"m",Wt).call(this),this.store.setState({danaReconnectAttempt:0}))},Ht=function(){l(this,Nt,"m",Pt).call(this)&&null===this._danaReconnectTimer&&null===this._danaReconnectAbort&&l(this,Nt,"m",jt).call(this,this.store.getState().danaReconnectAttempt)},jt=function(t){l(this,Nt,"m",Pt).call(this)&&(t>=Ue.length?this.store.setState({danaReconnectAttempt:t,danaStatus:"offline"}):(this.store.setState({danaReconnectAttempt:t,danaStatus:"connecting"}),this._danaReconnectTimer=setTimeout(()=>{this._danaReconnectTimer=null,l(this,Nt,"m",Ft).call(this,t)},Ue[t])))},Ft=async function(t){if(!l(this,Nt,"m",Pt).call(this))return;const e=new AbortController;this._danaReconnectAbort=e;try{const i=Et(l(this,Nt,"m",Pt).call(this)),n=setTimeout(()=>e.abort(),5e3);let s=!1;try{const t=await fetch(_t(`${i}/api/health`),{method:"GET",signal:e.signal,headers:{accept:"application/json"}});if(200===t.status)try{const e=await t.json();s="ok"===e?.status}catch{s=!0}}finally{clearTimeout(n)}this._danaReconnectAbort=null,s?(l(this,Nt,"m",Wt).call(this),l(this,Nt,"m",Bt).call(this,"online")):l(this,Nt,"m",jt).call(this,t+1)}catch{this._danaReconnectAbort=null,l(this,Nt,"m",jt).call(this,t+1)}},Wt=function(){if(null!==this._danaReconnectTimer&&(clearTimeout(this._danaReconnectTimer),this._danaReconnectTimer=null),null!==this._danaReconnectAbort){try{this._danaReconnectAbort.abort()}catch{}this._danaReconnectAbort=null}},Kt=function(){l(this,Nt,"m",Wt).call(this),this.store.setState({danaReconnectAttempt:0}),l(this,Nt,"m",jt).call(this,0)},Vt=function(t){l(this,Nt,"m",zt).call(this)&&(t>=Ue.length?this.store.setState({lumaReconnectAttempt:t}):(this.store.setState({lumaReconnectAttempt:t,lumaStatus:"connecting"}),this._lumaReconnectTimer=setTimeout(()=>{this._lumaReconnectTimer=null,l(this,Nt,"m",qt).call(this,t)},Ue[t])))},qt=async function(t){if(!l(this,Nt,"m",zt).call(this))return;const e=await r(l(this,Nt,"m",zt).call(this),6e3),i=De(e.status);this.store.setState({lumaStatus:i}),"ok"===e.status?(this.updateConfig(e.config),this.store.setState({lumaReconnectAttempt:0})):l(this,Nt,"m",Vt).call(this,t+1)},Zt=function(){null!==this._lumaReconnectTimer&&(clearTimeout(this._lumaReconnectTimer),this._lumaReconnectTimer=null)},Jt=function(t){const e=this.config.ui?.errorMessage;return e&&e.trim()?e.trim():this.i18n.t(function(t){return{DANA_UNAVAILABLE:"errorDanaUnavailable",DANA_TIMEOUT:"errorDanaTimeout",PROXY_ERROR:"errorProxyError",DANA_LLM_UNAVAILABLE:"errorDanaLlmUnavailable",DANA_LLM_AUTH:"errorDanaLlmAuth",DANA_LLM_TIMEOUT:"errorDanaLlmTimeout",DANA_INTERNAL:"errorDanaInternal",NETWORK_ERROR:"errorNetwork",OFFLINE:"errorOffline",UNKNOWN:"errorUnknown"}[t]??"errorUnknown"}(t))},Yt=function(e,i){const n=l(this,Nt,"m",Jt).call(this,e),s={id:t("e"),role:"system",text:n,timestamp:Date.now(),metadata:{isError:!0,errorCode:e,technicalDetail:i||e}},o=this.store.getState().messages;this.store.setState({messages:[...o,s]}),console.error(`[OCWI] Error [${e}]`,i||e)},Gt=function(){const t=l(this,Nt,"m",Pt).call(this),e=t||"mock";t?(this.api=new Dt(this.config),l(this,Nt,"m",Bt).call(this,"offline")):(this.api=new Ut,this.store.setState({danaStatus:"mock"})),this._apiKey!==e&&(this._apiKey=e,l(this,Nt,"m",Wt).call(this),this.store.setState({conversationId:null,messages:[],openActionsMessageId:null,expandedErrorIds:[],editingMessageId:null,editDraft:"",isStreaming:!1,status:"idle",danaReconnectAttempt:0}),l(this,Nt,"m",ee).call(this))},Xt=function(){return`ocwi_conversationId::${l(this,Nt,"m",Pt).call(this)||"mock"}`},Qt=function(){try{return localStorage.getItem(l(this,Nt,"m",Xt).call(this))||null}catch{return null}},te=function(t){try{const e=l(this,Nt,"m",Xt).call(this);t?localStorage.setItem(e,t):localStorage.removeItem(e)}catch{}},ee=async function(){const t=l(this,Nt,"m",Qt).call(this);if(t){this.store.setState({conversationId:t});try{const e=await this.api.getMessages(t);Array.isArray(e)&&e.length&&this.store.setState({messages:e}),l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"online")}catch{l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"offline")}}},ie=function(){const t=this.config.theme||{},e={"--ocwi-primary":t.primary,"--ocwi-z-index":t.ocwiZIndex,"--ocwi-width":t.ocwiWidth,"--ocwi-height":t.ocwiHeight,"--ocwi-radius":t.ocwiRadius,"--ocwi-spacing":t.ocwiSpacing,"--ocwi-bg":t.ocwiBg,"--ocwi-border":t.ocwiBorder,"--ocwi-header-bg":t.ocwiHeaderBg,"--ocwi-header-text":t.ocwiHeaderText,"--ocwi-bubble-user-bg":t.ocwiBubbleUserBg,"--ocwi-bubble-user-text":t.ocwiBubbleUserText,"--ocwi-bubble-assistant-bg":t.ocwiBubbleAssistantBg,"--ocwi-bubble-assistant-text":t.ocwiBubbleAssistantText,"--ocwi-bubble-max-width":t.ocwiBubbleMaxWidth,"--ocwi-input-bg":t.ocwiInputBg,"--ocwi-input-text":t.ocwiInputText,"--ocwi-input-placeholder":t.ocwiInputPlaceholder,"--ocwi-send-bg":t.ocwiSendBg,"--ocwi-send-text":t.ocwiSendText,"--ocwi-fab-bg":t.ocwiFabBg,"--ocwi-fab-text":t.ocwiFabText};for(const[t,i]of Object.entries(e))void 0!==i&&(i?this.style.setProperty(t,String(i)):this.style.removeProperty(t))},ne=function(){this.style.position="fixed",this.style.zIndex="var(--ocwi-z-index, 2147480000)";const t=this.config.ui?.position||"bottom-right",e={"top-left":{top:"16px",left:"16px"},"top-center":{top:"16px",left:"50%",transform:"translateX(-50%)"},"top-right":{top:"16px",right:"16px"},"center-left":{top:"50%",left:"16px",transform:"translateY(-50%)"},center:{top:"50%",left:"50%",transform:"translate(-50%,-50%)"},"center-right":{top:"50%",right:"16px",transform:"translateY(-50%)"},"bottom-left":{bottom:"16px",left:"16px"},"bottom-center":{bottom:"16px",left:"50%",transform:"translateX(-50%)"},"bottom-right":{bottom:"16px",right:"16px"}};Object.assign(this.style,{top:"auto",right:"auto",bottom:"auto",left:"auto",transform:""}),Object.assign(this.style,e[t]||e["bottom-right"])},se=function(){const t=this.config.watermark;if(!this.config.features?.watermark||!t?.imageUrl)return void this.style.setProperty("--ocwi-watermark-image","none");const e={none:"no-repeat",horizontal:"repeat-x",vertical:"repeat-y",both:"repeat"}[t.repeatMode??"none"],i={"top-left":"left 1rem top 1rem","top-right":"right 1rem top 1rem","bottom-left":"left 1rem bottom 1rem","bottom-right":"right 1rem bottom 1rem",middle:"center"}[t.position??"middle"],n=Math.max(1,Math.round(200*("number"==typeof t.scale?t.scale:1)));this.style.setProperty("--ocwi-watermark-image",`url("${t.imageUrl}")`),this.style.setProperty("--ocwi-watermark-repeat",e),this.style.setProperty("--ocwi-watermark-position",i),this.style.setProperty("--ocwi-watermark-size",`${n}px auto`)},oe=function(){const t=this.config.ui??{};"auto"===t.fontSize||null==t.fontSize?this.style.removeProperty("--ocwi-message-font"):this.style.setProperty("--ocwi-message-font",`${t.fontSize}px`)},re=function(){const{danaStatus:t,lumaStatus:e}=this.store.getState(),i=!!l(this,Nt,"m",zt).call(this),n=Te[t],s=i?Le[e]:n,o=Oe.includes(t)||i&&Re.includes(e),r=i?this.i18n.t(`statusLuma${e.charAt(0).toUpperCase()+e.slice(1)}`):"",a=this.i18n.t(`statusDana${t.charAt(0).toUpperCase()+t.slice(1)}`),c=i?`${r} · ${a}`:a;return Y` <span
716
+ class="status-dot ${o?"is-pulsing":""}"
717
+ style="--luma-clr:${s};--dana-clr:${n}"
718
+ title=${c}
719
+ aria-label=${c}
720
+ role="status"
721
+ ></span>`},ae=function(){this._userChangedWindowState=!0;const t=this.store.getState().windowState;this.store.setState("closed"===t?{windowState:"open"}:"open"===t?{windowState:"minimized"}:{windowState:"open"})},ce=function(){this._userChangedWindowState=!0,this.store.setState({windowState:"closed"}),l(this,Nt,"m",le).call(this)},le=async function(){try{this.api.stop()}catch{}const t=this.store.getState().conversationId||void 0;this.store.setState({messages:[],openActionsMessageId:null,expandedErrorIds:[],editingMessageId:null,editDraft:"",isStreaming:!1,status:"idle"});try{const e=await this.api.resetChat(t),i=String(e?.conversationId||"").trim();this.store.setState({conversationId:i||null}),l(this,Nt,"m",te).call(this,i||null),l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"online")}catch{l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"offline"),this.store.setState({conversationId:null}),l(this,Nt,"m",te).call(this,null)}},he=function(){if(this._userChangedWindowState)return;const t=this.config.ui?.initialState||"collapsed";let e="closed";"expanded"===t?e="open":"minimized"===t&&(e=!1===(this.config.features||{}).minimize?"open":"minimized"),this.store.getState().windowState!==e&&this.store.setState({windowState:e})},de=function(){this.store.setState({loggedIn:!this.store.getState().loggedIn})},ue=function(t){const e=(t.currentTarget?.value||"en").trim();this.updateConfig({i18n:{lang:e}})},pe=function(t){const e=this.store.getState().openActionsMessageId;this.store.setState({openActionsMessageId:e===t?null:t})},me=function(){null!==this.store.getState().openActionsMessageId&&this.store.setState({openActionsMessageId:null})},fe=function(){null!==this.store.getState().editingMessageId&&this.store.setState({editingMessageId:null,editDraft:""})},ge=function(t){const e=this.store.getState().expandedErrorIds,i=e.includes(t)?e.filter(e=>e!==t):[...e,t];this.store.setState({expandedErrorIds:i})},be=async function(t){if(navigator.clipboard?.writeText)try{return await navigator.clipboard.writeText(t),!0}catch{}const e=document.createElement("textarea");e.value=t,e.style.cssText="position:fixed;top:-9999px;left:-9999px",e.readOnly=!0,document.body.appendChild(e);try{return e.select(),e.setSelectionRange(0,t.length),document.execCommand("copy")}catch{return!1}finally{document.body.removeChild(e)}},we=function(t,e){const i=this.store.getState().messages,n=i.findIndex(e=>e.id===t);if(n<0)return;const s=i.slice();s[n]={...s[n],...e},this.store.setState({messages:s})},ve=function(t,e){if(!t||!e||t===e)return;const i=this.store.getState().messages,n=i.findIndex(e=>e.id===t);if(n<0)return;const s=i.slice();s[n]={...s[n],id:e};const o=this.store.getState().openActionsMessageId;this.store.setState({messages:s,openActionsMessageId:o===t?e:o})},ye=async function(e,i){const n=this.store.getState();if(n.isStreaming)return;const s=String(e||"").trim();if(!s)return;l(this,Nt,"m",me).call(this),l(this,Nt,"m",fe).call(this);const o=(i.userMessageId||t("u")).trim();let r=this.store.getState().messages;i.appendUser&&(r=[...r,{id:o,role:"user",text:s,timestamp:Date.now()}]);let a=t("a");r=[...r,{id:a,role:"assistant",text:"",timestamp:Date.now(),metadata:{streaming:!0}}],this.store.setState({messages:r,status:"sending",isStreaming:!0,openActionsMessageId:null}),l(this,Nt,"m",Pt).call(this)?(l(this,Nt,"m",Wt).call(this),l(this,Nt,"m",Bt).call(this,"connecting")):this.store.setState({danaStatus:"mock"});const c={prompt:s,conversationId:n.conversationId||void 0,clientMessageId:o,rewriteFromMessageId:i.rewriteFromMessageId};let h="";try{const t=await this.api.sendMessageStream(c,{onMeta:t=>{const e=String(t?.conversationId||"").trim();e&&e!==this.store.getState().conversationId&&(this.store.setState({conversationId:e}),l(this,Nt,"m",te).call(this,e));const i=String(t?.assistantMessageId||"").trim();i&&i!==a&&(l(this,Nt,"m",ve).call(this,a,i),a=i)},onChunk:t=>{h+=t,l(this,Nt,"m",we).call(this,a,{text:h,metadata:{streaming:!0}})}}),e=(h||t.assistant?.text||"").toString(),i=Boolean(t.stopped);l(this,Nt,"m",we).call(this,a,{text:e+(i?`\n\n[${this.i18n.t("generationStopped")}]`:""),timestamp:Date.now(),metadata:i?{stopped:!0}:void 0}),this.store.setState({status:"idle"}),l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"online"),this.bus.emit("message:received",{id:a,role:"assistant",text:e,timestamp:Date.now()})}catch(t){const e=this.store.getState().messages.filter(t=>t.id!==a);this.store.setState({messages:e,status:"error"}),l(this,Nt,"m",Pt).call(this)&&l(this,Nt,"m",Bt).call(this,"offline");const i="undefined"==typeof navigator||navigator.onLine,n=t?.text||t?.message||String(t||""),s=t?.metadata?.errorCode,o=s??It(n,!i),r=t?.metadata?.technicalDetail??n;l(this,Nt,"m",Yt).call(this,o,r),this.bus.emit("error",n)}finally{this.store.setState({isStreaming:!1})}},xe=function(e){if(e.preventDefault(),this.store.getState().isStreaming)return;const i=this.renderRoot?.querySelector("textarea"),n=(i?.value||"").trim();if(!n)return;i&&(i.value="",i.style.height="auto");const s={id:t("u"),role:"user",text:n,timestamp:Date.now()};this.bus.emit("message:sent",s),l(this,Nt,"m",ye).call(this,n,{appendUser:!0,userMessageId:s.id})},$e=function(){if(this.store.getState().isStreaming)try{this.api.stop()}catch{}},Se=function(){const t=Number(this.config.theme?.ocwiInputRows??1);return Number.isFinite(t)?Math.max(1,Math.min(10,Math.floor(t))):1},Ae=function(t){t.style.height="auto";const e=parseFloat(getComputedStyle(t).maxHeight||""),i=t.scrollHeight;t.style.height=Number.isFinite(e)&&e>0?`${Math.min(i,e)}px`:`${i}px`},_e=function(){if("open"!==this.store.getState().windowState)return;const t=this.renderRoot.querySelector(".wrap.open"),e=t?.querySelector("header"),i=t?.querySelector(".messages"),n=t?.querySelector("form"),s=n?.querySelector("textarea");if(!(t&&e&&i&&n&&s))return;const o=t.getBoundingClientRect().height,r=e.getBoundingClientRect().height;if(!Number.isFinite(o)||o<=0)return;const a=getComputedStyle(i),c=o-r-3*(parseFloat(a.paddingTop||"0")+parseFloat(a.paddingBottom||"0")+22),h=getComputedStyle(n),d=parseFloat(h.paddingTop||"0")+parseFloat(h.paddingBottom||"0")+parseFloat(h.borderTopWidth||"0")+parseFloat(h.borderBottomWidth||"0"),u=Math.max(36,Math.floor(c-d));if(!Number.isFinite(u)||u<=0)return;const p=`${u}px`;this.style.getPropertyValue("--ocwi-composer-max-height").trim()!==p&&this.style.setProperty("--ocwi-composer-max-height",p),l(this,Nt,"m",Ae).call(this,s)},ke=function(t){const e=t.currentTarget;e instanceof HTMLTextAreaElement&&l(this,Nt,"m",Ae).call(this,e)},Ee=function(t){const e=t.currentTarget;if("Escape"===t.key)return e.value="",e.style.height="auto",void t.stopPropagation();if("Enter"!==t.key)return;const i=t.ctrlKey||t.metaKey;({Enter:!t.shiftKey&&!t.altKey&&!i,"Shift+Enter":t.shiftKey&&!t.altKey&&!i,"Alt+Enter":t.altKey&&!t.shiftKey&&!i,"Ctrl+Enter":i&&!t.shiftKey&&!t.altKey,None:!1})[this.config.ui?.keybindForSend||"Enter"]&&(t.preventDefault(),t.stopPropagation(),this.renderRoot?.querySelector("form")?.requestSubmit())},Ce=function(t){"user"===t.role&&(l(this,Nt,"m",me).call(this),this.store.setState({editingMessageId:t.id,editDraft:t.text||""}))},Me=async function(t,e){if("user"!==t.role)return;const i=String(e||"").trim();if(!i)return;const n=this.store.getState().messages,s=n.findIndex(e=>e.id===t.id);if(s<0)return;const o=n.slice(0,s+1).map(e=>e.id===t.id?{...e,text:i,timestamp:Date.now()}:e);this.store.setState({messages:o,editingMessageId:null,editDraft:""}),await l(this,Nt,"m",ye).call(this,i,{appendUser:!1,userMessageId:t.id,rewriteFromMessageId:t.id})},Ie=function(t,e){const i=t.findIndex(t=>t.id===e);if(i<=0)return null;for(let e=i-1;e>=0;e--)if("user"===t[e].role)return t[e];return null},Ne.styles=gt,Ne.properties={config:{attribute:!1}},customElements.get("ocwi-chat")||customElements.define("ocwi-chat",Ne),function(t,i){const n=function(t){return"string"==typeof t?document.querySelector(t)||(console.warn(`[OCWI] Target selector "${t}" not found. Falling back to document.body.`),document.body):t instanceof Element?t:document.body}(t),o=document.createElement("ocwi-chat");o.config=e(s);const l=i?.api?.lumaUrl||i?.remote?.url||o.config.api?.lumaUrl,h=l?function(t){const e=String(t||"").trim();if(!e)return null;const i=function(t){if("undefined"==typeof document)return null;const e=document.cookie?document.cookie.split("; "):[];for(const i of e){const e=i.indexOf("=");if((e>=0?i.slice(0,e):i)===t)return e>=0?i.slice(e+1):""}return null}(a(e));if(!i)return null;const n=function(t){if(!t)return null;try{return JSON.parse(t)}catch{return null}}((()=>{try{return decodeURIComponent(i)}catch{return i}})());return n&&1===n.v&&n.config&&"object"==typeof n.config?n.config:null}(l):null;if(h)return o.updateConfig(h),o.setInitialLumaStatus("ok"),n.appendChild(o),i&&o.updateConfig(i),(async()=>{try{const t=await r(l);"ok"===t.status&&t.config&&Object.keys(t.config).length&&c(l??"",t.config),o.setInitialLumaStatus(t.status)}catch{}})(),o;if(l){const t=function(){const t=document.createElement("div");return t.setAttribute("data-ocwi-loading","true"),t.setAttribute("role","status"),t.setAttribute("aria-label","Loading chat"),t.style.cssText=["position:fixed","inset:auto 16px 16px auto","z-index:2147480000","width:77px","height:77px","border-radius:9999px","background:var(--ocwi-fab-bg, var(--ocwi-primary, var(--color-blue-600, #2563eb)))","color:var(--ocwi-fab-text, #ffffff)","display:grid","place-items:center","box-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05)","font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial","user-select:none","cursor:progress"].join(";"),t.innerHTML='\n <svg width="36" height="36" viewBox="0 0 24 24" fill="none" aria-hidden="true">\n <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-opacity="0.25" stroke-width="3"></circle>\n <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" stroke-width="3">\n <animateTransform attributeName="transform" type="rotate" from="0 12 12" to="360 12 12" dur="0.9s" repeatCount="indefinite"/>\n </path>\n </svg>\n ',t}();return n.appendChild(t),(async()=>{const e=await r(l).catch(()=>({config:{},status:"network_error"}));try{"ok"===e.status&&e.config&&Object.keys(e.config).length&&(o.updateConfig(e.config),c(l,e.config))}catch{}finally{try{t.remove()}catch{}o.setInitialLumaStatus(e.status),i&&o.updateConfig(i),n.appendChild(o)}})(),o}return n.appendChild(o),i&&o.updateConfig(i),o}}();
722
+ //# sourceMappingURL=ocwi.min.js.map