10 files changed
+180
-269
No files matched your search
@@ -12,6 +12,15 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<p>🎥 <b>Watch the Setup & Demo Video:</b> <a href="https://youtu.be/ESELhY-G_9w">https://youtu.be/ESELhY-G_9w</a></p>
|
||||
<a href="https://youtu.be/ESELhY-G_9w">
|
||||
<img src="https://img.youtube.com/vi/ESELhY-G_9w/maxresdefault.jpg" alt="Local AI Image Generator Video Tutorial" style="width:100%; max-width:800px; border-radius: 8px; margin-top: 10px;">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 📖 Overview
|
||||
**Local AI Image Generator** is a zero-configuration, portable desktop environment for running Stable Diffusion (Safetensors/GGUF/CKPT) offline on Windows. Double-clicking `start.bat` automatically handles dependency setup, GPU backend matching (CUDA/Vulkan), and launches a high-performance local web workspace.
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{i as D,t as i}from"./index-BOI9YDBQ.js";var _;(function(r){r.WINDOW_RESIZED="tauri://resize",r.WINDOW_MOVED="tauri://move",r.WINDOW_CLOSE_REQUESTED="tauri://close-requested",r.WINDOW_DESTROYED="tauri://destroyed",r.WINDOW_FOCUS="tauri://focus",r.WINDOW_BLUR="tauri://blur",r.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",r.WINDOW_THEME_CHANGED="tauri://theme-changed",r.WINDOW_CREATED="tauri://window-created",r.WINDOW_SUSPENDED="tauri://suspended",r.WINDOW_RESUMED="tauri://resumed",r.WEBVIEW_CREATED="tauri://webview-created",r.DRAG_ENTER="tauri://drag-enter",r.DRAG_OVER="tauri://drag-over",r.DRAG_DROP="tauri://drag-drop",r.DRAG_LEAVE="tauri://drag-leave"})(_||(_={}));async function l(r,a){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(r,a),await D("plugin:event|unlisten",{event:r,eventId:a})}async function n(r,a,e){var t;const W=typeof e?.target=="string"?{kind:"AnyLabel",label:e.target}:(t=e?.target)!==null&&t!==void 0?t:{kind:"Any"};return D("plugin:event|listen",{event:r,target:W,handler:i(a)}).then(d=>async()=>l(r,d))}export{_ as TauriEvent,n as listen};
|
||||
import{i as D,t as i}from"./index-CBtRYlFE.js";var _;(function(r){r.WINDOW_RESIZED="tauri://resize",r.WINDOW_MOVED="tauri://move",r.WINDOW_CLOSE_REQUESTED="tauri://close-requested",r.WINDOW_DESTROYED="tauri://destroyed",r.WINDOW_FOCUS="tauri://focus",r.WINDOW_BLUR="tauri://blur",r.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",r.WINDOW_THEME_CHANGED="tauri://theme-changed",r.WINDOW_CREATED="tauri://window-created",r.WINDOW_SUSPENDED="tauri://suspended",r.WINDOW_RESUMED="tauri://resumed",r.WEBVIEW_CREATED="tauri://webview-created",r.DRAG_ENTER="tauri://drag-enter",r.DRAG_OVER="tauri://drag-over",r.DRAG_DROP="tauri://drag-drop",r.DRAG_LEAVE="tauri://drag-leave"})(_||(_={}));async function l(r,a){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(r,a),await D("plugin:event|unlisten",{event:r,eventId:a})}async function n(r,a,e){var t;const W=typeof e?.target=="string"?{kind:"AnyLabel",label:e.target}:(t=e?.target)!==null&&t!==void 0?t:{kind:"Any"};return D("plugin:event|listen",{event:r,target:W,handler:i(a)}).then(d=>async()=>l(r,d))}export{_ as TauriEvent,n as listen};
|
||||
Vendored
-121
@@ -1,121 +0,0 @@
|
||||
(function(){const b=document.createElement("link").relList;if(b&&b.supports&&b.supports("modulepreload"))return;for(const _ of document.querySelectorAll('link[rel="modulepreload"]'))r(_);new MutationObserver(_=>{for(const D of _)if(D.type==="childList")for(const Y of D.addedNodes)Y.tagName==="LINK"&&Y.rel==="modulepreload"&&r(Y)}).observe(document,{childList:!0,subtree:!0});function A(_){const D={};return _.integrity&&(D.integrity=_.integrity),_.referrerPolicy&&(D.referrerPolicy=_.referrerPolicy),_.crossOrigin==="use-credentials"?D.credentials="include":_.crossOrigin==="anonymous"?D.credentials="omit":D.credentials="same-origin",D}function r(_){if(_.ep)return;_.ep=!0;const D=A(_);fetch(_.href,D)}})();function sm(f){return f&&f.__esModule&&Object.prototype.hasOwnProperty.call(f,"default")?f.default:f}var ws={exports:{}},ti={};var Vd;function z0(){if(Vd)return ti;Vd=1;var f=Symbol.for("react.transitional.element"),b=Symbol.for("react.fragment");function A(r,_,D){var Y=null;if(D!==void 0&&(Y=""+D),_.key!==void 0&&(Y=""+_.key),"key"in _){D={};for(var G in _)G!=="key"&&(D[G]=_[G])}else D=_;return _=D.ref,{$$typeof:f,type:r,key:Y,ref:_!==void 0?_:null,props:D}}return ti.Fragment=b,ti.jsx=A,ti.jsxs=A,ti}var Zd;function T0(){return Zd||(Zd=1,ws.exports=z0()),ws.exports}var c=T0(),Bs={exports:{}},le={};var Kd;function M0(){if(Kd)return le;Kd=1;var f=Symbol.for("react.transitional.element"),b=Symbol.for("react.portal"),A=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),_=Symbol.for("react.profiler"),D=Symbol.for("react.consumer"),Y=Symbol.for("react.context"),G=Symbol.for("react.forward_ref"),R=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),E=Symbol.for("react.lazy"),w=Symbol.for("react.activity"),Z=Symbol.iterator;function ce(d){return d===null||typeof d!="object"?null:(d=Z&&d[Z]||d["@@iterator"],typeof d=="function"?d:null)}var $={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},k=Object.assign,se={};function F(d,z,B){this.props=d,this.context=z,this.refs=se,this.updater=B||$}F.prototype.isReactComponent={},F.prototype.setState=function(d,z){if(typeof d!="object"&&typeof d!="function"&&d!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,d,z,"setState")},F.prototype.forceUpdate=function(d){this.updater.enqueueForceUpdate(this,d,"forceUpdate")};function ae(){}ae.prototype=F.prototype;function ue(d,z,B){this.props=d,this.context=z,this.refs=se,this.updater=B||$}var je=ue.prototype=new ae;je.constructor=ue,k(je,F.prototype),je.isPureReactComponent=!0;var Qe=Array.isArray;function Ve(){}var P={H:null,A:null,T:null,S:null},Te=Object.prototype.hasOwnProperty;function Fe(d,z,B){var H=B.ref;return{$$typeof:f,type:d,key:z,ref:H!==void 0?H:null,props:B}}function we(d,z){return Fe(d.type,z,d.props)}function Me(d){return typeof d=="object"&&d!==null&&d.$$typeof===f}function Je(d){var z={"=":"=0",":":"=2"};return"$"+d.replace(/[=:]/g,function(B){return z[B]})}var We=/\/+/g;function nt(d,z){return typeof d=="object"&&d!==null&&d.key!=null?Je(""+d.key):z.toString(36)}function $e(d){switch(d.status){case"fulfilled":return d.value;case"rejected":throw d.reason;default:switch(typeof d.status=="string"?d.then(Ve,Ve):(d.status="pending",d.then(function(z){d.status==="pending"&&(d.status="fulfilled",d.value=z)},function(z){d.status==="pending"&&(d.status="rejected",d.reason=z)})),d.status){case"fulfilled":return d.value;case"rejected":throw d.reason}}throw d}function x(d,z,B,H,I){var ee=typeof d;(ee==="undefined"||ee==="boolean")&&(d=null);var te=!1;if(d===null)te=!0;else switch(ee){case"bigint":case"string":case"number":te=!0;break;case"object":switch(d.$$typeof){case f:case b:te=!0;break;case E:return te=d._init,x(te(d._payload),z,B,H,I)}}if(te)return I=I(d),te=H===""?"."+nt(d,0):H,Qe(I)?(B="",te!=null&&(B=te.replace(We,"$&/")+"/"),x(I,z,B,"",function(Ut){return Ut})):I!=null&&(Me(I)&&(I=we(I,B+(I.key==null||d&&d.key===I.key?"":(""+I.key).replace(We,"$&/")+"/")+te)),z.push(I)),1;te=0;var qe=H===""?".":H+":";if(Qe(d))for(var Ee=0;Ee<d.length;Ee++)H=d[Ee],ee=qe+nt(H,Ee),te+=x(H,z,B,ee,I);else if(Ee=ce(d),typeof Ee=="function")for(d=Ee.call(d),Ee=0;!(H=d.next()).done;)H=H.value,ee=qe+nt(H,Ee++),te+=x(H,z,B,ee,I);else if(ee==="object"){if(typeof d.then=="function")return x($e(d),z,B,H,I);throw z=String(d),Error("Objects are not valid as a React child (found: "+(z==="[object Object]"?"object with keys {"+Object.keys(d).join(", ")+"}":z)+"). If you meant to render a collection of children, use an array instead.")}return te}function O(d,z,B){if(d==null)return d;var H=[],I=0;return x(d,H,"","",function(ee){return z.call(B,ee,I++)}),H}function K(d){if(d._status===-1){var z=d._result;z=z(),z.then(function(B){(d._status===0||d._status===-1)&&(d._status=1,d._result=B)},function(B){(d._status===0||d._status===-1)&&(d._status=2,d._result=B)}),Line truncated
|
||||
at`)?" (<anonymous>)":-1<l.stack.indexOf("@")?"@unknown:0:0":""}return`
|
||||
`+ht+e+el}var il=!1;function ol(e,t){if(!e||il)return"";il=!0;var l=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var a={DetermineComponentFrameRoot:function(){try{if(t){var N=function(){throw Error()};if(Object.defineProperty(N.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(N,[])}catch(S){var v=S}Reflect.construct(e,[],N)}else{try{N.call()}catch(S){v=S}e.call(N.prototype)}}else{try{throw Error()}catch(S){v=S}(N=e())&&typeof N.catch=="function"&&N.catch(function(){})}}catch(S){if(S&&v&&typeof S.stack=="string")return[S.stack,v.stack]}return[null,null]}};a.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var n=Object.getOwnPropertyDescriptor(a.DetermineComponentFrameRoot,"name");n&&n.configurable&&Object.defineProperty(a.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var i=a.DetermineComponentFrameRoot(),u=i[0],s=i[1];if(u&&s){var o=u.split(`
|
||||
`),g=s.split(`
|
||||
`);for(n=a=0;a<o.length&&!o[a].includes("DetermineComponentFrameRoot");)a++;for(;n<g.length&&!g[n].includes("DetermineComponentFrameRoot");)n++;if(a===o.length||n===g.length)for(a=o.length-1,n=g.length-1;1<=a&&0<=n&&o[a]!==g[n];)n--;for(;1<=a&&0<=n;a--,n--)if(o[a]!==g[n]){if(a!==1||n!==1)do if(a--,n--,0>n||o[a]!==g[n]){var j=`
|
||||
`+o[a].replace(" at new "," at ");return e.displayName&&j.includes("<anonymous>")&&(j=j.replace("<anonymous>",e.displayName)),j}while(1<=a&&0<=n);break}}}finally{il=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?Ie(l):""}function T(e,t){switch(e.tag){case 26:case 27:case 5:return Ie(e.type);case 16:return Ie("Lazy");case 13:return e.child!==t&&t!==null?Ie("Suspense Fallback"):Ie("Suspense");case 19:return Ie("SuspenseList");case 0:case 15:return ol(e.type,!1);case 11:return ol(e.type.render,!1);case 1:return ol(e.type,!0);case 31:return Ie("Activity");default:return""}}function C(e){try{var t="",l=null;do t+=T(e,l),l=e,e=e.return;while(e);return t}catch(a){return`
|
||||
Error generating stack: `+a.message+`
|
||||
`+a.stack}}var q=Object.prototype.hasOwnProperty,Q=f.unstable_scheduleCallback,Ze=f.unstable_cancelCallback,zt=f.unstable_shouldYield,wt=f.unstable_requestPaint,ge=f.unstable_now,Bt=f.unstable_getCurrentPriorityLevel,ui=f.unstable_ImmediatePriority,ci=f.unstable_UserBlockingPriority,_a=f.unstable_NormalPriority,_u=f.unstable_LowPriority,L=f.unstable_IdlePriority,be=f.log,Ge=f.unstable_setDisableYieldValue,tt=null,Be=null;function _t(e){if(typeof be=="function"&&Ge(e),Be&&typeof Be.setStrictMode=="function")try{Be.setStrictMode(tt,e)}catch{}}var rt=Math.clz32?Math.clz32:Se,ja=Math.log,yt=Math.LN2;function Se(e){return e>>>=0,e===0?32:31-(ja(e)/yt|0)|0}var me=256,Re=262144,ve=4194304;function Le(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function De(e,t,l){var a=e.pendingLanes;if(a===0)return 0;var n=0,i=e.suspendedLanes,u=e.pingedLanes;e=e.warmLanes;var s=a&134217727;return s!==0?(a=s&~i,a!==0?n=Le(a):(u&=s,u!==0?n=Le(u):l||(l=s&~e,l!==0&&(n=Le(l))))):(s=a&~i,s!==0?n=Le(s):u!==0?n=Le(u):l||(l=a&~e,l!==0&&(n=Le(l)))),n===0?0:t!==0&&t!==n&&(t&i)===0&&(i=n&-n,l=t&-t,i>=l||i===32&&(l&4194048)!==0)?t:n}function ft(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Rt(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function tl(){var e=ve;return ve<<=1,(ve&62914560)===0&&(ve=4194304),e}function on(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function rn(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function dm(e,t,l,a,n,i){var u=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var s=e.entanglements,o=e.expirationTimes,g=e.hiddenUpdates;for(l=u&~l;0<l;){var j=31-rt(l),N=1<<j;s[j]=0,o[j]=-1;var v=g[j];if(v!==null)for(g[j]=null,j=0;j<v.length;j++){var S=v[j];S!==null&&(S.lane&=-536870913)}l&=~N}a!==0&&Js(e,a,0),i!==0&&n===0&&e.tag!==0&&(e.suspendedLanes|=i&~(u&~t))}function Js(e,t,l){e.pendingLanes|=t,e.suspendedLanes&=~t;var a=31-rt(t);e.entangledLanes|=t,e.entanglements[a]=e.entanglements[a]|1073741824|l&261930}function $s(e,t){var l=e.entangledLanes|=t;for(e=e.entanglements;l;){var a=31-rt(l),n=1<<a;n&t|e[a]&t&&(e[a]|=t),l&=~n}}function Fs(e,t){var l=t&-t;return l=(l&42)!==0?1:ju(l),(l&(e.suspendedLanes|t))!==0?0:l}function ju(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function zu(e){return e&=-e,2<e?8<e?(e&134217727)!==0?32:268435456:8:2}function Ws(){var e=O.p;return e!==0?e:(e=window.event,e===void 0?32:Gd(e.type))}function Is(e,t){var l=O.p;try{return O.p=e,t()}finally{O.p=l}}var Dl=Math.random().toString(36).slice(2),pt="__reactFiber$"+Dl,Mt="__reactProps$"+Dl,za="__reactContainer$"+Dl,Tu="__reactEvents$"+Dl,mm="__reactListeners$"+Dl,hm="__reactHandles$"+Dl,Ps="__reactResources$"+Dl,dn="__reactMarker$"+Dl;function Mu(e){delete e[pt],delete e[Mt],delete e[Tu],delete e[mm],delete e[hm]}function Ta(e){var t=e[pt];if(t)return t;for(var l=e.parentNode;l;){if(t=l[za]||l[pt]){if(l=t.alternate,t.child!==null||l!==null&&l.child!==null)for(e=_d(e);e!==null;){if(l=e[pt])return l;e=_d(e)}return t}e=l,l=e.parentNode}return null}function Ma(e){if(e=e[pt]||e[za]){var t=e.tag;if(t===5||t===6||t===13||t===31||t===26||t===27||t===3)return e}return null}function mn(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e.stateNode;throw Error(r(33))}function Ea(e){var t=e[Ps];return t||(t=e[Ps]={hoistableStyles:new Map,hoistableScripts:new Map}),t}function dt(e){e[dn]=!0}var ef=new Set,tf={};function la(e,t){Na(e,t),Na(e+"Capture",t)}function Na(e,t){for(tf[e]=t,e=0;e<t.length;e++)ef.add(t[e])}var ym=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\
Line truncated
|
||||
`).replace(Zh,"")}function dd(e,t){return t=rd(t),rd(e)===t}function Oe(e,t,l,a,n,i){switch(l){case"children":typeof a=="string"?t==="body"||t==="textarea"&&a===""||Da(e,a):(typeof a=="number"||typeof a=="bigint")&&t!=="body"&&Da(e,""+a);break;case"className":fi(e,"class",a);break;case"tabIndex":fi(e,"tabindex",a);break;case"dir":case"role":case"viewBox":case"width":case"height":fi(e,l,a);break;case"style":rf(e,a,i);break;case"data":if(t!=="object"){fi(e,"data",a);break}case"src":case"href":if(a===""&&(t!=="a"||l!=="href")){e.removeAttribute(l);break}if(a==null||typeof a=="function"||typeof a=="symbol"||typeof a=="boolean"){e.removeAttribute(l);break}a=ri(""+a),e.setAttribute(l,a);break;case"action":case"formAction":if(typeof a=="function"){e.setAttribute(l,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof i=="function"&&(l==="formAction"?(t!=="input"&&Oe(e,t,"name",n.name,n,null),Oe(e,t,"formEncType",n.formEncType,n,null),Oe(e,t,"formMethod",n.formMethod,n,null),Oe(e,t,"formTarget",n.formTarget,n,null)):(Oe(e,t,"encType",n.encType,n,null),Oe(e,t,"method",n.method,n,null),Oe(e,t,"target",n.target,n,null)));if(a==null||typeof a=="symbol"||typeof a=="boolean"){e.removeAttribute(l);break}a=ri(""+a),e.setAttribute(l,a);break;case"onClick":a!=null&&(e.onclick=dl);break;case"onScroll":a!=null&&re("scroll",e);break;case"onScrollEnd":a!=null&&re("scrollend",e);break;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(r(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(r(60));e.innerHTML=l}}break;case"multiple":e.multiple=a&&typeof a!="function"&&typeof a!="symbol";break;case"muted":e.muted=a&&typeof a!="function"&&typeof a!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(a==null||typeof a=="function"||typeof a=="boolean"||typeof a=="symbol"){e.removeAttribute("xlink:href");break}l=ri(""+a),e.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",l);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":a!=null&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,""+a):e.removeAttribute(l);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":a&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,""):e.removeAttribute(l);break;case"capture":case"download":a===!0?e.setAttribute(l,""):a!==!1&&a!=null&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,a):e.removeAttribute(l);break;case"cols":case"rows":case"size":case"span":a!=null&&typeof a!="function"&&typeof a!="symbol"&&!isNaN(a)&&1<=a?e.setAttribute(l,a):e.removeAttribute(l);break;case"rowSpan":case"start":a==null||typeof a=="function"||typeof a=="symbol"||isNaN(a)?e.removeAttribute(l):e.setAttribute(l,a);break;case"popover":re("beforetoggle",e),re("toggle",e),si(e,"popover",a);break;case"xlinkActuate":rl(e,"http://www.w3.org/1999/xlink","xlink:actuate",a);break;case"xlinkArcrole":rl(e,"http://www.w3.org/1999/xlink","xlink:arcrole",a);break;case"xlinkRole":rl(e,"http://www.w3.org/1999/xlink","xlink:role",a);break;case"xlinkShow":rl(e,"http://www.w3.org/1999/xlink","xlink:show",a);break;case"xlinkTitle":rl(e,"http://www.w3.org/1999/xlink","xlink:title",a);break;case"xlinkType":rl(e,"http://www.w3.org/1999/xlink","xlink:type",a);break;case"xmlBase":rl(e,"http://www.w3.org/XML/1998/namespace","xml:base",a);break;case"xmlLang":rl(e,"http://www.w3.org/XML/1998/namespace","xml:lang",a);break;case"xmlSpace":rl(e,"http://www.w3.org/XML/1998/namespace","xml:space",a);break;case"is":si(e,"is",a);break;case"innerText":case"textContent":break;default:(!(2<l.length)||l[0]!=="o"&&l[0]!=="O"||l[1]!=="n"&&l[1]!=="N")&&(l=Sm.get(l)||l,si(e,l,a))}}function ps(e,t,l,a,n,i){switch(l){case"style":rf(e,a,i);break;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(r(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(r(60));e.innerHTML=l}}break;case"children":typeof a=="string"?Da(e,a):(typeof a=="number"||typeof a=="bigint")&&Da(e,""+a);break;case"onScroll":a!=null&&re("scroll",e);break;case"onScrollEnd":a!=null&&re("scrollend",e);break;case"onClick":a!=null&&(e.onclick=dl);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"inne
Line truncated
|
||||
<!-- Stars -->
|
||||
<circle cx="80" cy="100" r="1.5" fill="#ffffff" opacity="0.6"/>
|
||||
<circle cx="160" cy="60" r="1" fill="#ffffff" opacity="0.5"/>
|
||||
<circle cx="280" cy="120" r="2" fill="#ffffff" opacity="0.8"/>
|
||||
<circle cx="360" cy="80" r="1.5" fill="#ffffff" opacity="0.4"/>
|
||||
<circle cx="440" cy="150" r="1" fill="#ffffff" opacity="0.7"/>
|
||||
<circle cx="400" cy="280" r="2" fill="#ffffff" opacity="0.9"/>
|
||||
<circle cx="100" cy="300" r="1.5" fill="#ffffff" opacity="0.5"/>
|
||||
<!-- Moon -->
|
||||
<circle cx="256" cy="220" r="90" fill="url(#moonGrad)" />
|
||||
<circle cx="226" cy="190" r="80" fill="#0F172A" />
|
||||
`):k.includes("cat")||k.includes("kitten")||k.includes("feline")?(F="#4F46E5",ae="#7C3AED",je="Stylized Cat Portrait",ue=`
|
||||
<!-- Cat head & ears -->
|
||||
<polygon points="176,280 146,160 216,210" fill="#312E81" />
|
||||
<polygon points="336,280 366,160 296,210" fill="#312E81" />
|
||||
<circle cx="256" cy="270" r="80" fill="#4338CA" />
|
||||
<!-- Eyes -->
|
||||
<ellipse cx="226" cy="260" rx="14" ry="8" fill="#10B981" />
|
||||
<ellipse cx="286" cy="260" rx="14" ry="8" fill="#10B981" />
|
||||
<circle cx="226" cy="260" r="4" fill="#000" />
|
||||
<circle cx="286" cy="260" r="4" fill="#000" />
|
||||
<!-- Nose & Whiskers -->
|
||||
<polygon points="256,285 248,275 264,275" fill="#F43F5E" />
|
||||
<line x1="226" y1="290" x2="166" y2="280" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="226" y1="295" x2="156" y2="295" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="286" y1="290" x2="346" y2="280" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="286" y1="295" x2="356" y2="295" stroke="#E2E8F0" stroke-width="2" />
|
||||
`):k.includes("dog")||k.includes("puppy")||k.includes("canine")?(F="#D97706",ae="#B45309",je="Friendly Dog Portrait",ue=`
|
||||
<!-- Dog head & floppy ears -->
|
||||
<ellipse cx="166" cy="260" rx="20" ry="60" fill="#78350F" />
|
||||
<ellipse cx="346" cy="260" rx="20" ry="60" fill="#78350F" />
|
||||
<circle cx="256" cy="250" r="70" fill="#92400E" />
|
||||
<ellipse cx="256" cy="280" rx="40" ry="30" fill="#D97706" />
|
||||
<!-- Eyes -->
|
||||
<circle cx="226" cy="230" r="10" fill="#1E293B" />
|
||||
<circle cx="286" cy="230" r="10" fill="#1E293B" />
|
||||
<circle cx="222" cy="226" r="3" fill="#ffffff" />
|
||||
<circle cx="282" cy="226" r="3" fill="#ffffff" />
|
||||
<!-- Nose -->
|
||||
<ellipse cx="256" cy="275" rx="16" ry="10" fill="#1E293B" />
|
||||
`):k.includes("city")||k.includes("cyberpunk")||k.includes("tokyo")||k.includes("neon")?(F="#111827",ae="#311042",je="Neon Cyberpunk Skyline",ue=`
|
||||
<!-- Skyline -->
|
||||
<rect x="60" y="160" width="80" height="352" fill="#1F2937" opacity="0.9"/>
|
||||
<rect x="180" y="100" width="100" height="412" fill="#111827" />
|
||||
<rect x="320" y="200" width="120" height="312" fill="#1F2937" opacity="0.85"/>
|
||||
<rect x="100" y="240" width="110" height="272" fill="#374151" opacity="0.6"/>
|
||||
<!-- Neon details -->
|
||||
<line x1="230" y1="100" x2="230" y2="40" stroke="#EC4899" stroke-width="3" />
|
||||
<rect x="200" y="140" width="60" height="15" fill="#10B981" opacity="0.7"/>
|
||||
<rect x="200" y="170" width="60" height="15" fill="#10B981" opacity="0.7"/>
|
||||
<rect x="200" y="200" width="60" height="15" fill="#3B82F6" opacity="0.7"/>
|
||||
<rect x="70" y="200" width="15" height="100" fill="#F59E0B" opacity="0.5"/>
|
||||
<rect x="340" y="250" width="20" height="150" fill="#EF4444" opacity="0.6"/>
|
||||
`):k.includes("car")||k.includes("vehicle")||k.includes("supercar")?(F="#DC2626",ae="#991B1B",je="Futuristic Concept Car",ue=`
|
||||
<!-- Road / Perspective grid -->
|
||||
<line x1="256" y1="350" x2="0" y2="512" stroke="#4B5563" stroke-width="3" />
|
||||
<line x1="256" y1="350" x2="512" y2="512" stroke="#4B5563" stroke-width="3" />
|
||||
<!-- Car body -->
|
||||
<polygon points="126,380 256,330 386,380 346,440 166,440" fill="#EF4444" />
|
||||
<polygon points="176,370 256,340 336,370 326,390 186,390" fill="#1E293B" opacity="0.9" />
|
||||
<!-- Headlights -->
|
||||
<polygon points="136,410 176,415 166,425 136,420" fill="#FBBF24" />
|
||||
<polygon points="376,410 336,415 346,425 376,420" fill="#FBBF24" />
|
||||
<!-- Wheels -->
|
||||
<ellipse cx="156" cy="440" rx="30" ry="15" fill="#111" />
|
||||
<ellipse cx="356" cy="440" rx="30" ry="15" fill="#111" />
|
||||
`):(F="#06B6D4",ae="#0891B2",je="Abstract Creative Concept",ue=`
|
||||
<path d="M0,256 C150,150 350,350 512,256 L512,512 L0,512 Z" fill="#0891B2" opacity="0.4" />
|
||||
<path d="M0,350 C200,200 300,450 512,350 L512,512 L0,512 Z" fill="#0E7490" opacity="0.6" />
|
||||
<circle cx="380" cy="180" r="50" fill="#F59E0B" opacity="0.8" />
|
||||
`);const Qe=`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="${F}" />
|
||||
<stop offset="100%" stop-color="${ae}" />
|
||||
</linearGradient>
|
||||
<linearGradient id="moonGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#FEF08A" />
|
||||
<stop offset="100%" stop-color="#FDE047" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="512" height="512" fill="url(#bgGrad)" />
|
||||
|
||||
<!-- Shapes -->
|
||||
${ue}
|
||||
|
||||
<!-- Premium UI Overlay Frame -->
|
||||
<rect x="20" y="20" width="472" height="472" fill="none" stroke="#ffffff" stroke-width="1.5" opacity="0.15" rx="8"/>
|
||||
|
||||
<!-- Prompt & Details text -->
|
||||
<rect x="40" y="410" width="432" height="62" fill="#0F172A" opacity="0.85" rx="6" />
|
||||
<text x="60" y="435" fill="#F1F5F9" font-family="system-ui, -apple-system, sans-serif" font-size="13" font-weight="bold">${je}</text>
|
||||
<text x="60" y="455" fill="#94A3B8" font-family="system-ui, -apple-system, sans-serif" font-size="11">Seed: ${se} • Steps: ${E.steps} • Scale: ${E.cfg_scale}</text>
|
||||
</svg>
|
||||
`,P=`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(Qe)))}`,Te=parseFloat(((Date.now()-G)/1e3).toFixed(1));return{image:P,seed:E.seed,duration_sec:Te}},Z=!!E.image,ce={prompt:E.prompt,negative_prompt:E.negative_prompt||"",n:1,size:`${E.width}x${E.height}`,response_format:"b64_json",steps:E.steps,cfg_scale:E.cfg_scale,seed:E.seed,sample_method:E.sampler};Z&&(ce.init_images=[E.image],ce.denoising_strength=E.denoising_strength);try{const $=await fetch(`${y}/v1/images/generations`,{method:"POST",headers:{"Content-Type":"application/json"},signal:Y,body:JSON.stringify(ce)});if($.ok){const k=await $.json(),se=k?.data?.[0]?.b64_json??k?.images?.[0];if(se){const F=parseFloat(((Date.now()-G)/1e3).toFixed(1));return{image:`data:image/png;base64,${se}`,seed:k.data?.[0]?.seed??E.seed,duration_sec:F}}}else{let k=`Generation failed (HTTP ${$.status})`;try{const se=await $.json();(se?.detail||se?.error?.message)&&(k=se.detail||se.error.message)}catch{}throw new Error(k)}}catch($){if($.name==="AbortError"||$.message.startsWith("Generation failed"))throw $;console.warn("Could not reach local server. Falling back to simulation mode.",$)}return await w()}async function Ky(f,b,A){if(f instanceof File){const G=f;if(!Sa())throw new Error("File import requires the local image generator server.");return await Jy(G,b,A),{response:"Model imported successfully"}}if(Al()){const{listen:G}=await Oy(async()=>{const{listen:y}=await import("./event-CvjXGmc1.js");return{listen:y}},[]);let R=null;b&&(R=await G("import-progress",y=>{b(y.payload)}));try{return{response:await xa("import_model_file",{sourcePath:f}),unlisten:R}}catch(y){throw R&&R(),y}}const r=f.split(/[\\/]/).pop()||"imported_model.gguf";console.log(`Web Mode: Simulating copying ${r} to USB models folder`);const _=40;for(let G=1;G<=_;G++){if(A?.aborted)throw new DOMException("The user aborted a request.","AbortError");await new Promise(w=>setTimeout(w,150));const R=G/_*100,y=40+Math.sin(G)*5+Math.random()*2,E=(_-G)*.15;b&&b({filename:r,progress:R,speed_mb_s:y,eta_secs:E,status:"Copying to USB..."})}const D=localStorage.getItem("imported-models"),Y=D?JSON.parse(D):[];return Y.includes(r)||(Y.push({filename:r,sizeBytes:0,size:"Unknown"}),localStorage.setItem("imported-models",JSON.stringify(Y))),{response:"Model imported successfully"}}function Jy(f,b,A){return new Promise((r,_)=>{const D=new XMLHttpRequest,Y=Date.now();let G=!1;D.open("POST",`/api/import-model?filename=${encodeURIComponent(f.name)}`),D.setRequestHeader("Content-Type","application/octet-stream");const R=()=>{G=!0,D.abort()};A&&(A.aborted?R():A.addEventListener("abort",R,{once:!0})),D.upload.onprogress=y=>{if(!y.lengthComputable||!b)return;const E=Math.max(.1,(Date.now()-Y)/1e3),w=y.loaded/E,Z=Math.max(0,y.total-y.loaded);b({filename:f.name,progress:y.loaded/y.total*100,speed_mb_s:w/(1024*1024),eta_secs:Z/Math.max(1,w),status:"Copying to models folder..."})},D.onload=()=>{let y={};try{y=JSON.parse(D.responseText||"{}")}catch{}D.status>=200&&D.status<300&&y.ok!==!1?(b&&b({filename:f.name,progress:100,speed_mb_s:0,eta_secs:0,status:"Import complete"}),r(y)):_(new Error(y.error||`Import failed (HTTP ${D.status})`))},D.onerror=()=>_(new Error("Import failed while uploading the file.")),D.onabort=()=>_(new DOMException(G?"Import cancelled by user.":"Import aborted.","AbortError")),D.send(f)})}async function $y(f){if(Al())return await xa("delete_model_file",{filename:f});if(typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"))try{const _=await fetch("/api/delete-model",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filename:f})}),D=await _.json();if(!_.ok)throw new Error(D.error||"Failed to delete model file");return D}catch(_){throw console.error("Failed to delete model via local API:",_),_}const A=localStorage.getItem("imported-models");let r=A?JSON.parse(A):[];return r=r.filter(_=>ii(_).filename!==f),localStorage.setItem("imported-models",JSON.stringify(r)),`Simulated deletion of ${f} from browser session`}async function rm(){const b="http://127.0.0.1:8080";try{return(await fetch(`${b}/v1/models`,{method:"GET"})).ok}catch{return!1}}async function Fy(f=30){const b=Al()||Sa()?f:3;for(let A=0;A<b;A++){let r=!1;if(Sa()?r=!!(await ba()).ready:r=await rm(),r)return!0;await new Promise(_=>setTimeout(_,500))}return!1}async function Wy(f){try{return await(await fetch("/api/download-model",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:f})})).json()}catch(b){return console.error("Failed to start model download:",b),{ok:!1,error:b.message}}}async function Iy(){try{return await(await fetch("/api/cancel-download",{method:"POST"})).json()}catch(f){return console.error("Failed to cancel model download:",f),{ok:!1,error:f.message}}}async function um(){try{return await(await fetch("/api/download-progress")).json()}catch(f){return console.error("Failed to get download progress:",f),{active:!1,error:f.m
Line truncated
|
||||
Seed: ${f.seed}${f.duration_sec?`
|
||||
Time: ${f.duration_sec.toFixed(1)}s`:""}`,children:[c.jsx("img",{src:f.url,className:"gallery-thumb",alt:"Thumbnail",loading:"lazy",decoding:"async"}),A&&c.jsx("div",{className:"gallery-select-badge",children:c.jsx(Ys,{size:14})})]})});function t1({prompt:f,setPrompt:b,negativePrompt:A,setNegativePrompt:r,constraints:_,setConstraints:D,activeModel:Y,generatedImages:G,setGeneratedImages:R,isGenerating:y,setIsGenerating:E,generationProgress:w,setGenerationProgress:Z,setActiveTab:ce,inputImage:$,setInputImage:k,showAlert:se=async({message:ae})=>window.alert(ae),showConfirm:F=async({message:ae})=>window.confirm(ae)}){const[ae,ue]=U.useState(null),[je,Qe]=U.useState(null),[Ve,P]=U.useState(null),[Te,Fe]=U.useState(!1),[we,Me]=U.useState(0),[Je,We]=U.useState(0),[nt,$e]=U.useState(0),[x,O]=U.useState(""),[K,fe]=U.useState(!1),[de,d]=U.useState(!1),[z,B]=U.useState(!1),[H,I]=U.useState(null),[ee,te]=U.useState(null),[qe,Ee]=U.useState(!1),[Ut,xt]=U.useState([]),ht=U.useRef(null),el=U.useRef(null),Ie=U.useRef(null),il=()=>{el.current.click()},ol=L=>{const be=L.target.files[0];if(be){const Ge=new FileReader;Ge.onload=()=>{k(Ge.result)},Ge.readAsDataURL(be)}},T=L=>{L.stopPropagation(),k(null),el.current&&(el.current.value="")},C=async()=>{if(!f.trim())return;te(null),B(!0),I(null);let L=!1;try{const Se=await ba();if(Se&&Se.settings){const me=Se.settings,Re=me.model?me.model.split(/[\\/]/).pop():null,ve=Y?Y.split(/[\\/]/).pop():null;(Re!==ve||parseInt(me.steps)!==parseInt(_.steps)||Math.abs(parseFloat(me.cfgScale)-parseFloat(_.cfgScale))>.05||me.sampler!==_.sampler||parseInt(me.threads)!==parseInt(_.threads)||!!me.useGpu!=(_.useGpu!==!1)||(me.backendType||(me.useGpu===!1?"cpu":"auto"))!==(_.backendType||(_.useGpu===!1?"cpu":"auto")))&&(L=!0)}else L=!0}catch{L=!0}if(L)try{console.log("Settings out of sync, restarting backend..."),await Qs(Y,_);let Se=!1,me=null;for(let Re=0;Re<240;Re++){const ve=await ba();if(ve.loading&&I({progress:ve.loading.progress||0,phase:ve.loading.phase||"Loading model...",speed:ve.loading.speed||"",current:ve.loading.current||0,total:ve.loading.total||0,backendMode:ve.loading.backendMode||ve.settings?.backendMode||"",device:ve.loading.device||ve.settings?.backendDevice||""}),ve.ready){Se=!0;break}if(ve.error){me=ve.error;break}if(!ve.running&&Re>3){me="The backend process terminated immediately on startup.";break}await new Promise(Le=>setTimeout(Le,500))}if(!Se)throw new Error(me||"Backend server failed to start after applying configuration changes.")}catch(Se){console.error("Failed to restart backend:",Se),te(Se.message||"Failed to sync settings with backend."),B(!1);return}B(!1),I(null),ht.current&&clearInterval(ht.current),E(!0),Z(0),Me(0),$e(0),O(""),fe(!1),Ee(!1),P(null),ue(null);const be=(_.width>=1024?140:35)*.04,Ge=_.width>=1024?140:35,tt=(_.backendType||(_.useGpu===!1?"cpu":"auto"))!=="cpu";let Be=tt?be:Ge,_t=!1,rt=0,ja=0,yt=0;We(Math.round(_.steps*Be)),ht.current=setInterval(async()=>{yt++,Me(yt);try{const Se=await Py();if(Se&&Se.active){const me=Se.decoding||!1;Ee(me);const Re=me?Se.steps||_.steps||20:Se.step||0,ve=Se.steps||_.steps||20,Le=me?"":Se.speed||"";$e(Re),O(me?"decoding":Le);let De=0;me?De=99:ve>0&&(De=Math.round(Re/ve*100)),De=Math.min(99,De),Z(Rt=>Math.max(Rt,De));let ft=0;if(me)ft=3;else{const Rt=parseFloat(Le);if(!isNaN(Rt)&&Rt>0){const tl=Math.max(0,ve-Re);Le.includes("it/s")?ft=tl/Rt:Le.includes("s/it")&&(ft=tl*Rt)}else{const tl=tt?be:Ge;ft=Math.max(0,(ve-Re)*tl)}}if(tt&&!_t){const Rt=Le.includes("it/s")&&numericSpeed<.2,tl=Le.includes("s/it")&&numericSpeed>5;(Rt||tl)&&(_t=!0,fe(!0))}We(Math.round(ft))}else Z(me=>Math.min(15,me+1)),We(me=>Math.max(1,me-1))}catch(Se){console.warn("Failed to get generation progress, running simulation fallback:",Se),tt&&!_t&&yt>_.steps*be*1.3&&(_t=!0,fe(!0),Be=Ge,rt=yt,ja=Math.min(95,Math.round(yt/(_.steps*be)*100)));let me=Math.min(_.steps-1,Math.floor(yt/Be)),Re=_.steps*Be;if(yt>=Re){const De=Math.ceil(yt/Math.max(.5,me));Be=Math.max(Be+15,De+15),Re=_.steps*Be,me=Math.min(_.steps-1,Math.floor(yt/Be))}$e(me);const ve=Math.max(1,Re-yt);We(Math.round(ve));let Le=0;if(_t){const De=99-ja,ft=Re-rt;if(ft>0){const Rt=Math.min(1,(yt-rt)/ft);if(Rt<.85)Le=Math.round(ja+Rt*De);else{const tl=(yt-(rt+ft*.85))/(Be*2),on=1-Math.exp(-tl);Le=Math.min(99,Math.round(ja+.85*De+.14*De*on))}}else Le=99}else if(yt<Re*.85)Le=Math.round(yt/Re*100);else{const De=(yt-Re*.85)/(Be*2),ft=1-Math.exp(-De);Le=Math.min(99,Math.round(85+14*ft))}Z(De=>Math.max(De,Le))}},1e3);try{Ie.current=new AbortController;const Se=await Zy(f,A,_,Y,$,De=>Z(ft=>Math.max(ft,De)),Ie.current.signal);ht.current&&clearInterval(ht.current),Z(100),$e(_.steps),We(0),O("");const me={prompt:f,negativePrompt:A,seed:Se.seed,steps:_.steps,cfgScale:_.cfgScale,width:_.width,height:_.height,sampler:_.sampler,model:Y,duration_sec:Se.duration_sec,timestamp:new Date().toLocaleTimeString(),inputImage:!!$};let Re=null,ve=null;try{if(Re=await ky(Se.image,me),ve=Re.url,!ve)throw new Error("The local serverLine truncated
|
||||
|
||||
${Ze}
|
||||
|
||||
Update the UI status anyway?`,confirmLabel:"Update UI"})&&(b(T),r(!0)):await Y({title:"Backend Not Running",message:`C++ backend server is not running on port 8080.
|
||||
|
||||
To run locally, start:
|
||||
|
||||
${Ze}
|
||||
|
||||
Proceed in Simulation Mode instead?`,confirmLabel:"Proceed"})&&(b(T),r(!1));return}se(T),ae({progress:0,phase:"Starting backend...",speed:"",current:0,total:0,model:T,backendMode:"",backendBinary:"",device:""});try{const Q=await Qs(T,_);console.log(Q);let Ze=!1,zt=null;for(let wt=0;wt<240;wt++){const ge=await ba();if(ge.loading&&ae({progress:ge.loading.progress||0,phase:ge.loading.phase||"Loading model...",speed:ge.loading.speed||"",current:ge.loading.current||0,total:ge.loading.total||0,model:ge.loading.model||T,backendMode:ge.loading.backendMode||ge.settings?.backendMode||"",backendBinary:ge.loading.backendBinary||ge.settings?.backendBinary||"",device:ge.loading.device||ge.settings?.backendDevice||""}),ge.ready){Ze=!0;break}if(ge.error){zt=ge.error;break}if(!ge.running&&wt>3){zt="The backend process terminated immediately on startup.";break}await new Promise(Bt=>setTimeout(Bt,500))}if(Ze)ae(wt=>({...wt||{},progress:100,phase:"Model ready",speed:"",current:wt?.current||0,total:wt?.total||0,model:T})),b(T),r(!0);else throw new Error(zt||"Model server failed to respond on port 8080.")}catch(Q){console.error("Failed to load model:",Q),D({title:"Model Load Failed",message:Q.message||String(Q),danger:!0})}finally{setTimeout(()=>ae(null),800),se(null)}},Ut=async()=>{const T=$e;x(null),await xt(),T&&await Ee(T)},xt=async()=>{if(Me)return;Je(!0),nt({progress:10,phase:"Stopping backend process..."});const T=setInterval(async()=>{try{const C=await ba();C.unloading?.active?nt({progress:C.unloading.progress||50,phase:C.unloading.phase||"Unloading model..."}):nt(q=>({progress:Math.min(95,q.progress+10),phase:q.phase||"Unloading model..."}))}catch{}},300);try{await Ks(),nt({progress:100,phase:"Model unloaded"}),b(null),x(null),r(!1)}catch(C){console.error(C),D({title:"Unload Failed",message:C.message||String(C),danger:!0})}finally{clearInterval(T),setTimeout(()=>{Je(!1),nt({progress:0,phase:""})},500)}},ht=async T=>{if(await Y({title:"Delete Model?",message:`Delete "${T}" from your drive?`,confirmLabel:"Delete",danger:!0}))try{await $y(T),await B(),f===T&&await xt()}catch(C){console.error("Failed to delete model:",C),D({title:"Delete Failed",message:C.message||String(C),danger:!0})}},el=async(T,C)=>{const q=new AbortController;we(q),je(0),Ve({filename:C,speed:"0.0",eta:0,status:"Initiating file copy..."});try{await Ky(T,Q=>{je(Math.round(Q.progress)),Ve({filename:Q.filename,speed:Q.speed_mb_s.toFixed(1),eta:Math.round(Q.eta_secs),status:Q.status})},q.signal),await B()}catch(Q){console.error("Import failed:",Q),Q.name!=="AbortError"&&D({title:"Import Failed",message:Q.message||String(Q),danger:!0})}finally{je(null),we(null)}},Ie=()=>{Fe&&Fe.abort()},il=T=>{const C=T.target.files[0];C&&el(C,C.name),T.target.value=""},ol=!!y;return c.jsxs("div",{className:"workspace-area",children:[c.jsxs("div",{className:"workspace-title-section",children:[c.jsx("h2",{className:"workspace-title",children:"Model Manager"}),c.jsx("p",{className:"workspace-subtitle",children:"Manage local files and download recommended weights directly to your local models folder."})]}),f&&c.jsx("div",{className:"m3-card",style:{borderLeft:"4px solid var(--md-sys-color-primary)",background:"var(--md-sys-color-primary-container)",color:"var(--md-sys-color-on-primary-container)"},children:c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[c.jsxs("div",{children:[c.jsxs("h4",{style:{fontWeight:700},children:["Active Model: ",f]}),c.jsx("p",{style:{fontSize:"0.85rem",marginTop:"2px",opacity:.9},children:"The local C++ stable-diffusion server is running. Real-time telemetry is displaying performance status in the top bar."}),(O.backendMode||O.backendDevice||O.backendBinary)&&c.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"},children:[O.backendMode&&c.jsxs("span",{className:"status-chip",style:{cursor:"default"},children:[c.jsx(xu,{size:14}),c.jsxs("span",{children:["Loaded on ",O.backendMode]})]}),O.backendDevice&&c.jsx("span",{className:"status-chip",style:{cursor:"default"},children:c.jsx("span",{children:O.backendDevice})}),O.backendBinary&&c.jsx("span",{className:"status-chip",style:{cursor:"default"},children:c.jsx("span",{children:O.backendBinary})})]})]}),c.jsxs("button",{className:"m3-btn m3-btn-error",onClick:xt,disabled:Me||k!==null,children:[Me?c.jsx(ta,{className:"progress-spinner",size:16}):c.jsx(ai,{size:16}),c.jsx("span",{children:Me?"Unloading":"Unload Server"})]})]})}),Me&&c.jsxs("div",{className:"m3-card",style:{borderLeft:"4px solid var(--md-sys-color-error)",marginTop:"16px"},children:[c.jsx("h4",{style:{fontWeight:700,marginBottom:"8px"},children:"Unloading Model"}),c.jsxs("div",{className:"model-progress-section",style:{margin:"8px 0 0 0"},children:[c.jsxs("div",{className:"model-progress-label",children:[c.jsx("span",{children:We.phase||"Unloading model..."}),c.jsxs("span",{children:[Math.round(We.progress),"%"]})]}),c.jsx("div",{className:"model-progress-bar",chi
Line truncated
|
||||
|
||||
Models and generated outputs are not included.`,confirmLabel:"Clean",danger:!0})){We(!0);try{await Hy(we.map(q=>q.id)),await qe()}catch(q){D({title:"Cleanup Failed",message:q.message||String(q),danger:!0})}finally{We(!1)}}},[we,qe,D,_]);U.useEffect(()=>{async function T(){const C=await Xy();O(C)}T()},[]),U.useEffect(()=>{se?localStorage.setItem("active-model",se):localStorage.removeItem("active-model")},[se]),U.useEffect(()=>{let T=null;async function C(){const q=await ba();if(!!q.ready){T&&clearInterval(T);const Ze=localStorage.getItem("active-model");if(Ze)F(Ze),ue(!0);else{try{if(q&&q.settings&&q.settings.model){const zt=q.settings.model.split(/[\\/]/).pop();F(zt)}}catch{}ue(!0)}}else if(!(typeof window<"u"&&window.__TAURI_INTERNALS__!==void 0)){const zt=localStorage.getItem("active-model");zt&&(F(zt),ue(!1))}}return C(),T=setInterval(C,2e3),()=>{T&&clearInterval(T)}},[]),U.useEffect(()=>{async function T(){try{const q=await qy();I(Q=>Q.cpu_usage===q.cpu_usage&&Q.ram_used_gb===q.ram_used_gb&&Q.ram_total_gb===q.ram_total_gb&&Q.gpu_name===q.gpu_name&&Q.vram_used_gb===q.vram_used_gb&&Q.vram_total_gb===q.vram_total_gb?Q:q)}catch{}}T();const C=setInterval(T,1500);return()=>clearInterval(C)},[]),U.useEffect(()=>{if(se){const T=se.toLowerCase();T.includes("flux")||T.includes("schnell")?te(C=>({...C,steps:4,cfgScale:1,width:1024,height:1024})):T.includes("lightning")||T.includes("turbo")?te(C=>({...C,steps:4,cfgScale:1.5,width:1024,height:1024})):T.includes("sd15")?te(C=>({...C,steps:25,cfgScale:7,width:512,height:512})):T.includes("sd35")?te(C=>({...C,steps:20,cfgScale:4.5,width:1024,height:1024})):te(C=>({...C,steps:20,cfgScale:7,width:512,height:512}))}},[se]);const xt=U.useMemo(()=>{switch(R){case"generator":return c.jsx(l1,{prompt:E,setPrompt:w,negativePrompt:Z,setNegativePrompt:ce,constraints:ee,setConstraints:te,activeModel:se,generatedImages:x,setGeneratedImages:O,isGenerating:K,setIsGenerating:fe,generationProgress:de,setGenerationProgress:d,setActiveTab:y,inputImage:$,setInputImage:k,showAlert:D,showConfirm:_});case"models":return c.jsx(i1,{activeModel:se,setActiveModel:F,serverRunning:ae,setServerRunning:ue,constraints:ee,showAlert:D,showConfirm:_});case"constraints":return c.jsx(s1,{constraints:ee,setConstraints:te,activeModel:se,specs:z,backendOptions:Ve});default:return null}},[R,E,Z,ee,se,x,K,de,$,ae,z,Ve,D,_]),ht=U.useMemo(()=>c.jsx(Ey,{activeTab:R,setActiveTab:y,specs:z}),[R,z]),el=U.useCallback(async()=>{if(!(!ae||je)){Qe(!0);try{await Ks(),ue(!1),F(null)}catch(T){console.error("Failed to stop server:",T),D({title:"Stop Server Failed",message:T.message||String(T),danger:!0})}finally{Qe(!1)}}},[ae,je,D]),Ie=[...Te?.stale?["Restart Local AI Image Generator so the local server loads the latest API."]:[],...Te?.issues||[]],il=we.reduce((T,C)=>T+Number(C.sizeBytes||0),0),ol=!!(Te&&(Ie.length>0||we.length>0));return c.jsxs("div",{className:"app-container",children:[ht,c.jsxs("div",{className:"main-content",children:[c.jsx(Ay,{telemetry:H,serverRunning:ae,activeModel:se,onStopServer:el,isStoppingServer:je,theme:Y,setTheme:G}),ol&&c.jsxs("div",{className:`m3-card readiness-card ${Te?.stale||Ie.length>0?"readiness-card-warning":""}`,children:[c.jsxs("div",{className:"readiness-header",children:[c.jsxs("div",{children:[c.jsx("h3",{className:"m3-card-title",style:{marginBottom:"4px"},children:Te?.stale?"Restart Required":Ie.length>0?"System Readiness":"Safe Cleanup Available"}),c.jsx("p",{className:"m3-card-subtitle",style:{margin:0},children:Te?.stale?`Running server build: ${Te.build||"unknown"}`:Ie.length>0?"Local AI Image Generator found setup items that may need attention.":`${we.length} temporary item${we.length===1?"":"s"} can be cleaned (${ni(il)}).`})]}),c.jsxs("div",{className:"readiness-actions",children:[c.jsx("button",{className:"m3-btn m3-btn-outlined",onClick:qe,disabled:Je,children:Je?"Checking":"Refresh"}),c.jsx("button",{className:"m3-btn m3-btn-tonal",onClick:Ee,children:nt?"Copied":"Copy Diagnostics"}),we.length>0&&c.jsxs("button",{className:"m3-btn m3-btn-error",onClick:Ut,disabled:Je,children:["Clean ",ni(il)]})]})]}),Ie.length>0&&c.jsx("div",{className:"readiness-issues",children:Ie.slice(0,4).map(T=>c.jsx("span",{children:T},T))}),we.length>0&&c.jsx("div",{className:"readiness-cleanup-list",children:we.slice(0,3).map(T=>c.jsxs("span",{title:T.path,children:[T.name," · ",T.size," · ",T.reason]},T.id))})]}),xt]}),b&&c.jsx("div",{className:"app-dialog-backdrop",role:"presentation",children:c.jsxs("div",{className:"app-dialog",role:"dialog","aria-modal":"true","aria-labelledby":"app-dialog-title",children:[c.jsx("h3",{id:"app-dialog-title",className:"app-dialog-title",children:b.title}),c.jsx("p",{className:"app-dialog-message",children:b.message}),c.jsxs("div",{className:"app-dialog-actions",children:[b.type==="confirm"&&c.jsx("button",{className:"m3-btn m3-btn-outlined",onClick:()=>r(!1),children:b.cancelLabel}),c.jsx("button",{className:`m3-btn ${b.danger?"m3-btn-error":"m3-btn-fLine truncated
|
||||
Vendored
+121
@@ -0,0 +1,121 @@
|
||||
(function(){const S=document.createElement("link").relList;if(S&&S.supports&&S.supports("modulepreload"))return;for(const z of document.querySelectorAll('link[rel="modulepreload"]'))r(z);new MutationObserver(z=>{for(const A of z)if(A.type==="childList")for(const L of A.addedNodes)L.tagName==="LINK"&&L.rel==="modulepreload"&&r(L)}).observe(document,{childList:!0,subtree:!0});function N(z){const A={};return z.integrity&&(A.integrity=z.integrity),z.referrerPolicy&&(A.referrerPolicy=z.referrerPolicy),z.crossOrigin==="use-credentials"?A.credentials="include":z.crossOrigin==="anonymous"?A.credentials="omit":A.credentials="same-origin",A}function r(z){if(z.ep)return;z.ep=!0;const A=N(z);fetch(z.href,A)}})();function cm(f){return f&&f.__esModule&&Object.prototype.hasOwnProperty.call(f,"default")?f.default:f}var Os={exports:{}},ei={};var kd;function z0(){if(kd)return ei;kd=1;var f=Symbol.for("react.transitional.element"),S=Symbol.for("react.fragment");function N(r,z,A){var L=null;if(A!==void 0&&(L=""+A),z.key!==void 0&&(L=""+z.key),"key"in z){A={};for(var H in z)H!=="key"&&(A[H]=z[H])}else A=z;return z=A.ref,{$$typeof:f,type:r,key:L,ref:z!==void 0?z:null,props:A}}return ei.Fragment=S,ei.jsx=N,ei.jsxs=N,ei}var Zd;function T0(){return Zd||(Zd=1,Os.exports=z0()),Os.exports}var c=T0(),Us={exports:{}},ie={};var Vd;function M0(){if(Vd)return ie;Vd=1;var f=Symbol.for("react.transitional.element"),S=Symbol.for("react.portal"),N=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),z=Symbol.for("react.profiler"),A=Symbol.for("react.consumer"),L=Symbol.for("react.context"),H=Symbol.for("react.forward_ref"),B=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),E=Symbol.for("react.lazy"),O=Symbol.for("react.activity"),Z=Symbol.iterator;function ee(d){return d===null||typeof d!="object"?null:(d=Z&&d[Z]||d["@@iterator"],typeof d=="function"?d:null)}var q={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},W=Object.assign,ne={};function F(d,_,w){this.props=d,this.context=_,this.refs=ne,this.updater=w||q}F.prototype.isReactComponent={},F.prototype.setState=function(d,_){if(typeof d!="object"&&typeof d!="function"&&d!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,d,_,"setState")},F.prototype.forceUpdate=function(d){this.updater.enqueueForceUpdate(this,d,"forceUpdate")};function Oe(){}Oe.prototype=F.prototype;function ye(d,_,w){this.props=d,this.context=_,this.refs=ne,this.updater=w||q}var Le=ye.prototype=new Oe;Le.constructor=ye,W(Le,F.prototype),Le.isPureReactComponent=!0;var ke=Array.isArray;function Me(){}var te={H:null,A:null,T:null,S:null},de=Object.prototype.hasOwnProperty;function et(d,_,w){var G=w.ref;return{$$typeof:f,type:d,key:_,ref:G!==void 0?G:null,props:w}}function jt(d,_){return et(d.type,_,d.props)}function pe(d){return typeof d=="object"&&d!==null&&d.$$typeof===f}function Ke(d){var _={"=":"=0",":":"=2"};return"$"+d.replace(/[=:]/g,function(w){return _[w]})}var ut=/\/+/g;function Je(d,_){return typeof d=="object"&&d!==null&&d.key!=null?Ke(""+d.key):_.toString(36)}function Ye(d){switch(d.status){case"fulfilled":return d.value;case"rejected":throw d.reason;default:switch(typeof d.status=="string"?d.then(Me,Me):(d.status="pending",d.then(function(_){d.status==="pending"&&(d.status="fulfilled",d.value=_)},function(_){d.status==="pending"&&(d.status="rejected",d.reason=_)})),d.status){case"fulfilled":return d.value;case"rejected":throw d.reason}}throw d}function x(d,_,w,G,J){var le=typeof d;(le==="undefined"||le==="boolean")&&(d=null);var re=!1;if(d===null)re=!0;else switch(le){case"bigint":case"string":case"number":re=!0;break;case"object":switch(d.$$typeof){case f:case S:re=!0;break;case E:return re=d._init,x(re(d._payload),_,w,G,J)}}if(re)return J=J(d),re=G===""?"."+Je(d,0):G,ke(J)?(w="",re!=null&&(w=re.replace(ut,"$&/")+"/"),x(J,_,w,"",function(ct){return ct})):J!=null&&(pe(J)&&(J=jt(J,w+(J.key==null||d&&d.key===J.key?"":(""+J.key).replace(ut,"$&/")+"/")+re)),_.push(J)),1;re=0;var Ze=G===""?".":G+":";if(ke(d))for(var Ee=0;Ee<d.length;Ee++)G=d[Ee],le=Ze+Je(G,Ee),re+=x(G,_,w,le,J);else if(Ee=ee(d),typeof Ee=="function")for(d=Ee.call(d),Ee=0;!(G=d.next()).done;)G=G.value,le=Ze+Je(G,Ee++),re+=x(G,_,w,le,J);else if(le==="object"){if(typeof d.then=="function")return x(Ye(d),_,w,G,J);throw _=String(d),Error("Objects are not valid as a React child (found: "+(_==="[object Object]"?"object with keys {"+Object.keys(d).join(", ")+"}":_)+"). If you meant to render a collection of children, use an array instead.")}return re}function C(d,_,w){if(d==null)return d;var G=[],J=0;return x(d,G,"","",function(le){return _.call(w,le,J++)}),G}function K(d){if(d._status===-1){var _=d._result;_=_(),_.then(function(w){(d._status===0||d._status===-1)&&(d._status=1,d._result=w)},function(w){(d._status===0||d._status===-1)&&(d._status=2,d._result=w)})Line truncated
|
||||
at`)?" (<anonymous>)":-1<l.stack.indexOf("@")?"@unknown:0:0":""}return`
|
||||
`+ht+e+cl}var k=!1;function ce(e,t){if(!e||k)return"";k=!0;var l=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var a={DetermineComponentFrameRoot:function(){try{if(t){var M=function(){throw Error()};if(Object.defineProperty(M.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(M,[])}catch(b){var v=b}Reflect.construct(e,[],M)}else{try{M.call()}catch(b){v=b}e.call(M.prototype)}}else{try{throw Error()}catch(b){v=b}(M=e())&&typeof M.catch=="function"&&M.catch(function(){})}}catch(b){if(b&&v&&typeof b.stack=="string")return[b.stack,v.stack]}return[null,null]}};a.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var n=Object.getOwnPropertyDescriptor(a.DetermineComponentFrameRoot,"name");n&&n.configurable&&Object.defineProperty(a.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var i=a.DetermineComponentFrameRoot(),u=i[0],s=i[1];if(u&&s){var o=u.split(`
|
||||
`),g=s.split(`
|
||||
`);for(n=a=0;a<o.length&&!o[a].includes("DetermineComponentFrameRoot");)a++;for(;n<g.length&&!g[n].includes("DetermineComponentFrameRoot");)n++;if(a===o.length||n===g.length)for(a=o.length-1,n=g.length-1;1<=a&&0<=n&&o[a]!==g[n];)n--;for(;1<=a&&0<=n;a--,n--)if(o[a]!==g[n]){if(a!==1||n!==1)do if(a--,n--,0>n||o[a]!==g[n]){var j=`
|
||||
`+o[a].replace(" at new "," at ");return e.displayName&&j.includes("<anonymous>")&&(j=j.replace("<anonymous>",e.displayName)),j}while(1<=a&&0<=n);break}}}finally{k=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?Ut(l):""}function D(e,t){switch(e.tag){case 26:case 27:case 5:return Ut(e.type);case 16:return Ut("Lazy");case 13:return e.child!==t&&t!==null?Ut("Suspense Fallback"):Ut("Suspense");case 19:return Ut("SuspenseList");case 0:case 15:return ce(e.type,!1);case 11:return ce(e.type.render,!1);case 1:return ce(e.type,!0);case 31:return Ut("Activity");default:return""}}function R(e){try{var t="",l=null;do t+=D(e,l),l=e,e=e.return;while(e);return t}catch(a){return`
|
||||
Error generating stack: `+a.message+`
|
||||
`+a.stack}}var I=Object.prototype.hasOwnProperty,V=f.unstable_scheduleCallback,bt=f.unstable_cancelCallback,ea=f.unstable_shouldYield,It=f.unstable_requestPaint,_e=f.unstable_now,Y=f.unstable_getCurrentPriorityLevel,Ne=f.unstable_ImmediatePriority,Ve=f.unstable_UserBlockingPriority,tt=f.unstable_NormalPriority,zt=f.unstable_LowPriority,ll=f.unstable_IdlePriority,xa=f.log,_a=f.unstable_setDisableYieldValue,Fe=null,ae=null;function se(e){if(typeof xa=="function"&&_a(e),ae&&typeof ae.setStrictMode=="function")try{ae.setStrictMode(Fe,e)}catch{}}var ve=Math.clz32?Math.clz32:He,Ae=Math.log,st=Math.LN2;function He(e){return e>>>=0,e===0?32:31-(Ae(e)/st|0)|0}var rt=256,xt=262144,wt=4194304;function sl(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function ii(e,t,l){var a=e.pendingLanes;if(a===0)return 0;var n=0,i=e.suspendedLanes,u=e.pingedLanes;e=e.warmLanes;var s=a&134217727;return s!==0?(a=s&~i,a!==0?n=sl(a):(u&=s,u!==0?n=sl(u):l||(l=s&~e,l!==0&&(n=sl(l))))):(s=a&~i,s!==0?n=sl(s):u!==0?n=sl(u):l||(l=a&~e,l!==0&&(n=sl(l)))),n===0?0:t!==0&&t!==n&&(t&i)===0&&(i=n&-n,l=t&-t,i>=l||i===32&&(l&4194048)!==0)?t:n}function fn(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function rm(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Vs(){var e=wt;return wt<<=1,(wt&62914560)===0&&(wt=4194304),e}function bu(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function on(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function dm(e,t,l,a,n,i){var u=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var s=e.entanglements,o=e.expirationTimes,g=e.hiddenUpdates;for(l=u&~l;0<l;){var j=31-ve(l),M=1<<j;s[j]=0,o[j]=-1;var v=g[j];if(v!==null)for(g[j]=null,j=0;j<v.length;j++){var b=v[j];b!==null&&(b.lane&=-536870913)}l&=~M}a!==0&&Ks(e,a,0),i!==0&&n===0&&e.tag!==0&&(e.suspendedLanes|=i&~(u&~t))}function Ks(e,t,l){e.pendingLanes|=t,e.suspendedLanes&=~t;var a=31-ve(t);e.entangledLanes|=t,e.entanglements[a]=e.entanglements[a]|1073741824|l&261930}function Js(e,t){var l=e.entangledLanes|=t;for(e=e.entanglements;l;){var a=31-ve(l),n=1<<a;n&t|e[a]&t&&(e[a]|=t),l&=~n}}function $s(e,t){var l=t&-t;return l=(l&42)!==0?1:xu(l),(l&(e.suspendedLanes|t))!==0?0:l}function xu(e){switch(e){case 2:e=1;break;case 8:e=4;break;case 32:e=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:e=128;break;case 268435456:e=134217728;break;default:e=0}return e}function _u(e){return e&=-e,2<e?8<e?(e&134217727)!==0?32:268435456:8:2}function Ws(){var e=C.p;return e!==0?e:(e=window.event,e===void 0?32:Hd(e.type))}function Fs(e,t){var l=C.p;try{return C.p=e,t()}finally{C.p=l}}var El=Math.random().toString(36).slice(2),yt="__reactFiber$"+El,Mt="__reactProps$"+El,ja="__reactContainer$"+El,ju="__reactEvents$"+El,mm="__reactListeners$"+El,hm="__reactHandles$"+El,Is="__reactResources$"+El,rn="__reactMarker$"+El;function zu(e){delete e[yt],delete e[Mt],delete e[ju],delete e[mm],delete e[hm]}function za(e){var t=e[yt];if(t)return t;for(var l=e.parentNode;l;){if(t=l[ja]||l[yt]){if(l=t.alternate,t.child!==null||l!==null&&l.child!==null)for(e=xd(e);e!==null;){if(l=e[yt])return l;e=xd(e)}return t}e=l,l=e.parentNode}return null}function Ta(e){if(e=e[yt]||e[ja]){var t=e.tag;if(t===5||t===6||t===13||t===31||t===26||t===27||t===3)return e}return null}function dn(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e.stateNode;throw Error(r(33))}function Ma(e){var t=e[Is];return t||(t=e[Is]={hoistableStyles:new Map,hoistableScripts:new Map}),t}function dt(e){e[rn]=!0}var Ps=new Set,ef={};function ta(e,t){Ea(e,t),Ea(e+"Capture",t)}function Ea(e,t){for(ef[e]=t,e=0;e<t.length;e++)Ps.add(t[e])}var ym=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\
Line truncated
|
||||
`).replace(Vh,"")}function rd(e,t){return t=od(t),od(e)===t}function we(e,t,l,a,n,i){switch(l){case"children":typeof a=="string"?t==="body"||t==="textarea"&&a===""||Aa(e,a):(typeof a=="number"||typeof a=="bigint")&&t!=="body"&&Aa(e,""+a);break;case"className":ci(e,"class",a);break;case"tabIndex":ci(e,"tabindex",a);break;case"dir":case"role":case"viewBox":case"width":case"height":ci(e,l,a);break;case"style":of(e,a,i);break;case"data":if(t!=="object"){ci(e,"data",a);break}case"src":case"href":if(a===""&&(t!=="a"||l!=="href")){e.removeAttribute(l);break}if(a==null||typeof a=="function"||typeof a=="symbol"||typeof a=="boolean"){e.removeAttribute(l);break}a=fi(""+a),e.setAttribute(l,a);break;case"action":case"formAction":if(typeof a=="function"){e.setAttribute(l,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof i=="function"&&(l==="formAction"?(t!=="input"&&we(e,t,"name",n.name,n,null),we(e,t,"formEncType",n.formEncType,n,null),we(e,t,"formMethod",n.formMethod,n,null),we(e,t,"formTarget",n.formTarget,n,null)):(we(e,t,"encType",n.encType,n,null),we(e,t,"method",n.method,n,null),we(e,t,"target",n.target,n,null)));if(a==null||typeof a=="symbol"||typeof a=="boolean"){e.removeAttribute(l);break}a=fi(""+a),e.setAttribute(l,a);break;case"onClick":a!=null&&(e.onclick=ol);break;case"onScroll":a!=null&&he("scroll",e);break;case"onScrollEnd":a!=null&&he("scrollend",e);break;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(r(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(r(60));e.innerHTML=l}}break;case"multiple":e.multiple=a&&typeof a!="function"&&typeof a!="symbol";break;case"muted":e.muted=a&&typeof a!="function"&&typeof a!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(a==null||typeof a=="function"||typeof a=="boolean"||typeof a=="symbol"){e.removeAttribute("xlink:href");break}l=fi(""+a),e.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",l);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":a!=null&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,""+a):e.removeAttribute(l);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":a&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,""):e.removeAttribute(l);break;case"capture":case"download":a===!0?e.setAttribute(l,""):a!==!1&&a!=null&&typeof a!="function"&&typeof a!="symbol"?e.setAttribute(l,a):e.removeAttribute(l);break;case"cols":case"rows":case"size":case"span":a!=null&&typeof a!="function"&&typeof a!="symbol"&&!isNaN(a)&&1<=a?e.setAttribute(l,a):e.removeAttribute(l);break;case"rowSpan":case"start":a==null||typeof a=="function"||typeof a=="symbol"||isNaN(a)?e.removeAttribute(l):e.setAttribute(l,a);break;case"popover":he("beforetoggle",e),he("toggle",e),ui(e,"popover",a);break;case"xlinkActuate":fl(e,"http://www.w3.org/1999/xlink","xlink:actuate",a);break;case"xlinkArcrole":fl(e,"http://www.w3.org/1999/xlink","xlink:arcrole",a);break;case"xlinkRole":fl(e,"http://www.w3.org/1999/xlink","xlink:role",a);break;case"xlinkShow":fl(e,"http://www.w3.org/1999/xlink","xlink:show",a);break;case"xlinkTitle":fl(e,"http://www.w3.org/1999/xlink","xlink:title",a);break;case"xlinkType":fl(e,"http://www.w3.org/1999/xlink","xlink:type",a);break;case"xmlBase":fl(e,"http://www.w3.org/XML/1998/namespace","xml:base",a);break;case"xmlLang":fl(e,"http://www.w3.org/XML/1998/namespace","xml:lang",a);break;case"xmlSpace":fl(e,"http://www.w3.org/XML/1998/namespace","xml:space",a);break;case"is":ui(e,"is",a);break;case"innerText":case"textContent":break;default:(!(2<l.length)||l[0]!=="o"&&l[0]!=="O"||l[1]!=="n"&&l[1]!=="N")&&(l=bm.get(l)||l,ui(e,l,a))}}function hs(e,t,l,a,n,i){switch(l){case"style":of(e,a,i);break;case"dangerouslySetInnerHTML":if(a!=null){if(typeof a!="object"||!("__html"in a))throw Error(r(61));if(l=a.__html,l!=null){if(n.children!=null)throw Error(r(60));e.innerHTML=l}}break;case"children":typeof a=="string"?Aa(e,a):(typeof a=="number"||typeof a=="bigint")&&Aa(e,""+a);break;case"onScroll":a!=null&&he("scroll",e);break;case"onScrollEnd":a!=null&&he("scrollend",e);break;case"onClick":a!=null&&(e.onclick=ol);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"inne
Line truncated
|
||||
<!-- Stars -->
|
||||
<circle cx="80" cy="100" r="1.5" fill="#ffffff" opacity="0.6"/>
|
||||
<circle cx="160" cy="60" r="1" fill="#ffffff" opacity="0.5"/>
|
||||
<circle cx="280" cy="120" r="2" fill="#ffffff" opacity="0.8"/>
|
||||
<circle cx="360" cy="80" r="1.5" fill="#ffffff" opacity="0.4"/>
|
||||
<circle cx="440" cy="150" r="1" fill="#ffffff" opacity="0.7"/>
|
||||
<circle cx="400" cy="280" r="2" fill="#ffffff" opacity="0.9"/>
|
||||
<circle cx="100" cy="300" r="1.5" fill="#ffffff" opacity="0.5"/>
|
||||
<!-- Moon -->
|
||||
<circle cx="256" cy="220" r="90" fill="url(#moonGrad)" />
|
||||
<circle cx="226" cy="190" r="80" fill="#0F172A" />
|
||||
`):q.includes("cat")||q.includes("kitten")||q.includes("feline")?(ne="#4F46E5",F="#7C3AED",ye="Stylized Cat Portrait",Oe=`
|
||||
<!-- Cat head & ears -->
|
||||
<polygon points="176,280 146,160 216,210" fill="#312E81" />
|
||||
<polygon points="336,280 366,160 296,210" fill="#312E81" />
|
||||
<circle cx="256" cy="270" r="80" fill="#4338CA" />
|
||||
<!-- Eyes -->
|
||||
<ellipse cx="226" cy="260" rx="14" ry="8" fill="#10B981" />
|
||||
<ellipse cx="286" cy="260" rx="14" ry="8" fill="#10B981" />
|
||||
<circle cx="226" cy="260" r="4" fill="#000" />
|
||||
<circle cx="286" cy="260" r="4" fill="#000" />
|
||||
<!-- Nose & Whiskers -->
|
||||
<polygon points="256,285 248,275 264,275" fill="#F43F5E" />
|
||||
<line x1="226" y1="290" x2="166" y2="280" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="226" y1="295" x2="156" y2="295" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="286" y1="290" x2="346" y2="280" stroke="#E2E8F0" stroke-width="2" />
|
||||
<line x1="286" y1="295" x2="356" y2="295" stroke="#E2E8F0" stroke-width="2" />
|
||||
`):q.includes("dog")||q.includes("puppy")||q.includes("canine")?(ne="#D97706",F="#B45309",ye="Friendly Dog Portrait",Oe=`
|
||||
<!-- Dog head & floppy ears -->
|
||||
<ellipse cx="166" cy="260" rx="20" ry="60" fill="#78350F" />
|
||||
<ellipse cx="346" cy="260" rx="20" ry="60" fill="#78350F" />
|
||||
<circle cx="256" cy="250" r="70" fill="#92400E" />
|
||||
<ellipse cx="256" cy="280" rx="40" ry="30" fill="#D97706" />
|
||||
<!-- Eyes -->
|
||||
<circle cx="226" cy="230" r="10" fill="#1E293B" />
|
||||
<circle cx="286" cy="230" r="10" fill="#1E293B" />
|
||||
<circle cx="222" cy="226" r="3" fill="#ffffff" />
|
||||
<circle cx="282" cy="226" r="3" fill="#ffffff" />
|
||||
<!-- Nose -->
|
||||
<ellipse cx="256" cy="275" rx="16" ry="10" fill="#1E293B" />
|
||||
`):q.includes("city")||q.includes("cyberpunk")||q.includes("tokyo")||q.includes("neon")?(ne="#111827",F="#311042",ye="Neon Cyberpunk Skyline",Oe=`
|
||||
<!-- Skyline -->
|
||||
<rect x="60" y="160" width="80" height="352" fill="#1F2937" opacity="0.9"/>
|
||||
<rect x="180" y="100" width="100" height="412" fill="#111827" />
|
||||
<rect x="320" y="200" width="120" height="312" fill="#1F2937" opacity="0.85"/>
|
||||
<rect x="100" y="240" width="110" height="272" fill="#374151" opacity="0.6"/>
|
||||
<!-- Neon details -->
|
||||
<line x1="230" y1="100" x2="230" y2="40" stroke="#EC4899" stroke-width="3" />
|
||||
<rect x="200" y="140" width="60" height="15" fill="#10B981" opacity="0.7"/>
|
||||
<rect x="200" y="170" width="60" height="15" fill="#10B981" opacity="0.7"/>
|
||||
<rect x="200" y="200" width="60" height="15" fill="#3B82F6" opacity="0.7"/>
|
||||
<rect x="70" y="200" width="15" height="100" fill="#F59E0B" opacity="0.5"/>
|
||||
<rect x="340" y="250" width="20" height="150" fill="#EF4444" opacity="0.6"/>
|
||||
`):q.includes("car")||q.includes("vehicle")||q.includes("supercar")?(ne="#DC2626",F="#991B1B",ye="Futuristic Concept Car",Oe=`
|
||||
<!-- Road / Perspective grid -->
|
||||
<line x1="256" y1="350" x2="0" y2="512" stroke="#4B5563" stroke-width="3" />
|
||||
<line x1="256" y1="350" x2="512" y2="512" stroke="#4B5563" stroke-width="3" />
|
||||
<!-- Car body -->
|
||||
<polygon points="126,380 256,330 386,380 346,440 166,440" fill="#EF4444" />
|
||||
<polygon points="176,370 256,340 336,370 326,390 186,390" fill="#1E293B" opacity="0.9" />
|
||||
<!-- Headlights -->
|
||||
<polygon points="136,410 176,415 166,425 136,420" fill="#FBBF24" />
|
||||
<polygon points="376,410 336,415 346,425 376,420" fill="#FBBF24" />
|
||||
<!-- Wheels -->
|
||||
<ellipse cx="156" cy="440" rx="30" ry="15" fill="#111" />
|
||||
<ellipse cx="356" cy="440" rx="30" ry="15" fill="#111" />
|
||||
`):(ne="#06B6D4",F="#0891B2",ye="Abstract Creative Concept",Oe=`
|
||||
<path d="M0,256 C150,150 350,350 512,256 L512,512 L0,512 Z" fill="#0891B2" opacity="0.4" />
|
||||
<path d="M0,350 C200,200 300,450 512,350 L512,512 L0,512 Z" fill="#0E7490" opacity="0.6" />
|
||||
<circle cx="380" cy="180" r="50" fill="#F59E0B" opacity="0.8" />
|
||||
`);const Le=`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="${ne}" />
|
||||
<stop offset="100%" stop-color="${F}" />
|
||||
</linearGradient>
|
||||
<linearGradient id="moonGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#FEF08A" />
|
||||
<stop offset="100%" stop-color="#FDE047" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="512" height="512" fill="url(#bgGrad)" />
|
||||
|
||||
<!-- Shapes -->
|
||||
${Oe}
|
||||
|
||||
<!-- Premium UI Overlay Frame -->
|
||||
<rect x="20" y="20" width="472" height="472" fill="none" stroke="#ffffff" stroke-width="1.5" opacity="0.15" rx="8"/>
|
||||
|
||||
<!-- Prompt & Details text -->
|
||||
<rect x="40" y="410" width="432" height="62" fill="#0F172A" opacity="0.85" rx="6" />
|
||||
<text x="60" y="435" fill="#F1F5F9" font-family="system-ui, -apple-system, sans-serif" font-size="13" font-weight="bold">${ye}</text>
|
||||
<text x="60" y="455" fill="#94A3B8" font-family="system-ui, -apple-system, sans-serif" font-size="11">Seed: ${W} • Steps: ${E.steps} • Scale: ${E.cfg_scale}</text>
|
||||
</svg>
|
||||
`,Me=`data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(Le)))}`,te=parseFloat(((Date.now()-H)/1e3).toFixed(1));return{image:Me,seed:E.seed,duration_sec:te}},Z={prompt:E.prompt,negative_prompt:E.negative_prompt||"",n:1,size:`${E.width}x${E.height}`,response_format:"b64_json",steps:E.steps,cfg_scale:E.cfg_scale,seed:E.seed,sample_method:E.sampler};try{const ee=await fetch(`${y}/v1/images/generations`,{method:"POST",headers:{"Content-Type":"application/json"},signal:L,body:JSON.stringify(Z)});if(ee.ok){const q=await ee.json(),W=q?.data?.[0]?.b64_json??q?.images?.[0];if(W){const ne=parseFloat(((Date.now()-H)/1e3).toFixed(1));return{image:`data:image/png;base64,${W}`,seed:q.data?.[0]?.seed??E.seed,duration_sec:ne}}}else{let q=`Generation failed (HTTP ${ee.status})`;try{const W=await ee.json();(W?.detail||W?.error?.message)&&(q=W.detail||W.error.message)}catch{}throw new Error(q)}}catch(ee){if(ee.name==="AbortError"||ee.message.startsWith("Generation failed"))throw ee;console.warn("Could not reach local server. Falling back to simulation mode.",ee)}return await O()}async function Zy(f,S,N){if(f instanceof File){const H=f;if(!Sa())throw new Error("File import requires the local image generator server.");return await Vy(H,S,N),{response:"Model imported successfully"}}if(Pl()){const{listen:H}=await Dy(async()=>{const{listen:y}=await import("./event-DUWu82QQ.js");return{listen:y}},[]);let B=null;S&&(B=await H("import-progress",y=>{S(y.payload)}));try{return{response:await ba("import_model_file",{sourcePath:f}),unlisten:B}}catch(y){throw B&&B(),y}}const r=f.split(/[\\/]/).pop()||"imported_model.gguf";console.log(`Web Mode: Simulating copying ${r} to USB models folder`);const z=40;for(let H=1;H<=z;H++){if(N?.aborted)throw new DOMException("The user aborted a request.","AbortError");await new Promise(O=>setTimeout(O,150));const B=H/z*100,y=40+Math.sin(H)*5+Math.random()*2,E=(z-H)*.15;S&&S({filename:r,progress:B,speed_mb_s:y,eta_secs:E,status:"Copying to USB..."})}const A=localStorage.getItem("imported-models"),L=A?JSON.parse(A):[];return L.includes(r)||(L.push({filename:r,sizeBytes:0,size:"Unknown"}),localStorage.setItem("imported-models",JSON.stringify(L))),{response:"Model imported successfully"}}function Vy(f,S,N){return new Promise((r,z)=>{const A=new XMLHttpRequest,L=Date.now();let H=!1;A.open("POST",`/api/import-model?filename=${encodeURIComponent(f.name)}`),A.setRequestHeader("Content-Type","application/octet-stream");const B=()=>{H=!0,A.abort()};N&&(N.aborted?B():N.addEventListener("abort",B,{once:!0})),A.upload.onprogress=y=>{if(!y.lengthComputable||!S)return;const E=Math.max(.1,(Date.now()-L)/1e3),O=y.loaded/E,Z=Math.max(0,y.total-y.loaded);S({filename:f.name,progress:y.loaded/y.total*100,speed_mb_s:O/(1024*1024),eta_secs:Z/Math.max(1,O),status:"Copying to models folder..."})},A.onload=()=>{let y={};try{y=JSON.parse(A.responseText||"{}")}catch{}A.status>=200&&A.status<300&&y.ok!==!1?(S&&S({filename:f.name,progress:100,speed_mb_s:0,eta_secs:0,status:"Import complete"}),r(y)):z(new Error(y.error||`Import failed (HTTP ${A.status})`))},A.onerror=()=>z(new Error("Import failed while uploading the file.")),A.onabort=()=>z(new DOMException(H?"Import cancelled by user.":"Import aborted.","AbortError")),A.send(f)})}async function Ky(f){if(Pl())return await ba("delete_model_file",{filename:f});if(typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"))try{const z=await fetch("/api/delete-model",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filename:f})}),A=await z.json();if(!z.ok)throw new Error(A.error||"Failed to delete model file");return A}catch(z){throw console.error("Failed to delete model via local API:",z),z}const N=localStorage.getItem("imported-models");let r=N?JSON.parse(N):[];return r=r.filter(z=>ni(z).filename!==f),localStorage.setItem("imported-models",JSON.stringify(r)),`Simulated deletion of ${f} from browser session`}async function om(){const S="http://127.0.0.1:8080";try{return(await fetch(`${S}/v1/models`,{method:"GET"})).ok}catch{return!1}}async function Jy(f=30){const S=Pl()||Sa()?f:3;for(let N=0;N<S;N++){let r=!1;if(Sa()?r=!!(await va()).ready:r=await om(),r)return!0;await new Promise(z=>setTimeout(z,500))}return!1}async function $y(f){try{return await(await fetch("/api/download-model",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:f})})).json()}catch(S){return console.error("Failed to start model download:",S),{ok:!1,error:S.message}}}async function Wy(){try{return await(await fetch("/api/cancel-download",{method:"POST"})).json()}catch(f){return console.error("Failed to cancel model download:",f),{ok:!1,error:f.message}}}async function im(){try{return await(await fetch("/api/download-progress")).json()}catch(f){return console.error("Failed to get download progress:",f),{active:!1,error:f.message}}}async function Fy(){try{return await(await fetch("/api/generation-progre
Line truncated
|
||||
Seed: ${f.seed}${f.duration_sec?`
|
||||
Time: ${f.duration_sec.toFixed(1)}s`:""}`,children:[c.jsx("img",{src:f.url,className:"gallery-thumb",alt:"Thumbnail",loading:"lazy",decoding:"async"}),N&&c.jsx("div",{className:"gallery-select-badge",children:c.jsx(qs,{size:14})})]})});function Py({prompt:f,setPrompt:S,negativePrompt:N,setNegativePrompt:r,constraints:z,setConstraints:A,activeModel:L,generatedImages:H,setGeneratedImages:B,isGenerating:y,setIsGenerating:E,generationProgress:O,setGenerationProgress:Z,setActiveTab:ee,showAlert:q=async({message:ne})=>window.alert(ne),showConfirm:W=async({message:ne})=>window.confirm(ne)}){const[ne,F]=U.useState(null),[Oe,ye]=U.useState(null),[Le,ke]=U.useState(null),[Me,te]=U.useState(!1),[de,et]=U.useState(0),[jt,pe]=U.useState(0),[Ke,ut]=U.useState(0),[Je,Ye]=U.useState(""),[x,C]=U.useState(!1),[K,ge]=U.useState(!1),[oe,d]=U.useState(!1),[_,w]=U.useState(null),[G,J]=U.useState(null),[le,re]=U.useState(!1),[Ze,Ee]=U.useState([]),ct=U.useRef(null),ot=U.useRef(null),ht=U.useRef(!1),cl=async()=>{if(!f.trim())return;J(null),d(!0),w(null);let Y=!1;try{const ae=await va();if(ae&&ae.settings){const se=ae.settings,ve=se.model?se.model.split(/[\\/]/).pop():null,Ae=L?L.split(/[\\/]/).pop():null;(ve!==Ae||parseInt(se.steps)!==parseInt(z.steps)||Math.abs(parseFloat(se.cfgScale)-parseFloat(z.cfgScale))>.05||se.sampler!==z.sampler||parseInt(se.threads)!==parseInt(z.threads)||!!se.useGpu!=(z.useGpu!==!1)||(se.backendType||(se.useGpu===!1?"cpu":"auto"))!==(z.backendType||(z.useGpu===!1?"cpu":"auto")))&&(Y=!0)}else Y=!0}catch{Y=!0}if(Y)try{console.log("Settings out of sync, restarting backend..."),await Xs(L,z);let ae=!1,se=null;for(let ve=0;ve<240;ve++){const Ae=await va();if(Ae.loading&&w({progress:Ae.loading.progress||0,phase:Ae.loading.phase||"Loading model...",speed:Ae.loading.speed||"",current:Ae.loading.current||0,total:Ae.loading.total||0,backendMode:Ae.loading.backendMode||Ae.settings?.backendMode||"",device:Ae.loading.device||Ae.settings?.backendDevice||""}),Ae.ready){ae=!0;break}if(Ae.error){se=Ae.error;break}if(!Ae.running&&ve>3){se="The backend process terminated immediately on startup.";break}await new Promise(st=>setTimeout(st,500))}if(!ae)throw new Error(se||"Backend server failed to start after applying configuration changes.")}catch(ae){console.error("Failed to restart backend:",ae),J(ae.message||"Failed to sync settings with backend."),d(!1);return}d(!1),w(null),ct.current&&clearInterval(ct.current),E(!0),Z(0),et(0),ut(0),Ye(""),ht.current=!1,C(!1),re(!1),ke(null),F(null);const Ne=(z.width>=1024?140:35)*.04,Ve=z.width>=1024?140:35,tt=(z.backendType||(z.useGpu===!1?"cpu":"auto"))!=="cpu";let zt=tt?Ne:Ve,ll=!1,xa=0,_a=0,Fe=0;pe(Math.round(z.steps*zt)),ct.current=setInterval(async()=>{Fe++,et(Fe);try{const ae=await Fy();if(ae&&ae.active){const se=ae.decoding||!1;re(se);const ve=se?ae.steps||z.steps||20:ae.step||0,Ae=ae.steps||z.steps||20,st=se?"":ae.speed||"";(se||ae.steps>0)&&(ht.current=!0,ut(ve)),Ye(se?"decoding":st);let He=0;se?He=99:Ae>0&&(He=Math.round(ve/Ae*100)),He=Math.min(99,He),se||ae.steps>0?Z(He):Z(xt=>Math.max(xt,He));let rt=0;if(se)rt=3;else{const xt=parseFloat(st);if(!isNaN(xt)&&xt>0){const wt=Math.max(0,Ae-ve);st.includes("it/s")?rt=wt/xt:st.includes("s/it")&&(rt=wt*xt)}else{const wt=tt?Ne:Ve;rt=Math.max(0,(Ae-ve)*wt)}}if(tt&&!ll){const xt=st.includes("it/s")&&numericSpeed<.2,wt=st.includes("s/it")&&numericSpeed>5;(xt||wt)&&(ll=!0,C(!0))}pe(Math.round(rt))}else Z(se=>Math.min(15,se+1)),pe(se=>Math.max(1,se-1))}catch(ae){console.warn("Failed to get generation progress, running simulation fallback:",ae),tt&&!ll&&Fe>z.steps*Ne*1.3&&(ll=!0,C(!0),zt=Ve,xa=Fe,_a=Math.min(95,Math.round(Fe/(z.steps*Ne)*100)));let se=Math.min(z.steps-1,Math.floor(Fe/zt)),ve=z.steps*zt;if(Fe>=ve){const He=Math.ceil(Fe/Math.max(.5,se));zt=Math.max(zt+15,He+15),ve=z.steps*zt,se=Math.min(z.steps-1,Math.floor(Fe/zt))}const Ae=Math.max(1,ve-Fe);pe(Math.round(Ae));let st=0;if(ll){const He=99-_a,rt=ve-xa;if(rt>0){const xt=Math.min(1,(Fe-xa)/rt);if(xt<.85)st=Math.round(_a+xt*He);else{const wt=(Fe-(xa+rt*.85))/(zt*2),sl=1-Math.exp(-wt);st=Math.min(99,Math.round(_a+.85*He+.14*He*sl))}}else st=99}else if(Fe<ve*.85)st=Math.round(Fe/ve*100);else{const He=(Fe-ve*.85)/(zt*2),rt=1-Math.exp(-He);st=Math.min(99,Math.round(85+14*rt))}ht.current||Z(He=>Math.max(He,st))}},1e3);try{ot.current=new AbortController;const ae=await ky(f,N,z,L,null,He=>Z(rt=>Math.max(rt,He)),ot.current.signal);ct.current&&clearInterval(ct.current),Z(100),ut(z.steps),pe(0),Ye("");const se={prompt:f,negativePrompt:N,seed:ae.seed,steps:z.steps,cfgScale:z.cfgScale,width:z.width,height:z.height,sampler:z.sampler,model:L,duration_sec:ae.duration_sec,timestamp:new Date().toLocaleTimeString()};let ve=null,Ae=null;try{if(ve=await Yy(ae.image,se),Ae=ve.url,!Ae)throw new Error("The local server saved the image but did not return a file URL.")}catch(He){throw console.error("Generated image could not be saved:",He),new Error(`Image generated but could not be saved to USB: ${He.Line truncated
|
||||
|
||||
${bt}
|
||||
|
||||
Update the UI status anyway?`,confirmLabel:"Update UI"})&&(S(D),r(!0)):await L({title:"Backend Not Running",message:`C++ backend server is not running on port 8080.
|
||||
|
||||
To run locally, start:
|
||||
|
||||
${bt}
|
||||
|
||||
Proceed in Simulation Mode instead?`,confirmLabel:"Proceed"})&&(S(D),r(!1));return}ne(D),Oe({progress:0,phase:"Starting backend...",speed:"",current:0,total:0,model:D,backendMode:"",backendBinary:"",device:""});try{const V=await Xs(D,z);console.log(V);let bt=!1,ea=null;for(let It=0;It<240;It++){const _e=await va();if(_e.loading&&Oe({progress:_e.loading.progress||0,phase:_e.loading.phase||"Loading model...",speed:_e.loading.speed||"",current:_e.loading.current||0,total:_e.loading.total||0,model:_e.loading.model||D,backendMode:_e.loading.backendMode||_e.settings?.backendMode||"",backendBinary:_e.loading.backendBinary||_e.settings?.backendBinary||"",device:_e.loading.device||_e.settings?.backendDevice||""}),_e.ready){bt=!0;break}if(_e.error){ea=_e.error;break}if(!_e.running&&It>3){ea="The backend process terminated immediately on startup.";break}await new Promise(Y=>setTimeout(Y,500))}if(bt)Oe(It=>({...It||{},progress:100,phase:"Model ready",speed:"",current:It?.current||0,total:It?.total||0,model:D})),S(D),r(!0);else throw new Error(ea||"Model server failed to respond on port 8080.")}catch(V){console.error("Failed to load model:",V),A({title:"Model Load Failed",message:V.message||String(V),danger:!0})}finally{setTimeout(()=>Oe(null),800),ne(null)}},ct=async()=>{const D=Ye;x(null),await ot(),D&&await Ee(D)},ot=async()=>{if(pe)return;Ke(!0),Je({progress:10,phase:"Stopping backend process..."});const D=setInterval(async()=>{try{const R=await va();R.unloading?.active?Je({progress:R.unloading.progress||50,phase:R.unloading.phase||"Unloading model..."}):Je(I=>({progress:Math.min(95,I.progress+10),phase:I.phase||"Unloading model..."}))}catch{}},300);try{await Zs(),Je({progress:100,phase:"Model unloaded"}),S(null),x(null),r(!1)}catch(R){console.error(R),A({title:"Unload Failed",message:R.message||String(R),danger:!0})}finally{clearInterval(D),setTimeout(()=>{Ke(!1),Je({progress:0,phase:""})},500)}},ht=async D=>{if(await L({title:"Delete Model?",message:`Delete "${D}" from your drive?`,confirmLabel:"Delete",danger:!0}))try{await Ky(D),await w(),f===D&&await ot()}catch(R){console.error("Failed to delete model:",R),A({title:"Delete Failed",message:R.message||String(R),danger:!0})}},cl=async(D,R)=>{const I=new AbortController;jt(I),Le(0),Me({filename:R,speed:"0.0",eta:0,status:"Initiating file copy..."});try{await Zy(D,V=>{Le(Math.round(V.progress)),Me({filename:V.filename,speed:V.speed_mb_s.toFixed(1),eta:Math.round(V.eta_secs),status:V.status})},I.signal),await w()}catch(V){console.error("Import failed:",V),V.name!=="AbortError"&&A({title:"Import Failed",message:V.message||String(V),danger:!0})}finally{Le(null),jt(null)}},Ut=()=>{et&&et.abort()},k=D=>{const R=D.target.files[0];R&&cl(R,R.name),D.target.value=""},ce=!!y;return c.jsxs("div",{className:"workspace-area",children:[c.jsxs("div",{className:"workspace-title-section",children:[c.jsx("h2",{className:"workspace-title",children:"Model Manager"}),c.jsx("p",{className:"workspace-subtitle",children:"Manage local files and download recommended weights directly to your local models folder."})]}),f&&c.jsx("div",{className:"m3-card",style:{borderLeft:"4px solid var(--md-sys-color-primary)",background:"var(--md-sys-color-primary-container)",color:"var(--md-sys-color-on-primary-container)"},children:c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[c.jsxs("div",{children:[c.jsxs("h4",{style:{fontWeight:700},children:["Active Model: ",f]}),c.jsx("p",{style:{fontSize:"0.85rem",marginTop:"2px",opacity:.9},children:"The local C++ stable-diffusion server is running. Real-time telemetry is displaying performance status in the top bar."}),(C.backendMode||C.backendDevice||C.backendBinary)&&c.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"},children:[C.backendMode&&c.jsxs("span",{className:"status-chip",style:{cursor:"default"},children:[c.jsx(Su,{size:14}),c.jsxs("span",{children:["Loaded on ",C.backendMode]})]}),C.backendDevice&&c.jsx("span",{className:"status-chip",style:{cursor:"default"},children:c.jsx("span",{children:C.backendDevice})}),C.backendBinary&&c.jsx("span",{className:"status-chip",style:{cursor:"default"},children:c.jsx("span",{children:C.backendBinary})})]})]}),c.jsxs("button",{className:"m3-btn m3-btn-error",onClick:ot,disabled:pe||W!==null,children:[pe?c.jsx(Il,{className:"progress-spinner",size:16}):c.jsx(li,{size:16}),c.jsx("span",{children:pe?"Unloading":"Unload Server"})]})]})}),pe&&c.jsxs("div",{className:"m3-card",style:{borderLeft:"4px solid var(--md-sys-color-error)",marginTop:"16px"},children:[c.jsx("h4",{style:{fontWeight:700,marginBottom:"8px"},children:"Unloading Model"}),c.jsxs("div",{className:"model-progress-section",style:{margin:"8px 0 0 0"},children:[c.jsxs("div",{className:"model-progress-label",children:[c.jsx("span",{children:ut.phase||"Unloading model..."}),c.jsxs("span",{children:[Math.round(ut.progress),"%"]})]}),c.jsx("div",{className:"model-progress-bar",childr
Line truncated
|
||||
|
||||
Models and generated outputs are not included.`,confirmLabel:"Clean",danger:!0})){pe(!0);try{await By(de.map(D=>D.id)),await le()}catch(D){A({title:"Cleanup Failed",message:D.message||String(D),danger:!0})}finally{pe(!1)}}},[de,le,A,z]);U.useEffect(()=>{async function k(){const ce=await Ly();Ye(ce)}k()},[]),U.useEffect(()=>{q?localStorage.setItem("active-model",q):localStorage.removeItem("active-model")},[q]),U.useEffect(()=>{let k=null;async function ce(){const D=await va();if(!!D.ready){k&&clearInterval(k);const I=localStorage.getItem("active-model");if(I)W(I),F(!0);else{try{if(D&&D.settings&&D.settings.model){const V=D.settings.model.split(/[\\/]/).pop();W(V)}}catch{}F(!0)}}else if(!(typeof window<"u"&&window.__TAURI_INTERNALS__!==void 0)){const V=localStorage.getItem("active-model");V&&(W(V),F(!1))}}return ce(),k=setInterval(ce,2e3),()=>{k&&clearInterval(k)}},[]),U.useEffect(()=>{async function k(){try{const D=await Hy();w(R=>R.cpu_usage===D.cpu_usage&&R.ram_used_gb===D.ram_used_gb&&R.ram_total_gb===D.ram_total_gb&&R.gpu_name===D.gpu_name&&R.vram_used_gb===D.vram_used_gb&&R.vram_total_gb===D.vram_total_gb?R:D)}catch{}}k();const ce=setInterval(k,1500);return()=>clearInterval(ce)},[]),U.useEffect(()=>{if(q){const k=q.toLowerCase();k.includes("flux")||k.includes("schnell")?J(ce=>({...ce,steps:4,cfgScale:1,width:1024,height:1024})):k.includes("lightning")||k.includes("turbo")?J(ce=>({...ce,steps:4,cfgScale:1.5,width:1024,height:1024})):k.includes("sd15")?J(ce=>({...ce,steps:25,cfgScale:7,width:512,height:512})):k.includes("sd35")?J(ce=>({...ce,steps:20,cfgScale:4.5,width:1024,height:1024})):J(ce=>({...ce,steps:20,cfgScale:7,width:512,height:512}))}},[q]);const Ee=U.useMemo(()=>{switch(B){case"generator":return c.jsx(e1,{prompt:E,setPrompt:O,negativePrompt:Z,setNegativePrompt:ee,constraints:G,setConstraints:J,activeModel:q,generatedImages:Je,setGeneratedImages:Ye,isGenerating:x,setIsGenerating:C,generationProgress:K,setGenerationProgress:ge,setActiveTab:y,showAlert:A,showConfirm:z});case"models":return c.jsx(a1,{activeModel:q,setActiveModel:W,serverRunning:ne,setServerRunning:F,constraints:G,showAlert:A,showConfirm:z});case"constraints":return c.jsx(u1,{constraints:G,setConstraints:J,activeModel:q,specs:oe,backendOptions:Le});default:return null}},[B,E,Z,G,q,Je,x,K,ne,oe,Le,A,z]),ct=U.useMemo(()=>c.jsx(Ty,{activeTab:B,setActiveTab:y,specs:oe}),[B,oe]),ot=U.useCallback(async()=>{if(!(!ne||Oe)){ye(!0);try{await Zs(),F(!1),W(null)}catch(k){console.error("Failed to stop server:",k),A({title:"Stop Server Failed",message:k.message||String(k),danger:!0})}finally{ye(!1)}}},[ne,Oe,A]),ht=[...Me?.stale?["Restart Local AI Image Generator so the local server loads the latest API."]:[],...Me?.issues||[]],cl=de.reduce((k,ce)=>k+Number(ce.sizeBytes||0),0),Ut=!!(Me&&(ht.length>0||de.length>0));return c.jsxs("div",{className:"app-container",children:[ct,c.jsxs("div",{className:"main-content",children:[c.jsx(Ey,{telemetry:_,serverRunning:ne,activeModel:q,onStopServer:ot,isStoppingServer:Oe,theme:L,setTheme:H}),Ut&&c.jsxs("div",{className:`m3-card readiness-card ${Me?.stale||ht.length>0?"readiness-card-warning":""}`,children:[c.jsxs("div",{className:"readiness-header",children:[c.jsxs("div",{children:[c.jsx("h3",{className:"m3-card-title",style:{marginBottom:"4px"},children:Me?.stale?"Restart Required":ht.length>0?"System Readiness":"Safe Cleanup Available"}),c.jsx("p",{className:"m3-card-subtitle",style:{margin:0},children:Me?.stale?`Running server build: ${Me.build||"unknown"}`:ht.length>0?"Local AI Image Generator found setup items that may need attention.":`${de.length} temporary item${de.length===1?"":"s"} can be cleaned (${ai(cl)}).`})]}),c.jsxs("div",{className:"readiness-actions",children:[c.jsx("button",{className:"m3-btn m3-btn-outlined",onClick:le,disabled:jt,children:jt?"Checking":"Refresh"}),c.jsx("button",{className:"m3-btn m3-btn-tonal",onClick:re,children:Ke?"Copied":"Copy Diagnostics"}),de.length>0&&c.jsxs("button",{className:"m3-btn m3-btn-error",onClick:Ze,disabled:jt,children:["Clean ",ai(cl)]})]})]}),ht.length>0&&c.jsx("div",{className:"readiness-issues",children:ht.slice(0,4).map(k=>c.jsx("span",{children:k},k))}),de.length>0&&c.jsx("div",{className:"readiness-cleanup-list",children:de.slice(0,3).map(k=>c.jsxs("span",{title:k.path,children:[k.name," · ",k.size," · ",k.reason]},k.id))})]}),Ee]}),S&&c.jsx("div",{className:"app-dialog-backdrop",role:"presentation",children:c.jsxs("div",{className:"app-dialog",role:"dialog","aria-modal":"true","aria-labelledby":"app-dialog-title",children:[c.jsx("h3",{id:"app-dialog-title",className:"app-dialog-title",children:S.title}),c.jsx("p",{className:"app-dialog-message",children:S.message}),c.jsxs("div",{className:"app-dialog-actions",children:[S.type==="confirm"&&c.jsx("button",{className:"m3-btn m3-btn-outlined",onClick:()=>r(!1),children:S.cancelLabel}),c.jsx("button",{className:`m3-btn ${S.danger?"m3-btn-error":"m3-btn-filled"}`,onClick:()=>r(!0),children:S.con
Line truncated
|
||||
@@ -1 +1 @@
|
||||
:root{font-family:Outfit,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-shape-corner-small: 8px;--md-shape-corner-medium: 12px;--md-shape-corner-large: 16px;--md-shape-corner-extra-large: 22px;--md-shape-corner-full: 9999px;--md-transition-duration: .25s;--md-transition-easing: cubic-bezier(.4, 0, .2, 1);--md-sys-color-primary: #4f46e5;--md-sys-color-on-primary: #ffffff;--md-sys-color-primary-container: rgba(79, 70, 229, .06);--md-sys-color-on-primary-container: #4338ca;--md-sys-color-secondary: #0ea5e9;--md-sys-color-on-secondary: #ffffff;--md-sys-color-secondary-container: rgba(14, 165, 233, .06);--md-sys-color-on-secondary-container: #0369a1;--md-sys-color-tertiary: #d946ef;--md-sys-color-on-tertiary: #ffffff;--md-sys-color-background: #f8fafc;--md-sys-color-on-background: #0f172a;--md-sys-color-surface: rgba(255, 255, 255, .75);--md-sys-color-on-surface: #0f172a;--md-sys-color-surface-variant: rgba(241, 245, 249, .8);--md-sys-color-on-surface-variant: #475569;--md-sys-color-outline: #64748b;--md-sys-color-outline-variant: #94a3b8;--border-color: rgba(15, 23, 42, .08);--border-color-muted: rgba(15, 23, 42, .05);--md-sys-color-error: #ef4444;--md-sys-color-on-error: #ffffff;--md-sys-color-success: #10b981;--md-sys-color-on-success: #ffffff;--md-sys-color-card-border: rgba(15, 23, 42, .06);--glass-shadow: 0 8px 32px 0 rgba(15, 23, 42, .04);--glass-blur: blur(16px)}html[data-theme=dark]{--md-sys-color-primary: #6366f1;--md-sys-color-on-primary: #ffffff;--md-sys-color-primary-container: rgba(99, 102, 241, .12);--md-sys-color-on-primary-container: #c7d2fe;--md-sys-color-secondary: #38bdf8;--md-sys-color-on-secondary: #0f172a;--md-sys-color-secondary-container: rgba(56, 189, 248, .08);--md-sys-color-on-secondary-container: #bae6fd;--md-sys-color-tertiary: #f472b6;--md-sys-color-on-tertiary: #0f172a;--md-sys-color-background: #090a0f;--md-sys-color-on-background: #f4f4f5;--md-sys-color-surface: rgba(18, 20, 29, .65);--md-sys-color-on-surface: #f4f4f5;--md-sys-color-surface-variant: rgba(26, 29, 41, .55);--md-sys-color-on-surface-variant: #a1a1aa;--md-sys-color-outline: #a1a1aa;--md-sys-color-outline-variant: #71717a;--border-color: rgba(255, 255, 255, .09);--border-color-muted: rgba(255, 255, 255, .05);--md-sys-color-error: #f87171;--md-sys-color-on-error: #ffffff;--md-sys-color-success: #34d399;--md-sys-color-on-success: #090a0f;--md-sys-color-card-border: rgba(255, 255, 255, .04);--glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, .3);--glass-blur: blur(16px)}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--md-sys-color-background);background-image:radial-gradient(at 0% 0%,var(--md-sys-color-primary-container) 0px,transparent 50%),radial-gradient(at 100% 0%,var(--md-sys-color-secondary-container) 0px,transparent 40%);color:var(--md-sys-color-on-background);overflow:hidden;height:100vh;width:100vw;font-size:16px;transition:background-color var(--md-transition-duration) ease}.app-container{display:flex;flex-direction:row;height:100vh;width:100vw;overflow:hidden}.sidebar{width:280px;background-color:var(--md-sys-color-surface);backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);border-right:1px solid var(--border-color);display:flex;flex-direction:column;padding:28px 18px;justify-content:space-between;box-shadow:var(--glass-shadow);z-index:11;transition:all var(--md-transition-duration) var(--md-transition-easing)}.sidebar-logo{display:flex;align-items:center;gap:12px;padding:0 12px 28px}.sidebar-logo-icon{color:var(--md-sys-color-primary);width:26px;height:26px;filter:drop-shadow(0 2px 8px rgba(99,102,241,.3))}.sidebar-logo-text{font-size:1.15rem;font-weight:700;letter-spacing:-.02em;color:var(--md-sys-color-on-background)}.nav-list{display:flex;flex-direction:column;gap:6px;margin-bottom:auto}.nav-item{display:flex;align-items:center;gap:12px;padding:10px 16px;height:48px;border-radius:var(--md-shape-corner-medium);color:var(--md-sys-color-on-surface-variant);font-size:.9rem;font-weight:500;cursor:pointer;transition:all var(--md-transition-duration) var(--md-transition-easing);-webkit-user-select:none;user-select:none;text-decoration:none;position:relative}.nav-item:hover{background-color:var(--md-sys-color-surface-variant);color:var(--md-sys-color-primary);transform:translate(2px)}.nav-item.active{background-color:var(--md-sys-color-primary-container);color:var(--md-sys-color-primary);font-weight:600}.nav-item.active:before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:4px;background-color:var(--md-sys-color-primary);border-radius:0 4px 4px 0}.sidebar-footer{padding:18px 12px 0;border-top:1px solid var(--border-color);font-size:.78rem;color:var(--md-sys-color-on-surface-variant);display:flex;flex-direction:column;gap:6px;opacity:.95}.main-content{flex:1;display:flex;flex-direction:column;background-coLine truncated
|
||||
:root{font-family:Outfit,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-shape-corner-small: 8px;--md-shape-corner-medium: 12px;--md-shape-corner-large: 16px;--md-shape-corner-extra-large: 22px;--md-shape-corner-full: 9999px;--md-transition-duration: .25s;--md-transition-easing: cubic-bezier(.4, 0, .2, 1);--md-sys-color-primary: #4f46e5;--md-sys-color-on-primary: #ffffff;--md-sys-color-primary-container: rgba(79, 70, 229, .06);--md-sys-color-on-primary-container: #4338ca;--md-sys-color-secondary: #0ea5e9;--md-sys-color-on-secondary: #ffffff;--md-sys-color-secondary-container: rgba(14, 165, 233, .06);--md-sys-color-on-secondary-container: #0369a1;--md-sys-color-tertiary: #d946ef;--md-sys-color-on-tertiary: #ffffff;--md-sys-color-background: #f8fafc;--md-sys-color-on-background: #0f172a;--md-sys-color-surface: rgba(255, 255, 255, .75);--md-sys-color-on-surface: #0f172a;--md-sys-color-surface-variant: rgba(241, 245, 249, .8);--md-sys-color-on-surface-variant: #475569;--md-sys-color-outline: #64748b;--md-sys-color-outline-variant: #94a3b8;--border-color: rgba(15, 23, 42, .08);--border-color-muted: rgba(15, 23, 42, .05);--md-sys-color-error: #ef4444;--md-sys-color-on-error: #ffffff;--md-sys-color-success: #10b981;--md-sys-color-on-success: #ffffff;--md-sys-color-card-border: rgba(15, 23, 42, .06);--glass-shadow: 0 8px 32px 0 rgba(15, 23, 42, .04);--glass-blur: blur(16px)}html[data-theme=dark]{--md-sys-color-primary: #6366f1;--md-sys-color-on-primary: #ffffff;--md-sys-color-primary-container: rgba(99, 102, 241, .12);--md-sys-color-on-primary-container: #c7d2fe;--md-sys-color-secondary: #38bdf8;--md-sys-color-on-secondary: #0f172a;--md-sys-color-secondary-container: rgba(56, 189, 248, .08);--md-sys-color-on-secondary-container: #bae6fd;--md-sys-color-tertiary: #f472b6;--md-sys-color-on-tertiary: #0f172a;--md-sys-color-background: #090a0f;--md-sys-color-on-background: #f4f4f5;--md-sys-color-surface: rgba(18, 20, 29, .65);--md-sys-color-on-surface: #f4f4f5;--md-sys-color-surface-variant: rgba(26, 29, 41, .55);--md-sys-color-on-surface-variant: #a1a1aa;--md-sys-color-outline: #a1a1aa;--md-sys-color-outline-variant: #71717a;--border-color: rgba(255, 255, 255, .09);--border-color-muted: rgba(255, 255, 255, .05);--md-sys-color-error: #f87171;--md-sys-color-on-error: #ffffff;--md-sys-color-success: #34d399;--md-sys-color-on-success: #090a0f;--md-sys-color-card-border: rgba(255, 255, 255, .04);--glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, .3);--glass-blur: blur(16px)}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--md-sys-color-background);background-image:radial-gradient(at 0% 0%,var(--md-sys-color-primary-container) 0px,transparent 50%),radial-gradient(at 100% 0%,var(--md-sys-color-secondary-container) 0px,transparent 40%);color:var(--md-sys-color-on-background);overflow:hidden;height:100vh;width:100vw;font-size:16px;transition:background-color var(--md-transition-duration) ease}.app-container{display:flex;flex-direction:row;height:100vh;width:100vw;overflow:hidden}.sidebar{width:280px;background-color:var(--md-sys-color-surface);backdrop-filter:var(--glass-blur);-webkit-backdrop-filter:var(--glass-blur);border-right:1px solid var(--border-color);display:flex;flex-direction:column;padding:28px 18px;justify-content:space-between;box-shadow:var(--glass-shadow);z-index:11;transition:all var(--md-transition-duration) var(--md-transition-easing)}.sidebar-logo{display:flex;align-items:center;gap:12px;padding:0 12px 28px}.sidebar-logo-icon{color:var(--md-sys-color-primary);width:26px;height:26px;filter:drop-shadow(0 2px 8px rgba(99,102,241,.3))}.sidebar-logo-text{font-size:1.15rem;font-weight:700;letter-spacing:-.02em;color:var(--md-sys-color-on-background)}.nav-list{display:flex;flex-direction:column;gap:6px;margin-bottom:auto}.nav-item{display:flex;align-items:center;gap:12px;padding:10px 16px;height:48px;border-radius:var(--md-shape-corner-medium);color:var(--md-sys-color-on-surface-variant);font-size:.9rem;font-weight:500;cursor:pointer;transition:all var(--md-transition-duration) var(--md-transition-easing);-webkit-user-select:none;user-select:none;text-decoration:none;position:relative}.nav-item:hover{background-color:var(--md-sys-color-surface-variant);color:var(--md-sys-color-primary);transform:translate(2px)}.nav-item.active{background-color:var(--md-sys-color-primary-container);color:var(--md-sys-color-primary);font-weight:600}.nav-item.active:before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:4px;background-color:var(--md-sys-color-primary);border-radius:0 4px 4px 0}.sidebar-footer{padding:18px 12px 0;border-top:1px solid var(--border-color);font-size:.78rem;color:var(--md-sys-color-on-surface-variant);display:flex;flex-direction:column;gap:6px;opacity:.95}.main-content{flex:1;display:flex;flex-direction:column;background-coLine truncated
|
||||
Vendored
+2
-2
@@ -8,8 +8,8 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<title>Local AI Image Generator</title>
|
||||
<script type="module" crossorigin src="/assets/index-BOI9YDBQ.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BVK0F0Ah.css">
|
||||
<script type="module" crossorigin src="/assets/index-CBtRYlFE.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DW6G7wc2.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -777,46 +777,6 @@ html[data-theme="dark"] .m3-segment-item:hover:not(.active):not(.disabled) {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.image-to-image-section {
|
||||
margin-top: 12px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
/* Drag and Drop Zone */
|
||||
.image-dropzone {
|
||||
border: 2.5px dashed var(--border-color);
|
||||
border-radius: var(--md-shape-corner-large);
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background-color: var(--md-sys-color-surface-variant);
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
transition: all var(--md-transition-duration);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.image-dropzone:hover {
|
||||
background-color: var(--md-sys-color-primary-container);
|
||||
border-color: var(--md-sys-color-primary);
|
||||
color: var(--md-sys-color-primary);
|
||||
}
|
||||
|
||||
.dropped-image-preview {
|
||||
max-width: 100%;
|
||||
max-height: 160px;
|
||||
border-radius: var(--md-shape-corner-medium);
|
||||
object-fit: contain;
|
||||
box-shadow: var(--glass-shadow);
|
||||
}
|
||||
|
||||
/* Aspect Ratio Buttons with Previews */
|
||||
.aspect-ratio-btn {
|
||||
position: relative;
|
||||
|
||||
@@ -50,7 +50,6 @@ function App() {
|
||||
// Prompts
|
||||
const [prompt, setPrompt] = useState("");
|
||||
const [negativePrompt, setNegativePrompt] = useState("");
|
||||
const [inputImage, setInputImage] = useState(null); // base64 for Image-to-Image
|
||||
|
||||
// Model & Server Status
|
||||
const [activeModel, setActiveModel] = useState(null);
|
||||
@@ -342,8 +341,6 @@ function App() {
|
||||
generationProgress={generationProgress}
|
||||
setGenerationProgress={setGenerationProgress}
|
||||
setActiveTab={setActiveTab}
|
||||
inputImage={inputImage}
|
||||
setInputImage={setInputImage}
|
||||
showAlert={showAlert}
|
||||
showConfirm={showConfirm}
|
||||
/>
|
||||
@@ -382,7 +379,6 @@ function App() {
|
||||
generatedImages,
|
||||
isGenerating,
|
||||
generationProgress,
|
||||
inputImage,
|
||||
serverRunning,
|
||||
specs,
|
||||
backendOptions,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { memo, useState, useRef, useCallback } from "react";
|
||||
import { Sparkles, Download, Copy, RefreshCw, ImagePlus, Check, Sliders, Layers, Trash2 } from "lucide-react";
|
||||
import { generateImage, isTauri, startServer, stopServer, waitForServerReady, getBackendStatus, getGenerationProgress, saveGeneratedOutput, deleteGeneratedOutputs } from "../services/api";
|
||||
import { Sparkles, Download, Copy, RefreshCw, Check, Sliders, Layers, Trash2 } from "lucide-react";
|
||||
import { generateImage, startServer, stopServer, waitForServerReady, getBackendStatus, getGenerationProgress, saveGeneratedOutput, deleteGeneratedOutputs } from "../services/api";
|
||||
|
||||
const GalleryItem = memo(({ img, idx, isSelected, onClick }) => {
|
||||
const handleClick = (e) => {
|
||||
@@ -37,8 +37,6 @@ function Generator({
|
||||
generationProgress,
|
||||
setGenerationProgress,
|
||||
setActiveTab,
|
||||
inputImage,
|
||||
setInputImage,
|
||||
showAlert = async ({ message }) => window.alert(message),
|
||||
showConfirm = async ({ message }) => window.confirm(message),
|
||||
}) {
|
||||
@@ -58,31 +56,8 @@ function Generator({
|
||||
const [isDecoding, setIsDecoding] = useState(false);
|
||||
const [selectedGalleryIndexes, setSelectedGalleryIndexes] = useState([]);
|
||||
const timerRef = useRef(null);
|
||||
const fileInputRef = useRef(null);
|
||||
const abortControllerRef = useRef(null);
|
||||
|
||||
// Trigger file dialog for Image-to-Image
|
||||
const handleDropzoneClick = () => {
|
||||
fileInputRef.current.click();
|
||||
};
|
||||
|
||||
// Convert uploaded image file to Base64
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
setInputImage(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const clearInputImage = (e) => {
|
||||
e.stopPropagation();
|
||||
setInputImage(null);
|
||||
if (fileInputRef.current) fileInputRef.current.value = "";
|
||||
};
|
||||
const hasRealGenerationStepRef = useRef(false);
|
||||
|
||||
// Trigger main image generation process
|
||||
const handleGenerate = async () => {
|
||||
@@ -170,6 +145,7 @@ function Generator({
|
||||
setElapsedTime(0);
|
||||
setCurrentStep(0);
|
||||
setGenerationSpeed("");
|
||||
hasRealGenerationStepRef.current = false;
|
||||
setIsCpuFallback(false);
|
||||
setIsDecoding(false);
|
||||
setGenDuration(null);
|
||||
@@ -203,7 +179,10 @@ function Generator({
|
||||
const steps = progress.steps || constraints.steps || 20;
|
||||
const speed = decoding ? "" : (progress.speed || "");
|
||||
|
||||
setCurrentStep(step);
|
||||
if (decoding || progress.steps > 0) {
|
||||
hasRealGenerationStepRef.current = true;
|
||||
setCurrentStep(step);
|
||||
}
|
||||
if (!decoding) {
|
||||
setGenerationSpeed(speed);
|
||||
} else {
|
||||
@@ -218,7 +197,11 @@ function Generator({
|
||||
progressPercent = Math.round((step / steps) * 100);
|
||||
}
|
||||
progressPercent = Math.min(99, progressPercent);
|
||||
setGenerationProgress((prev) => Math.max(prev, progressPercent));
|
||||
if (decoding || progress.steps > 0) {
|
||||
setGenerationProgress(progressPercent);
|
||||
} else {
|
||||
setGenerationProgress((prev) => Math.max(prev, progressPercent));
|
||||
}
|
||||
|
||||
// Calculate remaining time
|
||||
let remaining = 0;
|
||||
@@ -275,8 +258,6 @@ function Generator({
|
||||
expectedTotal = constraints.steps * activeStepTime;
|
||||
step = Math.min(constraints.steps - 1, Math.floor(elapsedSeconds / activeStepTime));
|
||||
}
|
||||
setCurrentStep(step);
|
||||
|
||||
const remaining = Math.max(1, expectedTotal - elapsedSeconds);
|
||||
setEstimatedLeftTime(Math.round(remaining));
|
||||
|
||||
@@ -305,7 +286,9 @@ function Generator({
|
||||
progressPercent = Math.min(99, Math.round(85 + 14 * decay));
|
||||
}
|
||||
}
|
||||
setGenerationProgress((p) => Math.max(p, progressPercent));
|
||||
if (!hasRealGenerationStepRef.current) {
|
||||
setGenerationProgress((p) => Math.max(p, progressPercent));
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -316,7 +299,7 @@ function Generator({
|
||||
negativePrompt,
|
||||
constraints,
|
||||
activeModel,
|
||||
inputImage, // passes base64 if I2I
|
||||
null,
|
||||
(prog) => setGenerationProgress((prev) => Math.max(prev, prog)),
|
||||
abortControllerRef.current.signal
|
||||
);
|
||||
@@ -339,7 +322,6 @@ function Generator({
|
||||
model: activeModel,
|
||||
duration_sec: result.duration_sec,
|
||||
timestamp: new Date().toLocaleTimeString(),
|
||||
inputImage: Boolean(inputImage),
|
||||
};
|
||||
let savedOutput = null;
|
||||
let savedUrl = null;
|
||||
@@ -396,31 +378,29 @@ function Generator({
|
||||
abortControllerRef.current.abort();
|
||||
}
|
||||
|
||||
// In native desktop mode, restart the server process to immediately free CPU threads/memory
|
||||
if (isTauri()) {
|
||||
try {
|
||||
console.log("Cancelling: Stopping server to kill generation threads...");
|
||||
await stopServer();
|
||||
if (activeModel) {
|
||||
console.log("Cancelling: Restarting server for future generations...");
|
||||
await startServer(activeModel, constraints);
|
||||
const ready = await waitForServerReady();
|
||||
if (!ready) {
|
||||
console.warn("Server failed to restart properly.");
|
||||
}
|
||||
try {
|
||||
console.log("Cancelling: Stopping server to kill generation threads...");
|
||||
await stopServer();
|
||||
setCurrentStep(0);
|
||||
setGenerationSpeed("");
|
||||
setIsDecoding(false);
|
||||
hasRealGenerationStepRef.current = false;
|
||||
|
||||
if (activeModel) {
|
||||
console.log("Cancelling: Restarting server for future generations...");
|
||||
await startServer(activeModel, constraints);
|
||||
const ready = await waitForServerReady();
|
||||
if (!ready) {
|
||||
console.warn("Server failed to restart properly.");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to restart server on cancellation:", err);
|
||||
} finally {
|
||||
setIsCancelling(false);
|
||||
setIsGenerating(false);
|
||||
setGenerationProgress(0);
|
||||
}
|
||||
} else {
|
||||
// Browser Mode
|
||||
} catch (err) {
|
||||
console.error("Failed to restart server on cancellation:", err);
|
||||
} finally {
|
||||
setIsCancelling(false);
|
||||
setIsGenerating(false);
|
||||
setGenerationProgress(0);
|
||||
setEstimatedLeftTime(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -634,51 +614,6 @@ function Generator({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Image to Image Dropzone Toggle */}
|
||||
<div className="image-to-image-section">
|
||||
<label className="m3-text-field-label" style={{ display: "block", marginBottom: "8px" }}>
|
||||
Image-to-Image Source (Optional)
|
||||
</label>
|
||||
<div className="image-dropzone" onClick={handleDropzoneClick}>
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
style={{ display: "none" }}
|
||||
accept="image/*"
|
||||
onChange={handleFileChange}
|
||||
disabled={isGenerating}
|
||||
/>
|
||||
|
||||
{inputImage ? (
|
||||
<div style={{ position: "relative", width: "100%", height: "100%" }}>
|
||||
<img src={inputImage} className="dropped-image-preview" alt="Source" />
|
||||
<button
|
||||
className="m3-btn m3-btn-error"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "4px",
|
||||
right: "4px",
|
||||
height: "30px",
|
||||
width: "30px",
|
||||
borderRadius: "50%",
|
||||
padding: 0
|
||||
}}
|
||||
onClick={clearInputImage}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<ImagePlus size={24} style={{ color: "var(--md-sys-color-primary)" }} />
|
||||
<span style={{ fontSize: "0.85rem", fontWeight: 500 }}>
|
||||
Click or drag image here for Image-to-Image guidance
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Generate Trigger Button */}
|
||||
<button
|
||||
className="m3-btn m3-btn-filled"
|
||||
|
||||
@@ -638,6 +638,7 @@ function getDefaultModel() {
|
||||
|
||||
function killBackend() {
|
||||
return new Promise(resolve => {
|
||||
resetGenerationState();
|
||||
if (!backendProc) {
|
||||
backendUnloadState = { active: false, phase: "", progress: 0 };
|
||||
resolve();
|
||||
@@ -878,6 +879,16 @@ let generationState = {
|
||||
decoding: false,
|
||||
};
|
||||
|
||||
function resetGenerationState() {
|
||||
generationState = {
|
||||
active: false,
|
||||
step: 0,
|
||||
steps: 0,
|
||||
speed: "",
|
||||
decoding: false,
|
||||
};
|
||||
}
|
||||
|
||||
function startModelDownload(url, overrideFilename = null) {
|
||||
if (downloadState.active && !overrideFilename) {
|
||||
console.log(" [download] Already downloading a model");
|
||||
|
||||
Reference in new issue
Block a user