c33fe57433
Behebung der drei kritischsten UX-Schwachstellen aus dem Produkt-Audit:
1. ConnectPanel: Steps 2-4 (Modellauswahl, Tool-Picker, Config-Snippet,
Vision) werden blockiert wenn noch kein Modell installiert ist.
Stattdessen klarer Hinweis "Erst im Cookbook ein Modell holen" mit
direktem CTA. Verhindert dass Anfänger ein Snippet mit Fake-"coder"
kopieren, bevor ein echtes Modell existiert.
2. OverviewPanel: preload() schluckte Fehler still (catch {}). Zeigt
jetzt einen verständlichen Toast wenn die Engine nicht erreichbar ist.
Schnellstart ist kontextsensitiv: ohne Modelle zeigt er Onboarding-
Schritte (Modell holen → Verbinden → Guide lesen) statt sinnloser
Aktionen wie "Speicher freigeben".
3. CookbookPanel Profi-Suche: doDownload() nutzte zwei sequenzielle
API-Calls (download + register) — wenn der zweite scheiterte, blieb
das System in einem inkonsistenten Halbzustand. Jetzt ein einziger
atomarer Aufruf an /api/cookbook/install-model (wie Recipe/Discover).
Backend-Erweiterung: InstallModelReq akzeptiert jetzt 'file' und
'ctx' um Nutzer-Auswahl direkt zu übergeben.
4. Cookbook Section 1 als "Hier starten" markiert ("1 · Anwendungsfall
wählen & installieren" mit erklärendem Sub-Text).
5. Post-Download-Toasts: Alle drei Install-Pfade sagen nun einheitlich
"Modell erscheint danach automatisch im Modelle-Tab" statt nur
"siehe Aktivität".
6. too_tight-Alternative: Bei Modellen/Setups die den Speicher übersteigen
wird jetzt eine konkrete Alternative (kleinere Datei / passendes Rezept)
verlinkt statt nur "Trotzdem installieren".
7. Duplikat extract_params_b aus cookbook.py entfernt — importiert jetzt
aus hw_math (Single Source of Truth).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
115 lines
143 KiB
JavaScript
115 lines
143 KiB
JavaScript
var rl=Object.defineProperty;var zi=e=>{throw TypeError(e)};var il=(e,t,n)=>t in e?rl(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ra=(e,t,n)=>il(e,typeof t!="symbol"?t+"":t,n),Vr=(e,t,n)=>t.has(e)||zi("Cannot "+n);var f=(e,t,n)=>(Vr(e,t,"read from private field"),n?n.call(e):t.get(e)),ce=(e,t,n)=>t.has(e)?zi("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),oe=(e,t,n,r)=>(Vr(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),Fe=(e,t,n)=>(Vr(e,t,"access private method"),n);var mi=Array.isArray,sl=Array.prototype.indexOf,$r=Array.prototype.includes,Rr=Array.from,ll=Object.defineProperty,Zn=Object.getOwnPropertyDescriptor,ol=Object.getOwnPropertyDescriptors,dl=Object.prototype,cl=Array.prototype,os=Object.getPrototypeOf,Di=Object.isExtensible;const vl=()=>{};function ul(e){for(var t=0;t<e.length;t++)e[t]()}function ds(){var e,t,n=new Promise((r,i)=>{e=r,t=i});return{promise:n,resolve:e,reject:t}}function sr(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);const n=[];for(const r of e)if(n.push(r),n.length===t)break;return n}const Ut=2,On=4,Br=8,cs=1<<24,xa=16,Ma=32,Xa=64,ri=128,pa=512,Pt=1024,Kt=2048,Da=4096,Qt=8192,ha=16384,Kn=32768,ii=1<<25,Rn=65536,Ar=1<<17,fl=1<<18,Gn=1<<19,pl=1<<20,Ca=1<<25,bn=65536,Cr=1<<21,Tn=1<<22,Za=1<<23,$n=Symbol("$state"),hl=Symbol(""),xr=Symbol("attributes"),si=Symbol("class"),li=Symbol("style"),Wn=Symbol("text"),kr=Symbol("form reset"),Ir=new class extends Error{constructor(){super(...arguments);ra(this,"name","StaleReactionError");ra(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};var rs;const gl=!!((rs=globalThis.document)!=null&&rs.contentType)&&globalThis.document.contentType.includes("xml");function vs(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function _l(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function ml(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function bl(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function yl(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function wl(e){throw new Error("https://svelte.dev/e/effect_orphan")}function xl(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function kl(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Ml(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Sl(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function El(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const Tl=1,$l=2,us=4,Al=8,Cl=16,Ll=1,zl=2,Dt=Symbol("uninitialized"),fs="http://www.w3.org/1999/xhtml",Dl="http://www.w3.org/2000/svg",Pl="http://www.w3.org/1998/Math/MathML";function ql(){console.warn("https://svelte.dev/e/derived_inert")}function Ol(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Rl(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function ps(e){return e===this.v}function Bl(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function hs(e){return!Bl(e,this.v)}let Gt=null;function Bn(e){Gt=e}function tn(e,t=!1,n){Gt={p:Gt,i:!1,c:null,e:null,s:e,x:null,r:Se,l:null}}function an(e){var t=Gt,n=t.e;if(n!==null){t.e=null;for(var r of n)Rs(r)}return t.i=!0,Gt=t.p,{}}function gs(){return!0}let sn=[];function _s(){var e=sn;sn=[],ul(e)}function hn(e){if(sn.length===0&&!er){var t=sn;queueMicrotask(()=>{t===sn&&_s()})}sn.push(e)}function Il(){for(;sn.length>0;)_s()}function ms(e){var t=Se;if(t===null)return ye.f|=Za,e;if((t.f&Kn)===0&&(t.f&On)===0)throw e;Ja(e,t)}function Ja(e,t){if(!(t!==null&&(t.f&ha)!==0)){for(;t!==null;){if((t.f&ri)!==0){if((t.f&Kn)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}}const Nl=-7169;function $t(e,t){e.f=e.f&Nl|t}function bi(e){(e.f&pa)!==0||e.deps===null?$t(e,Pt):$t(e,Da)}function bs(e){if(e!==null)for(const t of e)(t.f&Ut)===0||(t.f&bn)===0||(t.f^=bn,bs(t.deps))}function ys(e,t,n){(e.f&Kt)!==0?t.add(e):(e.f&Da)!==0&&n.add(e),bs(e.deps),$t(e,Pt)}function Fl(e){let t=0,n=wn(0),r;return()=>{Ei()&&(a(n),Nr(()=>(t===0&&(r=Un(()=>e(()=>tr(n)))),t+=1,()=>{hn(()=>{t-=1,t===0&&(r==null||r(),r=void 0,tr(n))})})))}}var Kl=Rn|Gn;function Gl(e,t,n,r){new Ul(e,t,n,r)}var da,_i,ca,cn,Xt,va,jt,sa,Ra,vn,ja,An,cr,vr,Ba,Pr,xt,Hl,Vl,Wl,oi,Mr,Sr,di,ci;class Ul{constructor(t,n,r,i){ce(this,xt);ra(this,"parent");ra(this,"is_pending",!1);ra(this,"transform_error");ce(this,da);ce(this,_i,null);ce(this,ca);ce(this,cn);ce(this,Xt);ce(this,va,null);ce(this,jt,null);ce(this,sa,null);ce(this,Ra,null);ce(this,vn,0);ce(this,ja,0);ce(this,An,!1);ce(this,cr,new Set);ce(this,vr,new Set);ce(this,Ba,null);ce(this,Pr,Fl(()=>(oe(this,Ba,wn(f(this,vn))),()=>{oe(this,Ba,null)})));var o;oe(this,da,t),oe(this,ca,n),oe(this,cn,d=>{var c=Se;c.b=this,c.f|=ri,r(d)}),this.parent=Se.b,this.transform_error=i??((o=this.parent)==null?void 0:o.transform_error)??(d=>d),oe(this,Xt,$i(()=>{Fe(this,xt,oi).call(this)},Kl))}defer_effect(t){ys(t,f(this,cr),f(this,vr))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!f(this,ca).pending}update_pending_count(t,n){Fe(this,xt,di).call(this,t,n),oe(this,vn,f(this,vn)+t),!(!f(this,Ba)||f(this,An))&&(oe(this,An,!0),hn(()=>{oe(this,An,!1),f(this,Ba)&&In(f(this,Ba),f(this,vn))}))}get_effect_pending(){return f(this,Pr).call(this),a(f(this,Ba))}error(t){if(!f(this,ca).onerror&&!f(this,ca).failed)throw t;j!=null&&j.is_fork?(f(this,va)&&j.skip_effect(f(this,va)),f(this,jt)&&j.skip_effect(f(this,jt)),f(this,sa)&&j.skip_effect(f(this,sa)),j.oncommit(()=>{Fe(this,xt,ci).call(this,t)})):Fe(this,xt,ci).call(this,t)}}da=new WeakMap,_i=new WeakMap,ca=new WeakMap,cn=new WeakMap,Xt=new WeakMap,va=new WeakMap,jt=new WeakMap,sa=new WeakMap,Ra=new WeakMap,vn=new WeakMap,ja=new WeakMap,An=new WeakMap,cr=new WeakMap,vr=new WeakMap,Ba=new WeakMap,Pr=new WeakMap,xt=new WeakSet,Hl=function(){try{oe(this,va,ua(()=>f(this,cn).call(this,f(this,da))))}catch(t){this.error(t)}},Vl=function(t){const n=f(this,ca).failed;n&&oe(this,sa,ua(()=>{n(f(this,da),()=>t,()=>()=>{})}))},Wl=function(){const t=f(this,ca).pending;t&&(this.is_pending=!0,oe(this,jt,ua(()=>t(f(this,da)))),hn(()=>{var n=oe(this,Ra,document.createDocumentFragment()),r=Fa();n.append(r),oe(this,va,Fe(this,xt,Sr).call(this,()=>ua(()=>f(this,cn).call(this,r)))),f(this,ja)===0&&(f(this,da).before(n),oe(this,Ra,null),_n(f(this,jt),()=>{oe(this,jt,null)}),Fe(this,xt,Mr).call(this,j))}))},oi=function(){try{if(this.is_pending=this.has_pending_snippet(),oe(this,ja,0),oe(this,vn,0),oe(this,va,ua(()=>{f(this,cn).call(this,f(this,da))})),f(this,ja)>0){var t=oe(this,Ra,document.createDocumentFragment());Ci(f(this,va),t);const n=f(this,ca).pending;oe(this,jt,ua(()=>n(f(this,da))))}else Fe(this,xt,Mr).call(this,j)}catch(n){this.error(n)}},Mr=function(t){this.is_pending=!1,t.transfer_effects(f(this,cr),f(this,vr))},Sr=function(t){var n=Se,r=ye,i=Gt;Pa(f(this,Xt)),ga(f(this,Xt)),Bn(f(this,Xt).ctx);try{return yn.ensure(),t()}catch(o){return ms(o),null}finally{Pa(n),ga(r),Bn(i)}},di=function(t,n){var r;if(!this.has_pending_snippet()){this.parent&&Fe(r=this.parent,xt,di).call(r,t,n);return}oe(this,ja,f(this,ja)+t),f(this,ja)===0&&(Fe(this,xt,Mr).call(this,n),f(this,jt)&&_n(f(this,jt),()=>{oe(this,jt,null)}),f(this,Ra)&&(f(this,da).before(f(this,Ra)),oe(this,Ra,null)))},ci=function(t){f(this,va)&&(aa(f(this,va)),oe(this,va,null)),f(this,jt)&&(aa(f(this,jt)),oe(this,jt,null)),f(this,sa)&&(aa(f(this,sa)),oe(this,sa,null));var n=f(this,ca).onerror;let r=f(this,ca).failed;var i=!1,o=!1;const d=()=>{if(i){Rl();return}i=!0,o&&El(),f(this,sa)!==null&&_n(f(this,sa),()=>{oe(this,sa,null)}),Fe(this,xt,Sr).call(this,()=>{Fe(this,xt,oi).call(this)})},c=v=>{try{o=!0,n==null||n(v,d),o=!1}catch(u){Ja(u,f(this,Xt)&&f(this,Xt).parent)}r&&oe(this,sa,Fe(this,xt,Sr).call(this,()=>{try{return ua(()=>{var u=Se;u.b=this,u.f|=ri,r(f(this,da),()=>v,()=>d)})}catch(u){return Ja(u,f(this,Xt).parent),null}}))};hn(()=>{var v;try{v=this.transform_error(t)}catch(u){Ja(u,f(this,Xt)&&f(this,Xt).parent);return}v!==null&&typeof v=="object"&&typeof v.then=="function"?v.then(c,u=>Ja(u,f(this,Xt)&&f(this,Xt).parent)):c(v)})};function jl(e,t,n,r){const i=yi;var o=e.filter(x=>!x.settled),d=t.map(i);if(n.length===0&&o.length===0){r(d);return}var c=Se,v=Ql(),u=o.length===1?o[0].promise:o.length>1?Promise.all(o.map(x=>x.promise)):null;function h(x){if((c.f&ha)===0){v();try{r([...d,...x])}catch($){Ja($,c)}Lr()}}var E=ws();if(n.length===0){u.then(()=>h([])).finally(E);return}function p(){Promise.all(n.map(x=>Jl(x))).then(h).catch(x=>Ja(x,c)).finally(E)}u?u.then(()=>{v(),p(),Lr()}):p()}function Ql(){var e=Se,t=ye,n=Gt,r=j;return function(o=!0){Pa(e),ga(t),Bn(n),o&&(e.f&ha)===0&&(r==null||r.activate(),r==null||r.apply())}}function Lr(e=!0){Pa(null),ga(null),Bn(null),e&&(j==null||j.deactivate())}function ws(){var e=Se,t=e.b,n=j,r=!!(t!=null&&t.is_rendered());return t==null||t.update_pending_count(1,n),n.increment(r,e),()=>{t==null||t.update_pending_count(-1,n),n.decrement(r,e)}}function yi(e){var t=Ut|Kt;return Se!==null&&(Se.f|=Gn),{ctx:Gt,deps:null,effects:null,equals:ps,f:t,fn:e,reactions:null,rv:0,v:Dt,wv:0,parent:Se,ac:null}}const jn=Symbol("obsolete");function Jl(e,t,n){let r=Se;r===null&&_l();var i=void 0,o=wn(Dt),d=!ye,c=new Set;return po(()=>{var x,$;var v=Se,u=ds();i=u.promise;try{Promise.resolve(e()).then(u.resolve,L=>{L!==Ir&&u.reject(L)}).finally(Lr)}catch(L){u.reject(L),Lr()}var h=j;if(d){if((v.f&Kn)!==0)var E=ws();if((x=r.b)!=null&&x.is_rendered())($=h.async_deriveds.get(v))==null||$.reject(jn);else for(const L of c.values())L.reject(jn);c.add(u),h.async_deriveds.set(v,u)}const p=(L,k=void 0)=>{E==null||E(),c.delete(u),k!==jn&&(h.activate(),k?(o.f|=Za,In(o,k)):((o.f&Za)!==0&&(o.f^=Za),In(o,L)),h.deactivate())};u.promise.then(p,L=>p(null,L||"unknown"))}),Os(()=>{for(const v of c)v.reject(jn)}),new Promise(v=>{function u(h){function E(){h===i?v(o):u(i)}h.then(E,E)}u(i)})}function q(e){const t=yi(e);return Us(t),t}function Yl(e){const t=yi(e);return t.equals=hs,t}function Zl(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)aa(t[n])}}function wi(e){var t,n=Se,r=e.parent;if(!en&&r!==null&&e.v!==Dt&&(r.f&(ha|Qt))!==0)return ql(),e.v;Pa(r);try{e.f&=~bn,Zl(e),t=js(e)}finally{Pa(n)}return t}function xs(e){var t=wi(e);if(!e.equals(t)&&(e.wv=Vs(),(!(j!=null&&j.is_fork)||e.deps===null)&&(j!==null?(j.capture(e,t,!0),Xn==null||Xn.capture(e,t,!0)):e.v=t,e.deps===null))){$t(e,Pt);return}en||(Ft!==null?(Ei()||j!=null&&j.is_fork)&&Ft.set(e,t):bi(e))}function Xl(e){var t,n;if(e.effects!==null)for(const r of e.effects)(r.teardown||r.ac)&&((t=r.teardown)==null||t.call(r),(n=r.ac)==null||n.abort(Ir),r.fn!==null&&(r.teardown=vl),r.ac=null,lr(r,0),Ai(r))}function ks(e){if(e.effects!==null)for(const t of e.effects)t.teardown&&t.fn!==null&&Nn(t)}let Wr=null,Mn=null,j=null,Xn=null,Ft=null,vi=null,er=!1,jr=!1,En=null,Er=null;var Pi=0;let eo=1;var Cn,Qa,un,Ln,zn,Dn,Ia,Pn,ea,ur,Na,ba,$a,qn,fn,je,ui,Qn,fi,Ms,Ss,Sn,to,Jn;const qr=class qr{constructor(){ce(this,je);ra(this,"id",eo++);ce(this,Cn,!1);ra(this,"linked",!0);ce(this,Qa,null);ce(this,un,null);ra(this,"async_deriveds",new Map);ra(this,"current",new Map);ra(this,"previous",new Map);ce(this,Ln,new Set);ce(this,zn,new Set);ce(this,Dn,0);ce(this,Ia,new Map);ce(this,Pn,null);ce(this,ea,[]);ce(this,ur,[]);ce(this,Na,new Set);ce(this,ba,new Set);ce(this,$a,new Map);ce(this,qn,new Set);ra(this,"is_fork",!1);ce(this,fn,!1);Mn===null?Wr=Mn=this:(oe(Mn,un,this),oe(this,Qa,Mn)),Mn=this}skip_effect(t){f(this,$a).has(t)||f(this,$a).set(t,{d:[],m:[]}),f(this,qn).delete(t)}unskip_effect(t,n=r=>this.schedule(r)){var r=f(this,$a).get(t);if(r){f(this,$a).delete(t);for(var i of r.d)$t(i,Kt),n(i);for(i of r.m)$t(i,Da),n(i)}f(this,qn).add(t)}capture(t,n,r=!1){t.v!==Dt&&!this.previous.has(t)&&this.previous.set(t,t.v),(t.f&Za)===0&&(this.current.set(t,[n,r]),Ft==null||Ft.set(t,n)),this.is_fork||(t.v=n)}activate(){j=this}deactivate(){j=null,Ft=null}flush(){try{jr=!0,j=this,Fe(this,je,Qn).call(this)}finally{Pi=0,vi=null,En=null,Er=null,jr=!1,j=null,Ft=null,gn.clear()}}discard(){var t;for(const n of f(this,zn))n(this);f(this,zn).clear();for(const n of this.async_deriveds.values())n.reject(jn);Fe(this,je,Jn).call(this),(t=f(this,Pn))==null||t.resolve()}register_created_effect(t){f(this,ur).push(t)}increment(t,n){if(oe(this,Dn,f(this,Dn)+1),t){let r=f(this,Ia).get(n)??0;f(this,Ia).set(n,r+1)}}decrement(t,n){if(oe(this,Dn,f(this,Dn)-1),t){let r=f(this,Ia).get(n)??0;r===1?f(this,Ia).delete(n):f(this,Ia).set(n,r-1)}f(this,fn)||(oe(this,fn,!0),hn(()=>{oe(this,fn,!1),this.linked&&this.flush()}))}transfer_effects(t,n){for(const r of t)f(this,Na).add(r);for(const r of n)f(this,ba).add(r);t.clear(),n.clear()}oncommit(t){f(this,Ln).add(t)}ondiscard(t){f(this,zn).add(t)}settled(){return(f(this,Pn)??oe(this,Pn,ds())).promise}static ensure(){if(j===null){const t=j=new qr;!jr&&!er&&hn(()=>{f(t,Cn)||t.flush()})}return j}apply(){{Ft=null;return}}schedule(t){var i;if(vi=t,(i=t.b)!=null&&i.is_pending&&(t.f&(On|Br|cs))!==0&&(t.f&Kn)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(En!==null&&n===Se&&(ye===null||(ye.f&Ut)===0))return;if((r&(Xa|Ma))!==0){if((r&Pt)===0)return;n.f^=Pt}}f(this,ea).push(n)}};Cn=new WeakMap,Qa=new WeakMap,un=new WeakMap,Ln=new WeakMap,zn=new WeakMap,Dn=new WeakMap,Ia=new WeakMap,Pn=new WeakMap,ea=new WeakMap,ur=new WeakMap,Na=new WeakMap,ba=new WeakMap,$a=new WeakMap,qn=new WeakMap,fn=new WeakMap,je=new WeakSet,ui=function(){if(this.is_fork)return!0;for(const r of f(this,Ia).keys()){for(var t=r,n=!1;t.parent!==null;){if(f(this,$a).has(t)){n=!0;break}t=t.parent}if(!n)return!0}return!1},Qn=function(){var v,u,h,E;oe(this,Cn,!0),Pi++>1e3&&(Fe(this,je,Jn).call(this),no());for(const p of f(this,Na))f(this,ba).delete(p),$t(p,Kt),this.schedule(p);for(const p of f(this,ba))$t(p,Da),this.schedule(p);const t=f(this,ea);oe(this,ea,[]),this.apply();var n=En=[],r=[],i=Er=[];for(const p of t)try{Fe(this,je,fi).call(this,p,n,r)}catch(x){throw $s(p),Fe(this,je,ui).call(this)||this.discard(),x}if(j=null,i.length>0){var o=qr.ensure();for(const p of i)o.schedule(p)}if(En=null,Er=null,Fe(this,je,ui).call(this)){Fe(this,je,Sn).call(this,r),Fe(this,je,Sn).call(this,n);for(const[p,x]of f(this,$a))Ts(p,x);i.length>0&&Fe(v=j,je,Qn).call(v);return}const d=Fe(this,je,Ms).call(this);if(d){Fe(this,je,Sn).call(this,r),Fe(this,je,Sn).call(this,n),Fe(u=d,je,Ss).call(u,this);return}f(this,Na).clear(),f(this,ba).clear();for(const p of f(this,Ln))p(this);f(this,Ln).clear(),Xn=this,qi(r),qi(n),Xn=null,(h=f(this,Pn))==null||h.resolve();var c=j;if(f(this,Dn)===0&&(f(this,ea).length===0||c!==null)&&Fe(this,je,Jn).call(this),f(this,ea).length>0)if(c!==null){const p=c;f(p,ea).push(...f(this,ea).filter(x=>!f(p,ea).includes(x)))}else c=this;c!==null&&Fe(E=c,je,Qn).call(E)},fi=function(t,n,r){t.f^=Pt;for(var i=t.first;i!==null;){var o=i.f,d=(o&(Ma|Xa))!==0,c=d&&(o&Pt)!==0,v=c||(o&Qt)!==0||f(this,$a).has(i);if(!v&&i.fn!==null){d?i.f^=Pt:(o&On)!==0?n.push(i):gr(i)&&((o&xa)!==0&&f(this,ba).add(i),Nn(i));var u=i.first;if(u!==null){i=u;continue}}for(;i!==null;){var h=i.next;if(h!==null){i=h;break}i=i.parent}}},Ms=function(){for(var t=f(this,Qa);t!==null;){if(!t.is_fork){for(const[n,[,r]]of this.current)if(t.current.has(n)&&!r)return t}t=f(t,Qa)}return null},Ss=function(t){var r;for(const[i,o]of t.current)!this.previous.has(i)&&t.previous.has(i)&&this.previous.set(i,t.previous.get(i)),this.current.set(i,o);for(const[i,o]of t.async_deriveds){const d=this.async_deriveds.get(i);d&&o.promise.then(d.resolve).catch(d.reject)}t.async_deriveds.clear(),this.transfer_effects(f(t,Na),f(t,ba));const n=i=>{var o=i.reactions;if(o!==null)for(const v of o){var d=v.f;if((d&Ut)!==0)n(v);else{var c=v;d&(Tn|xa)&&!this.async_deriveds.has(c)&&(f(this,ba).delete(c),$t(c,Kt),this.schedule(c))}}};for(const i of this.current.keys())n(i);this.oncommit(()=>t.discard()),Fe(r=t,je,Jn).call(r),j=this,Fe(this,je,Qn).call(this)},Sn=function(t){for(var n=0;n<t.length;n+=1)ys(t[n],f(this,Na),f(this,ba))},to=function(){var E;for(let p=Wr;p!==null;p=f(p,un)){var t=p.id<this.id,n=[];for(const[x,[$,L]]of this.current){if(p.current.has(x)){var r=p.current.get(x)[0];if(t&&$!==r)p.current.set(x,[$,L]);else continue}n.push(x)}if(t)for(const[x,$]of this.async_deriveds){const L=p.async_deriveds.get(x);L&&$.promise.then(L.resolve).catch(L.reject)}var i=[...p.current.keys()].filter(x=>!p.current.get(x)[1]);if(!(!f(p,Cn)||i.length===0)){var o=i.filter(x=>!this.current.has(x));if(o.length===0)t&&p.discard();else if(n.length>0){if(t)for(const x of f(this,qn))p.unskip_effect(x,$=>{var L;($.f&(xa|Tn))!==0?p.schedule($):Fe(L=p,je,Sn).call(L,[$])});p.activate();var d=new Set,c=new Map;for(var v of n)Es(v,o,d,c);c=new Map;var u=[...p.current].filter(([x,$])=>{const L=this.current.get(x);return L?L[0]!==$[0]||L[1]!==$[1]:!0}).map(([x])=>x);if(u.length>0)for(const x of f(this,ur))(x.f&(ha|Qt|Ar))===0&&xi(x,u,c)&&((x.f&(Tn|xa))!==0?($t(x,Kt),p.schedule(x)):f(p,Na).add(x));if(f(p,ea).length>0&&!f(p,fn)){p.apply();for(var h of f(p,ea))Fe(E=p,je,fi).call(E,h,[],[]);oe(p,ea,[])}p.deactivate()}}}},Jn=function(){if(this.linked){var t=f(this,Qa),n=f(this,un);t===null?Wr=n:oe(t,un,n),n===null?Mn=t:oe(n,Qa,t),this.linked=!1}};let yn=qr;function ao(e){var t=er;er=!0;try{for(var n;;){if(Il(),j===null)return n;j.flush()}}finally{er=t}}function no(){try{xl()}catch(e){Ja(e,vi)}}let ma=null;function qi(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if((r.f&(ha|Qt))===0&&gr(r)&&(ma=new Set,Nn(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&Fs(r),(ma==null?void 0:ma.size)>0)){gn.clear();for(const i of ma){if((i.f&(ha|Qt))!==0)continue;const o=[i];let d=i.parent;for(;d!==null;)ma.has(d)&&(ma.delete(d),o.push(d)),d=d.parent;for(let c=o.length-1;c>=0;c--){const v=o[c];(v.f&(ha|Qt))===0&&Nn(v)}}ma.clear()}}ma=null}}function Es(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const i of e.reactions){const o=i.f;(o&Ut)!==0?Es(i,t,n,r):(o&(Tn|xa))!==0&&(o&Kt)===0&&xi(i,t,r)&&($t(i,Kt),ki(i))}}function xi(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const i of e.deps){if($r.call(t,i))return!0;if((i.f&Ut)!==0&&xi(i,t,n))return n.set(i,!0),!0}return n.set(e,!1),!1}function ki(e){j.schedule(e)}function Ts(e,t){if(!((e.f&Ma)!==0&&(e.f&Pt)!==0)){(e.f&Kt)!==0?t.d.push(e):(e.f&Da)!==0&&t.m.push(e),$t(e,Pt);for(var n=e.first;n!==null;)Ts(n,t),n=n.next}}function $s(e){$t(e,Pt);for(var t=e.first;t!==null;)$s(t),t=t.next}let zr=new Set;const gn=new Map;let As=!1;function wn(e,t){var n={f:0,v:e,reactions:null,equals:ps,rv:0,wv:0};return n}function O(e,t){const n=wn(e);return Us(n),n}function ro(e,t=!1,n=!0){const r=wn(e);return t||(r.equals=hs),r}function g(e,t,n=!1){ye!==null&&(!ka||(ye.f&Ar)!==0)&&gs()&&(ye.f&(Ut|xa|Tn|Ar))!==0&&(La===null||!La.has(e))&&Sl();let r=n?Ht(t):t;return In(e,r,Er)}function In(e,t,n=null){if(!e.equals(t)){gn.set(e,en?t:e.v);var r=yn.ensure();if(r.capture(e,t),(e.f&Ut)!==0){const i=e;(e.f&Kt)!==0&&wi(i),Ft===null&&bi(i)}e.wv=Vs(),Cs(e,Kt,n),Se!==null&&(Se.f&Pt)!==0&&(Se.f&(Ma|Xa))===0&&(oa===null?go([e]):oa.push(e)),!r.is_fork&&zr.size>0&&!As&&io()}return t}function io(){As=!1;for(const e of zr){(e.f&Pt)!==0&&$t(e,Da);let t;try{t=gr(e)}catch{t=!0}t&&Nn(e)}zr.clear()}function tr(e){g(e,e.v+1)}function Cs(e,t,n){var r=e.reactions;if(r!==null)for(var i=r.length,o=0;o<i;o++){var d=r[o],c=d.f,v=(c&Kt)===0;if(v&&$t(d,t),(c&Ar)!==0)zr.add(d);else if((c&Ut)!==0){var u=d;Ft==null||Ft.delete(u),(c&bn)===0&&(c&pa&&(Se===null||(Se.f&Cr)===0)&&(d.f|=bn),Cs(u,Da,n))}else if(v){var h=d;(c&xa)!==0&&ma!==null&&ma.add(h),n!==null?n.push(h):ki(h)}}}function Ht(e){if(typeof e!="object"||e===null||$n in e)return e;const t=os(e);if(t!==dl&&t!==cl)return e;var n=new Map,r=mi(e),i=O(0),o=mn,d=c=>{if(mn===o)return c();var v=ye,u=mn;ga(null),Ni(o);var h=c();return ga(v),Ni(u),h};return r&&n.set("length",O(e.length)),new Proxy(e,{defineProperty(c,v,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&kl();var h=n.get(v);return h===void 0?d(()=>{var E=O(u.value);return n.set(v,E),E}):g(h,u.value,!0),!0},deleteProperty(c,v){var u=n.get(v);if(u===void 0){if(v in c){const h=d(()=>O(Dt));n.set(v,h),tr(i)}}else g(u,Dt),tr(i);return!0},get(c,v,u){var x;if(v===$n)return e;var h=n.get(v),E=v in c;if(h===void 0&&(!E||(x=Zn(c,v))!=null&&x.writable)&&(h=d(()=>{var $=Ht(E?c[v]:Dt),L=O($);return L}),n.set(v,h)),h!==void 0){var p=a(h);return p===Dt?void 0:p}return Reflect.get(c,v,u)},getOwnPropertyDescriptor(c,v){var u=Reflect.getOwnPropertyDescriptor(c,v);if(u&&"value"in u){var h=n.get(v);h&&(u.value=a(h))}else if(u===void 0){var E=n.get(v),p=E==null?void 0:E.v;if(E!==void 0&&p!==Dt)return{enumerable:!0,configurable:!0,value:p,writable:!0}}return u},has(c,v){var p;if(v===$n)return!0;var u=n.get(v),h=u!==void 0&&u.v!==Dt||Reflect.has(c,v);if(u!==void 0||Se!==null&&(!h||(p=Zn(c,v))!=null&&p.writable)){u===void 0&&(u=d(()=>{var x=h?Ht(c[v]):Dt,$=O(x);return $}),n.set(v,u));var E=a(u);if(E===Dt)return!1}return h},set(c,v,u,h){var ne;var E=n.get(v),p=v in c;if(r&&v==="length")for(var x=u;x<E.v;x+=1){var $=n.get(x+"");$!==void 0?g($,Dt):x in c&&($=d(()=>O(Dt)),n.set(x+"",$))}if(E===void 0)(!p||(ne=Zn(c,v))!=null&&ne.writable)&&(E=d(()=>O(void 0)),g(E,Ht(u)),n.set(v,E));else{p=E.v!==Dt;var L=d(()=>Ht(u));g(E,L)}var k=Reflect.getOwnPropertyDescriptor(c,v);if(k!=null&&k.set&&k.set.call(h,u),!p){if(r&&typeof v=="string"){var D=n.get("length"),Pe=Number(v);Number.isInteger(Pe)&&Pe>=D.v&&g(D,Pe+1)}tr(i)}return!0},ownKeys(c){a(i);var v=Reflect.ownKeys(c).filter(E=>{var p=n.get(E);return p===void 0||p.v!==Dt});for(var[u,h]of n)h.v!==Dt&&!(u in c)&&v.push(u);return v},setPrototypeOf(){Ml()}})}function Oi(e){try{if(e!==null&&typeof e=="object"&&$n in e)return e[$n]}catch{}return e}function so(e,t){return Object.is(Oi(e),Oi(t))}var Ri,Ls,zs,Ds;function lo(){if(Ri===void 0){Ri=window,Ls=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;zs=Zn(t,"firstChild").get,Ds=Zn(t,"nextSibling").get,Di(e)&&(e[si]=void 0,e[xr]=null,e[li]=void 0,e.__e=void 0),Di(n)&&(n[Wn]=void 0)}}function Fa(e=""){return document.createTextNode(e)}function Ya(e){return zs.call(e)}function hr(e){return Ds.call(e)}function l(e,t){return Ya(e)}function ot(e,t=!1){{var n=Ya(e);return n instanceof Comment&&n.data===""?hr(n):n}}function s(e,t=1,n=!1){let r=e;for(;t--;)r=hr(r);return r}function oo(e){e.textContent=""}function Ps(){return!1}function qs(e,t,n){return t==null||t===fs?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}let Bi=!1;function co(){Bi||(Bi=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{var t;if(!e.defaultPrevented)for(const n of e.target.elements)(t=n[kr])==null||t.call(n)})},{capture:!0}))}function Mi(e){var t=ye,n=Se;ga(null),Pa(null);try{return e()}finally{ga(t),Pa(n)}}function Si(e,t,n,r=n){e.addEventListener(t,()=>Mi(n));const i=e[kr];i?e[kr]=()=>{i(),r(!0)}:e[kr]=()=>r(!0),co()}function vo(e){Se===null&&(ye===null&&wl(),yl()),en&&bl()}function uo(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Ka(e,t){var n=Se;n!==null&&(n.f&Qt)!==0&&(e|=Qt);var r={ctx:Gt,deps:null,nodes:null,f:e|Kt|pa,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};j==null||j.register_created_effect(r);var i=r;if((e&On)!==0)En!==null?En.push(r):yn.ensure().schedule(r);else if(t!==null){try{Nn(r)}catch(d){throw aa(r),d}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&(i.f&Gn)===0&&(i=i.first,(e&xa)!==0&&(e&Rn)!==0&&i!==null&&(i.f|=Rn))}if(i!==null&&(i.parent=n,n!==null&&uo(i,n),ye!==null&&(ye.f&Ut)!==0&&(e&Xa)===0)){var o=ye;(o.effects??(o.effects=[])).push(i)}return r}function Ei(){return ye!==null&&!ka}function Os(e){const t=Ka(Br,null);return $t(t,Pt),t.teardown=e,t}function Ti(e){vo();var t=Se.f,n=!ye&&(t&Ma)!==0&&Gt!==null&&!Gt.i;if(n){var r=Gt;(r.e??(r.e=[])).push(e)}else return Rs(e)}function Rs(e){return Ka(On|pl,e)}function fo(e){yn.ensure();const t=Ka(Xa|Gn,e);return(n={})=>new Promise(r=>{n.outro?_n(t,()=>{aa(t),r(void 0)}):(aa(t),r(void 0))})}function Bs(e){return Ka(On,e)}function po(e){return Ka(Tn|Gn,e)}function Nr(e,t=0){return Ka(Br|t,e)}function z(e,t=[],n=[],r=[]){jl(r,t,n,i=>{Ka(Br,()=>{e(...i.map(a))})})}function $i(e,t=0){var n=Ka(xa|t,e);return n}function ua(e){return Ka(Ma|Gn,e)}function Is(e){var t=e.teardown;if(t!==null){const n=en,r=ye;Ii(!0),ga(null);try{t.call(null)}finally{Ii(n),ga(r)}}}function Ai(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const i=n.ac;i!==null&&Mi(()=>{i.abort(Ir)});var r=n.next;(n.f&Xa)!==0?n.parent=null:aa(n,t),n=r}}function ho(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&Ma)===0&&aa(t),t=n}}function aa(e,t=!0){var n=!1;(t||(e.f&fl)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Ns(e.nodes.start,e.nodes.end),n=!0),e.f|=ii,Ai(e,t&&!n),lr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const o of r)o.stop();Is(e),e.f^=ii,e.f|=ha;var i=e.parent;i!==null&&i.first!==null&&Fs(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Ns(e,t){for(;e!==null;){var n=e===t?null:hr(e);e.remove(),e=n}}function Fs(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function _n(e,t,n=!0){var r=[];Ks(e,r,!0);var i=()=>{n&&aa(e),t&&t()},o=r.length;if(o>0){var d=()=>--o||i();for(var c of r)c.out(d)}else i()}function Ks(e,t,n){if((e.f&Qt)===0){e.f^=Qt;var r=e.nodes&&e.nodes.t;if(r!==null)for(const c of r)(c.is_global||n)&&t.push(c);for(var i=e.first;i!==null;){var o=i.next;if((i.f&Xa)===0){var d=(i.f&Rn)!==0||(i.f&Ma)!==0&&(e.f&xa)!==0;Ks(i,t,d?n:!1)}i=o}}}function Dr(e){Gs(e,!0)}function Gs(e,t){if((e.f&Qt)!==0){e.f^=Qt,(e.f&Pt)===0&&($t(e,Kt),yn.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=(n.f&Rn)!==0||(n.f&Ma)!==0;Gs(n,i?t:!1),n=r}var o=e.nodes&&e.nodes.t;if(o!==null)for(const d of o)(d.is_global||t)&&d.in()}}function Ci(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:hr(n);t.append(n),n=i}}let Tr=!1,en=!1;function Ii(e){en=e}let ye=null,ka=!1;function ga(e){ye=e}let Se=null;function Pa(e){Se=e}let La=null;function Us(e){ye!==null&&(La??(La=new Set)).add(e)}let ta=null,ia=0,oa=null;function go(e){oa=e}let Hs=1,ln=0,mn=ln;function Ni(e){mn=e}function Vs(){return++Hs}function gr(e){var t=e.f;if((t&Kt)!==0)return!0;if(t&Ut&&(e.f&=~bn),(t&Da)!==0){for(var n=e.deps,r=n.length,i=0;i<r;i++){var o=n[i];if(gr(o)&&xs(o),o.wv>e.wv)return!0}(t&pa)!==0&&Ft===null&&$t(e,Pt)}return!1}function Ws(e,t,n=!0){var r=e.reactions;if(r!==null&&!(La!==null&&La.has(e)))for(var i=0;i<r.length;i++){var o=r[i];(o.f&Ut)!==0?Ws(o,t,!1):t===o&&(n?$t(o,Kt):(o.f&Pt)!==0&&$t(o,Da),ki(o))}}function js(e){var L;var t=ta,n=ia,r=oa,i=ye,o=La,d=Gt,c=ka,v=mn,u=e.f;ta=null,ia=0,oa=null,ye=(u&(Ma|Xa))===0?e:null,La=null,Bn(e.ctx),ka=!1,mn=++ln,e.ac!==null&&(Mi(()=>{e.ac.abort(Ir)}),e.ac=null);try{e.f|=Cr;var h=e.fn,E=h();e.f|=Kn;var p=e.deps,x=j==null?void 0:j.is_fork;if(ta!==null){var $;if(x||lr(e,ia),p!==null&&ia>0)for(p.length=ia+ta.length,$=0;$<ta.length;$++)p[ia+$]=ta[$];else e.deps=p=ta;if(Ei()&&(e.f&pa)!==0)for($=ia;$<p.length;$++)((L=p[$]).reactions??(L.reactions=[])).push(e)}else!x&&p!==null&&ia<p.length&&(lr(e,ia),p.length=ia);if(gs()&&oa!==null&&!ka&&p!==null&&(e.f&(Ut|Da|Kt))===0)for($=0;$<oa.length;$++)Ws(oa[$],e);if(i!==null&&i!==e){if(ln++,i.deps!==null)for(let k=0;k<n;k+=1)i.deps[k].rv=ln;if(t!==null)for(const k of t)k.rv=ln;oa!==null&&(r===null?r=oa:r.push(...oa))}return(e.f&Za)!==0&&(e.f^=Za),E}catch(k){return ms(k)}finally{e.f^=Cr,ta=t,ia=n,oa=r,ye=i,La=o,Bn(d),ka=c,mn=v}}function _o(e,t){let n=t.reactions;if(n!==null){var r=sl.call(n,e);if(r!==-1){var i=n.length-1;i===0?n=t.reactions=null:(n[r]=n[i],n.pop())}}if(n===null&&(t.f&Ut)!==0&&(ta===null||!$r.call(ta,t))){var o=t;(o.f&pa)!==0&&(o.f^=pa,o.f&=~bn),o.v!==Dt&&bi(o),Xl(o),lr(o,0)}}function lr(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)_o(e,n[r])}function Nn(e){var t=e.f;if((t&ha)===0){$t(e,Pt);var n=Se,r=Tr;Se=e,Tr=!0;try{(t&(xa|cs))!==0?ho(e):Ai(e),Is(e);var i=js(e);e.teardown=typeof i=="function"?i:null,e.wv=Hs;var o}finally{Tr=r,Se=n}}}async function mo(){await Promise.resolve(),ao()}function a(e){var t=e.f,n=(t&Ut)!==0;if(ye!==null&&!ka){var r=Se!==null&&(Se.f&ha)!==0;if(!r&&(La===null||!La.has(e))){var i=ye.deps;if((ye.f&Cr)!==0)e.rv<ln&&(e.rv=ln,ta===null&&i!==null&&i[ia]===e?ia++:ta===null?ta=[e]:ta.push(e));else{ye.deps??(ye.deps=[]),$r.call(ye.deps,e)||ye.deps.push(e);var o=e.reactions;o===null?e.reactions=[ye]:$r.call(o,ye)||o.push(ye)}}}if(en&&gn.has(e))return gn.get(e);if(n){var d=e;if(en){var c=d.v;return((d.f&Pt)===0&&d.reactions!==null||Js(d))&&(c=wi(d)),gn.set(d,c),c}var v=(d.f&pa)===0&&!ka&&ye!==null&&(Tr||(ye.f&pa)!==0),u=(d.f&Kn)===0;gr(d)&&(v&&(d.f|=pa),xs(d)),v&&!u&&(ks(d),Qs(d))}if(Ft!=null&&Ft.has(e))return Ft.get(e);if((e.f&Za)!==0)throw e.v;return e.v}function Qs(e){if(e.f|=pa,e.deps!==null)for(const t of e.deps)(t.reactions??(t.reactions=[])).push(e),(t.f&Ut)!==0&&(t.f&pa)===0&&(ks(t),Qs(t))}function Js(e){if(e.v===Dt)return!0;if(e.deps===null)return!1;for(const t of e.deps)if(gn.has(t)||(t.f&Ut)!==0&&Js(t))return!0;return!1}function Un(e){var t=ka;try{return ka=!0,e()}finally{ka=t}}const bo=["touchstart","touchmove"];function yo(e){return bo.includes(e)}const on=Symbol("events"),Ys=new Set,pi=new Set;function A(e,t,n){(t[on]??(t[on]={}))[e]=n}function xn(e){for(var t=0;t<e.length;t++)Ys.add(e[t]);for(var n of pi)n(e)}let Fi=null;function Ki(e){var L,k;var t=this,n=t.ownerDocument,r=e.type,i=((L=e.composedPath)==null?void 0:L.call(e))||[],o=i[0]||e.target;Fi=e;var d=0,c=Fi===e&&e[on];if(c){var v=i.indexOf(c);if(v!==-1&&(t===document||t===window)){e[on]=t;return}var u=i.indexOf(t);if(u===-1)return;v<=u&&(d=v)}if(o=i[d]||e.target,o!==t){ll(e,"currentTarget",{configurable:!0,get(){return o||n}});var h=ye,E=Se;ga(null),Pa(null);try{for(var p,x=[];o!==null&&o!==t;){try{var $=(k=o[on])==null?void 0:k[r];$!=null&&(!o.disabled||e.target===o)&&$.call(o,e)}catch(D){p?x.push(D):p=D}if(e.cancelBubble)break;d++,o=d<i.length?i[d]:null}if(p){for(let D of x)queueMicrotask(()=>{throw D});throw p}}finally{e[on]=t,delete e.currentTarget,ga(h),Pa(E)}}}var is;const Qr=((is=globalThis==null?void 0:globalThis.window)==null?void 0:is.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function wo(e){return(Qr==null?void 0:Qr.createHTML(e))??e}function xo(e){var t=qs("template");return t.innerHTML=wo(e.replaceAll("<!>","<!---->")),t.content}function Fn(e,t){var n=Se;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function w(e,t){var n=(t&Ll)!==0,r=(t&zl)!==0,i,o=!e.startsWith("<!>");return()=>{i===void 0&&(i=xo(o?e:"<!>"+e),n||(i=Ya(i)));var d=r||Ls?document.importNode(i,!0):i.cloneNode(!0);if(n){var c=Ya(d),v=d.lastChild;Fn(c,v)}else Fn(d,d);return d}}function ar(e=""){{var t=Fa(e+"");return Fn(t,t),t}}function or(){var e=document.createDocumentFragment(),t=document.createComment(""),n=Fa();return e.append(t,n),Fn(t,n),e}function _(e,t){e!==null&&e.before(t)}function m(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e[Wn]??(e[Wn]=e.nodeValue))&&(e[Wn]=n,e.nodeValue=`${n}`)}function ko(e,t){return Mo(e,t)}const yr=new Map;function Mo(e,{target:t,anchor:n,props:r={},events:i,context:o,intro:d=!0,transformError:c}){lo();var v=void 0,u=fo(()=>{var h=n??t.appendChild(Fa());Gl(h,{pending:()=>{}},x=>{tn({});var $=Gt;o&&($.c=o),i&&(r.$$events=i),v=e(x,r)||{},an()},c);var E=new Set,p=x=>{for(var $=0;$<x.length;$++){var L=x[$];if(!E.has(L)){E.add(L);var k=yo(L);for(const ne of[t,document]){var D=yr.get(ne);D===void 0&&(D=new Map,yr.set(ne,D));var Pe=D.get(L);Pe===void 0?(ne.addEventListener(L,Ki,{passive:k}),D.set(L,1)):D.set(L,Pe+1)}}}};return p(Rr(Ys)),pi.add(p),()=>{var k;for(var x of E)for(const D of[t,document]){var $=yr.get(D),L=$.get(x);--L==0?(D.removeEventListener(x,Ki),$.delete(x),$.size===0&&yr.delete(D)):$.set(x,L)}pi.delete(p),h!==n&&((k=h.parentNode)==null||k.removeChild(h))}});return So.set(v,u),v}let So=new WeakMap;var ya,Aa,la,pn,fr,pr,Or;class Eo{constructor(t,n=!0){ra(this,"anchor");ce(this,ya,new Map);ce(this,Aa,new Map);ce(this,la,new Map);ce(this,pn,new Set);ce(this,fr,!0);ce(this,pr,t=>{if(f(this,ya).has(t)){var n=f(this,ya).get(t),r=f(this,Aa).get(n);if(r)Dr(r),f(this,pn).delete(n);else{var i=f(this,la).get(n);i&&(Dr(i.effect),f(this,Aa).set(n,i.effect),f(this,la).delete(n),i.fragment.lastChild.remove(),this.anchor.before(i.fragment),r=i.effect)}for(const[o,d]of f(this,ya)){if(f(this,ya).delete(o),o===t)break;const c=f(this,la).get(d);c&&(aa(c.effect),f(this,la).delete(d))}for(const[o,d]of f(this,Aa)){if(o===n||f(this,pn).has(o))continue;const c=()=>{if(Array.from(f(this,ya).values()).includes(o)){var u=document.createDocumentFragment();Ci(d,u),u.append(Fa()),f(this,la).set(o,{effect:d,fragment:u})}else aa(d);f(this,pn).delete(o),f(this,Aa).delete(o)};f(this,fr)||!r?(f(this,pn).add(o),_n(d,c,!1)):c()}}});ce(this,Or,t=>{f(this,ya).delete(t);const n=Array.from(f(this,ya).values());for(const[r,i]of f(this,la))n.includes(r)||(aa(i.effect),f(this,la).delete(r))});this.anchor=t,oe(this,fr,n)}ensure(t,n){var r=j,i=Ps();if(n&&!f(this,Aa).has(t)&&!f(this,la).has(t))if(i){var o=document.createDocumentFragment(),d=Fa();o.append(d),f(this,la).set(t,{effect:ua(()=>n(d)),fragment:o})}else f(this,Aa).set(t,ua(()=>n(this.anchor)));if(f(this,ya).set(r,t),i){for(const[c,v]of f(this,Aa))c===t?r.unskip_effect(v):r.skip_effect(v);for(const[c,v]of f(this,la))c===t?r.unskip_effect(v.effect):r.skip_effect(v.effect);r.oncommit(f(this,pr)),r.ondiscard(f(this,Or))}else f(this,pr).call(this,r)}}ya=new WeakMap,Aa=new WeakMap,la=new WeakMap,pn=new WeakMap,fr=new WeakMap,pr=new WeakMap,Or=new WeakMap;function I(e,t,n=!1){var r=new Eo(e),i=n?Rn:0;function o(d,c){r.ensure(d,c)}$i(()=>{var d=!1;t((c,v=0)=>{d=!0,o(v,c)}),d||o(-1,null)},i)}function ut(e,t){return t}function To(e,t,n){for(var r=[],i=t.length,o,d=t.length,c=0;c<i;c++){let E=t[c];_n(E,()=>{if(o){if(o.pending.delete(E),o.done.add(E),o.pending.size===0){var p=e.outrogroups;hi(e,Rr(o.done)),p.delete(o),p.size===0&&(e.outrogroups=null)}}else d-=1},!1)}if(d===0){var v=r.length===0&&n!==null;if(v){var u=n,h=u.parentNode;oo(h),h.append(u),e.items.clear()}hi(e,t,!v)}else o={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(o)}function hi(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(const d of e.pending.values())for(const c of d)r.add(e.items.get(c).e)}for(var i=0;i<t.length;i++){var o=t[i];if(r!=null&&r.has(o)){o.f|=Ca;const d=document.createDocumentFragment();Ci(o,d)}else aa(t[i],n)}}var Gi;function ft(e,t,n,r,i,o=null){var d=e,c=new Map,v=(t&us)!==0;if(v){var u=e;d=u.appendChild(Fa())}var h=null,E=Yl(()=>{var ne=n();return mi(ne)?ne:ne==null?[]:Rr(ne)}),p,x=new Map,$=!0;function L(ne){(Pe.effect.f&ha)===0&&(Pe.pending.delete(ne),Pe.fallback=h,$o(Pe,p,d,t,r),h!==null&&(p.length===0?(h.f&Ca)===0?Dr(h):(h.f^=Ca,Yn(h,null,d)):_n(h,()=>{h=null})))}function k(ne){Pe.pending.delete(ne)}var D=$i(()=>{p=a(E);for(var ne=p.length,pe=new Set,Ee=j,K=Ps(),U=0;U<ne;U+=1){var ue=p[U],he=r(ue,U),Le=$?null:c.get(he);Le?(Le.v&&In(Le.v,ue),Le.i&&In(Le.i,U),K&&Ee.unskip_effect(Le.e)):(Le=Ao(c,$?d:Gi??(Gi=Fa()),ue,he,U,i,t,n),$||(Le.e.f|=Ca),c.set(he,Le)),pe.add(he)}if(ne===0&&o&&!h&&($?h=ua(()=>o(d)):(h=ua(()=>o(Gi??(Gi=Fa()))),h.f|=Ca)),ne>pe.size&&ml(),!$)if(x.set(Ee,pe),K){for(const[Ue,_t]of c)pe.has(Ue)||Ee.skip_effect(_t.e);Ee.oncommit(L),Ee.ondiscard(k)}else L(Ee);a(E)}),Pe={effect:D,items:c,pending:x,outrogroups:null,fallback:h};$=!1}function Vn(e){for(;e!==null&&(e.f&Ma)===0;)e=e.next;return e}function $o(e,t,n,r,i){var Le,Ue,_t,T,W,re,He,J,ze;var o=(r&Al)!==0,d=t.length,c=e.items,v=Vn(e.effect.first),u,h=null,E,p=[],x=[],$,L,k,D;if(o)for(D=0;D<d;D+=1)$=t[D],L=i($,D),k=c.get(L).e,(k.f&Ca)===0&&((Ue=(Le=k.nodes)==null?void 0:Le.a)==null||Ue.measure(),(E??(E=new Set)).add(k));for(D=0;D<d;D+=1){if($=t[D],L=i($,D),k=c.get(L).e,e.outrogroups!==null)for(const Z of e.outrogroups)Z.pending.delete(k),Z.done.delete(k);if((k.f&Qt)!==0&&(Dr(k),o&&((T=(_t=k.nodes)==null?void 0:_t.a)==null||T.unfix(),(E??(E=new Set)).delete(k))),(k.f&Ca)!==0)if(k.f^=Ca,k===v)Yn(k,null,n);else{var Pe=h?h.next:v;k===e.effect.last&&(e.effect.last=k.prev),k.prev&&(k.prev.next=k.next),k.next&&(k.next.prev=k.prev),Va(e,h,k),Va(e,k,Pe),Yn(k,Pe,n),h=k,p=[],x=[],v=Vn(h.next);continue}if(k!==v){if(u!==void 0&&u.has(k)){if(p.length<x.length){var ne=x[0],pe;h=ne.prev;var Ee=p[0],K=p[p.length-1];for(pe=0;pe<p.length;pe+=1)Yn(p[pe],ne,n);for(pe=0;pe<x.length;pe+=1)u.delete(x[pe]);Va(e,Ee.prev,K.next),Va(e,h,Ee),Va(e,K,ne),v=ne,h=K,D-=1,p=[],x=[]}else u.delete(k),Yn(k,v,n),Va(e,k.prev,k.next),Va(e,k,h===null?e.effect.first:h.next),Va(e,h,k),h=k;continue}for(p=[],x=[];v!==null&&v!==k;)(u??(u=new Set)).add(v),x.push(v),v=Vn(v.next);if(v===null)continue}(k.f&Ca)===0&&p.push(k),h=k,v=Vn(k.next)}if(e.outrogroups!==null){for(const Z of e.outrogroups)Z.pending.size===0&&(hi(e,Rr(Z.done)),(W=e.outrogroups)==null||W.delete(Z));e.outrogroups.size===0&&(e.outrogroups=null)}if(v!==null||u!==void 0){var U=[];if(u!==void 0)for(k of u)(k.f&Qt)===0&&U.push(k);for(;v!==null;)(v.f&Qt)===0&&v!==e.fallback&&U.push(v),v=Vn(v.next);var ue=U.length;if(ue>0){var he=(r&us)!==0&&d===0?n:null;if(o){for(D=0;D<ue;D+=1)(He=(re=U[D].nodes)==null?void 0:re.a)==null||He.measure();for(D=0;D<ue;D+=1)(ze=(J=U[D].nodes)==null?void 0:J.a)==null||ze.fix()}To(e,U,he)}}o&&hn(()=>{var Z,rt;if(E!==void 0)for(k of E)(rt=(Z=k.nodes)==null?void 0:Z.a)==null||rt.apply()})}function Ao(e,t,n,r,i,o,d,c){var v=(d&Tl)!==0?(d&Cl)===0?ro(n,!1,!1):wn(n):null,u=(d&$l)!==0?wn(i):null;return{v,i:u,e:ua(()=>(o(t,v??n,u??i,c),()=>{e.delete(r)}))}}function Yn(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,o=t&&(t.f&Ca)===0?t.nodes.start:n;r!==null;){var d=hr(r);if(o.before(r),r===i)return;r=d}}function Va(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Ce(e,t,n=!1,r=!1,i=!1,o=!1){var d=e,c="";if(n)var v=e;z(()=>{var u=Se;if(c!==(c=t()??"")){if(n){u.nodes=null,v.innerHTML=c,c!==""&&Fn(Ya(v),v.lastChild);return}if(u.nodes!==null&&(Ns(u.nodes.start,u.nodes.end),u.nodes=null),c!==""){var h=r?Dl:i?Pl:void 0,E=qs(r?"svg":i?"math":"template",h);E.innerHTML=c;var p=r||i?E:E.content;if(Fn(Ya(p),p.lastChild),r||i)for(;Ya(p);)d.before(Ya(p));else d.before(p)}}})}function Co(e,t,n){var r=e==null?"":""+e;return r===""?null:r}function Lo(e,t){return e==null?null:String(e)}function wt(e,t,n,r,i,o){var d=e[si];if(d!==n||d===void 0){var c=Co(n);c==null?e.removeAttribute("class"):e.className=c,e[si]=n}return o}function fa(e,t,n,r){var i=e[li];if(i!==t){var o=Lo(t);o==null?e.removeAttribute("style"):e.style.cssText=o,e[li]=t}return r}function Zs(e,t,n=!1){if(e.multiple){if(t==null)return;if(!mi(t))return Ol();for(var r of e.options)r.selected=t.includes(rr(r));return}for(r of e.options){var i=rr(r);if(so(i,t)){r.selected=!0;return}}(!n||t!==void 0)&&(e.selectedIndex=-1)}function zo(e){var t=new MutationObserver(()=>{Zs(e,e.__value)});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),Os(()=>{t.disconnect()})}function nr(e,t,n=t){var r=new WeakSet,i=!0;Si(e,"change",o=>{var d=o?"[selected]":":checked",c;if(e.multiple)c=[].map.call(e.querySelectorAll(d),rr);else{var v=e.querySelector(d)??e.querySelector("option:not([disabled])");c=v&&rr(v)}n(c),e.__value=c,j!==null&&r.add(j)}),Bs(()=>{var o=t();if(e===document.activeElement){var d=j;if(r.has(d))return}if(Zs(e,o,i),i&&o===void 0){var c=e.querySelector(":checked");c!==null&&(o=rr(c),n(o))}e.__value=o,i=!1}),zo(e)}function rr(e){return"__value"in e?e.__value:e.value}const Do=Symbol("is custom element"),Po=Symbol("is html"),qo=gl?"progress":"PROGRESS";function wr(e,t){var n=Xs(e);n.value===(n.value=t??void 0)||e.value===t&&(t!==0||e.nodeName!==qo)||(e.value=t??"")}function Fr(e,t,n,r){var i=Xs(e);i[t]!==(i[t]=n)&&(t==="loading"&&(e[hl]=n),n==null?e.removeAttribute(t):typeof n!="string"&&Oo(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function Xs(e){return e[xr]??(e[xr]={[Do]:e.nodeName.includes("-"),[Po]:e.namespaceURI===fs})}var Ui=new Map;function Oo(e){var t=e.getAttribute("is")||e.nodeName,n=Ui.get(t);if(n)return n;Ui.set(t,n=[]);for(var r,i=e,o=Element.prototype;o!==i;){r=ol(i);for(var d in r)r[d].set&&d!=="innerHTML"&&d!=="textContent"&&d!=="innerText"&&n.push(d);i=os(i)}return n}function Ta(e,t,n=t){var r=new WeakSet;Si(e,"input",async i=>{var o=i?e.defaultValue:e.value;if(o=Jr(e)?Yr(o):o,n(o),j!==null&&r.add(j),await mo(),o!==(o=t())){var d=e.selectionStart,c=e.selectionEnd,v=e.value.length;if(e.value=o??"",c!==null){var u=e.value.length;d===c&&c===v&&u>v?(e.selectionStart=u,e.selectionEnd=u):(e.selectionStart=d,e.selectionEnd=Math.min(c,u))}}}),Un(t)==null&&e.value&&(n(Jr(e)?Yr(e.value):e.value),j!==null&&r.add(j)),Nr(()=>{var i=t();if(e===document.activeElement){var o=j;if(r.has(o))return}Jr(e)&&i===Yr(e.value)||e.type==="date"&&!i&&!e.value||i!==e.value&&(e.value=i??"")})}function Ro(e,t,n=t){Si(e,"change",r=>{var i=r?e.defaultChecked:e.checked;n(i)}),Un(t)==null&&n(e.checked),Nr(()=>{var r=t();e.checked=!!r})}function Jr(e){var t=e.type;return t==="number"||t==="range"}function Yr(e){return e===""?null:+e}function Zr(e,t){return e===t||(e==null?void 0:e[$n])===t}function Bo(e={},t,n,r){var i=Gt.r,o=Se;return Bs(()=>{var d,c;return Nr(()=>{d=c,c=[],Un(()=>{Zr(n(...c),e)||(t(e,...c),d&&Zr(n(...d),e)&&t(null,...d))})}),()=>{let v=o;for(;v!==i&&v.parent!==null&&v.parent.fⅈ)v=v.parent;const u=()=>{c&&Zr(n(...c),e)&&t(null,...c)},h=v.teardown;v.teardown=()=>{u(),h==null||h()}}}),e}function _r(e){Gt===null&&vs(),Ti(()=>{const t=Un(e);if(typeof t=="function")return t})}function Io(e){Gt===null&&vs(),_r(()=>()=>Un(e))}let dr=localStorage.getItem("mc_token")||"";function el(){return dr}function No(e){dr=(e||"").trim(),localStorage.setItem("mc_token",dr)}function Fo(){const e={"Content-Type":"application/json"};return dr&&(e["X-MC-Token"]=dr),e}function ir(){return localStorage.getItem("mc_hf_token")||""}function Ko(e){localStorage.setItem("mc_hf_token",(e||"").trim())}async function Me(e,t={}){const n=await fetch(e,{headers:Fo(),...t}),r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(r.error||"HTTP "+n.status);return r}const Go=(e,t=document)=>t.querySelector(e),Hi=(e,t=document)=>[...t.querySelectorAll(e)];function za(e){return String(e??"").replace(/[&<>]/g,t=>({"&":"&","<":"<",">":">"})[t])}let Vi;function ee(e,t=!1){const n=Go("#toast");n&&(n.textContent=e,n.className="toast show"+(t?" err":""),clearTimeout(Vi),Vi=setTimeout(()=>n.className="toast",3200))}function Uo(e,t){return e==="running"||e==="ready"?'<span class="badge b-run">geladen</span>':e==="loading"||e==="starting"?'<span class="badge b-load">lädt…</span>':e==="downloading"?`<span class="badge b-load">↓ Download${t!=null?` ${Math.round(t)}%`:""}</span>`:'<span class="badge b-run">bereit</span>'}const We=e=>`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">${e}</svg>`,Kr={logo:We('<circle cx="12" cy="12" r="3.2"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M19 5l-2 2M7 17l-2 2"/>'),grid:We('<rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/>'),cpu:We('<rect x="6" y="6" width="12" height="12" rx="2"/><path d="M9 1v3M15 1v3M9 20v3M15 20v3M1 9h3M1 15h3M20 9h3M20 15h3"/>'),pulse:We('<path d="M3 12h4l2 6 4-14 2 8h6"/>'),server:We('<rect x="3" y="4" width="18" height="7" rx="2"/><rect x="3" y="13" width="18" height="7" rx="2"/><path d="M7 7.5h.01M7 16.5h.01"/>'),book:We('<path d="M4 5a2 2 0 0 1 2-2h13v16H6a2 2 0 0 0-2 2z"/><path d="M19 19H6a2 2 0 0 0-2 2"/>'),help:We('<circle cx="12" cy="12" r="9"/><path d="M9.5 9.2a2.5 2.5 0 0 1 4.8 1c0 1.7-2.3 2-2.3 3.4"/><path d="M12 17h.01"/>'),settings:We('<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1A1.6 1.6 0 0 0 6.6 19l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.6 1.6 0 0 0-1.1-2.7H2a2 2 0 1 1 0-4h.1A1.6 1.6 0 0 0 4 6.6l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 9 4.6V4a2 2 0 1 1 4 0v.1A1.6 1.6 0 0 0 17.4 6l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0 1.1 2.7H21a2 2 0 1 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1z"/>'),swap:We('<path d="M7 4 3 8l4 4"/><path d="M3 8h12a4 4 0 0 1 0 8h-1"/><path d="m17 20 4-4-4-4"/>'),monitor:We('<rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4"/>'),layers:We('<path d="m12 2 9 5-9 5-9-5z"/><path d="m3 12 9 5 9-5M3 17l9 5 9-5"/>'),alert:We('<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/><path d="M12 9v4M12 17h.01"/>'),gauge:We('<path d="M12 14 16 9"/><circle cx="12" cy="13" r="9"/><path d="M12 4v2M21 13h-2M5 13H3"/>'),search:We('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),compass:We('<circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/>'),code:We('<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>'),eye:We('<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>'),refresh:We('<path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/>'),file:We('<path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/><path d="M9 13h6M9 17h5"/>'),database:We('<ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5"/><path d="M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/>'),thermo:We('<path d="M14 14.76V5a2 2 0 0 0-4 0v9.76a4 4 0 1 0 4 0z"/>'),shield:We('<path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7z"/><path d="m9 12 2 2 4-4"/>'),info:We('<circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/>'),chevron:We('<path d="m9 6 6 6-6 6"/>'),bolt:We('<path d="M13 2 3 14h7l-1 8 10-12h-7z"/>'),x:We('<path d="M18 6 6 18M6 6l12 12"/>'),check:We('<path d="M20 6 9 17l-5-5"/>'),download:We('<path d="M12 3v12M7 10l5 5 5-5"/><path d="M5 21h14"/>'),clock:We('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>')};function zt(e){return Kr[e]||""}function gi(e){return`<span class="info-dot" tabindex="0" title="${za(e)}" aria-label="${za(e)}">${Kr.info}</span>`}function rn(e){if(!e&&e!==0)return"–";const t=e/1024/1024/1024;return t>=1?t.toFixed(1)+" GB":Math.round(e/1024/1024)+" MB"}function wa({title:e,body:t,confirmLabel:n="Bestätigen",cancelLabel:r="Abbrechen",danger:i=!1}){return new Promise(o=>{const d=document.createElement("div");d.className="modal-overlay",d.innerHTML=`<div class="modal-card" role="dialog" aria-modal="true">
|
||
<h3>${za(e)}</h3>
|
||
<p>${t}</p>
|
||
<div class="modal-actions">
|
||
<button data-x="0">${za(r)}</button>
|
||
<button class="${i?"danger":"primary"}" data-x="1">${za(n)}</button>
|
||
</div></div>`;const c=v=>{d.remove(),o(v)};d.addEventListener("click",v=>{if(v.target===d)return c(!1);const u=v.target.closest("[data-x]");u&&c(u.getAttribute("data-x")==="1")}),document.body.appendChild(d),d.querySelector('[data-x="1"]').focus()})}function Wi({title:e,body:t="",placeholder:n="",password:r=!1,confirmLabel:i="Weiter",danger:o=!1}){return new Promise(d=>{const c=document.createElement("div");c.className="modal-overlay",c.innerHTML=`<div class="modal-card" role="dialog" aria-modal="true">
|
||
<h3>${za(e)}</h3>
|
||
${t?`<p>${t}</p>`:""}
|
||
<input type="${r?"password":"text"}" placeholder="${za(n)}" autocomplete="off" style="margin-bottom:18px">
|
||
<div class="modal-actions">
|
||
<button data-x="0">Abbrechen</button>
|
||
<button class="${o?"danger":"primary"}" data-x="1">${za(i)}</button>
|
||
</div></div>`;const v=c.querySelector("input"),u=h=>{c.remove(),d(h)};c.addEventListener("click",h=>{if(h.target===c)return u(null);const E=h.target.closest("[data-x]");E&&u(E.getAttribute("data-x")==="1"?v.value||"":null)}),v.addEventListener("keydown",h=>{h.key==="Enter"&&u(v.value||""),h.key==="Escape"&&u(null)}),document.body.appendChild(c),v.focus()})}function Ho(e="overview"){const t=Hi(".nav-item[data-view]:not(.disabled)"),n=Hi(".view[data-view]"),r=new Set(n.map(o=>o.dataset.view));function i(o){r.has(o)||(o=e),n.forEach(d=>d.hidden=d.dataset.view!==o),t.forEach(d=>d.classList.toggle("active",d.dataset.view===o)),location.hash!=="#/"+o&&(location.hash="#/"+o)}return t.forEach(o=>o.addEventListener("click",d=>{d.preventDefault(),i(o.dataset.view)})),window.addEventListener("hashchange",()=>i(location.hash.replace("#/",""))),i(location.hash.replace("#/","")||e),{show:i}}let ji=O(null);const mr={get value(){return a(ji)},set(e){g(ji,e,!0)}};let Qi=O(Ht([])),Wa=O(Ht([]));const dn={get value(){return a(Qi)},set(e){g(Qi,e||[],!0)},get tracked(){return a(Wa)},track(e){a(Wa).includes(e)||g(Wa,[...a(Wa),e],!0)},toggle(e){g(Wa,a(Wa).includes(e)?a(Wa).filter(t=>t!==e):[...a(Wa),e],!0)}};let Ji=O(null);const Li={get value(){return a(Ji)},set(e){g(Ji,e,!0)}},Vo="5";var ss;typeof window<"u"&&((ss=window.__svelte??(window.__svelte={})).v??(ss.v=new Set)).add(Vo);var Wo=w('<span style="font-size:13px;font-weight:400;color:var(--mut)">— bereit für Anfragen</span>'),jo=w('<div><div class="k-h"><span class="k-t">Temperatur (GPU)</span><span class="k-ic"></span></div> <div class="k-v"> </div> <div class="k-s"> </div></div> <div><div class="k-h"><span class="k-t">Freier Speicher</span><span class="k-ic"></span></div> <div class="k-v"> <small>GB</small></div> <div class="k-s"> </div></div>',1),Qo=w('<div class="kpi muted"><div class="k-h"><span class="k-t">Temperatur</span></div><div class="k-v">–</div><div class="k-s">messe…</div></div> <div class="kpi muted"><div class="k-h"><span class="k-t">Freier Speicher</span></div><div class="k-v">–</div><div class="k-s">messe…</div></div>',1),Jo=w('<div class="meter"><div class="meter-h"><span class="mk"> </span><span class="mv"> </span></div> <div><i></i></div></div>'),Yo=w('<div class="empty">Warte auf Messwerte…</div>'),Zo=w('<div class="card-sub">Noch kein Modell eingerichtet — starte hier:</div> <button class="qa"><span class="qa-ic teal"></span> <span class="qa-main"><span class="qa-t">Schritt 1 · Modell holen</span><span class="qa-s">Cookbook → passendes Setup installieren</span></span> <span class="qa-arrow"></span></button> <button class="qa" style="opacity:.55;pointer-events:none"><span class="qa-ic teal"></span> <span class="qa-main"><span class="qa-t">Schritt 2 · Tools verbinden</span><span class="qa-s">Erst nach dem Download verfügbar</span></span> <span class="qa-arrow"></span></button> <button class="qa"><span class="qa-ic blue"></span> <span class="qa-main"><span class="qa-t">Einsteiger-Guide lesen</span><span class="qa-s">Alle Begriffe erklärt, ohne Vorwissen</span></span> <span class="qa-arrow"></span></button>',1),Xo=w('<div class="card-sub">Die häufigsten Aufgaben — ein Klick.</div> <button class="qa"><span class="qa-ic teal"></span> <span class="qa-main"><span class="qa-t">Modell finden</span><span class="qa-s">Passend zu deiner Hardware</span></span> <span class="qa-arrow"></span></button> <button class="qa"><span class="qa-ic amber"></span> <span class="qa-main"><span class="qa-t">Speicher freigeben</span><span class="qa-s">Alle Modelle entladen</span></span> <span class="qa-arrow"></span></button> <button class="qa"><span class="qa-ic blue"></span> <span class="qa-main"><span class="qa-t">Logs ansehen</span><span class="qa-s">Live mitlesen, was läuft</span></span> <span class="qa-arrow"></span></button> <button class="qa"><span class="qa-ic teal"></span> <span class="qa-main"><span class="qa-t">Tools verbinden</span><span class="qa-s">Zed, OpenCode, Cline einrichten</span></span> <span class="qa-arrow"></span></button>',1),ed=w('<span class="tag img">Bild</span>'),td=w('<span class="tag code">Code</span>'),ad=w('<span class="tag text">Text</span>'),nd=w('<span class="chip" style="padding:2px 7px;font-size:11px">∞ aktiv</span>'),rd=w('<button class="ghost"> </button>'),id=w('<div class="li" style="padding:10px 4px"><span></span> <div class="li-main"><div class="flex items-center gap-2" style="flex-wrap:wrap"><span class="li-id"> </span> <!> <!></div> <div class="li-sub mono-sm"> </div></div> <div class="flex items-center gap-2"><span class="li-meta"> </span> <!></div></div>'),Yi=w('<div class="list"></div>'),sd=w('<div class="empty-c"><div class="e-t">Noch keine Modelle</div> <div class="e-s">Hol dir unter „Cookbook" ein Modell, das auf deine Hardware passt.</div> <button class="primary" style="margin-top:12px">Zum Cookbook →</button></div>'),ld=w('<a class="li" target="_blank" rel="noopener" style="text-decoration:none;color:inherit"><div class="li-main"><div style="font-size:13px;line-height:1.4"> </div> <div class="li-sub"> </div></div></a>'),od=w('<div class="empty">News gerade nicht ladbar.</div>'),dd=w('<div class="pagehead" style="margin-bottom:10px"><div><h1 style="display:flex;align-items:center;gap:10px"> <!></h1> <div class="sub"> </div></div></div> <div class="tiles"><div><div class="k-h"><span class="k-t">LLM-Engine</span> <span class="k-ic"></span></div> <div class="k-v"> </div> <div class="k-s"> </div></div> <div><div class="k-h"><span class="k-t">Aktives Modell</span> <span class="k-ic"></span></div> <div class="k-v" style="font-size:16px;word-break:break-word"> </div> <div class="k-s"><!></div></div> <!></div> <div class="split"><div class="card"><div class="card-h"><h3>System-Gesundheit</h3></div> <div class="card-sub">Auslastung in Echtzeit.</div> <!></div> <div class="card"><div class="card-h"><h3>Schnellstart</h3></div> <!></div></div> <div class="grid grid-2"><div class="card"><div class="card-h"><h3>Dein Stack</h3> <span class="meta"> </span></div> <!></div> <div class="card"><div class="card-h"><h3>Top-News</h3> <span class="meta" style="cursor:pointer" role="button" tabindex="0">Alle →</span></div> <!></div></div>',1);function cd(e,t){tn(t,!0);const n=q(()=>mr.value),r=q(()=>Li.value),i=q(()=>{var M;return((M=a(n))==null?void 0:M.models)||[]}),o=q(()=>{var M;return((M=a(n))==null?void 0:M.swap_ok)??!1}),d=["running","ready","loading","starting"],c=q(()=>a(i).find(M=>d.includes(M.state))),v=q(()=>a(i).filter(M=>!M.incomplete)),u=q(()=>a(n)?a(o)?a(r)&&a(r).ram.percent>=90?"Achtung: Speicher wird knapp.":"Alles läuft rund.":"LLM-Engine offline":"Verbinde…"),h=q(()=>a(n)?a(o)?a(r)&&a(r).ram.percent>=90?`Arbeitsspeicher bei ${Math.round(a(r).ram.percent)} % — eventuell Speicher freigeben.`:`${a(v).length} ${a(v).length===1?"Modell":"Modelle"} konfiguriert · ${a(c)?`„${a(c).name}" geladen`:"keines geladen"} · keine Warnungen.`:"Der llama-swap-Dienst antwortet gerade nicht.":""),E=q(()=>()=>{var G;const M=(G=a(r))==null?void 0:G.gpu;return M&&M.vram.total+M.gtt.total>0?(M.vram.used+M.gtt.used)/(M.vram.total+M.gtt.total)*100:0});let p=O(Ht([])),x=O(null);_r(async()=>{try{g(p,((await Me("/api/news")).items||[]).slice(0,4),!0)}catch{}});async function $(){await wa({title:"Speicher freigeben?",body:"Alle aktuell geladenen Modelle werden aus dem Grafikspeicher geworfen. Sie laden beim nächsten Aufruf automatisch neu.",confirmLabel:"Speicher freigeben"})&&(await Me("/api/unload",{method:"POST"}),k())}async function L(M){g(x,M,!0);try{await Me("/api/preload?model="+encodeURIComponent(M),{method:"POST"})}catch(G){ee("Laden fehlgeschlagen: "+(G.message||"Engine nicht erreichbar?"),!0)}g(x,null),k()}function k(){document.dispatchEvent(new Event("mc:refresh"))}function D(M){var G;(G=document.querySelector(`.nav-item[data-view="${M}"]`))==null||G.dispatchEvent(new MouseEvent("click"))}function Pe(M){return M>=90?"red":M>=75?"":"green"}function ne(M){return M==null?"":M>=75?"red":M>=55?"":"green"}function pe(M){return M>=90?"red":M>=70?"":"green"}var Ee=dd(),K=ot(Ee),U=l(K),ue=l(U),he=l(ue),Le=s(he);{var Ue=M=>{var G=Wo();_(M,G)};I(Le,M=>{a(o)&&!a(c)&&M(Ue)})}var _t=s(ue,2),T=l(_t),W=s(K,2),re=l(W),He=l(re),J=s(l(He),2);Ce(J,()=>zt("server"),!0);var ze=s(He,2),Z=l(ze),rt=s(ze,2),P=l(rt),H=s(re,2),ie=l(H),ge=s(l(ie),2);Ce(ge,()=>zt("cpu"),!0);var Te=s(ie,2),mt=l(Te),pt=s(Te,2),kt=l(pt);{var At=M=>{var G=ar();z(qe=>m(G,`${qe??""} · ${a(c).state??""}`),[()=>{var qe;return(qe=a(c).meta)!=null&&qe.ctx?Math.round(a(c).meta.ctx/1024)+"k ctx":""}]),_(M,G)},Mt=M=>{var G=ar("lädt bei erster Anfrage");_(M,G)};I(kt,M=>{a(c)?M(At):M(Mt,-1)})}var Lt=s(H,2);{var qt=M=>{const G=q(()=>{var Ua;return a(r).gpu_temp??((Ua=a(r).cpu)==null?void 0:Ua.temp)??null}),qe=q(()=>ne(a(G))),te=q(()=>a(r).ram.total-a(r).ram.used),Be=q(()=>100-a(r).ram.percent);var Ye=jo(),et=ot(Ye),ke=l(et),Ae=s(l(ke));Ce(Ae,()=>zt("thermo"),!0);var Oe=s(ke,2),Ot=l(Oe),Bt=s(Oe,2),Wt=l(Bt),na=s(et,2),_a=l(na),Ke=s(l(_a));Ce(Ke,()=>zt("database"),!0);var ht=s(_a,2),qa=l(ht),Ga=s(ht,2),nn=l(Ga);z((Ua,Hn,y,b)=>{wt(et,1,`kpi ${a(qe)??""}`),m(Ot,Ua),m(Wt,a(G)==null?"messe…":a(G)<55?"kühl":a(G)<75?"normal":"⚠ heiß"),wt(na,1,`kpi ${a(Be)<15?"red":a(Be)<30?"":"green"}`),m(qa,Hn),m(nn,`von ${y??""} GB · ${b??""} % frei`)},[()=>a(G)!=null?`${Math.round(a(G))}°C`:"–",()=>Math.round(a(te)/1073741824),()=>Math.round(a(r).ram.total/1073741824),()=>Math.round(a(Be))]),_(M,Ye)},Rt=M=>{var G=Qo();_(M,G)};I(Lt,M=>{a(r)?M(qt):M(Rt,-1)})}var C=s(W,2),F=l(C),$e=s(l(F),4);{var dt=M=>{const G=q(()=>a(E)());var qe=or(),te=ot(qe);ft(te,17,()=>{var Be;return[["Prozessor (CPU)",((Be=a(r).cpu)==null?void 0:Be.percent)??0,""],["Arbeitsspeicher (RAM)",a(r).ram.percent,Pe(a(r).ram.percent)],["Grafikspeicher (VRAM)",a(G),pe(a(G))]]},ut,(Be,Ye)=>{var et=q(()=>sr(a(Ye),3));let ke=()=>a(et)[0],Ae=()=>a(et)[1];const Oe=q(()=>Math.max(0,Math.min(100,Ae()||0)));var Ot=Jo(),Bt=l(Ot),Wt=l(Bt),na=l(Wt),_a=s(Wt),Ke=l(_a),ht=s(Bt,2),qa=l(ht);z((Ga,nn)=>{m(na,ke()),m(Ke,`${Ga??""} %`),wt(ht,1,`bar ${a(Oe)>=90?"bad":a(Oe)>=75?"warn":""}`),fa(qa,`width:${nn??""}%`)},[()=>Math.round(a(Oe)),()=>Math.max(2,a(Oe))]),_(Be,Ot)}),_(M,qe)},N=M=>{var G=Yo();_(M,G)};I($e,M=>{a(r)?M(dt):M(N,-1)})}var De=s(F,2),Q=s(l(De),2);{var de=M=>{var G=Zo(),qe=s(ot(G),2),te=l(qe);Ce(te,()=>zt("search"),!0);var Be=s(te,4);Ce(Be,()=>zt("chevron"),!0);var Ye=s(qe,2),et=l(Ye);Ce(et,()=>zt("swap"),!0);var ke=s(et,4);Ce(ke,()=>zt("chevron"),!0);var Ae=s(Ye,2),Oe=l(Ae);Ce(Oe,()=>zt("file"),!0);var Ot=s(Oe,4);Ce(Ot,()=>zt("chevron"),!0),A("click",qe,()=>D("cookbook")),A("click",Ye,()=>D("connect")),A("click",Ae,()=>D("guides")),_(M,G)},se=M=>{var G=Xo(),qe=s(ot(G),2),te=l(qe);Ce(te,()=>zt("search"),!0);var Be=s(te,4);Ce(Be,()=>zt("chevron"),!0);var Ye=s(qe,2),et=l(Ye);Ce(et,()=>zt("refresh"),!0);var ke=s(et,4);Ce(ke,()=>zt("chevron"),!0);var Ae=s(Ye,2),Oe=l(Ae);Ce(Oe,()=>zt("file"),!0);var Ot=s(Oe,4);Ce(Ot,()=>zt("chevron"),!0);var Bt=s(Ae,2),Wt=l(Bt);Ce(Wt,()=>zt("swap"),!0);var na=s(Wt,4);Ce(na,()=>zt("chevron"),!0),A("click",qe,()=>D("cookbook")),A("click",Ye,$),A("click",Ae,()=>D("server")),A("click",Bt,()=>D("connect")),_(M,G)};I(Q,M=>{a(v).length?M(se,-1):M(de)})}var Y=s(C,2),me=l(Y),ve=l(me),we=s(l(ve),2),xe=l(we),be=s(ve,2);{var S=M=>{var G=Yi();ft(G,21,()=>a(v),ut,(qe,te)=>{const Be=q(()=>d.includes(a(te).state)),Ye=q(()=>a(te).state==="downloading"),et=q(()=>a(te).state==="loading"||a(te).state==="starting"||a(Ye)?"load":a(Be)?"on":""),ke=q(()=>a(Ye)?`↓ ${a(te).download_progress!=null?Math.round(a(te).download_progress)+"%":"..."}`:a(te).state==="loading"||a(te).state==="starting"?"lädt…":a(Be)?"geladen ✓":"bereit");var Ae=id(),Oe=l(Ae),Ot=s(Oe,2),Bt=l(Ot),Wt=l(Bt),na=l(Wt),_a=s(Wt,2);{var Ke=X=>{var _e=ed();_(X,_e)},ht=q(()=>{var X,_e;return(_e=(X=a(te).meta)==null?void 0:X.caps)==null?void 0:_e.includes("Bild")}),qa=X=>{var _e=td();_(X,_e)},Ga=q(()=>{var X,_e;return(_e=(X=a(te).meta)==null?void 0:X.caps)==null?void 0:_e.includes("Code")}),nn=X=>{var _e=ad();_(X,_e)};I(_a,X=>{a(ht)?X(Ke):a(Ga)?X(qa,1):X(nn,-1)})}var Ua=s(_a,2);{var Hn=X=>{var _e=nd();_(X,_e)};I(Ua,X=>{a(te).ttl>=99999&&X(Hn)})}var y=s(Bt,2),b=l(y),B=s(Ot,2),R=l(B),ae=l(R),tt=s(R,2);{var it=X=>{var _e=rd(),Re=l(_e);z(()=>{fa(_e,`padding:3px 9px;font-size:12px;opacity:${a(x)===a(te).name?".5":"1"}`),_e.disabled=a(x)===a(te).name,m(Re,a(x)===a(te).name?"…":"Laden")}),A("click",_e,()=>L(a(te).name)),_(X,_e)};I(tt,X=>{!a(Be)&&!a(Ye)&&a(o)&&X(it)})}z((X,_e)=>{var Re;wt(Oe,1,`li-dot ${a(et)??""}`),fa(Wt,a(Be)?"color:var(--accent)":""),m(na,a(te).name),m(b,`${X??""}
|
||
${(Re=a(te).meta)!=null&&Re.quant?" · "+a(te).meta.quant:""}
|
||
${_e??""}`),fa(R,`white-space:nowrap;color:${a(Be)?"var(--on)":"var(--mut)"}`),m(ae,a(ke))},[()=>{var X;return(X=a(te).meta)!=null&&X.ctx?Math.round(a(te).meta.ctx/1024)+"k ctx":""},()=>{var X;return(X=a(te).meta)!=null&&X.size_bytes?" · "+(a(te).meta.size_bytes/1073741824).toFixed(1)+" GB":""}]),_(qe,Ae)}),_(M,G)},V=M=>{var G=sd(),qe=s(l(G),4);A("click",qe,()=>D("cookbook")),_(M,G)};I(be,M=>{a(v).length?M(S):M(V,-1)})}var le=s(me,2),Qe=l(le),Je=s(l(Qe),2),Jt=s(Qe,2);{var Yt=M=>{var G=Yi();ft(G,21,()=>a(p),ut,(qe,te)=>{var Be=ld(),Ye=l(Be),et=l(Ye),ke=l(et),Ae=s(et,2),Oe=l(Ae);z(()=>{Fr(Be,"href",a(te).link),m(ke,a(te).title),m(Oe,`${a(te).source??""}${a(te).relevant?" · für dich":""}`)}),_(qe,Be)}),_(M,G)},Vt=M=>{var G=od();_(M,G)};I(Jt,M=>{a(p).length?M(Yt):M(Vt,-1)})}z(M=>{m(he,`${a(u)??""} `),m(T,a(h)),wt(re,1,`kpi ${a(o)?"green":"red"}`),m(Z,a(o)?"Online":"Offline"),m(P,M),wt(H,1,`kpi ${a(c)?"blue":"muted"}`),m(mt,a(c)?a(c).name:"Keins"),m(xe,a(v).length?a(v).length+" konfiguriert":"")},[()=>{var M,G;return((G=(M=a(n))==null?void 0:M.swap_url)==null?void 0:G.replace(/^https?:\/\//,""))??"—"}]),A("click",Je,()=>D("news")),A("keydown",Je,M=>M.key==="Enter"&&D("news")),_(e,Ee),an()}xn(["click","keydown"]);var vd=w("<option> </option>"),ud=w('<div class="reply" style="margin-top:12px"> </div>'),fd=w('<div class="empty-c"><div class="e-t">Noch keine Modelle konfiguriert</div> <div class="e-s">Hol dir unter „Cookbook" ein passendes Modell.</div></div>'),pd=w('<tr style="opacity:.9"><td class="mid" style="font-weight:500"> <div class="li-sub mono-sm" style="color:var(--warn)">kein Modell hinterlegt</div></td><td>—</td><td><span class="mono-sm text-mut">leere Rolle</span></td><td><span class="badge">leer</span></td><td class="port">—</td><td style="text-align:right;white-space:nowrap"><button class="ghost">Modell zuweisen</button> <button class="ghost del">Löschen</button></td></tr>'),hd=w('<span class="tag" style="background:rgba(45,212,191,.14);color:var(--accent);border-color:rgba(45,212,191,.3)"> </span>'),gd=w('<div class="li-sub mono-sm"> </div>'),_d=w('<code style="cursor:pointer" title="Klicken zum Kopieren"> </code>'),md=w('<tr><td class="mid"><div style="font-weight:500;display:flex;align-items:center;gap:7px;flex-wrap:wrap"> <!></div> <!> <div class="li-sub mono-sm" style="margin-top:3px;display:flex;align-items:center;gap:6px;flex-wrap:wrap"><span class="text-mut">API-Name:</span> <!></div></td><td></td><td></td><td></td><td class="port"> </td><td style="text-align:right;white-space:nowrap"><button class="ghost">Rolle</button> <button class="ghost">Konfigurieren</button> <button class="ghost">Entladen</button> <button class="ghost del">Löschen</button></td></tr>'),bd=w('<table><thead><tr><th>Modell</th><th>Kann</th><th>Details</th><th>Status</th><th>Port</th><th style="text-align:right">Aktionen</th></tr></thead><tbody></tbody></table>'),yd=w('<div class="tile" style="display:flex;justify-content:space-between;align-items:center;margin:8px 0 10px"><div style="flex:1"><div style="font-size:13px">Empfohlen für deine Hardware</div> <div class="hint" style="margin:4px 0 0"> <br/> </div></div> <button class="ghost">Optimal übernehmen</button></div>'),wd=w('<div class="modal-overlay" role="dialog"><div class="modal-card"><button class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button> <h3>Modell konfigurieren</h3> <p class="mono-sm" style="margin:-4px 0 16px"> </p> <label>Kontext-Größe (Tokens) <!></label> <input type="number"/> <!> <div class="hint" style="margin-bottom:14px">Es läuft immer nur <b>ein</b> Modell gleichzeitig — ein größerer Kontext hier beeinflusst deine anderen Modelle nicht.</div> <div class="tile" style="display:flex;justify-content:space-between;align-items:center;margin:0 0 14px"><div style="flex:1"><div style="font-size:13px;font-weight:500">Immer aktiv halten</div> <div class="hint" style="margin:3px 0 0">Modell bleibt dauerhaft im RAM — nie automatisch entladen. Ideal für den kleinen Scout (~5 GB), der immer schnell antworten soll.</div></div> <label style="display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;flex:0 0 auto"><input type="checkbox" style="width:18px;height:18px;accent-color:var(--accent);cursor:pointer"/> <span class="mono-sm"> </span></label></div> <button class="primary" style="width:100%;margin-top:6px">Speichern</button></div></div>'),xd=w('<button style="border-radius:999px"> </button>'),kd=w('<div class="modal-overlay" role="dialog"><div class="modal-card"><button class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button> <h3>Rolle festlegen <!></h3> <p class="mono-sm" style="margin:-4px 0 16px"> </p> <div class="hint" style="margin-bottom:10px">Wähle eine Rolle als zweiten, sprechenden Namen. In deinen Tools funktionieren danach <b>beide</b>: der echte Modellname und die Rolle.</div> <div class="flex gap-2" style="flex-wrap:wrap;margin-bottom:12px"></div> <label>Eigene Rolle (optional)</label> <input placeholder="z.B. uebersetzer"/> <div class="btn-row" style="margin-top:14px;display:flex;gap:8px"><button class="ghost" style="flex:1">Rolle entfernen</button> <button class="primary" style="flex:2">Speichern</button></div></div></div>'),Md=w('<div id="m-head"><div class="pagehead"><div><h1>Modelle</h1> <div class="sub">Deine konfigurierten Modelle — testen, Kontext anpassen oder aus dem Speicher werfen.</div></div></div></div> <div class="card"><div class="card-h"><h3>Schnelltest</h3></div> <div class="card-sub">Schreib eine Nachricht — das gewählte Modell wird automatisch geweckt.</div> <label>Modell</label> <select></select> <label>Nachricht</label> <textarea placeholder="z.B. „Erklär mir kurz, was du kannst.""></textarea> <button class="primary"> </button> <!></div> <div class="card"><div class="card-h"><h3>Modelle & Ports</h3><span class="meta"> </span></div> <div class="card-sub">Modelle laden automatisch, sobald eine Anfrage kommt — du musst nichts manuell starten.</div> <!></div> <!> <!>',1);function Sd(e,t){tn(t,!0);const n="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr (längere Dateien/Chats), braucht aber mehr Speicher und wird etwas langsamer.",r="Die Rolle ist ein zusätzlicher, sprechender Name (z.B. coder). Du kannst in deinen Tools entweder den echten Modellnamen ODER die Rolle angeben — beides führt zum selben Modell.",i=[{id:"coder",label:"Coder",desc:"Programmieren & Code"},{id:"vision",label:"Vision",desc:"Bilder verstehen"},{id:"scout",label:"Scout",desc:"Schneller Allrounder"},{id:"reviewer",label:"Reviewer",desc:"Code/Texte prüfen"},{id:"manager",label:"Manager",desc:"Planen & koordinieren"}],o=q(()=>{var C;return((C=mr.value)==null?void 0:C.models)||[]});function d(){document.dispatchEvent(new Event("mc:refresh"))}let c=O(""),v=O(""),u=O(""),h=O(!1);const E=q(()=>a(o).filter(C=>!C.incomplete));async function p(){var F;const C=a(c)||((F=a(E)[0])==null?void 0:F.name);if(!(!C||!a(v).trim())){g(h,!0),g(u,"(wecke Modell, kann beim Laden kurz dauern…)");try{const $e=await Me("/api/chat",{method:"POST",body:JSON.stringify({model:C,message:a(v)})});g(u,$e.reply,!0)}catch($e){g(u,"Fehler: "+$e.message)}g(h,!1),d()}}const x=300;let $=O(!1),L=O(null),k=O(8192),D=O(!1);function Pe(C){var F;g(L,a(o).find($e=>$e.name===C),!0),a(L)&&(g(k,((F=a(L).meta)==null?void 0:F.ctx)||8192,!0),g(D,(a(L).ttl??x)>=99999),g($,!0))}async function ne(){const C=a(D)?99999:x;try{await Me("/api/update_model",{method:"POST",body:JSON.stringify({alias:a(L).name,ctx:a(k),ttl:C})}),ee("Gespeichert — aktiv beim nächsten Modell-Start."),g($,!1),d()}catch(F){ee(F.message,!0)}}let pe=O(!1),Ee=O(""),K=O(""),U=O("");function ue(C){const F=a(o).find($e=>$e.name===C);g(Ee,C,!0),g(U,(F==null?void 0:F.role)||"",!0),g(K,""),g(pe,!0)}async function he(C){try{await Me("/api/set_role",{method:"POST",body:JSON.stringify({alias:a(Ee),role:C})}),ee(C?`Rolle gesetzt: ${C}`:"Rolle entfernt."),g(pe,!1),d()}catch(F){ee(F.message,!0)}}async function Le(C){if(await wa({title:`„${C}" entladen?`,body:"Das Modell wird aus dem Grafikspeicher geworfen und lädt beim nächsten Aufruf automatisch neu.",confirmLabel:"Entladen"}))try{await Me("/api/unload?model="+encodeURIComponent(C),{method:"POST"}),ee("Entladen: "+C),setTimeout(d,600)}catch(F){ee(F.message,!0)}}async function Ue(C){if(await wa({title:`„${C}" wirklich löschen?`,body:"Das Modell wird aus der Konfiguration ausgetragen und seine Dateien werden von der Festplatte gelöscht, um Speicher freizugeben. <b>Das lässt sich nicht rückgängig machen</b> — später brauchst du dafür einen neuen Download.",confirmLabel:"Endgültig löschen",danger:!0}))try{const F=await Me("/api/delete_model",{method:"POST",body:JSON.stringify({alias:C})});ee(F.note||"Gelöscht: "+C),setTimeout(d,600)}catch(F){ee(F.message,!0)}}function _t(C){return C!=null&&C.length?C.map(F=>F==="Code"?'<span class="tag code">Code</span>':F==="Bild"?'<span class="tag img">Bild</span>':'<span class="tag text">Text</span>').join(" "):"–"}function T(C){if(!C)return"–";const F=C.quant||"?",$e=C.ctx?Math.round(C.ctx/1024)+"K":"?",dt=C.size_bytes?(C.size_bytes/1024**3).toFixed(1)+" GB":"?";return`<span class="mono-sm">${F} · ${$e} · ${dt}</span>`}function W(C){var F;(F=navigator.clipboard)==null||F.writeText(C),ee("Kopiert: "+C)}var re=Md(),He=s(ot(re),2),J=s(l(He),6);ft(J,21,()=>a(E),ut,(C,F)=>{var $e=vd(),dt=l($e),N={};z(()=>{m(dt,a(F).name),N!==(N=a(F).name)&&($e.value=($e.__value=a(F).name)??"")}),_(C,$e)});var ze=s(J,4),Z=s(ze,2),rt=l(Z),P=s(Z,2);{var H=C=>{var F=ud(),$e=l(F);z(()=>m($e,a(u))),_(C,F)};I(P,C=>{a(u)&&C(H)})}var ie=s(He,2),ge=l(ie),Te=s(l(ge)),mt=l(Te),pt=s(ge,4);{var kt=C=>{var F=fd();_(C,F)},At=C=>{var F=bd(),$e=s(l(F));ft($e,21,()=>a(o),ut,(dt,N)=>{var De=or(),Q=ot(De);{var de=Y=>{var me=pd(),ve=l(me),we=l(ve),xe=s(ve,5),be=l(xe),S=s(be,2);z(()=>m(we,a(N).name)),A("click",be,()=>{var V;ee("Lade im Cookbook ein Modell und setze den Alias auf: "+a(N).name),(V=document.querySelector(".nav-item[data-view='cookbook']"))==null||V.dispatchEvent(new MouseEvent("click"))}),A("click",S,()=>Ue(a(N).name)),_(Y,me)},se=Y=>{var me=md(),ve=l(me),we=l(ve),xe=l(we),be=s(xe);{var S=ke=>{var Ae=hd(),Oe=l(Ae);z(()=>m(Oe,a(N).role)),_(ke,Ae)};I(be,ke=>{a(N).role&&ke(S)})}var V=s(we,2);{var le=ke=>{var Ae=gd(),Oe=l(Ae);z(()=>m(Oe,a(N).meta.filename)),_(ke,Ae)};I(V,ke=>{var Ae;(Ae=a(N).meta)!=null&&Ae.filename&&ke(le)})}var Qe=s(V,2),Je=s(l(Qe),2);ft(Je,17,()=>{var ke;return(ke=a(N).api_ids)!=null&&ke.length?a(N).api_ids:[a(N).name]},ut,(ke,Ae)=>{var Oe=_d(),Ot=l(Oe);z(()=>m(Ot,a(Ae))),A("click",Oe,()=>W(a(Ae))),_(ke,Oe)});var Jt=s(ve);Ce(Jt,()=>{var ke;return _t((ke=a(N).meta)==null?void 0:ke.caps)},!0);var Yt=s(Jt);Ce(Yt,()=>T(a(N).meta),!0);var Vt=s(Yt);Ce(Vt,()=>Uo(a(N).state,a(N).download_progress),!0);var M=s(Vt),G=l(M),qe=s(M),te=l(qe),Be=s(te,2),Ye=s(Be,2),et=s(Ye,2);z(()=>{m(xe,`${a(N).name??""} `),m(G,a(N).port??"auto")}),A("click",te,()=>ue(a(N).name)),A("click",Be,()=>Pe(a(N).name)),A("click",Ye,()=>Le(a(N).name)),A("click",et,()=>Ue(a(N).name)),_(Y,me)};I(Q,Y=>{a(N).incomplete?Y(de):Y(se,-1)})}_(dt,De)}),_(C,F)};I(pt,C=>{a(o).length?C(At,-1):C(kt)})}var Mt=s(ie,2);{var Lt=C=>{var F=wd(),$e=l(F),dt=l($e),N=s(dt,4),De=l(N),Q=s(N,2),de=s(l(Q));Ce(de,()=>gi(n));var se=s(Q,2),Y=s(se,2);{var me=le=>{var Qe=yd(),Je=l(Qe),Jt=s(l(Je),2),Yt=l(Jt),Vt=s(Yt,2),M=s(Je,2);z((G,qe)=>{m(Yt,`Optimal ~${G??""}k → ~${a(L).meta.peak_ram_optimal_gb??""} GB Spitzenbedarf.`),m(Vt,` Aktuell ~${qe??""}k → ~${a(L).meta.peak_ram_gb??""} GB.`)},[()=>Math.round(a(L).meta.optimal_ctx/1024),()=>Math.round((a(L).meta.ctx||0)/1024)]),A("click",M,()=>g(k,a(L).meta.optimal_ctx,!0)),_(le,Qe)};I(Y,le=>{var Qe;(Qe=a(L).meta)!=null&&Qe.optimal_ctx&&le(me)})}var ve=s(Y,4),we=s(l(ve),2),xe=l(we),be=s(xe,2),S=l(be),V=s(ve,2);z(()=>{m(De,a(L).name),fa(be,`color:${a(D)?"var(--accent)":"var(--mut)"}`),m(S,a(D)?"An (TTL = ∞)":"Aus (TTL = 5 min)")}),A("click",F,le=>{le.target.classList.contains("modal-overlay")&&g($,!1)}),A("click",dt,()=>g($,!1)),Ta(se,()=>a(k),le=>g(k,le)),Ro(xe,()=>a(D),le=>g(D,le)),A("click",V,ne),_(C,F)};I(Mt,C=>{a($)&&a(L)&&C(Lt)})}var qt=s(Mt,2);{var Rt=C=>{var F=kd(),$e=l(F),dt=l($e),N=s(dt,2),De=s(l(N));Ce(De,()=>gi(r));var Q=s(N,2),de=l(Q),se=s(Q,4);ft(se,21,()=>i,ut,(xe,be)=>{var S=xd(),V=l(S);z(()=>{wt(S,1,a(U)===a(be).id?"primary":"ghost"),Fr(S,"title",a(be).desc),m(V,a(be).label)}),A("click",S,()=>he(a(be).id)),_(xe,S)});var Y=s(se,4),me=s(Y,2),ve=l(me),we=s(ve,2);z(()=>m(de,a(Ee))),A("click",F,xe=>{xe.target.classList.contains("modal-overlay")&&g(pe,!1)}),A("click",dt,()=>g(pe,!1)),Ta(Y,()=>a(K),xe=>g(K,xe)),A("click",ve,()=>he("")),A("click",we,()=>he(a(K).trim().toLowerCase())),_(C,F)};I(qt,C=>{a(pe)&&C(Rt)})}z(()=>{Z.disabled=a(h),m(rt,a(h)?"…":"Senden"),m(mt,a(o).length?a(o).length+" konfiguriert":"")}),nr(J,()=>a(c),C=>g(c,C)),Ta(ze,()=>a(v),C=>g(v,C)),A("click",Z,p),_(e,re),an()}xn(["click"]);var Ed=w('<div class="tiles"><div class="tile"><div class="t-l">Prozessor (CPU)</div> <div class="t-v"> <small>%</small></div> <div class="t-s"> </div></div> <div class="tile"><div class="t-l">Arbeitsspeicher</div> <div class="t-v"> <small>%</small></div> <div class="t-s"> </div></div> <div class="tile"><div class="t-l">Grafikspeicher</div> <div class="t-v"> <small>%</small></div> <div class="t-s"> </div></div></div> <div class="card"><div class="card-h"><h3>System-Metriken (Bosgame)</h3></div> <div class="card-sub">Live-Auslastung deines Mini-PCs, alle 0,5 Sekunden.</div> <div class="kv" style="margin-bottom:6px"><div class="kv-row"><span class="kv-k">Arbeitsspeicher (RAM)</span><span class="kv-v"> </span></div> <div class="kv-row"><span class="kv-k">Grafikspeicher (VRAM + GTT)</span> <span class="kv-v"> </span></div> <div class="kv-row"><span class="kv-k">Speicherplatz (Disk)</span><span class="kv-v"> </span></div> <div class="kv-row"><span class="kv-k">Temperatur (GPU / CPU)</span> <span class="kv-v"> </span></div></div> <div class="grid grid-3" style="margin-top:14px"><div><div class="meta text-xs">CPU-Verlauf</div><div style="display:flex;align-items:flex-end;gap:2px;height:38px;margin-top:10px"></div></div> <div><div class="meta text-xs">RAM-Verlauf</div><div style="display:flex;align-items:flex-end;gap:2px;height:38px;margin-top:10px"></div></div> <div><div class="meta text-xs">VRAM-Verlauf</div><div style="display:flex;align-items:flex-end;gap:2px;height:38px;margin-top:10px"></div></div></div></div>',1),Td=w('<button class="ghost" style="margin-left:auto;padding:4px 11px;font-size:12px">Verlauf leeren</button>'),$d=w('<div class="empty-c"><div class="e-t">Gerade nichts los.</div> <div class="e-s">Alles ruhig — keine laufenden Aufgaben.</div></div>'),Ad=w('<span class="mono-sm" style="margin-left:auto"> </span>'),Cd=w('<button class="ghost">Abbrechen</button>'),Ld=w('<button class="ghost" title="Aus Verlauf entfernen" style="margin-left:auto;margin-right:2px;padding:2px 9px;font-size:14px;line-height:1">×</button>'),zd=w('<div class="bar" style="margin-top:8px"><i></i></div>'),Dd=w('<div class="log"> </div>'),Pd=w('<div class="job"><div class="job-h" role="button" tabindex="0"><span></span> <span class="mid"> </span> <!> <!> <!></div> <!> <!></div>'),qd=w('<div class="pagehead"><div><h1>Aktivität</h1> <div class="sub">Live-Auslastung und laufende Aufgaben (Downloads, Updates) mit Protokoll.</div></div></div> <!> <div class="card"><div class="card-h"><h3>Hintergrund-Aufgaben</h3> <span class="meta"> </span> <!></div> <div class="card-sub">Downloads & Updates erscheinen hier mit Live-Protokoll — zum Aufklappen klicken.</div> <!></div>',1);function Od(e,t){tn(t,!0);const n=q(()=>dn.value),r=q(()=>dn.tracked),i=q(()=>Li.value);let o=Ht({cpu:[],ram:[],gpu:[]});Ti(()=>{var re;if(!a(i))return;const T=a(i).gpu,W=T&&T.vram.total+T.gtt.total>0?(T.vram.used+T.gtt.used)/(T.vram.total+T.gtt.total)*100:0;o.cpu=[...o.cpu,((re=a(i).cpu)==null?void 0:re.percent)??0].slice(-60),o.ram=[...o.ram,a(i).ram.percent].slice(-60),o.gpu=[...o.gpu,W].slice(-60)});const d=q(()=>()=>{var W;const T=(W=a(i))==null?void 0:W.gpu;return T&&T.vram.total+T.gtt.total>0?(T.vram.used+T.gtt.used)/(T.vram.total+T.gtt.total)*100:0}),c=q(()=>a(n).filter(T=>T.state!=="running"&&T.state!=="queued").length),v=q(()=>a(n).filter(T=>T.state==="failed").length);function u(T){if(T.state!=="running")return null;if(typeof T.progress=="number")return Math.min(100,T.progress);const re=((T.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return re?Math.min(100,parseFloat(re[1])):null}function h(T){return T==null||T<0?"":T>=90?`noch ~${Math.round(T/60)} min`:`noch ~${Math.max(1,Math.round(T))} s`}function E(T){return T==="done"?'<span class="badge b-run">fertig</span>':T==="failed"?'<span class="badge b-err">fehler</span>':T==="canceled"?'<span class="badge">abgebrochen</span>':'<span class="badge b-load">läuft…</span>'}function p(T){return T==="done"?"on":T==="failed"||T==="canceled"?"":"load"}async function x(T){try{await Me(`/api/jobs/${T}/cancel`,{method:"POST"}),ee("Abbruch angefordert…")}catch(W){ee(W.message,!0)}}async function $(T){try{await Me(`/api/jobs/${T}`,{method:"DELETE"})}catch(W){ee(W.message,!0)}}async function L(){try{const T=await Me("/api/jobs/clear",{method:"POST"});ee(`${T.removed} Einträge entfernt.`)}catch(T){ee(T.message,!0)}}function k(T,W){return T.map(re=>`<div style="width:4px;background:var(${W});opacity:.55;height:${Math.max(2,re)}%;border-radius:2px"></div>`).join("")}var D=qd(),Pe=s(ot(D),2);{var ne=T=>{const W=q(()=>a(d)());var re=Ed(),He=ot(re),J=l(He),ze=s(l(J),2),Z=l(ze),rt=s(ze,2),P=l(rt),H=s(J,2),ie=s(l(H),2),ge=l(ie),Te=s(ie,2),mt=l(Te),pt=s(H,2),kt=s(l(pt),2),At=l(kt),Mt=s(kt,2),Lt=l(Mt),qt=s(He,2),Rt=s(l(qt),4),C=l(Rt),F=s(l(C)),$e=l(F),dt=s(C,2),N=s(l(dt),2),De=l(N),Q=s(dt,2),de=s(l(Q)),se=l(de),Y=s(Q,2),me=s(l(Y),2),ve=l(me),we=s(Rt,2),xe=l(we),be=s(l(xe));Ce(be,()=>k(o.cpu,"--accent"),!0);var S=s(xe,2),V=s(l(S));Ce(V,()=>k(o.ram,"--purple"),!0);var le=s(S,2),Qe=s(l(le));Ce(Qe,()=>k(o.gpu,"--on"),!0),z((Je,Jt,Yt,Vt,M,G,qe,te,Be,Ye,et,ke,Ae)=>{m(Z,Je),m(P,Jt),m(ge,Yt),m(mt,`${Vt??""} / ${M??""}`),m(At,G),m(Lt,qe),m($e,`${te??""} / ${Be??""}`),m(De,Ye),m(se,`${et??""} % belegt`),m(ve,`${ke??""} / ${Ae??""}`)},[()=>{var Je;return Math.round(((Je=a(i).cpu)==null?void 0:Je.percent)??0)},()=>{var Je;return((Je=a(i).cpu)==null?void 0:Je.temp)!=null?`${Math.round(a(i).cpu.temp)}° CPU-Temp`:"Auslastung"},()=>Math.round(a(i).ram.percent),()=>rn(a(i).ram.used),()=>rn(a(i).ram.total),()=>Math.round(a(W)),()=>a(i).gpu_temp!=null?`${Math.round(a(i).gpu_temp)}° GPU-Temp`:"VRAM + GTT",()=>rn(a(i).ram.used),()=>rn(a(i).ram.total),()=>a(i).gpu?`${rn(a(i).gpu.vram.used+a(i).gpu.gtt.used)} / ${rn(a(i).gpu.vram.total+a(i).gpu.gtt.total)}`:"–",()=>{var Je;return Math.round(((Je=a(i).disk)==null?void 0:Je.percent)??0)},()=>a(i).gpu_temp!=null?Math.round(a(i).gpu_temp)+"°":"–",()=>{var Je;return((Je=a(i).cpu)==null?void 0:Je.temp)!=null?Math.round(a(i).cpu.temp)+"°":"–"}]),_(T,re)};I(Pe,T=>{a(i)&&T(ne)})}var pe=s(Pe,2),Ee=l(pe),K=s(l(Ee),2),U=l(K),ue=s(K,2);{var he=T=>{var W=Td();A("click",W,L),_(T,W)};I(ue,T=>{a(c)&&T(he)})}var Le=s(Ee,4);{var Ue=T=>{var W=$d();_(T,W)},_t=T=>{var W=or(),re=ot(W);ft(re,17,()=>a(n),ut,(He,J)=>{const ze=q(()=>u(a(J))),Z=q(()=>a(J).state==="running"?h(a(J).eta_s):""),rt=q(()=>a(J).state==="running"&&a(J).rate_bps?rn(a(J).rate_bps)+"/s":""),P=q(()=>[a(Z),a(rt)].filter(Boolean).join(" · ")),H=q(()=>a(r).includes(a(J).id));var ie=Pd(),ge=l(ie),Te=l(ge),mt=s(Te,2),pt=l(mt),kt=s(mt,2);{var At=N=>{var De=Ad(),Q=l(De);z(de=>m(Q,`${de??""} %${a(P)?` · ${a(P)}`:""}`),[()=>Math.round(a(ze))]),_(N,De)};I(kt,N=>{a(ze)!=null&&N(At)})}var Mt=s(kt,2);{var Lt=N=>{var De=Cd();z(()=>fa(De,`${a(ze)==null?"margin-left:auto;":""}margin-right:2px;padding:2px 9px;font-size:12px`)),A("click",De,Q=>{Q.stopPropagation(),x(a(J).id)}),_(N,De)},qt=N=>{var De=Ld();A("click",De,Q=>{Q.stopPropagation(),$(a(J).id)}),_(N,De)};I(Mt,N=>{a(J).state==="running"?N(Lt):N(qt,-1)})}var Rt=s(Mt,2);Ce(Rt,()=>E(a(J).state));var C=s(ge,2);{var F=N=>{var De=zd(),Q=l(De);z(()=>fa(Q,`width:${a(ze)??""}%`)),_(N,De)};I(C,N=>{a(ze)!=null&&a(J).state==="running"&&N(F)})}var $e=s(C,2);{var dt=N=>{var De=Dd(),Q=l(De);z(de=>m(Q,de),[()=>(a(J).log||[]).join(`
|
||
`)]),_(N,De)};I($e,N=>{a(H)&&N(dt)})}z(N=>{wt(Te,1,`li-dot ${N??""}`),m(pt,a(J).label)},[()=>p(a(J).state)]),A("click",ge,()=>dn.toggle(a(J).id)),A("keydown",ge,N=>N.key==="Enter"&&dn.toggle(a(J).id)),_(He,ie)}),_(T,W)};I(Le,T=>{a(n).length?T(_t,-1):T(Ue)})}z(()=>m(U,a(n).length?a(v)?a(v)+" Fehler":a(n).length+" gesamt":"")),_(e,D),an()}xn(["click","keydown"]);var Rd=w('<span class="mono-sm"> </span>'),Bd=w('<button class="ghost" style="margin-left:auto;padding:3px 12px">Abbrechen</button>'),Id=w('<span class="badge b-run">✓ fertig</span>'),Nd=w('<span class="badge b-err">✗ fehlgeschlagen</span>'),Fd=w('<span class="badge">abgebrochen</span>'),Kd=w('<span class="badge b-load">läuft…</span>'),Gd=w('<div class="bar" style="margin-bottom:10px"><i></i></div>'),Ud=w('<div class="card"><div class="card-h"><h3>Aktueller Vorgang</h3> <!> <span style="margin-left:10px"><!></span></div> <div class="card-sub"> </div> <!> <div class="log" style="max-height:280px"> </div></div>'),Hd=w('<div class="pagehead"><div><h1>Server & Wartung</h1> <div class="sub">Dienste steuern, Updates einspielen und live mitlesen — ganz ohne SSH oder Terminal.</div></div></div> <div class="card"><div class="card-h"><h3>LLM-Engine (llama-swap)</h3> <span class="chip"> </span></div> <div class="card-sub">Das Herzstück: lädt bei jeder Anfrage automatisch das passende Modell.</div> <div class="kv" style="margin-bottom:6px"><div class="kv-row"><span class="kv-k">Adresse (für deine Tools)</span><span class="kv-v mono-sm"> </span></div> <div class="kv-row"><span class="kv-k">Aktuell geladen</span> <span class="kv-v"> </span></div> <div class="kv-row"><span class="kv-k">Konfigurierte Modelle</span> <span class="kv-v"> </span></div></div> <div class="btn-row" style="display:flex;align-items:center;gap:10px"><button class="ghost">Verbindung prüfen</button> <!></div></div> <div class="card"><div class="card-h"><h3>Dienste & Applikation</h3></div> <div class="card-sub">Diese Aktionen sind harmlos und passwortlos — es geht nichts dabei verloren.</div> <button class="qa"><span class="qa-ic teal">↻</span> <span class="qa-main"><span class="qa-t">LLM-Engine neustarten</span><span class="qa-s">Startet llama-swap neu. Geladene Modelle laden danach automatisch wieder.</span></span> <span class="qa-arrow">›</span></button> <button class="qa"><span class="qa-ic blue">↻</span> <span class="qa-main"><span class="qa-t">Dashboard neustarten</span><span class="qa-s">Startet diese Oberfläche neu (~5 Sek).</span></span> <span class="qa-arrow">›</span></button> <button class="qa"><span class="qa-ic teal">⬇</span> <span class="qa-main"><span class="qa-t">Mission Control aktualisieren</span><span class="qa-s">Holt die neueste Version aus Gitea und startet automatisch neu (~10 Sek).</span></span> <span class="qa-arrow">›</span></button> <button class="qa"><span class="qa-ic blue">⚡</span> <span class="qa-main"><span class="qa-t">LLM-Engine aktualisieren</span><span class="qa-s">Lädt die neueste llama.cpp-Version (ROCm) für deine GPU.</span></span> <span class="qa-arrow">›</span></button> <button class="qa"><span class="qa-ic amber">🗄</span> <span class="qa-main"><span class="qa-t">Grafikspeicher leeren</span><span class="qa-s">Wirft alle aktuell geladenen Modelle aus dem VRAM. Fragt vorher nach.</span></span> <span class="qa-arrow">›</span></button></div> <div class="card"><div class="card-h"><h3>Betriebssystem (Bosgame)</h3></div> <div class="card-sub">Tiefe Eingriffe — das Dashboard fragt einmalig nach deinem sudo-Passwort.</div> <button class="qa"><span class="qa-ic amber">↻</span> <span class="qa-main"><span class="qa-t">OS-Updates installieren</span><span class="qa-s">Führt apt update & upgrade aus. Kann ein paar Minuten dauern.</span></span> <span class="qa-arrow">›</span></button> <button class="qa qa-danger"><span class="qa-ic red">⚡</span> <span class="qa-main"><span class="qa-t">Server neustarten (Reboot)</span><span class="qa-s">Bootet den ganzen Bosgame neu. Alles ist für ~1 Minute offline.</span></span> <span class="qa-arrow">›</span></button></div> <!> <div class="card"><div class="card-h"><h3>Live-Konsole</h3> <select style="margin:0 0 0 auto;width:240px"><option>LLM-Engine (llama-swap)</option><option>Dashboard (mission-control)</option><option>System (ganzer Server)</option></select></div> <div class="card-sub">Live mitlesen, was der Dienst gerade tut.</div> <div class="console"> </div></div>',1);function Vd(e,t){tn(t,!0);const n=q(()=>mr.value),r=q(()=>dn.value);let i=null,o=O(`Verbinde…
|
||
`),d=O("llama-swap"),c,v=O(null),u=O("");const h=new Set,E=q(()=>a(v)?a(r).find(S=>S.id===a(v)):null);Ti(()=>{if(!a(E))return;const S=a(E),V=S.state==="done",le=S.state==="failed",Qe=S.state==="canceled";(V||le||Qe)&&!h.has(S.id)&&(h.add(S.id),ee(V?`✓ ${a(u)} abgeschlossen.`:Qe?`${a(u)} abgebrochen.`:`✗ ${a(u)} fehlgeschlagen.`,le),V&&setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),800))});function p(S,V){g(v,S,!0),g(u,V,!0),dn.track(S)}_r(()=>{x()}),Io(()=>{i==null||i.close()});function x(){i==null||i.close();const S=a(d);g(o,`Verbinde mit ${S}…
|
||
`);const V=location.protocol==="https:"?"wss:":"ws:";i=new WebSocket(`${V}//${location.host}/api/logs/${S}?token=${encodeURIComponent(el())}`),i.onmessage=le=>{g(o,a(o)+le.data),c&&(c.scrollTop=c.scrollHeight)},i.onclose=()=>{g(o,a(o)+`
|
||
— Verbindung getrennt —`)},i.onerror=()=>i==null?void 0:i.close()}async function $(S,V,le){if(await wa({title:V,body:le,confirmLabel:"Neustarten"}))try{await Me(`/api/service/${S}/restart`,{method:"POST"}),ee("Neustart ausgelöst: "+S),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),2e3)}catch(Qe){ee(Qe.message,!0)}}async function L(){if(await wa({title:"Mission Control aktualisieren?",body:"Holt die neueste Dashboard-Version aus Gitea und startet automatisch neu. Die Seite trennt kurz und verbindet von selbst wieder (~10 Sek)."}))try{const S=await Me("/api/self-update",{method:"POST"});ee("Update läuft — Dashboard startet gleich neu."),p(S.job_id,"Mission Control Update")}catch(S){ee(S.message,!0)}}async function k(){if(await wa({title:"LLM-Engine aktualisieren?",body:"Lädt die neueste llama.cpp-ROCm-Version und installiert sie. Die Engine ist während des Updates kurz nicht erreichbar."}))try{const S=await Me("/api/update",{method:"POST"});ee("LLM-Engine-Update läuft."),p(S.job_id,"LLM-Engine-Update")}catch(S){ee(S.message,!0)}}async function D(){if(await wa({title:"Grafikspeicher leeren?",body:"Alle geladenen Modelle werden entladen. Sie laden beim nächsten Aufruf automatisch neu — es geht nichts verloren.",confirmLabel:"Leeren"}))try{await Me("/api/unload",{method:"POST"}),ee("Grafikspeicher geleert."),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),600)}catch(S){ee(S.message,!0)}}async function Pe(){if(!await wa({title:"OS-Updates installieren?",body:"Führt <code>apt update & upgrade</code> aus. Das kann ein paar Minuten dauern; der Fortschritt erscheint in der Aktivität."}))return;const S=await Wi({title:"sudo-Passwort",body:"Für die System-Updates wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Installieren"});if(S)try{const V=await Me("/api/os-update",{method:"POST",body:JSON.stringify({password:S})});ee("OS-Update gestartet."),p(V.job_id,"OS-Update")}catch(V){ee(V.message,!0)}}async function ne(){if(!await wa({title:"Server wirklich neu starten?",body:"Der ganze Bosgame startet physisch neu. Alles ist für ~1 Minute offline — auch dieses Dashboard.",confirmLabel:"Reboot",danger:!0}))return;const S=await Wi({title:"sudo-Passwort",body:"Für den Reboot wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Jetzt neustarten",danger:!0});if(S)try{await Me("/api/reboot",{method:"POST",body:JSON.stringify({password:S})}),ee("Reboot ausgelöst — bis gleich.")}catch(V){ee(V.message,!0)}}async function pe(){g(Ee,"prüfe…");try{const S=await Me("/api/integration/test");g(Ee,S.ok?`✓ Engine antwortet — ${S.models.length} Modell(e): ${S.models.join(", ")}`:`✗ keine Verbindung: ${S.error}`,!0),g(K,S.ok,!0)}catch(S){g(Ee,"✗ "+S.message),g(K,!1)}}let Ee=O(""),K=O(!1);const U=q(()=>{var S;return((S=a(n))==null?void 0:S.models)||[]}),ue=["running","ready","loading","starting"],he=q(()=>a(U).find(S=>ue.includes(S.state)));function Le(S){if(!S||S.state!=="running")return null;if(typeof S.progress=="number")return Math.min(100,S.progress);const le=((S.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return le?Math.min(100,parseFloat(le[1])):null}var Ue=Hd(),_t=s(ot(Ue),2),T=l(_t),W=s(l(T),2),re=l(W),He=s(T,4),J=l(He),ze=s(l(J)),Z=l(ze),rt=s(J,2),P=s(l(rt),2),H=l(P),ie=s(rt,2),ge=s(l(ie),2),Te=l(ge),mt=s(He,2),pt=l(mt),kt=s(pt,2);{var At=S=>{var V=Rd(),le=l(V);z(()=>{fa(V,`color:${a(K)?"#7ee29a":"#ff9b95"}`),m(le,a(Ee))}),_(S,V)};I(kt,S=>{a(Ee)&&S(At)})}var Mt=s(_t,2),Lt=s(l(Mt),4),qt=s(Lt,2),Rt=s(qt,2),C=s(Rt,2),F=s(C,2),$e=s(Mt,2),dt=s(l($e),4),N=s(dt,2),De=s($e,2);{var Q=S=>{const V=q(()=>a(E)),le=q(()=>a(V).state==="done"),Qe=q(()=>a(V).state==="failed"),Je=q(()=>a(V).state==="canceled"),Jt=q(()=>a(le)||a(Qe)||a(Je)),Yt=q(()=>Le(a(V)));var Vt=Ud(),M=l(Vt),G=s(l(M),2);{var qe=Ke=>{var ht=Bd();A("click",ht,async()=>{await wa({title:a(u)+" abbrechen?",body:"Der laufende Vorgang wird gestoppt.",confirmLabel:"Abbrechen",danger:!0})&&Me(`/api/jobs/${a(V).id}/cancel`,{method:"POST"})}),_(Ke,ht)};I(G,Ke=>{a(Jt)||Ke(qe)})}var te=s(G,2),Be=l(te);{var Ye=Ke=>{var ht=Id();_(Ke,ht)},et=Ke=>{var ht=Nd();_(Ke,ht)},ke=Ke=>{var ht=Fd();_(Ke,ht)},Ae=Ke=>{var ht=Kd();_(Ke,ht)};I(Be,Ke=>{a(le)?Ke(Ye):a(Qe)?Ke(et,1):a(Je)?Ke(ke,2):Ke(Ae,-1)})}var Oe=s(M,2),Ot=l(Oe),Bt=s(Oe,2);{var Wt=Ke=>{var ht=Gd(),qa=l(ht);z(()=>fa(qa,`width:${a(Yt)??""}%`)),_(Ke,ht)};I(Bt,Ke=>{a(Yt)!=null&&!a(Jt)&&Ke(Wt)})}var na=s(Bt,2),_a=l(na);z(Ke=>{m(Ot,`${a(u)??""}${a(Jt)?a(le)?" — erfolgreich.":a(Je)?" — abgebrochen.":" — fehlgeschlagen.":" läuft…"}`),m(_a,Ke)},[()=>(a(V).log||[]).join(`
|
||
`)]),_(S,Vt)};I(De,S=>{a(E)&&S(Q)})}var de=s(De,2),se=l(de),Y=s(l(se),2),me=l(Y);me.value=me.__value="llama-swap";var ve=s(me);ve.value=ve.__value="mission-control";var we=s(ve);we.value=we.__value="system";var xe=s(se,4),be=l(xe);Bo(xe,S=>c=S,()=>c),z(S=>{var V,le,Qe;fa(W,`margin-left:auto;${(V=a(n))!=null&&V.swap_ok?"background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a":"background:rgba(248,81,73,.12);border-color:rgba(248,81,73,.3);color:#ff9b95"}`),m(re,(le=a(n))!=null&&le.swap_ok?"● erreichbar":"● offline"),m(Z,(((Qe=a(n))==null?void 0:Qe.swap_url)||"—")+"/v1"),m(H,a(he)?a(he).name+` (${a(he).state})`:"nichts geladen — lädt bei der nächsten Anfrage"),m(Te,S),m(be,a(o))},[()=>a(U).filter(S=>!S.incomplete).length||"keine"]),A("click",pt,pe),A("click",Lt,()=>$("llama-swap","LLM-Engine neustarten?","Die Engine startet neu. Geladene Modelle werden kurz entladen (~5 Sekunden), laden danach automatisch wieder.")),A("click",qt,()=>$("mission-control","Dashboard neustarten?","Diese Oberfläche trennt sich kurz und verbindet automatisch wieder.")),A("click",Rt,L),A("click",C,k),A("click",F,D),A("click",dt,Pe),A("click",N,ne),A("change",Y,x),nr(Y,()=>a(d),S=>g(d,S)),_(e,Ue),an()}xn(["click","change"]);var Wd=w('<div class="empty" style="text-align:center;padding:30px">Lade Setups…</div>'),jd=w('<span title="Setup bearbeiten" style="position:absolute;top:10px;right:36px;color:var(--accent);cursor:pointer;font-size:14px;line-height:1" role="button" tabindex="0">✎</span> <span title="Setup löschen" style="position:absolute;top:9px;right:12px;color:var(--err);cursor:pointer;font-size:18px;line-height:1" role="button" tabindex="0">×</span>',1),Xr=w('<div class="cb-best-tag">★ Beste Wahl für dein System</div>'),Qd=w('<div class="cb-best-tag" style="background:var(--act);color:#fff">Dein Setup</div>'),Jd=w('<button style="text-align:left;position:relative"><!> <!> <div class="flex justify-between items-center"><span class="flex items-center gap-2"><h3 style="margin:0;font-size:15px"> </h3></span> <span> </span></div> <p> </p> <div class="text-xs text-mut"> </div></button>'),Yd=w('<div id="cb-recipes" class="grid grid-3" style="gap:10px;margin-top:6px"></div>'),Zd=w('<span style="color:var(--warn)">· ⚠ Cache veraltet</span>'),Xd=w("<!> <!>",1),ec=w('<div class="empty" style="text-align:center;padding:30px">Frage Quellen ab…</div>'),tc=w('<div class="li-sub" style="color:var(--warn);margin-top:3px"> </div>'),ac=w('<span class="fit-badge ok">✓ installiert</span>'),nc=w('<button class="primary" style="padding:6px 12px;font-size:12.5px">Installieren</button>'),rc=w('<div style="display:flex;flex-direction:column;position:relative"><!> <div class="flex justify-between" style="align-items:flex-start;gap:8px"><div style="min-width:0"><h3 style="margin:0;font-size:14px;font-weight:500;word-break:break-word"> </h3> <div class="text-xs text-mut" style="margin-top:3px"> </div></div> <span> </span></div> <div class="flex gap-2" style="flex-wrap:wrap;margin-top:7px"><!> <!></div> <div class="mono-sm text-mut" style="margin-top:8px;font-size:11.5px"> </div> <!> <div style="flex:1;min-height:8px"></div> <div class="flex justify-end" style="margin-top:10px"><!></div></div>'),ic=w('<div style="margin-bottom:8px"><div class="flex items-center gap-2" style="margin:6px 0 8px"><h4 style="margin:0;font-size:13.5px;font-weight:600"> </h4></div> <div class="grid grid-3"></div></div>'),sc=w('<button style="padding:4px 10px;border-radius:999px;font-size:12px"> </button>'),lc=w('<div style="display:flex;flex-direction:column;cursor:pointer"><!> <div class="flex justify-between" style="align-items:flex-start;gap:8px"><div style="min-width:0"><h3 style="margin:0;font-size:14.5px;font-weight:500;word-break:break-word"> </h3> <div class="text-xs text-mut" style="margin-top:3px"> </div></div> <span> </span></div> <div class="flex gap-2" style="flex-wrap:wrap;margin-top:7px"><!> <!></div> <div style="flex:1;margin-top:12px"></div> <div class="flex justify-between items-center text-xs text-mut" style="border-top:1px solid var(--line);padding-top:11px"><span class="mono-sm"> </span> <span class="mono-sm"> </span></div></div>'),oc=w('<div class="grid grid-3" id="cb-grid"></div>'),dc=w('<div class="li-sub"> </div>'),cc=w('<div class="li-sub mono-sm"> </div>'),vc=w("<span> </span>"),uc=w('<div class="li" style="align-items:flex-start"><div class="li-main"><div class="flex items-center gap-2" style="flex-wrap:wrap"><span class="li-id"> </span> <span class="tag text"> </span> <!></div> <!> <!></div> <!></div>'),fc=w('<div class="hint" style="margin:12px 0">Größter Spitzenbedarf: <b> </b>. Es läuft immer nur <b>ein</b> Modell gleichzeitig — das größte bestimmt, ob das Setup passt.</div>'),pc=w('Alternative: <a href="#" style="color:var(--accent)"> </a> — passt auf dein System.',1),hc=w('<div class="hint" style="color:var(--warn);margin-bottom:10px;border-left:2px solid var(--warn);padding-left:10px">⚠ Dieses Setup übersteigt deinen verfügbaren Speicher. <!></div>'),gc=w('<div class="modal-overlay" role="dialog"><div class="modal-card" style="max-width:560px"><button class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button> <h3> </h3> <p class="text-mut text-sm" style="margin:-4px 0 16px"> </p> <div class="list"></div> <!> <!> <button id="cb-r-install-btn" style="width:100%"> </button></div></div>'),_c=w('<div class="hint">Lade Dateien von HuggingFace…</div>'),Zi=w("<option> </option>"),mc=w('<div class="hint" style="margin:-6px 0 14px">Empfohlener Kontext für deine Hardware: <b> </b> — <a href="#">übernehmen</a></div>'),bc=w('<div class="tile" style="display:flex;justify-content:space-between;align-items:center;margin:8px 0 18px"><div><div style="font-size:13px">Ressourcen-Check</div> <div class="hint" style="margin:4px 0 0"> </div></div> <span> </span></div>'),yc=w('<div class="hint" style="color:var(--warn);margin:-8px 0 14px;border-left:2px solid var(--warn);padding-left:10px">⚠ Diese Datei ist zu groß für deinen Speicher. Kleinere Alternative: <a href="#" style="color:var(--accent)"> </a> — einfach auswählen.</div>'),wc=w('<div class="hint" style="color:var(--warn);margin:-8px 0 14px;border-left:2px solid var(--warn);padding-left:10px">⚠ Alle Varianten dieses Modells sind zu groß für deinen Speicher. Ein kleineres Modell aus den Empfehlungen wäre die bessere Wahl.</div>'),xc=w('<label>Quantisierung (GGUF-Datei) wählen</label> <select></select> <div class="row" style="margin-top:4px"><div><label>Rolle (optional)</label> <input placeholder="z.B. coder, vision, scout"/></div> <div><label>Kontext-Größe <!></label> <input type="number"/></div></div> <!> <!> <!> <button style="width:100%"> </button>',1),kc=w('<div class="hint">Keine GGUF-Dateien im Repo gefunden.</div>'),Mc=w('<div class="modal-overlay" role="dialog"><div class="modal-card" style="max-width:560px"><button class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button> <h3> </h3> <p class="mono-sm" style="margin:-4px 0 16px"> </p> <!></div></div>'),Sc=w('<div class="flex gap-2" style="margin-bottom:8px;align-items:center"><input placeholder="Repo, z.B. unsloth/Qwen3-8B-GGUF" style="flex:2;margin:0"/> <input placeholder="Rolle (z.B. coder)" style="flex:1;margin:0"/> <select style="width:auto;margin:0"></select> <button class="ghost del" style="margin:0;padding:6px 10px">×</button></div>'),Ec=w('<div class="modal-overlay" role="dialog"><div class="modal-card" style="max-width:640px"><button class="ghost" style="position:absolute;top:14px;right:14px">Schließen</button> <h3> </h3> <p class="text-mut text-sm" style="margin:-4px 0 16px">Stell dir aus beliebigen Modellen ein eigenes Setup zusammen.</p> <label>Titel</label> <input placeholder="z.B. Mein Schreib-Stack"/> <label>Kurzbeschreibung (optional)</label> <input placeholder="Wofür ist dieses Setup gut?"/> <label style="margin-top:10px">Modelle</label> <!> <button class="ghost" style="margin-top:8px">+ Modell hinzufügen</button> <div class="hint" style="margin-top:10px">Die <b>Repo-ID</b> findest du über die <b>Profi-Suche</b> weiter unten (z.B. <code>unsloth/Qwen3-8B-GGUF</code>).</div> <button class="primary" style="width:100%;margin-top:14px"> </button></div></div>'),Tc=w('<div class="pagehead"><div><h1>Cookbook</h1><div class="sub">Modelle finden, installieren und eigene Setups zusammenstellen.</div></div></div> <div class="card"><div class="card-h"><h3>1 · Anwendungsfall wählen & installieren</h3> <button class="ghost" style="margin-left:auto">+ Eigenes Setup</button></div> <div class="card-sub">Hier starten: Fertige Modell-Bundles für deinen Anwendungsfall — ein Klick installiert alles. Die Hardware-Ampel zeigt vorab, ob das Setup auf deinen PC passt.</div> <!></div> <div class="card"><div class="card-h"><h3>Aktuell die besten Modelle für dein System</h3> <span class="meta" style="margin-left:auto"><!></span> <button class="ghost" style="margin-left:8px"> </button></div> <div class="card-sub">Top-Modelle je Kategorie von HuggingFace — Hardware-Fit wird live für dein System berechnet.</div> <!></div> <div class="card"><div class="card-h"><h3>Profi-Suche (HuggingFace)</h3></div> <div class="card-sub">Direkt HuggingFace durchsuchen — oder eine Modell-URL einfügen für den direkten Sprung.</div> <div class="flex gap-2" style="align-items:stretch;margin-bottom:10px"><input placeholder="Suchbegriff oder HuggingFace-URL…" style="flex:1;margin:0"/> <select style="width:auto;margin:0"><option>Downloads</option><option>Trending</option><option>Neu</option></select> <button class="primary"> </button></div> <div class="flex gap-2" style="flex-wrap:wrap;margin-bottom:12px"></div> <!></div> <!> <!> <!>',1);function $c(e,t){tn(t,!0);const n="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr, braucht aber mehr Speicher und wird etwas langsamer.",r="MoE (Mixture of Experts): viele Parameter fürs Wissen, aber pro Wort ist nur ein kleiner Teil aktiv → fast große-Modell-Qualität bei hohem Tempo. Ideal für deine APU.",i={perfect:0,marginal:1,too_tight:2},o={vision:"Bilder",coder:"Coden",reasoning:"Logik",agent:"Agenten & Tools",scout:"Allrounder",reviewer:"Review",manager:"Manager"},d=[{label:"Bilder",kw:["-vl-","-vl","vision","llava","multimodal","-mm-","pixtral"]},{label:"Coden",kw:["coder","-code-","code-","codestral","starcoder"]},{label:"Logik",kw:["-r1","deepseek-r1","reasoning","qwq","magistral","-think","thinking","-o1"]},{label:"Agenten & Tools",kw:["hermes","-tool","command-r","watt","-fc-","function"]}];function c(y){const b=(y||"").toLowerCase();for(const B of d)if(B.kw.some(R=>b.includes(R)))return B.label;return"Allrounder"}function v(y=""){const b=y.toLowerCase();return/\d+x\d+(\.\d+)?b/.test(b)||new RegExp("(?<![a-z])a\\d+(\\.\\d+)?b\\b").test(b)||b.includes("mixtral")||/\bmoe\b/.test(b)}function u(y=""){const b=y.toLowerCase().match(new RegExp("(?<![a-z])a(\\d+(?:\\.\\d+)?)b\\b"));return b?b[1]:null}function h(y){return y==="perfect"?"ok":y==="marginal"?"warn":"bad"}function E(y){return y==="perfect"?"Passt":y==="marginal"?"Knapp":"Zu groß"}function p(y){return`~${(y.req_gb??0).toFixed(1)} GB · ~${Math.round(y.tps??0)} Tok/s`}let x=O(Ht([])),$=O(null),L=O(!0),k=O(null),D=O(!1),Pe=O(!1),ne=O(""),pe=O(Ht([])),Ee=O(!1),K=O(""),U=O("downloads"),ue=O(Ht([])),he=O(-1),Le=O(null),Ue=O(!1),_t=O(""),T=O(""),W=O(null),re=O(""),He=O(""),J=O(8192),ze=O(!1),Z=O(null),rt=O(!1),P=O(""),H=O(""),ie=O(Ht([{repo:"",role:"",quant:"Q4_K_M"}])),ge=O(null);function Te(y){var b;(b=document.querySelector(`.nav-item[data-view="${y}"]`))==null||b.dispatchEvent(new MouseEvent("click"))}_r(()=>{mt(),pt()});async function mt(){g(L,!0);try{const y=await Me("/api/cookbook/recipes");g(x,y.recipes||[],!0),g($,y.recommended_id||null,!0)}catch(y){ee(y.message,!0)}g(L,!1)}async function pt(y=!1){g(D,!0);try{const b=await Me("/api/cookbook/discover"+(y?"?force=true":""));g(k,b,!0),g(Pe,b.stale,!0)}catch(b){ee("Empfehlungen nicht ladbar: "+b.message,!0)}g(D,!1)}function kt(y){y=y.trim();const b=y.match(/huggingface\.co\/([^\s/]+\/[^\s/?#]+)/i);return b?b[1]:/^[\w.-]+\/[\w.-]+$/.test(y)?y:null}async function At(){const y=a(ne).trim(),b=kt(y);let B=y;if(a(K)&&!b&&(B=B?B+" "+a(K):a(K)),!B&&!b){g(pe,[],!0);return}g(Ee,!0),g(ue,[],!0),g(he,-1);try{if(b)g(pe,[{id:b,author:b.split("/")[0],downloads:0}],!0);else{const R=`https://huggingface.co/api/models?search=${encodeURIComponent(B)}&filter=gguf&sort=${encodeURIComponent(a(U))}&direction=-1&limit=40`,ae=await fetch(R);g(pe,await ae.json(),!0)}a(pe).forEach((R,ae)=>Mt(ae,R.id))}catch(R){ee(R.message,!0),g(pe,[],!0)}g(Ee,!1)}async function Mt(y,b){var B;try{const R=await Me("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:b,ctx:8192})});if(!((B=R.files)!=null&&B.length)){a(ue)[y]=null,Lt();return}const ae=R.files.find(tt=>{var it;return(it=tt.quant)==null?void 0:it.includes("Q4_K_M")})||R.files[0];a(ue)[y]=ae.fit.level,Lt()}catch{a(ue)[y]=null,Lt()}}function Lt(){let y=-1,b=99;a(ue).forEach((B,R)=>{if(B==null)return;const ae=i[B]??99;ae<b&&(b=ae,y=R)}),g(he,y>=0&&b<=1?y:-1,!0)}function qt(y){g(Le,a(x).find(b=>b.id===y),!0)}async function Rt(y){const b=document.getElementById("cb-r-install-btn");b&&(b.disabled=!0,b.textContent="Starte…");try{const B=await Me("/api/cookbook/install-recipe",{method:"POST",body:JSON.stringify({recipe_id:y,hf_token:ir()})});ee(`${B.count} Download${B.count!==1?"s":""} läuft — Modelle erscheinen danach automatisch im Modelle-Tab.`),g(Le,null),Te("activity")}catch(B){ee(B.message,!0),b&&(b.disabled=!1,b.textContent="Installieren")}}async function C(y,b){var B,R;g(Ue,!0),g(_t,b,!0),g(T,y,!0),g(He,""),g(J,8192),g(W,null),g(Z,null),g(re,""),g(ze,!0);try{if(g(W,await Me("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:y,ctx:8192})}),!0),(R=(B=a(W))==null?void 0:B.files)!=null&&R.length){const ae=a(W).files.find(tt=>{var it;return(it=tt.quant)==null?void 0:it.includes("Q4_K_M")})||a(W).files[0];g(re,ae.filename,!0),ae.optimal_ctx&&a(J)===8192&&g(J,ae.optimal_ctx,!0),F()}}catch(ae){ee(ae.message,!0)}g(ze,!1)}function F(){var y,b,B;!((b=(y=a(W))==null?void 0:y.files)!=null&&b.length)||!a(re)||(g(Z,a(W).files.find(R=>R.filename===a(re))||null,!0),(B=a(Z))!=null&&B.optimal_ctx&&a(J)===8192&&g(J,a(Z).optimal_ctx,!0))}async function $e(){var y,b;if(!a(T)||!a(re))return ee("Bitte eine GGUF-Datei wählen.",!0);g(ze,!0);try{const B=((y=a(W))==null?void 0:y.params_b)??7,R=((b=a(Z))==null?void 0:b.quant)??"Q4_K_M";await Me("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:a(T),role:a(He),params_b:B,quant:R,file:a(re),ctx:a(J),hf_token:ir()})}),ee("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),g(Ue,!1),Te("activity")}catch(B){ee("Fehler: "+B.message,!0)}g(ze,!1)}async function dt(y,b,B,R){R.disabled=!0,R.textContent="Starte…";try{await Me("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:y,role:b,params_b:B,quant:"Q4_K_M",hf_token:ir()})}),ee("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),Te("activity")}catch(ae){ee(ae.message,!0),R.disabled=!1,R.textContent="Installieren"}}function N(){g(ge,null),g(P,""),g(H,""),g(ie,[{repo:"",role:"",quant:"Q4_K_M"}],!0),g(rt,!0)}function De(y){const b=a(x).find(B=>B.id===y);b&&(g(ge,y,!0),g(P,b.title,!0),g(H,b.desc||"",!0),g(ie,b.models.map(B=>({repo:B.repo,role:B.role,quant:B.quant||"Q4_K_M"})),!0),g(rt,!0))}async function Q(){if(!a(P).trim())return ee("Bitte einen Titel angeben.",!0);const y=a(ie).filter(b=>b.repo.trim());if(!y.length)return ee("Mindestens ein Modell (Repo) angeben.",!0);try{a(ge)?(await Me("/api/cookbook/user-recipe/"+encodeURIComponent(a(ge)),{method:"PUT",body:JSON.stringify({title:a(P),desc:a(H),models:y})}),ee("Setup aktualisiert.")):(await Me("/api/cookbook/user-recipe",{method:"POST",body:JSON.stringify({title:a(P),desc:a(H),models:y})}),ee("Setup gespeichert.")),g(rt,!1),mt()}catch(b){ee(b.message,!0)}}async function de(y){const b=a(x).find(B=>B.id===y);if(await wa({title:`„${(b==null?void 0:b.title)||y}" löschen?`,body:"Dein eigenes Setup wird aus dem Cookbook entfernt. Bereits installierte Modelle bleiben unangetastet.",confirmLabel:"Löschen",danger:!0}))try{await Me("/api/cookbook/user-recipe/"+encodeURIComponent(y),{method:"DELETE"}),ee("Setup gelöscht."),mt()}catch(B){ee(B.message,!0)}}function se(y){if(!v(y))return"";const b=u(y);return`<span class="chip" title="${za(r)}">MoE${b?` · ~${b}B aktiv`:""}</span>`}function Y(y){return y?`<span class="chip">${za(y)}</span>`:""}var me=Tc(),ve=s(ot(me),2),we=l(ve),xe=s(l(we),2),be=s(we,4);{var S=y=>{var b=Wd();_(y,b)},V=y=>{var b=Yd();ft(b,21,()=>a(x),ut,(B,R)=>{const ae=q(()=>a(R).id===a($));var tt=Jd(),it=l(tt);{var X=fe=>{var Ze=jd(),Nt=ot(Ze),Tt=s(Nt,2);A("click",Nt,bt=>{bt.stopPropagation(),De(a(R).id)}),A("keydown",Nt,bt=>{bt.key==="Enter"&&(bt.stopPropagation(),De(a(R).id))}),A("click",Tt,bt=>{bt.stopPropagation(),de(a(R).id)}),A("keydown",Tt,bt=>{bt.key==="Enter"&&(bt.stopPropagation(),de(a(R).id))}),_(fe,Ze)};I(it,fe=>{a(R).user&&fe(X)})}var _e=s(it,2);{var Re=fe=>{var Ze=Xr();_(fe,Ze)},ct=fe=>{var Ze=Qd();_(fe,Ze)};I(_e,fe=>{a(ae)?fe(Re):a(R).user&&fe(ct,1)})}var Ie=s(_e,2),Ge=l(Ie),st=l(Ge),St=l(st),Zt=s(Ge,2),vt=l(Zt),Ne=s(Ie,2),Et=l(Ne),It=s(Ne,2),gt=l(It);z((fe,Ze)=>{wt(tt,1,`card-btn${a(ae)?" cb-best":""}`),m(St,a(R).title),wt(Zt,1,`fit-badge ${fe??""}`),m(vt,Ze),m(Et,a(R).desc),m(gt,`${a(R).models.length??""} Modell${a(R).models.length>1?"e":""} im Setup`)},[()=>h(a(R).fit_level),()=>E(a(R).fit_level)]),A("click",tt,()=>qt(a(R).id)),_(B,tt)}),_(y,b)};I(be,y=>{a(L)?y(S):y(V,-1)})}var le=s(ve,2),Qe=l(le),Je=s(l(Qe),2),Jt=l(Je);{var Yt=y=>{const b=q(()=>Math.round((Date.now()/1e3-a(k).updated)/60));var B=Xd(),R=ot(B);{var ae=Re=>{var ct=ar();z(()=>m(ct,`Quellen befragt vor ${a(b)??""} min`)),_(Re,ct)},tt=Re=>{var ct=ar();z(Ie=>m(ct,`Quellen befragt vor ${Ie??""} h`),[()=>Math.round(a(b)/60)]),_(Re,ct)},it=Re=>{var ct=ar();z(Ie=>m(ct,`Quellen befragt vor ${Ie??""} Tg.`),[()=>Math.round(a(b)/1440)]),_(Re,ct)};I(R,Re=>{a(b)<60?Re(ae):a(b)<1440?Re(tt,1):Re(it,-1)})}var X=s(R,2);{var _e=Re=>{var ct=Zd();_(Re,ct)};I(X,Re=>{a(Pe)&&Re(_e)})}_(y,B)};I(Jt,y=>{var b;(b=a(k))!=null&&b.updated&&y(Yt)})}var Vt=s(Je,2),M=l(Vt),G=s(Qe,4);{var qe=y=>{var b=ec();_(y,b)},te=y=>{var b=or(),B=ot(b);ft(B,17,()=>a(k).categories,ut,(R,ae)=>{var tt=ic(),it=l(tt),X=l(it),_e=l(X),Re=s(it,2);ft(Re,21,()=>a(ae).models,ut,(ct,Ie)=>{const Ge=q(()=>a(ae).recommended&&a(Ie).repo===a(ae).recommended);var st=rc(),St=l(st);{var Zt=Xe=>{var nt=Xr();_(Xe,nt)};I(St,Xe=>{a(Ge)&&Xe(Zt)})}var vt=s(St,2),Ne=l(vt),Et=l(Ne),It=l(Et),gt=s(Et,2),fe=l(gt),Ze=s(Ne,2),Nt=l(Ze),Tt=s(vt,2),bt=l(Tt);Ce(bt,()=>Y(o[a(Ie).role]||c(a(Ie).repo)));var Oa=s(bt,2);Ce(Oa,()=>se(a(Ie).repo));var Ha=s(Tt,2),Sa=l(Ha),kn=s(Ha,2);ft(kn,17,()=>a(Ie).requirements||[],ut,(Xe,nt)=>{var Ct=tc(),Ea=l(Ct);z(()=>m(Ea,`⚠ ${a(nt)??""}`)),_(Xe,Ct)});var lt=s(kn,4),Ve=l(lt);{var at=Xe=>{var nt=ac();z(()=>Fr(nt,"title",`bereits eingerichtet als ${a(Ie).installed??""}`)),_(Xe,nt)},yt=Xe=>{var nt=nc();A("click",nt,Ct=>dt(a(Ie).repo,a(Ie).role,a(Ie).params_b,Ct.currentTarget)),_(Xe,nt)};I(Ve,Xe=>{a(Ie).installed?Xe(at):Xe(yt,-1)})}z((Xe,nt,Ct)=>{wt(st,1,`card${a(Ge)?" res-best":""}`),m(It,a(Ie).name),m(fe,`${a(Ie).author??""} · ${a(Ie).params_b??""}B`),wt(Ze,1,`fit-badge ${Xe??""}`),m(Nt,a(Ie).fit.text),m(Sa,`${nt??""} · ⬇ ${Ct??""}`)},[()=>h(a(Ie).fit.level),()=>p(a(Ie).fit),()=>(a(Ie).downloads||0).toLocaleString()]),_(ct,st)}),z(()=>m(_e,a(ae).title)),_(R,tt)}),_(y,b)};I(G,y=>{var b;a(D)&&!a(k)?y(qe):(b=a(k))!=null&&b.categories&&y(te,1)})}var Be=s(le,2),Ye=s(l(Be),4),et=l(Ye),ke=s(et,2),Ae=l(ke);Ae.value=Ae.__value="downloads";var Oe=s(Ae);Oe.value=Oe.__value="trending";var Ot=s(Oe);Ot.value=Ot.__value="created_at";var Bt=s(ke,2),Wt=l(Bt),na=s(Ye,2);ft(na,20,()=>["","coder","vision","reasoning","chat","agent"],ut,(y,b)=>{var B=sc(),R=l(B);z(()=>{wt(B,1,a(K)===b?"primary":"ghost"),m(R,b||"Alle")}),A("click",B,()=>{g(K,b,!0),At()}),_(y,B)});var _a=s(na,2);{var Ke=y=>{var b=oc();ft(b,21,()=>a(pe),ut,(B,R,ae)=>{var tt=lc(),it=l(tt);{var X=Tt=>{var bt=Xr();_(Tt,bt)};I(it,Tt=>{ae===a(he)&&Tt(X)})}var _e=s(it,2),Re=l(_e),ct=l(Re),Ie=l(ct),Ge=s(ct,2),st=l(Ge),St=s(Re,2),Zt=l(St),vt=s(_e,2),Ne=l(vt);Ce(Ne,()=>Y(c(a(R).id)));var Et=s(Ne,2);Ce(Et,()=>se(a(R).id));var It=s(vt,4),gt=l(It),fe=l(gt),Ze=s(gt,2),Nt=l(Ze);z((Tt,bt,Oa,Ha,Sa)=>{wt(tt,1,`card${ae===a(he)?" res-best":""}`),m(Ie,Tt),m(st,a(R).author||""),wt(St,1,`fit-badge ${bt??""}`),m(Zt,Oa),m(fe,Ha),m(Nt,`⬇ ${Sa??""}`)},[()=>a(R).id.split("/").pop(),()=>a(ue)[ae]?h(a(ue)[ae]):"warn",()=>a(ue)[ae]?E(a(ue)[ae]):"prüfe…",()=>a(ue)[ae]?p({req_gb:0,tps:0}):"Hardware-Fit…",()=>(a(R).downloads||0).toLocaleString()]),A("click",tt,()=>C(a(R).id,a(R).id.split("/").pop())),_(B,tt)}),_(y,b)};I(_a,y=>{a(pe).length&&y(Ke)})}var ht=s(Be,2);{var qa=y=>{const b=q(()=>a(Le));var B=gc(),R=l(B),ae=l(R),tt=s(ae,2),it=l(tt),X=s(tt,2),_e=l(X),Re=s(X,2);ft(Re,21,()=>a(b).models,ut,(vt,Ne)=>{var Et=uc(),It=l(Et),gt=l(It),fe=l(gt),Ze=l(fe),Nt=s(fe,2),Tt=l(Nt),bt=s(Nt,2);Ce(bt,()=>se(a(Ne).repo));var Oa=s(gt,2);{var Ha=at=>{var yt=dc(),Xe=l(yt);z(()=>m(Xe,a(Ne).why)),_(at,yt)};I(Oa,at=>{a(Ne).why&&at(Ha)})}var Sa=s(Oa,2);{var kn=at=>{var yt=cc(),Xe=l(yt);z((nt,Ct,Ea)=>m(Xe,`~${nt??""} GB · ~${Ct??""} Tok/s · optimal ~${Ea??""}k Kontext`),[()=>(a(Ne).fit.req_gb??0).toFixed(1),()=>Math.round(a(Ne).fit.tps??0),()=>Math.round((a(Ne).optimal_ctx||8192)/1024)]),_(at,yt)};I(Sa,at=>{a(Ne).fit&&at(kn)})}var lt=s(It,2);{var Ve=at=>{var yt=vc(),Xe=l(yt);z(nt=>{wt(yt,1,`fit-badge ${nt??""}`),m(Xe,a(Ne).fit.text)},[()=>h(a(Ne).fit.level)]),_(at,yt)};I(lt,at=>{a(Ne).fit&&at(Ve)})}z(()=>{m(Ze,a(Ne).name),m(Tt,a(Ne).role)}),_(vt,Et)});var ct=s(Re,2);{var Ie=vt=>{const Ne=q(()=>Math.max(...a(b).models.map(fe=>{var Ze;return((Ze=fe.fit)==null?void 0:Ze.req_gb)??0})));var Et=fc(),It=s(l(Et)),gt=l(It);z(fe=>m(gt,`~${fe??""} GB`),[()=>a(Ne).toFixed(1)]),_(vt,Et)};I(ct,vt=>{a(b).models.length&&a(b).models[0].fit&&vt(Ie)})}var Ge=s(ct,2);{var st=vt=>{const Ne=q(()=>a(x).find(fe=>!fe.user&&fe.fit_level!=="too_tight"&&fe.id!==a(b).id));var Et=hc(),It=s(l(Et));{var gt=fe=>{var Ze=pc(),Nt=s(ot(Ze)),Tt=l(Nt);z(()=>m(Tt,`„${a(Ne).title??""}" ansehen`)),A("click",Nt,bt=>{bt.preventDefault(),g(Le,null),setTimeout(()=>qt(a(Ne).id),50)}),_(fe,Ze)};I(It,fe=>{a(Ne)&&fe(gt)})}_(vt,Et)};I(Ge,vt=>{a(b).fit_level==="too_tight"&&vt(st)})}var St=s(Ge,2),Zt=l(St);z(()=>{m(it,a(b).title),m(_e,a(b).desc),wt(St,1,`primary${a(b).fit_level==="too_tight"?" warn":""}`),m(Zt,a(b).fit_level==="too_tight"?"Trotzdem installieren (nicht empfohlen)":"Komplettes Setup installieren")}),A("click",B,vt=>{vt.target.classList.contains("modal-overlay")&&g(Le,null)}),A("click",ae,()=>g(Le,null)),A("click",St,()=>Rt(a(b).id)),_(y,B)};I(ht,y=>{a(Le)&&y(qa)})}var Ga=s(ht,2);{var nn=y=>{var b=Mc(),B=l(b),R=l(B),ae=s(R,2),tt=l(ae),it=s(ae,2),X=l(it),_e=s(it,2);{var Re=Ge=>{var st=_c();_(Ge,st)},ct=Ge=>{var st=xc(),St=s(ot(st),2);ft(St,21,()=>a(W).files,ut,(lt,Ve)=>{const at=q(()=>a(Ve).fit.level==="perfect"?"●":a(Ve).fit.level==="marginal"?"◐":"○");var yt=Zi(),Xe=l(yt),nt={};z(()=>{m(Xe,`${a(at)??""} ${a(Ve).filename??""}`),nt!==(nt=a(Ve).filename)&&(yt.value=(yt.__value=a(Ve).filename)??"")}),_(lt,yt)});var Zt=s(St,2),vt=l(Zt),Ne=s(l(vt),2),Et=s(vt,2),It=l(Et),gt=s(l(It));Ce(gt,()=>gi(n));var fe=s(It,2),Ze=s(Zt,2);{var Nt=lt=>{var Ve=mc(),at=s(l(Ve)),yt=l(at),Xe=s(at,2);z(nt=>m(yt,`~${nt??""}k`),[()=>Math.round(a(Z).optimal_ctx/1024)]),A("click",Xe,nt=>{nt.preventDefault(),g(J,a(Z).optimal_ctx,!0)}),_(lt,Ve)};I(Ze,lt=>{var Ve;(Ve=a(Z))!=null&&Ve.optimal_ctx&<(Nt)})}var Tt=s(Ze,2);{var bt=lt=>{var Ve=bc(),at=l(Ve),yt=s(l(at),2),Xe=l(yt),nt=s(at,2),Ct=l(nt);z((Ea,br,Ur)=>{m(Xe,`~${Ea??""} GB · ~${br??""} Tok/s · ${(a(Z).quant||"GGUF")??""}`),wt(nt,1,`fit-badge ${Ur??""}`),m(Ct,a(Z).fit.text)},[()=>(a(Z).fit.req_gb??0).toFixed(1),()=>Math.round(a(Z).fit.tps??0),()=>h(a(Z).fit.level)]),_(lt,Ve)};I(Tt,lt=>{a(Z)&<(bt)})}var Oa=s(Tt,2);{var Ha=lt=>{const Ve=q(()=>a(W).files.find(Ct=>Ct.fit.level!=="too_tight"&&Ct.filename!==a(re)));var at=or(),yt=ot(at);{var Xe=Ct=>{var Ea=yc(),br=s(l(Ea)),Ur=l(br);z(Hr=>m(Ur,`${a(Ve).filename??""} (${Hr??""})`),[()=>E(a(Ve).fit.level)]),A("click",br,Hr=>{Hr.preventDefault(),g(re,a(Ve).filename,!0),F()}),_(Ct,Ea)},nt=Ct=>{var Ea=wc();_(Ct,Ea)};I(yt,Ct=>{a(Ve)?Ct(Xe):Ct(nt,-1)})}_(lt,at)};I(Oa,lt=>{var Ve,at;((Ve=a(Z))==null?void 0:Ve.fit.level)==="too_tight"&&((at=a(W))!=null&&at.files)&<(Ha)})}var Sa=s(Oa,2),kn=l(Sa);z(()=>{var lt,Ve;wt(Sa,1,`primary${((lt=a(Z))==null?void 0:lt.fit.level)==="too_tight"?" warn":""}`),Sa.disabled=a(ze),m(kn,a(ze)?"Starte…":((Ve=a(Z))==null?void 0:Ve.fit.level)==="too_tight"?"Trotzdem holen (zu groß — nicht empfohlen)":"Herunterladen & Einpflegen")}),A("change",St,F),nr(St,()=>a(re),lt=>g(re,lt)),Ta(Ne,()=>a(He),lt=>g(He,lt)),Ta(fe,()=>a(J),lt=>g(J,lt)),A("click",Sa,$e),_(Ge,st)},Ie=Ge=>{var st=kc();_(Ge,st)};I(_e,Ge=>{var st,St;a(ze)&&!a(W)?Ge(Re):(St=(st=a(W))==null?void 0:st.files)!=null&&St.length?Ge(ct,1):a(ze)||Ge(Ie,2)})}z(()=>{m(tt,a(_t)),m(X,a(T))}),A("click",b,Ge=>{Ge.target.classList.contains("modal-overlay")&&g(Ue,!1)}),A("click",R,()=>g(Ue,!1)),_(y,b)};I(Ga,y=>{a(Ue)&&y(nn)})}var Ua=s(Ga,2);{var Hn=y=>{var b=Ec(),B=l(b),R=l(B),ae=s(R,2),tt=l(ae),it=s(ae,6),X=s(it,4),_e=s(X,4);ft(_e,17,()=>a(ie),ut,(Ge,st,St)=>{var Zt=Sc(),vt=l(Zt),Ne=s(vt,2),Et=s(Ne,2);ft(Et,20,()=>["Q4_K_M","Q5_K_M","Q6_K","Q8_0","Q3_K_M"],ut,(gt,fe)=>{var Ze=Zi(),Nt=l(Ze),Tt={};z(()=>{m(Nt,fe),Tt!==(Tt=fe)&&(Ze.__value=fe)}),_(gt,Ze)});var It=s(Et,2);Ta(vt,()=>a(st).repo,gt=>a(st).repo=gt),Ta(Ne,()=>a(st).role,gt=>a(st).role=gt),nr(Et,()=>a(st).quant,gt=>a(st).quant=gt),A("click",It,()=>g(ie,a(ie).filter((gt,fe)=>fe!==St),!0)),_(Ge,Zt)});var Re=s(_e,2),ct=s(Re,4),Ie=l(ct);z(()=>{m(tt,a(ge)?"Setup bearbeiten":"Eigenes Setup erstellen"),m(Ie,a(ge)?"Änderungen speichern":"Setup speichern")}),A("click",b,Ge=>{Ge.target.classList.contains("modal-overlay")&&g(rt,!1)}),A("click",R,()=>g(rt,!1)),Ta(it,()=>a(P),Ge=>g(P,Ge)),Ta(X,()=>a(H),Ge=>g(H,Ge)),A("click",Re,()=>g(ie,[...a(ie),{repo:"",role:"",quant:"Q4_K_M"}],!0)),A("click",ct,Q),_(y,b)};I(Ua,y=>{a(rt)&&y(Hn)})}z(()=>{Vt.disabled=a(D),m(M,a(D)?"Suche…":"Aktualisieren"),Bt.disabled=a(Ee),m(Wt,a(Ee)?"Lade…":"Suchen")}),A("click",xe,N),A("click",Vt,()=>pt(!0)),A("keydown",et,y=>y.key==="Enter"&&At()),Ta(et,()=>a(ne),y=>g(ne,y)),nr(ke,()=>a(U),y=>g(U,y)),A("click",Bt,At),_(e,me),an()}xn(["click","keydown","change"]);var Ac=w(`<div class="alert warn" style="margin:0 0 12px"><span class="a-dot"></span> <span>Du öffnest Mission Control über einen <b>Proxy/Namen</b>. Die Engine läuft auf <b>Port 8080 ohne HTTPS</b> direkt am Bosgame.
|
||
Trag in deinen Tools die <b>LAN-IP</b> ein: <code>http://192.168.178.151:8080/v1</code> — nicht den Proxy-Namen.</span></div>`),Cc=w('<span class="mono-sm"> </span>'),Lc=w('<div class="tile" style="display:flex;gap:12px;align-items:flex-start"><span style="font-size:20px;line-height:1;flex:0 0 auto"> </span> <div><div style="font-weight:500;font-size:13.5px"> </div> <div class="card-sub" style="margin:4px 0 0"> </div></div></div>'),zc=w('<span class="chip" role="button" tabindex="0"> </span>'),Dc=w('<div style="margin-top:10px"><a href="#" style="color:var(--mut);font-size:12.5px">Auswahl aufheben (alle)</a></div>'),Pc=w('<button style="text-align:left;padding:12px 16px"><div style="font-weight:500;font-size:13.5px"> </div> <div class="card-sub" style="margin:3px 0 0"> </div></button>'),qc=w('<p>Öffne die Zed-Settings mit <code>Cmd/Strg + ,</code> und <b>füge diesen Block</b> in deine bestehende <code>settings.json</code> ein. Falls bereits ein <code>"bosgame"</code>-Eintrag existiert: vorher löschen.</p> <div class="alert warn" style="margin-bottom:12px;padding:10px 14px"><span class="a-dot"></span><span>Nur diesen Block einfügen, <b>nicht die ganze Datei ersetzen</b> — sonst gehen andere Einstellungen verloren.</span></div> <div style="position:relative"><button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1">Kopieren</button> <div class="log" style="max-height:none"><code> </code></div></div> <p style="margin-top:12px"><b>API-Key:</b> Öffne den Agent-Panel → Anbieter <b>bosgame</b> → trag irgendeinen Wert ein (z.B. <code>local</code>).</p> <div class="hint">Danach im Agent-Panel das Modell <b> </b> auswählen.</div>',1),Oc=w('<p>Datei anlegen oder öffnen:</p> <p class="mono-sm" style="line-height:1.6">Windows: <code>%USERPROFILE%\\.config\\opencode\\opencode.json</code></p> <div class="alert warn" style="margin:8px 0 12px;padding:10px 14px"><span class="a-dot"></span><span>Nur den <code>"provider"</code>-Block einfügen. Falls bereits ein <code>"llama-swap"</code>-Eintrag vorhanden: <b>vorher löschen</b>, sonst erscheinen Modelle doppelt.</span></div> <div style="position:relative"><button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1">Kopieren</button> <div class="log" style="max-height:none"><code> </code></div></div> <p style="margin-top:12px">Danach in OpenCode <code>/models</code> → <b> </b> wählen.</p>',1),Rc=w('<p>In Cline/Cursor den Provider <b>„OpenAI Compatible"</b> wählen:</p> <label>Basis-URL</label> <div class="flex gap-2" style="align-items:stretch;margin-bottom:12px"><input class="mono-sm" readonly="" style="flex:1;margin:0"/> <button class="ghost">Kopieren</button></div> <label>Modell-ID</label> <div class="flex gap-2" style="align-items:stretch;margin-bottom:12px"><input class="mono-sm" readonly="" style="flex:1;margin:0"/> <button class="ghost">Kopieren</button></div> <div class="hint">API-Key: ein beliebiger Wert (z.B. <code>local</code>).</div>',1),Bc=w('<p>Settings → Admin Panel → Connections → neue OpenAI-Verbindung:</p> <label>Basis-URL</label> <div class="flex gap-2" style="align-items:stretch;margin-bottom:12px"><input class="mono-sm" readonly="" style="flex:1;margin:0"/> <button class="ghost">Kopieren</button></div> <label>API-Key</label> <div class="flex gap-2" style="align-items:stretch"><input class="mono-sm" readonly="" value="dummy-key" style="flex:1;margin:0"/> <button class="ghost">Kopieren</button></div>',1),Ic=w('<div class="card"><div class="card-h"><h3>Bilder einbinden (Vision)</h3> <span class="chip" style="background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a"><!> </span></div> <div class="card-sub">Mit Vision-Modellen kannst du Screenshots oder Fehlerbilder direkt mitschicken.</div> <div style="position:relative;margin-top:8px"><button class="ghost" style="position:absolute;top:8px;right:8px;z-index:1">Kopieren</button> <div class="log" style="max-height:none"><code> </code></div></div></div>'),Nc=w('<div class="card"><div class="card-h"><h3>2 · Modelle auswählen</h3> <span class="meta"> </span></div> <div class="card-sub">Wähle, welche Modelle im Config-Snippet erscheinen sollen.</div> <div class="flex gap-2" style="flex-wrap:wrap"></div> <!></div> <div class="card"><div class="card-h"><h3>3 · Tool wählen</h3></div> <div class="card-sub">Für welches Werkzeug brauchst du die Konfiguration?</div> <div class="grid grid-4" style="gap:8px"></div></div> <div class="card"><div class="card-h"><h3>4 · Config-Snippet</h3></div> <!></div> <!>',1),Fc=w('<div class="card"><div class="card-h"><h3>2 · Erst ein Modell installieren</h3></div> <div class="empty-c" style="padding:8px 0 4px"><div class="e-t">Noch kein Modell eingerichtet</div> <div class="e-s">Bevor du ein Tool verbinden kannst, braucht die Engine mindestens ein Modell. Das Config-Snippet wird dann automatisch mit deinen echten Modellnamen befüllt.</div> <button class="primary" style="margin-top:14px">→ Zum Cookbook (Modell holen)</button></div></div>'),Kc=w('<div class="pagehead"><div><h1>Verbinden</h1> <div class="sub">Schritt für Schritt: KI-Modelle in deine Tools einbinden — getestet, erklärt, mit Copy-Paste-Config.</div></div></div> <div class="card"><div class="card-h"><h3>1 · Verbindung prüfen</h3></div> <div class="card-sub">Stelle sicher, dass die LLM-Engine erreichbar ist, bevor du Tools konfigurierst.</div> <label>Engine-Adresse (für alle Tools)</label> <div class="flex gap-2" style="align-items:stretch;margin-bottom:12px"><input class="mono-sm" readonly="" style="flex:1;margin:0"/> <button class="ghost">Kopieren</button></div> <!> <div class="btn-row" style="display:flex;align-items:center;gap:10px"><button class="primary">Verbindung testen</button> <!></div></div> <div class="card"><div class="card-h"><h3>Wie funktioniert das Auto-Swap?</h3></div> <div style="display:flex;flex-direction:column;gap:10px"></div></div> <!>',1);function Gc(e,t){tn(t,!0);const n=q(()=>mr.value),r=q(()=>{var P;return(((P=a(n))==null?void 0:P.models)||[]).filter(H=>!H.incomplete)}),i=q(u);let o=O("zed"),d=O(Ht([])),c=O(""),v=O(!1);function u(){return`http://${location.hostname}:8080/v1`}function h(P){return/^\d{1,3}(\.\d{1,3}){3}$/.test(P)}function E(){return location.protocol==="https:"||!h(location.hostname)}const p=q(()=>a(d).length?a(d):a(r).map(P=>P.name)),x=q(()=>a(p)[0]||"coder"),$=q(()=>{var P;return(P=a(r).find(H=>{var ie,ge;return(ge=(ie=H.meta)==null?void 0:ie.caps)==null?void 0:ge.includes("Bild")}))==null?void 0:P.name});function L(P,H){const ge=(H.length?a(r).filter(Te=>H.includes(Te.name)):a(r).length?a(r):[{name:"coder",meta:{}}]).map(Te=>{var kt,At;const mt=(((kt=Te.meta)==null?void 0:kt.caps)||[]).some(Mt=>/Bild|Vision/i.test(Mt)),pt=((At=Te.meta)==null?void 0:At.ctx)||131072;return` { "name": "${Te.name}", "display_name": "${Te.name}", "max_tokens": ${pt}${mt?', "capabilities": { "tools": true, "images": true }':""} }`}).join(`,
|
||
`);return`"language_models": {
|
||
"openai_compatible": {
|
||
"bosgame": {
|
||
"api_url": "${P}",
|
||
"available_models": [
|
||
${ge}
|
||
]
|
||
}
|
||
}
|
||
}`}function k(P,H){const ge=(H.length?a(r).filter(Te=>H.includes(Te.name)):a(r).length?a(r):[{name:"coder",meta:{}}]).map(Te=>{var pt;const mt=((pt=Te.meta)==null?void 0:pt.ctx)||131072;return` "${Te.name}": { "name": "${Te.name}", "contextWindowSize": ${mt} }`}).join(`,
|
||
`);return`"provider": {
|
||
"llama-swap": {
|
||
"npm": "@ai-sdk/openai-compatible",
|
||
"name": "Bosgame (llama-swap)",
|
||
"options": {
|
||
"baseURL": "${P}",
|
||
"apiKey": "local"
|
||
},
|
||
"models": {
|
||
${ge}
|
||
}
|
||
}
|
||
}`}async function D(){g(c,"Teste…");try{const P=await Me("/api/integration/test");g(v,P.ok,!0),g(c,P.ok?`✓ Verbunden — ${P.models.length} Modell(e): ${P.models.join(", ")}`:`✗ Keine Verbindung: ${P.error}`,!0)}catch(P){g(v,!1),g(c,"✗ "+P.message)}}function Pe(P){var ie;const H=P.querySelector("code");H&&((ie=navigator.clipboard)==null||ie.writeText(H.textContent||""))}function ne(P){var H;(H=navigator.clipboard)==null||H.writeText(P.value)}var pe=Kc(),Ee=s(ot(pe),2),K=s(l(Ee),6),U=l(K),ue=s(U,2),he=s(K,2);{var Le=P=>{var H=Ac();_(P,H)},Ue=q(()=>E());I(he,P=>{a(Ue)&&P(Le)})}var _t=s(he,2),T=l(_t),W=s(T,2);{var re=P=>{var H=Cc(),ie=l(H);z(()=>{fa(H,`color:${a(v)?"#7ee29a":"#ff9b95"}`),m(ie,a(c))}),_(P,H)};I(W,P=>{a(c)&&P(re)})}var He=s(Ee,2),J=s(l(He),2);ft(J,20,()=>[["⚡","Kein manuelles Starten nötig",'Wenn du in Zed oder OpenCode „coder" auswählst und eine Anfrage sendest, lädt llama-swap das Modell automatisch — in ca. 2–5 Sekunden.'],["🔄","Modelle wechseln sich automatisch ab","Rufst du ein anderes Modell auf, entlädt llama-swap das aktuelle (nach TTL-Ablauf) und lädt das neue. Es läuft immer nur eines gleichzeitig."],["🧠","Zwei Modelle gleichzeitig aktiv halten","Du hast 124 GB RAM — genug für z.B. Scout 8B (~5 GB) dauerhaft geladen + ein größeres Modell das swappt. Dafür beim Scout im Modelle-Tab → Konfigurieren die TTL auf 99999 setzen."]],ut,(P,H)=>{var ie=q(()=>sr(H,3));let ge=()=>a(ie)[0],Te=()=>a(ie)[1],mt=()=>a(ie)[2];var pt=Lc(),kt=l(pt),At=l(kt),Mt=s(kt,2),Lt=l(Mt),qt=l(Lt),Rt=s(Lt,2),C=l(Rt);z(()=>{m(At,ge()),m(qt,Te()),m(C,mt())}),_(P,pt)});var ze=s(He,2);{var Z=P=>{var H=Nc(),ie=ot(H),ge=l(ie),Te=s(l(ge),2),mt=l(Te),pt=s(ge,4);ft(pt,21,()=>a(r),ut,(Q,de)=>{const se=q(()=>a(d).includes(a(de).name));var Y=zc(),me=l(Y);z(()=>{fa(Y,`cursor:pointer;${a(se)?"background:rgba(45,212,191,.2);border-color:var(--accent);color:var(--accent)":""}`),m(me,a(de).name)}),A("click",Y,()=>g(d,a(se)?a(d).filter(ve=>ve!==a(de).name):[...a(d),a(de).name],!0)),A("keydown",Y,ve=>ve.key==="Enter"&&g(d,a(se)?a(d).filter(we=>we!==a(de).name):[...a(d),a(de).name],!0)),_(Q,Y)});var kt=s(pt,2);{var At=Q=>{var de=Dc(),se=l(de);A("click",se,Y=>{Y.preventDefault(),g(d,[],!0)}),_(Q,de)};I(kt,Q=>{a(d).length&&Q(At)})}var Mt=s(ie,2),Lt=s(l(Mt),4);ft(Lt,20,()=>[["zed","Zed","Schneller nativer Editor — Empfohlen"],["opencode","OpenCode","Open-Source Coding-Agent (Terminal/Desktop)"],["cline","Cline / Cursor","VS Code Extension, Bring-Your-Own-Key"],["openwebui","OpenWebUI","Browser-Chat-Interface"]],ut,(Q,de)=>{var se=q(()=>sr(de,3));let Y=()=>a(se)[0],me=()=>a(se)[1],ve=()=>a(se)[2];var we=Pc(),xe=l(we),be=l(xe),S=s(xe,2),V=l(S);z(()=>{wt(we,1,`card-btn${a(o)===Y()?" cb-best":""}`),m(be,me()),m(V,ve())}),A("click",we,()=>g(o,Y(),!0)),_(Q,we)});var qt=s(Mt,2),Rt=s(l(qt),2);{var C=Q=>{const de=q(()=>L(a(i),a(p)));var se=qc(),Y=s(ot(se),4),me=l(Y),ve=s(me,2),we=l(ve),xe=l(we),be=s(Y,4),S=s(l(be)),V=l(S);z(()=>{m(xe,a(de)),m(V,`bosgame / ${a(x)??""}`)}),A("click",me,le=>Pe(le.currentTarget.parentElement)),_(Q,se)},F=Q=>{const de=q(()=>k(a(i),a(p)));var se=Oc(),Y=s(ot(se),6),me=l(Y),ve=s(me,2),we=l(ve),xe=l(we),be=s(Y,2),S=s(l(be),3),V=l(S);z(()=>{m(xe,a(de)),m(V,`llama-swap/${a(x)??""}`)}),A("click",me,le=>Pe(le.currentTarget.parentElement)),_(Q,se)},$e=Q=>{var de=Rc(),se=s(ot(de),4),Y=l(se),me=s(Y,2),ve=s(se,4),we=l(ve),xe=s(we,2);z(()=>{wr(Y,a(i)),wr(we,a(x))}),A("click",me,be=>ne(be.currentTarget.previousElementSibling)),A("click",xe,be=>ne(be.currentTarget.previousElementSibling)),_(Q,de)},dt=Q=>{var de=Bc(),se=s(ot(de),4),Y=l(se),me=s(Y,2),ve=s(se,4),we=l(ve),xe=s(we,2);z(()=>wr(Y,a(i))),A("click",me,be=>ne(be.currentTarget.previousElementSibling)),A("click",xe,be=>ne(be.currentTarget.previousElementSibling)),_(Q,de)};I(Rt,Q=>{a(o)==="zed"?Q(C):a(o)==="opencode"?Q(F,1):a(o)==="cline"?Q($e,2):a(o)==="openwebui"&&Q(dt,3)})}var N=s(qt,2);{var De=Q=>{const de=q(()=>`curl ${a(i)}/chat/completions \\
|
||
-H "Content-Type: application/json" \\
|
||
-d '{
|
||
"model": "${a($)}",
|
||
"messages": [{"role":"user","content":[{"type":"text","text":"Was ist auf dem Bild falsch?"},{"type":"image_url","image_url":{"url":"data:image/png;base64,<DEIN_BILD>"}}]}]
|
||
}'`);var se=Ic(),Y=l(se),me=s(l(Y),2),ve=l(me);Ce(ve,()=>zt("check"));var we=s(ve),xe=s(Y,4),be=l(xe),S=s(be,2),V=l(S),le=l(V);z(()=>{m(we,` „${a($)??""}" bereit`),m(le,a(de))}),A("click",be,Qe=>Pe(Qe.currentTarget.parentElement)),_(Q,se)};I(N,Q=>{a($)&&Q(De)})}z(()=>m(mt,a(d).length?`${a(d).length} von ${a(r).length} ausgewählt`:"alle werden eingeschlossen")),_(P,H)},rt=P=>{var H=Fc(),ie=s(l(H),2),ge=s(l(ie),4);A("click",ge,()=>{var Te;return(Te=document.querySelector(".nav-item[data-view='cookbook']"))==null?void 0:Te.dispatchEvent(new MouseEvent("click"))}),_(P,H)};I(ze,P=>{a(r).length?P(Z):P(rt,-1)})}z(()=>wr(U,a(i))),A("click",ue,P=>{const H=P.currentTarget.previousElementSibling;ne(H)}),A("click",T,D),_(e,pe),an()}xn(["click","keydown"]);var Uc=w('<div class="li" style="align-items:flex-start"><div class="li-main"><div class="flex items-center gap-2" style="flex-wrap:wrap"><span class="li-id" style="font-family:var(--sans);font-weight:500"> </span> <span> </span></div> <div class="li-sub"> </div></div> <button class="primary">Installieren</button></div>'),Hc=w('<div class="card" style="margin-bottom:18px;border-color:rgba(45,212,191,.25)"><div class="card-h"><h3>Für dich: Upgrades</h3> <span class="meta"> </span></div> <div class="card-sub">Neuere Modelle, die ein installiertes ersetzen können.</div> <div class="list"></div></div>'),Vc=w('<div class="empty" style="text-align:center;padding:40px">Lade News… (erstes Laden kann kurz dauern)</div>'),Wc=w('<div class="alert err" style="margin:0"> </div>'),jc=w('<div class="empty-c"><div class="e-t">Keine News geladen</div> <div class="e-s">Die Quellen sind gerade nicht erreichbar — später nochmal probieren.</div></div>'),Qc=w('<span class="news-rel">für dich</span>'),Jc=w('<a target="_blank" rel="noopener"><div class="news-meta"><span class="news-src"> </span> <!> <span class="news-date"> </span></div> <div class="news-title"> </div></a>'),Yc=w('<div class="news-grid"></div>'),Zc=w('<div class="pagehead"><div><h1>News</h1> <div class="sub">Aktuelles aus der Local-LLM-Welt — aus kuratierten Quellen.</div></div> <button class="ghost">Aktualisieren</button></div> <!> <!>',1);function Xc(e,t){tn(t,!0);let n=O(Ht([])),r=O(Ht([])),i=O(!0),o=O("");const d=K=>K==="perfect"?"ok":K==="marginal"?"warn":"bad";function c(K){const U=Math.max(0,Date.now()/1e3-K);return U<60?U+"s":U<3600?Math.floor(U/60)+"m":U<86400?Math.floor(U/3600)+"h":Math.floor(U/86400)+"d"}async function v(){g(i,!0),g(o,"");try{g(n,(await Me("/api/news")).items||[],!0)}catch(K){g(o,K.message||"Fehler beim Laden",!0)}finally{g(i,!1)}}async function u(){try{g(r,(await Me("/api/cookbook/upgrades")).upgrades||[],!0)}catch{g(r,[],!0)}}async function h(K,U){var ue;U.disabled=!0,U.textContent="Starte…";try{await Me("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:K.repo,role:K.role,params_b:K.params_b,quant:K.quant,hf_token:ir()})}),(ue=document.querySelector(".nav-item[data-view='activity']"))==null||ue.dispatchEvent(new MouseEvent("click"))}catch(he){U.disabled=!1,U.textContent="Installieren",alert("Fehler: "+he.message)}}function E(){v(),u()}_r(()=>{v(),u()});var p=Zc(),x=ot(p),$=s(l(x),2),L=s(x,2);{var k=K=>{var U=Hc(),ue=l(U),he=s(l(ue),2),Le=l(he),Ue=s(ue,4);ft(Ue,21,()=>a(r),ut,(_t,T)=>{var W=Uc(),re=l(W),He=l(re),J=l(He),ze=l(J),Z=s(J,2),rt=l(Z),P=s(He,2),H=l(P),ie=s(re,2);z(ge=>{m(ze,a(T).name),wt(Z,1,`fit-badge ${ge??""}`),m(rt,a(T).fit.text),m(H,`Ersetzt dein „${a(T).old??""}". ${a(T).why??""}`)},[()=>d(a(T).fit.level)]),A("click",ie,ge=>h(a(T),ge.currentTarget)),_(_t,W)}),z(()=>m(Le,a(r).length)),_(K,U)};I(L,K=>{a(r).length&&K(k)})}var D=s(L,2);{var Pe=K=>{var U=Vc();_(K,U)},ne=K=>{var U=Wc(),ue=l(U);z(()=>m(ue,a(o))),_(K,U)},pe=K=>{var U=jc();_(K,U)},Ee=K=>{var U=Yc();ft(U,21,()=>a(n),ut,(ue,he,Le)=>{var Ue=Jc();wt(Ue,1,`news-card${Le===0?" featured":""}`);var _t=l(Ue),T=l(_t),W=l(T),re=s(T,2);{var He=P=>{var H=Qc();_(P,H)};I(re,P=>{a(he).relevant&&P(He)})}var J=s(re,2),ze=l(J),Z=s(_t,2),rt=l(Z);z(P=>{Fr(Ue,"href",a(he).link),m(W,a(he).source),m(ze,P),m(rt,a(he).title)},[()=>a(he).ts?c(a(he).ts):""]),_(ue,Ue)}),_(K,U)};I(D,K=>{a(i)?K(Pe):a(o)?K(ne,1):a(n).length?K(Ee,-1):K(pe,2)})}A("click",$,E),_(e,p),an()}xn(["click"]);const ev=[["Dein erster Workflow — in 3 Schritten",`
|
||
<ol class="tut-steps">
|
||
<li><b>Modell holen:</b> Tab <b>Cookbook</b> → wähle deinen Anwendungsfall (z.B. „Coden") →
|
||
<b>Komplettes Setup installieren</b>. Der Download läuft im Tab <b>Aktivität</b>.</li>
|
||
<li><b>Verbinden:</b> Tab <b>Verbinden</b> → Basis-URL kopieren → in deinem Tool (z.B. OpenCode)
|
||
als „OpenAI-kompatibel" einfügen. <b>Verbindung testen</b> bestätigt, dass es läuft.</li>
|
||
<li><b>Arbeiten:</b> Im Tool das Modell (z.B. <code>coder</code>) wählen und loslegen. Das passende
|
||
Modell wird <b>automatisch geladen</b> — du musst nichts starten.</li>
|
||
</ol>`],["Wie leere ich den Kontext? Machen die Tools das selbst?",`
|
||
<p><b>Kurz: meistens ja, automatisch.</b> Der Kontext (das „Gedächtnis") gilt pro Unterhaltung.
|
||
Startest du im Tool einen <b>neuen Chat / eine neue Session</b>, ist der Kontext wieder leer —
|
||
das Tool verwaltet das Fenster für dich.</p>
|
||
<p>Du musst nur selten eingreifen: wird ein Gespräch sehr lang, fang einen neuen an. <b>Wichtig:</b>
|
||
„Grafikspeicher leeren" (Tab Server) ist etwas anderes — das wirft das <i>Modell</i> aus dem Speicher,
|
||
nicht den Gesprächsverlauf.</p>`],["Was passiert, wenn der Kontext volläuft?",`
|
||
<p>Ist das Kontextfenster voll, passiert je nach Tool eins von dreien: das Modell <b>vergisst den
|
||
Anfang</b> (älteste Nachrichten fallen raus), das Tool <b>kürzt automatisch</b>, oder du bekommst
|
||
einen Fehler wie „context length exceeded".</p>
|
||
<p><b>So gehst du vor:</b></p>
|
||
<ol class="tut-steps">
|
||
<li><b>Neuen Chat starten</b> — der einfachste Reset, Kontext ist wieder leer.</li>
|
||
<li><b>Zusammenfassen lassen:</b> „Fasse unseren Stand kurz zusammen", dann im neuen Chat einfügen.</li>
|
||
<li><b>Kontext vergrößern:</b> Tab <b>Modelle</b> → <b>Konfigurieren</b> → wir zeigen das Optimum
|
||
für deine Hardware (mehr Kontext = mehr Speicherbedarf).</li>
|
||
</ol>`],["Was ist ein Agent — und wann brauche ich einen?",`
|
||
<p>Ein nacktes Modell <b>schreibt nur Text zurück</b>. Ein <b>Agent</b> ist ein Programm drumherum,
|
||
das das Modell <b>handeln</b> lässt: Dateien lesen und ändern, Befehle ausführen, im Web suchen —
|
||
Schritt für Schritt in einer Schleife, bis die Aufgabe erledigt ist.</p>
|
||
<p><b>Wann lohnt sich was?</b></p>
|
||
<ul class="tut-steps" style="list-style:disc">
|
||
<li><b>Fragen, Texte, Erklärungen, Brainstorming</b> → kein Agent nötig, eine Chat-Oberfläche
|
||
wie <b>OpenWebUI</b> reicht völlig.</li>
|
||
<li><b>Coden über mehrere Dateien, Befehle ausführen, recherchieren + umsetzen</b>
|
||
→ <b>Agent</b> (OpenCode, Cline, Continue).</li>
|
||
</ul>
|
||
<p><b>Gut zu wissen:</b> Diese Agenten <b>laufen lokal auf deinem PC</b> — du brauchst
|
||
<b>keinen</b> Cloud-Dienst.</p>`],["Was sind Skills — und wie installiere ich sie?",`
|
||
<p>Ein <b>Skill</b> ist <b>verpacktes Können</b>: eine kurze Anleitung, die dem Agenten beibringt,
|
||
eine wiederkehrende Aufgabe jedes Mal so zu erledigen, wie <i>du</i> es willst.</p>
|
||
<p><b>Skill vs. MCP:</b> <b>MCP</b> gibt dem Agenten neue <b>Werkzeuge</b>. <b>Skills</b> geben
|
||
ihm <b>Know-how</b>. Kurz: <b>Werkzeuge = MCP, Anleitungen = Skills.</b></p>
|
||
<p><b>Installieren:</b> meist nur eine Datei ablegen — kein Build, kein Neustart:</p>
|
||
<ol class="tut-steps">
|
||
<li><b>Pro Projekt:</b> in den Projektordner (z.B. <code>AGENTS.md</code>, <code>.clinerules/</code>).</li>
|
||
<li><b>Global:</b> in den Konfig-Ordner des Tools — gilt überall.</li>
|
||
</ol>`],["MCP — deinem Agenten echte Werkzeuge geben",`
|
||
<p><b>MCP</b> (Model Context Protocol) ist ein einheitlicher „Stecker", über den ein Agent zusätzliche
|
||
<b>Werkzeuge</b> bekommt: das Web durchsuchen, Dateien lesen, eine Datenbank abfragen.</p>
|
||
<p>Du fügst in deinem Agenten einen „MCP-Server" hinzu (eine Zeile in der Konfiguration je Werkzeug).
|
||
Danach entscheidet der Agent selbst, wann er das Werkzeug einsetzt.</p>
|
||
<ul class="tut-steps" style="list-style:disc">
|
||
<li><b>Faustregel:</b> Fehlt dem Agenten eine <b>Fähigkeit</b> → MCP. Soll er etwas nur
|
||
<b>besser machen</b> → Skill.</li>
|
||
</ul>`],["Auto-Swap — wie das Laden funktioniert",`
|
||
<p>llama-swap lädt automatisch das Modell, das gerade angefragt wird, und entlädt es nach einer
|
||
Leerlaufzeit wieder. <b>Es läuft immer nur eines gleichzeitig.</b></p>
|
||
<p>Du richtest beliebig viele Modelle ein und wählst im Tool das passende —
|
||
das Laden/Entladen passiert im Hintergrund, ohne dass du etwas tun musst.</p>`],["Die empfohlenen Tools optimal nutzen",`
|
||
<ul class="tut-steps" style="list-style:disc">
|
||
<li><b>OpenCode:</b> Autonomes Coden im Terminal/Editor — ideal für „bau mir Feature X".</li>
|
||
<li><b>Cline:</b> Dasselbe als VS-Code-Erweiterung, mit Bestätigung vor jeder Aktion.</li>
|
||
<li><b>OpenWebUI:</b> Klassische Chat-Oberfläche für Fragen/Texte.</li>
|
||
</ul>
|
||
<p><b>Tipp:</b> starkes Modell (<code>coder</code>) für schwere Aufgaben, schnelles
|
||
(<code>scout</code>) für einfache — du wählst es einfach im Tool aus.</p>`]],tv=[["LLM / Modell","Die KI selbst — versteht und schreibt Text (wie ChatGPT, nur lokal auf deinem PC). Ein Modell ist eine konkrete Datei davon, oft auf etwas spezialisiert (Code, Bilder, Chat)."],["GGUF","Das lokal lauffähige Dateiformat. Unsere Engine lädt nur GGUF — Repos ohne GGUF kann sie nicht nutzen."],["Quantisierung (Q4_K_M)","Verkleinert ein Modell (16-Bit → 4-Bit), damit es in den Speicher passt — bei kaum Qualitätsverlust. Q4_K_M ist der beliebte Sweetspot."],["Kontextfenster","Das Kurzzeitgedächtnis: wie viel Text sich das Modell gleichzeitig merkt. Größer = mehr Überblick, mehr Speicher, etwas langsamer."],["Auto-Swap","llama-swap lädt/entlädt Modelle automatisch — immer nur eins gleichzeitig. Du managst nichts."],["Agent","Ein Programm (OpenCode, Cline, Continue), das das Modell handeln lässt — Dateien lesen/ändern, Befehle ausführen, planen, im Loop bis die Aufgabe erledigt ist."],["MCP","Model Context Protocol — der Anschluss, über den ein Agent zusätzliche Werkzeuge bekommt (Web, Dateien, Datenbank). MCP = Werkzeuge."],["Skills","Verpackte Anleitung für wiederkehrende Aufgaben — der Agent liest sie und macht es jedes Mal wie du willst. Skills = Anleitungen."],["Rules / Commands","Die konkrete Form von Skills je Tool: AGENTS.md (OpenCode), .clinerules (Cline), Rules/Prompts (Continue)."]];var av=w('<details class="guide-acc"><summary> </summary> <div class="acc-body"></div></details>'),nv=w('<div class="concept"><h4> </h4> <p> </p></div>'),rv=w('<div class="pagehead"><div><h1>Guide für Einsteiger</h1> <div class="sub">Praktische Workflows + die Local-LLM-Welt in Klartext — ohne Vorwissen.</div></div></div> <div class="card-h"><h3>Tutorials & Workflows</h3></div> <div class="card" style="padding:0;overflow:hidden"></div> <div class="card-h" style="margin-top:8px"><h3>Konzepte kurz erklärt</h3></div> <div class="concept-grid"></div>',1);function iv(e){var t=rv(),n=s(ot(t),4);ft(n,21,()=>ev,ut,(i,o,d)=>{var c=q(()=>sr(a(o),2));let v=()=>a(c)[0],u=()=>a(c)[1];var h=av();h.open=d===0;var E=l(h),p=l(E),x=s(E,2);Ce(x,u,!0),z(()=>m(p,v())),_(i,h)});var r=s(n,4);ft(r,21,()=>tv,ut,(i,o)=>{var d=q(()=>sr(a(o),2));let c=()=>a(d)[0],v=()=>a(d)[1];var u=nv(),h=l(u),E=l(h),p=s(h,2),x=l(p);z(()=>{m(E,c()),m(x,v())}),_(i,u)}),_(e,t)}let Xi={};function sv(){const e=document.getElementById("top-active-text");e&&(e.classList.add("swap-flash"),setTimeout(()=>e.classList.remove("swap-flash"),900))}function es(e){var i;const t=document.getElementById("swdot"),n=document.getElementById("swlabel"),r=document.getElementById("top-active-text");if(!e)t&&(t.className="dot off"),n&&(n.textContent="Backend nicht erreichbar"),r&&(r.textContent="Backend offline"),ts("Backend nicht erreichbar – läuft uvicorn?",!1);else{const o=(e.swap_url||"").replace(/^https?:\/\//,"");t&&(t.className="dot "+(e.swap_ok?"on":"off")),n&&(n.textContent=(e.swap_ok?"LLM-Engine: Online – ":"LLM-Engine: Offline – ")+o);const d=["running","ready","loading","starting"],c=(e.models||[]).find(u=>d.includes(u.state));if(r)if(c){const u=(i=c.meta)!=null&&i.ctx?` <span style="color:var(--mut);font-size:11.5px">· ${Math.round(c.meta.ctx/1024)}k ctx</span>`:"",h=c.state==="loading"||c.state==="starting"?' <span style="color:var(--warn);font-size:11.5px">lädt…</span>':"";r.innerHTML=`<b style="color:var(--accent)">${c.name}</b>${u}${h}`}else r.innerHTML='<span style="color:var(--mut)">Kein Modell im VRAM</span>';e.swap_ok?cv():ts(`LLM-Engine nicht erreichbar unter <b>${o}</b> – läuft der llama-swap Dienst?`,!0);const v={};for(const u of e.models||[])v[u.name]=u.state;for(const[u,h]of Object.entries(v)){const E=Xi[u];if(E&&E!==h&&(h==="running"||h==="loading")){sv();break}}Xi=v}lv(e),mr.set(e)}function lv(e){const t=document.getElementById("sec-chip"),n=document.getElementById("sec-chip-tx");!t||!n||(t.classList.toggle("ok",!!(e!=null&&e.secured)),n.textContent=e!=null&&e.secured?"Geschützt · Heimnetz":"Nur im Heimnetz (offen)")}function ov(e){dn.set(e||[])}function dv(e){Li.set(e)}function ts(e,t){const n=document.getElementById("alert");n.className="alert"+(t?" warn":""),n.innerHTML=`<span class="a-dot"></span><span>${e}</span>`,n.style.display="flex"}function cv(){const e=document.getElementById("alert");e&&(e.style.display="none")}const vv=e=>{var t;return(t=document.querySelector(`.nav-item[data-view="${e}"]`))==null?void 0:t.click()};function ei(e,t,n,r){const i=document.createElement("span");return i.className="upd-badge"+(t?" "+t:""),i.textContent=e,r&&(i.title=r),i.onclick=()=>vv(n),i}async function tl(){try{const e=await Me("/api/updates"),t=document.getElementById("update-badges");if(!t)return;const n=e.apt_cache_age_h,r=n!=null&&n>24,i=n!=null?` · apt-Cache: vor ${n}h`:"";t.innerHTML="",t.appendChild(ei(e.os>0?`OS: ${e.os} Updates`:r?"OS: ?":"OS: aktuell",e.os>0||r?"warn":"ok","server",e.os>0?`${e.os} Pakete${i}`:r?`apt-Cache veraltet (${n}h)`:`Keine Updates${i}`)),t.appendChild(ei(e.engine>0?"Engine: Update":"Engine: aktuell",e.engine>0?"warn":"ok","server")),t.appendChild(ei(e.models>0?`Modelle: ${e.models}`:"Modelle: aktuell",e.models>0?"warn":"ok","news"))}catch{}}async function Gr(){try{es(await Me("/api/status"))}catch{es(null)}}async function al(){try{ov(await Me("/api/jobs"))}catch{}}function nl(){const e=window.location.protocol==="https:"?"wss:":"ws:",t=new WebSocket(`${e}//${window.location.host}/api/system/stream`);t.onmessage=n=>{try{dv(JSON.parse(n.data))}catch{}},t.onclose=()=>{setTimeout(nl,3e3)},t.onerror=()=>t.close()}var ls;((ls=document.getElementById("logo"))==null?void 0:ls.innerHTML)!==void 0&&(document.getElementById("logo").innerHTML=Kr.logo);document.querySelectorAll("[data-ic]").forEach(e=>{e.innerHTML=Kr[e.dataset.ic||""]||""});const uv=[["overview",cd],["models",Sd],["activity",Od],["server",Vd],["cookbook",$c],["connect",Gc],["news",Xc],["guides",iv]];for(const[e,t]of uv){const n=document.querySelector(`.view[data-view="${e}"]`);n&&ko(t,{target:n})}Ho("overview");const ti=document.getElementById("token");ti&&(ti.value=el(),ti.addEventListener("change",e=>{No(e.target.value),Gr()}));const ai=document.getElementById("hf-token");ai&&(ai.value=ir(),ai.addEventListener("change",e=>Ko(e.target.value)));const as=document.getElementById("nav-settings"),ni=document.getElementById("settings-modal"),ns=document.getElementById("sm-close");as&&ni&&ns&&(as.addEventListener("click",()=>ni.style.display="flex"),ns.addEventListener("click",()=>ni.style.display="none"));function fv(){const e=document.getElementById("clock");e&&(e.textContent=new Date().toTimeString().slice(0,5))}document.addEventListener("mc:refresh",Gr);Gr();al();nl();setInterval(fv,1e3);setInterval(Gr,3e3);setInterval(al,1500);tl();setInterval(tl,6e4);
|