From eae4596aa39a1cc979f7244b34a5b4b5039c897e Mon Sep 17 00:00:00 2001 From: Yin Kou Date: Sat, 7 Nov 2026 00:07:22 +0800 Subject: [PATCH] feat(portal): migrate V3 console to React 19 + Vite + TypeScript + Zustand + Tailwind v4 --- .gitignore | 1 + stacks/portal/dist/assets/index-DCqVyTsd.js | 79 + stacks/portal/dist/assets/index-DWXFEfty.css | 1 + stacks/portal/dist/index.html | 20 + stacks/portal/server.py | 24 +- stacks/portal/web/index.html | 19 + stacks/portal/web/package-lock.json | 2635 +++++++++++++++++ stacks/portal/web/package.json | 28 + stacks/portal/web/src/App.tsx | 230 ++ .../web/src/components/AgyTerminalModal.tsx | 52 + .../web/src/components/CommandPalette.tsx | 248 ++ .../portal/web/src/components/ServiceCard.tsx | 124 + stacks/portal/web/src/components/SshShelf.tsx | 73 + .../portal/web/src/components/TopRibbon.tsx | 180 ++ stacks/portal/web/src/index.css | 170 ++ stacks/portal/web/src/main.tsx | 10 + stacks/portal/web/src/store/usePortalStore.ts | 154 + stacks/portal/web/src/types/telemetry.ts | 84 + stacks/portal/web/tsconfig.json | 17 + stacks/portal/web/vite.config.ts | 16 + 20 files changed, 4162 insertions(+), 3 deletions(-) create mode 100644 stacks/portal/dist/assets/index-DCqVyTsd.js create mode 100644 stacks/portal/dist/assets/index-DWXFEfty.css create mode 100644 stacks/portal/dist/index.html create mode 100644 stacks/portal/web/index.html create mode 100644 stacks/portal/web/package-lock.json create mode 100644 stacks/portal/web/package.json create mode 100644 stacks/portal/web/src/App.tsx create mode 100644 stacks/portal/web/src/components/AgyTerminalModal.tsx create mode 100644 stacks/portal/web/src/components/CommandPalette.tsx create mode 100644 stacks/portal/web/src/components/ServiceCard.tsx create mode 100644 stacks/portal/web/src/components/SshShelf.tsx create mode 100644 stacks/portal/web/src/components/TopRibbon.tsx create mode 100644 stacks/portal/web/src/index.css create mode 100644 stacks/portal/web/src/main.tsx create mode 100644 stacks/portal/web/src/store/usePortalStore.ts create mode 100644 stacks/portal/web/src/types/telemetry.ts create mode 100644 stacks/portal/web/tsconfig.json create mode 100644 stacks/portal/web/vite.config.ts diff --git a/.gitignore b/.gitignore index 1a04c7b..89dbf88 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ stacks/gateway/certs/*.key stacks/gateway/certs/*.pem stacks/lucky/goodluck/ +**/node_modules/ diff --git a/stacks/portal/dist/assets/index-DCqVyTsd.js b/stacks/portal/dist/assets/index-DCqVyTsd.js new file mode 100644 index 0000000..2464993 --- /dev/null +++ b/stacks/portal/dist/assets/index-DCqVyTsd.js @@ -0,0 +1,79 @@ +(function(){const A=document.createElement("link").relList;if(A&&A.supports&&A.supports("modulepreload"))return;for(const p of document.querySelectorAll('link[rel="modulepreload"]'))m(p);new MutationObserver(p=>{for(const q of p)if(q.type==="childList")for(const nl of q.addedNodes)nl.tagName==="LINK"&&nl.rel==="modulepreload"&&m(nl)}).observe(document,{childList:!0,subtree:!0});function _(p){const q={};return p.integrity&&(q.integrity=p.integrity),p.referrerPolicy&&(q.referrerPolicy=p.referrerPolicy),p.crossOrigin==="use-credentials"?q.credentials="include":p.crossOrigin==="anonymous"?q.credentials="omit":q.credentials="same-origin",q}function m(p){if(p.ep)return;p.ep=!0;const q=_(p);fetch(p.href,q)}})();function o0(b){return b&&b.__esModule&&Object.prototype.hasOwnProperty.call(b,"default")?b.default:b}var Ts={exports:{}},an={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ir;function dh(){if(Ir)return an;Ir=1;var b=Symbol.for("react.transitional.element"),A=Symbol.for("react.fragment");function _(m,p,q){var nl=null;if(q!==void 0&&(nl=""+q),p.key!==void 0&&(nl=""+p.key),"key"in p){q={};for(var w in p)w!=="key"&&(q[w]=p[w])}else q=p;return p=q.ref,{$$typeof:b,type:m,key:nl,ref:p!==void 0?p:null,props:q}}return an.Fragment=A,an.jsx=_,an.jsxs=_,an}var Pr;function mh(){return Pr||(Pr=1,Ts.exports=dh()),Ts.exports}var z=mh(),Es={exports:{}},L={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var l0;function rh(){if(l0)return L;l0=1;var b=Symbol.for("react.transitional.element"),A=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),m=Symbol.for("react.strict_mode"),p=Symbol.for("react.profiler"),q=Symbol.for("react.consumer"),nl=Symbol.for("react.context"),w=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),ll=Symbol.for("react.memo"),U=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),B=Symbol.for("react.view_transition"),Z=Symbol.iterator;function El(o){return o===null||typeof o!="object"?null:(o=Z&&o[Z]||o["@@iterator"],typeof o=="function"?o:null)}var wl={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},vl=Object.assign,kl={};function nt(o,N,j){this.props=o,this.context=N,this.refs=kl,this.updater=j||wl}nt.prototype.isReactComponent={},nt.prototype.setState=function(o,N){if(typeof o!="object"&&typeof o!="function"&&o!=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,o,N,"setState")},nt.prototype.forceUpdate=function(o){this.updater.enqueueForceUpdate(this,o,"forceUpdate")};function Ke(){}Ke.prototype=nt.prototype;function Bt(o,N,j){this.props=o,this.context=N,this.refs=kl,this.updater=j||wl}var qt=Bt.prototype=new Ke;qt.constructor=Bt,vl(qt,nt.prototype),qt.isPureReactComponent=!0;var it=Array.isArray;function W(){}var il={H:null,A:null,T:null,S:null},Gt=Object.prototype.hasOwnProperty;function bt(o,N,j){var Y=j.ref;return{$$typeof:b,type:o,key:N,ref:Y!==void 0?Y:null,props:j}}function Tt(o,N){return bt(o.type,N,o.props)}function ct(o){return typeof o=="object"&&o!==null&&o.$$typeof===b}function he(o){var N={"=":"=0",":":"=2"};return"$"+o.replace(/[=:]/g,function(j){return N[j]})}var Je=/\/+/g;function Cl(o,N){return typeof o=="object"&&o!==null&&o.key!=null?he(""+o.key):N.toString(36)}function O(o){switch(o.status){case"fulfilled":return o.value;case"rejected":throw o.reason;default:switch(typeof o.status=="string"?o.then(W,W):(o.status="pending",o.then(function(N){o.status==="pending"&&(o.status="fulfilled",o.value=N)},function(N){o.status==="pending"&&(o.status="rejected",o.reason=N)})),o.status){case"fulfilled":return o.value;case"rejected":throw o.reason}}throw o}function Q(o,N,j,Y,el){var ul=typeof o;(ul==="undefined"||ul==="boolean")&&(o=null);var cl=!1;if(o===null)cl=!0;else switch(ul){case"bigint":case"string":case"number":cl=!0;break;case"object":switch(o.$$typeof){case b:case A:cl=!0;break;case U:return cl=o._init,Q(cl(o._payload),N,j,Y,el)}}if(cl)return el=el(o),cl=Y===""?"."+Cl(o,0):Y,it(el)?(j="",cl!=null&&(j=cl.replace(Je,"$&/")+"/"),Q(el,N,j,"",function(le){return le})):el!=null&&(ct(el)&&(el=Tt(el,j+(el.key==null||o&&o.key===el.key?"":(""+el.key).replace(Je,"$&/")+"/")+cl)),N.push(el)),1;cl=0;var R=Y===""?".":Y+":";if(it(o))for(var V=0;V>>1,sl=O[hl];if(0>>1;hlp($e,X))op(N,$e)?(O[hl]=N,O[o]=X,hl=o):(O[hl]=$e,O[Pt]=X,hl=Pt);else if(op(N,X))O[hl]=N,O[o]=X,hl=o;else break l}}return Q}function p(O,Q){var X=O.sortIndex-Q.sortIndex;return X!==0?X:O.id-Q.id}if(b.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var q=performance;b.unstable_now=function(){return q.now()}}else{var nl=Date,w=nl.now();b.unstable_now=function(){return nl.now()-w}}var C=[],ll=[],U=1,S=null,B=3,Z=!1,El=!1,wl=!1,vl=!1,kl=typeof setTimeout=="function"?setTimeout:null,nt=typeof clearTimeout=="function"?clearTimeout:null,Ke=typeof setImmediate<"u"?setImmediate:null;function Bt(O){for(var Q=_(ll);Q!==null;){if(Q.callback===null)m(ll);else if(Q.startTime<=O)m(ll),Q.sortIndex=Q.expirationTime,A(C,Q);else break;Q=_(ll)}}function qt(O){if(wl=!1,Bt(O),!El)if(_(C)!==null)El=!0,it||(it=!0,ct());else{var Q=_(ll);Q!==null&&Cl(qt,Q.startTime-O)}}var it=!1,W=-1,il=5,Gt=-1;function bt(){return vl?!0:!(b.unstable_now()-GtO&&bt());){var hl=S.callback;if(typeof hl=="function"){S.callback=null,B=S.priorityLevel;var sl=hl(S.expirationTime<=O);if(O=b.unstable_now(),typeof sl=="function"){S.callback=sl,Bt(O),Q=!0;break t}S===_(C)&&m(C),Bt(O)}else m(C);S=_(C)}if(S!==null)Q=!0;else{var Dt=_(ll);Dt!==null&&Cl(qt,Dt.startTime-O),Q=!1}}break l}finally{S=null,B=X,Z=!1}Q=void 0}}finally{Q?ct():it=!1}}}var ct;if(typeof Ke=="function")ct=function(){Ke(Tt)};else if(typeof MessageChannel<"u"){var he=new MessageChannel,Je=he.port2;he.port1.onmessage=Tt,ct=function(){Je.postMessage(null)}}else ct=function(){kl(Tt,0)};function Cl(O,Q){W=kl(function(){O(b.unstable_now())},Q)}b.unstable_IdlePriority=5,b.unstable_ImmediatePriority=1,b.unstable_LowPriority=4,b.unstable_NormalPriority=3,b.unstable_Profiling=null,b.unstable_UserBlockingPriority=2,b.unstable_cancelCallback=function(O){O.callback=null},b.unstable_forceFrameRate=function(O){0>O||125hl?(O.sortIndex=X,A(ll,O),_(C)===null&&O===_(ll)&&(wl?(nt(W),W=-1):wl=!0,Cl(qt,X-hl))):(O.sortIndex=sl,A(C,O),El||Z||(El=!0,it||(it=!0,ct()))),O},b.unstable_shouldYield=bt,b.unstable_wrapCallback=function(O){var Q=B;return function(){var X=B;B=Q;try{return O.apply(this,arguments)}finally{B=X}}}})(Ns)),Ns}var u0;function yh(){return u0||(u0=1,_s.exports=vh()),_s.exports}var xs={exports:{}},Ll={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var a0;function hh(){if(a0)return Ll;a0=1;var b=Os();function A(U){var S="https://react.dev/errors/"+U;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(b)}catch(A){console.error(A)}}return b(),xs.exports=hh(),xs.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var i0;function Sh(){if(i0)return nn;i0=1;var b=yh(),A=Os(),_=gh();function m(l){var t="https://react.dev/errors/"+l;if(1Su||(l.current=qi[Su],qi[Su]=null,Su--)}function Sl(l,t){Su++,qi[Su]=l.current,l.current=t}var Xt=Qt(null),oa=Qt(null),ge=Qt(null),cn=Qt(null);function fn(l,t){switch(Sl(ge,t),Sl(oa,l),Sl(Xt,null),t.nodeType){case 9:case 11:l=(l=t.documentElement)&&(l=l.namespaceURI)?cr(l):0;break;default:if(l=t.tagName,t=t.namespaceURI)t=cr(t),l=fr(t,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}Bl(Xt),Sl(Xt,l)}function bu(){Bl(Xt),Bl(oa),Bl(ge)}function Gi(l){var t=l.memoizedState;t!==null&&(ia._currentValue=t.memoizedState,Sl(cn,l)),t=Xt.current;var e=fr(t,l.type);t!==e&&(Sl(oa,l),Sl(Xt,e))}function sn(l){oa.current===l&&(Bl(Xt),Bl(oa)),cn.current===l&&(Bl(cn),ia._currentValue=le)}var Qi,As;function Se(l){if(Qi===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Qi=t&&t[1]||"",As=-1)":-1a||f[u]!==v[a]){var g=` +`+f[u].replace(" at new "," at ");return l.displayName&&g.includes("")&&(g=g.replace("",l.displayName)),g}while(1<=u&&0<=a);break}}}finally{Xi=!1,Error.prepareStackTrace=e}return(e=l?l.displayName||l.name:"")?Se(e):""}function y0(l,t){switch(l.tag){case 26:case 27:case 5:return Se(l.type);case 16:return Se("Lazy");case 13:return l.child!==t&&t!==null?Se("Suspense Fallback"):Se("Suspense");case 19:return Se("SuspenseList");case 0:case 15:return Zi(l.type,!1);case 11:return Zi(l.type.render,!1);case 1:return Zi(l.type,!0);case 31:return Se("Activity");case 30:return Se("ViewTransition");default:return""}}function ps(l){try{var t="",e=null;do t+=y0(l,e),e=l,l=l.return;while(l);return t}catch(u){return` +Error generating stack: `+u.message+` +`+u.stack}}var Vi=Object.prototype.hasOwnProperty,Li=b.unstable_scheduleCallback,wi=b.unstable_cancelCallback,h0=b.unstable_shouldYield,g0=b.unstable_requestPaint,ft=b.unstable_now,S0=b.unstable_getCurrentPriorityLevel,Ms=b.unstable_ImmediatePriority,Ds=b.unstable_UserBlockingPriority,on=b.unstable_NormalPriority,b0=b.unstable_LowPriority,Us=b.unstable_IdlePriority,T0=b.log,E0=b.unstable_setDisableYieldValue,da=null,st=null;function be(l){if(typeof T0=="function"&&E0(l),st&&typeof st.setStrictMode=="function")try{st.setStrictMode(da,l)}catch{}}var ot=Math.clz32?Math.clz32:N0,z0=Math.log,_0=Math.LN2;function N0(l){return l>>>=0,l===0?32:31-(z0(l)/_0|0)|0}var dn=256,mn=262144,rn=4194304;function We(l){var t=l&42;if(t!==0)return t;switch(l&-l){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 l&-l;case 262144:case 524288:case 1048576:case 2097152:return l&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return l&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return l}}function vn(l,t,e){var u=l.pendingLanes;if(u===0)return 0;var a=0,n=l.suspendedLanes,i=l.pingedLanes;l=l.warmLanes;var c=u&134217727;return c!==0?(u=c&~n,u!==0?a=We(u):(i&=c,i!==0?a=We(i):e||(e=c&~l,e!==0&&(a=We(e))))):(c=u&~n,c!==0?a=We(c):i!==0?a=We(i):e||(e=u&~l,e!==0&&(a=We(e)))),a===0?0:t!==0&&t!==a&&(t&n)===0&&(n=a&-a,e=t&-t,n>=e||n===32&&(e&4194048)!==0)?t:a}function ma(l,t){return(l.pendingLanes&~(l.suspendedLanes&~l.pingedLanes)&t)===0}function Cs(l,t){(t&8)!==0&&(t|=t&32);var e=l.entangledLanes;if(e!==0)for(l=l.entanglements,e&=t;0e;e++)t.push(l);return t}function ra(l,t){l.pendingLanes|=t,t!==268435456&&(l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0)}function O0(l,t,e,u,a,n){var i=l.pendingLanes;l.pendingLanes=e,l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0,l.expiredLanes&=e,l.entangledLanes&=e,l.errorRecoveryDisabledLanes&=e,l.shellSuspendCounter=0;var c=l.entanglements,f=l.expirationTimes,v=l.hiddenUpdates;for(e=i&~e;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ec=!1;if(ue)try{var ga={};Object.defineProperty(ga,"passive",{get:function(){ec=!0}}),window.addEventListener("test",ga,ga),window.removeEventListener("test",ga,ga)}catch{ec=!1}var Te=null,uc=null,Tn=null;function eo(){if(Tn)return Tn;var l,t=uc,e=t.length,u,a="value"in Te?Te.value:Te.textContent,n=a.length;for(l=0;l=Ta),fo=" ",so=!1;function oo(l,t){switch(l){case"keyup":return fv.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function mo(l){return l=l.detail,typeof l=="object"&&"data"in l?l.data:null}var pu=!1;function ov(l,t){switch(l){case"compositionend":return mo(t);case"keypress":return t.which!==32?null:(so=!0,fo);case"textInput":return l=t.data,l===fo&&so?null:l;default:return null}}function dv(l,t){if(pu)return l==="compositionend"||!fc&&oo(l,t)?(l=eo(),Tn=uc=Te=null,pu=!1,l):null;switch(l){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1"u")return null;try{return l.activeElement||l.body}catch{return l.body}}function To(l){for(;l&&l.firstChild;)l=l.firstChild;return l}function Eo(l,t){var e=To(l);l=0;for(var u;e;){if(e.nodeType===3){if(u=l+e.textContent.length,l<=t&&u>=t)return{node:e,offset:t-l};l=u}l:{for(;e;){if(e.nextSibling){e=e.nextSibling;break l}e=e.parentNode}e=void 0}e=To(e)}}function zo(l,t){return l&&t?l===t?!0:l&&l.nodeType===3?!1:t&&t.nodeType===3?zo(l,t.parentNode):"contains"in l?l.contains(t):l.compareDocumentPosition?!!(l.compareDocumentPosition(t)&16):!1:!1}function _o(l){l=l!=null&&l.ownerDocument!=null&&l.ownerDocument.defaultView!=null?l.ownerDocument.defaultView:window;for(var t=dc(l.document);t instanceof l.HTMLIFrameElement;){try{var e=typeof t.contentWindow.location.href=="string"}catch{e=!1}if(e)l=t.contentWindow;else break;t=dc(l.document)}return t}function mc(l){var t=l&&l.nodeName&&l.nodeName.toLowerCase();return t&&(t==="input"&&(l.type==="text"||l.type==="search"||l.type==="tel"||l.type==="url"||l.type==="password")||t==="textarea"||l.contentEditable==="true")}var bv=ue&&"documentMode"in document&&11>=document.documentMode,Mu=null,rc=null,Na=null,vc=!1;function No(l,t,e){var u=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;vc||Mu==null||Mu!==dc(u)||(u=Mu,"selectionStart"in u&&mc(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),Na&&_a(Na,u)||(Na=u,u=xi(rc,"onSelect"),0>=i,a-=i,Vt=1<<32-ot(t)+a|e<G?(Dl=H,H=null):Dl=H.sibling;var tl=d(r,H,y[G],T);if(tl===null){H===null&&(H=Dl);break}l&&H&&tl.alternate===null&&t(r,H),s=n(tl,s,G),P===null?M=tl:P.sibling=tl,P=tl,H=Dl}if(G===y.length)return e(r,H),$&&ce(r,G),M;if(H===null){for(;GG?(Dl=H,H=null):Dl=H.sibling;var we=d(r,H,tl.value,T);if(we===null){H===null&&(H=Dl);break}l&&H&&we.alternate===null&&t(r,H),s=n(we,s,G),P===null?M=we:P.sibling=we,P=we,H=Dl}if(tl.done)return e(r,H),$&&ce(r,G),M;if(H===null){for(;!tl.done;G++,tl=y.next())tl=E(r,tl.value,T),tl!==null&&(s=n(tl,s,G),P===null?M=tl:P.sibling=tl,P=tl);return $&&ce(r,G),M}for(H=u(H);!tl.done;G++,tl=y.next())tl=h(H,r,G,tl.value,T),tl!==null&&(l&&(Dl=tl.alternate,Dl!==null&&H.delete(Dl.key===null?G:Dl.key)),s=n(tl,s,G),P===null?M=tl:P.sibling=tl,P=tl);return l&&H.forEach(function(oh){return t(r,oh)}),$&&ce(r,G),M}function J(r,s,y,T){if(typeof y=="object"&&y!==null&&y.type===Tt&&y.key===null&&y.props.ref===void 0&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case Gt:l:{for(var M=y.key;s!==null;){if(s.key===M){if(M=y.type,M===Tt){if(s.tag===7){e(r,s.sibling),T=a(s,y.props.children),Oe(T,y),T.return=r,r=T;break l}}else if(s.elementType===M||typeof M=="object"&&M!==null&&M.$$typeof===sl&&fu(M)===s.type){e(r,s.sibling),T=a(s,y.props),Oe(T,y),T.return=r,r=T;break l}e(r,s);break}else t(r,s);s=s.sibling}y.type===Tt?(T=tu(y.props.children,r.mode,T,y.key),Oe(T,y),T.return=r,r=T):(T=Dn(y.type,y.key,y.props,null,r.mode,T),Oe(T,y),T.return=r,r=T)}return i(r);case bt:l:{for(M=y.key;s!==null;){if(s.key===M)if(s.tag===4&&s.stateNode.containerInfo===y.containerInfo&&s.stateNode.implementation===y.implementation){e(r,s.sibling),T=a(s,y.children||[]),T.return=r,r=T;break l}else{e(r,s);break}else t(r,s);s=s.sibling}T=Ec(y,r.mode,T),T.return=r,r=T}return i(r);case sl:return y=fu(y),J(r,s,y,T)}if(cl(y))return x(r,s,y,T);if(Y(y)){if(M=Y(y),typeof M!="function")throw Error(m(150));return y=M.call(y),D(r,s,y,T)}if(typeof y.then=="function")return J(r,s,Qn(y),T);if(y.$$typeof===Cl)return J(r,s,Yn(r,y),T);Xn(r,y)}return typeof y=="string"&&y!==""||typeof y=="number"||typeof y=="bigint"?(y=""+y,s!==null&&s.tag===6?(e(r,s.sibling),T=a(s,y),T.return=r,r=T):(e(r,s),T=Tc(y,r.mode,T),T.return=r,r=T),i(r)):e(r,s)}return function(r,s,y,T){try{Da=0;var M=J(r,s,y,T);return qu=null,M}catch(H){if(H===Bu||H===qn)throw H;var P=Pl(29,H,null,r.mode);return P.lanes=T,P.return=r,P}finally{}}}var ou=$o(!0),Wo=$o(!1),Ae=!1;function Uc(l){l.updateQueue={baseState:l.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Cc(l,t){l=l.updateQueue,t.updateQueue===l&&(t.updateQueue={baseState:l.baseState,firstBaseUpdate:l.firstBaseUpdate,lastBaseUpdate:l.lastBaseUpdate,shared:l.shared,callbacks:null})}function pe(l){return{lane:l,tag:0,payload:null,callback:null,next:null}}function Me(l,t,e){var u=l.updateQueue;if(u===null)return null;if(u=u.shared,(fl&2)!==0){var a=u.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),u.pending=t,t=Mn(l),Co(l,null,e),t}return pn(l,u,t,e),Mn(l)}function Ua(l,t,e){if(t=t.updateQueue,t!==null&&(t=t.shared,(e&4194048)!==0)){var u=t.lanes;u&=l.pendingLanes,e|=u,t.lanes=e,js(l,e)}}function Rc(l,t){var e=l.updateQueue,u=l.alternate;if(u!==null&&(u=u.updateQueue,e===u)){var a=null,n=null;if(e=e.firstBaseUpdate,e!==null){do{var i={lane:e.lane,tag:e.tag,payload:e.payload,callback:null,next:null};n===null?a=n=i:n=n.next=i,e=e.next}while(e!==null);n===null?a=n=t:n=n.next=t}else a=n=t;e={baseState:u.baseState,firstBaseUpdate:a,lastBaseUpdate:n,shared:u.shared,callbacks:u.callbacks},l.updateQueue=e;return}l=e.lastBaseUpdate,l===null?e.firstBaseUpdate=t:l.next=t,e.lastBaseUpdate=t}var Hc=!1;function Ca(){if(Hc){var l=Yu;if(l!==null)throw l}}function Ra(l,t,e,u){Hc=!1;var a=l.updateQueue;Ae=!1;var n=a.firstBaseUpdate,i=a.lastBaseUpdate,c=a.shared.pending;if(c!==null){a.shared.pending=null;var f=c,v=f.next;f.next=null,i===null?n=v:i.next=v,i=f;var g=l.alternate;g!==null&&(g=g.updateQueue,c=g.lastBaseUpdate,c!==i&&(c===null?g.firstBaseUpdate=v:c.next=v,g.lastBaseUpdate=f))}if(n!==null){var E=a.baseState;i=0,g=v=f=null,c=n;do{var d=c.lane&-536870913,h=d!==c.lane;if(h?(I&d)===d:(u&d)===d){d!==0&&d===iu&&(Hc=!0),g!==null&&(g=g.next={lane:0,tag:c.tag,payload:c.payload,callback:null,next:null});l:{var x=l,D=c;d=t;var J=e;switch(D.tag){case 1:if(x=D.payload,typeof x=="function"){E=x.call(J,E,d);break l}E=x;break l;case 3:x.flags=x.flags&-65537|128;case 0:if(x=D.payload,d=typeof x=="function"?x.call(J,E,d):x,d==null)break l;E=W({},E,d);break l;case 2:Ae=!0}}d=c.callback,d!==null&&(l.flags|=64,h&&(l.flags|=8192),h=a.callbacks,h===null?a.callbacks=[d]:h.push(d))}else h={lane:d,tag:c.tag,payload:c.payload,callback:c.callback,next:null},g===null?(v=g=h,f=E):g=g.next=h,i|=d;if(c=c.next,c===null){if(c=a.shared.pending,c===null)break;h=c,c=h.next,h.next=null,a.lastBaseUpdate=h,a.shared.pending=null}}while(!0);g===null&&(f=E),a.baseState=f,a.firstBaseUpdate=v,a.lastBaseUpdate=g,n===null&&(a.shared.lanes=0),Ye|=i,l.lanes=i,l.memoizedState=E}}function Fo(l,t){if(typeof l!="function")throw Error(m(191,l));l.call(t)}function ko(l,t){var e=l.callbacks;if(e!==null)for(l.callbacks=null,l=0;ln?n:8;var i=R.T,c={};c.types=i!==null?i.types:null,R.T=c,lf(l,!1,t,e);try{var f=a(),v=R.S;if(v!==null&&v(c,f),f!==null&&typeof f=="object"&&typeof f.then=="function"){var g=Dv(f,u);Ba(l,t,g,gt(l))}else Ba(l,t,u,gt(l))}catch(E){Ba(l,t,{then:function(){},status:"rejected",reason:E},gt())}finally{V.p=n,i!==null&&c.types!==null&&(i.types=c.types),R.T=i}}function Yv(){}function Ic(l,t,e,u){if(l.tag!==5)throw Error(m(476));var a=Md(l).queue;pd(l,a,t,le,e===null?Yv:function(){return Dd(l),e(u)})}function Md(l){var t=l.memoizedState;if(t!==null)return t;t={memoizedState:le,baseState:le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:de,lastRenderedState:le},next:null};var e={};return t.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:de,lastRenderedState:e},next:null},l.memoizedState=t,l=l.alternate,l!==null&&(l.memoizedState=t),t}function Dd(l){var t=Md(l);t.next===null&&(t=l.alternate.memoizedState),Ba(l,t.next.queue,{},gt())}function Pc(){return Gl(ia)}function Ud(){return Ol().memoizedState}function Cd(){return Ol().memoizedState}function Bv(l){for(var t=l.return;t!==null;){switch(t.tag){case 24:case 3:var e=gt();l=pe(e);var u=Me(t,l,e);u!==null&&(ut(u,t,e),Ua(u,t,e)),t={cache:Ac()},l.payload=t;return}t=t.return}}function qv(l,t,e){var u=gt();e={lane:u,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null},kn(l)?Hd(t,e):(e=Sc(l,t,e,u),e!==null&&(ut(e,l,u),jd(e,t,u)))}function Rd(l,t,e){var u=gt();Ba(l,t,e,u)}function Ba(l,t,e,u){var a={lane:u,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null};if(kn(l))Hd(t,a);else{var n=l.alternate;if(l.lanes===0&&(n===null||n.lanes===0)&&(n=t.lastRenderedReducer,n!==null))try{var i=t.lastRenderedState,c=n(i,e);if(a.hasEagerState=!0,a.eagerState=c,mt(c,i))return pn(l,t,a,0),gl===null&&An(),!1}catch{}finally{}if(e=Sc(l,t,a,u),e!==null)return ut(e,l,u),jd(e,t,u),!0}return!1}function lf(l,t,e,u){if(u={lane:2,revertLane:wf(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},kn(l)){if(t)throw Error(m(479))}else t=Sc(l,e,u,2),t!==null&&ut(t,l,2)}function kn(l){var t=l.alternate;return l===K||t!==null&&t===K}function Hd(l,t){Gu=Ln=!0;var e=l.pending;e===null?t.next=t:(t.next=e.next,e.next=t),l.pending=t}function jd(l,t,e){if((e&4194048)!==0){var u=t.lanes;u&=l.pendingLanes,e|=u,t.lanes=e,js(l,e)}}var In={readContext:Gl,use:Jn,useCallback:Nl,useContext:Nl,useEffect:Nl,useImperativeHandle:Nl,useLayoutEffect:Nl,useInsertionEffect:Nl,useMemo:Nl,useReducer:Nl,useRef:Nl,useState:Nl,useDebugValue:Nl,useDeferredValue:Nl,useTransition:Nl,useSyncExternalStore:Nl,useId:Nl,useHostTransitionStatus:Nl,useFormState:Nl,useActionState:Nl,useOptimistic:Nl,useMemoCache:Nl,useCacheRefresh:Nl,useEffectEvent:Nl},Yd={readContext:Gl,use:Jn,useCallback:function(l,t){return $l().memoizedState=[l,t===void 0?null:t],l},useContext:Gl,useEffect:bd,useImperativeHandle:function(l,t,e){e=e!=null?e.concat([l]):null,Wn(4194308,4,_d.bind(null,t,l),e)},useLayoutEffect:function(l,t){return Wn(4194308,4,l,t)},useInsertionEffect:function(l,t){Wn(4,2,l,t)},useMemo:function(l,t){var e=$l();t=t===void 0?null:t;var u=l();if(du){be(!0);try{l()}finally{be(!1)}}return e.memoizedState=[u,t],u},useReducer:function(l,t,e){var u=$l();if(e!==void 0){var a=e(t);if(du){be(!0);try{e(t)}finally{be(!1)}}}else a=t;return u.memoizedState=u.baseState=a,l={pending:null,lanes:0,dispatch:null,lastRenderedReducer:l,lastRenderedState:a},u.queue=l,l=l.dispatch=qv.bind(null,K,l),[u.memoizedState,l]},useRef:function(l){var t=$l();return l={current:l},t.memoizedState=l},useState:function(l){l=Jc(l);var t=l.queue,e=Rd.bind(null,K,t);return t.dispatch=e,[l.memoizedState,e]},useDebugValue:Fc,useDeferredValue:function(l,t){var e=$l();return kc(e,l,t)},useTransition:function(){var l=Jc(!1);return l=pd.bind(null,K,l.queue,!0,!1),$l().memoizedState=l,[!1,l]},useSyncExternalStore:function(l,t,e){var u=K,a=$l();if($){if(e===void 0)throw Error(m(407));e=e()}else{if(e=t(),gl===null)throw Error(m(349));(I&127)!==0||ud(u,t,e)}a.memoizedState=e;var n={value:e,getSnapshot:t};return a.queue=n,bd(nd.bind(null,u,n,l),[l]),u.flags|=2048,Xu(9,{destroy:void 0},ad.bind(null,u,n,e,t),null),e},useId:function(){var l=$l(),t=gl.identifierPrefix;if($){var e=Lt,u=Vt;e=(u&~(1<<32-ot(u)-1)).toString(32)+e,t="_"+t+"R_"+e,e=wn++,0<\/script>",n=n.removeChild(n.firstChild);break;case"select":n=typeof u.is=="string"?i.createElement("select",{is:u.is}):i.createElement("select"),u.multiple?n.multiple=!0:u.size&&(n.size=u.size);break;default:n=typeof u.is=="string"?i.createElement(a,{is:u.is}):i.createElement(a)}}n[ql]=t,n[Il]=u;l:for(i=t.child;i!==null;){if(i.tag===5||i.tag===6)n.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===t)break l;for(;i.sibling===null;){if(i.return===null||i.return===t)break l;i=i.return}i.sibling.return=i.return,i=i.sibling}t.stateNode=n;l:switch(Vl(n,a,u),a){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break l;case"img":u=!0;break l;default:u=!1}u&&re(t)}}return Tl(t),t.subtreeFlags&=-33554433,vf(t,t.type,l===null?null:l.memoizedProps,t.pendingProps,e),null;case 6:if(l&&t.stateNode!=null)l.memoizedProps!==u&&re(t);else{if(typeof u!="string"&&t.stateNode===null)throw Error(m(166));if(l=ge.current,ju(t)){if(l=t.stateNode,e=t.memoizedProps,u=null,a=Hl,a!==null)switch(a.tag){case 27:case 5:u=a.memoizedProps}l[ql]=t,l=!!(l.nodeValue===e||u!==null&&u.suppressHydrationWarning===!0||nr(l.nodeValue,e)),l||Ne(t,!0)}else l=Fa(l).createTextNode(u),l[ql]=t,t.stateNode=l}return Tl(t),null;case 31:if(e=t.memoizedState,l===null||l.memoizedState!==null){if(u=ju(t),e!==null){if(l===null){if(!u)throw Error(m(318));if(l=t.memoizedState,l=l!==null?l.dehydrated:null,!l)throw Error(m(557));l[ql]=t}else eu(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Tl(t),l=!1}else e=Nc(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=e),l=!0;if(!l)return t.flags&256?(rt(t),t):(rt(t),null);if((t.flags&128)!==0)throw Error(m(558))}return Tl(t),null;case 13:if(u=t.memoizedState,l===null||l.memoizedState!==null&&l.memoizedState.dehydrated!==null){if(a=ju(t),u!==null&&u.dehydrated!==null){if(l===null){if(!a)throw Error(m(318));if(a=t.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(m(317));a[ql]=t}else eu(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Tl(t),a=!1}else a=Nc(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(rt(t),t):(rt(t),null)}return rt(t),(t.flags&128)!==0?(t.lanes=e,t):(e=u!==null,l=l!==null&&l.memoizedState!==null,e&&(u=t.child,a=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(a=u.alternate.memoizedState.cachePool.pool),n=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(n=u.memoizedState.cachePool.pool),n!==a&&(u.flags|=2048)),e!==l&&e&&(t.child.flags|=8192),ai(t,t.updateQueue),Tl(t),null);case 4:return bu(),l===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,Tl(t),null;case 10:return se(t.type),Tl(t),null;case 19:if(qc(t),u=t.memoizedState,u===null)return Tl(t),null;if(a=(t.flags&128)!==0,n=u.rendering,n===null)if(a)Ga(u,!1);else{if(xl!==0||l!==null&&(l.flags&128)!==0)for(l=t.child;l!==null;){if(n=Vn(l),n!==null){for(t.flags|=128,Ga(u,!1),l=n.updateQueue,t.updateQueue=l,ai(t,l),t.subtreeFlags=0,l=e,e=t.child;e!==null;)Ro(e,l),e=e.sibling;return Ha(t,Xl.current&1|2),$&&ce(t,u.treeForkCount),t.child}l=l.sibling}u.tail!==null&&ft()>hi&&(t.flags|=128,a=!0,Ga(u,!1),t.lanes=4194304)}else{if(!a)if(l=Vn(n),l!==null){if(t.flags|=128,a=!0,l=l.updateQueue,t.updateQueue=l,ai(t,l),Ga(u,!0),u.tail===null&&u.tailMode!=="collapsed"&&u.tailMode!=="visible"&&!n.alternate&&!$)return Tl(t),null}else 2*ft()-u.renderingStartTime>hi&&e!==536870912&&(t.flags|=128,a=!0,Ga(u,!1),t.lanes=4194304);u.isBackwards?(n.sibling=t.child,t.child=n):(l=u.last,l!==null?l.sibling=n:t.child=n,u.last=n)}if(u.tail!==null){l=u.tail;l:{for(e=l;e!==null;){if(e.alternate!==null){e=!1;break l}e=e.sibling}e=!0}return u.rendering=l,u.tail=l.sibling,u.renderingStartTime=ft(),l.sibling=null,n=Xl.current,n=a?n&1|2:n&1,u.tailMode==="visible"||u.tailMode==="collapsed"||!e||$?Ha(t,n):(e=n,Sl(Ql,t),Sl(Xl,e),Kl===null&&(Kl=t)),$&&ce(t,u.treeForkCount),l}return Tl(t),null;case 22:case 23:return rt(t),Yc(),u=t.memoizedState!==null,l!==null?l.memoizedState!==null!==u&&(t.flags|=8192):u&&(t.flags|=8192),u?(e&536870912)!==0&&(t.flags&128)===0&&(Tl(t),t.subtreeFlags&6&&(t.flags|=8192)):Tl(t),e=t.updateQueue,e!==null&&ai(t,e.retryQueue),e=null,l!==null&&l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(e=l.memoizedState.cachePool.pool),u=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(u=t.memoizedState.cachePool.pool),u!==e&&(t.flags|=2048),l!==null&&Bl(cu),null;case 24:return e=null,l!==null&&(e=l.memoizedState.cache),t.memoizedState.cache!==e&&(t.flags|=2048),se(Al),Tl(t),null;case 25:return null;case 30:return t.flags|=33554432,Tl(t),null}throw Error(m(156,t.tag))}function wv(l,t){switch(zc(t),t.tag){case 1:return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 3:return se(Al),bu(),l=t.flags,(l&65536)!==0&&(l&128)===0?(t.flags=l&-65537|128,t):null;case 26:case 27:case 5:return sn(t),null;case 31:if(t.memoizedState!==null){if(rt(t),t.alternate===null)throw Error(m(340));eu()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 13:if(rt(t),l=t.memoizedState,l!==null&&l.dehydrated!==null){if(t.alternate===null)throw Error(m(340));eu()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 19:return qc(t),l=t.flags,l&65536?(t.flags=l&-65537|128,l=t.memoizedState,l!==null&&(l.rendering=null,l.tail=null),t.flags|=4,t):null;case 4:return bu(),null;case 10:return se(t.type),null;case 22:case 23:return rt(t),Yc(),l!==null&&Bl(cu),l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 24:return se(Al),null;case 25:return null;default:return null}}function cm(l,t){switch(zc(t),t.tag){case 3:se(Al),bu();break;case 26:case 27:case 5:sn(t);break;case 4:bu();break;case 31:t.memoizedState!==null&&rt(t);break;case 13:rt(t);break;case 19:qc(t);break;case 10:se(t.type);break;case 22:case 23:rt(t),Yc(),l!==null&&Bl(cu);break;case 24:se(Al)}}function Qa(l,t){try{var e=t.updateQueue,u=e!==null?e.lastEffect:null;if(u!==null){var a=u.next;e=a;do{if((e.tag&l)===l){u=void 0;var n=e.create,i=e.inst;u=n(),i.destroy=u}e=e.next}while(e!==a)}}catch(c){ml(t,t.return,c)}}function Re(l,t,e){try{var u=t.updateQueue,a=u!==null?u.lastEffect:null;if(a!==null){var n=a.next;u=n;do{if((u.tag&l)===l){var i=u.inst,c=i.destroy;if(c!==void 0){i.destroy=void 0,a=t;var f=e,v=c;try{v()}catch(g){ml(a,f,g)}}}u=u.next}while(u!==n)}}catch(g){ml(t,t.return,g)}}function fm(l){var t=l.updateQueue;if(t!==null){var e=l.stateNode;try{ko(t,e)}catch(u){ml(l,l.return,u)}}}function sm(l,t,e){e.props=mu(l.type,l.memoizedProps),e.state=l.memoizedState;try{e.componentWillUnmount()}catch(u){ml(l,t,u)}}function wt(l,t){try{var e=l.ref;if(e!==null){switch(l.tag){case 26:case 27:case 5:var u=l.stateNode;break;case 30:var a=l.stateNode,n=ae(l.memoizedProps,a);(a.ref===null||a.ref.name!==n)&&(a.ref=hr(n)),u=a.ref;break;case 7:if(l.stateNode===null){var i=new St(l);S(l.child,!1,jy,i,void 0,void 0),l.stateNode=i}u=l.stateNode;break;default:u=l.stateNode}typeof e=="function"?l.refCleanup=e(u):e.current=u}}catch(c){ml(l,t,c)}}function Zl(l,t){var e=l.ref,u=l.refCleanup;if(e!==null)if(typeof u=="function")try{u()}catch(a){ml(l,t,a)}finally{l.refCleanup=null,l=l.alternate,l!=null&&(l.refCleanup=null)}else if(typeof e=="function")try{e(null)}catch(a){ml(l,t,a)}else e.current=null}function ni(l,t){if((l.tag===5||l.tag===27||l.tag===6)&&l.alternate===null&&t!==null)for(var e=0;e title"))),Vl(u,t,e),u[ql]=l,Rl(u),t=u;break l;case"link":if(n=Rr("link","href",a).get(t+(e.href||""))){for(i=0;iJ&&(i=J,J=D,D=i);var r=Eo(c,D),s=Eo(c,J);if(r&&s&&(h.rangeCount!==1||h.anchorNode!==r.node||h.anchorOffset!==r.offset||h.focusNode!==s.node||h.focusOffset!==s.offset)){var y=E.createRange();y.setStart(r.node,r.offset),h.removeAllRanges(),D>J?(h.addRange(y),h.extend(s.node,s.offset)):(y.setEnd(s.node,s.offset),h.addRange(y))}}}}for(E=[],h=c;h=h.parentNode;)h.nodeType===1&&E.push({element:h,left:h.scrollLeft,top:h.scrollTop});for(typeof c.focus=="function"&&c.focus(),c=0;ce?32:e,R.T=null,e=jf,jf=null;var n=jt,i=kt;if(_l=0,hu=jt=null,kt=0,(fl&6)!==0)throw Error(m(331));var c=fl;if(fl|=4,Cm(n.current),Mm(n,n.current,i,e),fl=c,Ja(0,!1),st&&typeof st.onPostCommitFiberRoot=="function")try{st.onPostCommitFiberRoot(da,n)}catch{}return!0}finally{V.p=a,R.T=u,Jm(l,t)}}function $m(l,t,e){t=_t(e,t),t=uf(l.stateNode,t,2),l=Me(l,t,2),l!==null&&(ra(l,2),It(l))}function ml(l,t,e){if(l.tag===3)$m(l,l,e);else for(;t!==null;){if(t.tag===3){$m(t,l,e);break}else if(t.tag===1){var u=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(Be===null||!Be.has(u))){l=_t(e,l),e=Ld(2),u=Me(t,e,2),u!==null&&(wd(e,u,t,l),ra(u,2),It(u));break}}t=t.return}}function Zf(l,t,e){var u=l.pingCache;if(u===null){u=l.pingCache=new Wv;var a=new Set;u.set(t,a)}else a=u.get(t),a===void 0&&(a=new Set,u.set(t,a));a.has(e)||(Cf=!0,a.add(e),l=uy.bind(null,l,t,e),t.then(l,l))}function uy(l,t,e){var u=l.pingCache;u!==null&&u.delete(t),l.pingedLanes|=l.suspendedLanes&e,l.warmLanes&=~e,gl===l&&(I&e)===e&&((xl===4||xl===3&&(I&62914560)===I&&300>ft()-yi)&&(fl&2)===0?Iu(l,0):vi|=e,Ju===I&&(Ju=0)),It(l)}function Wm(l,t){t===0&&(t=Rs()),l=lu(l,t),l!==null&&(ra(l,t),It(l))}function ay(l){var t=l.memoizedState,e=0;t!==null&&(e=t.retryLane),Wm(l,e)}function ny(l,t){var e=0;switch(l.tag){case 31:case 13:var u=l.stateNode,a=l.memoizedState;a!==null&&(e=a.retryLane);break;case 19:u=l.stateNode;break;case 22:u=l.stateNode._retryCache;break;default:throw Error(m(314))}u!==null&&u.delete(t),Wm(l,e)}function iy(l,t){return Li(l,t)}var la=null,ta=null,Vf=!1,_i=!1,Lf=!1,Ge=0;function It(l){l!==ta&&l.next===null&&(ta===null?la=ta=l:ta=ta.next=l),_i=!0,Vf||(Vf=!0,fy())}function Ja(l,t){if(!Lf&&_i){Lf=!0;do for(var e=!1,u=la;u!==null;){if(l!==0){var a=u.pendingLanes;if(a===0)var n=0;else{var i=u.suspendedLanes,c=u.pingedLanes;n=(1<<31-ot(42|l)+1)-1,n&=a&~(i&~c),n=n&201326741?n&201326741|1:n?n|2:0}n!==0&&(e=!0,Pm(u,n))}else n=I,n=vn(u,u===gl?n:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),(n&3)===0||ma(u,n)||(e=!0,Pm(u,n));u=u.next}while(e);Lf=!1}}function cy(){Fm()}function Fm(){_i=Vf=!1;var l=0;Ge!==0&&by()&&(l=Ge);for(var t=ft(),e=null,u=la;u!==null;){var a=u.next,n=km(u,t);n===0?(u.next=null,e===null?la=a:e.next=a,a===null&&(ta=e)):(e=u,(l!==0||(n&3)!==0)&&(_i=!0)),u=a}_l!==0&&_l!==5||Ja(l),Ge!==0&&(Ge=0)}function km(l,t){for(var e=l.suspendedLanes,u=l.pingedLanes,a=l.expirationTimes,n=l.pendingLanes&-62914561;0c)break;var g=f.transferSize,E=f.initiatorType;g&&ir(E)&&(f=f.responseEnd,i+=g*(fpi){D.length=x;break}y=new Promise(xy.bind(y)),D.push(y)}}}if(0"u"?null:document;function Mr(l,t,e){var u=ua;if(u&&typeof t=="string"&&t){var a=Et(t);a='link[rel="'+l+'"][href="'+a+'"]',typeof e=="string"&&(a+='[crossorigin="'+e+'"]'),pr.has(a)||(pr.add(a),l={rel:l,crossOrigin:e,href:t},u.querySelector(a)===null&&(t=u.createElement("link"),Vl(t,"link",l),Rl(t),u.head.appendChild(t)))}}function Ly(l){ye.D(l),Mr("dns-prefetch",l,null)}function wy(l,t){ye.C(l,t),Mr("preconnect",l,t)}function Ky(l,t,e){ye.L(l,t,e);var u=ua;if(u&&l&&t){var a='link[rel="preload"][as="'+Et(t)+'"]';t==="image"&&e&&e.imageSrcSet?(a+='[imagesrcset="'+Et(e.imageSrcSet)+'"]',typeof e.imageSizes=="string"&&(a+='[imagesizes="'+Et(e.imageSizes)+'"]')):a+='[href="'+Et(l)+'"]';var n=a;switch(t){case"style":n=aa(l);break;case"script":n=na(l)}if(!(Mt.has(n)||(l=W({rel:"preload",href:t==="image"&&e&&e.imageSrcSet?void 0:l,as:t},e),Mt.set(n,l),u.querySelector(a)!==null||t==="style"&&u.querySelector(Ia(n))||t==="script"&&u.querySelector(Pa(n))))){var i=u.createElement("link");Vl(i,"link",l),t==="style"&&(i[yn]=!0,i.onload=i.onerror=function(){Xs(i)}),Rl(i),u.head.appendChild(i)}}}function Jy(l,t){ye.m(l,t);var e=ua;if(e&&l){var u=t&&typeof t.as=="string"?t.as:"script",a='link[rel="modulepreload"][as="'+Et(u)+'"][href="'+Et(l)+'"]',n=a;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":n=na(l)}if(!Mt.has(n)&&(l=W({rel:"modulepreload",href:l},t),Mt.set(n,l),e.querySelector(a)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(e.querySelector(Pa(n)))return}u=e.createElement("link"),Vl(u,"link",l),Rl(u),e.head.appendChild(u)}}}function $y(l,t,e){ye.S(l,t,e);var u=ua;if(u&&l){var a=zu(u).hoistableStyles,n=aa(l);t=t||"default";var i=a.get(n);if(!i){var c={loading:0,preload:null};if(i=u.querySelector(Ia(n)))c.loading=5;else{l=W({rel:"stylesheet",href:l,"data-precedence":t},e),(e=Mt.get(n))&&ds(l,e);var f=i=u.createElement("link");Rl(f),Vl(f,"link",l),f._p=new Promise(function(v,g){f.onload=v,f.onerror=g}),f.addEventListener("load",function(){c.loading|=1}),f.addEventListener("error",function(){c.loading|=2}),c.loading|=4,Oi(i,t,u)}i={type:"stylesheet",instance:i,count:1,state:c},a.set(n,i)}}}function Wy(l,t){ye.X(l,t);var e=ua;if(e&&l){var u=zu(e).hoistableScripts,a=na(l),n=u.get(a);n||(n=e.querySelector(Pa(a)),n||(l=W({src:l,async:!0},t),(t=Mt.get(a))&&ms(l,t),n=e.createElement("script"),Rl(n),Vl(n,"link",l),e.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(a,n))}}function Fy(l,t){ye.M(l,t);var e=ua;if(e&&l){var u=zu(e).hoistableScripts,a=na(l),n=u.get(a);n||(n=e.querySelector(Pa(a)),n||(l=W({src:l,async:!0,type:"module"},t),(t=Mt.get(a))&&ms(l,t),n=e.createElement("script"),Rl(n),Vl(n,"link",l),e.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(a,n))}}function Dr(l,t,e,u){var a=(a=ge.current)?ka(a):null;if(!a)throw Error(m(446));switch(l){case"meta":case"title":return null;case"style":return typeof e.precedence=="string"&&typeof e.href=="string"?(e=aa(e.href),t=zu(a).hoistableStyles,u=t.get(e),u||(u={type:"style",instance:null,count:0,state:null},t.set(e,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(e.rel==="stylesheet"&&typeof e.href=="string"&&typeof e.precedence=="string"){l=aa(e.href);var n=zu(a).hoistableStyles,i=n.get(l);if(i||(a=a.ownerDocument||a,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},n.set(l,i),(n=a.querySelector(Ia(l)))?n._p||(i.instance=n,i.state.loading=5):(n=Mt.get(l),n||(n={rel:"preload",as:"style",href:e.href,crossOrigin:e.crossOrigin,integrity:e.integrity,media:e.media,hrefLang:e.hrefLang,referrerPolicy:e.referrerPolicy},Mt.set(l,n)),ky(a,l,n,i.state))),t&&u===null)throw Error(m(528,""));return i}if(t&&u!==null)throw Error(m(529,""));return null;case"script":return t=e.async,e=e.src,typeof e=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(e=na(e),t=zu(a).hoistableScripts,u=t.get(e),u||(u={type:"script",instance:null,count:0,state:null},t.set(e,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(m(444,l))}}function aa(l){return'href="'+Et(l)+'"'}function Ia(l){return'link[rel="stylesheet"]['+l+"]"}function Ur(l){return W({},l,{"data-precedence":l.precedence,precedence:null})}function ky(l,t,e,u){if(t=l.querySelector('link[rel="preload"][as="style"]['+t+"]")){if(t[yn]!==!0){u.loading=1;return}}else t=l.createElement("link"),t[yn]=!0,t.onload=t.onerror=Xs.bind(null,t),Vl(t,"link",e),Rl(t),l.head.appendChild(t);u.preload=t,t.addEventListener("load",function(){return u.loading|=1}),t.addEventListener("error",function(){return u.loading|=2})}function na(l){return'[src="'+Et(l)+'"]'}function Pa(l){return"script[async]"+l}function Cr(l,t,e){if(t.count++,t.instance===null)switch(t.type){case"style":var u=l.querySelector('style[data-href~="'+Et(e.href)+'"]');if(u)return t.instance=u,Rl(u),u;var a=W({},e,{"data-href":e.href,"data-precedence":e.precedence,href:null,precedence:null});return u=(l.ownerDocument||l).createElement("style"),Rl(u),Vl(u,"style",a),Oi(u,e.precedence,l),t.instance=u;case"stylesheet":a=aa(e.href);var n=l.querySelector(Ia(a));if(n)return t.state.loading|=4,t.instance=n,Rl(n),n;u=Ur(e),(a=Mt.get(a))&&ds(u,a),n=(l.ownerDocument||l).createElement("link"),Rl(n);var i=n;return i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),Vl(n,"link",u),t.state.loading|=4,Oi(n,e.precedence,l),t.instance=n;case"script":return n=na(e.src),(a=l.querySelector(Pa(n)))?(t.instance=a,Rl(a),a):(u=e,(a=Mt.get(n))&&(u=W({},e),ms(u,a)),l=l.ownerDocument||l,a=l.createElement("script"),Rl(a),Vl(a,"link",u),l.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(m(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(u=t.instance,t.state.loading|=4,Oi(u,e.precedence,l));return t.instance}function Oi(l,t,e){for(var u=e.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=u.length?u[u.length-1]:null,n=a,i=0;i title"):null)}function Iy(l,t,e){if(e===1||t.itemProp!=null)return!1;switch(l){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return l=t.disabled,typeof t.precedence=="string"&&l==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function Hr(l,t){return l==="img"&&t.src!=null&&t.src!==""&&t.onLoad==null&&t.loading!=="lazy"}function jr(l){return!(l.type==="stylesheet"&&(l.state.loading&3)===0)}function Yr(l){return(l.width||100)*(l.height||100)*(typeof devicePixelRatio=="number"?devicePixelRatio:1)*.25}function Br(l,t){typeof t.decode=="function"&&(l.imgCount++,t.complete||(l.imgBytes+=Yr(t),l.suspenseyImages.push(t)),l=th.bind(l),t.decode().then(l,l))}function Py(l,t,e,u){if(e.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&(e.state.loading&4)===0){if(e.instance===null){var a=aa(u.href),n=t.querySelector(Ia(a));if(n){t=n._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(l.count++,l=ln.bind(l),t.then(l,l)),e.state.loading|=4,e.instance=n,Rl(n);return}n=t.ownerDocument||t,u=Ur(u),(a=Mt.get(a))&&ds(u,a),n=n.createElement("link"),Rl(n);var i=n;i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),Vl(n,"link",u),e.instance=n}l.stylesheets===null&&(l.stylesheets=new Map),l.stylesheets.set(e,t),(t=e.state.preload)&&(e.state.loading&3)===0&&(l.count++,e=ln.bind(l),t.addEventListener("load",e),t.addEventListener("error",e))}}var pi=0;function lh(l,t){return l.stylesheets&&l.count===0&&Di(l,l.stylesheets),0pi?50:800)+t);return l.unsuspend=e,function(){l.unsuspend=null,clearTimeout(u),clearTimeout(a)}}:null}function qr(l){if(l.count===0&&(l.imgCount===0||!l.waitingForImages)){if(l.stylesheets)Di(l,l.stylesheets);else if(l.unsuspend){var t=l.unsuspend;l.unsuspend=null,t()}}}function ln(){this.count--,qr(this)}function th(){this.imgCount--,qr(this)}var Mi=null;function Di(l,t){l.stylesheets=null,l.unsuspend!==null&&(l.count++,Mi=new Map,t.forEach(eh,l),Mi=null,ln.call(l))}function eh(l,t){if(!(t.state.loading&4)){var e=Mi.get(l);if(e)var u=e.get(null);else{e=new Map,Mi.set(l,e);for(var a=l.querySelectorAll("link[data-precedence],style[data-precedence]"),n=0;n"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(b)}catch(A){console.error(A)}}return b(),zs.exports=Sh(),zs.exports}var Th=bh();const Eh=o0(Th),f0=b=>{let A;const _=new Set,m=(ll,U)=>{const S=typeof ll=="function"?ll(A):ll;if(!Object.is(S,A)){const B=A;A=U??(typeof S!="object"||S===null)?S:Object.assign({},A,S),_.forEach(Z=>Z(A,B))}},p=()=>A,w={setState:m,getState:p,getInitialState:()=>C,subscribe:ll=>(_.add(ll),()=>_.delete(ll))},C=A=b(m,p,w);return w},zh=(b=>b?f0(b):f0),_h=b=>b;function Nh(b,A=_h){const _=Bi.useSyncExternalStore(b.subscribe,Bi.useCallback(()=>A(b.getState()),[b,A]),()=>A(b.getInitialState()));return Bi.useDebugValue(_),_}const s0=b=>{const A=zh(b),_=m=>Nh(A,m);return Object.assign(_,A),_},xh=(b=>b?s0(b):s0),d0=localStorage.getItem("hl_theme")||"catppuccin",Oh=localStorage.getItem("hl_route_mode")||"auto";typeof document<"u"&&document.documentElement.setAttribute("data-theme",d0);const sa=xh((b,A)=>({theme:d0,routeMode:Oh,showAgyModal:!1,showCmdPalette:!1,toast:"",actionLoading:!1,telemetry:{mini:{chip:"Apple M6 (12核)",ip:"192.168.31.164",tailscale_ip:"100.108.205.40",cpu_pct:6.5,load_1m:.85,mem_used_gb:11.8,mem_total_gb:24,mem_pct:49.2,disk_used_gb:59.9,disk_total_gb:460.4,disk_pct:13,uptime:"运行中",agy_tmux:!0},nas:{ip:"192.168.31.185",online:!0,mounted:!0,total_tb:19.94,used_tb:3.36,free_tb:16.58,pct:16.8,latest_backup:"11-06 23:17"},network:{home_wan_ip:"124.90.142.21",ai_policy:"Ai平台 → 狮城节点",sg_node:"233boy-sea",sg_egress_ip:"104.43.105.243",sg_delay_ms:68},services:{agy:!0,vaultwarden:!0,nas:!0,clash:!0,router:!0,uptime:!0}},setTheme:_=>{localStorage.setItem("hl_theme",_),document.documentElement.setAttribute("data-theme",_),b({theme:_})},setRouteMode:_=>{localStorage.setItem("hl_route_mode",_),b({routeMode:_})},setShowAgyModal:_=>b({showAgyModal:_}),setShowCmdPalette:_=>b({showCmdPalette:_}),showToast:_=>{b({toast:_}),setTimeout(()=>{A().toast===_&&b({toast:""})},3e3)},fetchTelemetry:async()=>{try{const _=await fetch("/api/telemetry");if(_.ok){const m=await _.json();b({telemetry:m})}}catch{}},triggerAction:async(_,m)=>{const{showToast:p,fetchTelemetry:q}=A();b({actionLoading:!0}),p(m);try{const w=await(await fetch(`/api/action/${_}`,{method:"POST"})).json();p(w.message||"操作已完成"),await q()}catch{p("请求失败,请稍后重试")}finally{b({actionLoading:!1})}},copyCmd:async(_,m)=>{const{showToast:p}=A();try{await navigator.clipboard.writeText(_),p(`已复制「${m}」: ${_}`)}catch{p(_)}},getEffectiveMode:()=>{const{routeMode:_}=A();if(_!=="auto")return _;const m=window.location.hostname;return m.startsWith("192.168.")||m.startsWith("100.")||m==="localhost"?"lan":m.includes(".home.961504.xyz")||window.location.port==="10443"?"home10443":"edge443"}}));/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Ah=b=>b.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),m0=(...b)=>b.filter((A,_,m)=>!!A&&A.trim()!==""&&m.indexOf(A)===_).join(" ").trim();/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */var ph={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Mh=at.forwardRef(({color:b="currentColor",size:A=24,strokeWidth:_=2,absoluteStrokeWidth:m,className:p="",children:q,iconNode:nl,...w},C)=>at.createElement("svg",{ref:C,...ph,width:A,height:A,stroke:b,strokeWidth:m?Number(_)*24/Number(A):_,className:m0("lucide",p),...w},[...nl.map(([ll,U])=>at.createElement(ll,U)),...Array.isArray(q)?q:[q]]));/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const r0=(b,A)=>{const _=at.forwardRef(({className:m,...p},q)=>at.createElement(Mh,{ref:q,iconNode:A,className:m0(`lucide-${Ah(b)}`,m),...p}));return _.displayName=`${b}`,_};/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Dh=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]],v0=r0("Search",Dh);/** + * @license lucide-react v0.475.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Uh=[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]],Ch=r0("Terminal",Uh),Rh=[{id:"zinc-dark",label:"深色极客",dot:"#18181b"},{id:"zinc-light",label:"浅色纯净",dot:"#f8fafc"},{id:"catppuccin",label:"Catppuccin",dot:"#cba6f7"},{id:"nord",label:"Nord",dot:"#88c0d0"}],Hh=[{id:"auto",label:"智能路由"},{id:"edge443",label:"443 免端口"},{id:"home10443",label:"10443 家宽"},{id:"lan",label:"LAN 局域网"}],jh=()=>{const{theme:b,routeMode:A,telemetry:_,setTheme:m,setRouteMode:p,setShowAgyModal:q,setShowCmdPalette:nl}=sa();return z.jsx("header",{className:"border-b hl-border sticky top-0 z-30 backdrop-blur-md",style:{backgroundColor:"color-mix(in srgb, var(--bg-page) 86%, transparent)"},children:z.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3 flex flex-wrap items-center justify-between gap-3",children:[z.jsxs("div",{className:"flex flex-wrap items-center gap-2.5 sm:gap-3",children:[z.jsxs("div",{className:"flex items-center gap-2.5 pr-1",children:[z.jsx("img",{src:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/apple.png",alt:"Mac mini",className:"w-6 h-6 rounded"}),z.jsx("span",{className:"font-semibold text-sm tracking-tight",children:"HomeLab"}),z.jsx("span",{className:"w-2 h-2 rounded-full",style:{backgroundColor:"var(--success)"},title:"全屋 4 节点在线"})]}),z.jsxs("div",{className:"hidden xl:flex items-center gap-2 text-xs font-mono-num",children:[z.jsxs("div",{className:"hl-pill px-2.5 py-1 flex items-center gap-2",title:"Apple M6 12核处理器负载",children:[z.jsx("span",{style:{color:"var(--text-muted)"},children:"M6 CPU"}),z.jsx("div",{className:"w-12 h-1.5 rounded-full hl-muted overflow-hidden",children:z.jsx("div",{className:"h-full hl-bar-fill",style:{width:`${Math.max(5,_.mini.cpu_pct)}%`}})}),z.jsxs("span",{className:"font-medium",children:[_.mini.cpu_pct,"%"]})]}),z.jsxs("div",{className:"hl-pill px-2.5 py-1 flex items-center gap-2",title:"Mac mini 24GB 统一内存",children:[z.jsx("span",{style:{color:"var(--text-muted)"},children:"RAM"}),z.jsx("div",{className:"w-12 h-1.5 rounded-full hl-muted overflow-hidden",children:z.jsx("div",{className:"h-full hl-bar-fill",style:{width:`${Math.max(5,_.mini.mem_pct)}%`}})}),z.jsxs("span",{className:"font-medium",children:[_.mini.mem_used_gb,"G"]})]}),z.jsxs("div",{className:"hl-pill px-2.5 py-1 flex items-center gap-2",title:"极空间 Z4 20TB 存储阵列",children:[z.jsx("span",{style:{color:"var(--text-muted)"},children:"NAS 余量"}),z.jsx("div",{className:"w-12 h-1.5 rounded-full hl-muted overflow-hidden",children:z.jsx("div",{className:"h-full hl-bar-fill-green",style:{width:`${Math.max(5,_.nas.pct)}%`}})}),z.jsxs("span",{className:"font-medium",style:{color:"var(--success)"},children:[_.nas.free_tb," TB"]})]}),z.jsxs("div",{className:"hl-pill px-2.5 py-1 flex items-center gap-1.5",title:"AGY 锁定新加坡 Azure 专线出口",children:[z.jsx("span",{className:"w-1.5 h-1.5 rounded-full",style:{backgroundColor:"var(--success)"}}),z.jsx("span",{style:{color:"var(--text-muted)"},children:"SG 专线"}),z.jsx("span",{className:"font-medium",children:_.network.sg_delay_ms>0?`${_.network.sg_delay_ms}ms`:"直连"})]})]})]}),z.jsxs("div",{className:"flex items-center gap-2",children:[z.jsxs("button",{onClick:()=>nl(!0),className:"hl-btn-outline px-2.5 py-1 text-xs flex items-center gap-3 cursor-pointer",title:"按 Cmd+K 唤起全局命令面板",children:[z.jsxs("span",{className:"flex items-center gap-1.5",style:{color:"var(--text-muted)"},children:[z.jsx(v0,{className:"w-3.5 h-3.5"}),z.jsx("span",{className:"hidden sm:inline",children:"搜索或执行指令..."})]}),z.jsx("kbd",{className:"px-1.5 py-0.5 text-[10px] font-mono-num rounded hl-muted",style:{color:"var(--text-muted)"},children:"⌘K"})]}),z.jsx("div",{className:"hidden md:flex items-center p-0.5 rounded-lg hl-muted border hl-border text-xs",children:Hh.map(w=>z.jsx("button",{onClick:()=>p(w.id),className:"px-2 py-1 rounded-md font-medium transition-all cursor-pointer",style:A===w.id?{backgroundColor:"var(--bg-card)",color:"var(--text-main)",boxShadow:"0 1px 2px rgba(0,0,0,0.08)"}:{color:"var(--text-muted)"},children:w.label},w.id))}),z.jsx("div",{className:"flex items-center p-0.5 rounded-lg hl-muted border hl-border text-xs",children:Rh.map(w=>z.jsxs("button",{onClick:()=>m(w.id),className:"px-2 py-1 rounded-md font-medium transition-all flex items-center gap-1.5 cursor-pointer",style:b===w.id?{backgroundColor:"var(--bg-card)",color:"var(--text-main)",boxShadow:"0 1px 2px rgba(0,0,0,0.08)"}:{color:"var(--text-muted)"},title:w.label,children:[z.jsx("span",{className:"w-2 h-2 rounded-full border border-black/10",style:{backgroundColor:w.dot}}),z.jsx("span",{className:"hidden lg:inline",children:w.label})]},w.id))}),z.jsxs("button",{onClick:()=>q(!0),className:"hl-btn-primary px-3 py-1.5 text-xs flex items-center gap-1.5 cursor-pointer",children:[z.jsx(Ch,{className:"w-3.5 h-3.5"}),z.jsx("span",{children:"AGY 终端"})]})]})]})})},Yh=({card:b})=>{const{getEffectiveMode:A,setShowAgyModal:_,triggerAction:m}=sa(),p=A(),q=p==="lan"?b.lanUrl:p==="home10443"?b.homeUrl:b.edgeUrl,nl=p==="lan"?"LAN 直连":p==="home10443"?"10443":"443 免端口";return z.jsxs("a",{href:q,target:"_blank",rel:"noopener noreferrer",className:"hl-card hl-card-interactive flex flex-col justify-between overflow-hidden group cursor-pointer",children:[z.jsxs("div",{className:"p-4 sm:p-5 space-y-3",children:[z.jsxs("div",{className:"flex items-start justify-between gap-3",children:[z.jsxs("div",{className:"flex items-center gap-3.5 min-w-0",children:[z.jsx("div",{className:"w-10 h-10 rounded-xl hl-muted border hl-border p-1.5 flex items-center justify-center shrink-0",children:z.jsx("img",{src:b.iconUrl,alt:b.title,className:"w-full h-full object-contain"})}),z.jsxs("div",{className:"min-w-0",children:[z.jsxs("div",{className:"flex items-center gap-2",children:[z.jsx("h3",{className:"text-sm font-semibold truncate group-hover:underline",children:b.title}),z.jsx("span",{className:"w-2 h-2 rounded-full shrink-0",style:{backgroundColor:b.online!==!1?"var(--success)":"#ef4444"}})]}),z.jsx("p",{className:"text-[11px] font-mono-num truncate mt-0.5",style:{color:"var(--text-muted)"},children:b.subtitle})]})]}),b.actionType==="drawer"?z.jsx("button",{onClick:w=>{w.preventDefault(),_(!0)},className:"px-2 py-1 rounded-md text-[11px] font-medium shrink-0 transition-opacity hover:opacity-80 cursor-pointer",style:{backgroundColor:"var(--accent-soft)",color:"var(--accent)"},children:"页内终端"}):b.actionType==="backup"?z.jsx("button",{onClick:w=>{w.preventDefault(),m("backup_nas","正在打包备份至极空间 Z4...")},className:"px-2 py-1 rounded-md text-[11px] font-medium shrink-0 transition-opacity hover:opacity-80 cursor-pointer",style:{backgroundColor:"var(--success-soft)",color:"var(--success)"},children:"立即备份"}):z.jsx("span",{className:"text-xs font-mono-num px-2 py-0.5 rounded hl-muted shrink-0",style:{color:"var(--text-muted)"},children:nl})]}),z.jsx("p",{className:"text-xs leading-relaxed line-clamp-2",style:{color:"var(--text-muted)"},children:b.desc})]}),z.jsx("div",{className:"hl-widget-footer grid grid-cols-3 divide-x hl-border text-center",children:b.stats.map((w,C)=>z.jsxs("div",{className:"py-2.5 px-2 flex flex-col items-center justify-center",children:[z.jsx("span",{className:"text-[10px] uppercase tracking-wider truncate max-w-full",style:{color:"var(--text-subtle)"},children:w.label}),z.jsx("span",{className:"text-xs font-semibold font-mono-num mt-0.5 truncate max-w-full",style:{color:w.highlight?"var(--success)":"var(--text-main)"},children:w.value})]},C))})]})},Bh=[{label:"SSH 连接 Mac mini",cmd:"ssh mini"},{label:"终端接力 AGY 会话",cmd:'ssh mini -t "tmux attach -t agy"'},{label:"SSH 连接新加坡 Azure",cmd:"ssh azure"},{label:"SSH 连接小米主路由",cmd:"ssh root@192.168.31.1"}],qh=()=>{const{copyCmd:b,triggerAction:A}=sa();return z.jsxs("section",{className:"space-y-3 pt-1",children:[z.jsxs("div",{className:"flex items-center justify-between px-0.5",children:[z.jsxs("div",{className:"flex items-center gap-2",children:[z.jsx("h2",{className:"text-xs font-semibold uppercase tracking-wider",style:{color:"var(--text-muted)"},children:"终端快捷指令与备用直连书签"}),z.jsx("span",{className:"text-[11px] font-mono-num",style:{color:"var(--text-subtle)"},children:"· 点击指令即复制"})]}),z.jsxs("div",{className:"flex items-center gap-3 text-xs",children:[z.jsx("button",{onClick:()=>A("refresh_ddns","正在同步 Cloudflare DDNS..."),className:"hover:underline font-medium cursor-pointer",style:{color:"var(--accent)"},children:"刷新 DDNS 解析"}),z.jsx("button",{onClick:()=>A("mount_nas","正在巡检极空间 20TB SMB 挂载..."),className:"hover:underline font-medium cursor-pointer",style:{color:"var(--accent)"},children:"巡检极空间挂载"})]})]}),z.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3",children:Bh.map(_=>z.jsxs("button",{onClick:()=>b(_.cmd,_.label),className:"hl-card hl-card-interactive px-4 py-3 text-left flex items-center justify-between gap-2 cursor-pointer",children:[z.jsxs("div",{className:"min-w-0",children:[z.jsx("div",{className:"text-xs font-semibold",children:_.label}),z.jsx("div",{className:"text-[11px] font-mono-num truncate mt-0.5",style:{color:"var(--accent)"},children:_.cmd})]}),z.jsx("span",{className:"text-[10px] font-mono-num px-1.5 py-0.5 rounded hl-muted shrink-0",style:{color:"var(--text-muted)"},children:"COPY"})]},_.cmd))})]})},Gh=()=>{const{showCmdPalette:b,setShowCmdPalette:A,setShowAgyModal:_,setTheme:m,triggerAction:p,copyCmd:q,getEffectiveMode:nl}=sa(),[w,C]=at.useState(""),ll=at.useRef(null);at.useEffect(()=>{b&&(C(""),setTimeout(()=>{var Z;return(Z=ll.current)==null?void 0:Z.focus()},20))},[b]);const U=at.useMemo(()=>{const Z=nl(),El=(wl,vl,kl)=>Z==="lan"?kl:Z==="home10443"?vl:wl;return[{id:"open-agy-drawer",title:"在页内唤起 AGY 云端终端",hint:"tmux attach -t agy",type:"终端",run:()=>_(!0)},{id:"open-agy",title:"新窗口打开 AGY 云端工作台",hint:"https://agy.961504.xyz",type:"跳转",run:()=>window.open(El("https://agy.961504.xyz","https://agy.home.961504.xyz:10443","http://192.168.31.164:7681"),"_blank")},{id:"open-z4",title:"打开 极空间 Z4 私有云 (20TB)",hint:"192.168.31.185:5055",type:"跳转",run:()=>window.open(El("https://z4.home.961504.xyz:10443","https://z4.home.961504.xyz:10443","http://192.168.31.185:5055"),"_blank")},{id:"open-vw",title:"打开 Vaultwarden 密码保险箱",hint:"https://vw.961504.xyz",type:"跳转",run:()=>window.open(El("https://vw.961504.xyz","https://vw.home.961504.xyz:10443","http://192.168.31.164:8222"),"_blank")},{id:"open-clash",title:"打开 Mihomo 路由分流面板",hint:"192.168.31.1:9999",type:"跳转",run:()=>window.open(El("https://clash.home.961504.xyz:10443/ui/","https://clash.home.961504.xyz:10443/ui/","http://192.168.31.1:9999/ui/"),"_blank")},{id:"act-backup",title:"立即打包备份核心数据至极空间 Z4",hint:"backup-to-nas.sh",type:"运维",run:()=>p("backup_nas","正在打包备份至极空间 Z4...")},{id:"act-ddns",title:"立即刷新 Cloudflare DDNS 解析",hint:"cloudflare-ddns.sh",type:"运维",run:()=>p("refresh_ddns","正在同步 Cloudflare DDNS...")},{id:"ssh-mini",title:"复制 SSH 连接 Mac mini 指令",hint:"ssh mini",type:"SSH",run:()=>q("ssh mini","SSH Mac mini")},{id:"ssh-agy",title:"复制 终端接力 AGY 会话指令",hint:'ssh mini -t "tmux attach -t agy"',type:"SSH",run:()=>q('ssh mini -t "tmux attach -t agy"',"接力 AGY")},{id:"theme-light",title:"切换主题: 浅色纯净 (Shadcn Light)",hint:"zinc-light",type:"主题",run:()=>m("zinc-light")},{id:"theme-dark",title:"切换主题: 深色极客 (Shadcn Dark)",hint:"zinc-dark",type:"主题",run:()=>m("zinc-dark")},{id:"theme-cat",title:"切换主题: Catppuccin Mocha",hint:"catppuccin",type:"主题",run:()=>m("catppuccin")},{id:"theme-nord",title:"切换主题: Nord 极地霜蓝",hint:"nord",type:"主题",run:()=>m("nord")}]},[nl,_,m,p,q]),S=at.useMemo(()=>{const Z=w.trim().toLowerCase();return Z?U.filter(El=>El.title.toLowerCase().includes(Z)||El.hint.toLowerCase().includes(Z)):U},[w,U]);if(!b)return null;const B=Z=>{A(!1),Z.run()};return z.jsx("div",{onClick:Z=>{Z.target===Z.currentTarget&&A(!1)},className:"fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-start justify-center pt-20 px-4",children:z.jsxs("div",{className:"w-full max-w-xl hl-card overflow-hidden shadow-2xl",children:[z.jsxs("div",{className:"px-4 py-3 border-b hl-border flex items-center gap-3",children:[z.jsx(v0,{className:"w-4 h-4",style:{color:"var(--text-muted)"}}),z.jsx("input",{ref:ll,value:w,onChange:Z=>C(Z.target.value),type:"text",placeholder:"输入服务名称、SSH 指令、路由模式或主题...",className:"w-full bg-transparent text-sm outline-none",onKeyDown:Z=>{Z.key==="Escape"&&A(!1),Z.key==="Enter"&&S.length>0&&B(S[0])}}),z.jsx("kbd",{className:"px-1.5 py-0.5 text-[10px] font-mono-num rounded hl-muted",style:{color:"var(--text-muted)"},children:"ESC"})]}),z.jsxs("div",{className:"max-h-80 overflow-y-auto p-2 text-xs",children:[z.jsx("div",{className:"px-2.5 py-1 text-[10px] font-semibold uppercase tracking-wider",style:{color:"var(--text-subtle)"},children:"快速操作与服务直达"}),S.map(Z=>z.jsxs("button",{onClick:()=>B(Z),className:"w-full px-3 py-2 rounded-lg text-left flex items-center justify-between transition-colors cursor-pointer",onMouseEnter:El=>{El.currentTarget.style.backgroundColor="var(--bg-muted)"},onMouseLeave:El=>{El.currentTarget.style.backgroundColor="transparent"},children:[z.jsxs("div",{className:"flex items-center gap-2.5",children:[z.jsx("span",{className:"font-medium",children:Z.title}),z.jsx("span",{className:"font-mono-num text-[11px]",style:{color:"var(--text-muted)"},children:Z.hint})]}),z.jsx("span",{className:"text-[10px] font-mono-num px-1.5 py-0.5 rounded hl-muted",style:{color:"var(--text-muted)"},children:Z.type})]},Z.id))]})]})})},Qh=()=>{const{showAgyModal:b,setShowAgyModal:A,getEffectiveMode:_}=sa();if(!b)return null;const m=_(),p=m==="lan"?"http://192.168.31.164:7681":m==="home10443"?"https://agy.home.961504.xyz:10443":"https://agy.961504.xyz";return z.jsx("div",{className:"fixed inset-0 z-50 bg-black/75 backdrop-blur-sm flex items-center justify-center p-3 sm:p-6",children:z.jsxs("div",{className:"w-full h-full max-w-6xl hl-card flex flex-col overflow-hidden shadow-2xl",children:[z.jsxs("div",{className:"px-4 py-2.5 border-b hl-border flex items-center justify-between hl-muted",children:[z.jsxs("div",{className:"flex items-center gap-2.5",children:[z.jsx("img",{src:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/google-gemini.png",alt:"AGY",className:"w-4 h-4"}),z.jsx("span",{className:"text-xs font-mono-num font-medium",children:"AGY 云端工作台 · tmux 持久会话 (关窗不断连)"})]}),z.jsxs("div",{className:"flex items-center gap-2",children:[z.jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",className:"hl-btn-outline px-2.5 py-1 text-xs font-mono-num",children:"新标签页全屏 ↗"}),z.jsx("button",{onClick:()=>A(!1),className:"hl-btn-primary px-3 py-1 text-xs cursor-pointer",children:"收起终端"})]})]}),z.jsx("iframe",{src:p,title:"AGY Cloud Workbench",className:"w-full flex-1 bg-black border-0"})]})})},Xh=()=>{const{telemetry:b,toast:A,fetchTelemetry:_,setShowCmdPalette:m,getEffectiveMode:p,routeMode:q}=sa();at.useEffect(()=>{_();const C=setInterval(_,3e3),ll=U=>{(U.metaKey||U.ctrlKey)&&U.key.toLowerCase()==="k"&&(U.preventDefault(),m(!0))};return window.addEventListener("keydown",ll),()=>{clearInterval(C),window.removeEventListener("keydown",ll)}},[_,m]);const nl=at.useMemo(()=>{const C=p();return C==="lan"?"LAN 局域网极速直连 (192.168.31.x)":C==="home10443"?"10443 家宽公网 HTTPS 直连":"443 免端口 HTTPS 直达 (*.961504.xyz)"},[p,q]),w=at.useMemo(()=>{const C=b;return[{title:"核心工作台与私有云存储",subtitle:"Core Workbench & Storage",showRouteHint:!0,items:[{id:"agy",title:"AGY 云端工作台",subtitle:"agy.961504.xyz · ttyd + tmux",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/google-gemini.png",online:C.services.agy,actionType:"drawer",desc:"M6 Mac mini 上的 24 小时常驻 AI 编程终端,已同步 Google 登录态并锁定新加坡出口,关掉网页后台继续运行。",edgeUrl:"https://agy.961504.xyz",homeUrl:"https://agy.home.961504.xyz:10443",lanUrl:"http://192.168.31.164:7681",stats:[{label:"M6 CPU 负载",value:`${C.mini.cpu_pct}%`},{label:"已用内存",value:`${C.mini.mem_used_gb} / 24 GB`},{label:"tmux 会话",value:C.mini.agy_tmux?"常驻运行中":"待机",highlight:!0}]},{id:"zspace",title:"极空间 Z4 私有云",subtitle:"192.168.31.185 · 20TB RAID 存储池",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/synology-drive.png",online:C.services.nas,desc:"家庭 20TB 大容量存储中心、极影视蓝光影院与手机相册备份,已自动 SMB 挂载至 Mac mini ~/nas。",edgeUrl:"https://z4.home.961504.xyz:10443",homeUrl:"https://z4.home.961504.xyz:10443",lanUrl:"http://192.168.31.185:5055",stats:[{label:"剩余可用",value:`${C.nas.free_tb} TB`,highlight:!0},{label:"已用容量",value:`${C.nas.used_tb} TB (${C.nas.pct}%)`},{label:"SMB 挂载",value:C.nas.mounted?"~/nas 已挂载":"重连中"}]},{id:"vaultwarden",title:"Vaultwarden 密码保险箱",subtitle:"vw.961504.xyz · Bitwarden 兼容",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/vaultwarden.png",online:C.services.vaultwarden,actionType:"backup",desc:"自托管全平台加密密码库,支持 iOS / Android / 浏览器插件自动填充,每天凌晨 03:30 自动打包灾备至极空间。",edgeUrl:"https://vw.961504.xyz",homeUrl:"https://vw.home.961504.xyz:10443",lanUrl:"http://192.168.31.164:8222",stats:[{label:"容器状态",value:"Healthy",highlight:!0},{label:"最近极空间灾备",value:C.nas.latest_backup},{label:"Mac SSD 占用",value:`${C.mini.disk_pct}%`}]}]},{title:"网络网关、AI 专线与外部哨兵",subtitle:"Network Gateway & Cloud Edge",showRouteHint:!1,items:[{id:"clash",title:"Mihomo 路由分流面板",subtitle:"192.168.31.1:9999 · ShellCrash",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/clash.png",online:C.services.clash,desc:"小米主路由器透明网关控制台,实时监控全屋设备流量、分流规则与狮城 AI 算力专线锁定状态。",edgeUrl:"https://clash.home.961504.xyz:10443/ui/",homeUrl:"https://clash.home.961504.xyz:10443/ui/",lanUrl:"http://192.168.31.1:9999/ui/",stats:[{label:"AI 锁定策略",value:"狮城节点",highlight:!0},{label:"新加坡延迟",value:C.network.sg_delay_ms>0?`${C.network.sg_delay_ms} ms`:"直连"},{label:"固定出口 IP",value:C.network.sg_egress_ip}]},{id:"router",title:"小米主路由器后台",subtitle:"192.168.31.1 · PPPoE 公网网关",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/openwrt.png",online:C.services.router,desc:"管理家庭联通公网宽带拨号、DHCP 静态 IP 绑定、10443 与 41641 端口转发及全屋内网 Split-DNS。",edgeUrl:"https://router.home.961504.xyz:10443",homeUrl:"https://router.home.961504.xyz:10443",lanUrl:"http://192.168.31.1",stats:[{label:"联通公网 IPv4",value:C.network.home_wan_ip,highlight:!0},{label:"泛域名 DDNS",value:"*.home.961504.xyz"},{label:"内网网关",value:"192.168.31.1"}]},{id:"uptime",title:"Uptime Kuma 外部哨兵",subtitle:"status.961504.xyz · SG Azure",iconUrl:"https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/uptime-kuma.png",online:C.services.uptime,desc:"独立部署在新加坡 Azure 公有云上的 24 小时外部监控哨兵,通过 Tailscale P2P 专线实时探测家庭服务。",edgeUrl:"https://status.961504.xyz",homeUrl:"https://status.961504.xyz",lanUrl:"https://status.961504.xyz",stats:[{label:"云端公网 IP",value:"104.43.105.243"},{label:"Tailscale 专线",value:"100.115.204.51"},{label:"外部探测状态",value:"100% 在线",highlight:!0}]}]}]},[b]);return z.jsxs("div",{className:"min-h-screen flex flex-col",children:[A&&z.jsxs("div",{className:"fixed bottom-5 right-5 z-50 hl-card px-4 py-3 flex items-center gap-2.5 shadow-2xl",children:[z.jsx("span",{className:"w-2 h-2 rounded-full",style:{backgroundColor:"var(--success)"}}),z.jsx("span",{className:"text-xs font-medium",children:A})]}),z.jsx(jh,{}),z.jsxs("main",{className:"flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-7",children:[w.map(C=>z.jsxs("section",{className:"space-y-3",children:[z.jsxs("div",{className:"flex items-center justify-between px-0.5",children:[z.jsxs("div",{className:"flex items-center gap-2",children:[z.jsx("h2",{className:"text-xs font-semibold uppercase tracking-wider",style:{color:"var(--text-muted)"},children:C.title}),z.jsxs("span",{className:"text-[11px] font-mono-num",style:{color:"var(--text-subtle)"},children:["· ",C.subtitle]})]}),C.showRouteHint&&z.jsxs("span",{className:"text-[11px] font-mono-num hidden sm:inline",style:{color:"var(--text-subtle)"},children:["当前路由模式: ",nl]})]}),z.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:C.items.map(ll=>z.jsx(Yh,{card:ll},ll.id))})]},C.title)),z.jsx(qh,{})]}),z.jsx(Gh,{}),z.jsx(Qh,{})]})};Eh.createRoot(document.getElementById("root")).render(z.jsx(Bi.StrictMode,{children:z.jsx(Xh,{})})); diff --git a/stacks/portal/dist/assets/index-DWXFEfty.css b/stacks/portal/dist/assets/index-DWXFEfty.css new file mode 100644 index 0000000..910e161 --- /dev/null +++ b/stacks/portal/dist/assets/index-DWXFEfty.css @@ -0,0 +1 @@ +/*! tailwindcss v4.3.5 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:block))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--spacing:.25rem;--container-xl:36rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--blur-sm:8px;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.right-5{right:calc(var(--spacing) * 5)}.bottom-5{bottom:calc(var(--spacing) * 5)}.z-30{z-index:30}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-full{height:100%}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-6{width:calc(var(--spacing) * 6)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-full{width:100%}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-full{max-width:100%}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-7>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 7) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 7) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-black\/10{border-color:#0000001a}@supports (color:color-mix(in lab,red,red)){.border-black\/10{border-color:color-mix(in oklab,var(--color-black) 10%,transparent)}}.bg-black{background-color:var(--color-black)}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-black\/75{background-color:#000000bf}@supports (color:color-mix(in lab,red,red)){.bg-black\/75{background-color:color-mix(in oklab,var(--color-black) 75%,transparent)}}.bg-transparent{background-color:#0000}.object-contain{object-fit:contain}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-1{padding-top:var(--spacing)}.pt-20{padding-top:calc(var(--spacing) * 20)}.pr-1{padding-right:var(--spacing)}.text-center{text-align:center}.text-left{text-align:left}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.uppercase{text-transform:uppercase}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){:is(:where(.group):hover .group-hover\:underline),.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:p-5{padding:calc(var(--spacing) * 5)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media(min-width:48rem){.md\:flex{display:flex}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:inline{display:inline}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media(min-width:80rem){.xl\:flex{display:flex}}}:root,[data-theme=zinc-dark]{--bg-page:#09090b;--bg-card:#121215;--bg-widget:#16161a;--bg-muted:#18181b;--bg-hover:#1c1c21;--text-main:#f4f4f5;--text-muted:#a1a1aa;--text-subtle:#71717a;--border-color:#27272a;--border-subtle:#ffffff0f;--border-hover:#3f3f46;--primary:#fafafa;--primary-fg:#09090b;--accent:#3b82f6;--accent-soft:#3b82f624;--success:#10b981;--success-soft:#10b98124;--card-shadow:0 2px 8px -2px #00000080}[data-theme=zinc-light]{--bg-page:#f8fafc;--bg-card:#fff;--bg-widget:#f8fafc;--bg-muted:#f1f5f9;--bg-hover:#fff;--text-main:#0f172a;--text-muted:#64748b;--text-subtle:#94a3b8;--border-color:#e2e8f0;--border-subtle:#f1f5f9;--border-hover:#cbd5e1;--primary:#0f172a;--primary-fg:#fff;--accent:#2563eb;--accent-soft:#2563eb14;--success:#10b981;--success-soft:#10b9811a;--card-shadow:0 1px 3px 0 #0f172a0a, 0 1px 2px -1px #0f172a08}[data-theme=catppuccin]{--bg-page:#11111b;--bg-card:#1e1e2e;--bg-widget:#181825;--bg-muted:#313244;--bg-hover:#242438;--text-main:#cdd6f4;--text-muted:#a6adc8;--text-subtle:#6c7086;--border-color:#313244;--border-subtle:#cdd6f40f;--border-hover:#45475a;--primary:#cba6f7;--primary-fg:#11111b;--accent:#89b4fa;--accent-soft:#89b4fa26;--success:#a6e3a1;--success-soft:#a6e3a126;--card-shadow:0 4px 16px -4px #11111b99}[data-theme=nord]{--bg-page:#242933;--bg-card:#2e3440;--bg-widget:#292e39;--bg-muted:#3b4252;--bg-hover:#353c4a;--text-main:#eceff4;--text-muted:#d8dee9;--text-subtle:#81a1c1;--border-color:#3b4252;--border-subtle:#eceff40f;--border-hover:#4c566a;--primary:#88c0d0;--primary-fg:#2e3440;--accent:#88c0d0;--accent-soft:#88c0d026;--success:#a3be8c;--success-soft:#a3be8c26;--card-shadow:0 4px 12px -2px #00000059}body{background-color:var(--bg-page);color:var(--text-main);-webkit-font-smoothing:antialiased;font-family:Inter,-apple-system,BlinkMacSystemFont,PingFang SC,Microsoft YaHei,sans-serif;transition:background-color .2s,color .2s}.font-mono-num{font-variant-numeric:tabular-nums;font-family:JetBrains Mono,SF Mono,Menlo,monospace}.hl-card{background-color:var(--bg-card);border:1px solid var(--border-color);box-shadow:var(--card-shadow);border-radius:.75rem;transition:border-color .16s,transform .16s,box-shadow .16s}.hl-card-interactive:hover{border-color:var(--border-hover);background-color:var(--bg-hover);transform:translateY(-1px)}.hl-widget-footer{background-color:var(--bg-widget);border-top:1px solid var(--border-color)}.hl-pill{background-color:var(--bg-card);border:1px solid var(--border-color);border-radius:.5rem}.hl-muted{background-color:var(--bg-muted)}.hl-border{border-color:var(--border-color)}.hl-btn-primary{background-color:var(--primary);color:var(--primary-fg);border-radius:.5rem;font-weight:500;transition:opacity .15s}.hl-btn-primary:hover{opacity:.9}.hl-btn-outline{background-color:var(--bg-card);color:var(--text-main);border:1px solid var(--border-color);border-radius:.5rem;transition:background-color .15s,border-color .15s}.hl-btn-outline:hover{background-color:var(--bg-muted);border-color:var(--border-hover)}.hl-bar-fill{background-color:var(--accent);transition:width .5s cubic-bezier(.22,1,.36,1)}.hl-bar-fill-green{background-color:var(--success);transition:width .5s cubic-bezier(.22,1,.36,1)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false} diff --git a/stacks/portal/dist/index.html b/stacks/portal/dist/index.html new file mode 100644 index 0000000..0aaf1b5 --- /dev/null +++ b/stacks/portal/dist/index.html @@ -0,0 +1,20 @@ + + + + + + HomeLab Console · 家庭云边中控台 + + + + + + + + +
+ + diff --git a/stacks/portal/server.py b/stacks/portal/server.py index 728f289..33564f5 100755 --- a/stacks/portal/server.py +++ b/stacks/portal/server.py @@ -11,12 +11,14 @@ import subprocess import threading import time import urllib.request +import mimetypes from concurrent.futures import ThreadPoolExecutor from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path PORT = int(os.environ.get("PORT", "3004")) BASE_DIR = Path(__file__).resolve().parent +DIST_DIR = BASE_DIR / "dist" INDEX_FILE = BASE_DIR / "index.html" _cache = {"data": None, "ts": 0.0} @@ -285,9 +287,25 @@ class PortalHandler(BaseHTTPRequestHandler): self._send_json(collect_telemetry()) return - # Serve SPA index.html for root and any path - if INDEX_FILE.exists(): - body = INDEX_FILE.read_bytes() + # Serve static assets from Vite build output (dist/) if available + clean_path = self.path.split("?", 1)[0].lstrip("/") + if clean_path and DIST_DIR.exists(): + asset_file = (DIST_DIR / clean_path).resolve() + if str(asset_file).startswith(str(DIST_DIR.resolve())) and asset_file.is_file(): + body = asset_file.read_bytes() + mime, _ = mimetypes.guess_type(str(asset_file)) + self.send_response(200) + self.send_header("Content-Type", mime or "application/octet-stream") + self.send_header("Cache-Control", "public, max-age=86400") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + return + + # Serve SPA index.html from dist/index.html (React+Vite build) or fallback index.html + spa_index = (DIST_DIR / "index.html") if (DIST_DIR / "index.html").exists() else INDEX_FILE + if spa_index.exists(): + body = spa_index.read_bytes() self.send_response(200) self.send_header("Content-Type", "text/html; charset=utf-8") self.send_header("Cache-Control", "no-cache") diff --git a/stacks/portal/web/index.html b/stacks/portal/web/index.html new file mode 100644 index 0000000..32fe28a --- /dev/null +++ b/stacks/portal/web/index.html @@ -0,0 +1,19 @@ + + + + + + HomeLab Console · 家庭云边中控台 + + + + + + +
+ + + diff --git a/stacks/portal/web/package-lock.json b/stacks/portal/web/package-lock.json new file mode 100644 index 0000000..3242b00 --- /dev/null +++ b/stacks/portal/web/package-lock.json @@ -0,0 +1,2635 @@ +{ + "name": "homelab-console", + "version": "3.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "homelab-console", + "version": "3.0.0", + "dependencies": { + "clsx": "^2.1.1", + "lucide-react": "^0.475.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tailwind-merge": "^3.0.1", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.0.6", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "@vitejs/plugin-react": "^4.3.4", + "tailwindcss": "^4.0.6", + "typescript": "^5.7.3", + "vite": "^6.1.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.13.tgz", + "integrity": "sha512-j1nvOQCZYSgp7HLmisnCXFTpVvFODiijQ9QHkORfGKWH6YDtskTEeCJS7eV545GZ9UBzrq0e2xsOd5QQ5PjIqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.13", + "@babel/helper-compilation-targets": "^7.29.13", + "@babel/helper-module-transforms": "^7.29.13", + "@babel/helpers": "^7.29.13", + "@babel/parser": "^7.29.13", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.13", + "@babel/types": "^7.29.11", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.13.tgz", + "integrity": "sha512-T5FRo+RzVHvGjWOuF1Ljc44b+NXAOazodHkGUHp4I3zCkQ4/sNVJm56h1S278LMR0bY5xBhztGziSbli8zObIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.13", + "@babel/types": "^7.29.11", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.13.tgz", + "integrity": "sha512-8WxJ4/Vmes3ghacj8VOJy3NW8eyHiFY/4thU/LSBuBE470+igjR/j1ZTNn8fV5VdNrLx6iXUwig526UdOvfP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.13.tgz", + "integrity": "sha512-/U96wOz+SCoZ7Da/8kjDGltcNY280JPQcRNPK0Hk3PTbdpaiBDQImtC6JsbVwb1HGMr3usZQU2WsWVjhYNmRzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.13" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.13.tgz", + "integrity": "sha512-fWegr+WsEsiMVW4KUNdIIzzMTZSzNiqhy0//6+2MRi2d5NFNsL/AYwBQW8eBnRbTBVRnDVzjaJEUqKaCWjMMdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.13.tgz", + "integrity": "sha512-laoRpD/kO/iA4CDlgJbixHekg7oPvWALK0PQyK3Ob2I2njZRvVAD77RfWCIImtqWCq6KijoBoZK7bp/HlTWASQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.13.tgz", + "integrity": "sha512-fJM50YYjlTiBhgdkGmC1tBpv+FMAyo4annf2X6Aks+0yRlaiVkYW/3f07xAfVVkYIoZ9fFZp+mEThUFnuybhkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.11" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.13.tgz", + "integrity": "sha512-0ve0xMlFA73dgY1oyJRY6RoW+/bncdcOQqg6jjYcVfXBK90OdLXjm9R6lmRetdZVrPjXkKIoMVBqYFPjcAlZ4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.13", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.13", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.11", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.11.tgz", + "integrity": "sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.11", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.67.5.tgz", + "integrity": "sha512-FdWPeulkH+FH+rBzyKBD59tuVN4tRKvmVilSJm0OcnoYsQTpd9UhD78OaPcsYqo2fX6hCwAG0YIjrDLoQ3pR3g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.67.5.tgz", + "integrity": "sha512-bmkDuBGnF+Ji8atWlXcNjxIC52ShCbdXPbW7Nz0lRoCFi1lrvsO0XobJY36kTj7duc1vOmGJeQ9vtVuGjnzihA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-x64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-x64/-/rollup-android-x64-4.67.5.tgz", + "integrity": "sha512-6KvVfnqPTqmbQ5YobMl9HYiSymAsCt8HlNeriDshwJQcveXwT+vIMW6wGL1RcJbXH9+r3BAJvjab5+rIgtSEqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.67.5.tgz", + "integrity": "sha512-SNamgdrY69oPdBrQV9fKGo6PSmKcVhyn0D0jnDmcqgRJvrxQGGBhtekOHTUJ7TCgkW0nE8XMH9v2CwXmjNIzVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.67.5.tgz", + "integrity": "sha512-HNdl34thiJtHDSglogjmAlQ296L8cc8zA7ODH65nnmY7E+jPP55WEbh8J5583rWFLMjxyYywxZuwPOwRvEi5tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.67.5.tgz", + "integrity": "sha512-WvZYtANNswfHzSNHaJAoG6Ipfc4SyZIDYuIjFdHv07xXxhHl+Xx8o+bNDWsxpOADFT2mKXcXVrfOG4OlWTLo8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.67.5.tgz", + "integrity": "sha512-EUU+Wgf9NyHekceC+DxAdm42f6bq2ezH/7DEb/JnCb8SAUhG2xph5BiVukxplWal2m5pP8CzJZE+FLwRopywjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.67.5.tgz", + "integrity": "sha512-dgU1CvUuE2IkaJBAeuAbxpDdMHAdZBT5oth5u22DtuoMg4gXXYr2+Sm30RigPJG1F2VEoiGJUziGLuIh9+jPxA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.67.5.tgz", + "integrity": "sha512-rdgJcJig2VngYlcTCRQw2BA8kLWM6QwDFe9uLFo81lya0jPC1r8wZu92sAvTUIv48GWlkRVi6/fpsa5CoFSKoQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.67.5.tgz", + "integrity": "sha512-+jtCiQnrEFHWAUAcUpP7wppb1p6HKOgBP3mXx75cEYpDF2Y5MEqBky2HNz+osFuVx5uX44gnMTmbe5RJauzn6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.67.5.tgz", + "integrity": "sha512-heflX7ENhL8eHmLcUxDEHCSK8CKLyPprysb2JGoSTh5Ip7nHrzIRc+2USyxul3nxi98H8pGxJIEDEpURlS1X5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.67.5.tgz", + "integrity": "sha512-rRtNU0zBfRHkJ8pscHN9qRtUYLq8Rao4EX7aVWvKcFmJUANkCCXFRU7ovNBEMhpEONyUEB/3DRVDXwDDguSfHA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.67.5.tgz", + "integrity": "sha512-/6auyi9yj8MD/Q+8P+f2ay57jQ7a0j7Yp1JK86pecH6ZnRViQZ5GOjoRSjGArFeTSHFznRbM2QPQcBgDPyNMfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.67.5.tgz", + "integrity": "sha512-Hsc0vlt+vPvqzUkHKffWKf3YE/yexrY+yeFf7IsUvDC6PV7YGCsA/gJvPa+WJdgxGJnwuoO1HmLkbahaLKabYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.67.5.tgz", + "integrity": "sha512-Jx5TMMSPJwHY7F/JwPdS6nuBwny2ECRK+EsAJV5HZrfiddeSS6ZrohkLkFZm3rjqBUuQ4FPX5gGMtakUuQO6fQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.67.5.tgz", + "integrity": "sha512-fGWcq2lo/XCqAkBLOokg66D/z+MUouryB8i+QdU9RR6O5knG7rucc0WFPqWYL1Wk/wuiJouDfmyBxmZKRM9bag==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.67.5.tgz", + "integrity": "sha512-JwO/Ys3jybc0UW3V5XO2CMnp0RhvoczDDQTgAEE1IctT+HRY3W5parIIWLUpmAK4gHSeeYJofm2iQPFA62K6ag==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.67.5.tgz", + "integrity": "sha512-vVD4iqel6J6A1xAJlb4mxEO9i1wOJ4/SkcKoDKAuK/wqEBPOA7/P5dDyZvNx46ocHwOUwzo3WjhTdKqET9kEAg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.67.5.tgz", + "integrity": "sha512-HmEfNh5Cdd/NHxgqwMzKnjlvicQQA+D+w+vQXDJSV0x/aHiQSjVwh1Th5RoA7QsMieIaxibt/5iJq68BraTSUg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.67.5.tgz", + "integrity": "sha512-NfmALpbe009nYzZ2QqlSW6nzbGddXpqk3nwualrIr+4QflQCTGMzt3QKK20yARiAnSV9fJdM5WNwIYUf31x3uA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.67.5.tgz", + "integrity": "sha512-ngcE7Udpy/iJ3lexVhYcbpUV2OJIakRGus3snc6K52BnAAJetDBG1Ku5Eh3CECtnW3mpBYWg5VCD4tTaOXKOVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.67.5.tgz", + "integrity": "sha512-DZ01A2EdTYX8xVeGoGiWkJBRWDh+/BOflwGPVsBay43PDxcq8ez0xuovZnPnk1xjE3CdI0pdZXxsJp/Xjmf7uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.67.5.tgz", + "integrity": "sha512-nJKiMKDO140DUCEcQZl+f4HiGPMBxrW2webjuWJ2E3qPeoruHf2zByml4TP52lA1zDi6L4I92D/5stxeA/6pig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.67.5.tgz", + "integrity": "sha512-ykLkBCf+Kls24QmqM3IRf1T4sGMh0rXPyymtj+hXlWKPJnXbXraHqUUsKtOIxqLasjT1i7DhfQGAaZYeiHbSOw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.67.5.tgz", + "integrity": "sha512-NiFPUFw8cHhkmBlL1k1eaz+5AXXm89rztj+DQdDuQ7VGPM0+ADFhezQ2KcBMF50UEFzGUr0+DVjVND743XwKWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.67.5.tgz", + "integrity": "sha512-Khj/vrKCpdbiAWYbJAeSy4D5iep+qwW/86lNoKvdleJYGxgbRE7h87+5d5T9D7gt8NcqhNFpreRgIg8T4bLzKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.5.tgz", + "integrity": "sha512-yT53FzV4ke0cr/BguDxhWMpm5MJu1O2muzk+tKw6lKHjODAsYArBbWwFbJiaksfzFv1tpkO9QHGzmfs1hJT66g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.5", + "jiti": "^2.7.0", + "lightningcss": "1.33.0", + "magic-string": "^1.1.0", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.5" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.5.tgz", + "integrity": "sha512-PynqGLZsZvwM9tqD/CUxkOIfyd6K5elZ2MooauzJryP/UqXYgi3yYbtt3N0Xe+MHV/eFKPFQCEfIKAqlAS1CBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.5", + "@tailwindcss/oxide-darwin-arm64": "4.3.5", + "@tailwindcss/oxide-darwin-x64": "4.3.5", + "@tailwindcss/oxide-freebsd-x64": "4.3.5", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.5", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.5", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.5", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.5", + "@tailwindcss/oxide-linux-x64-musl": "4.3.5", + "@tailwindcss/oxide-wasm32-wasi": "4.3.5", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.5", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.5" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.5.tgz", + "integrity": "sha512-Se0z5xMqcSQanJD1IYmO0cGpK3iv0fp3ZsIT7xRJZ1Da5PghvNoc46zz4jIQn+aan3dV9T8AermFNN9QPmsh0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.5.tgz", + "integrity": "sha512-UPrgTDuUbvmqGMZuCnmI3FKee/tYKzKdp00/kuB4oSGB213VYg8QTdF7lVhnPoBXq/mIfJ+ILoBFqNOboWcMwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.5.tgz", + "integrity": "sha512-E+p7HEtjI0b8D7kbbWxH067cGui6d4c79COGko9fAPVE3rwc1E7ld2HFCbaG86AOGWS5VKQYqZOaf38ya4uxTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.5.tgz", + "integrity": "sha512-yWEWcWyAG7rWOcTpJTjdhQ3pcaFY2h+0bqTRfgU3G2fz87ZU3AKdvdZKhslD+kyHnjBUWKvNdRYwIYC5dI1tIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.5.tgz", + "integrity": "sha512-WmeVjtJhZlr+smpqcdR2kQkkn6arHIJnUIBxTO2EJcTLGY1ecVXNo2hbSn8xc0IH2aEtys936iMWKGyj0GaKnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.5.tgz", + "integrity": "sha512-DTCSyucc6ShMp1QMqV5R94Z7xlgNgUzkGmFF1rL5HH2Qjy4eSmEqy+YLGkqqYvWa4sILtgrBt1JjRKbneQtiFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.5.tgz", + "integrity": "sha512-H9lsvO4x9E4nE4Hi8h7NHHw0O/kcVSu+iOyFHNGdYzazGgDjFHZbE6S3hQ8kMcbNXSBlMdNi67LV5EVqtpaJtw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.5.tgz", + "integrity": "sha512-4uxQvtBvPuIdl13WfUBj9xMZHH14PtHZ8OZdtLmdyDtG66sCa1t599NZT+jagkUzRtWhuul1qRZQ1nAJscXN5g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.5.tgz", + "integrity": "sha512-0JQAzs7jwbA7O6+z/adU+Jk3AXwsu3npAhtr5escXS7TqEqWcaDV7qHuI+0Vy/KQRuVGnLQREcSJWYauyV3oqg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.5.tgz", + "integrity": "sha512-OJhFmlEfdzMr+avACdi40RPtnkW0B6hXyxL/8r+tnEHBWZji36CYRjEXrrvgBmaYsD3oEOBqwYFRKsYvzFe7Bw==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.3", + "@emnapi/runtime": "^1.11.3", + "@emnapi/wasi-threads": "^1.2.3", + "@napi-rs/wasm-runtime": "^1.2.2", + "@tybys/wasm-util": "^0.10.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.5.tgz", + "integrity": "sha512-9o8jgthi+QE5eandnboiJT64VQfnIArfZzSTdgbhEK5aafdiu2jTW9Honi/mwYHxBZuH1vAC57IFyrh+0iK5Gg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.5.tgz", + "integrity": "sha512-XiKFfIy1RWe7qK4WqByxNW7Oz1/nkOy8o/BWhHminyV1PmpUd8Eedj5v2A8h2kpqeVlz6xRnwk9Fr/ZXNLcZfg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-BCNiY0a1ZjdOHVqw7kyb7U72BwfMF3dfUuN+tQsLWky/J5JOI/r7abibglXfygrZhVO/3u3V+E25kkKTeMkXaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.5", + "@tailwindcss/oxide": "4.3.5", + "tailwindcss": "4.3.5" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz", + "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.35", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.35.tgz", + "integrity": "sha512-GNk8KX52CHqeNKGk8+7tZnQab/2k1t/BgrUHPKNdijzpEhF1saPQZHVKb6m5loSAxB39gyrTYw34Qf9CQ3u1qQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.5.tgz", + "integrity": "sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.33", + "caniuse-lite": "^1.0.30001819", + "electron-to-chromium": "^1.5.464", + "node-releases": "^2.0.60", + "update-browserslist-db": "^1.3.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001823", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001823.tgz", + "integrity": "sha512-TQ5s/djDjNk1axreUW+4rULH+BmdCMLiJkhaXnO5wqivG7tITkSUj4ItIdzqdZHKaXcHAV8dhH3JxOM7/7bwqw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.478", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.478.tgz", + "integrity": "sha512-pftG+ma5Lm8O6/p45bhYT6StBN5ziQymaRzmCZwFl8DwWHKPPD93FdOmP1aqftcepolQYvrcyTLa17kE8Yf+jg==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.26.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.1.tgz", + "integrity": "sha512-PPnnSJq3azKOIewXR/uppBV/6h98dprBJ/WaQ9Qgj10xX1lJLNfg+XShpbsrSqcDSy2yYYyhfXM1wWhftqgyzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.475.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.475.0.tgz", + "integrity": "sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.5.tgz", + "integrity": "sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.63", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.63.tgz", + "integrity": "sha512-6li2QanLsAXpIH2R6j77MzRyvOyrvdTqlKtO4CgBdHGNvN99ZZfyxszHc5o5+IZBWD5u6Hzwg83JoGXmqZNG9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.1.tgz", + "integrity": "sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz", + "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.67.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.67.5.tgz", + "integrity": "sha512-3Ve5VH1hacCVutdpbmu/htg4kz+JCOIWgy4Q3hjHPYGHeHeIElNHJ0LcJ3rCfIsd5G7qOl5k5mwpzGMj9kdHPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.10" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.67.5", + "@rollup/rollup-android-arm64": "4.67.5", + "@rollup/rollup-android-x64": "4.67.5", + "@rollup/rollup-darwin-arm64": "4.67.5", + "@rollup/rollup-darwin-x64": "4.67.5", + "@rollup/rollup-freebsd-arm64": "4.67.5", + "@rollup/rollup-freebsd-x64": "4.67.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.67.5", + "@rollup/rollup-linux-arm-musleabihf": "4.67.5", + "@rollup/rollup-linux-arm64-gnu": "4.67.5", + "@rollup/rollup-linux-arm64-musl": "4.67.5", + "@rollup/rollup-linux-loong64-gnu": "4.67.5", + "@rollup/rollup-linux-loong64-musl": "4.67.5", + "@rollup/rollup-linux-ppc64-gnu": "4.67.5", + "@rollup/rollup-linux-ppc64-musl": "4.67.5", + "@rollup/rollup-linux-riscv64-gnu": "4.67.5", + "@rollup/rollup-linux-riscv64-musl": "4.67.5", + "@rollup/rollup-linux-s390x-gnu": "4.67.5", + "@rollup/rollup-linux-x64-gnu": "4.67.5", + "@rollup/rollup-linux-x64-musl": "4.67.5", + "@rollup/rollup-openbsd-x64": "4.67.5", + "@rollup/rollup-openharmony-arm64": "4.67.5", + "@rollup/rollup-win32-arm64-msvc": "4.67.5", + "@rollup/rollup-win32-ia32-msvc": "4.67.5", + "@rollup/rollup-win32-x64-gnu": "4.67.5", + "@rollup/rollup-win32-x64-msvc": "4.67.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.2.tgz", + "integrity": "sha512-GYrCADwpu6yV5OAvchkQ27Z5wwMxWAEMg5NNWjyHh/5DboFFqbdbvYNIvZouQpxXyeMPoTOh0vdPYKlf0ZswdQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwind-merge": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.7.0.tgz", + "integrity": "sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.5.tgz", + "integrity": "sha512-FcQk9BuffmEHJP2G0XmB2SplU1aLTI7j07Kunk+U74Ny+XiWOtzXz9aujFZ/avntw1e2cOv/3PkgzflQ7gX2vQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.5.tgz", + "integrity": "sha512-4enwjFfi4IwtEh0w+jPzpLVOFQiPHmmzPxcHXQOyEur47o6u0jE573DmGpjA+7irXoMLYRZD5ZaFUEneS3abPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/zustand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.1.0.tgz", + "integrity": "sha512-ciJZlP48M1PTQbVQq81CGVFxHTLpZNrFjKqwjtCU34AWuXTZT/jrF3p9+fI84Cf1eSCMLapxqBy/SNTfwOBuqA==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/stacks/portal/web/package.json b/stacks/portal/web/package.json new file mode 100644 index 0000000..494f5c8 --- /dev/null +++ b/stacks/portal/web/package.json @@ -0,0 +1,28 @@ +{ + "name": "homelab-console", + "private": true, + "version": "3.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "clsx": "^2.1.1", + "lucide-react": "^0.475.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tailwind-merge": "^3.0.1", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.0.6", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "tailwindcss": "^4.0.6", + "typescript": "^5.7.3", + "vite": "^6.1.0", + "@vitejs/plugin-react": "^4.3.4" + } +} diff --git a/stacks/portal/web/src/App.tsx b/stacks/portal/web/src/App.tsx new file mode 100644 index 0000000..99a303b --- /dev/null +++ b/stacks/portal/web/src/App.tsx @@ -0,0 +1,230 @@ +import React, { useEffect, useMemo } from 'react'; +import { usePortalStore } from './store/usePortalStore'; +import { TopRibbon } from './components/TopRibbon'; +import { ServiceCard } from './components/ServiceCard'; +import { SshShelf } from './components/SshShelf'; +import { CommandPalette } from './components/CommandPalette'; +import { AgyTerminalModal } from './components/AgyTerminalModal'; +import type { ServiceGroup } from './types/telemetry'; + +export const App: React.FC = () => { + const { + telemetry, + toast, + fetchTelemetry, + setShowCmdPalette, + getEffectiveMode, + routeMode, + } = usePortalStore(); + + useEffect(() => { + fetchTelemetry(); + const timer = setInterval(fetchTelemetry, 3000); + + const onKeyDown = (e: KeyboardEvent) => { + if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { + e.preventDefault(); + setShowCmdPalette(true); + } + }; + window.addEventListener('keydown', onKeyDown); + return () => { + clearInterval(timer); + window.removeEventListener('keydown', onKeyDown); + }; + }, [fetchTelemetry, setShowCmdPalette]); + + const activeModeLabel = useMemo(() => { + const m = getEffectiveMode(); + if (m === 'lan') return 'LAN 局域网极速直连 (192.168.31.x)'; + if (m === 'home10443') return '10443 家宽公网 HTTPS 直连'; + return '443 免端口 HTTPS 直达 (*.961504.xyz)'; + }, [getEffectiveMode, routeMode]); + + const serviceGroups = useMemo(() => { + const t = telemetry; + return [ + { + title: '核心工作台与私有云存储', + subtitle: 'Core Workbench & Storage', + showRouteHint: true, + items: [ + { + id: 'agy', + title: 'AGY 云端工作台', + subtitle: 'agy.961504.xyz · ttyd + tmux', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/google-gemini.png', + online: t.services.agy, + actionType: 'drawer', + desc: 'M6 Mac mini 上的 24 小时常驻 AI 编程终端,已同步 Google 登录态并锁定新加坡出口,关掉网页后台继续运行。', + edgeUrl: 'https://agy.961504.xyz', + homeUrl: 'https://agy.home.961504.xyz:10443', + lanUrl: 'http://192.168.31.164:7681', + stats: [ + { label: 'M6 CPU 负载', value: `${t.mini.cpu_pct}%` }, + { label: '已用内存', value: `${t.mini.mem_used_gb} / 24 GB` }, + { + label: 'tmux 会话', + value: t.mini.agy_tmux ? '常驻运行中' : '待机', + highlight: true, + }, + ], + }, + { + id: 'zspace', + title: '极空间 Z4 私有云', + subtitle: '192.168.31.185 · 20TB RAID 存储池', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/synology-drive.png', + online: t.services.nas, + desc: '家庭 20TB 大容量存储中心、极影视蓝光影院与手机相册备份,已自动 SMB 挂载至 Mac mini ~/nas。', + edgeUrl: 'https://z4.home.961504.xyz:10443', + homeUrl: 'https://z4.home.961504.xyz:10443', + lanUrl: 'http://192.168.31.185:5055', + stats: [ + { label: '剩余可用', value: `${t.nas.free_tb} TB`, highlight: true }, + { label: '已用容量', value: `${t.nas.used_tb} TB (${t.nas.pct}%)` }, + { label: 'SMB 挂载', value: t.nas.mounted ? '~/nas 已挂载' : '重连中' }, + ], + }, + { + id: 'vaultwarden', + title: 'Vaultwarden 密码保险箱', + subtitle: 'vw.961504.xyz · Bitwarden 兼容', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/vaultwarden.png', + online: t.services.vaultwarden, + actionType: 'backup', + desc: '自托管全平台加密密码库,支持 iOS / Android / 浏览器插件自动填充,每天凌晨 03:30 自动打包灾备至极空间。', + edgeUrl: 'https://vw.961504.xyz', + homeUrl: 'https://vw.home.961504.xyz:10443', + lanUrl: 'http://192.168.31.164:8222', + stats: [ + { label: '容器状态', value: 'Healthy', highlight: true }, + { label: '最近极空间灾备', value: t.nas.latest_backup }, + { label: 'Mac SSD 占用', value: `${t.mini.disk_pct}%` }, + ], + }, + ], + }, + { + title: '网络网关、AI 专线与外部哨兵', + subtitle: 'Network Gateway & Cloud Edge', + showRouteHint: false, + items: [ + { + id: 'clash', + title: 'Mihomo 路由分流面板', + subtitle: '192.168.31.1:9999 · ShellCrash', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/clash.png', + online: t.services.clash, + desc: '小米主路由器透明网关控制台,实时监控全屋设备流量、分流规则与狮城 AI 算力专线锁定状态。', + edgeUrl: 'https://clash.home.961504.xyz:10443/ui/', + homeUrl: 'https://clash.home.961504.xyz:10443/ui/', + lanUrl: 'http://192.168.31.1:9999/ui/', + stats: [ + { label: 'AI 锁定策略', value: '狮城节点', highlight: true }, + { + label: '新加坡延迟', + value: t.network.sg_delay_ms > 0 ? `${t.network.sg_delay_ms} ms` : '直连', + }, + { label: '固定出口 IP', value: t.network.sg_egress_ip }, + ], + }, + { + id: 'router', + title: '小米主路由器后台', + subtitle: '192.168.31.1 · PPPoE 公网网关', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/openwrt.png', + online: t.services.router, + desc: '管理家庭联通公网宽带拨号、DHCP 静态 IP 绑定、10443 与 41641 端口转发及全屋内网 Split-DNS。', + edgeUrl: 'https://router.home.961504.xyz:10443', + homeUrl: 'https://router.home.961504.xyz:10443', + lanUrl: 'http://192.168.31.1', + stats: [ + { label: '联通公网 IPv4', value: t.network.home_wan_ip, highlight: true }, + { label: '泛域名 DDNS', value: '*.home.961504.xyz' }, + { label: '内网网关', value: '192.168.31.1' }, + ], + }, + { + id: 'uptime', + title: 'Uptime Kuma 外部哨兵', + subtitle: 'status.961504.xyz · SG Azure', + iconUrl: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/uptime-kuma.png', + online: t.services.uptime, + desc: '独立部署在新加坡 Azure 公有云上的 24 小时外部监控哨兵,通过 Tailscale P2P 专线实时探测家庭服务。', + edgeUrl: 'https://status.961504.xyz', + homeUrl: 'https://status.961504.xyz', + lanUrl: 'https://status.961504.xyz', + stats: [ + { label: '云端公网 IP', value: '104.43.105.243' }, + { label: 'Tailscale 专线', value: '100.115.204.51' }, + { label: '外部探测状态', value: '100% 在线', highlight: true }, + ], + }, + ], + }, + ]; + }, [telemetry]); + + return ( +
+ {/* Toast Notification */} + {toast && ( +
+ + {toast} +
+ )} + + {/* 1. Top Utility & System Resources Ribbon */} + + + {/* 2. Main Categorized 3-Column Rows */} +
+ {serviceGroups.map((group) => ( +
+
+
+

+ {group.title} +

+ + · {group.subtitle} + +
+ {group.showRouteHint && ( + + 当前路由模式: {activeModeLabel} + + )} +
+ +
+ {group.items.map((card) => ( + + ))} +
+
+ ))} + + {/* 3. Bottom SSH Quick Copy & Maintenance Shelf */} + +
+ + {/* 4. Global Cmd+K Command Palette */} + + + {/* 5. Embedded AGY Cloud Terminal Modal */} + +
+ ); +}; diff --git a/stacks/portal/web/src/components/AgyTerminalModal.tsx b/stacks/portal/web/src/components/AgyTerminalModal.tsx new file mode 100644 index 0000000..9b9ed2c --- /dev/null +++ b/stacks/portal/web/src/components/AgyTerminalModal.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { usePortalStore } from '../store/usePortalStore'; + +export const AgyTerminalModal: React.FC = () => { + const { showAgyModal, setShowAgyModal, getEffectiveMode } = usePortalStore(); + + if (!showAgyModal) return null; + + const mode = getEffectiveMode(); + const url = + mode === 'lan' + ? 'http://192.168.31.164:7681' + : mode === 'home10443' + ? 'https://agy.home.961504.xyz:10443' + : 'https://agy.961504.xyz'; + + return ( +
+
+
+
+ AGY + + AGY 云端工作台 · tmux 持久会话 (关窗不断连) + +
+
+ + 新标签页全屏 ↗ + + +
+
+