node-red-contrib-knx-ultimate 6.3.21 → 6.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))o(d);new MutationObserver(d=>{for(const u of d)if(u.type==="childList")for(const f of u.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&o(f)}).observe(document,{childList:!0,subtree:!0});function i(d){const u={};return d.integrity&&(u.integrity=d.integrity),d.referrerPolicy&&(u.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?u.credentials="include":d.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function o(d){if(d.ep)return;d.ep=!0;const u=i(d);fetch(d.href,u)}})();function rr(e){const t=Object.create(null);for(const i of e.split(","))t[i]=1;return i=>i in t}const we={},Ba=[],Rt=()=>{},Ki=()=>!1,Qn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),es=e=>e.startsWith("onUpdate:"),Ue=Object.assign,ir=(e,t)=>{const i=e.indexOf(t);i>-1&&e.splice(i,1)},Ed=Object.prototype.hasOwnProperty,ve=(e,t)=>Ed.call(e,t),J=Array.isArray,za=e=>Sn(e)==="[object Map]",ja=e=>Sn(e)==="[object Set]",ni=e=>Sn(e)==="[object Date]",te=e=>typeof e=="function",ke=e=>typeof e=="string",kt=e=>typeof e=="symbol",Se=e=>e!==null&&typeof e=="object",Vi=e=>(Se(e)||te(e))&&te(e.then)&&te(e.catch),Wi=Object.prototype.toString,Sn=e=>Wi.call(e),Gd=e=>Sn(e).slice(8,-1),Ui=e=>Sn(e)==="[object Object]",or=e=>ke(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,rn=rr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),ts=e=>{const t=Object.create(null);return(i=>t[i]||(t[i]=e(i)))},Fd=/-\w/g,pt=ts(e=>e.replace(Fd,t=>t.slice(1).toUpperCase())),Od=/\B([A-Z])/g,pa=ts(e=>e.replace(Od,"-$1").toLowerCase()),ji=ts(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ls=ts(e=>e?`on${ji(e)}`:""),Nt=(e,t)=>!Object.is(e,t),Kn=(e,...t)=>{for(let i=0;i<e.length;i++)e[i](...t)},Hi=(e,t,i,o=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:o,value:i})},as=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let si;const ns=()=>si||(si=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function pn(e){if(J(e)){const t={};for(let i=0;i<e.length;i++){const o=e[i],d=ke(o)?zd(o):pn(o);if(d)for(const u in d)t[u]=d[u]}return t}else if(ke(e)||Se(e))return e}const Ld=/;(?![^(]*\))/g,Md=/:([^]+)/,Bd=/\/\*[^]*?\*\//g;function zd(e){const t={};return e.replace(Bd,"").split(Ld).forEach(i=>{if(i){const o=i.split(Md);o.length>1&&(t[o[0].trim()]=o[1].trim())}}),t}function de(e){let t="";if(ke(e))t=e;else if(J(e))for(let i=0;i<e.length;i++){const o=de(e[i]);o&&(t+=o+" ")}else if(Se(e))for(const i in e)e[i]&&(t+=i+" ");return t.trim()}const $d="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Kd=rr($d);function Xi(e){return!!e||e===""}function Vd(e,t){if(e.length!==t.length)return!1;let i=!0;for(let o=0;i&&o<e.length;o++)i=Ha(e[o],t[o]);return i}function Ha(e,t){if(e===t)return!0;let i=ni(e),o=ni(t);if(i||o)return i&&o?e.getTime()===t.getTime():!1;if(i=kt(e),o=kt(t),i||o)return e===t;if(i=J(e),o=J(t),i||o)return i&&o?Vd(e,t):!1;if(i=Se(e),o=Se(t),i||o){if(!i||!o)return!1;const d=Object.keys(e).length,u=Object.keys(t).length;if(d!==u)return!1;for(const f in e){const p=e.hasOwnProperty(f),m=t.hasOwnProperty(f);if(p&&!m||!p&&m||!Ha(e[f],t[f]))return!1}}return String(e)===String(t)}function lr(e,t){return e.findIndex(i=>Ha(i,t))}const qi=e=>!!(e&&e.__v_isRef===!0),S=e=>ke(e)?e:e==null?"":J(e)||Se(e)&&(e.toString===Wi||!te(e.toString))?qi(e)?S(e.value):JSON.stringify(e,Ji,2):String(e),Ji=(e,t)=>qi(t)?Ji(e,t.value):za(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((i,[o,d],u)=>(i[Ms(o,u)+" =>"]=d,i),{})}:ja(t)?{[`Set(${t.size})`]:[...t.values()].map(i=>Ms(i))}:kt(t)?Ms(t):Se(t)&&!J(t)&&!Ui(t)?String(t):t,Ms=(e,t="")=>{var i;return kt(e)?`Symbol(${(i=e.description)!=null?i:t})`:e};let $e;class Wd{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&$e&&($e.active?(this.parent=$e,this.index=($e.scopes||($e.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,i;if(this.scopes){const o=this.scopes.slice();for(t=0,i=o.length;t<i;t++)o[t].pause()}for(t=0,i=this.effects.length;t<i;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,i;if(this.scopes){const d=this.scopes.slice();for(t=0,i=d.length;t<i;t++)d[t].resume()}const o=this.effects.slice();for(t=0,i=o.length;t<i;t++)o[t].resume()}}run(t){if(this._active){const i=$e;try{return $e=this,t()}finally{$e=i}}}on(){++this._on===1&&(this.prevScope=$e,$e=this)}off(){if(this._on>0&&--this._on===0){if($e===this)$e=this.prevScope;else{let t=$e;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let i,o;for(i=0,o=this.effects.length;i<o;i++)this.effects[i].stop();for(this.effects.length=0,i=0,o=this.cleanups.length;i<o;i++)this.cleanups[i]();if(this.cleanups.length=0,this.scopes){const d=this.scopes.slice();for(i=0,o=d.length;i<o;i++)d[i].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const d=this.parent.scopes.pop();d&&d!==this&&(this.parent.scopes[this.index]=d,d.index=this.index)}this.parent=void 0}}}function Ud(){return $e}let Te;const Bs=new WeakSet;class Zi{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,$e&&($e.active?$e.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Bs.has(this)&&(Bs.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Qi(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,ri(this),eo(this);const t=Te,i=gt;Te=this,gt=!0;try{return this.fn()}finally{to(this),Te=t,gt=i,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)cr(t);this.deps=this.depsTail=void 0,ri(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Bs.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){qs(this)&&this.run()}get dirty(){return qs(this)}}let Yi=0,on,ln;function Qi(e,t=!1){if(e.flags|=8,t){e.next=ln,ln=e;return}e.next=on,on=e}function dr(){Yi++}function ur(){if(--Yi>0)return;if(ln){let t=ln;for(ln=void 0;t;){const i=t.next;t.next=void 0,t.flags&=-9,t=i}}let e;for(;on;){let t=on;for(on=void 0;t;){const i=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(o){e||(e=o)}t=i}}if(e)throw e}function eo(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function to(e){let t,i=e.depsTail,o=i;for(;o;){const d=o.prevDep;o.version===-1?(o===i&&(i=d),cr(o),jd(o)):t=o,o.dep.activeLink=o.prevActiveLink,o.prevActiveLink=void 0,o=d}e.deps=t,e.depsTail=i}function qs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(ao(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function ao(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===gn)||(e.globalVersion=gn,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!qs(e))))return;e.flags|=2;const t=e.dep,i=Te,o=gt;Te=e,gt=!0;try{eo(e);const d=e.fn(e._value);(t.version===0||Nt(d,e._value))&&(e.flags|=128,e._value=d,t.version++)}catch(d){throw t.version++,d}finally{Te=i,gt=o,to(e),e.flags&=-3}}function cr(e,t=!1){const{dep:i,prevSub:o,nextSub:d}=e;if(o&&(o.nextSub=d,e.prevSub=void 0),d&&(d.prevSub=o,e.nextSub=void 0),i.subs===e&&(i.subs=o,!o&&i.computed)){i.computed.flags&=-5;for(let u=i.computed.deps;u;u=u.nextDep)cr(u,!0)}!t&&!--i.sc&&i.map&&i.map.delete(i.key)}function jd(e){const{prevDep:t,nextDep:i}=e;t&&(t.nextDep=i,e.prevDep=void 0),i&&(i.prevDep=t,e.nextDep=void 0)}let gt=!0;const no=[];function qt(){no.push(gt),gt=!1}function Jt(){const e=no.pop();gt=e===void 0?!0:e}function ri(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const i=Te;Te=void 0;try{t()}finally{Te=i}}}let gn=0;class Hd{constructor(t,i){this.sub=t,this.dep=i,this.version=i.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class fr{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Te||!gt||Te===this.computed)return;let i=this.activeLink;if(i===void 0||i.sub!==Te)i=this.activeLink=new Hd(Te,this),Te.deps?(i.prevDep=Te.depsTail,Te.depsTail.nextDep=i,Te.depsTail=i):Te.deps=Te.depsTail=i,so(i);else if(i.version===-1&&(i.version=this.version,i.nextDep)){const o=i.nextDep;o.prevDep=i.prevDep,i.prevDep&&(i.prevDep.nextDep=o),i.prevDep=Te.depsTail,i.nextDep=void 0,Te.depsTail.nextDep=i,Te.depsTail=i,Te.deps===i&&(Te.deps=o)}return i}trigger(t){this.version++,gn++,this.notify(t)}notify(t){dr();try{for(let i=this.subs;i;i=i.prevSub)i.sub.notify()&&i.sub.dep.notify()}finally{ur()}}}function so(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let o=t.deps;o;o=o.nextDep)so(o)}const i=e.dep.subs;i!==e&&(e.prevSub=i,i&&(i.nextSub=e)),e.dep.subs=e}}const Js=new WeakMap,Da=Symbol(""),Zs=Symbol(""),hn=Symbol("");function Ve(e,t,i){if(gt&&Te){let o=Js.get(e);o||Js.set(e,o=new Map);let d=o.get(i);d||(o.set(i,d=new fr),d.map=o,d.key=i),d.track()}}function Ht(e,t,i,o,d,u){const f=Js.get(e);if(!f){gn++;return}const p=m=>{m&&m.trigger()};if(dr(),t==="clear")f.forEach(p);else{const m=J(e),P=m&&or(i);if(m&&i==="length"){const A=Number(o);f.forEach((I,M)=>{(M==="length"||M===hn||!kt(M)&&M>=A)&&p(I)})}else switch((i!==void 0||f.has(void 0))&&p(f.get(i)),P&&p(f.get(hn)),t){case"add":m?P&&p(f.get("length")):(p(f.get(Da)),za(e)&&p(f.get(Zs)));break;case"delete":m||(p(f.get(Da)),za(e)&&p(f.get(Zs)));break;case"set":za(e)&&p(f.get(Da));break}}ur()}function La(e){const t=me(e);return t===e?t:(Ve(t,"iterate",hn),ut(e)?t:t.map(ht))}function ss(e){return Ve(e=me(e),"iterate",hn),e}function _t(e,t){return Zt(e)?Va(Na(e)?ht(t):t):ht(t)}const Xd={__proto__:null,[Symbol.iterator](){return zs(this,Symbol.iterator,e=>_t(this,e))},concat(...e){return La(this).concat(...e.map(t=>J(t)?La(t):t))},entries(){return zs(this,"entries",e=>(e[1]=_t(this,e[1]),e))},every(e,t){return Vt(this,"every",e,t,void 0,arguments)},filter(e,t){return Vt(this,"filter",e,t,i=>i.map(o=>_t(this,o)),arguments)},find(e,t){return Vt(this,"find",e,t,i=>_t(this,i),arguments)},findIndex(e,t){return Vt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Vt(this,"findLast",e,t,i=>_t(this,i),arguments)},findLastIndex(e,t){return Vt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Vt(this,"forEach",e,t,void 0,arguments)},includes(...e){return $s(this,"includes",e)},indexOf(...e){return $s(this,"indexOf",e)},join(e){return La(this).join(e)},lastIndexOf(...e){return $s(this,"lastIndexOf",e)},map(e,t){return Vt(this,"map",e,t,void 0,arguments)},pop(){return tn(this,"pop")},push(...e){return tn(this,"push",e)},reduce(e,...t){return ii(this,"reduce",e,t)},reduceRight(e,...t){return ii(this,"reduceRight",e,t)},shift(){return tn(this,"shift")},some(e,t){return Vt(this,"some",e,t,void 0,arguments)},splice(...e){return tn(this,"splice",e)},toReversed(){return La(this).toReversed()},toSorted(e){return La(this).toSorted(e)},toSpliced(...e){return La(this).toSpliced(...e)},unshift(...e){return tn(this,"unshift",e)},values(){return zs(this,"values",e=>_t(this,e))}};function zs(e,t,i){const o=ss(e),d=o[t]();return o!==e&&!ut(e)&&(d._next=d.next,d.next=()=>{const u=d._next();return u.done||(u.value=i(u.value)),u}),d}const qd=Array.prototype;function Vt(e,t,i,o,d,u){const f=ss(e),p=f!==e&&!ut(e),m=f[t];if(m!==qd[t]){const I=m.apply(e,u);return p?ht(I):I}let P=i;f!==e&&(p?P=function(I,M){return i.call(this,_t(e,I),M,e)}:i.length>2&&(P=function(I,M){return i.call(this,I,M,e)}));const A=m.call(f,P,o);return p&&d?d(A):A}function ii(e,t,i,o){const d=ss(e),u=d!==e&&!ut(e);let f=i,p=!1;d!==e&&(u?(p=o.length===0,f=function(P,A,I){return p&&(p=!1,P=_t(e,P)),i.call(this,P,_t(e,A),I,e)}):i.length>3&&(f=function(P,A,I){return i.call(this,P,A,I,e)}));const m=d[t](f,...o);return p?_t(e,m):m}function $s(e,t,i){const o=me(e);Ve(o,"iterate",hn);const d=o[t](...i);return(d===-1||d===!1)&&hr(i[0])?(i[0]=me(i[0]),o[t](...i)):d}function tn(e,t,i=[]){qt(),dr();const o=me(e)[t].apply(e,i);return ur(),Jt(),o}const Jd=rr("__proto__,__v_isRef,__isVue"),ro=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(kt));function Zd(e){kt(e)||(e=String(e));const t=me(this);return Ve(t,"has",e),t.hasOwnProperty(e)}class io{constructor(t=!1,i=!1){this._isReadonly=t,this._isShallow=i}get(t,i,o){if(i==="__v_skip")return t.__v_skip;const d=this._isReadonly,u=this._isShallow;if(i==="__v_isReactive")return!d;if(i==="__v_isReadonly")return d;if(i==="__v_isShallow")return u;if(i==="__v_raw")return o===(d?u?ou:co:u?uo:lo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(o)?t:void 0;const f=J(t);if(!d){let m;if(f&&(m=Xd[i]))return m;if(i==="hasOwnProperty")return Zd}const p=Reflect.get(t,i,We(t)?t:o);if((kt(i)?ro.has(i):Jd(i))||(d||Ve(t,"get",i),u))return p;if(We(p)){const m=f&&or(i)?p:p.value;return d&&Se(m)?Qs(m):m}return Se(p)?d?Qs(p):rs(p):p}}class oo extends io{constructor(t=!1){super(!1,t)}set(t,i,o,d){let u=t[i];const f=J(t)&&or(i);if(!this._isShallow){const P=Zt(u);if(!ut(o)&&!Zt(o)&&(u=me(u),o=me(o)),!f&&We(u)&&!We(o))return P||(u.value=o),!0}const p=f?Number(i)<t.length:ve(t,i),m=Reflect.set(t,i,o,We(t)?t:d);return t===me(d)&&m&&(p?Nt(o,u)&&Ht(t,"set",i,o):Ht(t,"add",i,o)),m}deleteProperty(t,i){const o=ve(t,i);t[i];const d=Reflect.deleteProperty(t,i);return d&&o&&Ht(t,"delete",i,void 0),d}has(t,i){const o=Reflect.has(t,i);return(!kt(i)||!ro.has(i))&&Ve(t,"has",i),o}ownKeys(t){return Ve(t,"iterate",J(t)?"length":Da),Reflect.ownKeys(t)}}class Yd extends io{constructor(t=!1){super(!0,t)}set(t,i){return!0}deleteProperty(t,i){return!0}}const Qd=new oo,eu=new Yd,tu=new oo(!0);const Ys=e=>e,Mn=e=>Reflect.getPrototypeOf(e);function au(e,t,i){return function(...o){const d=this.__v_raw,u=me(d),f=za(u),p=e==="entries"||e===Symbol.iterator&&f,m=e==="keys"&&f,P=d[e](...o),A=i?Ys:t?Va:ht;return!t&&Ve(u,"iterate",m?Zs:Da),Ue(Object.create(P),{next(){const{value:I,done:M}=P.next();return M?{value:I,done:M}:{value:p?[A(I[0]),A(I[1])]:A(I),done:M}}})}}function Bn(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function nu(e,t){const i={get(d){const u=this.__v_raw,f=me(u),p=me(d);e||(Nt(d,p)&&Ve(f,"get",d),Ve(f,"get",p));const{has:m}=Mn(f),P=t?Ys:e?Va:ht;if(m.call(f,d))return P(u.get(d));if(m.call(f,p))return P(u.get(p));u!==f&&u.get(d)},get size(){const d=this.__v_raw;return!e&&Ve(me(d),"iterate",Da),d.size},has(d){const u=this.__v_raw,f=me(u),p=me(d);return e||(Nt(d,p)&&Ve(f,"has",d),Ve(f,"has",p)),d===p?u.has(d):u.has(d)||u.has(p)},forEach(d,u){const f=this,p=f.__v_raw,m=me(p),P=t?Ys:e?Va:ht;return!e&&Ve(m,"iterate",Da),p.forEach((A,I)=>d.call(u,P(A),P(I),f))}};return Ue(i,e?{add:Bn("add"),set:Bn("set"),delete:Bn("delete"),clear:Bn("clear")}:{add(d){const u=me(this),f=Mn(u),p=me(d),m=!t&&!ut(d)&&!Zt(d)?p:d;return f.has.call(u,m)||Nt(d,m)&&f.has.call(u,d)||Nt(p,m)&&f.has.call(u,p)||(u.add(m),Ht(u,"add",m,m)),this},set(d,u){!t&&!ut(u)&&!Zt(u)&&(u=me(u));const f=me(this),{has:p,get:m}=Mn(f);let P=p.call(f,d);P||(d=me(d),P=p.call(f,d));const A=m.call(f,d);return f.set(d,u),P?Nt(u,A)&&Ht(f,"set",d,u):Ht(f,"add",d,u),this},delete(d){const u=me(this),{has:f,get:p}=Mn(u);let m=f.call(u,d);m||(d=me(d),m=f.call(u,d)),p&&p.call(u,d);const P=u.delete(d);return m&&Ht(u,"delete",d,void 0),P},clear(){const d=me(this),u=d.size!==0,f=d.clear();return u&&Ht(d,"clear",void 0,void 0),f}}),["keys","values","entries",Symbol.iterator].forEach(d=>{i[d]=au(d,e,t)}),i}function pr(e,t){const i=nu(e,t);return(o,d,u)=>d==="__v_isReactive"?!e:d==="__v_isReadonly"?e:d==="__v_raw"?o:Reflect.get(ve(i,d)&&d in o?i:o,d,u)}const su={get:pr(!1,!1)},ru={get:pr(!1,!0)},iu={get:pr(!0,!1)};const lo=new WeakMap,uo=new WeakMap,co=new WeakMap,ou=new WeakMap;function lu(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function rs(e){return Zt(e)?e:gr(e,!1,Qd,su,lo)}function du(e){return gr(e,!1,tu,ru,uo)}function Qs(e){return gr(e,!0,eu,iu,co)}function gr(e,t,i,o,d){if(!Se(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const u=d.get(e);if(u)return u;const f=lu(Gd(e));if(f===0)return e;const p=new Proxy(e,f===2?o:i);return d.set(e,p),p}function Na(e){return Zt(e)?Na(e.__v_raw):!!(e&&e.__v_isReactive)}function Zt(e){return!!(e&&e.__v_isReadonly)}function ut(e){return!!(e&&e.__v_isShallow)}function hr(e){return e?!!e.__v_raw:!1}function me(e){const t=e&&e.__v_raw;return t?me(t):e}function uu(e){return!ve(e,"__v_skip")&&Object.isExtensible(e)&&Hi(e,"__v_skip",!0),e}const ht=e=>Se(e)?rs(e):e,Va=e=>Se(e)?Qs(e):e;function We(e){return e?e.__v_isRef===!0:!1}function da(e){return cu(e,!1)}function cu(e,t){return We(e)?e:new fu(e,t)}class fu{constructor(t,i){this.dep=new fr,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=i?t:me(t),this._value=i?t:ht(t),this.__v_isShallow=i}get value(){return this.dep.track(),this._value}set value(t){const i=this._rawValue,o=this.__v_isShallow||ut(t)||Zt(t);t=o?t:me(t),Nt(t,i)&&(this._rawValue=t,this._value=o?t:ht(t),this.dep.trigger())}}function pu(e){return We(e)?e.value:e}const gu={get:(e,t,i)=>t==="__v_raw"?e:pu(Reflect.get(e,t,i)),set:(e,t,i,o)=>{const d=e[t];return We(d)&&!We(i)?(d.value=i,!0):Reflect.set(e,t,i,o)}};function fo(e){return Na(e)?e:new Proxy(e,gu)}class hu{constructor(t,i,o){this.fn=t,this.setter=i,this._value=void 0,this.dep=new fr(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=gn-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!i,this.isSSR=o}notify(){if(this.flags|=16,!(this.flags&8)&&Te!==this)return Qi(this,!0),!0}get value(){const t=this.dep.track();return ao(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function mu(e,t,i=!1){let o,d;return te(e)?o=e:(o=e.get,d=e.set),new hu(o,d,i)}const zn={},jn=new WeakMap;let _a;function vu(e,t=!1,i=_a){if(i){let o=jn.get(i);o||jn.set(i,o=[]),o.push(e)}}function bu(e,t,i=we){const{immediate:o,deep:d,once:u,scheduler:f,augmentJob:p,call:m}=i,P=K=>d?K:ut(K)||d===!1||d===0?Xt(K,1):Xt(K);let A,I,M,$,oe=!1,U=!1;if(We(e)?(I=()=>e.value,oe=ut(e)):Na(e)?(I=()=>P(e),oe=!0):J(e)?(U=!0,oe=e.some(K=>Na(K)||ut(K)),I=()=>e.map(K=>{if(We(K))return K.value;if(Na(K))return P(K);if(te(K))return m?m(K,2):K()})):te(e)?t?I=m?()=>m(e,2):e:I=()=>{if(M){qt();try{M()}finally{Jt()}}const K=_a;_a=A;try{return m?m(e,3,[$]):e($)}finally{_a=K}}:I=Rt,t&&d){const K=I,xe=d===!0?1/0:d;I=()=>Xt(K(),xe)}const Ne=Ud(),Pe=()=>{A.stop(),Ne&&Ne.active&&ir(Ne.effects,A)};if(u&&t){const K=t;t=(...xe)=>{const Me=K(...xe);return Pe(),Me}}let re=U?new Array(e.length).fill(zn):zn;const ge=K=>{if(!(!(A.flags&1)||!A.dirty&&!K))if(t){const xe=A.run();if(K||d||oe||(U?xe.some((Me,it)=>Nt(Me,re[it])):Nt(xe,re))){M&&M();const Me=_a;_a=A;try{const it=[xe,re===zn?void 0:U&&re[0]===zn?[]:re,$];re=xe,m?m(t,3,it):t(...it)}finally{_a=Me}}}else A.run()};return p&&p(ge),A=new Zi(I),A.scheduler=f?()=>f(ge,!1):ge,$=K=>vu(K,!1,A),M=A.onStop=()=>{const K=jn.get(A);if(K){if(m)m(K,4);else for(const xe of K)xe();jn.delete(A)}},t?o?ge(!0):re=A.run():f?f(ge.bind(null,!0),!0):A.run(),Pe.pause=A.pause.bind(A),Pe.resume=A.resume.bind(A),Pe.stop=Pe,Pe}function Xt(e,t=1/0,i){if(t<=0||!Se(e)||e.__v_skip||(i=i||new Map,(i.get(e)||0)>=t))return e;if(i.set(e,t),t--,We(e))Xt(e.value,t,i);else if(J(e))for(let o=0;o<e.length;o++)Xt(e[o],t,i);else if(ja(e)||za(e))e.forEach(o=>{Xt(o,t,i)});else if(Ui(e)){for(const o in e)Xt(e[o],t,i);for(const o of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,o)&&Xt(e[o],t,i)}return e}function wn(e,t,i,o){try{return o?e(...o):e()}catch(d){is(d,t,i)}}function mt(e,t,i,o){if(te(e)){const d=wn(e,t,i,o);return d&&Vi(d)&&d.catch(u=>{is(u,t,i)}),d}if(J(e)){const d=[];for(let u=0;u<e.length;u++)d.push(mt(e[u],t,i,o));return d}}function is(e,t,i,o=!0){const d=t?t.vnode:null,{errorHandler:u,throwUnhandledErrorInProduction:f}=t&&t.appContext.config||we;if(t){let p=t.parent;const m=t.proxy,P=`https://vuejs.org/error-reference/#runtime-${i}`;for(;p;){const A=p.ec;if(A){for(let I=0;I<A.length;I++)if(A[I](e,m,P)===!1)return}p=p.parent}if(u){qt(),wn(u,null,10,[e,m,P]),Jt();return}}yu(e,i,d,o,f)}function yu(e,t,i,o=!0,d=!1){if(d)throw e;console.error(e)}const qe=[];let Tt=-1;const $a=[];let ca=null,Ma=0;const po=Promise.resolve();let Hn=null;function dn(e){const t=Hn||po;return e?t.then(this?e.bind(this):e):t}function Au(e){let t=Tt+1,i=qe.length;for(;t<i;){const o=t+i>>>1,d=qe[o],u=mn(d);u<e||u===e&&d.flags&2?t=o+1:i=o}return t}function mr(e){if(!(e.flags&1)){const t=mn(e),i=qe[qe.length-1];!i||!(e.flags&2)&&t>=mn(i)?qe.push(e):qe.splice(Au(t),0,e),e.flags|=1,go()}}function go(){Hn||(Hn=po.then(mo))}function Su(e){if(!J(e))ca&&e.id===-1?ca.splice(Ma+1,0,e):e.flags&1||($a.push(e),e.flags|=1);else for(let t=0;t<e.length;t++)$a.push(e[t]);go()}function oi(e,t,i=Tt+1){for(;i<qe.length;i++){const o=qe[i];if(o&&o.flags&2){if(e&&o.id!==e.uid)continue;qe.splice(i,1),i--,o.flags&4&&(o.flags&=-2),o(),o.flags&4||(o.flags&=-2)}}}function ho(e){if($a.length){const t=[...new Set($a)].sort((i,o)=>mn(i)-mn(o));if($a.length=0,ca){for(let i=0;i<t.length;i++)ca.push(t[i]);return}for(ca=t,Ma=0;Ma<ca.length;Ma++){const i=ca[Ma];i.flags&4&&(i.flags&=-2),i.flags&8||i(),i.flags&=-2}ca=null,Ma=0}}const mn=e=>e.id==null?e.flags&2?-1:1/0:e.id;function mo(e){try{for(Tt=0;Tt<qe.length;Tt++){const t=qe[Tt];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),wn(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Tt<qe.length;Tt++){const t=qe[Tt];t&&(t.flags&=-2)}Tt=-1,qe.length=0,ho(),Hn=null,(qe.length||$a.length)&&mo()}}let dt=null,vo=null;function Xn(e){const t=dt;return dt=e,vo=e&&e.type.__scopeId||null,t}function wu(e,t=dt,i){if(!t||e._n)return e;const o=(...d)=>{o._d&&bi(-1);const u=Xn(t),f=Ia.length;let p;try{p=e(...d)}finally{for(let m=Ia.length;m>f;m--)Vo();Xn(u),o._d&&bi(1)}return p};return o._n=!0,o._c=!0,o._d=!0,o}function fe(e,t){if(dt===null)return e;const i=cs(dt),o=e.dirs||(e.dirs=[]);for(let d=0;d<t.length;d++){let[u,f,p,m=we]=t[d];u&&(te(u)&&(u={mounted:u,updated:u}),u.deep&&Xt(f),o.push({dir:u,instance:i,value:f,oldValue:void 0,arg:p,modifiers:m}))}return e}function wa(e,t,i,o){const d=e.dirs,u=t&&t.dirs;for(let f=0;f<d.length;f++){const p=d[f];u&&(p.oldValue=u[f].value);let m=p.dir[o];m&&(qt(),mt(m,i,8,[e.el,p,e,t]),Jt())}}function Pu(e,t){if(Je){let i=Je.provides;const o=Je.parent&&Je.parent.provides;o===i&&(i=Je.provides=Object.create(o)),i[e]=t}}function Vn(e,t,i=!1){const o=yc();if(o||Ka){let d=Ka?Ka._context.provides:o?o.parent==null||o.ce?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides:void 0;if(d&&e in d)return d[e];if(arguments.length>1)return i&&te(t)?t.call(o&&o.proxy):t}}const Tu=Symbol.for("v-scx"),_u=()=>Vn(Tu);function De(e,t,i){return bo(e,t,i)}function bo(e,t,i=we){const{immediate:o,deep:d,flush:u,once:f}=i,p=Ue({},i),m=t&&o||!t&&u!=="post";let P;if(yn){if(u==="sync"){const $=_u();P=$.__watcherHandles||($.__watcherHandles=[])}else if(!m){const $=()=>{};return $.stop=Rt,$.resume=Rt,$.pause=Rt,$}}const A=Je;p.call=($,oe,U)=>mt($,A,oe,U);let I=!1;u==="post"?p.scheduler=$=>{tt($,A&&A.suspense)}:u!=="sync"&&(I=!0,p.scheduler=($,oe)=>{oe?$():mr($)}),p.augmentJob=$=>{t&&($.flags|=4),I&&($.flags|=2,A&&($.id=A.uid,$.i=A))};const M=bu(e,t,p);return yn&&(P?P.push(M):m&&M()),M}function Du(e,t,i){const o=this.proxy,d=ke(e)?e.includes(".")?yo(o,e):()=>o[e]:e.bind(o,o);let u;te(t)?u=t:(u=t.handler,i=t);const f=Pn(this),p=bo(d,u.bind(o),i);return f(),p}function yo(e,t){const i=t.split(".");return()=>{let o=e;for(let d=0;d<i.length&&o;d++)o=o[i[d]];return o}}const Nu=Symbol("_vte"),os=e=>e.__isTeleport,Ks=Symbol("_leaveCb");function Iu(e){let t=e[0];if(e.length>1){for(const i of e)if(i.type!==Yt){t=i;break}}return t}function Ao(e){if(!br(e))return os(e.type)&&e.children?Iu(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:i}=e;if(i){if(t&16)return i[0];if(t&32&&te(i.default))return i.default()}}function vr(e,t){if(e.shapeFlag&6&&e.component){e.transition=t;const i=e.component.subTree;vr(os(i.type)&&Ao(i)||i,t)}else e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function So(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function li(e,t){let i;return!!((i=Object.getOwnPropertyDescriptor(e,t))&&!i.configurable)}const qn=new WeakMap;function un(e,t,i,o,d=!1){if(J(e)){e.forEach((U,Ne)=>un(U,t&&(J(t)?t[Ne]:t),i,o,d));return}if(cn(o)&&!d){o.shapeFlag&512&&o.type.__asyncResolved&&o.component.subTree.component&&un(e,t,i,o.component.subTree);return}const u=o.shapeFlag&4?cs(o.component):o.el,f=d?null:u,{i:p,r:m}=e,P=t&&t.r,A=p.refs===we?p.refs={}:p.refs,I=p.setupState,M=me(I),$=I===we?Ki:U=>li(A,U)?!1:ve(M,U),oe=(U,Ne)=>!(Ne&&li(A,Ne));if(P!=null&&P!==m){if(di(t),ke(P))A[P]=null,$(P)&&(I[P]=null);else if(We(P)){const U=t;oe(P,U.k)&&(P.value=null),U.k&&(A[U.k]=null)}}if(te(m))wn(m,p,12,[f,A]);else{const U=ke(m),Ne=We(m);if(U||Ne){const Pe=()=>{if(e.f){const re=U?$(m)?I[m]:A[m]:oe()||!e.k?m.value:A[e.k];if(d)J(re)&&ir(re,u);else if(J(re))re.includes(u)||re.push(u);else if(U)A[m]=[u],$(m)&&(I[m]=A[m]);else{const ge=[u];oe(m,e.k)&&(m.value=ge),e.k&&(A[e.k]=ge)}}else U?(A[m]=f,$(m)&&(I[m]=f)):Ne&&(oe(m,e.k)&&(m.value=f),e.k&&(A[e.k]=f))};if(f){const re=()=>{Pe(),qn.delete(e)};re.id=-1,qn.set(e,re),tt(re,i)}else di(e),Pe()}}}function di(e){const t=qn.get(e);t&&(t.flags|=8,qn.delete(e))}ns().requestIdleCallback;ns().cancelIdleCallback;const cn=e=>!!e.type.__asyncLoader,br=e=>e.type.__isKeepAlive;function Ru(e,t){wo(e,"a",t)}function Cu(e,t){wo(e,"da",t)}function wo(e,t,i=Je){const o=e.__wdc||(e.__wdc=()=>{let d=i;for(;d;){if(d.isDeactivated)return;d=d.parent}return e()});if(ls(t,o,i),i){let d=i.parent;for(;d&&d.parent;)br(d.parent.vnode)&&ku(o,t,i,d),d=d.parent}}function ku(e,t,i,o){const d=ls(t,e,o,!0);_o(()=>{ir(o[t],d)},i)}function ls(e,t,i=Je,o=!1){if(i){const d=i[e]||(i[e]=[]),u=t.__weh||(t.__weh=(...f)=>{qt();const p=Pn(i),m=mt(t,i,e,f);return p(),Jt(),m});return o?d.unshift(u):d.push(u),u}}const Qt=e=>(t,i=Je)=>{(!yn||e==="sp")&&ls(e,(...o)=>t(...o),i)},xu=Qt("bm"),Po=Qt("m"),Eu=Qt("bu"),Gu=Qt("u"),To=Qt("bum"),_o=Qt("um"),Fu=Qt("sp"),Ou=Qt("rtg"),Lu=Qt("rtc");function Mu(e,t=Je){ls("ec",e,t)}const Bu=Symbol.for("v-ndc");function se(e,t,i,o){let d;const u=i,f=J(e);if(f||ke(e)){const p=f&&Na(e);let m=!1,P=!1;p&&(m=!ut(e),P=Zt(e),e=ss(e)),d=new Array(e.length);for(let A=0,I=e.length;A<I;A++)d[A]=t(m?P?Va(ht(e[A])):ht(e[A]):e[A],A,void 0,u)}else if(typeof e=="number"){d=new Array(e);for(let p=0;p<e;p++)d[p]=t(p+1,p,void 0,u)}else if(Se(e))if(e[Symbol.iterator])d=Array.from(e,(p,m)=>t(p,m,void 0,u));else{const p=Object.keys(e);d=new Array(p.length);for(let m=0,P=p.length;m<P;m++){const A=p[m];d[m]=t(e[A],A,m,u)}}else d=[];return d}const er=e=>e?Ho(e)?cs(e):er(e.parent):null,fn=Ue(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>er(e.parent),$root:e=>er(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>No(e),$forceUpdate:e=>e.f||(e.f=()=>{mr(e.update)}),$nextTick:e=>e.n||(e.n=dn.bind(e.proxy)),$watch:e=>Du.bind(e)}),Vs=(e,t)=>e!==we&&!e.__isScriptSetup&&ve(e,t),zu={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:i,setupState:o,data:d,props:u,accessCache:f,type:p,appContext:m}=e;if(t[0]!=="$"){const M=f[t];if(M!==void 0)switch(M){case 1:return o[t];case 2:return d[t];case 4:return i[t];case 3:return u[t]}else{if(Vs(o,t))return f[t]=1,o[t];if(d!==we&&ve(d,t))return f[t]=2,d[t];if(ve(u,t))return f[t]=3,u[t];if(i!==we&&ve(i,t))return f[t]=4,i[t];tr&&(f[t]=0)}}const P=fn[t];let A,I;if(P)return t==="$attrs"&&Ve(e.attrs,"get",""),P(e);if((A=p.__cssModules)&&(A=A[t]))return A;if(i!==we&&ve(i,t))return f[t]=4,i[t];if(I=m.config.globalProperties,ve(I,t))return I[t]},set({_:e},t,i){const{data:o,setupState:d,ctx:u}=e;return Vs(d,t)?(d[t]=i,!0):o!==we&&ve(o,t)?(o[t]=i,!0):ve(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(u[t]=i,!0)},has({_:{data:e,setupState:t,accessCache:i,ctx:o,appContext:d,props:u,type:f}},p){let m;return!!(i[p]||e!==we&&p[0]!=="$"&&ve(e,p)||Vs(t,p)||ve(u,p)||ve(o,p)||ve(fn,p)||ve(d.config.globalProperties,p)||(m=f.__cssModules)&&m[p])},defineProperty(e,t,i){return i.get!=null?e._.accessCache[t]=0:ve(i,"value")&&this.set(e,t,i.value,null),Reflect.defineProperty(e,t,i)}};function ui(e){return J(e)?e.reduce((t,i)=>(t[i]=null,t),{}):e}let tr=!0;function $u(e){const t=No(e),i=e.proxy,o=e.ctx;tr=!1,t.beforeCreate&&ci(t.beforeCreate,e,"bc");const{data:d,computed:u,methods:f,watch:p,provide:m,inject:P,created:A,beforeMount:I,mounted:M,beforeUpdate:$,updated:oe,activated:U,deactivated:Ne,beforeDestroy:Pe,beforeUnmount:re,destroyed:ge,unmounted:K,render:xe,renderTracked:Me,renderTriggered:it,errorCaptured:vt,serverPrefetch:ga,expose:bt,inheritAttrs:ha,components:a,directives:ea,filters:ma}=t;if(P&&Ku(P,o,null),f)for(const ye in f){const ue=f[ye];te(ue)&&(o[ye]=ue.bind(i))}if(d){const ye=d.call(i,i);Se(ye)&&(e.data=rs(ye))}if(tr=!0,u)for(const ye in u){const ue=u[ye],Be=te(ue)?ue.bind(i,i):te(ue.get)?ue.get.bind(i,i):Rt,Ze=!te(ue)&&te(ue.set)?ue.set.bind(i):Rt,je=j({get:Be,set:Ze});Object.defineProperty(o,ye,{enumerable:!0,configurable:!0,get:()=>je.value,set:Ye=>je.value=Ye})}if(p)for(const ye in p)Do(p[ye],o,i,ye);if(m){const ye=te(m)?m.call(i):m;Reflect.ownKeys(ye).forEach(ue=>{Pu(ue,ye[ue])})}A&&ci(A,e,"c");function Ee(ye,ue){J(ue)?ue.forEach(Be=>ye(Be.bind(i))):ue&&ye(ue.bind(i))}if(Ee(xu,I),Ee(Po,M),Ee(Eu,$),Ee(Gu,oe),Ee(Ru,U),Ee(Cu,Ne),Ee(Mu,vt),Ee(Lu,Me),Ee(Ou,it),Ee(To,re),Ee(_o,K),Ee(Fu,ga),J(bt))if(bt.length){const ye=e.exposed||(e.exposed={});bt.forEach(ue=>{Object.defineProperty(ye,ue,{get:()=>i[ue],set:Be=>i[ue]=Be,enumerable:!0})})}else e.exposed||(e.exposed={});xe&&e.render===Rt&&(e.render=xe),ha!=null&&(e.inheritAttrs=ha),a&&(e.components=a),ea&&(e.directives=ea),ga&&So(e)}function Ku(e,t,i=Rt){J(e)&&(e=ar(e));for(const o in e){const d=e[o];let u;Se(d)?"default"in d?u=Vn(d.from||o,d.default,!0):u=Vn(d.from||o):u=Vn(d),We(u)?Object.defineProperty(t,o,{enumerable:!0,configurable:!0,get:()=>u.value,set:f=>u.value=f}):t[o]=u}}function ci(e,t,i){mt(J(e)?e.map(o=>o.bind(t.proxy)):e.bind(t.proxy),t,i)}function Do(e,t,i,o){let d=o.includes(".")?yo(i,o):()=>i[o];if(ke(e)){const u=t[e];te(u)&&De(d,u)}else if(te(e))De(d,e.bind(i));else if(Se(e))if(J(e))e.forEach(u=>Do(u,t,i,o));else{const u=te(e.handler)?e.handler.bind(i):t[e.handler];te(u)&&De(d,u,e)}}function No(e){const t=e.type,{mixins:i,extends:o}=t,{mixins:d,optionsCache:u,config:{optionMergeStrategies:f}}=e.appContext,p=u.get(t);let m;return p?m=p:!d.length&&!i&&!o?m=t:(m={},d.length&&d.forEach(P=>Jn(m,P,f,!0)),Jn(m,t,f)),Se(t)&&u.set(t,m),m}function Jn(e,t,i,o=!1){const{mixins:d,extends:u}=t;u&&Jn(e,u,i,!0),d&&d.forEach(f=>Jn(e,f,i,!0));for(const f in t)if(!(o&&f==="expose")){const p=Vu[f]||i&&i[f];e[f]=p?p(e[f],t[f]):t[f]}return e}const Vu={data:fi,props:pi,emits:pi,methods:nn,computed:nn,beforeCreate:Xe,created:Xe,beforeMount:Xe,mounted:Xe,beforeUpdate:Xe,updated:Xe,beforeDestroy:Xe,beforeUnmount:Xe,destroyed:Xe,unmounted:Xe,activated:Xe,deactivated:Xe,errorCaptured:Xe,serverPrefetch:Xe,components:nn,directives:nn,watch:Uu,provide:fi,inject:Wu};function fi(e,t){return t?e?function(){return Ue(te(e)?e.call(this,this):e,te(t)?t.call(this,this):t)}:t:e}function Wu(e,t){return nn(ar(e),ar(t))}function ar(e){if(J(e)){const t={};for(let i=0;i<e.length;i++)t[e[i]]=e[i];return t}return e}function Xe(e,t){return e?[...new Set([].concat(e,t))]:t}function nn(e,t){return e?Ue(Object.create(null),e,t):t}function pi(e,t){return e?J(e)&&J(t)?[...new Set([...e,...t])]:Ue(Object.create(null),ui(e),ui(t??{})):t}function Uu(e,t){if(!e)return t;if(!t)return e;const i=Ue(Object.create(null),e);for(const o in t)i[o]=Xe(e[o],t[o]);return i}function Io(){return{app:null,config:{isNativeTag:Ki,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let ju=0;function Hu(e,t){return function(o,d=null){te(o)||(o=Ue({},o)),d!=null&&!Se(d)&&(d=null);const u=Io(),f=new WeakSet,p=[];let m=!1;const P=u.app={_uid:ju++,_component:o,_props:d,_container:null,_context:u,_instance:null,version:_c,get config(){return u.config},set config(A){},use(A,...I){return f.has(A)||(A&&te(A.install)?(f.add(A),A.install(P,...I)):te(A)&&(f.add(A),A(P,...I))),P},mixin(A){return u.mixins.includes(A)||u.mixins.push(A),P},component(A,I){return I?(u.components[A]=I,P):u.components[A]},directive(A,I){return I?(u.directives[A]=I,P):u.directives[A]},mount(A,I,M){if(!m){const $=P._ceVNode||Ct(o,d);return $.appContext=u,M===!0?M="svg":M===!1&&(M=void 0),e($,A,M),m=!0,P._container=A,A.__vue_app__=P,cs($.component)}},onUnmount(A){p.push(A)},unmount(){m&&(mt(p,P._instance,16),e(null,P._container),delete P._container.__vue_app__)},provide(A,I){return u.provides[A]=I,P},runWithContext(A){const I=Ka;Ka=P;try{return A()}finally{Ka=I}}};return P}}let Ka=null;const Xu=(e,t)=>t==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${pt(t)}Modifiers`]||e[`${pa(t)}Modifiers`];function qu(e,t,...i){if(e.isUnmounted)return;const o=e.vnode.props||we;let d=i;const u=t.startsWith("update:"),f=u&&Xu(o,t.slice(7));f&&(f.trim&&(d=i.map(A=>ke(A)?A.trim():A)),f.number&&(d=i.map(as)));let p,m=o[p=Ls(t)]||o[p=Ls(pt(t))];!m&&u&&(m=o[p=Ls(pa(t))]),m&&mt(m,e,6,d);const P=o[p+"Once"];if(P){if(!e.emitted)e.emitted={};else if(e.emitted[p])return;e.emitted[p]=!0,mt(P,e,6,d)}}const Ju=new WeakMap;function Ro(e,t,i=!1){const o=i?Ju:t.emitsCache,d=o.get(e);if(d!==void 0)return d;const u=e.emits;let f={},p=!1;if(!te(e)){const m=P=>{const A=Ro(P,t,!0);A&&(p=!0,Ue(f,A))};!i&&t.mixins.length&&t.mixins.forEach(m),e.extends&&m(e.extends),e.mixins&&e.mixins.forEach(m)}return!u&&!p?(Se(e)&&o.set(e,null),null):(J(u)?u.forEach(m=>f[m]=null):Ue(f,u),Se(e)&&o.set(e,f),f)}function ds(e,t){return!e||!Qn(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),ve(e,t[0].toLowerCase()+t.slice(1))||ve(e,pa(t))||ve(e,t))}function gi(e){const{type:t,vnode:i,proxy:o,withProxy:d,propsOptions:[u],slots:f,attrs:p,emit:m,render:P,renderCache:A,props:I,data:M,setupState:$,ctx:oe,inheritAttrs:U}=e,Ne=Xn(e);let Pe,re;try{if(i.shapeFlag&4){const K=d||o,xe=K;Pe=Dt(P.call(xe,K,A,I,$,M,oe)),re=p}else{const K=t;Pe=Dt(K.length>1?K(I,{attrs:p,slots:f,emit:m}):K(I,null)),re=t.props?p:Zu(p)}}catch(K){Ia.length=0,is(K,e,1),Pe=Ct(Yt)}let ge=Pe;if(re&&U!==!1){const K=Object.keys(re),{shapeFlag:xe}=ge;K.length&&xe&7&&(u&&K.some(es)&&(re=Yu(re,u)),ge=Wa(ge,re,!1,!0))}if(i.dirs&&(ge=Wa(ge,null,!1,!0),ge.dirs=ge.dirs?ge.dirs.concat(i.dirs):i.dirs),i.transition){const K=os(ge.type)&&Ao(ge)||ge;vr(K,i.transition)}return Pe=ge,Xn(Ne),Pe}const Zu=e=>{let t;for(const i in e)(i==="class"||i==="style"||Qn(i))&&((t||(t={}))[i]=e[i]);return t},Yu=(e,t)=>{const i={};for(const o in e)(!es(o)||!(o.slice(9)in t))&&(i[o]=e[o]);return i};function Qu(e,t,i){const{props:o,children:d,component:u}=e,{props:f,children:p,patchFlag:m}=t,P=u.emitsOptions;if(t.dirs||t.transition)return!0;if(i&&m>=0){if(m&1024)return!0;if(m&16)return o?hi(o,f,P):!!f;if(m&8){const A=t.dynamicProps;for(let I=0;I<A.length;I++){const M=A[I];if(Co(f,o,M)&&!ds(P,M))return!0}}}else return(d||p)&&(!p||!p.$stable)?!0:o===f?!1:o?f?hi(o,f,P):!0:!!f;return!1}function hi(e,t,i){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let d=0;d<o.length;d++){const u=o[d];if(Co(t,e,u)&&!ds(i,u))return!0}return!1}function Co(e,t,i){const o=e[i],d=t[i];return i==="style"&&Se(o)&&Se(d)?!Ha(o,d):o!==d}function ec({vnode:e,parent:t,suspense:i},o){for(;t;){const d=t.subTree;if(d.suspense&&d.suspense.activeBranch===e&&(d.suspense.vnode.el=d.el=o,e=d),d===e)(e=t.vnode).el=o,t=t.parent;else break}i&&i.activeBranch===e&&(i.vnode.el=o)}const ko={},xo=()=>Object.create(ko),Eo=e=>Object.getPrototypeOf(e)===ko;function tc(e,t,i,o=!1){const d={},u=xo();e.propsDefaults=Object.create(null),Go(e,t,d,u);for(const f in e.propsOptions[0])f in d||(d[f]=void 0);i?e.props=o?d:du(d):e.type.props?e.props=d:e.props=u,e.attrs=u}function ac(e,t,i,o){const{props:d,attrs:u,vnode:{patchFlag:f}}=e,p=me(d),[m]=e.propsOptions;let P=!1;if((o||f>0)&&!(f&16)){if(f&8){const A=e.vnode.dynamicProps;for(let I=0;I<A.length;I++){let M=A[I];if(ds(e.emitsOptions,M))continue;const $=t[M];if(m)if(ve(u,M))$!==u[M]&&(u[M]=$,P=!0);else{const oe=pt(M);d[oe]=nr(m,p,oe,$,e,!1)}else $!==u[M]&&(u[M]=$,P=!0)}}}else{Go(e,t,d,u)&&(P=!0);let A;for(const I in p)(!t||!ve(t,I)&&((A=pa(I))===I||!ve(t,A)))&&(m?i&&(i[I]!==void 0||i[A]!==void 0)&&(d[I]=nr(m,p,I,void 0,e,!0)):delete d[I]);if(u!==p)for(const I in u)(!t||!ve(t,I))&&(delete u[I],P=!0)}P&&Ht(e.attrs,"set","")}function Go(e,t,i,o){const[d,u]=e.propsOptions;let f=!1,p;if(t)for(let m in t){if(rn(m))continue;const P=t[m];let A;d&&ve(d,A=pt(m))?!u||!u.includes(A)?i[A]=P:(p||(p={}))[A]=P:ds(e.emitsOptions,m)||(!(m in o)||P!==o[m])&&(o[m]=P,f=!0)}if(u){const m=me(i),P=p||we;for(let A=0;A<u.length;A++){const I=u[A];i[I]=nr(d,m,I,P[I],e,!ve(P,I))}}return f}function nr(e,t,i,o,d,u){const f=e[i];if(f!=null){const p=ve(f,"default");if(p&&o===void 0){const m=f.default;if(f.type!==Function&&!f.skipFactory&&te(m)){const{propsDefaults:P}=d;if(i in P)o=P[i];else{const A=Pn(d);o=P[i]=m.call(null,t),A()}}else o=m;d.ce&&d.ce._setProp(i,o)}f[0]&&(u&&!p?o=!1:f[1]&&(o===""||o===pa(i))&&(o=!0))}return o}const nc=new WeakMap;function Fo(e,t,i=!1){const o=i?nc:t.propsCache,d=o.get(e);if(d)return d;const u=e.props,f={},p=[];let m=!1;if(!te(e)){const A=I=>{m=!0;const[M,$]=Fo(I,t,!0);Ue(f,M),$&&p.push(...$)};!i&&t.mixins.length&&t.mixins.forEach(A),e.extends&&A(e.extends),e.mixins&&e.mixins.forEach(A)}if(!u&&!m)return Se(e)&&o.set(e,Ba),Ba;if(J(u))for(let A=0;A<u.length;A++){const I=pt(u[A]);mi(I)&&(f[I]=we)}else if(u)for(const A in u){const I=pt(A);if(mi(I)){const M=u[A],$=f[I]=J(M)||te(M)?{type:M}:Ue({},M),oe=$.type;let U=!1,Ne=!0;if(J(oe))for(let Pe=0;Pe<oe.length;++Pe){const re=oe[Pe],ge=te(re)&&re.name;if(ge==="Boolean"){U=!0;break}else ge==="String"&&(Ne=!1)}else U=te(oe)&&oe.name==="Boolean";$[0]=U,$[1]=Ne,(U||ve($,"default"))&&p.push(I)}}const P=[f,p];return Se(e)&&o.set(e,P),P}function mi(e){return e[0]!=="$"&&!rn(e)}const yr=e=>e==="_"||e==="_ctx"||e==="$stable",Ar=e=>J(e)?e.map(Dt):[Dt(e)],sc=(e,t,i)=>{if(t._n)return t;const o=wu((...d)=>Ar(t(...d)),i);return o._c=!1,o},Oo=(e,t,i)=>{const o=e._ctx;for(const d in e){if(yr(d))continue;const u=e[d];if(te(u))t[d]=sc(d,u,o);else if(u!=null){const f=Ar(u);t[d]=()=>f}}},Lo=(e,t)=>{const i=Ar(t);e.slots.default=()=>i},Mo=(e,t,i)=>{for(const o in t)(i||!yr(o))&&(e[o]=t[o])},rc=(e,t,i)=>{const o=e.slots=xo();if(e.vnode.shapeFlag&32){const d=t._;d?(Mo(o,t,i),i&&Hi(o,"_",d,!0)):Oo(t,o)}else t&&Lo(e,t)},ic=(e,t,i)=>{const{vnode:o,slots:d}=e;let u=!0,f=we;if(o.shapeFlag&32){const p=t._;p?i&&p===1?u=!1:Mo(d,t,i):(u=!t.$stable,Oo(t,d)),f=t}else t&&(Lo(e,t),f={default:1});if(u)for(const p in d)!yr(p)&&f[p]==null&&delete d[p]},tt=cc;function oc(e){return lc(e)}function lc(e,t){const i=ns();i.__VUE__=!0;const{insert:o,remove:d,patchProp:u,createElement:f,createText:p,createComment:m,setText:P,setElementText:A,parentNode:I,nextSibling:M,setScopeId:$=Rt,insertStaticContent:oe}=e,U=(h,y,_,x=null,k=null,C=null,L=void 0,O=null,F=!!y.dynamicChildren)=>{if(h===y)return;h&&!an(h,y)&&(x=ta(h),Ye(h,k,C,!0),h=null),y.patchFlag===-2&&(F=!1,y.dynamicChildren=null);const{type:D,ref:T,shapeFlag:E}=y;switch(D){case us:Ne(h,y,_,x);break;case Yt:Pe(h,y,_,x);break;case Wn:h==null&&re(y,_,x,L);break;case X:a(h,y,_,x,k,C,L,O,F);break;default:E&1?xe(h,y,_,x,k,C,L,O,F):E&6?ea(h,y,_,x,k,C,L,O,F):(E&64||E&128)&&D.process(h,y,_,x,k,C,L,O,F,Et)}T!=null&&k?un(T,h&&h.ref,C,y||h,!y):T==null&&h&&h.ref!=null&&un(h.ref,null,C,h,!0)},Ne=(h,y,_,x)=>{if(h==null)o(y.el=p(y.children),_,x);else{const k=y.el=h.el;y.children!==h.children&&P(k,y.children)}},Pe=(h,y,_,x)=>{h==null?o(y.el=m(y.children||""),_,x):y.el=h.el},re=(h,y,_,x)=>{[h.el,h.anchor]=oe(h.children,y,_,x,h.el,h.anchor)},ge=({el:h,anchor:y},_,x)=>{let k;for(;h&&h!==y;)k=M(h),o(h,_,x),h=k;o(y,_,x)},K=({el:h,anchor:y})=>{let _;for(;h&&h!==y;)_=M(h),d(h),h=_;d(y)},xe=(h,y,_,x,k,C,L,O,F)=>{if(y.type==="svg"?L="svg":y.type==="math"&&(L="mathml"),h==null)Me(y,_,x,k,C,L,O,F);else{const D=h.el&&h.el._isVueCE?h.el:null;try{D&&D._beginPatch(),ga(h,y,k,C,L,O,F)}finally{D&&D._endPatch()}}},Me=(h,y,_,x,k,C,L,O)=>{let F,D;const{props:T,shapeFlag:E,transition:W,dirs:H}=h;if(F=h.el=f(h.type,C,T&&T.is,T),E&8?A(F,h.children):E&16&&vt(h.children,F,null,x,k,Ws(h,C),L,O),H&&wa(h,null,x,"created"),it(F,h,h.scopeId,L,x),T){for(const be in T)be!=="value"&&!rn(be)&&u(F,be,null,T[be],C,x);"value"in T&&u(F,"value",null,T.value,C),(D=T.onVnodeBeforeMount)&&Pt(D,x,h)}H&&wa(h,null,x,"beforeMount");const ie=dc(k,W);ie&&W.beforeEnter(F),o(F,y,_),((D=T&&T.onVnodeMounted)||ie||H)&&tt(()=>{D&&Pt(D,x,h),ie&&W.enter(F),H&&wa(h,null,x,"mounted")},k)},it=(h,y,_,x,k)=>{if(_&&$(h,_),x)for(let C=0;C<x.length;C++)$(h,x[C]);if(k){let C=k.subTree;if(y===C||Ko(C.type)&&(C.ssContent===y||C.ssFallback===y)){const L=k.vnode;it(h,L,L.scopeId,L.slotScopeIds,k.parent)}}},vt=(h,y,_,x,k,C,L,O,F=0)=>{for(let D=F;D<h.length;D++){const T=h[D]=O?jt(h[D]):Dt(h[D]);U(null,T,y,_,x,k,C,L,O)}},ga=(h,y,_,x,k,C,L)=>{const O=y.el=h.el;let{patchFlag:F,dynamicChildren:D,dirs:T}=y;F|=h.patchFlag&16;const E=h.props||we,W=y.props||we;let H;if(_&&Pa(_,!1),(H=W.onVnodeBeforeUpdate)&&Pt(H,_,y,h),T&&wa(y,h,_,"beforeUpdate"),_&&Pa(_,!0),D&&(!h.dynamicChildren||h.dynamicChildren.length!==D.length)&&(F=0,L=!1,D=null),(E.innerHTML&&W.innerHTML==null||E.textContent&&W.textContent==null)&&A(O,""),D?bt(h.dynamicChildren,D,O,_,x,Ws(y,k),C):L||ue(h,y,O,null,_,x,Ws(y,k),C,!1),F>0){if(F&16)ha(O,E,W,_,k);else if(F&2&&E.class!==W.class&&u(O,"class",null,W.class,k),F&4&&u(O,"style",E.style,W.style,k),F&8){const ie=y.dynamicProps;for(let be=0;be<ie.length;be++){const ce=ie[be],Ie=E[ce],Oe=W[ce];(Oe!==Ie||ce==="value")&&u(O,ce,Ie,Oe,k,_)}}F&1&&h.children!==y.children&&A(O,y.children)}else!L&&D==null&&ha(O,E,W,_,k);((H=W.onVnodeUpdated)||T)&&tt(()=>{H&&Pt(H,_,y,h),T&&wa(y,h,_,"updated")},x)},bt=(h,y,_,x,k,C,L)=>{for(let O=0;O<y.length;O++){const F=h[O],D=y[O],T=F.el&&(F.type===X||!an(F,D)||F.shapeFlag&198)?I(F.el):_;U(F,D,T,null,x,k,C,L,!0)}},ha=(h,y,_,x,k)=>{if(y!==_){if(y!==we)for(const C in y)!rn(C)&&!(C in _)&&u(h,C,y[C],null,k,x);for(const C in _){if(rn(C))continue;const L=_[C],O=y[C];L!==O&&C!=="value"&&u(h,C,O,L,k,x)}"value"in _&&u(h,"value",y.value,_.value,k)}},a=(h,y,_,x,k,C,L,O,F)=>{const D=y.el=h?h.el:p(""),T=y.anchor=h?h.anchor:p("");let{patchFlag:E,dynamicChildren:W,slotScopeIds:H}=y;H&&(O=O?O.concat(H):H),h==null?(o(D,_,x),o(T,_,x),vt(y.children||[],_,T,k,C,L,O,F)):E>0&&E&64&&W&&h.dynamicChildren&&h.dynamicChildren.length===W.length?(bt(h.dynamicChildren,W,_,k,C,L,O),(y.key!=null||k&&y===k.subTree)&&Bo(h,y,!0)):ue(h,y,_,T,k,C,L,O,F)},ea=(h,y,_,x,k,C,L,O,F)=>{y.slotScopeIds=O,h==null?y.shapeFlag&512?k.ctx.activate(y,_,x,L,F):ma(y,_,x,k,C,L,F):Ra(h,y,F)},ma=(h,y,_,x,k,C,L)=>{const O=h.component=bc(h,x,k);if(br(h)&&(O.ctx.renderer=Et),Ac(O,!1,L),O.asyncDep){if(k&&k.registerDep(O,Ee,L),!h.el){const F=O.subTree=Ct(Yt);Pe(null,F,y,_),h.placeholder=F.el}}else Ee(O,h,y,_,k,C,L)},Ra=(h,y,_)=>{const x=y.component=h.component;if(Qu(h,y,_))if(x.asyncDep&&!x.asyncResolved){ye(x,y,_);return}else x.next=y,x.update();else y.el=h.el,x.vnode=y},Ee=(h,y,_,x,k,C,L)=>{const O=()=>{if(h.isMounted){let{next:E,bu:W,u:H,parent:ie,vnode:be}=h;{const Qe=zo(h);if(Qe){E&&(E.el=be.el,ye(h,E,L)),Qe.asyncDep.then(()=>{tt(()=>{h.isUnmounted||D()},k)});return}}let ce=E,Ie;Pa(h,!1),E?(E.el=be.el,ye(h,E,L)):E=be,W&&Kn(W),(Ie=E.props&&E.props.onVnodeBeforeUpdate)&&Pt(Ie,ie,E,be),Pa(h,!0);const Oe=gi(h),at=h.subTree;h.subTree=Oe,U(at,Oe,I(at.el),ta(at),h,k,C),E.el=Oe.el,ce===null&&ec(h,Oe.el),H&&tt(H,k),(Ie=E.props&&E.props.onVnodeUpdated)&&tt(()=>Pt(Ie,ie,E,be),k)}else{let E;const{el:W,props:H}=y,{bm:ie,m:be,parent:ce,root:Ie,type:Oe}=h,at=cn(y);Pa(h,!1),ie&&Kn(ie),!at&&(E=H&&H.onVnodeBeforeMount)&&Pt(E,ce,y),Pa(h,!0);{Ie.ce&&Ie.ce._hasShadowRoot()&&Ie.ce._injectChildStyle(Oe,h.parent?h.parent.type:void 0);const Qe=h.subTree=gi(h);U(null,Qe,_,x,h,k,C),y.el=Qe.el}if(be&&tt(be,k),!at&&(E=H&&H.onVnodeMounted)){const Qe=y;tt(()=>Pt(E,ce,Qe),k)}(y.shapeFlag&256||ce&&cn(ce.vnode)&&ce.vnode.shapeFlag&256)&&h.a&&tt(h.a,k),h.isMounted=!0,y=_=x=null}};h.scope.on();const F=h.effect=new Zi(O);h.scope.off();const D=h.update=F.run.bind(F),T=h.job=F.runIfDirty.bind(F);T.i=h,T.id=h.uid,F.scheduler=()=>mr(T),Pa(h,!0),D()},ye=(h,y,_)=>{y.component=h;const x=h.vnode.props;h.vnode=y,h.next=null,ac(h,y.props,x,_),ic(h,y.children,_),qt(),oi(h),Jt()},ue=(h,y,_,x,k,C,L,O,F=!1)=>{const D=h&&h.children,T=h?h.shapeFlag:0,E=y.children,{patchFlag:W,shapeFlag:H}=y;if(W>0){if(W&128){Ze(D,E,_,x,k,C,L,O,F);return}else if(W&256){Be(D,E,_,x,k,C,L,O,F);return}}H&8?(T&16&&xt(D,k,C),E!==D&&A(_,E)):T&16?H&16?Ze(D,E,_,x,k,C,L,O,F):xt(D,k,C,!0):(T&8&&A(_,""),H&16&&vt(E,_,x,k,C,L,O,F))},Be=(h,y,_,x,k,C,L,O,F)=>{h=h||Ba,y=y||Ba;const D=h.length,T=y.length,E=Math.min(D,T);let W;for(W=0;W<E;W++){const H=y[W]=F?jt(y[W]):Dt(y[W]);U(h[W],H,_,null,k,C,L,O,F)}D>T?xt(h,k,C,!0,!1,E):vt(y,_,x,k,C,L,O,F,E)},Ze=(h,y,_,x,k,C,L,O,F)=>{let D=0;const T=y.length;let E=h.length-1,W=T-1;for(;D<=E&&D<=W;){const H=h[D],ie=y[D]=F?jt(y[D]):Dt(y[D]);if(an(H,ie))U(H,ie,_,null,k,C,L,O,F);else break;D++}for(;D<=E&&D<=W;){const H=h[E],ie=y[W]=F?jt(y[W]):Dt(y[W]);if(an(H,ie))U(H,ie,_,null,k,C,L,O,F);else break;E--,W--}if(D>E){if(D<=W){const H=W+1,ie=H<T?y[H].el:x;for(;D<=W;)U(null,y[D]=F?jt(y[D]):Dt(y[D]),_,ie,k,C,L,O,F),D++}}else if(D>W)for(;D<=E;)Ye(h[D],k,C,!0),D++;else{const H=D,ie=D,be=new Map;for(D=ie;D<=W;D++){const ze=y[D]=F?jt(y[D]):Dt(y[D]);ze.key!=null&&be.set(ze.key,D)}let ce,Ie=0;const Oe=W-ie+1;let at=!1,Qe=0;const va=new Array(Oe);for(D=0;D<Oe;D++)va[D]=0;for(D=H;D<=E;D++){const ze=h[D];if(Ie>=Oe){Ye(ze,k,C,!0);continue}let Ke;if(ze.key!=null)Ke=be.get(ze.key);else for(ce=ie;ce<=W;ce++)if(va[ce-ie]===0&&an(ze,y[ce])){Ke=ce;break}Ke===void 0?Ye(ze,k,C,!0):(va[Ke-ie]=D+1,Ke>=Qe?Qe=Ke:at=!0,U(ze,y[Ke],_,null,k,C,L,O,F),Ie++)}const Tn=at?uc(va):Ba;for(ce=Tn.length-1,D=Oe-1;D>=0;D--){const ze=ie+D,Ke=y[ze],_n=y[ze+1],Ea=ze+1<T?_n.el||$o(_n):x;va[D]===0?U(null,Ke,_,Ea,k,C,L,O,F):at&&(ce<0||D!==Tn[ce]?je(Ke,_,Ea,2):ce--)}}},je=(h,y,_,x,k=null)=>{const{el:C,type:L,transition:O,children:F,shapeFlag:D}=h;if(D&6){je(h.component.subTree,y,_,x);return}if(D&128){h.suspense.move(y,_,x);return}if(D&64){L.move(h,y,_,Et);return}if(L===X){o(C,y,_);for(let E=0;E<F.length;E++)je(F[E],y,_,x);o(h.anchor,y,_);return}if(L===Wn){ge(h,y,_);return}if(x!==2&&D&1&&O)if(x===0)O.persisted&&!C[Ks]?o(C,y,_):(O.beforeEnter(C),o(C,y,_),tt(()=>O.enter(C),k));else{const{leave:E,delayLeave:W,afterLeave:H}=O,ie=()=>{h.ctx.isUnmounted?d(C):o(C,y,_)},be=()=>{const ce=C._isLeaving||!!C[Ks];C._isLeaving&&C[Ks](!0),O.persisted&&!ce?ie():E(C,()=>{ie(),H&&H()})};W?W(C,ie,be):be()}else o(C,y,_)},Ye=(h,y,_,x=!1,k=!1)=>{const{type:C,props:L,ref:O,children:F,dynamicChildren:D,shapeFlag:T,patchFlag:E,dirs:W,cacheIndex:H,memo:ie}=h;if(E===-2&&(k=!1),O!=null&&(qt(),un(O,null,_,h,!0),Jt()),H!=null&&(y.renderCache[H]=void 0),T&256){y.ctx.deactivate(h);return}const be=T&1&&W,ce=!cn(h);let Ie;if(ce&&(Ie=L&&L.onVnodeBeforeUnmount)&&Pt(Ie,y,h),T&6)Xa(h.component,_,x);else{if(T&128){h.suspense.unmount(_,x);return}be&&wa(h,null,y,"beforeUnmount"),T&64?h.type.remove(h,y,_,Et,x):D&&!D.hasOnce&&(C!==X||E>0&&E&64)?xt(D,y,_,!1,!0):(C===X&&E&384||!k&&T&16)&&xt(F,y,_),x&&Ca(h)}const Oe=ie!=null&&H==null;(ce&&(Ie=L&&L.onVnodeUnmounted)||be||Oe)&&tt(()=>{Ie&&Pt(Ie,y,h),be&&wa(h,null,y,"unmounted"),Oe&&(h.el=null)},_)},Ca=h=>{const{type:y,el:_,anchor:x,transition:k}=h;if(y===X){ka(_,x);return}if(y===Wn){K(h);return}const C=()=>{d(_),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(h.shapeFlag&1&&k&&!k.persisted){const{leave:L,delayLeave:O}=k,F=()=>L(_,C);O?O(h.el,C,F):F()}else C()},ka=(h,y)=>{let _;for(;h!==y;)_=M(h),d(h),h=_;d(y)},Xa=(h,y,_)=>{const{bum:x,scope:k,job:C,subTree:L,um:O,m:F,a:D}=h;vi(F),vi(D),x&&Kn(x),k.stop(),C&&(C.flags|=8,Ye(L,h,y,_)),O&&tt(O,y),tt(()=>{h.isUnmounted=!0},y)},xt=(h,y,_,x=!1,k=!1,C=0)=>{for(let L=C;L<h.length;L++)Ye(h[L],y,_,x,k)},ta=h=>{if(h.shapeFlag&6)return ta(h.component.subTree);if(h.shapeFlag&128)return h.suspense.next();const y=M(h.anchor||h.el),_=y&&y[Nu];return _?M(_):y};let aa=!1;const xa=(h,y,_)=>{let x;h==null?y._vnode&&(Ye(y._vnode,null,null,!0),x=y._vnode.component):U(y._vnode||null,h,y,null,null,null,_),y._vnode=h,aa||(aa=!0,oi(x),ho(),aa=!1)},Et={p:U,um:Ye,m:je,r:Ca,mt:ma,mc:vt,pc:ue,pbc:bt,n:ta,o:e};return{render:xa,hydrate:void 0,createApp:Hu(xa)}}function Ws({type:e,props:t},i){return i==="svg"&&e==="foreignObject"||i==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:i}function Pa({effect:e,job:t},i){i?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function dc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Bo(e,t,i=!1){const o=e.children,d=t.children;if(J(o)&&J(d))for(let u=0;u<o.length;u++){const f=o[u];let p=d[u];p.shapeFlag&1&&!p.dynamicChildren&&((p.patchFlag<=0||p.patchFlag===32)&&(p=d[u]=jt(d[u]),p.el=f.el),!i&&p.patchFlag!==-2&&Bo(f,p)),p.type===us&&(p.patchFlag===-1&&(p=d[u]=jt(p)),p.el=f.el),p.type===Yt&&!p.el&&(p.el=f.el)}}function uc(e){const t=e.slice(),i=[0];let o,d,u,f,p;const m=e.length;for(o=0;o<m;o++){const P=e[o];if(P!==0){if(d=i[i.length-1],e[d]<P){t[o]=d,i.push(o);continue}for(u=0,f=i.length-1;u<f;)p=u+f>>1,e[i[p]]<P?u=p+1:f=p;P<e[i[u]]&&(u>0&&(t[o]=i[u-1]),i[u]=o)}}for(u=i.length,f=i[u-1];u-- >0;)i[u]=f,f=t[f];return i}function zo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:zo(t)}function vi(e){if(e)for(let t=0;t<e.length;t++)e[t].flags|=8}function $o(e){if(e.placeholder)return e.placeholder;const t=e.component;return t?$o(t.subTree):null}const Ko=e=>e.__isSuspense;function cc(e,t){t&&t.pendingBranch?J(e)?t.effects.push(...e):t.effects.push(e):Su(e)}const X=Symbol.for("v-fgt"),us=Symbol.for("v-txt"),Yt=Symbol.for("v-cmt"),Wn=Symbol.for("v-stc"),Ia=[];let rt=null;function v(e=!1){Ia.push(rt=e?null:[])}function Vo(){Ia.pop(),rt=Ia[Ia.length-1]||null}let vn=1;function bi(e,t=!1){vn+=e,e<0&&rt&&t&&(rt.hasOnce=!0)}function Wo(e){return e.dynamicChildren=vn>0?rt||Ba:null,Vo(),vn>0&&rt&&rt.push(e),e}function b(e,t,i,o,d,u){return Wo(l(e,t,i,o,d,u,!0))}function fc(e,t,i,o,d){return Wo(Ct(e,t,i,o,d,!0))}function Uo(e){return e?e.__v_isVNode===!0:!1}function an(e,t){return e.type===t.type&&e.key===t.key}const jo=({key:e})=>e??null,Un=({ref:e,ref_key:t,ref_for:i})=>(typeof e=="number"&&(e=""+e),e!=null?ke(e)||We(e)||te(e)?{i:dt,r:e,k:t,f:!!i}:e:null);function l(e,t=null,i=null,o=0,d=null,u=e===X?0:1,f=!1,p=!1){const m={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&jo(t),ref:t&&Un(t),scopeId:vo,slotScopeIds:null,children:i,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:u,patchFlag:o,dynamicProps:d,dynamicChildren:null,appContext:null,ctx:dt};return p?(Zn(m,i),u&128&&e.normalize(m)):i&&(m.shapeFlag|=ke(i)?8:16),vn>0&&!f&&rt&&(m.patchFlag>0||u&6)&&m.patchFlag!==32&&rt.push(m),m}const Ct=pc;function pc(e,t=null,i=null,o=0,d=null,u=!1){if((!e||e===Bu)&&(e=Yt),Uo(e)){const p=Wa(e,t,!0);return i&&Zn(p,i),vn>0&&!u&&rt&&(p.shapeFlag&6?rt[rt.indexOf(e)]=p:rt.push(p)),p.patchFlag=-2,p}if(Tc(e)&&(e=e.__vccOpts),t){t=gc(t);let{class:p,style:m}=t;p&&!ke(p)&&(t.class=de(p)),Se(m)&&(hr(m)&&!J(m)&&(m=Ue({},m)),t.style=pn(m))}const f=ke(e)?1:Ko(e)?128:os(e)?64:Se(e)?4:te(e)?2:0;return l(e,t,i,o,d,f,u,!0)}function gc(e){return e?hr(e)||Eo(e)?Ue({},e):e:null}function Wa(e,t,i=!1,o=!1){const{props:d,ref:u,patchFlag:f,children:p,transition:m}=e,P=t?hc(d||{},t):d,A={__v_isVNode:!0,__v_skip:!0,type:e.type,props:P,key:P&&jo(P),ref:t&&t.ref?i&&u?J(u)?u.concat(Un(t)):[u,Un(t)]:Un(t):u,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:p,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==X?f===-1?16:f|16:f,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:m,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Wa(e.ssContent),ssFallback:e.ssFallback&&Wa(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return m&&o&&vr(A,m.clone(A)),A}function le(e=" ",t=0){return Ct(us,null,e,t)}function ua(e,t){const i=Ct(Wn,null,e);return i.staticCount=t,i}function G(e="",t=!1){return t?(v(),fc(Yt,null,e)):Ct(Yt,null,e)}function Dt(e){return e==null||typeof e=="boolean"?Ct(Yt):J(e)?Ct(X,null,e.slice()):Uo(e)?jt(e):Ct(us,null,String(e))}function jt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Wa(e)}function Zn(e,t){let i=0;const{shapeFlag:o}=e;if(t==null)t=null;else if(J(t))i=16;else if(typeof t=="object")if(o&65){const d=t.default;d&&(d._c&&(d._d=!1),Zn(e,d()),d._c&&(d._d=!0));return}else{i=32;const d=t._;!d&&!Eo(t)?t._ctx=dt:d===3&&dt&&(dt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(te(t)){if(o&65){Zn(e,{default:t});return}t={default:t,_ctx:dt},i=32}else t=String(t),o&64?(i=16,t=[le(t)]):i=8;e.children=t,e.shapeFlag|=i}function hc(...e){const t={};for(let i=0;i<e.length;i++){const o=e[i];for(const d in o)if(d==="class")t.class!==o.class&&(t.class=de([t.class,o.class]));else if(d==="style")t.style=pn([t.style,o.style]);else if(Qn(d)){const u=t[d],f=o[d];f&&u!==f&&!(J(u)&&u.includes(f))?t[d]=u?[].concat(u,f):f:f==null&&u==null&&!es(d)&&(t[d]=f)}else d!==""&&(t[d]=o[d])}return t}function Pt(e,t,i,o=null){mt(e,t,7,[i,o])}const mc=Io();let vc=0;function bc(e,t,i){const o=e.type,d=(t?t.appContext:e.appContext)||mc,u={uid:vc++,vnode:e,type:o,parent:t,appContext:d,root:null,next:null,subTree:null,effect:null,update:null,job:null,scope:new Wd(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(d.provides),ids:t?t.ids:["",0,0],accessCache:null,renderCache:[],components:null,directives:null,propsOptions:Fo(o,d),emitsOptions:Ro(o,d),emit:null,emitted:null,propsDefaults:we,inheritAttrs:o.inheritAttrs,ctx:we,data:we,props:we,attrs:we,slots:we,refs:we,setupState:we,setupContext:null,suspense:i,suspenseId:i?i.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return u.ctx={_:u},u.root=t?t.root:u,u.emit=qu.bind(null,u),e.ce&&e.ce(u),u}let Je=null;const yc=()=>Je||dt;let Yn,bn;{const e=ns(),t=(i,o)=>{let d;return(d=e[i])||(d=e[i]=[]),d.push(o),u=>{d.length>1?d.forEach(f=>f(u)):d[0](u)}};Yn=t("__VUE_INSTANCE_SETTERS__",i=>Je=i),bn=t("__VUE_SSR_SETTERS__",i=>yn=i)}const Pn=e=>{const t=Je;return Yn(e),e.scope.on(),()=>{e.scope.off(),Yn(t)}},yi=()=>{Je&&Je.scope.off(),Yn(null)};function Ho(e){return e.vnode.shapeFlag&4}let yn=!1;function Ac(e,t=!1,i=!1){t&&bn(t);const{props:o,children:d}=e.vnode,u=Ho(e);tc(e,o,u,t),rc(e,d,i||t);const f=u?Sc(e,t):void 0;return t&&bn(!1),f}function Sc(e,t){const i=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,zu);const{setup:o}=i;if(o){qt();const d=e.setupContext=o.length>1?Pc(e):null,u=Pn(e),f=wn(o,e,0,[e.props,d]),p=Vi(f);if(Jt(),u(),(p||e.sp)&&!cn(e)&&So(e),p){if(f.then(yi,yi),t)return f.then(m=>{bn(!0);try{Ai(e,m,t)}finally{bn(!1)}}).catch(m=>{is(m,e,0)});e.asyncDep=f}else Ai(e,f)}else Xo(e)}function Ai(e,t,i){te(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Se(t)&&(e.setupState=fo(t)),Xo(e)}function Xo(e,t,i){const o=e.type;e.render||(e.render=o.render||Rt);{const d=Pn(e);qt();try{$u(e)}finally{Jt(),d()}}}const wc={get(e,t){return Ve(e,"get",""),e[t]}};function Pc(e){const t=i=>{e.exposed=i||{}};return{attrs:new Proxy(e.attrs,wc),slots:e.slots,emit:e.emit,expose:t}}function cs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(fo(uu(e.exposed)),{get(t,i){if(i in t)return t[i];if(i in fn)return fn[i](e)},has(t,i){return i in t||i in fn}})):e.proxy}function Tc(e){return te(e)&&"__vccOpts"in e}const j=(e,t)=>mu(e,t,yn),_c="3.5.41";let sr;const Si=typeof window<"u"&&window.trustedTypes;if(Si)try{sr=Si.createPolicy("vue",{createHTML:e=>e})}catch{}const qo=sr?e=>sr.createHTML(e):e=>e,Dc="http://www.w3.org/2000/svg",Nc="http://www.w3.org/1998/Math/MathML",Ut=typeof document<"u"?document:null,wi=Ut&&Ut.createElement("template"),Ic={insert:(e,t,i)=>{t.insertBefore(e,i||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,i,o)=>{const d=t==="svg"?Ut.createElementNS(Dc,e):t==="mathml"?Ut.createElementNS(Nc,e):i?Ut.createElement(e,{is:i}):Ut.createElement(e);return e==="select"&&o&&o.multiple!=null&&d.setAttribute("multiple",o.multiple),d},createText:e=>Ut.createTextNode(e),createComment:e=>Ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,i,o,d,u){const f=i?i.previousSibling:t.lastChild;if(d&&(d===u||d.nextSibling))for(;t.insertBefore(d.cloneNode(!0),i),!(d===u||!(d=d.nextSibling)););else{wi.innerHTML=qo(o==="svg"?`<svg>${e}</svg>`:o==="mathml"?`<math>${e}</math>`:e);const p=wi.content;if(o==="svg"||o==="mathml"){const m=p.firstChild;for(;m.firstChild;)p.appendChild(m.firstChild);p.removeChild(m)}t.insertBefore(p,i)}return[f?f.nextSibling:t.firstChild,i?i.previousSibling:t.lastChild]}},Rc=Symbol("_vtc");function Cc(e,t,i){const o=e[Rc];o&&(t=(t?[t,...o]:[...o]).join(" ")),t==null?e.removeAttribute("class"):i?e.setAttribute("class",t):e.className=t}const Pi=Symbol("_vod"),kc=Symbol("_vsh"),xc=Symbol(""),Ec=/(?:^|;)\s*display\s*:/;function Gc(e,t,i){const o=e.style,d=ke(i);let u=!1;if(i&&!d){if(t)if(ke(t))for(const f of t.split(";")){const p=f.slice(0,f.indexOf(":")).trim();i[p]==null&&sn(o,p,"")}else for(const f in t)i[f]==null&&sn(o,f,"");for(const f in i){f==="display"&&(u=!0);const p=i[f];p!=null?Oc(e,f,!ke(t)&&t?t[f]:void 0,p)||sn(o,f,p):sn(o,f,"")}}else if(d){if(t!==i){const f=o[xc];f&&(i+=";"+f),o.cssText=i,u=Ec.test(i)}}else t&&e.removeAttribute("style");Pi in e&&(e[Pi]=u?o.display:"",e[kc]&&(o.display="none"))}const Ti=/\s*!important$/;function sn(e,t,i){if(J(i))i.forEach(o=>sn(e,t,o));else if(i==null&&(i=""),t.startsWith("--"))e.setProperty(t,i);else{const o=Fc(e,t);Ti.test(i)?e.setProperty(pa(o),i.replace(Ti,""),"important"):e[o]=i}}const _i=["Webkit","Moz","ms"],Us={};function Fc(e,t){const i=Us[t];if(i)return i;let o=pt(t);if(o!=="filter"&&o in e)return Us[t]=o;o=ji(o);for(let d=0;d<_i.length;d++){const u=_i[d]+o;if(u in e)return Us[t]=u}return t}function Oc(e,t,i,o){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ke(o)&&i===o}const Di="http://www.w3.org/1999/xlink";function Ni(e,t,i,o,d,u=Kd(t)){o&&t.startsWith("xlink:")?i==null?e.removeAttributeNS(Di,t.slice(6,t.length)):e.setAttributeNS(Di,t,i):i==null||u&&!Xi(i)?e.removeAttribute(t):e.setAttribute(t,u?"":kt(i)?String(i):i)}function Ii(e,t,i,o,d){if(t==="innerHTML"||t==="textContent"){i!=null&&(e[t]=t==="innerHTML"?qo(i):i);return}const u=e.tagName;if(t==="value"&&u!=="PROGRESS"&&!u.includes("-")){const p=u==="OPTION"?e.getAttribute("value")||"":e.value,m=i==null?e.type==="checkbox"?"on":"":String(i);(p!==m||!("_value"in e))&&(e.value=m),i==null&&e.removeAttribute(t),e._value=i;return}let f=!1;if(i===""||i==null){const p=typeof e[t];p==="boolean"?i=Xi(i):i==null&&p==="string"?(i="",f=!0):p==="number"&&(i=0,f=!0)}try{e[t]=i}catch{}f&&e.removeAttribute(d||t)}function fa(e,t,i,o){e.addEventListener(t,i,o)}function Lc(e,t,i,o){e.removeEventListener(t,i,o)}const Ri=Symbol("_vei");function Mc(e,t,i,o,d=null){const u=e[Ri]||(e[Ri]={}),f=u[t];if(o&&f)f.value=o;else{const[p,m]=$c(t);if(o){const P=u[t]=Wc(o,d);fa(e,p,P,m)}else f&&(Lc(e,p,f,m),u[t]=void 0)}}const Bc=/(Once|Passive|Capture)$/,zc=/^on:?(?:Once|Passive|Capture)$/;function $c(e){let t,i;for(;(i=e.match(Bc))&&!zc.test(e);)t||(t={}),e=e.slice(0,e.length-i[1].length),t[i[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):pa(e.slice(2)),t]}let js=0;const Kc=Promise.resolve(),Vc=()=>js||(Kc.then(()=>js=0),js=Date.now());function Wc(e,t){const i=o=>{if(!o._vts)o._vts=Date.now();else if(o._vts<=i.attached)return;const d=i.value;if(J(d)){const u=o.stopImmediatePropagation;o.stopImmediatePropagation=()=>{u.call(o),o._stopped=!0};const f=d.slice(),p=[o];for(let m=0;m<f.length&&!o._stopped;m++){const P=f[m];P&&mt(P,t,5,p)}}else mt(d,t,5,[o])};return i.value=e,i.attached=Vc(),i}const Ci=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Uc=(e,t,i,o,d,u)=>{const f=d==="svg";t==="class"?Cc(e,o,f):t==="style"?Gc(e,i,o):Qn(t)?es(t)||Mc(e,t,i,o,u):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):jc(e,t,o,f))?(Ii(e,t,o),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Ni(e,t,o,f,u,t!=="value")):e._isVueCE&&(Hc(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ke(o)))?Ii(e,pt(t),o,u,t):(t==="true-value"?e._trueValue=o:t==="false-value"&&(e._falseValue=o),Ni(e,t,o,f))};function jc(e,t,i,o){if(o)return!!(t==="innerHTML"||t==="textContent"||t in e&&Ci(t)&&te(i));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const d=e.tagName;if(d==="IMG"||d==="VIDEO"||d==="CANVAS"||d==="SOURCE")return!1}return Ci(t)&&ke(i)?!1:t in e}function Hc(e,t){const i=e._def.props;if(!i)return!1;const o=pt(t);return Array.isArray(i)?i.some(d=>pt(d)===o):Object.keys(i).some(d=>pt(d)===o)}const Ua=e=>{const t=e.props["onUpdate:modelValue"]||!1;return J(t)?i=>Kn(t,i):t};function Xc(e){e.target.composing=!0}function ki(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const It=Symbol("_assign"),$n=Symbol("_initialValue");function Hs(e,t,i){return t&&(e=e.trim()),i&&(e=as(e)),e}const Ce={created(e,{modifiers:{lazy:t,trim:i,number:o}},d){e.parentNode&&(e.type==="text"?e[$n]=e.defaultValue.replace(/[\r\n]/g,""):e.type==="textarea"&&(e[$n]=e.defaultValue.replace(/\r\n?/g,`
2
- `))),e[It]=Ua(d);const u=o||d.props&&d.props.type==="number";fa(e,t?"change":"input",f=>{f.target.composing||e[It](Hs(e.value,i,u))}),(i||u)&&fa(e,"change",()=>{e.value=Hs(e.value,i,u)}),t||(fa(e,"compositionstart",Xc),fa(e,"compositionend",ki),fa(e,"change",ki))},mounted(e,{value:t,modifiers:{trim:i,number:o}}){const d=t??"",u=e[$n];delete e[$n],u!==void 0&&(e.type==="text"||e.type==="textarea")&&e.value!==u?e[It](Hs(e.value,i,o)):e.value=d},beforeUpdate(e,{value:t,oldValue:i,modifiers:{lazy:o,trim:d,number:u}},f){if(e[It]=Ua(f),e.composing)return;const p=(u||e.type==="number")&&!/^0\d/.test(e.value)?as(e.value):e.value,m=t??"";if(p===m)return;const P=e.getRootNode();(P instanceof Document||P instanceof ShadowRoot)&&P.activeElement===e&&e.type!=="range"&&(o&&t===i||d&&e.value.trim()===m)||(e.value=m)}},Xs={deep:!0,created(e,t,i){e[It]=Ua(i),fa(e,"change",()=>{const o=e._modelValue,d=An(e),u=e.checked,f=e[It];if(J(o)){const p=lr(o,d),m=p!==-1;if(u&&!m)f(o.concat(d));else if(!u&&m){const P=[...o];P.splice(p,1),f(P)}}else if(ja(o)){const p=new Set(o);u?p.add(d):p.delete(d),f(p)}else f(Jo(e,u))})},mounted:xi,beforeUpdate(e,t,i){e[It]=Ua(i),xi(e,t,i)}};function xi(e,{value:t,oldValue:i},o){e._modelValue=t;let d;if(J(t))d=lr(t,o.props.value)>-1;else if(ja(t))d=t.has(o.props.value);else{if(t===i)return;d=Ha(t,Jo(e,!0))}e.checked!==d&&(e.checked=d)}const Ta={deep:!0,created(e,{value:t,modifiers:{number:i}},o){e._modelValue=t,fa(e,"change",()=>{const d=Array.prototype.filter.call(e.options,u=>u.selected).map(u=>i?as(An(u)):An(u));e[It](e.multiple?ja(e._modelValue)?new Set(d):d:d[0]),e._assigning=!0,dn(()=>{e._assigning=!1})}),e[It]=Ua(o)},mounted(e,{value:t}){Ei(e,t)},beforeUpdate(e,{value:t},i){e._modelValue=t,e[It]=Ua(i)},updated(e,{value:t}){e._assigning||Ei(e,t)}};function Ei(e,t){const i=e.multiple,o=J(t);if(!(i&&!o&&!ja(t))){for(let d=0,u=e.options.length;d<u;d++){const f=e.options[d],p=An(f);if(i)if(o){const m=typeof p;m==="string"||m==="number"?f.selected=t.some(P=>String(P)===String(p)):f.selected=lr(t,p)>-1}else f.selected=t.has(p);else if(Ha(An(f),t)){e.selectedIndex!==d&&(e.selectedIndex=d);return}}!i&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function An(e){return"_value"in e?e._value:e.value}function Jo(e,t){const i=t?"_trueValue":"_falseValue";return i in e?e[i]:t}const qc=["ctrl","shift","alt","meta"],Jc={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>qc.some(i=>e[`${i}Key`]&&!t.includes(i))},Wt=(e,t)=>{if(!e)return e;const i=e._withMods||(e._withMods={}),o=t.join(".");return i[o]||(i[o]=((d,...u)=>{for(let f=0;f<t.length;f++){const p=Jc[t[f]];if(p&&p(d,t))return}return e(d,...u)}))},Zc={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Yc=(e,t)=>{const i=e._withKeys||(e._withKeys={}),o=t.join(".");return i[o]||(i[o]=(d=>{if(!("key"in d))return;const u=pa(d.key);if(t.some(f=>f===u||Zc[f]===u))return e(d)}))},Qc=Ue({patchProp:Uc},Ic);let Gi;function ef(){return Gi||(Gi=oc(Qc))}const tf=((...e)=>{const t=ef().createApp(...e),{mount:i}=t;return t.mount=o=>{const d=nf(o);if(!d)return;const u=t._component;!te(u)&&!u.render&&!u.template&&(u.template=d.innerHTML),d.nodeType===1&&(d.textContent="");const f=i(d,!1,af(d));return d instanceof Element&&(d.removeAttribute("v-cloak"),d.setAttribute("data-v-app","")),f},t});function af(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function nf(e){return ke(e)?document.querySelector(e):e}const sf="modulepreload",rf=function(e,t){return new URL(e,t).href},Fi={},of=function(t,i,o){let d=Promise.resolve();if(i&&i.length>0){let P=function(A){return Promise.all(A.map(I=>Promise.resolve(I).then(M=>({status:"fulfilled",value:M}),M=>({status:"rejected",reason:M}))))};const f=document.getElementsByTagName("link"),p=document.querySelector("meta[property=csp-nonce]"),m=p?.nonce||p?.getAttribute("nonce");d=P(i.map(A=>{if(A=rf(A,o),A in Fi)return;Fi[A]=!0;const I=A.endsWith(".css"),M=I?'[rel="stylesheet"]':"";if(o)for(let oe=f.length-1;oe>=0;oe--){const U=f[oe];if(U.href===A&&(!I||U.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${A}"]${M}`))return;const $=document.createElement("link");if($.rel=I?"stylesheet":sf,I||($.as="script"),$.crossOrigin="",$.href=A,m&&$.setAttribute("nonce",m),document.head.appendChild($),I)return new Promise((oe,U)=>{$.addEventListener("load",oe),$.addEventListener("error",()=>U(new Error(`Unable to preload CSS for ${A}`)))})}))}function u(f){const p=new Event("vite:preloadError",{cancelable:!0});if(p.payload=f,window.dispatchEvent(p),!p.defaultPrevented)throw f}return d.then(f=>{for(const p of f||[])p.status==="rejected"&&u(p.reason);return t().catch(u)})},lf={en:{},it:{"Flow Builder":"Generatore di flussi","AI enabled":"AI abilitata","AI disabled":"AI disabilitata","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Descrivi l'automazione in linguaggio naturale. L'AI genera un flow Node-RED usando i nodi KNX Ultimate, i nodi Hue e i nodi nativi Function/logici, collegati ai group address importati. Copia il JSON, poi in Node-RED usa Menu > Importa e incollalo.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"es. Quando il sensore di movimento Hue del soggiorno rileva un movimento, accendi la luce del soggiorno.","Generate flow":"Genera flusso","Generating...":"Generazione...","Generating flow...":"Generazione del flusso...","Copy JSON":"Copia JSON","Copied!":"Copiato!","Flow JSON copied to clipboard":"JSON del flow copiato negli appunti","Flow generation failed":"Generazione del flow non riuscita","Could not copy to clipboard":"Impossibile copiare negli appunti","The generated flow JSON will appear here.":"Il JSON del flow generato apparirà qui.","{{count}} areas":"{{count}} aree","{{count}} available":"{{count}} disponibile","{{count}} event types":"{{count}} tipi di eventi","{{count}} recent":"{{count}} recente","{{count}} saved plans":"{{count}} piani salvati","{{count}} visible":"{{count}} visibile","Activate main actuators":"Attiva gli attuatori principali","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Attivare i principali attuatori presenti nell'area e verificare il feedback di stato per confermare che segua i comandi.","Active Read Request To Status GA":"Richiesta di lettura attiva allo stato GA","Actuator preset deleted":"Preimpostazione dell'attuatore cancellata","Actuator preset saved":"Preimpostazione dell'attuatore salvata","Actuator test complete":"Test dell'attuatore completato","Add group addresses to this area":"Aggiungi indirizzi di gruppo a quest'area","Add Step":"Aggiungi passaggio","Add Wait":"Aggiungi Aspetta","AI Area Builder":"Costruttore di aree AI","AI is selecting area GA...":"L'IA sta selezionando l'area GA...","anomaly x{{value}}":"anomalia x{{value}}","Applies to all matching lighting command GA in the selected area.":"Si applica a tutti i comandi di illuminazione corrispondenti GA nell'area selezionata.",Area:"Zona","Area {{value}}":"Area {{value}}","Area deleted":"Area eliminata","Area editor closed":"Redazione di area chiusa","Area GA membership":"Iscrizione all'area GA","Area name":"Nome dell'area","Area reset":"Reimpostazione dell'area","Area to test":"Zona da testare",Areas:"Aree","Ask failed":"Domanda fallita","Asking...":"Asking...",Assistant:"Assistente","Assistant prompt":"Richiesta dell'assistente","Available GA":"Disponibile GA","Building test plan...":"Piano di prova della costruzione...","Builds a deterministic active test using the supported command GA in the selected area.":"Costruisce un test attivo deterministico utilizzando il comando supportato GA nell'area selezionata.","Bus Connection Persistence":"Persistenza della connessione bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Scegli un report per esaminare metriche, controlli dettagliati e suggerimenti.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Scegli un modello di test standard per l'area selezionata, quindi crea il piano in modo deterministico dal catalogo ETS.",Close:"Chiudi","Close menu":"Chiudi menù",Command:"Comando","Command DPT":"Comando DPT","Command GA":"Comando GA","Command payload":"Carico utile del comando",Completed:"Completato","Config exported":"Configurazione esportata","Config imported":"Configurazione importata","Connected {{value}}":"Connesso {{value}}","Coverage {{value}}%":"Copertura {{value}}%","Define at least one area before creating a test plan":"Definire almeno un'area prima di creare un piano di test","Define at least one area before using Tests":"Definire almeno un'area prima di utilizzare i test","Delete Area":"Elimina area","Deleting actuator preset...":"Eliminazione della preimpostazione dell'attuatore...","Deleting area...":"Eliminazione area...","Deleting profile...":"Eliminazione profilo...","Deleting test plan...":"Eliminazione del piano di test...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Descrivi la stanza, la zona o la funzione che desideri.L'intelligenza artificiale suggerirà gli indirizzi dei gruppi più rilevanti per questa bozza.",Description:"Descrizione","Disconnected {{value}}":"Disconnesso {{value}}","Documentation: KNX AI Vue":"Documentazione: KNX AI Vue","Donate via PayPal":"Dona tramite PayPal","Drag step":"Trascina il passaggio",Duplicate:"Duplica","Duplicate Plan":"Duplica piano","Edit Area":"Modifica area","Edit Plan":"Modifica piano","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Abilita l'IA nel nodo KNX AI per rigenerare aree o suggerire GA per una nuova bozza.","Event distribution will appear after the first samples.":"La distribuzione degli eventi apparirà dopo i primi campioni.","Event Mix":"Mix di eventi","Example: Add all technical room lighting command and status GA.":"Esempio: aggiungere tutti i comandi e lo stato dell'illuminazione del locale tecnico GA.",Expected:"Previsto","Expected feedback value":"Valore di feedback previsto","Expected payload":"Carico utile previsto","Explain any anomalies you see and suggest what to check first.":"Spiega eventuali anomalie riscontrate e suggerisci cosa controllare prima.","Export PDF":"Esporta PDF","Exporting config...":"Esportazione della configurazione...",Fail:"Fallire","Failed to build the test plan":"Impossibile creare il piano di test","Failed to delete actuator preset":"Impossibile eliminare la preimpostazione dell'attuatore","Failed to delete area":"Impossibile eliminare l'area","Failed to delete profile":"Impossibile eliminare il profilo","Failed to delete test plan":"Impossibile eliminare il piano di test","Failed to delete test result":"Impossibile eliminare il risultato del test","Failed to export config":"Impossibile esportare la configurazione","Failed to import config":"Impossibile importare la configurazione","Failed to load area command/status catalog":"Impossibile caricare il catalogo comandi/stati dell'area","Failed to load GA catalog":"Impossibile caricare il catalogo GA","Failed to load nodes":"Impossibile caricare i nodi","Failed to load state":"Impossibile caricare lo stato","Failed to regenerate AI areas":"Impossibile rigenerare le aree AI","Failed to reset area":"Impossibile reimpostare l'area","Failed to run actuator test":"Impossibile eseguire il test dell'attuatore","Failed to run profile":"Impossibile eseguire il profilo","Failed to run test plan":"Impossibile eseguire il piano di test","Failed to save actuator preset":"Impossibile salvare la preimpostazione dell'attuatore","Failed to save area":"Impossibile salvare l'area","Failed to save GA role":"Impossibile salvare il ruolo GA","Failed to save profile":"Impossibile salvare il profilo","Failed to save test plan":"Impossibile salvare il piano di test","Failed to save test result":"Impossibile salvare il risultato del test","Failed to suggest area GA":"Impossibile suggerire l'area GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Genera un grafico a barre SVG dei principali indirizzi del gruppo con conteggi e titolo.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Il verde mostra l'ora collegata al bus KNX.Il rosso mostra i tempi di inattività all'interno della finestra della cronologia selezionata.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC controllo attivo","Importing config...":"Importazione configurazione...","in progress":"in corso","Installer alias":"Alias dell'installatore","KNX active test name":"KNX nome del test attivo","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Luci accese, poi spente","Live and saved reports generated by KNX active and read-only tests.":"Report in tempo reale e salvati generati da test attivi e di sola lettura di KNX.","Loading nodes...":"Caricamento nodi...","Loading...":"Loading...","n/a":"n/a","New Area":"Nuova zona","New Plan":"Nuovo piano","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Nessuna area corrisponde alla ricerca corrente oppure il file ETS non espone ancora una gerarchia utilizzabile.","No detailed entries stored for this report yet.":"Nessuna voce dettagliata ancora memorizzata per questo rapporto.","No feedback":"Nessun feedback","No GA selected for this area yet.":"Nessun GA ancora selezionato per quest'area.","No KNX AI nodes found.":"Nessun nodo KNX AI trovato.","No saved plans yet.":"Nessun piano ancora salvato.","No saved test results yet.":"Nessun risultato del test ancora salvato.","No test result selected to export":"Nessun risultato del test selezionato per l'esportazione","No test result selected.":"Nessun risultato del test selezionato.","No top group address data available yet.":"Nessun dato sugli indirizzi dei gruppi principali ancora disponibile.","Nodes {{nodes}} | Links {{links}}":"Nodi {{nodes}} |Collegamenti {{links}}",Now:"Adesso","Open and close shading":"Apri e chiudi l'ombreggiatura","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Aprire e chiudere gli attuatori ombreggianti presenti nell'area, quindi verificare che lo stato corrisponda ai comandi inviati.","Open Source Test":"Prova dell'open source","Optional note for diagnostics and reports":"Nota facoltativa per diagnostica e report","Original ETS path:":"Percorso ETS originale:",Overview:"Panoramica",Pass:"Passa",Payload:"Carico utile","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Scegli dal catalogo ETS.Gli GA già selezionati sono nascosti da questo elenco.","Plan changes discarded":"Modifiche al piano annullate","Plan duplicated":"Piano duplicato","Plan name":"Nome del piano",Plans:"Piani","Profile deleted":"Profilo eliminato","Profile report ready":"Rapporto sul profilo pronto","Profile saved":"Profilo salvato","Provider: {{provider}} | Model: {{model}}":"Fornitore: {{provider}} |Modello: {{model}}",Rate:"Vota","Read response timeout ms":"Leggi il timeout della risposta ms",Ready:"Pronto",Reason:"Motivo",Refresh:"Aggiorna","Regenerating AI areas...":"Rigenerazione delle aree AI...",Remove:"Rimuovi",Repeat:"Ripeti",Reset:"Ripristina","Resetting area...":"Reimpostazione dell'area...","Response timeout":"Timeout della risposta","Returned to the Tests page for the source actuator test.":"Ritornato alla pagina Test per il test dell'attuatore sorgente.","Returned to the Tests page for the source read-only profile.":"Ritornato alla pagina Test per il profilo di sola lettura di origine.","Returned to the Tests page.":"Ritornato alla pagina dei test.","Reusable deterministic active tests saved by the installer.":"Test attivi deterministici riutilizzabili salvati dall'installatore.",Role:"Ruolo","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Eseguire un test completo dei comandi HVAC nell'area e verificare che i setpoint e gli stati siano coerenti.",Running:"Correre","Running actuator test...":"Esecuzione del test dell'attuatore in corso...","Running profile...":"Profilo in esecuzione...","Running...":"Running...","Saving actuator preset...":"Salvataggio della preimpostazione dell'attuatore...","Saving profile...":"Salvataggio profilo...","Saving test plan...":"Salvataggio del piano di test...","Search GA, label or ETS path":"Cerca GA, etichetta o percorso ETS","Select an Area":"Seleziona un'area","Select area":"Seleziona zona","Select command GA":"Seleziona il comando GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Seleziona uno dei modelli standard.Il piano viene costruito solo dal comando GA disponibile nell'area selezionata.","Select test plan":"Seleziona il piano di prova","Select Test Result":"Seleziona Risultato del test","Selected template":"Modello selezionato","Send a":"Invia un",Settings:"Impostazioni","Short operator-facing description":"Breve descrizione rivolta all'operatore","Show AI Area Builder":"Mostra AI Area Builder","Show Template Builder":"Mostra generatore di modelli","Spontaneous Write From Status GA":"Scrittura spontanea dallo stato GA",Status:"Stato","Status DPT":"Stato DPT","Status GA":"Stato GA","Status write timeout ms":"Timeout scrittura stato ms","Step title":"Titolo del passaggio","Stopping repeat mode after the current cycle...":"Interruzione della modalità di ripetizione dopo il ciclo corrente...",Subscribe:"Iscriviti",Suggestions:"Suggerimenti","Summarize the current KNX traffic and highlight the busiest group addresses.":"Riepiloga il traffico corrente KNX ed evidenzia gli indirizzi dei gruppi più trafficati.",Summary:"Sommario","Targets supported HVAC command GA in the selected area.":"Bersagli supportati HVAC comando GA nell'area selezionata.","Targets supported shading command GA in the selected area.":"Gli obiettivi supportano il comando di ombreggiatura GA nell'area selezionata.","telegram from the status GA.":"telegramma dallo stato GA.","telegram to the status GA and wait for a":"telegramma allo stato GA e attendere un",Telegrams:"Telegrammi","Template Builder":"Generatore di modelli","Test editor closed":"Editor del test chiuso","Test plan deleted":"Piano di test eliminato","Test plan ready":"Piano di prova pronto","Test plan saved":"Piano di test salvato","Test completed":"Test completato","Repeat mode stopped":"Modalità ripetizione arrestata","Test result deleted":"Risultato del test cancellato","Test Results":"Risultati dei test","Test Running":"Prova in esecuzione",Tests:"Test","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"L'installatore può rinominare l'area e decidere esattamente a quali indirizzi di gruppo appartenere.Tutto è persistente per nodo KNX AI.",Timeout:"Timeout",Title:"Titolo","Toggle menu":"Cambia menu","Toggle sidebar":"Attiva/disattiva la barra laterale","Top Group Addresses":"Indirizzi di gruppo principali","true, false, 50":"vero, falso, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Accendi le luci, poi spegnile e verifica che i relativi valori di stato siano coerenti.","Unknown DPT":"Sconosciuto DPT","Unsaved changes":"Modifiche non salvate",Voice:"Voce",Wait:"Aspetta","Wait for a spontaneous":"Aspetta uno spontaneo","Wait ms":"Aspetta, signorina",Warn:"Avvertire","What this step checks":"Cosa controlla questo passaggio","Why this step exists":"Perché esiste questo passaggio","Window {{value}}s.":"Finestra {{value}}s.","Write timeout":"Scrivi timeout"},de:{"Flow Builder":"Flow-Generator","AI enabled":"KI aktiviert","AI disabled":"KI deaktiviert","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Beschreiben Sie die Automatisierung in natürlicher Sprache. Die KI erzeugt einen Node-RED-Flow mit KNX-Ultimate-Knoten, den Hue-Knoten und nativen Function-/Logik-Knoten, verdrahtet mit Ihren importierten Gruppenadressen. Kopieren Sie das JSON und fügen Sie es in Node-RED über Menü > Import ein.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"z. B. Wenn der Hue-Bewegungsmelder im Wohnzimmer Bewegung erkennt, schalte das Wohnzimmerlicht ein.","Generate flow":"Flow erzeugen","Generating...":"Wird erzeugt...","Generating flow...":"Flow wird erzeugt...","Copy JSON":"JSON kopieren","Copied!":"Kopiert!","Flow JSON copied to clipboard":"Flow-JSON in die Zwischenablage kopiert","Flow generation failed":"Flow-Erzeugung fehlgeschlagen","Could not copy to clipboard":"Kopieren in die Zwischenablage fehlgeschlagen","The generated flow JSON will appear here.":"Das generierte Flow-JSON erscheint hier.","{{count}} areas":"{{count}} Bereiche","{{count}} available":"{{count}} verfügbar","{{count}} event types":"{{count}} Ereignistypen","{{count}} recent":"{{count}} aktuell","{{count}} saved plans":"{{count}} gespeicherte Pläne","{{count}} visible":"{{count}} sichtbar","Activate main actuators":"Hauptaktoren aktivieren","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Aktivieren Sie die Hauptaktoren im Bereich und überprüfen Sie die Statusrückmeldung, um zu bestätigen, dass die Befehle befolgt werden.","Active Read Request To Status GA":"Aktive Leseanforderung an Status GA","Actuator preset deleted":"Aktorvoreinstellung gelöscht","Actuator preset saved":"Aktorvoreinstellung gespeichert","Actuator test complete":"Aktuatortest abgeschlossen","Add group addresses to this area":"Fügen Sie diesem Bereich Gruppenadressen hinzu","Add Step":"Schritt hinzufügen","Add Wait":"Warten hinzufügen","AI Area Builder":"AI Area Builder","AI is selecting area GA...":"KI wählt Bereich GA aus...","anomaly x{{value}}":"Anomalie x{{value}}","Applies to all matching lighting command GA in the selected area.":"Gilt für alle passenden Beleuchtungsbefehle GA im ausgewählten Bereich.",Area:"Bereich","Area {{value}}":"Bereich {{value}}","Area deleted":"Bereich gelöscht","Area editor closed":"Bereichseditor geschlossen","Area GA membership":"Bereich GA Mitgliedschaft","Area name":"Gebietsname","Area reset":"Bereich zurückgesetzt","Area to test":"Bereich zum Testen",Areas:"Bereiche","Ask failed":"Die Anfrage ist fehlgeschlagen","Asking...":"Asking...",Assistant:"Assistent","Assistant prompt":"Eingabeaufforderung des Assistenten","Available GA":"Verfügbar GA","Building test plan...":"Bautestplan...","Builds a deterministic active test using the supported command GA in the selected area.":"Erstellt einen deterministischen aktiven Test mit dem unterstützten Befehl GA im ausgewählten Bereich.","Bus Connection Persistence":"Persistenz der Busverbindung","Choose a report to inspect metrics, detailed checks, and suggestions.":"Wählen Sie einen Bericht aus, um Metriken, detaillierte Prüfungen und Vorschläge zu prüfen.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Wählen Sie eine Standardtestvorlage für den ausgewählten Bereich und erstellen Sie dann den Plan deterministisch aus dem Katalog ETS.",Close:"Schließen","Close menu":"Menü schließen",Command:"Befehl","Command DPT":"Befehl DPT","Command GA":"Befehl GA","Command payload":"Befehlsnutzlast",Completed:"Abgeschlossen","Config exported":"Konfiguration exportiert","Config imported":"Konfiguration importiert","Connected {{value}}":"Verbunden {{value}}","Coverage {{value}}%":"Abdeckung {{value}}%","Define at least one area before creating a test plan":"Definieren Sie mindestens einen Bereich, bevor Sie einen Testplan erstellen","Define at least one area before using Tests":"Definieren Sie mindestens einen Bereich, bevor Sie Tests verwenden","Delete Area":"Bereich löschen","Deleting actuator preset...":"Aktor-Preset wird gelöscht...","Deleting area...":"Bereich wird gelöscht...","Deleting profile...":"Profil wird gelöscht...","Deleting test plan...":"Testplan wird gelöscht...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Beschreiben Sie den Raum, die Zone oder die Funktion, die Sie wünschen.Die KI schlägt für diesen Entwurf die relevantesten Gruppenadressen vor.",Description:"Beschreibung","Disconnected {{value}}":"Getrennt {{value}}","Documentation: KNX AI Vue":"Dokumentation: KNX AI Vue","Donate via PayPal":"Spenden Sie über PayPal","Drag step":"Schritt ziehen",Duplicate:"Duplizieren","Duplicate Plan":"Plan duplizieren","Edit Area":"Bereich bearbeiten","Edit Plan":"Plan bearbeiten","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Aktivieren Sie die KI im Knoten KNX AI, um Bereiche neu zu generieren, oder schlagen Sie GA für einen neuen Entwurf vor.","Event distribution will appear after the first samples.":"Die Ereignisverteilung erscheint nach den ersten Proben.","Event Mix":"Event-Mix","Example: Add all technical room lighting command and status GA.":"Beispiel: Alle technischen Raumbeleuchtungsbefehle und den Status GA hinzufügen.",Expected:"Erwartet","Expected feedback value":"Erwarteter Feedbackwert","Expected payload":"Erwartete Nutzlast","Explain any anomalies you see and suggest what to check first.":"Erklären Sie alle Anomalien, die Sie sehen, und schlagen Sie vor, was Sie zuerst überprüfen sollten.","Export PDF":"PDF exportieren","Exporting config...":"Konfiguration wird exportiert...",Fail:"Scheitern","Failed to build the test plan":"Der Testplan konnte nicht erstellt werden","Failed to delete actuator preset":"Aktorvoreinstellung konnte nicht gelöscht werden","Failed to delete area":"Bereich konnte nicht gelöscht werden","Failed to delete profile":"Profil konnte nicht gelöscht werden","Failed to delete test plan":"Testplan konnte nicht gelöscht werden","Failed to delete test result":"Testergebnis konnte nicht gelöscht werden","Failed to export config":"Konfiguration konnte nicht exportiert werden","Failed to import config":"Konfiguration konnte nicht importiert werden","Failed to load area command/status catalog":"Der Befehls-/Statuskatalog für den Bereich konnte nicht geladen werden","Failed to load GA catalog":"Der Katalog GA konnte nicht geladen werden","Failed to load nodes":"Knoten konnten nicht geladen werden","Failed to load state":"Status konnte nicht geladen werden","Failed to regenerate AI areas":"KI-Bereiche konnten nicht regeneriert werden","Failed to reset area":"Bereich konnte nicht zurückgesetzt werden","Failed to run actuator test":"Aktuatortest konnte nicht ausgeführt werden","Failed to run profile":"Profil konnte nicht ausgeführt werden","Failed to run test plan":"Testplan konnte nicht ausgeführt werden","Failed to save actuator preset":"Aktorvoreinstellung konnte nicht gespeichert werden","Failed to save area":"Bereich konnte nicht gespeichert werden","Failed to save GA role":"Die Rolle GA konnte nicht gespeichert werden","Failed to save profile":"Profil konnte nicht gespeichert werden","Failed to save test plan":"Der Testplan konnte nicht gespeichert werden","Failed to save test result":"Testergebnis konnte nicht gespeichert werden","Failed to suggest area GA":"Bereich GA konnte nicht vorgeschlagen werden","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Erstellen Sie ein SVG-Balkendiagramm der Top-Gruppenadressen mit Anzahl und Titel.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Grün zeigt die mit dem Bus KNX verbundene Zeit an.Rot zeigt Ausfallzeiten im ausgewählten Verlaufsfenster an.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC aktive Prüfung","Importing config...":"Konfiguration wird importiert...","in progress":"in Bearbeitung","Installer alias":"Installer-Alias","KNX active test name":"KNX aktiver Testname","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Licht an, dann aus","Live and saved reports generated by KNX active and read-only tests.":"Live- und gespeicherte Berichte, die von KNX aktiven und schreibgeschützten Tests generiert wurden.","Loading nodes...":"Knoten werden geladen...","Loading...":"Loading...","n/a":"n/a","New Area":"Neuer Bereich","New Plan":"Neuer Plan","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Keine Bereiche stimmten mit der aktuellen Suche überein oder die Datei ETS stellt noch keine verwendbare Hierarchie bereit.","No detailed entries stored for this report yet.":"Für diesen Bericht sind noch keine detaillierten Einträge hinterlegt.","No feedback":"Keine Rückmeldung","No GA selected for this area yet.":"Für diesen Bereich wurde noch kein GA ausgewählt.","No KNX AI nodes found.":"Keine KNX AI Knoten gefunden.","No saved plans yet.":"Noch keine gespeicherten Pläne.","No saved test results yet.":"Noch keine gespeicherten Testergebnisse.","No test result selected to export":"Kein Testergebnis zum Exportieren ausgewählt","No test result selected.":"Kein Testergebnis ausgewählt.","No top group address data available yet.":"Es sind noch keine Daten zur Top-Gruppenadresse verfügbar.","Nodes {{nodes}} | Links {{links}}":"Knoten {{nodes}} |Links {{links}}",Now:"Jetzt","Open and close shading":"Beschattung öffnen und schließen","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Öffnen und schließen Sie die Beschattungsaktoren im Bereich und überprüfen Sie dann, ob der Status mit den gesendeten Befehlen übereinstimmt.","Open Source Test":"Open-Source-Test","Optional note for diagnostics and reports":"Optionaler Hinweis für Diagnosen und Berichte","Original ETS path:":"Ursprünglicher ETS Pfad:",Overview:"Übersicht",Pass:"Pass",Payload:"Nutzlast","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Wählen Sie aus dem Katalog ETS.Bereits ausgewählte GA werden aus dieser Liste ausgeblendet.","Plan changes discarded":"Planänderungen verworfen","Plan duplicated":"Plan dupliziert","Plan name":"Planname",Plans:"Pläne","Profile deleted":"Profil gelöscht","Profile report ready":"Profilbericht bereit","Profile saved":"Profil gespeichert","Provider: {{provider}} | Model: {{model}}":"Anbieter: {{provider}} |Modell: {{model}}",Rate:"Bewerten","Read response timeout ms":"Leseantwort-Timeout ms",Ready:"Bereit",Reason:"Grund",Refresh:"Aktualisieren","Regenerating AI areas...":"KI-Bereiche werden regeneriert...",Remove:"Entfernen",Repeat:"Wiederholen",Reset:"Zurücksetzen","Resetting area...":"Bereich wird zurückgesetzt...","Response timeout":"Antwortzeitüberschreitung","Returned to the Tests page for the source actuator test.":"Zurück zur Seite „Tests“ für den Quellaktuatortest.","Returned to the Tests page for the source read-only profile.":"Kehrt zur Seite „Tests“ für das schreibgeschützte Quellprofil zurück.","Returned to the Tests page.":"Zurück zur Seite „Tests“.","Reusable deterministic active tests saved by the installer.":"Wiederverwendbare deterministische aktive Tests, die vom Installationsprogramm gespeichert werden.",Role:"Rolle","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Führen Sie einen vollständigen Test der HVAC-Befehle im Bereich durch und stellen Sie sicher, dass Sollwerte und Status kohärent sind.",Running:"Laufen","Running actuator test...":"Aktuatortest wird ausgeführt...","Running profile...":"Laufprofil...","Running...":"Running...","Saving actuator preset...":"Aktorvoreinstellung speichern...","Saving profile...":"Profil wird gespeichert...","Saving test plan...":"Testplan wird gespeichert...","Search GA, label or ETS path":"Suchen Sie nach GA, Label oder ETS Pfad","Select an Area":"Wählen Sie einen Bereich aus","Select area":"Bereich auswählen","Select command GA":"Wählen Sie den Befehl GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Wählen Sie eine der Standardvorlagen aus.Der Plan wird nur mit dem Befehl GA erstellt, der im ausgewählten Bereich verfügbar ist.","Select test plan":"Testplan auswählen","Select Test Result":"Wählen Sie Testergebnis","Selected template":"Ausgewählte Vorlage","Send a":"Senden Sie eine",Settings:"Einstellungen","Short operator-facing description":"Kurze Beschreibung für den Bediener","Show AI Area Builder":"AI Area Builder anzeigen","Show Template Builder":"Template Builder anzeigen","Spontaneous Write From Status GA":"Spontanes Schreiben aus Status GA",Status:"Status","Status DPT":"Status DPT","Status GA":"Status GA","Status write timeout ms":"Statusschreib-Timeout ms","Step title":"Schritttitel","Stopping repeat mode after the current cycle...":"Stoppen des Wiederholungsmodus nach dem aktuellen Zyklus...",Subscribe:"Abonnieren",Suggestions:"Vorschläge","Summarize the current KNX traffic and highlight the busiest group addresses.":"Fassen Sie den aktuellen KNX-Verkehr zusammen und markieren Sie die am stärksten ausgelasteten Gruppenadressen.",Summary:"Zusammenfassung","Targets supported HVAC command GA in the selected area.":"Unterstützte Ziele: HVAC Befehl GA im ausgewählten Bereich.","Targets supported shading command GA in the selected area.":"Zielt auf den unterstützten Schattierungsbefehl GA im ausgewählten Bereich.","telegram from the status GA.":"Telegramm vom Status GA.","telegram to the status GA and wait for a":"Telegramm auf den Status GA und warten Sie auf a",Telegrams:"Telegramme","Template Builder":"Vorlagenersteller","Test editor closed":"Testeditor geschlossen","Test plan deleted":"Testplan gelöscht","Test plan ready":"Testplan fertig","Test plan saved":"Testplan gespeichert","Test completed":"Test abgeschlossen","Repeat mode stopped":"Wiederholungsmodus gestoppt","Test result deleted":"Testergebnis gelöscht","Test Results":"Testergebnisse","Test Running":"Testlauf",Tests:"Tests","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"Der Installateur kann den Bereich umbenennen und genau entscheiden, welche Gruppenadressen dazu gehören.Alles wird pro KNX AI-Knoten beibehalten.",Timeout:"Auszeit",Title:"Titel","Toggle menu":"Menü umschalten","Toggle sidebar":"Seitenleiste umschalten","Top Group Addresses":"Top-Gruppenadressen","true, false, 50":"wahr, falsch, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Schalten Sie die Lichter ein und wieder aus und überprüfen Sie, ob die zugehörigen Statuswerte kohärent sind.","Unknown DPT":"Unbekannt DPT","Unsaved changes":"Nicht gespeicherte Änderungen",Voice:"Stimme",Wait:"Warte","Wait for a spontaneous":"Warten Sie auf eine spontane","Wait ms":"Warten Sie, Frau",Warn:"Warnen","What this step checks":"Was dieser Schritt prüft","Why this step exists":"Warum es diesen Schritt gibt","Window {{value}}s.":"Fenster {{value}}s.","Write timeout":"Timeout schreiben"},fr:{"Flow Builder":"Générateur de flux","AI enabled":"IA activée","AI disabled":"IA désactivée","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Décrivez l'automatisation en langage naturel. L'IA génère un flux Node-RED en utilisant les nœuds KNX Ultimate, les nœuds Hue et les nœuds natifs Function/logique, reliés à vos adresses de groupe importées. Copiez le JSON, puis dans Node-RED utilisez Menu > Importer et collez-le.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"ex. Quand le détecteur de mouvement Hue du salon détecte un mouvement, allume la lumière du salon.","Generate flow":"Générer le flux","Generating...":"Génération...","Generating flow...":"Génération du flux...","Copy JSON":"Copier le JSON","Copied!":"Copié !","Flow JSON copied to clipboard":"JSON du flux copié dans le presse-papiers","Flow generation failed":"Échec de la génération du flux","Could not copy to clipboard":"Impossible de copier dans le presse-papiers","The generated flow JSON will appear here.":"Le JSON du flux généré apparaîtra ici.","{{count}} areas":"Zones {{count}}","{{count}} available":"{{count}} disponible","{{count}} event types":"{{count}} types d'événements","{{count}} recent":"{{count}} récent","{{count}} saved plans":"{{count}} plans enregistrés","{{count}} visible":"{{count}} visible","Activate main actuators":"Activer les actionneurs principaux","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Activez les principaux actionneurs de la zone et vérifiez le retour d'état pour confirmer qu'il suit les commandes.","Active Read Request To Status GA":"Demande de lecture active vers l'état GA","Actuator preset deleted":"Préréglage de l'actionneur supprimé","Actuator preset saved":"Préréglage de l'actionneur enregistré","Actuator test complete":"Test de l'actionneur terminé","Add group addresses to this area":"Ajouter des adresses de groupe à cette zone","Add Step":"Ajouter une étape","Add Wait":"Ajouter une attente","AI Area Builder":"Générateur de zones IA","AI is selecting area GA...":"L'IA sélectionne la zone GA...","anomaly x{{value}}":"anomalie x{{value}}","Applies to all matching lighting command GA in the selected area.":"S'applique à toutes les commandes d'éclairage correspondantes GA dans la zone sélectionnée.",Area:"Zone","Area {{value}}":"Zone {{value}}","Area deleted":"Zone supprimée","Area editor closed":"Éditeur de zone fermé","Area GA membership":"Adhésion à la zone GA","Area name":"Nom de la zone","Area reset":"Réinitialisation de la zone","Area to test":"Zone à tester",Areas:"Domaines","Ask failed":"La demande a échoué","Asking...":"Asking...",Assistant:"Assistante","Assistant prompt":"Invite de l'assistant","Available GA":"Disponible GA","Building test plan...":"Plan de test de construction...","Builds a deterministic active test using the supported command GA in the selected area.":"Construit un test actif déterministe à l'aide de la commande prise en charge GA dans la zone sélectionnée.","Bus Connection Persistence":"Persistance de la connexion de bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Choisissez un rapport pour inspecter les métriques, les contrôles détaillés et les suggestions.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Choisissez un modèle de test standard pour la zone sélectionnée, puis construisez le plan de manière déterministe à partir du catalogue ETS.",Close:"Fermer","Close menu":"Fermer le menu",Command:"Commande","Command DPT":"Commande DPT","Command GA":"Commande GA","Command payload":"Charge utile de commande",Completed:"Terminé","Config exported":"Configuration exportée","Config imported":"Configuration importée","Connected {{value}}":"Connecté {{value}}","Coverage {{value}}%":"Couverture {{value}}%","Define at least one area before creating a test plan":"Définir au moins un domaine avant de créer un plan de test","Define at least one area before using Tests":"Définir au moins une zone avant d'utiliser les tests","Delete Area":"Supprimer la zone","Deleting actuator preset...":"Suppression du préréglage de l'actionneur...","Deleting area...":"Suppression de la zone...","Deleting profile...":"Suppression du profil...","Deleting test plan...":"Suppression du plan de test...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Décrivez la pièce, la zone ou la fonction souhaitée.L'IA proposera les adresses de groupes les plus pertinentes pour ce projet.",Description:"Descriptif","Disconnected {{value}}":"Déconnecté {{value}}","Documentation: KNX AI Vue":"Documentation : KNX AI Vue","Donate via PayPal":"Faites un don via PayPal","Drag step":"Glisser l'étape",Duplicate:"Dupliquer","Duplicate Plan":"Dupliquer le plan","Edit Area":"Modifier la zone","Edit Plan":"Modifier le forfait","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Activez l'IA dans le nœud KNX AI pour régénérer les zones ou suggérez GA pour un nouveau brouillon.","Event distribution will appear after the first samples.":"La distribution des événements apparaîtra après les premiers échantillons.","Event Mix":"Mélange d'événements","Example: Add all technical room lighting command and status GA.":"Exemple : Ajouter toutes les commandes et statuts d'éclairage du local technique GA.",Expected:"Attendu","Expected feedback value":"Valeur attendue des commentaires","Expected payload":"Charge utile attendue","Explain any anomalies you see and suggest what to check first.":"Expliquez toutes les anomalies que vous voyez et suggérez quoi vérifier en premier.","Export PDF":"Exporter un PDF","Exporting config...":"Exportation de la configuration...",Fail:"Échec","Failed to build the test plan":"Échec de la création du plan de test","Failed to delete actuator preset":"Échec de la suppression du préréglage de l'actionneur","Failed to delete area":"Échec de la suppression de la zone","Failed to delete profile":"Échec de la suppression du profil","Failed to delete test plan":"Échec de la suppression du plan de test","Failed to delete test result":"Échec de la suppression du résultat du test","Failed to export config":"Échec de l'exportation de la configuration","Failed to import config":"Échec de l'importation de la configuration","Failed to load area command/status catalog":"Échec du chargement du catalogue de commandes/statuts de zone","Failed to load GA catalog":"Échec du chargement du catalogue GA","Failed to load nodes":"Échec du chargement des nœuds","Failed to load state":"Échec du chargement de l'état","Failed to regenerate AI areas":"Échec de la régénération des zones IA","Failed to reset area":"Échec de la réinitialisation de la zone","Failed to run actuator test":"Échec de l'exécution du test de l'actionneur","Failed to run profile":"Échec de l'exécution du profil","Failed to run test plan":"Échec de l'exécution du plan de test","Failed to save actuator preset":"Échec de l'enregistrement du préréglage de l'actionneur","Failed to save area":"Échec de l'enregistrement de la zone","Failed to save GA role":"Échec de l'enregistrement du rôle GA","Failed to save profile":"Échec de l'enregistrement du profil","Failed to save test plan":"Échec de l'enregistrement du plan de test","Failed to save test result":"Échec de l'enregistrement du résultat du test","Failed to suggest area GA":"Échec de la suggestion de la zone GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Générez un graphique à barres SVG des principales adresses des groupes avec le nombre et le titre.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Le vert indique l'heure connectée au bus KNX.Le rouge affiche les temps d'arrêt dans la fenêtre d'historique sélectionnée.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC chèque actif","Importing config...":"Importation de la configuration...","in progress":"en cours","Installer alias":"Alias de l'installateur","KNX active test name":"KNX nom du test actif","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Les lumières s'allument, puis s'éteignent","Live and saved reports generated by KNX active and read-only tests.":"Rapports en direct et enregistrés générés par KNX tests actifs et en lecture seule.","Loading nodes...":"Chargement des nœuds...","Loading...":"Loading...","n/a":"n/a","New Area":"Nouvelle zone","New Plan":"Nouveau forfait","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Aucune zone ne correspond à la recherche actuelle ou le fichier ETS n'expose pas encore de hiérarchie utilisable.","No detailed entries stored for this report yet.":"Aucune entrée détaillée n'est encore stockée pour ce rapport.","No feedback":"Aucun retour","No GA selected for this area yet.":"Aucun GA n'est encore sélectionné pour cette zone.","No KNX AI nodes found.":"Aucun nœud KNX AI trouvé.","No saved plans yet.":"Aucun plan enregistré pour l'instant.","No saved test results yet.":"Aucun résultat de test enregistré pour l'instant.","No test result selected to export":"Aucun résultat de test sélectionné pour exporter","No test result selected.":"Aucun résultat de test sélectionné.","No top group address data available yet.":"Aucune donnée d'adresse du groupe principal n'est encore disponible.","Nodes {{nodes}} | Links {{links}}":"Nœuds {{nodes}} |Liens {{links}}",Now:"Maintenant","Open and close shading":"Ombrage ouvert et fermé","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Ouvrez et fermez les actionneurs d'ombrage de la zone, puis vérifiez que l'état correspond aux commandes envoyées.","Open Source Test":"Test Open Source","Optional note for diagnostics and reports":"Remarque facultative pour les diagnostics et les rapports","Original ETS path:":"Chemin ETS d'origine :",Overview:"Aperçu",Pass:"Passer",Payload:"Charge utile","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Choisissez dans le catalogue ETS.Les GA déjà sélectionnés sont masqués de cette liste.","Plan changes discarded":"Modifications du plan rejetées","Plan duplicated":"Plan dupliqué","Plan name":"Nom du forfait",Plans:"Forfaits","Profile deleted":"Profil supprimé","Profile report ready":"Rapport de profil prêt","Profile saved":"Profil enregistré","Provider: {{provider}} | Model: {{model}}":"Fournisseur : {{provider}} |Modèle : {{model}}",Rate:"Tarif","Read response timeout ms":"Lire le délai de réponse ms",Ready:"Prêt",Reason:"Raison",Refresh:"Actualiser","Regenerating AI areas...":"Régénérer les zones d'IA...",Remove:"Supprimer",Repeat:"Répéter",Reset:"Réinitialiser","Resetting area...":"Zone de réinitialisation...","Response timeout":"Délai de réponse","Returned to the Tests page for the source actuator test.":"Retour à la page Tests pour le test de l'actionneur source.","Returned to the Tests page for the source read-only profile.":"Renvoyé à la page Tests pour le profil source en lecture seule.","Returned to the Tests page.":"Retour à la page Tests.","Reusable deterministic active tests saved by the installer.":"Tests actifs déterministes réutilisables enregistrés par l'installateur.",Role:"Rôle","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Exécutez un test complet des commandes HVAC dans la zone et vérifiez que les consignes et les états sont cohérents.",Running:"Courir","Running actuator test...":"Test de l'actionneur en cours...","Running profile...":"Profil de course...","Running...":"Running...","Saving actuator preset...":"Enregistrement du préréglage de l'actionneur...","Saving profile...":"Enregistrement du profil...","Saving test plan...":"Sauvegarde du plan de test...","Search GA, label or ETS path":"Recherchez GA, l'étiquette ou le chemin ETS","Select an Area":"Sélectionnez une zone","Select area":"Sélectionnez une zone","Select command GA":"Sélectionnez la commande GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Sélectionnez l'un des modèles standard.Le plan est construit uniquement à partir de la commande GA disponible dans la zone sélectionnée.","Select test plan":"Sélectionnez le plan de test","Select Test Result":"Sélectionnez le résultat du test","Selected template":"Modèle sélectionné","Send a":"Envoyez un",Settings:"Paramètres","Short operator-facing description":"Brève description destinée à l'opérateur","Show AI Area Builder":"Afficher le générateur de zone AI","Show Template Builder":"Afficher le générateur de modèles","Spontaneous Write From Status GA":"Écriture spontanée à partir du statut GA",Status:"Statut","Status DPT":"Statut DPT","Status GA":"Statut GA","Status write timeout ms":"Délai d'expiration de l'état en ms","Step title":"Titre de l'étape","Stopping repeat mode after the current cycle...":"Arrêt du mode répétition après le cycle en cours...",Subscribe:"Abonnez-vous",Suggestions:"Suggestions","Summarize the current KNX traffic and highlight the busiest group addresses.":"Résumez le trafic KNX actuel et mettez en surbrillance les adresses de groupe les plus fréquentées.",Summary:"Résumé","Targets supported HVAC command GA in the selected area.":"Cibles prises en charge par la commande HVAC GA dans la zone sélectionnée.","Targets supported shading command GA in the selected area.":"Cibles prenant en charge la commande d'ombrage GA dans la zone sélectionnée.","telegram from the status GA.":"télégramme du statut GA.","telegram to the status GA and wait for a":"télégramme au statut GA et attendez un",Telegrams:"Télégrammes","Template Builder":"Générateur de modèles","Test editor closed":"Éditeur de tests fermé","Test plan deleted":"Plan de test supprimé","Test plan ready":"Plan de test prêt","Test plan saved":"Plan de test enregistré","Test completed":"Test terminé","Repeat mode stopped":"Mode répétition arrêté","Test result deleted":"Résultat du test supprimé","Test Results":"Résultats des tests","Test Running":"Test en cours",Tests:"Essais","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"L'installateur peut renommer la zone et décider exactement quelles adresses de groupe lui appartiennent.Tout est conservé par nœud KNX AI.",Timeout:"Délai d'attente",Title:"Titre","Toggle menu":"Changer de menu","Toggle sidebar":"Basculer la barre latérale","Top Group Addresses":"Principales adresses des groupes","true, false, 50":"vrai, faux, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Allumez puis éteignez les lumières et vérifiez que les valeurs d'état associées sont cohérentes.","Unknown DPT":"Inconnu DPT","Unsaved changes":"Modifications non enregistrées",Voice:"Voix",Wait:"Attends","Wait for a spontaneous":"Attendez un spontané","Wait ms":"Attends madame",Warn:"Avertir","What this step checks":"Ce que cette étape vérifie","Why this step exists":"Pourquoi cette étape existe","Window {{value}}s.":"Fenêtre {{value}}s.","Write timeout":"Délai d'écriture"},es:{"Flow Builder":"Generador de flujos","AI enabled":"IA activada","AI disabled":"IA desactivada","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Describe la automatización en lenguaje natural. La IA genera un flujo de Node-RED usando los nodos KNX Ultimate, los nodos Hue y los nodos nativos Function/lógicos, conectados a tus direcciones de grupo importadas. Copia el JSON y luego en Node-RED usa Menú > Importar y pégalo.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"ej. Cuando el sensor de movimiento Hue del salón detecta movimiento, enciende la luz del salón.","Generate flow":"Generar flujo","Generating...":"Generando...","Generating flow...":"Generando flujo...","Copy JSON":"Copiar JSON","Copied!":"¡Copiado!","Flow JSON copied to clipboard":"JSON del flujo copiado al portapapeles","Flow generation failed":"Error al generar el flujo","Could not copy to clipboard":"No se pudo copiar al portapapeles","The generated flow JSON will appear here.":"El JSON del flujo generado aparecerá aquí.","{{count}} areas":"{{count}} áreas","{{count}} available":"{{count}} disponible","{{count}} event types":"{{count}} tipos de eventos","{{count}} recent":"{{count}} reciente","{{count}} saved plans":"{{count}} planes guardados","{{count}} visible":"{{count}} visible","Activate main actuators":"Activar actuadores principales","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Active los principales actuadores del área y verifique la retroalimentación de estado para confirmar que sigue los comandos.","Active Read Request To Status GA":"Solicitud de lectura activa al estado GA","Actuator preset deleted":"Preajuste del actuador eliminado","Actuator preset saved":"Preajuste del actuador guardado","Actuator test complete":"Prueba del actuador completa","Add group addresses to this area":"Agregar direcciones de grupo a esta área","Add Step":"Agregar paso","Add Wait":"Agregar esperar","AI Area Builder":"Generador de áreas de IA","AI is selecting area GA...":"La IA está seleccionando el área GA...","anomaly x{{value}}":"anomalía x{{value}}","Applies to all matching lighting command GA in the selected area.":"Se aplica a todos los comandos de iluminación coincidentes GA en el área seleccionada.",Area:"Área","Area {{value}}":"Área {{value}}","Area deleted":"Área eliminada","Area editor closed":"Editor de área cerrado","Area GA membership":"Membresía del área GA","Area name":"Nombre del área","Area reset":"Restablecer área","Area to test":"Área para probar",Areas:"Áreas","Ask failed":"Pregunta fallida","Asking...":"Asking...",Assistant:"Asistente","Assistant prompt":"Aviso del asistente","Available GA":"Disponible GA","Building test plan...":"Plano de pruebas del edificio...","Builds a deterministic active test using the supported command GA in the selected area.":"Crea una prueba activa determinista utilizando el comando admitido GA en el área seleccionada.","Bus Connection Persistence":"Persistencia de la conexión de bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Elija un informe para inspeccionar métricas, comprobaciones detalladas y sugerencias.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Elija una plantilla de prueba estándar para el área seleccionada y luego cree el plan de manera determinista a partir del catálogo ETS.",Close:"Cerrar","Close menu":"Cerrar menú",Command:"Comando","Command DPT":"Comando DPT","Command GA":"Comando GA","Command payload":"Carga útil de comando",Completed:"Completado","Config exported":"Configuración exportada","Config imported":"Configuración importada","Connected {{value}}":"Conectado {{value}}","Coverage {{value}}%":"Cobertura {{value}}%","Define at least one area before creating a test plan":"Defina al menos un área antes de crear un plan de prueba","Define at least one area before using Tests":"Defina al menos un área antes de usar Pruebas","Delete Area":"Eliminar área","Deleting actuator preset...":"Eliminando preajuste del actuador...","Deleting area...":"Eliminando área...","Deleting profile...":"Eliminando perfil...","Deleting test plan...":"Eliminando plan de prueba...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Describe la habitación, zona o función que deseas.La AI sugerirá las direcciones de grupo más relevantes para este borrador.",Description:"Descripción","Disconnected {{value}}":"Desconectado {{value}}","Documentation: KNX AI Vue":"Documentación: KNX AI Vue","Donate via PayPal":"Donar a través de PayPal","Drag step":"Paso de arrastre",Duplicate:"Duplicar","Duplicate Plan":"Duplicar plan","Edit Area":"Editar área","Edit Plan":"Editar plano","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Habilite la IA en el nodo KNX AI para regenerar áreas o sugiera GA para un nuevo borrador.","Event distribution will appear after the first samples.":"La distribución de eventos aparecerá después de las primeras muestras.","Event Mix":"Mezcla de eventos","Example: Add all technical room lighting command and status GA.":"Ejemplo: agregue todos los comandos y estados de iluminación de la sala técnica GA.",Expected:"esperado","Expected feedback value":"Valor de retroalimentación esperado","Expected payload":"Carga útil esperada","Explain any anomalies you see and suggest what to check first.":"Explique cualquier anomalía que observe y sugiera qué comprobar primero.","Export PDF":"Exportar PDF","Exporting config...":"Exportando configuración...",Fail:"fallar","Failed to build the test plan":"No se pudo construir el plan de prueba","Failed to delete actuator preset":"No se pudo eliminar el ajuste preestablecido del actuador","Failed to delete area":"No se pudo eliminar el área","Failed to delete profile":"No se pudo eliminar el perfil","Failed to delete test plan":"No se pudo eliminar el plan de prueba","Failed to delete test result":"No se pudo eliminar el resultado de la prueba","Failed to export config":"No se pudo exportar la configuración","Failed to import config":"No se pudo importar la configuración","Failed to load area command/status catalog":"No se pudo cargar el catálogo de comando/estado del área","Failed to load GA catalog":"No se pudo cargar el catálogo GA","Failed to load nodes":"No se pudieron cargar los nodos","Failed to load state":"No se pudo cargar el estado","Failed to regenerate AI areas":"No se pudieron regenerar las áreas de IA","Failed to reset area":"No se pudo restablecer el área","Failed to run actuator test":"No se pudo ejecutar la prueba del actuador","Failed to run profile":"No se pudo ejecutar el perfil","Failed to run test plan":"No se pudo ejecutar el plan de prueba","Failed to save actuator preset":"No se pudo guardar el ajuste preestablecido del actuador","Failed to save area":"No se pudo guardar el área","Failed to save GA role":"No se pudo guardar el rol GA","Failed to save profile":"No se pudo guardar el perfil","Failed to save test plan":"No se pudo guardar el plan de prueba","Failed to save test result":"No se pudo guardar el resultado de la prueba","Failed to suggest area GA":"No se pudo sugerir el área GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Genere un gráfico de barras SVG de direcciones de grupos principales con recuentos y título.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"El verde muestra el tiempo conectado al bus KNX.El rojo muestra el tiempo de inactividad dentro de la ventana del historial seleccionado.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC verificación activa","Importing config...":"Importando configuración...","in progress":"en progreso","Installer alias":"Alias del instalador","KNX active test name":"KNX nombre de prueba activo","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Luces encendidas y luego apagadas","Live and saved reports generated by KNX active and read-only tests.":"Informes en vivo y guardados generados por KNX pruebas activas y de solo lectura.","Loading nodes...":"Cargando nodos...","Loading...":"Loading...","n/a":"n/a","New Area":"Nueva Área","New Plan":"Nuevo Plan","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Ninguna área coincidió con la búsqueda actual o el archivo ETS aún no expone una jerarquía utilizable.","No detailed entries stored for this report yet.":"Aún no se han almacenado entradas detalladas para este informe.","No feedback":"Sin comentarios","No GA selected for this area yet.":"Aún no se ha seleccionado ningún GA para esta área.","No KNX AI nodes found.":"No se encontraron nodos KNX AI.","No saved plans yet.":"Aún no hay planes guardados.","No saved test results yet.":"Aún no hay resultados de pruebas guardados.","No test result selected to export":"No se seleccionó ningún resultado de prueba para exportar","No test result selected.":"No se seleccionó ningún resultado de prueba.","No top group address data available yet.":"Aún no hay datos de direcciones de grupos principales disponibles.","Nodes {{nodes}} | Links {{links}}":"Nodos {{nodes}} |Enlaces {{links}}",Now:"Ahora","Open and close shading":"Abrir y cerrar sombreado","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Abra y cierre los actuadores de sombreado del área, luego verifique que el estado coincida con los comandos enviados.","Open Source Test":"Prueba de código abierto","Optional note for diagnostics and reports":"Nota opcional para diagnósticos e informes.","Original ETS path:":"Ruta original ETS:",Overview:"Descripción general",Pass:"Pase",Payload:"Carga útil","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Elija del catálogo ETS.Los GA ya seleccionados están ocultos de esta lista.","Plan changes discarded":"Cambios de plan descartados","Plan duplicated":"Plano duplicado","Plan name":"Nombre del plan",Plans:"Planes","Profile deleted":"Perfil eliminado","Profile report ready":"Informe de perfil listo","Profile saved":"Perfil guardado","Provider: {{provider}} | Model: {{model}}":"Proveedor: {{provider}} |Modelo: {{model}}",Rate:"Tarifa","Read response timeout ms":"Tiempo de espera de respuesta de lectura ms",Ready:"Listo",Reason:"Razón",Refresh:"Actualizar","Regenerating AI areas...":"Regenerando áreas de IA...",Remove:"Quitar",Repeat:"repetir",Reset:"Reiniciar","Resetting area...":"Restableciendo área...","Response timeout":"Tiempo de espera de respuesta","Returned to the Tests page for the source actuator test.":"Regresó a la página Pruebas para la prueba del actuador fuente.","Returned to the Tests page for the source read-only profile.":"Regresó a la página Pruebas para el perfil de solo lectura de origen.","Returned to the Tests page.":"Regresó a la página de Pruebas.","Reusable deterministic active tests saved by the installer.":"Pruebas activas deterministas reutilizables guardadas por el instalador.",Role:"Rol","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Ejecute una prueba completa de los comandos HVAC en el área y verifique que los puntos de ajuste y los estados sean coherentes.",Running:"corriendo","Running actuator test...":"Ejecutando la prueba del actuador...","Running profile...":"Perfil de carrera...","Running...":"Running...","Saving actuator preset...":"Guardando preajuste del actuador...","Saving profile...":"Guardando perfil...","Saving test plan...":"Guardando plan de prueba...","Search GA, label or ETS path":"Buscar GA, etiqueta o ruta ETS","Select an Area":"Seleccione un área","Select area":"Seleccionar área","Select command GA":"Seleccione el comando GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Seleccione una de las plantillas estándar.El plan se construye únicamente a partir del comando GA disponible en el área seleccionada.","Select test plan":"Seleccionar plan de prueba","Select Test Result":"Seleccionar resultado de la prueba","Selected template":"Plantilla seleccionada","Send a":"Enviar un",Settings:"Configuración","Short operator-facing description":"Breve descripción orientada al operador","Show AI Area Builder":"Mostrar generador de áreas de IA","Show Template Builder":"Mostrar generador de plantillas","Spontaneous Write From Status GA":"Escritura espontánea desde el estado GA",Status:"Estado","Status DPT":"Estado DPT","Status GA":"Estado GA","Status write timeout ms":"Tiempo de espera de escritura de estado ms","Step title":"Título del paso","Stopping repeat mode after the current cycle...":"Deteniendo el modo de repetición después del ciclo actual...",Subscribe:"Suscríbete",Suggestions:"Sugerencias","Summarize the current KNX traffic and highlight the busiest group addresses.":"Resuma el tráfico KNX actual y resalte las direcciones de grupo más ocupadas.",Summary:"Resumen","Targets supported HVAC command GA in the selected area.":"Los objetivos admitieron el comando HVAC GA en el área seleccionada.","Targets supported shading command GA in the selected area.":"Los objetivos admiten el comando de sombreado GA en el área seleccionada.","telegram from the status GA.":"telegrama del estado GA.","telegram to the status GA and wait for a":"telegrama al estado GA y espere un",Telegrams:"telegramas","Template Builder":"Generador de plantillas","Test editor closed":"Editor de pruebas cerrado","Test plan deleted":"Plan de prueba eliminado","Test plan ready":"Plan de prueba listo","Test plan saved":"Plan de prueba guardado","Test completed":"Prueba completada","Repeat mode stopped":"Modo repetición detenido","Test result deleted":"Resultado de la prueba eliminado","Test Results":"Resultados de la prueba","Test Running":"Ejecución de prueba",Tests:"Pruebas","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"El instalador puede cambiar el nombre del área y decidir exactamente qué direcciones de grupo pertenecen a ella.Todo persiste por nodo KNX AI.",Timeout:"Tiempo de espera",Title:"Título","Toggle menu":"Alternar menú","Toggle sidebar":"Alternar barra lateral","Top Group Addresses":"Direcciones de grupos principales","true, false, 50":"verdadero, falso, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Encienda las luces, luego apáguelas y verifique que los valores de estado relacionados sean coherentes.","Unknown DPT":"Desconocido DPT","Unsaved changes":"Cambios no guardados",Voice:"Voz",Wait:"espera","Wait for a spontaneous":"Espere un espontaneo","Wait ms":"Espere señora",Warn:"Advertir","What this step checks":"Lo que verifica este paso","Why this step exists":"Por qué existe este paso","Window {{value}}s.":"Ventana {{value}}s.","Write timeout":"Escribir tiempo de espera"},"zh-CN":{"{{count}} areas":"{{count}} 区域","{{count}} available":"{{count}} 可用","{{count}} event types":"{{count}} 事件类型","{{count}} recent":"{{count}} 最近","{{count}} saved plans":"{{count}} 已保存计划","{{count}} visible":"{{count}} 可见","Activate main actuators":"激活主执行器","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"激活该区域的主执行器并验证状态反馈以确认其遵循命令。","Active Read Request To Status GA":"对状态 GA 的主动读取请求","Actuator preset deleted":"执行器预设已删除","Actuator preset saved":"执行器预设已保存","Actuator test complete":"执行器测试完成","Add group addresses to this area":"将组地址添加到该区域","Add Step":"添加步骤","Add Wait":"添加等待","AI Area Builder":"人工智能区域生成器","AI is selecting area GA...":"AI 正在选择区域 GA...","anomaly x{{value}}":"异常 x{{value}}","Applies to all matching lighting command GA in the selected area.":"适用于所选区域中所有匹配的照明命令 GA。",Area:"面积","Area {{value}}":"区域 {{value}}","Area deleted":"区域已删除","Area editor closed":"区域编辑器已关闭","Area GA membership":"区域 GA 会员资格","Area name":"地区名称","Area reset":"区域重置","Area to test":"测试区域",Areas:"领域","Ask failed":"询问失败","Asking...":"Asking...",Assistant:"助理","Assistant prompt":"助手提示","Available GA":"可用 GA","Building test plan...":"构建测试计划...","Builds a deterministic active test using the supported command GA in the selected area.":"在选定区域中使用支持的命令 GA 构建确定性主动测试。","Bus Connection Persistence":"总线连接持久性","Choose a report to inspect metrics, detailed checks, and suggestions.":"选择报告来检查指标、详细检查和建议。","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"为所选区域选择一个标准测试模板,然后从 ETS 目录中确定性地构建计划。",Close:"关闭","Close menu":"关闭菜单",Command:"命令","Command DPT":"命令 DPT","Command GA":"命令 GA","Command payload":"命令负载",Completed:"已完成","Config exported":"配置导出","Config imported":"配置已导入","Connected {{value}}":"已连接 {{value}}","Coverage {{value}}%":"覆盖率 {{value}}%","Define at least one area before creating a test plan":"在创建测试计划之前至少定义一个区域","Define at least one area before using Tests":"使用测试之前至少定义一个区域","Delete Area":"删除区域","Deleting actuator preset...":"正在删除执行器预设...","Deleting area...":"正在删除区域...","Deleting profile...":"正在删除个人资料...","Deleting test plan...":"正在删除测试计划...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"描述您想要的房间、区域或功能。AI 将为该草案建议最相关的群组地址。",Description:"描述","Disconnected {{value}}":"已断开连接 {{value}}","Documentation: KNX AI Vue":"文档:KNX AI Vue","Donate via PayPal":"通过 PayPal 捐赠","Drag step":"拖步",Duplicate:"复制","Duplicate Plan":"复制计划","Edit Area":"编辑区","Edit Plan":"编辑计划","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"启用 KNX AI 节点中的 AI 来重新生成区域或建议 GA 进行新草稿。","Event distribution will appear after the first samples.":"事件分布将出现在第一个样本之后。","Event Mix":"活动组合","Example: Add all technical room lighting command and status GA.":"示例:添加所有技术室照明命令和状态 GA。",Expected:"预计","Expected feedback value":"期望反馈值","Expected payload":"预期有效负载","Explain any anomalies you see and suggest what to check first.":"解释您看到的任何异常情况并建议首先检查哪些内容。","Export PDF":"导出PDF","Exporting config...":"正在导出配置...",Fail:"失败","Failed to build the test plan":"无法构建测试计划","Failed to delete actuator preset":"删除执行器预设失败","Failed to delete area":"删除区域失败","Failed to delete profile":"删除个人资料失败","Failed to delete test plan":"删除测试计划失败","Failed to delete test result":"删除测试结果失败","Failed to export config":"导出配置失败","Failed to import config":"导入配置失败","Failed to load area command/status catalog":"无法加载区域命令/状态目录","Failed to load GA catalog":"无法加载 GA 目录","Failed to load nodes":"加载节点失败","Failed to load state":"加载状态失败","Failed to regenerate AI areas":"无法重新生成AI区域","Failed to reset area":"重置区域失败","Failed to run actuator test":"无法运行执行器测试","Failed to run profile":"运行配置文件失败","Failed to run test plan":"无法运行测试计划","Failed to save actuator preset":"无法保存执行器预设","Failed to save area":"保存区域失败","Failed to save GA role":"无法保存 GA 角色","Failed to save profile":"保存个人资料失败","Failed to save test plan":"保存测试计划失败","Failed to save test result":"无法保存测试结果","Failed to suggest area GA":"无法建议区域 GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"生成包含计数和标题的顶级组地址的 SVG 条形图。","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"绿色显示连接到 KNX 总线的时间。红色显示所选历史窗口内的停机时间。",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC 主动检查","Importing config...":"正在导入配置...","in progress":"进行中","Installer alias":"安装人员别名","KNX active test name":"KNX 活动测试名称","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"灯亮,然后灭","Live and saved reports generated by KNX active and read-only tests.":"由 KNX 活动和只读测试生成的实时和保存的报告。","Loading nodes...":"正在加载节点...","Loading...":"Loading...","n/a":"n/a","New Area":"新区","New Plan":"新计划","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"没有区域与当前搜索匹配,或者 ETS 文件尚未公开可用的层次结构。","No detailed entries stored for this report yet.":"尚未存储此报告的详细条目。","No feedback":"无反馈","No GA selected for this area yet.":"尚未为此区域选择 GA。","No KNX AI nodes found.":"未找到 KNX AI 节点。","No saved plans yet.":"尚未保存计划。","No saved test results yet.":"尚未保存测试结果。","No test result selected to export":"未选择导出测试结果","No test result selected.":"未选择测试结果。","No top group address data available yet.":"尚无可用的顶级组地址数据。","Nodes {{nodes}} | Links {{links}}":"节点 {{nodes}} |链接 {{links}}",Now:"现在","Open and close shading":"打开和关闭阴影","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"打开和关闭该区域中的遮阳执行器,然后验证状态是否与发送的命令匹配。","Open Source Test":"开源测试","Optional note for diagnostics and reports":"诊断和报告的可选注释","Original ETS path:":"原始 ETS 路径:",Overview:"概述",Pass:"通行证",Payload:"有效载荷","Pick from the ETS catalog. Already selected GA are hidden from this list.":"从 ETS 目录中选择。已选择的 GA 从此列表中隐藏。","Plan changes discarded":"计划变更被放弃","Plan duplicated":"计划重复","Plan name":"计划名称",Plans:"计划","Profile deleted":"个人资料已删除","Profile report ready":"概况报告已准备就绪","Profile saved":"个人资料已保存","Provider: {{provider}} | Model: {{model}}":"提供商:{{provider}} |型号:{{model}}",Rate:"率","Read response timeout ms":"读取响应超时毫秒",Ready:"准备好",Reason:"原因",Refresh:"刷新","Regenerating AI areas...":"再生人工智能领域...",Remove:"删除",Repeat:"重复",Reset:"重置","Resetting area...":"重置区域...","Response timeout":"响应超时","Returned to the Tests page for the source actuator test.":"返回到源执行器测试的测试页面。","Returned to the Tests page for the source read-only profile.":"返回源只读配置文件的测试页面。","Returned to the Tests page.":"返回测试页面。","Reusable deterministic active tests saved by the installer.":"安装程序保存的可重复使用的确定性主动测试。",Role:"角色","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"在该区域中运行 HVAC 命令的完整测试,并验证设定点和状态是否一致。",Running:"跑步","Running actuator test...":"运行执行器测试...","Running profile...":"运行配置文件...","Running...":"Running...","Saving actuator preset...":"正在保存执行器预设...","Saving profile...":"正在保存个人资料...","Saving test plan...":"正在保存测试计划...","Search GA, label or ETS path":"搜索 GA、标签或 ETS 路径","Select an Area":"选择一个区域","Select area":"选择区域","Select command GA":"选择命令 GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"选择标准模板之一。该计划仅根据所选区域中可用的命令 GA 构建。","Select test plan":"选择测试计划","Select Test Result":"选择测试结果","Selected template":"选定的模板","Send a":"发送一个",Settings:"设置","Short operator-facing description":"面向操作员的简短描述","Show AI Area Builder":"显示 AI 区域生成器","Show Template Builder":"显示模板生成器","Spontaneous Write From Status GA":"从状态 GA 自发写入",Status:"状态","Status DPT":"状态 DPT","Status GA":"状态 GA","Status write timeout ms":"状态写入超时毫秒","Step title":"步骤标题","Stopping repeat mode after the current cycle...":"在当前周期后停止重复模式...",Subscribe:"订阅",Suggestions:"建议","Summarize the current KNX traffic and highlight the busiest group addresses.":"总结当前 KNX 流量并突出显示最繁忙的组地址。",Summary:"总结","Targets supported HVAC command GA in the selected area.":"所选区域中支持 HVAC 命令 GA 的目标。","Targets supported shading command GA in the selected area.":"目标在选定区域中支持着色命令 GA。","telegram from the status GA.":"来自状态 GA 的电报。","telegram to the status GA and wait for a":"电报到状态 GA 并等待",Telegrams:"电报","Template Builder":"模板生成器","Test editor closed":"测试编辑器已关闭","Test plan deleted":"测试计划已删除","Test plan ready":"测试计划准备就绪","Test plan saved":"测试计划已保存","Test completed":"测试完成","Repeat mode stopped":"重复模式已停止","Test result deleted":"测试结果已删除","Test Results":"测试结果","Test Running":"试运行",Tests:"测试","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"安装程序可以重命名该区域并准确决定哪些组地址属于该区域。一切都保存在每个 KNX AI 节点上。",Timeout:"超时",Title:"标题","Toggle menu":"切换菜单","Toggle sidebar":"切换侧边栏","Top Group Addresses":"顶级组地址","true, false, 50":"真、假、50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"打开灯,然后关闭它们,并验证相关状态值是否一致。","Unknown DPT":"未知 DPT","Unsaved changes":"未保存的更改",Voice:"语音",Wait:"等等","Wait for a spontaneous":"等待自发的","Wait ms":"等待毫秒",Warn:"警告","What this step checks":"此步骤检查什么","Why this step exists":"为什么存在这一步","Window {{value}}s.":"窗口 {{value}}s。","Write timeout":"写入超时"}},df=(e,t)=>{const i=e.__vccOpts||e;for(const[o,d]of t)i[o]=d;return i},uf={class:"m-header"},cf=["aria-expanded"],ff={class:"app-sidebar"},pf={id:"knx-ai-sidebar",class:"sidebar-brand-wrap"},gf=["aria-expanded"],hf={class:"sidebar-collapse-icon"},mf={class:"sidebar-nav"},vf=["disabled"],bf={key:0,class:"sidebar-panel sidebar-actions"},yf=["disabled"],Af={key:1,class:"sidebar-footer"},Sf={key:0,class:"running-spinner status-pill-spinner","aria-hidden":"true"},wf={key:0,class:"status-detail"},Pf={class:"workspace-shell"},Tf={class:"content-grid workspace-main"},_f={key:0,class:"card card-summary"},Df={class:"card-head"},Nf={key:0,class:"meta-chip"},If={class:"summary-pre"},Rf={class:"metric-grid"},Cf={class:"metric"},kf={class:"metric"},xf={class:"metric"},Ef={class:"metric"},Gf={key:1,class:"card card-areas"},Ff={class:"card-head"},Of={class:"card-head-actions"},Lf={class:"meta-chip"},Mf=["disabled"],Bf={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},zf=["disabled"],$f={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Kf={key:0,class:"planner-error-banner area-regenerate-error"},Vf={class:"areas-toolbar"},Wf={class:"pill-row"},Uf={class:"pill neutral"},jf={class:"pill neutral"},Hf={class:"pill neutral"},Xf={class:"pill neutral"},qf={key:1,class:"areas-layout"},Jf={key:0,class:"area-listbox-shell"},Zf={class:"flow-field"},Yf={class:"area-search-select"},Qf=["placeholder"],ep={key:0,class:"area-search-select-menu"},tp=["onMousedown"],ap={class:"area-editor"},np={key:0,class:"card-head"},sp={class:"card-head-actions action-cluster"},rp=["disabled"],ip=["disabled"],op=["disabled"],lp=["disabled"],dp={key:1,class:"area-editor-grid"},up={class:"flow-field"},cp={class:"flow-field area-editor-span"},fp={class:"flow-field area-editor-span"},pp={key:2,class:"ai-planner-shell area-llm-shell"},gp={key:0,class:"card-head-actions action-cluster"},hp={class:"area-editor-grid"},mp={class:"flow-field area-editor-span"},vp={class:"profile-runbar"},bp=["disabled"],yp={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Ap={key:0,class:"planner-error-banner"},Sp={key:1,class:"area-detail-subhead"},wp={key:3,class:"area-ga-editor"},Pp={key:0,class:"simple-list simple-list-mono area-ga-list"},Tp={class:"area-ga-main"},_p={key:0},Dp={key:0},Np={class:"area-ga-actions"},Ip={class:"flow-field area-ga-role-field"},Rp=["value","disabled","onChange"],Cp=["value"],kp=["onClick"],xp={key:1,class:"empty-state"},Ep={class:"card-head"},Gp={class:"meta-chip"},Fp={class:"area-ga-catalog"},Op=["onClick"],Lp={class:"area-list-title"},Mp={class:"area-list-meta"},Bp={class:"area-list-tags"},zp={key:0},$p={key:4,class:"area-editor-note"},Kp={key:2,class:"empty-state"},Vp={class:"card-head"},Wp={class:"area-detail-subhead"},Up={key:0,class:"card-head-actions"},jp={class:"meta-chip"},Hp={class:"meta-chip"},Xp=["disabled"],qp={key:1,class:"card-head-actions"},Jp={class:"meta-chip"},Zp=["disabled"],Yp={class:"profile-editor-stack"},Qp={key:0,class:"area-detail planner-sidecard"},eg={class:"area-listbox-shell"},tg={class:"flow-field"},ag={class:"area-search-select"},ng=["placeholder"],sg={key:0,class:"area-search-select-menu"},rg=["onMousedown"],ig={key:0,class:"empty-state"},og={key:1,class:"area-detail"},lg={key:0,class:"card-head"},dg={key:0,class:"area-detail-subhead"},ug={class:"card-head-actions action-cluster"},cg={key:0,class:"meta-chip"},fg={class:"checkbox flow-toggle compact-toggle"},pg=["disabled"],gg=["disabled"],hg=["disabled"],mg={key:2,class:"plan-run-actions"},vg=["disabled"],bg=["disabled"],yg={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Ag={key:1,class:"ai-planner-shell"},Sg={key:0,class:"card-head-actions action-cluster"},wg={class:"area-editor-grid"},Pg={class:"flow-field"},Tg=["value"],_g={class:"flow-field area-editor-span"},Dg=["value"],Ng={class:"preset-row compact-preset-row"},Ig=["onClick"],Rg={class:"area-detail-subhead"},Cg={class:"profile-runbar"},kg=["disabled"],xg={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Eg={key:0,class:"planner-error-banner"},Gg={key:1,class:"planner-generation"},Fg={key:0,class:"area-detail-subhead"},Og={key:1,class:"area-detail-subhead"},Lg={key:2,class:"area-detail planner-run-focus"},Mg={class:"card-head"},Bg={class:"area-detail-subhead"},zg={class:"meta-chip"},$g={class:"metric-grid area-metrics"},Kg={class:"metric"},Vg={class:"metric"},Wg={class:"metric"},Ug={class:"metric"},jg={key:0,class:"report-check report-pass planner-step-card planner-step-running"},Hg={class:"anomaly-head"},Xg={class:"area-detail-subhead"},qg={key:0,class:"planner-step-grid"},Jg={key:1,class:"planner-step-grid"},Zg={key:2,class:"planner-check-sections"},Yg={class:"planner-check-section"},Qg={class:"planner-step-grid compact-grid"},eh={class:"planner-check-section"},th={class:"planner-step-grid compact-grid"},ah={class:"card-head"},nh={class:"area-detail-subhead"},sh={class:"card-head-actions action-cluster"},rh={class:"meta-chip"},ih={key:0,class:"meta-chip"},oh={class:"meta-chip"},lh={class:"metric-grid area-metrics"},dh={class:"report-checks"},uh={class:"anomaly-head"},ch={class:"area-detail-subhead"},fh={key:0,class:"planner-check-sections result-check-sections"},ph={class:"planner-step-grid compact-grid"},gh={key:1,class:"planner-step-grid"},hh={key:0,class:"empty-state"},mh={key:1},vh={class:"simple-list"},bh={key:4,class:"area-detail plan-draft-shell"},yh={class:"card-head"},Ah={class:"running-headline"},Sh={key:0,class:"running-spinner","aria-hidden":"true"},wh={class:"card-head-actions action-cluster"},Ph={class:"meta-chip"},Th={class:"area-editor-grid"},_h={class:"flow-field"},Dh=["value","disabled"],Nh=["value"],Ih={class:"flow-field"},Rh={class:"flow-field area-editor-span"},Ch={class:"report-checks plan-steps-stack"},kh=["onDragenter","onDrop"],xh={class:"anomaly-head"},Eh={class:"planner-step-title"},Gh=["onDragstart"],Fh=["aria-expanded","title","onClick"],Oh={class:"card-head-actions action-cluster compact-actions"},Lh=["onClick"],Mh=["onClick"],Bh={key:0,class:"planner-step-summary"},zh={key:0},$h={key:1},Kh={key:2},Vh={key:3},Wh={key:4},Uh={key:5},jh={key:1,class:"planner-step-editor"},Hh={class:"flow-field"},Xh=["onUpdate:modelValue"],qh={class:"flow-field area-editor-span"},Jh=["onUpdate:modelValue"],Zh={key:0,class:"flow-field"},Yh=["onUpdate:modelValue"],Qh={key:1,class:"planner-field-group area-editor-span"},em={class:"planner-field-group-grid"},tm={class:"flow-field"},am=["onUpdate:modelValue","onChange"],nm=["value"],sm={class:"flow-field"},rm=["onUpdate:modelValue","onChange"],im={class:"flow-field group-span"},om=["onUpdate:modelValue"],lm=["value"],dm=["onUpdate:modelValue"],um={key:2,class:"planner-field-group area-editor-span"},cm={class:"planner-field-group-grid"},fm={class:"flow-field group-span"},pm=["onUpdate:modelValue","onChange"],gm=["value"],hm={class:"flow-field"},mm=["onUpdate:modelValue","onChange"],vm={class:"flow-field"},bm=["onUpdate:modelValue"],ym=["value"],Am=["onUpdate:modelValue"],Sm={key:3,class:"planner-check-sections editor-check-sections area-editor-span"},wm={class:"planner-check-section"},Pm={class:"flow-field"},Tm=["onUpdate:modelValue"],_m={class:"planner-check-section"},Dm={class:"flow-field"},Nm=["onUpdate:modelValue"],Im={class:"flow-field area-editor-span"},Rm=["onUpdate:modelValue"],Cm={key:3,class:"card card-profiles"},km={class:"card-head"},xm={class:"card-head-actions"},Em={class:"meta-chip"},Gm={class:"profiles-layout results-page-layout"},Fm={class:"area-detail planner-sidecard"},Om={class:"sidebar-results-list results-page-list"},Lm=["onClick"],Mm={class:"sidebar-result-head"},Bm={class:"sidebar-result-title"},zm={key:0,class:"running-spinner","aria-hidden":"true"},$m={class:"area-list-meta"},Km={key:0},Vm={class:"area-list-tags"},Wm={class:"area-list-tags"},Um=["disabled","onClick"],jm={key:0,class:"empty-state sidebar-empty-state"},Hm={class:"card-head"},Xm={class:"area-detail-subhead"},qm={class:"card-head-actions action-cluster"},Jm={class:"meta-chip"},Zm={key:0,class:"meta-chip"},Ym={class:"meta-chip"},Qm=["disabled"],ev={class:"metric-grid area-metrics"},tv={class:"report-checks"},av={class:"anomaly-head"},nv={class:"area-detail-subhead"},sv={key:0,class:"planner-check-sections result-check-sections"},rv={class:"planner-step-grid compact-grid"},iv={key:1,class:"planner-step-grid"},ov={key:0,class:"empty-state"},lv={key:1},dv={class:"simple-list"},uv={key:1,class:"area-detail"},cv={key:4,class:"card"},fv={class:"card-head"},pv={class:"meta-chip"},gv={key:0,class:"rank-list"},hv={class:"rank-title"},mv={class:"rank-label"},vv={key:1,class:"empty-state"},bv={key:5,class:"card"},yv={class:"card-head"},Av={class:"meta-chip"},Sv={key:0,class:"event-list"},wv={class:"event-name"},Pv={class:"event-bar"},Tv={key:1,class:"empty-state"},_v={key:6,class:"card card-bus"},Dv={class:"card-head"},Nv={key:0,class:"meta-chip"},Iv={class:"pill-row"},Rv={class:"pill success"},Cv={class:"pill danger"},kv={class:"pill neutral"},xv={class:"bus-track"},Ev=["title"],Gv={class:"bus-scale"},Fv={key:1,class:"empty-state"},Ov={class:"card-head"},Lv={class:"card-head-actions"},Mv={class:"meta-chip"},Bv={class:"flow-toolbar"},zv={class:"flow-field"},$v={class:"flow-field flow-field-search"},Kv={class:"flow-field flow-field-select"},Vv=["value"],Wv={class:"checkbox flow-toggle flow-toggle-inline"},Uv={class:"flow-frame"},jv=["viewBox"],Hv=["id"],Xv=["fill"],qv=["d","stroke","stroke-width","opacity","marker-end"],Jv=["cx","cy"],Zv=["x","y"],Yv=["x","y"],Qv=["x","y"],eb=["x","y"],tb={key:1,class:"empty-state flow-empty"},ab={class:"flow-note"},nb={key:8,class:"card card-anomalies"},sb={class:"card-head"},rb={class:"meta-chip"},ib={key:0,class:"anomaly-list"},ob={class:"anomaly-head"},lb={class:"anomaly-time"},db={key:1,class:"empty-state"},ub={key:9,class:"card card-chat"},cb={class:"card-head"},fb={class:"meta-chip"},pb={class:"chat-log"},gb=["innerHTML"],hb={key:1},mb={key:0,class:"chat-message chat-pending"},vb={class:"preset-row"},bb=["disabled","onClick"],yb={class:"ask-row"},Ab=["disabled"],Sb=["disabled"],wb={key:10,class:"card card-flow-builder"},Pb={class:"card-head"},Tb={class:"meta-chip"},_b={class:"flow-builder-split"},Db={class:"flow-builder-pane flow-builder-input"},Nb={class:"flow-builder-compose"},Ib=["disabled"],Rb={class:"flow-builder-actions"},Cb=["disabled"],kb={class:"flow-builder-pane flow-builder-output"},xb={key:0,class:"flow-builder-pending"},Eb={key:1,class:"flow-builder-error"},Gb={key:2,class:"flow-builder-result"},Fb={key:0,class:"flow-builder-notes"},Ob={key:1,class:"flow-builder-warnings"},Lb={class:"flow-builder-result-head"},Mb={class:"meta-chip"},Bb={key:0,class:"meta-chip"},zb={class:"flow-builder-json"},$b={key:3,class:"flow-builder-placeholder"},Kb={key:11,class:"card card-settings"},Vb={class:"settings-tab-strip"},Wb={key:0,class:"area-detail settings-panel"},Ub={class:"settings-node-grid"},jb={class:"flow-field"},Hb=["value"],Xb={class:"checkbox settings-node-checkbox"},qb={key:1,class:"area-detail settings-panel"},Jb={class:"card-head-actions action-cluster settings-config-actions"},Zb=["disabled"],Yb=["disabled"],Qb={key:0,class:"global-wait-overlay",role:"status","aria-live":"polite","aria-busy":"true"},ey={class:"global-wait-card"},ty={class:"area-detail-subhead"},ay={class:"modal-actions"},ny=["disabled"],sy={class:"area-detail-subhead"},ry={class:"modal-actions"},iy=["disabled"],Oi="knxUltimateAI:selectedNodeId",Li="knxUltimateAI:autoRefresh",oy="knxUltimateAI:activeTab",Mi="knxUltimateAI:settingsTab",Bi="knxUltimateAI:flowPreview",zi="knxUltimateAI:voiceEnabled",$i="knxUltimateAI:sidebarExpanded",ly="knxUltimateAI:selectedTestAreaId:",dy="https://supergiovane.github.io/node-red-contrib-knx-ultimate/wiki/knxUltimateAI-vue",uy="https://www.paypal.com/donate/?hosted_button_id=S8SKPUBSPK758",cy="https://www.youtube.com/@maxsupervibe",fy={__name:"App",setup(e){const t=["Summarize the current KNX traffic and highlight the busiest group addresses.","Explain any anomalies you see and suggest what to check first.","Generate an SVG bar chart of Top Group Addresses with counts and title."],i=[{id:"lights_on_off",title:"Lights on, then off",prompt:"Turn the lights on, then turn them off, and verify that the related status values are coherent.",description:"Applies to all matching lighting command GA in the selected area."},{id:"area_activate",title:"Activate main actuators",prompt:"Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.",description:"Builds a deterministic active test using the supported command GA in the selected area."},{id:"shading_open_close",title:"Open and close shading",prompt:"Open and close the shading actuators in the area, then verify that the status matches the commands sent.",description:"Targets supported shading command GA in the selected area."},{id:"hvac_check",title:"HVAC active check",prompt:"Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.",description:"Targets supported HVAC command GA in the selected area."}],o=[{value:"command",label:"Command"},{value:"status",label:"Status"},{value:"neutral",label:"Don't use in tests"}],d={write:"#ff9800",response:"#46b86d",read:"#d99a34",repeat:"#c34747",other:"#8d8578"},u=(()=>{try{return new URLSearchParams(window.location.search).get("nodeId")||""}catch{return""}})(),f=(()=>{try{return new URLSearchParams(window.location.search).get("access_token")||""}catch{return""}})();function p(){try{if(!window.localStorage)return"";const s=[];for(let n=0;n<window.localStorage.length;n+=1){const r=String(window.localStorage.key(n)||"");if(!r.startsWith("auth-tokens"))continue;const c=window.localStorage.getItem(r);if(!c)continue;let g=null;try{g=JSON.parse(c)}catch{g=null}const N=g&&typeof g.access_token=="string"?g.access_token.trim():"";if(!N)continue;const R=Number(g&&(g.expires_at||g.expiry||g.expires)?g.expires_at||g.expiry||g.expires:0);s.push({token:N,expiresAt:Number.isFinite(R)?R:0})}return s.length?(s.sort((n,r)=>r.expiresAt-n.expiresAt),s[0].token||""):""}catch{return""}}const m=(()=>{const s=String(f||"").trim();return s||p()})();function P(s){const n=Object.assign({},s||{});return m&&!n.Authorization&&!n.authorization&&(n.Authorization=`Bearer ${m}`),n}const A=da("en");let I=null,M=0,$=!1;const oe={it:{countAreas:"{{count}} aree",countNodes:"{{count}} nodi",countSavedPlans:"{{count}} piani salvati",countAvailable:"{{count}} disponibili",countVisible:"{{count}} visibili",countEventTypes:"{{count}} tipi di eventi",countRecent:"{{count}} recenti",nodesLinks:"Nodi {{nodes}} | Link {{links}}",connected:"Connesso {{value}}",disconnected:"Disconnesso {{value}}",coverage:"Copertura {{value}}%",windowSec:"Finestra {{value}}s.",anomalyCount:"anomalia x{{value}}",areaLabel:"Area {{value}}",providerModel:"Provider: {{provider}} | Modello: {{model}}"},de:{countAreas:"{{count}} Bereiche",countNodes:"{{count}} Knoten",countSavedPlans:"{{count}} gespeicherte Pläne",countAvailable:"{{count}} verfügbar",countVisible:"{{count}} sichtbar",countEventTypes:"{{count}} Ereignistypen",countRecent:"{{count}} aktuell",nodesLinks:"Knoten {{nodes}} | Verbindungen {{links}}",connected:"Verbunden {{value}}",disconnected:"Getrennt {{value}}",coverage:"Abdeckung {{value}}%",windowSec:"Fenster {{value}}s.",anomalyCount:"Anomalie x{{value}}",areaLabel:"Bereich {{value}}",providerModel:"Anbieter: {{provider}} | Modell: {{model}}"},fr:{countAreas:"{{count}} zones",countNodes:"{{count}} nœuds",countSavedPlans:"{{count}} plans enregistrés",countAvailable:"{{count}} disponibles",countVisible:"{{count}} visibles",countEventTypes:"{{count}} types d'événements",countRecent:"{{count}} récents",nodesLinks:"Nœuds {{nodes}} | Liens {{links}}",connected:"Connecté {{value}}",disconnected:"Déconnecté {{value}}",coverage:"Couverture {{value}}%",windowSec:"Fenêtre {{value}}s.",anomalyCount:"anomalie x{{value}}",areaLabel:"Zone {{value}}",providerModel:"Fournisseur : {{provider}} | Modèle : {{model}}"},es:{countAreas:"{{count}} áreas",countNodes:"{{count}} nodos",countSavedPlans:"{{count}} planes guardados",countAvailable:"{{count}} disponibles",countVisible:"{{count}} visibles",countEventTypes:"{{count}} tipos de eventos",countRecent:"{{count}} recientes",nodesLinks:"Nodos {{nodes}} | Enlaces {{links}}",connected:"Conectado {{value}}",disconnected:"Desconectado {{value}}",coverage:"Cobertura {{value}}%",windowSec:"Ventana {{value}}s.",anomalyCount:"anomalía x{{value}}",areaLabel:"Área {{value}}",providerModel:"Proveedor: {{provider}} | Modelo: {{model}}"},"zh-CN":{countAreas:"{{count}} 个区域",countNodes:"{{count}} 个节点",countSavedPlans:"{{count}} 个已保存计划",countAvailable:"{{count}} 可用",countVisible:"{{count}} 可见",countEventTypes:"{{count}} 种事件类型",countRecent:"{{count}} 条最近记录",nodesLinks:"节点 {{nodes}} | 连线 {{links}}",connected:"已连接 {{value}}",disconnected:"已断开 {{value}}",coverage:"覆盖率 {{value}}%",windowSec:"窗口 {{value}} 秒。",anomalyCount:"异常 x{{value}}",areaLabel:"区域 {{value}}",providerModel:"提供方: {{provider}} | 模型: {{model}}"}},U={en:"en","en-us":"en","en-gb":"en",it:"it","it-it":"it",de:"de","de-de":"de",fr:"fr","fr-fr":"fr",es:"es","es-es":"es",zh:"zh-CN","zh-cn":"zh-CN","zh-hans":"zh-CN","zh-hans-cn":"zh-CN"},Ne=new Set(["KNX AI","KNX Ultimate","GroupValue_Write","GroupValue_Response","GA","DPT","ETS","SVG"]),Pe={it:{"Open Source Test":"Apri Test Sorgente","Asking...":"Sto chiedendo...","Loading...":"Caricamento...","Running...":"In esecuzione...",Running:"In esecuzione","Flow Map":"Mappa Flussi",Anomalies:"Anomalie",Rate:"Frequenza",Pass:"OK",Fail:"Errore",Warn:"Attenzione",Wait:"Attesa","Wait ms":"Attesa (ms)","Response timeout":"Timeout risposta","Read response timeout ms":"Timeout risposta lettura (ms)","Status write timeout ms":"Timeout scrittura stato (ms)","Regenerating...":"Rigenerazione...","Regenerate AI Areas":"Rigenera Aree AI","Deleting...":"Eliminazione...","Delete AI Areas":"Elimina Aree AI","Test Results":"Risultati Test","Select Test Result":"Seleziona risultato test","No test result selected.":"Nessun risultato test selezionato.","Open and close shading":"Apri e chiudi schermature"},de:{"Open Source Test":"Quelltest öffnen","Asking...":"Anfrage läuft...","Loading...":"Wird geladen...","Running...":"Läuft...",Running:"Läuft","Flow Map":"Flusskarte",Anomalies:"Anomalien",Rate:"Rate",Pass:"OK",Fail:"Fehler",Warn:"Warnung",Wait:"Warten","Wait ms":"Warten (ms)","Regenerating...":"Wird neu erstellt...","Regenerate AI Areas":"KI-Bereiche neu erstellen","Deleting...":"Wird gelöscht...","Delete AI Areas":"KI-Bereiche löschen"},fr:{"Open Source Test":"Ouvrir le test source","Asking...":"Interrogation en cours...","Loading...":"Chargement...","Running...":"En cours...",Running:"En cours","Flow Map":"Carte des flux",Anomalies:"Anomalies",Rate:"Débit",Pass:"OK",Fail:"Échec",Warn:"Alerte",Wait:"Attente","Wait ms":"Attente (ms)","Regenerating...":"Régénération...","Regenerate AI Areas":"Régénérer les zones IA","Deleting...":"Suppression...","Delete AI Areas":"Supprimer les zones IA"},es:{"Open Source Test":"Abrir prueba de origen","Asking...":"Consultando...","Loading...":"Cargando...","Running...":"En ejecución...",Running:"En ejecución","Flow Map":"Mapa de flujo",Anomalies:"Anomalías",Rate:"Tasa",Pass:"OK",Fail:"Fallo",Warn:"Aviso",Wait:"Espera","Wait ms":"Espera (ms)","Regenerating...":"Regenerando...","Regenerate AI Areas":"Regenerar áreas de IA","Deleting...":"Eliminando...","Delete AI Areas":"Eliminar áreas de IA"},"zh-CN":{"Open Source Test":"打开源测试","Asking...":"正在提问...","Loading...":"加载中...","Running...":"运行中...",Running:"运行中","Flow Map":"流量拓扑图",Anomalies:"异常",Rate:"速率",Pass:"通过",Fail:"失败",Warn:"警告",Wait:"等待","Wait ms":"等待(毫秒)","Regenerating...":"正在重新生成...","Regenerate AI Areas":"重新生成 AI 区域","Deleting...":"正在删除...","Delete AI Areas":"删除 AI 区域"}};function re(s,n="en"){const r=String(s||"").trim().toLowerCase();if(!r)return n;if(U[r])return U[r];if(r.includes("-")){const c=r.split("-")[0];if(U[c])return U[c]}return n}function ge(){try{const r=new URLSearchParams(window.location.search).get("lang");if(r)return re(r,"en")}catch{}const s=re(String(navigator.language||""),"");if(s)return s;const n=String(document&&document.documentElement&&document.documentElement.lang?document.documentElement.lang:"").trim();return n?re(n,"en"):"en"}function K(s,n={}){return String(s||"").replace(/\{\{\s*([^}\s]+)\s*\}\}/g,(r,c)=>Object.prototype.hasOwnProperty.call(n,c)?String(n[c]):r)}function xe(s){const n=oe[A.value];if(!n)return"";let r=s.match(/^(\d+)\sareas$/i);return r?K(n.countAreas,{count:r[1]}):(r=s.match(/^(\d+)\snodes$/i),r?K(n.countNodes,{count:r[1]}):(r=s.match(/^(\d+)\ssaved plans$/i),r?K(n.countSavedPlans,{count:r[1]}):(r=s.match(/^(\d+)\savailable$/i),r?K(n.countAvailable,{count:r[1]}):(r=s.match(/^(\d+)\svisible$/i),r?K(n.countVisible,{count:r[1]}):(r=s.match(/^(\d+)\sevent types$/i),r?K(n.countEventTypes,{count:r[1]}):(r=s.match(/^(\d+)\srecent$/i),r?K(n.countRecent,{count:r[1]}):(r=s.match(/^Nodes\s+(.+?)\s+\|\s+Links\s+(.+)$/),r?K(n.nodesLinks,{nodes:r[1],links:r[2]}):(r=s.match(/^Connected\s+(.+)$/),r?K(n.connected,{value:r[1]}):(r=s.match(/^Disconnected\s+(.+)$/),r?K(n.disconnected,{value:r[1]}):(r=s.match(/^Coverage\s+(.+?)%$/),r?K(n.coverage,{value:r[1]}):(r=s.match(/^Window\s+(.+?)s\.$/),r?K(n.windowSec,{value:r[1]}):(r=s.match(/^anomaly x(.+)$/i),r?K(n.anomalyCount,{value:r[1]}):(r=s.match(/^Area\s+(.+)$/),r?K(n.areaLabel,{value:r[1]}):(r=s.match(/^Provider:\s+(.+?)\s+\|\s+Model:\s+(.+)$/),r?K(n.providerModel,{provider:r[1],model:r[2]}):""))))))))))))))}function Me(s){const n=String(s||""),r=n.trim();if(!r||A.value==="en"||Ne.has(r))return n;const c=Pe[A.value]||{},g=lf[A.value]||{},N=c[r]||g[r]||xe(r);return!N||N===r?n:n.replace(r,N)}function it(s){const n=s&&s.parentElement;if(!n)return!0;const r=String(n.tagName||"").toUpperCase();return!!(r==="SCRIPT"||r==="STYLE"||r==="CODE"||r==="PRE"||n.closest(".chat-log"))}function vt(s){const n=s||document.body;if(!(!n||A.value==="en")&&!$){$=!0;try{const r=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);let c=r.nextNode();for(;c;){if(!it(c)){const N=Me(c.nodeValue);N!==c.nodeValue&&(c.nodeValue=N)}c=r.nextNode()}const g=n.querySelectorAll("[placeholder], [title], [aria-label]");for(const N of g){const R=N.getAttribute("placeholder");if(R){const Q=Me(R);Q!==R&&N.setAttribute("placeholder",Q)}const B=N.getAttribute("title");if(B){const Q=Me(B);Q!==B&&N.setAttribute("title",Q)}const z=N.getAttribute("aria-label");if(z){const Q=Me(z);Q!==z&&N.setAttribute("aria-label",Q)}}}finally{$=!1}}}function ga(){A.value!=="en"&&(M||(M=window.requestAnimationFrame(()=>{M=0,vt(document.body)})))}function bt(){I&&(I.disconnect(),I=null),M&&(window.cancelAnimationFrame(M),M=0)}function ha(){A.value!=="en"&&(bt(),I=new MutationObserver(()=>{$||ga()}),I.observe(document.body,{childList:!0,subtree:!0,characterData:!0}),ga())}const a=rs({nodes:[],selectedNodeId:"",activeTab:"overview",settingsTab:Xa(Mi,"config"),autoRefresh:xt(Li,!0),voiceEnabled:xt(zi,!0),flowMaxNodes:ta().maxNodes,flowSelectedGa:ta().selectedGa,flowShowUniversalNodes:ta().showUniversalNodes,flowSearch:"",areaSearch:"",areaSearchOpen:!1,areaSelectedId:"",testAreaSelectedId:"",areaDraftName:"",areaDraftDescription:"",areaDraftTags:"",areaDraftGaList:[],areaDraftId:"",areaDraftIsNew:!1,areaLlmPrompt:"",areaLlmBusy:!1,areaLlmError:"",areaLlmRegenerating:!1,areaLlmBulkDeleting:!1,gaCatalog:[],gaCatalogSearch:"",gaCatalogLoading:!1,areaGaRoleSavingGa:"",areaSaving:!1,profileSelectedId:"",profileDraftMode:!1,profileDraftId:"",profileDraftName:"",profileDraftDescription:"",profileDraftTargetTags:"",profileDraftMinActivityPct:20,profileDraftMaxSilentPct:60,profileDraftMaxAnomalies:2,profileSaving:!1,profileRunning:!1,actuatorPresetSelectedId:"",actuatorDraftMode:!1,actuatorDraftId:"",actuatorDraftName:"",actuatorDraftDescription:"",actuatorDraftCommandGA:"",actuatorDraftCommandDPT:"",actuatorDraftCommandPayload:"",actuatorDraftStatusGA:"",actuatorDraftStatusDPT:"",actuatorDraftStatusWriteTimeoutMs:5e3,actuatorDraftStatusResponseTimeoutMs:5e3,actuatorSaving:!1,actuatorRunning:!1,testPlanSelectedId:"",testPlanSearch:"",testPlanSearchOpen:!1,selectedTestResultId:"",liveTestResultId:"",testResultsMenuOpen:!0,testResultFocusMode:!1,deletingTestResultId:"",testPlanPrompt:"",testPlanDraft:null,testPlanCatalog:null,testPlanCatalogLoading:!1,testPlanCatalogError:"",testPlanGenerating:!1,testPlanSaving:!1,testPlanDeleting:!1,testPlanRunning:!1,testPlanGeneration:null,testPlanGenerationError:"",testPlanRunConfirmOpen:!1,testPlanRunMode:"single",testPlanRunningStepId:"",testPlanRepeatForever:!1,testPlanRepeatStopRequested:!1,testPlanDraftBaseline:"",testPlanUnsavedConfirmOpen:!1,areaUnsavedConfirmOpen:!1,testPlanPendingActionLabel:"",draggedTestPlanStepId:"",dragOverTestPlanStepId:"",showAiPlanner:!0,testTemplateBuilderFocus:!1,showAiAreaBuilder:!1,areaBuilderFocus:!1,status:"Ready",loadingNodes:!1,loadingState:!1,asking:!1,stateData:null,lastError:"",chatMessages:[],chatDraft:"",flowBuilderPrompt:"",flowBuilderGenerating:!1,flowBuilderResult:null,flowBuilderError:"",flowBuilderCopied:!1,pollStateHandle:null,pollNodesHandle:null}),ea=da(null),ma=da(!1),Ra=da(null),Ee=da(null),ye=da(xt($i,!0)),ue=da(!1),Be=da(!1),Ze=j(()=>Be.value?ue.value:ye.value);let je=null,Ye=null,Ca=null;function ka(){if(je){try{je.pause(),je.src=""}catch{}je=null}}function Xa(s,n=""){try{return window.localStorage&&window.localStorage.getItem(s)||n}catch{return n}}function xt(s,n){try{if(!window.localStorage)return n;const r=window.localStorage.getItem(s);return r==null||r===""?n:r==="true"}catch{return n}}function ta(){try{if(!window.localStorage)return{maxNodes:14,selectedGa:[],showUniversalNodes:!1};const s=window.localStorage.getItem(Bi);if(!s)return{maxNodes:14,selectedGa:[],showUniversalNodes:!1};const n=JSON.parse(s),r=Math.max(4,Math.min(32,Number(n&&n.maxNodes)||14)),c=Array.isArray(n&&n.selectedGa)?Array.from(new Set(n.selectedGa.map(N=>String(N||"").trim()).filter(Boolean))).slice(0,80):[],g=n&&n.showUniversalNodes===!0;return{maxNodes:r,selectedGa:c,showUniversalNodes:g}}catch{return{maxNodes:14,selectedGa:[],showUniversalNodes:!1}}}function aa(s,n){try{window.localStorage&&window.localStorage.setItem(s,String(n??""))}catch{}}function xa(s,n){try{window.localStorage&&window.localStorage.setItem(s,n?"true":"false")}catch{}}function Et(){try{Be.value=window.matchMedia("(max-width: 1100px)").matches}catch{Be.value=window.innerWidth<=1100}Be.value||(ue.value=!1)}function fs(){if(Be.value){ue.value=ue.value!==!0;return}ye.value=ye.value!==!0}function h(){Be.value&&(ue.value=!1)}function y(s){!s||s.key!=="Escape"||h()}function _(s){const n=String(s||"").trim();return n?`${ly}${n}`:""}function x(s){const n=_(s);return n?Xa(n,""):""}function k(s,n){const r=_(s);if(!r)return;const c=String(n||"").trim();c&&aa(r,c)}function C(){const s=x(a.selectedNodeId);return!s||!Ae.value.find(n=>n.id===s)?!1:(a.testAreaSelectedId===s||(a.testAreaSelectedId=s),!0)}function L(){try{if(!window.localStorage)return;window.localStorage.setItem(Bi,JSON.stringify({maxNodes:Math.max(4,Math.min(32,Number(a.flowMaxNodes)||14)),selectedGa:Array.from(new Set((a.flowSelectedGa||[]).map(s=>String(s||"").trim()).filter(Boolean))).slice(0,80),showUniversalNodes:a.flowShowUniversalNodes===!0}))}catch{}}async function O(){const s=ea.value;if(!(!s||typeof s.requestFullscreen!="function"))try{document.fullscreenElement===s?await document.exitFullscreen():document.fullscreenElement||await s.requestFullscreen()}catch{}}function F(){ma.value=document.fullscreenElement===ea.value}function D(s){const n=new URL(s,window.location.href);return f&&n.searchParams.set("access_token",f),n.toString()}function T(s){a.status=Me(String(s||""))}async function E(s,n){const r=Object.assign({credentials:"same-origin"},n||{});r.headers=P(r.headers);const c=await fetch(s,r),g=String(c.headers.get("content-type")||"").toLowerCase(),N=await c.text();if(c.ok&&g.includes("text/html"))throw new Error("Authentication required or insufficient permissions (session token missing or expired).");let R={};try{R=N?JSON.parse(N):{}}catch{R={error:N||`HTTP ${c.status}`}}if(!c.ok){const B=R&&R.error?R.error:`HTTP ${c.status}`;throw c.status===401||c.status===403?new Error(`Authentication required or insufficient permissions (${c.status}).`):new Error(B)}return R}async function W(s,n){const r=Object.assign({credentials:"same-origin",cache:"no-store"},n||{});r.headers=P(r.headers);const c=await fetch(s,r);if(!c.ok){const N=await c.text();let R=N||`HTTP ${c.status}`;try{const B=N?JSON.parse(N):{};R=B&&B.error?B.error:R}catch{}throw c.status===401||c.status===403?new Error(`Authentication required or insufficient permissions (${c.status}).`):new Error(R)}const g=String(c.headers.get("content-type")||"").toLowerCase();if(!g.includes("audio/")){const N=await c.text();if(g.includes("text/html"))throw new Error("Authentication required or insufficient permissions (invalid audio response).");let R=N||`Unexpected audio response (${g||"unknown"}).`;try{const B=N?JSON.parse(N):{};R=B&&B.error?B.error:R}catch{}throw new Error(R)}return await c.blob()}function H(s){if(s==null)return"";if(typeof s=="string")return s;try{return JSON.stringify(s,null,2)}catch{return String(s)}}function ie(s){return String(s||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function be(s){const n=String(s||"").trim();return n.includes("-")&&/^\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(n)}function ce(s){let n=String(s||"").trim();return n.startsWith("|")&&(n=n.slice(1)),n.endsWith("|")&&(n=n.slice(0,-1)),n.split("|").map(r=>String(r||"").trim())}function Ie(s){return ce(s).map(n=>{const r=String(n||"").trim(),c=r.startsWith(":"),g=r.endsWith(":");return c&&g?"center":g?"right":"left"})}function Oe(s){const n=String(s||"").split(/\r?\n/);let r="",c=!1;const g=N=>{let R=String(N||"");return R=R.replace(/`([^`]+)`/g,"<code>$1</code>"),R=R.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),R=R.replace(/\*([^*]+)\*/g,"<em>$1</em>"),R=R.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(B,z,Q)=>`<a href="${/^javascript:/i.test(String(Q||"").trim())?"#":Q}" target="_blank" rel="noopener noreferrer">${z}</a>`),R};for(let N=0;N<n.length;N++){const R=n[N];if(/^```/.test(R.trim())){c=!c,r+=c?"<pre><code>":"</code></pre>";continue}if(c){r+=`${R}
3
- `;continue}if(/^###\s+/.test(R)){r+=`<h3>${R.replace(/^###\s+/,"")}</h3>`;continue}if(/^##\s+/.test(R)){r+=`<h2>${R.replace(/^##\s+/,"")}</h2>`;continue}if(/^#\s+/.test(R)){r+=`<h1>${R.replace(/^#\s+/,"")}</h1>`;continue}if(R.includes("|")&&N+1<n.length&&be(n[N+1])){const Q=ce(R),q=Ie(n[N+1]),pe=[];for(N+=2;N<n.length&&n[N]&&n[N].includes("|")&&!/^```/.test(n[N].trim());)pe.push(ce(n[N])),N++;N-=1;const Z=Math.max(Q.length,q.length,...pe.map(Y=>Y.length),0);r+='<div class="chat-table-wrap"><table><thead><tr>';for(let Y=0;Y<Z;Y++)r+=`<th style="text-align:${q[Y]||"left"};">${g(Q[Y]||"")}</th>`;r+="</tr></thead><tbody>",pe.forEach(Y=>{r+="<tr>";for(let ee=0;ee<Z;ee++)r+=`<td style="text-align:${q[ee]||"left"};">${g(Y[ee]||"")}</td>`;r+="</tr>"}),r+="</tbody></table></div>";continue}const B=/^\s*[-*]\s+/.test(R),z=/^\s*\d+\.\s+/.test(R);if(B||z){const Q=z?"ol":"ul",q=z?/^\s*\d+\.\s+/:/^\s*[-*]\s+/;for(r+=`<${Q}>`;N<n.length&&q.test(n[N]);)r+=`<li>${g(n[N].replace(q,""))}</li>`,N++;N-=1,r+=`</${Q}>`;continue}if(R.trim()===""){r+="<br>";continue}r+=`<p>${g(R)}</p>`}return c&&(r+="</code></pre>"),r}function at(s){return String(s||"").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&amp;/gi,"&")}function Qe(s){const n=[],r=/<svg[\s\S]*?<\/svg>/gi;let c;for(;(c=r.exec(String(s||"")))!==null;)c&&c[0]&&n.push(String(c[0]));return n}const va=new Set(["svg","g","path","line","polyline","polygon","circle","ellipse","rect","text","tspan","title","desc","defs","marker","lineargradient","radialgradient","stop","clippath"]),Tn=new Set(["xmlns","xmlns:xlink","viewbox","preserveaspectratio","width","height","role","aria-label","id","class","x","y","x1","y1","x2","y2","cx","cy","r","rx","ry","d","points","transform","fill","fill-opacity","stroke","stroke-width","stroke-opacity","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-size","font-family","font-weight","text-anchor","dominant-baseline","offset","stop-color","stop-opacity","gradientunits","gradienttransform","fx","fy","marker-start","marker-mid","marker-end","markerwidth","markerheight","refx","refy","orient","markerunits","href","xlink:href","clip-path","clippathunits"]);function ze(s){try{const r=new window.DOMParser().parseFromString(String(s||""),"image/svg+xml");if(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)return"";const c=r.documentElement;if(String(c.tagName||"").toLowerCase()!=="svg")return"";const g=R=>{const B=String(R.tagName||"").toLowerCase();if(!va.has(B)){R.remove();return}Array.from(R.attributes||[]).forEach(z=>{const Q=String(z.name||"").toLowerCase(),q=String(z.value||"");if(Q.startsWith("on")||!Tn.has(Q)){R.removeAttribute(z.name);return}(Q==="href"||Q==="xlink:href")&&q&&!String(q).trim().startsWith("#")&&R.removeAttribute(z.name)}),Array.from(R.childNodes||[]).forEach(z=>{z.nodeType===1?g(z):z.nodeType!==3&&z.remove()})};g(c),!c.getAttribute("viewBox")&&!c.getAttribute("viewbox")&&c.setAttribute("viewBox","0 0 920 360"),c.setAttribute("role",c.getAttribute("role")||"img");const N=new window.XMLSerializer().serializeToString(c);return N.length>12e4?"":N}catch{return""}}function Ke(s){return Oe(ie(s||""))}function _n(s){const n=H(s),r=n.trim();if(!r)return Ke("(empty answer)");const c=/```(?:svg|xml|html)?\s*([\s\S]*?)```/gi;let g="",N=0,R=!1,B;for(;(B=c.exec(n))!==null;){const Q=n.slice(N,B.index);Q.trim()&&(g+=Ke(Q));const q=String(B[1]||""),pe=at(q),Z=Qe(pe);if(Z.length){let Y=0;Z.forEach(ee=>{const he=ze(ee);he&&(Y++,R=!0,g+=`<div class="chat-svg-wrap">${he}</div>`)}),Y||(g+=`<pre><code>${ie(q)}</code></pre>`)}else{const Y=ze(pe);Y?(R=!0,g+=`<div class="chat-svg-wrap">${Y}</div>`):g+=`<pre><code>${ie(q)}</code></pre>`}N=B.index+B[0].length}const z=n.slice(N);if(z.trim()&&(g+=Ke(z)),!R){const Q=at(n),q=Array.from(new Set([...Qe(n),...Qe(Q)])).map(pe=>ze(pe)).filter(Boolean);if(q.length){const pe=n.replace(/<svg[\s\S]*?<\/svg>/gi,"").replace(/&lt;svg[\s\S]*?&lt;\/svg&gt;/gi,"").trim();g=pe?Ke(pe):"",q.forEach(Z=>{g+=`<div class="chat-svg-wrap">${Z}</div>`})}}return g||Ke(r)}function Ea(s){const n=Math.max(0,Math.round(Number(s)||0)),r=Math.floor(n/3600),c=Math.floor(n%3600/60),g=n%60;return r?`${r}h ${c}m`:c?`${c}m ${g}s`:`${g}s`}function Dn(s){if(!s)return"n/a";try{return new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return"n/a"}}function Gt(s){if(!s)return"";try{return new Date(s).toLocaleString()}catch{return String(s)}}function Nn(s){return s&&s.payload&&typeof s.payload=="object"?s.payload:{}}function Sr(s){return s==null?"":String(s).trim()}function Ft(s,n=null){try{return JSON.parse(JSON.stringify(s))}catch{return n}}function ps(s=[]){return Array.from(new Set((Array.isArray(s)?s:[]).map(n=>String(n||"").trim()).filter(Boolean))).sort()}function Zo(s=""){return ps(String(s||"").split(","))}function gs(s={}){return JSON.stringify({isNew:s.isNew===!0,areaId:String(s.areaId||"").trim(),name:String(s.name||"").trim(),description:String(s.description||"").trim(),tags:ps(s.tags||[]),gaList:ps(s.gaList||[]),llmPrompt:String(s.llmPrompt||"").trim()})}function wr(s={}){return JSON.stringify({prompt:String(s.prompt||""),draft:Ft(s.draft,null)})}function Yo(){return{selectedId:String(a.testPlanSelectedId||""),prompt:String(a.testPlanPrompt||""),draft:Ft(a.testPlanDraft,null),generation:Ft(a.testPlanGeneration,null),showAiPlanner:a.showAiPlanner===!0}}function Ga(){Ye=Yo(),a.testPlanDraftBaseline=wr(Ye)}function Qo(){const s=Ft(Ye,null);if(!s){a.testPlanSelectedId="",a.testPlanPrompt="",a.testPlanDraft=null,a.testPlanGeneration=null,a.testPlanRunConfirmOpen=!1,a.showAiPlanner=!0;return}a.testPlanSelectedId=String(s.selectedId||""),a.testPlanPrompt=String(s.prompt||""),a.testPlanDraft=Ft(s.draft,null),a.testPlanGeneration=Ft(s.generation,null),a.testPlanRunConfirmOpen=!1,a.showAiPlanner=s.showAiPlanner!==!1,s.draft&&s.draft.areaId&&Ae.value.find(n=>n.id===s.draft.areaId)&&(a.areaSelectedId=s.draft.areaId)}function el(s){const n=String(s||"").trim();return n.length>14?`${n.slice(0,12)}..`:n}function tl(s){const n=String(s||"").trim();return n?n.length>28?`${n.slice(0,26)}..`:n:""}function al(s){const n=Sr(s).replace(/\s+/g," ");return n?n.length>30?`${n.slice(0,28)}..`:n:""}function nl(s){const n=String(s||"").toLowerCase();return n.includes("repeat")?"repeat":n.includes("write")?"write":n.includes("response")?"response":n.includes("read")?"read":"other"}function sl(s){const n={write:0,response:0,read:0,repeat:0,other:0};return Object.keys(s||{}).forEach(r=>{const c=Number(s[r]||0);c<=0||(n[nl(r)]+=c)}),Object.keys(n).sort((r,c)=>n[c]-n[r])[0]||"other"}function hs(s){return!!(s&&s.kind==="node"&&s.listenAllGA)}function rl(s){const n=s&&s.summary?s.summary:{},r=Array.isArray(s&&s.anomalies)?s.anomalies:[],c=Array.isArray(n.patternTransitions)?n.patternTransitions:[],g=Array.isArray(n.patterns)?n.patterns:[],N=n&&typeof n.gaLabels=="object"?n.gaLabels:{},R=n&&typeof n.gaLastPayload=="object"?n.gaLastPayload:{},B=n&&typeof n.gaLastSeenAt=="object"?n.gaLastSeenAt:{},z=new Set((Array.isArray(n.flowKnownGAs)?n.flowKnownGAs:[]).map(w=>String(w||"").trim()).filter(Boolean)),Q={};r.forEach(w=>{const V=String(w&&w.payload&&w.payload.ga?w.payload.ga:"BUS").trim()||"BUS";Q[V]=(Q[V]||0)+1});const q=n&&n.flowMapTopology&&typeof n.flowMapTopology=="object"?n.flowMapTopology:null,pe=Array.isArray(q&&q.nodes)?q.nodes:[],Z=Array.isArray(q&&q.edges)?q.edges:[],Y=new Map,ee=w=>{const V=String(w&&w.from?w.from:"").trim(),ae=String(w&&w.to?w.to:"").trim();if(!V||!ae||V===ae)return;const Le=`${V}->${ae}`,He={key:Le,from:V,to:ae,weight:Math.max(1,Number(w&&(w.weight??w.currentWindowCount??w.totalCount??w.count)||1)),delta:Number(w&&w.delta?w.delta:0),edgeByEvent:w&&typeof w.edgeByEvent=="object"?w.edgeByEvent:{},lastAtMs:(()=>{const st=Number(w&&w.lastAtMs?w.lastAtMs:0);if(Number.isFinite(st)&&st>0)return st;const la=new Date(String(w&&w.lastAt?w.lastAt:"")).getTime();return Number.isFinite(la)?la:0})(),linkType:String(w&&w.linkType?w.linkType:"").trim()};if(!Y.has(Le)){Y.set(Le,He);return}const et=Y.get(Le);et.weight+=He.weight,et.delta+=He.delta,et.lastAtMs=Math.max(Number(et.lastAtMs||0),Number(He.lastAtMs||0)),Object.keys(He.edgeByEvent||{}).forEach(st=>{et.edgeByEvent[st]=Number(et.edgeByEvent[st]||0)+Number(He.edgeByEvent[st]||0)})};Z.length?Z.forEach(ee):c.length?c.forEach(ee):g.forEach(w=>ee({from:w&&w.from,to:w&&w.to,count:w&&w.count,edgeByEvent:{}}));const he=new Map,oa=(w,V={})=>{const ae=String(w||"").trim();return ae?(he.has(ae)||he.set(ae,{id:ae,displayId:String(V.displayId||ae).trim()||ae,kind:String(V.kind||(ae.startsWith("N:")?"node":"ga")).trim()||"ga",subtitle:String(V.subtitle||"").trim(),payload:Sr(V.payload),anomalyCount:Number(V.anomalyCount||Q[ae]||0),inFlow:V.inFlow!==void 0?!!V.inFlow:z.size?z.has(ae)||ae==="BUS"||ae.startsWith("N:"):!0,lastSeenAtMs:Number(V.lastSeenAtMs||0),score:Number(V.score||0),listenAllGA:V.listenAllGA===!0}),he.get(ae)):null};return pe.forEach(w=>{const V=String(w&&w.id?w.id:"").trim();V&&oa(V,{displayId:w&&w.displayId,kind:w&&w.kind,subtitle:w&&w.subtitle?w.subtitle:N[V],payload:w&&w.payload!==void 0?w.payload:R[V],anomalyCount:Number(w&&w.anomalyCount?w.anomalyCount:Q[V]||0),inFlow:w&&w.inFlow!==void 0?!!w.inFlow:void 0,lastSeenAtMs:Number(w&&w.lastSeenAtMs?w.lastSeenAtMs:new Date(String(w&&w.lastAt?w.lastAt:B[V]||"")).getTime()||0),score:Number(w&&w.score?w.score:0),listenAllGA:w&&w.listenAllGA===!0})}),Array.from(Y.values()).forEach(w=>{oa(w.from,{subtitle:N[w.from],payload:R[w.from],lastSeenAtMs:new Date(String(B[w.from]||"")).getTime()||w.lastAtMs||0}),oa(w.to,{subtitle:N[w.to],payload:R[w.to],lastSeenAtMs:new Date(String(B[w.to]||"")).getTime()||w.lastAtMs||0});const V=he.get(w.from),ae=he.get(w.to);V&&(V.score+=Number(w.weight||0)),ae&&(ae.score+=Number(w.weight||0))}),(Array.isArray(n.topGAs)?n.topGAs:[]).slice(0,12).forEach(w=>{const V=String(w&&w.ga?w.ga:"").trim();if(!V)return;const ae=oa(V,{subtitle:w&&w.label?w.label:N[V],payload:R[V],lastSeenAtMs:new Date(String(B[V]||"")).getTime()||0});ae&&(ae.score+=Number(w&&w.count?w.count:0))}),{nodes:Array.from(he.values()),edges:Array.from(Y.values()).sort((w,V)=>Number(V.weight||0)-Number(w.weight||0)).slice(0,48),telemetryWindowSec:Number(n&&n.graph&&n.graph.windowSec?n.graph.windowSec:n?.meta?.analysisWindowSec||0)}}function il(s){let n=Array.isArray(s&&s.nodes)?s.nodes.slice():[];const r=Array.isArray(s&&s.edges)?s.edges.slice():[];a.flowShowUniversalNodes!==!0&&(n=n.filter(w=>!hs(w)));const c=new Set(n.map(w=>w.id)),g=new Set((a.flowSelectedGa||[]).map(w=>String(w||"").trim()).filter(w=>w&&c.has(w))),N=Math.max(4,Math.min(32,Number(a.flowMaxNodes)||14));let R=n.slice().sort((w,V)=>{const ae=Number(w.anomalyCount||0)*10+Number(w.score||0),Le=Number(V.anomalyCount||0)*10+Number(V.score||0);return Le!==ae?Le-ae:String(w.id||"").localeCompare(String(V.id||""))});if(g.size){const w=new Set(g);r.forEach(V=>{g.has(V.from)&&w.add(V.to),g.has(V.to)&&w.add(V.from)}),R=R.filter(V=>w.has(V.id))}else R=R.slice(0,N);const B=new Set(R.map(w=>w.id)),z=r.filter(w=>B.has(w.from)&&B.has(w.to)),Q=Math.max(...z.map(w=>Number(w.weight||0)),1),q=Math.max(2,Math.min(6,Math.ceil(Math.sqrt(Math.max(R.length,4)*1.5)))),pe=Math.max(1,Math.ceil(R.length/q)),Z=1080,Y=Math.max(420,140+(pe-1)*150),ee=new Map;R.forEach((w,V)=>{const ae=Math.floor(V/q),Le=V%q,He=q===1?Z/2:90+Le*((Z-180)/Math.max(q-1,1)),et=92+ae*148;ee.set(w.id,{x:He,y:et,row:ae,col:Le})});const he=Date.now(),oa=z.map((w,V)=>{const ae=ee.get(w.from),Le=ee.get(w.to);if(!ae||!Le)return null;const He=Le.x-ae.x,et=Le.y-ae.y,st=Math.max(Math.hypot(He,et),1),la=He/st,Oa=et/st,_e=24,wt=ae.x+la*(_e+2),zt=ae.y+Oa*(_e+2),$t=Le.x-la*(_e+8),Kt=Le.y-Oa*(_e+8),Fn=-Oa,On=la,en=28+V%3*14,Ln=V%2===0?1:-1,Os=(wt+$t)/2+Fn*en*Ln,xd=(zt+Kt)/2+On*en*Ln,ti=sl(w.edgeByEvent),ai=Number(w.lastAtMs||0)>0&&he-Number(w.lastAtMs||0)<=5e3;return{key:w.key,from:w.from,to:w.to,d:`M ${wt} ${zt} Q ${Os} ${xd} ${$t} ${Kt}`,width:(.9+Number(w.weight||0)/Q*1.7).toFixed(2),color:d[ti]||d.other,opacity:ai?.82:.24,markerId:`flow-arrow-${ti}`,tooltip:`${w.from} -> ${w.to} | traffic: ${Number(w.weight||0)}${w.delta?` | delta: ${w.delta>0?"+":""}${w.delta}`:""}`,active:ai}}).filter(Boolean);return{width:Z,height:Y,telemetryWindowSec:Number(s&&s.telemetryWindowSec?s.telemetryWindowSec:0),nodes:R.map(w=>{const V=ee.get(w.id),ae=Number(w.lastSeenAtMs||0);return Object.assign({},w,V,{shortLabel:el(w.displayId||w.id),shortSubtitle:tl(w.subtitle),shortPayload:al(w.payload),isIdle:ae>0&&he-ae>45e3})}),edges:oa,maxNodes:N,selectedCount:g.size}}const In=j(()=>a.nodes.find(s=>s.id===a.selectedNodeId)||null),Ge=j(()=>a.stateData&&a.stateData.summary?a.stateData.summary:{}),ct=j(()=>a.stateData&&a.stateData.node?a.stateData.node:{}),ba=j(()=>a.stateData&&a.stateData.areas?a.stateData.areas:{suggested:[],totals:{}}),Ae=j(()=>Array.isArray(ba.value&&ba.value.suggested)?ba.value.suggested:[]),ol=j(()=>Ae.value.filter(s=>String(s&&s.id?s.id:"").startsWith("llm:"))),Pr=j(()=>Number(ol.value.length||0)),qa=j(()=>ba.value&&ba.value.totals?ba.value.totals:{}),ya=j(()=>Array.isArray(a.stateData&&a.stateData.profiles)?a.stateData.profiles:[]),ll=j(()=>a.stateData&&a.stateData.profileReport?a.stateData.profileReport:null),Aa=j(()=>Array.isArray(a.stateData&&a.stateData.actuatorTests)?a.stateData.actuatorTests:[]),dl=j(()=>a.stateData&&a.stateData.actuatorTestReport?a.stateData.actuatorTestReport:null),yt=j(()=>Array.isArray(a.stateData&&a.stateData.testPlans)?a.stateData.testPlans:[]),Tr=j(()=>{const s=String(a.testPlanSearch||"").trim().toLowerCase();return yt.value.filter(n=>s?[n.name,n.description,n.areaName,n.areaId].filter(Boolean).join(" ").toLowerCase().includes(s):!0)}),ft=j(()=>a.stateData&&a.stateData.testPlanReport?a.stateData.testPlanReport:null),Ja=j(()=>Array.isArray(a.stateData&&a.stateData.testResults)?a.stateData.testResults:[]),_r=j(()=>!a.liveTestResultId||!ft.value||ft.value.id!==a.liveTestResultId?null:Object.assign({},ft.value,{live:a.testPlanRunning===!0})),na=j(()=>{const s=[],n=new Set,r=(c,g=!1)=>{if(!c||typeof c!="object"||!c.id)return;const N=String(c.id);n.has(N)||(n.add(N),s.push(Object.assign({},c,{live:g})))};return r(_r.value,!0),Ja.value.forEach(c=>r(c,!1)),s}),ne=j(()=>{if(a.selectedTestResultId){const s=na.value.find(n=>n&&n.id===a.selectedTestResultId);if(s)return s}return _r.value||Ja.value[0]||null}),At=j(()=>a.activeTab==="tests"&&a.testResultFocusMode===!0&&!!ne.value),ul=j(()=>t.map(s=>{const n=String(s||"").trim(),r=String(Me(n)||"").trim();return{key:n,text:r||n}})),ms=j(()=>{const s=String(a.areaSearch||"").trim().toLowerCase();return Ae.value.filter(n=>s?[n.path,n.name,n.parentName,...Array.isArray(n.tags)?n.tags:[],...Array.isArray(n.sampleLabels)?n.sampleLabels:[]].filter(Boolean).join(" ").toLowerCase().includes(s):!0)}),Fe=j(()=>{if(a.areaDraftIsNew===!0&&!String(a.areaSelectedId||"").trim())return null;if(a.areaSelectedId){const s=Ae.value.find(n=>n.id===a.areaSelectedId);if(s)return s}return null}),ot=j(()=>{if(a.testAreaSelectedId){const s=Ae.value.find(n=>n.id===a.testAreaSelectedId);if(s)return s}return Ae.value[0]||null}),Ot=j(()=>{const s=String(a.testPlanDraft&&a.testPlanDraft.areaId?a.testPlanDraft.areaId:"").trim();if(s){const n=Ae.value.find(r=>r.id===s);if(n)return n}return ot.value}),Dr=j(()=>{const s=String(a.gaCatalogSearch||"").trim().toLowerCase(),n=new Set((a.areaDraftGaList||[]).map(r=>String(r||"").trim()).filter(Boolean));return(Array.isArray(a.gaCatalog)?a.gaCatalog:[]).filter(r=>!r||!r.ga||n.has(r.ga)?!1:s?[r.ga,r.label,r.hierarchyPath,...Array.isArray(r.tags)?r.tags:[]].filter(Boolean).join(" ").toLowerCase().includes(s):!0).slice(0,80)}),Nr=j(()=>{const s=new Map((Array.isArray(a.gaCatalog)?a.gaCatalog:[]).map(n=>[String(n&&n.ga?n.ga:"").trim(),n]));return(a.areaDraftGaList||[]).map(n=>s.get(String(n||"").trim())||{ga:String(n||"").trim(),label:"",dpt:"",hierarchyPath:"",tags:[]})}),vs=j(()=>Array.isArray(a.testPlanCatalog&&a.testPlanCatalog.commandSignals)?a.testPlanCatalog.commandSignals:[]),Ir=j(()=>Array.isArray(a.testPlanCatalog&&a.testPlanCatalog.statusSignals)?a.testPlanCatalog.statusSignals:[]),St=j(()=>{if(a.profileDraftMode===!0)return null;if(a.profileSelectedId){const s=ya.value.find(n=>n.id===a.profileSelectedId);if(s)return s}return ya.value[0]||null}),lt=j(()=>{if(a.actuatorDraftMode===!0)return null;if(a.actuatorPresetSelectedId){const s=Aa.value.find(n=>n.id===a.actuatorPresetSelectedId);if(s)return s}return Aa.value[0]||null}),sa=j(()=>a.testPlanSelectedId&&yt.value.find(s=>s.id===a.testPlanSelectedId)||null),Re=j(()=>!a.testPlanRunningStepId||!a.testPlanDraft||!Array.isArray(a.testPlanDraft.steps)?null:a.testPlanDraft.steps.find(s=>String(s&&s.id?s.id:"")===a.testPlanRunningStepId)||null),cl=j(()=>!!(a.testPlanDraft&&Array.isArray(a.testPlanDraft.steps)&&a.testPlanDraft.steps.length>0)),bs=j(()=>a.showAiPlanner===!0),Rr=j(()=>a.showAiAreaBuilder===!0),Cr=j(()=>a.testPlanDraft?wr({prompt:a.testPlanPrompt,draft:a.testPlanDraft})!==a.testPlanDraftBaseline:!1),fl=j(()=>{if(!(a.areaDraftIsNew===!0||!!Fe.value))return!1;const n=gs({isNew:a.areaDraftIsNew===!0,areaId:String(a.areaDraftId||a.areaSelectedId||"").trim(),name:a.areaDraftName,description:a.areaDraftDescription,tags:Zo(a.areaDraftTags),gaList:a.areaDraftGaList||[],llmPrompt:a.areaLlmPrompt});if(a.areaDraftIsNew===!0){const g=gs({isNew:!0,areaId:"",name:"New Area",description:"",tags:[],gaList:[],llmPrompt:""});return n!==g}const r=Fe.value;if(!r)return!1;const c=gs({isNew:!1,areaId:String(r.id||"").trim(),name:String(r.name||""),description:String(r.customDescription||""),tags:Array.isArray(r.tags)?r.tags:[],gaList:Array.isArray(r.gaList)?r.gaList:[],llmPrompt:""});return n!==c}),ys=j(()=>Array.isArray(a.stateData&&a.stateData.anomalies)?a.stateData.anomalies.slice().reverse():[]),As=j(()=>{const s=Array.isArray(Ge.value.topGAs)?Ge.value.topGAs:[],n=Ge.value&&typeof Ge.value.gaLabels=="object"?Ge.value.gaLabels:{};return s.slice(0,10).map(r=>{const c=r&&typeof r=="object"?r:{},g=String(c.ga||"").trim(),N=String(c.label||"").trim(),R=g?String(n[g]||"").trim():"";return Object.assign({},c,{ga:g,label:N||R})})}),Rn=j(()=>{const s=Ge.value&&Ge.value.byEvent&&typeof Ge.value.byEvent=="object"?Ge.value.byEvent:{};return Object.keys(s).map(n=>({name:n,count:Number(s[n]||0)})).filter(n=>n.count>0).sort((n,r)=>r.count-n.count)}),pl=j(()=>Math.max(...Rn.value.map(s=>s.count),1)),Ss=j(()=>rl(a.stateData)),ra=j(()=>il(Ss.value)),gl=j(()=>{const s=String(a.flowSearch||"").trim().toLowerCase();return Ss.value.nodes.slice().filter(n=>a.flowShowUniversalNodes===!0||!hs(n)).sort((n,r)=>String(n.id||"").localeCompare(String(r.id||""))).filter(n=>s?`${n.id} ${n.subtitle||""}`.toLowerCase().includes(s):!0).slice(0,120)}),nt=j(()=>Ge.value&&Ge.value.busConnection&&typeof Ge.value.busConnection=="object"?Ge.value.busConnection:null),hl=j(()=>{const s=Ge.value||{};if(!Object.keys(s).length)return"No data available.";const n=s.counters||{},r=[];return r.push(ct.value.name||In.value?.name||"KNX AI"),r.push(`Analysis window: ${Number(s.meta?.analysisWindowSec||0)}s`),r.push(`Telegrams: ${Number(n.telegrams||0)} | Rate: ${Number(n.overallRatePerSec||0)}/s`),r.push(`Echoed: ${Number(n.echoed||0)} | Repeat: ${Number(n.repeated||0)} | Unknown DPT: ${Number(n.unknownDpt||0)}`),nt.value&&r.push(`Bus: ${String(nt.value.currentState||"unknown")} | Connected: ${Number(nt.value.connectedPct||0)}% | Disconnected: ${Number(nt.value.disconnectedPct||0)}%`),r.join(`
4
- `)}),ml=j(()=>{const s=nt.value;return!s||!Array.isArray(s.segments)?[]:s.segments.map((n,r)=>{const c=Math.max(0,Math.min(1,Number(n&&n.ratioStart)||0)),g=Math.max(0,Math.min(1,Number(n&&n.ratioWidth)||0));return{key:`${r}-${n?.startedAt||""}`,left:`${(c*100).toFixed(3)}%`,width:`${Math.max(g*100,.4).toFixed(3)}%`,title:`${n?.state==="connected"?"Connected":"Disconnected"} | ${Dn(n?.startedAt)} -> ${Dn(n?.endedAt)} | ${Ea(n?.durationSec||0)}`,className:n?.state==="connected"?"segment-connected":"segment-disconnected"}}).filter(n=>Number.parseFloat(n.width)>0)}),vl=j(()=>a.chatMessages.map((s,n)=>({key:`${n}-${s.kind}`,kind:s.kind,rawText:H(s.text),html:s.kind==="assistant"?_n(s.text):""})));De(()=>a.selectedNodeId,s=>{aa(Oi,s||""),a.areaSelectedId="",a.testAreaSelectedId=x(s||"")}),De(()=>a.autoRefresh,s=>{xa(Li,s)}),De(()=>a.voiceEnabled,s=>{xa(zi,s),s!==!0&&ka()}),De(ye,s=>{xa($i,s)}),De(()=>a.activeTab,s=>{aa(oy,s||"overview")}),De(()=>a.settingsTab,s=>{aa(Mi,s||"config")}),De(()=>a.flowMaxNodes,s=>{a.flowMaxNodes=Math.max(4,Math.min(32,Number(s)||14)),L()}),De(()=>(a.flowSelectedGa||[]).join("|"),()=>{L()}),De(()=>a.flowShowUniversalNodes,s=>{s!==!0&&(a.flowSelectedGa=(a.flowSelectedGa||[]).filter(n=>{const r=Ss.value.nodes.find(c=>c.id===n);return!hs(r)})),L()}),De(()=>Ae.value.map(s=>s.id).join("|"),()=>{if(!Ae.value.length){a.areaSelectedId="",a.testAreaSelectedId="",a.activeTab==="tests"&&(a.activeTab="areas");return}if(a.areaDraftIsNew===!0&&!String(a.areaSelectedId||"").trim()){const r=String(a.testAreaSelectedId||"").trim();if(C())return;(!r||!Ae.value.find(c=>c.id===r))&&(a.testAreaSelectedId=Ae.value[0].id);return}const s=String(a.areaSelectedId||"").trim();s&&!Ae.value.find(r=>r.id===s)&&(a.areaSelectedId="");const n=String(a.testAreaSelectedId||"").trim();C()||(!n||!Ae.value.find(r=>r.id===n))&&(a.testAreaSelectedId=Ae.value[0].id)}),De(()=>a.testAreaSelectedId,s=>{a.selectedNodeId&&k(a.selectedNodeId,s||"")}),De(()=>Fe.value?JSON.stringify({id:Fe.value.id,name:Fe.value.name,customDescription:Fe.value.customDescription||"",tags:Fe.value.tags||[]}):"",()=>{if(a.areaDraftIsNew===!0&&!String(a.areaSelectedId||"").trim())return;const s=Fe.value;if(!s){a.areaDraftId="",a.areaDraftName="",a.areaDraftDescription="",a.areaDraftTags="",a.areaDraftGaList=[],a.areaLlmPrompt="",a.areaLlmError="",a.areaDraftIsNew=!1;return}a.areaDraftId=String(s.id||""),a.areaDraftName=String(s.name||""),a.areaDraftDescription=String(s.customDescription||""),a.areaDraftTags=Array.isArray(s.tags)?s.tags.join(", "):"",a.areaDraftGaList=Array.isArray(s.gaList)?s.gaList.slice():[],a.areaLlmPrompt="",a.areaLlmError="",a.areaDraftIsNew=!1}),De(()=>Ot.value?Ot.value.id:"",async(s,n)=>{if(!s||!a.selectedNodeId){a.testPlanCatalog=null,a.testPlanCatalogError="";return}n&&s!==n&&(a.testPlanRunConfirmOpen=!1,a.testPlanDraft&&!a.testPlanSelectedId&&(a.testPlanDraft.areaId=String(s||""),a.testPlanDraft.areaName=Ot.value?String(Ot.value.path||Ot.value.name||""):"")),await Kr()}),De(()=>ya.value.map(s=>s.id).join("|"),()=>{if(!ya.value.length){a.profileSelectedId="";return}a.profileDraftMode!==!0&&(!a.profileSelectedId||!ya.value.find(s=>s.id===a.profileSelectedId))&&(a.profileSelectedId=ya.value[0].id)}),De(()=>St.value?JSON.stringify({id:St.value.id,name:St.value.name,description:St.value.description,targetTags:St.value.targetTags||[],minActivityPct:St.value.minActivityPct,maxSilentPct:St.value.maxSilentPct,maxAnomalies:St.value.maxAnomalies,builtIn:St.value.builtIn===!0}):"",()=>{const s=St.value;if(!s){a.profileDraftId="",a.profileDraftName="",a.profileDraftDescription="",a.profileDraftTargetTags="",a.profileDraftMinActivityPct=20,a.profileDraftMaxSilentPct=60,a.profileDraftMaxAnomalies=2;return}a.profileDraftId=String(s.id||""),a.profileDraftName=String(s.name||""),a.profileDraftDescription=String(s.description||""),a.profileDraftTargetTags=Array.isArray(s.targetTags)?s.targetTags.join(", "):"",a.profileDraftMinActivityPct=Number(s.minActivityPct||20),a.profileDraftMaxSilentPct=Number(s.maxSilentPct||60),a.profileDraftMaxAnomalies=Number(s.maxAnomalies||2)}),De(()=>Aa.value.map(s=>s.id).join("|"),()=>{if(!Aa.value.length){a.actuatorPresetSelectedId="";return}a.actuatorDraftMode!==!0&&(!a.actuatorPresetSelectedId||!Aa.value.find(s=>s.id===a.actuatorPresetSelectedId))&&(a.actuatorPresetSelectedId=Aa.value[0].id)}),De(()=>lt.value?JSON.stringify({id:lt.value.id,name:lt.value.name,description:lt.value.description,commandGA:lt.value.commandGA,commandDPT:lt.value.commandDPT,commandPayload:lt.value.commandPayload,statusGA:lt.value.statusGA,statusDPT:lt.value.statusDPT,statusWriteTimeoutMs:lt.value.statusWriteTimeoutMs,statusResponseTimeoutMs:lt.value.statusResponseTimeoutMs}):"",()=>{const s=lt.value;if(!s){a.actuatorDraftId="",a.actuatorDraftName="",a.actuatorDraftDescription="",a.actuatorDraftCommandGA="",a.actuatorDraftCommandDPT="",a.actuatorDraftCommandPayload="",a.actuatorDraftStatusGA="",a.actuatorDraftStatusDPT="",a.actuatorDraftStatusWriteTimeoutMs=5e3,a.actuatorDraftStatusResponseTimeoutMs=5e3;return}a.actuatorDraftId=String(s.id||""),a.actuatorDraftName=String(s.name||""),a.actuatorDraftDescription=String(s.description||""),a.actuatorDraftCommandGA=String(s.commandGA||""),a.actuatorDraftCommandDPT=String(s.commandDPT||""),a.actuatorDraftCommandPayload=String(s.commandPayload||""),a.actuatorDraftStatusGA=String(s.statusGA||""),a.actuatorDraftStatusDPT=String(s.statusDPT||""),a.actuatorDraftStatusWriteTimeoutMs=Number(s.statusWriteTimeoutMs||5e3),a.actuatorDraftStatusResponseTimeoutMs=Number(s.statusResponseTimeoutMs||5e3)}),De(()=>yt.value.map(s=>s.id).join("|"),()=>{if(!yt.value.length){a.testPlanSelectedId="";return}a.testPlanSelectedId&&!yt.value.find(s=>s.id===a.testPlanSelectedId)&&(a.testPlanSelectedId="")}),De(()=>na.value.map(s=>s.id).join("|"),()=>{if(!na.value.length){a.selectedTestResultId="";return}(!a.selectedTestResultId||!na.value.find(s=>s.id===a.selectedTestResultId))&&(a.selectedTestResultId=String(na.value[0].id||"")),a.liveTestResultId&&Ja.value.some(s=>String(s&&s.id?s.id:"")===a.liveTestResultId)&&a.testPlanRunning!==!0&&(a.liveTestResultId="")}),De(()=>`${a.selectedTestResultId}|${a.activeTab}`,()=>{a.activeTab!=="results"||!a.selectedTestResultId||requestAnimationFrame(()=>{const s=document.querySelector(".results-page-list .area-list-item.active");s&&typeof s.scrollIntoView=="function"&&s.scrollIntoView({block:"nearest",behavior:"smooth"})})});function ws(s,n){a.chatMessages.push({kind:s,text:n})}function bl(){a.chatMessages=[]}function yl(s,n=null){const r=Array.isArray(s)?s:[];return{totalSteps:Math.max(r.length,Number(n||0)),pass:r.filter(g=>g&&g.status==="pass").length,warn:r.filter(g=>g&&g.status==="warn").length,fail:r.filter(g=>g&&g.status==="fail").length}}function Al(s){const n=[];return Number(s&&s.fail)>0&&n.push("At least one feedback object returned an incoherent value. Check the actuator/status pairing in ETS first."),Number(s&&s.warn)>0&&n.push("Some steps did not receive feedback in time. Verify the status group address and the actuator programming."),n.length||n.push("The selected active test completed with coherent feedback on all verified steps."),n}function Ps({plan:s,area:n,stepResults:r,reportId:c=""}){const g=yl(r,Array.isArray(s&&s.steps)?s.steps.length:0),N=g.fail>0?"fail":g.warn>0?"warn":"pass";return{id:String(c||`${s.id||"plan"}:${Date.now()}`),generatedAt:new Date().toISOString(),mode:"ai_test_plan",overallStatus:N,name:s.name,description:s.description,prompt:s.prompt,area:n,metrics:g,steps:r,suggestions:Al(g)}}function Cn(s){return!s||typeof s!="object"?"Test result":String(s.name||s.profile?.name||"Test result")}function kn(s){return!s||typeof s!="object"?"":String(s.area?.path||s.area?.name||s.area?.id||"")}function Za(s){const n=String(s&&s.mode?s.mode:"").trim().toLowerCase();return n==="ai_test_plan"?"Test Plan":n==="active_test"?"Actuator":n==="read_only"?"Read-only":n||"Test"}function Ts(s){const n=s&&s.metrics&&typeof s.metrics=="object"?s.metrics:{};return String(s&&s.mode?s.mode:"")==="read_only"?[{label:"Total GA",value:Number(n.totalGAs||0)},{label:"Active GA",value:Number(n.activeGaCount||0)},{label:"Silent GA",value:Number(n.silentGaCount||0)},{label:"Anomalies",value:Number(n.anomalyCount||0)}]:String(s&&s.mode?s.mode:"")==="active_test"?[{label:"Command GA",value:s&&s.command&&s.command.ga?s.command.ga:"n/a"},{label:"Status GA",value:s&&(s.statusResponse?.ga||s.statusWrite?.ga||s.statusRead?.ga)?s.statusResponse?.ga||s.statusWrite?.ga||s.statusRead?.ga:"n/a"},{label:"Status",value:s&&s.overallStatus?s.overallStatus:"n/a"},{label:"Generated",value:Gt(s&&s.generatedAt?s.generatedAt:"")||"n/a"}]:[{label:"Total Steps",value:Number(n.totalSteps||0)},{label:"Pass",value:Number(n.pass||0)},{label:"Warn",value:Number(n.warn||0)},{label:"Fail",value:Number(n.fail||0)}]}function Lt(s){if(s==null||s==="")return"n/a";if(typeof s=="string"||typeof s=="number"||typeof s=="boolean")return String(s);try{return JSON.stringify(s)}catch{return String(s)}}function _s(s,n,r="n/a"){const c=String(n||"").trim(),g=s==null?"":String(s);if(!c)return g||r;const N=ks(g,c),R=ia(c).find(B=>String(B.value)===String(N));return R&&R.label?R.label:g||r}function kr(s){if(!s||typeof s!="object")return"n/a";const n=s.ga||"n/a";if(s.ok===!0){const r=s.payloadLabel||Lt(s.payload),c=s.coherent===!1?"mismatch":"ok";return`${n} / ${r} / ${c}`}return`${n} / ${s.error||"timeout"}`}function Ds(s){return Gt(s||"")||"n/a"}function Sl(s,n="report"){return String(s||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||n}function xr({command:s,statusWrite:n,statusResponse:r,statusRead:c,expectedPayloadLabel:g,expectedPayload:N}){const R=r||c;return[{title:"Command",items:[{label:"Command",value:`${s?.ga||"n/a"} / ${s?.payloadLabel||Lt(s?.payload)}`},{label:"Command Sent",value:Ds(s?.sentAt)}]},{title:"Spontaneous Write From Status GA",items:[{label:"Result",value:kr(n)},{label:"Expected",value:n?.expectedPayloadLabel||g||Lt(N)},{label:"Received At",value:Ds(n?.at)},{label:"Event",value:n?.event||"n/a"}]},{title:"Active Read Request To Status GA",items:[{label:"Result",value:kr(R)},{label:"Expected",value:R?.expectedPayloadLabel||g||Lt(N)},{label:"Received At",value:Ds(R?.at)},{label:"Event",value:R?.event||"n/a"}]}]}function Ya(s){return!s||typeof s!="object"?[]:Array.isArray(s.steps)&&s.steps.length?s.steps.map(n=>{const r=n.kind==="wait"?[{label:"Wait",value:`${Number(n.delayMs||0)} ms`},{label:"Reason",value:n.reason||"Pause before next action"}]:[];return{id:String(n.id||`${s.id}-step`),title:n.title||n.id||"Step",status:n.status||"pass",message:n.message||n.description||"",details:r,detailGroups:n.kind==="wait"?[]:xr({command:n.command,statusWrite:n.statusWrite,statusResponse:n.statusResponse,statusRead:n.statusRead,expectedPayloadLabel:n.expectedPayloadLabel,expectedPayload:n.expectedPayload})}}):Array.isArray(s.checks)&&s.checks.length?s.checks.map(n=>({id:String(n.id||`${s.id}-check`),title:n.title||n.id||"Check",status:n.status||"pass",message:n.message||"",details:[{label:"Metrics",value:Lt(n.metrics||{})},{label:"Sample",value:Lt(n.sample||[])}]})):String(s.mode||"")==="active_test"?[{id:String(s.id||"active-test"),title:s.name||"Actuator Test",status:s.overallStatus||"pass",message:s.overallStatus==="pass"?"Both feedback checks passed.":s.overallStatus==="warn"?"One feedback check passed and one failed.":"Both feedback checks failed.",details:[],detailGroups:xr({command:s.command,statusWrite:s.statusWrite,statusResponse:s.statusResponse,statusRead:s.statusRead,expectedPayloadLabel:s.statusResponse?.expectedPayloadLabel||s.statusWrite?.expectedPayloadLabel||s.statusRead?.expectedPayloadLabel,expectedPayload:s.statusRead?.expectedPayload})}]:[]}function Qa(s){return Array.isArray(s&&s.suggestions)?s.suggestions:[]}function wl(s){const n=s&&s.source&&typeof s.source=="object"?s.source:{},r=String(s&&s.mode?s.mode:"").trim().toLowerCase(),c=String(n.areaId||s?.area?.id||"").trim();return r==="ai_test_plan"?{type:"ai_test_plan",planId:String(n.planId||String(s.id||"").split(":")[0]||"").trim(),areaId:c}:r==="read_only"?{type:"profile",profileId:String(n.profileId||s?.profile?.id||"").trim(),areaId:c}:r==="active_test"?{type:"actuator_test",presetId:String(n.presetId||String(s.id||"").split(":")[0]||"").trim(),areaId:c}:{type:"",areaId:c}}async function Er(){const s=ne.value;if(!s||typeof s!="object"){T("No test result selected to export");return}try{const{jsPDF:n}=await of(async()=>{const{jsPDF:_e}=await import("./chunk-jspdf.es.min.js").then(wt=>wt.j);return{jsPDF:_e}},[],import.meta.url),r=new n({orientation:"portrait",unit:"pt",format:"a4"}),c=r.internal.pageSize.getWidth(),g=r.internal.pageSize.getHeight(),N=42,R=42,B=44,z=42,Q=c-N-R;let q=B;const pe=(_e=14)=>{q+_e<=g-z||(r.addPage(),q=B)},Z=(_e,{size:wt=11,bold:zt=!1,indent:$t=0,color:Kt=[35,41,52],lineHeight:Fn=14,gapAfter:On=0}={})=>{const en=String(_e||"").trim();if(!en)return;r.setFont("helvetica",zt?"bold":"normal"),r.setFontSize(wt),r.setTextColor(Kt[0],Kt[1],Kt[2]);const Ln=r.splitTextToSize(en,Math.max(80,Q-$t));for(const Os of Ln)pe(Fn),r.text(String(Os),N+$t,q),q+=Fn;On>0&&(q+=On)},Y=()=>{pe(12),r.setDrawColor(210,214,222),r.line(N,q,c-R,q),q+=12},ee=Cn(s),he=Gt(new Date().toISOString())||new Date().toISOString(),oa=Gt(s.generatedAt||"")||String(s.generatedAt||"n/a"),w=kn(s)||"n/a",V=Za(s),ae=String(s.overallStatus||"n/a"),Le=Ts(s),He=Ya(s),et=Qa(s);Z("KNX AI Test Result",{size:17,bold:!0,color:[20,28,39],lineHeight:20}),Z(ee,{size:14,bold:!0,color:[20,28,39],lineHeight:17,gapAfter:4}),Z(`Exported: ${he}`,{size:10,color:[88,96,113]}),Z(`Generated: ${oa}`,{size:10,color:[88,96,113]}),Z(`Mode: ${V}`,{size:10,color:[88,96,113]}),Z(`Status: ${ae}`,{size:10,color:[88,96,113]}),Z(`Area: ${w}`,{size:10,color:[88,96,113]}),Z(`Report ID: ${String(s.id||"n/a")}`,{size:10,color:[88,96,113],gapAfter:2}),Y(),Le.length&&(Z("Metrics",{size:12,bold:!0,color:[20,28,39],gapAfter:2}),Le.forEach(_e=>{Z(`${_e.label}: ${Lt(_e.value)}`,{size:10,color:[35,41,52]})}),q+=4,Y()),Z(`Checks (${He.length})`,{size:12,bold:!0,color:[20,28,39],gapAfter:2}),He.length?He.forEach((_e,wt)=>{Z(`${wt+1}. ${_e.title||"Check"} [${String(_e.status||"n/a").toUpperCase()}]`,{size:11,bold:!0,color:[31,41,55]}),Z(_e.message||"No additional details available.",{size:10,color:[70,78,94]}),Array.isArray(_e.detailGroups)&&_e.detailGroups.length?_e.detailGroups.forEach(zt=>{Z(zt.title||"Details",{size:10,bold:!0,indent:12,color:[35,41,52]}),(Array.isArray(zt.items)?zt.items:[]).forEach(Kt=>{Z(`${Kt.label}: ${Lt(Kt.value)}`,{size:10,indent:24,color:[70,78,94]})})}):(Array.isArray(_e.details)?_e.details:[]).forEach($t=>{Z(`${$t.label}: ${Lt($t.value)}`,{size:10,indent:12,color:[70,78,94]})}),q+=2}):Z("No detailed entries stored for this report yet.",{size:10,color:[88,96,113]}),et.length&&(q+=4,Y(),Z("Suggestions",{size:12,bold:!0,color:[20,28,39],gapAfter:2}),et.forEach((_e,wt)=>{Z(`${wt+1}. ${String(_e||"")}`,{size:10,color:[35,41,52]})}));const st=new Date(s.generatedAt||Date.now()),la=Number.isFinite(st.getTime())?st.toISOString().replace(/[:.]/g,"-"):String(Date.now()),Oa=`knx-ai-test-result-${Sl(ee,"report")}-${la}.pdf`;r.save(Oa),T(`PDF exported (${Oa})`)}catch(n){a.lastError=n&&n.message?n.message:"Failed to export PDF",T(a.lastError)}}function Gr(s,n,r=new Date().toISOString()){const c=s&&s.kind==="wait";return{id:s&&s.id?s.id:`step-${Date.now()}`,title:s&&s.title?s.title:"Test Step",description:s&&s.description?s.description:"",reason:s&&s.reason?s.reason:"",kind:s&&s.kind?s.kind:"write_and_verify",status:"warn",command:c?null:{ga:s&&s.commandGA?s.commandGA:"",dpt:s&&s.commandDPT?s.commandDPT:"",payload:s?s.commandPayload:void 0,sentAt:r},statusWrite:null,statusResponse:null,statusRead:null,expectedPayload:c?void 0:s?s.expectedPayload:void 0,delayMs:Number(s&&s.delayMs?s.delayMs:0),statusWriteTimeoutMs:c?0:Number(s&&s.statusWriteTimeoutMs?s.statusWriteTimeoutMs:0),statusResponseTimeoutMs:c?0:Number(s&&s.statusResponseTimeoutMs?s.statusResponseTimeoutMs:0),message:n&&n.message?n.message:"Failed to run step"}}async function Fr(s){return ka(),await new Promise((n,r)=>{const c=URL.createObjectURL(s),g=new Audio(c);je=g;const N=()=>{je===g&&(je=null),g.onended=null,g.onerror=null,URL.revokeObjectURL(c)};g.onended=()=>{N(),n()},g.onerror=()=>{N(),r(new Error("Audio playback failed"))};const R=g.play();R&&typeof R.then=="function"&&R.catch(B=>{N(),r(B instanceof Error?B:new Error(String(B)))})})}function Pl(s,n=null){const r=String(s||"").trim();return!r||!a.testPlanDraft||!Array.isArray(a.testPlanDraft.steps)?n:a.testPlanDraft.steps.find(c=>String(c&&c.id?c.id:"")===r)||n}function Or(s,n=""){const r=`${String(s||"")} ${String(n||"")}`.trim().toLowerCase(),c=` ${r} `;if(!r)return String((navigator.language||"it").split("-")[0]||"it").trim().toLowerCase()||"it";const g=B=>B.some(z=>c.includes(z)),N=[{voice:"it",score:[g([" accendi "," spegni "," stato "," verifica "," coerente "," leggi "," apri "," chiudi "," attiva "," controlla "," area "," luce "," luci "," tapparella "," tapparelle "," clima "])?3:0,/[àèéìíîòóù]/.test(r)?2:0].reduce((B,z)=>B+z,0)},{voice:"en",score:[g([" turn on "," turn off "," verify "," feedback "," status "," check "," read "," open "," close "," command "," area "," light "," lights "])?3:0].reduce((B,z)=>B+z,0)},{voice:"fr",score:[g([" allume "," éteins "," etat "," état "," vérifier "," ouvre "," ferme "," lumière "," lumières "," zone "])?3:0,/[àâçéèêëîïôûùüÿœ]/.test(r)?2:0].reduce((B,z)=>B+z,0)},{voice:"de",score:[g([" einschalten "," ausschalten "," status "," prüfen "," öffne "," schließe "," licht "," bereich "])?3:0,/[äöüß]/.test(r)?2:0].reduce((B,z)=>B+z,0)},{voice:"es",score:[g([" enciende "," apaga "," estado "," verifica "," abre "," cierra "," luz "," luces "," zona "])?3:0,/[áéíóúñü]/.test(r)?2:0].reduce((B,z)=>B+z,0)},{voice:"pt",score:[g([" liga "," desliga "," estado "," verificar "," abre "," fecha "," luz "," luzes "," área "])?3:0,/[ãõâêôçáéíóú]/.test(r)?2:0].reduce((B,z)=>B+z,0)}];return N.sort((B,z)=>z.score-B.score),N[0]&&N[0].score>0?N[0].voice:String((navigator.language||"it").split("-")[0]||"it").trim().toLowerCase()||"it"}function Tl(s={},n=null){const r=Pl(s&&s.id?s.id:"",s),c=String(r&&r.title?r.title:"").trim(),g=String(r&&r.description?r.description:"").trim();return{text:`${Number.isInteger(n)&&n>0?`${n}. `:""}${c}`.trim(),voice:Or(c,g)}}async function _l(s={},n=null){if(a.voiceEnabled!==!0)return;const r=Tl(s,n),c=String(r.text||"").trim();if(!c||!a.selectedNodeId)return;const g=await W(`${D("tts/googletranslate")}?ts=${Date.now()}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,text:c,voice:r.voice,slow:!1})});await Fr(g)}async function Lr(s,n=""){if(a.voiceEnabled!==!0||!a.selectedNodeId)return;const r=String(s||"").trim();if(!r)return;const c=Or(r,n),g=await W(`${D("tts/googletranslate")}?ts=${Date.now()}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,text:r,voice:c,slow:!1})});await Fr(g)}function Dl(s){const n=u&&s.find(g=>g.id===u)?u:"",r=Xa(Oi,""),c=r&&s.find(g=>g.id===r)?r:"";return n||c||(s[0]?s[0].id:"")}async function Ns({preserveSelection:s=!0}={}){a.loadingNodes=!0,T("Loading nodes...");try{const n=await E(D("nodes")),r=Array.isArray(n&&n.nodes)?n.nodes:[];if(a.nodes=r,!r.length){a.selectedNodeId="",a.stateData=null,a.lastError="No KNX AI nodes found.",T(a.lastError);return}const c=s&&a.selectedNodeId&&r.find(g=>g.id===a.selectedNodeId)?a.selectedNodeId:Dl(r);a.selectedNodeId=c,a.lastError="",T("Ready")}catch(n){a.lastError=n.message||"Failed to load nodes",T(a.lastError)}finally{a.loadingNodes=!1}}async function Mt({fresh:s=!1}={}){if(!(!a.selectedNodeId||a.loadingState)){a.loadingState=!0,s&&T("Loading...");try{const n=a.testPlanRunning===!0&&a.liveTestResultId?Ft(a.stateData&&a.stateData.testPlanReport?a.stateData.testPlanReport:null,null):null,r=await E(D(`state?nodeId=${encodeURIComponent(a.selectedNodeId)}&fresh=${s?1:0}`));n&&n.id===a.liveTestResultId&&(r.testPlanReport=n),a.stateData=r,dn(()=>{a.areaDraftIsNew!==!0&&a.areaSelectedId&&!Ae.value.find(c=>c.id===a.areaSelectedId)&&(a.areaSelectedId=""),!C()&&!a.testAreaSelectedId&&Ae.value[0]&&(a.testAreaSelectedId=Ae.value[0].id)}),a.lastError="",T("Ready")}catch(n){a.lastError=n.message||"Failed to load state",T(a.lastError)}finally{a.loadingState=!1}}}async function Nl(){await Ns({preserveSelection:!0}),await Mt({fresh:!0}),await Fa()}async function Il(){bl(),a.selectedTestResultId="",a.liveTestResultId="",a.testResultFocusMode=!1,a.testAreaSelectedId=x(a.selectedNodeId),await Mt({fresh:!0}),await Fa()}function Mr(){a.selectedTestResultId="",a.testResultFocusMode=!1,a.testPlanSelectedId="",a.testPlanDraft=null,a.testPlanPrompt="",a.testPlanGeneration=null,a.testPlanRunConfirmOpen=!1,a.testPlanUnsavedConfirmOpen=!1,a.showAiPlanner=!0,a.testTemplateBuilderFocus=!1,!C()&&!a.testAreaSelectedId&&Ae.value[0]&&(a.testAreaSelectedId=Ae.value[0].id),Gs(),Es()}function Rl(){a.showAiPlanner=!0,a.testTemplateBuilderFocus=!0}function Cl(){a.testTemplateBuilderFocus=!1,a.showAiPlanner=!1}function kl(){a.showAiAreaBuilder=!0,a.areaBuilderFocus=!0}function xl(){a.areaBuilderFocus=!1,a.showAiAreaBuilder=!1}function Is(){a.areaSelectedId="",a.areaDraftIsNew=!1,a.areaDraftId="",a.areaDraftName="",a.areaDraftDescription="",a.areaDraftTags="",a.areaDraftGaList=[],a.areaLlmPrompt="",a.areaLlmError="",a.areaSearch="",a.areaSearchOpen=!1,a.showAiAreaBuilder=!1,a.areaBuilderFocus=!1,a.areaUnsavedConfirmOpen=!1}function El(){if(fl.value){a.areaUnsavedConfirmOpen=!0;return}Is(),T("Area editor closed")}function Br(){a.areaUnsavedConfirmOpen=!1}function Gl(){a.areaUnsavedConfirmOpen=!1,Is(),T("Area editor closed")}function Fl(){a.testPlanRunning||Fs(()=>{Mr(),a.testPlanSearchOpen=!1,T("Test editor closed")},"close the current test editor")}function zr(s){const n=String(s||"").trim();n!=="node"&&n!=="config"||(a.settingsTab=n)}function Sa(s){const n=String(s||"").trim();if(n){if(n==="tests"&&Ae.value.length===0){T("Define at least one area before using Tests");return}if(n==="areas"){const r=!!String(a.areaSelectedId||"").trim(),c=a.areaDraftIsNew===!0;!r&&!c&&Is()}if(n==="tests"){const r=!!String(a.testPlanSelectedId||"").trim(),c=!!String(a.selectedTestResultId||"").trim(),g=!!a.testPlanDraft;!r&&!c&&!g&&Mr()}a.activeTab!==n?a.activeTab=n:(a.activeTab="",dn(()=>{a.activeTab=n})),h()}}async function Rs(s){const n=String(s||"").trim();if(!(!n||!a.selectedNodeId||a.deletingTestResultId)){a.deletingTestResultId=n;try{const r=await E(D("test-results/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,reportId:n})}),c=Array.isArray(r&&r.testResults)?r.testResults:[];a.stateData=Object.assign({},a.stateData||{},{testResults:c}),a.selectedTestResultId===n&&(a.selectedTestResultId=c[0]&&c[0].id?String(c[0].id):"",c.length||(a.testResultFocusMode=!1)),a.liveTestResultId===n&&(a.liveTestResultId=""),T("Test result deleted")}catch(r){a.lastError=r.message||"Failed to delete test result",T(a.lastError)}finally{a.deletingTestResultId=""}}}function xn(s,{openMenu:n=!0,activateTestsTab:r=!1,activateResultsTab:c=!1,resultOnly:g=!0}={}){const N=String(s||"").trim();if(!N)return;n&&(a.testResultsMenuOpen=!0);const R=c?"results":r?"tests":"",B=()=>{R&&(a.activeTab=R),a.selectedTestResultId=N,a.testResultFocusMode=g===!0,dn(()=>{const z=document.querySelector(".results-page-list .area-list-item.active");z&&typeof z.scrollIntoView=="function"&&z.scrollIntoView({block:"nearest",behavior:"smooth"})})};a.selectedTestResultId===N&&(!R||a.activeTab===R)||B()}function $r(){const s=ne.value;if(!s)return;if(!Ae.value.length){T("Define at least one area before using Tests");return}const n=wl(s);if(a.activeTab="tests",a.testResultFocusMode=!1,n.type==="ai_test_plan"&&n.planId){const r=yt.value.find(c=>c&&c.id===n.planId);if(r){Jr(r),T(`Opened source plan "${r.name||r.id}"`);return}}if(n.type==="profile"){T("Returned to the Tests page for the source read-only profile.");return}if(n.type==="actuator_test"){T("Returned to the Tests page for the source actuator test.");return}T("Returned to the Tests page.")}async function Ol(s){if(!a.selectedNodeId||!s||typeof s!="object")return null;const n=await E(D("test-results/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,report:s})});return a.stateData=Object.assign({},a.stateData||{},{testResults:n.testResults||Ja.value,testPlanReport:n.report&&n.report.mode==="ai_test_plan"?n.report:ft.value,actuatorTestReport:n.report&&n.report.mode==="active_test"?n.report:dl.value,profileReport:n.report&&n.report.mode==="read_only"?n.report:ll.value}),n&&n.report&&n.report.id&&(a.liveTestResultId="",xn(n.report.id,{openMenu:!0,activateResultsTab:!0,resultOnly:!0})),n}async function Cs(s=""){const n=String(s||"").trim(),r=String(a.chatDraft||"").trim(),c=n||r;if(!(!c||!a.selectedNodeId)){ws("user",c),n||(a.chatDraft=""),a.asking=!0,T("Asking...");try{const g=await E(D("ask"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,question:c})});ws("assistant",g&&g.answer!==void 0?g.answer:""),T("Ready")}catch(g){ws("error",g.message||"Ask failed"),T(g.message||"Ask failed")}finally{a.asking=!1}}}async function Ll(){const s=String(a.flowBuilderPrompt||"").trim();if(!(!s||!a.selectedNodeId||a.flowBuilderGenerating)){a.flowBuilderGenerating=!0,a.flowBuilderError="",a.flowBuilderCopied=!1,T("Generating flow...");try{const n=await E(D("flow/generate"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,prompt:s,language:A.value})});a.flowBuilderResult=n||null,T("Ready")}catch(n){a.flowBuilderResult=null,a.flowBuilderError=n.message||"Flow generation failed",T(a.flowBuilderError)}finally{a.flowBuilderGenerating=!1}}}async function Ml(){const s=a.flowBuilderResult&&a.flowBuilderResult.flowJson?a.flowBuilderResult.flowJson:"";if(s)try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(s);else{const n=document.createElement("textarea");n.value=s,n.style.position="fixed",n.style.opacity="0",document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n)}a.flowBuilderCopied=!0,T("Flow JSON copied to clipboard"),setTimeout(()=>{a.flowBuilderCopied=!1},2500)}catch(n){a.flowBuilderError=n.message||"Could not copy to clipboard"}}async function Bl(){const s=Fe.value;if(!a.selectedNodeId||a.areaSaving||!a.areaDraftIsNew&&!s)return;const n=a.areaDraftIsNew===!0;a.areaSaving=!0,T(n?"Creating area...":"Saving area...");try{const c=await E(D(n?"areas/create":"areas/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:a.areaDraftIsNew?void 0:s.id,name:a.areaDraftName,description:a.areaDraftDescription,tags:String(a.areaDraftTags||"").split(",").map(g=>String(g||"").trim()).filter(Boolean),gaList:a.areaDraftGaList||[]})});c&&c.areas?(a.stateData=Object.assign({},a.stateData||{},{areas:c.areas}),c.areaId&&(a.areaSelectedId=c.areaId),a.areaLlmPrompt="",a.areaLlmError="",a.areaDraftIsNew=!1):await Mt({fresh:!0}),T(n?"Area created":"Area saved")}catch(r){a.lastError=r.message||"Failed to save area",T(a.lastError)}finally{a.areaSaving=!1}}async function zl(){const s=Fe.value;if(!(!s||!a.selectedNodeId||a.areaSaving)){a.areaSaving=!0,T("Resetting area...");try{const n=await E(D("areas/reset"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:s.id})});n&&n.areas?a.stateData=Object.assign({},a.stateData||{},{areas:n.areas}):await Mt({fresh:!0}),T("Area reset")}catch(n){a.lastError=n.message||"Failed to reset area",T(a.lastError)}finally{a.areaSaving=!1}}}async function $l(){const s=Fe.value;if(!(!s||!a.selectedNodeId||a.areaSaving)){a.areaSaving=!0,T("Deleting area...");try{const n=await E(D("areas/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:s.id})});if(n&&n.areas){a.stateData=Object.assign({},a.stateData||{},{areas:n.areas});const r=Array.isArray(n.areas&&n.areas.suggested)?n.areas.suggested:[];a.areaDraftIsNew=!1,a.areaSelectedId=r[0]&&r[0].id?r[0].id:""}else await Mt({fresh:!0});T("Area deleted")}catch(n){a.lastError=n.message||"Failed to delete area",T(a.lastError)}finally{a.areaSaving=!1}}}async function Kr(){const s=Ot.value;if(!s||!a.selectedNodeId){a.testPlanCatalog=null,a.testPlanCatalogError="";return}a.testPlanCatalogLoading=!0,a.testPlanCatalogError="";try{const n=await E(D("test-plans/catalog"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:s.id})});a.testPlanCatalog=n&&n.catalog?n.catalog:null,n&&n.testPlans&&(a.stateData=Object.assign({},a.stateData||{},{testPlans:n.testPlans}))}catch(n){a.testPlanCatalog=null,a.testPlanCatalogError=n.message||"Failed to load area command/status catalog"}finally{a.testPlanCatalogLoading=!1}}async function Fa(){if(!(!a.selectedNodeId||a.gaCatalogLoading)){a.gaCatalogLoading=!0;try{const s=await E(D("areas/catalog"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId})});a.gaCatalog=Array.isArray(s&&s.gaCatalog)?s.gaCatalog:[]}catch(s){a.lastError=s.message||"Failed to load GA catalog",T(a.lastError)}finally{a.gaCatalogLoading=!1}}}function Kl(s){const n=String(s||"").trim();n&&((a.areaDraftGaList||[]).includes(n)||(a.areaDraftGaList=[...a.areaDraftGaList||[],n]))}function Vr(s){const n=String(s||"").trim().toLowerCase(),r=o.find(c=>c.value===n);return r?r.label:n==="auto"?"Auto":"Command"}function Wr(s){const n=s&&typeof s=="object"?s:{},r=String(n.path||n.name||"Area").trim(),c=String(n.kind||"").trim(),g=Number(n.gaCount||0),N=Number(n.activeGaCount||0),R=[c,`${g} GA`,`active ${N}`].filter(Boolean).join(" | ");return R?`${r} ${R}`:r}function Vl(s){const n=s&&typeof s=="object"?s:null;!n||!n.id||(a.areaDraftIsNew=!1,a.showAiAreaBuilder=!1,a.areaBuilderFocus=!1,a.areaSelectedId=n.id,a.areaSearch="",a.areaSearchOpen=!1)}function Wl(){setTimeout(()=>{a.areaSearchOpen=!1},150)}function Ur(s){const n=s&&typeof s=="object"?s:{},r=String(n.name||"Plan").trim(),c=String(n.areaName||n.areaId||"").trim(),g=Number(n.steps&&n.steps.length?n.steps.length:0),N=[c,`${g} steps`].filter(Boolean).join(" | ");return N?`${r} ${N}`:r}function Ul(s){const n=s&&typeof s=="object"?s:null;!n||!n.id||(yd(n),a.testPlanSearch="",a.testPlanSearchOpen=!1)}function jl(){setTimeout(()=>{a.testPlanSearchOpen=!1},150)}function Hl(){return re(A.value,"en")}function Xl(s){const n=String(s||"").trim();n&&(a.areaDraftGaList=(a.areaDraftGaList||[]).filter(r=>r!==n))}async function ql(s,n){const r=String(s||"").trim();if(!(!a.selectedNodeId||!r||a.areaGaRoleSavingGa===r)){a.areaGaRoleSavingGa=r,T(`Saving role for ${r}...`);try{const c=await E(D("areas/ga-role/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,ga:r,role:n})});Array.isArray(c&&c.gaCatalog)&&(a.gaCatalog=c.gaCatalog),c&&c.areas&&(a.stateData=Object.assign({},a.stateData||{},{areas:c.areas})),Ot.value&&Array.isArray(Ot.value.gaList)&&Ot.value.gaList.includes(r)&&await Kr(),T(`Role saved for ${r}`)}catch(c){a.lastError=c.message||"Failed to save GA role",T(a.lastError)}finally{a.areaGaRoleSavingGa=""}}}function Jl(){a.activeTab="areas",a.areaDraftIsNew=!0,a.areaSelectedId="",a.areaDraftId="",a.areaDraftName="New Area",a.areaDraftDescription="",a.areaDraftTags="",a.areaDraftGaList=[],a.areaLlmPrompt="",a.areaLlmError="",a.showAiAreaBuilder=!1,a.areaBuilderFocus=!1}async function Zl(){const s=String(a.selectedNodeId||"").trim();if(!(a.areaLlmRegenerating||a.areaLlmBulkDeleting)){if(!s){a.areaLlmError="Select a KNX AI node first",T(a.areaLlmError);return}a.areaLlmRegenerating=!0,a.areaLlmError="",T("Regenerating AI areas...");try{const n=await E(D("areas/regenerate-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:s})}),r=Array.isArray(n&&n.gaCatalog);if(r&&(a.gaCatalog=n.gaCatalog),n&&(n.areas||n.profiles||n.actuatorTests||n.testPlans)){const c=Object.assign({},a.stateData||{});n.areas&&(c.areas=n.areas),n.profiles&&(c.profiles=n.profiles),n.actuatorTests&&(c.actuatorTests=n.actuatorTests),n.testPlans&&(c.testPlans=n.testPlans),a.stateData=c}else await Mt({fresh:!0});r||await Fa(),T(`AI areas regenerated (${Number(n&&n.generatedCount?n.generatedCount:0)})`)}catch(n){a.areaLlmError=n.message||"Failed to regenerate AI areas",T(a.areaLlmError)}finally{a.areaLlmRegenerating=!1}}}async function Yl(){const s=String(a.selectedNodeId||"").trim();if(a.areaLlmRegenerating||a.areaLlmBulkDeleting)return;if(!s){a.areaLlmError="Select a KNX AI node first",T(a.areaLlmError);return}const n=Number(Pr.value||0);if(n<=0){T("No AI areas to delete");return}if(window.confirm(`Delete all AI-generated areas (${n})?`)){a.areaLlmBulkDeleting=!0,a.areaLlmError="",T("Deleting AI areas...");try{const c=await E(D("areas/delete-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:s})});if(Array.isArray(c&&c.gaCatalog)&&(a.gaCatalog=c.gaCatalog),c&&(c.areas||c.profiles||c.actuatorTests||c.testPlans)){const g=Object.assign({},a.stateData||{});c.areas&&(g.areas=c.areas),c.profiles&&(g.profiles=c.profiles),c.actuatorTests&&(g.actuatorTests=c.actuatorTests),c.testPlans&&(g.testPlans=c.testPlans),a.stateData=g}else await Mt({fresh:!0});Array.isArray(c&&c.gaCatalog)||await Fa(),T(`AI areas deleted (${Number(c&&c.deletedCount?c.deletedCount:n)})`)}catch(c){a.areaLlmError=c.message||"Failed to delete AI areas",T(a.areaLlmError)}finally{a.areaLlmBulkDeleting=!1}}}async function Ql(){if(!a.selectedNodeId||a.areaLlmBusy)return;const s=String(a.areaLlmPrompt||"").trim();if(s){a.areaLlmBusy=!0,a.areaLlmError="",T("AI is selecting area GA...");try{const n=await E(D("areas/suggest-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,prompt:s,name:a.areaDraftName,description:a.areaDraftDescription,gaList:a.areaDraftGaList||[]})}),r=n&&n.suggestion?n.suggestion:null;if(Array.isArray(n&&n.gaCatalog)&&(a.gaCatalog=n.gaCatalog),!r||!Array.isArray(r.gaList)||!r.gaList.length)throw new Error("The AI did not return any group addresses");!String(a.areaDraftName||"").trim()&&r.name&&(a.areaDraftName=String(r.name)),!String(a.areaDraftDescription||"").trim()&&r.description&&(a.areaDraftDescription=String(r.description)),(!a.areaDraftTags||!String(a.areaDraftTags).trim())&&Array.isArray(r.tags)&&r.tags.length&&(a.areaDraftTags=r.tags.join(", ")),a.areaDraftGaList=Array.from(new Set([...a.areaDraftGaList||[],...r.gaList.map(c=>String(c||"").trim()).filter(Boolean)])),a.showAiAreaBuilder=!1,a.areaBuilderFocus=!1,T(`AI added ${Number(r.gaList.length||0)} GA to the draft`)}catch(n){a.areaLlmError=n.message||"Failed to suggest area GA",T(a.areaLlmError)}finally{a.areaLlmBusy=!1}}}function ed(s){if(s&&typeof s=="object"){a.testPlanPrompt=String(s.prompt||"").trim();return}a.testPlanPrompt=String(s||"").trim()}function jr(s){const n=String(s||"").trim();return n&&(Array.isArray(a.testPlanCatalog&&a.testPlanCatalog.pairs)?a.testPlanCatalog.pairs:[]).find(c=>c&&c.command&&c.command.ga===n)||null}function Hr(s){const n=String(s||"").trim();return vs.value.find(r=>r&&r.ga===n)||null}function td(s){const n=String(s||"").trim();return Ir.value.find(r=>r&&r.ga===n)||null}function ia(s){const n=String(s||"").trim();if(!n)return[];const r=a.testPlanCatalog&&a.testPlanCatalog.dptOptionsById&&typeof a.testPlanCatalog.dptOptionsById=="object"?a.testPlanCatalog.dptOptionsById:{};return Array.isArray(r[n])?r[n]:[]}function Bt(s){return String(s||"").trim().normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}const ad=[{type:"on",patterns:[/\bturn on\b/g,/\bturn(?:\s+\w+){1,4}\s+on\b/g,/\bswitch on\b/g,/\bswitch(?:\s+\w+){1,4}\s+on\b/g,/\bpower on\b/g,/\bpower(?:\s+\w+){1,4}\s+on\b/g,/\bstart\b/g,/\benable\b/g,/\bactivate\b/g,/\baccendi\b/g,/\battiva\b/g,/\ballume\b/g,/\bactive\b/g,/\beinschalten\b/g,/\baktivieren\b/g,/\benciende\b/g,/\bactivar\b/g,/\bliga\b/g,/\bativa\b/g,/\baan\b/g,/\binschakelen\b/g]},{type:"off",patterns:[/\bturn off\b/g,/\bturn(?:\s+\w+){1,4}\s+off\b/g,/\bswitch off\b/g,/\bswitch(?:\s+\w+){1,4}\s+off\b/g,/\bpower off\b/g,/\bpower(?:\s+\w+){1,4}\s+off\b/g,/\bdisable\b/g,/\bdeactivate\b/g,/\bshutdown\b/g,/\bspegni\b/g,/\bdisattiva\b/g,/\beteins\b/g,/\bdesactive\b/g,/\bausschalten\b/g,/\bdeaktivieren\b/g,/\bapaga\b/g,/\bdesactiva\b/g,/\bdesliga\b/g,/\bdesativa\b/g,/\buit\b/g,/\buitschakelen\b/g]},{type:"open",patterns:[/\bopen\b/g,/\braise\b/g,/\blift\b/g,/\bmove up\b/g,/\bapri\b/g,/\balza\b/g,/\bsolleva\b/g,/\bouvre\b/g,/\bmonte\b/g,/\boffnen\b/g,/\bhoch\b/g,/\bauf\b/g,/\babre\b/g,/\bsube\b/g,/\babrir\b/g,/\bsobe\b/g,/\bopenen\b/g,/\bomhoog\b/g]},{type:"close",patterns:[/\bclose\b/g,/\blower\b/g,/\bmove down\b/g,/\bchiudi\b/g,/\babbassa\b/g,/\bferme\b/g,/\bdescends?\b/g,/\bschliessen\b/g,/\brunter\b/g,/\bzu\b/g,/\bcierra\b/g,/\bbaja\b/g,/\bfechar\b/g,/\bdesce\b/g,/\bsluiten\b/g,/\bomlaag\b/g]},{type:"stop",patterns:[/\bstop\b/g,/\bhalt\b/g,/\bpause\b/g,/\bferma\b/g,/\barresta\b/g,/\barrete\b/g,/\bstoppe\b/g,/\banhalten\b/g,/\bstopp\b/g,/\bdeten\b/g,/\bparar\b/g,/\bpare\b/g,/\bstoppen\b/g]}];function nd(s){const n=Bt(s);if(!n)return"";const r=[];return ad.forEach(c=>{c.patterns.forEach(g=>{g.lastIndex=0;let N;for(;(N=g.exec(n))!==null;)r.push({type:c.type,index:N.index})})}),r.sort((c,g)=>c.index-g.index),r[0]?r[0].type:""}function sd(s){return["on","open"].includes(String(s||"").trim().toLowerCase())}function rd(s){return["off","close","stop"].includes(String(s||"").trim().toLowerCase())}function ks(s,n,r=""){const c=ia(n);if(!c.length)return String(s??"");const g=String(s??"").trim(),N=Bt(g),R=Bt(r),B=`${N} ${R}`.trim(),z=nd(r||B);if(z){if(sd(z)){const Y=c.find(he=>["true","1","100"].includes(String(he.value)));if(Y)return String(Y.value);const ee=c.find(he=>/\b(on|open|up|start|enable|enabled|active|acceso|accesa|aperto|aperta|su|einschalten|allume|enciende|liga|aan)\b/.test(Bt(he.label)));if(ee)return String(ee.value)}if(rd(z)){const Y=c.find(he=>["false","0"].includes(String(he.value)));if(Y)return String(Y.value);const ee=c.find(he=>/\b(off|close|down|stop|disable|disabled|inactive|chiuso|spento|giu|ausschalten|eteins|apaga|desliga|uit)\b/.test(Bt(he.label)));if(ee)return String(ee.value)}}if(c.some(Y=>String(Y.value)===g))return g;const Q=c.find(Y=>Bt(Y.label)===N);if(Q)return String(Q.value);const q=c.find(Y=>{const ee=Bt(Y.label);return N&&(ee.includes(N)||N.includes(ee))});if(q)return String(q.value);const pe=/\b(on|open|up|true|1|accendi|attiva|apri|su|acceso|accesa|accesi|accese|aperto|aperta|enabled|enable|start|allume|einschalten|enciende|liga|aan)\b/,Z=/\b(off|close|down|false|0|spegni|disattiva|chiudi|giu|spento|spenta|spenti|spente|chiuso|chiusa|disabled|disable|stop|ferma|eteins|ausschalten|apaga|desliga|uit)\b/;if(pe.test(B)){const Y=c.find(he=>["true","1","100"].includes(String(he.value)));if(Y)return String(Y.value);const ee=c.find(he=>/\b(on|open|up|start|enable|enabled|active|acceso|accesa|aperto|aperta|su)\b/.test(Bt(he.label)));if(ee)return String(ee.value)}if(Z.test(B)){const Y=c.find(he=>["false","0"].includes(String(he.value)));if(Y)return String(Y.value);const ee=c.find(he=>/\b(off|close|down|stop|disable|disabled|inactive|spento|spenta|chiuso|chiusa|giu)\b/.test(Bt(he.label)));if(ee)return String(ee.value)}return String(c[0].value)}function En(s){if(!s)return;const n=ia(s.commandDPT),r=ia(s.statusDPT||s.commandDPT),c=String(s.action||"").trim().toLowerCase();n.length&&(s.commandPayload=ks(s.commandPayload,s.commandDPT,c||`${s.title||""} ${s.description||""} ${s.reason||""}`)),r.length&&(s.expectedPayload=ks(s.expectedPayload,s.statusDPT||s.commandDPT,c||`${s.title||""} ${s.description||""} ${s.reason||""}`))}function xs(s={}){if(String(s.kind||"").trim().toLowerCase()==="wait")return{id:String(s.id||`step-${Date.now()}-${Math.round(Math.random()*1e3)}`),kind:"wait",action:"",collapsed:s.collapsed!==!1,title:String(s.title||"Wait"),description:String(s.description||""),reason:String(s.reason||""),delayMs:Number(s.delayMs||s.readDelayMs||1200),commandGA:"",commandDPT:"",commandPayload:"",statusGA:"",statusDPT:"",expectedPayload:"",statusWriteTimeoutMs:0,statusResponseTimeoutMs:0};const r=String(s.commandGA||"").trim()||String(vs.value[0]?.ga||""),c=jr(r),g=Hr(r),N=c&&c.status?c.status:null,R={id:String(s.id||`step-${Date.now()}-${Math.round(Math.random()*1e3)}`),kind:String(s.kind||(N?"write_and_verify":"write_only")),action:String(s.action||"").trim().toLowerCase(),collapsed:s.collapsed!==!1,title:String(s.title||(g?`Step ${g.label}`:"Manual Step")),description:String(s.description||""),reason:String(s.reason||""),commandGA:r,commandDPT:String(s.commandDPT||g?.dpt||""),commandPayload:String(s.commandPayload??""),statusGA:String(s.statusGA||N?.ga||""),statusDPT:String(s.statusDPT||N?.dpt||""),expectedPayload:String(s.expectedPayload??s.commandPayload??""),statusWriteTimeoutMs:Number(s.statusWriteTimeoutMs||s.timeoutMs||5e3),statusResponseTimeoutMs:Number(s.statusResponseTimeoutMs||s.timeoutMs||5e3)};return En(R),R}function Gn(s){const n=Ft(s,null);return n?(n.steps=(Array.isArray(n.steps)?n.steps:[]).map(r=>xs(r)),n):null}function id(){return Gn({id:"",name:"",description:"",areaId:ot.value?String(ot.value.id||""):"",areaName:ot.value?String(ot.value.path||ot.value.name||""):"",prompt:"",source:"manual",generatedAt:new Date().toISOString(),steps:[]})}function Xr(s){if(!s||s.kind==="wait")return;const n=Hr(s.commandGA),r=td(s.statusGA),c=jr(s.commandGA);n&&(s.commandDPT=String(n.dpt||"")),r&&(s.statusDPT=String(r.dpt||"")),c&&c.status&&(!s.statusGA||s.statusGA==="")&&(s.statusGA=String(c.status.ga||""),s.statusDPT=String(c.status.dpt||""),s.kind="write_and_verify"),s.statusGA&&(s.kind="write_and_verify"),s.expectedPayload||(s.expectedPayload=String(s.commandPayload??"")),s.statusGA||(s.statusDPT="",s.kind="write_only"),En(s)}function od(){if(!a.testPlanDraft)return;const s={id:`step-${Date.now()}-${Math.round(Math.random()*1e3)}`,kind:"write_only",action:"",collapsed:!0,title:"Manual Step",description:"",reason:"",commandGA:"",commandDPT:"",commandPayload:"",statusGA:"",statusDPT:"",expectedPayload:"",statusWriteTimeoutMs:5e3,statusResponseTimeoutMs:5e3};a.testPlanDraft.steps=[...a.testPlanDraft.steps||[],s]}function ld(){if(!a.testPlanDraft)return;const s=xs({id:`wait-${(a.testPlanDraft.steps?.length||0)+1}`,kind:"wait",title:"Wait",description:"Pause the test before the next action.",delayMs:1200});a.testPlanDraft.steps=[...a.testPlanDraft.steps||[],s]}function dd(s){if(!a.testPlanDraft||!Array.isArray(a.testPlanDraft.steps))return;const n=a.testPlanDraft.steps[s];if(!n)return;const r=xs(Object.assign({},n,{id:`${n.id||"step"}-copy`}));a.testPlanDraft.steps.splice(s+1,0,r)}function ud(s){!a.testPlanDraft||!Array.isArray(a.testPlanDraft.steps)||a.testPlanDraft.steps.splice(s,1)}function cd(s){s&&(s.collapsed=s.collapsed!==!0)}function Es(){a.draggedTestPlanStepId="",a.dragOverTestPlanStepId=""}function fd(s,n){const r=String(s||"").trim();r&&(a.draggedTestPlanStepId=r,a.dragOverTestPlanStepId="",n&&n.dataTransfer&&(n.dataTransfer.effectAllowed="move",n.dataTransfer.setData("text/plain",r)))}function pd(s){const n=String(s||"").trim();!n||!a.draggedTestPlanStepId||n===a.draggedTestPlanStepId||(a.dragOverTestPlanStepId=n)}function gd(s,n){if(!a.testPlanDraft||!Array.isArray(a.testPlanDraft.steps))return;const r=String(s||"").trim(),c=String(n||"").trim();if(!r||!c||r===c)return;const g=a.testPlanDraft.steps.slice(),N=g.findIndex(z=>String(z&&z.id?z.id:"")===r),R=g.findIndex(z=>String(z&&z.id?z.id:"")===c);if(N===-1||R===-1)return;const[B]=g.splice(N,1);g.splice(R,0,B),a.testPlanDraft.steps=g}function hd(s,n){n&&n.preventDefault();const r=String(a.draggedTestPlanStepId||"").trim(),c=String(s||"").trim();r&&c&&r!==c&&gd(r,c),Es()}function md(){!a.testPlanDraft||a.testPlanRunning||(a.testPlanRunMode="single",a.testPlanRepeatStopRequested=!1,a.testPlanRunConfirmOpen=!0)}function vd(){!a.testPlanDraft||a.testPlanRunning||(a.testPlanRunMode="repeat",a.testPlanRepeatStopRequested=!1,a.testPlanRunConfirmOpen=!0)}function qr(){a.testPlanRunConfirmOpen=!1,a.testPlanRunMode="single"}function bd(){a.testPlanRepeatForever===!0&&(a.testPlanRepeatStopRequested=!0,T("Stopping repeat mode after the current cycle..."))}function Jr(s=null){const n=s||sa.value;n&&(a.testResultFocusMode=!1,a.testPlanSelectedId=String(n.id||""),a.testPlanDraft=Gn(n),a.testPlanPrompt=String(n.prompt||""),a.testPlanGeneration={provider:String(n.source||"saved"),model:"",fallback:!1,error:""},a.testPlanRunConfirmOpen=!1,a.showAiPlanner=!1,a.testTemplateBuilderFocus=!1,Ga())}function Gs(){Ca=null,a.testPlanPendingActionLabel=""}function Zr(){a.testPlanUnsavedConfirmOpen=!1,Gs()}function Yr(){const s=Ca;a.testPlanUnsavedConfirmOpen=!1,Gs(),typeof s=="function"&&s()}function Fs(s,n="another plan"){if(!Cr.value){s();return}Ca=s,a.testPlanPendingActionLabel=String(n||"another plan"),a.testPlanUnsavedConfirmOpen=!0}function yd(s){if(!s||!s.id)return;const n=String(s.id);a.testPlanSelectedId!==n&&Fs(()=>Jr(s),`plan "${s.name||n}"`)}function Ad(){Qo(),T("Plan changes discarded")}async function Sd(){await ei()&&Yr()}function Qr(){if(!Ae.value.length){T("Define at least one area before creating a test plan");return}Fs(()=>{a.activeTab="tests",a.testResultFocusMode=!1,a.testPlanSelectedId="",a.testPlanDraft=id(),a.testPlanGeneration=null,a.testPlanRunConfirmOpen=!1,a.testPlanPrompt="",a.showAiPlanner=!1,a.testTemplateBuilderFocus=!1,Ga()},"a new plan")}function wd(s){const n=String(s||"").trim();if(!n)return;const r=Ae.value.find(c=>c&&c.id===n);r&&(a.testAreaSelectedId=n,a.testPlanDraft&&(a.testPlanDraft.areaId=n,a.testPlanDraft.areaName=String(r.path||r.name||"")))}function Pd(){const s=Ft(a.testPlanDraft||sa.value,null);s&&(a.activeTab="tests",a.testResultFocusMode=!1,a.testPlanSelectedId="",a.testPlanRunConfirmOpen=!1,a.testPlanGeneration={provider:"duplicated",model:"",fallback:!1,error:""},s.id="",s.name=String(s.name||"Plan Draft").trim()?`${String(s.name||"Plan Draft").trim()} Copy`:"Plan Copy",a.testPlanPrompt=String(s.prompt||a.testPlanPrompt||""),a.testPlanDraft=Gn(s),a.showAiPlanner=!0,a.testTemplateBuilderFocus=!1,Ga(),T("Plan duplicated"))}async function Td(){const s=ot.value,n=String(a.testPlanPrompt||"").trim(),r=Hl();if(!(!a.selectedNodeId||!s||!n||a.testPlanGenerating)){a.testPlanGenerating=!0,a.testTemplateBuilderFocus=!1,a.showAiPlanner=!1,a.testResultFocusMode=!1,a.testPlanGenerationError="",T("Building test plan...");try{const c=await E(D("test-plans/generate"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:s.id,prompt:n,language:r})});a.testPlanDraft=c&&c.plan?Gn(c.plan):null,a.testPlanCatalog=c&&c.catalog?c.catalog:a.testPlanCatalog,a.testPlanGeneration=c&&c.generation?c.generation:null,a.testPlanGenerationError="",a.testPlanSelectedId="",a.testPlanRunConfirmOpen=!1,a.showAiPlanner=!1,c&&c.testPlans&&(a.stateData=Object.assign({},a.stateData||{},{testPlans:c.testPlans})),Ga(),T("Test plan ready")}catch(c){const g=c.message||"Failed to build the test plan";a.lastError=g,a.testPlanGenerationError=g,a.testPlanGeneration={provider:"",model:"",fallback:!1,error:g},T(g)}finally{a.testPlanGenerating=!1}}}async function ei(){if(!a.selectedNodeId||!a.testPlanDraft||a.testPlanSaving)return!1;a.testPlanSaving=!0,T("Saving test plan...");try{const s=await E(D("test-plans/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,plan:Object.assign({},a.testPlanDraft,{prompt:a.testPlanPrompt})})});return s&&s.testPlans&&(a.stateData=Object.assign({},a.stateData||{},{testPlans:s.testPlans})),s&&s.planId&&(a.testPlanSelectedId=s.planId),s&&s.planId&&a.testPlanDraft&&(a.testPlanDraft.id=s.planId),a.testPlanRunConfirmOpen=!1,Ga(),T("Test plan saved"),!0}catch(s){return a.lastError=s.message||"Failed to save test plan",T(a.lastError),!1}finally{a.testPlanSaving=!1}}async function _d(){const s=sa.value;if(!(!s||!a.selectedNodeId||a.testPlanDeleting)){a.testPlanDeleting=!0,T("Deleting test plan...");try{const n=await E(D("test-plans/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,planId:s.id})});n&&n.testPlans&&(a.stateData=Object.assign({},a.stateData||{},{testPlans:n.testPlans})),a.testPlanDraft=null,a.testPlanGeneration=null,a.testPlanRunConfirmOpen=!1,a.showAiPlanner=!0,a.testTemplateBuilderFocus=!1,Ga(),T("Test plan deleted")}catch(n){a.lastError=n.message||"Failed to delete test plan",T(a.lastError)}finally{a.testPlanDeleting=!1}}}async function Dd(s="single"){if(!a.selectedNodeId||!a.testPlanDraft||a.testPlanRunning)return;const r=String(s||a.testPlanRunMode||"single").trim().toLowerCase()==="repeat";a.testPlanRunning=!0,a.showAiPlanner=!1,a.testTemplateBuilderFocus=!1,a.testPlanRepeatForever=r,a.testPlanRepeatStopRequested=!1,a.testPlanRunningStepId="",a.testPlanRunConfirmOpen=!1,a.lastError="",T(r?"Running test plan in repeat mode...":"Running test plan...");try{const c=JSON.parse(JSON.stringify(Object.assign({},a.testPlanDraft,{prompt:a.testPlanPrompt}))),g=Array.isArray(c.steps)?c.steps:[];if(!c.areaId)throw new Error("Missing areaId in test plan");if(!g.length)throw new Error("The test plan has no executable steps");let N=ot.value,R=0;do{R+=1;const z=`${c.id||"plan"}:${Date.now()}`,Q=[];a.liveTestResultId=z,a.testResultsMenuOpen=!0,xn(z,{openMenu:!0,activateResultsTab:!0,resultOnly:!0}),a.stateData=Object.assign({},a.stateData||{},{testPlanReport:Ps({plan:c,area:N,stepResults:[],reportId:z})});try{await Lr(c.name||"Test plan",c.description||"")}catch{}for(let pe=0;pe<g.length;pe+=1){const Z=g[pe];a.testPlanRunningStepId=Z&&Z.id?Z.id:"";const Y=r?`Cycle ${R} · `:"";T(`${Y}Step ${pe+1}/${g.length}: ${Z&&Z.title?Z.title:"Running..."}`);try{await _l(Z||{title:`Step ${pe+1}`},pe+1)}catch{T(`Voice unavailable for step ${pe+1}. Continuing test...`)}try{const ee=await E(D("test-plans/run-step"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,areaId:c.areaId,step:Z})});ee&&ee.area&&(N=ee.area),Q.push(ee&&ee.stepResult?ee.stepResult:Gr(Z,new Error("Step returned no result")))}catch(ee){Q.push(Gr(Z,ee))}a.stateData=Object.assign({},a.stateData||{},{testPlanReport:Ps({plan:c,area:N,stepResults:Q.slice(),reportId:z})})}const q=Ps({plan:c,area:N,stepResults:Q,reportId:z});a.stateData=Object.assign({},a.stateData||{},{testPlans:yt.value,testPlanReport:q}),xn(z,{openMenu:!0,activateResultsTab:!0,resultOnly:!0});try{await Ol(q)}catch(pe){a.lastError=pe.message||"Failed to save test result",T(`Test completed, but the result was not saved: ${a.lastError}`)}r&&a.testPlanRepeatStopRequested!==!0&&(a.testResultFocusMode=!1,T(`Cycle ${R} completed. Starting the next cycle...`))}while(r&&a.testPlanRepeatStopRequested!==!0);const B=r?"Repeat mode stopped":"Test completed";a.testPlanRunConfirmOpen=!1,a.lastError||T(B);try{await Lr(Me(B))}catch{}requestAnimationFrame(()=>{try{Ee.value&&typeof Ee.value.scrollIntoView=="function"&&Ee.value.scrollIntoView({behavior:"smooth",block:"start"})}catch{}})}catch(c){a.lastError=c.message||"Failed to run test plan",T(a.lastError)}finally{a.testPlanRunningStepId="",ka(),a.testPlanRunning=!1,a.testPlanRepeatForever=!1,a.testPlanRepeatStopRequested=!1,a.testPlanRunMode="single"}}async function Nd(){if(a.selectedNodeId){T("Exporting config...");try{const s=await E(D("config/export"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId})}),n=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),r=window.URL.createObjectURL(n),c=document.createElement("a");c.href=r,c.download=`knx-ai-config-${a.selectedNodeId}.json`,document.body.appendChild(c),c.click(),document.body.removeChild(c),window.URL.revokeObjectURL(r),T("Config exported")}catch(s){a.lastError=s.message||"Failed to export config",T(a.lastError)}}}function Id(){Ra.value&&Ra.value.click()}async function Rd(s){const n=s&&s.target&&s.target.files&&s.target.files[0]?s.target.files[0]:null;if(!(!n||!a.selectedNodeId)){T("Importing config...");try{const r=await n.text(),c=JSON.parse(r),g=await E(D("config/import"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:a.selectedNodeId,config:c})});a.stateData=Object.assign({},a.stateData||{},{areas:g.areas||ba.value,profiles:g.profiles||ya.value,actuatorTests:g.actuatorTests||Aa.value,testPlans:g.testPlans||yt.value,testResults:g.testResults||Ja.value}),await Fa(),T("Config imported")}catch(r){a.lastError=r.message||"Failed to import config",T(a.lastError)}finally{s&&s.target&&(s.target.value="")}}}function Cd(){a.pollStateHandle||(a.pollStateHandle=window.setInterval(()=>{a.autoRefresh&&Mt({fresh:!1})},1500)),a.pollNodesHandle||(a.pollNodesHandle=window.setInterval(()=>{Ns({preserveSelection:!0})},15e3))}function kd(){a.pollStateHandle&&(window.clearInterval(a.pollStateHandle),a.pollStateHandle=null),a.pollNodesHandle&&(window.clearInterval(a.pollNodesHandle),a.pollNodesHandle=null)}return Po(async()=>{A.value=ge(),Et(),window.addEventListener("resize",Et),document.addEventListener("keydown",y),document.addEventListener("fullscreenchange",F),await Ns({preserveSelection:!1}),await Mt({fresh:!0}),await Fa(),Cd(),ha()}),To(()=>{window.removeEventListener("resize",Et),document.removeEventListener("keydown",y),document.removeEventListener("fullscreenchange",F),bt(),kd(),ka()}),(s,n)=>(v(),b(X,null,[l("header",uf,[n[46]||(n[46]=l("div",{class:"m-header-brand"},[l("span",{class:"m-logo-mark"},"K"),l("span",{class:"hb-logo-text-mobile"},"KNX AI")],-1)),l("button",{class:de(["hamburger-icon",{"hamburger-icon-cross":Ze.value}]),type:"button","aria-expanded":Ze.value?"true":"false","aria-controls":"knx-ai-sidebar","aria-label":"Toggle menu",onClick:fs},[...n[45]||(n[45]=[l("span",null,null,-1),l("span",null,null,-1),l("span",null,null,-1),l("span",null,null,-1)])],10,cf)]),Be.value&&Ze.value?(v(),b("button",{key:0,class:"sidebar-overlay",type:"button","aria-label":"Close menu",onClick:h})):G("",!0),l("div",{class:de(["page-shell",{"sidebar-collapsed":!Ze.value,"sidebar-mobile-open":Be.value&&Ze.value}])},[l("aside",ff,[l("div",pf,[n[47]||(n[47]=l("div",{class:"sidebar-brand-mark","aria-hidden":"true"},"K",-1)),n[48]||(n[48]=l("div",{class:"sidebar-brand"},[l("p",{class:"eyebrow"},"KNX Ultimate")],-1)),l("button",{class:"sidebar-collapse-toggle",type:"button","aria-expanded":Ze.value?"true":"false","aria-controls":"knx-ai-sidebar","aria-label":"Toggle sidebar",onClick:fs},[l("span",hf,S(Ze.value?Be.value?"×":"‹":"›"),1)],8,gf)]),l("nav",mf,[l("button",{class:de(["tab-button",{active:a.activeTab==="overview"}]),type:"button",title:"Overview","aria-label":"Overview",onClick:n[0]||(n[0]=r=>Sa("overview"))},[...n[49]||(n[49]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M3 10.8 12 3l9 7.8v9.2a1 1 0 0 1-1 1h-5v-6h-6v6H4a1 1 0 0 1-1-1z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Overview</span></span>',2)])],2),l("button",{class:de(["tab-button",{active:a.activeTab==="areas"}]),type:"button",title:"Areas","aria-label":"Areas",onClick:n[1]||(n[1]=r=>Sa("areas"))},[...n[50]||(n[50]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M3 3h8v8H3zm10 0h8v8h-8zM3 13h8v8H3zm10 0h8v8h-8z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Areas</span></span>',2)])],2),l("button",{class:de(["tab-button sidebar-nav-child",{active:a.activeTab==="tests"}]),type:"button",title:"Tests","aria-label":"Tests",disabled:!Ae.value.length,onClick:n[2]||(n[2]=r=>Sa("tests"))},[...n[51]||(n[51]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M9 3h6v2h-1v4.3l5.5 8.8A2 2 0 0 1 17.8 21H6.2a2 2 0 0 1-1.7-2.9L10 9.3V5H9zm1.9 8.2L6.9 18h10.2l-4-6.8z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Tests</span></span>',2)])],10,vf),l("button",{class:de(["tab-button sidebar-nav-child",{active:a.activeTab==="results"}]),type:"button",title:"Test Results","aria-label":"Test Results",onClick:n[3]||(n[3]=r=>Sa("results"))},[...n[52]||(n[52]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M4 4h16v4H4zm0 6h16v4H4zm0 6h16v4H4z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Test Results</span></span>',2)])],2),l("button",{class:de(["tab-button",{active:a.activeTab==="assistant"}]),type:"button",title:"Assistant","aria-label":"Assistant",onClick:n[4]||(n[4]=r=>Sa("assistant"))},[...n[53]||(n[53]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M4 5h16a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9l-5 4v-4H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Assistant</span></span>',2)])],2),l("button",{class:de(["tab-button",{active:a.activeTab==="flowBuilder"}]),type:"button",title:"Flow Builder","aria-label":"Flow Builder",onClick:n[5]||(n[5]=r=>Sa("flowBuilder"))},[...n[54]||(n[54]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M2 5h8v4H6v2h6.2a3 3 0 0 1 2.8-2H22v4h-7a1 1 0 0 0-1 1v0a1 1 0 0 0 1 1h7v4h-7a3 3 0 0 1-2.8-2H6v2h4v4H2v-4h2v-6H2zm18 0h2v4h-2z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Flow Builder</span></span>',2)])],2),l("button",{class:de(["tab-button",{active:a.activeTab==="settings"}]),type:"button",title:"Settings","aria-label":"Settings",onClick:n[6]||(n[6]=r=>Sa("settings"))},[...n[55]||(n[55]=[ua('<span class="sidebar-nav-icon" aria-hidden="true" data-v-521d66a3><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-521d66a3><path d="M19.14 12.94a7.43 7.43 0 0 0 .05-.94 7.43 7.43 0 0 0-.05-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.18 7.18 0 0 0-1.63-.94l-.36-2.54A.5.5 0 0 0 13.9 2h-3.8a.5.5 0 0 0-.49.42l-.36 2.54a7.18 7.18 0 0 0-1.63.94l-2.39-.96a.5.5 0 0 0-.6.22L2.71 8.48a.5.5 0 0 0 .12.64l2.03 1.58a7.43 7.43 0 0 0-.05.94 7.43 7.43 0 0 0 .05.94l-2.03 1.58a.5.5 0 0 0-.12.64l1.92 3.32a.5.5 0 0 0 .6.22l2.39-.96c.5.39 1.04.71 1.63.94l.36 2.54a.5.5 0 0 0 .49.42h3.8a.5.5 0 0 0 .49-.42l.36-2.54c.59-.23 1.13-.55 1.63-.94l2.39.96a.5.5 0 0 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.64zM12 15.2A3.2 3.2 0 1 1 12 8.8a3.2 3.2 0 0 1 0 6.4z" data-v-521d66a3></path></svg></span><span class="sidebar-nav-copy" data-v-521d66a3><span class="sidebar-nav-title" data-v-521d66a3>Settings</span></span>',2)])],2)]),Ze.value?(v(),b("div",bf,[l("button",{class:"primary-button sidebar-action-button",type:"button",disabled:a.loadingNodes||a.loadingState,onClick:Nl}," Refresh ",8,yf),l("div",{class:"support-link-row"},[l("a",{class:"secondary-button support-link-button",href:uy,target:"_blank",rel:"noopener noreferrer"}," Donate via PayPal "),l("a",{class:"secondary-button support-link-button support-link-button-youtube",href:cy,target:"_blank",rel:"noopener noreferrer"}," Subscribe ")])])):G("",!0),Ze.value?(v(),b("div",Af,[l("span",{class:de(["status-pill",{error:!!a.lastError}])},[a.loadingNodes||a.loadingState||a.areaLlmRegenerating||a.areaLlmBulkDeleting||a.areaLlmBusy||a.testPlanGenerating||a.asking?(v(),b("span",Sf)):G("",!0),l("span",null,S(a.status),1)],2),In.value?(v(),b("span",wf,"Provider: "+S(In.value.llmProvider||"n/a")+" | Model: "+S(In.value.llmModel||"n/a"),1)):G("",!0),l("a",{class:"sidebar-doc-link",href:dy,target:"_blank",rel:"noopener noreferrer"}," Documentation: KNX AI Vue ")])):G("",!0)]),l("section",Pf,[l("main",Tf,[a.activeTab==="overview"?(v(),b("section",_f,[l("div",Df,[n[56]||(n[56]=l("h2",null,"Summary",-1)),Ge.value.meta?.generatedAt?(v(),b("span",Nf,S(Gt(Ge.value.meta.generatedAt)),1)):G("",!0)]),l("pre",If,S(hl.value),1),l("div",Rf,[l("article",Cf,[n[57]||(n[57]=l("span",null,"Telegrams",-1)),l("strong",null,S(Number(Ge.value.counters?.telegrams||0)),1)]),l("article",kf,[n[58]||(n[58]=l("span",null,"Rate",-1)),l("strong",null,S(Number(Ge.value.counters?.overallRatePerSec||0))+"/s",1)]),l("article",xf,[n[59]||(n[59]=l("span",null,"Repeat",-1)),l("strong",null,S(Number(Ge.value.counters?.repeated||0)),1)]),l("article",Ef,[n[60]||(n[60]=l("span",null,"Unknown DPT",-1)),l("strong",null,S(Number(Ge.value.counters?.unknownDpt||0)),1)])])])):G("",!0),a.activeTab==="areas"?(v(),b("section",Gf,[l("div",Ff,[n[61]||(n[61]=l("h2",null,"Select an Area",-1)),l("div",Of,[l("span",Lf,S(Number(qa.value.suggestedAreaCount||0))+" areas",1),l("button",{class:"secondary-button",type:"button",disabled:a.areaLlmRegenerating||a.areaLlmBulkDeleting||!ct.value.llmEnabled,onClick:Zl},[a.areaLlmRegenerating?(v(),b("span",Bf)):G("",!0),l("span",null,S(a.areaLlmRegenerating?"Regenerating...":"Regenerate AI Areas"),1)],8,Mf),l("button",{class:"danger-button",type:"button",disabled:a.areaLlmRegenerating||a.areaLlmBulkDeleting||Pr.value<=0,onClick:Yl},[a.areaLlmBulkDeleting?(v(),b("span",$f)):G("",!0),l("span",null,S(a.areaLlmBulkDeleting?"Deleting...":"Delete AI Areas"),1)],8,zf),l("button",{class:"secondary-button new-button",type:"button",onClick:Jl}," New Area ")])]),a.areaLlmError?(v(),b("p",Kf,S(a.areaLlmError),1)):G("",!0),l("div",Vf,[l("div",Wf,[l("span",Uf,"GA "+S(Number(qa.value.gaCount||0)),1),l("span",jf,"Hierarchical "+S(Number(qa.value.hierarchicalGaCount||0)),1),l("span",Hf,"Secondary "+S(Number(qa.value.secondaryGroupCount||0)),1),l("span",Xf,"Active "+S(Number(qa.value.activeAreaCount||0)),1)])]),ms.value.length||a.areaDraftIsNew?(v(),b("div",qf,[!Fe.value&&!a.areaDraftIsNew?(v(),b("div",Jf,[l("label",Zf,[n[62]||(n[62]=l("span",null,"Areas",-1)),l("div",Yf,[fe(l("input",{"onUpdate:modelValue":n[7]||(n[7]=r=>a.areaSearch=r),class:"area-search-select-input",type:"text",placeholder:Fe.value?Wr(Fe.value):"Search area...",onFocus:n[8]||(n[8]=r=>a.areaSearchOpen=!0),onInput:n[9]||(n[9]=r=>a.areaSearchOpen=!0),onBlur:Wl},null,40,Qf),[[Ce,a.areaSearch]]),a.areaSearchOpen&&ms.value.length?(v(),b("div",ep,[(v(!0),b(X,null,se(ms.value.slice(0,80),r=>(v(),b("button",{key:r.id,type:"button",class:de(["area-search-select-option",{active:Fe.value&&Fe.value.id===r.id}]),onMousedown:Wt(c=>Vl(r),["prevent"])},S(Wr(r)),43,tp))),128))])):G("",!0)])])])):G("",!0),Fe.value||a.areaDraftIsNew?(v(),b("article",{key:1,class:de(["area-detail",{"area-detail-wide":a.areaDraftIsNew}])},[l("div",ap,[a.areaBuilderFocus!==!0?(v(),b("div",np,[n[63]||(n[63]=l("div",null,[l("h4",null,"Edit Area"),l("p",{class:"area-detail-subhead"},"The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.")],-1)),l("div",sp,[a.areaDraftIsNew&&!Rr.value?(v(),b("button",{key:0,class:"secondary-button",type:"button",onClick:kl}," Show AI Area Builder ")):G("",!0),a.areaDraftIsNew?G("",!0):(v(),b("button",{key:1,class:"danger-button",type:"button",disabled:a.areaSaving,onClick:$l}," Delete Area ",8,rp)),l("button",{class:"secondary-button",type:"button",disabled:a.areaSaving,onClick:zl}," Reset ",8,ip),l("button",{class:"primary-button",type:"button",disabled:a.areaSaving,onClick:Bl},S(a.areaSaving?"Saving...":"Save Area"),9,op),l("button",{class:"secondary-button",type:"button",disabled:a.areaSaving,onClick:El}," Close ",8,lp)])])):G("",!0),a.areaBuilderFocus!==!0?(v(),b("div",dp,[l("label",up,[n[64]||(n[64]=l("span",null,"Area name",-1)),fe(l("input",{"onUpdate:modelValue":n[10]||(n[10]=r=>a.areaDraftName=r),type:"text",placeholder:"Installer alias"},null,512),[[Ce,a.areaDraftName]])]),l("label",cp,[n[65]||(n[65]=l("span",null,"Description",-1)),fe(l("textarea",{"onUpdate:modelValue":n[11]||(n[11]=r=>a.areaDraftDescription=r),rows:"3",placeholder:"Optional note for diagnostics and reports"},null,512),[[Ce,a.areaDraftDescription]])]),l("label",fp,[n[66]||(n[66]=l("span",null,"Add group addresses to this area",-1)),fe(l("input",{"onUpdate:modelValue":n[12]||(n[12]=r=>a.gaCatalogSearch=r),type:"text",placeholder:"Search GA, label or ETS path"},null,512),[[Ce,a.gaCatalogSearch]])])])):G("",!0),a.areaDraftIsNew&&Rr.value?(v(),b("div",pp,[l("div",{class:de(["ai-planner-shell-head",{"template-builder-focus-head":a.areaBuilderFocus===!0}])},[n[67]||(n[67]=l("div",null,[l("h4",null,"AI Area Builder"),l("p",{class:"area-detail-subhead"},"Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.")],-1)),a.areaBuilderFocus===!0?(v(),b("div",gp,[l("button",{class:"secondary-button",type:"button",onClick:xl}," Close ")])):G("",!0)],2),l("div",hp,[l("label",mp,[n[68]||(n[68]=l("span",null,"Assistant prompt",-1)),fe(l("textarea",{"onUpdate:modelValue":n[13]||(n[13]=r=>a.areaLlmPrompt=r),rows:"3",placeholder:"Example: Add all technical room lighting command and status GA."},null,512),[[Ce,a.areaLlmPrompt]])])]),l("div",vp,[l("button",{class:"primary-button",type:"button",disabled:a.areaLlmBusy||!a.areaLlmPrompt.trim()||!ct.value.llmEnabled,onClick:Ql},[a.areaLlmBusy?(v(),b("span",yp)):G("",!0),le(" "+S(a.areaLlmBusy?"Suggesting...":"Suggest GA with AI"),1)],8,bp)]),a.areaLlmError?(v(),b("p",Ap,S(a.areaLlmError),1)):G("",!0),ct.value.llmEnabled?G("",!0):(v(),b("p",Sp," Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft. "))])):G("",!0),a.areaBuilderFocus!==!0?(v(),b("div",wp,[l("div",null,[n[70]||(n[70]=l("h4",null,"Area GA membership",-1)),Nr.value.length?(v(),b("ul",Pp,[(v(!0),b(X,null,se(Nr.value,r=>(v(),b("li",{key:r.ga,class:"area-ga-item"},[l("div",Tp,[l("strong",null,S(r.ga),1),l("span",null,[le(S(r.label||"Unlabeled GA"),1),r.dpt?(v(),b("span",_p," | DPT "+S(r.dpt),1)):G("",!0)]),l("span",null,[le("Role "+S(Vr(r.role)),1),r.roleSource?(v(),b("span",Dp," | source "+S(r.roleSource),1)):G("",!0)])]),l("div",Np,[l("label",Ip,[n[69]||(n[69]=l("span",null,"Role",-1)),l("select",{value:r.roleOverride&&r.roleOverride!=="auto"?r.roleOverride:r.role||"neutral",disabled:a.areaGaRoleSavingGa===r.ga,onChange:c=>ql(r.ga,c.target.value)},[(v(),b(X,null,se(o,c=>l("option",{key:c.value,value:c.value},S(c.label),9,Cp)),64))],40,Rp)]),l("button",{class:"secondary-button",type:"button",onClick:c=>Xl(r.ga)}," Remove ",8,kp)])]))),128))])):(v(),b("p",xp,"No GA selected for this area yet."))]),l("div",null,[l("div",Ep,[n[71]||(n[71]=l("div",null,[l("h4",null,"Available GA"),l("p",{class:"area-detail-subhead"},"Pick from the ETS catalog. Already selected GA are hidden from this list.")],-1)),l("span",Gp,S(a.gaCatalogLoading?"Loading...":`${Dr.value.length} visible`),1)]),l("div",Fp,[(v(!0),b(X,null,se(Dr.value,r=>(v(),b("button",{key:r.ga,type:"button",class:"area-list-item",onClick:c=>Kl(r.ga)},[l("span",Lp,S(r.ga),1),l("span",Mp,S(r.label||"Unlabeled GA"),1),l("span",Bp,[le(S(r.hierarchyPath||r.dpt||""),1),r.role?(v(),b("span",zp," | "+S(Vr(r.role)),1)):G("",!0)])],8,Op))),128))])])])):G("",!0),a.areaBuilderFocus!==!0?(v(),b("p",$p,[n[72]||(n[72]=le(" Original ETS path: ",-1)),l("strong",null,S(a.areaDraftIsNew?"Manual area":Fe.value.basePath||Fe.value.path||Fe.value.name),1)])):G("",!0)])],2)):G("",!0)])):(v(),b("p",Kp,"No areas matched the current search or the ETS file does not expose a usable hierarchy yet."))])):G("",!0),a.activeTab==="tests"?(v(),b("section",{key:2,class:de(["card card-profiles",{"card-results-focus":At.value}])},[l("div",Vp,[l("div",null,[l("h2",null,S(At.value?"Test Result":"Test Planner"),1),l("p",Wp,S(At.value?"Showing only the selected test report.":"Select an area, choose a standard test template, review the generated plan, then save or run it."),1)]),At.value?(v(),b("div",qp,[l("span",Jp,S(Za(ne.value)),1),l("button",{class:"danger-button",type:"button",disabled:!ne.value||a.deletingTestResultId===ne.value.id,onClick:n[14]||(n[14]=r=>Rs(ne.value?.id))},S(a.deletingTestResultId===ne.value?.id?"Deleting...":"Delete"),9,Zp),l("button",{class:"secondary-button",type:"button",onClick:$r}," Open Source Test ")])):(v(),b("div",Up,[l("span",jp,"Area "+S(ot.value?ot.value.path||ot.value.name:"n/a"),1),l("span",Hp,S(yt.value.length)+" saved plans",1),l("button",{class:"secondary-button",type:"button",disabled:!a.testPlanDraft,onClick:Pd}," Duplicate Plan ",8,Xp),l("button",{class:"secondary-button new-button",type:"button",onClick:Qr}," New Plan ")]))]),l("div",{class:de(["profiles-layout test-planner-layout",{"result-only-layout":At.value}])},[l("div",Yp,[!At.value&&!a.testPlanDraft&&!a.testPlanRunning?(v(),b("article",Qp,[n[74]||(n[74]=l("div",{class:"card-head"},[l("div",null,[l("h3",null,"Select test plan"),l("p",{class:"area-detail-subhead"},"Reusable deterministic active tests saved by the installer.")])],-1)),l("div",eg,[l("label",tg,[n[73]||(n[73]=l("span",null,"Plans",-1)),l("div",ag,[fe(l("input",{"onUpdate:modelValue":n[15]||(n[15]=r=>a.testPlanSearch=r),class:"area-search-select-input",type:"text",placeholder:sa.value?Ur(sa.value):"Search saved plan...",onFocus:n[16]||(n[16]=r=>a.testPlanSearchOpen=!0),onInput:n[17]||(n[17]=r=>a.testPlanSearchOpen=!0),onBlur:jl},null,40,ng),[[Ce,a.testPlanSearch]]),a.testPlanSearchOpen&&Tr.value.length?(v(),b("div",sg,[(v(!0),b(X,null,se(Tr.value.slice(0,80),r=>(v(),b("button",{key:r.id,type:"button",class:de(["area-search-select-option",{active:sa.value&&sa.value.id===r.id}]),onMousedown:Wt(c=>Ul(r),["prevent"])},S(Ur(r)),43,rg))),128))])):G("",!0)])])]),yt.value.length?G("",!0):(v(),b("p",ig,"No saved plans yet."))])):G("",!0),!At.value&&a.testPlanDraft?(v(),b("article",og,[a.testTemplateBuilderFocus!==!0?(v(),b("div",lg,[l("div",null,[l("h3",null,S(a.testPlanDraft?.name||"Plan Draft"),1),bs.value?(v(),b("p",dg,"Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.")):G("",!0)]),l("div",ug,[Cr.value?(v(),b("span",cg,"Unsaved changes")):G("",!0),l("button",{class:"secondary-button new-button",type:"button",onClick:Qr}," New Plan "),bs.value?G("",!0):(v(),b("button",{key:1,class:"secondary-button",type:"button",onClick:Rl}," Show Template Builder ")),l("label",fg,[fe(l("input",{"onUpdate:modelValue":n[18]||(n[18]=r=>a.voiceEnabled=r),type:"checkbox"},null,512),[[Xs,a.voiceEnabled]]),n[75]||(n[75]=l("span",null,"Voice",-1))]),l("button",{class:"danger-button",type:"button",disabled:a.testPlanDeleting||!sa.value,onClick:_d},S(a.testPlanDeleting?"Deleting...":"Delete"),9,pg),l("button",{class:"secondary-button",type:"button",disabled:a.testPlanSaving||a.testPlanRunning,onClick:Fl}," Close ",8,gg),l("button",{class:"secondary-button",type:"button",disabled:a.testPlanSaving||!a.testPlanDraft,onClick:ei},S(a.testPlanSaving?"Saving...":"Save Plan"),9,hg),cl.value?(v(),b("div",mg,[l("button",{class:"secondary-button",type:"button",disabled:!a.testPlanDraft&&a.testPlanRepeatForever!==!0||a.testPlanRunning&&a.testPlanRepeatForever!==!0||a.testPlanRepeatStopRequested===!0,onClick:n[19]||(n[19]=r=>a.testPlanRepeatForever===!0?bd():vd())},S(a.testPlanRepeatForever===!0?a.testPlanRepeatStopRequested===!0?"Stopping...":"Stop Repeat":"Repeat Forever"),9,vg),l("button",{class:"primary-button",type:"button",disabled:a.testPlanRunning||!a.testPlanDraft,onClick:md},[a.testPlanRunning?(v(),b("span",yg)):G("",!0),l("span",null,S(a.testPlanRunning?"Running...":"Run Plan"),1)],8,bg)])):G("",!0)])])):G("",!0),bs.value?(v(),b("div",Ag,[l("div",{class:de(["ai-planner-shell-head",{"template-builder-focus-head":a.testTemplateBuilderFocus===!0}])},[n[76]||(n[76]=l("div",null,[l("h4",null,"Template Builder"),l("p",{class:"area-detail-subhead"},"Select one of the standard templates. The plan is built only from the command GA available in the selected area.")],-1)),a.testTemplateBuilderFocus===!0?(v(),b("div",Sg,[l("button",{class:"secondary-button",type:"button",onClick:Cl}," Close ")])):G("",!0)],2),l("div",wg,[l("label",Pg,[n[77]||(n[77]=l("span",null,"Area to test",-1)),fe(l("select",{"onUpdate:modelValue":n[20]||(n[20]=r=>a.testAreaSelectedId=r)},[(v(!0),b(X,null,se(Ae.value,r=>(v(),b("option",{key:r.id,value:r.id},S(r.path||r.name),9,Tg))),128))],512),[[Ta,a.testAreaSelectedId]])]),l("label",_g,[n[78]||(n[78]=l("span",null,"Selected template",-1)),l("textarea",{value:a.testPlanPrompt||"Select one of the templates below.",rows:"4",readonly:""},null,8,Dg)])]),l("div",Ng,[(v(),b(X,null,se(i,r=>l("button",{key:r.id,class:de(["preset-button",{active:a.testPlanPrompt===r.prompt}]),type:"button",onClick:c=>ed(r)},S(r.title),11,Ig)),64))]),l("p",Rg,S((i.find(r=>r.prompt===a.testPlanPrompt)||{}).description||"Choose a template to see what the deterministic builder will do in the selected area."),1),l("div",Cg,[l("button",{class:"primary-button",type:"button",disabled:a.testPlanGenerating||!ot.value||!a.testPlanPrompt.trim(),onClick:Td},[a.testPlanGenerating?(v(),b("span",xg)):G("",!0),le(" "+S(a.testPlanGenerating?"Building...":"Build Test Plan"),1)],8,kg)]),a.testPlanGenerationError?(v(),b("p",Eg,S(a.testPlanGenerationError),1)):G("",!0),a.testPlanGeneration?(v(),b("div",Gg,[a.testPlanGeneration.error?G("",!0):(v(),b("p",Fg," Built with "+S(a.testPlanGeneration.provider||"deterministic builder")+". ",1)),a.testPlanGeneration.error?(v(),b("p",Og,S(a.testPlanGeneration.error),1)):G("",!0)])):G("",!0)])):G("",!0)])):G("",!0),a.testPlanRunning&&!At.value?(v(),b("article",Lg,[l("div",Mg,[l("div",null,[n[79]||(n[79]=l("h3",{class:"running-headline"},[l("span",{class:"running-spinner","aria-hidden":"true"}),l("span",null,"Test Running")],-1)),l("p",Bg,S(Re.value?.title||"Executing current step..."),1)]),l("span",zg,S(ft.value?.metrics?.totalSteps?`${Number(ft.value.steps?.length||0)}/${Number(ft.value.metrics.totalSteps||0)}`:"in progress"),1)]),l("div",$g,[l("article",Kg,[n[80]||(n[80]=l("span",null,"Completed",-1)),l("strong",null,S(Number(ft.value?.steps?.length||0)),1)]),l("article",Vg,[n[81]||(n[81]=l("span",null,"Pass",-1)),l("strong",null,S(Number(ft.value?.metrics?.pass||0)),1)]),l("article",Wg,[n[82]||(n[82]=l("span",null,"Warn",-1)),l("strong",null,S(Number(ft.value?.metrics?.warn||0)),1)]),l("article",Ug,[n[83]||(n[83]=l("span",null,"Fail",-1)),l("strong",null,S(Number(ft.value?.metrics?.fail||0)),1)])]),Re.value?(v(),b("div",jg,[l("div",Hg,[l("strong",null,S(Re.value.title||Re.value.id),1),l("span",null,S(Re.value.kind),1)]),l("p",Xg,S(Re.value.description||"Current step in execution."),1),Re.value.kind==="wait"?(v(),b("div",qg,[l("span",null,[n[84]||(n[84]=l("strong",null,"Wait",-1)),le(" "+S(Number(Re.value.delayMs||0))+" ms",1)]),l("span",null,[n[85]||(n[85]=l("strong",null,"Reason",-1)),le(" "+S(Re.value.reason||"Pause before next action"),1)])])):(v(),b("div",Jg,[l("span",null,[n[86]||(n[86]=l("strong",null,"Command",-1)),le(" "+S(Re.value.commandGA||"n/a"),1)]),l("span",null,[n[87]||(n[87]=l("strong",null,"Status GA",-1)),le(" "+S(Re.value.statusGA||"n/a"),1)]),l("span",null,[n[88]||(n[88]=l("strong",null,"Payload",-1)),le(" "+S(_s(Re.value.commandPayload,Re.value.commandDPT)),1)]),l("span",null,[n[89]||(n[89]=l("strong",null,"Expected",-1)),le(" "+S(_s(Re.value.expectedPayload,Re.value.statusDPT||Re.value.commandDPT)),1)])])),Re.value.kind!=="wait"&&Re.value.statusGA?(v(),b("div",Zg,[l("section",Yg,[n[92]||(n[92]=l("h4",null,"Spontaneous Write From Status GA",-1)),l("div",Qg,[l("span",null,[n[90]||(n[90]=l("strong",null,"Status GA",-1)),le(" "+S(Re.value.statusGA||"n/a"),1)]),l("span",null,[n[91]||(n[91]=l("strong",null,"Timeout",-1)),le(" "+S(Number(Re.value.statusWriteTimeoutMs||0))+" ms",1)])])]),l("section",eh,[n[95]||(n[95]=l("h4",null,"Active Read Request To Status GA",-1)),l("div",th,[l("span",null,[n[93]||(n[93]=l("strong",null,"Status GA",-1)),le(" "+S(Re.value.statusGA||"n/a"),1)]),l("span",null,[n[94]||(n[94]=l("strong",null,"Timeout",-1)),le(" "+S(Number(Re.value.statusResponseTimeoutMs||0))+" ms",1)])])])])):G("",!0)])):G("",!0)])):G("",!0),ne.value&&At.value?(v(),b("article",{key:3,ref_key:"testPlanReportRef",ref:Ee,class:"area-detail"},[l("div",ah,[l("div",null,[l("h3",null,S(Cn(ne.value)),1),l("p",nh,S(kn(ne.value)||Gt(ne.value.generatedAt)),1)]),l("div",sh,[l("span",rh,S(Za(ne.value)),1),ne.value.live===!0?(v(),b("span",ih,[...n[96]||(n[96]=[l("span",{class:"running-spinner run-chip-spinner","aria-hidden":"true"},null,-1),l("span",null,"Running",-1)])])):G("",!0),l("span",oh,S(ne.value.overallStatus),1),l("button",{class:"secondary-button",type:"button",onClick:Er}," Export PDF ")])]),l("div",lh,[(v(!0),b(X,null,se(Ts(ne.value),r=>(v(),b("article",{key:r.label,class:"metric"},[l("span",null,S(r.label),1),l("strong",null,S(r.value),1)]))),128))]),l("div",dh,[(v(!0),b(X,null,se(Ya(ne.value),r=>(v(),b("article",{key:r.id,class:de(["report-check",`report-${r.status}`])},[l("div",uh,[l("strong",null,S(r.title),1),l("span",null,S(r.status),1)]),l("p",ch,S(r.message||"No additional details available."),1),r.detailGroups?.length?(v(),b("div",fh,[(v(!0),b(X,null,se(r.detailGroups,c=>(v(),b("section",{key:`${r.id}-${c.title}`,class:"planner-check-section"},[l("h4",null,S(c.title),1),l("div",ph,[(v(!0),b(X,null,se(c.items,g=>(v(),b("span",{key:`${r.id}-${c.title}-${g.label}`},[l("strong",null,S(g.label),1),le(" "+S(g.value),1)]))),128))])]))),128))])):(v(),b("div",gh,[(v(!0),b(X,null,se(r.details,c=>(v(),b("span",{key:`${r.id}-${c.label}`},[l("strong",null,S(c.label),1),le(" "+S(c.value),1)]))),128))]))],2))),128))]),Ya(ne.value).length?G("",!0):(v(),b("p",hh,"No detailed entries stored for this report yet.")),Qa(ne.value).length?(v(),b("div",mh,[n[97]||(n[97]=l("h4",null,"Suggestions",-1)),l("ul",vh,[(v(!0),b(X,null,se(Qa(ne.value),r=>(v(),b("li",{key:r},S(r),1))),128))])])):G("",!0)],512)):G("",!0),a.testPlanDraft&&!a.testPlanRunning&&!At.value&&a.testTemplateBuilderFocus!==!0?(v(),b("article",bh,[l("div",yh,[l("div",null,[l("h3",Ah,[n[98]||(n[98]=l("span",null,"Edit Plan",-1)),a.testPlanGenerating?(v(),b("span",Sh)):G("",!0)])]),l("div",wh,[l("span",Ph,S(Number(a.testPlanDraft.steps?.length||0))+" steps",1),l("button",{class:"secondary-button",type:"button",onClick:od}," Add Step "),l("button",{class:"secondary-button",type:"button",onClick:ld}," Add Wait ")])]),l("div",Th,[l("label",_h,[n[100]||(n[100]=l("span",null,"Area",-1)),l("select",{value:a.testPlanDraft.areaId||a.testAreaSelectedId||"",disabled:!Ae.value.length,onChange:n[21]||(n[21]=r=>wd(r.target.value))},[n[99]||(n[99]=l("option",{value:"",disabled:""},"Select area",-1)),(v(!0),b(X,null,se(Ae.value,r=>(v(),b("option",{key:r.id,value:r.id},S(r.path||r.name),9,Nh))),128))],40,Dh)]),l("label",Ih,[n[101]||(n[101]=l("span",null,"Plan name",-1)),fe(l("input",{"onUpdate:modelValue":n[22]||(n[22]=r=>a.testPlanDraft.name=r),type:"text",placeholder:"KNX active test name"},null,512),[[Ce,a.testPlanDraft.name]])]),l("label",Rh,[n[102]||(n[102]=l("span",null,"Description",-1)),fe(l("textarea",{"onUpdate:modelValue":n[23]||(n[23]=r=>a.testPlanDraft.description=r),rows:"2",placeholder:"Short operator-facing description"},null,512),[[Ce,a.testPlanDraft.description]])])]),l("div",Ch,[(v(!0),b(X,null,se(a.testPlanDraft.steps||[],(r,c)=>(v(),b("article",{key:r.id,class:de(["report-check report-pass planner-step-card",{"planner-step-running":a.testPlanRunning&&a.testPlanRunningStepId===r.id,"planner-step-dragging":a.draggedTestPlanStepId===r.id,"planner-step-drop-target":a.dragOverTestPlanStepId===r.id}]),onDragenter:Wt(g=>pd(r.id),["prevent"]),onDragover:n[24]||(n[24]=Wt(()=>{},["prevent"])),onDrop:g=>hd(r.id,g)},[l("div",xh,[l("div",Eh,[l("button",{class:"drag-handle",type:"button",draggable:"true",tabindex:"-1","aria-label":"Drag step",title:"Drag step",onDragstart:g=>fd(r.id,g),onDragend:Es}," ⋮⋮ ",40,Gh),l("button",{class:"collapse-toggle",type:"button","aria-expanded":r.collapsed!==!0,title:r.collapsed===!0?"Expand step":"Collapse step",onClick:g=>cd(r)},[l("span",{class:de(["collapse-icon",{collapsed:r.collapsed===!0}])},"▾",2)],8,Fh),l("strong",null,S(r.title||r.id),1)]),l("div",Oh,[l("span",null,S(r.kind),1),l("button",{class:"secondary-button",type:"button",onClick:g=>dd(c)}," Duplicate ",8,Lh),l("button",{class:"secondary-button",type:"button",onClick:g=>ud(c)}," Remove ",8,Mh)])]),r.collapsed===!0?(v(),b("div",Bh,[r.kind==="wait"?(v(),b("span",zh,[n[103]||(n[103]=l("strong",null,"Wait",-1)),le(" "+S(Number(r.delayMs||0))+" ms",1)])):(v(),b("span",$h,[n[104]||(n[104]=l("strong",null,"Command",-1)),le(" "+S(r.commandGA||"n/a"),1)])),r.kind!=="wait"?(v(),b("span",Kh,[n[105]||(n[105]=l("strong",null,"Status GA",-1)),le(" "+S(r.statusGA||"n/a"),1)])):G("",!0),r.kind!=="wait"?(v(),b("span",Vh,[n[106]||(n[106]=l("strong",null,"Payload",-1)),le(" "+S(_s(r.commandPayload,r.commandDPT)),1)])):G("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("span",Wh,[n[107]||(n[107]=l("strong",null,"Write timeout",-1)),le(" "+S(Number(r.statusWriteTimeoutMs||0))+" ms",1)])):G("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("span",Uh,[n[108]||(n[108]=l("strong",null,"Response timeout",-1)),le(" "+S(Number(r.statusResponseTimeoutMs||0))+" ms",1)])):G("",!0)])):(v(),b("div",jh,[l("label",Hh,[n[109]||(n[109]=l("span",null,"Title",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.title=g,type:"text",placeholder:"Step title"},null,8,Xh),[[Ce,r.title]])]),l("label",qh,[n[110]||(n[110]=l("span",null,"Description",-1)),fe(l("textarea",{"onUpdate:modelValue":g=>r.description=g,rows:"2",placeholder:"What this step checks"},null,8,Jh),[[Ce,r.description]])]),r.kind==="wait"?(v(),b("label",Zh,[n[111]||(n[111]=l("span",null,"Wait ms",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.delayMs=g,type:"number",min:"0",max:"30000",step:"100"},null,8,Yh),[[Ce,r.delayMs,void 0,{number:!0}]])])):G("",!0),r.kind!=="wait"?(v(),b("section",Qh,[n[116]||(n[116]=l("h4",null,"Command",-1)),l("div",em,[l("label",tm,[n[113]||(n[113]=l("span",null,"Command GA",-1)),fe(l("select",{"onUpdate:modelValue":g=>r.commandGA=g,onChange:g=>Xr(r)},[n[112]||(n[112]=l("option",{value:""},"Select command GA",-1)),(v(!0),b(X,null,se(vs.value,g=>(v(),b("option",{key:g.ga,value:g.ga},S(`${g.ga} | ${g.label}`),9,nm))),128))],40,am),[[Ta,r.commandGA]])]),l("label",sm,[n[114]||(n[114]=l("span",null,"Command DPT",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.commandDPT=g,type:"text",placeholder:"1.001",onChange:g=>En(r)},null,40,rm),[[Ce,r.commandDPT]])]),l("label",im,[n[115]||(n[115]=l("span",null,"Command payload",-1)),ia(r.commandDPT).length?fe((v(),b("select",{key:0,"onUpdate:modelValue":g=>r.commandPayload=g},[(v(!0),b(X,null,se(ia(r.commandDPT),g=>(v(),b("option",{key:`${r.id}-command-${g.value}`,value:String(g.value)},S(g.label),9,lm))),128))],8,om)),[[Ta,r.commandPayload]]):fe((v(),b("input",{key:1,"onUpdate:modelValue":g=>r.commandPayload=g,type:"text",placeholder:"true, false, 50"},null,8,dm)),[[Ce,r.commandPayload]])])])])):G("",!0),r.kind!=="wait"?(v(),b("section",um,[n[121]||(n[121]=l("h4",null,"Status",-1)),l("div",cm,[l("label",fm,[n[118]||(n[118]=l("span",null,"Status GA",-1)),fe(l("select",{"onUpdate:modelValue":g=>r.statusGA=g,onChange:g=>Xr(r)},[n[117]||(n[117]=l("option",{value:""},"No feedback",-1)),(v(!0),b(X,null,se(Ir.value,g=>(v(),b("option",{key:g.ga,value:g.ga},S(`${g.ga} | ${g.label}`),9,gm))),128))],40,pm),[[Ta,r.statusGA]])]),l("label",hm,[n[119]||(n[119]=l("span",null,"Status DPT",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.statusDPT=g,type:"text",placeholder:"1.001",onChange:g=>En(r)},null,40,mm),[[Ce,r.statusDPT]])]),l("label",vm,[n[120]||(n[120]=l("span",null,"Expected payload",-1)),ia(r.statusDPT||r.commandDPT).length?fe((v(),b("select",{key:0,"onUpdate:modelValue":g=>r.expectedPayload=g},[(v(!0),b(X,null,se(ia(r.statusDPT||r.commandDPT),g=>(v(),b("option",{key:`${r.id}-expected-${g.value}`,value:String(g.value)},S(g.label),9,ym))),128))],8,bm)),[[Ta,r.expectedPayload]]):fe((v(),b("input",{key:1,"onUpdate:modelValue":g=>r.expectedPayload=g,type:"text",placeholder:"Expected feedback value"},null,8,Am)),[[Ce,r.expectedPayload]])])])])):G("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("div",Sm,[l("section",wm,[n[123]||(n[123]=l("h4",null,"Spontaneous Write From Status GA",-1)),n[124]||(n[124]=l("p",{class:"area-detail-subhead"},[le("Wait for a spontaneous "),l("code",null,"GroupValue_Write"),le(" telegram from the status GA.")],-1)),l("label",Pm,[n[122]||(n[122]=l("span",null,"Status write timeout ms",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.statusWriteTimeoutMs=g,type:"number",min:"500",max:"60000",step:"100"},null,8,Tm),[[Ce,r.statusWriteTimeoutMs,void 0,{number:!0}]])])]),l("section",_m,[n[126]||(n[126]=l("h4",null,"Active Read Request To Status GA",-1)),n[127]||(n[127]=l("p",{class:"area-detail-subhead"},[le("Send a "),l("code",null,"read"),le(" telegram to the status GA and wait for a "),l("code",null,"GroupValue_Response"),le(".")],-1)),l("label",Dm,[n[125]||(n[125]=l("span",null,"Read response timeout ms",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.statusResponseTimeoutMs=g,type:"number",min:"500",max:"60000",step:"100"},null,8,Nm),[[Ce,r.statusResponseTimeoutMs,void 0,{number:!0}]])])])])):G("",!0),l("label",Im,[n[128]||(n[128]=l("span",null,"Reason",-1)),fe(l("input",{"onUpdate:modelValue":g=>r.reason=g,type:"text",placeholder:"Why this step exists"},null,8,Rm),[[Ce,r.reason]])])]))],42,kh))),128))])])):G("",!0)])],2)],2)):G("",!0),a.activeTab==="results"?(v(),b("section",Cm,[l("div",km,[n[129]||(n[129]=l("div",null,[l("h2",null,"Test Results"),l("p",{class:"area-detail-subhead"},"Live and saved reports generated by KNX active and read-only tests.")],-1)),l("div",xm,[l("span",Em,S(na.value.length)+" available",1)])]),l("div",Gm,[l("article",Fm,[n[130]||(n[130]=l("div",{class:"card-head"},[l("div",null,[l("h3",null,"Select Test Result"),l("p",{class:"area-detail-subhead"},"Choose a report to inspect metrics, detailed checks, and suggestions.")])],-1)),l("div",Om,[(v(!0),b(X,null,se(na.value,r=>(v(),b("div",{key:r.id,class:"sidebar-result-row"},[l("button",{type:"button",class:de(["area-list-item sidebar-result-item",{active:ne.value&&ne.value.id===r.id,running:r.live===!0}]),onClick:c=>xn(r.id,{openMenu:!1,activateResultsTab:!0,resultOnly:!0})},[l("span",Mm,[l("strong",Bm,[r.live===!0?(v(),b("span",zm)):G("",!0),l("span",null,S(Cn(r)),1)]),l("span",{class:de(["sidebar-result-status",`status-${r.overallStatus||"pass"}`])},S(r.overallStatus||"n/a"),3)]),l("span",$m,[le(S(Za(r)),1),r.live===!0?(v(),b("span",Km," | running")):G("",!0)]),l("span",Vm,S(kn(r)||Gt(r.generatedAt)),1),l("span",Wm,S(Gt(r.generatedAt)),1)],10,Lm),l("button",{class:"sidebar-result-delete-button",type:"button",disabled:a.deletingTestResultId===r.id,onClick:Wt(c=>Rs(r.id),["stop"])},S(a.deletingTestResultId===r.id?"Deleting...":"Delete"),9,Um)]))),128)),na.value.length?G("",!0):(v(),b("p",jm,"No saved test results yet."))])]),ne.value?(v(),b("article",{key:0,ref_key:"testPlanReportRef",ref:Ee,class:"area-detail"},[l("div",Hm,[l("div",null,[l("h3",null,S(Cn(ne.value)),1),l("p",Xm,S(kn(ne.value)||Gt(ne.value.generatedAt)),1)]),l("div",qm,[l("span",Jm,S(Za(ne.value)),1),ne.value.live===!0?(v(),b("span",Zm,[...n[131]||(n[131]=[l("span",{class:"running-spinner run-chip-spinner","aria-hidden":"true"},null,-1),l("span",null,"Running",-1)])])):G("",!0),l("span",Ym,S(ne.value.overallStatus),1),l("button",{class:"secondary-button",type:"button",onClick:Er}," Export PDF "),l("button",{class:"danger-button",type:"button",disabled:!ne.value||a.deletingTestResultId===ne.value.id,onClick:n[25]||(n[25]=r=>Rs(ne.value?.id))},S(a.deletingTestResultId===ne.value?.id?"Deleting...":"Delete"),9,Qm),l("button",{class:"secondary-button",type:"button",onClick:$r}," Open Source Test ")])]),l("div",ev,[(v(!0),b(X,null,se(Ts(ne.value),r=>(v(),b("article",{key:r.label,class:"metric"},[l("span",null,S(r.label),1),l("strong",null,S(r.value),1)]))),128))]),l("div",tv,[(v(!0),b(X,null,se(Ya(ne.value),r=>(v(),b("article",{key:r.id,class:de(["report-check",`report-${r.status}`])},[l("div",av,[l("strong",null,S(r.title),1),l("span",null,S(r.status),1)]),l("p",nv,S(r.message||"No additional details available."),1),r.detailGroups?.length?(v(),b("div",sv,[(v(!0),b(X,null,se(r.detailGroups,c=>(v(),b("section",{key:`${r.id}-${c.title}`,class:"planner-check-section"},[l("h4",null,S(c.title),1),l("div",rv,[(v(!0),b(X,null,se(c.items,g=>(v(),b("span",{key:`${r.id}-${c.title}-${g.label}`},[l("strong",null,S(g.label),1),le(" "+S(g.value),1)]))),128))])]))),128))])):(v(),b("div",iv,[(v(!0),b(X,null,se(r.details,c=>(v(),b("span",{key:`${r.id}-${c.label}`},[l("strong",null,S(c.label),1),le(" "+S(c.value),1)]))),128))]))],2))),128))]),Ya(ne.value).length?G("",!0):(v(),b("p",ov,"No detailed entries stored for this report yet.")),Qa(ne.value).length?(v(),b("div",lv,[n[132]||(n[132]=l("h4",null,"Suggestions",-1)),l("ul",dv,[(v(!0),b(X,null,se(Qa(ne.value),r=>(v(),b("li",{key:r},S(r),1))),128))])])):G("",!0)],512)):(v(),b("article",uv,[...n[133]||(n[133]=[l("p",{class:"empty-state"},"No test result selected.",-1)])]))])])):G("",!0),a.activeTab==="overview"?(v(),b("section",cv,[l("div",fv,[n[134]||(n[134]=l("h2",null,"Top Group Addresses",-1)),l("span",pv,S(As.value.length)+" visible",1)]),As.value.length?(v(),b("ul",gv,[(v(!0),b(X,null,se(As.value,r=>(v(),b("li",{key:r.ga,class:"rank-row"},[l("span",hv,S(r.ga),1),l("span",mv,S(r.label||"Unlabeled"),1),l("strong",null,S(Number(r.count||0)),1)]))),128))])):(v(),b("p",vv,"No top group address data available yet."))])):G("",!0),a.activeTab==="overview"?(v(),b("section",bv,[l("div",yv,[n[135]||(n[135]=l("h2",null,"Event Mix",-1)),l("span",Av,S(Rn.value.length)+" event types",1)]),Rn.value.length?(v(),b("ul",Sv,[(v(!0),b(X,null,se(Rn.value,r=>(v(),b("li",{key:r.name,class:"event-row"},[l("span",wv,S(r.name),1),l("div",Pv,[l("span",{class:"event-bar-fill",style:pn({width:`${Math.max(r.count/pl.value*100,6)}%`})},null,4)]),l("strong",null,S(r.count),1)]))),128))])):(v(),b("p",Tv,"Event distribution will appear after the first samples."))])):G("",!0),a.activeTab==="overview"?(v(),b("section",_v,[l("div",Dv,[n[136]||(n[136]=l("h2",null,"Bus Connection Persistence",-1)),nt.value?(v(),b("span",Nv,S(String(nt.value.currentState||"unknown")),1)):G("",!0)]),nt.value?(v(),b(X,{key:0},[l("div",Iv,[l("span",Rv,"Connected "+S(Ea(nt.value.connectedSec||0)),1),l("span",Cv,"Disconnected "+S(Ea(nt.value.disconnectedSec||0)),1),l("span",kv,"Coverage "+S(Number(nt.value.knownCoveragePct||0))+"%",1)]),l("div",xv,[(v(!0),b(X,null,se(ml.value,r=>(v(),b("span",{key:r.key,class:de(["bus-segment",r.className]),style:pn({left:r.left,width:r.width}),title:r.title},null,14,Ev))),128))]),l("div",Gv,[l("span",null,S(Dn(nt.value.windowStartAt)),1),l("span",null,S(Dn(nt.value.windowEndAt)),1),n[137]||(n[137]=l("span",null,"Now",-1))]),n[138]||(n[138]=l("p",{class:"bus-note"},"Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.",-1))],64)):(v(),b("p",Fv,"Waiting for connection persistence data..."))])):G("",!0),a.activeTab==="overview"?(v(),b("section",{key:7,ref_key:"flowCardRef",ref:ea,class:de(["card card-flow",{"is-fullscreen":ma.value}])},[l("div",Ov,[n[139]||(n[139]=l("h2",null,"Flow Map",-1)),l("div",Lv,[l("span",Mv," Nodes "+S(ra.value.nodes.length)+" | Links "+S(ra.value.edges.length),1),l("button",{class:"secondary-button",type:"button",onClick:O},S(ma.value?"Exit Fullscreen":"Fullscreen"),1)])]),l("div",Bv,[l("label",zv,[n[140]||(n[140]=l("span",null,"Max nodes",-1)),fe(l("input",{"onUpdate:modelValue":n[26]||(n[26]=r=>a.flowMaxNodes=r),type:"number",min:"4",max:"32",step:"1"},null,512),[[Ce,a.flowMaxNodes,void 0,{number:!0}]])]),l("label",$v,[n[141]||(n[141]=l("span",null,"Find GA",-1)),fe(l("input",{"onUpdate:modelValue":n[27]||(n[27]=r=>a.flowSearch=r),type:"text",placeholder:"Search GA or label"},null,512),[[Ce,a.flowSearch]])]),l("div",Kv,[n[143]||(n[143]=l("span",null,"Select Nodes to Filter by",-1)),fe(l("select",{"onUpdate:modelValue":n[28]||(n[28]=r=>a.flowSelectedGa=r),multiple:"",size:"5"},[(v(!0),b(X,null,se(gl.value,r=>(v(),b("option",{key:r.id,value:r.id},S(`${r.id}${r.subtitle?` | ${r.subtitle}`:""}`),9,Vv))),128))],512),[[Ta,a.flowSelectedGa]]),l("label",Wv,[fe(l("input",{"onUpdate:modelValue":n[29]||(n[29]=r=>a.flowShowUniversalNodes=r),type:"checkbox"},null,512),[[Xs,a.flowShowUniversalNodes]]),n[142]||(n[142]=l("span",null,"Show Universal Mode nodes",-1))])]),n[144]||(n[144]=ua('<div class="flow-legend" data-v-521d66a3><span data-v-521d66a3><i class="legend-line legend-write" data-v-521d66a3></i>Write</span><span data-v-521d66a3><i class="legend-line legend-response" data-v-521d66a3></i>Response</span><span data-v-521d66a3><i class="legend-line legend-read" data-v-521d66a3></i>Read</span><span data-v-521d66a3><i class="legend-line legend-repeat" data-v-521d66a3></i>Repeat</span><span data-v-521d66a3><i class="legend-dot legend-anomaly" data-v-521d66a3></i>Anomaly</span><span data-v-521d66a3><i class="legend-dot legend-external" data-v-521d66a3></i>External</span></div>',1))]),l("div",Uv,[ra.value.nodes.length?(v(),b("svg",{key:0,class:"flow-svg",viewBox:`0 0 ${ra.value.width} ${ra.value.height}`,preserveAspectRatio:"xMidYMid meet"},[l("defs",null,[(v(),b(X,null,se(d,(r,c)=>l("marker",{id:`flow-arrow-${c}`,key:c,viewBox:"0 0 10 8",markerWidth:"10",markerHeight:"8",refX:"8.8",refY:"4",orient:"auto",markerUnits:"userSpaceOnUse"},[l("path",{d:"M0,0 L10,4 L0,8 z",fill:r},null,8,Xv)],8,Hv)),64))]),(v(!0),b(X,null,se(ra.value.edges,r=>(v(),b("path",{key:r.key,class:de(["flow-edge",{"flow-edge-active":r.active,"flow-edge-idle":!r.active}]),d:r.d,stroke:r.color,"stroke-width":r.width,opacity:r.opacity,"marker-end":`url(#${r.markerId})`},[l("title",null,S(r.tooltip),1)],10,qv))),128)),(v(!0),b(X,null,se(ra.value.nodes,r=>(v(),b("g",{key:r.id,class:de(["flow-node",{"is-anomaly":r.anomalyCount>0,"is-external":!r.inFlow,"is-idle":r.isIdle}])},[l("circle",{cx:r.x,cy:r.y,r:"24"},null,8,Jv),l("text",{class:"node-label",x:r.x,y:r.y+1},S(r.shortLabel),9,Zv),r.shortSubtitle?(v(),b("text",{key:0,class:"node-subtitle",x:r.x,y:r.y+38},S(r.shortSubtitle),9,Yv)):G("",!0),r.shortPayload?(v(),b("text",{key:1,class:"node-payload",x:r.x,y:r.y+52},S(r.shortPayload),9,Qv)):G("",!0),r.anomalyCount>0?(v(),b("text",{key:2,class:"node-badge",x:r.x,y:r.y-30},"anomaly x"+S(r.anomalyCount),9,eb)):G("",!0),l("title",null,S(`${r.id}${r.subtitle?` | ${r.subtitle}`:""}${r.payload?` | payload: ${r.payload}`:""}`),1)],2))),128))],8,jv)):(v(),b("p",tb,"No topology data available yet."))]),l("p",ab,"Window "+S(ra.value.telemetryWindowSec||0)+"s.",1)],2)):G("",!0),a.activeTab==="overview"?(v(),b("section",nb,[l("div",sb,[n[145]||(n[145]=l("h2",null,"Anomalies",-1)),l("span",rb,S(ys.value.length)+" recent",1)]),ys.value.length?(v(),b("div",ib,[(v(!0),b(X,null,se(ys.value.slice(0,20),r=>(v(),b("article",{key:`${r.at}-${Nn(r).ga||""}`,class:"anomaly-card"},[l("div",ob,[l("strong",null,S(Nn(r).type||"anomaly"),1),l("span",null,S(Nn(r).ga||"no GA"),1)]),l("p",lb,S(r.at||""),1),l("pre",null,S(JSON.stringify(Nn(r),null,2)),1)]))),128))])):(v(),b("p",db,"No anomalies detected right now."))])):G("",!0),a.activeTab==="assistant"?(v(),b("section",ub,[l("div",cb,[n[146]||(n[146]=l("h2",null,"Ask",-1)),l("span",fb,S(ct.value.llmEnabled?"AI enabled":"AI disabled"),1)]),l("div",pb,[(v(!0),b(X,null,se(vl.value,r=>(v(),b("article",{key:r.key,class:de(["chat-message",`chat-${r.kind}`])},[r.kind==="assistant"?(v(),b("div",{key:0,innerHTML:r.html},null,8,gb)):(v(),b("pre",hb,S(r.rawText),1))],2))),128)),a.asking?(v(),b("article",mb,[...n[147]||(n[147]=[l("span",{class:"chat-pending-spinner","aria-hidden":"true"},null,-1),l("span",null,"Thinking...",-1)])])):G("",!0)]),l("div",vb,[(v(!0),b(X,null,se(ul.value,r=>(v(),b("button",{key:r.key,class:"preset-button",type:"button",disabled:a.asking||!ct.value.llmEnabled,onClick:c=>Cs(r.text)},S(r.text),9,bb))),128))]),l("div",yb,[fe(l("input",{"onUpdate:modelValue":n[30]||(n[30]=r=>a.chatDraft=r),class:"ask-input",type:"text",disabled:a.asking||!ct.value.llmEnabled,placeholder:"Ask a question about KNX traffic...",onKeydown:n[31]||(n[31]=Yc(Wt(r=>Cs(),["prevent"]),["enter"]))},null,40,Ab),[[Ce,a.chatDraft]]),l("button",{class:"primary-button",type:"button",disabled:a.asking||!ct.value.llmEnabled,onClick:n[32]||(n[32]=r=>Cs())}," Send ",8,Sb)])])):G("",!0),a.activeTab==="flowBuilder"?(v(),b("section",wb,[l("div",Pb,[n[148]||(n[148]=l("h2",null,[le("Flow Builder "),l("span",{class:"beta-badge"},"BETA")],-1)),l("span",Tb,S(ct.value.llmEnabled?"AI enabled":"AI disabled"),1)]),l("div",_b,[l("div",Db,[n[149]||(n[149]=l("p",{class:"flow-builder-hint"}," Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it. ",-1)),l("div",Nb,[fe(l("textarea",{"onUpdate:modelValue":n[33]||(n[33]=r=>a.flowBuilderPrompt=r),class:"flow-builder-textarea",rows:"6",disabled:a.flowBuilderGenerating||!ct.value.llmEnabled,placeholder:"e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light."},null,8,Ib),[[Ce,a.flowBuilderPrompt]]),l("div",Rb,[l("button",{class:"primary-button",type:"button",disabled:a.flowBuilderGenerating||!ct.value.llmEnabled||!String(a.flowBuilderPrompt||"").trim(),onClick:n[34]||(n[34]=r=>Ll())},S(a.flowBuilderGenerating?"Generating...":"Generate flow"),9,Cb)])])]),l("div",kb,[a.flowBuilderGenerating?(v(),b("article",xb,[...n[150]||(n[150]=[l("span",{class:"chat-pending-spinner","aria-hidden":"true"},null,-1),l("span",null,"Generating flow...",-1)])])):a.flowBuilderError?(v(),b("article",Eb,[l("pre",null,S(a.flowBuilderError),1)])):a.flowBuilderResult?(v(),b("div",Gb,[a.flowBuilderResult.notes?(v(),b("p",Fb,S(a.flowBuilderResult.notes),1)):G("",!0),a.flowBuilderResult.warnings&&a.flowBuilderResult.warnings.length?(v(),b("ul",Ob,[(v(!0),b(X,null,se(a.flowBuilderResult.warnings,(r,c)=>(v(),b("li",{key:c},S(r),1))),128))])):G("",!0),l("div",Lb,[l("span",Mb,S(a.flowBuilderResult.generation&&a.flowBuilderResult.generation.nodeCount||0)+" nodes",1),a.flowBuilderResult.generation&&a.flowBuilderResult.generation.model?(v(),b("span",Bb,S(a.flowBuilderResult.generation.model),1)):G("",!0),l("button",{class:"secondary-button",type:"button",onClick:n[35]||(n[35]=r=>Ml())},S(a.flowBuilderCopied?"Copied!":"Copy JSON"),1)]),l("pre",zb,S(a.flowBuilderResult.flowJson),1)])):(v(),b("p",$b,"The generated flow JSON will appear here."))])])])):G("",!0),a.activeTab==="settings"?(v(),b("section",Kb,[n[157]||(n[157]=l("div",{class:"card-head"},[l("div",null,[l("h2",null,"Settings"),l("p",{class:"area-detail-subhead"},"Manage node options and full configuration import/export.")])],-1)),l("div",Vb,[l("button",{class:de(["settings-tab-button",{active:a.settingsTab==="node"}]),type:"button",onClick:n[36]||(n[36]=r=>zr("node"))}," KNX AI Node ",2),l("button",{class:de(["settings-tab-button",{active:a.settingsTab==="config"}]),type:"button",onClick:n[37]||(n[37]=r=>zr("config"))}," Import / Export ",2)]),a.settingsTab==="node"?(v(),b("article",Wb,[n[153]||(n[153]=l("div",{class:"card-head settings-panel-head"},[l("h3",null,"KNX AI Node"),l("span",{class:"meta-chip"},"Runtime preferences")],-1)),n[154]||(n[154]=l("p",{class:"area-detail-subhead"},"Select the node used by this UI and control refresh behavior.",-1)),l("div",Ub,[l("label",jb,[n[151]||(n[151]=l("span",null,"Node",-1)),fe(l("select",{"onUpdate:modelValue":n[38]||(n[38]=r=>a.selectedNodeId=r),class:"node-select",onChange:Il},[(v(!0),b(X,null,se(a.nodes,r=>(v(),b("option",{key:r.id,value:r.id},S(`${r.name||"KNX AI"}${r.gatewayName?` | ${r.gatewayName}`:""}`),9,Hb))),128))],544),[[Ta,a.selectedNodeId]])]),l("label",Xb,[fe(l("input",{"onUpdate:modelValue":n[39]||(n[39]=r=>a.autoRefresh=r),type:"checkbox"},null,512),[[Xs,a.autoRefresh]]),n[152]||(n[152]=l("span",null,"Auto refresh",-1))])])])):(v(),b("article",qb,[n[155]||(n[155]=l("div",{class:"card-head settings-panel-head"},[l("h3",null,"Import / Export"),l("span",{class:"meta-chip"},"Full configuration")],-1)),n[156]||(n[156]=l("p",{class:"area-detail-subhead"},"Export or import the full KNX AI configuration for the selected node.",-1)),l("div",Jb,[l("button",{class:"secondary-button",type:"button",disabled:!a.selectedNodeId,onClick:Nd}," Export Configuration ",8,Zb),l("button",{class:"secondary-button",type:"button",disabled:!a.selectedNodeId,onClick:Id}," Import Configuration ",8,Yb)])])),l("input",{ref_key:"configImportRef",ref:Ra,type:"file",accept:"application/json,.json",class:"hidden-file-input",onChange:Rd},null,544)])):G("",!0)])]),a.areaLlmRegenerating||a.areaLlmBulkDeleting||a.testPlanGenerating?(v(),b("div",Qb,[l("div",ey,[n[158]||(n[158]=l("span",{class:"running-spinner global-wait-spinner","aria-hidden":"true"},null,-1)),l("strong",null,S(a.testPlanGenerating?"Building Test Plan":a.areaLlmBulkDeleting?"Deleting AI Areas":"Regenerating AI Areas"),1),l("span",null,S(a.testPlanGenerating?"Please wait while the template builder generates the test plan.":a.areaLlmBulkDeleting?"Please wait while AI-generated areas are removed.":"Please wait, this can take a while with large ETS projects."),1)])])):G("",!0),a.testPlanRunConfirmOpen?(v(),b("div",{key:1,class:"modal-backdrop",onClick:qr},[l("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"run-test-title",onClick:n[41]||(n[41]=Wt(()=>{},["stop"]))},[n[159]||(n[159]=l("h3",{id:"run-test-title"},"Start test?",-1)),l("p",ty,S(a.testPlanRunMode==="repeat"?"This will send real telegrams on the KNX bus and repeat the selected test plan until you press Stop Repeat.":"This will send real telegrams on the KNX bus for the selected test plan."),1),l("div",ay,[l("button",{class:"secondary-button",type:"button",autofocus:"",onClick:qr}," Cancel "),l("button",{class:"primary-button",type:"button",disabled:a.testPlanRunning,onClick:n[40]||(n[40]=r=>Dd(a.testPlanRunMode))}," Start Test ",8,ny)])])])):G("",!0),a.testPlanUnsavedConfirmOpen?(v(),b("div",{key:2,class:"modal-backdrop",onClick:Zr},[l("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"unsaved-plan-title",onClick:n[43]||(n[43]=Wt(()=>{},["stop"]))},[n[160]||(n[160]=l("h3",{id:"unsaved-plan-title"},"Unsaved changes",-1)),l("p",sy,"Save or discard the current plan changes before opening "+S(a.testPlanPendingActionLabel||"another plan")+".",1),l("div",ry,[l("button",{class:"secondary-button",type:"button",autofocus:"",onClick:Zr}," Stay Here "),l("button",{class:"secondary-button",type:"button",onClick:n[42]||(n[42]=r=>{Ad(),Yr()})}," Discard Changes "),l("button",{class:"primary-button",type:"button",disabled:a.testPlanSaving||!a.testPlanDraft,onClick:Sd},S(a.testPlanSaving?"Saving...":"Save and Continue"),9,iy)])])])):G("",!0),a.areaUnsavedConfirmOpen?(v(),b("div",{key:3,class:"modal-backdrop",onClick:Br},[l("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"unsaved-area-title",onClick:n[44]||(n[44]=Wt(()=>{},["stop"]))},[n[161]||(n[161]=l("h3",{id:"unsaved-area-title"},"Unsaved changes",-1)),n[162]||(n[162]=l("p",{class:"area-detail-subhead"},"Discard the current area changes and close the editor?",-1)),l("div",{class:"modal-actions"},[l("button",{class:"secondary-button",type:"button",autofocus:"",onClick:Br}," Stay Here "),l("button",{class:"primary-button",type:"button",onClick:Gl}," Discard and Close ")])])])):G("",!0)],2)],64))}},py=df(fy,[["__scopeId","data-v-521d66a3"]]);tf(py).mount("#app");export{of as _};
1
+ (function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))l(d);new MutationObserver(d=>{for(const c of d)if(c.type==="childList")for(const f of c.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&l(f)}).observe(document,{childList:!0,subtree:!0});function i(d){const c={};return d.integrity&&(c.integrity=d.integrity),d.referrerPolicy&&(c.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?c.credentials="include":d.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function l(d){if(d.ep)return;d.ep=!0;const c=i(d);fetch(d.href,c)}})();function pr(e){const a=Object.create(null);for(const i of e.split(","))a[i]=1;return i=>i in a}const Te={},Oa=[],Dt=()=>{},Yi=()=>!1,ns=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),ss=e=>e.startsWith("onUpdate:"),We=Object.assign,gr=(e,a)=>{const i=e.indexOf(a);i>-1&&e.splice(i,1)},Zd=Object.prototype.hasOwnProperty,be=(e,a)=>Zd.call(e,a),Y=Array.isArray,Ma=e=>Tn(e)==="[object Map]",Ua=e=>Tn(e)==="[object Set]",pi=e=>Tn(e)==="[object Date]",ne=e=>typeof e=="function",xe=e=>typeof e=="string",xt=e=>typeof e=="symbol",Se=e=>e!==null&&typeof e=="object",Qi=e=>(Se(e)||ne(e))&&ne(e.then)&&ne(e.catch),eo=Object.prototype.toString,Tn=e=>eo.call(e),Yd=e=>Tn(e).slice(8,-1),to=e=>Tn(e)==="[object Object]",hr=e=>xe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ln=pr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),rs=e=>{const a=Object.create(null);return(i=>a[i]||(a[i]=e(i)))},Qd=/-\w/g,ht=rs(e=>e.replace(Qd,a=>a.slice(1).toUpperCase())),ec=/\B([A-Z])/g,ha=rs(e=>e.replace(ec,"-$1").toLowerCase()),ao=rs(e=>e.charAt(0).toUpperCase()+e.slice(1)),Us=rs(e=>e?`on${ao(e)}`:""),Nt=(e,a)=>!Object.is(e,a),Wn=(e,...a)=>{for(let i=0;i<e.length;i++)e[i](...a)},no=(e,a,i,l=!1)=>{Object.defineProperty(e,a,{configurable:!0,enumerable:!1,writable:l,value:i})},is=e=>{const a=parseFloat(e);return isNaN(a)?e:a};let gi;const os=()=>gi||(gi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function hn(e){if(Y(e)){const a={};for(let i=0;i<e.length;i++){const l=e[i],d=xe(l)?sc(l):hn(l);if(d)for(const c in d)a[c]=d[c]}return a}else if(xe(e)||Se(e))return e}const tc=/;(?![^(]*\))/g,ac=/:([^]+)/,nc=/\/\*[^]*?\*\//g;function sc(e){const a={};return e.replace(nc,"").split(tc).forEach(i=>{if(i){const l=i.split(ac);l.length>1&&(a[l[0].trim()]=l[1].trim())}}),a}function le(e){let a="";if(xe(e))a=e;else if(Y(e))for(let i=0;i<e.length;i++){const l=le(e[i]);l&&(a+=l+" ")}else if(Se(e))for(const i in e)e[i]&&(a+=i+" ");return a.trim()}const rc="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",ic=pr(rc);function so(e){return!!e||e===""}function oc(e,a){if(e.length!==a.length)return!1;let i=!0;for(let l=0;i&&l<e.length;l++)i=Wa(e[l],a[l]);return i}function Wa(e,a){if(e===a)return!0;let i=pi(e),l=pi(a);if(i||l)return i&&l?e.getTime()===a.getTime():!1;if(i=xt(e),l=xt(a),i||l)return e===a;if(i=Y(e),l=Y(a),i||l)return i&&l?oc(e,a):!1;if(i=Se(e),l=Se(a),i||l){if(!i||!l)return!1;const d=Object.keys(e).length,c=Object.keys(a).length;if(d!==c)return!1;for(const f in e){const p=e.hasOwnProperty(f),m=a.hasOwnProperty(f);if(p&&!m||!p&&m||!Wa(e[f],a[f]))return!1}}return String(e)===String(a)}function mr(e,a){return e.findIndex(i=>Wa(i,a))}const ro=e=>!!(e&&e.__v_isRef===!0),A=e=>xe(e)?e:e==null?"":Y(e)||Se(e)&&(e.toString===eo||!ne(e.toString))?ro(e)?A(e.value):JSON.stringify(e,io,2):String(e),io=(e,a)=>ro(a)?io(e,a.value):Ma(a)?{[`Map(${a.size})`]:[...a.entries()].reduce((i,[l,d],c)=>(i[Ws(l,c)+" =>"]=d,i),{})}:Ua(a)?{[`Set(${a.size})`]:[...a.values()].map(i=>Ws(i))}:xt(a)?Ws(a):Se(a)&&!Y(a)&&!to(a)?String(a):a,Ws=(e,a="")=>{var i;return xt(e)?`Symbol(${(i=e.description)!=null?i:a})`:e};let Ke;class lc{constructor(a=!1){this.detached=a,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!a&&Ke&&(Ke.active?(this.parent=Ke,this.index=(Ke.scopes||(Ke.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let a,i;if(this.scopes){const l=this.scopes.slice();for(a=0,i=l.length;a<i;a++)l[a].pause()}for(a=0,i=this.effects.length;a<i;a++)this.effects[a].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let a,i;if(this.scopes){const d=this.scopes.slice();for(a=0,i=d.length;a<i;a++)d[a].resume()}const l=this.effects.slice();for(a=0,i=l.length;a<i;a++)l[a].resume()}}run(a){if(this._active){const i=Ke;try{return Ke=this,a()}finally{Ke=i}}}on(){++this._on===1&&(this.prevScope=Ke,Ke=this)}off(){if(this._on>0&&--this._on===0){if(Ke===this)Ke=this.prevScope;else{let a=Ke;for(;a;){if(a.prevScope===this){a.prevScope=this.prevScope;break}a=a.prevScope}}this.prevScope=void 0}}stop(a){if(this._active){this._active=!1;let i,l;for(i=0,l=this.effects.length;i<l;i++)this.effects[i].stop();for(this.effects.length=0,i=0,l=this.cleanups.length;i<l;i++)this.cleanups[i]();if(this.cleanups.length=0,this.scopes){const d=this.scopes.slice();for(i=0,l=d.length;i<l;i++)d[i].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!a){const d=this.parent.scopes.pop();d&&d!==this&&(this.parent.scopes[this.index]=d,d.index=this.index)}this.parent=void 0}}}function dc(){return Ke}let _e;const Hs=new WeakSet;class oo{constructor(a){this.fn=a,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,Ke&&(Ke.active?Ke.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Hs.has(this)&&(Hs.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||co(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,hi(this),uo(this);const a=_e,i=mt;_e=this,mt=!0;try{return this.fn()}finally{fo(this),_e=a,mt=i,this.flags&=-3}}stop(){if(this.flags&1){for(let a=this.deps;a;a=a.nextDep)yr(a);this.deps=this.depsTail=void 0,hi(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Hs.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){nr(this)&&this.run()}get dirty(){return nr(this)}}let lo=0,dn,cn;function co(e,a=!1){if(e.flags|=8,a){e.next=cn,cn=e;return}e.next=dn,dn=e}function vr(){lo++}function br(){if(--lo>0)return;if(cn){let a=cn;for(cn=void 0;a;){const i=a.next;a.next=void 0,a.flags&=-9,a=i}}let e;for(;dn;){let a=dn;for(dn=void 0;a;){const i=a.next;if(a.next=void 0,a.flags&=-9,a.flags&1)try{a.trigger()}catch(l){e||(e=l)}a=i}}if(e)throw e}function uo(e){for(let a=e.deps;a;a=a.nextDep)a.version=-1,a.prevActiveLink=a.dep.activeLink,a.dep.activeLink=a}function fo(e){let a,i=e.depsTail,l=i;for(;l;){const d=l.prevDep;l.version===-1?(l===i&&(i=d),yr(l),cc(l)):a=l,l.dep.activeLink=l.prevActiveLink,l.prevActiveLink=void 0,l=d}e.deps=a,e.depsTail=i}function nr(e){for(let a=e.deps;a;a=a.nextDep)if(a.dep.version!==a.version||a.dep.computed&&(po(a.dep.computed)||a.dep.version!==a.version))return!0;return!!e._dirty}function po(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===mn)||(e.globalVersion=mn,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!nr(e))))return;e.flags|=2;const a=e.dep,i=_e,l=mt;_e=e,mt=!0;try{uo(e);const d=e.fn(e._value);(a.version===0||Nt(d,e._value))&&(e.flags|=128,e._value=d,a.version++)}catch(d){throw a.version++,d}finally{_e=i,mt=l,fo(e),e.flags&=-3}}function yr(e,a=!1){const{dep:i,prevSub:l,nextSub:d}=e;if(l&&(l.nextSub=d,e.prevSub=void 0),d&&(d.prevSub=l,e.nextSub=void 0),i.subs===e&&(i.subs=l,!l&&i.computed)){i.computed.flags&=-5;for(let c=i.computed.deps;c;c=c.nextDep)yr(c,!0)}!a&&!--i.sc&&i.map&&i.map.delete(i.key)}function cc(e){const{prevDep:a,nextDep:i}=e;a&&(a.nextDep=i,e.prevDep=void 0),i&&(i.prevDep=a,e.nextDep=void 0)}let mt=!0;const go=[];function Qt(){go.push(mt),mt=!1}function ea(){const e=go.pop();mt=e===void 0?!0:e}function hi(e){const{cleanup:a}=e;if(e.cleanup=void 0,a){const i=_e;_e=void 0;try{a()}finally{_e=i}}}let mn=0;class uc{constructor(a,i){this.sub=a,this.dep=i,this.version=i.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ar{constructor(a){this.computed=a,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(a){if(!_e||!mt||_e===this.computed)return;let i=this.activeLink;if(i===void 0||i.sub!==_e)i=this.activeLink=new uc(_e,this),_e.deps?(i.prevDep=_e.depsTail,_e.depsTail.nextDep=i,_e.depsTail=i):_e.deps=_e.depsTail=i,ho(i);else if(i.version===-1&&(i.version=this.version,i.nextDep)){const l=i.nextDep;l.prevDep=i.prevDep,i.prevDep&&(i.prevDep.nextDep=l),i.prevDep=_e.depsTail,i.nextDep=void 0,_e.depsTail.nextDep=i,_e.depsTail=i,_e.deps===i&&(_e.deps=l)}return i}trigger(a){this.version++,mn++,this.notify(a)}notify(a){vr();try{for(let i=this.subs;i;i=i.prevSub)i.sub.notify()&&i.sub.dep.notify()}finally{br()}}}function ho(e){if(e.dep.sc++,e.sub.flags&4){const a=e.dep.computed;if(a&&!e.dep.subs){a.flags|=20;for(let l=a.deps;l;l=l.nextDep)ho(l)}const i=e.dep.subs;i!==e&&(e.prevSub=i,i&&(i.nextSub=e)),e.dep.subs=e}}const sr=new WeakMap,Ca=Symbol(""),rr=Symbol(""),vn=Symbol("");function je(e,a,i){if(mt&&_e){let l=sr.get(e);l||sr.set(e,l=new Map);let d=l.get(i);d||(l.set(i,d=new Ar),d.map=l,d.key=i),d.track()}}function Zt(e,a,i,l,d,c){const f=sr.get(e);if(!f){mn++;return}const p=m=>{m&&m.trigger()};if(vr(),a==="clear")f.forEach(p);else{const m=Y(e),T=m&&hr(i);if(m&&i==="length"){const S=Number(l);f.forEach((I,F)=>{(F==="length"||F===vn||!xt(F)&&F>=S)&&p(I)})}else switch((i!==void 0||f.has(void 0))&&p(f.get(i)),T&&p(f.get(vn)),a){case"add":m?T&&p(f.get("length")):(p(f.get(Ca)),Ma(e)&&p(f.get(rr)));break;case"delete":m||(p(f.get(Ca)),Ma(e)&&p(f.get(rr)));break;case"set":Ma(e)&&p(f.get(Ca));break}}br()}function Fa(e){const a=ve(e);return a===e?a:(je(a,"iterate",vn),ft(e)?a:a.map(vt))}function ls(e){return je(e=ve(e),"iterate",vn),e}function Ct(e,a){return ta(e)?Ka(Ia(e)?vt(a):a):vt(a)}const fc={__proto__:null,[Symbol.iterator](){return Xs(this,Symbol.iterator,e=>Ct(this,e))},concat(...e){return Fa(this).concat(...e.map(a=>Y(a)?Fa(a):a))},entries(){return Xs(this,"entries",e=>(e[1]=Ct(this,e[1]),e))},every(e,a){return Wt(this,"every",e,a,void 0,arguments)},filter(e,a){return Wt(this,"filter",e,a,i=>i.map(l=>Ct(this,l)),arguments)},find(e,a){return Wt(this,"find",e,a,i=>Ct(this,i),arguments)},findIndex(e,a){return Wt(this,"findIndex",e,a,void 0,arguments)},findLast(e,a){return Wt(this,"findLast",e,a,i=>Ct(this,i),arguments)},findLastIndex(e,a){return Wt(this,"findLastIndex",e,a,void 0,arguments)},forEach(e,a){return Wt(this,"forEach",e,a,void 0,arguments)},includes(...e){return qs(this,"includes",e)},indexOf(...e){return qs(this,"indexOf",e)},join(e){return Fa(this).join(e)},lastIndexOf(...e){return qs(this,"lastIndexOf",e)},map(e,a){return Wt(this,"map",e,a,void 0,arguments)},pop(){return nn(this,"pop")},push(...e){return nn(this,"push",e)},reduce(e,...a){return mi(this,"reduce",e,a)},reduceRight(e,...a){return mi(this,"reduceRight",e,a)},shift(){return nn(this,"shift")},some(e,a){return Wt(this,"some",e,a,void 0,arguments)},splice(...e){return nn(this,"splice",e)},toReversed(){return Fa(this).toReversed()},toSorted(e){return Fa(this).toSorted(e)},toSpliced(...e){return Fa(this).toSpliced(...e)},unshift(...e){return nn(this,"unshift",e)},values(){return Xs(this,"values",e=>Ct(this,e))}};function Xs(e,a,i){const l=ls(e),d=l[a]();return l!==e&&!ft(e)&&(d._next=d.next,d.next=()=>{const c=d._next();return c.done||(c.value=i(c.value)),c}),d}const pc=Array.prototype;function Wt(e,a,i,l,d,c){const f=ls(e),p=f!==e&&!ft(e),m=f[a];if(m!==pc[a]){const I=m.apply(e,c);return p?vt(I):I}let T=i;f!==e&&(p?T=function(I,F){return i.call(this,Ct(e,I),F,e)}:i.length>2&&(T=function(I,F){return i.call(this,I,F,e)}));const S=m.call(f,T,l);return p&&d?d(S):S}function mi(e,a,i,l){const d=ls(e),c=d!==e&&!ft(e);let f=i,p=!1;d!==e&&(c?(p=l.length===0,f=function(T,S,I){return p&&(p=!1,T=Ct(e,T)),i.call(this,T,Ct(e,S),I,e)}):i.length>3&&(f=function(T,S,I){return i.call(this,T,S,I,e)}));const m=d[a](f,...l);return p?Ct(e,m):m}function qs(e,a,i){const l=ve(e);je(l,"iterate",vn);const d=l[a](...i);return(d===-1||d===!1)&&Tr(i[0])?(i[0]=ve(i[0]),l[a](...i)):d}function nn(e,a,i=[]){Qt(),vr();const l=ve(e)[a].apply(e,i);return br(),ea(),l}const gc=pr("__proto__,__v_isRef,__isVue"),mo=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(xt));function hc(e){xt(e)||(e=String(e));const a=ve(this);return je(a,"has",e),a.hasOwnProperty(e)}class vo{constructor(a=!1,i=!1){this._isReadonly=a,this._isShallow=i}get(a,i,l){if(i==="__v_skip")return a.__v_skip;const d=this._isReadonly,c=this._isShallow;if(i==="__v_isReactive")return!d;if(i==="__v_isReadonly")return d;if(i==="__v_isShallow")return c;if(i==="__v_raw")return l===(d?c?_c:So:c?Ao:yo).get(a)||Object.getPrototypeOf(a)===Object.getPrototypeOf(l)?a:void 0;const f=Y(a);if(!d){let m;if(f&&(m=fc[i]))return m;if(i==="hasOwnProperty")return hc}const p=Reflect.get(a,i,Ue(a)?a:l);if((xt(i)?mo.has(i):gc(i))||(d||je(a,"get",i),c))return p;if(Ue(p)){const m=f&&hr(i)?p:p.value;return d&&Se(m)?or(m):m}return Se(p)?d?or(p):ds(p):p}}class bo extends vo{constructor(a=!1){super(!1,a)}set(a,i,l,d){let c=a[i];const f=Y(a)&&hr(i);if(!this._isShallow){const T=ta(c);if(!ft(l)&&!ta(l)&&(c=ve(c),l=ve(l)),!f&&Ue(c)&&!Ue(l))return T||(c.value=l),!0}const p=f?Number(i)<a.length:be(a,i),m=Reflect.set(a,i,l,Ue(a)?a:d);return a===ve(d)&&m&&(p?Nt(l,c)&&Zt(a,"set",i,l):Zt(a,"add",i,l)),m}deleteProperty(a,i){const l=be(a,i);a[i];const d=Reflect.deleteProperty(a,i);return d&&l&&Zt(a,"delete",i,void 0),d}has(a,i){const l=Reflect.has(a,i);return(!xt(i)||!mo.has(i))&&je(a,"has",i),l}ownKeys(a){return je(a,"iterate",Y(a)?"length":Ca),Reflect.ownKeys(a)}}class mc extends vo{constructor(a=!1){super(!0,a)}set(a,i){return!0}deleteProperty(a,i){return!0}}const vc=new bo,bc=new mc,yc=new bo(!0);const ir=e=>e,Kn=e=>Reflect.getPrototypeOf(e);function Ac(e,a,i){return function(...l){const d=this.__v_raw,c=ve(d),f=Ma(c),p=e==="entries"||e===Symbol.iterator&&f,m=e==="keys"&&f,T=d[e](...l),S=i?ir:a?Ka:vt;return!a&&je(c,"iterate",m?rr:Ca),We(Object.create(T),{next(){const{value:I,done:F}=T.next();return F?{value:I,done:F}:{value:p?[S(I[0]),S(I[1])]:S(I),done:F}}})}}function Vn(e){return function(...a){return e==="delete"?!1:e==="clear"?void 0:this}}function Sc(e,a){const i={get(d){const c=this.__v_raw,f=ve(c),p=ve(d);e||(Nt(d,p)&&je(f,"get",d),je(f,"get",p));const{has:m}=Kn(f),T=a?ir:e?Ka:vt;if(m.call(f,d))return T(c.get(d));if(m.call(f,p))return T(c.get(p));c!==f&&c.get(d)},get size(){const d=this.__v_raw;return!e&&je(ve(d),"iterate",Ca),d.size},has(d){const c=this.__v_raw,f=ve(c),p=ve(d);return e||(Nt(d,p)&&je(f,"has",d),je(f,"has",p)),d===p?c.has(d):c.has(d)||c.has(p)},forEach(d,c){const f=this,p=f.__v_raw,m=ve(p),T=a?ir:e?Ka:vt;return!e&&je(m,"iterate",Ca),p.forEach((S,I)=>d.call(c,T(S),T(I),f))}};return We(i,e?{add:Vn("add"),set:Vn("set"),delete:Vn("delete"),clear:Vn("clear")}:{add(d){const c=ve(this),f=Kn(c),p=ve(d),m=!a&&!ft(d)&&!ta(d)?p:d;return f.has.call(c,m)||Nt(d,m)&&f.has.call(c,d)||Nt(p,m)&&f.has.call(c,p)||(c.add(m),Zt(c,"add",m,m)),this},set(d,c){!a&&!ft(c)&&!ta(c)&&(c=ve(c));const f=ve(this),{has:p,get:m}=Kn(f);let T=p.call(f,d);T||(d=ve(d),T=p.call(f,d));const S=m.call(f,d);return f.set(d,c),T?Nt(c,S)&&Zt(f,"set",d,c):Zt(f,"add",d,c),this},delete(d){const c=ve(this),{has:f,get:p}=Kn(c);let m=f.call(c,d);m||(d=ve(d),m=f.call(c,d)),p&&p.call(c,d);const T=c.delete(d);return m&&Zt(c,"delete",d,void 0),T},clear(){const d=ve(this),c=d.size!==0,f=d.clear();return c&&Zt(d,"clear",void 0,void 0),f}}),["keys","values","entries",Symbol.iterator].forEach(d=>{i[d]=Ac(d,e,a)}),i}function Sr(e,a){const i=Sc(e,a);return(l,d,c)=>d==="__v_isReactive"?!e:d==="__v_isReadonly"?e:d==="__v_raw"?l:Reflect.get(be(i,d)&&d in l?i:l,d,c)}const wc={get:Sr(!1,!1)},Tc={get:Sr(!1,!0)},Pc={get:Sr(!0,!1)};const yo=new WeakMap,Ao=new WeakMap,So=new WeakMap,_c=new WeakMap;function Cc(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function ds(e){return ta(e)?e:wr(e,!1,vc,wc,yo)}function Ic(e){return wr(e,!1,yc,Tc,Ao)}function or(e){return wr(e,!0,bc,Pc,So)}function wr(e,a,i,l,d){if(!Se(e)||e.__v_raw&&!(a&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const c=d.get(e);if(c)return c;const f=Cc(Yd(e));if(f===0)return e;const p=new Proxy(e,f===2?l:i);return d.set(e,p),p}function Ia(e){return ta(e)?Ia(e.__v_raw):!!(e&&e.__v_isReactive)}function ta(e){return!!(e&&e.__v_isReadonly)}function ft(e){return!!(e&&e.__v_isShallow)}function Tr(e){return e?!!e.__v_raw:!1}function ve(e){const a=e&&e.__v_raw;return a?ve(a):e}function Nc(e){return!be(e,"__v_skip")&&Object.isExtensible(e)&&no(e,"__v_skip",!0),e}const vt=e=>Se(e)?ds(e):e,Ka=e=>Se(e)?or(e):e;function Ue(e){return e?e.__v_isRef===!0:!1}function Ht(e){return Rc(e,!1)}function Rc(e,a){return Ue(e)?e:new Dc(e,a)}class Dc{constructor(a,i){this.dep=new Ar,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=i?a:ve(a),this._value=i?a:vt(a),this.__v_isShallow=i}get value(){return this.dep.track(),this._value}set value(a){const i=this._rawValue,l=this.__v_isShallow||ft(a)||ta(a);a=l?a:ve(a),Nt(a,i)&&(this._rawValue=a,this._value=l?a:vt(a),this.dep.trigger())}}function kc(e){return Ue(e)?e.value:e}const xc={get:(e,a,i)=>a==="__v_raw"?e:kc(Reflect.get(e,a,i)),set:(e,a,i,l)=>{const d=e[a];return Ue(d)&&!Ue(i)?(d.value=i,!0):Reflect.set(e,a,i,l)}};function wo(e){return Ia(e)?e:new Proxy(e,xc)}class Ec{constructor(a,i,l){this.fn=a,this.setter=i,this._value=void 0,this.dep=new Ar(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=mn-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!i,this.isSSR=l}notify(){if(this.flags|=16,!(this.flags&8)&&_e!==this)return co(this,!0),!0}get value(){const a=this.dep.track();return po(this),a&&(a.version=this.dep.version),this._value}set value(a){this.setter&&this.setter(a)}}function Lc(e,a,i=!1){let l,d;return ne(e)?l=e:(l=e.get,d=e.set),new Ec(l,d,i)}const jn={},Jn=new WeakMap;let _a;function Gc(e,a=!1,i=_a){if(i){let l=Jn.get(i);l||Jn.set(i,l=[]),l.push(e)}}function Fc(e,a,i=Te){const{immediate:l,deep:d,once:c,scheduler:f,augmentJob:p,call:m}=i,T=X=>d?X:ft(X)||d===!1||d===0?Yt(X,1):Yt(X);let S,I,F,K,se=!1,H=!1;if(Ue(e)?(I=()=>e.value,se=ft(e)):Ia(e)?(I=()=>T(e),se=!0):Y(e)?(H=!0,se=e.some(X=>Ia(X)||ft(X)),I=()=>e.map(X=>{if(Ue(X))return X.value;if(Ia(X))return T(X);if(ne(X))return m?m(X,2):X()})):ne(e)?a?I=m?()=>m(e,2):e:I=()=>{if(F){Qt();try{F()}finally{ea()}}const X=_a;_a=S;try{return m?m(e,3,[K]):e(K)}finally{_a=X}}:I=Dt,a&&d){const X=I,Ee=d===!0?1/0:d;I=()=>Yt(X(),Ee)}const De=dc(),ye=()=>{S.stop(),De&&De.active&&gr(De.effects,S)};if(c&&a){const X=a;a=(...Ee)=>{const Pe=X(...Ee);return ye(),Pe}}let ce=H?new Array(e.length).fill(jn):jn;const ge=X=>{if(!(!(S.flags&1)||!S.dirty&&!X))if(a){const Ee=S.run();if(X||d||se||(H?Ee.some((Pe,it)=>Nt(Pe,ce[it])):Nt(Ee,ce))){F&&F();const Pe=_a;_a=S;try{const it=[Ee,ce===jn?void 0:H&&ce[0]===jn?[]:ce,K];ce=Ee,m?m(a,3,it):a(...it)}finally{_a=Pe}}}else S.run()};return p&&p(ge),S=new oo(I),S.scheduler=f?()=>f(ge,!1):ge,K=X=>Gc(X,!1,S),F=S.onStop=()=>{const X=Jn.get(S);if(X){if(m)m(X,4);else for(const Ee of X)Ee();Jn.delete(S)}},a?l?ge(!0):ce=S.run():f?f(ge.bind(null,!0),!0):S.run(),ye.pause=S.pause.bind(S),ye.resume=S.resume.bind(S),ye.stop=ye,ye}function Yt(e,a=1/0,i){if(a<=0||!Se(e)||e.__v_skip||(i=i||new Map,(i.get(e)||0)>=a))return e;if(i.set(e,a),a--,Ue(e))Yt(e.value,a,i);else if(Y(e))for(let l=0;l<e.length;l++)Yt(e[l],a,i);else if(Ua(e)||Ma(e))e.forEach(l=>{Yt(l,a,i)});else if(to(e)){for(const l in e)Yt(e[l],a,i);for(const l of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,l)&&Yt(e[l],a,i)}return e}function Pn(e,a,i,l){try{return l?e(...l):e()}catch(d){cs(d,a,i)}}function bt(e,a,i,l){if(ne(e)){const d=Pn(e,a,i,l);return d&&Qi(d)&&d.catch(c=>{cs(c,a,i)}),d}if(Y(e)){const d=[];for(let c=0;c<e.length;c++)d.push(bt(e[c],a,i,l));return d}}function cs(e,a,i,l=!0){const d=a?a.vnode:null,{errorHandler:c,throwUnhandledErrorInProduction:f}=a&&a.appContext.config||Te;if(a){let p=a.parent;const m=a.proxy,T=`https://vuejs.org/error-reference/#runtime-${i}`;for(;p;){const S=p.ec;if(S){for(let I=0;I<S.length;I++)if(S[I](e,m,T)===!1)return}p=p.parent}if(c){Qt(),Pn(c,null,10,[e,m,T]),ea();return}}zc(e,i,d,l,f)}function zc(e,a,i,l=!0,d=!1){if(d)throw e;console.error(e)}const qe=[];let _t=-1;const Ba=[];let pa=null,za=0;const To=Promise.resolve();let Zn=null;function un(e){const a=Zn||To;return e?a.then(this?e.bind(this):e):a}function Oc(e){let a=_t+1,i=qe.length;for(;a<i;){const l=a+i>>>1,d=qe[l],c=bn(d);c<e||c===e&&d.flags&2?a=l+1:i=l}return a}function Pr(e){if(!(e.flags&1)){const a=bn(e),i=qe[qe.length-1];!i||!(e.flags&2)&&a>=bn(i)?qe.push(e):qe.splice(Oc(a),0,e),e.flags|=1,Po()}}function Po(){Zn||(Zn=To.then(Co))}function Mc(e){if(!Y(e))pa&&e.id===-1?pa.splice(za+1,0,e):e.flags&1||(Ba.push(e),e.flags|=1);else for(let a=0;a<e.length;a++)Ba.push(e[a]);Po()}function vi(e,a,i=_t+1){for(;i<qe.length;i++){const l=qe[i];if(l&&l.flags&2){if(e&&l.id!==e.uid)continue;qe.splice(i,1),i--,l.flags&4&&(l.flags&=-2),l(),l.flags&4||(l.flags&=-2)}}}function _o(e){if(Ba.length){const a=[...new Set(Ba)].sort((i,l)=>bn(i)-bn(l));if(Ba.length=0,pa){for(let i=0;i<a.length;i++)pa.push(a[i]);return}for(pa=a,za=0;za<pa.length;za++){const i=pa[za];i.flags&4&&(i.flags&=-2),i.flags&8||i(),i.flags&=-2}pa=null,za=0}}const bn=e=>e.id==null?e.flags&2?-1:1/0:e.id;function Co(e){try{for(_t=0;_t<qe.length;_t++){const a=qe[_t];a&&!(a.flags&8)&&(a.flags&4&&(a.flags&=-2),Pn(a,a.i,a.i?15:14),a.flags&4||(a.flags&=-2))}}finally{for(;_t<qe.length;_t++){const a=qe[_t];a&&(a.flags&=-2)}_t=-1,qe.length=0,_o(),Zn=null,(qe.length||Ba.length)&&Co()}}let ut=null,Io=null;function Yn(e){const a=ut;return ut=e,Io=e&&e.type.__scopeId||null,a}function Bc(e,a=ut,i){if(!a||e._n)return e;const l=(...d)=>{l._d&&Ni(-1);const c=Yn(a),f=Na.length;let p;try{p=e(...d)}finally{for(let m=Na.length;m>f;m--)Qo();Yn(c),l._d&&Ni(1)}return p};return l._n=!0,l._c=!0,l._d=!0,l}function ue(e,a){if(ut===null)return e;const i=hs(ut),l=e.dirs||(e.dirs=[]);for(let d=0;d<a.length;d++){let[c,f,p,m=Te]=a[d];c&&(ne(c)&&(c={mounted:c,updated:c}),c.deep&&Yt(f),l.push({dir:c,instance:i,value:f,oldValue:void 0,arg:p,modifiers:m}))}return e}function wa(e,a,i,l){const d=e.dirs,c=a&&a.dirs;for(let f=0;f<d.length;f++){const p=d[f];c&&(p.oldValue=c[f].value);let m=p.dir[l];m&&(Qt(),bt(m,i,8,[e.el,p,e,a]),ea())}}function $c(e,a){if(Je){let i=Je.provides;const l=Je.parent&&Je.parent.provides;l===i&&(i=Je.provides=Object.create(l)),i[e]=a}}function Hn(e,a,i=!1){const l=zu();if(l||$a){let d=$a?$a._context.provides:l?l.parent==null||l.ce?l.vnode.appContext&&l.vnode.appContext.provides:l.parent.provides:void 0;if(d&&e in d)return d[e];if(arguments.length>1)return i&&ne(a)?a.call(l&&l.proxy):a}}const Kc=Symbol.for("v-scx"),Vc=()=>Hn(Kc);function Re(e,a,i){return No(e,a,i)}function No(e,a,i=Te){const{immediate:l,deep:d,flush:c,once:f}=i,p=We({},i),m=a&&l||!a&&c!=="post";let T;if(Sn){if(c==="sync"){const K=Vc();T=K.__watcherHandles||(K.__watcherHandles=[])}else if(!m){const K=()=>{};return K.stop=Dt,K.resume=Dt,K.pause=Dt,K}}const S=Je;p.call=(K,se,H)=>bt(K,S,se,H);let I=!1;c==="post"?p.scheduler=K=>{et(K,S&&S.suspense)}:c!=="sync"&&(I=!0,p.scheduler=(K,se)=>{se?K():Pr(K)}),p.augmentJob=K=>{a&&(K.flags|=4),I&&(K.flags|=2,S&&(K.id=S.uid,K.i=S))};const F=Fc(e,a,p);return Sn&&(T?T.push(F):m&&F()),F}function jc(e,a,i){const l=this.proxy,d=xe(e)?e.includes(".")?Ro(l,e):()=>l[e]:e.bind(l,l);let c;ne(a)?c=a:(c=a.handler,i=a);const f=_n(this),p=No(d,c.bind(l),i);return f(),p}function Ro(e,a){const i=a.split(".");return()=>{let l=e;for(let d=0;d<i.length&&l;d++)l=l[i[d]];return l}}const Uc=Symbol("_vte"),us=e=>e.__isTeleport,Js=Symbol("_leaveCb");function Wc(e){let a=e[0];if(e.length>1){for(const i of e)if(i.type!==aa){a=i;break}}return a}function Do(e){if(!Cr(e))return us(e.type)&&e.children?Wc(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:a,children:i}=e;if(i){if(a&16)return i[0];if(a&32&&ne(i.default))return i.default()}}function _r(e,a){if(e.shapeFlag&6&&e.component){e.transition=a;const i=e.component.subTree;_r(us(i.type)&&Do(i)||i,a)}else e.shapeFlag&128?(e.ssContent.transition=a.clone(e.ssContent),e.ssFallback.transition=a.clone(e.ssFallback)):e.transition=a}function ko(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function bi(e,a){let i;return!!((i=Object.getOwnPropertyDescriptor(e,a))&&!i.configurable)}const Qn=new WeakMap;function fn(e,a,i,l,d=!1){if(Y(e)){e.forEach((H,De)=>fn(H,a&&(Y(a)?a[De]:a),i,l,d));return}if(pn(l)&&!d){l.shapeFlag&512&&l.type.__asyncResolved&&l.component.subTree.component&&fn(e,a,i,l.component.subTree);return}const c=l.shapeFlag&4?hs(l.component):l.el,f=d?null:c,{i:p,r:m}=e,T=a&&a.r,S=p.refs===Te?p.refs={}:p.refs,I=p.setupState,F=ve(I),K=I===Te?Yi:H=>bi(S,H)?!1:be(F,H),se=(H,De)=>!(De&&bi(S,De));if(T!=null&&T!==m){if(yi(a),xe(T))S[T]=null,K(T)&&(I[T]=null);else if(Ue(T)){const H=a;se(T,H.k)&&(T.value=null),H.k&&(S[H.k]=null)}}if(ne(m))Pn(m,p,12,[f,S]);else{const H=xe(m),De=Ue(m);if(H||De){const ye=()=>{if(e.f){const ce=H?K(m)?I[m]:S[m]:se()||!e.k?m.value:S[e.k];if(d)Y(ce)&&gr(ce,c);else if(Y(ce))ce.includes(c)||ce.push(c);else if(H)S[m]=[c],K(m)&&(I[m]=S[m]);else{const ge=[c];se(m,e.k)&&(m.value=ge),e.k&&(S[e.k]=ge)}}else H?(S[m]=f,K(m)&&(I[m]=f)):De&&(se(m,e.k)&&(m.value=f),e.k&&(S[e.k]=f))};if(f){const ce=()=>{ye(),Qn.delete(e)};ce.id=-1,Qn.set(e,ce),et(ce,i)}else yi(e),ye()}}}function yi(e){const a=Qn.get(e);a&&(a.flags|=8,Qn.delete(e))}os().requestIdleCallback;os().cancelIdleCallback;const pn=e=>!!e.type.__asyncLoader,Cr=e=>e.type.__isKeepAlive;function Hc(e,a){xo(e,"a",a)}function Xc(e,a){xo(e,"da",a)}function xo(e,a,i=Je){const l=e.__wdc||(e.__wdc=()=>{let d=i;for(;d;){if(d.isDeactivated)return;d=d.parent}return e()});if(fs(a,l,i),i){let d=i.parent;for(;d&&d.parent;)Cr(d.parent.vnode)&&qc(l,a,i,d),d=d.parent}}function qc(e,a,i,l){const d=fs(a,e,l,!0);Go(()=>{gr(l[a],d)},i)}function fs(e,a,i=Je,l=!1){if(i){const d=i[e]||(i[e]=[]),c=a.__weh||(a.__weh=(...f)=>{Qt();const p=_n(i),m=bt(a,i,e,f);return p(),ea(),m});return l?d.unshift(c):d.push(c),c}}const na=e=>(a,i=Je)=>{(!Sn||e==="sp")&&fs(e,(...l)=>a(...l),i)},Jc=na("bm"),Eo=na("m"),Zc=na("bu"),Yc=na("u"),Lo=na("bum"),Go=na("um"),Qc=na("sp"),eu=na("rtg"),tu=na("rtc");function au(e,a=Je){fs("ec",e,a)}const nu=Symbol.for("v-ndc");function oe(e,a,i,l){let d;const c=i,f=Y(e);if(f||xe(e)){const p=f&&Ia(e);let m=!1,T=!1;p&&(m=!ft(e),T=ta(e),e=ls(e)),d=new Array(e.length);for(let S=0,I=e.length;S<I;S++)d[S]=a(m?T?Ka(vt(e[S])):vt(e[S]):e[S],S,void 0,c)}else if(typeof e=="number"){d=new Array(e);for(let p=0;p<e;p++)d[p]=a(p+1,p,void 0,c)}else if(Se(e))if(e[Symbol.iterator])d=Array.from(e,(p,m)=>a(p,m,void 0,c));else{const p=Object.keys(e);d=new Array(p.length);for(let m=0,T=p.length;m<T;m++){const S=p[m];d[m]=a(e[S],S,m,c)}}else d=[];return d}const lr=e=>e?nl(e)?hs(e):lr(e.parent):null,gn=We(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>lr(e.parent),$root:e=>lr(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>zo(e),$forceUpdate:e=>e.f||(e.f=()=>{Pr(e.update)}),$nextTick:e=>e.n||(e.n=un.bind(e.proxy)),$watch:e=>jc.bind(e)}),Zs=(e,a)=>e!==Te&&!e.__isScriptSetup&&be(e,a),su={get({_:e},a){if(a==="__v_skip")return!0;const{ctx:i,setupState:l,data:d,props:c,accessCache:f,type:p,appContext:m}=e;if(a[0]!=="$"){const F=f[a];if(F!==void 0)switch(F){case 1:return l[a];case 2:return d[a];case 4:return i[a];case 3:return c[a]}else{if(Zs(l,a))return f[a]=1,l[a];if(d!==Te&&be(d,a))return f[a]=2,d[a];if(be(c,a))return f[a]=3,c[a];if(i!==Te&&be(i,a))return f[a]=4,i[a];dr&&(f[a]=0)}}const T=gn[a];let S,I;if(T)return a==="$attrs"&&je(e.attrs,"get",""),T(e);if((S=p.__cssModules)&&(S=S[a]))return S;if(i!==Te&&be(i,a))return f[a]=4,i[a];if(I=m.config.globalProperties,be(I,a))return I[a]},set({_:e},a,i){const{data:l,setupState:d,ctx:c}=e;return Zs(d,a)?(d[a]=i,!0):l!==Te&&be(l,a)?(l[a]=i,!0):be(e.props,a)||a[0]==="$"&&a.slice(1)in e?!1:(c[a]=i,!0)},has({_:{data:e,setupState:a,accessCache:i,ctx:l,appContext:d,props:c,type:f}},p){let m;return!!(i[p]||e!==Te&&p[0]!=="$"&&be(e,p)||Zs(a,p)||be(c,p)||be(l,p)||be(gn,p)||be(d.config.globalProperties,p)||(m=f.__cssModules)&&m[p])},defineProperty(e,a,i){return i.get!=null?e._.accessCache[a]=0:be(i,"value")&&this.set(e,a,i.value,null),Reflect.defineProperty(e,a,i)}};function Ai(e){return Y(e)?e.reduce((a,i)=>(a[i]=null,a),{}):e}let dr=!0;function ru(e){const a=zo(e),i=e.proxy,l=e.ctx;dr=!1,a.beforeCreate&&Si(a.beforeCreate,e,"bc");const{data:d,computed:c,methods:f,watch:p,provide:m,inject:T,created:S,beforeMount:I,mounted:F,beforeUpdate:K,updated:se,activated:H,deactivated:De,beforeDestroy:ye,beforeUnmount:ce,destroyed:ge,unmounted:X,render:Ee,renderTracked:Pe,renderTriggered:it,errorCaptured:Be,serverPrefetch:Ra,expose:Et,inheritAttrs:sa,components:ma,directives:Da,filters:t}=a;if(T&&iu(T,l,null),f)for(const we in f){const he=f[we];ne(he)&&(l[we]=he.bind(i))}if(d){const we=d.call(i,i);Se(we)&&(e.data=ds(we))}if(dr=!0,c)for(const we in c){const he=c[we],tt=ne(he)?he.bind(i,i):ne(he.get)?he.get.bind(i,i):Dt,Lt=!ne(he)&&ne(he.set)?he.set.bind(i):Dt,at=W({get:tt,set:Lt});Object.defineProperty(l,we,{enumerable:!0,configurable:!0,get:()=>at.value,set:Ge=>at.value=Ge})}if(p)for(const we in p)Fo(p[we],l,i,we);if(m){const we=ne(m)?m.call(i):m;Reflect.ownKeys(we).forEach(he=>{$c(he,we[he])})}S&&Si(S,e,"c");function Oe(we,he){Y(he)?he.forEach(tt=>we(tt.bind(i))):he&&we(he.bind(i))}if(Oe(Jc,I),Oe(Eo,F),Oe(Zc,K),Oe(Yc,se),Oe(Hc,H),Oe(Xc,De),Oe(au,Be),Oe(tu,Pe),Oe(eu,it),Oe(Lo,ce),Oe(Go,X),Oe(Qc,Ra),Y(Et))if(Et.length){const we=e.exposed||(e.exposed={});Et.forEach(he=>{Object.defineProperty(we,he,{get:()=>i[he],set:tt=>i[he]=tt,enumerable:!0})})}else e.exposed||(e.exposed={});Ee&&e.render===Dt&&(e.render=Ee),sa!=null&&(e.inheritAttrs=sa),ma&&(e.components=ma),Da&&(e.directives=Da),Ra&&ko(e)}function iu(e,a,i=Dt){Y(e)&&(e=cr(e));for(const l in e){const d=e[l];let c;Se(d)?"default"in d?c=Hn(d.from||l,d.default,!0):c=Hn(d.from||l):c=Hn(d),Ue(c)?Object.defineProperty(a,l,{enumerable:!0,configurable:!0,get:()=>c.value,set:f=>c.value=f}):a[l]=c}}function Si(e,a,i){bt(Y(e)?e.map(l=>l.bind(a.proxy)):e.bind(a.proxy),a,i)}function Fo(e,a,i,l){let d=l.includes(".")?Ro(i,l):()=>i[l];if(xe(e)){const c=a[e];ne(c)&&Re(d,c)}else if(ne(e))Re(d,e.bind(i));else if(Se(e))if(Y(e))e.forEach(c=>Fo(c,a,i,l));else{const c=ne(e.handler)?e.handler.bind(i):a[e.handler];ne(c)&&Re(d,c,e)}}function zo(e){const a=e.type,{mixins:i,extends:l}=a,{mixins:d,optionsCache:c,config:{optionMergeStrategies:f}}=e.appContext,p=c.get(a);let m;return p?m=p:!d.length&&!i&&!l?m=a:(m={},d.length&&d.forEach(T=>es(m,T,f,!0)),es(m,a,f)),Se(a)&&c.set(a,m),m}function es(e,a,i,l=!1){const{mixins:d,extends:c}=a;c&&es(e,c,i,!0),d&&d.forEach(f=>es(e,f,i,!0));for(const f in a)if(!(l&&f==="expose")){const p=ou[f]||i&&i[f];e[f]=p?p(e[f],a[f]):a[f]}return e}const ou={data:wi,props:Ti,emits:Ti,methods:rn,computed:rn,beforeCreate:Xe,created:Xe,beforeMount:Xe,mounted:Xe,beforeUpdate:Xe,updated:Xe,beforeDestroy:Xe,beforeUnmount:Xe,destroyed:Xe,unmounted:Xe,activated:Xe,deactivated:Xe,errorCaptured:Xe,serverPrefetch:Xe,components:rn,directives:rn,watch:du,provide:wi,inject:lu};function wi(e,a){return a?e?function(){return We(ne(e)?e.call(this,this):e,ne(a)?a.call(this,this):a)}:a:e}function lu(e,a){return rn(cr(e),cr(a))}function cr(e){if(Y(e)){const a={};for(let i=0;i<e.length;i++)a[e[i]]=e[i];return a}return e}function Xe(e,a){return e?[...new Set([].concat(e,a))]:a}function rn(e,a){return e?We(Object.create(null),e,a):a}function Ti(e,a){return e?Y(e)&&Y(a)?[...new Set([...e,...a])]:We(Object.create(null),Ai(e),Ai(a??{})):a}function du(e,a){if(!e)return a;if(!a)return e;const i=We(Object.create(null),e);for(const l in a)i[l]=Xe(e[l],a[l]);return i}function Oo(){return{app:null,config:{isNativeTag:Yi,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let cu=0;function uu(e,a){return function(l,d=null){ne(l)||(l=We({},l)),d!=null&&!Se(d)&&(d=null);const c=Oo(),f=new WeakSet,p=[];let m=!1;const T=c.app={_uid:cu++,_component:l,_props:d,_container:null,_context:c,_instance:null,version:Vu,get config(){return c.config},set config(S){},use(S,...I){return f.has(S)||(S&&ne(S.install)?(f.add(S),S.install(T,...I)):ne(S)&&(f.add(S),S(T,...I))),T},mixin(S){return c.mixins.includes(S)||c.mixins.push(S),T},component(S,I){return I?(c.components[S]=I,T):c.components[S]},directive(S,I){return I?(c.directives[S]=I,T):c.directives[S]},mount(S,I,F){if(!m){const K=T._ceVNode||kt(l,d);return K.appContext=c,F===!0?F="svg":F===!1&&(F=void 0),e(K,S,F),m=!0,T._container=S,S.__vue_app__=T,hs(K.component)}},onUnmount(S){p.push(S)},unmount(){m&&(bt(p,T._instance,16),e(null,T._container),delete T._container.__vue_app__)},provide(S,I){return c.provides[S]=I,T},runWithContext(S){const I=$a;$a=T;try{return S()}finally{$a=I}}};return T}}let $a=null;const fu=(e,a)=>a==="modelValue"||a==="model-value"?e.modelModifiers:e[`${a}Modifiers`]||e[`${ht(a)}Modifiers`]||e[`${ha(a)}Modifiers`];function pu(e,a,...i){if(e.isUnmounted)return;const l=e.vnode.props||Te;let d=i;const c=a.startsWith("update:"),f=c&&fu(l,a.slice(7));f&&(f.trim&&(d=i.map(S=>xe(S)?S.trim():S)),f.number&&(d=i.map(is)));let p,m=l[p=Us(a)]||l[p=Us(ht(a))];!m&&c&&(m=l[p=Us(ha(a))]),m&&bt(m,e,6,d);const T=l[p+"Once"];if(T){if(!e.emitted)e.emitted={};else if(e.emitted[p])return;e.emitted[p]=!0,bt(T,e,6,d)}}const gu=new WeakMap;function Mo(e,a,i=!1){const l=i?gu:a.emitsCache,d=l.get(e);if(d!==void 0)return d;const c=e.emits;let f={},p=!1;if(!ne(e)){const m=T=>{const S=Mo(T,a,!0);S&&(p=!0,We(f,S))};!i&&a.mixins.length&&a.mixins.forEach(m),e.extends&&m(e.extends),e.mixins&&e.mixins.forEach(m)}return!c&&!p?(Se(e)&&l.set(e,null),null):(Y(c)?c.forEach(m=>f[m]=null):We(f,c),Se(e)&&l.set(e,f),f)}function ps(e,a){return!e||!ns(a)?!1:(a=a.slice(2),a=a==="Once"?a:a.replace(/Once$/,""),be(e,a[0].toLowerCase()+a.slice(1))||be(e,ha(a))||be(e,a))}function Pi(e){const{type:a,vnode:i,proxy:l,withProxy:d,propsOptions:[c],slots:f,attrs:p,emit:m,render:T,renderCache:S,props:I,data:F,setupState:K,ctx:se,inheritAttrs:H}=e,De=Yn(e);let ye,ce;try{if(i.shapeFlag&4){const X=d||l,Ee=X;ye=It(T.call(Ee,X,S,I,K,F,se)),ce=p}else{const X=a;ye=It(X.length>1?X(I,{attrs:p,slots:f,emit:m}):X(I,null)),ce=a.props?p:hu(p)}}catch(X){Na.length=0,cs(X,e,1),ye=kt(aa)}let ge=ye;if(ce&&H!==!1){const X=Object.keys(ce),{shapeFlag:Ee}=ge;X.length&&Ee&7&&(c&&X.some(ss)&&(ce=mu(ce,c)),ge=Va(ge,ce,!1,!0))}if(i.dirs&&(ge=Va(ge,null,!1,!0),ge.dirs=ge.dirs?ge.dirs.concat(i.dirs):i.dirs),i.transition){const X=us(ge.type)&&Do(ge)||ge;_r(X,i.transition)}return ye=ge,Yn(De),ye}const hu=e=>{let a;for(const i in e)(i==="class"||i==="style"||ns(i))&&((a||(a={}))[i]=e[i]);return a},mu=(e,a)=>{const i={};for(const l in e)(!ss(l)||!(l.slice(9)in a))&&(i[l]=e[l]);return i};function vu(e,a,i){const{props:l,children:d,component:c}=e,{props:f,children:p,patchFlag:m}=a,T=c.emitsOptions;if(a.dirs||a.transition)return!0;if(i&&m>=0){if(m&1024)return!0;if(m&16)return l?_i(l,f,T):!!f;if(m&8){const S=a.dynamicProps;for(let I=0;I<S.length;I++){const F=S[I];if(Bo(f,l,F)&&!ps(T,F))return!0}}}else return(d||p)&&(!p||!p.$stable)?!0:l===f?!1:l?f?_i(l,f,T):!0:!!f;return!1}function _i(e,a,i){const l=Object.keys(a);if(l.length!==Object.keys(e).length)return!0;for(let d=0;d<l.length;d++){const c=l[d];if(Bo(a,e,c)&&!ps(i,c))return!0}return!1}function Bo(e,a,i){const l=e[i],d=a[i];return i==="style"&&Se(l)&&Se(d)?!Wa(l,d):l!==d}function bu({vnode:e,parent:a,suspense:i},l){for(;a;){const d=a.subTree;if(d.suspense&&d.suspense.activeBranch===e&&(d.suspense.vnode.el=d.el=l,e=d),d===e)(e=a.vnode).el=l,a=a.parent;else break}i&&i.activeBranch===e&&(i.vnode.el=l)}const $o={},Ko=()=>Object.create($o),Vo=e=>Object.getPrototypeOf(e)===$o;function yu(e,a,i,l=!1){const d={},c=Ko();e.propsDefaults=Object.create(null),jo(e,a,d,c);for(const f in e.propsOptions[0])f in d||(d[f]=void 0);i?e.props=l?d:Ic(d):e.type.props?e.props=d:e.props=c,e.attrs=c}function Au(e,a,i,l){const{props:d,attrs:c,vnode:{patchFlag:f}}=e,p=ve(d),[m]=e.propsOptions;let T=!1;if((l||f>0)&&!(f&16)){if(f&8){const S=e.vnode.dynamicProps;for(let I=0;I<S.length;I++){let F=S[I];if(ps(e.emitsOptions,F))continue;const K=a[F];if(m)if(be(c,F))K!==c[F]&&(c[F]=K,T=!0);else{const se=ht(F);d[se]=ur(m,p,se,K,e,!1)}else K!==c[F]&&(c[F]=K,T=!0)}}}else{jo(e,a,d,c)&&(T=!0);let S;for(const I in p)(!a||!be(a,I)&&((S=ha(I))===I||!be(a,S)))&&(m?i&&(i[I]!==void 0||i[S]!==void 0)&&(d[I]=ur(m,p,I,void 0,e,!0)):delete d[I]);if(c!==p)for(const I in c)(!a||!be(a,I))&&(delete c[I],T=!0)}T&&Zt(e.attrs,"set","")}function jo(e,a,i,l){const[d,c]=e.propsOptions;let f=!1,p;if(a)for(let m in a){if(ln(m))continue;const T=a[m];let S;d&&be(d,S=ht(m))?!c||!c.includes(S)?i[S]=T:(p||(p={}))[S]=T:ps(e.emitsOptions,m)||(!(m in l)||T!==l[m])&&(l[m]=T,f=!0)}if(c){const m=ve(i),T=p||Te;for(let S=0;S<c.length;S++){const I=c[S];i[I]=ur(d,m,I,T[I],e,!be(T,I))}}return f}function ur(e,a,i,l,d,c){const f=e[i];if(f!=null){const p=be(f,"default");if(p&&l===void 0){const m=f.default;if(f.type!==Function&&!f.skipFactory&&ne(m)){const{propsDefaults:T}=d;if(i in T)l=T[i];else{const S=_n(d);l=T[i]=m.call(null,a),S()}}else l=m;d.ce&&d.ce._setProp(i,l)}f[0]&&(c&&!p?l=!1:f[1]&&(l===""||l===ha(i))&&(l=!0))}return l}const Su=new WeakMap;function Uo(e,a,i=!1){const l=i?Su:a.propsCache,d=l.get(e);if(d)return d;const c=e.props,f={},p=[];let m=!1;if(!ne(e)){const S=I=>{m=!0;const[F,K]=Uo(I,a,!0);We(f,F),K&&p.push(...K)};!i&&a.mixins.length&&a.mixins.forEach(S),e.extends&&S(e.extends),e.mixins&&e.mixins.forEach(S)}if(!c&&!m)return Se(e)&&l.set(e,Oa),Oa;if(Y(c))for(let S=0;S<c.length;S++){const I=ht(c[S]);Ci(I)&&(f[I]=Te)}else if(c)for(const S in c){const I=ht(S);if(Ci(I)){const F=c[S],K=f[I]=Y(F)||ne(F)?{type:F}:We({},F),se=K.type;let H=!1,De=!0;if(Y(se))for(let ye=0;ye<se.length;++ye){const ce=se[ye],ge=ne(ce)&&ce.name;if(ge==="Boolean"){H=!0;break}else ge==="String"&&(De=!1)}else H=ne(se)&&se.name==="Boolean";K[0]=H,K[1]=De,(H||be(K,"default"))&&p.push(I)}}const T=[f,p];return Se(e)&&l.set(e,T),T}function Ci(e){return e[0]!=="$"&&!ln(e)}const Ir=e=>e==="_"||e==="_ctx"||e==="$stable",Nr=e=>Y(e)?e.map(It):[It(e)],wu=(e,a,i)=>{if(a._n)return a;const l=Bc((...d)=>Nr(a(...d)),i);return l._c=!1,l},Wo=(e,a,i)=>{const l=e._ctx;for(const d in e){if(Ir(d))continue;const c=e[d];if(ne(c))a[d]=wu(d,c,l);else if(c!=null){const f=Nr(c);a[d]=()=>f}}},Ho=(e,a)=>{const i=Nr(a);e.slots.default=()=>i},Xo=(e,a,i)=>{for(const l in a)(i||!Ir(l))&&(e[l]=a[l])},Tu=(e,a,i)=>{const l=e.slots=Ko();if(e.vnode.shapeFlag&32){const d=a._;d?(Xo(l,a,i),i&&no(l,"_",d,!0)):Wo(a,l)}else a&&Ho(e,a)},Pu=(e,a,i)=>{const{vnode:l,slots:d}=e;let c=!0,f=Te;if(l.shapeFlag&32){const p=a._;p?i&&p===1?c=!1:Xo(d,a,i):(c=!a.$stable,Wo(a,d)),f=a}else a&&(Ho(e,a),f={default:1});if(c)for(const p in d)!Ir(p)&&f[p]==null&&delete d[p]},et=Ru;function _u(e){return Cu(e)}function Cu(e,a){const i=os();i.__VUE__=!0;const{insert:l,remove:d,patchProp:c,createElement:f,createText:p,createComment:m,setText:T,setElementText:S,parentNode:I,nextSibling:F,setScopeId:K=Dt,insertStaticContent:se}=e,H=(h,y,P,x=null,k=null,D=null,z=void 0,G=null,L=!!y.dynamicChildren)=>{if(h===y)return;h&&!sn(h,y)&&(x=$e(h),Ge(h,k,D,!0),h=null),y.patchFlag===-2&&(L=!1,y.dynamicChildren=null);const{type:R,ref:U,shapeFlag:B}=y;switch(R){case gs:De(h,y,P,x);break;case aa:ye(h,y,P,x);break;case Xn:h==null&&ce(y,P,x,z);break;case J:ma(h,y,P,x,k,D,z,G,L);break;default:B&1?Ee(h,y,P,x,k,D,z,G,L):B&6?Da(h,y,P,x,k,D,z,G,L):(B&64||B&128)&&R.process(h,y,P,x,k,D,z,G,L,zt)}U!=null&&k?fn(U,h&&h.ref,D,y||h,!y):U==null&&h&&h.ref!=null&&fn(h.ref,null,D,h,!0)},De=(h,y,P,x)=>{if(h==null)l(y.el=p(y.children),P,x);else{const k=y.el=h.el;y.children!==h.children&&T(k,y.children)}},ye=(h,y,P,x)=>{h==null?l(y.el=m(y.children||""),P,x):y.el=h.el},ce=(h,y,P,x)=>{[h.el,h.anchor]=se(h.children,y,P,x,h.el,h.anchor)},ge=({el:h,anchor:y},P,x)=>{let k;for(;h&&h!==y;)k=F(h),l(h,P,x),h=k;l(y,P,x)},X=({el:h,anchor:y})=>{let P;for(;h&&h!==y;)P=F(h),d(h),h=P;d(y)},Ee=(h,y,P,x,k,D,z,G,L)=>{if(y.type==="svg"?z="svg":y.type==="math"&&(z="mathml"),h==null)Pe(y,P,x,k,D,z,G,L);else{const R=h.el&&h.el._isVueCE?h.el:null;try{R&&R._beginPatch(),Ra(h,y,k,D,z,G,L)}finally{R&&R._endPatch()}}},Pe=(h,y,P,x,k,D,z,G)=>{let L,R;const{props:U,shapeFlag:B,transition:j,dirs:O}=h;if(L=h.el=f(h.type,D,U&&U.is,U),B&8?S(L,h.children):B&16&&Be(h.children,L,null,x,k,Ys(h,D),z,G),O&&wa(h,null,x,"created"),it(L,h,h.scopeId,z,x),U){for(const q in U)q!=="value"&&!ln(q)&&c(L,q,null,U[q],D,x);"value"in U&&c(L,"value",null,U.value,D),(R=U.onVnodeBeforeMount)&&Pt(R,x,h)}O&&wa(h,null,x,"beforeMount");const _=Iu(k,j);_&&j.beforeEnter(L),l(L,y,P),((R=U&&U.onVnodeMounted)||_||O)&&et(()=>{R&&Pt(R,x,h),_&&j.enter(L),O&&wa(h,null,x,"mounted")},k)},it=(h,y,P,x,k)=>{if(P&&K(h,P),x)for(let D=0;D<x.length;D++)K(h,x[D]);if(k){let D=k.subTree;if(y===D||Yo(D.type)&&(D.ssContent===y||D.ssFallback===y)){const z=k.vnode;it(h,z,z.scopeId,z.slotScopeIds,k.parent)}}},Be=(h,y,P,x,k,D,z,G,L=0)=>{for(let R=L;R<h.length;R++){const U=h[R]=G?Jt(h[R]):It(h[R]);H(null,U,y,P,x,k,D,z,G)}},Ra=(h,y,P,x,k,D,z)=>{const G=y.el=h.el;let{patchFlag:L,dynamicChildren:R,dirs:U}=y;L|=h.patchFlag&16;const B=h.props||Te,j=y.props||Te;let O;if(P&&Ta(P,!1),(O=j.onVnodeBeforeUpdate)&&Pt(O,P,y,h),U&&wa(y,h,P,"beforeUpdate"),P&&Ta(P,!0),R&&(!h.dynamicChildren||h.dynamicChildren.length!==R.length)&&(L=0,z=!1,R=null),(B.innerHTML&&j.innerHTML==null||B.textContent&&j.textContent==null)&&S(G,""),R?Et(h.dynamicChildren,R,G,P,x,Ys(y,k),D):z||he(h,y,G,null,P,x,Ys(y,k),D,!1),L>0){if(L&16)sa(G,B,j,P,k);else if(L&2&&B.class!==j.class&&c(G,"class",null,j.class,k),L&4&&c(G,"style",B.style,j.style,k),L&8){const _=y.dynamicProps;for(let q=0;q<_.length;q++){const fe=_[q],Ie=B[fe],Le=j[fe];(Le!==Ie||fe==="value")&&c(G,fe,Ie,Le,k,P)}}L&1&&h.children!==y.children&&S(G,y.children)}else!z&&R==null&&sa(G,B,j,P,k);((O=j.onVnodeUpdated)||U)&&et(()=>{O&&Pt(O,P,y,h),U&&wa(y,h,P,"updated")},x)},Et=(h,y,P,x,k,D,z)=>{for(let G=0;G<y.length;G++){const L=h[G],R=y[G],U=L.el&&(L.type===J||!sn(L,R)||L.shapeFlag&198)?I(L.el):P;H(L,R,U,null,x,k,D,z,!0)}},sa=(h,y,P,x,k)=>{if(y!==P){if(y!==Te)for(const D in y)!ln(D)&&!(D in P)&&c(h,D,y[D],null,k,x);for(const D in P){if(ln(D))continue;const z=P[D],G=y[D];z!==G&&D!=="value"&&c(h,D,G,z,k,x)}"value"in P&&c(h,"value",y.value,P.value,k)}},ma=(h,y,P,x,k,D,z,G,L)=>{const R=y.el=h?h.el:p(""),U=y.anchor=h?h.anchor:p("");let{patchFlag:B,dynamicChildren:j,slotScopeIds:O}=y;O&&(G=G?G.concat(O):O),h==null?(l(R,P,x),l(U,P,x),Be(y.children||[],P,U,k,D,z,G,L)):B>0&&B&64&&j&&h.dynamicChildren&&h.dynamicChildren.length===j.length?(Et(h.dynamicChildren,j,P,k,D,z,G),(y.key!=null||k&&y===k.subTree)&&qo(h,y,!0)):he(h,y,P,U,k,D,z,G,L)},Da=(h,y,P,x,k,D,z,G,L)=>{y.slotScopeIds=G,h==null?y.shapeFlag&512?k.ctx.activate(y,P,x,z,L):t(y,P,x,k,D,z,L):ka(h,y,L)},t=(h,y,P,x,k,D,z)=>{const G=h.component=Fu(h,x,k);if(Cr(h)&&(G.ctx.renderer=zt),Ou(G,!1,z),G.asyncDep){if(k&&k.registerDep(G,Oe,z),!h.el){const L=G.subTree=kt(aa);ye(null,L,y,P),h.placeholder=L.el}}else Oe(G,h,y,P,k,D,z)},ka=(h,y,P)=>{const x=y.component=h.component;if(vu(h,y,P))if(x.asyncDep&&!x.asyncResolved){we(x,y,P);return}else x.next=y,x.update();else y.el=h.el,x.vnode=y},Oe=(h,y,P,x,k,D,z)=>{const G=()=>{if(h.isMounted){let{next:B,bu:j,u:O,parent:_,vnode:q}=h;{const Ze=Jo(h);if(Ze){B&&(B.el=q.el,we(h,B,z)),Ze.asyncDep.then(()=>{et(()=>{h.isUnmounted||R()},k)});return}}let fe=B,Ie;Ta(h,!1),B?(B.el=q.el,we(h,B,z)):B=q,j&&Wn(j),(Ie=B.props&&B.props.onVnodeBeforeUpdate)&&Pt(Ie,_,B,q),Ta(h,!0);const Le=Pi(h),lt=h.subTree;h.subTree=Le,H(lt,Le,I(lt.el),$e(lt),h,k,D),B.el=Le.el,fe===null&&bu(h,Le.el),O&&et(O,k),(Ie=B.props&&B.props.onVnodeUpdated)&&et(()=>Pt(Ie,_,B,q),k)}else{let B;const{el:j,props:O}=y,{bm:_,m:q,parent:fe,root:Ie,type:Le}=h,lt=pn(y);Ta(h,!1),_&&Wn(_),!lt&&(B=O&&O.onVnodeBeforeMount)&&Pt(B,fe,y),Ta(h,!0);{Ie.ce&&Ie.ce._hasShadowRoot()&&Ie.ce._injectChildStyle(Le,h.parent?h.parent.type:void 0);const Ze=h.subTree=Pi(h);H(null,Ze,P,x,h,k,D),y.el=Ze.el}if(q&&et(q,k),!lt&&(B=O&&O.onVnodeMounted)){const Ze=y;et(()=>Pt(B,fe,Ze),k)}(y.shapeFlag&256||fe&&pn(fe.vnode)&&fe.vnode.shapeFlag&256)&&h.a&&et(h.a,k),h.isMounted=!0,y=P=x=null}};h.scope.on();const L=h.effect=new oo(G);h.scope.off();const R=h.update=L.run.bind(L),U=h.job=L.runIfDirty.bind(L);U.i=h,U.id=h.uid,L.scheduler=()=>Pr(U),Ta(h,!0),R()},we=(h,y,P)=>{y.component=h;const x=h.vnode.props;h.vnode=y,h.next=null,Au(h,y.props,x,P),Pu(h,y.children,P),Qt(),vi(h),ea()},he=(h,y,P,x,k,D,z,G,L=!1)=>{const R=h&&h.children,U=h?h.shapeFlag:0,B=y.children,{patchFlag:j,shapeFlag:O}=y;if(j>0){if(j&128){Lt(R,B,P,x,k,D,z,G,L);return}else if(j&256){tt(R,B,P,x,k,D,z,G,L);return}}O&8?(U&16&&Ft(R,k,D),B!==R&&S(P,B)):U&16?O&16?Lt(R,B,P,x,k,D,z,G,L):Ft(R,k,D,!0):(U&8&&S(P,""),O&16&&Be(B,P,x,k,D,z,G,L))},tt=(h,y,P,x,k,D,z,G,L)=>{h=h||Oa,y=y||Oa;const R=h.length,U=y.length,B=Math.min(R,U);let j;for(j=0;j<B;j++){const O=y[j]=L?Jt(y[j]):It(y[j]);H(h[j],O,P,null,k,D,z,G,L)}R>U?Ft(h,k,D,!0,!1,B):Be(y,P,x,k,D,z,G,L,B)},Lt=(h,y,P,x,k,D,z,G,L)=>{let R=0;const U=y.length;let B=h.length-1,j=U-1;for(;R<=B&&R<=j;){const O=h[R],_=y[R]=L?Jt(y[R]):It(y[R]);if(sn(O,_))H(O,_,P,null,k,D,z,G,L);else break;R++}for(;R<=B&&R<=j;){const O=h[B],_=y[j]=L?Jt(y[j]):It(y[j]);if(sn(O,_))H(O,_,P,null,k,D,z,G,L);else break;B--,j--}if(R>B){if(R<=j){const O=j+1,_=O<U?y[O].el:x;for(;R<=j;)H(null,y[R]=L?Jt(y[R]):It(y[R]),P,_,k,D,z,G,L),R++}}else if(R>j)for(;R<=B;)Ge(h[R],k,D,!0),R++;else{const O=R,_=R,q=new Map;for(R=_;R<=j;R++){const Ve=y[R]=L?Jt(y[R]):It(y[R]);Ve.key!=null&&q.set(Ve.key,R)}let fe,Ie=0;const Le=j-_+1;let lt=!1,Ze=0;const va=new Array(Le);for(R=0;R<Le;R++)va[R]=0;for(R=O;R<=B;R++){const Ve=h[R];if(Ie>=Le){Ge(Ve,k,D,!0);continue}let Ye;if(Ve.key!=null)Ye=q.get(Ve.key);else for(fe=_;fe<=j;fe++)if(va[fe-_]===0&&sn(Ve,y[fe])){Ye=fe;break}Ye===void 0?Ge(Ve,k,D,!0):(va[Ye-_]=R+1,Ye>=Ze?Ze=Ye:lt=!0,H(Ve,y[Ye],P,null,k,D,z,G,L),Ie++)}const In=lt?Nu(va):Oa;for(fe=In.length-1,R=Le-1;R>=0;R--){const Ve=_+R,Ye=y[Ve],Nn=y[Ve+1],Rn=Ve+1<U?Nn.el||Zo(Nn):x;va[R]===0?H(null,Ye,P,Rn,k,D,z,G,L):lt&&(fe<0||R!==In[fe]?at(Ye,P,Rn,2):fe--)}}},at=(h,y,P,x,k=null)=>{const{el:D,type:z,transition:G,children:L,shapeFlag:R}=h;if(R&6){at(h.component.subTree,y,P,x);return}if(R&128){h.suspense.move(y,P,x);return}if(R&64){z.move(h,y,P,zt);return}if(z===J){l(D,y,P);for(let B=0;B<L.length;B++)at(L[B],y,P,x);l(h.anchor,y,P);return}if(z===Xn){ge(h,y,P);return}if(x!==2&&R&1&&G)if(x===0)G.persisted&&!D[Js]?l(D,y,P):(G.beforeEnter(D),l(D,y,P),et(()=>G.enter(D),k));else{const{leave:B,delayLeave:j,afterLeave:O}=G,_=()=>{h.ctx.isUnmounted?d(D):l(D,y,P)},q=()=>{const fe=D._isLeaving||!!D[Js];D._isLeaving&&D[Js](!0),G.persisted&&!fe?_():B(D,()=>{_(),O&&O()})};j?j(D,_,q):q()}else l(D,y,P)},Ge=(h,y,P,x=!1,k=!1)=>{const{type:D,props:z,ref:G,children:L,dynamicChildren:R,shapeFlag:U,patchFlag:B,dirs:j,cacheIndex:O,memo:_}=h;if(B===-2&&(k=!1),G!=null&&(Qt(),fn(G,null,P,h,!0),ea()),O!=null&&(y.renderCache[O]=void 0),U&256){y.ctx.deactivate(h);return}const q=U&1&&j,fe=!pn(h);let Ie;if(fe&&(Ie=z&&z.onVnodeBeforeUnmount)&&Pt(Ie,y,h),U&6)Ha(h.component,P,x);else{if(U&128){h.suspense.unmount(P,x);return}q&&wa(h,null,y,"beforeUnmount"),U&64?h.type.remove(h,y,P,zt,x):R&&!R.hasOnce&&(D!==J||B>0&&B&64)?Ft(R,y,P,!1,!0):(D===J&&B&384||!k&&U&16)&&Ft(L,y,P),x&&ot(h)}const Le=_!=null&&O==null;(fe&&(Ie=z&&z.onVnodeUnmounted)||q||Le)&&et(()=>{Ie&&Pt(Ie,y,h),q&&wa(h,null,y,"unmounted"),Le&&(h.el=null)},P)},ot=h=>{const{type:y,el:P,anchor:x,transition:k}=h;if(y===J){Gt(P,x);return}if(y===Xn){X(h);return}const D=()=>{d(P),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(h.shapeFlag&1&&k&&!k.persisted){const{leave:z,delayLeave:G}=k,L=()=>z(P,D);G?G(h.el,D,L):L()}else D()},Gt=(h,y)=>{let P;for(;h!==y;)P=F(h),d(h),h=P;d(y)},Ha=(h,y,P)=>{const{bum:x,scope:k,job:D,subTree:z,um:G,m:L,a:R}=h;Ii(L),Ii(R),x&&Wn(x),k.stop(),D&&(D.flags|=8,Ge(z,h,y,P)),G&&et(G,y),et(()=>{h.isUnmounted=!0},y)},Ft=(h,y,P,x=!1,k=!1,D=0)=>{for(let z=D;z<h.length;z++)Ge(h[z],y,P,x,k)},$e=h=>{if(h.shapeFlag&6)return $e(h.component.subTree);if(h.shapeFlag&128)return h.suspense.next();const y=F(h.anchor||h.el),P=y&&y[Uc];return P?F(P):y};let ra=!1;const xa=(h,y,P)=>{let x;h==null?y._vnode&&(Ge(y._vnode,null,null,!0),x=y._vnode.component):H(y._vnode||null,h,y,null,null,null,P),y._vnode=h,ra||(ra=!0,vi(x),_o(),ra=!1)},zt={p:H,um:Ge,m:at,r:ot,mt:t,mc:Be,pc:he,pbc:Et,n:$e,o:e};return{render:xa,hydrate:void 0,createApp:uu(xa)}}function Ys({type:e,props:a},i){return i==="svg"&&e==="foreignObject"||i==="mathml"&&e==="annotation-xml"&&a&&a.encoding&&a.encoding.includes("html")?void 0:i}function Ta({effect:e,job:a},i){i?(e.flags|=32,a.flags|=4):(e.flags&=-33,a.flags&=-5)}function Iu(e,a){return(!e||e&&!e.pendingBranch)&&a&&!a.persisted}function qo(e,a,i=!1){const l=e.children,d=a.children;if(Y(l)&&Y(d))for(let c=0;c<l.length;c++){const f=l[c];let p=d[c];p.shapeFlag&1&&!p.dynamicChildren&&((p.patchFlag<=0||p.patchFlag===32)&&(p=d[c]=Jt(d[c]),p.el=f.el),!i&&p.patchFlag!==-2&&qo(f,p)),p.type===gs&&(p.patchFlag===-1&&(p=d[c]=Jt(p)),p.el=f.el),p.type===aa&&!p.el&&(p.el=f.el)}}function Nu(e){const a=e.slice(),i=[0];let l,d,c,f,p;const m=e.length;for(l=0;l<m;l++){const T=e[l];if(T!==0){if(d=i[i.length-1],e[d]<T){a[l]=d,i.push(l);continue}for(c=0,f=i.length-1;c<f;)p=c+f>>1,e[i[p]]<T?c=p+1:f=p;T<e[i[c]]&&(c>0&&(a[l]=i[c-1]),i[c]=l)}}for(c=i.length,f=i[c-1];c-- >0;)i[c]=f,f=a[f];return i}function Jo(e){const a=e.subTree.component;if(a)return a.asyncDep&&!a.asyncResolved?a:Jo(a)}function Ii(e){if(e)for(let a=0;a<e.length;a++)e[a].flags|=8}function Zo(e){if(e.placeholder)return e.placeholder;const a=e.component;return a?Zo(a.subTree):null}const Yo=e=>e.__isSuspense;function Ru(e,a){a&&a.pendingBranch?Y(e)?a.effects.push(...e):a.effects.push(e):Mc(e)}const J=Symbol.for("v-fgt"),gs=Symbol.for("v-txt"),aa=Symbol.for("v-cmt"),Xn=Symbol.for("v-stc"),Na=[];let rt=null;function v(e=!1){Na.push(rt=e?null:[])}function Qo(){Na.pop(),rt=Na[Na.length-1]||null}let yn=1;function Ni(e,a=!1){yn+=e,e<0&&rt&&a&&(rt.hasOnce=!0)}function el(e){return e.dynamicChildren=yn>0?rt||Oa:null,Qo(),yn>0&&rt&&rt.push(e),e}function b(e,a,i,l,d,c){return el(o(e,a,i,l,d,c,!0))}function Du(e,a,i,l,d){return el(kt(e,a,i,l,d,!0))}function tl(e){return e?e.__v_isVNode===!0:!1}function sn(e,a){return e.type===a.type&&e.key===a.key}const al=({key:e})=>e??null,qn=({ref:e,ref_key:a,ref_for:i})=>(typeof e=="number"&&(e=""+e),e!=null?xe(e)||Ue(e)||ne(e)?{i:ut,r:e,k:a,f:!!i}:e:null);function o(e,a=null,i=null,l=0,d=null,c=e===J?0:1,f=!1,p=!1){const m={__v_isVNode:!0,__v_skip:!0,type:e,props:a,key:a&&al(a),ref:a&&qn(a),scopeId:Io,slotScopeIds:null,children:i,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:c,patchFlag:l,dynamicProps:d,dynamicChildren:null,appContext:null,ctx:ut};return p?(ts(m,i),c&128&&e.normalize(m)):i&&(m.shapeFlag|=xe(i)?8:16),yn>0&&!f&&rt&&(m.patchFlag>0||c&6)&&m.patchFlag!==32&&rt.push(m),m}const kt=ku;function ku(e,a=null,i=null,l=0,d=null,c=!1){if((!e||e===nu)&&(e=aa),tl(e)){const p=Va(e,a,!0);return i&&ts(p,i),yn>0&&!c&&rt&&(p.shapeFlag&6?rt[rt.indexOf(e)]=p:rt.push(p)),p.patchFlag=-2,p}if(Ku(e)&&(e=e.__vccOpts),a){a=xu(a);let{class:p,style:m}=a;p&&!xe(p)&&(a.class=le(p)),Se(m)&&(Tr(m)&&!Y(m)&&(m=We({},m)),a.style=hn(m))}const f=xe(e)?1:Yo(e)?128:us(e)?64:Se(e)?4:ne(e)?2:0;return o(e,a,i,l,d,f,c,!0)}function xu(e){return e?Tr(e)||Vo(e)?We({},e):e:null}function Va(e,a,i=!1,l=!1){const{props:d,ref:c,patchFlag:f,children:p,transition:m}=e,T=a?Eu(d||{},a):d,S={__v_isVNode:!0,__v_skip:!0,type:e.type,props:T,key:T&&al(T),ref:a&&a.ref?i&&c?Y(c)?c.concat(qn(a)):[c,qn(a)]:qn(a):c,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:p,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:a&&e.type!==J?f===-1?16:f|16:f,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:m,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Va(e.ssContent),ssFallback:e.ssFallback&&Va(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return m&&l&&_r(S,m.clone(S)),S}function de(e=" ",a=0){return kt(gs,null,e,a)}function fa(e,a){const i=kt(Xn,null,e);return i.staticCount=a,i}function E(e="",a=!1){return a?(v(),Du(aa,null,e)):kt(aa,null,e)}function It(e){return e==null||typeof e=="boolean"?kt(aa):Y(e)?kt(J,null,e.slice()):tl(e)?Jt(e):kt(gs,null,String(e))}function Jt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Va(e)}function ts(e,a){let i=0;const{shapeFlag:l}=e;if(a==null)a=null;else if(Y(a))i=16;else if(typeof a=="object")if(l&65){const d=a.default;d&&(d._c&&(d._d=!1),ts(e,d()),d._c&&(d._d=!0));return}else{i=32;const d=a._;!d&&!Vo(a)?a._ctx=ut:d===3&&ut&&(ut.slots._===1?a._=1:(a._=2,e.patchFlag|=1024))}else if(ne(a)){if(l&65){ts(e,{default:a});return}a={default:a,_ctx:ut},i=32}else a=String(a),l&64?(i=16,a=[de(a)]):i=8;e.children=a,e.shapeFlag|=i}function Eu(...e){const a={};for(let i=0;i<e.length;i++){const l=e[i];for(const d in l)if(d==="class")a.class!==l.class&&(a.class=le([a.class,l.class]));else if(d==="style")a.style=hn([a.style,l.style]);else if(ns(d)){const c=a[d],f=l[d];f&&c!==f&&!(Y(c)&&c.includes(f))?a[d]=c?[].concat(c,f):f:f==null&&c==null&&!ss(d)&&(a[d]=f)}else d!==""&&(a[d]=l[d])}return a}function Pt(e,a,i,l=null){bt(e,a,7,[i,l])}const Lu=Oo();let Gu=0;function Fu(e,a,i){const l=e.type,d=(a?a.appContext:e.appContext)||Lu,c={uid:Gu++,vnode:e,type:l,parent:a,appContext:d,root:null,next:null,subTree:null,effect:null,update:null,job:null,scope:new lc(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:a?a.provides:Object.create(d.provides),ids:a?a.ids:["",0,0],accessCache:null,renderCache:[],components:null,directives:null,propsOptions:Uo(l,d),emitsOptions:Mo(l,d),emit:null,emitted:null,propsDefaults:Te,inheritAttrs:l.inheritAttrs,ctx:Te,data:Te,props:Te,attrs:Te,slots:Te,refs:Te,setupState:Te,setupContext:null,suspense:i,suspenseId:i?i.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return c.ctx={_:c},c.root=a?a.root:c,c.emit=pu.bind(null,c),e.ce&&e.ce(c),c}let Je=null;const zu=()=>Je||ut;let as,An;{const e=os(),a=(i,l)=>{let d;return(d=e[i])||(d=e[i]=[]),d.push(l),c=>{d.length>1?d.forEach(f=>f(c)):d[0](c)}};as=a("__VUE_INSTANCE_SETTERS__",i=>Je=i),An=a("__VUE_SSR_SETTERS__",i=>Sn=i)}const _n=e=>{const a=Je;return as(e),e.scope.on(),()=>{e.scope.off(),as(a)}},Ri=()=>{Je&&Je.scope.off(),as(null)};function nl(e){return e.vnode.shapeFlag&4}let Sn=!1;function Ou(e,a=!1,i=!1){a&&An(a);const{props:l,children:d}=e.vnode,c=nl(e);yu(e,l,c,a),Tu(e,d,i||a);const f=c?Mu(e,a):void 0;return a&&An(!1),f}function Mu(e,a){const i=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,su);const{setup:l}=i;if(l){Qt();const d=e.setupContext=l.length>1?$u(e):null,c=_n(e),f=Pn(l,e,0,[e.props,d]),p=Qi(f);if(ea(),c(),(p||e.sp)&&!pn(e)&&ko(e),p){if(f.then(Ri,Ri),a)return f.then(m=>{An(!0);try{Di(e,m,a)}finally{An(!1)}}).catch(m=>{cs(m,e,0)});e.asyncDep=f}else Di(e,f)}else sl(e)}function Di(e,a,i){ne(a)?e.type.__ssrInlineRender?e.ssrRender=a:e.render=a:Se(a)&&(e.setupState=wo(a)),sl(e)}function sl(e,a,i){const l=e.type;e.render||(e.render=l.render||Dt);{const d=_n(e);Qt();try{ru(e)}finally{ea(),d()}}}const Bu={get(e,a){return je(e,"get",""),e[a]}};function $u(e){const a=i=>{e.exposed=i||{}};return{attrs:new Proxy(e.attrs,Bu),slots:e.slots,emit:e.emit,expose:a}}function hs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(wo(Nc(e.exposed)),{get(a,i){if(i in a)return a[i];if(i in gn)return gn[i](e)},has(a,i){return i in a||i in gn}})):e.proxy}function Ku(e){return ne(e)&&"__vccOpts"in e}const W=(e,a)=>Lc(e,a,Sn),Vu="3.5.41";let fr;const ki=typeof window<"u"&&window.trustedTypes;if(ki)try{fr=ki.createPolicy("vue",{createHTML:e=>e})}catch{}const rl=fr?e=>fr.createHTML(e):e=>e,ju="http://www.w3.org/2000/svg",Uu="http://www.w3.org/1998/Math/MathML",qt=typeof document<"u"?document:null,xi=qt&&qt.createElement("template"),Wu={insert:(e,a,i)=>{a.insertBefore(e,i||null)},remove:e=>{const a=e.parentNode;a&&a.removeChild(e)},createElement:(e,a,i,l)=>{const d=a==="svg"?qt.createElementNS(ju,e):a==="mathml"?qt.createElementNS(Uu,e):i?qt.createElement(e,{is:i}):qt.createElement(e);return e==="select"&&l&&l.multiple!=null&&d.setAttribute("multiple",l.multiple),d},createText:e=>qt.createTextNode(e),createComment:e=>qt.createComment(e),setText:(e,a)=>{e.nodeValue=a},setElementText:(e,a)=>{e.textContent=a},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>qt.querySelector(e),setScopeId(e,a){e.setAttribute(a,"")},insertStaticContent(e,a,i,l,d,c){const f=i?i.previousSibling:a.lastChild;if(d&&(d===c||d.nextSibling))for(;a.insertBefore(d.cloneNode(!0),i),!(d===c||!(d=d.nextSibling)););else{xi.innerHTML=rl(l==="svg"?`<svg>${e}</svg>`:l==="mathml"?`<math>${e}</math>`:e);const p=xi.content;if(l==="svg"||l==="mathml"){const m=p.firstChild;for(;m.firstChild;)p.appendChild(m.firstChild);p.removeChild(m)}a.insertBefore(p,i)}return[f?f.nextSibling:a.firstChild,i?i.previousSibling:a.lastChild]}},Hu=Symbol("_vtc");function Xu(e,a,i){const l=e[Hu];l&&(a=(a?[a,...l]:[...l]).join(" ")),a==null?e.removeAttribute("class"):i?e.setAttribute("class",a):e.className=a}const Ei=Symbol("_vod"),qu=Symbol("_vsh"),Ju=Symbol(""),Zu=/(?:^|;)\s*display\s*:/;function Yu(e,a,i){const l=e.style,d=xe(i);let c=!1;if(i&&!d){if(a)if(xe(a))for(const f of a.split(";")){const p=f.slice(0,f.indexOf(":")).trim();i[p]==null&&on(l,p,"")}else for(const f in a)i[f]==null&&on(l,f,"");for(const f in i){f==="display"&&(c=!0);const p=i[f];p!=null?ef(e,f,!xe(a)&&a?a[f]:void 0,p)||on(l,f,p):on(l,f,"")}}else if(d){if(a!==i){const f=l[Ju];f&&(i+=";"+f),l.cssText=i,c=Zu.test(i)}}else a&&e.removeAttribute("style");Ei in e&&(e[Ei]=c?l.display:"",e[qu]&&(l.display="none"))}const Li=/\s*!important$/;function on(e,a,i){if(Y(i))i.forEach(l=>on(e,a,l));else if(i==null&&(i=""),a.startsWith("--"))e.setProperty(a,i);else{const l=Qu(e,a);Li.test(i)?e.setProperty(ha(l),i.replace(Li,""),"important"):e[l]=i}}const Gi=["Webkit","Moz","ms"],Qs={};function Qu(e,a){const i=Qs[a];if(i)return i;let l=ht(a);if(l!=="filter"&&l in e)return Qs[a]=l;l=ao(l);for(let d=0;d<Gi.length;d++){const c=Gi[d]+l;if(c in e)return Qs[a]=c}return a}function ef(e,a,i,l){return e.tagName==="TEXTAREA"&&(a==="width"||a==="height")&&xe(l)&&i===l}const Fi="http://www.w3.org/1999/xlink";function zi(e,a,i,l,d,c=ic(a)){l&&a.startsWith("xlink:")?i==null?e.removeAttributeNS(Fi,a.slice(6,a.length)):e.setAttributeNS(Fi,a,i):i==null||c&&!so(i)?e.removeAttribute(a):e.setAttribute(a,c?"":xt(i)?String(i):i)}function Oi(e,a,i,l,d){if(a==="innerHTML"||a==="textContent"){i!=null&&(e[a]=a==="innerHTML"?rl(i):i);return}const c=e.tagName;if(a==="value"&&c!=="PROGRESS"&&!c.includes("-")){const p=c==="OPTION"?e.getAttribute("value")||"":e.value,m=i==null?e.type==="checkbox"?"on":"":String(i);(p!==m||!("_value"in e))&&(e.value=m),i==null&&e.removeAttribute(a),e._value=i;return}let f=!1;if(i===""||i==null){const p=typeof e[a];p==="boolean"?i=so(i):i==null&&p==="string"?(i="",f=!0):p==="number"&&(i=0,f=!0)}try{e[a]=i}catch{}f&&e.removeAttribute(d||a)}function ga(e,a,i,l){e.addEventListener(a,i,l)}function tf(e,a,i,l){e.removeEventListener(a,i,l)}const Mi=Symbol("_vei");function af(e,a,i,l,d=null){const c=e[Mi]||(e[Mi]={}),f=c[a];if(l&&f)f.value=l;else{const[p,m]=rf(a);if(l){const T=c[a]=df(l,d);ga(e,p,T,m)}else f&&(tf(e,p,f,m),c[a]=void 0)}}const nf=/(Once|Passive|Capture)$/,sf=/^on:?(?:Once|Passive|Capture)$/;function rf(e){let a,i;for(;(i=e.match(nf))&&!sf.test(e);)a||(a={}),e=e.slice(0,e.length-i[1].length),a[i[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):ha(e.slice(2)),a]}let er=0;const of=Promise.resolve(),lf=()=>er||(of.then(()=>er=0),er=Date.now());function df(e,a){const i=l=>{if(!l._vts)l._vts=Date.now();else if(l._vts<=i.attached)return;const d=i.value;if(Y(d)){const c=l.stopImmediatePropagation;l.stopImmediatePropagation=()=>{c.call(l),l._stopped=!0};const f=d.slice(),p=[l];for(let m=0;m<f.length&&!l._stopped;m++){const T=f[m];T&&bt(T,a,5,p)}}else bt(d,a,5,[l])};return i.value=e,i.attached=lf(),i}const Bi=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,cf=(e,a,i,l,d,c)=>{const f=d==="svg";a==="class"?Xu(e,l,f):a==="style"?Yu(e,i,l):ns(a)?ss(a)||af(e,a,i,l,c):(a[0]==="."?(a=a.slice(1),!0):a[0]==="^"?(a=a.slice(1),!1):uf(e,a,l,f))?(Oi(e,a,l),!e.tagName.includes("-")&&(a==="value"||a==="checked"||a==="selected")&&zi(e,a,l,f,c,a!=="value")):e._isVueCE&&(ff(e,a)||e._def.__asyncLoader&&(/[A-Z]/.test(a)||!xe(l)))?Oi(e,ht(a),l,c,a):(a==="true-value"?e._trueValue=l:a==="false-value"&&(e._falseValue=l),zi(e,a,l,f))};function uf(e,a,i,l){if(l)return!!(a==="innerHTML"||a==="textContent"||a in e&&Bi(a)&&ne(i));if(a==="spellcheck"||a==="draggable"||a==="translate"||a==="autocorrect"||a==="sandbox"&&e.tagName==="IFRAME"||a==="form"||a==="list"&&e.tagName==="INPUT"||a==="type"&&e.tagName==="TEXTAREA")return!1;if(a==="width"||a==="height"){const d=e.tagName;if(d==="IMG"||d==="VIDEO"||d==="CANVAS"||d==="SOURCE")return!1}return Bi(a)&&xe(i)?!1:a in e}function ff(e,a){const i=e._def.props;if(!i)return!1;const l=ht(a);return Array.isArray(i)?i.some(d=>ht(d)===l):Object.keys(i).some(d=>ht(d)===l)}const ja=e=>{const a=e.props["onUpdate:modelValue"]||!1;return Y(a)?i=>Wn(a,i):a};function pf(e){e.target.composing=!0}function $i(e){const a=e.target;a.composing&&(a.composing=!1,a.dispatchEvent(new Event("input")))}const Rt=Symbol("_assign"),Un=Symbol("_initialValue");function tr(e,a,i){return a&&(e=e.trim()),i&&(e=is(e)),e}const Ne={created(e,{modifiers:{lazy:a,trim:i,number:l}},d){e.parentNode&&(e.type==="text"?e[Un]=e.defaultValue.replace(/[\r\n]/g,""):e.type==="textarea"&&(e[Un]=e.defaultValue.replace(/\r\n?/g,`
2
+ `))),e[Rt]=ja(d);const c=l||d.props&&d.props.type==="number";ga(e,a?"change":"input",f=>{f.target.composing||e[Rt](tr(e.value,i,c))}),(i||c)&&ga(e,"change",()=>{e.value=tr(e.value,i,c)}),a||(ga(e,"compositionstart",pf),ga(e,"compositionend",$i),ga(e,"change",$i))},mounted(e,{value:a,modifiers:{trim:i,number:l}}){const d=a??"",c=e[Un];delete e[Un],c!==void 0&&(e.type==="text"||e.type==="textarea")&&e.value!==c?e[Rt](tr(e.value,i,l)):e.value=d},beforeUpdate(e,{value:a,oldValue:i,modifiers:{lazy:l,trim:d,number:c}},f){if(e[Rt]=ja(f),e.composing)return;const p=(c||e.type==="number")&&!/^0\d/.test(e.value)?is(e.value):e.value,m=a??"";if(p===m)return;const T=e.getRootNode();(T instanceof Document||T instanceof ShadowRoot)&&T.activeElement===e&&e.type!=="range"&&(l&&a===i||d&&e.value.trim()===m)||(e.value=m)}},ar={deep:!0,created(e,a,i){e[Rt]=ja(i),ga(e,"change",()=>{const l=e._modelValue,d=wn(e),c=e.checked,f=e[Rt];if(Y(l)){const p=mr(l,d),m=p!==-1;if(c&&!m)f(l.concat(d));else if(!c&&m){const T=[...l];T.splice(p,1),f(T)}}else if(Ua(l)){const p=new Set(l);c?p.add(d):p.delete(d),f(p)}else f(il(e,c))})},mounted:Ki,beforeUpdate(e,a,i){e[Rt]=ja(i),Ki(e,a,i)}};function Ki(e,{value:a,oldValue:i},l){e._modelValue=a;let d;if(Y(a))d=mr(a,l.props.value)>-1;else if(Ua(a))d=a.has(l.props.value);else{if(a===i)return;d=Wa(a,il(e,!0))}e.checked!==d&&(e.checked=d)}const Pa={deep:!0,created(e,{value:a,modifiers:{number:i}},l){e._modelValue=a,ga(e,"change",()=>{const d=Array.prototype.filter.call(e.options,c=>c.selected).map(c=>i?is(wn(c)):wn(c));e[Rt](e.multiple?Ua(e._modelValue)?new Set(d):d:d[0]),e._assigning=!0,un(()=>{e._assigning=!1})}),e[Rt]=ja(l)},mounted(e,{value:a}){Vi(e,a)},beforeUpdate(e,{value:a},i){e._modelValue=a,e[Rt]=ja(i)},updated(e,{value:a}){e._assigning||Vi(e,a)}};function Vi(e,a){const i=e.multiple,l=Y(a);if(!(i&&!l&&!Ua(a))){for(let d=0,c=e.options.length;d<c;d++){const f=e.options[d],p=wn(f);if(i)if(l){const m=typeof p;m==="string"||m==="number"?f.selected=a.some(T=>String(T)===String(p)):f.selected=mr(a,p)>-1}else f.selected=a.has(p);else if(Wa(wn(f),a)){e.selectedIndex!==d&&(e.selectedIndex=d);return}}!i&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function wn(e){return"_value"in e?e._value:e.value}function il(e,a){const i=a?"_trueValue":"_falseValue";return i in e?e[i]:a}const gf=["ctrl","shift","alt","meta"],hf={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,a)=>gf.some(i=>e[`${i}Key`]&&!a.includes(i))},Xt=(e,a)=>{if(!e)return e;const i=e._withMods||(e._withMods={}),l=a.join(".");return i[l]||(i[l]=((d,...c)=>{for(let f=0;f<a.length;f++){const p=hf[a[f]];if(p&&p(d,a))return}return e(d,...c)}))},mf={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},vf=(e,a)=>{const i=e._withKeys||(e._withKeys={}),l=a.join(".");return i[l]||(i[l]=(d=>{if(!("key"in d))return;const c=ha(d.key);if(a.some(f=>f===c||mf[f]===c))return e(d)}))},bf=We({patchProp:cf},Wu);let ji;function yf(){return ji||(ji=_u(bf))}const Af=((...e)=>{const a=yf().createApp(...e),{mount:i}=a;return a.mount=l=>{const d=wf(l);if(!d)return;const c=a._component;!ne(c)&&!c.render&&!c.template&&(c.template=d.innerHTML),d.nodeType===1&&(d.textContent="");const f=i(d,!1,Sf(d));return d instanceof Element&&(d.removeAttribute("v-cloak"),d.setAttribute("data-v-app","")),f},a});function Sf(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function wf(e){return xe(e)?document.querySelector(e):e}const Tf="modulepreload",Pf=function(e,a){return new URL(e,a).href},Ui={},_f=function(a,i,l){let d=Promise.resolve();if(i&&i.length>0){let T=function(S){return Promise.all(S.map(I=>Promise.resolve(I).then(F=>({status:"fulfilled",value:F}),F=>({status:"rejected",reason:F}))))};const f=document.getElementsByTagName("link"),p=document.querySelector("meta[property=csp-nonce]"),m=p?.nonce||p?.getAttribute("nonce");d=T(i.map(S=>{if(S=Pf(S,l),S in Ui)return;Ui[S]=!0;const I=S.endsWith(".css"),F=I?'[rel="stylesheet"]':"";if(l)for(let se=f.length-1;se>=0;se--){const H=f[se];if(H.href===S&&(!I||H.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${S}"]${F}`))return;const K=document.createElement("link");if(K.rel=I?"stylesheet":Tf,I||(K.as="script"),K.crossOrigin="",K.href=S,m&&K.setAttribute("nonce",m),document.head.appendChild(K),I)return new Promise((se,H)=>{K.addEventListener("load",se),K.addEventListener("error",()=>H(new Error(`Unable to preload CSS for ${S}`)))})}))}function c(f){const p=new Event("vite:preloadError",{cancelable:!0});if(p.payload=f,window.dispatchEvent(p),!p.defaultPrevented)throw f}return d.then(f=>{for(const p of f||[])p.status==="rejected"&&c(p.reason);return a().catch(c)})},Cf={en:{},it:{"AI Chat Learning":"Apprendimento AI Chat","Manage node options, shared CHAT learning and full configuration import/export.":"Gestisci le opzioni del nodo, l’apprendimento CHAT condiviso e l’import/export della configurazione completa.","View, edit and back up the shared learning file used by every KNX AI node on this storage.":"Visualizza, modifica e salva una copia del file di apprendimento condiviso usato da ogni nodo KNX AI in questo archivio.",sessions:"sessioni","The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately.":"I record nativi KNX AI sono autorevoli e modificabili. Il salvataggio li valida e sostituisce immediatamente il contesto CHAT condiviso attivo.","Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated.":"È accettato soltanto il formato KNXAI_CHAT_CONTEXT 3 attuale. I precedenti file Markdown/JSON e Base64 non vengono letti, importati né migrati.","File path":"Percorso file","AI Chat Learning file":"File di apprendimento AI Chat","Reload from disk":"Ricarica dal disco",Copy:"Copia","Download Backup":"Scarica backup","Restore Backup":"Ripristina backup","Reinitialize Memory":"Re-inizializza memoria","Reinitializing...":"Re-inizializzazione...","Save Changes":"Salva modifiche","Saving...":"Salvataggio...","Last saved:":"Ultimo salvataggio:","Discard unsaved chat-learning changes and reload?":"Scartare le modifiche non salvate all’apprendimento della chat e ricaricare?","Loading chat learning...":"Caricamento apprendimento chat...","Chat learning loaded":"Apprendimento chat caricato","Saving chat learning...":"Salvataggio apprendimento chat...","Chat learning saved":"Apprendimento chat salvato","Failed to load chat learning":"Impossibile caricare l’apprendimento chat","Failed to save chat learning":"Impossibile salvare l’apprendimento chat","This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?":"Questa operazione elimina definitivamente tutte le sessioni, le istruzioni e le sorveglianze telecamera salvate nell’Apprendimento AI Chat e scarta le modifiche non salvate nell’editor. Re-inizializzare la memoria da zero?","Reinitializing chat learning...":"Re-inizializzazione dell’apprendimento chat...","Chat learning reinitialized":"Apprendimento chat re-inizializzato","Failed to reinitialize chat learning":"Impossibile re-inizializzare l’apprendimento chat","Chat-learning file copied to clipboard":"File di apprendimento chat copiato negli appunti","Chat-learning backup downloaded":"Backup dell’apprendimento chat scaricato","Chat-learning backup loaded; review it and save to apply it.":"Backup dell’apprendimento chat caricato; controllalo e salvalo per applicarlo.","Chat-learning backup exceeds the file-size limit":"Il backup dell’apprendimento chat supera il limite di dimensione","Failed to load chat-learning backup":"Impossibile caricare il backup dell’apprendimento chat","Flow Builder":"Generatore di flussi","AI enabled":"AI abilitata","AI disabled":"AI disabilitata","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Descrivi l'automazione in linguaggio naturale. L'AI genera un flow Node-RED usando i nodi KNX Ultimate, i nodi Hue e i nodi nativi Function/logici, collegati ai group address importati. Copia il JSON, poi in Node-RED usa Menu > Importa e incollalo.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"es. Quando il sensore di movimento Hue del soggiorno rileva un movimento, accendi la luce del soggiorno.","Generate flow":"Genera flusso","Generating...":"Generazione...","Generating flow...":"Generazione del flusso...","Copy JSON":"Copia JSON","Copied!":"Copiato!","Flow JSON copied to clipboard":"JSON del flow copiato negli appunti","Flow generation failed":"Generazione del flow non riuscita","Could not copy to clipboard":"Impossibile copiare negli appunti","The generated flow JSON will appear here.":"Il JSON del flow generato apparirà qui.","{{count}} areas":"{{count}} aree","{{count}} available":"{{count}} disponibile","{{count}} event types":"{{count}} tipi di eventi","{{count}} recent":"{{count}} recente","{{count}} saved plans":"{{count}} piani salvati","{{count}} visible":"{{count}} visibile","Activate main actuators":"Attiva gli attuatori principali","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Attivare i principali attuatori presenti nell'area e verificare il feedback di stato per confermare che segua i comandi.","Active Read Request To Status GA":"Richiesta di lettura attiva allo stato GA","Actuator preset deleted":"Preimpostazione dell'attuatore cancellata","Actuator preset saved":"Preimpostazione dell'attuatore salvata","Actuator test complete":"Test dell'attuatore completato","Add group addresses to this area":"Aggiungi indirizzi di gruppo a quest'area","Add Step":"Aggiungi passaggio","Add Wait":"Aggiungi Aspetta","AI Area Builder":"Costruttore di aree AI","AI is selecting area GA...":"L'IA sta selezionando l'area GA...","anomaly x{{value}}":"anomalia x{{value}}","Applies to all matching lighting command GA in the selected area.":"Si applica a tutti i comandi di illuminazione corrispondenti GA nell'area selezionata.",Area:"Zona","Area {{value}}":"Area {{value}}","Area deleted":"Area eliminata","Area editor closed":"Redazione di area chiusa","Area GA membership":"Iscrizione all'area GA","Area name":"Nome dell'area","Area reset":"Reimpostazione dell'area","Area to test":"Zona da testare",Areas:"Aree","Ask failed":"Domanda fallita","Asking...":"Asking...",Assistant:"Assistente","Assistant prompt":"Richiesta dell'assistente","Available GA":"Disponibile GA","Building test plan...":"Piano di prova della costruzione...","Builds a deterministic active test using the supported command GA in the selected area.":"Costruisce un test attivo deterministico utilizzando il comando supportato GA nell'area selezionata.","Bus Connection Persistence":"Persistenza della connessione bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Scegli un report per esaminare metriche, controlli dettagliati e suggerimenti.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Scegli un modello di test standard per l'area selezionata, quindi crea il piano in modo deterministico dal catalogo ETS.",Close:"Chiudi","Close menu":"Chiudi menù",Command:"Comando","Command DPT":"Comando DPT","Command GA":"Comando GA","Command payload":"Carico utile del comando",Completed:"Completato","Config exported":"Configurazione esportata","Config imported":"Configurazione importata","Connected {{value}}":"Connesso {{value}}","Coverage {{value}}%":"Copertura {{value}}%","Define at least one area before creating a test plan":"Definire almeno un'area prima di creare un piano di test","Define at least one area before using Tests":"Definire almeno un'area prima di utilizzare i test","Delete Area":"Elimina area","Deleting actuator preset...":"Eliminazione della preimpostazione dell'attuatore...","Deleting area...":"Eliminazione area...","Deleting profile...":"Eliminazione profilo...","Deleting test plan...":"Eliminazione del piano di test...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Descrivi la stanza, la zona o la funzione che desideri.L'intelligenza artificiale suggerirà gli indirizzi dei gruppi più rilevanti per questa bozza.",Description:"Descrizione","Disconnected {{value}}":"Disconnesso {{value}}","Documentation: KNX AI Vue":"Documentazione: KNX AI Vue","Donate via PayPal":"Dona tramite PayPal","Drag step":"Trascina il passaggio",Duplicate:"Duplica","Duplicate Plan":"Duplica piano","Edit Area":"Modifica area","Edit Plan":"Modifica piano","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Abilita l'IA nel nodo KNX AI per rigenerare aree o suggerire GA per una nuova bozza.","Event distribution will appear after the first samples.":"La distribuzione degli eventi apparirà dopo i primi campioni.","Event Mix":"Mix di eventi","Example: Add all technical room lighting command and status GA.":"Esempio: aggiungere tutti i comandi e lo stato dell'illuminazione del locale tecnico GA.",Expected:"Previsto","Expected feedback value":"Valore di feedback previsto","Expected payload":"Carico utile previsto","Explain any anomalies you see and suggest what to check first.":"Spiega eventuali anomalie riscontrate e suggerisci cosa controllare prima.","Export PDF":"Esporta PDF","Exporting config...":"Esportazione della configurazione...",Fail:"Fallire","Failed to build the test plan":"Impossibile creare il piano di test","Failed to delete actuator preset":"Impossibile eliminare la preimpostazione dell'attuatore","Failed to delete area":"Impossibile eliminare l'area","Failed to delete profile":"Impossibile eliminare il profilo","Failed to delete test plan":"Impossibile eliminare il piano di test","Failed to delete test result":"Impossibile eliminare il risultato del test","Failed to export config":"Impossibile esportare la configurazione","Failed to import config":"Impossibile importare la configurazione","Failed to load area command/status catalog":"Impossibile caricare il catalogo comandi/stati dell'area","Failed to load GA catalog":"Impossibile caricare il catalogo GA","Failed to load nodes":"Impossibile caricare i nodi","Failed to load state":"Impossibile caricare lo stato","Failed to regenerate AI areas":"Impossibile rigenerare le aree AI","Failed to reset area":"Impossibile reimpostare l'area","Failed to run actuator test":"Impossibile eseguire il test dell'attuatore","Failed to run profile":"Impossibile eseguire il profilo","Failed to run test plan":"Impossibile eseguire il piano di test","Failed to save actuator preset":"Impossibile salvare la preimpostazione dell'attuatore","Failed to save area":"Impossibile salvare l'area","Failed to save GA role":"Impossibile salvare il ruolo GA","Failed to save profile":"Impossibile salvare il profilo","Failed to save test plan":"Impossibile salvare il piano di test","Failed to save test result":"Impossibile salvare il risultato del test","Failed to suggest area GA":"Impossibile suggerire l'area GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Genera un grafico a barre SVG dei principali indirizzi del gruppo con conteggi e titolo.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Il verde mostra l'ora collegata al bus KNX.Il rosso mostra i tempi di inattività all'interno della finestra della cronologia selezionata.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC controllo attivo","Importing config...":"Importazione configurazione...","in progress":"in corso","Installer alias":"Alias dell'installatore","KNX active test name":"KNX nome del test attivo","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Luci accese, poi spente","Live and saved reports generated by KNX active and read-only tests.":"Report in tempo reale e salvati generati da test attivi e di sola lettura di KNX.","Loading nodes...":"Caricamento nodi...","Loading...":"Loading...","n/a":"n/a","New Area":"Nuova zona","New Plan":"Nuovo piano","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Nessuna area corrisponde alla ricerca corrente oppure il file ETS non espone ancora una gerarchia utilizzabile.","No detailed entries stored for this report yet.":"Nessuna voce dettagliata ancora memorizzata per questo rapporto.","No feedback":"Nessun feedback","No GA selected for this area yet.":"Nessun GA ancora selezionato per quest'area.","No KNX AI nodes found.":"Nessun nodo KNX AI trovato.","No saved plans yet.":"Nessun piano ancora salvato.","No saved test results yet.":"Nessun risultato del test ancora salvato.","No test result selected to export":"Nessun risultato del test selezionato per l'esportazione","No test result selected.":"Nessun risultato del test selezionato.","No top group address data available yet.":"Nessun dato sugli indirizzi dei gruppi principali ancora disponibile.","Nodes {{nodes}} | Links {{links}}":"Nodi {{nodes}} |Collegamenti {{links}}",Now:"Adesso","Open and close shading":"Apri e chiudi l'ombreggiatura","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Aprire e chiudere gli attuatori ombreggianti presenti nell'area, quindi verificare che lo stato corrisponda ai comandi inviati.","Open Source Test":"Prova dell'open source","Optional note for diagnostics and reports":"Nota facoltativa per diagnostica e report","Original ETS path:":"Percorso ETS originale:",Overview:"Panoramica",Pass:"Passa",Payload:"Carico utile","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Scegli dal catalogo ETS.Gli GA già selezionati sono nascosti da questo elenco.","Plan changes discarded":"Modifiche al piano annullate","Plan duplicated":"Piano duplicato","Plan name":"Nome del piano",Plans:"Piani","Profile deleted":"Profilo eliminato","Profile report ready":"Rapporto sul profilo pronto","Profile saved":"Profilo salvato","Provider: {{provider}} | Model: {{model}}":"Fornitore: {{provider}} |Modello: {{model}}",Rate:"Vota","Read response timeout ms":"Leggi il timeout della risposta ms",Ready:"Pronto",Reason:"Motivo",Refresh:"Aggiorna","Regenerating AI areas...":"Rigenerazione delle aree AI...",Remove:"Rimuovi",Repeat:"Ripeti",Reset:"Ripristina","Resetting area...":"Reimpostazione dell'area...","Response timeout":"Timeout della risposta","Returned to the Tests page for the source actuator test.":"Ritornato alla pagina Test per il test dell'attuatore sorgente.","Returned to the Tests page for the source read-only profile.":"Ritornato alla pagina Test per il profilo di sola lettura di origine.","Returned to the Tests page.":"Ritornato alla pagina dei test.","Reusable deterministic active tests saved by the installer.":"Test attivi deterministici riutilizzabili salvati dall'installatore.",Role:"Ruolo","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Eseguire un test completo dei comandi HVAC nell'area e verificare che i setpoint e gli stati siano coerenti.",Running:"Correre","Running actuator test...":"Esecuzione del test dell'attuatore in corso...","Running profile...":"Profilo in esecuzione...","Running...":"Running...","Saving actuator preset...":"Salvataggio della preimpostazione dell'attuatore...","Saving profile...":"Salvataggio profilo...","Saving test plan...":"Salvataggio del piano di test...","Search GA, label or ETS path":"Cerca GA, etichetta o percorso ETS","Select an Area":"Seleziona un'area","Select area":"Seleziona zona","Select command GA":"Seleziona il comando GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Seleziona uno dei modelli standard.Il piano viene costruito solo dal comando GA disponibile nell'area selezionata.","Select test plan":"Seleziona il piano di prova","Select Test Result":"Seleziona Risultato del test","Selected template":"Modello selezionato","Send a":"Invia un",Settings:"Impostazioni","Short operator-facing description":"Breve descrizione rivolta all'operatore","Show AI Area Builder":"Mostra AI Area Builder","Show Template Builder":"Mostra generatore di modelli","Spontaneous Write From Status GA":"Scrittura spontanea dallo stato GA",Status:"Stato","Status DPT":"Stato DPT","Status GA":"Stato GA","Status write timeout ms":"Timeout scrittura stato ms","Step title":"Titolo del passaggio","Stopping repeat mode after the current cycle...":"Interruzione della modalità di ripetizione dopo il ciclo corrente...",Subscribe:"Iscriviti",Suggestions:"Suggerimenti","Summarize the current KNX traffic and highlight the busiest group addresses.":"Riepiloga il traffico corrente KNX ed evidenzia gli indirizzi dei gruppi più trafficati.",Summary:"Sommario","Targets supported HVAC command GA in the selected area.":"Bersagli supportati HVAC comando GA nell'area selezionata.","Targets supported shading command GA in the selected area.":"Gli obiettivi supportano il comando di ombreggiatura GA nell'area selezionata.","telegram from the status GA.":"telegramma dallo stato GA.","telegram to the status GA and wait for a":"telegramma allo stato GA e attendere un",Telegrams:"Telegrammi","Template Builder":"Generatore di modelli","Test editor closed":"Editor del test chiuso","Test plan deleted":"Piano di test eliminato","Test plan ready":"Piano di prova pronto","Test plan saved":"Piano di test salvato","Test completed":"Test completato","Repeat mode stopped":"Modalità ripetizione arrestata","Test result deleted":"Risultato del test cancellato","Test Results":"Risultati dei test","Test Running":"Prova in esecuzione",Tests:"Test","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"L'installatore può rinominare l'area e decidere esattamente a quali indirizzi di gruppo appartenere.Tutto è persistente per nodo KNX AI.",Timeout:"Timeout",Title:"Titolo","Toggle menu":"Cambia menu","Toggle sidebar":"Attiva/disattiva la barra laterale","Top Group Addresses":"Indirizzi di gruppo principali","true, false, 50":"vero, falso, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Accendi le luci, poi spegnile e verifica che i relativi valori di stato siano coerenti.","Unknown DPT":"Sconosciuto DPT","Unsaved changes":"Modifiche non salvate",Voice:"Voce",Wait:"Aspetta","Wait for a spontaneous":"Aspetta uno spontaneo","Wait ms":"Aspetta, signorina",Warn:"Avvertire","What this step checks":"Cosa controlla questo passaggio","Why this step exists":"Perché esiste questo passaggio","Window {{value}}s.":"Finestra {{value}}s.","Write timeout":"Scrivi timeout"},de:{"AI Chat Learning":"KI-Chat-Lernen","Manage node options, shared CHAT learning and full configuration import/export.":"Verwalten Sie Node-Optionen, gemeinsames CHAT-Lernen und den Import/Export der vollständigen Konfiguration.","View, edit and back up the shared learning file used by every KNX AI node on this storage.":"Zeigen, bearbeiten und sichern Sie die gemeinsame Lerndatei, die von allen KNX-AI-Knoten in diesem Speicher verwendet wird.",sessions:"Sitzungen","The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately.":"Die nativen KNX-AI-Datensätze sind maßgeblich und bearbeitbar. Beim Speichern werden sie geprüft und der aktive gemeinsame CHAT-Kontext sofort ersetzt.","Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated.":"Nur das aktuelle Format KNXAI_CHAT_CONTEXT 3 wird akzeptiert. Frühere Markdown/JSON- und Base64-Dateien werden weder gelesen noch importiert oder migriert.","File path":"Dateipfad","AI Chat Learning file":"KI-Chat-Lerndatei","Reload from disk":"Von Festplatte neu laden",Copy:"Kopieren","Download Backup":"Sicherung herunterladen","Restore Backup":"Sicherung wiederherstellen","Reinitialize Memory":"Speicher neu initialisieren","Reinitializing...":"Wird neu initialisiert...","Save Changes":"Änderungen speichern","Saving...":"Speichern...","Last saved:":"Zuletzt gespeichert:","Discard unsaved chat-learning changes and reload?":"Ungespeicherte Chat-Lernänderungen verwerfen und neu laden?","Loading chat learning...":"Chat-Lernen wird geladen...","Chat learning loaded":"Chat-Lernen geladen","Saving chat learning...":"Chat-Lernen wird gespeichert...","Chat learning saved":"Chat-Lernen gespeichert","Failed to load chat learning":"Chat-Lernen konnte nicht geladen werden","Failed to save chat learning":"Chat-Lernen konnte nicht gespeichert werden","This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?":"Dadurch werden alle gespeicherten Sitzungen, Anweisungen und Kameraüberwachungen des KI-Chat-Lernens dauerhaft gelöscht und nicht gespeicherte Editoränderungen verworfen. Speicher von Grund auf neu initialisieren?","Reinitializing chat learning...":"Chat-Lernen wird neu initialisiert...","Chat learning reinitialized":"Chat-Lernen wurde neu initialisiert","Failed to reinitialize chat learning":"Chat-Lernen konnte nicht neu initialisiert werden","Chat-learning file copied to clipboard":"Chat-Lerndatei in die Zwischenablage kopiert","Chat-learning backup downloaded":"Chat-Lernsicherung heruntergeladen","Chat-learning backup loaded; review it and save to apply it.":"Chat-Lernsicherung geladen; prüfen und speichern Sie sie, um sie anzuwenden.","Chat-learning backup exceeds the file-size limit":"Die Chat-Lernsicherung überschreitet die Dateigrößenbegrenzung","Failed to load chat-learning backup":"Chat-Lernsicherung konnte nicht geladen werden","Flow Builder":"Flow-Generator","AI enabled":"KI aktiviert","AI disabled":"KI deaktiviert","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Beschreiben Sie die Automatisierung in natürlicher Sprache. Die KI erzeugt einen Node-RED-Flow mit KNX-Ultimate-Knoten, den Hue-Knoten und nativen Function-/Logik-Knoten, verdrahtet mit Ihren importierten Gruppenadressen. Kopieren Sie das JSON und fügen Sie es in Node-RED über Menü > Import ein.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"z. B. Wenn der Hue-Bewegungsmelder im Wohnzimmer Bewegung erkennt, schalte das Wohnzimmerlicht ein.","Generate flow":"Flow erzeugen","Generating...":"Wird erzeugt...","Generating flow...":"Flow wird erzeugt...","Copy JSON":"JSON kopieren","Copied!":"Kopiert!","Flow JSON copied to clipboard":"Flow-JSON in die Zwischenablage kopiert","Flow generation failed":"Flow-Erzeugung fehlgeschlagen","Could not copy to clipboard":"Kopieren in die Zwischenablage fehlgeschlagen","The generated flow JSON will appear here.":"Das generierte Flow-JSON erscheint hier.","{{count}} areas":"{{count}} Bereiche","{{count}} available":"{{count}} verfügbar","{{count}} event types":"{{count}} Ereignistypen","{{count}} recent":"{{count}} aktuell","{{count}} saved plans":"{{count}} gespeicherte Pläne","{{count}} visible":"{{count}} sichtbar","Activate main actuators":"Hauptaktoren aktivieren","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Aktivieren Sie die Hauptaktoren im Bereich und überprüfen Sie die Statusrückmeldung, um zu bestätigen, dass die Befehle befolgt werden.","Active Read Request To Status GA":"Aktive Leseanforderung an Status GA","Actuator preset deleted":"Aktorvoreinstellung gelöscht","Actuator preset saved":"Aktorvoreinstellung gespeichert","Actuator test complete":"Aktuatortest abgeschlossen","Add group addresses to this area":"Fügen Sie diesem Bereich Gruppenadressen hinzu","Add Step":"Schritt hinzufügen","Add Wait":"Warten hinzufügen","AI Area Builder":"AI Area Builder","AI is selecting area GA...":"KI wählt Bereich GA aus...","anomaly x{{value}}":"Anomalie x{{value}}","Applies to all matching lighting command GA in the selected area.":"Gilt für alle passenden Beleuchtungsbefehle GA im ausgewählten Bereich.",Area:"Bereich","Area {{value}}":"Bereich {{value}}","Area deleted":"Bereich gelöscht","Area editor closed":"Bereichseditor geschlossen","Area GA membership":"Bereich GA Mitgliedschaft","Area name":"Gebietsname","Area reset":"Bereich zurückgesetzt","Area to test":"Bereich zum Testen",Areas:"Bereiche","Ask failed":"Die Anfrage ist fehlgeschlagen","Asking...":"Asking...",Assistant:"Assistent","Assistant prompt":"Eingabeaufforderung des Assistenten","Available GA":"Verfügbar GA","Building test plan...":"Bautestplan...","Builds a deterministic active test using the supported command GA in the selected area.":"Erstellt einen deterministischen aktiven Test mit dem unterstützten Befehl GA im ausgewählten Bereich.","Bus Connection Persistence":"Persistenz der Busverbindung","Choose a report to inspect metrics, detailed checks, and suggestions.":"Wählen Sie einen Bericht aus, um Metriken, detaillierte Prüfungen und Vorschläge zu prüfen.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Wählen Sie eine Standardtestvorlage für den ausgewählten Bereich und erstellen Sie dann den Plan deterministisch aus dem Katalog ETS.",Close:"Schließen","Close menu":"Menü schließen",Command:"Befehl","Command DPT":"Befehl DPT","Command GA":"Befehl GA","Command payload":"Befehlsnutzlast",Completed:"Abgeschlossen","Config exported":"Konfiguration exportiert","Config imported":"Konfiguration importiert","Connected {{value}}":"Verbunden {{value}}","Coverage {{value}}%":"Abdeckung {{value}}%","Define at least one area before creating a test plan":"Definieren Sie mindestens einen Bereich, bevor Sie einen Testplan erstellen","Define at least one area before using Tests":"Definieren Sie mindestens einen Bereich, bevor Sie Tests verwenden","Delete Area":"Bereich löschen","Deleting actuator preset...":"Aktor-Preset wird gelöscht...","Deleting area...":"Bereich wird gelöscht...","Deleting profile...":"Profil wird gelöscht...","Deleting test plan...":"Testplan wird gelöscht...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Beschreiben Sie den Raum, die Zone oder die Funktion, die Sie wünschen.Die KI schlägt für diesen Entwurf die relevantesten Gruppenadressen vor.",Description:"Beschreibung","Disconnected {{value}}":"Getrennt {{value}}","Documentation: KNX AI Vue":"Dokumentation: KNX AI Vue","Donate via PayPal":"Spenden Sie über PayPal","Drag step":"Schritt ziehen",Duplicate:"Duplizieren","Duplicate Plan":"Plan duplizieren","Edit Area":"Bereich bearbeiten","Edit Plan":"Plan bearbeiten","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Aktivieren Sie die KI im Knoten KNX AI, um Bereiche neu zu generieren, oder schlagen Sie GA für einen neuen Entwurf vor.","Event distribution will appear after the first samples.":"Die Ereignisverteilung erscheint nach den ersten Proben.","Event Mix":"Event-Mix","Example: Add all technical room lighting command and status GA.":"Beispiel: Alle technischen Raumbeleuchtungsbefehle und den Status GA hinzufügen.",Expected:"Erwartet","Expected feedback value":"Erwarteter Feedbackwert","Expected payload":"Erwartete Nutzlast","Explain any anomalies you see and suggest what to check first.":"Erklären Sie alle Anomalien, die Sie sehen, und schlagen Sie vor, was Sie zuerst überprüfen sollten.","Export PDF":"PDF exportieren","Exporting config...":"Konfiguration wird exportiert...",Fail:"Scheitern","Failed to build the test plan":"Der Testplan konnte nicht erstellt werden","Failed to delete actuator preset":"Aktorvoreinstellung konnte nicht gelöscht werden","Failed to delete area":"Bereich konnte nicht gelöscht werden","Failed to delete profile":"Profil konnte nicht gelöscht werden","Failed to delete test plan":"Testplan konnte nicht gelöscht werden","Failed to delete test result":"Testergebnis konnte nicht gelöscht werden","Failed to export config":"Konfiguration konnte nicht exportiert werden","Failed to import config":"Konfiguration konnte nicht importiert werden","Failed to load area command/status catalog":"Der Befehls-/Statuskatalog für den Bereich konnte nicht geladen werden","Failed to load GA catalog":"Der Katalog GA konnte nicht geladen werden","Failed to load nodes":"Knoten konnten nicht geladen werden","Failed to load state":"Status konnte nicht geladen werden","Failed to regenerate AI areas":"KI-Bereiche konnten nicht regeneriert werden","Failed to reset area":"Bereich konnte nicht zurückgesetzt werden","Failed to run actuator test":"Aktuatortest konnte nicht ausgeführt werden","Failed to run profile":"Profil konnte nicht ausgeführt werden","Failed to run test plan":"Testplan konnte nicht ausgeführt werden","Failed to save actuator preset":"Aktorvoreinstellung konnte nicht gespeichert werden","Failed to save area":"Bereich konnte nicht gespeichert werden","Failed to save GA role":"Die Rolle GA konnte nicht gespeichert werden","Failed to save profile":"Profil konnte nicht gespeichert werden","Failed to save test plan":"Der Testplan konnte nicht gespeichert werden","Failed to save test result":"Testergebnis konnte nicht gespeichert werden","Failed to suggest area GA":"Bereich GA konnte nicht vorgeschlagen werden","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Erstellen Sie ein SVG-Balkendiagramm der Top-Gruppenadressen mit Anzahl und Titel.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Grün zeigt die mit dem Bus KNX verbundene Zeit an.Rot zeigt Ausfallzeiten im ausgewählten Verlaufsfenster an.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC aktive Prüfung","Importing config...":"Konfiguration wird importiert...","in progress":"in Bearbeitung","Installer alias":"Installer-Alias","KNX active test name":"KNX aktiver Testname","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Licht an, dann aus","Live and saved reports generated by KNX active and read-only tests.":"Live- und gespeicherte Berichte, die von KNX aktiven und schreibgeschützten Tests generiert wurden.","Loading nodes...":"Knoten werden geladen...","Loading...":"Loading...","n/a":"n/a","New Area":"Neuer Bereich","New Plan":"Neuer Plan","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Keine Bereiche stimmten mit der aktuellen Suche überein oder die Datei ETS stellt noch keine verwendbare Hierarchie bereit.","No detailed entries stored for this report yet.":"Für diesen Bericht sind noch keine detaillierten Einträge hinterlegt.","No feedback":"Keine Rückmeldung","No GA selected for this area yet.":"Für diesen Bereich wurde noch kein GA ausgewählt.","No KNX AI nodes found.":"Keine KNX AI Knoten gefunden.","No saved plans yet.":"Noch keine gespeicherten Pläne.","No saved test results yet.":"Noch keine gespeicherten Testergebnisse.","No test result selected to export":"Kein Testergebnis zum Exportieren ausgewählt","No test result selected.":"Kein Testergebnis ausgewählt.","No top group address data available yet.":"Es sind noch keine Daten zur Top-Gruppenadresse verfügbar.","Nodes {{nodes}} | Links {{links}}":"Knoten {{nodes}} |Links {{links}}",Now:"Jetzt","Open and close shading":"Beschattung öffnen und schließen","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Öffnen und schließen Sie die Beschattungsaktoren im Bereich und überprüfen Sie dann, ob der Status mit den gesendeten Befehlen übereinstimmt.","Open Source Test":"Open-Source-Test","Optional note for diagnostics and reports":"Optionaler Hinweis für Diagnosen und Berichte","Original ETS path:":"Ursprünglicher ETS Pfad:",Overview:"Übersicht",Pass:"Pass",Payload:"Nutzlast","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Wählen Sie aus dem Katalog ETS.Bereits ausgewählte GA werden aus dieser Liste ausgeblendet.","Plan changes discarded":"Planänderungen verworfen","Plan duplicated":"Plan dupliziert","Plan name":"Planname",Plans:"Pläne","Profile deleted":"Profil gelöscht","Profile report ready":"Profilbericht bereit","Profile saved":"Profil gespeichert","Provider: {{provider}} | Model: {{model}}":"Anbieter: {{provider}} |Modell: {{model}}",Rate:"Bewerten","Read response timeout ms":"Leseantwort-Timeout ms",Ready:"Bereit",Reason:"Grund",Refresh:"Aktualisieren","Regenerating AI areas...":"KI-Bereiche werden regeneriert...",Remove:"Entfernen",Repeat:"Wiederholen",Reset:"Zurücksetzen","Resetting area...":"Bereich wird zurückgesetzt...","Response timeout":"Antwortzeitüberschreitung","Returned to the Tests page for the source actuator test.":"Zurück zur Seite „Tests“ für den Quellaktuatortest.","Returned to the Tests page for the source read-only profile.":"Kehrt zur Seite „Tests“ für das schreibgeschützte Quellprofil zurück.","Returned to the Tests page.":"Zurück zur Seite „Tests“.","Reusable deterministic active tests saved by the installer.":"Wiederverwendbare deterministische aktive Tests, die vom Installationsprogramm gespeichert werden.",Role:"Rolle","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Führen Sie einen vollständigen Test der HVAC-Befehle im Bereich durch und stellen Sie sicher, dass Sollwerte und Status kohärent sind.",Running:"Laufen","Running actuator test...":"Aktuatortest wird ausgeführt...","Running profile...":"Laufprofil...","Running...":"Running...","Saving actuator preset...":"Aktorvoreinstellung speichern...","Saving profile...":"Profil wird gespeichert...","Saving test plan...":"Testplan wird gespeichert...","Search GA, label or ETS path":"Suchen Sie nach GA, Label oder ETS Pfad","Select an Area":"Wählen Sie einen Bereich aus","Select area":"Bereich auswählen","Select command GA":"Wählen Sie den Befehl GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Wählen Sie eine der Standardvorlagen aus.Der Plan wird nur mit dem Befehl GA erstellt, der im ausgewählten Bereich verfügbar ist.","Select test plan":"Testplan auswählen","Select Test Result":"Wählen Sie Testergebnis","Selected template":"Ausgewählte Vorlage","Send a":"Senden Sie eine",Settings:"Einstellungen","Short operator-facing description":"Kurze Beschreibung für den Bediener","Show AI Area Builder":"AI Area Builder anzeigen","Show Template Builder":"Template Builder anzeigen","Spontaneous Write From Status GA":"Spontanes Schreiben aus Status GA",Status:"Status","Status DPT":"Status DPT","Status GA":"Status GA","Status write timeout ms":"Statusschreib-Timeout ms","Step title":"Schritttitel","Stopping repeat mode after the current cycle...":"Stoppen des Wiederholungsmodus nach dem aktuellen Zyklus...",Subscribe:"Abonnieren",Suggestions:"Vorschläge","Summarize the current KNX traffic and highlight the busiest group addresses.":"Fassen Sie den aktuellen KNX-Verkehr zusammen und markieren Sie die am stärksten ausgelasteten Gruppenadressen.",Summary:"Zusammenfassung","Targets supported HVAC command GA in the selected area.":"Unterstützte Ziele: HVAC Befehl GA im ausgewählten Bereich.","Targets supported shading command GA in the selected area.":"Zielt auf den unterstützten Schattierungsbefehl GA im ausgewählten Bereich.","telegram from the status GA.":"Telegramm vom Status GA.","telegram to the status GA and wait for a":"Telegramm auf den Status GA und warten Sie auf a",Telegrams:"Telegramme","Template Builder":"Vorlagenersteller","Test editor closed":"Testeditor geschlossen","Test plan deleted":"Testplan gelöscht","Test plan ready":"Testplan fertig","Test plan saved":"Testplan gespeichert","Test completed":"Test abgeschlossen","Repeat mode stopped":"Wiederholungsmodus gestoppt","Test result deleted":"Testergebnis gelöscht","Test Results":"Testergebnisse","Test Running":"Testlauf",Tests:"Tests","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"Der Installateur kann den Bereich umbenennen und genau entscheiden, welche Gruppenadressen dazu gehören.Alles wird pro KNX AI-Knoten beibehalten.",Timeout:"Auszeit",Title:"Titel","Toggle menu":"Menü umschalten","Toggle sidebar":"Seitenleiste umschalten","Top Group Addresses":"Top-Gruppenadressen","true, false, 50":"wahr, falsch, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Schalten Sie die Lichter ein und wieder aus und überprüfen Sie, ob die zugehörigen Statuswerte kohärent sind.","Unknown DPT":"Unbekannt DPT","Unsaved changes":"Nicht gespeicherte Änderungen",Voice:"Stimme",Wait:"Warte","Wait for a spontaneous":"Warten Sie auf eine spontane","Wait ms":"Warten Sie, Frau",Warn:"Warnen","What this step checks":"Was dieser Schritt prüft","Why this step exists":"Warum es diesen Schritt gibt","Window {{value}}s.":"Fenster {{value}}s.","Write timeout":"Timeout schreiben"},fr:{"AI Chat Learning":"Apprentissage du chat IA","Manage node options, shared CHAT learning and full configuration import/export.":"Gérez les options du nœud, l’apprentissage CHAT partagé et l’import/export de la configuration complète.","View, edit and back up the shared learning file used by every KNX AI node on this storage.":"Affichez, modifiez et sauvegardez le fichier d’apprentissage partagé utilisé par tous les nœuds KNX AI de ce stockage.",sessions:"sessions","The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately.":"Les enregistrements natifs KNX AI font autorité et sont modifiables. L’enregistrement les valide et remplace immédiatement le contexte CHAT partagé actif.","Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated.":"Seul le format KNXAI_CHAT_CONTEXT 3 actuel est accepté. Les anciens fichiers Markdown/JSON et Base64 ne sont ni lus, ni importés, ni migrés.","File path":"Chemin du fichier","AI Chat Learning file":"Fichier d’apprentissage du chat IA","Reload from disk":"Recharger depuis le disque",Copy:"Copier","Download Backup":"Télécharger la sauvegarde","Restore Backup":"Restaurer la sauvegarde","Reinitialize Memory":"Réinitialiser la mémoire","Reinitializing...":"Réinitialisation...","Save Changes":"Enregistrer les modifications","Saving...":"Enregistrement...","Last saved:":"Dernier enregistrement :","Discard unsaved chat-learning changes and reload?":"Ignorer les modifications d’apprentissage non enregistrées et recharger ?","Loading chat learning...":"Chargement de l’apprentissage du chat...","Chat learning loaded":"Apprentissage du chat chargé","Saving chat learning...":"Enregistrement de l’apprentissage du chat...","Chat learning saved":"Apprentissage du chat enregistré","Failed to load chat learning":"Impossible de charger l’apprentissage du chat","Failed to save chat learning":"Impossible d’enregistrer l’apprentissage du chat","This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?":"Cette opération supprime définitivement toutes les sessions, instructions et surveillances de caméra enregistrées dans l’apprentissage du chat IA et abandonne les modifications non enregistrées dans l’éditeur. Réinitialiser complètement la mémoire ?","Reinitializing chat learning...":"Réinitialisation de l’apprentissage du chat...","Chat learning reinitialized":"Apprentissage du chat réinitialisé","Failed to reinitialize chat learning":"Impossible de réinitialiser l’apprentissage du chat","Chat-learning file copied to clipboard":"Fichier d’apprentissage du chat copié dans le presse-papiers","Chat-learning backup downloaded":"Sauvegarde de l’apprentissage du chat téléchargée","Chat-learning backup loaded; review it and save to apply it.":"Sauvegarde de l’apprentissage chargée ; vérifiez-la puis enregistrez-la pour l’appliquer.","Chat-learning backup exceeds the file-size limit":"La sauvegarde de l’apprentissage dépasse la taille maximale","Failed to load chat-learning backup":"Impossible de charger la sauvegarde de l’apprentissage du chat","Flow Builder":"Générateur de flux","AI enabled":"IA activée","AI disabled":"IA désactivée","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Décrivez l'automatisation en langage naturel. L'IA génère un flux Node-RED en utilisant les nœuds KNX Ultimate, les nœuds Hue et les nœuds natifs Function/logique, reliés à vos adresses de groupe importées. Copiez le JSON, puis dans Node-RED utilisez Menu > Importer et collez-le.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"ex. Quand le détecteur de mouvement Hue du salon détecte un mouvement, allume la lumière du salon.","Generate flow":"Générer le flux","Generating...":"Génération...","Generating flow...":"Génération du flux...","Copy JSON":"Copier le JSON","Copied!":"Copié !","Flow JSON copied to clipboard":"JSON du flux copié dans le presse-papiers","Flow generation failed":"Échec de la génération du flux","Could not copy to clipboard":"Impossible de copier dans le presse-papiers","The generated flow JSON will appear here.":"Le JSON du flux généré apparaîtra ici.","{{count}} areas":"Zones {{count}}","{{count}} available":"{{count}} disponible","{{count}} event types":"{{count}} types d'événements","{{count}} recent":"{{count}} récent","{{count}} saved plans":"{{count}} plans enregistrés","{{count}} visible":"{{count}} visible","Activate main actuators":"Activer les actionneurs principaux","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Activez les principaux actionneurs de la zone et vérifiez le retour d'état pour confirmer qu'il suit les commandes.","Active Read Request To Status GA":"Demande de lecture active vers l'état GA","Actuator preset deleted":"Préréglage de l'actionneur supprimé","Actuator preset saved":"Préréglage de l'actionneur enregistré","Actuator test complete":"Test de l'actionneur terminé","Add group addresses to this area":"Ajouter des adresses de groupe à cette zone","Add Step":"Ajouter une étape","Add Wait":"Ajouter une attente","AI Area Builder":"Générateur de zones IA","AI is selecting area GA...":"L'IA sélectionne la zone GA...","anomaly x{{value}}":"anomalie x{{value}}","Applies to all matching lighting command GA in the selected area.":"S'applique à toutes les commandes d'éclairage correspondantes GA dans la zone sélectionnée.",Area:"Zone","Area {{value}}":"Zone {{value}}","Area deleted":"Zone supprimée","Area editor closed":"Éditeur de zone fermé","Area GA membership":"Adhésion à la zone GA","Area name":"Nom de la zone","Area reset":"Réinitialisation de la zone","Area to test":"Zone à tester",Areas:"Domaines","Ask failed":"La demande a échoué","Asking...":"Asking...",Assistant:"Assistante","Assistant prompt":"Invite de l'assistant","Available GA":"Disponible GA","Building test plan...":"Plan de test de construction...","Builds a deterministic active test using the supported command GA in the selected area.":"Construit un test actif déterministe à l'aide de la commande prise en charge GA dans la zone sélectionnée.","Bus Connection Persistence":"Persistance de la connexion de bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Choisissez un rapport pour inspecter les métriques, les contrôles détaillés et les suggestions.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Choisissez un modèle de test standard pour la zone sélectionnée, puis construisez le plan de manière déterministe à partir du catalogue ETS.",Close:"Fermer","Close menu":"Fermer le menu",Command:"Commande","Command DPT":"Commande DPT","Command GA":"Commande GA","Command payload":"Charge utile de commande",Completed:"Terminé","Config exported":"Configuration exportée","Config imported":"Configuration importée","Connected {{value}}":"Connecté {{value}}","Coverage {{value}}%":"Couverture {{value}}%","Define at least one area before creating a test plan":"Définir au moins un domaine avant de créer un plan de test","Define at least one area before using Tests":"Définir au moins une zone avant d'utiliser les tests","Delete Area":"Supprimer la zone","Deleting actuator preset...":"Suppression du préréglage de l'actionneur...","Deleting area...":"Suppression de la zone...","Deleting profile...":"Suppression du profil...","Deleting test plan...":"Suppression du plan de test...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Décrivez la pièce, la zone ou la fonction souhaitée.L'IA proposera les adresses de groupes les plus pertinentes pour ce projet.",Description:"Descriptif","Disconnected {{value}}":"Déconnecté {{value}}","Documentation: KNX AI Vue":"Documentation : KNX AI Vue","Donate via PayPal":"Faites un don via PayPal","Drag step":"Glisser l'étape",Duplicate:"Dupliquer","Duplicate Plan":"Dupliquer le plan","Edit Area":"Modifier la zone","Edit Plan":"Modifier le forfait","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Activez l'IA dans le nœud KNX AI pour régénérer les zones ou suggérez GA pour un nouveau brouillon.","Event distribution will appear after the first samples.":"La distribution des événements apparaîtra après les premiers échantillons.","Event Mix":"Mélange d'événements","Example: Add all technical room lighting command and status GA.":"Exemple : Ajouter toutes les commandes et statuts d'éclairage du local technique GA.",Expected:"Attendu","Expected feedback value":"Valeur attendue des commentaires","Expected payload":"Charge utile attendue","Explain any anomalies you see and suggest what to check first.":"Expliquez toutes les anomalies que vous voyez et suggérez quoi vérifier en premier.","Export PDF":"Exporter un PDF","Exporting config...":"Exportation de la configuration...",Fail:"Échec","Failed to build the test plan":"Échec de la création du plan de test","Failed to delete actuator preset":"Échec de la suppression du préréglage de l'actionneur","Failed to delete area":"Échec de la suppression de la zone","Failed to delete profile":"Échec de la suppression du profil","Failed to delete test plan":"Échec de la suppression du plan de test","Failed to delete test result":"Échec de la suppression du résultat du test","Failed to export config":"Échec de l'exportation de la configuration","Failed to import config":"Échec de l'importation de la configuration","Failed to load area command/status catalog":"Échec du chargement du catalogue de commandes/statuts de zone","Failed to load GA catalog":"Échec du chargement du catalogue GA","Failed to load nodes":"Échec du chargement des nœuds","Failed to load state":"Échec du chargement de l'état","Failed to regenerate AI areas":"Échec de la régénération des zones IA","Failed to reset area":"Échec de la réinitialisation de la zone","Failed to run actuator test":"Échec de l'exécution du test de l'actionneur","Failed to run profile":"Échec de l'exécution du profil","Failed to run test plan":"Échec de l'exécution du plan de test","Failed to save actuator preset":"Échec de l'enregistrement du préréglage de l'actionneur","Failed to save area":"Échec de l'enregistrement de la zone","Failed to save GA role":"Échec de l'enregistrement du rôle GA","Failed to save profile":"Échec de l'enregistrement du profil","Failed to save test plan":"Échec de l'enregistrement du plan de test","Failed to save test result":"Échec de l'enregistrement du résultat du test","Failed to suggest area GA":"Échec de la suggestion de la zone GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Générez un graphique à barres SVG des principales adresses des groupes avec le nombre et le titre.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"Le vert indique l'heure connectée au bus KNX.Le rouge affiche les temps d'arrêt dans la fenêtre d'historique sélectionnée.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC chèque actif","Importing config...":"Importation de la configuration...","in progress":"en cours","Installer alias":"Alias de l'installateur","KNX active test name":"KNX nom du test actif","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Les lumières s'allument, puis s'éteignent","Live and saved reports generated by KNX active and read-only tests.":"Rapports en direct et enregistrés générés par KNX tests actifs et en lecture seule.","Loading nodes...":"Chargement des nœuds...","Loading...":"Loading...","n/a":"n/a","New Area":"Nouvelle zone","New Plan":"Nouveau forfait","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Aucune zone ne correspond à la recherche actuelle ou le fichier ETS n'expose pas encore de hiérarchie utilisable.","No detailed entries stored for this report yet.":"Aucune entrée détaillée n'est encore stockée pour ce rapport.","No feedback":"Aucun retour","No GA selected for this area yet.":"Aucun GA n'est encore sélectionné pour cette zone.","No KNX AI nodes found.":"Aucun nœud KNX AI trouvé.","No saved plans yet.":"Aucun plan enregistré pour l'instant.","No saved test results yet.":"Aucun résultat de test enregistré pour l'instant.","No test result selected to export":"Aucun résultat de test sélectionné pour exporter","No test result selected.":"Aucun résultat de test sélectionné.","No top group address data available yet.":"Aucune donnée d'adresse du groupe principal n'est encore disponible.","Nodes {{nodes}} | Links {{links}}":"Nœuds {{nodes}} |Liens {{links}}",Now:"Maintenant","Open and close shading":"Ombrage ouvert et fermé","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Ouvrez et fermez les actionneurs d'ombrage de la zone, puis vérifiez que l'état correspond aux commandes envoyées.","Open Source Test":"Test Open Source","Optional note for diagnostics and reports":"Remarque facultative pour les diagnostics et les rapports","Original ETS path:":"Chemin ETS d'origine :",Overview:"Aperçu",Pass:"Passer",Payload:"Charge utile","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Choisissez dans le catalogue ETS.Les GA déjà sélectionnés sont masqués de cette liste.","Plan changes discarded":"Modifications du plan rejetées","Plan duplicated":"Plan dupliqué","Plan name":"Nom du forfait",Plans:"Forfaits","Profile deleted":"Profil supprimé","Profile report ready":"Rapport de profil prêt","Profile saved":"Profil enregistré","Provider: {{provider}} | Model: {{model}}":"Fournisseur : {{provider}} |Modèle : {{model}}",Rate:"Tarif","Read response timeout ms":"Lire le délai de réponse ms",Ready:"Prêt",Reason:"Raison",Refresh:"Actualiser","Regenerating AI areas...":"Régénérer les zones d'IA...",Remove:"Supprimer",Repeat:"Répéter",Reset:"Réinitialiser","Resetting area...":"Zone de réinitialisation...","Response timeout":"Délai de réponse","Returned to the Tests page for the source actuator test.":"Retour à la page Tests pour le test de l'actionneur source.","Returned to the Tests page for the source read-only profile.":"Renvoyé à la page Tests pour le profil source en lecture seule.","Returned to the Tests page.":"Retour à la page Tests.","Reusable deterministic active tests saved by the installer.":"Tests actifs déterministes réutilisables enregistrés par l'installateur.",Role:"Rôle","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Exécutez un test complet des commandes HVAC dans la zone et vérifiez que les consignes et les états sont cohérents.",Running:"Courir","Running actuator test...":"Test de l'actionneur en cours...","Running profile...":"Profil de course...","Running...":"Running...","Saving actuator preset...":"Enregistrement du préréglage de l'actionneur...","Saving profile...":"Enregistrement du profil...","Saving test plan...":"Sauvegarde du plan de test...","Search GA, label or ETS path":"Recherchez GA, l'étiquette ou le chemin ETS","Select an Area":"Sélectionnez une zone","Select area":"Sélectionnez une zone","Select command GA":"Sélectionnez la commande GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Sélectionnez l'un des modèles standard.Le plan est construit uniquement à partir de la commande GA disponible dans la zone sélectionnée.","Select test plan":"Sélectionnez le plan de test","Select Test Result":"Sélectionnez le résultat du test","Selected template":"Modèle sélectionné","Send a":"Envoyez un",Settings:"Paramètres","Short operator-facing description":"Brève description destinée à l'opérateur","Show AI Area Builder":"Afficher le générateur de zone AI","Show Template Builder":"Afficher le générateur de modèles","Spontaneous Write From Status GA":"Écriture spontanée à partir du statut GA",Status:"Statut","Status DPT":"Statut DPT","Status GA":"Statut GA","Status write timeout ms":"Délai d'expiration de l'état en ms","Step title":"Titre de l'étape","Stopping repeat mode after the current cycle...":"Arrêt du mode répétition après le cycle en cours...",Subscribe:"Abonnez-vous",Suggestions:"Suggestions","Summarize the current KNX traffic and highlight the busiest group addresses.":"Résumez le trafic KNX actuel et mettez en surbrillance les adresses de groupe les plus fréquentées.",Summary:"Résumé","Targets supported HVAC command GA in the selected area.":"Cibles prises en charge par la commande HVAC GA dans la zone sélectionnée.","Targets supported shading command GA in the selected area.":"Cibles prenant en charge la commande d'ombrage GA dans la zone sélectionnée.","telegram from the status GA.":"télégramme du statut GA.","telegram to the status GA and wait for a":"télégramme au statut GA et attendez un",Telegrams:"Télégrammes","Template Builder":"Générateur de modèles","Test editor closed":"Éditeur de tests fermé","Test plan deleted":"Plan de test supprimé","Test plan ready":"Plan de test prêt","Test plan saved":"Plan de test enregistré","Test completed":"Test terminé","Repeat mode stopped":"Mode répétition arrêté","Test result deleted":"Résultat du test supprimé","Test Results":"Résultats des tests","Test Running":"Test en cours",Tests:"Essais","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"L'installateur peut renommer la zone et décider exactement quelles adresses de groupe lui appartiennent.Tout est conservé par nœud KNX AI.",Timeout:"Délai d'attente",Title:"Titre","Toggle menu":"Changer de menu","Toggle sidebar":"Basculer la barre latérale","Top Group Addresses":"Principales adresses des groupes","true, false, 50":"vrai, faux, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Allumez puis éteignez les lumières et vérifiez que les valeurs d'état associées sont cohérentes.","Unknown DPT":"Inconnu DPT","Unsaved changes":"Modifications non enregistrées",Voice:"Voix",Wait:"Attends","Wait for a spontaneous":"Attendez un spontané","Wait ms":"Attends madame",Warn:"Avertir","What this step checks":"Ce que cette étape vérifie","Why this step exists":"Pourquoi cette étape existe","Window {{value}}s.":"Fenêtre {{value}}s.","Write timeout":"Délai d'écriture"},es:{"AI Chat Learning":"Aprendizaje del chat IA","Manage node options, shared CHAT learning and full configuration import/export.":"Gestiona las opciones del nodo, el aprendizaje CHAT compartido y la importación/exportación de la configuración completa.","View, edit and back up the shared learning file used by every KNX AI node on this storage.":"Consulta, edita y guarda una copia del archivo de aprendizaje compartido que usan todos los nodos KNX AI de este almacenamiento.",sessions:"sesiones","The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately.":"Los registros nativos de KNX AI son la referencia y se pueden editar. Al guardar se validan y se sustituye inmediatamente el contexto CHAT compartido activo.","Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated.":"Solo se acepta el formato KNXAI_CHAT_CONTEXT 3 actual. Los archivos Markdown/JSON y Base64 anteriores no se leen, importan ni migran.","File path":"Ruta del archivo","AI Chat Learning file":"Archivo de aprendizaje del chat IA","Reload from disk":"Recargar desde el disco",Copy:"Copiar","Download Backup":"Descargar copia","Restore Backup":"Restaurar copia","Reinitialize Memory":"Reinicializar memoria","Reinitializing...":"Reinicializando...","Save Changes":"Guardar cambios","Saving...":"Guardando...","Last saved:":"Último guardado:","Discard unsaved chat-learning changes and reload?":"¿Descartar los cambios de aprendizaje no guardados y recargar?","Loading chat learning...":"Cargando el aprendizaje del chat...","Chat learning loaded":"Aprendizaje del chat cargado","Saving chat learning...":"Guardando el aprendizaje del chat...","Chat learning saved":"Aprendizaje del chat guardado","Failed to load chat learning":"No se pudo cargar el aprendizaje del chat","Failed to save chat learning":"No se pudo guardar el aprendizaje del chat","This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?":"Esta operación elimina definitivamente todas las sesiones, instrucciones y vigilancias de cámara guardadas en el aprendizaje del chat IA y descarta los cambios no guardados del editor. ¿Reinicializar la memoria desde cero?","Reinitializing chat learning...":"Reinicializando el aprendizaje del chat...","Chat learning reinitialized":"Aprendizaje del chat reinicializado","Failed to reinitialize chat learning":"No se pudo reinicializar el aprendizaje del chat","Chat-learning file copied to clipboard":"Archivo de aprendizaje del chat copiado al portapapeles","Chat-learning backup downloaded":"Copia del aprendizaje del chat descargada","Chat-learning backup loaded; review it and save to apply it.":"Copia del aprendizaje cargada; revísala y guárdala para aplicarla.","Chat-learning backup exceeds the file-size limit":"La copia del aprendizaje supera el límite de tamaño","Failed to load chat-learning backup":"No se pudo cargar la copia del aprendizaje del chat","Flow Builder":"Generador de flujos","AI enabled":"IA activada","AI disabled":"IA desactivada","Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it.":"Describe la automatización en lenguaje natural. La IA genera un flujo de Node-RED usando los nodos KNX Ultimate, los nodos Hue y los nodos nativos Function/lógicos, conectados a tus direcciones de grupo importadas. Copia el JSON y luego en Node-RED usa Menú > Importar y pégalo.","e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light.":"ej. Cuando el sensor de movimiento Hue del salón detecta movimiento, enciende la luz del salón.","Generate flow":"Generar flujo","Generating...":"Generando...","Generating flow...":"Generando flujo...","Copy JSON":"Copiar JSON","Copied!":"¡Copiado!","Flow JSON copied to clipboard":"JSON del flujo copiado al portapapeles","Flow generation failed":"Error al generar el flujo","Could not copy to clipboard":"No se pudo copiar al portapapeles","The generated flow JSON will appear here.":"El JSON del flujo generado aparecerá aquí.","{{count}} areas":"{{count}} áreas","{{count}} available":"{{count}} disponible","{{count}} event types":"{{count}} tipos de eventos","{{count}} recent":"{{count}} reciente","{{count}} saved plans":"{{count}} planes guardados","{{count}} visible":"{{count}} visible","Activate main actuators":"Activar actuadores principales","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"Active los principales actuadores del área y verifique la retroalimentación de estado para confirmar que sigue los comandos.","Active Read Request To Status GA":"Solicitud de lectura activa al estado GA","Actuator preset deleted":"Preajuste del actuador eliminado","Actuator preset saved":"Preajuste del actuador guardado","Actuator test complete":"Prueba del actuador completa","Add group addresses to this area":"Agregar direcciones de grupo a esta área","Add Step":"Agregar paso","Add Wait":"Agregar esperar","AI Area Builder":"Generador de áreas de IA","AI is selecting area GA...":"La IA está seleccionando el área GA...","anomaly x{{value}}":"anomalía x{{value}}","Applies to all matching lighting command GA in the selected area.":"Se aplica a todos los comandos de iluminación coincidentes GA en el área seleccionada.",Area:"Área","Area {{value}}":"Área {{value}}","Area deleted":"Área eliminada","Area editor closed":"Editor de área cerrado","Area GA membership":"Membresía del área GA","Area name":"Nombre del área","Area reset":"Restablecer área","Area to test":"Área para probar",Areas:"Áreas","Ask failed":"Pregunta fallida","Asking...":"Asking...",Assistant:"Asistente","Assistant prompt":"Aviso del asistente","Available GA":"Disponible GA","Building test plan...":"Plano de pruebas del edificio...","Builds a deterministic active test using the supported command GA in the selected area.":"Crea una prueba activa determinista utilizando el comando admitido GA en el área seleccionada.","Bus Connection Persistence":"Persistencia de la conexión de bus","Choose a report to inspect metrics, detailed checks, and suggestions.":"Elija un informe para inspeccionar métricas, comprobaciones detalladas y sugerencias.","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"Elija una plantilla de prueba estándar para el área seleccionada y luego cree el plan de manera determinista a partir del catálogo ETS.",Close:"Cerrar","Close menu":"Cerrar menú",Command:"Comando","Command DPT":"Comando DPT","Command GA":"Comando GA","Command payload":"Carga útil de comando",Completed:"Completado","Config exported":"Configuración exportada","Config imported":"Configuración importada","Connected {{value}}":"Conectado {{value}}","Coverage {{value}}%":"Cobertura {{value}}%","Define at least one area before creating a test plan":"Defina al menos un área antes de crear un plan de prueba","Define at least one area before using Tests":"Defina al menos un área antes de usar Pruebas","Delete Area":"Eliminar área","Deleting actuator preset...":"Eliminando preajuste del actuador...","Deleting area...":"Eliminando área...","Deleting profile...":"Eliminando perfil...","Deleting test plan...":"Eliminando plan de prueba...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"Describe la habitación, zona o función que deseas.La AI sugerirá las direcciones de grupo más relevantes para este borrador.",Description:"Descripción","Disconnected {{value}}":"Desconectado {{value}}","Documentation: KNX AI Vue":"Documentación: KNX AI Vue","Donate via PayPal":"Donar a través de PayPal","Drag step":"Paso de arrastre",Duplicate:"Duplicar","Duplicate Plan":"Duplicar plan","Edit Area":"Editar área","Edit Plan":"Editar plano","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"Habilite la IA en el nodo KNX AI para regenerar áreas o sugiera GA para un nuevo borrador.","Event distribution will appear after the first samples.":"La distribución de eventos aparecerá después de las primeras muestras.","Event Mix":"Mezcla de eventos","Example: Add all technical room lighting command and status GA.":"Ejemplo: agregue todos los comandos y estados de iluminación de la sala técnica GA.",Expected:"esperado","Expected feedback value":"Valor de retroalimentación esperado","Expected payload":"Carga útil esperada","Explain any anomalies you see and suggest what to check first.":"Explique cualquier anomalía que observe y sugiera qué comprobar primero.","Export PDF":"Exportar PDF","Exporting config...":"Exportando configuración...",Fail:"fallar","Failed to build the test plan":"No se pudo construir el plan de prueba","Failed to delete actuator preset":"No se pudo eliminar el ajuste preestablecido del actuador","Failed to delete area":"No se pudo eliminar el área","Failed to delete profile":"No se pudo eliminar el perfil","Failed to delete test plan":"No se pudo eliminar el plan de prueba","Failed to delete test result":"No se pudo eliminar el resultado de la prueba","Failed to export config":"No se pudo exportar la configuración","Failed to import config":"No se pudo importar la configuración","Failed to load area command/status catalog":"No se pudo cargar el catálogo de comando/estado del área","Failed to load GA catalog":"No se pudo cargar el catálogo GA","Failed to load nodes":"No se pudieron cargar los nodos","Failed to load state":"No se pudo cargar el estado","Failed to regenerate AI areas":"No se pudieron regenerar las áreas de IA","Failed to reset area":"No se pudo restablecer el área","Failed to run actuator test":"No se pudo ejecutar la prueba del actuador","Failed to run profile":"No se pudo ejecutar el perfil","Failed to run test plan":"No se pudo ejecutar el plan de prueba","Failed to save actuator preset":"No se pudo guardar el ajuste preestablecido del actuador","Failed to save area":"No se pudo guardar el área","Failed to save GA role":"No se pudo guardar el rol GA","Failed to save profile":"No se pudo guardar el perfil","Failed to save test plan":"No se pudo guardar el plan de prueba","Failed to save test result":"No se pudo guardar el resultado de la prueba","Failed to suggest area GA":"No se pudo sugerir el área GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"Genere un gráfico de barras SVG de direcciones de grupos principales con recuentos y título.","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"El verde muestra el tiempo conectado al bus KNX.El rojo muestra el tiempo de inactividad dentro de la ventana del historial seleccionado.",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC verificación activa","Importing config...":"Importando configuración...","in progress":"en progreso","Installer alias":"Alias del instalador","KNX active test name":"KNX nombre de prueba activo","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"Luces encendidas y luego apagadas","Live and saved reports generated by KNX active and read-only tests.":"Informes en vivo y guardados generados por KNX pruebas activas y de solo lectura.","Loading nodes...":"Cargando nodos...","Loading...":"Loading...","n/a":"n/a","New Area":"Nueva Área","New Plan":"Nuevo Plan","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"Ninguna área coincidió con la búsqueda actual o el archivo ETS aún no expone una jerarquía utilizable.","No detailed entries stored for this report yet.":"Aún no se han almacenado entradas detalladas para este informe.","No feedback":"Sin comentarios","No GA selected for this area yet.":"Aún no se ha seleccionado ningún GA para esta área.","No KNX AI nodes found.":"No se encontraron nodos KNX AI.","No saved plans yet.":"Aún no hay planes guardados.","No saved test results yet.":"Aún no hay resultados de pruebas guardados.","No test result selected to export":"No se seleccionó ningún resultado de prueba para exportar","No test result selected.":"No se seleccionó ningún resultado de prueba.","No top group address data available yet.":"Aún no hay datos de direcciones de grupos principales disponibles.","Nodes {{nodes}} | Links {{links}}":"Nodos {{nodes}} |Enlaces {{links}}",Now:"Ahora","Open and close shading":"Abrir y cerrar sombreado","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"Abra y cierre los actuadores de sombreado del área, luego verifique que el estado coincida con los comandos enviados.","Open Source Test":"Prueba de código abierto","Optional note for diagnostics and reports":"Nota opcional para diagnósticos e informes.","Original ETS path:":"Ruta original ETS:",Overview:"Descripción general",Pass:"Pase",Payload:"Carga útil","Pick from the ETS catalog. Already selected GA are hidden from this list.":"Elija del catálogo ETS.Los GA ya seleccionados están ocultos de esta lista.","Plan changes discarded":"Cambios de plan descartados","Plan duplicated":"Plano duplicado","Plan name":"Nombre del plan",Plans:"Planes","Profile deleted":"Perfil eliminado","Profile report ready":"Informe de perfil listo","Profile saved":"Perfil guardado","Provider: {{provider}} | Model: {{model}}":"Proveedor: {{provider}} |Modelo: {{model}}",Rate:"Tarifa","Read response timeout ms":"Tiempo de espera de respuesta de lectura ms",Ready:"Listo",Reason:"Razón",Refresh:"Actualizar","Regenerating AI areas...":"Regenerando áreas de IA...",Remove:"Quitar",Repeat:"repetir",Reset:"Reiniciar","Resetting area...":"Restableciendo área...","Response timeout":"Tiempo de espera de respuesta","Returned to the Tests page for the source actuator test.":"Regresó a la página Pruebas para la prueba del actuador fuente.","Returned to the Tests page for the source read-only profile.":"Regresó a la página Pruebas para el perfil de solo lectura de origen.","Returned to the Tests page.":"Regresó a la página de Pruebas.","Reusable deterministic active tests saved by the installer.":"Pruebas activas deterministas reutilizables guardadas por el instalador.",Role:"Rol","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"Ejecute una prueba completa de los comandos HVAC en el área y verifique que los puntos de ajuste y los estados sean coherentes.",Running:"corriendo","Running actuator test...":"Ejecutando la prueba del actuador...","Running profile...":"Perfil de carrera...","Running...":"Running...","Saving actuator preset...":"Guardando preajuste del actuador...","Saving profile...":"Guardando perfil...","Saving test plan...":"Guardando plan de prueba...","Search GA, label or ETS path":"Buscar GA, etiqueta o ruta ETS","Select an Area":"Seleccione un área","Select area":"Seleccionar área","Select command GA":"Seleccione el comando GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"Seleccione una de las plantillas estándar.El plan se construye únicamente a partir del comando GA disponible en el área seleccionada.","Select test plan":"Seleccionar plan de prueba","Select Test Result":"Seleccionar resultado de la prueba","Selected template":"Plantilla seleccionada","Send a":"Enviar un",Settings:"Configuración","Short operator-facing description":"Breve descripción orientada al operador","Show AI Area Builder":"Mostrar generador de áreas de IA","Show Template Builder":"Mostrar generador de plantillas","Spontaneous Write From Status GA":"Escritura espontánea desde el estado GA",Status:"Estado","Status DPT":"Estado DPT","Status GA":"Estado GA","Status write timeout ms":"Tiempo de espera de escritura de estado ms","Step title":"Título del paso","Stopping repeat mode after the current cycle...":"Deteniendo el modo de repetición después del ciclo actual...",Subscribe:"Suscríbete",Suggestions:"Sugerencias","Summarize the current KNX traffic and highlight the busiest group addresses.":"Resuma el tráfico KNX actual y resalte las direcciones de grupo más ocupadas.",Summary:"Resumen","Targets supported HVAC command GA in the selected area.":"Los objetivos admitieron el comando HVAC GA en el área seleccionada.","Targets supported shading command GA in the selected area.":"Los objetivos admiten el comando de sombreado GA en el área seleccionada.","telegram from the status GA.":"telegrama del estado GA.","telegram to the status GA and wait for a":"telegrama al estado GA y espere un",Telegrams:"telegramas","Template Builder":"Generador de plantillas","Test editor closed":"Editor de pruebas cerrado","Test plan deleted":"Plan de prueba eliminado","Test plan ready":"Plan de prueba listo","Test plan saved":"Plan de prueba guardado","Test completed":"Prueba completada","Repeat mode stopped":"Modo repetición detenido","Test result deleted":"Resultado de la prueba eliminado","Test Results":"Resultados de la prueba","Test Running":"Ejecución de prueba",Tests:"Pruebas","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"El instalador puede cambiar el nombre del área y decidir exactamente qué direcciones de grupo pertenecen a ella.Todo persiste por nodo KNX AI.",Timeout:"Tiempo de espera",Title:"Título","Toggle menu":"Alternar menú","Toggle sidebar":"Alternar barra lateral","Top Group Addresses":"Direcciones de grupos principales","true, false, 50":"verdadero, falso, 50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"Encienda las luces, luego apáguelas y verifique que los valores de estado relacionados sean coherentes.","Unknown DPT":"Desconocido DPT","Unsaved changes":"Cambios no guardados",Voice:"Voz",Wait:"espera","Wait for a spontaneous":"Espere un espontaneo","Wait ms":"Espere señora",Warn:"Advertir","What this step checks":"Lo que verifica este paso","Why this step exists":"Por qué existe este paso","Window {{value}}s.":"Ventana {{value}}s.","Write timeout":"Escribir tiempo de espera"},"zh-CN":{"AI Chat Learning":"AI 聊天学习","Manage node options, shared CHAT learning and full configuration import/export.":"管理节点选项、共享 CHAT 学习以及完整配置的导入/导出。","View, edit and back up the shared learning file used by every KNX AI node on this storage.":"查看、编辑并备份此存储中所有 KNX AI 节点共用的学习文件。",sessions:"会话","The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately.":"原生 KNX AI 记录是可编辑的权威数据。保存时会验证记录并立即替换当前共享的聊天上下文。","Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated.":"仅接受当前的 KNXAI_CHAT_CONTEXT 3 格式。以前的 Markdown/JSON 和 Base64 文件不会被读取、导入或迁移。","File path":"文件路径","AI Chat Learning file":"AI 聊天学习文件","Reload from disk":"从磁盘重新加载",Copy:"复制","Download Backup":"下载备份","Restore Backup":"恢复备份","Reinitialize Memory":"重新初始化记忆","Reinitializing...":"正在重新初始化...","Save Changes":"保存更改","Saving...":"正在保存...","Last saved:":"上次保存:","Discard unsaved chat-learning changes and reload?":"放弃未保存的聊天学习更改并重新加载吗?","Loading chat learning...":"正在加载聊天学习...","Chat learning loaded":"聊天学习已加载","Saving chat learning...":"正在保存聊天学习...","Chat learning saved":"聊天学习已保存","Failed to load chat learning":"无法加载聊天学习","Failed to save chat learning":"无法保存聊天学习","This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?":"此操作将永久删除 AI 聊天学习中所有已保存的会话、指令和摄像机监视,并放弃编辑器中未保存的更改。是否从零重新初始化记忆?","Reinitializing chat learning...":"正在重新初始化聊天学习...","Chat learning reinitialized":"聊天学习已重新初始化","Failed to reinitialize chat learning":"无法重新初始化聊天学习","Chat-learning file copied to clipboard":"聊天学习文件已复制到剪贴板","Chat-learning backup downloaded":"聊天学习备份已下载","Chat-learning backup loaded; review it and save to apply it.":"聊天学习备份已加载;请检查并保存以应用。","Chat-learning backup exceeds the file-size limit":"聊天学习备份超过文件大小限制","Failed to load chat-learning backup":"无法加载聊天学习备份","{{count}} areas":"{{count}} 区域","{{count}} available":"{{count}} 可用","{{count}} event types":"{{count}} 事件类型","{{count}} recent":"{{count}} 最近","{{count}} saved plans":"{{count}} 已保存计划","{{count}} visible":"{{count}} 可见","Activate main actuators":"激活主执行器","Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.":"激活该区域的主执行器并验证状态反馈以确认其遵循命令。","Active Read Request To Status GA":"对状态 GA 的主动读取请求","Actuator preset deleted":"执行器预设已删除","Actuator preset saved":"执行器预设已保存","Actuator test complete":"执行器测试完成","Add group addresses to this area":"将组地址添加到该区域","Add Step":"添加步骤","Add Wait":"添加等待","AI Area Builder":"人工智能区域生成器","AI is selecting area GA...":"AI 正在选择区域 GA...","anomaly x{{value}}":"异常 x{{value}}","Applies to all matching lighting command GA in the selected area.":"适用于所选区域中所有匹配的照明命令 GA。",Area:"面积","Area {{value}}":"区域 {{value}}","Area deleted":"区域已删除","Area editor closed":"区域编辑器已关闭","Area GA membership":"区域 GA 会员资格","Area name":"地区名称","Area reset":"区域重置","Area to test":"测试区域",Areas:"领域","Ask failed":"询问失败","Asking...":"Asking...",Assistant:"助理","Assistant prompt":"助手提示","Available GA":"可用 GA","Building test plan...":"构建测试计划...","Builds a deterministic active test using the supported command GA in the selected area.":"在选定区域中使用支持的命令 GA 构建确定性主动测试。","Bus Connection Persistence":"总线连接持久性","Choose a report to inspect metrics, detailed checks, and suggestions.":"选择报告来检查指标、详细检查和建议。","Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.":"为所选区域选择一个标准测试模板,然后从 ETS 目录中确定性地构建计划。",Close:"关闭","Close menu":"关闭菜单",Command:"命令","Command DPT":"命令 DPT","Command GA":"命令 GA","Command payload":"命令负载",Completed:"已完成","Config exported":"配置导出","Config imported":"配置已导入","Connected {{value}}":"已连接 {{value}}","Coverage {{value}}%":"覆盖率 {{value}}%","Define at least one area before creating a test plan":"在创建测试计划之前至少定义一个区域","Define at least one area before using Tests":"使用测试之前至少定义一个区域","Delete Area":"删除区域","Deleting actuator preset...":"正在删除执行器预设...","Deleting area...":"正在删除区域...","Deleting profile...":"正在删除个人资料...","Deleting test plan...":"正在删除测试计划...","Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.":"描述您想要的房间、区域或功能。AI 将为该草案建议最相关的群组地址。",Description:"描述","Disconnected {{value}}":"已断开连接 {{value}}","Documentation: KNX AI Vue":"文档:KNX AI Vue","Donate via PayPal":"通过 PayPal 捐赠","Drag step":"拖步",Duplicate:"复制","Duplicate Plan":"复制计划","Edit Area":"编辑区","Edit Plan":"编辑计划","Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft.":"启用 KNX AI 节点中的 AI 来重新生成区域或建议 GA 进行新草稿。","Event distribution will appear after the first samples.":"事件分布将出现在第一个样本之后。","Event Mix":"活动组合","Example: Add all technical room lighting command and status GA.":"示例:添加所有技术室照明命令和状态 GA。",Expected:"预计","Expected feedback value":"期望反馈值","Expected payload":"预期有效负载","Explain any anomalies you see and suggest what to check first.":"解释您看到的任何异常情况并建议首先检查哪些内容。","Export PDF":"导出PDF","Exporting config...":"正在导出配置...",Fail:"失败","Failed to build the test plan":"无法构建测试计划","Failed to delete actuator preset":"删除执行器预设失败","Failed to delete area":"删除区域失败","Failed to delete profile":"删除个人资料失败","Failed to delete test plan":"删除测试计划失败","Failed to delete test result":"删除测试结果失败","Failed to export config":"导出配置失败","Failed to import config":"导入配置失败","Failed to load area command/status catalog":"无法加载区域命令/状态目录","Failed to load GA catalog":"无法加载 GA 目录","Failed to load nodes":"加载节点失败","Failed to load state":"加载状态失败","Failed to regenerate AI areas":"无法重新生成AI区域","Failed to reset area":"重置区域失败","Failed to run actuator test":"无法运行执行器测试","Failed to run profile":"运行配置文件失败","Failed to run test plan":"无法运行测试计划","Failed to save actuator preset":"无法保存执行器预设","Failed to save area":"保存区域失败","Failed to save GA role":"无法保存 GA 角色","Failed to save profile":"保存个人资料失败","Failed to save test plan":"保存测试计划失败","Failed to save test result":"无法保存测试结果","Failed to suggest area GA":"无法建议区域 GA","Generate an SVG bar chart of Top Group Addresses with counts and title.":"生成包含计数和标题的顶级组地址的 SVG 条形图。","Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.":"绿色显示连接到 KNX 总线的时间。红色显示所选历史窗口内的停机时间。",GroupValue_Response:"Response",GroupValue_Write:"Write","HVAC active check":"HVAC 主动检查","Importing config...":"正在导入配置...","in progress":"进行中","Installer alias":"安装人员别名","KNX active test name":"KNX 活动测试名称","KNX AI":"KNX AI","KNX Ultimate":"KNX Ultimate","Lights on, then off":"灯亮,然后灭","Live and saved reports generated by KNX active and read-only tests.":"由 KNX 活动和只读测试生成的实时和保存的报告。","Loading nodes...":"正在加载节点...","Loading...":"Loading...","n/a":"n/a","New Area":"新区","New Plan":"新计划","No areas matched the current search or the ETS file does not expose a usable hierarchy yet.":"没有区域与当前搜索匹配,或者 ETS 文件尚未公开可用的层次结构。","No detailed entries stored for this report yet.":"尚未存储此报告的详细条目。","No feedback":"无反馈","No GA selected for this area yet.":"尚未为此区域选择 GA。","No KNX AI nodes found.":"未找到 KNX AI 节点。","No saved plans yet.":"尚未保存计划。","No saved test results yet.":"尚未保存测试结果。","No test result selected to export":"未选择导出测试结果","No test result selected.":"未选择测试结果。","No top group address data available yet.":"尚无可用的顶级组地址数据。","Nodes {{nodes}} | Links {{links}}":"节点 {{nodes}} |链接 {{links}}",Now:"现在","Open and close shading":"打开和关闭阴影","Open and close the shading actuators in the area, then verify that the status matches the commands sent.":"打开和关闭该区域中的遮阳执行器,然后验证状态是否与发送的命令匹配。","Open Source Test":"开源测试","Optional note for diagnostics and reports":"诊断和报告的可选注释","Original ETS path:":"原始 ETS 路径:",Overview:"概述",Pass:"通行证",Payload:"有效载荷","Pick from the ETS catalog. Already selected GA are hidden from this list.":"从 ETS 目录中选择。已选择的 GA 从此列表中隐藏。","Plan changes discarded":"计划变更被放弃","Plan duplicated":"计划重复","Plan name":"计划名称",Plans:"计划","Profile deleted":"个人资料已删除","Profile report ready":"概况报告已准备就绪","Profile saved":"个人资料已保存","Provider: {{provider}} | Model: {{model}}":"提供商:{{provider}} |型号:{{model}}",Rate:"率","Read response timeout ms":"读取响应超时毫秒",Ready:"准备好",Reason:"原因",Refresh:"刷新","Regenerating AI areas...":"再生人工智能领域...",Remove:"删除",Repeat:"重复",Reset:"重置","Resetting area...":"重置区域...","Response timeout":"响应超时","Returned to the Tests page for the source actuator test.":"返回到源执行器测试的测试页面。","Returned to the Tests page for the source read-only profile.":"返回源只读配置文件的测试页面。","Returned to the Tests page.":"返回测试页面。","Reusable deterministic active tests saved by the installer.":"安装程序保存的可重复使用的确定性主动测试。",Role:"角色","Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.":"在该区域中运行 HVAC 命令的完整测试,并验证设定点和状态是否一致。",Running:"跑步","Running actuator test...":"运行执行器测试...","Running profile...":"运行配置文件...","Running...":"Running...","Saving actuator preset...":"正在保存执行器预设...","Saving profile...":"正在保存个人资料...","Saving test plan...":"正在保存测试计划...","Search GA, label or ETS path":"搜索 GA、标签或 ETS 路径","Select an Area":"选择一个区域","Select area":"选择区域","Select command GA":"选择命令 GA","Select one of the standard templates. The plan is built only from the command GA available in the selected area.":"选择标准模板之一。该计划仅根据所选区域中可用的命令 GA 构建。","Select test plan":"选择测试计划","Select Test Result":"选择测试结果","Selected template":"选定的模板","Send a":"发送一个",Settings:"设置","Short operator-facing description":"面向操作员的简短描述","Show AI Area Builder":"显示 AI 区域生成器","Show Template Builder":"显示模板生成器","Spontaneous Write From Status GA":"从状态 GA 自发写入",Status:"状态","Status DPT":"状态 DPT","Status GA":"状态 GA","Status write timeout ms":"状态写入超时毫秒","Step title":"步骤标题","Stopping repeat mode after the current cycle...":"在当前周期后停止重复模式...",Subscribe:"订阅",Suggestions:"建议","Summarize the current KNX traffic and highlight the busiest group addresses.":"总结当前 KNX 流量并突出显示最繁忙的组地址。",Summary:"总结","Targets supported HVAC command GA in the selected area.":"所选区域中支持 HVAC 命令 GA 的目标。","Targets supported shading command GA in the selected area.":"目标在选定区域中支持着色命令 GA。","telegram from the status GA.":"来自状态 GA 的电报。","telegram to the status GA and wait for a":"电报到状态 GA 并等待",Telegrams:"电报","Template Builder":"模板生成器","Test editor closed":"测试编辑器已关闭","Test plan deleted":"测试计划已删除","Test plan ready":"测试计划准备就绪","Test plan saved":"测试计划已保存","Test completed":"测试完成","Repeat mode stopped":"重复模式已停止","Test result deleted":"测试结果已删除","Test Results":"测试结果","Test Running":"试运行",Tests:"测试","The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.":"安装程序可以重命名该区域并准确决定哪些组地址属于该区域。一切都保存在每个 KNX AI 节点上。",Timeout:"超时",Title:"标题","Toggle menu":"切换菜单","Toggle sidebar":"切换侧边栏","Top Group Addresses":"顶级组地址","true, false, 50":"真、假、50","Turn the lights on, then turn them off, and verify that the related status values are coherent.":"打开灯,然后关闭它们,并验证相关状态值是否一致。","Unknown DPT":"未知 DPT","Unsaved changes":"未保存的更改",Voice:"语音",Wait:"等等","Wait for a spontaneous":"等待自发的","Wait ms":"等待毫秒",Warn:"警告","What this step checks":"此步骤检查什么","Why this step exists":"为什么存在这一步","Window {{value}}s.":"窗口 {{value}}s。","Write timeout":"写入超时"}},If=(e,a)=>{const i=e.__vccOpts||e;for(const[l,d]of a)i[l]=d;return i},Nf={class:"m-header"},Rf=["aria-expanded"],Df={class:"app-sidebar"},kf={id:"knx-ai-sidebar",class:"sidebar-brand-wrap"},xf=["aria-expanded"],Ef={class:"sidebar-collapse-icon"},Lf={class:"sidebar-nav"},Gf=["disabled"],Ff={key:0,class:"sidebar-panel sidebar-actions"},zf=["disabled"],Of={key:1,class:"sidebar-footer"},Mf={key:0,class:"running-spinner status-pill-spinner","aria-hidden":"true"},Bf={key:0,class:"status-detail"},$f={class:"workspace-shell"},Kf={class:"content-grid workspace-main"},Vf={key:0,class:"card card-summary"},jf={class:"card-head"},Uf={key:0,class:"meta-chip"},Wf={class:"summary-pre"},Hf={class:"metric-grid"},Xf={class:"metric"},qf={class:"metric"},Jf={class:"metric"},Zf={class:"metric"},Yf={key:1,class:"card card-areas"},Qf={class:"card-head"},ep={class:"card-head-actions"},tp={class:"meta-chip"},ap=["disabled"],np={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},sp=["disabled"],rp={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},ip={key:0,class:"planner-error-banner area-regenerate-error"},op={class:"areas-toolbar"},lp={class:"pill-row"},dp={class:"pill neutral"},cp={class:"pill neutral"},up={class:"pill neutral"},fp={class:"pill neutral"},pp={key:1,class:"areas-layout"},gp={key:0,class:"area-listbox-shell"},hp={class:"flow-field"},mp={class:"area-search-select"},vp=["placeholder"],bp={key:0,class:"area-search-select-menu"},yp=["onMousedown"],Ap={class:"area-editor"},Sp={key:0,class:"card-head"},wp={class:"card-head-actions action-cluster"},Tp=["disabled"],Pp=["disabled"],_p=["disabled"],Cp=["disabled"],Ip={key:1,class:"area-editor-grid"},Np={class:"flow-field"},Rp={class:"flow-field area-editor-span"},Dp={class:"flow-field area-editor-span"},kp={key:2,class:"ai-planner-shell area-llm-shell"},xp={key:0,class:"card-head-actions action-cluster"},Ep={class:"area-editor-grid"},Lp={class:"flow-field area-editor-span"},Gp={class:"profile-runbar"},Fp=["disabled"],zp={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Op={key:0,class:"planner-error-banner"},Mp={key:1,class:"area-detail-subhead"},Bp={key:3,class:"area-ga-editor"},$p={key:0,class:"simple-list simple-list-mono area-ga-list"},Kp={class:"area-ga-main"},Vp={key:0},jp={key:0},Up={class:"area-ga-actions"},Wp={class:"flow-field area-ga-role-field"},Hp=["value","disabled","onChange"],Xp=["value"],qp=["onClick"],Jp={key:1,class:"empty-state"},Zp={class:"card-head"},Yp={class:"meta-chip"},Qp={class:"area-ga-catalog"},eg=["onClick"],tg={class:"area-list-title"},ag={class:"area-list-meta"},ng={class:"area-list-tags"},sg={key:0},rg={key:4,class:"area-editor-note"},ig={key:2,class:"empty-state"},og={class:"card-head"},lg={class:"area-detail-subhead"},dg={key:0,class:"card-head-actions"},cg={class:"meta-chip"},ug={class:"meta-chip"},fg=["disabled"],pg={key:1,class:"card-head-actions"},gg={class:"meta-chip"},hg=["disabled"],mg={class:"profile-editor-stack"},vg={key:0,class:"area-detail planner-sidecard"},bg={class:"area-listbox-shell"},yg={class:"flow-field"},Ag={class:"area-search-select"},Sg=["placeholder"],wg={key:0,class:"area-search-select-menu"},Tg=["onMousedown"],Pg={key:0,class:"empty-state"},_g={key:1,class:"area-detail"},Cg={key:0,class:"card-head"},Ig={key:0,class:"area-detail-subhead"},Ng={class:"card-head-actions action-cluster"},Rg={key:0,class:"meta-chip"},Dg={class:"checkbox flow-toggle compact-toggle"},kg=["disabled"],xg=["disabled"],Eg=["disabled"],Lg={key:2,class:"plan-run-actions"},Gg=["disabled"],Fg=["disabled"],zg={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Og={key:1,class:"ai-planner-shell"},Mg={key:0,class:"card-head-actions action-cluster"},Bg={class:"area-editor-grid"},$g={class:"flow-field"},Kg=["value"],Vg={class:"flow-field area-editor-span"},jg=["value"],Ug={class:"preset-row compact-preset-row"},Wg=["onClick"],Hg={class:"area-detail-subhead"},Xg={class:"profile-runbar"},qg=["disabled"],Jg={key:0,class:"running-spinner run-button-spinner","aria-hidden":"true"},Zg={key:0,class:"planner-error-banner"},Yg={key:1,class:"planner-generation"},Qg={key:0,class:"area-detail-subhead"},eh={key:1,class:"area-detail-subhead"},th={key:2,class:"area-detail planner-run-focus"},ah={class:"card-head"},nh={class:"area-detail-subhead"},sh={class:"meta-chip"},rh={class:"metric-grid area-metrics"},ih={class:"metric"},oh={class:"metric"},lh={class:"metric"},dh={class:"metric"},ch={key:0,class:"report-check report-pass planner-step-card planner-step-running"},uh={class:"anomaly-head"},fh={class:"area-detail-subhead"},ph={key:0,class:"planner-step-grid"},gh={key:1,class:"planner-step-grid"},hh={key:2,class:"planner-check-sections"},mh={class:"planner-check-section"},vh={class:"planner-step-grid compact-grid"},bh={class:"planner-check-section"},yh={class:"planner-step-grid compact-grid"},Ah={class:"card-head"},Sh={class:"area-detail-subhead"},wh={class:"card-head-actions action-cluster"},Th={class:"meta-chip"},Ph={key:0,class:"meta-chip"},_h={class:"meta-chip"},Ch={class:"metric-grid area-metrics"},Ih={class:"report-checks"},Nh={class:"anomaly-head"},Rh={class:"area-detail-subhead"},Dh={key:0,class:"planner-check-sections result-check-sections"},kh={class:"planner-step-grid compact-grid"},xh={key:1,class:"planner-step-grid"},Eh={key:0,class:"empty-state"},Lh={key:1},Gh={class:"simple-list"},Fh={key:4,class:"area-detail plan-draft-shell"},zh={class:"card-head"},Oh={class:"running-headline"},Mh={key:0,class:"running-spinner","aria-hidden":"true"},Bh={class:"card-head-actions action-cluster"},$h={class:"meta-chip"},Kh={class:"area-editor-grid"},Vh={class:"flow-field"},jh=["value","disabled"],Uh=["value"],Wh={class:"flow-field"},Hh={class:"flow-field area-editor-span"},Xh={class:"report-checks plan-steps-stack"},qh=["onDragenter","onDrop"],Jh={class:"anomaly-head"},Zh={class:"planner-step-title"},Yh=["onDragstart"],Qh=["aria-expanded","title","onClick"],em={class:"card-head-actions action-cluster compact-actions"},tm=["onClick"],am=["onClick"],nm={key:0,class:"planner-step-summary"},sm={key:0},rm={key:1},im={key:2},om={key:3},lm={key:4},dm={key:5},cm={key:1,class:"planner-step-editor"},um={class:"flow-field"},fm=["onUpdate:modelValue"],pm={class:"flow-field area-editor-span"},gm=["onUpdate:modelValue"],hm={key:0,class:"flow-field"},mm=["onUpdate:modelValue"],vm={key:1,class:"planner-field-group area-editor-span"},bm={class:"planner-field-group-grid"},ym={class:"flow-field"},Am=["onUpdate:modelValue","onChange"],Sm=["value"],wm={class:"flow-field"},Tm=["onUpdate:modelValue","onChange"],Pm={class:"flow-field group-span"},_m=["onUpdate:modelValue"],Cm=["value"],Im=["onUpdate:modelValue"],Nm={key:2,class:"planner-field-group area-editor-span"},Rm={class:"planner-field-group-grid"},Dm={class:"flow-field group-span"},km=["onUpdate:modelValue","onChange"],xm=["value"],Em={class:"flow-field"},Lm=["onUpdate:modelValue","onChange"],Gm={class:"flow-field"},Fm=["onUpdate:modelValue"],zm=["value"],Om=["onUpdate:modelValue"],Mm={key:3,class:"planner-check-sections editor-check-sections area-editor-span"},Bm={class:"planner-check-section"},$m={class:"flow-field"},Km=["onUpdate:modelValue"],Vm={class:"planner-check-section"},jm={class:"flow-field"},Um=["onUpdate:modelValue"],Wm={class:"flow-field area-editor-span"},Hm=["onUpdate:modelValue"],Xm={key:3,class:"card card-profiles"},qm={class:"card-head"},Jm={class:"card-head-actions"},Zm={class:"meta-chip"},Ym={class:"profiles-layout results-page-layout"},Qm={class:"area-detail planner-sidecard"},ev={class:"sidebar-results-list results-page-list"},tv=["onClick"],av={class:"sidebar-result-head"},nv={class:"sidebar-result-title"},sv={key:0,class:"running-spinner","aria-hidden":"true"},rv={class:"area-list-meta"},iv={key:0},ov={class:"area-list-tags"},lv={class:"area-list-tags"},dv=["disabled","onClick"],cv={key:0,class:"empty-state sidebar-empty-state"},uv={class:"card-head"},fv={class:"area-detail-subhead"},pv={class:"card-head-actions action-cluster"},gv={class:"meta-chip"},hv={key:0,class:"meta-chip"},mv={class:"meta-chip"},vv=["disabled"],bv={class:"metric-grid area-metrics"},yv={class:"report-checks"},Av={class:"anomaly-head"},Sv={class:"area-detail-subhead"},wv={key:0,class:"planner-check-sections result-check-sections"},Tv={class:"planner-step-grid compact-grid"},Pv={key:1,class:"planner-step-grid"},_v={key:0,class:"empty-state"},Cv={key:1},Iv={class:"simple-list"},Nv={key:1,class:"area-detail"},Rv={key:4,class:"card"},Dv={class:"card-head"},kv={class:"meta-chip"},xv={key:0,class:"rank-list"},Ev={class:"rank-title"},Lv={class:"rank-label"},Gv={key:1,class:"empty-state"},Fv={key:5,class:"card"},zv={class:"card-head"},Ov={class:"meta-chip"},Mv={key:0,class:"event-list"},Bv={class:"event-name"},$v={class:"event-bar"},Kv={key:1,class:"empty-state"},Vv={key:6,class:"card card-bus"},jv={class:"card-head"},Uv={key:0,class:"meta-chip"},Wv={class:"pill-row"},Hv={class:"pill success"},Xv={class:"pill danger"},qv={class:"pill neutral"},Jv={class:"bus-track"},Zv=["title"],Yv={class:"bus-scale"},Qv={key:1,class:"empty-state"},eb={class:"card-head"},tb={class:"card-head-actions"},ab={class:"meta-chip"},nb={class:"flow-toolbar"},sb={class:"flow-field"},rb={class:"flow-field flow-field-search"},ib={class:"flow-field flow-field-select"},ob=["value"],lb={class:"checkbox flow-toggle flow-toggle-inline"},db={class:"flow-frame"},cb=["viewBox"],ub=["id"],fb=["fill"],pb=["d","stroke","stroke-width","opacity","marker-end"],gb=["cx","cy"],hb=["x","y"],mb=["x","y"],vb=["x","y"],bb=["x","y"],yb={key:1,class:"empty-state flow-empty"},Ab={class:"flow-note"},Sb={key:8,class:"card card-anomalies"},wb={class:"card-head"},Tb={class:"meta-chip"},Pb={key:0,class:"anomaly-list"},_b={class:"anomaly-head"},Cb={class:"anomaly-time"},Ib={key:1,class:"empty-state"},Nb={key:9,class:"card card-chat"},Rb={class:"card-head"},Db={class:"meta-chip"},kb={class:"chat-log"},xb=["innerHTML"],Eb={key:1},Lb={key:0,class:"chat-message chat-pending"},Gb={class:"preset-row"},Fb=["disabled","onClick"],zb={class:"ask-row"},Ob=["disabled"],Mb=["disabled"],Bb={key:10,class:"card card-flow-builder"},$b={class:"card-head"},Kb={class:"meta-chip"},Vb={class:"flow-builder-split"},jb={class:"flow-builder-pane flow-builder-input"},Ub={class:"flow-builder-compose"},Wb=["disabled"],Hb={class:"flow-builder-actions"},Xb=["disabled"],qb={class:"flow-builder-pane flow-builder-output"},Jb={key:0,class:"flow-builder-pending"},Zb={key:1,class:"flow-builder-error"},Yb={key:2,class:"flow-builder-result"},Qb={key:0,class:"flow-builder-notes"},ey={key:1,class:"flow-builder-warnings"},ty={class:"flow-builder-result-head"},ay={class:"meta-chip"},ny={key:0,class:"meta-chip"},sy={class:"flow-builder-json"},ry={key:3,class:"flow-builder-placeholder"},iy={key:11,class:"card card-settings"},oy={class:"settings-tab-strip"},ly={key:0,class:"area-detail settings-panel"},dy={class:"settings-node-grid"},cy={class:"flow-field"},uy=["value"],fy={class:"checkbox settings-node-checkbox"},py={key:1,class:"area-detail settings-panel"},gy={class:"card-head-actions action-cluster settings-config-actions"},hy=["disabled"],my=["disabled"],vy={key:2,class:"area-detail settings-panel chat-learning-panel"},by={class:"card-head settings-panel-head"},yy={class:"chat-learning-meta"},Ay={class:"meta-chip"},Sy={key:0,class:"meta-chip chat-learning-dirty"},wy={class:"flow-field chat-learning-path-field"},Ty=["disabled"],Py={key:0,class:"error-banner chat-learning-error",role:"alert"},_y={class:"card-head-actions action-cluster chat-learning-actions"},Cy=["disabled"],Iy=["disabled"],Ny=["disabled"],Ry=["disabled"],Dy=["disabled"],ky=["disabled"],xy={key:1,class:"area-detail-subhead chat-learning-modified"},Ey={key:0,class:"global-wait-overlay",role:"status","aria-live":"polite","aria-busy":"true"},Ly={class:"global-wait-card"},Gy={class:"area-detail-subhead"},Fy={class:"modal-actions"},zy=["disabled"],Oy={class:"area-detail-subhead"},My={class:"modal-actions"},By=["disabled"],Wi="knxUltimateAI:selectedNodeId",Hi="knxUltimateAI:autoRefresh",$y="knxUltimateAI:activeTab",Xi="knxUltimateAI:settingsTab",qi="knxUltimateAI:flowPreview",Ji="knxUltimateAI:voiceEnabled",Zi="knxUltimateAI:sidebarExpanded",Ky="knxUltimateAI:selectedTestAreaId:",Vy="https://supergiovane.github.io/node-red-contrib-knx-ultimate/wiki/knxUltimateAI-vue",jy="https://www.paypal.com/donate/?hosted_button_id=S8SKPUBSPK758",Uy="https://www.youtube.com/@maxsupervibe",Wy={__name:"App",setup(e){const a=["Summarize the current KNX traffic and highlight the busiest group addresses.","Explain any anomalies you see and suggest what to check first.","Generate an SVG bar chart of Top Group Addresses with counts and title."],i=[{id:"lights_on_off",title:"Lights on, then off",prompt:"Turn the lights on, then turn them off, and verify that the related status values are coherent.",description:"Applies to all matching lighting command GA in the selected area."},{id:"area_activate",title:"Activate main actuators",prompt:"Activate the main actuators in the area and verify the status feedback to confirm that it follows the commands.",description:"Builds a deterministic active test using the supported command GA in the selected area."},{id:"shading_open_close",title:"Open and close shading",prompt:"Open and close the shading actuators in the area, then verify that the status matches the commands sent.",description:"Targets supported shading command GA in the selected area."},{id:"hvac_check",title:"HVAC active check",prompt:"Run a full test of the HVAC commands in the area and verify that setpoints and statuses are coherent.",description:"Targets supported HVAC command GA in the selected area."}],l=[{value:"command",label:"Command"},{value:"status",label:"Status"},{value:"neutral",label:"Don't use in tests"}],d={write:"#ff9800",response:"#46b86d",read:"#d99a34",repeat:"#c34747",other:"#8d8578"},c=(()=>{try{return new URLSearchParams(window.location.search).get("nodeId")||""}catch{return""}})(),f=(()=>{try{return new URLSearchParams(window.location.search).get("tab")==="settings"?"settings":"overview"}catch{return"overview"}})(),p=(()=>{try{return new URLSearchParams(window.location.search).get("settingsTab")==="learning"?"learning":""}catch{return""}})(),m=(()=>{try{return new URLSearchParams(window.location.search).get("access_token")||""}catch{return""}})();function T(){try{if(!window.localStorage)return"";const s=[];for(let n=0;n<window.localStorage.length;n+=1){const r=String(window.localStorage.key(n)||"");if(!r.startsWith("auth-tokens"))continue;const u=window.localStorage.getItem(r);if(!u)continue;let g=null;try{g=JSON.parse(u)}catch{g=null}const C=g&&typeof g.access_token=="string"?g.access_token.trim():"";if(!C)continue;const N=Number(g&&(g.expires_at||g.expiry||g.expires)?g.expires_at||g.expiry||g.expires:0);s.push({token:C,expiresAt:Number.isFinite(N)?N:0})}return s.length?(s.sort((n,r)=>r.expiresAt-n.expiresAt),s[0].token||""):""}catch{return""}}const S=(()=>{const s=String(m||"").trim();return s||T()})();function I(s){const n=Object.assign({},s||{});return S&&!n.Authorization&&!n.authorization&&(n.Authorization=`Bearer ${S}`),n}const F=Ht("en");let K=null,se=0,H=!1;const De={it:{countAreas:"{{count}} aree",countNodes:"{{count}} nodi",countSavedPlans:"{{count}} piani salvati",countAvailable:"{{count}} disponibili",countVisible:"{{count}} visibili",countEventTypes:"{{count}} tipi di eventi",countRecent:"{{count}} recenti",nodesLinks:"Nodi {{nodes}} | Link {{links}}",connected:"Connesso {{value}}",disconnected:"Disconnesso {{value}}",coverage:"Copertura {{value}}%",windowSec:"Finestra {{value}}s.",anomalyCount:"anomalia x{{value}}",areaLabel:"Area {{value}}",providerModel:"Provider: {{provider}} | Modello: {{model}}"},de:{countAreas:"{{count}} Bereiche",countNodes:"{{count}} Knoten",countSavedPlans:"{{count}} gespeicherte Pläne",countAvailable:"{{count}} verfügbar",countVisible:"{{count}} sichtbar",countEventTypes:"{{count}} Ereignistypen",countRecent:"{{count}} aktuell",nodesLinks:"Knoten {{nodes}} | Verbindungen {{links}}",connected:"Verbunden {{value}}",disconnected:"Getrennt {{value}}",coverage:"Abdeckung {{value}}%",windowSec:"Fenster {{value}}s.",anomalyCount:"Anomalie x{{value}}",areaLabel:"Bereich {{value}}",providerModel:"Anbieter: {{provider}} | Modell: {{model}}"},fr:{countAreas:"{{count}} zones",countNodes:"{{count}} nœuds",countSavedPlans:"{{count}} plans enregistrés",countAvailable:"{{count}} disponibles",countVisible:"{{count}} visibles",countEventTypes:"{{count}} types d'événements",countRecent:"{{count}} récents",nodesLinks:"Nœuds {{nodes}} | Liens {{links}}",connected:"Connecté {{value}}",disconnected:"Déconnecté {{value}}",coverage:"Couverture {{value}}%",windowSec:"Fenêtre {{value}}s.",anomalyCount:"anomalie x{{value}}",areaLabel:"Zone {{value}}",providerModel:"Fournisseur : {{provider}} | Modèle : {{model}}"},es:{countAreas:"{{count}} áreas",countNodes:"{{count}} nodos",countSavedPlans:"{{count}} planes guardados",countAvailable:"{{count}} disponibles",countVisible:"{{count}} visibles",countEventTypes:"{{count}} tipos de eventos",countRecent:"{{count}} recientes",nodesLinks:"Nodos {{nodes}} | Enlaces {{links}}",connected:"Conectado {{value}}",disconnected:"Desconectado {{value}}",coverage:"Cobertura {{value}}%",windowSec:"Ventana {{value}}s.",anomalyCount:"anomalía x{{value}}",areaLabel:"Área {{value}}",providerModel:"Proveedor: {{provider}} | Modelo: {{model}}"},"zh-CN":{countAreas:"{{count}} 个区域",countNodes:"{{count}} 个节点",countSavedPlans:"{{count}} 个已保存计划",countAvailable:"{{count}} 可用",countVisible:"{{count}} 可见",countEventTypes:"{{count}} 种事件类型",countRecent:"{{count}} 条最近记录",nodesLinks:"节点 {{nodes}} | 连线 {{links}}",connected:"已连接 {{value}}",disconnected:"已断开 {{value}}",coverage:"覆盖率 {{value}}%",windowSec:"窗口 {{value}} 秒。",anomalyCount:"异常 x{{value}}",areaLabel:"区域 {{value}}",providerModel:"提供方: {{provider}} | 模型: {{model}}"}},ye={en:"en","en-us":"en","en-gb":"en",it:"it","it-it":"it",de:"de","de-de":"de",fr:"fr","fr-fr":"fr",es:"es","es-es":"es",zh:"zh-CN","zh-cn":"zh-CN","zh-hans":"zh-CN","zh-hans-cn":"zh-CN"},ce=new Set(["KNX AI","KNX Ultimate","GroupValue_Write","GroupValue_Response","GA","DPT","ETS","SVG"]),ge={it:{"Open Source Test":"Apri Test Sorgente","Asking...":"Sto chiedendo...","Loading...":"Caricamento...","Running...":"In esecuzione...",Running:"In esecuzione","Flow Map":"Mappa Flussi",Anomalies:"Anomalie",Rate:"Frequenza",Pass:"OK",Fail:"Errore",Warn:"Attenzione",Wait:"Attesa","Wait ms":"Attesa (ms)","Response timeout":"Timeout risposta","Read response timeout ms":"Timeout risposta lettura (ms)","Status write timeout ms":"Timeout scrittura stato (ms)","Regenerating...":"Rigenerazione...","Regenerate AI Areas":"Rigenera Aree AI","Deleting...":"Eliminazione...","Delete AI Areas":"Elimina Aree AI","Test Results":"Risultati Test","Select Test Result":"Seleziona risultato test","No test result selected.":"Nessun risultato test selezionato.","Open and close shading":"Apri e chiudi schermature"},de:{"Open Source Test":"Quelltest öffnen","Asking...":"Anfrage läuft...","Loading...":"Wird geladen...","Running...":"Läuft...",Running:"Läuft","Flow Map":"Flusskarte",Anomalies:"Anomalien",Rate:"Rate",Pass:"OK",Fail:"Fehler",Warn:"Warnung",Wait:"Warten","Wait ms":"Warten (ms)","Regenerating...":"Wird neu erstellt...","Regenerate AI Areas":"KI-Bereiche neu erstellen","Deleting...":"Wird gelöscht...","Delete AI Areas":"KI-Bereiche löschen"},fr:{"Open Source Test":"Ouvrir le test source","Asking...":"Interrogation en cours...","Loading...":"Chargement...","Running...":"En cours...",Running:"En cours","Flow Map":"Carte des flux",Anomalies:"Anomalies",Rate:"Débit",Pass:"OK",Fail:"Échec",Warn:"Alerte",Wait:"Attente","Wait ms":"Attente (ms)","Regenerating...":"Régénération...","Regenerate AI Areas":"Régénérer les zones IA","Deleting...":"Suppression...","Delete AI Areas":"Supprimer les zones IA"},es:{"Open Source Test":"Abrir prueba de origen","Asking...":"Consultando...","Loading...":"Cargando...","Running...":"En ejecución...",Running:"En ejecución","Flow Map":"Mapa de flujo",Anomalies:"Anomalías",Rate:"Tasa",Pass:"OK",Fail:"Fallo",Warn:"Aviso",Wait:"Espera","Wait ms":"Espera (ms)","Regenerating...":"Regenerando...","Regenerate AI Areas":"Regenerar áreas de IA","Deleting...":"Eliminando...","Delete AI Areas":"Eliminar áreas de IA"},"zh-CN":{"Open Source Test":"打开源测试","Asking...":"正在提问...","Loading...":"加载中...","Running...":"运行中...",Running:"运行中","Flow Map":"流量拓扑图",Anomalies:"异常",Rate:"速率",Pass:"通过",Fail:"失败",Warn:"警告",Wait:"等待","Wait ms":"等待(毫秒)","Regenerating...":"正在重新生成...","Regenerate AI Areas":"重新生成 AI 区域","Deleting...":"正在删除...","Delete AI Areas":"删除 AI 区域"}};function X(s,n="en"){const r=String(s||"").trim().toLowerCase();if(!r)return n;if(ye[r])return ye[r];if(r.includes("-")){const u=r.split("-")[0];if(ye[u])return ye[u]}return n}function Ee(){try{const r=new URLSearchParams(window.location.search).get("lang");if(r)return X(r,"en")}catch{}const s=X(String(navigator.language||""),"");if(s)return s;const n=String(document&&document.documentElement&&document.documentElement.lang?document.documentElement.lang:"").trim();return n?X(n,"en"):"en"}function Pe(s,n={}){return String(s||"").replace(/\{\{\s*([^}\s]+)\s*\}\}/g,(r,u)=>Object.prototype.hasOwnProperty.call(n,u)?String(n[u]):r)}function it(s){const n=De[F.value];if(!n)return"";let r=s.match(/^(\d+)\sareas$/i);return r?Pe(n.countAreas,{count:r[1]}):(r=s.match(/^(\d+)\snodes$/i),r?Pe(n.countNodes,{count:r[1]}):(r=s.match(/^(\d+)\ssaved plans$/i),r?Pe(n.countSavedPlans,{count:r[1]}):(r=s.match(/^(\d+)\savailable$/i),r?Pe(n.countAvailable,{count:r[1]}):(r=s.match(/^(\d+)\svisible$/i),r?Pe(n.countVisible,{count:r[1]}):(r=s.match(/^(\d+)\sevent types$/i),r?Pe(n.countEventTypes,{count:r[1]}):(r=s.match(/^(\d+)\srecent$/i),r?Pe(n.countRecent,{count:r[1]}):(r=s.match(/^Nodes\s+(.+?)\s+\|\s+Links\s+(.+)$/),r?Pe(n.nodesLinks,{nodes:r[1],links:r[2]}):(r=s.match(/^Connected\s+(.+)$/),r?Pe(n.connected,{value:r[1]}):(r=s.match(/^Disconnected\s+(.+)$/),r?Pe(n.disconnected,{value:r[1]}):(r=s.match(/^Coverage\s+(.+?)%$/),r?Pe(n.coverage,{value:r[1]}):(r=s.match(/^Window\s+(.+?)s\.$/),r?Pe(n.windowSec,{value:r[1]}):(r=s.match(/^anomaly x(.+)$/i),r?Pe(n.anomalyCount,{value:r[1]}):(r=s.match(/^Area\s+(.+)$/),r?Pe(n.areaLabel,{value:r[1]}):(r=s.match(/^Provider:\s+(.+?)\s+\|\s+Model:\s+(.+)$/),r?Pe(n.providerModel,{provider:r[1],model:r[2]}):""))))))))))))))}function Be(s){const n=String(s||""),r=n.trim();if(!r||F.value==="en"||ce.has(r))return n;const u=ge[F.value]||{},g=Cf[F.value]||{},C=u[r]||g[r]||it(r);return!C||C===r?n:n.replace(r,C)}function Ra(s){const n=s&&s.parentElement;if(!n)return!0;const r=String(n.tagName||"").toUpperCase();return!!(r==="SCRIPT"||r==="STYLE"||r==="CODE"||r==="PRE"||n.closest(".chat-log"))}function Et(s){const n=s||document.body;if(!(!n||F.value==="en")&&!H){H=!0;try{const r=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);let u=r.nextNode();for(;u;){if(!Ra(u)){const C=Be(u.nodeValue);C!==u.nodeValue&&(u.nodeValue=C)}u=r.nextNode()}const g=n.querySelectorAll("[placeholder], [title], [aria-label]");for(const C of g){const N=C.getAttribute("placeholder");if(N){const te=Be(N);te!==N&&C.setAttribute("placeholder",te)}const M=C.getAttribute("title");if(M){const te=Be(M);te!==M&&C.setAttribute("title",te)}const $=C.getAttribute("aria-label");if($){const te=Be($);te!==$&&C.setAttribute("aria-label",te)}}}finally{H=!1}}}function sa(){F.value!=="en"&&(se||(se=window.requestAnimationFrame(()=>{se=0,Et(document.body)})))}function ma(){K&&(K.disconnect(),K=null),se&&(window.cancelAnimationFrame(se),se=0)}function Da(){F.value!=="en"&&(ma(),K=new MutationObserver(()=>{H||sa()}),K.observe(document.body,{childList:!0,subtree:!0,characterData:!0}),sa())}const t=ds({nodes:[],selectedNodeId:"",activeTab:f,settingsTab:p||xa(Xi,"config"),autoRefresh:zt(Hi,!0),voiceEnabled:zt(Ji,!0),flowMaxNodes:Cn().maxNodes,flowSelectedGa:Cn().selectedGa,flowShowUniversalNodes:Cn().showUniversalNodes,flowSearch:"",areaSearch:"",areaSearchOpen:!1,areaSelectedId:"",testAreaSelectedId:"",areaDraftName:"",areaDraftDescription:"",areaDraftTags:"",areaDraftGaList:[],areaDraftId:"",areaDraftIsNew:!1,areaLlmPrompt:"",areaLlmBusy:!1,areaLlmError:"",areaLlmRegenerating:!1,areaLlmBulkDeleting:!1,gaCatalog:[],gaCatalogSearch:"",gaCatalogLoading:!1,areaGaRoleSavingGa:"",areaSaving:!1,profileSelectedId:"",profileDraftMode:!1,profileDraftId:"",profileDraftName:"",profileDraftDescription:"",profileDraftTargetTags:"",profileDraftMinActivityPct:20,profileDraftMaxSilentPct:60,profileDraftMaxAnomalies:2,profileSaving:!1,profileRunning:!1,actuatorPresetSelectedId:"",actuatorDraftMode:!1,actuatorDraftId:"",actuatorDraftName:"",actuatorDraftDescription:"",actuatorDraftCommandGA:"",actuatorDraftCommandDPT:"",actuatorDraftCommandPayload:"",actuatorDraftStatusGA:"",actuatorDraftStatusDPT:"",actuatorDraftStatusWriteTimeoutMs:5e3,actuatorDraftStatusResponseTimeoutMs:5e3,actuatorSaving:!1,actuatorRunning:!1,testPlanSelectedId:"",testPlanSearch:"",testPlanSearchOpen:!1,selectedTestResultId:"",liveTestResultId:"",testResultsMenuOpen:!0,testResultFocusMode:!1,deletingTestResultId:"",testPlanPrompt:"",testPlanDraft:null,testPlanCatalog:null,testPlanCatalogLoading:!1,testPlanCatalogError:"",testPlanGenerating:!1,testPlanSaving:!1,testPlanDeleting:!1,testPlanRunning:!1,testPlanGeneration:null,testPlanGenerationError:"",testPlanRunConfirmOpen:!1,testPlanRunMode:"single",testPlanRunningStepId:"",testPlanRepeatForever:!1,testPlanRepeatStopRequested:!1,testPlanDraftBaseline:"",testPlanUnsavedConfirmOpen:!1,areaUnsavedConfirmOpen:!1,testPlanPendingActionLabel:"",draggedTestPlanStepId:"",dragOverTestPlanStepId:"",showAiPlanner:!0,testTemplateBuilderFocus:!1,showAiAreaBuilder:!1,areaBuilderFocus:!1,status:"Ready",loadingNodes:!1,loadingState:!1,asking:!1,stateData:null,lastError:"",chatMessages:[],chatDraft:"",flowBuilderPrompt:"",flowBuilderGenerating:!1,flowBuilderResult:null,flowBuilderError:"",flowBuilderCopied:!1,chatLearningContent:"",chatLearningBaseline:"",chatLearningRevision:"",chatLearningName:"",chatLearningPath:"",chatLearningBytes:0,chatLearningMaxBytes:512*1024,chatLearningModifiedAt:"",chatLearningSessionCount:0,chatLearningLoadedNodeId:"",chatLearningLoading:!1,chatLearningSaving:!1,chatLearningResetting:!1,chatLearningCopied:!1,chatLearningError:"",pollStateHandle:null,pollNodesHandle:null}),ka=Ht(null),Oe=Ht(!1),we=Ht(null),he=Ht(null),tt=Ht(null),Lt=Ht(zt(Zi,!0)),at=Ht(!1),Ge=Ht(!1),ot=W(()=>Ge.value?at.value:Lt.value);let Gt=null,Ha=null,Ft=null,$e=0;function ra(){if(Gt){try{Gt.pause(),Gt.src=""}catch{}Gt=null}}function xa(s,n=""){try{return window.localStorage&&window.localStorage.getItem(s)||n}catch{return n}}function zt(s,n){try{if(!window.localStorage)return n;const r=window.localStorage.getItem(s);return r==null||r===""?n:r==="true"}catch{return n}}function Cn(){try{if(!window.localStorage)return{maxNodes:14,selectedGa:[],showUniversalNodes:!1};const s=window.localStorage.getItem(qi);if(!s)return{maxNodes:14,selectedGa:[],showUniversalNodes:!1};const n=JSON.parse(s),r=Math.max(4,Math.min(32,Number(n&&n.maxNodes)||14)),u=Array.isArray(n&&n.selectedGa)?Array.from(new Set(n.selectedGa.map(C=>String(C||"").trim()).filter(Boolean))).slice(0,80):[],g=n&&n.showUniversalNodes===!0;return{maxNodes:r,selectedGa:u,showUniversalNodes:g}}catch{return{maxNodes:14,selectedGa:[],showUniversalNodes:!1}}}function h(s,n){try{window.localStorage&&window.localStorage.setItem(s,String(n??""))}catch{}}function y(s,n){try{window.localStorage&&window.localStorage.setItem(s,n?"true":"false")}catch{}}function P(){try{Ge.value=window.matchMedia("(max-width: 1100px)").matches}catch{Ge.value=window.innerWidth<=1100}Ge.value||(at.value=!1)}function x(){if(Ge.value){at.value=at.value!==!0;return}Lt.value=Lt.value!==!0}function k(){Ge.value&&(at.value=!1)}function D(s){!s||s.key!=="Escape"||k()}function z(s){const n=String(s||"").trim();return n?`${Ky}${n}`:""}function G(s){const n=z(s);return n?xa(n,""):""}function L(s,n){const r=z(s);if(!r)return;const u=String(n||"").trim();u&&h(r,u)}function R(){const s=G(t.selectedNodeId);return!s||!Ae.value.find(n=>n.id===s)?!1:(t.testAreaSelectedId===s||(t.testAreaSelectedId=s),!0)}function U(){try{if(!window.localStorage)return;window.localStorage.setItem(qi,JSON.stringify({maxNodes:Math.max(4,Math.min(32,Number(t.flowMaxNodes)||14)),selectedGa:Array.from(new Set((t.flowSelectedGa||[]).map(s=>String(s||"").trim()).filter(Boolean))).slice(0,80),showUniversalNodes:t.flowShowUniversalNodes===!0}))}catch{}}async function B(){const s=ka.value;if(!(!s||typeof s.requestFullscreen!="function"))try{document.fullscreenElement===s?await document.exitFullscreen():document.fullscreenElement||await s.requestFullscreen()}catch{}}function j(){Oe.value=document.fullscreenElement===ka.value}function O(s){const n=new URL(s,window.location.href);return m&&n.searchParams.set("access_token",m),n.toString()}function _(s){t.status=Be(String(s||""))}async function q(s,n){const r=Object.assign({credentials:"same-origin"},n||{});r.headers=I(r.headers);const u=await fetch(s,r),g=String(u.headers.get("content-type")||"").toLowerCase(),C=await u.text();if(u.ok&&g.includes("text/html"))throw new Error("Authentication required or insufficient permissions (session token missing or expired).");let N={};try{N=C?JSON.parse(C):{}}catch{N={error:C||`HTTP ${u.status}`}}if(!u.ok){const M=N&&N.error?N.error:`HTTP ${u.status}`;throw u.status===401||u.status===403?new Error(`Authentication required or insufficient permissions (${u.status}).`):new Error(M)}return N}async function fe(s,n){const r=Object.assign({credentials:"same-origin",cache:"no-store"},n||{});r.headers=I(r.headers);const u=await fetch(s,r);if(!u.ok){const C=await u.text();let N=C||`HTTP ${u.status}`;try{const M=C?JSON.parse(C):{};N=M&&M.error?M.error:N}catch{}throw u.status===401||u.status===403?new Error(`Authentication required or insufficient permissions (${u.status}).`):new Error(N)}const g=String(u.headers.get("content-type")||"").toLowerCase();if(!g.includes("audio/")){const C=await u.text();if(g.includes("text/html"))throw new Error("Authentication required or insufficient permissions (invalid audio response).");let N=C||`Unexpected audio response (${g||"unknown"}).`;try{const M=C?JSON.parse(C):{};N=M&&M.error?M.error:N}catch{}throw new Error(N)}return await u.blob()}function Ie(s){if(s==null)return"";if(typeof s=="string")return s;try{return JSON.stringify(s,null,2)}catch{return String(s)}}function Le(s){return String(s||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function lt(s){const n=String(s||"").trim();return n.includes("-")&&/^\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(n)}function Ze(s){let n=String(s||"").trim();return n.startsWith("|")&&(n=n.slice(1)),n.endsWith("|")&&(n=n.slice(0,-1)),n.split("|").map(r=>String(r||"").trim())}function va(s){return Ze(s).map(n=>{const r=String(n||"").trim(),u=r.startsWith(":"),g=r.endsWith(":");return u&&g?"center":g?"right":"left"})}function In(s){const n=String(s||"").split(/\r?\n/);let r="",u=!1;const g=C=>{let N=String(C||"");return N=N.replace(/`([^`]+)`/g,"<code>$1</code>"),N=N.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),N=N.replace(/\*([^*]+)\*/g,"<em>$1</em>"),N=N.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(M,$,te)=>`<a href="${/^javascript:/i.test(String(te||"").trim())?"#":te}" target="_blank" rel="noopener noreferrer">${$}</a>`),N};for(let C=0;C<n.length;C++){const N=n[C];if(/^```/.test(N.trim())){u=!u,r+=u?"<pre><code>":"</code></pre>";continue}if(u){r+=`${N}
3
+ `;continue}if(/^###\s+/.test(N)){r+=`<h3>${N.replace(/^###\s+/,"")}</h3>`;continue}if(/^##\s+/.test(N)){r+=`<h2>${N.replace(/^##\s+/,"")}</h2>`;continue}if(/^#\s+/.test(N)){r+=`<h1>${N.replace(/^#\s+/,"")}</h1>`;continue}if(N.includes("|")&&C+1<n.length&&lt(n[C+1])){const te=Ze(N),Z=va(n[C+1]),pe=[];for(C+=2;C<n.length&&n[C]&&n[C].includes("|")&&!/^```/.test(n[C].trim());)pe.push(Ze(n[C])),C++;C-=1;const Q=Math.max(te.length,Z.length,...pe.map(ee=>ee.length),0);r+='<div class="chat-table-wrap"><table><thead><tr>';for(let ee=0;ee<Q;ee++)r+=`<th style="text-align:${Z[ee]||"left"};">${g(te[ee]||"")}</th>`;r+="</tr></thead><tbody>",pe.forEach(ee=>{r+="<tr>";for(let ae=0;ae<Q;ae++)r+=`<td style="text-align:${Z[ae]||"left"};">${g(ee[ae]||"")}</td>`;r+="</tr>"}),r+="</tbody></table></div>";continue}const M=/^\s*[-*]\s+/.test(N),$=/^\s*\d+\.\s+/.test(N);if(M||$){const te=$?"ol":"ul",Z=$?/^\s*\d+\.\s+/:/^\s*[-*]\s+/;for(r+=`<${te}>`;C<n.length&&Z.test(n[C]);)r+=`<li>${g(n[C].replace(Z,""))}</li>`,C++;C-=1,r+=`</${te}>`;continue}if(N.trim()===""){r+="<br>";continue}r+=`<p>${g(N)}</p>`}return u&&(r+="</code></pre>"),r}function Ve(s){return String(s||"").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&amp;/gi,"&")}function Ye(s){const n=[],r=/<svg[\s\S]*?<\/svg>/gi;let u;for(;(u=r.exec(String(s||"")))!==null;)u&&u[0]&&n.push(String(u[0]));return n}const Nn=new Set(["svg","g","path","line","polyline","polygon","circle","ellipse","rect","text","tspan","title","desc","defs","marker","lineargradient","radialgradient","stop","clippath"]),Rn=new Set(["xmlns","xmlns:xlink","viewbox","preserveaspectratio","width","height","role","aria-label","id","class","x","y","x1","y1","x2","y2","cx","cy","r","rx","ry","d","points","transform","fill","fill-opacity","stroke","stroke-width","stroke-opacity","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-size","font-family","font-weight","text-anchor","dominant-baseline","offset","stop-color","stop-opacity","gradientunits","gradienttransform","fx","fy","marker-start","marker-mid","marker-end","markerwidth","markerheight","refx","refy","orient","markerunits","href","xlink:href","clip-path","clippathunits"]);function ms(s){try{const r=new window.DOMParser().parseFromString(String(s||""),"image/svg+xml");if(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)return"";const u=r.documentElement;if(String(u.tagName||"").toLowerCase()!=="svg")return"";const g=N=>{const M=String(N.tagName||"").toLowerCase();if(!Nn.has(M)){N.remove();return}Array.from(N.attributes||[]).forEach($=>{const te=String($.name||"").toLowerCase(),Z=String($.value||"");if(te.startsWith("on")||!Rn.has(te)){N.removeAttribute($.name);return}(te==="href"||te==="xlink:href")&&Z&&!String(Z).trim().startsWith("#")&&N.removeAttribute($.name)}),Array.from(N.childNodes||[]).forEach($=>{$.nodeType===1?g($):$.nodeType!==3&&$.remove()})};g(u),!u.getAttribute("viewBox")&&!u.getAttribute("viewbox")&&u.setAttribute("viewBox","0 0 920 360"),u.setAttribute("role",u.getAttribute("role")||"img");const C=new window.XMLSerializer().serializeToString(u);return C.length>12e4?"":C}catch{return""}}function Xa(s){return In(Le(s||""))}function ol(s){const n=Ie(s),r=n.trim();if(!r)return Xa("(empty answer)");const u=/```(?:svg|xml|html)?\s*([\s\S]*?)```/gi;let g="",C=0,N=!1,M;for(;(M=u.exec(n))!==null;){const te=n.slice(C,M.index);te.trim()&&(g+=Xa(te));const Z=String(M[1]||""),pe=Ve(Z),Q=Ye(pe);if(Q.length){let ee=0;Q.forEach(ae=>{const me=ms(ae);me&&(ee++,N=!0,g+=`<div class="chat-svg-wrap">${me}</div>`)}),ee||(g+=`<pre><code>${Le(Z)}</code></pre>`)}else{const ee=ms(pe);ee?(N=!0,g+=`<div class="chat-svg-wrap">${ee}</div>`):g+=`<pre><code>${Le(Z)}</code></pre>`}C=M.index+M[0].length}const $=n.slice(C);if($.trim()&&(g+=Xa($)),!N){const te=Ve(n),Z=Array.from(new Set([...Ye(n),...Ye(te)])).map(pe=>ms(pe)).filter(Boolean);if(Z.length){const pe=n.replace(/<svg[\s\S]*?<\/svg>/gi,"").replace(/&lt;svg[\s\S]*?&lt;\/svg&gt;/gi,"").trim();g=pe?Xa(pe):"",Z.forEach(Q=>{g+=`<div class="chat-svg-wrap">${Q}</div>`})}}return g||Xa(r)}function vs(s){const n=Math.max(0,Math.round(Number(s)||0)),r=Math.floor(n/3600),u=Math.floor(n%3600/60),g=n%60;return r?`${r}h ${u}m`:u?`${u}m ${g}s`:`${g}s`}function Dn(s){if(!s)return"n/a";try{return new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return"n/a"}}function yt(s){if(!s)return"";try{return new Date(s).toLocaleString()}catch{return String(s)}}function Rr(s){const n=Math.max(0,Number(s)||0);return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(n<10240?1:0)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function kn(s){return s&&s.payload&&typeof s.payload=="object"?s.payload:{}}function Dr(s){return s==null?"":String(s).trim()}function Ot(s,n=null){try{return JSON.parse(JSON.stringify(s))}catch{return n}}function bs(s=[]){return Array.from(new Set((Array.isArray(s)?s:[]).map(n=>String(n||"").trim()).filter(Boolean))).sort()}function ll(s=""){return bs(String(s||"").split(","))}function ys(s={}){return JSON.stringify({isNew:s.isNew===!0,areaId:String(s.areaId||"").trim(),name:String(s.name||"").trim(),description:String(s.description||"").trim(),tags:bs(s.tags||[]),gaList:bs(s.gaList||[]),llmPrompt:String(s.llmPrompt||"").trim()})}function kr(s={}){return JSON.stringify({prompt:String(s.prompt||""),draft:Ot(s.draft,null)})}function dl(){return{selectedId:String(t.testPlanSelectedId||""),prompt:String(t.testPlanPrompt||""),draft:Ot(t.testPlanDraft,null),generation:Ot(t.testPlanGeneration,null),showAiPlanner:t.showAiPlanner===!0}}function Ea(){Ha=dl(),t.testPlanDraftBaseline=kr(Ha)}function cl(){const s=Ot(Ha,null);if(!s){t.testPlanSelectedId="",t.testPlanPrompt="",t.testPlanDraft=null,t.testPlanGeneration=null,t.testPlanRunConfirmOpen=!1,t.showAiPlanner=!0;return}t.testPlanSelectedId=String(s.selectedId||""),t.testPlanPrompt=String(s.prompt||""),t.testPlanDraft=Ot(s.draft,null),t.testPlanGeneration=Ot(s.generation,null),t.testPlanRunConfirmOpen=!1,t.showAiPlanner=s.showAiPlanner!==!1,s.draft&&s.draft.areaId&&Ae.value.find(n=>n.id===s.draft.areaId)&&(t.areaSelectedId=s.draft.areaId)}function ul(s){const n=String(s||"").trim();return n.length>14?`${n.slice(0,12)}..`:n}function fl(s){const n=String(s||"").trim();return n?n.length>28?`${n.slice(0,26)}..`:n:""}function pl(s){const n=Dr(s).replace(/\s+/g," ");return n?n.length>30?`${n.slice(0,28)}..`:n:""}function gl(s){const n=String(s||"").toLowerCase();return n.includes("repeat")?"repeat":n.includes("write")?"write":n.includes("response")?"response":n.includes("read")?"read":"other"}function hl(s){const n={write:0,response:0,read:0,repeat:0,other:0};return Object.keys(s||{}).forEach(r=>{const u=Number(s[r]||0);u<=0||(n[gl(r)]+=u)}),Object.keys(n).sort((r,u)=>n[u]-n[r])[0]||"other"}function As(s){return!!(s&&s.kind==="node"&&s.listenAllGA)}function ml(s){const n=s&&s.summary?s.summary:{},r=Array.isArray(s&&s.anomalies)?s.anomalies:[],u=Array.isArray(n.patternTransitions)?n.patternTransitions:[],g=Array.isArray(n.patterns)?n.patterns:[],C=n&&typeof n.gaLabels=="object"?n.gaLabels:{},N=n&&typeof n.gaLastPayload=="object"?n.gaLastPayload:{},M=n&&typeof n.gaLastSeenAt=="object"?n.gaLastSeenAt:{},$=new Set((Array.isArray(n.flowKnownGAs)?n.flowKnownGAs:[]).map(w=>String(w||"").trim()).filter(Boolean)),te={};r.forEach(w=>{const V=String(w&&w.payload&&w.payload.ga?w.payload.ga:"BUS").trim()||"BUS";te[V]=(te[V]||0)+1});const Z=n&&n.flowMapTopology&&typeof n.flowMapTopology=="object"?n.flowMapTopology:null,pe=Array.isArray(Z&&Z.nodes)?Z.nodes:[],Q=Array.isArray(Z&&Z.edges)?Z.edges:[],ee=new Map,ae=w=>{const V=String(w&&w.from?w.from:"").trim(),re=String(w&&w.to?w.to:"").trim();if(!V||!re||V===re)return;const Me=`${V}->${re}`,He={key:Me,from:V,to:re,weight:Math.max(1,Number(w&&(w.weight??w.currentWindowCount??w.totalCount??w.count)||1)),delta:Number(w&&w.delta?w.delta:0),edgeByEvent:w&&typeof w.edgeByEvent=="object"?w.edgeByEvent:{},lastAtMs:(()=>{const st=Number(w&&w.lastAtMs?w.lastAtMs:0);if(Number.isFinite(st)&&st>0)return st;const ua=new Date(String(w&&w.lastAt?w.lastAt:"")).getTime();return Number.isFinite(ua)?ua:0})(),linkType:String(w&&w.linkType?w.linkType:"").trim()};if(!ee.has(Me)){ee.set(Me,He);return}const Qe=ee.get(Me);Qe.weight+=He.weight,Qe.delta+=He.delta,Qe.lastAtMs=Math.max(Number(Qe.lastAtMs||0),Number(He.lastAtMs||0)),Object.keys(He.edgeByEvent||{}).forEach(st=>{Qe.edgeByEvent[st]=Number(Qe.edgeByEvent[st]||0)+Number(He.edgeByEvent[st]||0)})};Q.length?Q.forEach(ae):u.length?u.forEach(ae):g.forEach(w=>ae({from:w&&w.from,to:w&&w.to,count:w&&w.count,edgeByEvent:{}}));const me=new Map,ca=(w,V={})=>{const re=String(w||"").trim();return re?(me.has(re)||me.set(re,{id:re,displayId:String(V.displayId||re).trim()||re,kind:String(V.kind||(re.startsWith("N:")?"node":"ga")).trim()||"ga",subtitle:String(V.subtitle||"").trim(),payload:Dr(V.payload),anomalyCount:Number(V.anomalyCount||te[re]||0),inFlow:V.inFlow!==void 0?!!V.inFlow:$.size?$.has(re)||re==="BUS"||re.startsWith("N:"):!0,lastSeenAtMs:Number(V.lastSeenAtMs||0),score:Number(V.score||0),listenAllGA:V.listenAllGA===!0}),me.get(re)):null};return pe.forEach(w=>{const V=String(w&&w.id?w.id:"").trim();V&&ca(V,{displayId:w&&w.displayId,kind:w&&w.kind,subtitle:w&&w.subtitle?w.subtitle:C[V],payload:w&&w.payload!==void 0?w.payload:N[V],anomalyCount:Number(w&&w.anomalyCount?w.anomalyCount:te[V]||0),inFlow:w&&w.inFlow!==void 0?!!w.inFlow:void 0,lastSeenAtMs:Number(w&&w.lastSeenAtMs?w.lastSeenAtMs:new Date(String(w&&w.lastAt?w.lastAt:M[V]||"")).getTime()||0),score:Number(w&&w.score?w.score:0),listenAllGA:w&&w.listenAllGA===!0})}),Array.from(ee.values()).forEach(w=>{ca(w.from,{subtitle:C[w.from],payload:N[w.from],lastSeenAtMs:new Date(String(M[w.from]||"")).getTime()||w.lastAtMs||0}),ca(w.to,{subtitle:C[w.to],payload:N[w.to],lastSeenAtMs:new Date(String(M[w.to]||"")).getTime()||w.lastAtMs||0});const V=me.get(w.from),re=me.get(w.to);V&&(V.score+=Number(w.weight||0)),re&&(re.score+=Number(w.weight||0))}),(Array.isArray(n.topGAs)?n.topGAs:[]).slice(0,12).forEach(w=>{const V=String(w&&w.ga?w.ga:"").trim();if(!V)return;const re=ca(V,{subtitle:w&&w.label?w.label:C[V],payload:N[V],lastSeenAtMs:new Date(String(M[V]||"")).getTime()||0});re&&(re.score+=Number(w&&w.count?w.count:0))}),{nodes:Array.from(me.values()),edges:Array.from(ee.values()).sort((w,V)=>Number(V.weight||0)-Number(w.weight||0)).slice(0,48),telemetryWindowSec:Number(n&&n.graph&&n.graph.windowSec?n.graph.windowSec:n?.meta?.analysisWindowSec||0)}}function vl(s){let n=Array.isArray(s&&s.nodes)?s.nodes.slice():[];const r=Array.isArray(s&&s.edges)?s.edges.slice():[];t.flowShowUniversalNodes!==!0&&(n=n.filter(w=>!As(w)));const u=new Set(n.map(w=>w.id)),g=new Set((t.flowSelectedGa||[]).map(w=>String(w||"").trim()).filter(w=>w&&u.has(w))),C=Math.max(4,Math.min(32,Number(t.flowMaxNodes)||14));let N=n.slice().sort((w,V)=>{const re=Number(w.anomalyCount||0)*10+Number(w.score||0),Me=Number(V.anomalyCount||0)*10+Number(V.score||0);return Me!==re?Me-re:String(w.id||"").localeCompare(String(V.id||""))});if(g.size){const w=new Set(g);r.forEach(V=>{g.has(V.from)&&w.add(V.to),g.has(V.to)&&w.add(V.from)}),N=N.filter(V=>w.has(V.id))}else N=N.slice(0,C);const M=new Set(N.map(w=>w.id)),$=r.filter(w=>M.has(w.from)&&M.has(w.to)),te=Math.max(...$.map(w=>Number(w.weight||0)),1),Z=Math.max(2,Math.min(6,Math.ceil(Math.sqrt(Math.max(N.length,4)*1.5)))),pe=Math.max(1,Math.ceil(N.length/Z)),Q=1080,ee=Math.max(420,140+(pe-1)*150),ae=new Map;N.forEach((w,V)=>{const re=Math.floor(V/Z),Me=V%Z,He=Z===1?Q/2:90+Me*((Q-180)/Math.max(Z-1,1)),Qe=92+re*148;ae.set(w.id,{x:He,y:Qe,row:re,col:Me})});const me=Date.now(),ca=$.map((w,V)=>{const re=ae.get(w.from),Me=ae.get(w.to);if(!re||!Me)return null;const He=Me.x-re.x,Qe=Me.y-re.y,st=Math.max(Math.hypot(He,Qe),1),ua=He/st,Ga=Qe/st,Ce=24,Tt=re.x+ua*(Ce+2),Vt=re.y+Ga*(Ce+2),jt=Me.x-ua*(Ce+8),Ut=Me.y-Ga*(Ce+8),Mn=-Ga,Bn=ua,an=28+V%3*14,$n=V%2===0?1:-1,js=(Tt+jt)/2+Mn*an*$n,Jd=(Vt+Ut)/2+Bn*an*$n,ui=hl(w.edgeByEvent),fi=Number(w.lastAtMs||0)>0&&me-Number(w.lastAtMs||0)<=5e3;return{key:w.key,from:w.from,to:w.to,d:`M ${Tt} ${Vt} Q ${js} ${Jd} ${jt} ${Ut}`,width:(.9+Number(w.weight||0)/te*1.7).toFixed(2),color:d[ui]||d.other,opacity:fi?.82:.24,markerId:`flow-arrow-${ui}`,tooltip:`${w.from} -> ${w.to} | traffic: ${Number(w.weight||0)}${w.delta?` | delta: ${w.delta>0?"+":""}${w.delta}`:""}`,active:fi}}).filter(Boolean);return{width:Q,height:ee,telemetryWindowSec:Number(s&&s.telemetryWindowSec?s.telemetryWindowSec:0),nodes:N.map(w=>{const V=ae.get(w.id),re=Number(w.lastSeenAtMs||0);return Object.assign({},w,V,{shortLabel:ul(w.displayId||w.id),shortSubtitle:fl(w.subtitle),shortPayload:pl(w.payload),isIdle:re>0&&me-re>45e3})}),edges:ca,maxNodes:C,selectedCount:g.size}}const xn=W(()=>t.nodes.find(s=>s.id===t.selectedNodeId)||null),qa=W(()=>t.chatLearningContent!==t.chatLearningBaseline),xr=W(()=>new Blob([String(t.chatLearningContent||"")]).size),Ss=W(()=>xr.value>t.chatLearningMaxBytes),Fe=W(()=>t.stateData&&t.stateData.summary?t.stateData.summary:{}),pt=W(()=>t.stateData&&t.stateData.node?t.stateData.node:{}),ba=W(()=>t.stateData&&t.stateData.areas?t.stateData.areas:{suggested:[],totals:{}}),Ae=W(()=>Array.isArray(ba.value&&ba.value.suggested)?ba.value.suggested:[]),bl=W(()=>Ae.value.filter(s=>String(s&&s.id?s.id:"").startsWith("llm:"))),Er=W(()=>Number(bl.value.length||0)),Ja=W(()=>ba.value&&ba.value.totals?ba.value.totals:{}),ya=W(()=>Array.isArray(t.stateData&&t.stateData.profiles)?t.stateData.profiles:[]),yl=W(()=>t.stateData&&t.stateData.profileReport?t.stateData.profileReport:null),Aa=W(()=>Array.isArray(t.stateData&&t.stateData.actuatorTests)?t.stateData.actuatorTests:[]),Al=W(()=>t.stateData&&t.stateData.actuatorTestReport?t.stateData.actuatorTestReport:null),At=W(()=>Array.isArray(t.stateData&&t.stateData.testPlans)?t.stateData.testPlans:[]),Lr=W(()=>{const s=String(t.testPlanSearch||"").trim().toLowerCase();return At.value.filter(n=>s?[n.name,n.description,n.areaName,n.areaId].filter(Boolean).join(" ").toLowerCase().includes(s):!0)}),gt=W(()=>t.stateData&&t.stateData.testPlanReport?t.stateData.testPlanReport:null),Za=W(()=>Array.isArray(t.stateData&&t.stateData.testResults)?t.stateData.testResults:[]),Gr=W(()=>!t.liveTestResultId||!gt.value||gt.value.id!==t.liveTestResultId?null:Object.assign({},gt.value,{live:t.testPlanRunning===!0})),ia=W(()=>{const s=[],n=new Set,r=(u,g=!1)=>{if(!u||typeof u!="object"||!u.id)return;const C=String(u.id);n.has(C)||(n.add(C),s.push(Object.assign({},u,{live:g})))};return r(Gr.value,!0),Za.value.forEach(u=>r(u,!1)),s}),ie=W(()=>{if(t.selectedTestResultId){const s=ia.value.find(n=>n&&n.id===t.selectedTestResultId);if(s)return s}return Gr.value||Za.value[0]||null}),St=W(()=>t.activeTab==="tests"&&t.testResultFocusMode===!0&&!!ie.value),Sl=W(()=>a.map(s=>{const n=String(s||"").trim(),r=String(Be(n)||"").trim();return{key:n,text:r||n}})),ws=W(()=>{const s=String(t.areaSearch||"").trim().toLowerCase();return Ae.value.filter(n=>s?[n.path,n.name,n.parentName,...Array.isArray(n.tags)?n.tags:[],...Array.isArray(n.sampleLabels)?n.sampleLabels:[]].filter(Boolean).join(" ").toLowerCase().includes(s):!0)}),ze=W(()=>{if(t.areaDraftIsNew===!0&&!String(t.areaSelectedId||"").trim())return null;if(t.areaSelectedId){const s=Ae.value.find(n=>n.id===t.areaSelectedId);if(s)return s}return null}),dt=W(()=>{if(t.testAreaSelectedId){const s=Ae.value.find(n=>n.id===t.testAreaSelectedId);if(s)return s}return Ae.value[0]||null}),Mt=W(()=>{const s=String(t.testPlanDraft&&t.testPlanDraft.areaId?t.testPlanDraft.areaId:"").trim();if(s){const n=Ae.value.find(r=>r.id===s);if(n)return n}return dt.value}),Fr=W(()=>{const s=String(t.gaCatalogSearch||"").trim().toLowerCase(),n=new Set((t.areaDraftGaList||[]).map(r=>String(r||"").trim()).filter(Boolean));return(Array.isArray(t.gaCatalog)?t.gaCatalog:[]).filter(r=>!r||!r.ga||n.has(r.ga)?!1:s?[r.ga,r.label,r.hierarchyPath,...Array.isArray(r.tags)?r.tags:[]].filter(Boolean).join(" ").toLowerCase().includes(s):!0).slice(0,80)}),zr=W(()=>{const s=new Map((Array.isArray(t.gaCatalog)?t.gaCatalog:[]).map(n=>[String(n&&n.ga?n.ga:"").trim(),n]));return(t.areaDraftGaList||[]).map(n=>s.get(String(n||"").trim())||{ga:String(n||"").trim(),label:"",dpt:"",hierarchyPath:"",tags:[]})}),Ts=W(()=>Array.isArray(t.testPlanCatalog&&t.testPlanCatalog.commandSignals)?t.testPlanCatalog.commandSignals:[]),Or=W(()=>Array.isArray(t.testPlanCatalog&&t.testPlanCatalog.statusSignals)?t.testPlanCatalog.statusSignals:[]),wt=W(()=>{if(t.profileDraftMode===!0)return null;if(t.profileSelectedId){const s=ya.value.find(n=>n.id===t.profileSelectedId);if(s)return s}return ya.value[0]||null}),ct=W(()=>{if(t.actuatorDraftMode===!0)return null;if(t.actuatorPresetSelectedId){const s=Aa.value.find(n=>n.id===t.actuatorPresetSelectedId);if(s)return s}return Aa.value[0]||null}),oa=W(()=>t.testPlanSelectedId&&At.value.find(s=>s.id===t.testPlanSelectedId)||null),ke=W(()=>!t.testPlanRunningStepId||!t.testPlanDraft||!Array.isArray(t.testPlanDraft.steps)?null:t.testPlanDraft.steps.find(s=>String(s&&s.id?s.id:"")===t.testPlanRunningStepId)||null),wl=W(()=>!!(t.testPlanDraft&&Array.isArray(t.testPlanDraft.steps)&&t.testPlanDraft.steps.length>0)),Ps=W(()=>t.showAiPlanner===!0),Mr=W(()=>t.showAiAreaBuilder===!0),Br=W(()=>t.testPlanDraft?kr({prompt:t.testPlanPrompt,draft:t.testPlanDraft})!==t.testPlanDraftBaseline:!1),Tl=W(()=>{if(!(t.areaDraftIsNew===!0||!!ze.value))return!1;const n=ys({isNew:t.areaDraftIsNew===!0,areaId:String(t.areaDraftId||t.areaSelectedId||"").trim(),name:t.areaDraftName,description:t.areaDraftDescription,tags:ll(t.areaDraftTags),gaList:t.areaDraftGaList||[],llmPrompt:t.areaLlmPrompt});if(t.areaDraftIsNew===!0){const g=ys({isNew:!0,areaId:"",name:"New Area",description:"",tags:[],gaList:[],llmPrompt:""});return n!==g}const r=ze.value;if(!r)return!1;const u=ys({isNew:!1,areaId:String(r.id||"").trim(),name:String(r.name||""),description:String(r.customDescription||""),tags:Array.isArray(r.tags)?r.tags:[],gaList:Array.isArray(r.gaList)?r.gaList:[],llmPrompt:""});return n!==u}),_s=W(()=>Array.isArray(t.stateData&&t.stateData.anomalies)?t.stateData.anomalies.slice().reverse():[]),Cs=W(()=>{const s=Array.isArray(Fe.value.topGAs)?Fe.value.topGAs:[],n=Fe.value&&typeof Fe.value.gaLabels=="object"?Fe.value.gaLabels:{};return s.slice(0,10).map(r=>{const u=r&&typeof r=="object"?r:{},g=String(u.ga||"").trim(),C=String(u.label||"").trim(),N=g?String(n[g]||"").trim():"";return Object.assign({},u,{ga:g,label:C||N})})}),En=W(()=>{const s=Fe.value&&Fe.value.byEvent&&typeof Fe.value.byEvent=="object"?Fe.value.byEvent:{};return Object.keys(s).map(n=>({name:n,count:Number(s[n]||0)})).filter(n=>n.count>0).sort((n,r)=>r.count-n.count)}),Pl=W(()=>Math.max(...En.value.map(s=>s.count),1)),Is=W(()=>ml(t.stateData)),la=W(()=>vl(Is.value)),_l=W(()=>{const s=String(t.flowSearch||"").trim().toLowerCase();return Is.value.nodes.slice().filter(n=>t.flowShowUniversalNodes===!0||!As(n)).sort((n,r)=>String(n.id||"").localeCompare(String(r.id||""))).filter(n=>s?`${n.id} ${n.subtitle||""}`.toLowerCase().includes(s):!0).slice(0,120)}),nt=W(()=>Fe.value&&Fe.value.busConnection&&typeof Fe.value.busConnection=="object"?Fe.value.busConnection:null),Cl=W(()=>{const s=Fe.value||{};if(!Object.keys(s).length)return"No data available.";const n=s.counters||{},r=[];return r.push(pt.value.name||xn.value?.name||"KNX AI"),r.push(`Analysis window: ${Number(s.meta?.analysisWindowSec||0)}s`),r.push(`Telegrams: ${Number(n.telegrams||0)} | Rate: ${Number(n.overallRatePerSec||0)}/s`),r.push(`Echoed: ${Number(n.echoed||0)} | Repeat: ${Number(n.repeated||0)} | Unknown DPT: ${Number(n.unknownDpt||0)}`),nt.value&&r.push(`Bus: ${String(nt.value.currentState||"unknown")} | Connected: ${Number(nt.value.connectedPct||0)}% | Disconnected: ${Number(nt.value.disconnectedPct||0)}%`),r.join(`
4
+ `)}),Il=W(()=>{const s=nt.value;return!s||!Array.isArray(s.segments)?[]:s.segments.map((n,r)=>{const u=Math.max(0,Math.min(1,Number(n&&n.ratioStart)||0)),g=Math.max(0,Math.min(1,Number(n&&n.ratioWidth)||0));return{key:`${r}-${n?.startedAt||""}`,left:`${(u*100).toFixed(3)}%`,width:`${Math.max(g*100,.4).toFixed(3)}%`,title:`${n?.state==="connected"?"Connected":"Disconnected"} | ${Dn(n?.startedAt)} -> ${Dn(n?.endedAt)} | ${vs(n?.durationSec||0)}`,className:n?.state==="connected"?"segment-connected":"segment-disconnected"}}).filter(n=>Number.parseFloat(n.width)>0)}),Nl=W(()=>t.chatMessages.map((s,n)=>({key:`${n}-${s.kind}`,kind:s.kind,rawText:Ie(s.text),html:s.kind==="assistant"?ol(s.text):""})));Re(()=>t.selectedNodeId,s=>{h(Wi,s||""),t.areaSelectedId="",t.testAreaSelectedId=G(s||""),$d()}),Re(()=>t.autoRefresh,s=>{y(Hi,s)}),Re(()=>t.voiceEnabled,s=>{y(Ji,s),s!==!0&&ra()}),Re(Lt,s=>{y(Zi,s)}),Re(()=>t.activeTab,s=>{h($y,s||"overview")}),Re(()=>t.settingsTab,s=>{h(Xi,s||"config")}),Re(()=>t.flowMaxNodes,s=>{t.flowMaxNodes=Math.max(4,Math.min(32,Number(s)||14)),U()}),Re(()=>(t.flowSelectedGa||[]).join("|"),()=>{U()}),Re(()=>t.flowShowUniversalNodes,s=>{s!==!0&&(t.flowSelectedGa=(t.flowSelectedGa||[]).filter(n=>{const r=Is.value.nodes.find(u=>u.id===n);return!As(r)})),U()}),Re(()=>Ae.value.map(s=>s.id).join("|"),()=>{if(!Ae.value.length){t.areaSelectedId="",t.testAreaSelectedId="",t.activeTab==="tests"&&(t.activeTab="areas");return}if(t.areaDraftIsNew===!0&&!String(t.areaSelectedId||"").trim()){const r=String(t.testAreaSelectedId||"").trim();if(R())return;(!r||!Ae.value.find(u=>u.id===r))&&(t.testAreaSelectedId=Ae.value[0].id);return}const s=String(t.areaSelectedId||"").trim();s&&!Ae.value.find(r=>r.id===s)&&(t.areaSelectedId="");const n=String(t.testAreaSelectedId||"").trim();R()||(!n||!Ae.value.find(r=>r.id===n))&&(t.testAreaSelectedId=Ae.value[0].id)}),Re(()=>t.testAreaSelectedId,s=>{t.selectedNodeId&&L(t.selectedNodeId,s||"")}),Re(()=>ze.value?JSON.stringify({id:ze.value.id,name:ze.value.name,customDescription:ze.value.customDescription||"",tags:ze.value.tags||[]}):"",()=>{if(t.areaDraftIsNew===!0&&!String(t.areaSelectedId||"").trim())return;const s=ze.value;if(!s){t.areaDraftId="",t.areaDraftName="",t.areaDraftDescription="",t.areaDraftTags="",t.areaDraftGaList=[],t.areaLlmPrompt="",t.areaLlmError="",t.areaDraftIsNew=!1;return}t.areaDraftId=String(s.id||""),t.areaDraftName=String(s.name||""),t.areaDraftDescription=String(s.customDescription||""),t.areaDraftTags=Array.isArray(s.tags)?s.tags.join(", "):"",t.areaDraftGaList=Array.isArray(s.gaList)?s.gaList.slice():[],t.areaLlmPrompt="",t.areaLlmError="",t.areaDraftIsNew=!1}),Re(()=>Mt.value?Mt.value.id:"",async(s,n)=>{if(!s||!t.selectedNodeId){t.testPlanCatalog=null,t.testPlanCatalogError="";return}n&&s!==n&&(t.testPlanRunConfirmOpen=!1,t.testPlanDraft&&!t.testPlanSelectedId&&(t.testPlanDraft.areaId=String(s||""),t.testPlanDraft.areaName=Mt.value?String(Mt.value.path||Mt.value.name||""):"")),await Yr()}),Re(()=>ya.value.map(s=>s.id).join("|"),()=>{if(!ya.value.length){t.profileSelectedId="";return}t.profileDraftMode!==!0&&(!t.profileSelectedId||!ya.value.find(s=>s.id===t.profileSelectedId))&&(t.profileSelectedId=ya.value[0].id)}),Re(()=>wt.value?JSON.stringify({id:wt.value.id,name:wt.value.name,description:wt.value.description,targetTags:wt.value.targetTags||[],minActivityPct:wt.value.minActivityPct,maxSilentPct:wt.value.maxSilentPct,maxAnomalies:wt.value.maxAnomalies,builtIn:wt.value.builtIn===!0}):"",()=>{const s=wt.value;if(!s){t.profileDraftId="",t.profileDraftName="",t.profileDraftDescription="",t.profileDraftTargetTags="",t.profileDraftMinActivityPct=20,t.profileDraftMaxSilentPct=60,t.profileDraftMaxAnomalies=2;return}t.profileDraftId=String(s.id||""),t.profileDraftName=String(s.name||""),t.profileDraftDescription=String(s.description||""),t.profileDraftTargetTags=Array.isArray(s.targetTags)?s.targetTags.join(", "):"",t.profileDraftMinActivityPct=Number(s.minActivityPct||20),t.profileDraftMaxSilentPct=Number(s.maxSilentPct||60),t.profileDraftMaxAnomalies=Number(s.maxAnomalies||2)}),Re(()=>Aa.value.map(s=>s.id).join("|"),()=>{if(!Aa.value.length){t.actuatorPresetSelectedId="";return}t.actuatorDraftMode!==!0&&(!t.actuatorPresetSelectedId||!Aa.value.find(s=>s.id===t.actuatorPresetSelectedId))&&(t.actuatorPresetSelectedId=Aa.value[0].id)}),Re(()=>ct.value?JSON.stringify({id:ct.value.id,name:ct.value.name,description:ct.value.description,commandGA:ct.value.commandGA,commandDPT:ct.value.commandDPT,commandPayload:ct.value.commandPayload,statusGA:ct.value.statusGA,statusDPT:ct.value.statusDPT,statusWriteTimeoutMs:ct.value.statusWriteTimeoutMs,statusResponseTimeoutMs:ct.value.statusResponseTimeoutMs}):"",()=>{const s=ct.value;if(!s){t.actuatorDraftId="",t.actuatorDraftName="",t.actuatorDraftDescription="",t.actuatorDraftCommandGA="",t.actuatorDraftCommandDPT="",t.actuatorDraftCommandPayload="",t.actuatorDraftStatusGA="",t.actuatorDraftStatusDPT="",t.actuatorDraftStatusWriteTimeoutMs=5e3,t.actuatorDraftStatusResponseTimeoutMs=5e3;return}t.actuatorDraftId=String(s.id||""),t.actuatorDraftName=String(s.name||""),t.actuatorDraftDescription=String(s.description||""),t.actuatorDraftCommandGA=String(s.commandGA||""),t.actuatorDraftCommandDPT=String(s.commandDPT||""),t.actuatorDraftCommandPayload=String(s.commandPayload||""),t.actuatorDraftStatusGA=String(s.statusGA||""),t.actuatorDraftStatusDPT=String(s.statusDPT||""),t.actuatorDraftStatusWriteTimeoutMs=Number(s.statusWriteTimeoutMs||5e3),t.actuatorDraftStatusResponseTimeoutMs=Number(s.statusResponseTimeoutMs||5e3)}),Re(()=>At.value.map(s=>s.id).join("|"),()=>{if(!At.value.length){t.testPlanSelectedId="";return}t.testPlanSelectedId&&!At.value.find(s=>s.id===t.testPlanSelectedId)&&(t.testPlanSelectedId="")}),Re(()=>ia.value.map(s=>s.id).join("|"),()=>{if(!ia.value.length){t.selectedTestResultId="";return}(!t.selectedTestResultId||!ia.value.find(s=>s.id===t.selectedTestResultId))&&(t.selectedTestResultId=String(ia.value[0].id||"")),t.liveTestResultId&&Za.value.some(s=>String(s&&s.id?s.id:"")===t.liveTestResultId)&&t.testPlanRunning!==!0&&(t.liveTestResultId="")}),Re(()=>`${t.selectedTestResultId}|${t.activeTab}`,()=>{t.activeTab!=="results"||!t.selectedTestResultId||requestAnimationFrame(()=>{const s=document.querySelector(".results-page-list .area-list-item.active");s&&typeof s.scrollIntoView=="function"&&s.scrollIntoView({block:"nearest",behavior:"smooth"})})});function Ns(s,n){t.chatMessages.push({kind:s,text:n})}function Rl(){t.chatMessages=[]}function Dl(s,n=null){const r=Array.isArray(s)?s:[];return{totalSteps:Math.max(r.length,Number(n||0)),pass:r.filter(g=>g&&g.status==="pass").length,warn:r.filter(g=>g&&g.status==="warn").length,fail:r.filter(g=>g&&g.status==="fail").length}}function kl(s){const n=[];return Number(s&&s.fail)>0&&n.push("At least one feedback object returned an incoherent value. Check the actuator/status pairing in ETS first."),Number(s&&s.warn)>0&&n.push("Some steps did not receive feedback in time. Verify the status group address and the actuator programming."),n.length||n.push("The selected active test completed with coherent feedback on all verified steps."),n}function Rs({plan:s,area:n,stepResults:r,reportId:u=""}){const g=Dl(r,Array.isArray(s&&s.steps)?s.steps.length:0),C=g.fail>0?"fail":g.warn>0?"warn":"pass";return{id:String(u||`${s.id||"plan"}:${Date.now()}`),generatedAt:new Date().toISOString(),mode:"ai_test_plan",overallStatus:C,name:s.name,description:s.description,prompt:s.prompt,area:n,metrics:g,steps:r,suggestions:kl(g)}}function Ln(s){return!s||typeof s!="object"?"Test result":String(s.name||s.profile?.name||"Test result")}function Gn(s){return!s||typeof s!="object"?"":String(s.area?.path||s.area?.name||s.area?.id||"")}function Ya(s){const n=String(s&&s.mode?s.mode:"").trim().toLowerCase();return n==="ai_test_plan"?"Test Plan":n==="active_test"?"Actuator":n==="read_only"?"Read-only":n||"Test"}function Ds(s){const n=s&&s.metrics&&typeof s.metrics=="object"?s.metrics:{};return String(s&&s.mode?s.mode:"")==="read_only"?[{label:"Total GA",value:Number(n.totalGAs||0)},{label:"Active GA",value:Number(n.activeGaCount||0)},{label:"Silent GA",value:Number(n.silentGaCount||0)},{label:"Anomalies",value:Number(n.anomalyCount||0)}]:String(s&&s.mode?s.mode:"")==="active_test"?[{label:"Command GA",value:s&&s.command&&s.command.ga?s.command.ga:"n/a"},{label:"Status GA",value:s&&(s.statusResponse?.ga||s.statusWrite?.ga||s.statusRead?.ga)?s.statusResponse?.ga||s.statusWrite?.ga||s.statusRead?.ga:"n/a"},{label:"Status",value:s&&s.overallStatus?s.overallStatus:"n/a"},{label:"Generated",value:yt(s&&s.generatedAt?s.generatedAt:"")||"n/a"}]:[{label:"Total Steps",value:Number(n.totalSteps||0)},{label:"Pass",value:Number(n.pass||0)},{label:"Warn",value:Number(n.warn||0)},{label:"Fail",value:Number(n.fail||0)}]}function Bt(s){if(s==null||s==="")return"n/a";if(typeof s=="string"||typeof s=="number"||typeof s=="boolean")return String(s);try{return JSON.stringify(s)}catch{return String(s)}}function ks(s,n,r="n/a"){const u=String(n||"").trim(),g=s==null?"":String(s);if(!u)return g||r;const C=Os(g,u),N=da(u).find(M=>String(M.value)===String(C));return N&&N.label?N.label:g||r}function $r(s){if(!s||typeof s!="object")return"n/a";const n=s.ga||"n/a";if(s.ok===!0){const r=s.payloadLabel||Bt(s.payload),u=s.coherent===!1?"mismatch":"ok";return`${n} / ${r} / ${u}`}return`${n} / ${s.error||"timeout"}`}function xs(s){return yt(s||"")||"n/a"}function xl(s,n="report"){return String(s||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||n}function Kr({command:s,statusWrite:n,statusResponse:r,statusRead:u,expectedPayloadLabel:g,expectedPayload:C}){const N=r||u;return[{title:"Command",items:[{label:"Command",value:`${s?.ga||"n/a"} / ${s?.payloadLabel||Bt(s?.payload)}`},{label:"Command Sent",value:xs(s?.sentAt)}]},{title:"Spontaneous Write From Status GA",items:[{label:"Result",value:$r(n)},{label:"Expected",value:n?.expectedPayloadLabel||g||Bt(C)},{label:"Received At",value:xs(n?.at)},{label:"Event",value:n?.event||"n/a"}]},{title:"Active Read Request To Status GA",items:[{label:"Result",value:$r(N)},{label:"Expected",value:N?.expectedPayloadLabel||g||Bt(C)},{label:"Received At",value:xs(N?.at)},{label:"Event",value:N?.event||"n/a"}]}]}function Qa(s){return!s||typeof s!="object"?[]:Array.isArray(s.steps)&&s.steps.length?s.steps.map(n=>{const r=n.kind==="wait"?[{label:"Wait",value:`${Number(n.delayMs||0)} ms`},{label:"Reason",value:n.reason||"Pause before next action"}]:[];return{id:String(n.id||`${s.id}-step`),title:n.title||n.id||"Step",status:n.status||"pass",message:n.message||n.description||"",details:r,detailGroups:n.kind==="wait"?[]:Kr({command:n.command,statusWrite:n.statusWrite,statusResponse:n.statusResponse,statusRead:n.statusRead,expectedPayloadLabel:n.expectedPayloadLabel,expectedPayload:n.expectedPayload})}}):Array.isArray(s.checks)&&s.checks.length?s.checks.map(n=>({id:String(n.id||`${s.id}-check`),title:n.title||n.id||"Check",status:n.status||"pass",message:n.message||"",details:[{label:"Metrics",value:Bt(n.metrics||{})},{label:"Sample",value:Bt(n.sample||[])}]})):String(s.mode||"")==="active_test"?[{id:String(s.id||"active-test"),title:s.name||"Actuator Test",status:s.overallStatus||"pass",message:s.overallStatus==="pass"?"Both feedback checks passed.":s.overallStatus==="warn"?"One feedback check passed and one failed.":"Both feedback checks failed.",details:[],detailGroups:Kr({command:s.command,statusWrite:s.statusWrite,statusResponse:s.statusResponse,statusRead:s.statusRead,expectedPayloadLabel:s.statusResponse?.expectedPayloadLabel||s.statusWrite?.expectedPayloadLabel||s.statusRead?.expectedPayloadLabel,expectedPayload:s.statusRead?.expectedPayload})}]:[]}function en(s){return Array.isArray(s&&s.suggestions)?s.suggestions:[]}function El(s){const n=s&&s.source&&typeof s.source=="object"?s.source:{},r=String(s&&s.mode?s.mode:"").trim().toLowerCase(),u=String(n.areaId||s?.area?.id||"").trim();return r==="ai_test_plan"?{type:"ai_test_plan",planId:String(n.planId||String(s.id||"").split(":")[0]||"").trim(),areaId:u}:r==="read_only"?{type:"profile",profileId:String(n.profileId||s?.profile?.id||"").trim(),areaId:u}:r==="active_test"?{type:"actuator_test",presetId:String(n.presetId||String(s.id||"").split(":")[0]||"").trim(),areaId:u}:{type:"",areaId:u}}async function Vr(){const s=ie.value;if(!s||typeof s!="object"){_("No test result selected to export");return}try{const{jsPDF:n}=await _f(async()=>{const{jsPDF:Ce}=await import("./chunk-jspdf.es.min.js").then(Tt=>Tt.j);return{jsPDF:Ce}},[],import.meta.url),r=new n({orientation:"portrait",unit:"pt",format:"a4"}),u=r.internal.pageSize.getWidth(),g=r.internal.pageSize.getHeight(),C=42,N=42,M=44,$=42,te=u-C-N;let Z=M;const pe=(Ce=14)=>{Z+Ce<=g-$||(r.addPage(),Z=M)},Q=(Ce,{size:Tt=11,bold:Vt=!1,indent:jt=0,color:Ut=[35,41,52],lineHeight:Mn=14,gapAfter:Bn=0}={})=>{const an=String(Ce||"").trim();if(!an)return;r.setFont("helvetica",Vt?"bold":"normal"),r.setFontSize(Tt),r.setTextColor(Ut[0],Ut[1],Ut[2]);const $n=r.splitTextToSize(an,Math.max(80,te-jt));for(const js of $n)pe(Mn),r.text(String(js),C+jt,Z),Z+=Mn;Bn>0&&(Z+=Bn)},ee=()=>{pe(12),r.setDrawColor(210,214,222),r.line(C,Z,u-N,Z),Z+=12},ae=Ln(s),me=yt(new Date().toISOString())||new Date().toISOString(),ca=yt(s.generatedAt||"")||String(s.generatedAt||"n/a"),w=Gn(s)||"n/a",V=Ya(s),re=String(s.overallStatus||"n/a"),Me=Ds(s),He=Qa(s),Qe=en(s);Q("KNX AI Test Result",{size:17,bold:!0,color:[20,28,39],lineHeight:20}),Q(ae,{size:14,bold:!0,color:[20,28,39],lineHeight:17,gapAfter:4}),Q(`Exported: ${me}`,{size:10,color:[88,96,113]}),Q(`Generated: ${ca}`,{size:10,color:[88,96,113]}),Q(`Mode: ${V}`,{size:10,color:[88,96,113]}),Q(`Status: ${re}`,{size:10,color:[88,96,113]}),Q(`Area: ${w}`,{size:10,color:[88,96,113]}),Q(`Report ID: ${String(s.id||"n/a")}`,{size:10,color:[88,96,113],gapAfter:2}),ee(),Me.length&&(Q("Metrics",{size:12,bold:!0,color:[20,28,39],gapAfter:2}),Me.forEach(Ce=>{Q(`${Ce.label}: ${Bt(Ce.value)}`,{size:10,color:[35,41,52]})}),Z+=4,ee()),Q(`Checks (${He.length})`,{size:12,bold:!0,color:[20,28,39],gapAfter:2}),He.length?He.forEach((Ce,Tt)=>{Q(`${Tt+1}. ${Ce.title||"Check"} [${String(Ce.status||"n/a").toUpperCase()}]`,{size:11,bold:!0,color:[31,41,55]}),Q(Ce.message||"No additional details available.",{size:10,color:[70,78,94]}),Array.isArray(Ce.detailGroups)&&Ce.detailGroups.length?Ce.detailGroups.forEach(Vt=>{Q(Vt.title||"Details",{size:10,bold:!0,indent:12,color:[35,41,52]}),(Array.isArray(Vt.items)?Vt.items:[]).forEach(Ut=>{Q(`${Ut.label}: ${Bt(Ut.value)}`,{size:10,indent:24,color:[70,78,94]})})}):(Array.isArray(Ce.details)?Ce.details:[]).forEach(jt=>{Q(`${jt.label}: ${Bt(jt.value)}`,{size:10,indent:12,color:[70,78,94]})}),Z+=2}):Q("No detailed entries stored for this report yet.",{size:10,color:[88,96,113]}),Qe.length&&(Z+=4,ee(),Q("Suggestions",{size:12,bold:!0,color:[20,28,39],gapAfter:2}),Qe.forEach((Ce,Tt)=>{Q(`${Tt+1}. ${String(Ce||"")}`,{size:10,color:[35,41,52]})}));const st=new Date(s.generatedAt||Date.now()),ua=Number.isFinite(st.getTime())?st.toISOString().replace(/[:.]/g,"-"):String(Date.now()),Ga=`knx-ai-test-result-${xl(ae,"report")}-${ua}.pdf`;r.save(Ga),_(`PDF exported (${Ga})`)}catch(n){t.lastError=n&&n.message?n.message:"Failed to export PDF",_(t.lastError)}}function jr(s,n,r=new Date().toISOString()){const u=s&&s.kind==="wait";return{id:s&&s.id?s.id:`step-${Date.now()}`,title:s&&s.title?s.title:"Test Step",description:s&&s.description?s.description:"",reason:s&&s.reason?s.reason:"",kind:s&&s.kind?s.kind:"write_and_verify",status:"warn",command:u?null:{ga:s&&s.commandGA?s.commandGA:"",dpt:s&&s.commandDPT?s.commandDPT:"",payload:s?s.commandPayload:void 0,sentAt:r},statusWrite:null,statusResponse:null,statusRead:null,expectedPayload:u?void 0:s?s.expectedPayload:void 0,delayMs:Number(s&&s.delayMs?s.delayMs:0),statusWriteTimeoutMs:u?0:Number(s&&s.statusWriteTimeoutMs?s.statusWriteTimeoutMs:0),statusResponseTimeoutMs:u?0:Number(s&&s.statusResponseTimeoutMs?s.statusResponseTimeoutMs:0),message:n&&n.message?n.message:"Failed to run step"}}async function Ur(s){return ra(),await new Promise((n,r)=>{const u=URL.createObjectURL(s),g=new Audio(u);Gt=g;const C=()=>{Gt===g&&(Gt=null),g.onended=null,g.onerror=null,URL.revokeObjectURL(u)};g.onended=()=>{C(),n()},g.onerror=()=>{C(),r(new Error("Audio playback failed"))};const N=g.play();N&&typeof N.then=="function"&&N.catch(M=>{C(),r(M instanceof Error?M:new Error(String(M)))})})}function Ll(s,n=null){const r=String(s||"").trim();return!r||!t.testPlanDraft||!Array.isArray(t.testPlanDraft.steps)?n:t.testPlanDraft.steps.find(u=>String(u&&u.id?u.id:"")===r)||n}function Wr(s,n=""){const r=`${String(s||"")} ${String(n||"")}`.trim().toLowerCase(),u=` ${r} `;if(!r)return String((navigator.language||"it").split("-")[0]||"it").trim().toLowerCase()||"it";const g=M=>M.some($=>u.includes($)),C=[{voice:"it",score:[g([" accendi "," spegni "," stato "," verifica "," coerente "," leggi "," apri "," chiudi "," attiva "," controlla "," area "," luce "," luci "," tapparella "," tapparelle "," clima "])?3:0,/[àèéìíîòóù]/.test(r)?2:0].reduce((M,$)=>M+$,0)},{voice:"en",score:[g([" turn on "," turn off "," verify "," feedback "," status "," check "," read "," open "," close "," command "," area "," light "," lights "])?3:0].reduce((M,$)=>M+$,0)},{voice:"fr",score:[g([" allume "," éteins "," etat "," état "," vérifier "," ouvre "," ferme "," lumière "," lumières "," zone "])?3:0,/[àâçéèêëîïôûùüÿœ]/.test(r)?2:0].reduce((M,$)=>M+$,0)},{voice:"de",score:[g([" einschalten "," ausschalten "," status "," prüfen "," öffne "," schließe "," licht "," bereich "])?3:0,/[äöüß]/.test(r)?2:0].reduce((M,$)=>M+$,0)},{voice:"es",score:[g([" enciende "," apaga "," estado "," verifica "," abre "," cierra "," luz "," luces "," zona "])?3:0,/[áéíóúñü]/.test(r)?2:0].reduce((M,$)=>M+$,0)},{voice:"pt",score:[g([" liga "," desliga "," estado "," verificar "," abre "," fecha "," luz "," luzes "," área "])?3:0,/[ãõâêôçáéíóú]/.test(r)?2:0].reduce((M,$)=>M+$,0)}];return C.sort((M,$)=>$.score-M.score),C[0]&&C[0].score>0?C[0].voice:String((navigator.language||"it").split("-")[0]||"it").trim().toLowerCase()||"it"}function Gl(s={},n=null){const r=Ll(s&&s.id?s.id:"",s),u=String(r&&r.title?r.title:"").trim(),g=String(r&&r.description?r.description:"").trim();return{text:`${Number.isInteger(n)&&n>0?`${n}. `:""}${u}`.trim(),voice:Wr(u,g)}}async function Fl(s={},n=null){if(t.voiceEnabled!==!0)return;const r=Gl(s,n),u=String(r.text||"").trim();if(!u||!t.selectedNodeId)return;const g=await fe(`${O("tts/googletranslate")}?ts=${Date.now()}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,text:u,voice:r.voice,slow:!1})});await Ur(g)}async function Hr(s,n=""){if(t.voiceEnabled!==!0||!t.selectedNodeId)return;const r=String(s||"").trim();if(!r)return;const u=Wr(r,n),g=await fe(`${O("tts/googletranslate")}?ts=${Date.now()}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,text:r,voice:u,slow:!1})});await Ur(g)}function zl(s){const n=c&&s.find(g=>g.id===c)?c:"",r=xa(Wi,""),u=r&&s.find(g=>g.id===r)?r:"";return n||u||(s[0]?s[0].id:"")}async function Es({preserveSelection:s=!0}={}){t.loadingNodes=!0,_("Loading nodes...");try{const n=await q(O("nodes")),r=Array.isArray(n&&n.nodes)?n.nodes:[];if(t.nodes=r,!r.length){t.selectedNodeId="",t.stateData=null,t.lastError="No KNX AI nodes found.",_(t.lastError);return}const u=s&&t.selectedNodeId&&r.find(g=>g.id===t.selectedNodeId)?t.selectedNodeId:zl(r);t.selectedNodeId=u,t.lastError="",_("Ready")}catch(n){t.lastError=n.message||"Failed to load nodes",_(t.lastError)}finally{t.loadingNodes=!1}}async function $t({fresh:s=!1}={}){if(!(!t.selectedNodeId||t.loadingState)){t.loadingState=!0,s&&_("Loading...");try{const n=t.testPlanRunning===!0&&t.liveTestResultId?Ot(t.stateData&&t.stateData.testPlanReport?t.stateData.testPlanReport:null,null):null,r=await q(O(`state?nodeId=${encodeURIComponent(t.selectedNodeId)}&fresh=${s?1:0}`));n&&n.id===t.liveTestResultId&&(r.testPlanReport=n),t.stateData=r,un(()=>{t.areaDraftIsNew!==!0&&t.areaSelectedId&&!Ae.value.find(u=>u.id===t.areaSelectedId)&&(t.areaSelectedId=""),!R()&&!t.testAreaSelectedId&&Ae.value[0]&&(t.testAreaSelectedId=Ae.value[0].id)}),t.lastError="",_("Ready")}catch(n){t.lastError=n.message||"Failed to load state",_(t.lastError)}finally{t.loadingState=!1}}}async function Ol(){await Es({preserveSelection:!0}),await $t({fresh:!0}),await La()}async function Ml(){Rl(),t.selectedTestResultId="",t.liveTestResultId="",t.testResultFocusMode=!1,t.testAreaSelectedId=G(t.selectedNodeId),await $t({fresh:!0}),await La(),t.activeTab==="settings"&&t.settingsTab==="learning"&&await tn()}function Xr(){t.selectedTestResultId="",t.testResultFocusMode=!1,t.testPlanSelectedId="",t.testPlanDraft=null,t.testPlanPrompt="",t.testPlanGeneration=null,t.testPlanRunConfirmOpen=!1,t.testPlanUnsavedConfirmOpen=!1,t.showAiPlanner=!0,t.testTemplateBuilderFocus=!1,!R()&&!t.testAreaSelectedId&&Ae.value[0]&&(t.testAreaSelectedId=Ae.value[0].id),$s(),Bs()}function Bl(){t.showAiPlanner=!0,t.testTemplateBuilderFocus=!0}function $l(){t.testTemplateBuilderFocus=!1,t.showAiPlanner=!1}function Kl(){t.showAiAreaBuilder=!0,t.areaBuilderFocus=!0}function Vl(){t.areaBuilderFocus=!1,t.showAiAreaBuilder=!1}function Ls(){t.areaSelectedId="",t.areaDraftIsNew=!1,t.areaDraftId="",t.areaDraftName="",t.areaDraftDescription="",t.areaDraftTags="",t.areaDraftGaList=[],t.areaLlmPrompt="",t.areaLlmError="",t.areaSearch="",t.areaSearchOpen=!1,t.showAiAreaBuilder=!1,t.areaBuilderFocus=!1,t.areaUnsavedConfirmOpen=!1}function jl(){if(Tl.value){t.areaUnsavedConfirmOpen=!0;return}Ls(),_("Area editor closed")}function qr(){t.areaUnsavedConfirmOpen=!1}function Ul(){t.areaUnsavedConfirmOpen=!1,Ls(),_("Area editor closed")}function Wl(){t.testPlanRunning||Ks(()=>{Xr(),t.testPlanSearchOpen=!1,_("Test editor closed")},"close the current test editor")}function Gs(s){const n=String(s||"").trim();n!=="node"&&n!=="config"&&n!=="learning"||(t.settingsTab=n,n==="learning"&&tn())}function Sa(s){const n=String(s||"").trim();if(n){if(n==="tests"&&Ae.value.length===0){_("Define at least one area before using Tests");return}if(n==="areas"){const r=!!String(t.areaSelectedId||"").trim(),u=t.areaDraftIsNew===!0;!r&&!u&&Ls()}if(n==="tests"){const r=!!String(t.testPlanSelectedId||"").trim(),u=!!String(t.selectedTestResultId||"").trim(),g=!!t.testPlanDraft;!r&&!u&&!g&&Xr()}n==="settings"&&t.settingsTab==="learning"&&tn(),t.activeTab!==n?t.activeTab=n:(t.activeTab="",un(()=>{t.activeTab=n})),k()}}async function Fs(s){const n=String(s||"").trim();if(!(!n||!t.selectedNodeId||t.deletingTestResultId)){t.deletingTestResultId=n;try{const r=await q(O("test-results/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,reportId:n})}),u=Array.isArray(r&&r.testResults)?r.testResults:[];t.stateData=Object.assign({},t.stateData||{},{testResults:u}),t.selectedTestResultId===n&&(t.selectedTestResultId=u[0]&&u[0].id?String(u[0].id):"",u.length||(t.testResultFocusMode=!1)),t.liveTestResultId===n&&(t.liveTestResultId=""),_("Test result deleted")}catch(r){t.lastError=r.message||"Failed to delete test result",_(t.lastError)}finally{t.deletingTestResultId=""}}}function Fn(s,{openMenu:n=!0,activateTestsTab:r=!1,activateResultsTab:u=!1,resultOnly:g=!0}={}){const C=String(s||"").trim();if(!C)return;n&&(t.testResultsMenuOpen=!0);const N=u?"results":r?"tests":"",M=()=>{N&&(t.activeTab=N),t.selectedTestResultId=C,t.testResultFocusMode=g===!0,un(()=>{const $=document.querySelector(".results-page-list .area-list-item.active");$&&typeof $.scrollIntoView=="function"&&$.scrollIntoView({block:"nearest",behavior:"smooth"})})};t.selectedTestResultId===C&&(!N||t.activeTab===N)||M()}function Jr(){const s=ie.value;if(!s)return;if(!Ae.value.length){_("Define at least one area before using Tests");return}const n=El(s);if(t.activeTab="tests",t.testResultFocusMode=!1,n.type==="ai_test_plan"&&n.planId){const r=At.value.find(u=>u&&u.id===n.planId);if(r){ii(r),_(`Opened source plan "${r.name||r.id}"`);return}}if(n.type==="profile"){_("Returned to the Tests page for the source read-only profile.");return}if(n.type==="actuator_test"){_("Returned to the Tests page for the source actuator test.");return}_("Returned to the Tests page.")}async function Hl(s){if(!t.selectedNodeId||!s||typeof s!="object")return null;const n=await q(O("test-results/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,report:s})});return t.stateData=Object.assign({},t.stateData||{},{testResults:n.testResults||Za.value,testPlanReport:n.report&&n.report.mode==="ai_test_plan"?n.report:gt.value,actuatorTestReport:n.report&&n.report.mode==="active_test"?n.report:Al.value,profileReport:n.report&&n.report.mode==="read_only"?n.report:yl.value}),n&&n.report&&n.report.id&&(t.liveTestResultId="",Fn(n.report.id,{openMenu:!0,activateResultsTab:!0,resultOnly:!0})),n}async function zs(s=""){const n=String(s||"").trim(),r=String(t.chatDraft||"").trim(),u=n||r;if(!(!u||!t.selectedNodeId)){Ns("user",u),n||(t.chatDraft=""),t.asking=!0,_("Asking...");try{const g=await q(O("ask"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,question:u})});Ns("assistant",g&&g.answer!==void 0?g.answer:""),_("Ready")}catch(g){Ns("error",g.message||"Ask failed"),_(g.message||"Ask failed")}finally{t.asking=!1}}}async function Xl(){const s=String(t.flowBuilderPrompt||"").trim();if(!(!s||!t.selectedNodeId||t.flowBuilderGenerating)){t.flowBuilderGenerating=!0,t.flowBuilderError="",t.flowBuilderCopied=!1,_("Generating flow...");try{const n=await q(O("flow/generate"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,prompt:s,language:F.value})});t.flowBuilderResult=n||null,_("Ready")}catch(n){t.flowBuilderResult=null,t.flowBuilderError=n.message||"Flow generation failed",_(t.flowBuilderError)}finally{t.flowBuilderGenerating=!1}}}async function Zr(s){const n=String(s||"");if(navigator.clipboard&&navigator.clipboard.writeText){await navigator.clipboard.writeText(n);return}const r=document.createElement("textarea");r.value=n,r.style.position="fixed",r.style.opacity="0",document.body.appendChild(r),r.select(),document.execCommand("copy"),document.body.removeChild(r)}async function ql(){const s=t.flowBuilderResult&&t.flowBuilderResult.flowJson?t.flowBuilderResult.flowJson:"";if(s)try{await Zr(s),t.flowBuilderCopied=!0,_("Flow JSON copied to clipboard"),setTimeout(()=>{t.flowBuilderCopied=!1},2500)}catch(n){t.flowBuilderError=n.message||"Could not copy to clipboard"}}async function Jl(){const s=ze.value;if(!t.selectedNodeId||t.areaSaving||!t.areaDraftIsNew&&!s)return;const n=t.areaDraftIsNew===!0;t.areaSaving=!0,_(n?"Creating area...":"Saving area...");try{const u=await q(O(n?"areas/create":"areas/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:t.areaDraftIsNew?void 0:s.id,name:t.areaDraftName,description:t.areaDraftDescription,tags:String(t.areaDraftTags||"").split(",").map(g=>String(g||"").trim()).filter(Boolean),gaList:t.areaDraftGaList||[]})});u&&u.areas?(t.stateData=Object.assign({},t.stateData||{},{areas:u.areas}),u.areaId&&(t.areaSelectedId=u.areaId),t.areaLlmPrompt="",t.areaLlmError="",t.areaDraftIsNew=!1):await $t({fresh:!0}),_(n?"Area created":"Area saved")}catch(r){t.lastError=r.message||"Failed to save area",_(t.lastError)}finally{t.areaSaving=!1}}async function Zl(){const s=ze.value;if(!(!s||!t.selectedNodeId||t.areaSaving)){t.areaSaving=!0,_("Resetting area...");try{const n=await q(O("areas/reset"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:s.id})});n&&n.areas?t.stateData=Object.assign({},t.stateData||{},{areas:n.areas}):await $t({fresh:!0}),_("Area reset")}catch(n){t.lastError=n.message||"Failed to reset area",_(t.lastError)}finally{t.areaSaving=!1}}}async function Yl(){const s=ze.value;if(!(!s||!t.selectedNodeId||t.areaSaving)){t.areaSaving=!0,_("Deleting area...");try{const n=await q(O("areas/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:s.id})});if(n&&n.areas){t.stateData=Object.assign({},t.stateData||{},{areas:n.areas});const r=Array.isArray(n.areas&&n.areas.suggested)?n.areas.suggested:[];t.areaDraftIsNew=!1,t.areaSelectedId=r[0]&&r[0].id?r[0].id:""}else await $t({fresh:!0});_("Area deleted")}catch(n){t.lastError=n.message||"Failed to delete area",_(t.lastError)}finally{t.areaSaving=!1}}}async function Yr(){const s=Mt.value;if(!s||!t.selectedNodeId){t.testPlanCatalog=null,t.testPlanCatalogError="";return}t.testPlanCatalogLoading=!0,t.testPlanCatalogError="";try{const n=await q(O("test-plans/catalog"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:s.id})});t.testPlanCatalog=n&&n.catalog?n.catalog:null,n&&n.testPlans&&(t.stateData=Object.assign({},t.stateData||{},{testPlans:n.testPlans}))}catch(n){t.testPlanCatalog=null,t.testPlanCatalogError=n.message||"Failed to load area command/status catalog"}finally{t.testPlanCatalogLoading=!1}}async function La(){if(!(!t.selectedNodeId||t.gaCatalogLoading)){t.gaCatalogLoading=!0;try{const s=await q(O("areas/catalog"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId})});t.gaCatalog=Array.isArray(s&&s.gaCatalog)?s.gaCatalog:[]}catch(s){t.lastError=s.message||"Failed to load GA catalog",_(t.lastError)}finally{t.gaCatalogLoading=!1}}}function Ql(s){const n=String(s||"").trim();n&&((t.areaDraftGaList||[]).includes(n)||(t.areaDraftGaList=[...t.areaDraftGaList||[],n]))}function Qr(s){const n=String(s||"").trim().toLowerCase(),r=l.find(u=>u.value===n);return r?r.label:n==="auto"?"Auto":"Command"}function ei(s){const n=s&&typeof s=="object"?s:{},r=String(n.path||n.name||"Area").trim(),u=String(n.kind||"").trim(),g=Number(n.gaCount||0),C=Number(n.activeGaCount||0),N=[u,`${g} GA`,`active ${C}`].filter(Boolean).join(" | ");return N?`${r} ${N}`:r}function ed(s){const n=s&&typeof s=="object"?s:null;!n||!n.id||(t.areaDraftIsNew=!1,t.showAiAreaBuilder=!1,t.areaBuilderFocus=!1,t.areaSelectedId=n.id,t.areaSearch="",t.areaSearchOpen=!1)}function td(){setTimeout(()=>{t.areaSearchOpen=!1},150)}function ti(s){const n=s&&typeof s=="object"?s:{},r=String(n.name||"Plan").trim(),u=String(n.areaName||n.areaId||"").trim(),g=Number(n.steps&&n.steps.length?n.steps.length:0),C=[u,`${g} steps`].filter(Boolean).join(" | ");return C?`${r} ${C}`:r}function ad(s){const n=s&&typeof s=="object"?s:null;!n||!n.id||(Dd(n),t.testPlanSearch="",t.testPlanSearchOpen=!1)}function nd(){setTimeout(()=>{t.testPlanSearchOpen=!1},150)}function sd(){return X(F.value,"en")}function rd(s){const n=String(s||"").trim();n&&(t.areaDraftGaList=(t.areaDraftGaList||[]).filter(r=>r!==n))}async function id(s,n){const r=String(s||"").trim();if(!(!t.selectedNodeId||!r||t.areaGaRoleSavingGa===r)){t.areaGaRoleSavingGa=r,_(`Saving role for ${r}...`);try{const u=await q(O("areas/ga-role/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,ga:r,role:n})});Array.isArray(u&&u.gaCatalog)&&(t.gaCatalog=u.gaCatalog),u&&u.areas&&(t.stateData=Object.assign({},t.stateData||{},{areas:u.areas})),Mt.value&&Array.isArray(Mt.value.gaList)&&Mt.value.gaList.includes(r)&&await Yr(),_(`Role saved for ${r}`)}catch(u){t.lastError=u.message||"Failed to save GA role",_(t.lastError)}finally{t.areaGaRoleSavingGa=""}}}function od(){t.activeTab="areas",t.areaDraftIsNew=!0,t.areaSelectedId="",t.areaDraftId="",t.areaDraftName="New Area",t.areaDraftDescription="",t.areaDraftTags="",t.areaDraftGaList=[],t.areaLlmPrompt="",t.areaLlmError="",t.showAiAreaBuilder=!1,t.areaBuilderFocus=!1}async function ld(){const s=String(t.selectedNodeId||"").trim();if(!(t.areaLlmRegenerating||t.areaLlmBulkDeleting)){if(!s){t.areaLlmError="Select a KNX AI node first",_(t.areaLlmError);return}t.areaLlmRegenerating=!0,t.areaLlmError="",_("Regenerating AI areas...");try{const n=await q(O("areas/regenerate-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:s})}),r=Array.isArray(n&&n.gaCatalog);if(r&&(t.gaCatalog=n.gaCatalog),n&&(n.areas||n.profiles||n.actuatorTests||n.testPlans)){const u=Object.assign({},t.stateData||{});n.areas&&(u.areas=n.areas),n.profiles&&(u.profiles=n.profiles),n.actuatorTests&&(u.actuatorTests=n.actuatorTests),n.testPlans&&(u.testPlans=n.testPlans),t.stateData=u}else await $t({fresh:!0});r||await La(),_(`AI areas regenerated (${Number(n&&n.generatedCount?n.generatedCount:0)})`)}catch(n){t.areaLlmError=n.message||"Failed to regenerate AI areas",_(t.areaLlmError)}finally{t.areaLlmRegenerating=!1}}}async function dd(){const s=String(t.selectedNodeId||"").trim();if(t.areaLlmRegenerating||t.areaLlmBulkDeleting)return;if(!s){t.areaLlmError="Select a KNX AI node first",_(t.areaLlmError);return}const n=Number(Er.value||0);if(n<=0){_("No AI areas to delete");return}if(window.confirm(`Delete all AI-generated areas (${n})?`)){t.areaLlmBulkDeleting=!0,t.areaLlmError="",_("Deleting AI areas...");try{const u=await q(O("areas/delete-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:s})});if(Array.isArray(u&&u.gaCatalog)&&(t.gaCatalog=u.gaCatalog),u&&(u.areas||u.profiles||u.actuatorTests||u.testPlans)){const g=Object.assign({},t.stateData||{});u.areas&&(g.areas=u.areas),u.profiles&&(g.profiles=u.profiles),u.actuatorTests&&(g.actuatorTests=u.actuatorTests),u.testPlans&&(g.testPlans=u.testPlans),t.stateData=g}else await $t({fresh:!0});Array.isArray(u&&u.gaCatalog)||await La(),_(`AI areas deleted (${Number(u&&u.deletedCount?u.deletedCount:n)})`)}catch(u){t.areaLlmError=u.message||"Failed to delete AI areas",_(t.areaLlmError)}finally{t.areaLlmBulkDeleting=!1}}}async function cd(){if(!t.selectedNodeId||t.areaLlmBusy)return;const s=String(t.areaLlmPrompt||"").trim();if(s){t.areaLlmBusy=!0,t.areaLlmError="",_("AI is selecting area GA...");try{const n=await q(O("areas/suggest-llm"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,prompt:s,name:t.areaDraftName,description:t.areaDraftDescription,gaList:t.areaDraftGaList||[]})}),r=n&&n.suggestion?n.suggestion:null;if(Array.isArray(n&&n.gaCatalog)&&(t.gaCatalog=n.gaCatalog),!r||!Array.isArray(r.gaList)||!r.gaList.length)throw new Error("The AI did not return any group addresses");!String(t.areaDraftName||"").trim()&&r.name&&(t.areaDraftName=String(r.name)),!String(t.areaDraftDescription||"").trim()&&r.description&&(t.areaDraftDescription=String(r.description)),(!t.areaDraftTags||!String(t.areaDraftTags).trim())&&Array.isArray(r.tags)&&r.tags.length&&(t.areaDraftTags=r.tags.join(", ")),t.areaDraftGaList=Array.from(new Set([...t.areaDraftGaList||[],...r.gaList.map(u=>String(u||"").trim()).filter(Boolean)])),t.showAiAreaBuilder=!1,t.areaBuilderFocus=!1,_(`AI added ${Number(r.gaList.length||0)} GA to the draft`)}catch(n){t.areaLlmError=n.message||"Failed to suggest area GA",_(t.areaLlmError)}finally{t.areaLlmBusy=!1}}}function ud(s){if(s&&typeof s=="object"){t.testPlanPrompt=String(s.prompt||"").trim();return}t.testPlanPrompt=String(s||"").trim()}function ai(s){const n=String(s||"").trim();return n&&(Array.isArray(t.testPlanCatalog&&t.testPlanCatalog.pairs)?t.testPlanCatalog.pairs:[]).find(u=>u&&u.command&&u.command.ga===n)||null}function ni(s){const n=String(s||"").trim();return Ts.value.find(r=>r&&r.ga===n)||null}function fd(s){const n=String(s||"").trim();return Or.value.find(r=>r&&r.ga===n)||null}function da(s){const n=String(s||"").trim();if(!n)return[];const r=t.testPlanCatalog&&t.testPlanCatalog.dptOptionsById&&typeof t.testPlanCatalog.dptOptionsById=="object"?t.testPlanCatalog.dptOptionsById:{};return Array.isArray(r[n])?r[n]:[]}function Kt(s){return String(s||"").trim().normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}const pd=[{type:"on",patterns:[/\bturn on\b/g,/\bturn(?:\s+\w+){1,4}\s+on\b/g,/\bswitch on\b/g,/\bswitch(?:\s+\w+){1,4}\s+on\b/g,/\bpower on\b/g,/\bpower(?:\s+\w+){1,4}\s+on\b/g,/\bstart\b/g,/\benable\b/g,/\bactivate\b/g,/\baccendi\b/g,/\battiva\b/g,/\ballume\b/g,/\bactive\b/g,/\beinschalten\b/g,/\baktivieren\b/g,/\benciende\b/g,/\bactivar\b/g,/\bliga\b/g,/\bativa\b/g,/\baan\b/g,/\binschakelen\b/g]},{type:"off",patterns:[/\bturn off\b/g,/\bturn(?:\s+\w+){1,4}\s+off\b/g,/\bswitch off\b/g,/\bswitch(?:\s+\w+){1,4}\s+off\b/g,/\bpower off\b/g,/\bpower(?:\s+\w+){1,4}\s+off\b/g,/\bdisable\b/g,/\bdeactivate\b/g,/\bshutdown\b/g,/\bspegni\b/g,/\bdisattiva\b/g,/\beteins\b/g,/\bdesactive\b/g,/\bausschalten\b/g,/\bdeaktivieren\b/g,/\bapaga\b/g,/\bdesactiva\b/g,/\bdesliga\b/g,/\bdesativa\b/g,/\buit\b/g,/\buitschakelen\b/g]},{type:"open",patterns:[/\bopen\b/g,/\braise\b/g,/\blift\b/g,/\bmove up\b/g,/\bapri\b/g,/\balza\b/g,/\bsolleva\b/g,/\bouvre\b/g,/\bmonte\b/g,/\boffnen\b/g,/\bhoch\b/g,/\bauf\b/g,/\babre\b/g,/\bsube\b/g,/\babrir\b/g,/\bsobe\b/g,/\bopenen\b/g,/\bomhoog\b/g]},{type:"close",patterns:[/\bclose\b/g,/\blower\b/g,/\bmove down\b/g,/\bchiudi\b/g,/\babbassa\b/g,/\bferme\b/g,/\bdescends?\b/g,/\bschliessen\b/g,/\brunter\b/g,/\bzu\b/g,/\bcierra\b/g,/\bbaja\b/g,/\bfechar\b/g,/\bdesce\b/g,/\bsluiten\b/g,/\bomlaag\b/g]},{type:"stop",patterns:[/\bstop\b/g,/\bhalt\b/g,/\bpause\b/g,/\bferma\b/g,/\barresta\b/g,/\barrete\b/g,/\bstoppe\b/g,/\banhalten\b/g,/\bstopp\b/g,/\bdeten\b/g,/\bparar\b/g,/\bpare\b/g,/\bstoppen\b/g]}];function gd(s){const n=Kt(s);if(!n)return"";const r=[];return pd.forEach(u=>{u.patterns.forEach(g=>{g.lastIndex=0;let C;for(;(C=g.exec(n))!==null;)r.push({type:u.type,index:C.index})})}),r.sort((u,g)=>u.index-g.index),r[0]?r[0].type:""}function hd(s){return["on","open"].includes(String(s||"").trim().toLowerCase())}function md(s){return["off","close","stop"].includes(String(s||"").trim().toLowerCase())}function Os(s,n,r=""){const u=da(n);if(!u.length)return String(s??"");const g=String(s??"").trim(),C=Kt(g),N=Kt(r),M=`${C} ${N}`.trim(),$=gd(r||M);if($){if(hd($)){const ee=u.find(me=>["true","1","100"].includes(String(me.value)));if(ee)return String(ee.value);const ae=u.find(me=>/\b(on|open|up|start|enable|enabled|active|acceso|accesa|aperto|aperta|su|einschalten|allume|enciende|liga|aan)\b/.test(Kt(me.label)));if(ae)return String(ae.value)}if(md($)){const ee=u.find(me=>["false","0"].includes(String(me.value)));if(ee)return String(ee.value);const ae=u.find(me=>/\b(off|close|down|stop|disable|disabled|inactive|chiuso|spento|giu|ausschalten|eteins|apaga|desliga|uit)\b/.test(Kt(me.label)));if(ae)return String(ae.value)}}if(u.some(ee=>String(ee.value)===g))return g;const te=u.find(ee=>Kt(ee.label)===C);if(te)return String(te.value);const Z=u.find(ee=>{const ae=Kt(ee.label);return C&&(ae.includes(C)||C.includes(ae))});if(Z)return String(Z.value);const pe=/\b(on|open|up|true|1|accendi|attiva|apri|su|acceso|accesa|accesi|accese|aperto|aperta|enabled|enable|start|allume|einschalten|enciende|liga|aan)\b/,Q=/\b(off|close|down|false|0|spegni|disattiva|chiudi|giu|spento|spenta|spenti|spente|chiuso|chiusa|disabled|disable|stop|ferma|eteins|ausschalten|apaga|desliga|uit)\b/;if(pe.test(M)){const ee=u.find(me=>["true","1","100"].includes(String(me.value)));if(ee)return String(ee.value);const ae=u.find(me=>/\b(on|open|up|start|enable|enabled|active|acceso|accesa|aperto|aperta|su)\b/.test(Kt(me.label)));if(ae)return String(ae.value)}if(Q.test(M)){const ee=u.find(me=>["false","0"].includes(String(me.value)));if(ee)return String(ee.value);const ae=u.find(me=>/\b(off|close|down|stop|disable|disabled|inactive|spento|spenta|chiuso|chiusa|giu)\b/.test(Kt(me.label)));if(ae)return String(ae.value)}return String(u[0].value)}function zn(s){if(!s)return;const n=da(s.commandDPT),r=da(s.statusDPT||s.commandDPT),u=String(s.action||"").trim().toLowerCase();n.length&&(s.commandPayload=Os(s.commandPayload,s.commandDPT,u||`${s.title||""} ${s.description||""} ${s.reason||""}`)),r.length&&(s.expectedPayload=Os(s.expectedPayload,s.statusDPT||s.commandDPT,u||`${s.title||""} ${s.description||""} ${s.reason||""}`))}function Ms(s={}){if(String(s.kind||"").trim().toLowerCase()==="wait")return{id:String(s.id||`step-${Date.now()}-${Math.round(Math.random()*1e3)}`),kind:"wait",action:"",collapsed:s.collapsed!==!1,title:String(s.title||"Wait"),description:String(s.description||""),reason:String(s.reason||""),delayMs:Number(s.delayMs||s.readDelayMs||1200),commandGA:"",commandDPT:"",commandPayload:"",statusGA:"",statusDPT:"",expectedPayload:"",statusWriteTimeoutMs:0,statusResponseTimeoutMs:0};const r=String(s.commandGA||"").trim()||String(Ts.value[0]?.ga||""),u=ai(r),g=ni(r),C=u&&u.status?u.status:null,N={id:String(s.id||`step-${Date.now()}-${Math.round(Math.random()*1e3)}`),kind:String(s.kind||(C?"write_and_verify":"write_only")),action:String(s.action||"").trim().toLowerCase(),collapsed:s.collapsed!==!1,title:String(s.title||(g?`Step ${g.label}`:"Manual Step")),description:String(s.description||""),reason:String(s.reason||""),commandGA:r,commandDPT:String(s.commandDPT||g?.dpt||""),commandPayload:String(s.commandPayload??""),statusGA:String(s.statusGA||C?.ga||""),statusDPT:String(s.statusDPT||C?.dpt||""),expectedPayload:String(s.expectedPayload??s.commandPayload??""),statusWriteTimeoutMs:Number(s.statusWriteTimeoutMs||s.timeoutMs||5e3),statusResponseTimeoutMs:Number(s.statusResponseTimeoutMs||s.timeoutMs||5e3)};return zn(N),N}function On(s){const n=Ot(s,null);return n?(n.steps=(Array.isArray(n.steps)?n.steps:[]).map(r=>Ms(r)),n):null}function vd(){return On({id:"",name:"",description:"",areaId:dt.value?String(dt.value.id||""):"",areaName:dt.value?String(dt.value.path||dt.value.name||""):"",prompt:"",source:"manual",generatedAt:new Date().toISOString(),steps:[]})}function si(s){if(!s||s.kind==="wait")return;const n=ni(s.commandGA),r=fd(s.statusGA),u=ai(s.commandGA);n&&(s.commandDPT=String(n.dpt||"")),r&&(s.statusDPT=String(r.dpt||"")),u&&u.status&&(!s.statusGA||s.statusGA==="")&&(s.statusGA=String(u.status.ga||""),s.statusDPT=String(u.status.dpt||""),s.kind="write_and_verify"),s.statusGA&&(s.kind="write_and_verify"),s.expectedPayload||(s.expectedPayload=String(s.commandPayload??"")),s.statusGA||(s.statusDPT="",s.kind="write_only"),zn(s)}function bd(){if(!t.testPlanDraft)return;const s={id:`step-${Date.now()}-${Math.round(Math.random()*1e3)}`,kind:"write_only",action:"",collapsed:!0,title:"Manual Step",description:"",reason:"",commandGA:"",commandDPT:"",commandPayload:"",statusGA:"",statusDPT:"",expectedPayload:"",statusWriteTimeoutMs:5e3,statusResponseTimeoutMs:5e3};t.testPlanDraft.steps=[...t.testPlanDraft.steps||[],s]}function yd(){if(!t.testPlanDraft)return;const s=Ms({id:`wait-${(t.testPlanDraft.steps?.length||0)+1}`,kind:"wait",title:"Wait",description:"Pause the test before the next action.",delayMs:1200});t.testPlanDraft.steps=[...t.testPlanDraft.steps||[],s]}function Ad(s){if(!t.testPlanDraft||!Array.isArray(t.testPlanDraft.steps))return;const n=t.testPlanDraft.steps[s];if(!n)return;const r=Ms(Object.assign({},n,{id:`${n.id||"step"}-copy`}));t.testPlanDraft.steps.splice(s+1,0,r)}function Sd(s){!t.testPlanDraft||!Array.isArray(t.testPlanDraft.steps)||t.testPlanDraft.steps.splice(s,1)}function wd(s){s&&(s.collapsed=s.collapsed!==!0)}function Bs(){t.draggedTestPlanStepId="",t.dragOverTestPlanStepId=""}function Td(s,n){const r=String(s||"").trim();r&&(t.draggedTestPlanStepId=r,t.dragOverTestPlanStepId="",n&&n.dataTransfer&&(n.dataTransfer.effectAllowed="move",n.dataTransfer.setData("text/plain",r)))}function Pd(s){const n=String(s||"").trim();!n||!t.draggedTestPlanStepId||n===t.draggedTestPlanStepId||(t.dragOverTestPlanStepId=n)}function _d(s,n){if(!t.testPlanDraft||!Array.isArray(t.testPlanDraft.steps))return;const r=String(s||"").trim(),u=String(n||"").trim();if(!r||!u||r===u)return;const g=t.testPlanDraft.steps.slice(),C=g.findIndex($=>String($&&$.id?$.id:"")===r),N=g.findIndex($=>String($&&$.id?$.id:"")===u);if(C===-1||N===-1)return;const[M]=g.splice(C,1);g.splice(N,0,M),t.testPlanDraft.steps=g}function Cd(s,n){n&&n.preventDefault();const r=String(t.draggedTestPlanStepId||"").trim(),u=String(s||"").trim();r&&u&&r!==u&&_d(r,u),Bs()}function Id(){!t.testPlanDraft||t.testPlanRunning||(t.testPlanRunMode="single",t.testPlanRepeatStopRequested=!1,t.testPlanRunConfirmOpen=!0)}function Nd(){!t.testPlanDraft||t.testPlanRunning||(t.testPlanRunMode="repeat",t.testPlanRepeatStopRequested=!1,t.testPlanRunConfirmOpen=!0)}function ri(){t.testPlanRunConfirmOpen=!1,t.testPlanRunMode="single"}function Rd(){t.testPlanRepeatForever===!0&&(t.testPlanRepeatStopRequested=!0,_("Stopping repeat mode after the current cycle..."))}function ii(s=null){const n=s||oa.value;n&&(t.testResultFocusMode=!1,t.testPlanSelectedId=String(n.id||""),t.testPlanDraft=On(n),t.testPlanPrompt=String(n.prompt||""),t.testPlanGeneration={provider:String(n.source||"saved"),model:"",fallback:!1,error:""},t.testPlanRunConfirmOpen=!1,t.showAiPlanner=!1,t.testTemplateBuilderFocus=!1,Ea())}function $s(){Ft=null,t.testPlanPendingActionLabel=""}function oi(){t.testPlanUnsavedConfirmOpen=!1,$s()}function li(){const s=Ft;t.testPlanUnsavedConfirmOpen=!1,$s(),typeof s=="function"&&s()}function Ks(s,n="another plan"){if(!Br.value){s();return}Ft=s,t.testPlanPendingActionLabel=String(n||"another plan"),t.testPlanUnsavedConfirmOpen=!0}function Dd(s){if(!s||!s.id)return;const n=String(s.id);t.testPlanSelectedId!==n&&Ks(()=>ii(s),`plan "${s.name||n}"`)}function kd(){cl(),_("Plan changes discarded")}async function xd(){await ci()&&li()}function di(){if(!Ae.value.length){_("Define at least one area before creating a test plan");return}Ks(()=>{t.activeTab="tests",t.testResultFocusMode=!1,t.testPlanSelectedId="",t.testPlanDraft=vd(),t.testPlanGeneration=null,t.testPlanRunConfirmOpen=!1,t.testPlanPrompt="",t.showAiPlanner=!1,t.testTemplateBuilderFocus=!1,Ea()},"a new plan")}function Ed(s){const n=String(s||"").trim();if(!n)return;const r=Ae.value.find(u=>u&&u.id===n);r&&(t.testAreaSelectedId=n,t.testPlanDraft&&(t.testPlanDraft.areaId=n,t.testPlanDraft.areaName=String(r.path||r.name||"")))}function Ld(){const s=Ot(t.testPlanDraft||oa.value,null);s&&(t.activeTab="tests",t.testResultFocusMode=!1,t.testPlanSelectedId="",t.testPlanRunConfirmOpen=!1,t.testPlanGeneration={provider:"duplicated",model:"",fallback:!1,error:""},s.id="",s.name=String(s.name||"Plan Draft").trim()?`${String(s.name||"Plan Draft").trim()} Copy`:"Plan Copy",t.testPlanPrompt=String(s.prompt||t.testPlanPrompt||""),t.testPlanDraft=On(s),t.showAiPlanner=!0,t.testTemplateBuilderFocus=!1,Ea(),_("Plan duplicated"))}async function Gd(){const s=dt.value,n=String(t.testPlanPrompt||"").trim(),r=sd();if(!(!t.selectedNodeId||!s||!n||t.testPlanGenerating)){t.testPlanGenerating=!0,t.testTemplateBuilderFocus=!1,t.showAiPlanner=!1,t.testResultFocusMode=!1,t.testPlanGenerationError="",_("Building test plan...");try{const u=await q(O("test-plans/generate"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:s.id,prompt:n,language:r})});t.testPlanDraft=u&&u.plan?On(u.plan):null,t.testPlanCatalog=u&&u.catalog?u.catalog:t.testPlanCatalog,t.testPlanGeneration=u&&u.generation?u.generation:null,t.testPlanGenerationError="",t.testPlanSelectedId="",t.testPlanRunConfirmOpen=!1,t.showAiPlanner=!1,u&&u.testPlans&&(t.stateData=Object.assign({},t.stateData||{},{testPlans:u.testPlans})),Ea(),_("Test plan ready")}catch(u){const g=u.message||"Failed to build the test plan";t.lastError=g,t.testPlanGenerationError=g,t.testPlanGeneration={provider:"",model:"",fallback:!1,error:g},_(g)}finally{t.testPlanGenerating=!1}}}async function ci(){if(!t.selectedNodeId||!t.testPlanDraft||t.testPlanSaving)return!1;t.testPlanSaving=!0,_("Saving test plan...");try{const s=await q(O("test-plans/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,plan:Object.assign({},t.testPlanDraft,{prompt:t.testPlanPrompt})})});return s&&s.testPlans&&(t.stateData=Object.assign({},t.stateData||{},{testPlans:s.testPlans})),s&&s.planId&&(t.testPlanSelectedId=s.planId),s&&s.planId&&t.testPlanDraft&&(t.testPlanDraft.id=s.planId),t.testPlanRunConfirmOpen=!1,Ea(),_("Test plan saved"),!0}catch(s){return t.lastError=s.message||"Failed to save test plan",_(t.lastError),!1}finally{t.testPlanSaving=!1}}async function Fd(){const s=oa.value;if(!(!s||!t.selectedNodeId||t.testPlanDeleting)){t.testPlanDeleting=!0,_("Deleting test plan...");try{const n=await q(O("test-plans/delete"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,planId:s.id})});n&&n.testPlans&&(t.stateData=Object.assign({},t.stateData||{},{testPlans:n.testPlans})),t.testPlanDraft=null,t.testPlanGeneration=null,t.testPlanRunConfirmOpen=!1,t.showAiPlanner=!0,t.testTemplateBuilderFocus=!1,Ea(),_("Test plan deleted")}catch(n){t.lastError=n.message||"Failed to delete test plan",_(t.lastError)}finally{t.testPlanDeleting=!1}}}async function zd(s="single"){if(!t.selectedNodeId||!t.testPlanDraft||t.testPlanRunning)return;const r=String(s||t.testPlanRunMode||"single").trim().toLowerCase()==="repeat";t.testPlanRunning=!0,t.showAiPlanner=!1,t.testTemplateBuilderFocus=!1,t.testPlanRepeatForever=r,t.testPlanRepeatStopRequested=!1,t.testPlanRunningStepId="",t.testPlanRunConfirmOpen=!1,t.lastError="",_(r?"Running test plan in repeat mode...":"Running test plan...");try{const u=JSON.parse(JSON.stringify(Object.assign({},t.testPlanDraft,{prompt:t.testPlanPrompt}))),g=Array.isArray(u.steps)?u.steps:[];if(!u.areaId)throw new Error("Missing areaId in test plan");if(!g.length)throw new Error("The test plan has no executable steps");let C=dt.value,N=0;do{N+=1;const $=`${u.id||"plan"}:${Date.now()}`,te=[];t.liveTestResultId=$,t.testResultsMenuOpen=!0,Fn($,{openMenu:!0,activateResultsTab:!0,resultOnly:!0}),t.stateData=Object.assign({},t.stateData||{},{testPlanReport:Rs({plan:u,area:C,stepResults:[],reportId:$})});try{await Hr(u.name||"Test plan",u.description||"")}catch{}for(let pe=0;pe<g.length;pe+=1){const Q=g[pe];t.testPlanRunningStepId=Q&&Q.id?Q.id:"";const ee=r?`Cycle ${N} · `:"";_(`${ee}Step ${pe+1}/${g.length}: ${Q&&Q.title?Q.title:"Running..."}`);try{await Fl(Q||{title:`Step ${pe+1}`},pe+1)}catch{_(`Voice unavailable for step ${pe+1}. Continuing test...`)}try{const ae=await q(O("test-plans/run-step"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,areaId:u.areaId,step:Q})});ae&&ae.area&&(C=ae.area),te.push(ae&&ae.stepResult?ae.stepResult:jr(Q,new Error("Step returned no result")))}catch(ae){te.push(jr(Q,ae))}t.stateData=Object.assign({},t.stateData||{},{testPlanReport:Rs({plan:u,area:C,stepResults:te.slice(),reportId:$})})}const Z=Rs({plan:u,area:C,stepResults:te,reportId:$});t.stateData=Object.assign({},t.stateData||{},{testPlans:At.value,testPlanReport:Z}),Fn($,{openMenu:!0,activateResultsTab:!0,resultOnly:!0});try{await Hl(Z)}catch(pe){t.lastError=pe.message||"Failed to save test result",_(`Test completed, but the result was not saved: ${t.lastError}`)}r&&t.testPlanRepeatStopRequested!==!0&&(t.testResultFocusMode=!1,_(`Cycle ${N} completed. Starting the next cycle...`))}while(r&&t.testPlanRepeatStopRequested!==!0);const M=r?"Repeat mode stopped":"Test completed";t.testPlanRunConfirmOpen=!1,t.lastError||_(M);try{await Hr(Be(M))}catch{}requestAnimationFrame(()=>{try{tt.value&&typeof tt.value.scrollIntoView=="function"&&tt.value.scrollIntoView({behavior:"smooth",block:"start"})}catch{}})}catch(u){t.lastError=u.message||"Failed to run test plan",_(t.lastError)}finally{t.testPlanRunningStepId="",ra(),t.testPlanRunning=!1,t.testPlanRepeatForever=!1,t.testPlanRepeatStopRequested=!1,t.testPlanRunMode="single"}}async function Od(){if(t.selectedNodeId){_("Exporting config...");try{const s=await q(O("config/export"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId})}),n=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),r=window.URL.createObjectURL(n),u=document.createElement("a");u.href=r,u.download=`knx-ai-config-${t.selectedNodeId}.json`,document.body.appendChild(u),u.click(),document.body.removeChild(u),window.URL.revokeObjectURL(r),_("Config exported")}catch(s){t.lastError=s.message||"Failed to export config",_(t.lastError)}}}function Md(){we.value&&we.value.click()}async function Bd(s){const n=s&&s.target&&s.target.files&&s.target.files[0]?s.target.files[0]:null;if(!(!n||!t.selectedNodeId)){_("Importing config...");try{const r=await n.text(),u=JSON.parse(r),g=await q(O("config/import"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:t.selectedNodeId,config:u})});t.stateData=Object.assign({},t.stateData||{},{areas:g.areas||ba.value,profiles:g.profiles||ya.value,actuatorTests:g.actuatorTests||Aa.value,testPlans:g.testPlans||At.value,testResults:g.testResults||Za.value}),await La(),_("Config imported")}catch(r){t.lastError=r.message||"Failed to import config",_(t.lastError)}finally{s&&s.target&&(s.target.value="")}}}function $d(){$e+=1,t.chatLearningContent="",t.chatLearningBaseline="",t.chatLearningRevision="",t.chatLearningName="",t.chatLearningPath="",t.chatLearningBytes=0,t.chatLearningModifiedAt="",t.chatLearningSessionCount=0,t.chatLearningLoadedNodeId="",t.chatLearningLoading=!1,t.chatLearningSaving=!1,t.chatLearningResetting=!1,t.chatLearningCopied=!1,t.chatLearningError=""}function Vs(s={},n=t.selectedNodeId){const r=String(s.content||"");t.chatLearningContent=r,t.chatLearningBaseline=r,t.chatLearningRevision=String(s.revision||""),t.chatLearningName=String(s.name||"knxai-chat-context.knxctx"),t.chatLearningPath=String(s.path||""),t.chatLearningBytes=Math.max(0,Number(s.bytes)||new Blob([r]).size),t.chatLearningMaxBytes=Math.max(1,Number(s.maxBytes)||512*1024),t.chatLearningModifiedAt=String(s.modifiedAt||s.updatedAt||""),t.chatLearningSessionCount=Math.max(0,Number(s.sessionCount)||0),t.chatLearningLoadedNodeId=n,t.chatLearningError=""}async function tn({force:s=!1}={}){if(!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting||qa.value&&!s||qa.value&&s&&!window.confirm(Be("Discard unsaved chat-learning changes and reload?")))return;const n=t.selectedNodeId,r=++$e;t.chatLearningLoading=!0,t.chatLearningError="",_("Loading chat learning...");try{const u=await q(O(`chat-learning?nodeId=${encodeURIComponent(n)}`));if(r!==$e||t.selectedNodeId!==n)return;Vs(u,n),_("Chat learning loaded")}catch(u){if(r!==$e||t.selectedNodeId!==n)return;t.chatLearningError=u.message||"Failed to load chat learning",_(t.chatLearningError)}finally{r===$e&&(t.chatLearningLoading=!1)}}async function Kd(){if(!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting||!qa.value||Ss.value)return;const s=t.selectedNodeId,n=++$e;t.chatLearningSaving=!0,t.chatLearningError="",_("Saving chat learning...");try{const r=await q(O("chat-learning/save"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:s,content:t.chatLearningContent,revision:t.chatLearningRevision})});if(n!==$e||t.selectedNodeId!==s)return;Vs(r,s),_("Chat learning saved")}catch(r){if(n!==$e||t.selectedNodeId!==s)return;t.chatLearningError=r.message||"Failed to save chat learning",_(t.chatLearningError)}finally{n===$e&&(t.chatLearningSaving=!1)}}async function Vd(){if(!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting||!window.confirm(Be("This permanently deletes all saved AI Chat Learning sessions, instructions and camera watches, and discards unsaved editor changes. Reinitialize memory from zero?")))return;const n=t.selectedNodeId,r=++$e;t.chatLearningResetting=!0,t.chatLearningError="",_("Reinitializing chat learning...");try{const u=await q(O("chat-learning/reset"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({nodeId:n,revision:t.chatLearningRevision})});if(r!==$e||t.selectedNodeId!==n)return;Vs(u,n),_("Chat learning reinitialized")}catch(u){if(r!==$e||t.selectedNodeId!==n)return;t.chatLearningError=u.message||"Failed to reinitialize chat learning",_(t.chatLearningError)}finally{r===$e&&(t.chatLearningResetting=!1)}}async function jd(){if(t.chatLearningContent)try{await Zr(t.chatLearningContent),t.chatLearningCopied=!0,t.chatLearningError="",_("Chat-learning file copied to clipboard"),setTimeout(()=>{t.chatLearningCopied=!1},2500)}catch(s){t.chatLearningError=s.message||"Could not copy to clipboard",_(t.chatLearningError)}}function Ud(){if(!t.chatLearningContent)return;const s=new Blob([t.chatLearningContent],{type:"text/plain;charset=utf-8"}),n=window.URL.createObjectURL(s),r=document.createElement("a");r.href=n,r.download=t.chatLearningName||"knxai-chat-context.knxctx",document.body.appendChild(r),r.click(),document.body.removeChild(r),window.URL.revokeObjectURL(n),_("Chat-learning backup downloaded")}function Wd(){he.value&&he.value.click()}async function Hd(s){const n=s&&s.target&&s.target.files&&s.target.files[0]?s.target.files[0]:null;if(n)try{const r=await n.text();if(new Blob([r]).size>t.chatLearningMaxBytes)throw new Error("Chat-learning backup exceeds the file-size limit");t.chatLearningContent=r,t.chatLearningError="",_("Chat-learning backup loaded; review it and save to apply it.")}catch(r){t.chatLearningError=r.message||"Failed to load chat-learning backup",_(t.chatLearningError)}finally{s&&s.target&&(s.target.value="")}}function Xd(){t.pollStateHandle||(t.pollStateHandle=window.setInterval(()=>{t.autoRefresh&&$t({fresh:!1})},1500)),t.pollNodesHandle||(t.pollNodesHandle=window.setInterval(()=>{Es({preserveSelection:!0})},15e3))}function qd(){t.pollStateHandle&&(window.clearInterval(t.pollStateHandle),t.pollStateHandle=null),t.pollNodesHandle&&(window.clearInterval(t.pollNodesHandle),t.pollNodesHandle=null)}return Eo(async()=>{F.value=Ee(),P(),window.addEventListener("resize",P),document.addEventListener("keydown",D),document.addEventListener("fullscreenchange",j),await Es({preserveSelection:!1}),await $t({fresh:!0}),await La(),t.settingsTab==="learning"&&await tn(),Xd(),Da()}),Lo(()=>{window.removeEventListener("resize",P),document.removeEventListener("keydown",D),document.removeEventListener("fullscreenchange",j),ma(),qd(),ra()}),(s,n)=>(v(),b(J,null,[o("header",Nf,[n[49]||(n[49]=o("div",{class:"m-header-brand"},[o("span",{class:"m-logo-mark"},"K"),o("span",{class:"hb-logo-text-mobile"},"KNX AI")],-1)),o("button",{class:le(["hamburger-icon",{"hamburger-icon-cross":ot.value}]),type:"button","aria-expanded":ot.value?"true":"false","aria-controls":"knx-ai-sidebar","aria-label":"Toggle menu",onClick:x},[...n[48]||(n[48]=[o("span",null,null,-1),o("span",null,null,-1),o("span",null,null,-1),o("span",null,null,-1)])],10,Rf)]),Ge.value&&ot.value?(v(),b("button",{key:0,class:"sidebar-overlay",type:"button","aria-label":"Close menu",onClick:k})):E("",!0),o("div",{class:le(["page-shell",{"sidebar-collapsed":!ot.value,"sidebar-mobile-open":Ge.value&&ot.value}])},[o("aside",Df,[o("div",kf,[n[50]||(n[50]=o("div",{class:"sidebar-brand-mark","aria-hidden":"true"},"K",-1)),n[51]||(n[51]=o("div",{class:"sidebar-brand"},[o("p",{class:"eyebrow"},"KNX Ultimate")],-1)),o("button",{class:"sidebar-collapse-toggle",type:"button","aria-expanded":ot.value?"true":"false","aria-controls":"knx-ai-sidebar","aria-label":"Toggle sidebar",onClick:x},[o("span",Ef,A(ot.value?Ge.value?"×":"‹":"›"),1)],8,xf)]),o("nav",Lf,[o("button",{class:le(["tab-button",{active:t.activeTab==="overview"}]),type:"button",title:"Overview","aria-label":"Overview",onClick:n[0]||(n[0]=r=>Sa("overview"))},[...n[52]||(n[52]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M3 10.8 12 3l9 7.8v9.2a1 1 0 0 1-1 1h-5v-6h-6v6H4a1 1 0 0 1-1-1z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Overview</span></span>',2)])],2),o("button",{class:le(["tab-button",{active:t.activeTab==="areas"}]),type:"button",title:"Areas","aria-label":"Areas",onClick:n[1]||(n[1]=r=>Sa("areas"))},[...n[53]||(n[53]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M3 3h8v8H3zm10 0h8v8h-8zM3 13h8v8H3zm10 0h8v8h-8z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Areas</span></span>',2)])],2),o("button",{class:le(["tab-button sidebar-nav-child",{active:t.activeTab==="tests"}]),type:"button",title:"Tests","aria-label":"Tests",disabled:!Ae.value.length,onClick:n[2]||(n[2]=r=>Sa("tests"))},[...n[54]||(n[54]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M9 3h6v2h-1v4.3l5.5 8.8A2 2 0 0 1 17.8 21H6.2a2 2 0 0 1-1.7-2.9L10 9.3V5H9zm1.9 8.2L6.9 18h10.2l-4-6.8z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Tests</span></span>',2)])],10,Gf),o("button",{class:le(["tab-button sidebar-nav-child",{active:t.activeTab==="results"}]),type:"button",title:"Test Results","aria-label":"Test Results",onClick:n[3]||(n[3]=r=>Sa("results"))},[...n[55]||(n[55]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M4 4h16v4H4zm0 6h16v4H4zm0 6h16v4H4z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Test Results</span></span>',2)])],2),o("button",{class:le(["tab-button",{active:t.activeTab==="assistant"}]),type:"button",title:"Assistant","aria-label":"Assistant",onClick:n[4]||(n[4]=r=>Sa("assistant"))},[...n[56]||(n[56]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M4 5h16a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9l-5 4v-4H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Assistant</span></span>',2)])],2),o("button",{class:le(["tab-button",{active:t.activeTab==="flowBuilder"}]),type:"button",title:"Flow Builder","aria-label":"Flow Builder",onClick:n[5]||(n[5]=r=>Sa("flowBuilder"))},[...n[57]||(n[57]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M2 5h8v4H6v2h6.2a3 3 0 0 1 2.8-2H22v4h-7a1 1 0 0 0-1 1v0a1 1 0 0 0 1 1h7v4h-7a3 3 0 0 1-2.8-2H6v2h4v4H2v-4h2v-6H2zm18 0h2v4h-2z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Flow Builder</span></span>',2)])],2),o("button",{class:le(["tab-button",{active:t.activeTab==="settings"}]),type:"button",title:"Settings","aria-label":"Settings",onClick:n[6]||(n[6]=r=>Sa("settings"))},[...n[58]||(n[58]=[fa('<span class="sidebar-nav-icon" aria-hidden="true" data-v-4f1ccfd9><svg viewBox="0 0 24 24" class="sidebar-nav-svg" data-v-4f1ccfd9><path d="M19.14 12.94a7.43 7.43 0 0 0 .05-.94 7.43 7.43 0 0 0-.05-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.18 7.18 0 0 0-1.63-.94l-.36-2.54A.5.5 0 0 0 13.9 2h-3.8a.5.5 0 0 0-.49.42l-.36 2.54a7.18 7.18 0 0 0-1.63.94l-2.39-.96a.5.5 0 0 0-.6.22L2.71 8.48a.5.5 0 0 0 .12.64l2.03 1.58a7.43 7.43 0 0 0-.05.94 7.43 7.43 0 0 0 .05.94l-2.03 1.58a.5.5 0 0 0-.12.64l1.92 3.32a.5.5 0 0 0 .6.22l2.39-.96c.5.39 1.04.71 1.63.94l.36 2.54a.5.5 0 0 0 .49.42h3.8a.5.5 0 0 0 .49-.42l.36-2.54c.59-.23 1.13-.55 1.63-.94l2.39.96a.5.5 0 0 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.64zM12 15.2A3.2 3.2 0 1 1 12 8.8a3.2 3.2 0 0 1 0 6.4z" data-v-4f1ccfd9></path></svg></span><span class="sidebar-nav-copy" data-v-4f1ccfd9><span class="sidebar-nav-title" data-v-4f1ccfd9>Settings</span></span>',2)])],2)]),ot.value?(v(),b("div",Ff,[o("button",{class:"primary-button sidebar-action-button",type:"button",disabled:t.loadingNodes||t.loadingState,onClick:Ol}," Refresh ",8,zf),o("div",{class:"support-link-row"},[o("a",{class:"secondary-button support-link-button",href:jy,target:"_blank",rel:"noopener noreferrer"}," Donate via PayPal "),o("a",{class:"secondary-button support-link-button support-link-button-youtube",href:Uy,target:"_blank",rel:"noopener noreferrer"}," Subscribe ")])])):E("",!0),ot.value?(v(),b("div",Of,[o("span",{class:le(["status-pill",{error:!!t.lastError}])},[t.loadingNodes||t.loadingState||t.areaLlmRegenerating||t.areaLlmBulkDeleting||t.areaLlmBusy||t.testPlanGenerating||t.asking?(v(),b("span",Mf)):E("",!0),o("span",null,A(t.status),1)],2),xn.value?(v(),b("span",Bf,"Provider: "+A(xn.value.llmProvider||"n/a")+" | Model: "+A(xn.value.llmModel||"n/a"),1)):E("",!0),o("a",{class:"sidebar-doc-link",href:Vy,target:"_blank",rel:"noopener noreferrer"}," Documentation: KNX AI Vue ")])):E("",!0)]),o("section",$f,[o("main",Kf,[t.activeTab==="overview"?(v(),b("section",Vf,[o("div",jf,[n[59]||(n[59]=o("h2",null,"Summary",-1)),Fe.value.meta?.generatedAt?(v(),b("span",Uf,A(yt(Fe.value.meta.generatedAt)),1)):E("",!0)]),o("pre",Wf,A(Cl.value),1),o("div",Hf,[o("article",Xf,[n[60]||(n[60]=o("span",null,"Telegrams",-1)),o("strong",null,A(Number(Fe.value.counters?.telegrams||0)),1)]),o("article",qf,[n[61]||(n[61]=o("span",null,"Rate",-1)),o("strong",null,A(Number(Fe.value.counters?.overallRatePerSec||0))+"/s",1)]),o("article",Jf,[n[62]||(n[62]=o("span",null,"Repeat",-1)),o("strong",null,A(Number(Fe.value.counters?.repeated||0)),1)]),o("article",Zf,[n[63]||(n[63]=o("span",null,"Unknown DPT",-1)),o("strong",null,A(Number(Fe.value.counters?.unknownDpt||0)),1)])])])):E("",!0),t.activeTab==="areas"?(v(),b("section",Yf,[o("div",Qf,[n[64]||(n[64]=o("h2",null,"Select an Area",-1)),o("div",ep,[o("span",tp,A(Number(Ja.value.suggestedAreaCount||0))+" areas",1),o("button",{class:"secondary-button",type:"button",disabled:t.areaLlmRegenerating||t.areaLlmBulkDeleting||!pt.value.llmEnabled,onClick:ld},[t.areaLlmRegenerating?(v(),b("span",np)):E("",!0),o("span",null,A(t.areaLlmRegenerating?"Regenerating...":"Regenerate AI Areas"),1)],8,ap),o("button",{class:"danger-button",type:"button",disabled:t.areaLlmRegenerating||t.areaLlmBulkDeleting||Er.value<=0,onClick:dd},[t.areaLlmBulkDeleting?(v(),b("span",rp)):E("",!0),o("span",null,A(t.areaLlmBulkDeleting?"Deleting...":"Delete AI Areas"),1)],8,sp),o("button",{class:"secondary-button new-button",type:"button",onClick:od}," New Area ")])]),t.areaLlmError?(v(),b("p",ip,A(t.areaLlmError),1)):E("",!0),o("div",op,[o("div",lp,[o("span",dp,"GA "+A(Number(Ja.value.gaCount||0)),1),o("span",cp,"Hierarchical "+A(Number(Ja.value.hierarchicalGaCount||0)),1),o("span",up,"Secondary "+A(Number(Ja.value.secondaryGroupCount||0)),1),o("span",fp,"Active "+A(Number(Ja.value.activeAreaCount||0)),1)])]),ws.value.length||t.areaDraftIsNew?(v(),b("div",pp,[!ze.value&&!t.areaDraftIsNew?(v(),b("div",gp,[o("label",hp,[n[65]||(n[65]=o("span",null,"Areas",-1)),o("div",mp,[ue(o("input",{"onUpdate:modelValue":n[7]||(n[7]=r=>t.areaSearch=r),class:"area-search-select-input",type:"text",placeholder:ze.value?ei(ze.value):"Search area...",onFocus:n[8]||(n[8]=r=>t.areaSearchOpen=!0),onInput:n[9]||(n[9]=r=>t.areaSearchOpen=!0),onBlur:td},null,40,vp),[[Ne,t.areaSearch]]),t.areaSearchOpen&&ws.value.length?(v(),b("div",bp,[(v(!0),b(J,null,oe(ws.value.slice(0,80),r=>(v(),b("button",{key:r.id,type:"button",class:le(["area-search-select-option",{active:ze.value&&ze.value.id===r.id}]),onMousedown:Xt(u=>ed(r),["prevent"])},A(ei(r)),43,yp))),128))])):E("",!0)])])])):E("",!0),ze.value||t.areaDraftIsNew?(v(),b("article",{key:1,class:le(["area-detail",{"area-detail-wide":t.areaDraftIsNew}])},[o("div",Ap,[t.areaBuilderFocus!==!0?(v(),b("div",Sp,[n[66]||(n[66]=o("div",null,[o("h4",null,"Edit Area"),o("p",{class:"area-detail-subhead"},"The installer can rename the area and decide exactly which group addresses belong to it. Everything is persisted per KNX AI node.")],-1)),o("div",wp,[t.areaDraftIsNew&&!Mr.value?(v(),b("button",{key:0,class:"secondary-button",type:"button",onClick:Kl}," Show AI Area Builder ")):E("",!0),t.areaDraftIsNew?E("",!0):(v(),b("button",{key:1,class:"danger-button",type:"button",disabled:t.areaSaving,onClick:Yl}," Delete Area ",8,Tp)),o("button",{class:"secondary-button",type:"button",disabled:t.areaSaving,onClick:Zl}," Reset ",8,Pp),o("button",{class:"primary-button",type:"button",disabled:t.areaSaving,onClick:Jl},A(t.areaSaving?"Saving...":"Save Area"),9,_p),o("button",{class:"secondary-button",type:"button",disabled:t.areaSaving,onClick:jl}," Close ",8,Cp)])])):E("",!0),t.areaBuilderFocus!==!0?(v(),b("div",Ip,[o("label",Np,[n[67]||(n[67]=o("span",null,"Area name",-1)),ue(o("input",{"onUpdate:modelValue":n[10]||(n[10]=r=>t.areaDraftName=r),type:"text",placeholder:"Installer alias"},null,512),[[Ne,t.areaDraftName]])]),o("label",Rp,[n[68]||(n[68]=o("span",null,"Description",-1)),ue(o("textarea",{"onUpdate:modelValue":n[11]||(n[11]=r=>t.areaDraftDescription=r),rows:"3",placeholder:"Optional note for diagnostics and reports"},null,512),[[Ne,t.areaDraftDescription]])]),o("label",Dp,[n[69]||(n[69]=o("span",null,"Add group addresses to this area",-1)),ue(o("input",{"onUpdate:modelValue":n[12]||(n[12]=r=>t.gaCatalogSearch=r),type:"text",placeholder:"Search GA, label or ETS path"},null,512),[[Ne,t.gaCatalogSearch]])])])):E("",!0),t.areaDraftIsNew&&Mr.value?(v(),b("div",kp,[o("div",{class:le(["ai-planner-shell-head",{"template-builder-focus-head":t.areaBuilderFocus===!0}])},[n[70]||(n[70]=o("div",null,[o("h4",null,"AI Area Builder"),o("p",{class:"area-detail-subhead"},"Describe the room, zone or function you want. The AI will suggest the most relevant group addresses for this draft.")],-1)),t.areaBuilderFocus===!0?(v(),b("div",xp,[o("button",{class:"secondary-button",type:"button",onClick:Vl}," Close ")])):E("",!0)],2),o("div",Ep,[o("label",Lp,[n[71]||(n[71]=o("span",null,"Assistant prompt",-1)),ue(o("textarea",{"onUpdate:modelValue":n[13]||(n[13]=r=>t.areaLlmPrompt=r),rows:"3",placeholder:"Example: Add all technical room lighting command and status GA."},null,512),[[Ne,t.areaLlmPrompt]])])]),o("div",Gp,[o("button",{class:"primary-button",type:"button",disabled:t.areaLlmBusy||!t.areaLlmPrompt.trim()||!pt.value.llmEnabled,onClick:cd},[t.areaLlmBusy?(v(),b("span",zp)):E("",!0),de(" "+A(t.areaLlmBusy?"Suggesting...":"Suggest GA with AI"),1)],8,Fp)]),t.areaLlmError?(v(),b("p",Op,A(t.areaLlmError),1)):E("",!0),pt.value.llmEnabled?E("",!0):(v(),b("p",Mp," Enable the AI in the KNX AI node to regenerate areas or suggest GA for a new draft. "))])):E("",!0),t.areaBuilderFocus!==!0?(v(),b("div",Bp,[o("div",null,[n[73]||(n[73]=o("h4",null,"Area GA membership",-1)),zr.value.length?(v(),b("ul",$p,[(v(!0),b(J,null,oe(zr.value,r=>(v(),b("li",{key:r.ga,class:"area-ga-item"},[o("div",Kp,[o("strong",null,A(r.ga),1),o("span",null,[de(A(r.label||"Unlabeled GA"),1),r.dpt?(v(),b("span",Vp," | DPT "+A(r.dpt),1)):E("",!0)]),o("span",null,[de("Role "+A(Qr(r.role)),1),r.roleSource?(v(),b("span",jp," | source "+A(r.roleSource),1)):E("",!0)])]),o("div",Up,[o("label",Wp,[n[72]||(n[72]=o("span",null,"Role",-1)),o("select",{value:r.roleOverride&&r.roleOverride!=="auto"?r.roleOverride:r.role||"neutral",disabled:t.areaGaRoleSavingGa===r.ga,onChange:u=>id(r.ga,u.target.value)},[(v(),b(J,null,oe(l,u=>o("option",{key:u.value,value:u.value},A(u.label),9,Xp)),64))],40,Hp)]),o("button",{class:"secondary-button",type:"button",onClick:u=>rd(r.ga)}," Remove ",8,qp)])]))),128))])):(v(),b("p",Jp,"No GA selected for this area yet."))]),o("div",null,[o("div",Zp,[n[74]||(n[74]=o("div",null,[o("h4",null,"Available GA"),o("p",{class:"area-detail-subhead"},"Pick from the ETS catalog. Already selected GA are hidden from this list.")],-1)),o("span",Yp,A(t.gaCatalogLoading?"Loading...":`${Fr.value.length} visible`),1)]),o("div",Qp,[(v(!0),b(J,null,oe(Fr.value,r=>(v(),b("button",{key:r.ga,type:"button",class:"area-list-item",onClick:u=>Ql(r.ga)},[o("span",tg,A(r.ga),1),o("span",ag,A(r.label||"Unlabeled GA"),1),o("span",ng,[de(A(r.hierarchyPath||r.dpt||""),1),r.role?(v(),b("span",sg," | "+A(Qr(r.role)),1)):E("",!0)])],8,eg))),128))])])])):E("",!0),t.areaBuilderFocus!==!0?(v(),b("p",rg,[n[75]||(n[75]=de(" Original ETS path: ",-1)),o("strong",null,A(t.areaDraftIsNew?"Manual area":ze.value.basePath||ze.value.path||ze.value.name),1)])):E("",!0)])],2)):E("",!0)])):(v(),b("p",ig,"No areas matched the current search or the ETS file does not expose a usable hierarchy yet."))])):E("",!0),t.activeTab==="tests"?(v(),b("section",{key:2,class:le(["card card-profiles",{"card-results-focus":St.value}])},[o("div",og,[o("div",null,[o("h2",null,A(St.value?"Test Result":"Test Planner"),1),o("p",lg,A(St.value?"Showing only the selected test report.":"Select an area, choose a standard test template, review the generated plan, then save or run it."),1)]),St.value?(v(),b("div",pg,[o("span",gg,A(Ya(ie.value)),1),o("button",{class:"danger-button",type:"button",disabled:!ie.value||t.deletingTestResultId===ie.value.id,onClick:n[14]||(n[14]=r=>Fs(ie.value?.id))},A(t.deletingTestResultId===ie.value?.id?"Deleting...":"Delete"),9,hg),o("button",{class:"secondary-button",type:"button",onClick:Jr}," Open Source Test ")])):(v(),b("div",dg,[o("span",cg,"Area "+A(dt.value?dt.value.path||dt.value.name:"n/a"),1),o("span",ug,A(At.value.length)+" saved plans",1),o("button",{class:"secondary-button",type:"button",disabled:!t.testPlanDraft,onClick:Ld}," Duplicate Plan ",8,fg),o("button",{class:"secondary-button new-button",type:"button",onClick:di}," New Plan ")]))]),o("div",{class:le(["profiles-layout test-planner-layout",{"result-only-layout":St.value}])},[o("div",mg,[!St.value&&!t.testPlanDraft&&!t.testPlanRunning?(v(),b("article",vg,[n[77]||(n[77]=o("div",{class:"card-head"},[o("div",null,[o("h3",null,"Select test plan"),o("p",{class:"area-detail-subhead"},"Reusable deterministic active tests saved by the installer.")])],-1)),o("div",bg,[o("label",yg,[n[76]||(n[76]=o("span",null,"Plans",-1)),o("div",Ag,[ue(o("input",{"onUpdate:modelValue":n[15]||(n[15]=r=>t.testPlanSearch=r),class:"area-search-select-input",type:"text",placeholder:oa.value?ti(oa.value):"Search saved plan...",onFocus:n[16]||(n[16]=r=>t.testPlanSearchOpen=!0),onInput:n[17]||(n[17]=r=>t.testPlanSearchOpen=!0),onBlur:nd},null,40,Sg),[[Ne,t.testPlanSearch]]),t.testPlanSearchOpen&&Lr.value.length?(v(),b("div",wg,[(v(!0),b(J,null,oe(Lr.value.slice(0,80),r=>(v(),b("button",{key:r.id,type:"button",class:le(["area-search-select-option",{active:oa.value&&oa.value.id===r.id}]),onMousedown:Xt(u=>ad(r),["prevent"])},A(ti(r)),43,Tg))),128))])):E("",!0)])])]),At.value.length?E("",!0):(v(),b("p",Pg,"No saved plans yet."))])):E("",!0),!St.value&&t.testPlanDraft?(v(),b("article",_g,[t.testTemplateBuilderFocus!==!0?(v(),b("div",Cg,[o("div",null,[o("h3",null,A(t.testPlanDraft?.name||"Plan Draft"),1),Ps.value?(v(),b("p",Ig,"Choose a standard test template for the selected area, then build the plan deterministically from the ETS catalog.")):E("",!0)]),o("div",Ng,[Br.value?(v(),b("span",Rg,"Unsaved changes")):E("",!0),o("button",{class:"secondary-button new-button",type:"button",onClick:di}," New Plan "),Ps.value?E("",!0):(v(),b("button",{key:1,class:"secondary-button",type:"button",onClick:Bl}," Show Template Builder ")),o("label",Dg,[ue(o("input",{"onUpdate:modelValue":n[18]||(n[18]=r=>t.voiceEnabled=r),type:"checkbox"},null,512),[[ar,t.voiceEnabled]]),n[78]||(n[78]=o("span",null,"Voice",-1))]),o("button",{class:"danger-button",type:"button",disabled:t.testPlanDeleting||!oa.value,onClick:Fd},A(t.testPlanDeleting?"Deleting...":"Delete"),9,kg),o("button",{class:"secondary-button",type:"button",disabled:t.testPlanSaving||t.testPlanRunning,onClick:Wl}," Close ",8,xg),o("button",{class:"secondary-button",type:"button",disabled:t.testPlanSaving||!t.testPlanDraft,onClick:ci},A(t.testPlanSaving?"Saving...":"Save Plan"),9,Eg),wl.value?(v(),b("div",Lg,[o("button",{class:"secondary-button",type:"button",disabled:!t.testPlanDraft&&t.testPlanRepeatForever!==!0||t.testPlanRunning&&t.testPlanRepeatForever!==!0||t.testPlanRepeatStopRequested===!0,onClick:n[19]||(n[19]=r=>t.testPlanRepeatForever===!0?Rd():Nd())},A(t.testPlanRepeatForever===!0?t.testPlanRepeatStopRequested===!0?"Stopping...":"Stop Repeat":"Repeat Forever"),9,Gg),o("button",{class:"primary-button",type:"button",disabled:t.testPlanRunning||!t.testPlanDraft,onClick:Id},[t.testPlanRunning?(v(),b("span",zg)):E("",!0),o("span",null,A(t.testPlanRunning?"Running...":"Run Plan"),1)],8,Fg)])):E("",!0)])])):E("",!0),Ps.value?(v(),b("div",Og,[o("div",{class:le(["ai-planner-shell-head",{"template-builder-focus-head":t.testTemplateBuilderFocus===!0}])},[n[79]||(n[79]=o("div",null,[o("h4",null,"Template Builder"),o("p",{class:"area-detail-subhead"},"Select one of the standard templates. The plan is built only from the command GA available in the selected area.")],-1)),t.testTemplateBuilderFocus===!0?(v(),b("div",Mg,[o("button",{class:"secondary-button",type:"button",onClick:$l}," Close ")])):E("",!0)],2),o("div",Bg,[o("label",$g,[n[80]||(n[80]=o("span",null,"Area to test",-1)),ue(o("select",{"onUpdate:modelValue":n[20]||(n[20]=r=>t.testAreaSelectedId=r)},[(v(!0),b(J,null,oe(Ae.value,r=>(v(),b("option",{key:r.id,value:r.id},A(r.path||r.name),9,Kg))),128))],512),[[Pa,t.testAreaSelectedId]])]),o("label",Vg,[n[81]||(n[81]=o("span",null,"Selected template",-1)),o("textarea",{value:t.testPlanPrompt||"Select one of the templates below.",rows:"4",readonly:""},null,8,jg)])]),o("div",Ug,[(v(),b(J,null,oe(i,r=>o("button",{key:r.id,class:le(["preset-button",{active:t.testPlanPrompt===r.prompt}]),type:"button",onClick:u=>ud(r)},A(r.title),11,Wg)),64))]),o("p",Hg,A((i.find(r=>r.prompt===t.testPlanPrompt)||{}).description||"Choose a template to see what the deterministic builder will do in the selected area."),1),o("div",Xg,[o("button",{class:"primary-button",type:"button",disabled:t.testPlanGenerating||!dt.value||!t.testPlanPrompt.trim(),onClick:Gd},[t.testPlanGenerating?(v(),b("span",Jg)):E("",!0),de(" "+A(t.testPlanGenerating?"Building...":"Build Test Plan"),1)],8,qg)]),t.testPlanGenerationError?(v(),b("p",Zg,A(t.testPlanGenerationError),1)):E("",!0),t.testPlanGeneration?(v(),b("div",Yg,[t.testPlanGeneration.error?E("",!0):(v(),b("p",Qg," Built with "+A(t.testPlanGeneration.provider||"deterministic builder")+". ",1)),t.testPlanGeneration.error?(v(),b("p",eh,A(t.testPlanGeneration.error),1)):E("",!0)])):E("",!0)])):E("",!0)])):E("",!0),t.testPlanRunning&&!St.value?(v(),b("article",th,[o("div",ah,[o("div",null,[n[82]||(n[82]=o("h3",{class:"running-headline"},[o("span",{class:"running-spinner","aria-hidden":"true"}),o("span",null,"Test Running")],-1)),o("p",nh,A(ke.value?.title||"Executing current step..."),1)]),o("span",sh,A(gt.value?.metrics?.totalSteps?`${Number(gt.value.steps?.length||0)}/${Number(gt.value.metrics.totalSteps||0)}`:"in progress"),1)]),o("div",rh,[o("article",ih,[n[83]||(n[83]=o("span",null,"Completed",-1)),o("strong",null,A(Number(gt.value?.steps?.length||0)),1)]),o("article",oh,[n[84]||(n[84]=o("span",null,"Pass",-1)),o("strong",null,A(Number(gt.value?.metrics?.pass||0)),1)]),o("article",lh,[n[85]||(n[85]=o("span",null,"Warn",-1)),o("strong",null,A(Number(gt.value?.metrics?.warn||0)),1)]),o("article",dh,[n[86]||(n[86]=o("span",null,"Fail",-1)),o("strong",null,A(Number(gt.value?.metrics?.fail||0)),1)])]),ke.value?(v(),b("div",ch,[o("div",uh,[o("strong",null,A(ke.value.title||ke.value.id),1),o("span",null,A(ke.value.kind),1)]),o("p",fh,A(ke.value.description||"Current step in execution."),1),ke.value.kind==="wait"?(v(),b("div",ph,[o("span",null,[n[87]||(n[87]=o("strong",null,"Wait",-1)),de(" "+A(Number(ke.value.delayMs||0))+" ms",1)]),o("span",null,[n[88]||(n[88]=o("strong",null,"Reason",-1)),de(" "+A(ke.value.reason||"Pause before next action"),1)])])):(v(),b("div",gh,[o("span",null,[n[89]||(n[89]=o("strong",null,"Command",-1)),de(" "+A(ke.value.commandGA||"n/a"),1)]),o("span",null,[n[90]||(n[90]=o("strong",null,"Status GA",-1)),de(" "+A(ke.value.statusGA||"n/a"),1)]),o("span",null,[n[91]||(n[91]=o("strong",null,"Payload",-1)),de(" "+A(ks(ke.value.commandPayload,ke.value.commandDPT)),1)]),o("span",null,[n[92]||(n[92]=o("strong",null,"Expected",-1)),de(" "+A(ks(ke.value.expectedPayload,ke.value.statusDPT||ke.value.commandDPT)),1)])])),ke.value.kind!=="wait"&&ke.value.statusGA?(v(),b("div",hh,[o("section",mh,[n[95]||(n[95]=o("h4",null,"Spontaneous Write From Status GA",-1)),o("div",vh,[o("span",null,[n[93]||(n[93]=o("strong",null,"Status GA",-1)),de(" "+A(ke.value.statusGA||"n/a"),1)]),o("span",null,[n[94]||(n[94]=o("strong",null,"Timeout",-1)),de(" "+A(Number(ke.value.statusWriteTimeoutMs||0))+" ms",1)])])]),o("section",bh,[n[98]||(n[98]=o("h4",null,"Active Read Request To Status GA",-1)),o("div",yh,[o("span",null,[n[96]||(n[96]=o("strong",null,"Status GA",-1)),de(" "+A(ke.value.statusGA||"n/a"),1)]),o("span",null,[n[97]||(n[97]=o("strong",null,"Timeout",-1)),de(" "+A(Number(ke.value.statusResponseTimeoutMs||0))+" ms",1)])])])])):E("",!0)])):E("",!0)])):E("",!0),ie.value&&St.value?(v(),b("article",{key:3,ref_key:"testPlanReportRef",ref:tt,class:"area-detail"},[o("div",Ah,[o("div",null,[o("h3",null,A(Ln(ie.value)),1),o("p",Sh,A(Gn(ie.value)||yt(ie.value.generatedAt)),1)]),o("div",wh,[o("span",Th,A(Ya(ie.value)),1),ie.value.live===!0?(v(),b("span",Ph,[...n[99]||(n[99]=[o("span",{class:"running-spinner run-chip-spinner","aria-hidden":"true"},null,-1),o("span",null,"Running",-1)])])):E("",!0),o("span",_h,A(ie.value.overallStatus),1),o("button",{class:"secondary-button",type:"button",onClick:Vr}," Export PDF ")])]),o("div",Ch,[(v(!0),b(J,null,oe(Ds(ie.value),r=>(v(),b("article",{key:r.label,class:"metric"},[o("span",null,A(r.label),1),o("strong",null,A(r.value),1)]))),128))]),o("div",Ih,[(v(!0),b(J,null,oe(Qa(ie.value),r=>(v(),b("article",{key:r.id,class:le(["report-check",`report-${r.status}`])},[o("div",Nh,[o("strong",null,A(r.title),1),o("span",null,A(r.status),1)]),o("p",Rh,A(r.message||"No additional details available."),1),r.detailGroups?.length?(v(),b("div",Dh,[(v(!0),b(J,null,oe(r.detailGroups,u=>(v(),b("section",{key:`${r.id}-${u.title}`,class:"planner-check-section"},[o("h4",null,A(u.title),1),o("div",kh,[(v(!0),b(J,null,oe(u.items,g=>(v(),b("span",{key:`${r.id}-${u.title}-${g.label}`},[o("strong",null,A(g.label),1),de(" "+A(g.value),1)]))),128))])]))),128))])):(v(),b("div",xh,[(v(!0),b(J,null,oe(r.details,u=>(v(),b("span",{key:`${r.id}-${u.label}`},[o("strong",null,A(u.label),1),de(" "+A(u.value),1)]))),128))]))],2))),128))]),Qa(ie.value).length?E("",!0):(v(),b("p",Eh,"No detailed entries stored for this report yet.")),en(ie.value).length?(v(),b("div",Lh,[n[100]||(n[100]=o("h4",null,"Suggestions",-1)),o("ul",Gh,[(v(!0),b(J,null,oe(en(ie.value),r=>(v(),b("li",{key:r},A(r),1))),128))])])):E("",!0)],512)):E("",!0),t.testPlanDraft&&!t.testPlanRunning&&!St.value&&t.testTemplateBuilderFocus!==!0?(v(),b("article",Fh,[o("div",zh,[o("div",null,[o("h3",Oh,[n[101]||(n[101]=o("span",null,"Edit Plan",-1)),t.testPlanGenerating?(v(),b("span",Mh)):E("",!0)])]),o("div",Bh,[o("span",$h,A(Number(t.testPlanDraft.steps?.length||0))+" steps",1),o("button",{class:"secondary-button",type:"button",onClick:bd}," Add Step "),o("button",{class:"secondary-button",type:"button",onClick:yd}," Add Wait ")])]),o("div",Kh,[o("label",Vh,[n[103]||(n[103]=o("span",null,"Area",-1)),o("select",{value:t.testPlanDraft.areaId||t.testAreaSelectedId||"",disabled:!Ae.value.length,onChange:n[21]||(n[21]=r=>Ed(r.target.value))},[n[102]||(n[102]=o("option",{value:"",disabled:""},"Select area",-1)),(v(!0),b(J,null,oe(Ae.value,r=>(v(),b("option",{key:r.id,value:r.id},A(r.path||r.name),9,Uh))),128))],40,jh)]),o("label",Wh,[n[104]||(n[104]=o("span",null,"Plan name",-1)),ue(o("input",{"onUpdate:modelValue":n[22]||(n[22]=r=>t.testPlanDraft.name=r),type:"text",placeholder:"KNX active test name"},null,512),[[Ne,t.testPlanDraft.name]])]),o("label",Hh,[n[105]||(n[105]=o("span",null,"Description",-1)),ue(o("textarea",{"onUpdate:modelValue":n[23]||(n[23]=r=>t.testPlanDraft.description=r),rows:"2",placeholder:"Short operator-facing description"},null,512),[[Ne,t.testPlanDraft.description]])])]),o("div",Xh,[(v(!0),b(J,null,oe(t.testPlanDraft.steps||[],(r,u)=>(v(),b("article",{key:r.id,class:le(["report-check report-pass planner-step-card",{"planner-step-running":t.testPlanRunning&&t.testPlanRunningStepId===r.id,"planner-step-dragging":t.draggedTestPlanStepId===r.id,"planner-step-drop-target":t.dragOverTestPlanStepId===r.id}]),onDragenter:Xt(g=>Pd(r.id),["prevent"]),onDragover:n[24]||(n[24]=Xt(()=>{},["prevent"])),onDrop:g=>Cd(r.id,g)},[o("div",Jh,[o("div",Zh,[o("button",{class:"drag-handle",type:"button",draggable:"true",tabindex:"-1","aria-label":"Drag step",title:"Drag step",onDragstart:g=>Td(r.id,g),onDragend:Bs}," ⋮⋮ ",40,Yh),o("button",{class:"collapse-toggle",type:"button","aria-expanded":r.collapsed!==!0,title:r.collapsed===!0?"Expand step":"Collapse step",onClick:g=>wd(r)},[o("span",{class:le(["collapse-icon",{collapsed:r.collapsed===!0}])},"▾",2)],8,Qh),o("strong",null,A(r.title||r.id),1)]),o("div",em,[o("span",null,A(r.kind),1),o("button",{class:"secondary-button",type:"button",onClick:g=>Ad(u)}," Duplicate ",8,tm),o("button",{class:"secondary-button",type:"button",onClick:g=>Sd(u)}," Remove ",8,am)])]),r.collapsed===!0?(v(),b("div",nm,[r.kind==="wait"?(v(),b("span",sm,[n[106]||(n[106]=o("strong",null,"Wait",-1)),de(" "+A(Number(r.delayMs||0))+" ms",1)])):(v(),b("span",rm,[n[107]||(n[107]=o("strong",null,"Command",-1)),de(" "+A(r.commandGA||"n/a"),1)])),r.kind!=="wait"?(v(),b("span",im,[n[108]||(n[108]=o("strong",null,"Status GA",-1)),de(" "+A(r.statusGA||"n/a"),1)])):E("",!0),r.kind!=="wait"?(v(),b("span",om,[n[109]||(n[109]=o("strong",null,"Payload",-1)),de(" "+A(ks(r.commandPayload,r.commandDPT)),1)])):E("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("span",lm,[n[110]||(n[110]=o("strong",null,"Write timeout",-1)),de(" "+A(Number(r.statusWriteTimeoutMs||0))+" ms",1)])):E("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("span",dm,[n[111]||(n[111]=o("strong",null,"Response timeout",-1)),de(" "+A(Number(r.statusResponseTimeoutMs||0))+" ms",1)])):E("",!0)])):(v(),b("div",cm,[o("label",um,[n[112]||(n[112]=o("span",null,"Title",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.title=g,type:"text",placeholder:"Step title"},null,8,fm),[[Ne,r.title]])]),o("label",pm,[n[113]||(n[113]=o("span",null,"Description",-1)),ue(o("textarea",{"onUpdate:modelValue":g=>r.description=g,rows:"2",placeholder:"What this step checks"},null,8,gm),[[Ne,r.description]])]),r.kind==="wait"?(v(),b("label",hm,[n[114]||(n[114]=o("span",null,"Wait ms",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.delayMs=g,type:"number",min:"0",max:"30000",step:"100"},null,8,mm),[[Ne,r.delayMs,void 0,{number:!0}]])])):E("",!0),r.kind!=="wait"?(v(),b("section",vm,[n[119]||(n[119]=o("h4",null,"Command",-1)),o("div",bm,[o("label",ym,[n[116]||(n[116]=o("span",null,"Command GA",-1)),ue(o("select",{"onUpdate:modelValue":g=>r.commandGA=g,onChange:g=>si(r)},[n[115]||(n[115]=o("option",{value:""},"Select command GA",-1)),(v(!0),b(J,null,oe(Ts.value,g=>(v(),b("option",{key:g.ga,value:g.ga},A(`${g.ga} | ${g.label}`),9,Sm))),128))],40,Am),[[Pa,r.commandGA]])]),o("label",wm,[n[117]||(n[117]=o("span",null,"Command DPT",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.commandDPT=g,type:"text",placeholder:"1.001",onChange:g=>zn(r)},null,40,Tm),[[Ne,r.commandDPT]])]),o("label",Pm,[n[118]||(n[118]=o("span",null,"Command payload",-1)),da(r.commandDPT).length?ue((v(),b("select",{key:0,"onUpdate:modelValue":g=>r.commandPayload=g},[(v(!0),b(J,null,oe(da(r.commandDPT),g=>(v(),b("option",{key:`${r.id}-command-${g.value}`,value:String(g.value)},A(g.label),9,Cm))),128))],8,_m)),[[Pa,r.commandPayload]]):ue((v(),b("input",{key:1,"onUpdate:modelValue":g=>r.commandPayload=g,type:"text",placeholder:"true, false, 50"},null,8,Im)),[[Ne,r.commandPayload]])])])])):E("",!0),r.kind!=="wait"?(v(),b("section",Nm,[n[124]||(n[124]=o("h4",null,"Status",-1)),o("div",Rm,[o("label",Dm,[n[121]||(n[121]=o("span",null,"Status GA",-1)),ue(o("select",{"onUpdate:modelValue":g=>r.statusGA=g,onChange:g=>si(r)},[n[120]||(n[120]=o("option",{value:""},"No feedback",-1)),(v(!0),b(J,null,oe(Or.value,g=>(v(),b("option",{key:g.ga,value:g.ga},A(`${g.ga} | ${g.label}`),9,xm))),128))],40,km),[[Pa,r.statusGA]])]),o("label",Em,[n[122]||(n[122]=o("span",null,"Status DPT",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.statusDPT=g,type:"text",placeholder:"1.001",onChange:g=>zn(r)},null,40,Lm),[[Ne,r.statusDPT]])]),o("label",Gm,[n[123]||(n[123]=o("span",null,"Expected payload",-1)),da(r.statusDPT||r.commandDPT).length?ue((v(),b("select",{key:0,"onUpdate:modelValue":g=>r.expectedPayload=g},[(v(!0),b(J,null,oe(da(r.statusDPT||r.commandDPT),g=>(v(),b("option",{key:`${r.id}-expected-${g.value}`,value:String(g.value)},A(g.label),9,zm))),128))],8,Fm)),[[Pa,r.expectedPayload]]):ue((v(),b("input",{key:1,"onUpdate:modelValue":g=>r.expectedPayload=g,type:"text",placeholder:"Expected feedback value"},null,8,Om)),[[Ne,r.expectedPayload]])])])])):E("",!0),r.kind!=="wait"&&r.statusGA?(v(),b("div",Mm,[o("section",Bm,[n[126]||(n[126]=o("h4",null,"Spontaneous Write From Status GA",-1)),n[127]||(n[127]=o("p",{class:"area-detail-subhead"},[de("Wait for a spontaneous "),o("code",null,"GroupValue_Write"),de(" telegram from the status GA.")],-1)),o("label",$m,[n[125]||(n[125]=o("span",null,"Status write timeout ms",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.statusWriteTimeoutMs=g,type:"number",min:"500",max:"60000",step:"100"},null,8,Km),[[Ne,r.statusWriteTimeoutMs,void 0,{number:!0}]])])]),o("section",Vm,[n[129]||(n[129]=o("h4",null,"Active Read Request To Status GA",-1)),n[130]||(n[130]=o("p",{class:"area-detail-subhead"},[de("Send a "),o("code",null,"read"),de(" telegram to the status GA and wait for a "),o("code",null,"GroupValue_Response"),de(".")],-1)),o("label",jm,[n[128]||(n[128]=o("span",null,"Read response timeout ms",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.statusResponseTimeoutMs=g,type:"number",min:"500",max:"60000",step:"100"},null,8,Um),[[Ne,r.statusResponseTimeoutMs,void 0,{number:!0}]])])])])):E("",!0),o("label",Wm,[n[131]||(n[131]=o("span",null,"Reason",-1)),ue(o("input",{"onUpdate:modelValue":g=>r.reason=g,type:"text",placeholder:"Why this step exists"},null,8,Hm),[[Ne,r.reason]])])]))],42,qh))),128))])])):E("",!0)])],2)],2)):E("",!0),t.activeTab==="results"?(v(),b("section",Xm,[o("div",qm,[n[132]||(n[132]=o("div",null,[o("h2",null,"Test Results"),o("p",{class:"area-detail-subhead"},"Live and saved reports generated by KNX active and read-only tests.")],-1)),o("div",Jm,[o("span",Zm,A(ia.value.length)+" available",1)])]),o("div",Ym,[o("article",Qm,[n[133]||(n[133]=o("div",{class:"card-head"},[o("div",null,[o("h3",null,"Select Test Result"),o("p",{class:"area-detail-subhead"},"Choose a report to inspect metrics, detailed checks, and suggestions.")])],-1)),o("div",ev,[(v(!0),b(J,null,oe(ia.value,r=>(v(),b("div",{key:r.id,class:"sidebar-result-row"},[o("button",{type:"button",class:le(["area-list-item sidebar-result-item",{active:ie.value&&ie.value.id===r.id,running:r.live===!0}]),onClick:u=>Fn(r.id,{openMenu:!1,activateResultsTab:!0,resultOnly:!0})},[o("span",av,[o("strong",nv,[r.live===!0?(v(),b("span",sv)):E("",!0),o("span",null,A(Ln(r)),1)]),o("span",{class:le(["sidebar-result-status",`status-${r.overallStatus||"pass"}`])},A(r.overallStatus||"n/a"),3)]),o("span",rv,[de(A(Ya(r)),1),r.live===!0?(v(),b("span",iv," | running")):E("",!0)]),o("span",ov,A(Gn(r)||yt(r.generatedAt)),1),o("span",lv,A(yt(r.generatedAt)),1)],10,tv),o("button",{class:"sidebar-result-delete-button",type:"button",disabled:t.deletingTestResultId===r.id,onClick:Xt(u=>Fs(r.id),["stop"])},A(t.deletingTestResultId===r.id?"Deleting...":"Delete"),9,dv)]))),128)),ia.value.length?E("",!0):(v(),b("p",cv,"No saved test results yet."))])]),ie.value?(v(),b("article",{key:0,ref_key:"testPlanReportRef",ref:tt,class:"area-detail"},[o("div",uv,[o("div",null,[o("h3",null,A(Ln(ie.value)),1),o("p",fv,A(Gn(ie.value)||yt(ie.value.generatedAt)),1)]),o("div",pv,[o("span",gv,A(Ya(ie.value)),1),ie.value.live===!0?(v(),b("span",hv,[...n[134]||(n[134]=[o("span",{class:"running-spinner run-chip-spinner","aria-hidden":"true"},null,-1),o("span",null,"Running",-1)])])):E("",!0),o("span",mv,A(ie.value.overallStatus),1),o("button",{class:"secondary-button",type:"button",onClick:Vr}," Export PDF "),o("button",{class:"danger-button",type:"button",disabled:!ie.value||t.deletingTestResultId===ie.value.id,onClick:n[25]||(n[25]=r=>Fs(ie.value?.id))},A(t.deletingTestResultId===ie.value?.id?"Deleting...":"Delete"),9,vv),o("button",{class:"secondary-button",type:"button",onClick:Jr}," Open Source Test ")])]),o("div",bv,[(v(!0),b(J,null,oe(Ds(ie.value),r=>(v(),b("article",{key:r.label,class:"metric"},[o("span",null,A(r.label),1),o("strong",null,A(r.value),1)]))),128))]),o("div",yv,[(v(!0),b(J,null,oe(Qa(ie.value),r=>(v(),b("article",{key:r.id,class:le(["report-check",`report-${r.status}`])},[o("div",Av,[o("strong",null,A(r.title),1),o("span",null,A(r.status),1)]),o("p",Sv,A(r.message||"No additional details available."),1),r.detailGroups?.length?(v(),b("div",wv,[(v(!0),b(J,null,oe(r.detailGroups,u=>(v(),b("section",{key:`${r.id}-${u.title}`,class:"planner-check-section"},[o("h4",null,A(u.title),1),o("div",Tv,[(v(!0),b(J,null,oe(u.items,g=>(v(),b("span",{key:`${r.id}-${u.title}-${g.label}`},[o("strong",null,A(g.label),1),de(" "+A(g.value),1)]))),128))])]))),128))])):(v(),b("div",Pv,[(v(!0),b(J,null,oe(r.details,u=>(v(),b("span",{key:`${r.id}-${u.label}`},[o("strong",null,A(u.label),1),de(" "+A(u.value),1)]))),128))]))],2))),128))]),Qa(ie.value).length?E("",!0):(v(),b("p",_v,"No detailed entries stored for this report yet.")),en(ie.value).length?(v(),b("div",Cv,[n[135]||(n[135]=o("h4",null,"Suggestions",-1)),o("ul",Iv,[(v(!0),b(J,null,oe(en(ie.value),r=>(v(),b("li",{key:r},A(r),1))),128))])])):E("",!0)],512)):(v(),b("article",Nv,[...n[136]||(n[136]=[o("p",{class:"empty-state"},"No test result selected.",-1)])]))])])):E("",!0),t.activeTab==="overview"?(v(),b("section",Rv,[o("div",Dv,[n[137]||(n[137]=o("h2",null,"Top Group Addresses",-1)),o("span",kv,A(Cs.value.length)+" visible",1)]),Cs.value.length?(v(),b("ul",xv,[(v(!0),b(J,null,oe(Cs.value,r=>(v(),b("li",{key:r.ga,class:"rank-row"},[o("span",Ev,A(r.ga),1),o("span",Lv,A(r.label||"Unlabeled"),1),o("strong",null,A(Number(r.count||0)),1)]))),128))])):(v(),b("p",Gv,"No top group address data available yet."))])):E("",!0),t.activeTab==="overview"?(v(),b("section",Fv,[o("div",zv,[n[138]||(n[138]=o("h2",null,"Event Mix",-1)),o("span",Ov,A(En.value.length)+" event types",1)]),En.value.length?(v(),b("ul",Mv,[(v(!0),b(J,null,oe(En.value,r=>(v(),b("li",{key:r.name,class:"event-row"},[o("span",Bv,A(r.name),1),o("div",$v,[o("span",{class:"event-bar-fill",style:hn({width:`${Math.max(r.count/Pl.value*100,6)}%`})},null,4)]),o("strong",null,A(r.count),1)]))),128))])):(v(),b("p",Kv,"Event distribution will appear after the first samples."))])):E("",!0),t.activeTab==="overview"?(v(),b("section",Vv,[o("div",jv,[n[139]||(n[139]=o("h2",null,"Bus Connection Persistence",-1)),nt.value?(v(),b("span",Uv,A(String(nt.value.currentState||"unknown")),1)):E("",!0)]),nt.value?(v(),b(J,{key:0},[o("div",Wv,[o("span",Hv,"Connected "+A(vs(nt.value.connectedSec||0)),1),o("span",Xv,"Disconnected "+A(vs(nt.value.disconnectedSec||0)),1),o("span",qv,"Coverage "+A(Number(nt.value.knownCoveragePct||0))+"%",1)]),o("div",Jv,[(v(!0),b(J,null,oe(Il.value,r=>(v(),b("span",{key:r.key,class:le(["bus-segment",r.className]),style:hn({left:r.left,width:r.width}),title:r.title},null,14,Zv))),128))]),o("div",Yv,[o("span",null,A(Dn(nt.value.windowStartAt)),1),o("span",null,A(Dn(nt.value.windowEndAt)),1),n[140]||(n[140]=o("span",null,"Now",-1))]),n[141]||(n[141]=o("p",{class:"bus-note"},"Green shows time connected to the KNX bus. Red shows downtime inside the selected history window.",-1))],64)):(v(),b("p",Qv,"Waiting for connection persistence data..."))])):E("",!0),t.activeTab==="overview"?(v(),b("section",{key:7,ref_key:"flowCardRef",ref:ka,class:le(["card card-flow",{"is-fullscreen":Oe.value}])},[o("div",eb,[n[142]||(n[142]=o("h2",null,"Flow Map",-1)),o("div",tb,[o("span",ab," Nodes "+A(la.value.nodes.length)+" | Links "+A(la.value.edges.length),1),o("button",{class:"secondary-button",type:"button",onClick:B},A(Oe.value?"Exit Fullscreen":"Fullscreen"),1)])]),o("div",nb,[o("label",sb,[n[143]||(n[143]=o("span",null,"Max nodes",-1)),ue(o("input",{"onUpdate:modelValue":n[26]||(n[26]=r=>t.flowMaxNodes=r),type:"number",min:"4",max:"32",step:"1"},null,512),[[Ne,t.flowMaxNodes,void 0,{number:!0}]])]),o("label",rb,[n[144]||(n[144]=o("span",null,"Find GA",-1)),ue(o("input",{"onUpdate:modelValue":n[27]||(n[27]=r=>t.flowSearch=r),type:"text",placeholder:"Search GA or label"},null,512),[[Ne,t.flowSearch]])]),o("div",ib,[n[146]||(n[146]=o("span",null,"Select Nodes to Filter by",-1)),ue(o("select",{"onUpdate:modelValue":n[28]||(n[28]=r=>t.flowSelectedGa=r),multiple:"",size:"5"},[(v(!0),b(J,null,oe(_l.value,r=>(v(),b("option",{key:r.id,value:r.id},A(`${r.id}${r.subtitle?` | ${r.subtitle}`:""}`),9,ob))),128))],512),[[Pa,t.flowSelectedGa]]),o("label",lb,[ue(o("input",{"onUpdate:modelValue":n[29]||(n[29]=r=>t.flowShowUniversalNodes=r),type:"checkbox"},null,512),[[ar,t.flowShowUniversalNodes]]),n[145]||(n[145]=o("span",null,"Show Universal Mode nodes",-1))])]),n[147]||(n[147]=fa('<div class="flow-legend" data-v-4f1ccfd9><span data-v-4f1ccfd9><i class="legend-line legend-write" data-v-4f1ccfd9></i>Write</span><span data-v-4f1ccfd9><i class="legend-line legend-response" data-v-4f1ccfd9></i>Response</span><span data-v-4f1ccfd9><i class="legend-line legend-read" data-v-4f1ccfd9></i>Read</span><span data-v-4f1ccfd9><i class="legend-line legend-repeat" data-v-4f1ccfd9></i>Repeat</span><span data-v-4f1ccfd9><i class="legend-dot legend-anomaly" data-v-4f1ccfd9></i>Anomaly</span><span data-v-4f1ccfd9><i class="legend-dot legend-external" data-v-4f1ccfd9></i>External</span></div>',1))]),o("div",db,[la.value.nodes.length?(v(),b("svg",{key:0,class:"flow-svg",viewBox:`0 0 ${la.value.width} ${la.value.height}`,preserveAspectRatio:"xMidYMid meet"},[o("defs",null,[(v(),b(J,null,oe(d,(r,u)=>o("marker",{id:`flow-arrow-${u}`,key:u,viewBox:"0 0 10 8",markerWidth:"10",markerHeight:"8",refX:"8.8",refY:"4",orient:"auto",markerUnits:"userSpaceOnUse"},[o("path",{d:"M0,0 L10,4 L0,8 z",fill:r},null,8,fb)],8,ub)),64))]),(v(!0),b(J,null,oe(la.value.edges,r=>(v(),b("path",{key:r.key,class:le(["flow-edge",{"flow-edge-active":r.active,"flow-edge-idle":!r.active}]),d:r.d,stroke:r.color,"stroke-width":r.width,opacity:r.opacity,"marker-end":`url(#${r.markerId})`},[o("title",null,A(r.tooltip),1)],10,pb))),128)),(v(!0),b(J,null,oe(la.value.nodes,r=>(v(),b("g",{key:r.id,class:le(["flow-node",{"is-anomaly":r.anomalyCount>0,"is-external":!r.inFlow,"is-idle":r.isIdle}])},[o("circle",{cx:r.x,cy:r.y,r:"24"},null,8,gb),o("text",{class:"node-label",x:r.x,y:r.y+1},A(r.shortLabel),9,hb),r.shortSubtitle?(v(),b("text",{key:0,class:"node-subtitle",x:r.x,y:r.y+38},A(r.shortSubtitle),9,mb)):E("",!0),r.shortPayload?(v(),b("text",{key:1,class:"node-payload",x:r.x,y:r.y+52},A(r.shortPayload),9,vb)):E("",!0),r.anomalyCount>0?(v(),b("text",{key:2,class:"node-badge",x:r.x,y:r.y-30},"anomaly x"+A(r.anomalyCount),9,bb)):E("",!0),o("title",null,A(`${r.id}${r.subtitle?` | ${r.subtitle}`:""}${r.payload?` | payload: ${r.payload}`:""}`),1)],2))),128))],8,cb)):(v(),b("p",yb,"No topology data available yet."))]),o("p",Ab,"Window "+A(la.value.telemetryWindowSec||0)+"s.",1)],2)):E("",!0),t.activeTab==="overview"?(v(),b("section",Sb,[o("div",wb,[n[148]||(n[148]=o("h2",null,"Anomalies",-1)),o("span",Tb,A(_s.value.length)+" recent",1)]),_s.value.length?(v(),b("div",Pb,[(v(!0),b(J,null,oe(_s.value.slice(0,20),r=>(v(),b("article",{key:`${r.at}-${kn(r).ga||""}`,class:"anomaly-card"},[o("div",_b,[o("strong",null,A(kn(r).type||"anomaly"),1),o("span",null,A(kn(r).ga||"no GA"),1)]),o("p",Cb,A(r.at||""),1),o("pre",null,A(JSON.stringify(kn(r),null,2)),1)]))),128))])):(v(),b("p",Ib,"No anomalies detected right now."))])):E("",!0),t.activeTab==="assistant"?(v(),b("section",Nb,[o("div",Rb,[n[149]||(n[149]=o("h2",null,"Ask",-1)),o("span",Db,A(pt.value.llmEnabled?"AI enabled":"AI disabled"),1)]),o("div",kb,[(v(!0),b(J,null,oe(Nl.value,r=>(v(),b("article",{key:r.key,class:le(["chat-message",`chat-${r.kind}`])},[r.kind==="assistant"?(v(),b("div",{key:0,innerHTML:r.html},null,8,xb)):(v(),b("pre",Eb,A(r.rawText),1))],2))),128)),t.asking?(v(),b("article",Lb,[...n[150]||(n[150]=[o("span",{class:"chat-pending-spinner","aria-hidden":"true"},null,-1),o("span",null,"Thinking...",-1)])])):E("",!0)]),o("div",Gb,[(v(!0),b(J,null,oe(Sl.value,r=>(v(),b("button",{key:r.key,class:"preset-button",type:"button",disabled:t.asking||!pt.value.llmEnabled,onClick:u=>zs(r.text)},A(r.text),9,Fb))),128))]),o("div",zb,[ue(o("input",{"onUpdate:modelValue":n[30]||(n[30]=r=>t.chatDraft=r),class:"ask-input",type:"text",disabled:t.asking||!pt.value.llmEnabled,placeholder:"Ask a question about KNX traffic...",onKeydown:n[31]||(n[31]=vf(Xt(r=>zs(),["prevent"]),["enter"]))},null,40,Ob),[[Ne,t.chatDraft]]),o("button",{class:"primary-button",type:"button",disabled:t.asking||!pt.value.llmEnabled,onClick:n[32]||(n[32]=r=>zs())}," Send ",8,Mb)])])):E("",!0),t.activeTab==="flowBuilder"?(v(),b("section",Bb,[o("div",$b,[n[151]||(n[151]=o("h2",null,[de("Flow Builder "),o("span",{class:"beta-badge"},"BETA")],-1)),o("span",Kb,A(pt.value.llmEnabled?"AI enabled":"AI disabled"),1)]),o("div",Vb,[o("div",jb,[n[152]||(n[152]=o("p",{class:"flow-builder-hint"}," Describe the automation in plain language. The AI generates a Node-RED flow using KNX Ultimate nodes, the Hue nodes and native Function/logic nodes, wired to your imported group addresses. Copy the JSON, then in Node-RED use Menu > Import and paste it. ",-1)),o("div",Ub,[ue(o("textarea",{"onUpdate:modelValue":n[33]||(n[33]=r=>t.flowBuilderPrompt=r),class:"flow-builder-textarea",rows:"6",disabled:t.flowBuilderGenerating||!pt.value.llmEnabled,placeholder:"e.g. When the Hue motion sensor in the living room detects movement, switch on the living room light."},null,8,Wb),[[Ne,t.flowBuilderPrompt]]),o("div",Hb,[o("button",{class:"primary-button",type:"button",disabled:t.flowBuilderGenerating||!pt.value.llmEnabled||!String(t.flowBuilderPrompt||"").trim(),onClick:n[34]||(n[34]=r=>Xl())},A(t.flowBuilderGenerating?"Generating...":"Generate flow"),9,Xb)])])]),o("div",qb,[t.flowBuilderGenerating?(v(),b("article",Jb,[...n[153]||(n[153]=[o("span",{class:"chat-pending-spinner","aria-hidden":"true"},null,-1),o("span",null,"Generating flow...",-1)])])):t.flowBuilderError?(v(),b("article",Zb,[o("pre",null,A(t.flowBuilderError),1)])):t.flowBuilderResult?(v(),b("div",Yb,[t.flowBuilderResult.notes?(v(),b("p",Qb,A(t.flowBuilderResult.notes),1)):E("",!0),t.flowBuilderResult.warnings&&t.flowBuilderResult.warnings.length?(v(),b("ul",ey,[(v(!0),b(J,null,oe(t.flowBuilderResult.warnings,(r,u)=>(v(),b("li",{key:u},A(r),1))),128))])):E("",!0),o("div",ty,[o("span",ay,A(t.flowBuilderResult.generation&&t.flowBuilderResult.generation.nodeCount||0)+" nodes",1),t.flowBuilderResult.generation&&t.flowBuilderResult.generation.model?(v(),b("span",ny,A(t.flowBuilderResult.generation.model),1)):E("",!0),o("button",{class:"secondary-button",type:"button",onClick:n[35]||(n[35]=r=>ql())},A(t.flowBuilderCopied?"Copied!":"Copy JSON"),1)]),o("pre",sy,A(t.flowBuilderResult.flowJson),1)])):(v(),b("p",ry,"The generated flow JSON will appear here."))])])])):E("",!0),t.activeTab==="settings"?(v(),b("section",iy,[n[165]||(n[165]=o("div",{class:"card-head"},[o("div",null,[o("h2",null,"Settings"),o("p",{class:"area-detail-subhead"},"Manage node options, shared CHAT learning and full configuration import/export.")])],-1)),o("div",oy,[o("button",{class:le(["settings-tab-button",{active:t.settingsTab==="node"}]),type:"button",onClick:n[36]||(n[36]=r=>Gs("node"))}," KNX AI Node ",2),o("button",{class:le(["settings-tab-button",{active:t.settingsTab==="config"}]),type:"button",onClick:n[37]||(n[37]=r=>Gs("config"))}," Import / Export ",2),o("button",{class:le(["settings-tab-button",{active:t.settingsTab==="learning"}]),type:"button",onClick:n[38]||(n[38]=r=>Gs("learning"))}," AI Chat Learning ",2)]),t.settingsTab==="node"?(v(),b("article",ly,[n[156]||(n[156]=o("div",{class:"card-head settings-panel-head"},[o("h3",null,"KNX AI Node"),o("span",{class:"meta-chip"},"Runtime preferences")],-1)),n[157]||(n[157]=o("p",{class:"area-detail-subhead"},"Select the node used by this UI and control refresh behavior.",-1)),o("div",dy,[o("label",cy,[n[154]||(n[154]=o("span",null,"Node",-1)),ue(o("select",{"onUpdate:modelValue":n[39]||(n[39]=r=>t.selectedNodeId=r),class:"node-select",onChange:Ml},[(v(!0),b(J,null,oe(t.nodes,r=>(v(),b("option",{key:r.id,value:r.id},A(`${r.name||"KNX AI"}${r.gatewayName?` | ${r.gatewayName}`:""}`),9,uy))),128))],544),[[Pa,t.selectedNodeId]])]),o("label",fy,[ue(o("input",{"onUpdate:modelValue":n[40]||(n[40]=r=>t.autoRefresh=r),type:"checkbox"},null,512),[[ar,t.autoRefresh]]),n[155]||(n[155]=o("span",null,"Auto refresh",-1))])])])):t.settingsTab==="config"?(v(),b("article",py,[n[158]||(n[158]=o("div",{class:"card-head settings-panel-head"},[o("h3",null,"Import / Export"),o("span",{class:"meta-chip"},"Full configuration")],-1)),n[159]||(n[159]=o("p",{class:"area-detail-subhead"},"Export or import the full KNX AI configuration for the selected node.",-1)),o("div",gy,[o("button",{class:"secondary-button",type:"button",disabled:!t.selectedNodeId,onClick:Od}," Export Configuration ",8,hy),o("button",{class:"secondary-button",type:"button",disabled:!t.selectedNodeId,onClick:Md}," Import Configuration ",8,my)])])):(v(),b("article",vy,[o("div",by,[n[161]||(n[161]=o("div",null,[o("h3",null,"AI Chat Learning"),o("p",{class:"area-detail-subhead"},"View, edit and back up the shared learning file used by every KNX AI node on this storage.")],-1)),o("div",yy,[o("span",Ay,[de(A(t.chatLearningSessionCount)+" ",1),n[160]||(n[160]=o("span",null,"sessions",-1))]),o("span",{class:le(["meta-chip",{"chat-learning-size-over":Ss.value}])},A(Rr(xr.value))+" / "+A(Rr(t.chatLearningMaxBytes)),3),qa.value?(v(),b("span",Sy,"Unsaved changes")):E("",!0)])]),n[163]||(n[163]=o("p",{class:"chat-learning-note"}," The native KNX AI records are authoritative and editable. Saving validates and replaces the live shared CHAT context immediately. ",-1)),n[164]||(n[164]=o("p",{class:"chat-learning-note"}," Only the current KNXAI_CHAT_CONTEXT 3 format is accepted. Previous Markdown/JSON and Base64 files are not read, imported or migrated. ",-1)),o("label",wy,[n[162]||(n[162]=o("span",null,"File path",-1)),o("code",null,A(t.chatLearningPath||"Loading chat learning..."),1)]),ue(o("textarea",{"onUpdate:modelValue":n[41]||(n[41]=r=>t.chatLearningContent=r),class:"chat-learning-editor",disabled:t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting||!t.selectedNodeId,spellcheck:"false","aria-label":"AI Chat Learning file"},null,8,Ty),[[Ne,t.chatLearningContent]]),t.chatLearningError?(v(),b("p",Py,A(t.chatLearningError),1)):E("",!0),o("div",_y,[o("button",{class:"secondary-button",type:"button",disabled:!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting,onClick:n[42]||(n[42]=r=>tn({force:!0}))},A(t.chatLearningLoading?"Loading...":"Reload from disk"),9,Cy),o("button",{class:"secondary-button",type:"button",disabled:!t.chatLearningContent||t.chatLearningResetting,onClick:jd},A(t.chatLearningCopied?"Copied!":"Copy"),9,Iy),o("button",{class:"secondary-button",type:"button",disabled:!t.chatLearningContent||t.chatLearningResetting,onClick:Ud}," Download Backup ",8,Ny),o("button",{class:"secondary-button",type:"button",disabled:!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting,onClick:Wd}," Restore Backup ",8,Ry),o("button",{class:"primary-button",type:"button",disabled:!t.selectedNodeId||!qa.value||Ss.value||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting,onClick:Kd},A(t.chatLearningSaving?"Saving...":"Save Changes"),9,Dy),o("button",{class:"danger-button",type:"button",disabled:!t.selectedNodeId||t.chatLearningLoading||t.chatLearningSaving||t.chatLearningResetting,onClick:Vd},A(t.chatLearningResetting?"Reinitializing...":"Reinitialize Memory"),9,ky)]),t.chatLearningModifiedAt?(v(),b("p",xy," Last saved: "+A(yt(t.chatLearningModifiedAt)),1)):E("",!0)])),o("input",{ref_key:"configImportRef",ref:we,type:"file",accept:"application/json,.json",class:"hidden-file-input",onChange:Bd},null,544),o("input",{ref_key:"chatLearningImportRef",ref:he,type:"file",accept:"text/plain,.knxctx",class:"hidden-file-input",onChange:Hd},null,544)])):E("",!0)])]),t.areaLlmRegenerating||t.areaLlmBulkDeleting||t.testPlanGenerating?(v(),b("div",Ey,[o("div",Ly,[n[166]||(n[166]=o("span",{class:"running-spinner global-wait-spinner","aria-hidden":"true"},null,-1)),o("strong",null,A(t.testPlanGenerating?"Building Test Plan":t.areaLlmBulkDeleting?"Deleting AI Areas":"Regenerating AI Areas"),1),o("span",null,A(t.testPlanGenerating?"Please wait while the template builder generates the test plan.":t.areaLlmBulkDeleting?"Please wait while AI-generated areas are removed.":"Please wait, this can take a while with large ETS projects."),1)])])):E("",!0),t.testPlanRunConfirmOpen?(v(),b("div",{key:1,class:"modal-backdrop",onClick:ri},[o("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"run-test-title",onClick:n[44]||(n[44]=Xt(()=>{},["stop"]))},[n[167]||(n[167]=o("h3",{id:"run-test-title"},"Start test?",-1)),o("p",Gy,A(t.testPlanRunMode==="repeat"?"This will send real telegrams on the KNX bus and repeat the selected test plan until you press Stop Repeat.":"This will send real telegrams on the KNX bus for the selected test plan."),1),o("div",Fy,[o("button",{class:"secondary-button",type:"button",autofocus:"",onClick:ri}," Cancel "),o("button",{class:"primary-button",type:"button",disabled:t.testPlanRunning,onClick:n[43]||(n[43]=r=>zd(t.testPlanRunMode))}," Start Test ",8,zy)])])])):E("",!0),t.testPlanUnsavedConfirmOpen?(v(),b("div",{key:2,class:"modal-backdrop",onClick:oi},[o("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"unsaved-plan-title",onClick:n[46]||(n[46]=Xt(()=>{},["stop"]))},[n[168]||(n[168]=o("h3",{id:"unsaved-plan-title"},"Unsaved changes",-1)),o("p",Oy,"Save or discard the current plan changes before opening "+A(t.testPlanPendingActionLabel||"another plan")+".",1),o("div",My,[o("button",{class:"secondary-button",type:"button",autofocus:"",onClick:oi}," Stay Here "),o("button",{class:"secondary-button",type:"button",onClick:n[45]||(n[45]=r=>{kd(),li()})}," Discard Changes "),o("button",{class:"primary-button",type:"button",disabled:t.testPlanSaving||!t.testPlanDraft,onClick:xd},A(t.testPlanSaving?"Saving...":"Save and Continue"),9,By)])])])):E("",!0),t.areaUnsavedConfirmOpen?(v(),b("div",{key:3,class:"modal-backdrop",onClick:qr},[o("div",{class:"modal-card",role:"dialog","aria-modal":"true","aria-labelledby":"unsaved-area-title",onClick:n[47]||(n[47]=Xt(()=>{},["stop"]))},[n[169]||(n[169]=o("h3",{id:"unsaved-area-title"},"Unsaved changes",-1)),n[170]||(n[170]=o("p",{class:"area-detail-subhead"},"Discard the current area changes and close the editor?",-1)),o("div",{class:"modal-actions"},[o("button",{class:"secondary-button",type:"button",autofocus:"",onClick:qr}," Stay Here "),o("button",{class:"primary-button",type:"button",onClick:Ul}," Discard and Close ")])])])):E("",!0)],2)],64))}},Hy=If(Wy,[["__scopeId","data-v-4f1ccfd9"]]);Af(Hy).mount("#app");export{_f as _};