@mbubela/oaa-assistant 0.0.8 → 0.0.9
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 +3 -2
- package/bundles/web-components.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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 zl[this.name]?.viewBox||"0 0 24 24"}get svgContent(){let t=zl[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(tf))};static \u0275cmp=Pe({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),ph("innerHTML",n.svgContent,yd),ia("width",n.width)("height",n.height)("viewBox",n.viewBox)("fill",n.fill))},dependencies:[we],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"]},Vw=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=Pe({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&&(p(0,"div",0)(1,"button",1),E("click",function(){return n.onMenuClick()}),q(2,"app-icon",2),y(),p(3,"div",3),q(4,"app-icon",4),p(5,"span"),H(6),y()(),p(7,"button",5),E("click",function(){return n.onCloseClick()}),q(8,"app-icon",6),y()()),t&2&&(x(6),Me(n.title))},dependencies:[we,ln],styles:[".header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;background:#fff;border-bottom:1px solid #f0f0f0;height:64px;box-sizing:border-box}.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}"]})},Nw=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=Pe({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()}),H(1),oa()),t&2&&(Te("disabled",n.disabled),x(),Vn(" ",n.text," "))},dependencies:[we],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}"]})},rf=(()=>{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(Mt))};static \u0275dir=Ce({type:e})}return e})(),Rw=(()=>{class e extends rf{static \u0275fac=(()=>{let n;return function(r){return(n||(n=Zc(e)))(r||e)}})();static \u0275dir=Ce({type:e,features:[on]})}return e})(),sf=new S(""),Lw={provide:sf,useExisting:Nn(()=>qn),multi:!0};function Fw(){let e=ei()?ei().getUserAgent():"";return/android (\d+)/.test(e.toLowerCase())}var jw=new S(""),qn=(()=>{class e extends rf{_compositionMode;_composing=!1;constructor(n,r,i){super(n,r),this._compositionMode=i,this._compositionMode==null&&(this._compositionMode=!Fw())}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(Mt),j(jw,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&&E("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([Lw]),on]})}return e})();function Hw(e){return e==null?null:Array.isArray(e)||typeof e=="string"?e.length:e instanceof Set?e.size:null}var of=new S(""),zw=new S("");function Bw(e){return t=>{let n=t.value?.length??Hw(t.value);return n!==null&&n>e?{maxlength:{requiredLength:e,actualLength:n}}:null}}function Bl(e){return null}function af(e){return e!=null}function lf(e){return ra(e)?ho(e):e}function uf(e){let t={};return e.forEach(n=>{t=n!=null?T(T({},t),n):t}),Object.keys(t).length===0?null:t}function cf(e,t){return t.map(n=>n(e))}function Uw(e){return!e.validate}function df(e){return e.map(t=>Uw(t)?t:n=>t.validate(n))}function $w(e){if(!e)return null;let t=e.filter(af);return t.length==0?null:function(n){return uf(cf(n,t))}}function hf(e){return e!=null?$w(df(e)):null}function qw(e){if(!e)return null;let t=e.filter(af);return t.length==0?null:function(n){let r=cf(n,t).map(lf);return Yp(r).pipe(Oe(uf))}}function ff(e){return e!=null?qw(df(e)):null}function Ul(e,t){return e===null?[t]:Array.isArray(e)?[...e,t]:[e,t]}function Zw(e){return e._rawValidators}function Gw(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 pf=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=hf(this._rawValidators)}_setAsyncValidators(e){this._rawAsyncValidators=e||[],this._composedAsyncValidatorFn=ff(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}},Ww=class extends pf{name;get formDirective(){return null}get path(){return null}},va=class extends pf{_parent=null;name=null;valueAccessor=null},Qw=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}},Yw={"[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({},Yw),{"[class.ng-submitted]":"isSubmitted"}),ya=(()=>{class e extends Qw{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",fn="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}},Kw=class extends Zn{source;constructor(e){super(),this.source=e}};function Jw(e){return(Ei(e)?e.validators:e)||null}function Xw(e){return Array.isArray(e)?hf(e):e||null}function e_(e,t){return(Ei(t)?t.asyncValidators:e)||null}function t_(e){return Array.isArray(e)?ff(e):e||null}function Ei(e){return e!=null&&!Array.isArray(e)&&typeof e=="object"}var n_=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 Pt(this.statusReactive)}set status(e){Pt(()=>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===fn}get enabled(){return this.status!==fn}errors;get pristine(){return Pt(this.pristineReactive)}set pristine(e){Pt(()=>this.pristineReactive.set(e))}_pristine=it(()=>this.pristineReactive());pristineReactive=ae(!0);get dirty(){return!this.pristine}get touched(){return Pt(this.touchedReactive)}set touched(e){Pt(()=>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=fn,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()?fn: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=lf(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()?fn: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){Ei(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=Xw(this._rawValidators)}_assignAsyncValidators(e){this._rawAsyncValidators=Array.isArray(e)?e.slice():e,this._composedAsyncValidatorFn=t_(this._rawAsyncValidators)}},gf=new S("",{providedIn:"root",factory:()=>ba}),ba="always";function r_(e,t){return[...t.path,e]}function i_(e,t,n=ba){o_(e,t),t.valueAccessor.writeValue(e.value),(e.disabled||n==="always")&&t.valueAccessor.setDisabledState?.(e.disabled),a_(e,t),u_(e,t),l_(e,t),s_(e,t)}function Gl(e,t){e.forEach(n=>{n.registerOnValidatorChange&&n.registerOnValidatorChange(t)})}function s_(e,t){if(t.valueAccessor.setDisabledState){let n=r=>{t.valueAccessor.setDisabledState(r)};e.registerOnDisabledChange(n),t._registerOnDestroy(()=>{e._unregisterOnDisabledChange(n)})}}function o_(e,t){let n=Zw(e);t.validator!==null?e.setValidators(Ul(n,t.validator)):typeof n=="function"&&e.setValidators([n]);let r=Gw(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 a_(e,t){t.valueAccessor.registerOnChange(n=>{e._pendingValue=n,e._pendingChange=!0,e._pendingDirty=!0,e.updateOn==="change"&&mf(e,t)})}function l_(e,t){t.valueAccessor.registerOnTouched(()=>{e._pendingTouched=!0,e.updateOn==="blur"&&e._pendingChange&&mf(e,t),e.updateOn!=="submit"&&e.markAsTouched()})}function mf(e,t){e._pendingDirty&&e.markAsDirty(),e.setValue(e._pendingValue,{emitModelToViewChange:!1}),t.viewToModelUpdate(e._pendingValue),e._pendingChange=!1}function u_(e,t){let n=(r,i)=>{t.valueAccessor.writeValue(r),i&&t.viewToModelUpdate(r)};e.registerOnChange(n),t._registerOnDestroy(()=>{e._unregisterOnChange(n)})}function c_(e,t){if(!e.hasOwnProperty("model"))return!1;let n=e.model;return n.isFirstChange()?!0:!Object.is(t,n.currentValue)}function d_(e){return Object.getPrototypeOf(e.constructor)===Rw}function h_(e,t){if(!t)return null;Array.isArray(t);let n,r,i;return t.forEach(s=>{s.constructor===qn?n=s:d_(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 f_=class extends n_{defaultValue=null;_onChange=[];_pendingValue;_pendingChange=!1;constructor(e=null,t,n){super(Jw(t),e_(n,t)),this._applyFormState(e),this._setUpdateStrategy(t),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator}),Ei(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 Kw(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}},p_={provide:va,useExisting:Nn(()=>Mi)},Yl=Promise.resolve(),Mi=(()=>{class e extends va{_changeDetectorRef;callSetDisabledState;control=new f_;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=h_(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),c_(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(){i_(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?r_(n,this._parent):[n]}static \u0275fac=function(n){return new(n||e)(j(Ww,9),j(of,10),j(zw,10),j(sf,10),j(xb,8),j(gf,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([p_]),on,gi]})}return e})();function g_(e){return typeof e=="number"?e:parseInt(e,10)}var m_=(()=>{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})(),v_={provide:of,useExisting:Nn(()=>vf),multi:!0},vf=(()=>{class e extends m_{maxlength;inputName="maxlength";normalizeInput=n=>g_(n);createValidator=n=>Bw(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([v_]),on]})}return e})(),y_=(()=>{class e{static \u0275fac=function(n){return new(n||e)};static \u0275mod=_i({type:e});static \u0275inj=oi({})}return e})(),Ca=(()=>{class e{static withConfig(n){return{ngModule:e,providers:[{provide:gf,useValue:n.callSetDisabledState??ba}]}}static \u0275fac=function(n){return new(n||e)};static \u0275mod=_i({type:e});static \u0275inj=oi({imports:[y_]})}return e})(),b_=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=Pe({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&&(p(0,"div",0)(1,"div",1)(2,"button",2),E("click",function(){return n.onAddClick()}),q(3,"app-icon",3),y(),p(4,"input",4),E("ngModelChange",function(r){return n.onInputChange(r)})("keyup.enter",function(){return n.onSubmit()}),y(),p(5,"button",5),E("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:[we,Ca,qn,ya,Mi,ln],styles:[".input-container[_ngcontent-%COMP%]{padding:16px 20px;background:#fff;border-top:1px solid #f0f0f0}.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 C_(e,t){e&1&&(p(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=P();A("innerHTML",n.message.text,yd)}}var __=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=Pe({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&&(p(0,"div",0)(1,"div",1)(2,"div",2)(3,"div",3),pe(4,C_,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:[we,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%}}"]})},x_=["messagesContainer"];function k_(e,t){if(e&1&&q(0,"app-message",7),e&2){let n=t.$implicit;A("message",n)}}function S_(e,t){if(e&1&&(p(0,"div",5),pe(1,k_,1,1,"app-message",6),y()),e&2){let n=P();x(),A("ngForOf",n.messages)("ngForTrackBy",n.trackByMessageId)}}function O_(e,t){e&1&&(p(0,"div",8)(1,"p",9),H(2,"Start a conversation by typing a message or selecting a suggestion below."),y()())}var E_=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=Pe({type:Ys,selectors:[["app-chat-history"]],viewQuery:function(t,n){if(t&1&&vh(x_,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();p(0,"div",1)(1,"div",2,0),E("scroll",function(){return V(r),N(n.onScroll())}),pe(3,S_,2,2,"div",3)(4,O_,3,0,"div",4),y()()}t&2&&(x(3),A("ngIf",n.messages.length>0),x(),A("ngIf",n.messages.length===0))},dependencies:[we,ki,an,__],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 M_(e,t){if(e&1){let n=et();p(0,"div",1),E("click",function(){V(n);let r=P();return N(r.onOverlayClick())}),p(1,"div",2),E("click",function(r){V(n);let i=P();return N(i.onModalClick(r))}),p(2,"div",3)(3,"button",4),E("click",function(){V(n);let r=P();return N(r.onBackClick())}),q(4,"app-icon",5),y(),p(5,"h2",6),H(6,"Rename Chat"),y(),p(7,"button",7),E("click",function(){V(n);let r=P();return N(r.onCloseClick())}),q(8,"app-icon",8),y()(),p(9,"div",9)(10,"input",10),la("ngModelChange",function(r){V(n);let i=P();return _h(i.editedTitle,r)||(i.editedTitle=r),N(r)}),E("keydown",function(r){V(n);let i=P();return N(i.onInputKeydown(r))}),y()(),p(11,"div",11)(12,"button",12),E("click",function(){V(n);let r=P();return N(r.onCancel())}),H(13," Cancel "),y(),p(14,"button",13),E("click",function(){V(n);let r=P();return N(r.onSave())}),H(15," Save "),y()()()()}if(e&2){let n=P();x(10),aa("ngModel",n.editedTitle),A("maxlength",500)}}var T_=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=Pe({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&&pe(0,M_,16,2,"div",0),t&2&&A("ngIf",n.isOpen)},dependencies:[we,an,Ca,qn,ya,vf,Mi,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}}"]})},I_=["scrollContainer"],P_=e=>({compact:e});function A_(e,t){if(e&1){let n=et();p(0,"div",34)(1,"button",35),E("click",function(r){V(n);let i=P().$implicit,s=P(2);return N(s.onEditClick(i.id,i.title,r))}),q(2,"app-icon",36),p(3,"span"),H(4,"Rename"),y()(),p(5,"button",37),E("click",function(r){V(n);let i=P().$implicit,s=P(2);return N(s.onDeleteClick(i.id,r))}),q(6,"app-icon",38),p(7,"span"),H(8,"Delete"),y()()()}}function D_(e,t){if(e&1){let n=et();p(0,"div",25),E("click",function(){let r=V(n).$implicit,i=P(2);return N(i.onConversationClick(r.id))}),p(1,"div",26)(2,"div",27)(3,"span",28),H(4),y()(),p(5,"span",29),H(6),y()(),p(7,"div",30)(8,"button",31),E("click",function(r){let i=V(n).$implicit,s=P(2);return N(s.toggleMenu(i.id,r))}),q(9,"app-icon",32),y(),pe(10,A_,9,0,"div",33),y()()}if(e&2){let n=t.$implicit,r=P(2);x(4),Me(n.title),x(2),Me(n.date),x(4),A("ngIf",r.isMenuOpen(n.id))}}function V_(e,t){if(e&1&&(p(0,"div",23),pe(1,D_,11,3,"div",24),y()),e&2){let n=P();x(),A("ngForOf",n.conversations)}}function N_(e,t){if(e&1&&(p(0,"div",39)(1,"div",40),q(2,"div",41),p(3,"p",42),H(4,"Loading conversations..."),y()()()),e&2){let n=P();x(),A("ngClass",ob(1,P_,!(n.isLoading&&n.conversations.length===0)))}}function R_(e,t){e&1&&(p(0,"div",43)(1,"p"),H(2,"No conversations yet"),y()())}var L_=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=Pe({type:Js,selectors:[["app-sidebar"]],viewQuery:function(t,n){if(t&1&&vh(I_,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();p(0,"div",1),E("click",function(){return V(r),N(n.onOverlayClick())}),y(),p(1,"div",2),E("click",function(){return V(r),N(n.onSidebarClick())}),p(2,"div",3)(3,"button",4),E("click",function(){return V(r),N(n.onBackClick())}),q(4,"app-icon",5),p(5,"span"),H(6,"Back to Chat"),y()(),p(7,"div",6)(8,"button",7),E("click",function(){return V(r),N(n.onSettingsClick())}),q(9,"app-icon",8),y(),p(10,"button",9),E("click",function(){return V(r),N(n.onCloseClick())}),q(11,"app-icon",10),y()()(),p(12,"div",11,0),E("scroll",function(){return V(r),N(n.onScroll())}),p(14,"h3",12),H(15,"Conversations"),y(),pe(16,V_,2,1,"div",13)(17,N_,5,3,"div",14)(18,R_,3,0,"div",15),y(),p(19,"div",16)(20,"div",17),q(21,"app-icon",18),p(22,"input",19),la("ngModelChange",function(i){return V(r),_h(n.searchQuery,i)||(n.searchQuery=i),N(i)}),E("input",function(){return V(r),N(n.onSearchChange())}),y()(),p(23,"button",20),E("click",function(){return V(r),N(n.onNewChatClick())}),q(24,"app-icon",21),y()()(),p(25,"app-rename-modal",22),E("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:[we,pC,ki,an,Ca,qn,ya,Mi,ln,T_],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}}"]})},yf=class _r{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||_r)};static \u0275prov=O({token:_r,factory:_r.\u0275fac,providedIn:"root"})};function F_(e,t){e&1&&(p(0,"span"),H(1,"\u2713"),y())}function j_(e,t){e&1&&(p(0,"span"),H(1,"\u2715"),y())}function H_(e,t){e&1&&(p(0,"span"),H(1,"\u26A0"),y())}function z_(e,t){e&1&&(p(0,"span"),H(1,"\u2139"),y())}function B_(e,t){if(e&1){let n=et();p(0,"div",2)(1,"div",3)(2,"span",4),hh(3,5),pe(4,F_,2,0,"span",6)(5,j_,2,0,"span",6)(6,H_,2,0,"span",6)(7,z_,2,0,"span",6),fh(),y(),p(8,"span",7),H(9),y()(),p(10,"button",8),E("click",function(){let r=V(n).$implicit,i=P();return N(i.onClose(r.id))}),H(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),Me(n.message)}}var U_=class Xs{toastService=v(yf);toasts=this.toastService.toasts$;onClose(t){this.toastService.remove(t)}static \u0275fac=function(t){return new(t||Xs)};static \u0275cmp=Pe({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&&(p(0,"div",0),pe(1,B_,12,14,"div",1),y()),t&2&&(x(),A("ngForOf",n.toasts()))},dependencies:[we,ki,Ph,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}}"]})},bf=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 $_(e,t){if(e&1){let n=et();p(0,"div",1),E("click",function(){V(n);let r=P();return N(r.onOverlayClick())}),p(1,"div",2),E("click",function(r){V(n);let i=P();return N(i.onModalClick(r))}),p(2,"div",3)(3,"button",4),E("click",function(){V(n);let r=P();return N(r.onBackClick())}),q(4,"app-icon",5),y(),p(5,"h2",6),H(6),y(),p(7,"button",7),E("click",function(){V(n);let r=P();return N(r.onCloseClick())}),q(8,"app-icon",8),y()(),p(9,"div",9)(10,"p",10),H(11),y()(),p(12,"div",11)(13,"button",12),E("click",function(){V(n);let r=P();return N(r.onCancel())}),H(14),y(),p(15,"button",13),E("click",function(){V(n);let r=P();return N(r.onConfirm())}),H(16),y()()()()}if(e&2){let n,r,i,s,o,a,l=P();x(6),Me(((n=l.config())==null?null:n.title)||"Back"),x(5),Me((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 q_=class eo{confirmationService=v(bf);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=Pe({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&&pe(0,$_,17,8,"div",0),t&2&&A("ngIf",n.isOpen())},dependencies:[we,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:3e4,environmentName:"production"},Z_=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(ft(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(ft(this.timeout),ke(this.handleError))}getConversation(t){return this.http.get(`${this.apiUrl}/conversations/${t}`).pipe(ft(this.timeout),ke(this.handleError))}deleteConversation(t){return this.http.delete(`${this.apiUrl}/conversations/${t}`).pipe(ft(this.timeout),ke(this.handleError))}updateConversationTitle(t,n){return this.http.patch(`${this.apiUrl}/conversations/${t}/title`,n).pipe(ft(this.timeout),ke(this.handleError))}sendMessage(t,n){return this.http.post(`${this.apiUrl}/conversations/${t}/messages`,n).pipe(ft(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(ft(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}`,fo(()=>new Error(n))};static \u0275fac=function(t){return new(t||kr)};static \u0275prov=O({token:kr,factory:kr.\u0275fac,providedIn:"root"})},G_=class Sr{apiService=v(Z_);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"})},W_=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"})},Cf=class Er{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||Er)(C(ga))};static \u0275prov=O({token:Er,factory:Er.\u0275fac,providedIn:"root"})},wf=class Mr{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||Mr)};static \u0275prov=O({token:Mr,factory:Mr.\u0275fac,providedIn:"root"})};function Q_(e,t){if(e&1&&(p(0,"div",8)(1,"div",9),q(2,"app-icon",10),y(),p(3,"h1",11),H(4),y(),p(5,"p",12),H(6),y(),p(7,"p",13),H(8),y()()),e&2){let n=P();x(4),Me(n.greeting),x(2),Me(n.welcomeText),x(2),Me(n.description)}}function Y_(e,t){if(e&1){let n=et();p(0,"app-chat-history",14),E("loadMore",function(){V(n);let r=P();return N(r.onLoadMoreHistory())}),y()}if(e&2){let n=P();A("messages",n.messages())("canLoadMore",n.canLoadMoreHistory())("isLoadingMore",n.isLoadingMoreHistory())}}function K_(e,t){if(e&1){let n=et();p(0,"app-suggestion-button",19),E("buttonClick",function(r){V(n);let i=P(2);return N(i.onSuggestionClick(r))}),y()}if(e&2){let n=t.$implicit,r=P(2);A("text",n)("disabled",r.isLoading())}}function J_(e,t){if(e&1&&(p(0,"div",15)(1,"p",16),H(2),y(),p(3,"div",17),pe(4,K_,1,2,"app-suggestion-button",18),y()()),e&2){let n=P();x(2),Me(n.personalizationText),x(2),A("ngForOf",n.suggestions)}}var X_=class to{chatService=v(G_);toastService=v(yf);confirmationService=v(bf);voiceRecognition=v(W_);configService=v(Cf);authService=v(wf);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=Pe({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&&(p(0,"app-sidebar",0),E("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(),p(1,"div",1)(2,"app-header",2),E("menuClick",function(){return n.onMenuClick()})("closeClick",function(){return n.onCloseClick()}),y(),p(3,"div",3),pe(4,Q_,9,3,"div",4)(5,Y_,1,3,"app-chat-history",5)(6,J_,5,2,"div",6),y(),p(7,"app-input-field",7),E("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:[we,ki,an,Vw,Nw,b_,ln,E_,L_,U_,q_],styles:[".assistant-page[_ngcontent-%COMP%]{display:flex;flex-direction:column;height:100vh;max-height:100vh;background:#fff;font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif;overflow:hidden}.content[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;overflow:hidden;min-height:0;position:relative}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:flex-end;padding:20px 24px 30px;text-align:center;flex:1}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:16px}.greeting[_ngcontent-%COMP%]{font-size:28px;font-weight:700;margin:0 0 12px;color:#1a1a1a}.welcome-text[_ngcontent-%COMP%]{font-size:18px;font-weight:500;margin:0 0 12px;color:#333}.description[_ngcontent-%COMP%]{font-size:15px;font-weight:400;margin:0 0 20px;color:#666;max-width:400px;line-height:1.4}.personalization-section[_ngcontent-%COMP%]{padding:0 24px 24px;display:flex;flex-direction:column;align-items:center;gap:16px;flex-shrink:0}.personalization-text[_ngcontent-%COMP%]{font-size:15px;color:#666;margin:0;text-align:center;max-width:400px;line-height:1.4}.suggestions[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:400px}@media (max-width: 768px){.suggestions[_ngcontent-%COMP%]{max-width:100%}}"]})},ex=class Tr{authService=v(wf);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),fo(()=>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 _f(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}),bw(Cw()),{provide:Yh,useClass:ex,multi:!0},{provide:lh,useFactory:_f,deps:[Cf],multi:!0},Ah,Dw.forRoot({level:ri.production?W.WARN:W.DEBUG,serverLogLevel:W.ERROR,disableConsoleLogging:!1,enableSourceMaps:!0,timestampFormat:"short"}).providers||[]]}),t=qb(X_,{injector:e.injector});customElements.define("app-assistant",t),console.log("\u2705 Web Component registered: app-assistant")});return Mf(tx);})();
|
|
24
|
+
Message: ${t.message}`,fo(()=>new Error(n))};static \u0275fac=function(t){return new(t||kr)};static \u0275prov=O({token:kr,factory:kr.\u0275fac,providedIn:"root"})},G_=class Sr{apiService=v(Z_);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"})},W_=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"})},Cf=class Er{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||Er)(C(ga))};static \u0275prov=O({token:Er,factory:Er.\u0275fac,providedIn:"root"})},wf=class Mr{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||Mr)};static \u0275prov=O({token:Mr,factory:Mr.\u0275fac,providedIn:"root"})};function Q_(e,t){if(e&1&&(p(0,"div",8)(1,"div",9),q(2,"app-icon",10),y(),p(3,"h1",11),H(4),y(),p(5,"p",12),H(6),y(),p(7,"p",13),H(8),y()()),e&2){let n=P();x(4),Me(n.greeting),x(2),Me(n.welcomeText),x(2),Me(n.description)}}function Y_(e,t){if(e&1){let n=et();p(0,"app-chat-history",14),E("loadMore",function(){V(n);let r=P();return N(r.onLoadMoreHistory())}),y()}if(e&2){let n=P();A("messages",n.messages())("canLoadMore",n.canLoadMoreHistory())("isLoadingMore",n.isLoadingMoreHistory())}}function K_(e,t){if(e&1){let n=et();p(0,"app-suggestion-button",19),E("buttonClick",function(r){V(n);let i=P(2);return N(i.onSuggestionClick(r))}),y()}if(e&2){let n=t.$implicit,r=P(2);A("text",n)("disabled",r.isLoading())}}function J_(e,t){if(e&1&&(p(0,"div",15)(1,"p",16),H(2),y(),p(3,"div",17),pe(4,K_,1,2,"app-suggestion-button",18),y()()),e&2){let n=P();x(2),Me(n.personalizationText),x(2),A("ngForOf",n.suggestions)}}var X_=class to{chatService=v(G_);toastService=v(yf);confirmationService=v(bf);voiceRecognition=v(W_);configService=v(Cf);authService=v(wf);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=Pe({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&&(p(0,"app-sidebar",0),E("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(),p(1,"div",1)(2,"app-header",2),E("menuClick",function(){return n.onMenuClick()})("closeClick",function(){return n.onCloseClick()}),y(),p(3,"div",3),pe(4,Q_,9,3,"div",4)(5,Y_,1,3,"app-chat-history",5)(6,J_,5,2,"div",6),y(),p(7,"app-input-field",7),E("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:[we,ki,an,Vw,Nw,b_,ln,E_,L_,U_,q_],styles:["[_nghost-%COMP%]{display:block;height:100%;width:100%}.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}.content[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column;overflow:hidden;min-height:0;position:relative}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:flex-end;padding:20px 24px 30px;text-align:center;flex:1}.icon-wrapper[_ngcontent-%COMP%]{margin-bottom:16px}.greeting[_ngcontent-%COMP%]{font-size:28px;font-weight:700;margin:0 0 12px;color:#1a1a1a}.welcome-text[_ngcontent-%COMP%]{font-size:18px;font-weight:500;margin:0 0 12px;color:#333}.description[_ngcontent-%COMP%]{font-size:15px;font-weight:400;margin:0 0 20px;color:#666;max-width:400px;line-height:1.4}.personalization-section[_ngcontent-%COMP%]{padding:0 24px 24px;display:flex;flex-direction:column;align-items:center;gap:16px;flex-shrink:0}.personalization-text[_ngcontent-%COMP%]{font-size:15px;color:#666;margin:0;text-align:center;max-width:400px;line-height:1.4}.suggestions[_ngcontent-%COMP%]{display:flex;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:400px}@media (max-width: 768px){.suggestions[_ngcontent-%COMP%]{max-width:100%}}"]})},ex=class Tr{authService=v(wf);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),fo(()=>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 _f(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}),bw(Cw()),{provide:Yh,useClass:ex,multi:!0},{provide:lh,useFactory:_f,deps:[Cf],multi:!0},Ah,Dw.forRoot({level:ri.production?W.WARN:W.DEBUG,serverLogLevel:W.ERROR,disableConsoleLogging:!1,enableSourceMaps:!0,timestampFormat:"short"}).providers||[]]}),t=qb(X_,{injector:e.injector});customElements.define("app-assistant",t),console.log("\u2705 Web Component registered: app-assistant")});return Mf(tx);})();
|
|
25
25
|
/*! Bundled license information:
|
|
26
26
|
|
|
27
27
|
@angular/core/fesm2022/not_found.mjs:
|