diff --git a/server/public/assets/index-C3cFkTvH.js b/server/public/assets/index-C3cFkTvH.js deleted file mode 100644 index 07110366..00000000 --- a/server/public/assets/index-C3cFkTvH.js +++ /dev/null @@ -1,126 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OrbitControls-BJ-UXxdt.js","assets/three.module--MGUDD-H.js"])))=>i.map(i=>d[i]); -(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))o(u);new MutationObserver(u=>{for(const f of u)if(f.type==="childList")for(const p of f.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&o(p)}).observe(document,{childList:!0,subtree:!0});function r(u){const f={};return u.integrity&&(f.integrity=u.integrity),u.referrerPolicy&&(f.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?f.credentials="include":u.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function o(u){if(u.ep)return;u.ep=!0;const f=r(u);fetch(u.href,f)}})();function kd(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var he={exports:{}},h8={};var Kr;function Rd(){if(Kr)return h8;Kr=1;var t=Symbol.for("react.transitional.element"),a=Symbol.for("react.fragment");function r(o,u,f){var p=null;if(f!==void 0&&(p=""+f),u.key!==void 0&&(p=""+u.key),"key"in u){f={};for(var v in u)v!=="key"&&(f[v]=u[v])}else f=u;return u=f.ref,{$$typeof:t,type:o,key:p,ref:u!==void 0?u:null,props:f}}return h8.Fragment=a,h8.jsx=r,h8.jsxs=r,h8}var Qr;function Ed(){return Qr||(Qr=1,he.exports=Rd()),he.exports}var l=Ed(),de={exports:{}},k1={};var Xr;function Td(){if(Xr)return k1;Xr=1;var t=Symbol.for("react.transitional.element"),a=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),f=Symbol.for("react.consumer"),p=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),z=Symbol.for("react.suspense"),g=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),y=Symbol.iterator;function S(F){return F===null||typeof F!="object"?null:(F=y&&F[y]||F["@@iterator"],typeof F=="function"?F:null)}var L={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},w=Object.assign,C={};function H(F,$,t1){this.props=F,this.context=$,this.refs=C,this.updater=t1||L}H.prototype.isReactComponent={},H.prototype.setState=function(F,$){if(typeof F!="object"&&typeof F!="function"&&F!=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,F,$,"setState")},H.prototype.forceUpdate=function(F){this.updater.enqueueForceUpdate(this,F,"forceUpdate")};function j(){}j.prototype=H.prototype;function V(F,$,t1){this.props=F,this.context=$,this.refs=C,this.updater=t1||L}var B=V.prototype=new j;B.constructor=V,w(B,H.prototype),B.isPureReactComponent=!0;var R=Array.isArray;function E(){}var k={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function _(F,$,t1){var f1=t1.ref;return{$$typeof:t,type:F,key:$,ref:f1!==void 0?f1:null,props:t1}}function U(F,$){return _(F.type,$,F.props)}function P(F){return typeof F=="object"&&F!==null&&F.$$typeof===t}function Z(F){var $={"=":"=0",":":"=2"};return"$"+F.replace(/[=:]/g,function(t1){return $[t1]})}var o1=/\/+/g;function i1(F,$){return typeof F=="object"&&F!==null&&F.key!=null?Z(""+F.key):$.toString(36)}function W(F){switch(F.status){case"fulfilled":return F.value;case"rejected":throw F.reason;default:switch(typeof F.status=="string"?F.then(E,E):(F.status="pending",F.then(function($){F.status==="pending"&&(F.status="fulfilled",F.value=$)},function($){F.status==="pending"&&(F.status="rejected",F.reason=$)})),F.status){case"fulfilled":return F.value;case"rejected":throw F.reason}}throw F}function N(F,$,t1,f1,g1){var M1=typeof F;(M1==="undefined"||M1==="boolean")&&(F=null);var a1=!1;if(F===null)a1=!0;else switch(M1){case"bigint":case"string":case"number":a1=!0;break;case"object":switch(F.$$typeof){case t:case a:a1=!0;break;case x:return a1=F._init,N(a1(F._payload),$,t1,f1,g1)}}if(a1)return g1=g1(F),a1=f1===""?"."+i1(F,0):f1,R(g1)?(t1="",a1!=null&&(t1=a1.replace(o1,"$&/")+"/"),N(g1,$,t1,"",function(z1){return z1})):g1!=null&&(P(g1)&&(g1=U(g1,t1+(g1.key==null||F&&F.key===g1.key?"":(""+g1.key).replace(o1,"$&/")+"/")+a1)),$.push(g1)),1;a1=0;var y1=f1===""?".":f1+":";if(R(F))for(var d1=0;d1>>1,r1=N[J];if(0>>1;Ju(t1,G))f1u(g1,t1)?(N[J]=g1,N[f1]=G,J=f1):(N[J]=t1,N[$]=G,J=$);else if(f1u(g1,G))N[J]=g1,N[f1]=G,J=f1;else break t}}return D}function u(N,D){var G=N.sortIndex-D.sortIndex;return G!==0?G:N.id-D.id}if(t.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var f=performance;t.unstable_now=function(){return f.now()}}else{var p=Date,v=p.now();t.unstable_now=function(){return p.now()-v}}var z=[],g=[],x=1,b=null,y=3,S=!1,L=!1,w=!1,C=!1,H=typeof setTimeout=="function"?setTimeout:null,j=typeof clearTimeout=="function"?clearTimeout:null,V=typeof setImmediate<"u"?setImmediate:null;function B(N){for(var D=r(g);D!==null;){if(D.callback===null)o(g);else if(D.startTime<=N)o(g),D.sortIndex=D.expirationTime,a(z,D);else break;D=r(g)}}function R(N){if(w=!1,B(N),!L)if(r(z)!==null)L=!0,E||(E=!0,Z());else{var D=r(g);D!==null&&W(R,D.startTime-N)}}var E=!1,k=-1,T=5,_=-1;function U(){return C?!0:!(t.unstable_now()-_N&&U());){var J=b.callback;if(typeof J=="function"){b.callback=null,y=b.priorityLevel;var r1=J(b.expirationTime<=N);if(N=t.unstable_now(),typeof r1=="function"){b.callback=r1,B(N),D=!0;break e}b===r(z)&&o(z),B(N)}else o(z);b=r(z)}if(b!==null)D=!0;else{var F=r(g);F!==null&&W(R,F.startTime-N),D=!1}}break t}finally{b=null,y=G,S=!1}D=void 0}}finally{D?Z():E=!1}}}var Z;if(typeof V=="function")Z=function(){V(P)};else if(typeof MessageChannel<"u"){var o1=new MessageChannel,i1=o1.port2;o1.port1.onmessage=P,Z=function(){i1.postMessage(null)}}else Z=function(){H(P,0)};function W(N,D){k=H(function(){N(t.unstable_now())},D)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(N){N.callback=null},t.unstable_forceFrameRate=function(N){0>N||125J?(N.sortIndex=G,a(g,N),r(z)===null&&N===r(g)&&(w?(j(k),k=-1):w=!0,W(R,G-J))):(N.sortIndex=r1,a(z,N),L||S||(L=!0,E||(E=!0,Z()))),N},t.unstable_shouldYield=U,t.unstable_wrapCallback=function(N){var D=y;return function(){var G=y;y=D;try{return N.apply(this,arguments)}finally{y=G}}}})(ve)),ve}var ti;function Dd(){return ti||(ti=1,me.exports=qd()),me.exports}var pe={exports:{}},U2={};var ei;function _d(){if(ei)return U2;ei=1;var t=pc();function a(z){var g="https://react.dev/errors/"+z;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(a){console.error(a)}}return t(),pe.exports=_d(),pe.exports}var ai;function Od(){if(ai)return d8;ai=1;var t=Dd(),a=pc(),r=Vs();function o(e){var c="https://react.dev/errors/"+e;if(1r1||(e.current=J[r1],J[r1]=null,r1--)}function t1(e,c){r1++,J[r1]=e.current,e.current=c}var f1=F(null),g1=F(null),M1=F(null),a1=F(null);function y1(e,c){switch(t1(M1,c),t1(g1,e),t1(f1,null),c.nodeType){case 9:case 11:e=(e=c.documentElement)&&(e=e.namespaceURI)?xr(e):0;break;default:if(e=c.tagName,c=c.namespaceURI)c=xr(c),e=zr(c,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}$(f1),t1(f1,e)}function d1(){$(f1),$(g1),$(M1)}function z1(e){e.memoizedState!==null&&t1(a1,e);var c=f1.current,n=zr(c,e.type);c!==n&&(t1(g1,e),t1(f1,n))}function b1(e){g1.current===e&&($(f1),$(g1)),a1.current===e&&($(a1),i8._currentValue=G)}var c1,V1;function L1(e){if(c1===void 0)try{throw Error()}catch(n){var c=n.stack.trim().match(/\n( *(at )?)/);c1=c&&c[1]||"",V1=-1)":-1h||q[s]!==K[h]){var e1=` -`+q[s].replace(" at new "," at ");return e.displayName&&e1.includes("")&&(e1=e1.replace("",e.displayName)),e1}while(1<=s&&0<=h);break}}}finally{x1=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?L1(n):""}function Q1(e,c){switch(e.tag){case 26:case 27:case 5:return L1(e.type);case 16:return L1("Lazy");case 13:return e.child!==c&&c!==null?L1("Suspense Fallback"):L1("Suspense");case 19:return L1("SuspenseList");case 0:case 15:return A1(e.type,!1);case 11:return A1(e.type.render,!1);case 1:return A1(e.type,!0);case 31:return L1("Activity");default:return""}}function L2(e){try{var c="",n=null;do c+=Q1(e,n),n=e,e=e.return;while(e);return c}catch(s){return` -Error generating stack: `+s.message+` -`+s.stack}}var u1=Object.prototype.hasOwnProperty,s1=t.unstable_scheduleCallback,v1=t.unstable_cancelCallback,H1=t.unstable_shouldYield,D1=t.unstable_requestPaint,N1=t.unstable_now,r2=t.unstable_getCurrentPriorityLevel,e2=t.unstable_ImmediatePriority,I1=t.unstable_UserBlockingPriority,B2=t.unstable_NormalPriority,m1=t.unstable_LowPriority,p1=t.unstable_IdlePriority,X1=t.log,b0=t.unstable_setDisableYieldValue,q3=null,O2=null;function N4(e){if(typeof X1=="function"&&b0(e),O2&&typeof O2.setStrictMode=="function")try{O2.setStrictMode(q3,e)}catch{}}var C1=Math.clz32?Math.clz32:G1,i2=Math.log,s2=Math.LN2;function G1(e){return e>>>=0,e===0?32:31-(i2(e)/s2|0)|0}var J1=256,I2=262144,F4=4194304;function o4(e){var c=e&42;if(c!==0)return c;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function v2(e,c,n){var s=e.pendingLanes;if(s===0)return 0;var h=0,d=e.suspendedLanes,M=e.pingedLanes;e=e.warmLanes;var A=s&134217727;return A!==0?(s=A&~d,s!==0?h=o4(s):(M&=A,M!==0?h=o4(M):n||(n=A&~e,n!==0&&(h=o4(n))))):(A=s&~d,A!==0?h=o4(A):M!==0?h=o4(M):n||(n=s&~e,n!==0&&(h=o4(n)))),h===0?0:c!==0&&c!==h&&(c&d)===0&&(d=h&-h,n=c&-c,d>=n||d===32&&(n&4194048)!==0)?c:h}function C4(e,c){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&c)===0}function Mu(e,c){switch(e){case 1:case 2:case 4:case 8:case 64:return c+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return c+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Jc(){var e=F4;return F4<<=1,(F4&62914560)===0&&(F4=4194304),e}function W7(e){for(var c=[],n=0;31>n;n++)c.push(e);return c}function M0(e,c){e.pendingLanes|=c,c!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function yu(e,c,n,s,h,d){var M=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var A=e.entanglements,q=e.expirationTimes,K=e.hiddenUpdates;for(n=M&~n;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Au=/[\n"\\]/g;function h4(e){return e.replace(Au,function(c){return"\\"+c.charCodeAt(0).toString(16)+" "})}function lt(e,c,n,s,h,d,M,A){e.name="",M!=null&&typeof M!="function"&&typeof M!="symbol"&&typeof M!="boolean"?e.type=M:e.removeAttribute("type"),c!=null?M==="number"?(c===0&&e.value===""||e.value!=c)&&(e.value=""+u4(c)):e.value!==""+u4(c)&&(e.value=""+u4(c)):M!=="submit"&&M!=="reset"||e.removeAttribute("value"),c!=null?rt(e,M,u4(c)):n!=null?rt(e,M,u4(n)):s!=null&&e.removeAttribute("value"),h==null&&d!=null&&(e.defaultChecked=!!d),h!=null&&(e.checked=h&&typeof h!="function"&&typeof h!="symbol"),A!=null&&typeof A!="function"&&typeof A!="symbol"&&typeof A!="boolean"?e.name=""+u4(A):e.removeAttribute("name")}function ha(e,c,n,s,h,d,M,A){if(d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"&&(e.type=d),c!=null||n!=null){if(!(d!=="submit"&&d!=="reset"||c!=null)){nt(e);return}n=n!=null?""+u4(n):"",c=c!=null?""+u4(c):n,A||c===e.value||(e.value=c),e.defaultValue=c}s=s??h,s=typeof s!="function"&&typeof s!="symbol"&&!!s,e.checked=A?e.checked:!!s,e.defaultChecked=!!s,M!=null&&typeof M!="function"&&typeof M!="symbol"&&typeof M!="boolean"&&(e.name=M),nt(e)}function rt(e,c,n){c==="number"&&U8(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function x6(e,c,n,s){if(e=e.options,c){c={};for(var h=0;h"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ht=!1;if(U4)try{var H0={};Object.defineProperty(H0,"passive",{get:function(){ht=!0}}),window.addEventListener("test",H0,H0),window.removeEventListener("test",H0,H0)}catch{ht=!1}var f3=null,dt=null,$8=null;function xa(){if($8)return $8;var e,c=dt,n=c.length,s,h="value"in f3?f3.value:f3.textContent,d=h.length;for(e=0;e=A0),Ca=" ",Ha=!1;function Sa(e,c){switch(e){case"keyup":return ch.indexOf(c.keyCode)!==-1;case"keydown":return c.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Va(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var y6=!1;function nh(e,c){switch(e){case"compositionend":return Va(c);case"keypress":return c.which!==32?null:(Ha=!0,Ca);case"textInput":return e=c.data,e===Ca&&Ha?null:e;default:return null}}function lh(e,c){if(y6)return e==="compositionend"||!gt&&Sa(e,c)?(e=xa(),$8=dt=f3=null,y6=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(c.ctrlKey||c.altKey||c.metaKey)||c.ctrlKey&&c.altKey){if(c.char&&1=c)return{node:n,offset:c-e};e=s}t:{for(;n;){if(n.nextSibling){n=n.nextSibling;break t}n=n.parentNode}n=void 0}n=Ra(n)}}function Ta(e,c){return e&&c?e===c?!0:e&&e.nodeType===3?!1:c&&c.nodeType===3?Ta(e,c.parentNode):"contains"in e?e.contains(c):e.compareDocumentPosition?!!(e.compareDocumentPosition(c)&16):!1:!1}function qa(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var c=U8(e.document);c instanceof e.HTMLIFrameElement;){try{var n=typeof c.contentWindow.location.href=="string"}catch{n=!1}if(n)e=c.contentWindow;else break;c=U8(e.document)}return c}function bt(e){var c=e&&e.nodeName&&e.nodeName.toLowerCase();return c&&(c==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||c==="textarea"||e.contentEditable==="true")}var fh=U4&&"documentMode"in document&&11>=document.documentMode,w6=null,Mt=null,N0=null,yt=!1;function Da(e,c,n){var s=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;yt||w6==null||w6!==U8(s)||(s=w6,"selectionStart"in s&&bt(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),N0&&j0(N0,s)||(N0=s,s=T5(Mt,"onSelect"),0>=M,h-=M,k4=1<<32-C1(c)+h|n<T1?(Z1=S1,S1=null):Z1=S1.sibling;var Y1=Q(I,S1,Y[T1],n1);if(Y1===null){S1===null&&(S1=Z1);break}e&&S1&&Y1.alternate===null&&c(I,S1),O=d(Y1,O,T1),P1===null?B1=Y1:P1.sibling=Y1,P1=Y1,S1=Z1}if(T1===Y.length)return n(I,S1),$1&&$4(I,T1),B1;if(S1===null){for(;T1T1?(Z1=S1,S1=null):Z1=S1.sibling;var R3=Q(I,S1,Y1.value,n1);if(R3===null){S1===null&&(S1=Z1);break}e&&S1&&R3.alternate===null&&c(I,S1),O=d(R3,O,T1),P1===null?B1=R3:P1.sibling=R3,P1=R3,S1=Z1}if(Y1.done)return n(I,S1),$1&&$4(I,T1),B1;if(S1===null){for(;!Y1.done;T1++,Y1=Y.next())Y1=l1(I,Y1.value,n1),Y1!==null&&(O=d(Y1,O,T1),P1===null?B1=Y1:P1.sibling=Y1,P1=Y1);return $1&&$4(I,T1),B1}for(S1=s(S1);!Y1.done;T1++,Y1=Y.next())Y1=X(S1,I,T1,Y1.value,n1),Y1!==null&&(e&&Y1.alternate!==null&&S1.delete(Y1.key===null?T1:Y1.key),O=d(Y1,O,T1),P1===null?B1=Y1:P1.sibling=Y1,P1=Y1);return e&&S1.forEach(function(Fd){return c(I,Fd)}),$1&&$4(I,T1),B1}function n2(I,O,Y,n1){if(typeof Y=="object"&&Y!==null&&Y.type===w&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case S:t:{for(var B1=Y.key;O!==null;){if(O.key===B1){if(B1=Y.type,B1===w){if(O.tag===7){n(I,O.sibling),n1=h(O,Y.props.children),n1.return=I,I=n1;break t}}else if(O.elementType===B1||typeof B1=="object"&&B1!==null&&B1.$$typeof===T&&K3(B1)===O.type){n(I,O.sibling),n1=h(O,Y.props),q0(n1,Y),n1.return=I,I=n1;break t}n(I,O);break}else c(I,O);O=O.sibling}Y.type===w?(n1=$3(Y.props.children,I.mode,n1,Y.key),n1.return=I,I=n1):(n1=t5(Y.type,Y.key,Y.props,null,I.mode,n1),q0(n1,Y),n1.return=I,I=n1)}return M(I);case L:t:{for(B1=Y.key;O!==null;){if(O.key===B1)if(O.tag===4&&O.stateNode.containerInfo===Y.containerInfo&&O.stateNode.implementation===Y.implementation){n(I,O.sibling),n1=h(O,Y.children||[]),n1.return=I,I=n1;break t}else{n(I,O);break}else c(I,O);O=O.sibling}n1=Lt(Y,I.mode,n1),n1.return=I,I=n1}return M(I);case T:return Y=K3(Y),n2(I,O,Y,n1)}if(W(Y))return w1(I,O,Y,n1);if(Z(Y)){if(B1=Z(Y),typeof B1!="function")throw Error(o(150));return Y=B1.call(Y),j1(I,O,Y,n1)}if(typeof Y.then=="function")return n2(I,O,i5(Y),n1);if(Y.$$typeof===V)return n2(I,O,a5(I,Y),n1);s5(I,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"||typeof Y=="bigint"?(Y=""+Y,O!==null&&O.tag===6?(n(I,O.sibling),n1=h(O,Y),n1.return=I,I=n1):(n(I,O),n1=At(Y,I.mode,n1),n1.return=I,I=n1),M(I)):n(I,O)}return function(I,O,Y,n1){try{T0=0;var B1=n2(I,O,Y,n1);return k6=null,B1}catch(S1){if(S1===F6||S1===l5)throw S1;var P1=e4(29,S1,null,I.mode);return P1.lanes=n1,P1.return=I,P1}finally{}}}var X3=on(!0),un=on(!1),x3=!1;function Ot(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ut(e,c){e=e.updateQueue,c.updateQueue===e&&(c.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function z3(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function b3(e,c,n){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(K1&2)!==0){var h=s.pending;return h===null?c.next=c:(c.next=h.next,h.next=c),s.pending=c,c=W8(e),Ia(e,null,n),c}return J8(e,s,c,n),W8(e)}function D0(e,c,n){if(c=c.updateQueue,c!==null&&(c=c.shared,(n&4194048)!==0)){var s=c.lanes;s&=e.pendingLanes,n|=s,c.lanes=n,ta(e,n)}}function Zt(e,c){var n=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,n===s)){var h=null,d=null;if(n=n.firstBaseUpdate,n!==null){do{var M={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};d===null?h=d=M:d=d.next=M,n=n.next}while(n!==null);d===null?h=d=c:d=d.next=c}else h=d=c;n={baseState:s.baseState,firstBaseUpdate:h,lastBaseUpdate:d,shared:s.shared,callbacks:s.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=c:e.next=c,n.lastBaseUpdate=c}var $t=!1;function _0(){if($t){var e=N6;if(e!==null)throw e}}function O0(e,c,n,s){$t=!1;var h=e.updateQueue;x3=!1;var d=h.firstBaseUpdate,M=h.lastBaseUpdate,A=h.shared.pending;if(A!==null){h.shared.pending=null;var q=A,K=q.next;q.next=null,M===null?d=K:M.next=K,M=q;var e1=e.alternate;e1!==null&&(e1=e1.updateQueue,A=e1.lastBaseUpdate,A!==M&&(A===null?e1.firstBaseUpdate=K:A.next=K,e1.lastBaseUpdate=q))}if(d!==null){var l1=h.baseState;M=0,e1=K=q=null,A=d;do{var Q=A.lane&-536870913,X=Q!==A.lane;if(X?(U1&Q)===Q:(s&Q)===Q){Q!==0&&Q===j6&&($t=!0),e1!==null&&(e1=e1.next={lane:0,tag:A.tag,payload:A.payload,callback:null,next:null});t:{var w1=e,j1=A;Q=c;var n2=n;switch(j1.tag){case 1:if(w1=j1.payload,typeof w1=="function"){l1=w1.call(n2,l1,Q);break t}l1=w1;break t;case 3:w1.flags=w1.flags&-65537|128;case 0:if(w1=j1.payload,Q=typeof w1=="function"?w1.call(n2,l1,Q):w1,Q==null)break t;l1=b({},l1,Q);break t;case 2:x3=!0}}Q=A.callback,Q!==null&&(e.flags|=64,X&&(e.flags|=8192),X=h.callbacks,X===null?h.callbacks=[Q]:X.push(Q))}else X={lane:Q,tag:A.tag,payload:A.payload,callback:A.callback,next:null},e1===null?(K=e1=X,q=l1):e1=e1.next=X,M|=Q;if(A=A.next,A===null){if(A=h.shared.pending,A===null)break;X=A,A=X.next,X.next=null,h.lastBaseUpdate=X,h.shared.pending=null}}while(!0);e1===null&&(q=l1),h.baseState=q,h.firstBaseUpdate=K,h.lastBaseUpdate=e1,d===null&&(h.shared.lanes=0),H3|=M,e.lanes=M,e.memoizedState=l1}}function hn(e,c){if(typeof e!="function")throw Error(o(191,e));e.call(c)}function dn(e,c){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ed?d:8;var M=N.T,A={};N.T=A,o9(e,!1,c,n);try{var q=h(),K=N.S;if(K!==null&&K(A,q),q!==null&&typeof q=="object"&&typeof q.then=="function"){var e1=yh(q,s);$0(e,c,e1,r4(e))}else $0(e,c,s,r4(e))}catch(l1){$0(e,c,{then:function(){},status:"rejected",reason:l1},r4())}finally{D.p=d,M!==null&&A.types!==null&&(M.types=A.types),N.T=M}}function Ah(){}function i9(e,c,n,s){if(e.tag!==5)throw Error(o(476));var h=$n(e).queue;Zn(e,h,c,G,n===null?Ah:function(){return Gn(e),n(s)})}function $n(e){var c=e.memoizedState;if(c!==null)return c;c={memoizedState:G,baseState:G,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Y4,lastRenderedState:G},next:null};var n={};return c.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Y4,lastRenderedState:n},next:null},e.memoizedState=c,e=e.alternate,e!==null&&(e.memoizedState=c),c}function Gn(e){var c=$n(e);c.next===null&&(c=e.alternate.memoizedState),$0(e,c.next.queue,{},r4())}function s9(){return E2(i8)}function In(){return z2().memoizedState}function Pn(){return z2().memoizedState}function Lh(e){for(var c=e.return;c!==null;){switch(c.tag){case 24:case 3:var n=r4();e=z3(n);var s=b3(c,e,n);s!==null&&(W2(s,c,n),D0(s,c,n)),c={cache:Tt()},e.payload=c;return}c=c.return}}function Bh(e,c,n){var s=r4();n={lane:s,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},x5(e)?Kn(c,n):(n=St(e,c,n,s),n!==null&&(W2(n,e,s),Qn(n,c,s)))}function Yn(e,c,n){var s=r4();$0(e,c,n,s)}function $0(e,c,n,s){var h={lane:s,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(x5(e))Kn(c,h);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=c.lastRenderedReducer,d!==null))try{var M=c.lastRenderedState,A=d(M,n);if(h.hasEagerState=!0,h.eagerState=A,t4(A,M))return J8(e,c,h,0),l2===null&&X8(),!1}catch{}finally{}if(n=St(e,c,h,s),n!==null)return W2(n,e,s),Qn(n,c,s),!0}return!1}function o9(e,c,n,s){if(s={lane:2,revertLane:O9(),gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null},x5(e)){if(c)throw Error(o(479))}else c=St(e,n,s,2),c!==null&&W2(c,e,2)}function x5(e){var c=e.alternate;return e===E1||c!==null&&c===E1}function Kn(e,c){E6=h5=!0;var n=e.pending;n===null?c.next=c:(c.next=n.next,n.next=c),e.pending=c}function Qn(e,c,n){if((n&4194048)!==0){var s=c.lanes;s&=e.pendingLanes,n|=s,c.lanes=n,ta(e,n)}}var G0={readContext:E2,use:m5,useCallback:p2,useContext:p2,useEffect:p2,useImperativeHandle:p2,useLayoutEffect:p2,useInsertionEffect:p2,useMemo:p2,useReducer:p2,useRef:p2,useState:p2,useDebugValue:p2,useDeferredValue:p2,useTransition:p2,useSyncExternalStore:p2,useId:p2,useHostTransitionStatus:p2,useFormState:p2,useActionState:p2,useOptimistic:p2,useMemoCache:p2,useCacheRefresh:p2};G0.useEffectEvent=p2;var Xn={readContext:E2,use:m5,useCallback:function(e,c){return $2().memoizedState=[e,c===void 0?null:c],e},useContext:E2,useEffect:kn,useImperativeHandle:function(e,c,n){n=n!=null?n.concat([e]):null,p5(4194308,4,qn.bind(null,c,e),n)},useLayoutEffect:function(e,c){return p5(4194308,4,e,c)},useInsertionEffect:function(e,c){p5(4,2,e,c)},useMemo:function(e,c){var n=$2();c=c===void 0?null:c;var s=e();if(J3){N4(!0);try{e()}finally{N4(!1)}}return n.memoizedState=[s,c],s},useReducer:function(e,c,n){var s=$2();if(n!==void 0){var h=n(c);if(J3){N4(!0);try{n(c)}finally{N4(!1)}}}else h=c;return s.memoizedState=s.baseState=h,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:h},s.queue=e,e=e.dispatch=Bh.bind(null,E1,e),[s.memoizedState,e]},useRef:function(e){var c=$2();return e={current:e},c.memoizedState=e},useState:function(e){e=c9(e);var c=e.queue,n=Yn.bind(null,E1,c);return c.dispatch=n,[e.memoizedState,n]},useDebugValue:l9,useDeferredValue:function(e,c){var n=$2();return r9(n,e,c)},useTransition:function(){var e=c9(!1);return e=Zn.bind(null,E1,e.queue,!0,!1),$2().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,c,n){var s=E1,h=$2();if($1){if(n===void 0)throw Error(o(407));n=n()}else{if(n=c(),l2===null)throw Error(o(349));(U1&127)!==0||xn(s,c,n)}h.memoizedState=n;var d={value:n,getSnapshot:c};return h.queue=d,kn(bn.bind(null,s,d,e),[e]),s.flags|=2048,q6(9,{destroy:void 0},zn.bind(null,s,d,n,c),null),n},useId:function(){var e=$2(),c=l2.identifierPrefix;if($1){var n=R4,s=k4;n=(s&~(1<<32-C1(s)-1)).toString(32)+n,c="_"+c+"R_"+n,n=d5++,0<\/script>",d=d.removeChild(d.firstChild);break;case"select":d=typeof s.is=="string"?M.createElement("select",{is:s.is}):M.createElement("select"),s.multiple?d.multiple=!0:s.size&&(d.size=s.size);break;default:d=typeof s.is=="string"?M.createElement(h,{is:s.is}):M.createElement(h)}}d[k2]=c,d[P2]=s;t:for(M=c.child;M!==null;){if(M.tag===5||M.tag===6)d.appendChild(M.stateNode);else if(M.tag!==4&&M.tag!==27&&M.child!==null){M.child.return=M,M=M.child;continue}if(M===c)break t;for(;M.sibling===null;){if(M.return===null||M.return===c)break t;M=M.return}M.sibling.return=M.return,M=M.sibling}c.stateNode=d;t:switch(q2(d,h,s),h){case"button":case"input":case"select":case"textarea":s=!!s.autoFocus;break t;case"img":s=!0;break t;default:s=!1}s&&Q4(c)}}return u2(c),w9(c,c.type,e===null?null:e.memoizedProps,c.pendingProps,n),null;case 6:if(e&&c.stateNode!=null)e.memoizedProps!==s&&Q4(c);else{if(typeof s!="string"&&c.stateNode===null)throw Error(o(166));if(e=M1.current,L6(c)){if(e=c.stateNode,n=c.memoizedProps,s=null,h=R2,h!==null)switch(h.tag){case 27:case 5:s=h.memoizedProps}e[k2]=c,e=!!(e.nodeValue===n||s!==null&&s.suppressHydrationWarning===!0||pr(e.nodeValue,n)),e||p3(c,!0)}else e=q5(e).createTextNode(s),e[k2]=c,c.stateNode=e}return u2(c),null;case 31:if(n=c.memoizedState,e===null||e.memoizedState!==null){if(s=L6(c),n!==null){if(e===null){if(!s)throw Error(o(318));if(e=c.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(o(557));e[k2]=c}else G3(),(c.flags&128)===0&&(c.memoizedState=null),c.flags|=4;u2(c),e=!1}else n=Ft(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return c.flags&256?(a4(c),c):(a4(c),null);if((c.flags&128)!==0)throw Error(o(558))}return u2(c),null;case 13:if(s=c.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(h=L6(c),s!==null&&s.dehydrated!==null){if(e===null){if(!h)throw Error(o(318));if(h=c.memoizedState,h=h!==null?h.dehydrated:null,!h)throw Error(o(317));h[k2]=c}else G3(),(c.flags&128)===0&&(c.memoizedState=null),c.flags|=4;u2(c),h=!1}else h=Ft(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=h),h=!0;if(!h)return c.flags&256?(a4(c),c):(a4(c),null)}return a4(c),(c.flags&128)!==0?(c.lanes=n,c):(n=s!==null,e=e!==null&&e.memoizedState!==null,n&&(s=c.child,h=null,s.alternate!==null&&s.alternate.memoizedState!==null&&s.alternate.memoizedState.cachePool!==null&&(h=s.alternate.memoizedState.cachePool.pool),d=null,s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(d=s.memoizedState.cachePool.pool),d!==h&&(s.flags|=2048)),n!==e&&n&&(c.child.flags|=8192),w5(c,c.updateQueue),u2(c),null);case 4:return d1(),e===null&&G9(c.stateNode.containerInfo),u2(c),null;case 10:return I4(c.type),u2(c),null;case 19:if($(x2),s=c.memoizedState,s===null)return u2(c),null;if(h=(c.flags&128)!==0,d=s.rendering,d===null)if(h)P0(s,!1);else{if(g2!==0||e!==null&&(e.flags&128)!==0)for(e=c.child;e!==null;){if(d=u5(e),d!==null){for(c.flags|=128,P0(s,!1),e=d.updateQueue,c.updateQueue=e,w5(c,e),c.subtreeFlags=0,e=n,n=c.child;n!==null;)Pa(n,e),n=n.sibling;return t1(x2,x2.current&1|2),$1&&$4(c,s.treeForkCount),c.child}e=e.sibling}s.tail!==null&&N1()>A5&&(c.flags|=128,h=!0,P0(s,!1),c.lanes=4194304)}else{if(!h)if(e=u5(d),e!==null){if(c.flags|=128,h=!0,e=e.updateQueue,c.updateQueue=e,w5(c,e),P0(s,!0),s.tail===null&&s.tailMode==="hidden"&&!d.alternate&&!$1)return u2(c),null}else 2*N1()-s.renderingStartTime>A5&&n!==536870912&&(c.flags|=128,h=!0,P0(s,!1),c.lanes=4194304);s.isBackwards?(d.sibling=c.child,c.child=d):(e=s.last,e!==null?e.sibling=d:c.child=d,s.last=d)}return s.tail!==null?(e=s.tail,s.rendering=e,s.tail=e.sibling,s.renderingStartTime=N1(),e.sibling=null,n=x2.current,t1(x2,h?n&1|2:n&1),$1&&$4(c,s.treeForkCount),e):(u2(c),null);case 22:case 23:return a4(c),It(),s=c.memoizedState!==null,e!==null?e.memoizedState!==null!==s&&(c.flags|=8192):s&&(c.flags|=8192),s?(n&536870912)!==0&&(c.flags&128)===0&&(u2(c),c.subtreeFlags&6&&(c.flags|=8192)):u2(c),n=c.updateQueue,n!==null&&w5(c,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),s=null,c.memoizedState!==null&&c.memoizedState.cachePool!==null&&(s=c.memoizedState.cachePool.pool),s!==n&&(c.flags|=2048),e!==null&&$(Y3),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),c.memoizedState.cache!==n&&(c.flags|=2048),I4(M2),u2(c),null;case 25:return null;case 30:return null}throw Error(o(156,c.tag))}function Rh(e,c){switch(jt(c),c.tag){case 1:return e=c.flags,e&65536?(c.flags=e&-65537|128,c):null;case 3:return I4(M2),d1(),e=c.flags,(e&65536)!==0&&(e&128)===0?(c.flags=e&-65537|128,c):null;case 26:case 27:case 5:return b1(c),null;case 31:if(c.memoizedState!==null){if(a4(c),c.alternate===null)throw Error(o(340));G3()}return e=c.flags,e&65536?(c.flags=e&-65537|128,c):null;case 13:if(a4(c),e=c.memoizedState,e!==null&&e.dehydrated!==null){if(c.alternate===null)throw Error(o(340));G3()}return e=c.flags,e&65536?(c.flags=e&-65537|128,c):null;case 19:return $(x2),null;case 4:return d1(),null;case 10:return I4(c.type),null;case 22:case 23:return a4(c),It(),e!==null&&$(Y3),e=c.flags,e&65536?(c.flags=e&-65537|128,c):null;case 24:return I4(M2),null;case 25:return null;default:return null}}function Ml(e,c){switch(jt(c),c.tag){case 3:I4(M2),d1();break;case 26:case 27:case 5:b1(c);break;case 4:d1();break;case 31:c.memoizedState!==null&&a4(c);break;case 13:a4(c);break;case 19:$(x2);break;case 10:I4(c.type);break;case 22:case 23:a4(c),It(),e!==null&&$(Y3);break;case 24:I4(M2)}}function Y0(e,c){try{var n=c.updateQueue,s=n!==null?n.lastEffect:null;if(s!==null){var h=s.next;n=h;do{if((n.tag&e)===e){s=void 0;var d=n.create,M=n.inst;s=d(),M.destroy=s}n=n.next}while(n!==h)}}catch(A){t2(c,c.return,A)}}function w3(e,c,n){try{var s=c.updateQueue,h=s!==null?s.lastEffect:null;if(h!==null){var d=h.next;s=d;do{if((s.tag&e)===e){var M=s.inst,A=M.destroy;if(A!==void 0){M.destroy=void 0,h=c;var q=n,K=A;try{K()}catch(e1){t2(h,q,e1)}}}s=s.next}while(s!==d)}}catch(e1){t2(c,c.return,e1)}}function yl(e){var c=e.updateQueue;if(c!==null){var n=e.stateNode;try{dn(c,n)}catch(s){t2(e,e.return,s)}}}function wl(e,c,n){n.props=W3(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(s){t2(e,c,s)}}function K0(e,c){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var s=e.stateNode;break;case 30:s=e.stateNode;break;default:s=e.stateNode}typeof n=="function"?e.refCleanup=n(s):n.current=s}}catch(h){t2(e,c,h)}}function E4(e,c){var n=e.ref,s=e.refCleanup;if(n!==null)if(typeof s=="function")try{s()}catch(h){t2(e,c,h)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n=="function")try{n(null)}catch(h){t2(e,c,h)}else n.current=null}function Cl(e){var c=e.type,n=e.memoizedProps,s=e.stateNode;try{t:switch(c){case"button":case"input":case"select":case"textarea":n.autoFocus&&s.focus();break t;case"img":n.src?s.src=n.src:n.srcSet&&(s.srcset=n.srcSet)}}catch(h){t2(e,e.return,h)}}function C9(e,c,n){try{var s=e.stateNode;ad(s,e.type,n,c),s[P2]=c}catch(h){t2(e,e.return,h)}}function Hl(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&B3(e.type)||e.tag===4}function H9(e){t:for(;;){for(;e.sibling===null;){if(e.return===null||Hl(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&B3(e.type)||e.flags&2||e.child===null||e.tag===4)continue t;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function S9(e,c,n){var s=e.tag;if(s===5||s===6)e=e.stateNode,c?(n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n).insertBefore(e,c):(c=n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n,c.appendChild(e),n=n._reactRootContainer,n!=null||c.onclick!==null||(c.onclick=O4));else if(s!==4&&(s===27&&B3(e.type)&&(n=e.stateNode,c=null),e=e.child,e!==null))for(S9(e,c,n),e=e.sibling;e!==null;)S9(e,c,n),e=e.sibling}function C5(e,c,n){var s=e.tag;if(s===5||s===6)e=e.stateNode,c?n.insertBefore(e,c):n.appendChild(e);else if(s!==4&&(s===27&&B3(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(C5(e,c,n),e=e.sibling;e!==null;)C5(e,c,n),e=e.sibling}function Sl(e){var c=e.stateNode,n=e.memoizedProps;try{for(var s=e.type,h=c.attributes;h.length;)c.removeAttributeNode(h[0]);q2(c,s,n),c[k2]=e,c[P2]=n}catch(d){t2(e,e.return,d)}}var X4=!1,C2=!1,V9=!1,Vl=typeof WeakSet=="function"?WeakSet:Set,N2=null;function Eh(e,c){if(e=e.containerInfo,Y9=G5,e=qa(e),bt(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else t:{n=(n=e.ownerDocument)&&n.defaultView||window;var s=n.getSelection&&n.getSelection();if(s&&s.rangeCount!==0){n=s.anchorNode;var h=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{n.nodeType,d.nodeType}catch{n=null;break t}var M=0,A=-1,q=-1,K=0,e1=0,l1=e,Q=null;e:for(;;){for(var X;l1!==n||h!==0&&l1.nodeType!==3||(A=M+h),l1!==d||s!==0&&l1.nodeType!==3||(q=M+s),l1.nodeType===3&&(M+=l1.nodeValue.length),(X=l1.firstChild)!==null;)Q=l1,l1=X;for(;;){if(l1===e)break e;if(Q===n&&++K===h&&(A=M),Q===d&&++e1===s&&(q=M),(X=l1.nextSibling)!==null)break;l1=Q,Q=l1.parentNode}l1=X}n=A===-1||q===-1?null:{start:A,end:q}}else n=null}n=n||{start:0,end:0}}else n=null;for(K9={focusedElem:e,selectionRange:n},G5=!1,N2=c;N2!==null;)if(c=N2,e=c.child,(c.subtreeFlags&1028)!==0&&e!==null)e.return=c,N2=e;else for(;N2!==null;){switch(c=N2,d=c.alternate,e=c.flags,c.tag){case 0:if((e&4)!==0&&(e=c.updateQueue,e=e!==null?e.events:null,e!==null))for(n=0;n title"))),q2(d,s,n),d[k2]=e,j2(d),s=d;break t;case"link":var M=Fr("link","href",h).get(s+(n.href||""));if(M){for(var A=0;An2&&(M=n2,n2=j1,j1=M);var I=Ea(A,j1),O=Ea(A,n2);if(I&&O&&(X.rangeCount!==1||X.anchorNode!==I.node||X.anchorOffset!==I.offset||X.focusNode!==O.node||X.focusOffset!==O.offset)){var Y=l1.createRange();Y.setStart(I.node,I.offset),X.removeAllRanges(),j1>n2?(X.addRange(Y),X.extend(O.node,O.offset)):(Y.setEnd(O.node,O.offset),X.addRange(Y))}}}}for(l1=[],X=A;X=X.parentNode;)X.nodeType===1&&l1.push({element:X,left:X.scrollLeft,top:X.scrollTop});for(typeof A.focus=="function"&&A.focus(),A=0;An?32:n,N.T=null,n=k9,k9=null;var d=V3,M=c3;if(A2=0,Z6=V3=null,c3=0,(K1&6)!==0)throw Error(o(331));var A=K1;if(K1|=4,ql(d.current),Rl(d,d.current,M,n),K1=A,e8(0,!1),O2&&typeof O2.onPostCommitFiberRoot=="function")try{O2.onPostCommitFiberRoot(q3,d)}catch{}return!0}finally{D.p=h,N.T=s,cr(e,c)}}function nr(e,c,n){c=f4(n,c),c=f9(e.stateNode,c,2),e=b3(e,c,2),e!==null&&(M0(e,2),T4(e))}function t2(e,c,n){if(e.tag===3)nr(e,e,n);else for(;c!==null;){if(c.tag===3){nr(c,e,n);break}else if(c.tag===1){var s=c.stateNode;if(typeof c.type.getDerivedStateFromError=="function"||typeof s.componentDidCatch=="function"&&(S3===null||!S3.has(s))){e=f4(n,e),n=ll(2),s=b3(c,n,2),s!==null&&(rl(n,s,c,e),M0(s,2),T4(s));break}}c=c.return}}function q9(e,c,n){var s=e.pingCache;if(s===null){s=e.pingCache=new Dh;var h=new Set;s.set(c,h)}else h=s.get(c),h===void 0&&(h=new Set,s.set(c,h));h.has(n)||(B9=!0,h.add(n),e=$h.bind(null,e,c,n),c.then(e,e))}function $h(e,c,n){var s=e.pingCache;s!==null&&s.delete(c),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,l2===e&&(U1&n)===n&&(g2===4||g2===3&&(U1&62914560)===U1&&300>N1()-V5?(K1&2)===0&&$6(e,0):j9|=n,U6===U1&&(U6=0)),T4(e)}function lr(e,c){c===0&&(c=Jc()),e=Z3(e,c),e!==null&&(M0(e,c),T4(e))}function Gh(e){var c=e.memoizedState,n=0;c!==null&&(n=c.retryLane),lr(e,n)}function Ih(e,c){var n=0;switch(e.tag){case 31:case 13:var s=e.stateNode,h=e.memoizedState;h!==null&&(n=h.retryLane);break;case 19:s=e.stateNode;break;case 22:s=e.stateNode._retryCache;break;default:throw Error(o(314))}s!==null&&s.delete(c),lr(e,n)}function Ph(e,c){return s1(e,c)}var k5=null,I6=null,D9=!1,R5=!1,_9=!1,L3=0;function T4(e){e!==I6&&e.next===null&&(I6===null?k5=I6=e:I6=I6.next=e),R5=!0,D9||(D9=!0,Kh())}function e8(e,c){if(!_9&&R5){_9=!0;do for(var n=!1,s=k5;s!==null;){if(e!==0){var h=s.pendingLanes;if(h===0)var d=0;else{var M=s.suspendedLanes,A=s.pingedLanes;d=(1<<31-C1(42|e)+1)-1,d&=h&~(M&~A),d=d&201326741?d&201326741|1:d?d|2:0}d!==0&&(n=!0,or(s,d))}else d=U1,d=v2(s,s===l2?d:0,s.cancelPendingCommit!==null||s.timeoutHandle!==-1),(d&3)===0||C4(s,d)||(n=!0,or(s,d));s=s.next}while(n);_9=!1}}function Yh(){rr()}function rr(){R5=D9=!1;var e=0;L3!==0&&ld()&&(e=L3);for(var c=N1(),n=null,s=k5;s!==null;){var h=s.next,d=ir(s,c);d===0?(s.next=null,n===null?k5=h:n.next=h,h===null&&(I6=n)):(n=s,(e!==0||(d&3)!==0)&&(R5=!0)),s=h}A2!==0&&A2!==5||e8(e),L3!==0&&(L3=0)}function ir(e,c){for(var n=e.suspendedLanes,s=e.pingedLanes,h=e.expirationTimes,d=e.pendingLanes&-62914561;0A)break;var e1=q.transferSize,l1=q.initiatorType;e1&&gr(l1)&&(q=q.responseEnd,M+=e1*(q"u"?null:document;function Lr(e,c,n){var s=P6;if(s&&typeof c=="string"&&c){var h=h4(c);h='link[rel="'+e+'"][href="'+h+'"]',typeof n=="string"&&(h+='[crossorigin="'+n+'"]'),Ar.has(h)||(Ar.add(h),e={rel:e,crossOrigin:n,href:c},s.querySelector(h)===null&&(c=s.createElement("link"),q2(c,"link",e),j2(c),s.head.appendChild(c)))}}function md(e){a3.D(e),Lr("dns-prefetch",e,null)}function vd(e,c){a3.C(e,c),Lr("preconnect",e,c)}function pd(e,c,n){a3.L(e,c,n);var s=P6;if(s&&e&&c){var h='link[rel="preload"][as="'+h4(c)+'"]';c==="image"&&n&&n.imageSrcSet?(h+='[imagesrcset="'+h4(n.imageSrcSet)+'"]',typeof n.imageSizes=="string"&&(h+='[imagesizes="'+h4(n.imageSizes)+'"]')):h+='[href="'+h4(e)+'"]';var d=h;switch(c){case"style":d=Y6(e);break;case"script":d=K6(e)}z4.has(d)||(e=b({rel:"preload",href:c==="image"&&n&&n.imageSrcSet?void 0:e,as:c},n),z4.set(d,e),s.querySelector(h)!==null||c==="style"&&s.querySelector(l8(d))||c==="script"&&s.querySelector(r8(d))||(c=s.createElement("link"),q2(c,"link",e),j2(c),s.head.appendChild(c)))}}function gd(e,c){a3.m(e,c);var n=P6;if(n&&e){var s=c&&typeof c.as=="string"?c.as:"script",h='link[rel="modulepreload"][as="'+h4(s)+'"][href="'+h4(e)+'"]',d=h;switch(s){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":d=K6(e)}if(!z4.has(d)&&(e=b({rel:"modulepreload",href:e},c),z4.set(d,e),n.querySelector(h)===null)){switch(s){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(r8(d)))return}s=n.createElement("link"),q2(s,"link",e),j2(s),n.head.appendChild(s)}}}function xd(e,c,n){a3.S(e,c,n);var s=P6;if(s&&e){var h=p6(s).hoistableStyles,d=Y6(e);c=c||"default";var M=h.get(d);if(!M){var A={loading:0,preload:null};if(M=s.querySelector(l8(d)))A.loading=5;else{e=b({rel:"stylesheet",href:e,"data-precedence":c},n),(n=z4.get(d))&&ce(e,n);var q=M=s.createElement("link");j2(q),q2(q,"link",e),q._p=new Promise(function(K,e1){q.onload=K,q.onerror=e1}),q.addEventListener("load",function(){A.loading|=1}),q.addEventListener("error",function(){A.loading|=2}),A.loading|=4,_5(M,c,s)}M={type:"stylesheet",instance:M,count:1,state:A},h.set(d,M)}}}function zd(e,c){a3.X(e,c);var n=P6;if(n&&e){var s=p6(n).hoistableScripts,h=K6(e),d=s.get(h);d||(d=n.querySelector(r8(h)),d||(e=b({src:e,async:!0},c),(c=z4.get(h))&&ae(e,c),d=n.createElement("script"),j2(d),q2(d,"link",e),n.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},s.set(h,d))}}function bd(e,c){a3.M(e,c);var n=P6;if(n&&e){var s=p6(n).hoistableScripts,h=K6(e),d=s.get(h);d||(d=n.querySelector(r8(h)),d||(e=b({src:e,async:!0,type:"module"},c),(c=z4.get(h))&&ae(e,c),d=n.createElement("script"),j2(d),q2(d,"link",e),n.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},s.set(h,d))}}function Br(e,c,n,s){var h=(h=M1.current)?D5(h):null;if(!h)throw Error(o(446));switch(e){case"meta":case"title":return null;case"style":return typeof n.precedence=="string"&&typeof n.href=="string"?(c=Y6(n.href),n=p6(h).hoistableStyles,s=n.get(c),s||(s={type:"style",instance:null,count:0,state:null},n.set(c,s)),s):{type:"void",instance:null,count:0,state:null};case"link":if(n.rel==="stylesheet"&&typeof n.href=="string"&&typeof n.precedence=="string"){e=Y6(n.href);var d=p6(h).hoistableStyles,M=d.get(e);if(M||(h=h.ownerDocument||h,M={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},d.set(e,M),(d=h.querySelector(l8(e)))&&!d._p&&(M.instance=d,M.state.loading=5),z4.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},z4.set(e,n),d||Md(h,e,n,M.state))),c&&s===null)throw Error(o(528,""));return M}if(c&&s!==null)throw Error(o(529,""));return null;case"script":return c=n.async,n=n.src,typeof n=="string"&&c&&typeof c!="function"&&typeof c!="symbol"?(c=K6(n),n=p6(h).hoistableScripts,s=n.get(c),s||(s={type:"script",instance:null,count:0,state:null},n.set(c,s)),s):{type:"void",instance:null,count:0,state:null};default:throw Error(o(444,e))}}function Y6(e){return'href="'+h4(e)+'"'}function l8(e){return'link[rel="stylesheet"]['+e+"]"}function jr(e){return b({},e,{"data-precedence":e.precedence,precedence:null})}function Md(e,c,n,s){e.querySelector('link[rel="preload"][as="style"]['+c+"]")?s.loading=1:(c=e.createElement("link"),s.preload=c,c.addEventListener("load",function(){return s.loading|=1}),c.addEventListener("error",function(){return s.loading|=2}),q2(c,"link",n),j2(c),e.head.appendChild(c))}function K6(e){return'[src="'+h4(e)+'"]'}function r8(e){return"script[async]"+e}function Nr(e,c,n){if(c.count++,c.instance===null)switch(c.type){case"style":var s=e.querySelector('style[data-href~="'+h4(n.href)+'"]');if(s)return c.instance=s,j2(s),s;var h=b({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return s=(e.ownerDocument||e).createElement("style"),j2(s),q2(s,"style",h),_5(s,n.precedence,e),c.instance=s;case"stylesheet":h=Y6(n.href);var d=e.querySelector(l8(h));if(d)return c.state.loading|=4,c.instance=d,j2(d),d;s=jr(n),(h=z4.get(h))&&ce(s,h),d=(e.ownerDocument||e).createElement("link"),j2(d);var M=d;return M._p=new Promise(function(A,q){M.onload=A,M.onerror=q}),q2(d,"link",s),c.state.loading|=4,_5(d,n.precedence,e),c.instance=d;case"script":return d=K6(n.src),(h=e.querySelector(r8(d)))?(c.instance=h,j2(h),h):(s=n,(h=z4.get(d))&&(s=b({},n),ae(s,h)),e=e.ownerDocument||e,h=e.createElement("script"),j2(h),q2(h,"link",s),e.head.appendChild(h),c.instance=h);case"void":return null;default:throw Error(o(443,c.type))}else c.type==="stylesheet"&&(c.state.loading&4)===0&&(s=c.instance,c.state.loading|=4,_5(s,n.precedence,e));return c.instance}function _5(e,c,n){for(var s=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),h=s.length?s[s.length-1]:null,d=h,M=0;M title"):null)}function yd(e,c,n){if(n===1||c.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof c.precedence!="string"||typeof c.href!="string"||c.href==="")break;return!0;case"link":if(typeof c.rel!="string"||typeof c.href!="string"||c.href===""||c.onLoad||c.onError)break;switch(c.rel){case"stylesheet":return e=c.disabled,typeof c.precedence=="string"&&e==null;default:return!0}case"script":if(c.async&&typeof c.async!="function"&&typeof c.async!="symbol"&&!c.onLoad&&!c.onError&&c.src&&typeof c.src=="string")return!0}return!1}function Rr(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function wd(e,c,n,s){if(n.type==="stylesheet"&&(typeof s.media!="string"||matchMedia(s.media).matches!==!1)&&(n.state.loading&4)===0){if(n.instance===null){var h=Y6(s.href),d=c.querySelector(l8(h));if(d){c=d._p,c!==null&&typeof c=="object"&&typeof c.then=="function"&&(e.count++,e=U5.bind(e),c.then(e,e)),n.state.loading|=4,n.instance=d,j2(d);return}d=c.ownerDocument||c,s=jr(s),(h=z4.get(h))&&ce(s,h),d=d.createElement("link"),j2(d);var M=d;M._p=new Promise(function(A,q){M.onload=A,M.onerror=q}),q2(d,"link",s),n.instance=d}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,c),(c=n.state.preload)&&(n.state.loading&3)===0&&(e.count++,n=U5.bind(e),c.addEventListener("load",n),c.addEventListener("error",n))}}var ne=0;function Cd(e,c){return e.stylesheets&&e.count===0&&$5(e,e.stylesheets),0ne?50:800)+c);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(s),clearTimeout(h)}}:null}function U5(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)$5(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Z5=null;function $5(e,c){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Z5=new Map,c.forEach(Hd,e),Z5=null,U5.call(e))}function Hd(e,c){if(!(c.state.loading&4)){var n=Z5.get(e);if(n)var s=n.get(null);else{n=new Map,Z5.set(e,n);for(var h=e.querySelectorAll("link[data-precedence],style[data-precedence]"),d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(a){console.error(a)}}return t(),fe.exports=Od(),fe.exports}var Zd=Ud();var li="popstate";function $d(t={}){function a(o,u){let{pathname:f,search:p,hash:v}=o.location;return Ke("",{pathname:f,search:p,hash:v},u.state&&u.state.usr||null,u.state&&u.state.key||"default")}function r(o,u){return typeof u=="string"?u:C8(u)}return Id(a,r,null,t)}function f2(t,a){if(t===!1||t===null||typeof t>"u")throw new Error(a)}function j4(t,a){if(!t){typeof console<"u"&&console.warn(a);try{throw new Error(a)}catch{}}}function Gd(){return Math.random().toString(36).substring(2,10)}function ri(t,a){return{usr:t.state,key:t.key,idx:a}}function Ke(t,a,r=null,o){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof a=="string"?m0(a):a,state:r,key:a&&a.key||o||Gd()}}function C8({pathname:t="/",search:a="",hash:r=""}){return a&&a!=="?"&&(t+=a.charAt(0)==="?"?a:"?"+a),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function m0(t){let a={};if(t){let r=t.indexOf("#");r>=0&&(a.hash=t.substring(r),t=t.substring(0,r));let o=t.indexOf("?");o>=0&&(a.search=t.substring(o),t=t.substring(0,o)),t&&(a.pathname=t)}return a}function Id(t,a,r,o={}){let{window:u=document.defaultView,v5Compat:f=!1}=o,p=u.history,v="POP",z=null,g=x();g==null&&(g=0,p.replaceState({...p.state,idx:g},""));function x(){return(p.state||{idx:null}).idx}function b(){v="POP";let C=x(),H=C==null?null:C-g;g=C,z&&z({action:v,location:w.location,delta:H})}function y(C,H){v="PUSH";let j=Ke(w.location,C,H);g=x()+1;let V=ri(j,g),B=w.createHref(j);try{p.pushState(V,"",B)}catch(R){if(R instanceof DOMException&&R.name==="DataCloneError")throw R;u.location.assign(B)}f&&z&&z({action:v,location:w.location,delta:1})}function S(C,H){v="REPLACE";let j=Ke(w.location,C,H);g=x();let V=ri(j,g),B=w.createHref(j);p.replaceState(V,"",B),f&&z&&z({action:v,location:w.location,delta:0})}function L(C){return Pd(C)}let w={get action(){return v},get location(){return t(u,p)},listen(C){if(z)throw new Error("A history only accepts one active listener");return u.addEventListener(li,b),z=C,()=>{u.removeEventListener(li,b),z=null}},createHref(C){return a(u,C)},createURL:L,encodeLocation(C){let H=L(C);return{pathname:H.pathname,search:H.search,hash:H.hash}},push:y,replace:S,go(C){return p.go(C)}};return w}function Pd(t,a=!1){let r="http://localhost";typeof window<"u"&&(r=window.location.origin!=="null"?window.location.origin:window.location.href),f2(r,"No window.location.(origin|href) available to create URL");let o=typeof t=="string"?t:C8(t);return o=o.replace(/ $/,"%20"),!a&&o.startsWith("//")&&(o=r+o),new URL(o,r)}function As(t,a,r="/"){return Yd(t,a,r,!1)}function Yd(t,a,r,o){let u=typeof a=="string"?m0(a):a,f=u3(u.pathname||"/",r);if(f==null)return null;let p=Ls(t);Kd(p);let v=null;for(let z=0;v==null&&z{let x={relativePath:g===void 0?p.path||"":g,caseSensitive:p.caseSensitive===!0,childrenIndex:v,route:p};if(x.relativePath.startsWith("/")){if(!x.relativePath.startsWith(o)&&z)return;f2(x.relativePath.startsWith(o),`Absolute route path "${x.relativePath}" nested under path "${o}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),x.relativePath=x.relativePath.slice(o.length)}let b=o3([o,x.relativePath]),y=r.concat(x);p.children&&p.children.length>0&&(f2(p.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${b}".`),Ls(p.children,a,y,b,z)),!(p.path==null&&!p.index)&&a.push({path:b,score:cf(b,p.index),routesMeta:y})};return t.forEach((p,v)=>{if(p.path===""||!p.path?.includes("?"))f(p,v);else for(let z of Bs(p.path))f(p,v,!0,z)}),a}function Bs(t){let a=t.split("/");if(a.length===0)return[];let[r,...o]=a,u=r.endsWith("?"),f=r.replace(/\?$/,"");if(o.length===0)return u?[f,""]:[f];let p=Bs(o.join("/")),v=[];return v.push(...p.map(z=>z===""?f:[f,z].join("/"))),u&&v.push(...p),v.map(z=>t.startsWith("/")&&z===""?"/":z)}function Kd(t){t.sort((a,r)=>a.score!==r.score?r.score-a.score:af(a.routesMeta.map(o=>o.childrenIndex),r.routesMeta.map(o=>o.childrenIndex)))}var Qd=/^:[\w-]+$/,Xd=3,Jd=2,Wd=1,tf=10,ef=-2,ii=t=>t==="*";function cf(t,a){let r=t.split("/"),o=r.length;return r.some(ii)&&(o+=ef),a&&(o+=Jd),r.filter(u=>!ii(u)).reduce((u,f)=>u+(Qd.test(f)?Xd:f===""?Wd:tf),o)}function af(t,a){return t.length===a.length&&t.slice(0,-1).every((o,u)=>o===a[u])?t[t.length-1]-a[a.length-1]:0}function nf(t,a,r=!1){let{routesMeta:o}=t,u={},f="/",p=[];for(let v=0;v{if(x==="*"){let L=v[y]||"";p=f.slice(0,f.length-L.length).replace(/(.)\/+$/,"$1")}const S=v[y];return b&&!S?g[x]=void 0:g[x]=(S||"").replace(/%2F/g,"/"),g},{}),pathname:f,pathnameBase:p,pattern:t}}function lf(t,a=!1,r=!0){j4(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let o=[],u="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(p,v,z)=>(o.push({paramName:v,isOptional:z!=null}),z?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(o.push({paramName:"*"}),u+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?u+="\\/*$":t!==""&&t!=="/"&&(u+="(?:(?=\\/|$))"),[new RegExp(u,a?void 0:"i"),o]}function rf(t){try{return t.split("/").map(a=>decodeURIComponent(a).replace(/\//g,"%2F")).join("/")}catch(a){return j4(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${a}).`),t}}function u3(t,a){if(a==="/")return t;if(!t.toLowerCase().startsWith(a.toLowerCase()))return null;let r=a.endsWith("/")?a.length-1:a.length,o=t.charAt(r);return o&&o!=="/"?null:t.slice(r)||"/"}var sf=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,of=t=>sf.test(t);function uf(t,a="/"){let{pathname:r,search:o="",hash:u=""}=typeof t=="string"?m0(t):t,f;if(r)if(of(r))f=r;else{if(r.includes("//")){let p=r;r=r.replace(/\/\/+/g,"/"),j4(!1,`Pathnames cannot have embedded double slashes - normalizing ${p} -> ${r}`)}r.startsWith("/")?f=si(r.substring(1),"/"):f=si(r,a)}else f=a;return{pathname:f,search:ff(o),hash:mf(u)}}function si(t,a){let r=a.replace(/\/+$/,"").split("/");return t.split("/").forEach(u=>{u===".."?r.length>1&&r.pop():u!=="."&&r.push(u)}),r.length>1?r.join("/"):"/"}function ge(t,a,r,o){return`Cannot include a '${t}' character in a manually specified \`to.${a}\` field [${JSON.stringify(o)}]. Please separate it out to the \`to.${r}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function hf(t){return t.filter((a,r)=>r===0||a.route.path&&a.route.path.length>0)}function js(t){let a=hf(t);return a.map((r,o)=>o===a.length-1?r.pathname:r.pathnameBase)}function Ns(t,a,r,o=!1){let u;typeof t=="string"?u=m0(t):(u={...t},f2(!u.pathname||!u.pathname.includes("?"),ge("?","pathname","search",u)),f2(!u.pathname||!u.pathname.includes("#"),ge("#","pathname","hash",u)),f2(!u.search||!u.search.includes("#"),ge("#","search","hash",u)));let f=t===""||u.pathname==="",p=f?"/":u.pathname,v;if(p==null)v=r;else{let b=a.length-1;if(!o&&p.startsWith("..")){let y=p.split("/");for(;y[0]==="..";)y.shift(),b-=1;u.pathname=y.join("/")}v=b>=0?a[b]:"/"}let z=uf(u,v),g=p&&p!=="/"&&p.endsWith("/"),x=(f||p===".")&&r.endsWith("/");return!z.pathname.endsWith("/")&&(g||x)&&(z.pathname+="/"),z}var o3=t=>t.join("/").replace(/\/\/+/g,"/"),df=t=>t.replace(/\/+$/,"").replace(/^\/*/,"/"),ff=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,mf=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t;function vf(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Fs=["POST","PUT","PATCH","DELETE"];new Set(Fs);var pf=["GET",...Fs];new Set(pf);var v0=m.createContext(null);v0.displayName="DataRouter";var U7=m.createContext(null);U7.displayName="DataRouterState";m.createContext(!1);var ks=m.createContext({isTransitioning:!1});ks.displayName="ViewTransition";var gf=m.createContext(new Map);gf.displayName="Fetchers";var xf=m.createContext(null);xf.displayName="Await";var D4=m.createContext(null);D4.displayName="Navigation";var j8=m.createContext(null);j8.displayName="Location";var h3=m.createContext({outlet:null,matches:[],isDataRoute:!1});h3.displayName="Route";var gc=m.createContext(null);gc.displayName="RouteError";function zf(t,{relative:a}={}){f2(N8(),"useHref() may be used only in the context of a component.");let{basename:r,navigator:o}=m.useContext(D4),{hash:u,pathname:f,search:p}=F8(t,{relative:a}),v=f;return r!=="/"&&(v=f==="/"?r:o3([r,f])),o.createHref({pathname:v,search:p,hash:u})}function N8(){return m.useContext(j8)!=null}function d6(){return f2(N8(),"useLocation() may be used only in the context of a component."),m.useContext(j8).location}var Rs="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Es(t){m.useContext(D4).static||m.useLayoutEffect(t)}function bf(){let{isDataRoute:t}=m.useContext(h3);return t?Ff():Mf()}function Mf(){f2(N8(),"useNavigate() may be used only in the context of a component.");let t=m.useContext(v0),{basename:a,navigator:r}=m.useContext(D4),{matches:o}=m.useContext(h3),{pathname:u}=d6(),f=JSON.stringify(js(o)),p=m.useRef(!1);return Es(()=>{p.current=!0}),m.useCallback((z,g={})=>{if(j4(p.current,Rs),!p.current)return;if(typeof z=="number"){r.go(z);return}let x=Ns(z,JSON.parse(f),u,g.relative==="path");t==null&&a!=="/"&&(x.pathname=x.pathname==="/"?a:o3([a,x.pathname])),(g.replace?r.replace:r.push)(x,g.state,g)},[a,r,f,u,t])}m.createContext(null);function F8(t,{relative:a}={}){let{matches:r}=m.useContext(h3),{pathname:o}=d6(),u=JSON.stringify(js(r));return m.useMemo(()=>Ns(t,JSON.parse(u),o,a==="path"),[t,u,o,a])}function yf(t,a){return Ts(t,a)}function Ts(t,a,r,o,u){f2(N8(),"useRoutes() may be used only in the context of a component.");let{navigator:f}=m.useContext(D4),{matches:p}=m.useContext(h3),v=p[p.length-1],z=v?v.params:{},g=v?v.pathname:"/",x=v?v.pathnameBase:"/",b=v&&v.route;{let j=b&&b.path||"";qs(g,!b||j.endsWith("*")||j.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${g}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. - -Please change the parent to .`)}let y=d6(),S;if(a){let j=typeof a=="string"?m0(a):a;f2(x==="/"||j.pathname?.startsWith(x),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${x}" but pathname "${j.pathname}" was given in the \`location\` prop.`),S=j}else S=y;let L=S.pathname||"/",w=L;if(x!=="/"){let j=x.replace(/^\//,"").split("/");w="/"+L.replace(/^\//,"").split("/").slice(j.length).join("/")}let C=As(t,{pathname:w});j4(b||C!=null,`No routes matched location "${S.pathname}${S.search}${S.hash}" `),j4(C==null||C[C.length-1].route.element!==void 0||C[C.length-1].route.Component!==void 0||C[C.length-1].route.lazy!==void 0,`Matched leaf route at location "${S.pathname}${S.search}${S.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let H=Vf(C&&C.map(j=>Object.assign({},j,{params:Object.assign({},z,j.params),pathname:o3([x,f.encodeLocation?f.encodeLocation(j.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:j.pathname]),pathnameBase:j.pathnameBase==="/"?x:o3([x,f.encodeLocation?f.encodeLocation(j.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:j.pathnameBase])})),p,r,o,u);return a&&H?m.createElement(j8.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...S},navigationType:"POP"}},H):H}function wf(){let t=Nf(),a=vf(t)?`${t.status} ${t.statusText}`:t instanceof Error?t.message:JSON.stringify(t),r=t instanceof Error?t.stack:null,o="rgba(200,200,200, 0.5)",u={padding:"0.5rem",backgroundColor:o},f={padding:"2px 4px",backgroundColor:o},p=null;return console.error("Error handled by React Router default ErrorBoundary:",t),p=m.createElement(m.Fragment,null,m.createElement("p",null,"💿 Hey developer 👋"),m.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",m.createElement("code",{style:f},"ErrorBoundary")," or"," ",m.createElement("code",{style:f},"errorElement")," prop on your route.")),m.createElement(m.Fragment,null,m.createElement("h2",null,"Unexpected Application Error!"),m.createElement("h3",{style:{fontStyle:"italic"}},a),r?m.createElement("pre",{style:u},r):null,p)}var Cf=m.createElement(wf,null),Hf=class extends m.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,a){return a.location!==t.location||a.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:a.error,location:a.location,revalidation:t.revalidation||a.revalidation}}componentDidCatch(t,a){this.props.onError?this.props.onError(t,a):console.error("React Router caught the following error during render",t)}render(){return this.state.error!==void 0?m.createElement(h3.Provider,{value:this.props.routeContext},m.createElement(gc.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function Sf({routeContext:t,match:a,children:r}){let o=m.useContext(v0);return o&&o.static&&o.staticContext&&(a.route.errorElement||a.route.ErrorBoundary)&&(o.staticContext._deepestRenderedBoundaryId=a.route.id),m.createElement(h3.Provider,{value:t},r)}function Vf(t,a=[],r=null,o=null,u=null){if(t==null){if(!r)return null;if(r.errors)t=r.matches;else if(a.length===0&&!r.initialized&&r.matches.length>0)t=r.matches;else return null}let f=t,p=r?.errors;if(p!=null){let x=f.findIndex(b=>b.route.id&&p?.[b.route.id]!==void 0);f2(x>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(p).join(",")}`),f=f.slice(0,Math.min(f.length,x+1))}let v=!1,z=-1;if(r)for(let x=0;x=0?f=f.slice(0,z+1):f=[f[0]];break}}}let g=r&&o?(x,b)=>{o(x,{location:r.location,params:r.matches?.[0]?.params??{},errorInfo:b})}:void 0;return f.reduceRight((x,b,y)=>{let S,L=!1,w=null,C=null;r&&(S=p&&b.route.id?p[b.route.id]:void 0,w=b.route.errorElement||Cf,v&&(z<0&&y===0?(qs("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),L=!0,C=null):z===y&&(L=!0,C=b.route.hydrateFallbackElement||null)));let H=a.concat(f.slice(0,y+1)),j=()=>{let V;return S?V=w:L?V=C:b.route.Component?V=m.createElement(b.route.Component,null):b.route.element?V=b.route.element:V=x,m.createElement(Sf,{match:b,routeContext:{outlet:x,matches:H,isDataRoute:r!=null},children:V})};return r&&(b.route.ErrorBoundary||b.route.errorElement||y===0)?m.createElement(Hf,{location:r.location,revalidation:r.revalidation,component:w,error:S,children:j(),routeContext:{outlet:null,matches:H,isDataRoute:!0},onError:g}):j()},null)}function xc(t){return`${t} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Af(t){let a=m.useContext(v0);return f2(a,xc(t)),a}function Lf(t){let a=m.useContext(U7);return f2(a,xc(t)),a}function Bf(t){let a=m.useContext(h3);return f2(a,xc(t)),a}function zc(t){let a=Bf(t),r=a.matches[a.matches.length-1];return f2(r.route.id,`${t} can only be used on routes that contain a unique "id"`),r.route.id}function jf(){return zc("useRouteId")}function Nf(){let t=m.useContext(gc),a=Lf("useRouteError"),r=zc("useRouteError");return t!==void 0?t:a.errors?.[r]}function Ff(){let{router:t}=Af("useNavigate"),a=zc("useNavigate"),r=m.useRef(!1);return Es(()=>{r.current=!0}),m.useCallback(async(u,f={})=>{j4(r.current,Rs),r.current&&(typeof u=="number"?t.navigate(u):await t.navigate(u,{fromRouteId:a,...f}))},[t,a])}var oi={};function qs(t,a,r){!a&&!oi[t]&&(oi[t]=!0,j4(!1,r))}m.memo(kf);function kf({routes:t,future:a,state:r,unstable_onError:o}){return Ts(t,void 0,r,o,a)}function n0(t){f2(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function Rf({basename:t="/",children:a=null,location:r,navigationType:o="POP",navigator:u,static:f=!1}){f2(!N8(),"You cannot render a inside another . You should never have more than one in your app.");let p=t.replace(/^\/*/,"/"),v=m.useMemo(()=>({basename:p,navigator:u,static:f,future:{}}),[p,u,f]);typeof r=="string"&&(r=m0(r));let{pathname:z="/",search:g="",hash:x="",state:b=null,key:y="default"}=r,S=m.useMemo(()=>{let L=u3(z,p);return L==null?null:{location:{pathname:L,search:g,hash:x,state:b,key:y},navigationType:o}},[p,z,g,x,b,y,o]);return j4(S!=null,` is not able to match the URL "${z}${g}${x}" because it does not start with the basename, so the won't render anything.`),S==null?null:m.createElement(D4.Provider,{value:v},m.createElement(j8.Provider,{children:a,value:S}))}function Ef({children:t,location:a}){return yf(Qe(t),a)}function Qe(t,a=[]){let r=[];return m.Children.forEach(t,(o,u)=>{if(!m.isValidElement(o))return;let f=[...a,u];if(o.type===m.Fragment){r.push.apply(r,Qe(o.props.children,f));return}f2(o.type===n0,`[${typeof o.type=="string"?o.type:o.type.name}] is not a component. All component children of must be a or `),f2(!o.props.index||!o.props.children,"An index route cannot have child routes.");let p={id:o.props.id||f.join("-"),caseSensitive:o.props.caseSensitive,element:o.props.element,Component:o.props.Component,index:o.props.index,path:o.props.path,middleware:o.props.middleware,loader:o.props.loader,action:o.props.action,hydrateFallbackElement:o.props.hydrateFallbackElement,HydrateFallback:o.props.HydrateFallback,errorElement:o.props.errorElement,ErrorBoundary:o.props.ErrorBoundary,hasErrorBoundary:o.props.hasErrorBoundary===!0||o.props.ErrorBoundary!=null||o.props.errorElement!=null,shouldRevalidate:o.props.shouldRevalidate,handle:o.props.handle,lazy:o.props.lazy};o.props.children&&(p.children=Qe(o.props.children,f)),r.push(p)}),r}var d7="get",f7="application/x-www-form-urlencoded";function Z7(t){return t!=null&&typeof t.tagName=="string"}function Tf(t){return Z7(t)&&t.tagName.toLowerCase()==="button"}function qf(t){return Z7(t)&&t.tagName.toLowerCase()==="form"}function Df(t){return Z7(t)&&t.tagName.toLowerCase()==="input"}function _f(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}function Of(t,a){return t.button===0&&(!a||a==="_self")&&!_f(t)}var J5=null;function Uf(){if(J5===null)try{new FormData(document.createElement("form"),0),J5=!1}catch{J5=!0}return J5}var Zf=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function xe(t){return t!=null&&!Zf.has(t)?(j4(!1,`"${t}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${f7}"`),null):t}function $f(t,a){let r,o,u,f,p;if(qf(t)){let v=t.getAttribute("action");o=v?u3(v,a):null,r=t.getAttribute("method")||d7,u=xe(t.getAttribute("enctype"))||f7,f=new FormData(t)}else if(Tf(t)||Df(t)&&(t.type==="submit"||t.type==="image")){let v=t.form;if(v==null)throw new Error('Cannot submit a + ); + })} + +
+ stopDrivePad('stop')} + /> +
+ + ); +} diff --git a/webui/src/components/MobileControls/MobileControlsContent.jsx b/webui/src/components/MobileControls/MobileControlsContent.jsx deleted file mode 100644 index c5172ec4..00000000 --- a/webui/src/components/MobileControls/MobileControlsContent.jsx +++ /dev/null @@ -1,499 +0,0 @@ -// Mobile Controls Content -// Purpose: Defines the Mobile Controls Content module and the local helpers/components used in this file. -// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit. -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useControlSystem } from '../../controls/index.js'; -import { normalizeKeymapEntries } from '../../controls/keymapUtils.js'; -import { - computeKeyboardDriveVector, - getKeyboardDriveSpeedOptions, - resolveKeyboardSpeeds, -} from '../../controls/inputs/driveIntent.js'; -import DriveDockAction, { useDriveDockState } from '../DriveDockAction/index.jsx'; -import NightVisionControl from '../NightVisionControl/index.jsx'; -import HornControl from '../HornControl/index.jsx'; -import FloatingJoystick from './FloatingJoystick.jsx'; -import MobileAuxButton from './MobileAuxButton.jsx'; -import { - SOURCE, - DRIVE_PAD_REPEAT_MS, - DRIVE_PAD_SPEED_MODES, - AUX_ZERO, - AUX_ALL_FORWARD, - AUX_ALL_BACKWARD, -} from './constants.js'; -import { useManualDockAssist } from '../../features/manualDockAssist/useManualDockAssist.js'; -import { useSettingsNamespace } from '../../settings/index.js'; -import { INPUT_SETTINGS_DEFAULTS } from '../../settings/namespaces.js'; - -function firstTokenForAction(keymap, actionId) { - const bindingSet = keymap?.[actionId]; - if (!bindingSet || bindingSet.size === 0) return null; - return bindingSet.values().next().value ?? null; -} - -function getSpeedModeConfig(speedMode) { - return DRIVE_PAD_SPEED_MODES.find((mode) => mode.id === speedMode) || DRIVE_PAD_SPEED_MODES[1]; -} - -function clampCameraAngle(value, min, max) { - if (!Number.isFinite(value)) return min; - return Math.max(min, Math.min(max, value)); -} - -function formatCameraAngle(value) { - if (typeof value !== 'number' || Number.isNaN(value)) return '—'; - return `${value > 0 ? '+' : ''}${value.toFixed(1)}°`; -} - -function MobileCameraTiltSlider({ - value, - min, - max, - step = 0.5, - disabled = false, - onChange, -}) { - const trackRef = useRef(null); - const pointerIdRef = useRef(null); - - const valuePercent = useMemo(() => { - if (max === min) return 50; - return ((clampCameraAngle(value, min, max) - min) / (max - min)) * 100; - }, [max, min, value]); - const disabledClass = disabled ? 'opacity-50' : ''; - - const valueFromPointer = useCallback( - (event) => { - const track = trackRef.current; - if (!track) return value; - const rect = track.getBoundingClientRect(); - const usableHeight = Math.max(1, rect.height); - const rawPercent = 1 - (event.clientY - rect.top) / usableHeight; - const unclamped = min + clampCameraAngle(rawPercent, 0, 1) * (max - min); - const stepped = Math.round(unclamped / step) * step; - return clampCameraAngle(stepped, min, max); - }, - [max, min, step, value], - ); - - const sendPointerValue = useCallback( - (event) => { - const next = valueFromPointer(event); - onChange?.(next); - }, - [onChange, valueFromPointer], - ); - - const handlePointerDown = useCallback( - (event) => { - if (disabled) return; - if (pointerIdRef.current !== null) return; - - /* - Native vertical range inputs are unreliable as a second simultaneous - touch on mobile Safari while the drive pad owns another active pointer. - This custom track captures only the camera finger, so the drive thumb can - continue moving without stealing or cancelling camera tilt updates. - */ - event.preventDefault(); - pointerIdRef.current = event.pointerId; - trackRef.current?.setPointerCapture?.(event.pointerId); - sendPointerValue(event); - }, - [disabled, sendPointerValue], - ); - - const handlePointerMove = useCallback( - (event) => { - if (pointerIdRef.current !== event.pointerId) return; - event.preventDefault(); - sendPointerValue(event); - }, - [sendPointerValue], - ); - - const handlePointerEnd = useCallback((event) => { - if (pointerIdRef.current !== event.pointerId) return; - event.preventDefault(); - pointerIdRef.current = null; - trackRef.current?.releasePointerCapture?.(event.pointerId); - }, []); - - return ( -
- - Camera tilt - -
{ - if (pointerIdRef.current === event.pointerId) pointerIdRef.current = null; - }} - onContextMenu={(event) => event.preventDefault()} - /* - touchAction stays inline as a second line of defense because this is the - element that must keep browser panning/zooming out of the multi-touch - camera gesture. - */ - style={{ touchAction: 'none' }} - className={`mobile-touch-control mobile-drag-control relative h-full w-6 rounded-full border border-emerald-100/80 bg-emerald-950 shadow-inner focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-emerald-200 ${disabledClass}`.trim()} - > -
-
-
-
- ); -} - -function MobileJoystickPanel({ layout }) { - const { - state: { roverId, keymap: rawKeymap }, - actions: { setDriveVector, registerInputState }, - } = useControlSystem(); - const { value: inputSettings } = useSettingsNamespace('inputs', INPUT_SETTINGS_DEFAULTS); - const driveDockState = useDriveDockState(roverId); - const dockedNotDriving = driveDockState.docked && !driveDockState.driving; - const expandAction = dockedNotDriving || driveDockState.dockingInProgress; - const disabled = !roverId; - const [speedMode, setSpeedMode] = useState('normal'); - const [activeInputLabel, setActiveInputLabel] = useState('stop'); - const speedModeRef = useRef('normal'); - const activeCellRef = useRef(null); - const repeatTimerRef = useRef(null); - const keymap = useMemo(() => normalizeKeymapEntries(rawKeymap), [rawKeymap]); - const keyboardSpeeds = useMemo(() => resolveKeyboardSpeeds(inputSettings), [inputSettings]); - - const clearRepeatTimer = useCallback(() => { - if (!repeatTimerRef.current) return; - clearInterval(repeatTimerRef.current); - repeatTimerRef.current = null; - }, []); - - const buildVirtualKeyTokens = useCallback( - (cell, modeId = speedModeRef.current) => { - const tokens = new Set(); - const speedModeConfig = getSpeedModeConfig(modeId); - const actionIds = [ - ...(Array.isArray(cell?.actions) ? cell.actions : []), - speedModeConfig.modifierAction, - ].filter(Boolean); - - actionIds.forEach((actionId) => { - const token = firstTokenForAction(keymap, actionId); - if (token) tokens.add(token); - }); - - return tokens; - }, - [keymap], - ); - - const sendDriveCell = useCallback( - (cell, lastEvent = 'move', modeId = speedModeRef.current) => { - if (disabled) return; - const tokens = buildVirtualKeyTokens(cell, modeId); - const vector = computeKeyboardDriveVector(tokens, keymap); - const speedOptions = getKeyboardDriveSpeedOptions(tokens, keymap, keyboardSpeeds); - - // Mobile deliberately routes through the keyboard vector/speed helpers. The - // thumb pad only chooses which virtual keys are down, so changes to keyboard - // drive behavior automatically stay matched here. - setDriveVector(vector, { source: SOURCE, speedOptions }); - registerInputState(SOURCE, { - keys: Array.from(tokens), - vector, - activeCell: cell?.id ?? 'stop', - speedMode: modeId, - lastEvent, - }); - }, - [ - buildVirtualKeyTokens, - disabled, - keyboardSpeeds, - keymap, - registerInputState, - setDriveVector, - ], - ); - - const stopDrivePad = useCallback( - (lastEvent = 'stop') => { - clearRepeatTimer(); - activeCellRef.current = null; - setActiveInputLabel('stop'); - sendDriveCell({ id: 'stop', actions: [] }, lastEvent, 'normal'); - }, - [clearRepeatTimer, sendDriveCell], - ); - - const startRepeatTimer = useCallback(() => { - if (repeatTimerRef.current) return; - repeatTimerRef.current = setInterval(() => { - if (!activeCellRef.current) return; - sendDriveCell(activeCellRef.current, 'repeat'); - }, DRIVE_PAD_REPEAT_MS); - }, [sendDriveCell]); - - const handleCellChange = useCallback( - (cell) => { - if (disabled) return; - activeCellRef.current = cell; - setActiveInputLabel(cell?.label || 'stop'); - sendDriveCell(cell, 'move'); - startRepeatTimer(); - }, - [disabled, sendDriveCell, startRepeatTimer], - ); - - const handleSpeedModeChange = useCallback( - (nextMode) => { - setSpeedMode(nextMode); - speedModeRef.current = nextMode; - if (activeCellRef.current) { - sendDriveCell(activeCellRef.current, 'speed', nextMode); - } - }, - [sendDriveCell], - ); - - useEffect(() => { - return () => clearRepeatTimer(); - }, [clearRepeatTimer]); - - useEffect(() => { - if (!disabled) return; - stopDrivePad('disabled'); - }, [disabled, stopDrivePad]); - - // The mobile control column itself also blocks selection because Safari can - // otherwise start selecting text from a child label before the child's pointer - // handler gets enough movement to claim the gesture. - const fillClass = dockedNotDriving ? 'max-h-screen self-start' : ''; - const containerClass = `mobile-touch-control flex h-full flex-col gap-0.5 text-slate-100 ${fillClass}`; - - return ( -
- - {!expandAction ? ( - // Keep the drive launcher card fully opaque so camera video or page - // backgrounds never show through the target the driver is trying to hold. -
-
- {DRIVE_PAD_SPEED_MODES.map((mode) => { - const active = speedMode === mode.id; - const speedValue = - mode.id === 'precision' - ? keyboardSpeeds.precisionSpeed - : mode.id === 'turbo' - ? keyboardSpeeds.turboSpeed - : keyboardSpeeds.baseSpeed; - return ( - - ); - })} -
-
- stopDrivePad('stop')} - /> -
-
- ) : null} -
- ); -} - -function MobileActionsColumnContent() { - const { - state: { roverId, camera, horn }, - pipeline, - actions: { setServoAngle, setNightVision, setAuxMotors, startHorn, stopHorn }, - } = useControlSystem(); - const dockAssist = useManualDockAssist(); - const disabled = !roverId; - const activeRef = useRef(null); - const cameraConfig = camera?.config; - const cameraEnabled = Boolean(roverId && camera?.enabled && cameraConfig); - const nightVisionAvailable = Boolean(roverId && pipeline?.nightVision); - const nightVisionState = pipeline?.nightVisionState; - const hornAvailable = Boolean(roverId && pipeline?.horn); - const hornBlocked = horn?.overheated; - const cameraMin = typeof cameraConfig?.minAngle === 'number' ? cameraConfig.minAngle : -45; - const cameraMax = typeof cameraConfig?.maxAngle === 'number' ? cameraConfig.maxAngle : 45; - const cameraValue = - typeof camera?.angle === 'number' - ? camera.angle - : typeof cameraConfig?.homeAngle === 'number' - ? cameraConfig.homeAngle - : (cameraMin + cameraMax) / 2; - const cameraDisabled = Boolean(disabled || dockAssist.cameraLocked); - - const handleNightVisionToggle = useCallback( - (nextOn) => { - if (!nightVisionAvailable) return; - setNightVision(nextOn); - }, - [nightVisionAvailable, setNightVision], - ); - - const handleAuxPress = useCallback( - (id, values) => { - if (disabled) return; - activeRef.current = id; - setAuxMotors(values); - }, - [disabled, setAuxMotors], - ); - - const handleAuxRelease = useCallback( - (id) => { - if (disabled) return; - if (activeRef.current === id) { - activeRef.current = null; - setAuxMotors(AUX_ZERO); - } - }, - [disabled, setAuxMotors], - ); - - return ( -
-
- - -
-
- {cameraEnabled ? ( - // Match the desktop camera tilt card's emerald styling so the vertical - // mobile control reads as the same feature in a phone-sized layout. -
- -
- ) : null} - {nightVisionAvailable ? ( - - ) : null} -
-
- {hornAvailable ? ( - - ) : null} -
-
- ); -} - -export function MobileActionsColumn({ layout, className = '' }) { - return ( -
- -
- ); -} - -export function MobileDriveColumn({ layout, className = '' }) { - return ( -
- -
- ); -} - -export default function MobilePortraitControls({ swapColumns = false }) { - const columnHeight = 'h-[min(60svh,24rem)]'; - const firstColumn = swapColumns - ? - : ; - const secondColumn = swapColumns - ? - : ; - return ( - // Portrait controls need layout grouping but no painted panel behind them; - // each child control owns its own visible surface. -
-
- {firstColumn} - {secondColumn} -
-
- ); -} diff --git a/webui/src/components/MobileControls/MovementColumn.jsx b/webui/src/components/MobileControls/MovementColumn.jsx new file mode 100644 index 00000000..a5fe0fd3 --- /dev/null +++ b/webui/src/components/MobileControls/MovementColumn.jsx @@ -0,0 +1,45 @@ +// Movement Column +// Purpose: Assembles the mobile movement column, which is the right column by default. +// Scope: Integrates drive/dock actions with the mobile control pad without hiding that dependency inside the pad. +import { useControlSystem } from '../../controls/index.js'; +import DriveDockAction, { useDriveDockState } from '../DriveDockAction/index.jsx'; +import ControlPadPanel from './ControlPadPanel.jsx'; + +function MovementColumnContent({ layout }) { + const { + state: { roverId }, + } = useControlSystem(); + const driveDockState = useDriveDockState(roverId); + const dockedNotDriving = driveDockState.docked && !driveDockState.driving; + const expandAction = dockedNotDriving || driveDockState.dockingInProgress; + const disabled = !roverId; + + /* + DriveDockAction owns whether the rover is ready to accept movement, while + ControlPadPanel owns only movement intent. Keeping the integration here makes + the column layout explicit and prevents the pad component from knowing about + docking state. + */ + const fillClass = dockedNotDriving ? 'max-h-screen self-start' : ''; + const containerClass = `mobile-touch-control flex h-full flex-col gap-0.5 text-slate-100 ${fillClass}`; + + return ( +
+ + {!expandAction ? : null} +
+ ); +} + +export default function MovementColumn({ layout, className = '' }) { + return ( +
+ +
+ ); +} diff --git a/webui/src/components/MobileControls/VacuumControls.jsx b/webui/src/components/MobileControls/VacuumControls.jsx new file mode 100644 index 00000000..4797f139 --- /dev/null +++ b/webui/src/components/MobileControls/VacuumControls.jsx @@ -0,0 +1,34 @@ +// Vacuum Controls +// Purpose: Renders the mobile-only vacuum forward/backward auxiliary motor controls. +// Scope: Owns only the two vacuum buttons; the parent column owns rover state and aux motor commands. +import MobileAuxButton from './MobileAuxButton.jsx'; +import { AUX_ALL_BACKWARD, AUX_ALL_FORWARD } from './constants.js'; + +export default function VacuumControls({ + disabled, + onPress, + onRelease, +}) { + return ( +
+ + +
+ ); +} diff --git a/webui/src/components/MobileControls/VerticalCameraTilt.jsx b/webui/src/components/MobileControls/VerticalCameraTilt.jsx new file mode 100644 index 00000000..5361555b --- /dev/null +++ b/webui/src/components/MobileControls/VerticalCameraTilt.jsx @@ -0,0 +1,132 @@ +// Vertical Camera Tilt +// Purpose: Provides the mobile-only camera tilt slider that supports simultaneous two-finger mobile driving. +// Scope: Owns pointer tracking and visual slider state for the compact vertical mobile camera control. +import { useCallback, useMemo, useRef } from 'react'; + +function clampCameraAngle(value, min, max) { + if (!Number.isFinite(value)) return min; + return Math.max(min, Math.min(max, value)); +} + +function formatCameraAngle(value) { + if (typeof value !== 'number' || Number.isNaN(value)) return '—'; + return `${value > 0 ? '+' : ''}${value.toFixed(1)}°`; +} + +export default function VerticalCameraTilt({ + value, + min, + max, + step = 0.5, + disabled = false, + onChange, +}) { + const trackRef = useRef(null); + const pointerIdRef = useRef(null); + + const valuePercent = useMemo(() => { + if (max === min) return 50; + return ((clampCameraAngle(value, min, max) - min) / (max - min)) * 100; + }, [max, min, value]); + const disabledClass = disabled ? 'opacity-50' : ''; + + const valueFromPointer = useCallback( + (event) => { + const track = trackRef.current; + if (!track) return value; + const rect = track.getBoundingClientRect(); + const usableHeight = Math.max(1, rect.height); + const rawPercent = 1 - (event.clientY - rect.top) / usableHeight; + const unclamped = min + clampCameraAngle(rawPercent, 0, 1) * (max - min); + const stepped = Math.round(unclamped / step) * step; + return clampCameraAngle(stepped, min, max); + }, + [max, min, step, value], + ); + + const sendPointerValue = useCallback( + (event) => { + const next = valueFromPointer(event); + onChange?.(next); + }, + [onChange, valueFromPointer], + ); + + const handlePointerDown = useCallback( + (event) => { + if (disabled) return; + if (pointerIdRef.current !== null) return; + + /* + Native vertical range inputs are unreliable as a second simultaneous + touch on mobile Safari while the drive pad owns another active pointer. + This custom track captures only the camera finger, so the drive thumb can + continue moving without stealing or cancelling camera tilt updates. + */ + event.preventDefault(); + pointerIdRef.current = event.pointerId; + trackRef.current?.setPointerCapture?.(event.pointerId); + sendPointerValue(event); + }, + [disabled, sendPointerValue], + ); + + const handlePointerMove = useCallback( + (event) => { + if (pointerIdRef.current !== event.pointerId) return; + event.preventDefault(); + sendPointerValue(event); + }, + [sendPointerValue], + ); + + const handlePointerEnd = useCallback((event) => { + if (pointerIdRef.current !== event.pointerId) return; + event.preventDefault(); + pointerIdRef.current = null; + trackRef.current?.releasePointerCapture?.(event.pointerId); + }, []); + + return ( +
+ + Camera tilt + +
{ + if (pointerIdRef.current === event.pointerId) pointerIdRef.current = null; + }} + onContextMenu={(event) => event.preventDefault()} + /* + touchAction stays inline as a second line of defense because this is the + element that must keep browser panning/zooming out of the multi-touch + camera gesture. + */ + style={{ touchAction: 'none' }} + className={`mobile-touch-control mobile-drag-control relative h-full w-6 rounded-full border border-emerald-100/80 bg-emerald-950 shadow-inner focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-emerald-200 ${disabledClass}`.trim()} + > +
+
+
+
+ ); +} diff --git a/webui/src/components/MobileControls/index.jsx b/webui/src/components/MobileControls/index.jsx deleted file mode 100644 index 2e2210cb..00000000 --- a/webui/src/components/MobileControls/index.jsx +++ /dev/null @@ -1,7 +0,0 @@ -// Mobile Controls -// Purpose: Defines the Mobile Controls module and the local helpers/components used in this file. -// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit. -import MobilePortraitControls, { MobileActionsColumn, MobileDriveColumn } from './MobileControlsContent.jsx'; - -export { MobileActionsColumn, MobileDriveColumn }; -export default MobilePortraitControls;