@mbubela/oaa-assistant 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,6 +46,6 @@ Then use in templates:
46
46
 
47
47
  ## Build Info
48
48
 
49
- Built: NPM_Publish_20251217.6
50
- Commit: c17df012c5c47c7c46fe95115d7de567b644ced7
51
- Version: 0.0.12
49
+ Built: NPM_Publish_20251217.7
50
+ Commit: ee66f110e8c8a96c50a92a31ef0df30ccd2d3b95
51
+ Version: 0.0.13
@@ -21,7 +21,7 @@ ${t.map((n,r)=>`${r+1}) ${n.toString()}`).join(`
21
21
  <path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>`},check:{viewBox:"0 0 24 24",path:'<polyline points="20 6 9 17 4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>'},"chevron-left":{viewBox:"0 0 24 24",path:'<polyline points="15 18 9 12 15 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>'},"more-horizontal":{viewBox:"0 0 24 24",path:`<circle cx="12" cy="12" r="1.5" fill="currentColor"/>
22
22
  <circle cx="19" cy="12" r="1.5" fill="currentColor"/>
23
23
  <circle cx="5" cy="12" r="1.5" fill="currentColor"/>`}},ln=class $s{constructor(t){this.sanitizer=t}name="";width="24";height="24";fill="none";dropShadow="";get viewBox(){return Hl[this.name]?.viewBox||"0 0 24 24"}get svgContent(){let t=Hl[this.name];if(!t)return"";let n=t.path+(t.defs||"");return this.sanitizer.bypassSecurityTrustHtml(n)}static \u0275fac=function(t){return new(t||$s)(j(tp))};static \u0275cmp=Ie({type:$s,selectors:[["app-icon"]],inputs:{name:"name",width:"width",height:"height",fill:"fill",dropShadow:"dropShadow"},decls:1,vars:7,consts:[["xmlns","http://www.w3.org/2000/svg",3,"innerHTML"]],template:function(t,n){t&1&&(im(),ch(0,"svg",0)),t&2&&(Ch("filter",n.dropShadow),fh("innerHTML",n.svgContent,yd),ia("width",n.width)("height",n.height)("viewBox",n.viewBox)("fill",n.fill))},dependencies:[_e],styles:["[_nghost-%COMP%]{display:inline-block;line-height:0}"]})},Be={TITLE:"App Agent",WELCOME:{GREETING:"Hi!",TEXT:"Welcome to Open as App!",DESCRIPTION:"I'm your AI assistant, and I'm here to help you get started.",PERSONALIZATION:"To personalize my guidance, could you tell me what you're hoping to do?"},INPUT:{PLACEHOLDER:"Ask me anything..."},SUGGESTIONS:["Summarize data","What are the key columns","What is this app about"]},V_=class qs{title=Be.TITLE;menuClick=new F;closeClick=new F;onMenuClick(){this.menuClick.emit()}onCloseClick(){this.closeClick.emit()}static \u0275fac=function(t){return new(t||qs)};static \u0275cmp=Ie({type:qs,selectors:[["app-header"]],inputs:{title:"title"},outputs:{menuClick:"menuClick",closeClick:"closeClick"},decls:9,vars:1,consts:[[1,"header"],["aria-label","Menu",1,"icon-button","menu-button",3,"click"],["name","menu","width","24","height","24"],[1,"header-title"],["name","sparkle","width","24","height","24",1,"title-icon"],["aria-label","Close",1,"icon-button","close-button",3,"click"],["name","close","width","24","height","24"]],template:function(t,n){t&1&&(f(0,"div",0)(1,"button",1),M("click",function(){return n.onMenuClick()}),q(2,"app-icon",2),y(),f(3,"div",3),q(4,"app-icon",4),f(5,"span"),z(6),y()(),f(7,"button",5),M("click",function(){return n.onCloseClick()}),q(8,"app-icon",6),y()()),t&2&&(x(6),Ee(n.title))},dependencies:[_e,ln],styles:[".header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#fff;border-bottom:1px solid #f0f0f0;min-height:56px;box-sizing:border-box;flex-shrink:0}@media (max-width: 768px){.header[_ngcontent-%COMP%]{min-height:52px;padding:10px 12px}}.icon-button[_ngcontent-%COMP%]{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:8px;transition:background-color .2s;color:#333}.icon-button[_ngcontent-%COMP%]:hover{background-color:#f5f5f5}.icon-button[_ngcontent-%COMP%]:active{background-color:#e0e0e0}.header-title[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;font-size:20px;font-weight:600;color:#ff6b6b;flex:1;justify-content:center}.title-icon[_ngcontent-%COMP%]{width:24px;height:24px}.menu-button[_ngcontent-%COMP%], .close-button[_ngcontent-%COMP%]{width:40px;height:40px}.close-button[_ngcontent-%COMP%]{background-color:#f5f5f5;border-radius:50%}.close-button[_ngcontent-%COMP%]:hover{background-color:#e8e8e8}"]})},N_=class Zs{text="";disabled=!1;buttonClick=new F;onClick(){this.disabled||this.buttonClick.emit(this.text)}static \u0275fac=function(t){return new(t||Zs)};static \u0275cmp=Ie({type:Zs,selectors:[["app-suggestion-button"]],inputs:{text:"text",disabled:"disabled"},outputs:{buttonClick:"buttonClick"},decls:2,vars:3,consts:[[1,"suggestion-button",3,"click"]],template:function(t,n){t&1&&(sa(0,"button",0),gh("click",function(){return n.onClick()}),z(1),oa()),t&2&&(Te("disabled",n.disabled),x(),Vn(" ",n.text," "))},dependencies:[_e],styles:[".suggestion-button[_ngcontent-%COMP%]{background:#fff;border:1.5px solid #FF6B6B;border-radius:8px;padding:14px 24px;font-size:15px;font-weight:500;color:#ff6b6b;cursor:pointer;transition:all .2s ease;white-space:nowrap;box-shadow:0 2px 4px #0000000d;display:inline-block;width:auto;text-align:center}.suggestion-button[_ngcontent-%COMP%]:hover:not(.disabled){background:#fff5f5;border-color:#ff5252;transform:translateY(-1px);box-shadow:0 4px 8px #ff6b6b26}.suggestion-button[_ngcontent-%COMP%]:active:not(.disabled){transform:translateY(0);box-shadow:0 2px 4px #0000000d}.suggestion-button.disabled[_ngcontent-%COMP%]{opacity:.5;cursor:not-allowed}"]})},rp=(()=>{class e{_renderer;_elementRef;onChange=n=>{};onTouched=()=>{};constructor(n,r){this._renderer=n,this._elementRef=r}setProperty(n,r){this._renderer.setProperty(this._elementRef.nativeElement,n,r)}registerOnTouched(n){this.onTouched=n}registerOnChange(n){this.onChange=n}setDisabledState(n){this.setProperty("disabled",n)}static \u0275fac=function(n){return new(n||e)(j(Xo),j(Et))};static \u0275dir=Ce({type:e})}return e})(),R_=(()=>{class e extends rp{static \u0275fac=(()=>{let n;return function(r){return(n||(n=Zc(e)))(r||e)}})();static \u0275dir=Ce({type:e,features:[on]})}return e})(),ip=new S(""),L_={provide:ip,useExisting:Nn(()=>qn),multi:!0};function F_(){let e=ei()?ei().getUserAgent():"";return/android (\d+)/.test(e.toLowerCase())}var j_=new S(""),qn=(()=>{class e extends rp{_compositionMode;_composing=!1;constructor(n,r,i){super(n,r),this._compositionMode=i,this._compositionMode==null&&(this._compositionMode=!F_())}writeValue(n){let r=n??"";this.setProperty("value",r)}_handleInput(n){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(n)}_compositionStart(){this._composing=!0}_compositionEnd(n){this._composing=!1,this._compositionMode&&this.onChange(n)}static \u0275fac=function(n){return new(n||e)(j(Xo),j(Et),j(j_,8))};static \u0275dir=Ce({type:e,selectors:[["input","formControlName","",3,"type","checkbox"],["textarea","formControlName",""],["input","formControl","",3,"type","checkbox"],["textarea","formControl",""],["input","ngModel","",3,"type","checkbox"],["textarea","ngModel",""],["","ngDefaultControl",""]],hostBindings:function(n,r){n&1&&M("input",function(i){return r._handleInput(i.target.value)})("blur",function(){return r.onTouched()})("compositionstart",function(){return r._compositionStart()})("compositionend",function(i){return r._compositionEnd(i.target.value)})},standalone:!1,features:[ua([L_]),on]})}return e})();function z_(e){return e==null?null:Array.isArray(e)||typeof e=="string"?e.length:e instanceof Set?e.size:null}var sp=new S(""),H_=new S("");function B_(e){return t=>{let n=t.value?.length??z_(t.value);return n!==null&&n>e?{maxlength:{requiredLength:e,actualLength:n}}:null}}function Bl(e){return null}function op(e){return e!=null}function ap(e){return ra(e)?ho(e):e}function lp(e){let t={};return e.forEach(n=>{t=n!=null?T(T({},t),n):t}),Object.keys(t).length===0?null:t}function up(e,t){return t.map(n=>n(e))}function U_(e){return!e.validate}function cp(e){return e.map(t=>U_(t)?t:n=>t.validate(n))}function $_(e){if(!e)return null;let t=e.filter(op);return t.length==0?null:function(n){return lp(up(n,t))}}function dp(e){return e!=null?$_(cp(e)):null}function q_(e){if(!e)return null;let t=e.filter(op);return t.length==0?null:function(n){let r=up(n,t).map(ap);return Yf(r).pipe(Oe(lp))}}function hp(e){return e!=null?q_(cp(e)):null}function Ul(e,t){return e===null?[t]:Array.isArray(e)?[...e,t]:[e,t]}function Z_(e){return e._rawValidators}function G_(e){return e._rawAsyncValidators}function Gs(e){return e?Array.isArray(e)?e:[e]:[]}function ni(e,t){return Array.isArray(e)?e.includes(t):e===t}function $l(e,t){let n=Gs(t);return Gs(e).forEach(r=>{ni(n,r)||n.push(r)}),n}function ql(e,t){return Gs(t).filter(n=>!ni(e,n))}var pp=class{get value(){return this.control?this.control.value:null}get valid(){return this.control?this.control.valid:null}get invalid(){return this.control?this.control.invalid:null}get pending(){return this.control?this.control.pending:null}get disabled(){return this.control?this.control.disabled:null}get enabled(){return this.control?this.control.enabled:null}get errors(){return this.control?this.control.errors:null}get pristine(){return this.control?this.control.pristine:null}get dirty(){return this.control?this.control.dirty:null}get touched(){return this.control?this.control.touched:null}get status(){return this.control?this.control.status:null}get untouched(){return this.control?this.control.untouched:null}get statusChanges(){return this.control?this.control.statusChanges:null}get valueChanges(){return this.control?this.control.valueChanges:null}get path(){return null}_composedValidatorFn;_composedAsyncValidatorFn;_rawValidators=[];_rawAsyncValidators=[];_setValidators(e){this._rawValidators=e||[],this._composedValidatorFn=dp(this._rawValidators)}_setAsyncValidators(e){this._rawAsyncValidators=e||[],this._composedAsyncValidatorFn=hp(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn||null}get asyncValidator(){return this._composedAsyncValidatorFn||null}_onDestroyCallbacks=[];_registerOnDestroy(e){this._onDestroyCallbacks.push(e)}_invokeOnDestroyCallbacks(){this._onDestroyCallbacks.forEach(e=>e()),this._onDestroyCallbacks=[]}reset(e=void 0){this.control&&this.control.reset(e)}hasError(e,t){return this.control?this.control.hasError(e,t):!1}getError(e,t){return this.control?this.control.getError(e,t):null}},W_=class extends pp{name;get formDirective(){return null}get path(){return null}},va=class extends pp{_parent=null;name=null;valueAccessor=null},Q_=class{_cd;constructor(e){this._cd=e}get isTouched(){return this._cd?.control?._touched?.(),!!this._cd?.control?.touched}get isUntouched(){return!!this._cd?.control?.untouched}get isPristine(){return this._cd?.control?._pristine?.(),!!this._cd?.control?.pristine}get isDirty(){return!!this._cd?.control?.dirty}get isValid(){return this._cd?.control?._status?.(),!!this._cd?.control?.valid}get isInvalid(){return!!this._cd?.control?.invalid}get isPending(){return!!this._cd?.control?.pending}get isSubmitted(){return this._cd?._submitted?.(),!!this._cd?.submitted}},Y_={"[class.ng-untouched]":"isUntouched","[class.ng-touched]":"isTouched","[class.ng-pristine]":"isPristine","[class.ng-dirty]":"isDirty","[class.ng-valid]":"isValid","[class.ng-invalid]":"isInvalid","[class.ng-pending]":"isPending"},ox=D(T({},Y_),{"[class.ng-submitted]":"isSubmitted"}),ya=(()=>{class e extends Q_{constructor(n){super(n)}static \u0275fac=function(n){return new(n||e)(j(va,2))};static \u0275dir=Ce({type:e,selectors:[["","formControlName",""],["","ngModel",""],["","formControl",""]],hostVars:14,hostBindings:function(n,r){n&2&&Te("ng-untouched",r.isUntouched)("ng-touched",r.isTouched)("ng-pristine",r.isPristine)("ng-dirty",r.isDirty)("ng-valid",r.isValid)("ng-invalid",r.isInvalid)("ng-pending",r.isPending)},standalone:!1,features:[on]})}return e})(),hn="VALID",ar="INVALID",At="PENDING",pn="DISABLED",Zn=class{},Zl=class extends Zn{value;source;constructor(e,t){super(),this.value=e,this.source=t}},os=class extends Zn{pristine;source;constructor(e,t){super(),this.pristine=e,this.source=t}},as=class extends Zn{touched;source;constructor(e,t){super(),this.touched=e,this.source=t}},lr=class extends Zn{status;source;constructor(e,t){super(),this.status=e,this.source=t}},K_=class extends Zn{source;constructor(e){super(),this.source=e}};function J_(e){return(Mi(e)?e.validators:e)||null}function X_(e){return Array.isArray(e)?dp(e):e||null}function ew(e,t){return(Mi(t)?t.asyncValidators:e)||null}function tw(e){return Array.isArray(e)?hp(e):e||null}function Mi(e){return e!=null&&!Array.isArray(e)&&typeof e=="object"}var nw=class{_pendingDirty=!1;_hasOwnPendingAsyncValidator=null;_pendingTouched=!1;_onCollectionChange=()=>{};_updateOn;_parent=null;_asyncValidationSubscription;_composedValidatorFn;_composedAsyncValidatorFn;_rawValidators;_rawAsyncValidators;value;constructor(e,t){this._assignValidators(e),this._assignAsyncValidators(t)}get validator(){return this._composedValidatorFn}set validator(e){this._rawValidators=this._composedValidatorFn=e}get asyncValidator(){return this._composedAsyncValidatorFn}set asyncValidator(e){this._rawAsyncValidators=this._composedAsyncValidatorFn=e}get parent(){return this._parent}get status(){return It(this.statusReactive)}set status(e){It(()=>this.statusReactive.set(e))}_status=it(()=>this.statusReactive());statusReactive=ae(void 0);get valid(){return this.status===hn}get invalid(){return this.status===ar}get pending(){return this.status==At}get disabled(){return this.status===pn}get enabled(){return this.status!==pn}errors;get pristine(){return It(this.pristineReactive)}set pristine(e){It(()=>this.pristineReactive.set(e))}_pristine=it(()=>this.pristineReactive());pristineReactive=ae(!0);get dirty(){return!this.pristine}get touched(){return It(this.touchedReactive)}set touched(e){It(()=>this.touchedReactive.set(e))}_touched=it(()=>this.touchedReactive());touchedReactive=ae(!1);get untouched(){return!this.touched}_events=new ut;events=this._events.asObservable();valueChanges;statusChanges;get updateOn(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"}setValidators(e){this._assignValidators(e)}setAsyncValidators(e){this._assignAsyncValidators(e)}addValidators(e){this.setValidators($l(e,this._rawValidators))}addAsyncValidators(e){this.setAsyncValidators($l(e,this._rawAsyncValidators))}removeValidators(e){this.setValidators(ql(e,this._rawValidators))}removeAsyncValidators(e){this.setAsyncValidators(ql(e,this._rawAsyncValidators))}hasValidator(e){return ni(this._rawValidators,e)}hasAsyncValidator(e){return ni(this._rawAsyncValidators,e)}clearValidators(){this.validator=null}clearAsyncValidators(){this.asyncValidator=null}markAsTouched(e={}){let t=this.touched===!1;this.touched=!0;let n=e.sourceControl??this;this._parent&&!e.onlySelf&&this._parent.markAsTouched(D(T({},e),{sourceControl:n})),t&&e.emitEvent!==!1&&this._events.next(new as(!0,n))}markAllAsDirty(e={}){this.markAsDirty({onlySelf:!0,emitEvent:e.emitEvent,sourceControl:this}),this._forEachChild(t=>t.markAllAsDirty(e))}markAllAsTouched(e={}){this.markAsTouched({onlySelf:!0,emitEvent:e.emitEvent,sourceControl:this}),this._forEachChild(t=>t.markAllAsTouched(e))}markAsUntouched(e={}){let t=this.touched===!0;this.touched=!1,this._pendingTouched=!1;let n=e.sourceControl??this;this._forEachChild(r=>{r.markAsUntouched({onlySelf:!0,emitEvent:e.emitEvent,sourceControl:n})}),this._parent&&!e.onlySelf&&this._parent._updateTouched(e,n),t&&e.emitEvent!==!1&&this._events.next(new as(!1,n))}markAsDirty(e={}){let t=this.pristine===!0;this.pristine=!1;let n=e.sourceControl??this;this._parent&&!e.onlySelf&&this._parent.markAsDirty(D(T({},e),{sourceControl:n})),t&&e.emitEvent!==!1&&this._events.next(new os(!1,n))}markAsPristine(e={}){let t=this.pristine===!1;this.pristine=!0,this._pendingDirty=!1;let n=e.sourceControl??this;this._forEachChild(r=>{r.markAsPristine({onlySelf:!0,emitEvent:e.emitEvent})}),this._parent&&!e.onlySelf&&this._parent._updatePristine(e,n),t&&e.emitEvent!==!1&&this._events.next(new os(!0,n))}markAsPending(e={}){this.status=At;let t=e.sourceControl??this;e.emitEvent!==!1&&(this._events.next(new lr(this.status,t)),this.statusChanges.emit(this.status)),this._parent&&!e.onlySelf&&this._parent.markAsPending(D(T({},e),{sourceControl:t}))}disable(e={}){let t=this._parentMarkedDirty(e.onlySelf);this.status=pn,this.errors=null,this._forEachChild(r=>{r.disable(D(T({},e),{onlySelf:!0}))}),this._updateValue();let n=e.sourceControl??this;e.emitEvent!==!1&&(this._events.next(new Zl(this.value,n)),this._events.next(new lr(this.status,n)),this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(D(T({},e),{skipPristineCheck:t}),this),this._onDisabledChange.forEach(r=>r(!0))}enable(e={}){let t=this._parentMarkedDirty(e.onlySelf);this.status=hn,this._forEachChild(n=>{n.enable(D(T({},e),{onlySelf:!0}))}),this.updateValueAndValidity({onlySelf:!0,emitEvent:e.emitEvent}),this._updateAncestors(D(T({},e),{skipPristineCheck:t}),this),this._onDisabledChange.forEach(n=>n(!1))}_updateAncestors(e,t){this._parent&&!e.onlySelf&&(this._parent.updateValueAndValidity(e),e.skipPristineCheck||this._parent._updatePristine({},t),this._parent._updateTouched({},t))}setParent(e){this._parent=e}getRawValue(){return this.value}updateValueAndValidity(e={}){if(this._setInitialStatus(),this._updateValue(),this.enabled){let n=this._cancelExistingSubscription();this.errors=this._runValidator(),this.status=this._calculateStatus(),(this.status===hn||this.status===At)&&this._runAsyncValidator(n,e.emitEvent)}let t=e.sourceControl??this;e.emitEvent!==!1&&(this._events.next(new Zl(this.value,t)),this._events.next(new lr(this.status,t)),this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!e.onlySelf&&this._parent.updateValueAndValidity(D(T({},e),{sourceControl:t}))}_updateTreeValidity(e={emitEvent:!0}){this._forEachChild(t=>t._updateTreeValidity(e)),this.updateValueAndValidity({onlySelf:!0,emitEvent:e.emitEvent})}_setInitialStatus(){this.status=this._allControlsDisabled()?pn:hn}_runValidator(){return this.validator?this.validator(this):null}_runAsyncValidator(e,t){if(this.asyncValidator){this.status=At,this._hasOwnPendingAsyncValidator={emitEvent:t!==!1,shouldHaveEmitted:e!==!1};let n=ap(this.asyncValidator(this));this._asyncValidationSubscription=n.subscribe(r=>{this._hasOwnPendingAsyncValidator=null,this.setErrors(r,{emitEvent:t,shouldHaveEmitted:e})})}}_cancelExistingSubscription(){if(this._asyncValidationSubscription){this._asyncValidationSubscription.unsubscribe();let e=(this._hasOwnPendingAsyncValidator?.emitEvent||this._hasOwnPendingAsyncValidator?.shouldHaveEmitted)??!1;return this._hasOwnPendingAsyncValidator=null,e}return!1}setErrors(e,t={}){this.errors=e,this._updateControlsErrors(t.emitEvent!==!1,this,t.shouldHaveEmitted)}get(e){let t=e;return t==null||(Array.isArray(t)||(t=t.split(".")),t.length===0)?null:t.reduce((n,r)=>n&&n._find(r),this)}getError(e,t){let n=t?this.get(t):this;return n&&n.errors?n.errors[e]:null}hasError(e,t){return!!this.getError(e,t)}get root(){let e=this;for(;e._parent;)e=e._parent;return e}_updateControlsErrors(e,t,n){this.status=this._calculateStatus(),e&&this.statusChanges.emit(this.status),(e||n)&&this._events.next(new lr(this.status,t)),this._parent&&this._parent._updateControlsErrors(e,t,n)}_initObservables(){this.valueChanges=new F,this.statusChanges=new F}_calculateStatus(){return this._allControlsDisabled()?pn:this.errors?ar:this._hasOwnPendingAsyncValidator||this._anyControlsHaveStatus(At)?At:this._anyControlsHaveStatus(ar)?ar:hn}_anyControlsHaveStatus(e){return this._anyControls(t=>t.status===e)}_anyControlsDirty(){return this._anyControls(e=>e.dirty)}_anyControlsTouched(){return this._anyControls(e=>e.touched)}_updatePristine(e,t){let n=!this._anyControlsDirty(),r=this.pristine!==n;this.pristine=n,this._parent&&!e.onlySelf&&this._parent._updatePristine(e,t),r&&this._events.next(new os(this.pristine,t))}_updateTouched(e={},t){this.touched=this._anyControlsTouched(),this._events.next(new as(this.touched,t)),this._parent&&!e.onlySelf&&this._parent._updateTouched(e,t)}_onDisabledChange=[];_registerOnCollectionChange(e){this._onCollectionChange=e}_setUpdateStrategy(e){Mi(e)&&e.updateOn!=null&&(this._updateOn=e.updateOn)}_parentMarkedDirty(e){let t=this._parent&&this._parent.dirty;return!e&&!!t&&!this._parent._anyControlsDirty()}_find(e){return null}_assignValidators(e){this._rawValidators=Array.isArray(e)?e.slice():e,this._composedValidatorFn=X_(this._rawValidators)}_assignAsyncValidators(e){this._rawAsyncValidators=Array.isArray(e)?e.slice():e,this._composedAsyncValidatorFn=tw(this._rawAsyncValidators)}},fp=new S("",{providedIn:"root",factory:()=>ba}),ba="always";function rw(e,t){return[...t.path,e]}function iw(e,t,n=ba){ow(e,t),t.valueAccessor.writeValue(e.value),(e.disabled||n==="always")&&t.valueAccessor.setDisabledState?.(e.disabled),aw(e,t),uw(e,t),lw(e,t),sw(e,t)}function Gl(e,t){e.forEach(n=>{n.registerOnValidatorChange&&n.registerOnValidatorChange(t)})}function sw(e,t){if(t.valueAccessor.setDisabledState){let n=r=>{t.valueAccessor.setDisabledState(r)};e.registerOnDisabledChange(n),t._registerOnDestroy(()=>{e._unregisterOnDisabledChange(n)})}}function ow(e,t){let n=Z_(e);t.validator!==null?e.setValidators(Ul(n,t.validator)):typeof n=="function"&&e.setValidators([n]);let r=G_(e);t.asyncValidator!==null?e.setAsyncValidators(Ul(r,t.asyncValidator)):typeof r=="function"&&e.setAsyncValidators([r]);let i=()=>e.updateValueAndValidity();Gl(t._rawValidators,i),Gl(t._rawAsyncValidators,i)}function aw(e,t){t.valueAccessor.registerOnChange(n=>{e._pendingValue=n,e._pendingChange=!0,e._pendingDirty=!0,e.updateOn==="change"&&gp(e,t)})}function lw(e,t){t.valueAccessor.registerOnTouched(()=>{e._pendingTouched=!0,e.updateOn==="blur"&&e._pendingChange&&gp(e,t),e.updateOn!=="submit"&&e.markAsTouched()})}function gp(e,t){e._pendingDirty&&e.markAsDirty(),e.setValue(e._pendingValue,{emitModelToViewChange:!1}),t.viewToModelUpdate(e._pendingValue),e._pendingChange=!1}function uw(e,t){let n=(r,i)=>{t.valueAccessor.writeValue(r),i&&t.viewToModelUpdate(r)};e.registerOnChange(n),t._registerOnDestroy(()=>{e._unregisterOnChange(n)})}function cw(e,t){if(!e.hasOwnProperty("model"))return!1;let n=e.model;return n.isFirstChange()?!0:!Object.is(t,n.currentValue)}function dw(e){return Object.getPrototypeOf(e.constructor)===R_}function hw(e,t){if(!t)return null;Array.isArray(t);let n,r,i;return t.forEach(s=>{s.constructor===qn?n=s:dw(s)?r=s:i=s}),i||r||n||null}function Wl(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}function Ql(e){return typeof e=="object"&&e!==null&&Object.keys(e).length===2&&"value"in e&&"disabled"in e}var pw=class extends nw{defaultValue=null;_onChange=[];_pendingValue;_pendingChange=!1;constructor(e=null,t,n){super(J_(t),ew(n,t)),this._applyFormState(e),this._setUpdateStrategy(t),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator}),Mi(t)&&(t.nonNullable||t.initialValueIsDefault)&&(Ql(e)?this.defaultValue=e.value:this.defaultValue=e)}setValue(e,t={}){this.value=this._pendingValue=e,this._onChange.length&&t.emitModelToViewChange!==!1&&this._onChange.forEach(n=>n(this.value,t.emitViewToModelChange!==!1)),this.updateValueAndValidity(t)}patchValue(e,t={}){this.setValue(e,t)}reset(e=this.defaultValue,t={}){this._applyFormState(e),this.markAsPristine(t),this.markAsUntouched(t),this.setValue(this.value,t),this._pendingChange=!1,t?.emitEvent!==!1&&this._events.next(new K_(this))}_updateValue(){}_anyControls(e){return!1}_allControlsDisabled(){return this.disabled}registerOnChange(e){this._onChange.push(e)}_unregisterOnChange(e){Wl(this._onChange,e)}registerOnDisabledChange(e){this._onDisabledChange.push(e)}_unregisterOnDisabledChange(e){Wl(this._onDisabledChange,e)}_forEachChild(e){}_syncPendingControls(){return this.updateOn==="submit"&&(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),this._pendingChange)?(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),!0):!1}_applyFormState(e){Ql(e)?(this.value=this._pendingValue=e.value,e.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=e}},fw={provide:va,useExisting:Nn(()=>Ei)},Yl=Promise.resolve(),Ei=(()=>{class e extends va{_changeDetectorRef;callSetDisabledState;control=new pw;static ngAcceptInputType_isDisabled;_registered=!1;viewModel;name="";isDisabled;model;options;update=new F;constructor(n,r,i,s,o,a){super(),this._changeDetectorRef=o,this.callSetDisabledState=a,this._parent=n,this._setValidators(r),this._setAsyncValidators(i),this.valueAccessor=hw(this,s)}ngOnChanges(n){if(this._checkForErrors(),!this._registered||"name"in n){if(this._registered&&(this._checkName(),this.formDirective)){let r=n.name.previousValue;this.formDirective.removeControl({name:r,path:this._getPath(r)})}this._setUpControl()}"isDisabled"in n&&this._updateDisabled(n),cw(n,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}get path(){return this._getPath(this.name)}get formDirective(){return this._parent?this._parent.formDirective:null}viewToModelUpdate(n){this.viewModel=n,this.update.emit(n)}_setUpControl(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0}_setUpdateStrategy(){this.options&&this.options.updateOn!=null&&(this.control._updateOn=this.options.updateOn)}_isStandalone(){return!this._parent||!!(this.options&&this.options.standalone)}_setUpStandalone(){iw(this.control,this,this.callSetDisabledState),this.control.updateValueAndValidity({emitEvent:!1})}_checkForErrors(){this._checkName()}_checkName(){this.options&&this.options.name&&(this.name=this.options.name),!this._isStandalone()&&this.name}_updateValue(n){Yl.then(()=>{this.control.setValue(n,{emitViewToModelChange:!1}),this._changeDetectorRef?.markForCheck()})}_updateDisabled(n){let r=n.isDisabled.currentValue,i=r!==0&&Ab(r);Yl.then(()=>{i&&!this.control.disabled?this.control.disable():!i&&this.control.disabled&&this.control.enable(),this._changeDetectorRef?.markForCheck()})}_getPath(n){return this._parent?rw(n,this._parent):[n]}static \u0275fac=function(n){return new(n||e)(j(W_,9),j(sp,10),j(H_,10),j(ip,10),j(xb,8),j(fp,8))};static \u0275dir=Ce({type:e,selectors:[["","ngModel","",3,"formControlName","",3,"formControl",""]],inputs:{name:"name",isDisabled:[0,"disabled","isDisabled"],model:[0,"ngModel","model"],options:[0,"ngModelOptions","options"]},outputs:{update:"ngModelChange"},exportAs:["ngModel"],standalone:!1,features:[ua([fw]),on,gi]})}return e})();function gw(e){return typeof e=="number"?e:parseInt(e,10)}var mw=(()=>{class e{_validator=Bl;_onChange;_enabled;ngOnChanges(n){if(this.inputName in n){let r=this.normalizeInput(n[this.inputName].currentValue);this._enabled=this.enabled(r),this._validator=this._enabled?this.createValidator(r):Bl,this._onChange&&this._onChange()}}validate(n){return this._validator(n)}registerOnValidatorChange(n){this._onChange=n}enabled(n){return n!=null}static \u0275fac=function(n){return new(n||e)};static \u0275dir=Ce({type:e,features:[gi]})}return e})(),vw={provide:sp,useExisting:Nn(()=>mp),multi:!0},mp=(()=>{class e extends mw{maxlength;inputName="maxlength";normalizeInput=n=>gw(n);createValidator=n=>B_(n);static \u0275fac=(()=>{let n;return function(r){return(n||(n=Zc(e)))(r||e)}})();static \u0275dir=Ce({type:e,selectors:[["","maxlength","","formControlName",""],["","maxlength","","formControl",""],["","maxlength","","ngModel",""]],hostVars:1,hostBindings:function(n,r){n&2&&ia("maxlength",r._enabled?r.maxlength:null)},inputs:{maxlength:"maxlength"},standalone:!1,features:[ua([vw]),on]})}return e})(),yw=(()=>{class e{static \u0275fac=function(n){return new(n||e)};static \u0275mod=wi({type:e});static \u0275inj=oi({})}return e})(),Ca=(()=>{class e{static withConfig(n){return{ngModule:e,providers:[{provide:fp,useValue:n.callSetDisabledState??ba}]}}static \u0275fac=function(n){return new(n||e)};static \u0275mod=wi({type:e});static \u0275inj=oi({imports:[yw]})}return e})(),bw=class Ws{placeholder=Be.INPUT.PLACEHOLDER;disabled=!1;value="";voiceStatus={state:"idle",transcript:"",interimTranscript:""};valueChange=new F;submitMessage=new F;voiceClick=new F;addClick=new F;get isListening(){return this.voiceStatus.state==="listening"}get displayValue(){if(this.isListening){let t=this.voiceStatus.transcript||"",n=this.voiceStatus.interimTranscript||"";return t+(t&&n?" ":"")+n}return this.value}get displayPlaceholder(){return this.isListening?"Listening... Speak now":this.placeholder}onInputChange(t){!this.isListening&&t!==void 0&&(this.value=t,this.valueChange.emit(this.value))}onSubmit(){if(this.value.trim()&&!this.isListening){let t=this.value;this.value="",this.valueChange.emit(this.value),this.submitMessage.emit(t)}}onVoiceClick(){this.voiceClick.emit()}onAddClick(){this.addClick.emit()}static \u0275fac=function(t){return new(t||Ws)};static \u0275cmp=Ie({type:Ws,selectors:[["app-input-field"]],inputs:{placeholder:"placeholder",disabled:"disabled",value:"value",voiceStatus:"voiceStatus"},outputs:{valueChange:"valueChange",submitMessage:"submitMessage",voiceClick:"voiceClick",addClick:"addClick"},decls:7,vars:8,consts:[[1,"input-container"],[1,"input-wrapper"],["aria-label","Add",1,"icon-button","add-button",3,"click"],["name","add","width","24","height","24"],["type","text",1,"input-field",3,"ngModelChange","keyup.enter","ngModel","placeholder","disabled","readonly"],["aria-label","Voice input",1,"icon-button","voice-button",3,"click"],["name","microphone","width","24","height","24","fill","currentColor"]],template:function(t,n){t&1&&(f(0,"div",0)(1,"div",1)(2,"button",2),M("click",function(){return n.onAddClick()}),q(3,"app-icon",3),y(),f(4,"input",4),M("ngModelChange",function(r){return n.onInputChange(r)})("keyup.enter",function(){return n.onSubmit()}),y(),f(5,"button",5),M("click",function(){return n.onVoiceClick()}),q(6,"app-icon",6),y()()()),t&2&&(x(4),Te("listening",n.isListening),A("ngModel",n.displayValue)("placeholder",n.displayPlaceholder)("disabled",n.disabled||n.isListening)("readonly",n.isListening),x(),Te("active",n.isListening))},dependencies:[_e,Ca,qn,ya,Ei,ln],styles:[".input-container[_ngcontent-%COMP%]{padding:12px 16px;background:#fff;border-top:1px solid #f0f0f0;flex-shrink:0;box-sizing:border-box}@media (max-width: 768px){.input-container[_ngcontent-%COMP%]{padding:10px 12px}}@media (max-height: 600px){.input-container[_ngcontent-%COMP%]{padding:8px 12px}}.input-wrapper[_ngcontent-%COMP%]{display:flex;align-items:center;gap:12px;background:#f8f8f8;border-radius:12px;padding:8px 16px;transition:background-color .2s}.input-wrapper[_ngcontent-%COMP%]:focus-within{background:#f0f0f0}.input-field[_ngcontent-%COMP%]{flex:1;border:none;background:transparent;font-size:15px;color:#333;outline:none;padding:8px 0}.input-field[_ngcontent-%COMP%]::placeholder{color:#999}.input-field[_ngcontent-%COMP%]:disabled{opacity:.5;cursor:not-allowed}.input-field.listening[_ngcontent-%COMP%]{color:#ff6b6b;font-style:italic}.icon-button[_ngcontent-%COMP%]{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:50%;transition:background-color .2s;color:#666;min-width:40px;min-height:40px}.icon-button[_ngcontent-%COMP%]:hover{background-color:#0000000d;color:#333}.icon-button[_ngcontent-%COMP%]:active{background-color:#0000001a}.voice-button.active[_ngcontent-%COMP%]{color:#ff6b6b;animation:_ngcontent-%COMP%_pulse 1.5s ease-in-out infinite}@keyframes _ngcontent-%COMP%_pulse{0%,to{opacity:1}50%{opacity:.6}}"]})};function Cw(e,t){e&1&&(f(0,"div",6),q(1,"span")(2,"span")(3,"span"),y())}function _w(e,t){if(e&1&&q(0,"div",7),e&2){let n=I();A("innerHTML",n.message.text,yd)}}var ww=class Qs{message;get isUser(){return this.message.sender==="user"}get isAssistant(){return this.message.sender==="assistant"}static \u0275fac=function(t){return new(t||Qs)};static \u0275cmp=Ie({type:Qs,selectors:[["app-message"]],inputs:{message:"message"},decls:6,vars:8,consts:[[1,"message"],[1,"message-container"],[1,"message-content"],[1,"message-bubble"],["class","typing-indicator",4,"ngIf"],["class","message-text",3,"innerHTML",4,"ngIf"],[1,"typing-indicator"],[1,"message-text",3,"innerHTML"]],template:function(t,n){t&1&&(f(0,"div",0)(1,"div",1)(2,"div",2)(3,"div",3),fe(4,Cw,4,0,"div",4)(5,_w,1,1,"div",5),y()()()()),t&2&&(Te("user",n.isUser)("assistant",n.isAssistant),x(3),Te("typing",n.message.isTyping),x(),A("ngIf",n.message.isTyping),x(),A("ngIf",!n.message.isTyping))},dependencies:[_e,an],styles:[".message[_ngcontent-%COMP%]{display:flex;margin-bottom:16px;animation:_ngcontent-%COMP%_fadeIn .3s ease-in}@keyframes _ngcontent-%COMP%_fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.message-container[_ngcontent-%COMP%]{display:flex;align-items:flex-start;max-width:100%;width:100%}.message.user[_ngcontent-%COMP%] .message-container[_ngcontent-%COMP%]{justify-content:flex-end}.message-content[_ngcontent-%COMP%]{display:flex;flex-direction:column;max-width:85%}.message.user[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%]{align-items:flex-end}.message-bubble[_ngcontent-%COMP%]{padding:12px 16px;border-radius:10px;word-wrap:break-word;width:fit-content}.message.user[_ngcontent-%COMP%] .message-bubble[_ngcontent-%COMP%]{background:#ff6b4a;color:#fff;border-radius:10px;box-shadow:0 1px 2px #0000001a}.message.assistant[_ngcontent-%COMP%] .message-bubble[_ngcontent-%COMP%]{background:transparent;color:#2c3e50;border:none;box-shadow:none;padding:0}.message-bubble.typing[_ngcontent-%COMP%]{padding:16px;min-width:60px}.message-text[_ngcontent-%COMP%]{margin:0;line-height:1.5;font-size:14px;white-space:normal}.message-text[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:0 0 8px}.message-text[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child{margin-bottom:0}.message-text[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] h4[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] h5[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] h6[_ngcontent-%COMP%]{margin:12px 0 8px;font-weight:600}.message-text[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]:first-child, .message-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]:first-child, .message-text[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]:first-child, .message-text[_ngcontent-%COMP%] h4[_ngcontent-%COMP%]:first-child, .message-text[_ngcontent-%COMP%] h5[_ngcontent-%COMP%]:first-child, .message-text[_ngcontent-%COMP%] h6[_ngcontent-%COMP%]:first-child{margin-top:0}.message-text[_ngcontent-%COMP%] ul[_ngcontent-%COMP%], .message-text[_ngcontent-%COMP%] ol[_ngcontent-%COMP%]{margin:8px 0;padding-left:24px}.message-text[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{margin:4px 0}.message-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{font-weight:600}.message-text[_ngcontent-%COMP%] em[_ngcontent-%COMP%]{font-style:italic}.message-text[_ngcontent-%COMP%] code[_ngcontent-%COMP%]{background:#0000000d;padding:2px 4px;border-radius:3px;font-family:Courier New,monospace;font-size:13px}.message-text[_ngcontent-%COMP%] pre[_ngcontent-%COMP%]{background:#0000000d;padding:12px;border-radius:6px;overflow-x:auto;margin:8px 0}.message-text[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%]{background:none;padding:0}.typing-indicator[_ngcontent-%COMP%]{display:flex;align-items:center;gap:4px;height:16px}.typing-indicator[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:50%;background-color:#95a5a6;animation:_ngcontent-%COMP%_typing 1.4s infinite}.typing-indicator[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:nth-child(2){animation-delay:.2s}.typing-indicator[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:nth-child(3){animation-delay:.4s}@keyframes _ngcontent-%COMP%_typing{0%,60%,to{transform:translateY(0);opacity:.5}30%{transform:translateY(-10px);opacity:1}}@media (max-width: 768px){.message-bubble[_ngcontent-%COMP%]{max-width:90%}}"]})},xw=["messagesContainer"];function kw(e,t){if(e&1&&q(0,"app-message",7),e&2){let n=t.$implicit;A("message",n)}}function Sw(e,t){if(e&1&&(f(0,"div",5),fe(1,kw,1,1,"app-message",6),y()),e&2){let n=I();x(),A("ngForOf",n.messages)("ngForTrackBy",n.trackByMessageId)}}function Ow(e,t){e&1&&(f(0,"div",8)(1,"p",9),z(2,"Start a conversation by typing a message or selecting a suggestion below."),y()())}var Mw=class Ys{messages=[];canLoadMore=!1;isLoadingMore=!1;loadMore=new F;messagesContainer;restoreScrollAfterPrepend=!1;previousScrollHeight=0;suppressNextScroll=!1;lastScrollTop=Number.MAX_SAFE_INTEGER;scrollInitialized=!1;initialScrollPending=!0;initialScrollRequested=!1;get container(){return this.messagesContainer?.nativeElement??null}ngAfterViewChecked(){if(this.restoreScrollAfterPrepend&&this.messagesContainer){let t=this.messagesContainer.nativeElement,n=t.scrollHeight-this.previousScrollHeight;t.scrollTop=n+t.scrollTop,this.restoreScrollAfterPrepend=!1}}ngOnChanges(t){if(!t.messages)return;let n=t.messages.currentValue,r=t.messages.previousValue;this.initialScrollPending?this.queueInitialScroll():this.hasAppendedMessage(r,n)&&this.scrollToBottomAfterRender()}onScroll(){if(!this.canLoadMore)return;let t=this.container;t&&(this.shouldSkipScroll(t)||this.isNearTop(t.scrollTop)&&this.prepareForLoadMore(t))}trackByMessageId(t,n){return n.id}queueInitialScroll(){this.initialScrollRequested||(this.initialScrollRequested=!0,Promise.resolve().then(()=>{let t=this.container;if(!t||!this.initialScrollPending){this.initialScrollRequested=!1;return}this.scrollToBottom(t),this.initialScrollPending=!1,this.initialScrollRequested=!1}))}scrollToBottomAfterRender(){Promise.resolve().then(()=>{let t=this.container;t&&this.scrollToBottom(t)})}scrollToBottom(t){this.suppressNextScroll=!0,t.scrollTop=t.scrollHeight,this.lastScrollTop=t.scrollTop,this.scrollInitialized=!0}triggerLoadMore(t){if(!this.canLoadMore||this.isLoadingMore)return;let n=t??this.container;n&&(this.previousScrollHeight=n.scrollHeight,this.restoreScrollAfterPrepend=!0),this.loadMore.emit()}hasAppendedMessage(t,n){if(!n||n.length===0)return!1;if(!t||t.length===0)return!0;if(n.length<=t.length)return!1;let r=t[t.length-1]?.id;return n[n.length-1]?.id!==r}shouldSkipScroll(t){let n=t.scrollTop,r=t.scrollHeight,i=t.clientHeight;if(this.suppressNextScroll)return this.suppressNextScroll=!1,this.lastScrollTop=n,!0;if(r<=i+200)return this.lastScrollTop=n,!0;if(!this.scrollInitialized)return this.scrollInitialized=!0,this.lastScrollTop=n,!0;let s=n<this.lastScrollTop;return this.lastScrollTop=n,!s}isNearTop(t){return t<=200}prepareForLoadMore(t){this.suppressNextScroll=!0,this.triggerLoadMore(t)}static \u0275fac=function(t){return new(t||Ys)};static \u0275cmp=Ie({type:Ys,selectors:[["app-chat-history"]],viewQuery:function(t,n){if(t&1&&vh(xw,5),t&2){let r;yh(r=bh())&&(n.messagesContainer=r.first)}},inputs:{messages:"messages",canLoadMore:"canLoadMore",isLoadingMore:"isLoadingMore"},outputs:{loadMore:"loadMore"},features:[gi],decls:5,vars:2,consts:[["messagesContainer",""],[1,"chat-history"],[1,"messages-container",3,"scroll"],["class","messages-list",4,"ngIf"],["class","empty-state",4,"ngIf"],[1,"messages-list"],[3,"message",4,"ngFor","ngForOf","ngForTrackBy"],[3,"message"],[1,"empty-state"],[1,"empty-text"]],template:function(t,n){if(t&1){let r=et();f(0,"div",1)(1,"div",2,0),M("scroll",function(){return V(r),N(n.onScroll())}),fe(3,Sw,2,2,"div",3)(4,Ow,3,0,"div",4),y()()}t&2&&(x(3),A("ngIf",n.messages.length>0),x(),A("ngIf",n.messages.length===0))},dependencies:[_e,ki,an,ww],styles:[".chat-history[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;overflow:hidden;width:100%;min-height:0;max-height:100%}.messages-container[_ngcontent-%COMP%]{flex:1;overflow-y:auto;overflow-x:hidden;padding:16px;scroll-behavior:smooth;min-height:0;-webkit-overflow-scrolling:touch}.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar{width:6px}.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-track{background:transparent}.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb{background:#0003;border-radius:3px}.messages-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover{background:#0000004d}.messages-list[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:8px}.empty-state[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:center;height:100%;padding:32px}.empty-text[_ngcontent-%COMP%]{color:#95a5a6;font-size:14px;text-align:center;line-height:1.6;max-width:400px}"]})};function Ew(e,t){if(e&1){let n=et();f(0,"div",1),M("click",function(){V(n);let r=I();return N(r.onOverlayClick())}),f(1,"div",2),M("click",function(r){V(n);let i=I();return N(i.onModalClick(r))}),f(2,"div",3)(3,"button",4),M("click",function(){V(n);let r=I();return N(r.onBackClick())}),q(4,"app-icon",5),y(),f(5,"h2",6),z(6,"Rename Chat"),y(),f(7,"button",7),M("click",function(){V(n);let r=I();return N(r.onCloseClick())}),q(8,"app-icon",8),y()(),f(9,"div",9)(10,"input",10),la("ngModelChange",function(r){V(n);let i=I();return wh(i.editedTitle,r)||(i.editedTitle=r),N(r)}),M("keydown",function(r){V(n);let i=I();return N(i.onInputKeydown(r))}),y()(),f(11,"div",11)(12,"button",12),M("click",function(){V(n);let r=I();return N(r.onCancel())}),z(13," Cancel "),y(),f(14,"button",13),M("click",function(){V(n);let r=I();return N(r.onSave())}),z(15," Save "),y()()()()}if(e&2){let n=I();x(10),aa("ngModel",n.editedTitle),A("maxlength",500)}}var Tw=class Ks{isOpen=!1;currentTitle="";close=new F;save=new F;editedTitle="";ngOnChanges(t){t.isOpen&&this.isOpen&&(this.editedTitle=this.currentTitle),t.currentTitle&&(this.editedTitle=this.currentTitle)}onBackClick(){this.close.emit()}onCloseClick(){this.close.emit()}onCancel(){this.close.emit()}onSave(){let t=this.editedTitle.trim();t&&t!==this.currentTitle&&this.save.emit(t),this.close.emit()}onOverlayClick(){this.close.emit()}onModalClick(t){t.stopPropagation()}onInputKeydown(t){t.key==="Enter"?(t.preventDefault(),this.onSave()):t.key==="Escape"&&(t.preventDefault(),this.onCancel())}static \u0275fac=function(t){return new(t||Ks)};static \u0275cmp=Ie({type:Ks,selectors:[["app-rename-modal"]],inputs:{isOpen:"isOpen",currentTitle:"currentTitle"},outputs:{close:"close",save:"save"},features:[gi],decls:1,vars:1,consts:[["class","modal-overlay",3,"click",4,"ngIf"],[1,"modal-overlay",3,"click"],[1,"modal-container",3,"click"],[1,"modal-header"],["aria-label","Back",1,"icon-button","back-button",3,"click"],["name","chevron-left","width","24","height","24"],[1,"modal-title"],["aria-label","Close",1,"icon-button","close-button",3,"click"],["name","close","width","24","height","24"],[1,"modal-body"],["type","text","placeholder","Enter chat name","autofocus","",1,"rename-input",3,"ngModelChange","keydown","ngModel","maxlength"],[1,"modal-footer"],[1,"btn","btn-cancel",3,"click"],[1,"btn","btn-save",3,"click"]],template:function(t,n){t&1&&fe(0,Ew,16,2,"div",0),t&2&&A("ngIf",n.isOpen)},dependencies:[_e,an,Ca,qn,ya,mp,Ei,ln],styles:[".modal-overlay[_ngcontent-%COMP%]{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:flex-end;justify-content:center;z-index:1000;animation:_ngcontent-%COMP%_fadeIn .2s ease-out}@keyframes _ngcontent-%COMP%_fadeIn{0%{opacity:0}to{opacity:1}}.modal-container[_ngcontent-%COMP%]{background-color:#fff;border-radius:16px 16px 0 0;width:100%;max-width:600px;max-height:90vh;display:flex;flex-direction:column;box-shadow:0 -2px 24px #00000026;animation:_ngcontent-%COMP%_slideUp .3s ease-out}@keyframes _ngcontent-%COMP%_slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.modal-header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e5e7eb;gap:12px}.modal-title[_ngcontent-%COMP%]{flex:1;text-align:center;font-size:18px;font-weight:600;color:#111827;margin:0}.icon-button[_ngcontent-%COMP%]{background:none;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:8px;color:#6b7280;transition:all .2s ease}.icon-button[_ngcontent-%COMP%]:hover{background-color:#f3f4f6;color:#111827}.icon-button[_ngcontent-%COMP%]:active{transform:scale(.95)}.back-button[_ngcontent-%COMP%], .close-button[_ngcontent-%COMP%]{flex-shrink:0}.modal-body[_ngcontent-%COMP%]{padding:24px 20px;flex:1;overflow-y:auto}.rename-input[_ngcontent-%COMP%]{width:100%;padding:12px 16px;font-size:16px;border:1px solid #d1d5db;border-radius:8px;outline:none;transition:all .2s ease;font-family:inherit;color:#111827}.rename-input[_ngcontent-%COMP%]:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.rename-input[_ngcontent-%COMP%]::placeholder{color:#9ca3af}.modal-footer[_ngcontent-%COMP%]{display:flex;gap:12px;padding:16px 20px;border-top:1px solid #e5e7eb}.btn[_ngcontent-%COMP%]{flex:1;padding:12px 24px;font-size:16px;font-weight:500;border-radius:8px;border:none;cursor:pointer;transition:all .2s ease;font-family:inherit}.btn[_ngcontent-%COMP%]:active{transform:scale(.98)}.btn-cancel[_ngcontent-%COMP%]{background-color:#fff;color:#374151;border:1px solid #d1d5db}.btn-cancel[_ngcontent-%COMP%]:hover{background-color:#f9fafb;border-color:#9ca3af}.btn-save[_ngcontent-%COMP%]{background-color:#ef4444;color:#fff}.btn-save[_ngcontent-%COMP%]:hover{background-color:#dc2626}.btn-save[_ngcontent-%COMP%]:disabled{background-color:#fca5a5;cursor:not-allowed}@media (min-width: 768px){.modal-overlay[_ngcontent-%COMP%]{align-items:center}.modal-container[_ngcontent-%COMP%]{border-radius:16px;max-height:400px}}"]})},Pw=["scrollContainer"],Iw=e=>({compact:e});function Aw(e,t){if(e&1){let n=et();f(0,"div",34)(1,"button",35),M("click",function(r){V(n);let i=I().$implicit,s=I(2);return N(s.onEditClick(i.id,i.title,r))}),q(2,"app-icon",36),f(3,"span"),z(4,"Rename"),y()(),f(5,"button",37),M("click",function(r){V(n);let i=I().$implicit,s=I(2);return N(s.onDeleteClick(i.id,r))}),q(6,"app-icon",38),f(7,"span"),z(8,"Delete"),y()()()}}function Dw(e,t){if(e&1){let n=et();f(0,"div",25),M("click",function(){let r=V(n).$implicit,i=I(2);return N(i.onConversationClick(r.id))}),f(1,"div",26)(2,"div",27)(3,"span",28),z(4),y()(),f(5,"span",29),z(6),y()(),f(7,"div",30)(8,"button",31),M("click",function(r){let i=V(n).$implicit,s=I(2);return N(s.toggleMenu(i.id,r))}),q(9,"app-icon",32),y(),fe(10,Aw,9,0,"div",33),y()()}if(e&2){let n=t.$implicit,r=I(2);x(4),Ee(n.title),x(2),Ee(n.date),x(4),A("ngIf",r.isMenuOpen(n.id))}}function Vw(e,t){if(e&1&&(f(0,"div",23),fe(1,Dw,11,3,"div",24),y()),e&2){let n=I();x(),A("ngForOf",n.conversations)}}function Nw(e,t){if(e&1&&(f(0,"div",39)(1,"div",40),q(2,"div",41),f(3,"p",42),z(4,"Loading conversations..."),y()()()),e&2){let n=I();x(),A("ngClass",ob(1,Iw,!(n.isLoading&&n.conversations.length===0)))}}function Rw(e,t){e&1&&(f(0,"div",43)(1,"p"),z(2,"No conversations yet"),y()())}var Lw=class Js{isOpen=!1;conversations=[];canLoadMore=!1;isLoadingMore=!1;isLoading=!1;scrollContainer;backClick=new F;settingsClick=new F;closeClick=new F;conversationClick=new F;deleteClick=new F;newChatClick=new F;searchChange=new F;titleUpdate=new F;loadMore=new F;searchQuery="";isRenameModalOpen=!1;renamingConversationId=null;renamingConversationTitle="";activeMenuId=null;onBackClick(){this.backClick.emit()}onSettingsClick(){this.settingsClick.emit()}onCloseClick(){this.closeClick.emit()}onOverlayClick(){this.closeClick.emit(),this.closeMenu()}onConversationClick(t){this.conversationClick.emit(t)}onDeleteClick(t,n){n.stopPropagation(),this.deleteClick.emit(t),this.closeMenu()}onNewChatClick(){this.newChatClick.emit()}onSearchChange(){this.searchChange.emit(this.searchQuery)}onEditClick(t,n,r){r.stopPropagation(),this.renamingConversationId=t,this.renamingConversationTitle=n,this.isRenameModalOpen=!0,this.closeMenu()}onRenameModalClose(){this.isRenameModalOpen=!1,this.renamingConversationId=null,this.renamingConversationTitle=""}onRenameModalSave(t){this.renamingConversationId&&t.trim()&&this.titleUpdate.emit({id:this.renamingConversationId,title:t.trim()})}toggleMenu(t,n){n.stopPropagation(),this.activeMenuId===t?this.activeMenuId=null:this.activeMenuId=t}closeMenu(){this.activeMenuId=null}isMenuOpen(t){return this.activeMenuId===t}onSidebarClick(){this.closeMenu()}onScroll(){if(!this.canLoadMore||this.isLoadingMore||this.isLoading)return;let t=this.scrollContainer?.nativeElement;t&&t.scrollHeight-t.scrollTop-t.clientHeight<=80&&this.loadMore.emit()}static \u0275fac=function(t){return new(t||Js)};static \u0275cmp=Ie({type:Js,selectors:[["app-sidebar"]],viewQuery:function(t,n){if(t&1&&vh(Pw,5),t&2){let r;yh(r=bh())&&(n.scrollContainer=r.first)}},inputs:{isOpen:"isOpen",conversations:"conversations",canLoadMore:"canLoadMore",isLoadingMore:"isLoadingMore",isLoading:"isLoading"},outputs:{backClick:"backClick",settingsClick:"settingsClick",closeClick:"closeClick",conversationClick:"conversationClick",deleteClick:"deleteClick",newChatClick:"newChatClick",searchChange:"searchChange",titleUpdate:"titleUpdate",loadMore:"loadMore"},decls:26,vars:10,consts:[["scrollContainer",""],[1,"sidebar-overlay",3,"click"],[1,"sidebar",3,"click"],[1,"sidebar-header"],[1,"back-text-button",3,"click"],["name","chevron-left","width","16","height","16"],[1,"header-actions"],["aria-label","Settings",1,"icon-button","settings-button",3,"click"],["name","settings","width","20","height","20"],["aria-label","Close",1,"icon-button","close-button",3,"click"],["name","close","width","20","height","20"],[1,"sidebar-content",3,"scroll"],[1,"conversations-title"],["class","conversations-list",4,"ngIf"],["class","load-more",4,"ngIf"],["class","empty-conversations",4,"ngIf"],[1,"sidebar-footer"],[1,"search-container"],["name","search","width","18","height","18",1,"search-icon"],["type","text","placeholder","Search",1,"search-input",3,"ngModelChange","input","ngModel"],["aria-label","New Chat",1,"icon-button","new-chat-button",3,"click"],["name","edit","width","20","height","20"],[3,"close","save","isOpen","currentTitle"],[1,"conversations-list"],["class","conversation-item",3,"click",4,"ngFor","ngForOf"],[1,"conversation-item",3,"click"],[1,"conversation-info"],[1,"conversation-title-container"],[1,"conversation-title"],[1,"conversation-date"],[1,"menu-container"],["aria-label","More options",1,"icon-button","menu-button",3,"click"],["name","more-horizontal","width","20","height","20"],["class","context-menu",4,"ngIf"],[1,"context-menu"],[1,"menu-item",3,"click"],["name","edit","width","16","height","16"],[1,"menu-item","delete-item",3,"click"],["name","trash","width","16","height","16"],[1,"load-more"],["aria-live","polite",1,"loading-state",3,"ngClass"],["aria-hidden","true",1,"spinner"],[1,"loading-text"],[1,"empty-conversations"]],template:function(t,n){if(t&1){let r=et();f(0,"div",1),M("click",function(){return V(r),N(n.onOverlayClick())}),y(),f(1,"div",2),M("click",function(){return V(r),N(n.onSidebarClick())}),f(2,"div",3)(3,"button",4),M("click",function(){return V(r),N(n.onBackClick())}),q(4,"app-icon",5),f(5,"span"),z(6,"Back to Chat"),y()(),f(7,"div",6)(8,"button",7),M("click",function(){return V(r),N(n.onSettingsClick())}),q(9,"app-icon",8),y(),f(10,"button",9),M("click",function(){return V(r),N(n.onCloseClick())}),q(11,"app-icon",10),y()()(),f(12,"div",11,0),M("scroll",function(){return V(r),N(n.onScroll())}),f(14,"h3",12),z(15,"Conversations"),y(),fe(16,Vw,2,1,"div",13)(17,Nw,5,3,"div",14)(18,Rw,3,0,"div",15),y(),f(19,"div",16)(20,"div",17),q(21,"app-icon",18),f(22,"input",19),la("ngModelChange",function(i){return V(r),wh(n.searchQuery,i)||(n.searchQuery=i),N(i)}),M("input",function(){return V(r),N(n.onSearchChange())}),y()(),f(23,"button",20),M("click",function(){return V(r),N(n.onNewChatClick())}),q(24,"app-icon",21),y()()(),f(25,"app-rename-modal",22),M("close",function(){return V(r),N(n.onRenameModalClose())})("save",function(i){return V(r),N(n.onRenameModalSave(i))}),y()}t&2&&(Te("visible",n.isOpen),x(),Te("open",n.isOpen),x(15),A("ngIf",n.conversations.length>0),x(),A("ngIf",n.isLoading&&n.conversations.length===0||n.isLoadingMore&&n.conversations.length>0),x(),A("ngIf",!n.isLoading&&n.conversations.length===0),x(4),aa("ngModel",n.searchQuery),x(3),A("isOpen",n.isRenameModalOpen)("currentTitle",n.renamingConversationTitle))},dependencies:[_e,fC,ki,an,Ca,qn,ya,Ei,ln,Tw],styles:[".sidebar-overlay[_ngcontent-%COMP%]{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;z-index:998;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease}.sidebar-overlay.visible[_ngcontent-%COMP%]{opacity:1;visibility:visible}.sidebar[_ngcontent-%COMP%]{position:fixed;top:0;left:0;width:85%;max-width:400px;height:100%;background:#fff;z-index:999;transform:translate(-100%);transition:transform .3s ease;display:flex;flex-direction:column;box-shadow:2px 0 8px #0000001a}.sidebar.open[_ngcontent-%COMP%]{transform:translate(0)}.sidebar-header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:16px;border-bottom:1px solid #e8ecf1}.back-text-button[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;background:none;border:none;cursor:pointer;font-size:16px;font-weight:500;color:#1a1a1a;padding:8px;border-radius:8px;transition:background .2s ease}.back-text-button[_ngcontent-%COMP%]:hover{background:#f5f7fa}.header-actions[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px}.icon-button[_ngcontent-%COMP%]{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:8px;transition:background .2s ease;color:#5f6368}.icon-button[_ngcontent-%COMP%]:hover{background:#f5f7fa;color:#1a1a1a}.icon-button[_ngcontent-%COMP%]:active{background:#e8ecf1}.sidebar-content[_ngcontent-%COMP%]{flex:1;overflow-y:auto;padding:16px}.conversations-title[_ngcontent-%COMP%]{font-size:13px;font-weight:500;color:#95a5a6;text-transform:uppercase;letter-spacing:.5px;margin:0 0 16px}.conversations-list[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:8px}.loading-state[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px 20px;color:#1a1a1a}.spinner[_ngcontent-%COMP%]{width:32px;height:32px;border:3px solid rgba(0,0,0,.1);border-top-color:#2c3e50;border-radius:50%;animation:_ngcontent-%COMP%_spin .9s linear infinite}.loading-text[_ngcontent-%COMP%]{font-size:14px;color:#54606c;margin:0}.loading-state.compact[_ngcontent-%COMP%]{flex-direction:row;padding:12px 16px;gap:10px}.loading-state.compact[_ngcontent-%COMP%] .loading-text[_ngcontent-%COMP%]{font-size:13px}@keyframes _ngcontent-%COMP%_spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.conversation-item[_ngcontent-%COMP%]{display:flex;align-items:center;padding:12px;background:#fff;border-radius:8px;cursor:pointer;transition:background .2s ease;gap:12px;position:relative}.conversation-item[_ngcontent-%COMP%]:hover{background:#f5f7fa}.conversation-info[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.conversation-title-container[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;min-width:0}.conversation-title[_ngcontent-%COMP%]{flex:1;font-size:14px;font-weight:500;color:#1a1a1a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.conversation-date[_ngcontent-%COMP%]{font-size:12px;color:#95a5a6}.menu-container[_ngcontent-%COMP%]{position:relative}.menu-button[_ngcontent-%COMP%]{opacity:0;transition:opacity .2s ease}.conversation-item[_ngcontent-%COMP%]:hover .menu-button[_ngcontent-%COMP%], .menu-button[_ngcontent-%COMP%]:focus, .menu-container[_ngcontent-%COMP%]:focus-within .menu-button[_ngcontent-%COMP%]{opacity:1}.context-menu[_ngcontent-%COMP%]{position:absolute;top:100%;right:0;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;border:1px solid #e8ecf1;padding:4px;min-width:140px;z-index:1000;display:flex;flex-direction:column;gap:2px}.menu-item[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;padding:8px 12px;border:none;background:none;width:100%;text-align:left;cursor:pointer;border-radius:6px;font-size:14px;color:#1a1a1a;transition:background .2s ease}.menu-item[_ngcontent-%COMP%]:hover{background:#f5f7fa}.menu-item[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:#5f6368}.delete-item[_ngcontent-%COMP%]{color:#dc3545}.delete-item[_ngcontent-%COMP%]:hover{background:#fee}.delete-item[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{color:#dc3545}.loading-container[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;gap:16px}.spinner[_ngcontent-%COMP%]{width:40px;height:40px;border:3px solid #f5f7fa;border-top-color:#ff5337;border-radius:50%;animation:_ngcontent-%COMP%_spin .8s linear infinite}@keyframes _ngcontent-%COMP%_spin{to{transform:rotate(360deg)}}.loading-text[_ngcontent-%COMP%]{color:#95a5a6;font-size:14px;margin:0}.empty-conversations[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:center;padding:40px 20px;text-align:center}.empty-conversations[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{color:#95a5a6;font-size:14px;margin:0}.load-more[_ngcontent-%COMP%]{display:flex;justify-content:center;margin-top:12px}.load-more-button[_ngcontent-%COMP%]{background:transparent;border:1px solid rgba(0,0,0,.1);border-radius:999px;color:#2c3e50;font-size:13px;padding:6px 16px;cursor:pointer;transition:background .2s ease,border-color .2s ease}.load-more-button[_ngcontent-%COMP%]:hover:not(:disabled){background:#0000000a;border-color:#0003}.load-more-button[_ngcontent-%COMP%]:disabled{cursor:not-allowed;opacity:.6}.sidebar-footer[_ngcontent-%COMP%]{padding:16px;border-top:1px solid #e8ecf1;display:flex;align-items:center;gap:12px}.search-container[_ngcontent-%COMP%]{flex:1;position:relative;display:flex;align-items:center;background:#f5f7fa;border-radius:8px;padding:8px 12px;gap:8px}.search-icon[_ngcontent-%COMP%]{flex-shrink:0;color:#95a5a6}.search-input[_ngcontent-%COMP%]{flex:1;border:none;background:none;font-size:14px;color:#1a1a1a;outline:none;padding:0}.search-input[_ngcontent-%COMP%]::placeholder{color:#95a5a6}.new-chat-button[_ngcontent-%COMP%]{flex-shrink:0;background:#fff;border:1px solid #e8ecf1;border-radius:8px;width:40px;height:40px;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.new-chat-button[_ngcontent-%COMP%]:hover{background:#f5f7fa;border-color:#d0d7de}@media (max-width: 480px){.sidebar[_ngcontent-%COMP%]{width:100%;max-width:none}}"]})},vp=class wr{toasts=ae([]);toasts$=this.toasts.asReadonly();show(t,n="info",r=3e3){let i=Math.random().toString(36).substring(7),s={id:i,message:t,type:n,duration:r};this.toasts.update(o=>[...o,s]),r>0&&setTimeout(()=>this.remove(i),r)}success(t,n){this.show(t,"success",n)}error(t,n){this.show(t,"error",n)}warning(t,n){this.show(t,"warning",n)}info(t,n){this.show(t,"info",n)}remove(t){this.toasts.update(n=>n.filter(r=>r.id!==t))}static \u0275fac=function(t){return new(t||wr)};static \u0275prov=O({token:wr,factory:wr.\u0275fac,providedIn:"root"})};function Fw(e,t){e&1&&(f(0,"span"),z(1,"\u2713"),y())}function jw(e,t){e&1&&(f(0,"span"),z(1,"\u2715"),y())}function zw(e,t){e&1&&(f(0,"span"),z(1,"\u26A0"),y())}function Hw(e,t){e&1&&(f(0,"span"),z(1,"\u2139"),y())}function Bw(e,t){if(e&1){let n=et();f(0,"div",2)(1,"div",3)(2,"span",4),hh(3,5),fe(4,Fw,2,0,"span",6)(5,jw,2,0,"span",6)(6,zw,2,0,"span",6)(7,Hw,2,0,"span",6),ph(),y(),f(8,"span",7),z(9),y()(),f(10,"button",8),M("click",function(){let r=V(n).$implicit,i=I();return N(i.onClose(r.id))}),z(11,"\u2715"),y()()}if(e&2){let n=t.$implicit;Te("success",n.type==="success")("error",n.type==="error")("warning",n.type==="warning")("info",n.type==="info"),x(3),A("ngSwitch",n.type),x(),A("ngSwitchCase","success"),x(),A("ngSwitchCase","error"),x(),A("ngSwitchCase","warning"),x(),A("ngSwitchCase","info"),x(2),Ee(n.message)}}var Uw=class Xs{toastService=v(vp);toasts=this.toastService.toasts$;onClose(t){this.toastService.remove(t)}static \u0275fac=function(t){return new(t||Xs)};static \u0275cmp=Ie({type:Xs,selectors:[["app-toast-container"]],decls:2,vars:1,consts:[[1,"toast-container"],["class","toast",3,"success","error","warning","info",4,"ngFor","ngForOf"],[1,"toast"],[1,"toast-content"],[1,"toast-icon"],[3,"ngSwitch"],[4,"ngSwitchCase"],[1,"toast-message"],[1,"toast-close",3,"click"]],template:function(t,n){t&1&&(f(0,"div",0),fe(1,Bw,12,14,"div",1),y()),t&2&&(x(),A("ngForOf",n.toasts()))},dependencies:[_e,ki,Ih,yC],styles:[".toast-container[_ngcontent-%COMP%]{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;gap:12px;max-width:400px}.toast[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-radius:8px;box-shadow:0 4px 12px #00000026;background:#fff;min-width:300px;animation:_ngcontent-%COMP%_slideIn .3s ease-out}@keyframes _ngcontent-%COMP%_slideIn{0%{transform:translate(400px);opacity:0}to{transform:translate(0);opacity:1}}.toast-content[_ngcontent-%COMP%]{display:flex;align-items:center;gap:12px;flex:1}.toast-icon[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;font-size:14px;font-weight:700}.toast.success[_ngcontent-%COMP%]{border-left:4px solid #10b981}.toast.success[_ngcontent-%COMP%] .toast-icon[_ngcontent-%COMP%]{background:#10b981;color:#fff}.toast.error[_ngcontent-%COMP%]{border-left:4px solid #ef4444}.toast.error[_ngcontent-%COMP%] .toast-icon[_ngcontent-%COMP%]{background:#ef4444;color:#fff}.toast.warning[_ngcontent-%COMP%]{border-left:4px solid #f59e0b}.toast.warning[_ngcontent-%COMP%] .toast-icon[_ngcontent-%COMP%]{background:#f59e0b;color:#fff}.toast.info[_ngcontent-%COMP%]{border-left:4px solid #3b82f6}.toast.info[_ngcontent-%COMP%] .toast-icon[_ngcontent-%COMP%]{background:#3b82f6;color:#fff}.toast-message[_ngcontent-%COMP%]{flex:1;font-size:14px;color:#2c3e50;line-height:1.4}.toast-close[_ngcontent-%COMP%]{background:none;border:none;color:#95a5a6;cursor:pointer;font-size:18px;padding:4px 8px;display:flex;align-items:center;justify-content:center;transition:color .2s}.toast-close[_ngcontent-%COMP%]:hover{color:#2c3e50}@media (max-width: 768px){.toast-container[_ngcontent-%COMP%]{top:10px;right:10px;left:10px;max-width:none}.toast[_ngcontent-%COMP%]{min-width:auto}}"]})},yp=class xr{isOpenSignal=ae(!1);configSignal=ae(null);resolveCallback=null;isOpen$=this.isOpenSignal.asReadonly();config$=this.configSignal.asReadonly();confirm(t){return this.configSignal.set(T({confirmText:"Confirm",cancelText:"Cancel",confirmColor:"primary"},t)),this.isOpenSignal.set(!0),new Promise(n=>{this.resolveCallback=n})}close(t){this.isOpenSignal.set(!1),this.resolveCallback&&(this.resolveCallback(t),this.resolveCallback=null)}static \u0275fac=function(t){return new(t||xr)};static \u0275prov=O({token:xr,factory:xr.\u0275fac,providedIn:"root"})};function $w(e,t){if(e&1){let n=et();f(0,"div",1),M("click",function(){V(n);let r=I();return N(r.onOverlayClick())}),f(1,"div",2),M("click",function(r){V(n);let i=I();return N(i.onModalClick(r))}),f(2,"div",3)(3,"button",4),M("click",function(){V(n);let r=I();return N(r.onBackClick())}),q(4,"app-icon",5),y(),f(5,"h2",6),z(6),y(),f(7,"button",7),M("click",function(){V(n);let r=I();return N(r.onCloseClick())}),q(8,"app-icon",8),y()(),f(9,"div",9)(10,"p",10),z(11),y()(),f(12,"div",11)(13,"button",12),M("click",function(){V(n);let r=I();return N(r.onCancel())}),z(14),y(),f(15,"button",13),M("click",function(){V(n);let r=I();return N(r.onConfirm())}),z(16),y()()()()}if(e&2){let n,r,i,s,o,a,l=I();x(6),Ee(((n=l.config())==null?null:n.title)||"Back"),x(5),Ee((r=l.config())==null?null:r.message),x(3),Vn(" ",((i=l.config())==null?null:i.cancelText)||"Cancel"," "),x(),Te("btn-danger",((s=l.config())==null?null:s.confirmColor)==="danger")("btn-primary",((o=l.config())==null?null:o.confirmColor)==="primary"),x(),Vn(" ",((a=l.config())==null?null:a.confirmText)||"Confirm"," ")}}var qw=class eo{confirmationService=v(yp);isOpen=this.confirmationService.isOpen$;config=this.confirmationService.config$;onConfirm(){this.confirmationService.close(!0)}onCancel(){this.confirmationService.close(!1)}onBackClick(){this.confirmationService.close(!1)}onCloseClick(){this.confirmationService.close(!1)}onOverlayClick(){this.confirmationService.close(!1)}onModalClick(t){t.stopPropagation()}static \u0275fac=function(t){return new(t||eo)};static \u0275cmp=Ie({type:eo,selectors:[["app-confirmation-modal"]],decls:1,vars:1,consts:[["class","modal-overlay",3,"click",4,"ngIf"],[1,"modal-overlay",3,"click"],[1,"modal-container",3,"click"],[1,"modal-header"],["aria-label","Back",1,"icon-button","back-button",3,"click"],["name","chevron-left","width","24","height","24"],[1,"modal-title"],["aria-label","Close",1,"icon-button","close-button",3,"click"],["name","close","width","24","height","24"],[1,"modal-body"],[1,"modal-message"],[1,"modal-footer"],[1,"btn","btn-cancel",3,"click"],[1,"btn","btn-confirm",3,"click"]],template:function(t,n){t&1&&fe(0,$w,17,8,"div",0),t&2&&A("ngIf",n.isOpen())},dependencies:[_e,an,ln],styles:[".modal-overlay[_ngcontent-%COMP%]{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:flex-end;justify-content:center;z-index:10000;animation:_ngcontent-%COMP%_fadeIn .2s ease-out}@keyframes _ngcontent-%COMP%_fadeIn{0%{opacity:0}to{opacity:1}}.modal-container[_ngcontent-%COMP%]{background-color:#fff;border-radius:16px 16px 0 0;width:100%;max-width:600px;max-height:90vh;display:flex;flex-direction:column;box-shadow:0 -2px 24px #00000026;animation:_ngcontent-%COMP%_slideUp .3s ease-out}@keyframes _ngcontent-%COMP%_slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.modal-header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e5e7eb;gap:12px}.modal-title[_ngcontent-%COMP%]{flex:1;text-align:center;font-size:18px;font-weight:600;color:#111827;margin:0}.icon-button[_ngcontent-%COMP%]{background:none;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:8px;color:#6b7280;transition:all .2s ease}.icon-button[_ngcontent-%COMP%]:hover{background-color:#f3f4f6;color:#111827}.icon-button[_ngcontent-%COMP%]:active{transform:scale(.95)}.back-button[_ngcontent-%COMP%], .close-button[_ngcontent-%COMP%]{flex-shrink:0}.modal-body[_ngcontent-%COMP%]{padding:32px 20px;flex:1;overflow-y:auto}.modal-message[_ngcontent-%COMP%]{margin:0;font-size:16px;line-height:1.5;color:#111827;text-align:left}.modal-footer[_ngcontent-%COMP%]{display:flex;gap:12px;padding:16px 20px;border-top:1px solid #e5e7eb}.btn[_ngcontent-%COMP%]{flex:1;padding:12px 24px;font-size:16px;font-weight:500;border-radius:8px;border:none;cursor:pointer;transition:all .2s ease;font-family:inherit}.btn[_ngcontent-%COMP%]:active{transform:scale(.98)}.btn-cancel[_ngcontent-%COMP%]{background-color:#fff;color:#374151;border:1px solid #d1d5db}.btn-cancel[_ngcontent-%COMP%]:hover{background-color:#f9fafb;border-color:#9ca3af}.btn-confirm[_ngcontent-%COMP%]{color:#fff}.btn-primary[_ngcontent-%COMP%]{background-color:#3b82f6}.btn-primary[_ngcontent-%COMP%]:hover{background-color:#2563eb}.btn-danger[_ngcontent-%COMP%]{background-color:#ef4444}.btn-danger[_ngcontent-%COMP%]:hover{background-color:#dc2626}.btn-danger[_ngcontent-%COMP%]:disabled, .btn-primary[_ngcontent-%COMP%]:disabled{opacity:.5;cursor:not-allowed}@media (min-width: 768px){.modal-overlay[_ngcontent-%COMP%]{align-items:center}.modal-container[_ngcontent-%COMP%]{border-radius:16px;max-height:500px}}"]})},ri={production:!0,apiUrl:"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io",apiTimeout:6e4,environmentName:"production"},Zw=class kr{http=v(ga);logger=v(Ye);get apiUrl(){return ri.apiUrl}get timeout(){return ri.apiTimeout}createConversation(t){return this.http.post(`${this.apiUrl}/conversations`,t).pipe(pt(this.timeout),ke(this.handleError))}getConversations(t,n,r=0,i=20){let s=new qe().set("offset",r.toString()).set("limit",i.toString());return t&&(s=s.set("status",t)),n&&(s=s.set("search",n)),this.http.get(`${this.apiUrl}/conversations`,{params:s}).pipe(pt(this.timeout),ke(this.handleError))}getConversation(t){return this.http.get(`${this.apiUrl}/conversations/${t}`).pipe(pt(this.timeout),ke(this.handleError))}deleteConversation(t){return this.http.delete(`${this.apiUrl}/conversations/${t}`).pipe(pt(this.timeout),ke(this.handleError))}updateConversationTitle(t,n){return this.http.patch(`${this.apiUrl}/conversations/${t}/title`,n).pipe(pt(this.timeout),ke(this.handleError))}sendMessage(t,n){return this.http.post(`${this.apiUrl}/conversations/${t}/messages`,n).pipe(pt(this.timeout),ke(this.handleError))}getMessages(t,n=0,r=20){let i=new qe().set("offset",n.toString()).set("limit",r.toString());return this.http.get(`${this.apiUrl}/conversations/${t}/messages`,{params:i}).pipe(pt(this.timeout),ke(this.handleError))}handleError=t=>{this.logger.error("API Error:",t);let n="An error occurred";return t.error instanceof ErrorEvent?n=`Error: ${t.error.message}`:n=`Error Code: ${t.status}
24
- Message: ${t.message}`,po(()=>new Error(n))};static \u0275fac=function(t){return new(t||kr)};static \u0275prov=O({token:kr,factory:kr.\u0275fac,providedIn:"root"})},Gw=class Sr{apiService=v(Zw);logger=v(Ye);pageSize=10;chatState=ae({messages:[],isLoading:!1,currentInput:"",isLoadingMore:!1,hasMoreHistory:!1,pageSize:this.pageSize,currentOffset:0,totalMessages:0});currentConversationId=null;mockAppId="00000000-0000-0000-0000-000000000001";typingSimulationDelay=500;getState(){return this.chatState.asReadonly()}addMessage(t,n){let r={id:this.generateId(),text:t,sender:n,timestamp:new Date,isTyping:!1};this.chatState.update(i=>D(T({},i),{messages:[...i.messages,r],totalMessages:i.totalMessages+1}))}sendMessage(t){return Y(this,null,function*(){try{this.addMessage(t,"user"),this.chatState.update(i=>D(T({},i),{isLoading:!0})),this.currentConversationId||(yield this.createConversation());let n={id:"typing-"+Date.now(),text:"",sender:"assistant",timestamp:new Date,isTyping:!0};this.chatState.update(i=>D(T({},i),{messages:[...i.messages,n]})),yield this.delay(this.typingSimulationDelay);let r=yield tt(this.apiService.sendMessage(this.currentConversationId,{message:t}));this.chatState.update(i=>D(T({},i),{messages:i.messages.filter(s=>s.id!==n.id),isLoading:!1})),this.addMessage(r.assistantMessage,"assistant")}catch(n){this.logger.error("Error sending message:",n),this.chatState.update(r=>D(T({},r),{messages:r.messages.filter(i=>!i.isTyping),isLoading:!1})),this.addMessage("Sorry, I encountered an error. Please try again.","assistant")}})}createConversation(){return Y(this,null,function*(){try{let t=yield tt(this.apiService.createConversation({appId:this.mockAppId,title:"New Chat"}));this.currentConversationId=t.id}catch(t){throw this.logger.error("Error creating conversation:",t),t}})}loadConversation(t){return Y(this,null,function*(){try{this.chatState.update(o=>D(T({},o),{isLoading:!0}));let n=this.pageSize,r=yield tt(this.apiService.getMessages(t,0,n)),i=r.total,s=(r.messages??[]).slice().reverse().map(o=>({id:o.id,text:o.content,sender:o.role==="user"?"user":"assistant",timestamp:new Date(o.createdAt),isTyping:!1}));this.currentConversationId=t,this.chatState.update(o=>D(T({},o),{messages:s,isLoading:!1,hasMoreHistory:r.hasMore,currentOffset:r.offset+s.length,totalMessages:i,pageSize:n,isLoadingMore:!1}))}catch(n){this.logger.error("Error loading conversation:",n),this.chatState.update(r=>D(T({},r),{isLoading:!1}))}})}clearChat(){this.chatState.update(t=>D(T({},t),{messages:[],hasMoreHistory:!1,currentOffset:0,totalMessages:0,isLoadingMore:!1})),this.currentConversationId=null}getCurrentConversationId(){return this.currentConversationId}getConversations(t,n,r=0,i=20){return Y(this,null,function*(){try{return yield tt(this.apiService.getConversations(t,n,r,i))}catch(s){throw this.logger.error("Error loading conversations:",s),s}})}deleteConversation(t){return Y(this,null,function*(){try{yield tt(this.apiService.deleteConversation(t)),this.currentConversationId===t&&this.clearChat()}catch(n){throw this.logger.error("Error deleting conversation:",n),n}})}updateConversationTitle(t,n){return Y(this,null,function*(){try{yield tt(this.apiService.updateConversationTitle(t,{title:n}))}catch(r){throw this.logger.error("Error updating conversation title:",r),r}})}loadMoreHistory(){return Y(this,null,function*(){let t=this.chatState();if(!this.currentConversationId||t.isLoadingMore||!t.hasMoreHistory)return;let n=t.currentOffset;this.chatState.update(r=>D(T({},r),{isLoadingMore:!0}));try{let r=yield tt(this.apiService.getMessages(this.currentConversationId,n,t.pageSize)),i=(r.messages??[]).slice().reverse().map(o=>({id:o.id,text:o.content,sender:o.role==="user"?"user":"assistant",timestamp:new Date(o.createdAt),isTyping:!1})),s=n+(r.messages?.length??0);this.chatState.update(o=>D(T({},o),{messages:[...i,...o.messages],currentOffset:s,hasMoreHistory:r.hasMore,totalMessages:r.total,isLoadingMore:!1}))}catch(r){this.logger.error("Error loading more messages:",r),this.chatState.update(i=>D(T({},i),{isLoadingMore:!1}))}})}generateId(){return`msg-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}delay(t){return new Promise(n=>setTimeout(n,t))}static \u0275fac=function(t){return new(t||Sr)};static \u0275prov=O({token:Sr,factory:Sr.\u0275fac,providedIn:"root"})},Ww=class Or{constructor(t){this.logger=t,this.initializeRecognition()}recognition=null;isSupported=!1;resolveStop=null;statusSignal=ae({state:"idle",transcript:"",interimTranscript:""});getStatus(){return this.statusSignal.asReadonly()}isVoiceRecognitionSupported(){return this.isSupported}getCurrentTranscript(){return this.statusSignal().transcript}initializeRecognition(){let t=window.SpeechRecognition||window.webkitSpeechRecognition;if(!t){this.logger.warn("Speech Recognition API is not supported in this browser"),this.isSupported=!1;return}this.isSupported=!0,this.recognition=new t,this.recognition.continuous=!0,this.recognition.interimResults=!0,this.recognition.lang="en-US",this.recognition.maxAlternatives=1,this.recognition.onstart=()=>{this.logger.debug("Voice recognition started"),this.statusSignal.update(n=>D(T({},n),{state:"listening",errorMessage:void 0}))},this.recognition.onresult=n=>{let r="",i=this.statusSignal().transcript;this.logger.debug("Voice recognition onresult event",{resultIndex:n.resultIndex,resultsLength:n.results.length});for(let s=n.resultIndex;s<n.results.length;s++){let o=n.results[s][0].transcript,a=n.results[s].isFinal;this.logger.debug(`Result ${s}:`,{transcript:o,isFinal:a}),a?i+=o+" ":r+=o}this.statusSignal.update(s=>D(T({},s),{transcript:i.trim(),interimTranscript:r.trim()})),this.logger.debug("Updated status:",{transcript:i.trim(),interimTranscript:r.trim()})},this.recognition.onerror=n=>{this.logger.error("Voice recognition error:",n.error);let r="Voice recognition error";switch(n.error){case"no-speech":r="No speech detected. Please try again.";break;case"audio-capture":r="No microphone found. Please check your microphone.";break;case"not-allowed":r="Microphone access denied. Please allow microphone access.";break;case"network":r="Network error occurred. Please check your connection.";break;default:r=`Voice recognition error: ${n.error}`}this.statusSignal.update(i=>D(T({},i),{state:"error",errorMessage:r}))},this.recognition.onend=()=>{this.logger.debug("Voice recognition ended");let n=this.statusSignal().transcript;this.logger.debug("Final transcript:",n),this.resolveStop&&(this.resolveStop({transcript:n.trim(),success:n.trim().length>0}),this.resolveStop=null),this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0})}}startListening(t="en-US"){if(!this.isSupported){this.statusSignal.set({state:"error",transcript:"",interimTranscript:"",errorMessage:"Voice recognition is not supported in this browser"});return}if(this.statusSignal().state==="listening"){this.logger.warn("Voice recognition is already active");return}this.statusSignal.set({state:"listening",transcript:"",interimTranscript:"",errorMessage:void 0});try{this.recognition.lang=t,this.recognition.start()}catch(n){this.logger.error("Failed to start voice recognition:",n),this.statusSignal.update(r=>D(T({},r),{state:"error",errorMessage:"Failed to start voice recognition"}))}}stopListening(){return Y(this,null,function*(){return this.isSupported?this.statusSignal().state!=="listening"?{transcript:"",success:!1}:new Promise(t=>{this.resolveStop=t,this.statusSignal.update(n=>D(T({},n),{state:"processing"}));try{this.recognition.stop()}catch(n){this.logger.error("Failed to stop voice recognition:",n),this.resolveStop=null,this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0}),t({transcript:"",success:!1})}}):{transcript:"",success:!1}})}cancelListening(){if(this.isSupported){if(this.statusSignal().state==="listening")try{this.recognition.abort()}catch(t){this.logger.error("Failed to cancel voice recognition:",t)}this.resolveStop&&(this.resolveStop({transcript:"",success:!1}),this.resolveStop=null),this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0})}}static \u0275fac=function(t){return new(t||Or)(C(Ye))};static \u0275prov=O({token:Or,factory:Or.\u0275fac,providedIn:"root"})},bp=class Mr{constructor(t){this.http=t}config=null;loadConfig(){return Y(this,null,function*(){try{this.config=yield tt(this.http.get("/config.json")),console.log("Configuration loaded:",this.config?.environmentName)}catch(t){console.error("Failed to load configuration, using defaults",t),this.config={apiUrl:"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io",apiTimeout:3e4,environmentName:"dev"}}})}get apiUrl(){return this.config?.apiUrl||"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io"}get apiTimeout(){return this.config?.apiTimeout||3e4}get environmentName(){return this.config?.environmentName||"dev"}getConfig(){return this.config||{apiUrl:"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io",apiTimeout:3e4,environmentName:"dev"}}setConfig(t){this.config=t,console.log("Configuration updated:",this.config.environmentName)}static \u0275fac=function(t){return new(t||Mr)(C(ga))};static \u0275prov=O({token:Mr,factory:Mr.\u0275fac,providedIn:"root"})},Cp=class Er{logger=v(Ye);TOKEN_KEY="jwt_token";CLOCK_SKEW_BUFFER=60;authState=ae({isAuthenticated:!1,token:null,user:null});state=this.authState.asReadonly();constructor(){this.initializeAuthState()}initializeAuthState(){let t=this.getToken();if(t){let n=this.getUserFromToken(t);this.authState.set({isAuthenticated:!0,token:t,user:n}),this.logger.debug("Auth state initialized from localStorage",{user:n})}else this.logger.debug("No valid token found in localStorage")}getToken(){try{let t=localStorage.getItem(this.TOKEN_KEY);return t?this.isTokenExpired()?(this.logger.warn("Token found but expired, clearing"),this.clearToken(),null):t:null}catch(t){return this.logger.error("Error reading token from localStorage",t),null}}setToken(t){try{let n=this.decodeToken(t);if(!n){this.logger.error("Cannot store invalid token");return}localStorage.setItem(this.TOKEN_KEY,t);let r=this.getUserFromToken(t);this.authState.set({isAuthenticated:!0,token:t,user:r}),this.logger.debug("Token stored successfully",{exp:n.exp,user:r})}catch(n){throw n instanceof DOMException&&(n.name==="QuotaExceededError"||n.name==="NS_ERROR_DOM_QUOTA_REACHED")?this.logger.error("localStorage quota exceeded",n):this.logger.error("Error storing token",n),n}}isTokenExpired(){try{let t=localStorage.getItem(this.TOKEN_KEY);if(!t)return!0;let n=this.decodeToken(t);if(!n)return!0;let r=n.exp,i=Math.floor(Date.now()/1e3),s=i>r-this.CLOCK_SKEW_BUFFER;return s&&this.logger.debug("Token expired",{exp:r,now:i,diff:r-i}),s}catch(t){return this.logger.error("Error checking token expiration",t),!0}}isAuthenticated(){return this.getToken()!==null}clearToken(){try{localStorage.removeItem(this.TOKEN_KEY),this.authState.set({isAuthenticated:!1,token:null,user:null}),this.logger.debug("Token cleared, user logged out")}catch(t){this.logger.error("Error clearing token",t)}}logout(){this.logger.info("User logged out"),this.clearToken()}getUserFromToken(t){let n=t||this.getToken();if(!n)return null;let r=this.decodeToken(n);return r?{id:r.sub,name:r.name,email:r.email}:null}createValidToken(){let t={alg:"HS256",typ:"JWT"},n=Math.floor(Date.now()/1e3),r={sub:"00000000-0000-0000-0000-000000000000",name:"Development User",email:"dev@localhost",iss:"http://oaa-api.azurewebsites.net/",iat:n,exp:n+1440*60},i=u=>{let c=JSON.stringify(u);return btoa(c).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")},s=i(t),o=i(r),a=i({dev:!0}),l=`${s}.${o}.${a}`;return this.logger.debug("Created development token",{exp:r.exp,expiresIn:"24 hours"}),l}validateToken(t){try{let n=this.decodeToken(t);if(!n)return{isValid:!1,isExpired:!1,error:"Invalid token format"};let r=Math.floor(Date.now()/1e3)>n.exp;return{isValid:!r,isExpired:r,payload:n}}catch(n){return{isValid:!1,isExpired:!1,error:n instanceof Error?n.message:"Unknown error"}}}decodeToken(t){try{let n=t.split(".");if(n.length!==3)return this.logger.error("Invalid token format - must have 3 parts"),null;let r=n[1];if(!r)return this.logger.error("Invalid token - missing payload"),null;let i=r.replace(/-/g,"+").replace(/_/g,"/"),s=decodeURIComponent(atob(i).split("").map(a=>"%"+("00"+a.charCodeAt(0).toString(16)).slice(-2)).join("")),o=JSON.parse(s);return!o.sub||!o.exp||!o.iat?(this.logger.error("Invalid token payload - missing required fields"),null):o}catch(n){return this.logger.error("Token decode failed",n),null}}static \u0275fac=function(t){return new(t||Er)};static \u0275prov=O({token:Er,factory:Er.\u0275fac,providedIn:"root"})};function Qw(e,t){if(e&1&&(f(0,"div",8)(1,"div",9),q(2,"app-icon",10),y(),f(3,"h1",11),z(4),y(),f(5,"p",12),z(6),y(),f(7,"p",13),z(8),y()()),e&2){let n=I();x(4),Ee(n.greeting),x(2),Ee(n.welcomeText),x(2),Ee(n.description)}}function Yw(e,t){if(e&1){let n=et();f(0,"app-chat-history",14),M("loadMore",function(){V(n);let r=I();return N(r.onLoadMoreHistory())}),y()}if(e&2){let n=I();A("messages",n.messages())("canLoadMore",n.canLoadMoreHistory())("isLoadingMore",n.isLoadingMoreHistory())}}function Kw(e,t){if(e&1){let n=et();f(0,"app-suggestion-button",19),M("buttonClick",function(r){V(n);let i=I(2);return N(i.onSuggestionClick(r))}),y()}if(e&2){let n=t.$implicit,r=I(2);A("text",n)("disabled",r.isLoading())}}function Jw(e,t){if(e&1&&(f(0,"div",15)(1,"p",16),z(2),y(),f(3,"div",17),fe(4,Kw,1,2,"app-suggestion-button",18),y()()),e&2){let n=I();x(2),Ee(n.personalizationText),x(2),A("ngForOf",n.suggestions)}}var Xw=class to{chatService=v(Gw);toastService=v(vp);confirmationService=v(yp);voiceRecognition=v(Ww);configService=v(bp);authService=v(Cp);logger=v(Ye);_apiUrl;_apiTimeout;set apiUrl(t){this._apiUrl=t,t&&this.updateConfig()}get apiUrl(){return this._apiUrl}set apiTimeout(t){this._apiTimeout=t,t&&this.updateConfig()}get apiTimeout(){return this._apiTimeout}set config(t){t&&(this.configService.setConfig(t),console.log("Config updated via Input:",t))}set jwtToken(t){t&&t.trim()&&(this.authService.setToken(t),console.log("JWT token set from parent application"))}title=Be.TITLE;greeting=Be.WELCOME.GREETING;welcomeText=Be.WELCOME.TEXT;description=Be.WELCOME.DESCRIPTION;personalizationText=Be.WELCOME.PERSONALIZATION;inputPlaceholder=Be.INPUT.PLACEHOLDER;suggestions=[...Be.SUGGESTIONS];chatState=this.chatService.getState();messages=it(()=>this.chatState().messages);isLoading=it(()=>this.chatState().isLoading);hasMessages=it(()=>this.messages().length>0);canLoadMoreHistory=it(()=>this.chatState().hasMoreHistory);isLoadingMoreHistory=it(()=>this.chatState().isLoadingMore);voiceStatus=this.voiceRecognition.getStatus();sidebarOpenSignal=ae(!1);isSidebarOpen=this.sidebarOpenSignal.asReadonly();conversationsSignal=ae([]);conversations=this.conversationsSignal.asReadonly();isLoadingConversationsSignal=ae(!1);isLoadingConversations=this.isLoadingConversationsSignal.asReadonly();searchQuerySignal=ae("");inputValueSignal=ae("");inputValue=this.inputValueSignal.asReadonly();ngOnInit(){console.log("AssistantPage initialized with config:",this.configService.getConfig())}updateConfig(){let t=this.configService.getConfig();this.configService.setConfig({apiUrl:this._apiUrl||t.apiUrl,apiTimeout:this._apiTimeout||t.apiTimeout,environmentName:t.environmentName}),console.log("Config updated:",this.configService.getConfig())}onMenuClick(){return Y(this,null,function*(){this.sidebarOpenSignal.set(!0),this.searchQuerySignal.set(""),yield this.loadConversations()})}onCloseClick(){this.chatService.clearChat()}onSuggestionClick(t){return Y(this,null,function*(){yield this.chatService.sendMessage(t)})}onMessageSubmit(t){return Y(this,null,function*(){t.trim()&&(this.inputValueSignal.set(""),yield this.chatService.sendMessage(t))})}onInputValueChange(t){this.inputValueSignal.set(t)}onVoiceClick(){return Y(this,null,function*(){let t=this.voiceStatus();if(!this.voiceRecognition.isVoiceRecognitionSupported()){this.toastService.error("Voice recognition is not supported in your browser. Please try Chrome, Edge, or Safari.");return}if(t.state==="listening"){let n=yield this.voiceRecognition.stopListening();this.logger.debug("Voice recognition result:",n),n.success&&n.transcript?(this.inputValueSignal.set(n.transcript),this.toastService.success("Voice input captured. Click send when ready.")):this.toastService.warning("No speech detected. Please try again.")}else t.state==="idle"?(this.voiceRecognition.startListening(),this.toastService.info("Listening... Click the microphone button again when done.")):t.state==="error"&&this.toastService.error(t.errorMessage||"Voice recognition error")})}onAddClick(){this.toastService.info("Attachment feature coming soon!")}onLoadMoreHistory(){return Y(this,null,function*(){yield this.chatService.loadMoreHistory()})}onSidebarBackClick(){this.sidebarOpenSignal.set(!1)}onSidebarSettingsClick(){this.toastService.info("Settings feature coming soon!")}onSidebarCloseClick(){this.sidebarOpenSignal.set(!1)}onConversationClick(t){return Y(this,null,function*(){this.sidebarOpenSignal.set(!1);try{yield this.chatService.loadConversation(t)}catch(n){this.logger.error("Failed to load conversation:",n),this.toastService.error("Failed to load conversation. Please try again.")}})}onConversationDeleteClick(t){return Y(this,null,function*(){if(this.logger.debug("Delete conversation:",t),!!(yield this.confirmationService.confirm({title:"Delete Conversation",message:"Are you sure you want to delete this conversation? This action cannot be undone.",confirmText:"Delete",cancelText:"Cancel",confirmColor:"danger"})))try{yield this.chatService.deleteConversation(t);let n=this.conversationsSignal();this.conversationsSignal.set(n.filter(r=>r.id!==t)),this.toastService.success("Conversation deleted successfully")}catch(n){this.logger.error("Failed to delete conversation:",n),this.toastService.error("Failed to delete conversation. Please try again.")}})}onNewChatClick(){this.chatService.clearChat(),this.sidebarOpenSignal.set(!1)}onSearchChange(t){return Y(this,null,function*(){this.searchQuerySignal.set(t),yield this.loadConversations()})}onConversationTitleUpdate(t){return Y(this,null,function*(){try{yield this.chatService.updateConversationTitle(t.id,t.title);let n=this.conversationsSignal();this.conversationsSignal.set(n.map(r=>r.id===t.id?D(T({},r),{title:t.title}):r)),this.toastService.success("Conversation title updated")}catch(n){this.logger.error("Failed to update conversation title:",n),this.toastService.error("Failed to update conversation title. Please try again.")}})}loadConversations(){return Y(this,null,function*(){if(!this.isLoadingConversationsSignal()){this.isLoadingConversationsSignal.set(!0);try{let t=this.searchQuerySignal(),n=(yield this.chatService.getConversations(void 0,t||void 0)).conversations.map(r=>({id:r.id,title:r.title||"Untitled Conversation",date:new Date(r.createdAt).toLocaleDateString("ru-RU",{day:"2-digit",month:"2-digit",year:"numeric"})}));this.conversationsSignal.set(n)}catch(t){this.logger.error("Failed to load conversations:",t)}finally{this.isLoadingConversationsSignal.set(!1)}}})}static \u0275fac=function(t){return new(t||to)};static \u0275cmp=Ie({type:to,selectors:[["app-assistant"]],inputs:{apiUrl:"apiUrl",apiTimeout:"apiTimeout",config:"config",jwtToken:"jwtToken",title:"title",greeting:"greeting",welcomeText:"welcomeText",description:"description",personalizationText:"personalizationText",inputPlaceholder:"inputPlaceholder",suggestions:"suggestions"},decls:10,vars:11,consts:[[3,"backClick","settingsClick","closeClick","conversationClick","deleteClick","newChatClick","searchChange","titleUpdate","isOpen","conversations","isLoading"],[1,"assistant-page"],[3,"menuClick","closeClick","title"],[1,"content"],["class","welcome-container",4,"ngIf"],[3,"messages","canLoadMore","isLoadingMore","loadMore",4,"ngIf"],["class","personalization-section",4,"ngIf"],[3,"valueChange","submitMessage","voiceClick","addClick","placeholder","disabled","voiceStatus","value"],[1,"welcome-container"],[1,"icon-wrapper"],["name","sparkle","width","64","height","64","dropShadow","drop-shadow(0 4px 8px rgba(255, 107, 107, 0.2))",1,"sparkle-icon"],[1,"greeting"],[1,"welcome-text"],[1,"description"],[3,"loadMore","messages","canLoadMore","isLoadingMore"],[1,"personalization-section"],[1,"personalization-text"],[1,"suggestions"],[3,"text","disabled","buttonClick",4,"ngFor","ngForOf"],[3,"buttonClick","text","disabled"]],template:function(t,n){t&1&&(f(0,"app-sidebar",0),M("backClick",function(){return n.onSidebarBackClick()})("settingsClick",function(){return n.onSidebarSettingsClick()})("closeClick",function(){return n.onSidebarCloseClick()})("conversationClick",function(r){return n.onConversationClick(r)})("deleteClick",function(r){return n.onConversationDeleteClick(r)})("newChatClick",function(){return n.onNewChatClick()})("searchChange",function(r){return n.onSearchChange(r)})("titleUpdate",function(r){return n.onConversationTitleUpdate(r)}),y(),f(1,"div",1)(2,"app-header",2),M("menuClick",function(){return n.onMenuClick()})("closeClick",function(){return n.onCloseClick()}),y(),f(3,"div",3),fe(4,Qw,9,3,"div",4)(5,Yw,1,3,"app-chat-history",5)(6,Jw,5,2,"div",6),y(),f(7,"app-input-field",7),M("valueChange",function(r){return n.onInputValueChange(r)})("submitMessage",function(r){return n.onMessageSubmit(r)})("voiceClick",function(){return n.onVoiceClick()})("addClick",function(){return n.onAddClick()}),y()(),q(8,"app-toast-container")(9,"app-confirmation-modal")),t&2&&(A("isOpen",n.isSidebarOpen())("conversations",n.conversations())("isLoading",n.isLoadingConversations()),x(2),A("title",n.title),x(2),A("ngIf",!n.hasMessages()),x(),A("ngIf",n.hasMessages()),x(),A("ngIf",!n.hasMessages()),x(),A("placeholder",n.inputPlaceholder)("disabled",n.isLoading())("voiceStatus",n.voiceStatus())("value",n.inputValue()))},dependencies:[_e,ki,an,V_,N_,bw,ln,Mw,Lw,Uw,qw],styles:["[_nghost-%COMP%]{display:block;height:100%;width:100%;overflow:hidden}.assistant-page[_ngcontent-%COMP%]{display:flex;flex-direction:column;height:100%;max-height:100%;width:100%;background:#fff;font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif;overflow:hidden;position:relative}.content[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden;min-height:0;position:relative;-webkit-overflow-scrolling:touch}app-chat-history[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.welcome-container[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px 20px;text-align:center;flex-shrink:0}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:12px;flex-shrink:0}.greeting[_ngcontent-%COMP%]{font-size:24px;font-weight:700;margin:0 0 8px;color:#1a1a1a;flex-shrink:0}.welcome-text[_ngcontent-%COMP%]{font-size:16px;font-weight:500;margin:0 0 8px;color:#333;flex-shrink:0}.description[_ngcontent-%COMP%]{font-size:14px;font-weight:400;margin:0 0 12px;color:#666;max-width:400px;line-height:1.4;flex-shrink:0}.personalization-section[_ngcontent-%COMP%]{padding:0 20px 16px;display:flex;flex-direction:column;align-items:center;gap:12px;flex-shrink:0;max-width:100%;box-sizing:border-box}.personalization-text[_ngcontent-%COMP%]{font-size:14px;color:#666;margin:0;text-align:center;max-width:400px;line-height:1.4;flex-shrink:0}.suggestions[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;max-width:400px;flex-shrink:0}@media (max-width: 768px){.greeting[_ngcontent-%COMP%]{font-size:20px}.welcome-text[_ngcontent-%COMP%]{font-size:15px}.description[_ngcontent-%COMP%]{font-size:13px;margin-bottom:8px}.welcome-container[_ngcontent-%COMP%]{padding:12px 16px}.personalization-section[_ngcontent-%COMP%]{padding:0 16px 12px;gap:10px}.personalization-text[_ngcontent-%COMP%]{font-size:13px}.suggestions[_ngcontent-%COMP%]{max-width:100%;gap:8px}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:8px}}@media (max-height: 600px){.greeting[_ngcontent-%COMP%]{font-size:18px;margin-bottom:6px}.welcome-text[_ngcontent-%COMP%]{font-size:14px;margin-bottom:6px}.description[_ngcontent-%COMP%]{font-size:12px;margin-bottom:8px}.welcome-container[_ngcontent-%COMP%]{padding:8px 16px}.personalization-section[_ngcontent-%COMP%]{padding:0 16px 8px;gap:8px}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:6px}.icon-wrapper[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{transform:scale(.8)}}"]})},ex=class Tr{authService=v(Cp);logger=v(Ye);isLoggingOut=!1;PUBLIC_ENDPOINTS=["/config.json","/assets/"];intercept(t,n){if(this.isPublicEndpoint(t.url))return this.logger.debug("Public endpoint, skipping auth",{url:t.url}),n.handle(t);let r=this.authService.getToken();if(!r&&!ri.production&&(this.logger.debug("No token found in localStorage, creating development token"),r=this.authService.createValidToken(),this.authService.setToken(r)),!r)return this.logger.debug("No token available, proceeding without auth header"),n.handle(t);let i=t.clone({setHeaders:{Authorization:`Bearer ${r}`}});return this.logger.debug("Added Authorization header to request",{url:t.url}),n.handle(i).pipe(ke(s=>(s.status===401?this.handle401Error(s):s.status===403?this.handle403Error(s):s.status===0&&this.handleNetworkError(s),po(()=>s))))}isPublicEndpoint(t){return this.PUBLIC_ENDPOINTS.some(n=>t.includes(n))}handle401Error(t){if(this.isLoggingOut){this.logger.debug("Logout already in progress, skipping");return}this.isLoggingOut=!0,this.logger.warn("401 Unauthorized - authentication failed, logging out",{url:t.url,message:t.message}),this.authService.logout(),setTimeout(()=>{this.isLoggingOut=!1},1e3)}handle403Error(t){this.logger.warn("403 Forbidden - insufficient permissions",{url:t.url,message:t.message})}handleNetworkError(t){this.logger.error("Network error - server unreachable or timeout",{url:t.url,message:t.message})}static \u0275fac=function(t){return new(t||Tr)};static \u0275prov=O({token:Tr,factory:Tr.\u0275fac})};function _p(e){return()=>e.loadConfig()}Y(null,null,function*(){if(customElements.get("app-assistant")){console.log("\u26A0\uFE0F Web Component already registered, skipping...");return}let e=yield jC({providers:[dm(),db({eventCoalescing:!0}),b_(C_()),{provide:Yh,useClass:ex,multi:!0},{provide:lh,useFactory:_p,deps:[bp],multi:!0},Ah,D_.forRoot({level:ri.production?W.WARN:W.DEBUG,serverLogLevel:W.ERROR,disableConsoleLogging:!1,enableSourceMaps:!0,timestampFormat:"short"}).providers||[]]}),t=qb(Xw,{injector:e.injector});customElements.define("app-assistant",t),console.log("\u2705 Web Component registered: app-assistant")});return Mp(tx);})();
24
+ Message: ${t.message}`,po(()=>new Error(n))};static \u0275fac=function(t){return new(t||kr)};static \u0275prov=O({token:kr,factory:kr.\u0275fac,providedIn:"root"})},Gw=class Sr{apiService=v(Zw);logger=v(Ye);pageSize=10;chatState=ae({messages:[],isLoading:!1,currentInput:"",isLoadingMore:!1,hasMoreHistory:!1,pageSize:this.pageSize,currentOffset:0,totalMessages:0});currentConversationId=null;mockAppId="00000000-0000-0000-0000-000000000001";typingSimulationDelay=500;getState(){return this.chatState.asReadonly()}addMessage(t,n){let r={id:this.generateId(),text:t,sender:n,timestamp:new Date,isTyping:!1};this.chatState.update(i=>D(T({},i),{messages:[...i.messages,r],totalMessages:i.totalMessages+1}))}sendMessage(t){return Y(this,null,function*(){try{this.addMessage(t,"user"),this.chatState.update(i=>D(T({},i),{isLoading:!0})),this.currentConversationId||(yield this.createConversation());let n={id:"typing-"+Date.now(),text:"",sender:"assistant",timestamp:new Date,isTyping:!0};this.chatState.update(i=>D(T({},i),{messages:[...i.messages,n]})),yield this.delay(this.typingSimulationDelay);let r=yield tt(this.apiService.sendMessage(this.currentConversationId,{message:t}));this.chatState.update(i=>D(T({},i),{messages:i.messages.filter(s=>s.id!==n.id),isLoading:!1})),this.addMessage(r.assistantMessage,"assistant")}catch(n){this.logger.error("Error sending message:",n),this.chatState.update(r=>D(T({},r),{messages:r.messages.filter(i=>!i.isTyping),isLoading:!1})),this.addMessage("Sorry, I encountered an error. Please try again.","assistant")}})}createConversation(){return Y(this,null,function*(){try{let t=yield tt(this.apiService.createConversation({appId:this.mockAppId,title:"New chat"}));this.currentConversationId=t.id}catch(t){throw this.logger.error("Error creating conversation:",t),t}})}loadConversation(t){return Y(this,null,function*(){try{this.chatState.update(o=>D(T({},o),{isLoading:!0}));let n=this.pageSize,r=yield tt(this.apiService.getMessages(t,0,n)),i=r.total,s=(r.messages??[]).slice().reverse().map(o=>({id:o.id,text:o.content,sender:o.role==="user"?"user":"assistant",timestamp:new Date(o.createdAt),isTyping:!1}));this.currentConversationId=t,this.chatState.update(o=>D(T({},o),{messages:s,isLoading:!1,hasMoreHistory:r.hasMore,currentOffset:r.offset+s.length,totalMessages:i,pageSize:n,isLoadingMore:!1}))}catch(n){this.logger.error("Error loading conversation:",n),this.chatState.update(r=>D(T({},r),{isLoading:!1}))}})}clearChat(){this.chatState.update(t=>D(T({},t),{messages:[],hasMoreHistory:!1,currentOffset:0,totalMessages:0,isLoadingMore:!1})),this.currentConversationId=null}getCurrentConversationId(){return this.currentConversationId}getConversations(t,n,r=0,i=20){return Y(this,null,function*(){try{return yield tt(this.apiService.getConversations(t,n,r,i))}catch(s){throw this.logger.error("Error loading conversations:",s),s}})}deleteConversation(t){return Y(this,null,function*(){try{yield tt(this.apiService.deleteConversation(t)),this.currentConversationId===t&&this.clearChat()}catch(n){throw this.logger.error("Error deleting conversation:",n),n}})}updateConversationTitle(t,n){return Y(this,null,function*(){try{yield tt(this.apiService.updateConversationTitle(t,{title:n}))}catch(r){throw this.logger.error("Error updating conversation title:",r),r}})}loadMoreHistory(){return Y(this,null,function*(){let t=this.chatState();if(!this.currentConversationId||t.isLoadingMore||!t.hasMoreHistory)return;let n=t.currentOffset;this.chatState.update(r=>D(T({},r),{isLoadingMore:!0}));try{let r=yield tt(this.apiService.getMessages(this.currentConversationId,n,t.pageSize)),i=(r.messages??[]).slice().reverse().map(o=>({id:o.id,text:o.content,sender:o.role==="user"?"user":"assistant",timestamp:new Date(o.createdAt),isTyping:!1})),s=n+(r.messages?.length??0);this.chatState.update(o=>D(T({},o),{messages:[...i,...o.messages],currentOffset:s,hasMoreHistory:r.hasMore,totalMessages:r.total,isLoadingMore:!1}))}catch(r){this.logger.error("Error loading more messages:",r),this.chatState.update(i=>D(T({},i),{isLoadingMore:!1}))}})}generateId(){return`msg-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}delay(t){return new Promise(n=>setTimeout(n,t))}static \u0275fac=function(t){return new(t||Sr)};static \u0275prov=O({token:Sr,factory:Sr.\u0275fac,providedIn:"root"})},Ww=class Or{constructor(t){this.logger=t,this.initializeRecognition()}recognition=null;isSupported=!1;resolveStop=null;statusSignal=ae({state:"idle",transcript:"",interimTranscript:""});getStatus(){return this.statusSignal.asReadonly()}isVoiceRecognitionSupported(){return this.isSupported}getCurrentTranscript(){return this.statusSignal().transcript}initializeRecognition(){let t=window.SpeechRecognition||window.webkitSpeechRecognition;if(!t){this.logger.warn("Speech Recognition API is not supported in this browser"),this.isSupported=!1;return}this.isSupported=!0,this.recognition=new t,this.recognition.continuous=!0,this.recognition.interimResults=!0,this.recognition.lang="en-US",this.recognition.maxAlternatives=1,this.recognition.onstart=()=>{this.logger.debug("Voice recognition started"),this.statusSignal.update(n=>D(T({},n),{state:"listening",errorMessage:void 0}))},this.recognition.onresult=n=>{let r="",i=this.statusSignal().transcript;this.logger.debug("Voice recognition onresult event",{resultIndex:n.resultIndex,resultsLength:n.results.length});for(let s=n.resultIndex;s<n.results.length;s++){let o=n.results[s][0].transcript,a=n.results[s].isFinal;this.logger.debug(`Result ${s}:`,{transcript:o,isFinal:a}),a?i+=o+" ":r+=o}this.statusSignal.update(s=>D(T({},s),{transcript:i.trim(),interimTranscript:r.trim()})),this.logger.debug("Updated status:",{transcript:i.trim(),interimTranscript:r.trim()})},this.recognition.onerror=n=>{this.logger.error("Voice recognition error:",n.error);let r="Voice recognition error";switch(n.error){case"no-speech":r="No speech detected. Please try again.";break;case"audio-capture":r="No microphone found. Please check your microphone.";break;case"not-allowed":r="Microphone access denied. Please allow microphone access.";break;case"network":r="Network error occurred. Please check your connection.";break;default:r=`Voice recognition error: ${n.error}`}this.statusSignal.update(i=>D(T({},i),{state:"error",errorMessage:r}))},this.recognition.onend=()=>{this.logger.debug("Voice recognition ended");let n=this.statusSignal().transcript;this.logger.debug("Final transcript:",n),this.resolveStop&&(this.resolveStop({transcript:n.trim(),success:n.trim().length>0}),this.resolveStop=null),this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0})}}startListening(t="en-US"){if(!this.isSupported){this.statusSignal.set({state:"error",transcript:"",interimTranscript:"",errorMessage:"Voice recognition is not supported in this browser"});return}if(this.statusSignal().state==="listening"){this.logger.warn("Voice recognition is already active");return}this.statusSignal.set({state:"listening",transcript:"",interimTranscript:"",errorMessage:void 0});try{this.recognition.lang=t,this.recognition.start()}catch(n){this.logger.error("Failed to start voice recognition:",n),this.statusSignal.update(r=>D(T({},r),{state:"error",errorMessage:"Failed to start voice recognition"}))}}stopListening(){return Y(this,null,function*(){return this.isSupported?this.statusSignal().state!=="listening"?{transcript:"",success:!1}:new Promise(t=>{this.resolveStop=t,this.statusSignal.update(n=>D(T({},n),{state:"processing"}));try{this.recognition.stop()}catch(n){this.logger.error("Failed to stop voice recognition:",n),this.resolveStop=null,this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0}),t({transcript:"",success:!1})}}):{transcript:"",success:!1}})}cancelListening(){if(this.isSupported){if(this.statusSignal().state==="listening")try{this.recognition.abort()}catch(t){this.logger.error("Failed to cancel voice recognition:",t)}this.resolveStop&&(this.resolveStop({transcript:"",success:!1}),this.resolveStop=null),this.statusSignal.set({state:"idle",transcript:"",interimTranscript:"",errorMessage:void 0})}}static \u0275fac=function(t){return new(t||Or)(C(Ye))};static \u0275prov=O({token:Or,factory:Or.\u0275fac,providedIn:"root"})},bp=class Mr{constructor(t){this.http=t}config=null;loadConfig(){return Y(this,null,function*(){try{this.config=yield tt(this.http.get("/config.json")),console.log("Configuration loaded:",this.config?.environmentName)}catch(t){console.error("Failed to load configuration, using defaults",t),this.config={apiUrl:"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io",apiTimeout:3e4,environmentName:"dev"}}})}get apiUrl(){return this.config?.apiUrl||"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io"}get apiTimeout(){return this.config?.apiTimeout||3e4}get environmentName(){return this.config?.environmentName||"dev"}getConfig(){return this.config||{apiUrl:"https://ca-oaa-ai-dev-we-api.proudforest-87e29140.westeurope.azurecontainerapps.io",apiTimeout:3e4,environmentName:"dev"}}setConfig(t){this.config=t,console.log("Configuration updated:",this.config.environmentName)}static \u0275fac=function(t){return new(t||Mr)(C(ga))};static \u0275prov=O({token:Mr,factory:Mr.\u0275fac,providedIn:"root"})},Cp=class Er{logger=v(Ye);TOKEN_KEY="jwt_token";CLOCK_SKEW_BUFFER=60;authState=ae({isAuthenticated:!1,token:null,user:null});state=this.authState.asReadonly();constructor(){this.initializeAuthState()}initializeAuthState(){let t=this.getToken();if(t){let n=this.getUserFromToken(t);this.authState.set({isAuthenticated:!0,token:t,user:n}),this.logger.debug("Auth state initialized from localStorage",{user:n})}else this.logger.debug("No valid token found in localStorage")}getToken(){try{let t=localStorage.getItem(this.TOKEN_KEY);return t?this.isTokenExpired()?(this.logger.warn("Token found but expired, clearing"),this.clearToken(),null):t:null}catch(t){return this.logger.error("Error reading token from localStorage",t),null}}setToken(t){try{let n=this.decodeToken(t);if(!n){this.logger.error("Cannot store invalid token");return}localStorage.setItem(this.TOKEN_KEY,t);let r=this.getUserFromToken(t);this.authState.set({isAuthenticated:!0,token:t,user:r}),this.logger.debug("Token stored successfully",{exp:n.exp,user:r})}catch(n){throw n instanceof DOMException&&(n.name==="QuotaExceededError"||n.name==="NS_ERROR_DOM_QUOTA_REACHED")?this.logger.error("localStorage quota exceeded",n):this.logger.error("Error storing token",n),n}}isTokenExpired(){try{let t=localStorage.getItem(this.TOKEN_KEY);if(!t)return!0;let n=this.decodeToken(t);if(!n)return!0;let r=n.exp,i=Math.floor(Date.now()/1e3),s=i>r-this.CLOCK_SKEW_BUFFER;return s&&this.logger.debug("Token expired",{exp:r,now:i,diff:r-i}),s}catch(t){return this.logger.error("Error checking token expiration",t),!0}}isAuthenticated(){return this.getToken()!==null}clearToken(){try{localStorage.removeItem(this.TOKEN_KEY),this.authState.set({isAuthenticated:!1,token:null,user:null}),this.logger.debug("Token cleared, user logged out")}catch(t){this.logger.error("Error clearing token",t)}}logout(){this.logger.info("User logged out"),this.clearToken()}getUserFromToken(t){let n=t||this.getToken();if(!n)return null;let r=this.decodeToken(n);return r?{id:r.sub,name:r.name,email:r.email}:null}createValidToken(){let t={alg:"HS256",typ:"JWT"},n=Math.floor(Date.now()/1e3),r={sub:"00000000-0000-0000-0000-000000000000",name:"Development User",email:"dev@localhost",iss:"http://oaa-api.azurewebsites.net/",iat:n,exp:n+1440*60},i=u=>{let c=JSON.stringify(u);return btoa(c).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")},s=i(t),o=i(r),a=i({dev:!0}),l=`${s}.${o}.${a}`;return this.logger.debug("Created development token",{exp:r.exp,expiresIn:"24 hours"}),l}validateToken(t){try{let n=this.decodeToken(t);if(!n)return{isValid:!1,isExpired:!1,error:"Invalid token format"};let r=Math.floor(Date.now()/1e3)>n.exp;return{isValid:!r,isExpired:r,payload:n}}catch(n){return{isValid:!1,isExpired:!1,error:n instanceof Error?n.message:"Unknown error"}}}decodeToken(t){try{let n=t.split(".");if(n.length!==3)return this.logger.error("Invalid token format - must have 3 parts"),null;let r=n[1];if(!r)return this.logger.error("Invalid token - missing payload"),null;let i=r.replace(/-/g,"+").replace(/_/g,"/"),s=decodeURIComponent(atob(i).split("").map(a=>"%"+("00"+a.charCodeAt(0).toString(16)).slice(-2)).join("")),o=JSON.parse(s);return!o.sub||!o.exp||!o.iat?(this.logger.error("Invalid token payload - missing required fields"),null):o}catch(n){return this.logger.error("Token decode failed",n),null}}static \u0275fac=function(t){return new(t||Er)};static \u0275prov=O({token:Er,factory:Er.\u0275fac,providedIn:"root"})};function Qw(e,t){if(e&1&&(f(0,"div",8)(1,"div",9),q(2,"app-icon",10),y(),f(3,"h1",11),z(4),y(),f(5,"p",12),z(6),y(),f(7,"p",13),z(8),y()()),e&2){let n=I();x(4),Ee(n.greeting),x(2),Ee(n.welcomeText),x(2),Ee(n.description)}}function Yw(e,t){if(e&1){let n=et();f(0,"app-chat-history",14),M("loadMore",function(){V(n);let r=I();return N(r.onLoadMoreHistory())}),y()}if(e&2){let n=I();A("messages",n.messages())("canLoadMore",n.canLoadMoreHistory())("isLoadingMore",n.isLoadingMoreHistory())}}function Kw(e,t){if(e&1){let n=et();f(0,"app-suggestion-button",19),M("buttonClick",function(r){V(n);let i=I(2);return N(i.onSuggestionClick(r))}),y()}if(e&2){let n=t.$implicit,r=I(2);A("text",n)("disabled",r.isLoading())}}function Jw(e,t){if(e&1&&(f(0,"div",15)(1,"p",16),z(2),y(),f(3,"div",17),fe(4,Kw,1,2,"app-suggestion-button",18),y()()),e&2){let n=I();x(2),Ee(n.personalizationText),x(2),A("ngForOf",n.suggestions)}}var Xw=class to{chatService=v(Gw);toastService=v(vp);confirmationService=v(yp);voiceRecognition=v(Ww);configService=v(bp);authService=v(Cp);logger=v(Ye);_apiUrl;_apiTimeout;set apiUrl(t){this._apiUrl=t,t&&this.updateConfig()}get apiUrl(){return this._apiUrl}set apiTimeout(t){this._apiTimeout=t,t&&this.updateConfig()}get apiTimeout(){return this._apiTimeout}set config(t){t&&(this.configService.setConfig(t),console.log("Config updated via Input:",t))}set jwtToken(t){t&&t.trim()&&(this.authService.setToken(t),console.log("JWT token set from parent application"))}title=Be.TITLE;greeting=Be.WELCOME.GREETING;welcomeText=Be.WELCOME.TEXT;description=Be.WELCOME.DESCRIPTION;personalizationText=Be.WELCOME.PERSONALIZATION;inputPlaceholder=Be.INPUT.PLACEHOLDER;suggestions=[...Be.SUGGESTIONS];chatState=this.chatService.getState();messages=it(()=>this.chatState().messages);isLoading=it(()=>this.chatState().isLoading);hasMessages=it(()=>this.messages().length>0);canLoadMoreHistory=it(()=>this.chatState().hasMoreHistory);isLoadingMoreHistory=it(()=>this.chatState().isLoadingMore);voiceStatus=this.voiceRecognition.getStatus();sidebarOpenSignal=ae(!1);isSidebarOpen=this.sidebarOpenSignal.asReadonly();conversationsSignal=ae([]);conversations=this.conversationsSignal.asReadonly();isLoadingConversationsSignal=ae(!1);isLoadingConversations=this.isLoadingConversationsSignal.asReadonly();searchQuerySignal=ae("");inputValueSignal=ae("");inputValue=this.inputValueSignal.asReadonly();ngOnInit(){console.log("AssistantPage initialized with config:",this.configService.getConfig())}updateConfig(){let t=this.configService.getConfig();this.configService.setConfig({apiUrl:this._apiUrl||t.apiUrl,apiTimeout:this._apiTimeout||t.apiTimeout,environmentName:t.environmentName}),console.log("Config updated:",this.configService.getConfig())}onMenuClick(){return Y(this,null,function*(){this.sidebarOpenSignal.set(!0),this.searchQuerySignal.set(""),yield this.loadConversations()})}onCloseClick(){this.chatService.clearChat()}onSuggestionClick(t){return Y(this,null,function*(){yield this.chatService.sendMessage(t)})}onMessageSubmit(t){return Y(this,null,function*(){t.trim()&&(this.inputValueSignal.set(""),yield this.chatService.sendMessage(t))})}onInputValueChange(t){this.inputValueSignal.set(t)}onVoiceClick(){return Y(this,null,function*(){let t=this.voiceStatus();if(!this.voiceRecognition.isVoiceRecognitionSupported()){this.toastService.error("Voice recognition is not supported in your browser. Please try Chrome, Edge, or Safari.");return}if(t.state==="listening"){let n=yield this.voiceRecognition.stopListening();this.logger.debug("Voice recognition result:",n),n.success&&n.transcript?(this.inputValueSignal.set(n.transcript),this.toastService.success("Voice input captured. Click send when ready.")):this.toastService.warning("No speech detected. Please try again.")}else t.state==="idle"?(this.voiceRecognition.startListening(),this.toastService.info("Listening... Click the microphone button again when done.")):t.state==="error"&&this.toastService.error(t.errorMessage||"Voice recognition error")})}onAddClick(){this.toastService.info("Attachment feature coming soon!")}onLoadMoreHistory(){return Y(this,null,function*(){yield this.chatService.loadMoreHistory()})}onSidebarBackClick(){this.sidebarOpenSignal.set(!1)}onSidebarSettingsClick(){this.toastService.info("Settings feature coming soon!")}onSidebarCloseClick(){this.sidebarOpenSignal.set(!1)}onConversationClick(t){return Y(this,null,function*(){this.sidebarOpenSignal.set(!1);try{yield this.chatService.loadConversation(t)}catch(n){this.logger.error("Failed to load conversation:",n),this.toastService.error("Failed to load conversation. Please try again.")}})}onConversationDeleteClick(t){return Y(this,null,function*(){if(this.logger.debug("Delete conversation:",t),!!(yield this.confirmationService.confirm({title:"Delete Conversation",message:"Are you sure you want to delete this conversation? This action cannot be undone.",confirmText:"Delete",cancelText:"Cancel",confirmColor:"danger"})))try{yield this.chatService.deleteConversation(t);let n=this.conversationsSignal();this.conversationsSignal.set(n.filter(r=>r.id!==t)),this.toastService.success("Conversation deleted successfully")}catch(n){this.logger.error("Failed to delete conversation:",n),this.toastService.error("Failed to delete conversation. Please try again.")}})}onNewChatClick(){this.chatService.clearChat(),this.sidebarOpenSignal.set(!1)}onSearchChange(t){return Y(this,null,function*(){this.searchQuerySignal.set(t),yield this.loadConversations()})}onConversationTitleUpdate(t){return Y(this,null,function*(){try{yield this.chatService.updateConversationTitle(t.id,t.title);let n=this.conversationsSignal();this.conversationsSignal.set(n.map(r=>r.id===t.id?D(T({},r),{title:t.title}):r)),this.toastService.success("Conversation title updated")}catch(n){this.logger.error("Failed to update conversation title:",n),this.toastService.error("Failed to update conversation title. Please try again.")}})}loadConversations(){return Y(this,null,function*(){if(!this.isLoadingConversationsSignal()){this.isLoadingConversationsSignal.set(!0);try{let t=this.searchQuerySignal(),n=(yield this.chatService.getConversations(void 0,t||void 0)).conversations.map(r=>({id:r.id,title:r.title||"Untitled Conversation",date:new Date(r.createdAt).toLocaleDateString("ru-RU",{day:"2-digit",month:"2-digit",year:"numeric"})}));this.conversationsSignal.set(n)}catch(t){this.logger.error("Failed to load conversations:",t)}finally{this.isLoadingConversationsSignal.set(!1)}}})}static \u0275fac=function(t){return new(t||to)};static \u0275cmp=Ie({type:to,selectors:[["app-assistant"]],inputs:{apiUrl:"apiUrl",apiTimeout:"apiTimeout",config:"config",jwtToken:"jwtToken",title:"title",greeting:"greeting",welcomeText:"welcomeText",description:"description",personalizationText:"personalizationText",inputPlaceholder:"inputPlaceholder",suggestions:"suggestions"},decls:10,vars:11,consts:[[3,"backClick","settingsClick","closeClick","conversationClick","deleteClick","newChatClick","searchChange","titleUpdate","isOpen","conversations","isLoading"],[1,"assistant-page"],[3,"menuClick","closeClick","title"],[1,"content"],["class","welcome-container",4,"ngIf"],[3,"messages","canLoadMore","isLoadingMore","loadMore",4,"ngIf"],["class","personalization-section",4,"ngIf"],[3,"valueChange","submitMessage","voiceClick","addClick","placeholder","disabled","voiceStatus","value"],[1,"welcome-container"],[1,"icon-wrapper"],["name","sparkle","width","64","height","64","dropShadow","drop-shadow(0 4px 8px rgba(255, 107, 107, 0.2))",1,"sparkle-icon"],[1,"greeting"],[1,"welcome-text"],[1,"description"],[3,"loadMore","messages","canLoadMore","isLoadingMore"],[1,"personalization-section"],[1,"personalization-text"],[1,"suggestions"],[3,"text","disabled","buttonClick",4,"ngFor","ngForOf"],[3,"buttonClick","text","disabled"]],template:function(t,n){t&1&&(f(0,"app-sidebar",0),M("backClick",function(){return n.onSidebarBackClick()})("settingsClick",function(){return n.onSidebarSettingsClick()})("closeClick",function(){return n.onSidebarCloseClick()})("conversationClick",function(r){return n.onConversationClick(r)})("deleteClick",function(r){return n.onConversationDeleteClick(r)})("newChatClick",function(){return n.onNewChatClick()})("searchChange",function(r){return n.onSearchChange(r)})("titleUpdate",function(r){return n.onConversationTitleUpdate(r)}),y(),f(1,"div",1)(2,"app-header",2),M("menuClick",function(){return n.onMenuClick()})("closeClick",function(){return n.onCloseClick()}),y(),f(3,"div",3),fe(4,Qw,9,3,"div",4)(5,Yw,1,3,"app-chat-history",5)(6,Jw,5,2,"div",6),y(),f(7,"app-input-field",7),M("valueChange",function(r){return n.onInputValueChange(r)})("submitMessage",function(r){return n.onMessageSubmit(r)})("voiceClick",function(){return n.onVoiceClick()})("addClick",function(){return n.onAddClick()}),y()(),q(8,"app-toast-container")(9,"app-confirmation-modal")),t&2&&(A("isOpen",n.isSidebarOpen())("conversations",n.conversations())("isLoading",n.isLoadingConversations()),x(2),A("title",n.title),x(2),A("ngIf",!n.hasMessages()),x(),A("ngIf",n.hasMessages()),x(),A("ngIf",!n.hasMessages()),x(),A("placeholder",n.inputPlaceholder)("disabled",n.isLoading())("voiceStatus",n.voiceStatus())("value",n.inputValue()))},dependencies:[_e,ki,an,V_,N_,bw,ln,Mw,Lw,Uw,qw],styles:["[_nghost-%COMP%]{display:block;height:100%;width:100%;overflow:hidden}.assistant-page[_ngcontent-%COMP%]{display:flex;flex-direction:column;height:100%;max-height:100%;width:100%;background:#fff;font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif;overflow:hidden;position:relative}.content[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden;min-height:0;position:relative;-webkit-overflow-scrolling:touch}app-chat-history[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}.welcome-container[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px 20px;text-align:center;flex-shrink:0}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:12px;flex-shrink:0}.greeting[_ngcontent-%COMP%]{font-size:24px;font-weight:700;margin:0 0 8px;color:#1a1a1a;flex-shrink:0}.welcome-text[_ngcontent-%COMP%]{font-size:16px;font-weight:500;margin:0 0 8px;color:#333;flex-shrink:0}.description[_ngcontent-%COMP%]{font-size:14px;font-weight:400;margin:0 0 12px;color:#666;max-width:400px;line-height:1.4;flex-shrink:0}.personalization-section[_ngcontent-%COMP%]{padding:0 20px 16px;display:flex;flex-direction:column;align-items:center;gap:12px;flex-shrink:0;max-width:100%;box-sizing:border-box}.personalization-text[_ngcontent-%COMP%]{font-size:14px;color:#666;margin:0;text-align:center;max-width:400px;line-height:1.4;flex-shrink:0}.suggestions[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;max-width:400px;flex-shrink:0}@media (max-width: 768px){.greeting[_ngcontent-%COMP%]{font-size:20px}.welcome-text[_ngcontent-%COMP%]{font-size:15px}.description[_ngcontent-%COMP%]{font-size:13px;margin-bottom:8px}.welcome-container[_ngcontent-%COMP%]{padding:12px 16px}.personalization-section[_ngcontent-%COMP%]{padding:0 16px 12px;gap:10px}.personalization-text[_ngcontent-%COMP%]{font-size:13px}.suggestions[_ngcontent-%COMP%]{max-width:100%;gap:8px}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:8px}}@media (max-height: 600px){.greeting[_ngcontent-%COMP%]{font-size:18px;margin-bottom:6px}.welcome-text[_ngcontent-%COMP%]{font-size:14px;margin-bottom:6px}.description[_ngcontent-%COMP%]{font-size:12px;margin-bottom:8px}.welcome-container[_ngcontent-%COMP%]{padding:8px 16px}.personalization-section[_ngcontent-%COMP%]{padding:0 16px 8px;gap:8px}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:6px}.icon-wrapper[_ngcontent-%COMP%] app-icon[_ngcontent-%COMP%]{transform:scale(.8)}}"]})},ex=class Tr{authService=v(Cp);logger=v(Ye);isLoggingOut=!1;PUBLIC_ENDPOINTS=["/config.json","/assets/"];intercept(t,n){if(this.isPublicEndpoint(t.url))return this.logger.debug("Public endpoint, skipping auth",{url:t.url}),n.handle(t);let r=this.authService.getToken();if(!r&&!ri.production&&(this.logger.debug("No token found in localStorage, creating development token"),r=this.authService.createValidToken(),this.authService.setToken(r)),!r)return this.logger.debug("No token available, proceeding without auth header"),n.handle(t);let i=t.clone({setHeaders:{Authorization:`Bearer ${r}`}});return this.logger.debug("Added Authorization header to request",{url:t.url}),n.handle(i).pipe(ke(s=>(s.status===401?this.handle401Error(s):s.status===403?this.handle403Error(s):s.status===0&&this.handleNetworkError(s),po(()=>s))))}isPublicEndpoint(t){return this.PUBLIC_ENDPOINTS.some(n=>t.includes(n))}handle401Error(t){if(this.isLoggingOut){this.logger.debug("Logout already in progress, skipping");return}this.isLoggingOut=!0,this.logger.warn("401 Unauthorized - authentication failed, logging out",{url:t.url,message:t.message}),this.authService.logout(),setTimeout(()=>{this.isLoggingOut=!1},1e3)}handle403Error(t){this.logger.warn("403 Forbidden - insufficient permissions",{url:t.url,message:t.message})}handleNetworkError(t){this.logger.error("Network error - server unreachable or timeout",{url:t.url,message:t.message})}static \u0275fac=function(t){return new(t||Tr)};static \u0275prov=O({token:Tr,factory:Tr.\u0275fac})};function _p(e){return()=>e.loadConfig()}Y(null,null,function*(){if(customElements.get("app-assistant")){console.log("\u26A0\uFE0F Web Component already registered, skipping...");return}let e=yield jC({providers:[dm(),db({eventCoalescing:!0}),b_(C_()),{provide:Yh,useClass:ex,multi:!0},{provide:lh,useFactory:_p,deps:[bp],multi:!0},Ah,D_.forRoot({level:ri.production?W.WARN:W.DEBUG,serverLogLevel:W.ERROR,disableConsoleLogging:!1,enableSourceMaps:!0,timestampFormat:"short"}).providers||[]]}),t=qb(Xw,{injector:e.injector});customElements.define("app-assistant",t),console.log("\u2705 Web Component registered: app-assistant")});return Mp(tx);})();
25
25
  /*! Bundled license information:
26
26
 
27
27
  @angular/core/fesm2022/not_found.mjs:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mbubela/oaa-assistant",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "OpenAsApp AI Assistant - Web Components (Angular Elements)",
5
5
  "main": "bundles/web-components.js",
6
6
  "files": [