From dcb743620fde552a03fed4062b13470209bca2d8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 4 May 2026 14:10:11 +0000 Subject: [PATCH 1/6] Add UI roadmap and release-centric P0 serve UX Document phased UI goals in docs/ui-roadmap.md. Overview gains a focused-release hero (?release=), row shortcuts to Diff/Runs/Promote with query params, and promoted baseline hints. Diff/Runs/Actions read URL search params; Diff syncs params on compute and shows a prominent policy verdict banner plus link to Promote. E2e script defaults to python3 with FLIGHTDECK_E2E_PYTHON override; extend smoke tests for deep links. Co-authored-by: Gottam Sai Bharath --- docs/ui-roadmap.md | 49 ++++++ .../server/static/assets/index-B7p9SpNf.js | 11 ++ .../server/static/assets/index-BPDMrxvX.js | 11 -- ...{index-Dr1ovfXv.css => index-D9BWBTvc.css} | 2 +- src/flightdeck/server/static/index.html | 4 +- web/e2e/smoke.spec.ts | 18 ++ web/scripts/e2e-server.mjs | 5 +- web/src/components/ReleaseLifecycleStrip.tsx | 3 +- web/src/index.css | 80 +++++++++ web/src/pages/ActionsPage.tsx | 11 ++ web/src/pages/DiffPage.tsx | 96 ++++++++++- web/src/pages/OverviewPage.tsx | 163 +++++++++++++++++- web/src/pages/RunsPage.tsx | 13 +- web/src/urlSearch.ts | 15 ++ 14 files changed, 448 insertions(+), 33 deletions(-) create mode 100644 docs/ui-roadmap.md create mode 100644 src/flightdeck/server/static/assets/index-B7p9SpNf.js delete mode 100644 src/flightdeck/server/static/assets/index-BPDMrxvX.js rename src/flightdeck/server/static/assets/{index-Dr1ovfXv.css => index-D9BWBTvc.css} (60%) create mode 100644 web/src/urlSearch.ts diff --git a/docs/ui-roadmap.md b/docs/ui-roadmap.md new file mode 100644 index 0000000..3ebb440 --- /dev/null +++ b/docs/ui-roadmap.md @@ -0,0 +1,49 @@ +# FlightDeck Serve UI roadmap + +This document turns the strict UI review into sequenced work. Scope is the checked-in React app under `web/` (served from `flightdeck serve`). Goal: move from **ledger viewer** to a **release-centric control plane** without changing core product boundaries (CLI-first, local ledger). + +## Principles + +1. **One spine**: a release under judgment → diff verdict → promotion action (evidence on demand). +2. **URL is state**: deep links prefill forms so operators can share “this comparison” and “this promotion.” +3. **Verdict before detail**: policy outcome and blockers must dominate; tables and JSON stay secondary. +4. **Boring over flashy**: prefer clear hierarchy and high-contrast failure states over decorative chrome. + +## Phase 0 — Done in repo (this slice) + +| Item | Outcome | +|------|---------| +| Release-centric hero | Overview highlights a focused release when `?release=` is set; row shortcuts jump to Diff / Runs / Promote with params. | +| Wire navigation to state | `Diff`, `Runs`, and `Promote` read `baseline`, `candidate`, `release_id`, `window`, `environment` from the URL search string. | +| Blocked / pass unavoidable | Diff page shows a full-width **verdict banner** (alert on FAIL) above the result card stack. | +| Bridge Diff → Promote | After a computed diff, a primary **Continue to promote** action links to Promote with release + environment + window prefilled (read-only builds omit). | + +## Phase 1 — Hierarchy and differentiation + +| Priority | Work | +|----------|------| +| P1 | Collapse or relocate **Ledger metrics** on Overview so the releases + promoted story leads. | +| P1 | **Reorder Diff result**: top fold = verdict + key deltas; pricing/catalog in collapsed sections or tabs. | +| P1 | **Promoted vs candidate** narrative per `agent + environment` (e.g. inline summary above tables). | +| P1 | Reduce reliance on **manual checksum scanning** — surface version + agent + env as the human keys. | + +## Phase 2 — Polish and operator UX + +| Priority | Work | +|----------|------| +| P2 | Typography scale for page vs card titles; consistent vertical rhythm. | +| P2 | Table ergonomics: row hover, optional filters, copy-to-clipboard for release IDs. | +| P2 | Tone down gradient accents for a more **infra / audit** aesthetic (keep accessible contrast). | +| P2 | Copy pass: each primary page answers *What changed?* *Is it safe?* *Can I ship?* in one short block. | + +## Non-goals (near term) + +- Embedded orchestration or graph execution. +- Chart-heavy analytics dashboards (prefer summary metrics tied to gates). +- Replacing the CLI registration / ingest workflow. + +## Verification + +After `web/` changes: from `web/`, `npm ci && npm run build`; commit `src/flightdeck/server/static/` updates; run `npm run test:e2e` when navigation or forms behavior changes. + +On Unix hosts where `python` is not on `PATH`, set `FLIGHTDECK_E2E_PYTHON` to a Python that has FlightDeck installed (for example the repo venv: `FLIGHTDECK_E2E_PYTHON=/path/to/.venv/bin/python npm run test:e2e`). The default is `python3`. diff --git a/src/flightdeck/server/static/assets/index-B7p9SpNf.js b/src/flightdeck/server/static/assets/index-B7p9SpNf.js new file mode 100644 index 0000000..b5b2958 --- /dev/null +++ b/src/flightdeck/server/static/assets/index-B7p9SpNf.js @@ -0,0 +1,11 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const m of document.querySelectorAll('link[rel="modulepreload"]'))f(m);new MutationObserver(m=>{for(const h of m)if(h.type==="childList")for(const b of h.addedNodes)b.tagName==="LINK"&&b.rel==="modulepreload"&&f(b)}).observe(document,{childList:!0,subtree:!0});function o(m){const h={};return m.integrity&&(h.integrity=m.integrity),m.referrerPolicy&&(h.referrerPolicy=m.referrerPolicy),m.crossOrigin==="use-credentials"?h.credentials="include":m.crossOrigin==="anonymous"?h.credentials="omit":h.credentials="same-origin",h}function f(m){if(m.ep)return;m.ep=!0;const h=o(m);fetch(m.href,h)}})();var Zc={exports:{}},$n={};var xm;function Bp(){if(xm)return $n;xm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(f,m,h){var b=null;if(h!==void 0&&(b=""+h),m.key!==void 0&&(b=""+m.key),"key"in m){h={};for(var j in m)j!=="key"&&(h[j]=m[j])}else h=m;return m=h.ref,{$$typeof:s,type:f,key:b,ref:m!==void 0?m:null,props:h}}return $n.Fragment=r,$n.jsx=o,$n.jsxs=o,$n}var Sm;function Yp(){return Sm||(Sm=1,Zc.exports=Bp()),Zc.exports}var u=Yp(),Kc={exports:{}},ce={};var jm;function Gp(){if(jm)return ce;jm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),f=Symbol.for("react.strict_mode"),m=Symbol.for("react.profiler"),h=Symbol.for("react.consumer"),b=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),O=Symbol.for("react.lazy"),N=Symbol.for("react.activity"),H=Symbol.iterator;function Z(g){return g===null||typeof g!="object"?null:(g=H&&g[H]||g["@@iterator"],typeof g=="function"?g:null)}var J={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},G=Object.assign,w={};function k(g,M,Y){this.props=g,this.context=M,this.refs=w,this.updater=Y||J}k.prototype.isReactComponent={},k.prototype.setState=function(g,M){if(typeof g!="object"&&typeof g!="function"&&g!=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,g,M,"setState")},k.prototype.forceUpdate=function(g){this.updater.enqueueForceUpdate(this,g,"forceUpdate")};function ee(){}ee.prototype=k.prototype;function Q(g,M,Y){this.props=g,this.context=M,this.refs=w,this.updater=Y||J}var q=Q.prototype=new ee;q.constructor=Q,G(q,k.prototype),q.isPureReactComponent=!0;var I=Array.isArray;function X(){}var F={H:null,A:null,T:null,S:null},ue=Object.prototype.hasOwnProperty;function K(g,M,Y){var $=Y.ref;return{$$typeof:s,type:g,key:M,ref:$!==void 0?$:null,props:Y}}function He(g,M){return K(g.type,M,g.props)}function re(g){return typeof g=="object"&&g!==null&&g.$$typeof===s}function Ae(g){var M={"=":"=0",":":"=2"};return"$"+g.replace(/[=:]/g,function(Y){return M[Y]})}var Se=/\/+/g;function he(g,M){return typeof g=="object"&&g!==null&&g.key!=null?Ae(""+g.key):M.toString(36)}function ve(g){switch(g.status){case"fulfilled":return g.value;case"rejected":throw g.reason;default:switch(typeof g.status=="string"?g.then(X,X):(g.status="pending",g.then(function(M){g.status==="pending"&&(g.status="fulfilled",g.value=M)},function(M){g.status==="pending"&&(g.status="rejected",g.reason=M)})),g.status){case"fulfilled":return g.value;case"rejected":throw g.reason}}throw g}function C(g,M,Y,$,ne){var se=typeof g;(se==="undefined"||se==="boolean")&&(g=null);var _e=!1;if(g===null)_e=!0;else switch(se){case"bigint":case"string":case"number":_e=!0;break;case"object":switch(g.$$typeof){case s:case r:_e=!0;break;case O:return _e=g._init,C(_e(g._payload),M,Y,$,ne)}}if(_e)return ne=ne(g),_e=$===""?"."+he(g,0):$,I(ne)?(Y="",_e!=null&&(Y=_e.replace(Se,"$&/")+"/"),C(ne,M,Y,"",function(L){return L})):ne!=null&&(re(ne)&&(ne=He(ne,Y+(ne.key==null||g&&g.key===ne.key?"":(""+ne.key).replace(Se,"$&/")+"/")+_e)),M.push(ne)),1;_e=0;var Ke=$===""?".":$+":";if(I(g))for(var qe=0;qe>>1,Ne=C[je];if(0>>1;jem(Y,le))$m(ne,Y)?(C[je]=ne,C[$]=le,je=$):(C[je]=Y,C[M]=le,je=M);else if($m(ne,le))C[je]=ne,C[$]=le,je=$;else break e}}return B}function m(C,B){var le=C.sortIndex-B.sortIndex;return le!==0?le:C.id-B.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var h=performance;s.unstable_now=function(){return h.now()}}else{var b=Date,j=b.now();s.unstable_now=function(){return b.now()-j}}var x=[],y=[],O=1,N=null,H=3,Z=!1,J=!1,G=!1,w=!1,k=typeof setTimeout=="function"?setTimeout:null,ee=typeof clearTimeout=="function"?clearTimeout:null,Q=typeof setImmediate<"u"?setImmediate:null;function q(C){for(var B=o(y);B!==null;){if(B.callback===null)f(y);else if(B.startTime<=C)f(y),B.sortIndex=B.expirationTime,r(x,B);else break;B=o(y)}}function I(C){if(G=!1,q(C),!J)if(o(x)!==null)J=!0,X||(X=!0,Ae());else{var B=o(y);B!==null&&ve(I,B.startTime-C)}}var X=!1,F=-1,ue=5,K=-1;function He(){return w?!0:!(s.unstable_now()-KC&&He());){var je=N.callback;if(typeof je=="function"){N.callback=null,H=N.priorityLevel;var Ne=je(N.expirationTime<=C);if(C=s.unstable_now(),typeof Ne=="function"){N.callback=Ne,q(C),B=!0;break t}N===o(x)&&f(x),q(C)}else f(x);N=o(x)}if(N!==null)B=!0;else{var g=o(y);g!==null&&ve(I,g.startTime-C),B=!1}}break e}finally{N=null,H=le,Z=!1}B=void 0}}finally{B?Ae():X=!1}}}var Ae;if(typeof Q=="function")Ae=function(){Q(re)};else if(typeof MessageChannel<"u"){var Se=new MessageChannel,he=Se.port2;Se.port1.onmessage=re,Ae=function(){he.postMessage(null)}}else Ae=function(){k(re,0)};function ve(C,B){F=k(function(){C(s.unstable_now())},B)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(C){C.callback=null},s.unstable_forceFrameRate=function(C){0>C||125je?(C.sortIndex=le,r(y,C),o(x)===null&&C===o(y)&&(G?(ee(F),F=-1):G=!0,ve(I,le-je))):(C.sortIndex=Ne,r(x,C),J||Z||(J=!0,X||(X=!0,Ae()))),C},s.unstable_shouldYield=He,s.unstable_wrapCallback=function(C){var B=H;return function(){var le=H;H=B;try{return C.apply(this,arguments)}finally{H=le}}}})($c)),$c}var Tm;function Xp(){return Tm||(Tm=1,kc.exports=Qp()),kc.exports}var Fc={exports:{}},st={};var Rm;function Vp(){if(Rm)return st;Rm=1;var s=cr();function r(x){var y="https://react.dev/errors/"+x;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Fc.exports=Vp(),Fc.exports}var Om;function Kp(){if(Om)return Fn;Om=1;var s=Xp(),r=cr(),o=Zp();function f(e){var t="https://react.dev/errors/"+e;if(1Ne||(e.current=je[Ne],je[Ne]=null,Ne--)}function Y(e,t){Ne++,je[Ne]=e.current,e.current=t}var $=g(null),ne=g(null),se=g(null),_e=g(null);function Ke(e,t){switch(Y(se,t),Y(ne,e),Y($,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Zd(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}M($),Y($,e)}function qe(){M($),M(ne),M(se)}function L(e){e.memoizedState!==null&&Y(_e,e);var t=$.current,l=Zd(t,e.type);t!==l&&(Y(ne,e),Y($,l))}function de(e){ne.current===e&&(M($),M(ne)),_e.current===e&&(M(_e),Zn._currentValue=le)}var Ue,V;function ie(e){if(Ue===void 0)try{throw Error()}catch(l){var t=l.stack.trim().match(/\n( *(at )?)/);Ue=t&&t[1]||"",V=-1)":-1n||p[a]!==T[n]){var z=` +`+p[a].replace(" at new "," at ");return e.displayName&&z.includes("")&&(z=z.replace("",e.displayName)),z}while(1<=a&&0<=n);break}}}finally{me=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?ie(l):""}function Ot(e,t){switch(e.tag){case 26:case 27:case 5:return ie(e.type);case 16:return ie("Lazy");case 13:return e.child!==t&&t!==null?ie("Suspense Fallback"):ie("Suspense");case 19:return ie("SuspenseList");case 0:case 15:return ut(e.type,!1);case 11:return ut(e.type.render,!1);case 1:return ut(e.type,!0);case 31:return ie("Activity");default:return""}}function Ie(e){try{var t="",l=null;do t+=Ot(e,l),l=e,e=e.return;while(e);return t}catch(a){return` +Error generating stack: `+a.message+` +`+a.stack}}var tn=Object.prototype.hasOwnProperty,zu=s.unstable_scheduleCallback,Du=s.unstable_cancelCallback,yh=s.unstable_shouldYield,gh=s.unstable_requestPaint,yt=s.unstable_now,bh=s.unstable_getCurrentPriorityLevel,_r=s.unstable_ImmediatePriority,xr=s.unstable_UserBlockingPriority,ai=s.unstable_NormalPriority,_h=s.unstable_LowPriority,Sr=s.unstable_IdlePriority,xh=s.log,Sh=s.unstable_setDisableYieldValue,ln=null,gt=null;function pl(e){if(typeof xh=="function"&&Sh(e),gt&&typeof gt.setStrictMode=="function")try{gt.setStrictMode(ln,e)}catch{}}var bt=Math.clz32?Math.clz32:Eh,jh=Math.log,Nh=Math.LN2;function Eh(e){return e>>>=0,e===0?32:31-(jh(e)/Nh|0)|0}var ni=256,ii=262144,ui=4194304;function Vl(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function si(e,t,l){var a=e.pendingLanes;if(a===0)return 0;var n=0,i=e.suspendedLanes,c=e.pingedLanes;e=e.warmLanes;var d=a&134217727;return d!==0?(a=d&~i,a!==0?n=Vl(a):(c&=d,c!==0?n=Vl(c):l||(l=d&~e,l!==0&&(n=Vl(l))))):(d=a&~i,d!==0?n=Vl(d):c!==0?n=Vl(c):l||(l=a&~e,l!==0&&(n=Vl(l)))),n===0?0:t!==0&&t!==n&&(t&i)===0&&(i=n&-n,l=t&-t,i>=l||i===32&&(l&4194048)!==0)?t:n}function an(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Th(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function jr(){var e=ui;return ui<<=1,(ui&62914560)===0&&(ui=4194304),e}function Mu(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function nn(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Rh(e,t,l,a,n,i){var c=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var d=e.entanglements,p=e.expirationTimes,T=e.hiddenUpdates;for(l=c&~l;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Mh=/[\n"\\]/g;function zt(e){return e.replace(Mh,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Bu(e,t,l,a,n,i,c,d){e.name="",c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?e.type=c:e.removeAttribute("type"),t!=null?c==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Ct(t)):e.value!==""+Ct(t)&&(e.value=""+Ct(t)):c!=="submit"&&c!=="reset"||e.removeAttribute("value"),t!=null?Yu(e,c,Ct(t)):l!=null?Yu(e,c,Ct(l)):a!=null&&e.removeAttribute("value"),n==null&&i!=null&&(e.defaultChecked=!!i),n!=null&&(e.checked=n&&typeof n!="function"&&typeof n!="symbol"),d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"?e.name=""+Ct(d):e.removeAttribute("name")}function Hr(e,t,l,a,n,i,c,d){if(i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.type=i),t!=null||l!=null){if(!(i!=="submit"&&i!=="reset"||t!=null)){Lu(e);return}l=l!=null?""+Ct(l):"",t=t!=null?""+Ct(t):l,d||t===e.value||(e.value=t),e.defaultValue=t}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=d?e.checked:!!a,e.defaultChecked=!!a,c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"&&(e.name=c),Lu(e)}function Yu(e,t,l){t==="number"&&fi(e.ownerDocument)===e||e.defaultValue===""+l||(e.defaultValue=""+l)}function ya(e,t,l,a){if(e=e.options,t){t={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Zu=!1;if(Pt)try{var rn={};Object.defineProperty(rn,"passive",{get:function(){Zu=!0}}),window.addEventListener("test",rn,rn),window.removeEventListener("test",rn,rn)}catch{Zu=!1}var gl=null,Ku=null,di=null;function Xr(){if(di)return di;var e,t=Ku,l=t.length,a,n="value"in gl?gl.value:gl.textContent,i=n.length;for(e=0;e=dn),$r=" ",Fr=!1;function Wr(e,t){switch(e){case"keyup":return sv.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ir(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var xa=!1;function rv(e,t){switch(e){case"compositionend":return Ir(t);case"keypress":return t.which!==32?null:(Fr=!0,$r);case"textInput":return e=t.data,e===$r&&Fr?null:e;default:return null}}function fv(e,t){if(xa)return e==="compositionend"||!Wu&&Wr(e,t)?(e=Xr(),di=Ku=gl=null,xa=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:l,offset:t-e};e=a}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=sf(l)}}function rf(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?rf(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function ff(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=fi(e.document);t instanceof e.HTMLIFrameElement;){try{var l=typeof t.contentWindow.location.href=="string"}catch{l=!1}if(l)e=t.contentWindow;else break;t=fi(e.document)}return t}function es(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var gv=Pt&&"documentMode"in document&&11>=document.documentMode,Sa=null,ts=null,pn=null,ls=!1;function of(e,t,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;ls||Sa==null||Sa!==fi(a)||(a=Sa,"selectionStart"in a&&es(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),pn&&vn(pn,a)||(pn=a,a=iu(ts,"onSelect"),0>=c,n-=c,Jt=1<<32-bt(t)+n|l<oe?(be=P,P=null):be=P.sibling;var Te=R(S,P,E[oe],D);if(Te===null){P===null&&(P=be);break}e&&P&&Te.alternate===null&&t(S,P),_=i(Te,_,oe),Ee===null?te=Te:Ee.sibling=Te,Ee=Te,P=be}if(oe===E.length)return l(S,P),xe&&tl(S,oe),te;if(P===null){for(;oeoe?(be=P,P=null):be=P.sibling;var Yl=R(S,P,Te.value,D);if(Yl===null){P===null&&(P=be);break}e&&P&&Yl.alternate===null&&t(S,P),_=i(Yl,_,oe),Ee===null?te=Yl:Ee.sibling=Yl,Ee=Yl,P=be}if(Te.done)return l(S,P),xe&&tl(S,oe),te;if(P===null){for(;!Te.done;oe++,Te=E.next())Te=U(S,Te.value,D),Te!==null&&(_=i(Te,_,oe),Ee===null?te=Te:Ee.sibling=Te,Ee=Te);return xe&&tl(S,oe),te}for(P=a(P);!Te.done;oe++,Te=E.next())Te=A(P,S,oe,Te.value,D),Te!==null&&(e&&Te.alternate!==null&&P.delete(Te.key===null?oe:Te.key),_=i(Te,_,oe),Ee===null?te=Te:Ee.sibling=Te,Ee=Te);return e&&P.forEach(function(Lp){return t(S,Lp)}),xe&&tl(S,oe),te}function Me(S,_,E,D){if(typeof E=="object"&&E!==null&&E.type===G&&E.key===null&&(E=E.props.children),typeof E=="object"&&E!==null){switch(E.$$typeof){case Z:e:{for(var te=E.key;_!==null;){if(_.key===te){if(te=E.type,te===G){if(_.tag===7){l(S,_.sibling),D=n(_,E.props.children),D.return=S,S=D;break e}}else if(_.elementType===te||typeof te=="object"&&te!==null&&te.$$typeof===ue&&ta(te)===_.type){l(S,_.sibling),D=n(_,E.props),Sn(D,E),D.return=S,S=D;break e}l(S,_);break}else t(S,_);_=_.sibling}E.type===G?(D=Fl(E.props.children,S.mode,D,E.key),D.return=S,S=D):(D=Si(E.type,E.key,E.props,null,S.mode,D),Sn(D,E),D.return=S,S=D)}return c(S);case J:e:{for(te=E.key;_!==null;){if(_.key===te)if(_.tag===4&&_.stateNode.containerInfo===E.containerInfo&&_.stateNode.implementation===E.implementation){l(S,_.sibling),D=n(_,E.children||[]),D.return=S,S=D;break e}else{l(S,_);break}else t(S,_);_=_.sibling}D=rs(E,S.mode,D),D.return=S,S=D}return c(S);case ue:return E=ta(E),Me(S,_,E,D)}if(ve(E))return W(S,_,E,D);if(Ae(E)){if(te=Ae(E),typeof te!="function")throw Error(f(150));return E=te.call(E),ae(S,_,E,D)}if(typeof E.then=="function")return Me(S,_,Oi(E),D);if(E.$$typeof===Q)return Me(S,_,Ei(S,E),D);Ci(S,E)}return typeof E=="string"&&E!==""||typeof E=="number"||typeof E=="bigint"?(E=""+E,_!==null&&_.tag===6?(l(S,_.sibling),D=n(_,E),D.return=S,S=D):(l(S,_),D=cs(E,S.mode,D),D.return=S,S=D),c(S)):l(S,_)}return function(S,_,E,D){try{xn=0;var te=Me(S,_,E,D);return Ma=null,te}catch(P){if(P===Da||P===Ri)throw P;var Ee=xt(29,P,null,S.mode);return Ee.lanes=D,Ee.return=S,Ee}}}var aa=Uf(!0),wf=Uf(!1),jl=!1;function xs(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ss(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Nl(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function El(e,t,l){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(Re&2)!==0){var n=a.pending;return n===null?t.next=t:(t.next=n.next,n.next=t),a.pending=t,t=xi(e),gf(e,null,l),t}return _i(e,a,t,l),xi(e)}function jn(e,t,l){if(t=t.updateQueue,t!==null&&(t=t.shared,(l&4194048)!==0)){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Er(e,l)}}function js(e,t){var l=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,i=null;if(l=l.firstBaseUpdate,l!==null){do{var c={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};i===null?n=i=c:i=i.next=c,l=l.next}while(l!==null);i===null?n=i=t:i=i.next=t}else n=i=t;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:i,shared:a.shared,callbacks:a.callbacks},e.updateQueue=l;return}e=l.lastBaseUpdate,e===null?l.firstBaseUpdate=t:e.next=t,l.lastBaseUpdate=t}var Ns=!1;function Nn(){if(Ns){var e=za;if(e!==null)throw e}}function En(e,t,l,a){Ns=!1;var n=e.updateQueue;jl=!1;var i=n.firstBaseUpdate,c=n.lastBaseUpdate,d=n.shared.pending;if(d!==null){n.shared.pending=null;var p=d,T=p.next;p.next=null,c===null?i=T:c.next=T,c=p;var z=e.alternate;z!==null&&(z=z.updateQueue,d=z.lastBaseUpdate,d!==c&&(d===null?z.firstBaseUpdate=T:d.next=T,z.lastBaseUpdate=p))}if(i!==null){var U=n.baseState;c=0,z=T=p=null,d=i;do{var R=d.lane&-536870913,A=R!==d.lane;if(A?(ge&R)===R:(a&R)===R){R!==0&&R===Ca&&(Ns=!0),z!==null&&(z=z.next={lane:0,tag:d.tag,payload:d.payload,callback:null,next:null});e:{var W=e,ae=d;R=t;var Me=l;switch(ae.tag){case 1:if(W=ae.payload,typeof W=="function"){U=W.call(Me,U,R);break e}U=W;break e;case 3:W.flags=W.flags&-65537|128;case 0:if(W=ae.payload,R=typeof W=="function"?W.call(Me,U,R):W,R==null)break e;U=N({},U,R);break e;case 2:jl=!0}}R=d.callback,R!==null&&(e.flags|=64,A&&(e.flags|=8192),A=n.callbacks,A===null?n.callbacks=[R]:A.push(R))}else A={lane:R,tag:d.tag,payload:d.payload,callback:d.callback,next:null},z===null?(T=z=A,p=U):z=z.next=A,c|=R;if(d=d.next,d===null){if(d=n.shared.pending,d===null)break;A=d,d=A.next,A.next=null,n.lastBaseUpdate=A,n.shared.pending=null}}while(!0);z===null&&(p=U),n.baseState=p,n.firstBaseUpdate=T,n.lastBaseUpdate=z,i===null&&(n.shared.lanes=0),Cl|=c,e.lanes=c,e.memoizedState=U}}function Hf(e,t){if(typeof e!="function")throw Error(f(191,e));e.call(t)}function qf(e,t){var l=e.callbacks;if(l!==null)for(e.callbacks=null,e=0;ei?i:8;var c=C.T,d={};C.T=d,Xs(e,!1,t,l);try{var p=n(),T=C.S;if(T!==null&&T(d,p),p!==null&&typeof p=="object"&&typeof p.then=="function"){var z=Rv(p,a);An(e,t,z,Tt(e))}else An(e,t,a,Tt(e))}catch(U){An(e,t,{then:function(){},status:"rejected",reason:U},Tt())}finally{B.p=i,c!==null&&d.types!==null&&(c.types=d.types),C.T=c}}function Mv(){}function Gs(e,t,l,a){if(e.tag!==5)throw Error(f(476));var n=po(e).queue;vo(e,n,t,le,l===null?Mv:function(){return yo(e),l(a)})}function po(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:le,baseState:le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:le},next:null};var l={};return t.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:l},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function yo(e){var t=po(e);t.next===null&&(t=e.alternate.memoizedState),An(e,t.next.queue,{},Tt())}function Qs(){return at(Zn)}function go(){return Ze().memoizedState}function bo(){return Ze().memoizedState}function Uv(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var l=Tt();e=Nl(l);var a=El(t,e,l);a!==null&&(pt(a,t,l),jn(a,t,l)),t={cache:ys()},e.payload=t;return}t=t.return}}function wv(e,t,l){var a=Tt();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Yi(e)?xo(t,l):(l=us(e,t,l,a),l!==null&&(pt(l,e,a),So(l,t,a)))}function _o(e,t,l){var a=Tt();An(e,t,l,a)}function An(e,t,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Yi(e))xo(t,n);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var c=t.lastRenderedState,d=i(c,l);if(n.hasEagerState=!0,n.eagerState=d,_t(d,c))return _i(e,t,n,0),we===null&&bi(),!1}catch{}if(l=us(e,t,n,a),l!==null)return pt(l,e,a),So(l,t,a),!0}return!1}function Xs(e,t,l,a){if(a={lane:2,revertLane:xc(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Yi(e)){if(t)throw Error(f(479))}else t=us(e,l,a,2),t!==null&&pt(t,e,2)}function Yi(e){var t=e.alternate;return e===fe||t!==null&&t===fe}function xo(e,t){wa=Mi=!0;var l=e.pending;l===null?t.next=t:(t.next=l.next,l.next=t),e.pending=t}function So(e,t,l){if((l&4194048)!==0){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Er(e,l)}}var On={readContext:at,use:Hi,useCallback:Qe,useContext:Qe,useEffect:Qe,useImperativeHandle:Qe,useLayoutEffect:Qe,useInsertionEffect:Qe,useMemo:Qe,useReducer:Qe,useRef:Qe,useState:Qe,useDebugValue:Qe,useDeferredValue:Qe,useTransition:Qe,useSyncExternalStore:Qe,useId:Qe,useHostTransitionStatus:Qe,useFormState:Qe,useActionState:Qe,useOptimistic:Qe,useMemoCache:Qe,useCacheRefresh:Qe};On.useEffectEvent=Qe;var jo={readContext:at,use:Hi,useCallback:function(e,t){return rt().memoizedState=[e,t===void 0?null:t],e},useContext:at,useEffect:io,useImperativeHandle:function(e,t,l){l=l!=null?l.concat([e]):null,Li(4194308,4,ro.bind(null,t,e),l)},useLayoutEffect:function(e,t){return Li(4194308,4,e,t)},useInsertionEffect:function(e,t){Li(4,2,e,t)},useMemo:function(e,t){var l=rt();t=t===void 0?null:t;var a=e();if(na){pl(!0);try{e()}finally{pl(!1)}}return l.memoizedState=[a,t],a},useReducer:function(e,t,l){var a=rt();if(l!==void 0){var n=l(t);if(na){pl(!0);try{l(t)}finally{pl(!1)}}}else n=t;return a.memoizedState=a.baseState=n,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},a.queue=e,e=e.dispatch=wv.bind(null,fe,e),[a.memoizedState,e]},useRef:function(e){var t=rt();return e={current:e},t.memoizedState=e},useState:function(e){e=Hs(e);var t=e.queue,l=_o.bind(null,fe,t);return t.dispatch=l,[e.memoizedState,l]},useDebugValue:Bs,useDeferredValue:function(e,t){var l=rt();return Ys(l,e,t)},useTransition:function(){var e=Hs(!1);return e=vo.bind(null,fe,e.queue,!0,!1),rt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,l){var a=fe,n=rt();if(xe){if(l===void 0)throw Error(f(407));l=l()}else{if(l=t(),we===null)throw Error(f(349));(ge&127)!==0||Xf(a,t,l)}n.memoizedState=l;var i={value:l,getSnapshot:t};return n.queue=i,io(Zf.bind(null,a,i,e),[e]),a.flags|=2048,qa(9,{destroy:void 0},Vf.bind(null,a,i,l,t),null),l},useId:function(){var e=rt(),t=we.identifierPrefix;if(xe){var l=kt,a=Jt;l=(a&~(1<<32-bt(a)-1)).toString(32)+l,t="_"+t+"R_"+l,l=Ui++,0<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof a.is=="string"?c.createElement("select",{is:a.is}):c.createElement("select"),a.multiple?i.multiple=!0:a.size&&(i.size=a.size);break;default:i=typeof a.is=="string"?c.createElement(n,{is:a.is}):c.createElement(n)}}i[tt]=t,i[ft]=a;e:for(c=t.child;c!==null;){if(c.tag===5||c.tag===6)i.appendChild(c.stateNode);else if(c.tag!==4&&c.tag!==27&&c.child!==null){c.child.return=c,c=c.child;continue}if(c===t)break e;for(;c.sibling===null;){if(c.return===null||c.return===t)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}t.stateNode=i;e:switch(it(i,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&sl(t)}}return Be(t),ac(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,l),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==a&&sl(t);else{if(typeof a!="string"&&t.stateNode===null)throw Error(f(166));if(e=se.current,Aa(t)){if(e=t.stateNode,l=t.memoizedProps,a=null,n=lt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}e[tt]=t,e=!!(e.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||Qd(e.nodeValue,l)),e||xl(t,!0)}else e=uu(e).createTextNode(a),e[tt]=t,t.stateNode=e}return Be(t),null;case 31:if(l=t.memoizedState,e===null||e.memoizedState!==null){if(a=Aa(t),l!==null){if(e===null){if(!a)throw Error(f(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(f(557));e[tt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),e=!1}else l=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=l),e=!0;if(!e)return t.flags&256?(jt(t),t):(jt(t),null);if((t.flags&128)!==0)throw Error(f(558))}return Be(t),null;case 13:if(a=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(n=Aa(t),a!==null&&a.dehydrated!==null){if(e===null){if(!n)throw Error(f(318));if(n=t.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(f(317));n[tt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),n=!1}else n=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),n=!0;if(!n)return t.flags&256?(jt(t),t):(jt(t),null)}return jt(t),(t.flags&128)!==0?(t.lanes=l,t):(l=a!==null,e=e!==null&&e.memoizedState!==null,l&&(a=t.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),i=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(i=a.memoizedState.cachePool.pool),i!==n&&(a.flags|=2048)),l!==e&&l&&(t.child.flags|=8192),Zi(t,t.updateQueue),Be(t),null);case 4:return qe(),e===null&&Ec(t.stateNode.containerInfo),Be(t),null;case 10:return al(t.type),Be(t),null;case 19:if(M(Ve),a=t.memoizedState,a===null)return Be(t),null;if(n=(t.flags&128)!==0,i=a.rendering,i===null)if(n)zn(a,!1);else{if(Xe!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(i=Di(e),i!==null){for(t.flags|=128,zn(a,!1),e=i.updateQueue,t.updateQueue=e,Zi(t,e),t.subtreeFlags=0,e=l,l=t.child;l!==null;)bf(l,e),l=l.sibling;return Y(Ve,Ve.current&1|2),xe&&tl(t,a.treeForkCount),t.child}e=e.sibling}a.tail!==null&&yt()>Fi&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304)}else{if(!n)if(e=Di(i),e!==null){if(t.flags|=128,n=!0,e=e.updateQueue,t.updateQueue=e,Zi(t,e),zn(a,!0),a.tail===null&&a.tailMode==="hidden"&&!i.alternate&&!xe)return Be(t),null}else 2*yt()-a.renderingStartTime>Fi&&l!==536870912&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304);a.isBackwards?(i.sibling=t.child,t.child=i):(e=a.last,e!==null?e.sibling=i:t.child=i,a.last=i)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=yt(),e.sibling=null,l=Ve.current,Y(Ve,n?l&1|2:l&1),xe&&tl(t,a.treeForkCount),e):(Be(t),null);case 22:case 23:return jt(t),Ts(),a=t.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(t.flags|=8192):a&&(t.flags|=8192),a?(l&536870912)!==0&&(t.flags&128)===0&&(Be(t),t.subtreeFlags&6&&(t.flags|=8192)):Be(t),l=t.updateQueue,l!==null&&Zi(t,l.retryQueue),l=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),a=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),a!==l&&(t.flags|=2048),e!==null&&M(ea),null;case 24:return l=null,e!==null&&(l=e.memoizedState.cache),t.memoizedState.cache!==l&&(t.flags|=2048),al(Je),Be(t),null;case 25:return null;case 30:return null}throw Error(f(156,t.tag))}function Yv(e,t){switch(os(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return al(Je),qe(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return de(t),null;case 31:if(t.memoizedState!==null){if(jt(t),t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(jt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return M(Ve),null;case 4:return qe(),null;case 10:return al(t.type),null;case 22:case 23:return jt(t),Ts(),e!==null&&M(ea),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return al(Je),null;case 25:return null;default:return null}}function Jo(e,t){switch(os(t),t.tag){case 3:al(Je),qe();break;case 26:case 27:case 5:de(t);break;case 4:qe();break;case 31:t.memoizedState!==null&&jt(t);break;case 13:jt(t);break;case 19:M(Ve);break;case 10:al(t.type);break;case 22:case 23:jt(t),Ts(),e!==null&&M(ea);break;case 24:al(Je)}}function Dn(e,t){try{var l=t.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&e)===e){a=void 0;var i=l.create,c=l.inst;a=i(),c.destroy=a}l=l.next}while(l!==n)}}catch(d){Ce(t,t.return,d)}}function Al(e,t,l){try{var a=t.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var i=n.next;a=i;do{if((a.tag&e)===e){var c=a.inst,d=c.destroy;if(d!==void 0){c.destroy=void 0,n=t;var p=l,T=d;try{T()}catch(z){Ce(n,p,z)}}}a=a.next}while(a!==i)}}catch(z){Ce(t,t.return,z)}}function ko(e){var t=e.updateQueue;if(t!==null){var l=e.stateNode;try{qf(t,l)}catch(a){Ce(e,e.return,a)}}}function $o(e,t,l){l.props=ia(e.type,e.memoizedProps),l.state=e.memoizedState;try{l.componentWillUnmount()}catch(a){Ce(e,t,a)}}function Mn(e,t){try{var l=e.ref;if(l!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof l=="function"?e.refCleanup=l(a):l.current=a}}catch(n){Ce(e,t,n)}}function $t(e,t){var l=e.ref,a=e.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){Ce(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){Ce(e,t,n)}else l.current=null}function Fo(e){var t=e.type,l=e.memoizedProps,a=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":l.autoFocus&&a.focus();break e;case"img":l.src?a.src=l.src:l.srcSet&&(a.srcset=l.srcSet)}}catch(n){Ce(e,e.return,n)}}function nc(e,t,l){try{var a=e.stateNode;cp(a,e.type,l,t),a[ft]=t}catch(n){Ce(e,e.return,n)}}function Wo(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&wl(e.type)||e.tag===4}function ic(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Wo(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&&wl(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function uc(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(e,t):(t=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,t.appendChild(e),l=l._reactRootContainer,l!=null||t.onclick!==null||(t.onclick=It));else if(a!==4&&(a===27&&wl(e.type)&&(l=e.stateNode,t=null),e=e.child,e!==null))for(uc(e,t,l),e=e.sibling;e!==null;)uc(e,t,l),e=e.sibling}function Ki(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?l.insertBefore(e,t):l.appendChild(e);else if(a!==4&&(a===27&&wl(e.type)&&(l=e.stateNode),e=e.child,e!==null))for(Ki(e,t,l),e=e.sibling;e!==null;)Ki(e,t,l),e=e.sibling}function Io(e){var t=e.stateNode,l=e.memoizedProps;try{for(var a=e.type,n=t.attributes;n.length;)t.removeAttributeNode(n[0]);it(t,a,l),t[tt]=e,t[ft]=l}catch(i){Ce(e,e.return,i)}}var cl=!1,Fe=!1,sc=!1,Po=typeof WeakSet=="function"?WeakSet:Set,et=null;function Gv(e,t){if(e=e.containerInfo,Ac=mu,e=ff(e),es(e)){if("selectionStart"in e)var l={start:e.selectionStart,end:e.selectionEnd};else e:{l=(l=e.ownerDocument)&&l.defaultView||window;var a=l.getSelection&&l.getSelection();if(a&&a.rangeCount!==0){l=a.anchorNode;var n=a.anchorOffset,i=a.focusNode;a=a.focusOffset;try{l.nodeType,i.nodeType}catch{l=null;break e}var c=0,d=-1,p=-1,T=0,z=0,U=e,R=null;t:for(;;){for(var A;U!==l||n!==0&&U.nodeType!==3||(d=c+n),U!==i||a!==0&&U.nodeType!==3||(p=c+a),U.nodeType===3&&(c+=U.nodeValue.length),(A=U.firstChild)!==null;)R=U,U=A;for(;;){if(U===e)break t;if(R===l&&++T===n&&(d=c),R===i&&++z===a&&(p=c),(A=U.nextSibling)!==null)break;U=R,R=U.parentNode}U=A}l=d===-1||p===-1?null:{start:d,end:p}}else l=null}l=l||{start:0,end:0}}else l=null;for(Oc={focusedElem:e,selectionRange:l},mu=!1,et=t;et!==null;)if(t=et,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,et=e;else for(;et!==null;){switch(t=et,i=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(l=0;l title"))),it(i,a,l),i[tt]=e,Pe(i),a=i;break e;case"link":var c=im("link","href",n).get(a+(l.href||""));if(c){for(var d=0;dMe&&(c=Me,Me=ae,ae=c);var S=cf(d,ae),_=cf(d,Me);if(S&&_&&(A.rangeCount!==1||A.anchorNode!==S.node||A.anchorOffset!==S.offset||A.focusNode!==_.node||A.focusOffset!==_.offset)){var E=U.createRange();E.setStart(S.node,S.offset),A.removeAllRanges(),ae>Me?(A.addRange(E),A.extend(_.node,_.offset)):(E.setEnd(_.node,_.offset),A.addRange(E))}}}}for(U=[],A=d;A=A.parentNode;)A.nodeType===1&&U.push({element:A,left:A.scrollLeft,top:A.scrollTop});for(typeof d.focus=="function"&&d.focus(),d=0;dl?32:l,C.T=null,l=hc,hc=null;var i=Dl,c=ml;if(We=0,Qa=Dl=null,ml=0,(Re&6)!==0)throw Error(f(331));var d=Re;if(Re|=4,fd(i.current),sd(i,i.current,c,l),Re=d,Bn(0,!1),gt&&typeof gt.onPostCommitFiberRoot=="function")try{gt.onPostCommitFiberRoot(ln,i)}catch{}return!0}finally{B.p=n,C.T=a,Ad(e,t)}}function Cd(e,t,l){t=Mt(l,t),t=Js(e.stateNode,t,2),e=El(e,t,2),e!==null&&(nn(e,2),Ft(e))}function Ce(e,t,l){if(e.tag===3)Cd(e,e,l);else for(;t!==null;){if(t.tag===3){Cd(t,e,l);break}else if(t.tag===1){var a=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(zl===null||!zl.has(a))){e=Mt(l,e),l=zo(2),a=El(t,l,2),a!==null&&(Do(l,a,t,e),nn(a,2),Ft(a));break}}t=t.return}}function gc(e,t,l){var a=e.pingCache;if(a===null){a=e.pingCache=new Vv;var n=new Set;a.set(t,n)}else n=a.get(t),n===void 0&&(n=new Set,a.set(t,n));n.has(l)||(fc=!0,n.add(l),e=$v.bind(null,e,t,l),t.then(e,e))}function $v(e,t,l){var a=e.pingCache;a!==null&&a.delete(t),e.pingedLanes|=e.suspendedLanes&l,e.warmLanes&=~l,we===e&&(ge&l)===l&&(Xe===4||Xe===3&&(ge&62914560)===ge&&300>yt()-$i?(Re&2)===0&&Xa(e,0):oc|=l,Ga===ge&&(Ga=0)),Ft(e)}function zd(e,t){t===0&&(t=jr()),e=$l(e,t),e!==null&&(nn(e,t),Ft(e))}function Fv(e){var t=e.memoizedState,l=0;t!==null&&(l=t.retryLane),zd(e,l)}function Wv(e,t){var l=0;switch(e.tag){case 31:case 13:var a=e.stateNode,n=e.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(f(314))}a!==null&&a.delete(t),zd(e,l)}function Iv(e,t){return zu(e,t)}var lu=null,Za=null,bc=!1,au=!1,_c=!1,Ul=0;function Ft(e){e!==Za&&e.next===null&&(Za===null?lu=Za=e:Za=Za.next=e),au=!0,bc||(bc=!0,ep())}function Bn(e,t){if(!_c&&au){_c=!0;do for(var l=!1,a=lu;a!==null;){if(e!==0){var n=a.pendingLanes;if(n===0)var i=0;else{var c=a.suspendedLanes,d=a.pingedLanes;i=(1<<31-bt(42|e)+1)-1,i&=n&~(c&~d),i=i&201326741?i&201326741|1:i?i|2:0}i!==0&&(l=!0,wd(a,i))}else i=ge,i=si(a,a===we?i:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(i&3)===0||an(a,i)||(l=!0,wd(a,i));a=a.next}while(l);_c=!1}}function Pv(){Dd()}function Dd(){au=bc=!1;var e=0;Ul!==0&&fp()&&(e=Ul);for(var t=yt(),l=null,a=lu;a!==null;){var n=a.next,i=Md(a,t);i===0?(a.next=null,l===null?lu=n:l.next=n,n===null&&(Za=l)):(l=a,(e!==0||(i&3)!==0)&&(au=!0)),a=n}We!==0&&We!==5||Bn(e),Ul!==0&&(Ul=0)}function Md(e,t){for(var l=e.suspendedLanes,a=e.pingedLanes,n=e.expirationTimes,i=e.pendingLanes&-62914561;0d)break;var z=p.transferSize,U=p.initiatorType;z&&Xd(U)&&(p=p.responseEnd,c+=z*(p"u"?null:document;function tm(e,t,l){var a=Ka;if(a&&typeof t=="string"&&t){var n=zt(t);n='link[rel="'+e+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),em.has(n)||(em.add(n),e={rel:e,crossOrigin:l,href:t},a.querySelector(n)===null&&(t=a.createElement("link"),it(t,"link",e),Pe(t),a.head.appendChild(t)))}}function bp(e){hl.D(e),tm("dns-prefetch",e,null)}function _p(e,t){hl.C(e,t),tm("preconnect",e,t)}function xp(e,t,l){hl.L(e,t,l);var a=Ka;if(a&&e&&t){var n='link[rel="preload"][as="'+zt(t)+'"]';t==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+zt(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+zt(l.imageSizes)+'"]')):n+='[href="'+zt(e)+'"]';var i=n;switch(t){case"style":i=Ja(e);break;case"script":i=ka(e)}Bt.has(i)||(e=N({rel:"preload",href:t==="image"&&l&&l.imageSrcSet?void 0:e,as:t},l),Bt.set(i,e),a.querySelector(n)!==null||t==="style"&&a.querySelector(Xn(i))||t==="script"&&a.querySelector(Vn(i))||(t=a.createElement("link"),it(t,"link",e),Pe(t),a.head.appendChild(t)))}}function Sp(e,t){hl.m(e,t);var l=Ka;if(l&&e){var a=t&&typeof t.as=="string"?t.as:"script",n='link[rel="modulepreload"][as="'+zt(a)+'"][href="'+zt(e)+'"]',i=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":i=ka(e)}if(!Bt.has(i)&&(e=N({rel:"modulepreload",href:e},t),Bt.set(i,e),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(Vn(i)))return}a=l.createElement("link"),it(a,"link",e),Pe(a),l.head.appendChild(a)}}}function jp(e,t,l){hl.S(e,t,l);var a=Ka;if(a&&e){var n=va(a).hoistableStyles,i=Ja(e);t=t||"default";var c=n.get(i);if(!c){var d={loading:0,preload:null};if(c=a.querySelector(Xn(i)))d.loading=5;else{e=N({rel:"stylesheet",href:e,"data-precedence":t},l),(l=Bt.get(i))&&Hc(e,l);var p=c=a.createElement("link");Pe(p),it(p,"link",e),p._p=new Promise(function(T,z){p.onload=T,p.onerror=z}),p.addEventListener("load",function(){d.loading|=1}),p.addEventListener("error",function(){d.loading|=2}),d.loading|=4,cu(c,t,a)}c={type:"stylesheet",instance:c,count:1,state:d},n.set(i,c)}}}function Np(e,t){hl.X(e,t);var l=Ka;if(l&&e){var a=va(l).hoistableScripts,n=ka(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),Pe(i),it(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function Ep(e,t){hl.M(e,t);var l=Ka;if(l&&e){var a=va(l).hoistableScripts,n=ka(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0,type:"module"},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),Pe(i),it(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function lm(e,t,l,a){var n=(n=se.current)?su(n):null;if(!n)throw Error(f(446));switch(e){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(t=Ja(l.href),l=va(n).hoistableStyles,a=l.get(t),a||(a={type:"style",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){e=Ja(l.href);var i=va(n).hoistableStyles,c=i.get(e);if(c||(n=n.ownerDocument||n,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},i.set(e,c),(i=n.querySelector(Xn(e)))&&!i._p&&(c.instance=i,c.state.loading=5),Bt.has(e)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Bt.set(e,l),i||Tp(n,e,l,c.state))),t&&a===null)throw Error(f(528,""));return c}if(t&&a!==null)throw Error(f(529,""));return null;case"script":return t=l.async,l=l.src,typeof l=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=ka(l),l=va(n).hoistableScripts,a=l.get(t),a||(a={type:"script",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(f(444,e))}}function Ja(e){return'href="'+zt(e)+'"'}function Xn(e){return'link[rel="stylesheet"]['+e+"]"}function am(e){return N({},e,{"data-precedence":e.precedence,precedence:null})}function Tp(e,t,l,a){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?a.loading=1:(t=e.createElement("link"),a.preload=t,t.addEventListener("load",function(){return a.loading|=1}),t.addEventListener("error",function(){return a.loading|=2}),it(t,"link",l),Pe(t),e.head.appendChild(t))}function ka(e){return'[src="'+zt(e)+'"]'}function Vn(e){return"script[async]"+e}function nm(e,t,l){if(t.count++,t.instance===null)switch(t.type){case"style":var a=e.querySelector('style[data-href~="'+zt(l.href)+'"]');if(a)return t.instance=a,Pe(a),a;var n=N({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Pe(a),it(a,"style",n),cu(a,l.precedence,e),t.instance=a;case"stylesheet":n=Ja(l.href);var i=e.querySelector(Xn(n));if(i)return t.state.loading|=4,t.instance=i,Pe(i),i;a=am(l),(n=Bt.get(n))&&Hc(a,n),i=(e.ownerDocument||e).createElement("link"),Pe(i);var c=i;return c._p=new Promise(function(d,p){c.onload=d,c.onerror=p}),it(i,"link",a),t.state.loading|=4,cu(i,l.precedence,e),t.instance=i;case"script":return i=ka(l.src),(n=e.querySelector(Vn(i)))?(t.instance=n,Pe(n),n):(a=l,(n=Bt.get(i))&&(a=N({},l),qc(a,n)),e=e.ownerDocument||e,n=e.createElement("script"),Pe(n),it(n,"link",a),e.head.appendChild(n),t.instance=n);case"void":return null;default:throw Error(f(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(a=t.instance,t.state.loading|=4,cu(a,l.precedence,e));return t.instance}function cu(e,t,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,i=n,c=0;c title"):null)}function Rp(e,t,l){if(l===1||t.itemProp!=null)return!1;switch(e){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;return t.rel==="stylesheet"?(e=t.disabled,typeof t.precedence=="string"&&e==null):!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 sm(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function Ap(e,t,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=Ja(a.href),i=t.querySelector(Xn(n));if(i){t=i._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=fu.bind(e),t.then(e,e)),l.state.loading|=4,l.instance=i,Pe(i);return}i=t.ownerDocument||t,a=am(a),(n=Bt.get(n))&&Hc(a,n),i=i.createElement("link"),Pe(i);var c=i;c._p=new Promise(function(d,p){c.onload=d,c.onerror=p}),it(i,"link",a),l.instance=i}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(l,t),(t=l.state.preload)&&(l.state.loading&3)===0&&(e.count++,l=fu.bind(e),t.addEventListener("load",l),t.addEventListener("error",l))}}var Lc=0;function Op(e,t){return e.stylesheets&&e.count===0&&du(e,e.stylesheets),0Lc?50:800)+t);return e.unsuspend=l,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function fu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)du(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ou=null;function du(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ou=new Map,t.forEach(Cp,e),ou=null,fu.call(e))}function Cp(e,t){if(!(t.state.loading&4)){var l=ou.get(e);if(l)var a=l.get(null);else{l=new Map,ou.set(e,l);for(var n=e.querySelectorAll("link[data-precedence],style[data-precedence]"),i=0;i"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Jc.exports=Kp(),Jc.exports}var kp=Jp();var zm="popstate";function Dm(s){return typeof s=="object"&&s!=null&&"pathname"in s&&"search"in s&&"hash"in s&&"state"in s&&"key"in s}function $p(s={}){function r(m,h){let{pathname:b="/",search:j="",hash:x=""}=fa(m.location.hash.substring(1));return!b.startsWith("/")&&!b.startsWith(".")&&(b="/"+b),lr("",{pathname:b,search:j,hash:x},h.state&&h.state.usr||null,h.state&&h.state.key||"default")}function o(m,h){let b=m.document.querySelector("base"),j="";if(b&&b.getAttribute("href")){let x=m.location.href,y=x.indexOf("#");j=y===-1?x:x.slice(0,y)}return j+"#"+(typeof h=="string"?h:ei(h))}function f(m,h){Rt(m.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(h)})`)}return Wp(r,o,f,s)}function Ge(s,r){if(s===!1||s===null||typeof s>"u")throw new Error(r)}function Rt(s,r){if(!s){typeof console<"u"&&console.warn(r);try{throw new Error(r)}catch{}}}function Fp(){return Math.random().toString(36).substring(2,10)}function Mm(s,r){return{usr:s.state,key:s.key,idx:r,masked:s.unstable_mask?{pathname:s.pathname,search:s.search,hash:s.hash}:void 0}}function lr(s,r,o=null,f,m){return{pathname:typeof s=="string"?s:s.pathname,search:"",hash:"",...typeof r=="string"?fa(r):r,state:o,key:r&&r.key||f||Fp(),unstable_mask:m}}function ei({pathname:s="/",search:r="",hash:o=""}){return r&&r!=="?"&&(s+=r.charAt(0)==="?"?r:"?"+r),o&&o!=="#"&&(s+=o.charAt(0)==="#"?o:"#"+o),s}function fa(s){let r={};if(s){let o=s.indexOf("#");o>=0&&(r.hash=s.substring(o),s=s.substring(0,o));let f=s.indexOf("?");f>=0&&(r.search=s.substring(f),s=s.substring(0,f)),s&&(r.pathname=s)}return r}function Wp(s,r,o,f={}){let{window:m=document.defaultView,v5Compat:h=!1}=f,b=m.history,j="POP",x=null,y=O();y==null&&(y=0,b.replaceState({...b.state,idx:y},""));function O(){return(b.state||{idx:null}).idx}function N(){j="POP";let w=O(),k=w==null?null:w-y;y=w,x&&x({action:j,location:G.location,delta:k})}function H(w,k){j="PUSH";let ee=Dm(w)?w:lr(G.location,w,k);o&&o(ee,w),y=O()+1;let Q=Mm(ee,y),q=G.createHref(ee.unstable_mask||ee);try{b.pushState(Q,"",q)}catch(I){if(I instanceof DOMException&&I.name==="DataCloneError")throw I;m.location.assign(q)}h&&x&&x({action:j,location:G.location,delta:1})}function Z(w,k){j="REPLACE";let ee=Dm(w)?w:lr(G.location,w,k);o&&o(ee,w),y=O();let Q=Mm(ee,y),q=G.createHref(ee.unstable_mask||ee);b.replaceState(Q,"",q),h&&x&&x({action:j,location:G.location,delta:0})}function J(w){return Ip(w)}let G={get action(){return j},get location(){return s(m,b)},listen(w){if(x)throw new Error("A history only accepts one active listener");return m.addEventListener(zm,N),x=w,()=>{m.removeEventListener(zm,N),x=null}},createHref(w){return r(m,w)},createURL:J,encodeLocation(w){let k=J(w);return{pathname:k.pathname,search:k.search,hash:k.hash}},push:H,replace:Z,go(w){return b.go(w)}};return G}function Ip(s,r=!1){let o="http://localhost";typeof window<"u"&&(o=window.location.origin!=="null"?window.location.origin:window.location.href),Ge(o,"No window.location.(origin|href) available to create URL");let f=typeof s=="string"?s:ei(s);return f=f.replace(/ $/,"%20"),!r&&f.startsWith("//")&&(f=o+f),new URL(f,o)}function Qm(s,r,o="/"){return Pp(s,r,o,!1)}function Pp(s,r,o,f){let m=typeof r=="string"?fa(r):r,h=vl(m.pathname||"/",o);if(h==null)return null;let b=Xm(s);ey(b);let j=null;for(let x=0;j==null&&x{let O={relativePath:y===void 0?b.path||"":y,caseSensitive:b.caseSensitive===!0,childrenIndex:j,route:b};if(O.relativePath.startsWith("/")){if(!O.relativePath.startsWith(f)&&x)return;Ge(O.relativePath.startsWith(f),`Absolute route path "${O.relativePath}" nested under path "${f}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),O.relativePath=O.relativePath.slice(f.length)}let N=Vt([f,O.relativePath]),H=o.concat(O);b.children&&b.children.length>0&&(Ge(b.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${N}".`),Xm(b.children,r,H,N,x)),!(b.path==null&&!b.index)&&r.push({path:N,score:sy(N,b.index),routesMeta:H})};return s.forEach((b,j)=>{if(b.path===""||!b.path?.includes("?"))h(b,j);else for(let x of Vm(b.path))h(b,j,!0,x)}),r}function Vm(s){let r=s.split("/");if(r.length===0)return[];let[o,...f]=r,m=o.endsWith("?"),h=o.replace(/\?$/,"");if(f.length===0)return m?[h,""]:[h];let b=Vm(f.join("/")),j=[];return j.push(...b.map(x=>x===""?h:[h,x].join("/"))),m&&j.push(...b),j.map(x=>s.startsWith("/")&&x===""?"/":x)}function ey(s){s.sort((r,o)=>r.score!==o.score?o.score-r.score:cy(r.routesMeta.map(f=>f.childrenIndex),o.routesMeta.map(f=>f.childrenIndex)))}var ty=/^:[\w-]+$/,ly=3,ay=2,ny=1,iy=10,uy=-2,Um=s=>s==="*";function sy(s,r){let o=s.split("/"),f=o.length;return o.some(Um)&&(f+=uy),r&&(f+=ay),o.filter(m=>!Um(m)).reduce((m,h)=>m+(ty.test(h)?ly:h===""?ny:iy),f)}function cy(s,r){return s.length===r.length&&s.slice(0,-1).every((f,m)=>f===r[m])?s[s.length-1]-r[r.length-1]:0}function ry(s,r,o=!1){let{routesMeta:f}=s,m={},h="/",b=[];for(let j=0;j{if(O==="*"){let J=j[H]||"";b=h.slice(0,h.length-J.length).replace(/(.)\/+$/,"$1")}const Z=j[H];return N&&!Z?y[O]=void 0:y[O]=(Z||"").replace(/%2F/g,"/"),y},{}),pathname:h,pathnameBase:b,pattern:s}}function fy(s,r=!1,o=!0){Rt(s==="*"||!s.endsWith("*")||s.endsWith("/*"),`Route path "${s}" will be treated as if it were "${s.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${s.replace(/\*$/,"/*")}".`);let f=[],m="^"+s.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(b,j,x,y,O)=>{if(f.push({paramName:j,isOptional:x!=null}),x){let N=O.charAt(y+b.length);return N&&N!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return s.endsWith("*")?(f.push({paramName:"*"}),m+=s==="*"||s==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):o?m+="\\/*$":s!==""&&s!=="/"&&(m+="(?:(?=\\/|$))"),[new RegExp(m,r?void 0:"i"),f]}function oy(s){try{return s.split("/").map(r=>decodeURIComponent(r).replace(/\//g,"%2F")).join("/")}catch(r){return Rt(!1,`The URL path "${s}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${r}).`),s}}function vl(s,r){if(r==="/")return s;if(!s.toLowerCase().startsWith(r.toLowerCase()))return null;let o=r.endsWith("/")?r.length-1:r.length,f=s.charAt(o);return f&&f!=="/"?null:s.slice(o)||"/"}var dy=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function my(s,r="/"){let{pathname:o,search:f="",hash:m=""}=typeof s=="string"?fa(s):s,h;return o?(o=Zm(o),o.startsWith("/")?h=wm(o.substring(1),"/"):h=wm(o,r)):h=r,{pathname:h,search:py(f),hash:yy(m)}}function wm(s,r){let o=Tu(r).split("/");return s.split("/").forEach(m=>{m===".."?o.length>1&&o.pop():m!=="."&&o.push(m)}),o.length>1?o.join("/"):"/"}function Wc(s,r,o,f){return`Cannot include a '${s}' character in a manually specified \`to.${r}\` field [${JSON.stringify(f)}]. Please separate it out to the \`to.${o}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function hy(s){return s.filter((r,o)=>o===0||r.route.path&&r.route.path.length>0)}function rr(s){let r=hy(s);return r.map((o,f)=>f===r.length-1?o.pathname:o.pathnameBase)}function Ru(s,r,o,f=!1){let m;typeof s=="string"?m=fa(s):(m={...s},Ge(!m.pathname||!m.pathname.includes("?"),Wc("?","pathname","search",m)),Ge(!m.pathname||!m.pathname.includes("#"),Wc("#","pathname","hash",m)),Ge(!m.search||!m.search.includes("#"),Wc("#","search","hash",m)));let h=s===""||m.pathname==="",b=h?"/":m.pathname,j;if(b==null)j=o;else{let N=r.length-1;if(!f&&b.startsWith("..")){let H=b.split("/");for(;H[0]==="..";)H.shift(),N-=1;m.pathname=H.join("/")}j=N>=0?r[N]:"/"}let x=my(m,j),y=b&&b!=="/"&&b.endsWith("/"),O=(h||b===".")&&o.endsWith("/");return!x.pathname.endsWith("/")&&(y||O)&&(x.pathname+="/"),x}var Zm=s=>s.replace(/\/\/+/g,"/"),Vt=s=>Zm(s.join("/")),Tu=s=>s.replace(/\/+$/,""),vy=s=>Tu(s).replace(/^\/*/,"/"),py=s=>!s||s==="?"?"":s.startsWith("?")?s:"?"+s,yy=s=>!s||s==="#"?"":s.startsWith("#")?s:"#"+s,gy=class{constructor(s,r,o,f=!1){this.status=s,this.statusText=r||"",this.internal=f,o instanceof Error?(this.data=o.toString(),this.error=o):this.data=o}};function by(s){return s!=null&&typeof s.status=="number"&&typeof s.statusText=="string"&&typeof s.internal=="boolean"&&"data"in s}function _y(s){let r=s.map(o=>o.route.path).filter(Boolean);return Vt(r)||"/"}var Km=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function Jm(s,r){let o=s;if(typeof o!="string"||!dy.test(o))return{absoluteURL:void 0,isExternal:!1,to:o};let f=o,m=!1;if(Km)try{let h=new URL(window.location.href),b=o.startsWith("//")?new URL(h.protocol+o):new URL(o),j=vl(b.pathname,r);b.origin===h.origin&&j!=null?o=j+b.search+b.hash:m=!0}catch{Rt(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:f,isExternal:m,to:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var km=["POST","PUT","PATCH","DELETE"];new Set(km);var xy=["GET",...km];new Set(xy);var Pa=v.createContext(null);Pa.displayName="DataRouter";var Au=v.createContext(null);Au.displayName="DataRouterState";var $m=v.createContext(!1);function Sy(){return v.useContext($m)}var Fm=v.createContext({isTransitioning:!1});Fm.displayName="ViewTransition";var jy=v.createContext(new Map);jy.displayName="Fetchers";var Ny=v.createContext(null);Ny.displayName="Await";var At=v.createContext(null);At.displayName="Navigation";var ti=v.createContext(null);ti.displayName="Location";var Zt=v.createContext({outlet:null,matches:[],isDataRoute:!1});Zt.displayName="Route";var fr=v.createContext(null);fr.displayName="RouteError";var Wm="REACT_ROUTER_ERROR",Ey="REDIRECT",Ty="ROUTE_ERROR_RESPONSE";function Ry(s){if(s.startsWith(`${Wm}:${Ey}:{`))try{let r=JSON.parse(s.slice(28));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string"&&typeof r.location=="string"&&typeof r.reloadDocument=="boolean"&&typeof r.replace=="boolean")return r}catch{}}function Ay(s){if(s.startsWith(`${Wm}:${Ty}:{`))try{let r=JSON.parse(s.slice(40));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string")return new gy(r.status,r.statusText,r.data)}catch{}}function Oy(s,{relative:r}={}){Ge(en(),"useHref() may be used only in the context of a component.");let{basename:o,navigator:f}=v.useContext(At),{hash:m,pathname:h,search:b}=li(s,{relative:r}),j=h;return o!=="/"&&(j=h==="/"?o:Vt([o,h])),f.createHref({pathname:j,search:b,hash:m})}function en(){return v.useContext(ti)!=null}function Kt(){return Ge(en(),"useLocation() may be used only in the context of a component."),v.useContext(ti).location}var Im="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Pm(s){v.useContext(At).static||v.useLayoutEffect(s)}function or(){let{isDataRoute:s}=v.useContext(Zt);return s?Vy():Cy()}function Cy(){Ge(en(),"useNavigate() may be used only in the context of a component.");let s=v.useContext(Pa),{basename:r,navigator:o}=v.useContext(At),{matches:f}=v.useContext(Zt),{pathname:m}=Kt(),h=JSON.stringify(rr(f)),b=v.useRef(!1);return Pm(()=>{b.current=!0}),v.useCallback((x,y={})=>{if(Rt(b.current,Im),!b.current)return;if(typeof x=="number"){o.go(x);return}let O=Ru(x,JSON.parse(h),m,y.relative==="path");s==null&&r!=="/"&&(O.pathname=O.pathname==="/"?r:Vt([r,O.pathname])),(y.replace?o.replace:o.push)(O,y.state,y)},[r,o,h,m,s])}var zy=v.createContext(null);function Dy(s){let r=v.useContext(Zt).outlet;return v.useMemo(()=>r&&v.createElement(zy.Provider,{value:s},r),[r,s])}function li(s,{relative:r}={}){let{matches:o}=v.useContext(Zt),{pathname:f}=Kt(),m=JSON.stringify(rr(o));return v.useMemo(()=>Ru(s,JSON.parse(m),f,r==="path"),[s,m,f,r])}function My(s,r){return eh(s,r)}function eh(s,r,o){Ge(en(),"useRoutes() may be used only in the context of a component.");let{navigator:f}=v.useContext(At),{matches:m}=v.useContext(Zt),h=m[m.length-1],b=h?h.params:{},j=h?h.pathname:"/",x=h?h.pathnameBase:"/",y=h&&h.route;{let w=y&&y.path||"";lh(j,!y||w.endsWith("*")||w.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${j}" (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 O=Kt(),N;if(r){let w=typeof r=="string"?fa(r):r;Ge(x==="/"||w.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 "${w.pathname}" was given in the \`location\` prop.`),N=w}else N=O;let H=N.pathname||"/",Z=H;if(x!=="/"){let w=x.replace(/^\//,"").split("/");Z="/"+H.replace(/^\//,"").split("/").slice(w.length).join("/")}let J=Qm(s,{pathname:Z});Rt(y||J!=null,`No routes matched location "${N.pathname}${N.search}${N.hash}" `),Rt(J==null||J[J.length-1].route.element!==void 0||J[J.length-1].route.Component!==void 0||J[J.length-1].route.lazy!==void 0,`Matched leaf route at location "${N.pathname}${N.search}${N.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 G=Ly(J&&J.map(w=>Object.assign({},w,{params:Object.assign({},b,w.params),pathname:Vt([x,f.encodeLocation?f.encodeLocation(w.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathname]),pathnameBase:w.pathnameBase==="/"?x:Vt([x,f.encodeLocation?f.encodeLocation(w.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:w.pathnameBase])})),m,o);return r&&G?v.createElement(ti.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...N},navigationType:"POP"}},G):G}function Uy(){let s=Xy(),r=by(s)?`${s.status} ${s.statusText}`:s instanceof Error?s.message:JSON.stringify(s),o=s instanceof Error?s.stack:null,f="rgba(200,200,200, 0.5)",m={padding:"0.5rem",backgroundColor:f},h={padding:"2px 4px",backgroundColor:f},b=null;return console.error("Error handled by React Router default ErrorBoundary:",s),b=v.createElement(v.Fragment,null,v.createElement("p",null,"💿 Hey developer 👋"),v.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",v.createElement("code",{style:h},"ErrorBoundary")," or"," ",v.createElement("code",{style:h},"errorElement")," prop on your route.")),v.createElement(v.Fragment,null,v.createElement("h2",null,"Unexpected Application Error!"),v.createElement("h3",{style:{fontStyle:"italic"}},r),o?v.createElement("pre",{style:m},o):null,b)}var wy=v.createElement(Uy,null),th=class extends v.Component{constructor(s){super(s),this.state={location:s.location,revalidation:s.revalidation,error:s.error}}static getDerivedStateFromError(s){return{error:s}}static getDerivedStateFromProps(s,r){return r.location!==s.location||r.revalidation!=="idle"&&s.revalidation==="idle"?{error:s.error,location:s.location,revalidation:s.revalidation}:{error:s.error!==void 0?s.error:r.error,location:r.location,revalidation:s.revalidation||r.revalidation}}componentDidCatch(s,r){this.props.onError?this.props.onError(s,r):console.error("React Router caught the following error during render",s)}render(){let s=this.state.error;if(this.context&&typeof s=="object"&&s&&"digest"in s&&typeof s.digest=="string"){const o=Ay(s.digest);o&&(s=o)}let r=s!==void 0?v.createElement(Zt.Provider,{value:this.props.routeContext},v.createElement(fr.Provider,{value:s,children:this.props.component})):this.props.children;return this.context?v.createElement(Hy,{error:s},r):r}};th.contextType=$m;var Ic=new WeakMap;function Hy({children:s,error:r}){let{basename:o}=v.useContext(At);if(typeof r=="object"&&r&&"digest"in r&&typeof r.digest=="string"){let f=Ry(r.digest);if(f){let m=Ic.get(r);if(m)throw m;let h=Jm(f.location,o);if(Km&&!Ic.get(r))if(h.isExternal||f.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const b=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:f.replace}));throw Ic.set(r,b),b}return v.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return s}function qy({routeContext:s,match:r,children:o}){let f=v.useContext(Pa);return f&&f.static&&f.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(f.staticContext._deepestRenderedBoundaryId=r.route.id),v.createElement(Zt.Provider,{value:s},o)}function Ly(s,r=[],o){let f=o?.state;if(s==null){if(!f)return null;if(f.errors)s=f.matches;else if(r.length===0&&!f.initialized&&f.matches.length>0)s=f.matches;else return null}let m=s,h=f?.errors;if(h!=null){let O=m.findIndex(N=>N.route.id&&h?.[N.route.id]!==void 0);Ge(O>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(h).join(",")}`),m=m.slice(0,Math.min(m.length,O+1))}let b=!1,j=-1;if(o&&f){b=f.renderFallback;for(let O=0;O=0?m=m.slice(0,j+1):m=[m[0]];break}}}}let x=o?.onError,y=f&&x?(O,N)=>{x(O,{location:f.location,params:f.matches?.[0]?.params??{},unstable_pattern:_y(f.matches),errorInfo:N})}:void 0;return m.reduceRight((O,N,H)=>{let Z,J=!1,G=null,w=null;f&&(Z=h&&N.route.id?h[N.route.id]:void 0,G=N.route.errorElement||wy,b&&(j<0&&H===0?(lh("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),J=!0,w=null):j===H&&(J=!0,w=N.route.hydrateFallbackElement||null)));let k=r.concat(m.slice(0,H+1)),ee=()=>{let Q;return Z?Q=G:J?Q=w:N.route.Component?Q=v.createElement(N.route.Component,null):N.route.element?Q=N.route.element:Q=O,v.createElement(qy,{match:N,routeContext:{outlet:O,matches:k,isDataRoute:f!=null},children:Q})};return f&&(N.route.ErrorBoundary||N.route.errorElement||H===0)?v.createElement(th,{location:f.location,revalidation:f.revalidation,component:G,error:Z,children:ee(),routeContext:{outlet:null,matches:k,isDataRoute:!0},onError:y}):ee()},null)}function dr(s){return`${s} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function By(s){let r=v.useContext(Pa);return Ge(r,dr(s)),r}function Yy(s){let r=v.useContext(Au);return Ge(r,dr(s)),r}function Gy(s){let r=v.useContext(Zt);return Ge(r,dr(s)),r}function mr(s){let r=Gy(s),o=r.matches[r.matches.length-1];return Ge(o.route.id,`${s} can only be used on routes that contain a unique "id"`),o.route.id}function Qy(){return mr("useRouteId")}function Xy(){let s=v.useContext(fr),r=Yy("useRouteError"),o=mr("useRouteError");return s!==void 0?s:r.errors?.[o]}function Vy(){let{router:s}=By("useNavigate"),r=mr("useNavigate"),o=v.useRef(!1);return Pm(()=>{o.current=!0}),v.useCallback(async(m,h={})=>{Rt(o.current,Im),o.current&&(typeof m=="number"?await s.navigate(m):await s.navigate(m,{fromRouteId:r,...h}))},[s,r])}var Hm={};function lh(s,r,o){!r&&!Hm[s]&&(Hm[s]=!0,Rt(!1,o))}v.memo(Zy);function Zy({routes:s,future:r,state:o,isStatic:f,onError:m}){return eh(s,void 0,{state:o,isStatic:f,onError:m})}function Ky({to:s,replace:r,state:o,relative:f}){Ge(en()," may be used only in the context of a component.");let{static:m}=v.useContext(At);Rt(!m," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:h}=v.useContext(Zt),{pathname:b}=Kt(),j=or(),x=Ru(s,rr(h),b,f==="path"),y=JSON.stringify(x);return v.useEffect(()=>{j(JSON.parse(y),{replace:r,state:o,relative:f})},[j,y,f,r,o]),null}function Jy(s){return Dy(s.context)}function Ql(s){Ge(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function ky({basename:s="/",children:r=null,location:o,navigationType:f="POP",navigator:m,static:h=!1,unstable_useTransitions:b}){Ge(!en(),"You cannot render a inside another . You should never have more than one in your app.");let j=s.replace(/^\/*/,"/"),x=v.useMemo(()=>({basename:j,navigator:m,static:h,unstable_useTransitions:b,future:{}}),[j,m,h,b]);typeof o=="string"&&(o=fa(o));let{pathname:y="/",search:O="",hash:N="",state:H=null,key:Z="default",unstable_mask:J}=o,G=v.useMemo(()=>{let w=vl(y,j);return w==null?null:{location:{pathname:w,search:O,hash:N,state:H,key:Z,unstable_mask:J},navigationType:f}},[j,y,O,N,H,Z,f,J]);return Rt(G!=null,` is not able to match the URL "${y}${O}${N}" because it does not start with the basename, so the won't render anything.`),G==null?null:v.createElement(At.Provider,{value:x},v.createElement(ti.Provider,{children:r,value:G}))}function $y({children:s,location:r}){return My(ar(s),r)}function ar(s,r=[]){let o=[];return v.Children.forEach(s,(f,m)=>{if(!v.isValidElement(f))return;let h=[...r,m];if(f.type===v.Fragment){o.push.apply(o,ar(f.props.children,h));return}Ge(f.type===Ql,`[${typeof f.type=="string"?f.type:f.type.name}] is not a component. All component children of must be a or `),Ge(!f.props.index||!f.props.children,"An index route cannot have child routes.");let b={id:f.props.id||h.join("-"),caseSensitive:f.props.caseSensitive,element:f.props.element,Component:f.props.Component,index:f.props.index,path:f.props.path,middleware:f.props.middleware,loader:f.props.loader,action:f.props.action,hydrateFallbackElement:f.props.hydrateFallbackElement,HydrateFallback:f.props.HydrateFallback,errorElement:f.props.errorElement,ErrorBoundary:f.props.ErrorBoundary,hasErrorBoundary:f.props.hasErrorBoundary===!0||f.props.ErrorBoundary!=null||f.props.errorElement!=null,shouldRevalidate:f.props.shouldRevalidate,handle:f.props.handle,lazy:f.props.lazy};f.props.children&&(b.children=ar(f.props.children,h)),o.push(b)}),o}var xu="get",Su="application/x-www-form-urlencoded";function Ou(s){return typeof HTMLElement<"u"&&s instanceof HTMLElement}function Fy(s){return Ou(s)&&s.tagName.toLowerCase()==="button"}function Wy(s){return Ou(s)&&s.tagName.toLowerCase()==="form"}function Iy(s){return Ou(s)&&s.tagName.toLowerCase()==="input"}function Py(s){return!!(s.metaKey||s.altKey||s.ctrlKey||s.shiftKey)}function eg(s,r){return s.button===0&&(!r||r==="_self")&&!Py(s)}function nr(s=""){return new URLSearchParams(typeof s=="string"||Array.isArray(s)||s instanceof URLSearchParams?s:Object.keys(s).reduce((r,o)=>{let f=s[o];return r.concat(Array.isArray(f)?f.map(m=>[o,m]):[[o,f]])},[]))}function tg(s,r){let o=nr(s);return r&&r.forEach((f,m)=>{o.has(m)||r.getAll(m).forEach(h=>{o.append(m,h)})}),o}var _u=null;function lg(){if(_u===null)try{new FormData(document.createElement("form"),0),_u=!1}catch{_u=!0}return _u}var ag=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Pc(s){return s!=null&&!ag.has(s)?(Rt(!1,`"${s}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Su}"`),null):s}function ng(s,r){let o,f,m,h,b;if(Wy(s)){let j=s.getAttribute("action");f=j?vl(j,r):null,o=s.getAttribute("method")||xu,m=Pc(s.getAttribute("enctype"))||Su,h=new FormData(s)}else if(Fy(s)||Iy(s)&&(s.type==="submit"||s.type==="image")){let j=s.form;if(j==null)throw new Error('Cannot submit a + + + ) : ( +
+ Unknown release in URL. No registered release matches{" "} + {shortId(focusReleaseId, 20, 10)}.{" "} + +
+ ) + ) : null} + {error && !loading ?

{error}

: null} {loading ? (
@@ -196,12 +300,13 @@ export function OverviewPage() { Environment Checksum Created + Shortcuts {data.releases.length === 0 ? ( - + No releases yet. @@ -209,9 +314,12 @@ export function OverviewPage() { data.releases.map((r: ReleaseRow) => ( - - {shortId(r.release_id)} - + + {shortId(r.release_id)} + {r.agent_id} {r.version} @@ -222,6 +330,49 @@ export function OverviewPage() { {new Date(r.created_at).toLocaleString()} + +
+ + Diff + + + Runs + + {UI_READ_ONLY ? null : ( + + Promote + + )} +
+ )) )} diff --git a/web/src/pages/RunsPage.tsx b/web/src/pages/RunsPage.tsx index 6d450f9..07d7854 100644 --- a/web/src/pages/RunsPage.tsx +++ b/web/src/pages/RunsPage.tsx @@ -1,8 +1,9 @@ import { useCallback, useEffect, useId, useRef, useState, type ReactNode } from "react"; -import { Link } from "react-router-dom"; +import { Link, useSearchParams } from "react-router-dom"; import type { ReleaseRow, RunsListPayload } from "../api"; import { fetchRuns, fetchRunsExportBlob, loadTimeline } from "../api"; import { JsonPanel } from "../components/JsonPanel"; +import { pickTrimmedSearch } from "../urlSearch"; function shortId(id: string, keepStart = 12, keepEnd = 6) { if (id.length <= keepStart + keepEnd + 1) return id; @@ -102,6 +103,7 @@ function buildTraceGroups(events: unknown[]): { key: string; rows: Record(null); const drawerPanelRef = useRef(null); const drawerReturnFocusRef = useRef(null); @@ -138,6 +140,15 @@ export function RunsPage() { }); }, []); + useEffect(() => { + const rid = pickTrimmedSearch(searchParams, "release_id"); + const win = pickTrimmedSearch(searchParams, "window"); + const env = pickTrimmedSearch(searchParams, "environment"); + if (rid) setReleaseId(rid); + if (win) setWindowVal(win); + setEnvironment(env); + }, [searchParams]); + const closeDrawer = useCallback(() => { setDetailEvent(null); window.setTimeout(() => { diff --git a/web/src/urlSearch.ts b/web/src/urlSearch.ts new file mode 100644 index 0000000..9445077 --- /dev/null +++ b/web/src/urlSearch.ts @@ -0,0 +1,15 @@ +/** Hash-router search helpers for deep-linking forms. */ + +export function pickTrimmedSearch(searchParams: URLSearchParams, key: string): string { + const raw = searchParams.get(key); + return raw !== null ? raw.trim() : ""; +} + +export function searchParamsFromRecord(rec: Record): string { + const sp = new URLSearchParams(); + for (const [k, v] of Object.entries(rec)) { + if (v !== "") sp.set(k, v); + } + const s = sp.toString(); + return s ? `?${s}` : ""; +} From 1d9978445567c3067d332aba3fc4936aa3f63ddb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 4 May 2026 15:20:25 +0000 Subject: [PATCH 2/6] docs: append Blueprint alignment section to UI roadmap Captures adopted principles, merged IA, deferred backend-gated items, and evaluation-scoped policy terminology from product blueprint review. Co-authored-by: Gottam Sai Bharath --- docs/ui-roadmap.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/ui-roadmap.md b/docs/ui-roadmap.md index 3ebb440..5823ecb 100644 --- a/docs/ui-roadmap.md +++ b/docs/ui-roadmap.md @@ -47,3 +47,41 @@ This document turns the strict UI review into sequenced work. Scope is the check After `web/` changes: from `web/`, `npm ci && npm run build`; commit `src/flightdeck/server/static/` updates; run `npm run test:e2e` when navigation or forms behavior changes. On Unix hosts where `python` is not on `PATH`, set `FLIGHTDECK_E2E_PYTHON` to a Python that has FlightDeck installed (for example the repo venv: `FLIGHTDECK_E2E_PYTHON=/path/to/.venv/bin/python npm run test:e2e`). The default is `python3`. + +## Blueprint alignment (external product IA review) + +This section maps a fuller “control plane” blueprint to FlightDeck’s **current** CLI-first ledger and HTTP surface. Use it to avoid building UI that implies APIs or workflows we do not ship yet. + +### Adopted from the blueprint + +- **Page litmus**: each primary screen should answer at least one of — *What changed?* · *What happened because of it?* · *Can I ship?* +- **Cross-page consistency**: shared status semantics (pass / fail / warn / neutral), fixed vocabulary (**Release**, **Diff**, **Policy**, **Evidence**), repeated rhythm (**header → summary → detail → actions**). +- **Sparse chrome**: summary metrics and tables over chart-heavy dashboards (matches roadmap non-goals). +- **Diff as differentiator**: structured comparison and policy outcome stay central; layout can evolve toward “baseline vs candidate” twin + verdict-first fold (Phase 1). +- **Evidence as ground truth**: runs + rollups remain the forensic surface; avoid Langfuse-style analytics_scope creep. +- **Component direction**: prefer one reusable set (`ReleaseHeader`, `StatusBadge`, `MetricCard`, etc.) over one-off page styling. + +### Merged information architecture (near term) + +Avoid exploding to eight top-level nav items before contracts exist. Practical sequencing: + +1. **Overview** — situational awareness; add promoted / last-action strip before burying operators in ledger counters (Phase 1). +2. **Releases** — table-first browsing (today: Overview table; later: dedicated route if needed). +3. **Release detail** — evolve `?release=` hero into `/release/:id` when we want a stable bookmark per artifact. +4. **Diff** — deep dive; expand “change → impact → policy” **only** when diff payloads expose comparable structure (prompt/tools/model deltas as data, not copy). +5. **Evidence** — Runs page (rename in nav only if it helps operators). +6. **Promote** — Actions; surface approval flow when `promotion_requires_approval` is on (today: request / confirm API). + +Defer standalone **Policies** (rule catalog with thresholds), **multi-role approval chains**, and **rich audit timeline filters** until read APIs and persistence match those stories. + +### Deferred / backend-gated (do not imply in UI yet) + +- **Per-release row status** (“Blocked”, “Live”, “Rolled back”) with sortable **cost Δ / latency Δ**: “Live” can align with promoted pointers; “blocked” is **evaluation-scoped** (depends on baseline, window, environment)—not a global attribute unless we store or cache last evaluation per release. +- **Policies page** listing rules with “expected vs actual”: needs a stable **rule listing** or workspace-backed contract; today policy output is **evaluated reasons**, not necessarily a browsable catalog. +- **Approvals** as org chart (Platform → ML → Security): requires identity, roles, and workflow beyond optional promotion request/confirm. +- **Risk score** / composite **HIGH** labels: needs a defined server-side aggregate or explicit mapping from existing fields (e.g. sample confidence alone is not a full risk model). +- **Release twin** lines such as “system prompt +N tokens” unless those deltas exist on the wire from release/diff payloads. + +### Terminology note + +Treat **policy FAIL** as **do not promote this candidate under this evaluation context** (baseline + window + environment), not “this release ID is permanently blocked everywhere.” From 89b9cd827a9a05d2ff04221af4da748a18a84f58 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 4 May 2026 15:50:58 +0000 Subject: [PATCH 3/6] feat(web): UI roadmap P1/P2 hierarchy, diff fold, copy filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collapse ledger metrics behind toggle; reorder Overview (promoted first) with Live badges, release filters, and copy-to-clipboard. Diff page puts samples and rollups before collapsible pricing detail. Infra-style polish: solid primary buttons, subtler table hover, page intros with decision litmus. Update roadmap Phase 1–2 status; refresh static bundle and e2e for metrics toggle. Co-authored-by: Gottam Sai Bharath --- docs/ui-roadmap.md | 24 +- .../server/static/assets/index-B6xFtJ7-.js | 11 + .../server/static/assets/index-B7p9SpNf.js | 11 - .../server/static/assets/index-D9BWBTvc.css | 1 - .../server/static/assets/index-Dygsz4d1.css | 1 + src/flightdeck/server/static/index.html | 4 +- web/e2e/smoke.spec.ts | 6 +- web/e2e/theme.spec.ts | 4 +- web/src/components/AppShell.tsx | 2 +- web/src/components/CopyTextButton.tsx | 52 ++ web/src/index.css | 182 ++++++- web/src/pages/ActionsPage.tsx | 15 +- web/src/pages/DiffPage.tsx | 193 ++++---- web/src/pages/OverviewPage.tsx | 467 ++++++++++++------ web/src/pages/RunsPage.tsx | 16 +- web/src/pages/SettingsPage.tsx | 6 +- 16 files changed, 679 insertions(+), 316 deletions(-) create mode 100644 src/flightdeck/server/static/assets/index-B6xFtJ7-.js delete mode 100644 src/flightdeck/server/static/assets/index-B7p9SpNf.js delete mode 100644 src/flightdeck/server/static/assets/index-D9BWBTvc.css create mode 100644 src/flightdeck/server/static/assets/index-Dygsz4d1.css create mode 100644 web/src/components/CopyTextButton.tsx diff --git a/docs/ui-roadmap.md b/docs/ui-roadmap.md index 5823ecb..6bf09fd 100644 --- a/docs/ui-roadmap.md +++ b/docs/ui-roadmap.md @@ -20,21 +20,21 @@ This document turns the strict UI review into sequenced work. Scope is the check ## Phase 1 — Hierarchy and differentiation -| Priority | Work | -|----------|------| -| P1 | Collapse or relocate **Ledger metrics** on Overview so the releases + promoted story leads. | -| P1 | **Reorder Diff result**: top fold = verdict + key deltas; pricing/catalog in collapsed sections or tabs. | -| P1 | **Promoted vs candidate** narrative per `agent + environment` (e.g. inline summary above tables). | -| P1 | Reduce reliance on **manual checksum scanning** — surface version + agent + env as the human keys. | +| Priority | Work | Status | +|----------|------|--------| +| P1 | Collapse or relocate **Ledger metrics** on Overview so the releases + promoted story leads. | Done — metrics in collapsible panel below tables (collapsed by default). | +| P1 | **Reorder Diff result**: top fold = verdict + key deltas; pricing/catalog in collapsed sections or tabs. | Done — verdict banner; samples + rollups; pricing summary inline with expandable detail. | +| P1 | **Promoted vs candidate** narrative per `agent + environment` (e.g. inline summary above tables). | Done — promoted table first with version column; releases show Live vs Registered. | +| P1 | Reduce reliance on **manual checksum scanning** — surface version + agent + env as the human keys. | Done — Primary column on releases table; hero leads with agent/version/env. | ## Phase 2 — Polish and operator UX -| Priority | Work | -|----------|------| -| P2 | Typography scale for page vs card titles; consistent vertical rhythm. | -| P2 | Table ergonomics: row hover, optional filters, copy-to-clipboard for release IDs. | -| P2 | Tone down gradient accents for a more **infra / audit** aesthetic (keep accessible contrast). | -| P2 | Copy pass: each primary page answers *What changed?* *Is it safe?* *Can I ship?* in one short block. | +| Priority | Work | Status | +|----------|------|--------| +| P2 | Typography scale for page vs card titles; consistent vertical rhythm. | Done — `fd-page-sub--tight` / `--meta`, wider page header measure. | +| P2 | Table ergonomics: row hover, optional filters, copy-to-clipboard for release IDs. | Done — filter row on releases; copy buttons; hover accent on `fd-table--hover`. | +| P2 | Tone down gradient accents for a more **infra / audit** aesthetic (keep accessible contrast). | Done — solid primary buttons; flat logo tile; nav indicator unchanged. | +| P2 | Copy pass: each primary page answers *What changed?* *Is it safe?* *Can I ship?* in one short block. | Done — Overview, Diff, Runs, Actions, Settings intros. | ## Non-goals (near term) diff --git a/src/flightdeck/server/static/assets/index-B6xFtJ7-.js b/src/flightdeck/server/static/assets/index-B6xFtJ7-.js new file mode 100644 index 0000000..78f8d41 --- /dev/null +++ b/src/flightdeck/server/static/assets/index-B6xFtJ7-.js @@ -0,0 +1,11 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const m of document.querySelectorAll('link[rel="modulepreload"]'))f(m);new MutationObserver(m=>{for(const h of m)if(h.type==="childList")for(const b of h.addedNodes)b.tagName==="LINK"&&b.rel==="modulepreload"&&f(b)}).observe(document,{childList:!0,subtree:!0});function o(m){const h={};return m.integrity&&(h.integrity=m.integrity),m.referrerPolicy&&(h.referrerPolicy=m.referrerPolicy),m.crossOrigin==="use-credentials"?h.credentials="include":m.crossOrigin==="anonymous"?h.credentials="omit":h.credentials="same-origin",h}function f(m){if(m.ep)return;m.ep=!0;const h=o(m);fetch(m.href,h)}})();var Zc={exports:{}},$n={};var Sm;function Yv(){if(Sm)return $n;Sm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(f,m,h){var b=null;if(h!==void 0&&(b=""+h),m.key!==void 0&&(b=""+m.key),"key"in m){h={};for(var j in m)j!=="key"&&(h[j]=m[j])}else h=m;return m=h.ref,{$$typeof:s,type:f,key:b,ref:m!==void 0?m:null,props:h}}return $n.Fragment=r,$n.jsx=o,$n.jsxs=o,$n}var jm;function Gv(){return jm||(jm=1,Zc.exports=Yv()),Zc.exports}var u=Gv(),Kc={exports:{}},ce={};var Nm;function Qv(){if(Nm)return ce;Nm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),f=Symbol.for("react.strict_mode"),m=Symbol.for("react.profiler"),h=Symbol.for("react.consumer"),b=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),O=Symbol.for("react.lazy"),N=Symbol.for("react.activity"),L=Symbol.iterator;function G(g){return g===null||typeof g!="object"?null:(g=L&&g[L]||g["@@iterator"],typeof g=="function"?g:null)}var J={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Q=Object.assign,H={};function Z(g,w,Y){this.props=g,this.context=w,this.refs=H,this.updater=Y||J}Z.prototype.isReactComponent={},Z.prototype.setState=function(g,w){if(typeof g!="object"&&typeof g!="function"&&g!=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,g,w,"setState")},Z.prototype.forceUpdate=function(g){this.updater.enqueueForceUpdate(this,g,"forceUpdate")};function ee(){}ee.prototype=Z.prototype;function I(g,w,Y){this.props=g,this.context=w,this.refs=H,this.updater=Y||J}var ye=I.prototype=new ee;ye.constructor=I,Q(ye,Z.prototype),ye.isPureReactComponent=!0;var re=Array.isArray;function ie(){}var F={H:null,A:null,T:null,S:null},le=Object.prototype.hasOwnProperty;function X(g,w,Y){var k=Y.ref;return{$$typeof:s,type:g,key:w,ref:k!==void 0?k:null,props:Y}}function He(g,w){return X(g.type,w,g.props)}function fe(g){return typeof g=="object"&&g!==null&&g.$$typeof===s}function K(g){var w={"=":"=0",":":"=2"};return"$"+g.replace(/[=:]/g,function(Y){return w[Y]})}var de=/\/+/g;function me(g,w){return typeof g=="object"&&g!==null&&g.key!=null?K(""+g.key):w.toString(36)}function M(g){switch(g.status){case"fulfilled":return g.value;case"rejected":throw g.reason;default:switch(typeof g.status=="string"?g.then(ie,ie):(g.status="pending",g.then(function(w){g.status==="pending"&&(g.status="fulfilled",g.value=w)},function(w){g.status==="pending"&&(g.status="rejected",g.reason=w)})),g.status){case"fulfilled":return g.value;case"rejected":throw g.reason}}throw g}function E(g,w,Y,k,ne){var se=typeof g;(se==="undefined"||se==="boolean")&&(g=null);var Ne=!1;if(g===null)Ne=!0;else switch(se){case"bigint":case"string":case"number":Ne=!0;break;case"object":switch(g.$$typeof){case s:case r:Ne=!0;break;case O:return Ne=g._init,E(Ne(g._payload),w,Y,k,ne)}}if(Ne)return ne=ne(g),Ne=k===""?"."+me(g,0):k,re(ne)?(Y="",Ne!=null&&(Y=Ne.replace(de,"$&/")+"/"),E(ne,w,Y,"",function(B){return B})):ne!=null&&(fe(ne)&&(ne=He(ne,Y+(ne.key==null||g&&g.key===ne.key?"":(""+ne.key).replace(de,"$&/")+"/")+Ne)),w.push(ne)),1;Ne=0;var Ke=k===""?".":k+":";if(re(g))for(var qe=0;qe>>1,xe=E[_e];if(0>>1;_em(Y,W))km(ne,Y)?(E[_e]=ne,E[k]=W,_e=k):(E[_e]=Y,E[w]=W,_e=w);else if(km(ne,W))E[_e]=ne,E[k]=W,_e=k;else break e}}return q}function m(E,q){var W=E.sortIndex-q.sortIndex;return W!==0?W:E.id-q.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var h=performance;s.unstable_now=function(){return h.now()}}else{var b=Date,j=b.now();s.unstable_now=function(){return b.now()-j}}var x=[],y=[],O=1,N=null,L=3,G=!1,J=!1,Q=!1,H=!1,Z=typeof setTimeout=="function"?setTimeout:null,ee=typeof clearTimeout=="function"?clearTimeout:null,I=typeof setImmediate<"u"?setImmediate:null;function ye(E){for(var q=o(y);q!==null;){if(q.callback===null)f(y);else if(q.startTime<=E)f(y),q.sortIndex=q.expirationTime,r(x,q);else break;q=o(y)}}function re(E){if(Q=!1,ye(E),!J)if(o(x)!==null)J=!0,ie||(ie=!0,K());else{var q=o(y);q!==null&&M(re,q.startTime-E)}}var ie=!1,F=-1,le=5,X=-1;function He(){return H?!0:!(s.unstable_now()-XE&&He());){var _e=N.callback;if(typeof _e=="function"){N.callback=null,L=N.priorityLevel;var xe=_e(N.expirationTime<=E);if(E=s.unstable_now(),typeof xe=="function"){N.callback=xe,ye(E),q=!0;break t}N===o(x)&&f(x),ye(E)}else f(x);N=o(x)}if(N!==null)q=!0;else{var g=o(y);g!==null&&M(re,g.startTime-E),q=!1}}break e}finally{N=null,L=W,G=!1}q=void 0}}finally{q?K():ie=!1}}}var K;if(typeof I=="function")K=function(){I(fe)};else if(typeof MessageChannel<"u"){var de=new MessageChannel,me=de.port2;de.port1.onmessage=fe,K=function(){me.postMessage(null)}}else K=function(){Z(fe,0)};function M(E,q){F=Z(function(){E(s.unstable_now())},q)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(E){E.callback=null},s.unstable_forceFrameRate=function(E){0>E||125_e?(E.sortIndex=W,r(y,E),o(x)===null&&E===o(y)&&(Q?(ee(F),F=-1):Q=!0,M(re,W-_e))):(E.sortIndex=xe,r(x,E),J||G||(J=!0,ie||(ie=!0,K()))),E},s.unstable_shouldYield=He,s.unstable_wrapCallback=function(E){var q=L;return function(){var W=L;L=q;try{return E.apply(this,arguments)}finally{L=W}}}})($c)),$c}var Rm;function Vv(){return Rm||(Rm=1,kc.exports=Xv()),kc.exports}var Fc={exports:{}},ct={};var Am;function Zv(){if(Am)return ct;Am=1;var s=rr();function r(x){var y="https://react.dev/errors/"+x;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Fc.exports=Zv(),Fc.exports}var Om;function Jv(){if(Om)return Fn;Om=1;var s=Vv(),r=rr(),o=Kv();function f(e){var t="https://react.dev/errors/"+e;if(1xe||(e.current=_e[xe],_e[xe]=null,xe--)}function Y(e,t){xe++,_e[xe]=e.current,e.current=t}var k=g(null),ne=g(null),se=g(null),Ne=g(null);function Ke(e,t){switch(Y(se,t),Y(ne,e),Y(k,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Zd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Zd(t),e=Kd(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}w(k),Y(k,e)}function qe(){w(k),w(ne),w(se)}function B(e){e.memoizedState!==null&&Y(Ne,e);var t=k.current,l=Kd(t,e.type);t!==l&&(Y(ne,e),Y(k,l))}function pe(e){ne.current===e&&(w(k),w(ne)),Ne.current===e&&(w(Ne),Zn._currentValue=W)}var we,V;function ue(e){if(we===void 0)try{throw Error()}catch(l){var t=l.stack.trim().match(/\n( *(at )?)/);we=t&&t[1]||"",V=-1)":-1n||v[a]!==R[n]){var z=` +`+v[a].replace(" at new "," at ");return e.displayName&&z.includes("")&&(z=z.replace("",e.displayName)),z}while(1<=a&&0<=n);break}}}finally{ve=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?ue(l):""}function Ct(e,t){switch(e.tag){case 26:case 27:case 5:return ue(e.type);case 16:return ue("Lazy");case 13:return e.child!==t&&t!==null?ue("Suspense Fallback"):ue("Suspense");case 19:return ue("SuspenseList");case 0:case 15:return st(e.type,!1);case 11:return st(e.type.render,!1);case 1:return st(e.type,!0);case 31:return ue("Activity");default:return""}}function Pe(e){try{var t="",l=null;do t+=Ct(e,l),l=e,e=e.return;while(e);return t}catch(a){return` +Error generating stack: `+a.message+` +`+a.stack}}var tn=Object.prototype.hasOwnProperty,zu=s.unstable_scheduleCallback,Du=s.unstable_cancelCallback,gh=s.unstable_shouldYield,bh=s.unstable_requestPaint,yt=s.unstable_now,_h=s.unstable_getCurrentPriorityLevel,xr=s.unstable_ImmediatePriority,Sr=s.unstable_UserBlockingPriority,ai=s.unstable_NormalPriority,xh=s.unstable_LowPriority,jr=s.unstable_IdlePriority,Sh=s.log,jh=s.unstable_setDisableYieldValue,ln=null,gt=null;function yl(e){if(typeof Sh=="function"&&jh(e),gt&&typeof gt.setStrictMode=="function")try{gt.setStrictMode(ln,e)}catch{}}var bt=Math.clz32?Math.clz32:Th,Nh=Math.log,Eh=Math.LN2;function Th(e){return e>>>=0,e===0?32:31-(Nh(e)/Eh|0)|0}var ni=256,ii=262144,ui=4194304;function Vl(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function si(e,t,l){var a=e.pendingLanes;if(a===0)return 0;var n=0,i=e.suspendedLanes,c=e.pingedLanes;e=e.warmLanes;var d=a&134217727;return d!==0?(a=d&~i,a!==0?n=Vl(a):(c&=d,c!==0?n=Vl(c):l||(l=d&~e,l!==0&&(n=Vl(l))))):(d=a&~i,d!==0?n=Vl(d):c!==0?n=Vl(c):l||(l=a&~e,l!==0&&(n=Vl(l)))),n===0?0:t!==0&&t!==n&&(t&i)===0&&(i=n&-n,l=t&-t,i>=l||i===32&&(l&4194048)!==0)?t:n}function an(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Rh(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Nr(){var e=ui;return ui<<=1,(ui&62914560)===0&&(ui=4194304),e}function Mu(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function nn(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ah(e,t,l,a,n,i){var c=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var d=e.entanglements,v=e.expirationTimes,R=e.hiddenUpdates;for(l=c&~l;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var wh=/[\n"\\]/g;function zt(e){return e.replace(wh,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Bu(e,t,l,a,n,i,c,d){e.name="",c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?e.type=c:e.removeAttribute("type"),t!=null?c==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Ot(t)):e.value!==""+Ot(t)&&(e.value=""+Ot(t)):c!=="submit"&&c!=="reset"||e.removeAttribute("value"),t!=null?Yu(e,c,Ot(t)):l!=null?Yu(e,c,Ot(l)):a!=null&&e.removeAttribute("value"),n==null&&i!=null&&(e.defaultChecked=!!i),n!=null&&(e.checked=n&&typeof n!="function"&&typeof n!="symbol"),d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"?e.name=""+Ot(d):e.removeAttribute("name")}function qr(e,t,l,a,n,i,c,d){if(i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.type=i),t!=null||l!=null){if(!(i!=="submit"&&i!=="reset"||t!=null)){Lu(e);return}l=l!=null?""+Ot(l):"",t=t!=null?""+Ot(t):l,d||t===e.value||(e.value=t),e.defaultValue=t}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=d?e.checked:!!a,e.defaultChecked=!!a,c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"&&(e.name=c),Lu(e)}function Yu(e,t,l){t==="number"&&fi(e.ownerDocument)===e||e.defaultValue===""+l||(e.defaultValue=""+l)}function ga(e,t,l,a){if(e=e.options,t){t={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Zu=!1;if(Pt)try{var rn={};Object.defineProperty(rn,"passive",{get:function(){Zu=!0}}),window.addEventListener("test",rn,rn),window.removeEventListener("test",rn,rn)}catch{Zu=!1}var bl=null,Ku=null,di=null;function Vr(){if(di)return di;var e,t=Ku,l=t.length,a,n="value"in bl?bl.value:bl.textContent,i=n.length;for(e=0;e=dn),Fr=" ",Wr=!1;function Ir(e,t){switch(e){case"keyup":return cp.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Pr(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Sa=!1;function fp(e,t){switch(e){case"compositionend":return Pr(t);case"keypress":return t.which!==32?null:(Wr=!0,Fr);case"textInput":return e=t.data,e===Fr&&Wr?null:e;default:return null}}function op(e,t){if(Sa)return e==="compositionend"||!Wu&&Ir(e,t)?(e=Vr(),di=Ku=bl=null,Sa=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:l,offset:t-e};e=a}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=cf(l)}}function ff(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?ff(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function of(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=fi(e.document);t instanceof e.HTMLIFrameElement;){try{var l=typeof t.contentWindow.location.href=="string"}catch{l=!1}if(l)e=t.contentWindow;else break;t=fi(e.document)}return t}function es(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var bp=Pt&&"documentMode"in document&&11>=document.documentMode,ja=null,ts=null,vn=null,ls=!1;function df(e,t,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;ls||ja==null||ja!==fi(a)||(a=ja,"selectionStart"in a&&es(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),vn&&pn(vn,a)||(vn=a,a=iu(ts,"onSelect"),0>=c,n-=c,Jt=1<<32-bt(t)+n|l<he?(je=P,P=null):je=P.sibling;var Re=A(S,P,T[he],D);if(Re===null){P===null&&(P=je);break}e&&P&&Re.alternate===null&&t(S,P),_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re,P=je}if(he===T.length)return l(S,P),Ee&&tl(S,he),te;if(P===null){for(;hehe?(je=P,P=null):je=P.sibling;var Gl=A(S,P,Re.value,D);if(Gl===null){P===null&&(P=je);break}e&&P&&Gl.alternate===null&&t(S,P),_=i(Gl,_,he),Te===null?te=Gl:Te.sibling=Gl,Te=Gl,P=je}if(Re.done)return l(S,P),Ee&&tl(S,he),te;if(P===null){for(;!Re.done;he++,Re=T.next())Re=U(S,Re.value,D),Re!==null&&(_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re);return Ee&&tl(S,he),te}for(P=a(P);!Re.done;he++,Re=T.next())Re=C(P,S,he,Re.value,D),Re!==null&&(e&&Re.alternate!==null&&P.delete(Re.key===null?he:Re.key),_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re);return e&&P.forEach(function(Bv){return t(S,Bv)}),Ee&&tl(S,he),te}function Me(S,_,T,D){if(typeof T=="object"&&T!==null&&T.type===Q&&T.key===null&&(T=T.props.children),typeof T=="object"&&T!==null){switch(T.$$typeof){case G:e:{for(var te=T.key;_!==null;){if(_.key===te){if(te=T.type,te===Q){if(_.tag===7){l(S,_.sibling),D=n(_,T.props.children),D.return=S,S=D;break e}}else if(_.elementType===te||typeof te=="object"&&te!==null&&te.$$typeof===le&&ta(te)===_.type){l(S,_.sibling),D=n(_,T.props),Sn(D,T),D.return=S,S=D;break e}l(S,_);break}else t(S,_);_=_.sibling}T.type===Q?(D=Fl(T.props.children,S.mode,D,T.key),D.return=S,S=D):(D=Si(T.type,T.key,T.props,null,S.mode,D),Sn(D,T),D.return=S,S=D)}return c(S);case J:e:{for(te=T.key;_!==null;){if(_.key===te)if(_.tag===4&&_.stateNode.containerInfo===T.containerInfo&&_.stateNode.implementation===T.implementation){l(S,_.sibling),D=n(_,T.children||[]),D.return=S,S=D;break e}else{l(S,_);break}else t(S,_);_=_.sibling}D=rs(T,S.mode,D),D.return=S,S=D}return c(S);case le:return T=ta(T),Me(S,_,T,D)}if(M(T))return $(S,_,T,D);if(K(T)){if(te=K(T),typeof te!="function")throw Error(f(150));return T=te.call(T),ae(S,_,T,D)}if(typeof T.then=="function")return Me(S,_,Ci(T),D);if(T.$$typeof===I)return Me(S,_,Ei(S,T),D);Oi(S,T)}return typeof T=="string"&&T!==""||typeof T=="number"||typeof T=="bigint"?(T=""+T,_!==null&&_.tag===6?(l(S,_.sibling),D=n(_,T),D.return=S,S=D):(l(S,_),D=cs(T,S.mode,D),D.return=S,S=D),c(S)):l(S,_)}return function(S,_,T,D){try{xn=0;var te=Me(S,_,T,D);return wa=null,te}catch(P){if(P===Ma||P===Ri)throw P;var Te=xt(29,P,null,S.mode);return Te.lanes=D,Te.return=S,Te}}}var aa=Uf(!0),Hf=Uf(!1),Nl=!1;function xs(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ss(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function El(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Tl(e,t,l){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(Ae&2)!==0){var n=a.pending;return n===null?t.next=t:(t.next=n.next,n.next=t),a.pending=t,t=xi(e),bf(e,null,l),t}return _i(e,a,t,l),xi(e)}function jn(e,t,l){if(t=t.updateQueue,t!==null&&(t=t.shared,(l&4194048)!==0)){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Tr(e,l)}}function js(e,t){var l=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,i=null;if(l=l.firstBaseUpdate,l!==null){do{var c={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};i===null?n=i=c:i=i.next=c,l=l.next}while(l!==null);i===null?n=i=t:i=i.next=t}else n=i=t;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:i,shared:a.shared,callbacks:a.callbacks},e.updateQueue=l;return}e=l.lastBaseUpdate,e===null?l.firstBaseUpdate=t:e.next=t,l.lastBaseUpdate=t}var Ns=!1;function Nn(){if(Ns){var e=Da;if(e!==null)throw e}}function En(e,t,l,a){Ns=!1;var n=e.updateQueue;Nl=!1;var i=n.firstBaseUpdate,c=n.lastBaseUpdate,d=n.shared.pending;if(d!==null){n.shared.pending=null;var v=d,R=v.next;v.next=null,c===null?i=R:c.next=R,c=v;var z=e.alternate;z!==null&&(z=z.updateQueue,d=z.lastBaseUpdate,d!==c&&(d===null?z.firstBaseUpdate=R:d.next=R,z.lastBaseUpdate=v))}if(i!==null){var U=n.baseState;c=0,z=R=v=null,d=i;do{var A=d.lane&-536870913,C=A!==d.lane;if(C?(Se&A)===A:(a&A)===A){A!==0&&A===za&&(Ns=!0),z!==null&&(z=z.next={lane:0,tag:d.tag,payload:d.payload,callback:null,next:null});e:{var $=e,ae=d;A=t;var Me=l;switch(ae.tag){case 1:if($=ae.payload,typeof $=="function"){U=$.call(Me,U,A);break e}U=$;break e;case 3:$.flags=$.flags&-65537|128;case 0:if($=ae.payload,A=typeof $=="function"?$.call(Me,U,A):$,A==null)break e;U=N({},U,A);break e;case 2:Nl=!0}}A=d.callback,A!==null&&(e.flags|=64,C&&(e.flags|=8192),C=n.callbacks,C===null?n.callbacks=[A]:C.push(A))}else C={lane:A,tag:d.tag,payload:d.payload,callback:d.callback,next:null},z===null?(R=z=C,v=U):z=z.next=C,c|=A;if(d=d.next,d===null){if(d=n.shared.pending,d===null)break;C=d,d=C.next,C.next=null,n.lastBaseUpdate=C,n.shared.pending=null}}while(!0);z===null&&(v=U),n.baseState=v,n.firstBaseUpdate=R,n.lastBaseUpdate=z,i===null&&(n.shared.lanes=0),zl|=c,e.lanes=c,e.memoizedState=U}}function qf(e,t){if(typeof e!="function")throw Error(f(191,e));e.call(t)}function Lf(e,t){var l=e.callbacks;if(l!==null)for(e.callbacks=null,e=0;ei?i:8;var c=E.T,d={};E.T=d,Xs(e,!1,t,l);try{var v=n(),R=E.S;if(R!==null&&R(d,v),v!==null&&typeof v=="object"&&typeof v.then=="function"){var z=Ap(v,a);An(e,t,z,Tt(e))}else An(e,t,a,Tt(e))}catch(U){An(e,t,{then:function(){},status:"rejected",reason:U},Tt())}finally{q.p=i,c!==null&&d.types!==null&&(c.types=d.types),E.T=c}}function wp(){}function Gs(e,t,l,a){if(e.tag!==5)throw Error(f(476));var n=yo(e).queue;vo(e,n,t,W,l===null?wp:function(){return go(e),l(a)})}function yo(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:W,baseState:W,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:W},next:null};var l={};return t.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:l},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function go(e){var t=yo(e);t.next===null&&(t=e.alternate.memoizedState),An(e,t.next.queue,{},Tt())}function Qs(){return nt(Zn)}function bo(){return Ze().memoizedState}function _o(){return Ze().memoizedState}function Up(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var l=Tt();e=El(l);var a=Tl(t,e,l);a!==null&&(vt(a,t,l),jn(a,t,l)),t={cache:ys()},e.payload=t;return}t=t.return}}function Hp(e,t,l){var a=Tt();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Yi(e)?So(t,l):(l=us(e,t,l,a),l!==null&&(vt(l,e,a),jo(l,t,a)))}function xo(e,t,l){var a=Tt();An(e,t,l,a)}function An(e,t,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Yi(e))So(t,n);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var c=t.lastRenderedState,d=i(c,l);if(n.hasEagerState=!0,n.eagerState=d,_t(d,c))return _i(e,t,n,0),Ue===null&&bi(),!1}catch{}if(l=us(e,t,n,a),l!==null)return vt(l,e,a),jo(l,t,a),!0}return!1}function Xs(e,t,l,a){if(a={lane:2,revertLane:xc(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Yi(e)){if(t)throw Error(f(479))}else t=us(e,l,a,2),t!==null&&vt(t,e,2)}function Yi(e){var t=e.alternate;return e===oe||t!==null&&t===oe}function So(e,t){Ha=Mi=!0;var l=e.pending;l===null?t.next=t:(t.next=l.next,l.next=t),e.pending=t}function jo(e,t,l){if((l&4194048)!==0){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Tr(e,l)}}var Cn={readContext:nt,use:Hi,useCallback:Qe,useContext:Qe,useEffect:Qe,useImperativeHandle:Qe,useLayoutEffect:Qe,useInsertionEffect:Qe,useMemo:Qe,useReducer:Qe,useRef:Qe,useState:Qe,useDebugValue:Qe,useDeferredValue:Qe,useTransition:Qe,useSyncExternalStore:Qe,useId:Qe,useHostTransitionStatus:Qe,useFormState:Qe,useActionState:Qe,useOptimistic:Qe,useMemoCache:Qe,useCacheRefresh:Qe};Cn.useEffectEvent=Qe;var No={readContext:nt,use:Hi,useCallback:function(e,t){return rt().memoizedState=[e,t===void 0?null:t],e},useContext:nt,useEffect:uo,useImperativeHandle:function(e,t,l){l=l!=null?l.concat([e]):null,Li(4194308,4,fo.bind(null,t,e),l)},useLayoutEffect:function(e,t){return Li(4194308,4,e,t)},useInsertionEffect:function(e,t){Li(4,2,e,t)},useMemo:function(e,t){var l=rt();t=t===void 0?null:t;var a=e();if(na){yl(!0);try{e()}finally{yl(!1)}}return l.memoizedState=[a,t],a},useReducer:function(e,t,l){var a=rt();if(l!==void 0){var n=l(t);if(na){yl(!0);try{l(t)}finally{yl(!1)}}}else n=t;return a.memoizedState=a.baseState=n,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},a.queue=e,e=e.dispatch=Hp.bind(null,oe,e),[a.memoizedState,e]},useRef:function(e){var t=rt();return e={current:e},t.memoizedState=e},useState:function(e){e=Hs(e);var t=e.queue,l=xo.bind(null,oe,t);return t.dispatch=l,[e.memoizedState,l]},useDebugValue:Bs,useDeferredValue:function(e,t){var l=rt();return Ys(l,e,t)},useTransition:function(){var e=Hs(!1);return e=vo.bind(null,oe,e.queue,!0,!1),rt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,l){var a=oe,n=rt();if(Ee){if(l===void 0)throw Error(f(407));l=l()}else{if(l=t(),Ue===null)throw Error(f(349));(Se&127)!==0||Vf(a,t,l)}n.memoizedState=l;var i={value:l,getSnapshot:t};return n.queue=i,uo(Kf.bind(null,a,i,e),[e]),a.flags|=2048,La(9,{destroy:void 0},Zf.bind(null,a,i,l,t),null),l},useId:function(){var e=rt(),t=Ue.identifierPrefix;if(Ee){var l=kt,a=Jt;l=(a&~(1<<32-bt(a)-1)).toString(32)+l,t="_"+t+"R_"+l,l=wi++,0<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof a.is=="string"?c.createElement("select",{is:a.is}):c.createElement("select"),a.multiple?i.multiple=!0:a.size&&(i.size=a.size);break;default:i=typeof a.is=="string"?c.createElement(n,{is:a.is}):c.createElement(n)}}i[lt]=t,i[ft]=a;e:for(c=t.child;c!==null;){if(c.tag===5||c.tag===6)i.appendChild(c.stateNode);else if(c.tag!==4&&c.tag!==27&&c.child!==null){c.child.return=c,c=c.child;continue}if(c===t)break e;for(;c.sibling===null;){if(c.return===null||c.return===t)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}t.stateNode=i;e:switch(ut(i,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&sl(t)}}return Be(t),ac(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,l),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==a&&sl(t);else{if(typeof a!="string"&&t.stateNode===null)throw Error(f(166));if(e=se.current,Ca(t)){if(e=t.stateNode,l=t.memoizedProps,a=null,n=at,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}e[lt]=t,e=!!(e.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||Xd(e.nodeValue,l)),e||Sl(t,!0)}else e=uu(e).createTextNode(a),e[lt]=t,t.stateNode=e}return Be(t),null;case 31:if(l=t.memoizedState,e===null||e.memoizedState!==null){if(a=Ca(t),l!==null){if(e===null){if(!a)throw Error(f(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(f(557));e[lt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),e=!1}else l=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=l),e=!0;if(!e)return t.flags&256?(jt(t),t):(jt(t),null);if((t.flags&128)!==0)throw Error(f(558))}return Be(t),null;case 13:if(a=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(n=Ca(t),a!==null&&a.dehydrated!==null){if(e===null){if(!n)throw Error(f(318));if(n=t.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(f(317));n[lt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),n=!1}else n=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),n=!0;if(!n)return t.flags&256?(jt(t),t):(jt(t),null)}return jt(t),(t.flags&128)!==0?(t.lanes=l,t):(l=a!==null,e=e!==null&&e.memoizedState!==null,l&&(a=t.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),i=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(i=a.memoizedState.cachePool.pool),i!==n&&(a.flags|=2048)),l!==e&&l&&(t.child.flags|=8192),Zi(t,t.updateQueue),Be(t),null);case 4:return qe(),e===null&&Ec(t.stateNode.containerInfo),Be(t),null;case 10:return al(t.type),Be(t),null;case 19:if(w(Ve),a=t.memoizedState,a===null)return Be(t),null;if(n=(t.flags&128)!==0,i=a.rendering,i===null)if(n)zn(a,!1);else{if(Xe!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(i=Di(e),i!==null){for(t.flags|=128,zn(a,!1),e=i.updateQueue,t.updateQueue=e,Zi(t,e),t.subtreeFlags=0,e=l,l=t.child;l!==null;)_f(l,e),l=l.sibling;return Y(Ve,Ve.current&1|2),Ee&&tl(t,a.treeForkCount),t.child}e=e.sibling}a.tail!==null&&yt()>Fi&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304)}else{if(!n)if(e=Di(i),e!==null){if(t.flags|=128,n=!0,e=e.updateQueue,t.updateQueue=e,Zi(t,e),zn(a,!0),a.tail===null&&a.tailMode==="hidden"&&!i.alternate&&!Ee)return Be(t),null}else 2*yt()-a.renderingStartTime>Fi&&l!==536870912&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304);a.isBackwards?(i.sibling=t.child,t.child=i):(e=a.last,e!==null?e.sibling=i:t.child=i,a.last=i)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=yt(),e.sibling=null,l=Ve.current,Y(Ve,n?l&1|2:l&1),Ee&&tl(t,a.treeForkCount),e):(Be(t),null);case 22:case 23:return jt(t),Ts(),a=t.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(t.flags|=8192):a&&(t.flags|=8192),a?(l&536870912)!==0&&(t.flags&128)===0&&(Be(t),t.subtreeFlags&6&&(t.flags|=8192)):Be(t),l=t.updateQueue,l!==null&&Zi(t,l.retryQueue),l=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),a=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),a!==l&&(t.flags|=2048),e!==null&&w(ea),null;case 24:return l=null,e!==null&&(l=e.memoizedState.cache),t.memoizedState.cache!==l&&(t.flags|=2048),al(Je),Be(t),null;case 25:return null;case 30:return null}throw Error(f(156,t.tag))}function Gp(e,t){switch(os(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return al(Je),qe(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return pe(t),null;case 31:if(t.memoizedState!==null){if(jt(t),t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(jt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return w(Ve),null;case 4:return qe(),null;case 10:return al(t.type),null;case 22:case 23:return jt(t),Ts(),e!==null&&w(ea),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return al(Je),null;case 25:return null;default:return null}}function ko(e,t){switch(os(t),t.tag){case 3:al(Je),qe();break;case 26:case 27:case 5:pe(t);break;case 4:qe();break;case 31:t.memoizedState!==null&&jt(t);break;case 13:jt(t);break;case 19:w(Ve);break;case 10:al(t.type);break;case 22:case 23:jt(t),Ts(),e!==null&&w(ea);break;case 24:al(Je)}}function Dn(e,t){try{var l=t.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&e)===e){a=void 0;var i=l.create,c=l.inst;a=i(),c.destroy=a}l=l.next}while(l!==n)}}catch(d){Oe(t,t.return,d)}}function Cl(e,t,l){try{var a=t.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var i=n.next;a=i;do{if((a.tag&e)===e){var c=a.inst,d=c.destroy;if(d!==void 0){c.destroy=void 0,n=t;var v=l,R=d;try{R()}catch(z){Oe(n,v,z)}}}a=a.next}while(a!==i)}}catch(z){Oe(t,t.return,z)}}function $o(e){var t=e.updateQueue;if(t!==null){var l=e.stateNode;try{Lf(t,l)}catch(a){Oe(e,e.return,a)}}}function Fo(e,t,l){l.props=ia(e.type,e.memoizedProps),l.state=e.memoizedState;try{l.componentWillUnmount()}catch(a){Oe(e,t,a)}}function Mn(e,t){try{var l=e.ref;if(l!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof l=="function"?e.refCleanup=l(a):l.current=a}}catch(n){Oe(e,t,n)}}function $t(e,t){var l=e.ref,a=e.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){Oe(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){Oe(e,t,n)}else l.current=null}function Wo(e){var t=e.type,l=e.memoizedProps,a=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":l.autoFocus&&a.focus();break e;case"img":l.src?a.src=l.src:l.srcSet&&(a.srcset=l.srcSet)}}catch(n){Oe(e,e.return,n)}}function nc(e,t,l){try{var a=e.stateNode;rv(a,e.type,l,t),a[ft]=t}catch(n){Oe(e,e.return,n)}}function Io(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Hl(e.type)||e.tag===4}function ic(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Io(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&&Hl(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function uc(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(e,t):(t=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,t.appendChild(e),l=l._reactRootContainer,l!=null||t.onclick!==null||(t.onclick=It));else if(a!==4&&(a===27&&Hl(e.type)&&(l=e.stateNode,t=null),e=e.child,e!==null))for(uc(e,t,l),e=e.sibling;e!==null;)uc(e,t,l),e=e.sibling}function Ki(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?l.insertBefore(e,t):l.appendChild(e);else if(a!==4&&(a===27&&Hl(e.type)&&(l=e.stateNode),e=e.child,e!==null))for(Ki(e,t,l),e=e.sibling;e!==null;)Ki(e,t,l),e=e.sibling}function Po(e){var t=e.stateNode,l=e.memoizedProps;try{for(var a=e.type,n=t.attributes;n.length;)t.removeAttributeNode(n[0]);ut(t,a,l),t[lt]=e,t[ft]=l}catch(i){Oe(e,e.return,i)}}var cl=!1,Fe=!1,sc=!1,ed=typeof WeakSet=="function"?WeakSet:Set,tt=null;function Qp(e,t){if(e=e.containerInfo,Ac=mu,e=of(e),es(e)){if("selectionStart"in e)var l={start:e.selectionStart,end:e.selectionEnd};else e:{l=(l=e.ownerDocument)&&l.defaultView||window;var a=l.getSelection&&l.getSelection();if(a&&a.rangeCount!==0){l=a.anchorNode;var n=a.anchorOffset,i=a.focusNode;a=a.focusOffset;try{l.nodeType,i.nodeType}catch{l=null;break e}var c=0,d=-1,v=-1,R=0,z=0,U=e,A=null;t:for(;;){for(var C;U!==l||n!==0&&U.nodeType!==3||(d=c+n),U!==i||a!==0&&U.nodeType!==3||(v=c+a),U.nodeType===3&&(c+=U.nodeValue.length),(C=U.firstChild)!==null;)A=U,U=C;for(;;){if(U===e)break t;if(A===l&&++R===n&&(d=c),A===i&&++z===a&&(v=c),(C=U.nextSibling)!==null)break;U=A,A=U.parentNode}U=C}l=d===-1||v===-1?null:{start:d,end:v}}else l=null}l=l||{start:0,end:0}}else l=null;for(Cc={focusedElem:e,selectionRange:l},mu=!1,tt=t;tt!==null;)if(t=tt,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,tt=e;else for(;tt!==null;){switch(t=tt,i=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(l=0;l title"))),ut(i,a,l),i[lt]=e,et(i),a=i;break e;case"link":var c=um("link","href",n).get(a+(l.href||""));if(c){for(var d=0;dMe&&(c=Me,Me=ae,ae=c);var S=rf(d,ae),_=rf(d,Me);if(S&&_&&(C.rangeCount!==1||C.anchorNode!==S.node||C.anchorOffset!==S.offset||C.focusNode!==_.node||C.focusOffset!==_.offset)){var T=U.createRange();T.setStart(S.node,S.offset),C.removeAllRanges(),ae>Me?(C.addRange(T),C.extend(_.node,_.offset)):(T.setEnd(_.node,_.offset),C.addRange(T))}}}}for(U=[],C=d;C=C.parentNode;)C.nodeType===1&&U.push({element:C,left:C.scrollLeft,top:C.scrollTop});for(typeof d.focus=="function"&&d.focus(),d=0;dl?32:l,E.T=null,l=hc,hc=null;var i=Ml,c=ml;if(We=0,Xa=Ml=null,ml=0,(Ae&6)!==0)throw Error(f(331));var d=Ae;if(Ae|=4,od(i.current),cd(i,i.current,c,l),Ae=d,Bn(0,!1),gt&&typeof gt.onPostCommitFiberRoot=="function")try{gt.onPostCommitFiberRoot(ln,i)}catch{}return!0}finally{q.p=n,E.T=a,Cd(e,t)}}function zd(e,t,l){t=Mt(l,t),t=Js(e.stateNode,t,2),e=Tl(e,t,2),e!==null&&(nn(e,2),Ft(e))}function Oe(e,t,l){if(e.tag===3)zd(e,e,l);else for(;t!==null;){if(t.tag===3){zd(t,e,l);break}else if(t.tag===1){var a=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(Dl===null||!Dl.has(a))){e=Mt(l,e),l=Do(2),a=Tl(t,l,2),a!==null&&(Mo(l,a,t,e),nn(a,2),Ft(a));break}}t=t.return}}function gc(e,t,l){var a=e.pingCache;if(a===null){a=e.pingCache=new Zp;var n=new Set;a.set(t,n)}else n=a.get(t),n===void 0&&(n=new Set,a.set(t,n));n.has(l)||(fc=!0,n.add(l),e=Fp.bind(null,e,t,l),t.then(e,e))}function Fp(e,t,l){var a=e.pingCache;a!==null&&a.delete(t),e.pingedLanes|=e.suspendedLanes&l,e.warmLanes&=~l,Ue===e&&(Se&l)===l&&(Xe===4||Xe===3&&(Se&62914560)===Se&&300>yt()-$i?(Ae&2)===0&&Va(e,0):oc|=l,Qa===Se&&(Qa=0)),Ft(e)}function Dd(e,t){t===0&&(t=Nr()),e=$l(e,t),e!==null&&(nn(e,t),Ft(e))}function Wp(e){var t=e.memoizedState,l=0;t!==null&&(l=t.retryLane),Dd(e,l)}function Ip(e,t){var l=0;switch(e.tag){case 31:case 13:var a=e.stateNode,n=e.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(f(314))}a!==null&&a.delete(t),Dd(e,l)}function Pp(e,t){return zu(e,t)}var lu=null,Ka=null,bc=!1,au=!1,_c=!1,Ul=0;function Ft(e){e!==Ka&&e.next===null&&(Ka===null?lu=Ka=e:Ka=Ka.next=e),au=!0,bc||(bc=!0,tv())}function Bn(e,t){if(!_c&&au){_c=!0;do for(var l=!1,a=lu;a!==null;){if(e!==0){var n=a.pendingLanes;if(n===0)var i=0;else{var c=a.suspendedLanes,d=a.pingedLanes;i=(1<<31-bt(42|e)+1)-1,i&=n&~(c&~d),i=i&201326741?i&201326741|1:i?i|2:0}i!==0&&(l=!0,Hd(a,i))}else i=Se,i=si(a,a===Ue?i:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(i&3)===0||an(a,i)||(l=!0,Hd(a,i));a=a.next}while(l);_c=!1}}function ev(){Md()}function Md(){au=bc=!1;var e=0;Ul!==0&&ov()&&(e=Ul);for(var t=yt(),l=null,a=lu;a!==null;){var n=a.next,i=wd(a,t);i===0?(a.next=null,l===null?lu=n:l.next=n,n===null&&(Ka=l)):(l=a,(e!==0||(i&3)!==0)&&(au=!0)),a=n}We!==0&&We!==5||Bn(e),Ul!==0&&(Ul=0)}function wd(e,t){for(var l=e.suspendedLanes,a=e.pingedLanes,n=e.expirationTimes,i=e.pendingLanes&-62914561;0d)break;var z=v.transferSize,U=v.initiatorType;z&&Vd(U)&&(v=v.responseEnd,c+=z*(v"u"?null:document;function lm(e,t,l){var a=Ja;if(a&&typeof t=="string"&&t){var n=zt(t);n='link[rel="'+e+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),tm.has(n)||(tm.add(n),e={rel:e,crossOrigin:l,href:t},a.querySelector(n)===null&&(t=a.createElement("link"),ut(t,"link",e),et(t),a.head.appendChild(t)))}}function _v(e){hl.D(e),lm("dns-prefetch",e,null)}function xv(e,t){hl.C(e,t),lm("preconnect",e,t)}function Sv(e,t,l){hl.L(e,t,l);var a=Ja;if(a&&e&&t){var n='link[rel="preload"][as="'+zt(t)+'"]';t==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+zt(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+zt(l.imageSizes)+'"]')):n+='[href="'+zt(e)+'"]';var i=n;switch(t){case"style":i=ka(e);break;case"script":i=$a(e)}Bt.has(i)||(e=N({rel:"preload",href:t==="image"&&l&&l.imageSrcSet?void 0:e,as:t},l),Bt.set(i,e),a.querySelector(n)!==null||t==="style"&&a.querySelector(Xn(i))||t==="script"&&a.querySelector(Vn(i))||(t=a.createElement("link"),ut(t,"link",e),et(t),a.head.appendChild(t)))}}function jv(e,t){hl.m(e,t);var l=Ja;if(l&&e){var a=t&&typeof t.as=="string"?t.as:"script",n='link[rel="modulepreload"][as="'+zt(a)+'"][href="'+zt(e)+'"]',i=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":i=$a(e)}if(!Bt.has(i)&&(e=N({rel:"modulepreload",href:e},t),Bt.set(i,e),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(Vn(i)))return}a=l.createElement("link"),ut(a,"link",e),et(a),l.head.appendChild(a)}}}function Nv(e,t,l){hl.S(e,t,l);var a=Ja;if(a&&e){var n=va(a).hoistableStyles,i=ka(e);t=t||"default";var c=n.get(i);if(!c){var d={loading:0,preload:null};if(c=a.querySelector(Xn(i)))d.loading=5;else{e=N({rel:"stylesheet",href:e,"data-precedence":t},l),(l=Bt.get(i))&&Hc(e,l);var v=c=a.createElement("link");et(v),ut(v,"link",e),v._p=new Promise(function(R,z){v.onload=R,v.onerror=z}),v.addEventListener("load",function(){d.loading|=1}),v.addEventListener("error",function(){d.loading|=2}),d.loading|=4,cu(c,t,a)}c={type:"stylesheet",instance:c,count:1,state:d},n.set(i,c)}}}function Ev(e,t){hl.X(e,t);var l=Ja;if(l&&e){var a=va(l).hoistableScripts,n=$a(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),et(i),ut(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function Tv(e,t){hl.M(e,t);var l=Ja;if(l&&e){var a=va(l).hoistableScripts,n=$a(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0,type:"module"},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),et(i),ut(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function am(e,t,l,a){var n=(n=se.current)?su(n):null;if(!n)throw Error(f(446));switch(e){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(t=ka(l.href),l=va(n).hoistableStyles,a=l.get(t),a||(a={type:"style",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){e=ka(l.href);var i=va(n).hoistableStyles,c=i.get(e);if(c||(n=n.ownerDocument||n,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},i.set(e,c),(i=n.querySelector(Xn(e)))&&!i._p&&(c.instance=i,c.state.loading=5),Bt.has(e)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Bt.set(e,l),i||Rv(n,e,l,c.state))),t&&a===null)throw Error(f(528,""));return c}if(t&&a!==null)throw Error(f(529,""));return null;case"script":return t=l.async,l=l.src,typeof l=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=$a(l),l=va(n).hoistableScripts,a=l.get(t),a||(a={type:"script",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(f(444,e))}}function ka(e){return'href="'+zt(e)+'"'}function Xn(e){return'link[rel="stylesheet"]['+e+"]"}function nm(e){return N({},e,{"data-precedence":e.precedence,precedence:null})}function Rv(e,t,l,a){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?a.loading=1:(t=e.createElement("link"),a.preload=t,t.addEventListener("load",function(){return a.loading|=1}),t.addEventListener("error",function(){return a.loading|=2}),ut(t,"link",l),et(t),e.head.appendChild(t))}function $a(e){return'[src="'+zt(e)+'"]'}function Vn(e){return"script[async]"+e}function im(e,t,l){if(t.count++,t.instance===null)switch(t.type){case"style":var a=e.querySelector('style[data-href~="'+zt(l.href)+'"]');if(a)return t.instance=a,et(a),a;var n=N({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),et(a),ut(a,"style",n),cu(a,l.precedence,e),t.instance=a;case"stylesheet":n=ka(l.href);var i=e.querySelector(Xn(n));if(i)return t.state.loading|=4,t.instance=i,et(i),i;a=nm(l),(n=Bt.get(n))&&Hc(a,n),i=(e.ownerDocument||e).createElement("link"),et(i);var c=i;return c._p=new Promise(function(d,v){c.onload=d,c.onerror=v}),ut(i,"link",a),t.state.loading|=4,cu(i,l.precedence,e),t.instance=i;case"script":return i=$a(l.src),(n=e.querySelector(Vn(i)))?(t.instance=n,et(n),n):(a=l,(n=Bt.get(i))&&(a=N({},l),qc(a,n)),e=e.ownerDocument||e,n=e.createElement("script"),et(n),ut(n,"link",a),e.head.appendChild(n),t.instance=n);case"void":return null;default:throw Error(f(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(a=t.instance,t.state.loading|=4,cu(a,l.precedence,e));return t.instance}function cu(e,t,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,i=n,c=0;c title"):null)}function Av(e,t,l){if(l===1||t.itemProp!=null)return!1;switch(e){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;return t.rel==="stylesheet"?(e=t.disabled,typeof t.precedence=="string"&&e==null):!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 cm(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function Cv(e,t,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=ka(a.href),i=t.querySelector(Xn(n));if(i){t=i._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=fu.bind(e),t.then(e,e)),l.state.loading|=4,l.instance=i,et(i);return}i=t.ownerDocument||t,a=nm(a),(n=Bt.get(n))&&Hc(a,n),i=i.createElement("link"),et(i);var c=i;c._p=new Promise(function(d,v){c.onload=d,c.onerror=v}),ut(i,"link",a),l.instance=i}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(l,t),(t=l.state.preload)&&(l.state.loading&3)===0&&(e.count++,l=fu.bind(e),t.addEventListener("load",l),t.addEventListener("error",l))}}var Lc=0;function Ov(e,t){return e.stylesheets&&e.count===0&&du(e,e.stylesheets),0Lc?50:800)+t);return e.unsuspend=l,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function fu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)du(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ou=null;function du(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ou=new Map,t.forEach(zv,e),ou=null,fu.call(e))}function zv(e,t){if(!(t.state.loading&4)){var l=ou.get(e);if(l)var a=l.get(null);else{l=new Map,ou.set(e,l);for(var n=e.querySelectorAll("link[data-precedence],style[data-precedence]"),i=0;i"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Jc.exports=Jv(),Jc.exports}var $v=kv();var Dm="popstate";function Mm(s){return typeof s=="object"&&s!=null&&"pathname"in s&&"search"in s&&"hash"in s&&"state"in s&&"key"in s}function Fv(s={}){function r(m,h){let{pathname:b="/",search:j="",hash:x=""}=oa(m.location.hash.substring(1));return!b.startsWith("/")&&!b.startsWith(".")&&(b="/"+b),ar("",{pathname:b,search:j,hash:x},h.state&&h.state.usr||null,h.state&&h.state.key||"default")}function o(m,h){let b=m.document.querySelector("base"),j="";if(b&&b.getAttribute("href")){let x=m.location.href,y=x.indexOf("#");j=y===-1?x:x.slice(0,y)}return j+"#"+(typeof h=="string"?h:ei(h))}function f(m,h){Rt(m.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(h)})`)}return Iv(r,o,f,s)}function Ge(s,r){if(s===!1||s===null||typeof s>"u")throw new Error(r)}function Rt(s,r){if(!s){typeof console<"u"&&console.warn(r);try{throw new Error(r)}catch{}}}function Wv(){return Math.random().toString(36).substring(2,10)}function wm(s,r){return{usr:s.state,key:s.key,idx:r,masked:s.unstable_mask?{pathname:s.pathname,search:s.search,hash:s.hash}:void 0}}function ar(s,r,o=null,f,m){return{pathname:typeof s=="string"?s:s.pathname,search:"",hash:"",...typeof r=="string"?oa(r):r,state:o,key:r&&r.key||f||Wv(),unstable_mask:m}}function ei({pathname:s="/",search:r="",hash:o=""}){return r&&r!=="?"&&(s+=r.charAt(0)==="?"?r:"?"+r),o&&o!=="#"&&(s+=o.charAt(0)==="#"?o:"#"+o),s}function oa(s){let r={};if(s){let o=s.indexOf("#");o>=0&&(r.hash=s.substring(o),s=s.substring(0,o));let f=s.indexOf("?");f>=0&&(r.search=s.substring(f),s=s.substring(0,f)),s&&(r.pathname=s)}return r}function Iv(s,r,o,f={}){let{window:m=document.defaultView,v5Compat:h=!1}=f,b=m.history,j="POP",x=null,y=O();y==null&&(y=0,b.replaceState({...b.state,idx:y},""));function O(){return(b.state||{idx:null}).idx}function N(){j="POP";let H=O(),Z=H==null?null:H-y;y=H,x&&x({action:j,location:Q.location,delta:Z})}function L(H,Z){j="PUSH";let ee=Mm(H)?H:ar(Q.location,H,Z);o&&o(ee,H),y=O()+1;let I=wm(ee,y),ye=Q.createHref(ee.unstable_mask||ee);try{b.pushState(I,"",ye)}catch(re){if(re instanceof DOMException&&re.name==="DataCloneError")throw re;m.location.assign(ye)}h&&x&&x({action:j,location:Q.location,delta:1})}function G(H,Z){j="REPLACE";let ee=Mm(H)?H:ar(Q.location,H,Z);o&&o(ee,H),y=O();let I=wm(ee,y),ye=Q.createHref(ee.unstable_mask||ee);b.replaceState(I,"",ye),h&&x&&x({action:j,location:Q.location,delta:0})}function J(H){return Pv(H)}let Q={get action(){return j},get location(){return s(m,b)},listen(H){if(x)throw new Error("A history only accepts one active listener");return m.addEventListener(Dm,N),x=H,()=>{m.removeEventListener(Dm,N),x=null}},createHref(H){return r(m,H)},createURL:J,encodeLocation(H){let Z=J(H);return{pathname:Z.pathname,search:Z.search,hash:Z.hash}},push:L,replace:G,go(H){return b.go(H)}};return Q}function Pv(s,r=!1){let o="http://localhost";typeof window<"u"&&(o=window.location.origin!=="null"?window.location.origin:window.location.href),Ge(o,"No window.location.(origin|href) available to create URL");let f=typeof s=="string"?s:ei(s);return f=f.replace(/ $/,"%20"),!r&&f.startsWith("//")&&(f=o+f),new URL(f,o)}function Xm(s,r,o="/"){return ey(s,r,o,!1)}function ey(s,r,o,f){let m=typeof r=="string"?oa(r):r,h=vl(m.pathname||"/",o);if(h==null)return null;let b=Vm(s);ty(b);let j=null;for(let x=0;j==null&&x{let O={relativePath:y===void 0?b.path||"":y,caseSensitive:b.caseSensitive===!0,childrenIndex:j,route:b};if(O.relativePath.startsWith("/")){if(!O.relativePath.startsWith(f)&&x)return;Ge(O.relativePath.startsWith(f),`Absolute route path "${O.relativePath}" nested under path "${f}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),O.relativePath=O.relativePath.slice(f.length)}let N=Vt([f,O.relativePath]),L=o.concat(O);b.children&&b.children.length>0&&(Ge(b.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${N}".`),Vm(b.children,r,L,N,x)),!(b.path==null&&!b.index)&&r.push({path:N,score:cy(N,b.index),routesMeta:L})};return s.forEach((b,j)=>{if(b.path===""||!b.path?.includes("?"))h(b,j);else for(let x of Zm(b.path))h(b,j,!0,x)}),r}function Zm(s){let r=s.split("/");if(r.length===0)return[];let[o,...f]=r,m=o.endsWith("?"),h=o.replace(/\?$/,"");if(f.length===0)return m?[h,""]:[h];let b=Zm(f.join("/")),j=[];return j.push(...b.map(x=>x===""?h:[h,x].join("/"))),m&&j.push(...b),j.map(x=>s.startsWith("/")&&x===""?"/":x)}function ty(s){s.sort((r,o)=>r.score!==o.score?o.score-r.score:ry(r.routesMeta.map(f=>f.childrenIndex),o.routesMeta.map(f=>f.childrenIndex)))}var ly=/^:[\w-]+$/,ay=3,ny=2,iy=1,uy=10,sy=-2,Um=s=>s==="*";function cy(s,r){let o=s.split("/"),f=o.length;return o.some(Um)&&(f+=sy),r&&(f+=ny),o.filter(m=>!Um(m)).reduce((m,h)=>m+(ly.test(h)?ay:h===""?iy:uy),f)}function ry(s,r){return s.length===r.length&&s.slice(0,-1).every((f,m)=>f===r[m])?s[s.length-1]-r[r.length-1]:0}function fy(s,r,o=!1){let{routesMeta:f}=s,m={},h="/",b=[];for(let j=0;j{if(O==="*"){let J=j[L]||"";b=h.slice(0,h.length-J.length).replace(/(.)\/+$/,"$1")}const G=j[L];return N&&!G?y[O]=void 0:y[O]=(G||"").replace(/%2F/g,"/"),y},{}),pathname:h,pathnameBase:b,pattern:s}}function oy(s,r=!1,o=!0){Rt(s==="*"||!s.endsWith("*")||s.endsWith("/*"),`Route path "${s}" will be treated as if it were "${s.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${s.replace(/\*$/,"/*")}".`);let f=[],m="^"+s.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(b,j,x,y,O)=>{if(f.push({paramName:j,isOptional:x!=null}),x){let N=O.charAt(y+b.length);return N&&N!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return s.endsWith("*")?(f.push({paramName:"*"}),m+=s==="*"||s==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):o?m+="\\/*$":s!==""&&s!=="/"&&(m+="(?:(?=\\/|$))"),[new RegExp(m,r?void 0:"i"),f]}function dy(s){try{return s.split("/").map(r=>decodeURIComponent(r).replace(/\//g,"%2F")).join("/")}catch(r){return Rt(!1,`The URL path "${s}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${r}).`),s}}function vl(s,r){if(r==="/")return s;if(!s.toLowerCase().startsWith(r.toLowerCase()))return null;let o=r.endsWith("/")?r.length-1:r.length,f=s.charAt(o);return f&&f!=="/"?null:s.slice(o)||"/"}var my=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function hy(s,r="/"){let{pathname:o,search:f="",hash:m=""}=typeof s=="string"?oa(s):s,h;return o?(o=Km(o),o.startsWith("/")?h=Hm(o.substring(1),"/"):h=Hm(o,r)):h=r,{pathname:h,search:yy(f),hash:gy(m)}}function Hm(s,r){let o=Tu(r).split("/");return s.split("/").forEach(m=>{m===".."?o.length>1&&o.pop():m!=="."&&o.push(m)}),o.length>1?o.join("/"):"/"}function Wc(s,r,o,f){return`Cannot include a '${s}' character in a manually specified \`to.${r}\` field [${JSON.stringify(f)}]. Please separate it out to the \`to.${o}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function py(s){return s.filter((r,o)=>o===0||r.route.path&&r.route.path.length>0)}function fr(s){let r=py(s);return r.map((o,f)=>f===r.length-1?o.pathname:o.pathnameBase)}function Ru(s,r,o,f=!1){let m;typeof s=="string"?m=oa(s):(m={...s},Ge(!m.pathname||!m.pathname.includes("?"),Wc("?","pathname","search",m)),Ge(!m.pathname||!m.pathname.includes("#"),Wc("#","pathname","hash",m)),Ge(!m.search||!m.search.includes("#"),Wc("#","search","hash",m)));let h=s===""||m.pathname==="",b=h?"/":m.pathname,j;if(b==null)j=o;else{let N=r.length-1;if(!f&&b.startsWith("..")){let L=b.split("/");for(;L[0]==="..";)L.shift(),N-=1;m.pathname=L.join("/")}j=N>=0?r[N]:"/"}let x=hy(m,j),y=b&&b!=="/"&&b.endsWith("/"),O=(h||b===".")&&o.endsWith("/");return!x.pathname.endsWith("/")&&(y||O)&&(x.pathname+="/"),x}var Km=s=>s.replace(/\/\/+/g,"/"),Vt=s=>Km(s.join("/")),Tu=s=>s.replace(/\/+$/,""),vy=s=>Tu(s).replace(/^\/*/,"/"),yy=s=>!s||s==="?"?"":s.startsWith("?")?s:"?"+s,gy=s=>!s||s==="#"?"":s.startsWith("#")?s:"#"+s,by=class{constructor(s,r,o,f=!1){this.status=s,this.statusText=r||"",this.internal=f,o instanceof Error?(this.data=o.toString(),this.error=o):this.data=o}};function _y(s){return s!=null&&typeof s.status=="number"&&typeof s.statusText=="string"&&typeof s.internal=="boolean"&&"data"in s}function xy(s){let r=s.map(o=>o.route.path).filter(Boolean);return Vt(r)||"/"}var Jm=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function km(s,r){let o=s;if(typeof o!="string"||!my.test(o))return{absoluteURL:void 0,isExternal:!1,to:o};let f=o,m=!1;if(Jm)try{let h=new URL(window.location.href),b=o.startsWith("//")?new URL(h.protocol+o):new URL(o),j=vl(b.pathname,r);b.origin===h.origin&&j!=null?o=j+b.search+b.hash:m=!0}catch{Rt(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:f,isExternal:m,to:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var $m=["POST","PUT","PATCH","DELETE"];new Set($m);var Sy=["GET",...$m];new Set(Sy);var Pa=p.createContext(null);Pa.displayName="DataRouter";var Au=p.createContext(null);Au.displayName="DataRouterState";var Fm=p.createContext(!1);function jy(){return p.useContext(Fm)}var Wm=p.createContext({isTransitioning:!1});Wm.displayName="ViewTransition";var Ny=p.createContext(new Map);Ny.displayName="Fetchers";var Ey=p.createContext(null);Ey.displayName="Await";var At=p.createContext(null);At.displayName="Navigation";var ti=p.createContext(null);ti.displayName="Location";var Zt=p.createContext({outlet:null,matches:[],isDataRoute:!1});Zt.displayName="Route";var or=p.createContext(null);or.displayName="RouteError";var Im="REACT_ROUTER_ERROR",Ty="REDIRECT",Ry="ROUTE_ERROR_RESPONSE";function Ay(s){if(s.startsWith(`${Im}:${Ty}:{`))try{let r=JSON.parse(s.slice(28));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string"&&typeof r.location=="string"&&typeof r.reloadDocument=="boolean"&&typeof r.replace=="boolean")return r}catch{}}function Cy(s){if(s.startsWith(`${Im}:${Ry}:{`))try{let r=JSON.parse(s.slice(40));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string")return new by(r.status,r.statusText,r.data)}catch{}}function Oy(s,{relative:r}={}){Ge(en(),"useHref() may be used only in the context of a component.");let{basename:o,navigator:f}=p.useContext(At),{hash:m,pathname:h,search:b}=li(s,{relative:r}),j=h;return o!=="/"&&(j=h==="/"?o:Vt([o,h])),f.createHref({pathname:j,search:b,hash:m})}function en(){return p.useContext(ti)!=null}function Kt(){return Ge(en(),"useLocation() may be used only in the context of a component."),p.useContext(ti).location}var Pm="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function eh(s){p.useContext(At).static||p.useLayoutEffect(s)}function dr(){let{isDataRoute:s}=p.useContext(Zt);return s?Zy():zy()}function zy(){Ge(en(),"useNavigate() may be used only in the context of a component.");let s=p.useContext(Pa),{basename:r,navigator:o}=p.useContext(At),{matches:f}=p.useContext(Zt),{pathname:m}=Kt(),h=JSON.stringify(fr(f)),b=p.useRef(!1);return eh(()=>{b.current=!0}),p.useCallback((x,y={})=>{if(Rt(b.current,Pm),!b.current)return;if(typeof x=="number"){o.go(x);return}let O=Ru(x,JSON.parse(h),m,y.relative==="path");s==null&&r!=="/"&&(O.pathname=O.pathname==="/"?r:Vt([r,O.pathname])),(y.replace?o.replace:o.push)(O,y.state,y)},[r,o,h,m,s])}var Dy=p.createContext(null);function My(s){let r=p.useContext(Zt).outlet;return p.useMemo(()=>r&&p.createElement(Dy.Provider,{value:s},r),[r,s])}function li(s,{relative:r}={}){let{matches:o}=p.useContext(Zt),{pathname:f}=Kt(),m=JSON.stringify(fr(o));return p.useMemo(()=>Ru(s,JSON.parse(m),f,r==="path"),[s,m,f,r])}function wy(s,r){return th(s,r)}function th(s,r,o){Ge(en(),"useRoutes() may be used only in the context of a component.");let{navigator:f}=p.useContext(At),{matches:m}=p.useContext(Zt),h=m[m.length-1],b=h?h.params:{},j=h?h.pathname:"/",x=h?h.pathnameBase:"/",y=h&&h.route;{let H=y&&y.path||"";ah(j,!y||H.endsWith("*")||H.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${j}" (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 O=Kt(),N;if(r){let H=typeof r=="string"?oa(r):r;Ge(x==="/"||H.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 "${H.pathname}" was given in the \`location\` prop.`),N=H}else N=O;let L=N.pathname||"/",G=L;if(x!=="/"){let H=x.replace(/^\//,"").split("/");G="/"+L.replace(/^\//,"").split("/").slice(H.length).join("/")}let J=Xm(s,{pathname:G});Rt(y||J!=null,`No routes matched location "${N.pathname}${N.search}${N.hash}" `),Rt(J==null||J[J.length-1].route.element!==void 0||J[J.length-1].route.Component!==void 0||J[J.length-1].route.lazy!==void 0,`Matched leaf route at location "${N.pathname}${N.search}${N.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 Q=By(J&&J.map(H=>Object.assign({},H,{params:Object.assign({},b,H.params),pathname:Vt([x,f.encodeLocation?f.encodeLocation(H.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathname]),pathnameBase:H.pathnameBase==="/"?x:Vt([x,f.encodeLocation?f.encodeLocation(H.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathnameBase])})),m,o);return r&&Q?p.createElement(ti.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...N},navigationType:"POP"}},Q):Q}function Uy(){let s=Vy(),r=_y(s)?`${s.status} ${s.statusText}`:s instanceof Error?s.message:JSON.stringify(s),o=s instanceof Error?s.stack:null,f="rgba(200,200,200, 0.5)",m={padding:"0.5rem",backgroundColor:f},h={padding:"2px 4px",backgroundColor:f},b=null;return console.error("Error handled by React Router default ErrorBoundary:",s),b=p.createElement(p.Fragment,null,p.createElement("p",null,"💿 Hey developer 👋"),p.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",p.createElement("code",{style:h},"ErrorBoundary")," or"," ",p.createElement("code",{style:h},"errorElement")," prop on your route.")),p.createElement(p.Fragment,null,p.createElement("h2",null,"Unexpected Application Error!"),p.createElement("h3",{style:{fontStyle:"italic"}},r),o?p.createElement("pre",{style:m},o):null,b)}var Hy=p.createElement(Uy,null),lh=class extends p.Component{constructor(s){super(s),this.state={location:s.location,revalidation:s.revalidation,error:s.error}}static getDerivedStateFromError(s){return{error:s}}static getDerivedStateFromProps(s,r){return r.location!==s.location||r.revalidation!=="idle"&&s.revalidation==="idle"?{error:s.error,location:s.location,revalidation:s.revalidation}:{error:s.error!==void 0?s.error:r.error,location:r.location,revalidation:s.revalidation||r.revalidation}}componentDidCatch(s,r){this.props.onError?this.props.onError(s,r):console.error("React Router caught the following error during render",s)}render(){let s=this.state.error;if(this.context&&typeof s=="object"&&s&&"digest"in s&&typeof s.digest=="string"){const o=Cy(s.digest);o&&(s=o)}let r=s!==void 0?p.createElement(Zt.Provider,{value:this.props.routeContext},p.createElement(or.Provider,{value:s,children:this.props.component})):this.props.children;return this.context?p.createElement(qy,{error:s},r):r}};lh.contextType=Fm;var Ic=new WeakMap;function qy({children:s,error:r}){let{basename:o}=p.useContext(At);if(typeof r=="object"&&r&&"digest"in r&&typeof r.digest=="string"){let f=Ay(r.digest);if(f){let m=Ic.get(r);if(m)throw m;let h=km(f.location,o);if(Jm&&!Ic.get(r))if(h.isExternal||f.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const b=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:f.replace}));throw Ic.set(r,b),b}return p.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return s}function Ly({routeContext:s,match:r,children:o}){let f=p.useContext(Pa);return f&&f.static&&f.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(f.staticContext._deepestRenderedBoundaryId=r.route.id),p.createElement(Zt.Provider,{value:s},o)}function By(s,r=[],o){let f=o?.state;if(s==null){if(!f)return null;if(f.errors)s=f.matches;else if(r.length===0&&!f.initialized&&f.matches.length>0)s=f.matches;else return null}let m=s,h=f?.errors;if(h!=null){let O=m.findIndex(N=>N.route.id&&h?.[N.route.id]!==void 0);Ge(O>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(h).join(",")}`),m=m.slice(0,Math.min(m.length,O+1))}let b=!1,j=-1;if(o&&f){b=f.renderFallback;for(let O=0;O=0?m=m.slice(0,j+1):m=[m[0]];break}}}}let x=o?.onError,y=f&&x?(O,N)=>{x(O,{location:f.location,params:f.matches?.[0]?.params??{},unstable_pattern:xy(f.matches),errorInfo:N})}:void 0;return m.reduceRight((O,N,L)=>{let G,J=!1,Q=null,H=null;f&&(G=h&&N.route.id?h[N.route.id]:void 0,Q=N.route.errorElement||Hy,b&&(j<0&&L===0?(ah("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),J=!0,H=null):j===L&&(J=!0,H=N.route.hydrateFallbackElement||null)));let Z=r.concat(m.slice(0,L+1)),ee=()=>{let I;return G?I=Q:J?I=H:N.route.Component?I=p.createElement(N.route.Component,null):N.route.element?I=N.route.element:I=O,p.createElement(Ly,{match:N,routeContext:{outlet:O,matches:Z,isDataRoute:f!=null},children:I})};return f&&(N.route.ErrorBoundary||N.route.errorElement||L===0)?p.createElement(lh,{location:f.location,revalidation:f.revalidation,component:Q,error:G,children:ee(),routeContext:{outlet:null,matches:Z,isDataRoute:!0},onError:y}):ee()},null)}function mr(s){return`${s} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Yy(s){let r=p.useContext(Pa);return Ge(r,mr(s)),r}function Gy(s){let r=p.useContext(Au);return Ge(r,mr(s)),r}function Qy(s){let r=p.useContext(Zt);return Ge(r,mr(s)),r}function hr(s){let r=Qy(s),o=r.matches[r.matches.length-1];return Ge(o.route.id,`${s} can only be used on routes that contain a unique "id"`),o.route.id}function Xy(){return hr("useRouteId")}function Vy(){let s=p.useContext(or),r=Gy("useRouteError"),o=hr("useRouteError");return s!==void 0?s:r.errors?.[o]}function Zy(){let{router:s}=Yy("useNavigate"),r=hr("useNavigate"),o=p.useRef(!1);return eh(()=>{o.current=!0}),p.useCallback(async(m,h={})=>{Rt(o.current,Pm),o.current&&(typeof m=="number"?await s.navigate(m):await s.navigate(m,{fromRouteId:r,...h}))},[s,r])}var qm={};function ah(s,r,o){!r&&!qm[s]&&(qm[s]=!0,Rt(!1,o))}p.memo(Ky);function Ky({routes:s,future:r,state:o,isStatic:f,onError:m}){return th(s,void 0,{state:o,isStatic:f,onError:m})}function Jy({to:s,replace:r,state:o,relative:f}){Ge(en()," may be used only in the context of a component.");let{static:m}=p.useContext(At);Rt(!m," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:h}=p.useContext(Zt),{pathname:b}=Kt(),j=dr(),x=Ru(s,fr(h),b,f==="path"),y=JSON.stringify(x);return p.useEffect(()=>{j(JSON.parse(y),{replace:r,state:o,relative:f})},[j,y,f,r,o]),null}function ky(s){return My(s.context)}function Xl(s){Ge(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function $y({basename:s="/",children:r=null,location:o,navigationType:f="POP",navigator:m,static:h=!1,unstable_useTransitions:b}){Ge(!en(),"You cannot render a inside another . You should never have more than one in your app.");let j=s.replace(/^\/*/,"/"),x=p.useMemo(()=>({basename:j,navigator:m,static:h,unstable_useTransitions:b,future:{}}),[j,m,h,b]);typeof o=="string"&&(o=oa(o));let{pathname:y="/",search:O="",hash:N="",state:L=null,key:G="default",unstable_mask:J}=o,Q=p.useMemo(()=>{let H=vl(y,j);return H==null?null:{location:{pathname:H,search:O,hash:N,state:L,key:G,unstable_mask:J},navigationType:f}},[j,y,O,N,L,G,f,J]);return Rt(Q!=null,` is not able to match the URL "${y}${O}${N}" because it does not start with the basename, so the won't render anything.`),Q==null?null:p.createElement(At.Provider,{value:x},p.createElement(ti.Provider,{children:r,value:Q}))}function Fy({children:s,location:r}){return wy(nr(s),r)}function nr(s,r=[]){let o=[];return p.Children.forEach(s,(f,m)=>{if(!p.isValidElement(f))return;let h=[...r,m];if(f.type===p.Fragment){o.push.apply(o,nr(f.props.children,h));return}Ge(f.type===Xl,`[${typeof f.type=="string"?f.type:f.type.name}] is not a component. All component children of must be a or `),Ge(!f.props.index||!f.props.children,"An index route cannot have child routes.");let b={id:f.props.id||h.join("-"),caseSensitive:f.props.caseSensitive,element:f.props.element,Component:f.props.Component,index:f.props.index,path:f.props.path,middleware:f.props.middleware,loader:f.props.loader,action:f.props.action,hydrateFallbackElement:f.props.hydrateFallbackElement,HydrateFallback:f.props.HydrateFallback,errorElement:f.props.errorElement,ErrorBoundary:f.props.ErrorBoundary,hasErrorBoundary:f.props.hasErrorBoundary===!0||f.props.ErrorBoundary!=null||f.props.errorElement!=null,shouldRevalidate:f.props.shouldRevalidate,handle:f.props.handle,lazy:f.props.lazy};f.props.children&&(b.children=nr(f.props.children,h)),o.push(b)}),o}var xu="get",Su="application/x-www-form-urlencoded";function Cu(s){return typeof HTMLElement<"u"&&s instanceof HTMLElement}function Wy(s){return Cu(s)&&s.tagName.toLowerCase()==="button"}function Iy(s){return Cu(s)&&s.tagName.toLowerCase()==="form"}function Py(s){return Cu(s)&&s.tagName.toLowerCase()==="input"}function eg(s){return!!(s.metaKey||s.altKey||s.ctrlKey||s.shiftKey)}function tg(s,r){return s.button===0&&(!r||r==="_self")&&!eg(s)}function ir(s=""){return new URLSearchParams(typeof s=="string"||Array.isArray(s)||s instanceof URLSearchParams?s:Object.keys(s).reduce((r,o)=>{let f=s[o];return r.concat(Array.isArray(f)?f.map(m=>[o,m]):[[o,f]])},[]))}function lg(s,r){let o=ir(s);return r&&r.forEach((f,m)=>{o.has(m)||r.getAll(m).forEach(h=>{o.append(m,h)})}),o}var _u=null;function ag(){if(_u===null)try{new FormData(document.createElement("form"),0),_u=!1}catch{_u=!0}return _u}var ng=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Pc(s){return s!=null&&!ng.has(s)?(Rt(!1,`"${s}" is not a valid \`encType\` for \`\`/\`\` and will default to "${Su}"`),null):s}function ig(s,r){let o,f,m,h,b;if(Iy(s)){let j=s.getAttribute("action");f=j?vl(j,r):null,o=s.getAttribute("method")||xu,m=Pc(s.getAttribute("enctype"))||Su,h=new FormData(s)}else if(Wy(s)||Py(s)&&(s.type==="submit"||s.type==="image")){let j=s.form;if(j==null)throw new Error('Cannot submit a
-

Diffs, evidence, policy gates

+

Release safety ledger

+ ); +} diff --git a/web/src/index.css b/web/src/index.css index bc70e99..642a8ef 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -257,9 +257,9 @@ body { flex-shrink: 0; overflow: hidden; border-radius: 12px; - background: linear-gradient(165deg, var(--fd-surface-2) 0%, var(--fd-surface) 100%); + background: var(--fd-surface); box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 0 1px var(--fd-border); } @@ -559,12 +559,27 @@ html[data-theme="dark"] .fd-theme-toggle--settings .fd-theme-toggle__label:has(. .fd-page-sub { margin: 0.4rem 0 0; - max-width: 52ch; + max-width: min(52ch, 100%); font-size: var(--fd-type-page-sub); line-height: var(--fd-type-page-sub--lh); color: var(--fd-muted); } +.fd-page-sub--tight { + margin-top: 0.35rem; +} + +.fd-page-sub--meta { + margin-top: 0.45rem; + font-size: 0.875rem; + line-height: 1.42; + max-width: min(56ch, 100%); +} + +.fd-page-head > div:first-child { + max-width: min(56rem, 100%); +} + .fd-page-sub a { color: var(--fd-accent); font-weight: 600; @@ -765,16 +780,162 @@ html[data-theme="dark"] .fd-theme-toggle--settings .fd-theme-toggle__label:has(. border-bottom: none; } -.fd-table tbody tr:hover td { - background: var(--fd-surface-2); +.fd-table--hover tbody tr:hover td { + background: color-mix(in srgb, var(--fd-surface-2) 88%, var(--fd-accent) 12%); } @media (prefers-reduced-motion: no-preference) { - .fd-table tbody tr:hover td { + .fd-table--hover tbody tr:hover td { transition: background 0.12s ease; } } +.fd-th-narrow { + width: 4.5rem; +} + +.fd-table-toolbar { + padding: 0 0 0.65rem; + margin: 0 0 0.25rem; + border-bottom: 1px solid var(--fd-border); +} + +.fd-filter-row { + display: flex; + flex-wrap: wrap; + gap: 0.65rem 1rem; + align-items: flex-end; +} + +.fd-field--compact { + min-width: 10rem; +} + +.fd-field--compact .fd-field__label { + font-size: 0.72rem; +} + +.fd-cell-stack { + display: flex; + flex-direction: column; + gap: 0.25rem; + align-items: flex-start; +} + +.fd-cell-stack__main { + font-size: 0.9rem; + color: var(--fd-text); +} + +.fd-cell-stack__sub { + font-size: 0.78rem; + color: var(--fd-muted); +} + +.fd-cell-inline { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.35rem 0.5rem; +} + +.fd-copy-btn { + padding: 0.2rem 0.45rem; + font-size: 0.75rem; + min-height: 0; +} + +.fd-card--collapse { + padding-bottom: 0.35rem; +} + +.fd-collapse-head { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 0.35rem 0.75rem; + width: 100%; + padding: 0.65rem 0.85rem; + margin: 0; + border: none; + border-radius: var(--fd-radius-sm); + background: var(--fd-surface-2); + font: inherit; + text-align: left; + cursor: pointer; + color: var(--fd-text); +} + +.fd-collapse-head:hover { + background: color-mix(in srgb, var(--fd-surface-2) 92%, var(--fd-border) 8%); +} + +.fd-collapse-head:focus-visible { + outline: none; + box-shadow: var(--fd-focus-ring); +} + +.fd-collapse-head__chevron { + flex-shrink: 0; + width: 1rem; + color: var(--fd-muted); +} + +.fd-collapse-head__title { + font-weight: 650; + font-size: var(--fd-type-card-title); +} + +.fd-collapse-head__hint { + flex: 1 1 12rem; + font-size: 0.78rem; + color: var(--fd-muted); +} + +.fd-collapse-body { + padding: 0 0.85rem 0.85rem; +} + +.fd-metric-meta { + margin: 0 0 0.75rem; +} + +.fd-release-hero__primary { + color: var(--fd-text); +} + +.fd-release-hero__env { + font-weight: 500; + color: var(--fd-muted); +} + +.fd-diff-pricing-inline { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + gap: 0.35rem 0.75rem; +} + +.fd-diff-pricing-inline__summary { + flex: 1 1 14rem; +} + +.fd-diff-detail-toggle { + flex-shrink: 0; + margin-left: auto; +} + +.fd-mx-xs { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +@media (max-width: 36rem) { + .fd-diff-detail-toggle { + margin-left: 0; + } +} + .fd-mono { font-family: var(--fd-mono); font-size: 0.82rem; @@ -890,19 +1051,18 @@ code.fd-mono--sm { } .fd-btn--primary { - background-image: var(--fd-accent-gradient); - background-origin: border-box; background-color: var(--fd-accent); - border-color: transparent; + border-color: color-mix(in srgb, var(--fd-accent) 65%, var(--fd-border-strong)); color: var(--fd-on-accent); } .fd-btn--primary:hover:not(:disabled) { - filter: brightness(1.08); + background-color: var(--fd-accent-hover); + filter: none; } .fd-btn--primary:active:not(:disabled) { - filter: brightness(0.96); + filter: brightness(0.94); } @media (prefers-reduced-motion: reduce) { diff --git a/web/src/pages/ActionsPage.tsx b/web/src/pages/ActionsPage.tsx index 9c15027..cc152c4 100644 --- a/web/src/pages/ActionsPage.tsx +++ b/web/src/pages/ActionsPage.tsx @@ -289,11 +289,16 @@ export function ActionsPage() {

Promote & rollback

-

- Writes use the same HTTP contract as the CLI. When{" "} +

+ What changed? You choose the candidate release and window. Is it safe? The + server evaluates policy before mutating the ledger. Can I ship? Promotion succeeds only when + policy passes (or follow request/confirm when approval is required). +

+

+ Same HTTP contract as the CLI. When{" "} FLIGHTDECK_LOCAL_API_TOKEN is set, include it via{" "} - VITE_FLIGHTDECK_LOCAL_API_TOKEN so reads and mutations - send Authorization: Bearer. + VITE_FLIGHTDECK_LOCAL_API_TOKEN so reads and mutations send{" "} + Authorization: Bearer.

@@ -468,7 +473,7 @@ export function ActionsPage() {

No pending requests. After you request a promotion, it appears here.

) : (
- +
diff --git a/web/src/pages/DiffPage.tsx b/web/src/pages/DiffPage.tsx index 2943de6..e7141c0 100644 --- a/web/src/pages/DiffPage.tsx +++ b/web/src/pages/DiffPage.tsx @@ -1,7 +1,6 @@ -import { useEffect, useState } from "react"; +import { useEffect, useId, useState } from "react"; import { Link, useSearchParams } from "react-router-dom"; import { fetchJson } from "../api"; -import { Badge } from "../components/Badge"; import { JsonPanel } from "../components/JsonPanel"; import { UI_READ_ONLY } from "../uiConfig"; import { pickTrimmedSearch, searchParamsFromRecord } from "../urlSearch"; @@ -160,6 +159,8 @@ function Metric({ export function DiffPage() { const [searchParams, setSearchParams] = useSearchParams(); + const pricingPanelId = useId(); + const [pricingDetailOpen, setPricingDetailOpen] = useState(false); const [diffBaseline, setDiffBaseline] = useState(""); const [diffCandidate, setDiffCandidate] = useState(""); const [diffWindow, setDiffWindow] = useState("7d"); @@ -177,6 +178,10 @@ export function DiffPage() { setDiffEnv(e !== "" ? e : "local"); }, [searchParams]); + useEffect(() => { + setPricingDetailOpen(false); + }, [diffOut]); + const runDiff = async () => { setDiffErr(null); setDiffOut(null); @@ -227,15 +232,18 @@ export function DiffPage() {

Run diff

-

- Compare baseline vs candidate over a window. Same contract as{" "} - flightdeck release diff.{" "} - Overview shortcuts and shared URLs can prefill{" "} +

+ What changed? Baseline vs candidate releases over a window. Is it safe? Policy + verdict below. Can I ship? Use promote when policy passes —{" "} + Actions. +

+

+ Overview shortcuts and URLs can prefill{" "} baseline,{" "} candidate,{" "} - window, and{" "} - environment query params; click{" "} - Compute diff to run. + window,{" "} + environment; click Compute diff to run (same + contract as flightdeck release diff).

@@ -351,39 +359,12 @@ export function DiffPage() {
-

Diff result

+

Evidence window

-
-

- Policy gate -

- {policy ? ( -
- {policy.passed ? "PASS" : "FAIL"} - {policy.evaluatedAt ? ( - evaluated_at {policy.evaluatedAt} - ) : null} - {policy.reasons.length > 0 ? ( -
    - {policy.reasons.map((r) => ( -
  • {r}
  • - ))} -
- ) : ( -

- No policy constraint messages (pass with empty reasons, or policy omitted). -

- )} -
- ) : ( -

No policy block in this response.

- )} -
-

- Evidence window + Sample coverage

{samples ? (

@@ -397,18 +378,65 @@ export function DiffPage() { )}

-
-

- Pricing, model, and catalog +
+

+ Cost and quality rollups

- {pricing ? ( -
-

- Resolved models:{" "} + {metrics ? ( +

+ = 0 ? "+" : ""}${(metrics.delta_cost_per_run_pct * 100).toFixed(2)}% vs baseline)` + : "" + }` + : undefined + } + /> + + +
+ ) : ( +

No metrics block in this response.

+ )} +
+ +
+
+

+ Pricing & model +

+ {pricing ? ( +

{pricing.baselineProvider}/{pricing.baselineVersion} {pricing.baselineModel} - {" "} - →{" "} + + + → + {pricing.candidateProvider}/{pricing.candidateVersion} {pricing.candidateModel} @@ -418,6 +446,23 @@ export function DiffPage() { unchanged )}

+ ) : ( +

No pricing block in this response.

+ )} + {pricing ? ( + + ) : null} +
+ {pricing && pricingDetailOpen ? ( +
{(() => { const bp = pricing.baselineProvider.trim(); const cp = pricing.candidateProvider.trim(); @@ -488,9 +533,7 @@ export function DiffPage() { ) : null}

) : ( -

- Catalog disabled or incomplete for this diff. -

+

Catalog disabled or incomplete for this diff.

)} {pricing.catalog.warnings.length > 0 ? (
    @@ -531,55 +574,7 @@ export function DiffPage() { ) : null}
- ) : ( -

No pricing block in this response.

- )} -
- -
-

- Cost and quality rollups -

- {metrics ? ( -
- = 0 ? "+" : ""}${(metrics.delta_cost_per_run_pct * 100).toFixed(2)}% vs baseline)` - : "" - }` - : undefined - } - /> - - -
- ) : ( -

No metrics block in this response.

- )} + ) : null}

diff --git a/web/src/pages/OverviewPage.tsx b/web/src/pages/OverviewPage.tsx index 23d0e11..f0728b9 100644 --- a/web/src/pages/OverviewPage.tsx +++ b/web/src/pages/OverviewPage.tsx @@ -4,6 +4,7 @@ import type { ActionRow, MetricsPayload, PromotedRow, ReleaseRow, TimelinePayloa import { fetchMetrics, loadTimeline } from "../api"; import { useTimelineRefresh } from "../context/TimelineRefreshContext"; import { Badge } from "../components/Badge"; +import { CopyTextButton } from "../components/CopyTextButton"; import { JsonPanel } from "../components/JsonPanel"; import { ReleaseLifecycleStrip } from "../components/ReleaseLifecycleStrip"; import { UI_READ_ONLY } from "../uiConfig"; @@ -19,10 +20,12 @@ function shortId(id: string, keepStart = 10, keepEnd = 6) { function TableShell({ title, description, + toolbar, children, }: { title: string; description?: string; + toolbar?: ReactNode; children: ReactNode; }) { const hid = useId(); @@ -34,6 +37,7 @@ function TableShell({ {description ?

{description}

: null} + {toolbar ?
{toolbar}
: null}
{children}
); @@ -122,15 +126,49 @@ export function OverviewPage() { const baselineReleaseForRow = (r: ReleaseRow) => data?.promoted.find((p) => p.agent_id === r.agent_id && p.environment === r.environment)?.release_id ?? ""; + const releaseLookup = useMemo(() => { + const m = new Map(); + if (!data) return m; + for (const r of data.releases) m.set(r.release_id, r); + return m; + }, [data]); + + const [filterAgent, setFilterAgent] = useState(""); + const [filterEnv, setFilterEnv] = useState(""); + const [filterPromoted, setFilterPromoted] = useState<"" | "live" | "not-live">(""); + + const filteredReleases = useMemo(() => { + if (!data) return []; + const a = filterAgent.trim().toLowerCase(); + const e = filterEnv.trim().toLowerCase(); + return data.releases.filter((r) => { + if (a && !r.agent_id.toLowerCase().includes(a)) return false; + if (e && !r.environment.toLowerCase().includes(e)) return false; + const baseline = + data.promoted.find((p) => p.agent_id === r.agent_id && p.environment === r.environment)?.release_id ?? ""; + const isLive = baseline !== "" && baseline === r.release_id; + if (filterPromoted === "live" && !isLive) return false; + if (filterPromoted === "not-live" && isLive) return false; + return true; + }); + }, [data, filterAgent, filterEnv, filterPromoted]); + + const metricsPanelId = useId(); + const [metricsOpen, setMetricsOpen] = useState(false); + return ( <>

Overview

-

- Registered releases, promotion pointers, and recent ledger actions. Refreshes automatically every{" "} - {OVERVIEW_POLL_MS / 1000}s while this tab is visible; also updates after promote or rollback from{" "} - Actions. +

+ What changed? Scan releases and promotion pointers. Is it safe? Use{" "} + Diff for policy on baseline vs candidate. Can I ship? Promote from{" "} + Actions when policy passes. +

+

+ Tables refresh every {OVERVIEW_POLL_MS / 1000}s while this tab is visible; mutations update after promote or + rollback.

@@ -141,13 +179,17 @@ export function OverviewPage() { focusRelease ? (

- Focused release{" "} + + {focusRelease.agent_id} v{focusRelease.version} + {" "} + ({focusRelease.environment}) +

+

+ Release ID{" "} {shortId(focusRelease.release_id, 14, 8)} - -

- {focusRelease.agent_id} · v{focusRelease.version} · {focusRelease.environment} · checksum{" "} + · checksum{" "} {shortId(focusRelease.checksum, 8, 6)} @@ -223,198 +265,210 @@ export function OverviewPage() { ) : null} - {metrics ? ( -

-
-

Ledger metrics

-

- Read-only counters from{" "} - GET /v1/metrics (schema v - {metrics.schema_version}, generated{" "} - {new Date(metrics.generated_at).toLocaleString()}). -

-
-
-
-
Releases
-
- {metrics.counters.releases_total} -
-

Registered release.yaml bundles in this workspace.

-
-
-
Pricing tables
-
- {metrics.counters.pricing_tables_total} -
-

Imported pricing CSV snapshots used for diff economics.

-
-
-
Run events
-
- {metrics.counters.run_events_total} -
-

Ingested runtime evidence rows (CLI ingest or POST /v1/events).

-
-
-
Promoted pointers
-
- {metrics.counters.promoted_pointers_total} -
-

Active promoted release pointers per agent/environment pair.

-
-
-
Actions
-
- {metrics.counters.actions_total} -
- {Object.keys(metrics.counters.actions_by_action).length > 0 ? ( -
- {Object.entries(metrics.counters.actions_by_action) - .sort(([a], [b]) => a.localeCompare(b)) - .map(([k, v]) => `${k}=${v}`) - .join(" · ")} -
- ) : null} -

Ledger audit rows for promote/rollback attempts (policy outcome recorded).

-
-
-

- Next: open Diff to compare releases, or Runs for evidence - forensics. -

-
- ) : metricsError && !loading ? ( -

Ledger metrics unavailable: {metricsError}

- ) : null} - {data ? ( <> - -
Request ID
+ +
- - - - - + + + - {data.releases.length === 0 ? ( + {data.promoted.length === 0 ? ( - ) : ( - data.releases.map((r: ReleaseRow) => ( - - - - - - - - + + + - - )) + + + + + ); + }) )}
Release ID AgentVersion EnvironmentChecksumCreatedShortcutsPromoted releaseVersion + Copy +
- No releases yet. + + No promotion pointers yet.
- - {shortId(r.release_id)} - - {r.agent_id}{r.version}{r.environment} - - {shortId(r.checksum, 8, 6)} - - {new Date(r.created_at).toLocaleString()} -
+ data.promoted.map((p: PromotedRow) => { + const row = releaseLookup.get(p.release_id); + return ( +
{p.agent_id}{p.environment} - Diff + + {shortId(p.release_id)} + - - Runs - - {UI_READ_ONLY ? null : ( - - Promote - - )} - -
{row?.version ?? "—"} + +
- - + + + + + + } + > +
- - - + + + + + - {data.promoted.length === 0 ? ( + {data.releases.length === 0 ? ( - + + ) : filteredReleases.length === 0 ? ( + + ) : ( - data.promoted.map((p: PromotedRow) => ( - - - - - - )) + filteredReleases.map((r: ReleaseRow) => { + const baseline = baselineReleaseForRow(r); + const isLive = baseline !== "" && baseline === r.release_id; + return ( + + + + + + + + ); + }) )}
AgentEnvironmentActive releasePrimaryRelease IDChecksumCreatedShortcuts
- No promotion pointers yet. + + No releases yet. +
+ No releases match filters.
{p.agent_id}{p.environment} - - {shortId(p.release_id)} - -
+
+ + {r.agent_id} v{r.version} + + {r.environment} + {isLive ? ( + Live + ) : ( + Registered + )} +
+
+
+ + {shortId(r.release_id)} + + +
+
+ + {shortId(r.checksum, 8, 6)} + + {new Date(r.created_at).toLocaleString()} +
+ + Diff + + + Runs + + {UI_READ_ONLY ? null : ( + + Promote + + )} +
+
- +
@@ -456,6 +510,91 @@ export function OverviewPage() {
When
+ {metrics ? ( +
+ + +
+ ) : metricsError && !loading ? ( +

Ledger metrics unavailable: {metricsError}

+ ) : null} + ) : null} diff --git a/web/src/pages/RunsPage.tsx b/web/src/pages/RunsPage.tsx index 07d7854..a929662 100644 --- a/web/src/pages/RunsPage.tsx +++ b/web/src/pages/RunsPage.tsx @@ -374,10 +374,14 @@ export function RunsPage() {

Run events

-

- Read-only slice of ingested runs (GET /v1/runs). Newest - first; offset pages through the match set. Paste a release ID from Overview (or the CLI), then load. Use a row's View action for structured detail (same payload - as export lines). +

+ What changed? Inspect ingested runs for a release. Is it safe? Correlate with{" "} + Diff policy. Can I ship? Evidence supports the promotion decision on{" "} + Actions. +

+

+ Read-only GET /v1/runs, newest first; paste a release ID from{" "} + Overview or the CLI. Row View opens structured detail (same shape as export lines).

@@ -564,7 +568,7 @@ export function RunsPage() { )}
- +
{tableHead} {g.rows.map((rec, idx) => renderEventRow(rec, idx, g.key))}
@@ -575,7 +579,7 @@ export function RunsPage() {
) : (
- +
{tableHead} {result.events.length === 0 ? ( diff --git a/web/src/pages/SettingsPage.tsx b/web/src/pages/SettingsPage.tsx index 431eed9..5c45367 100644 --- a/web/src/pages/SettingsPage.tsx +++ b/web/src/pages/SettingsPage.tsx @@ -6,7 +6,11 @@ export function SettingsPage() {

Settings

-

Appearance and workspace preferences (more options later).

+

+ What changed? Theme preference only for now. Is it safe? Stored locally in this + browser. Can I ship? Unrelated to promotion — use Actions for ledger writes. +

+

Appearance and workspace preferences (more options later).

From 812988b3b170e875160bac15bc378addb58ee811 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 4 May 2026 15:59:25 +0000 Subject: [PATCH 4/6] docs(ui-roadmap): add production wireframe direction section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maps change→impact→policy→decision stack to current serve UI, suggested components, illustrative vs actual data contracts, and non-goals. Co-authored-by: Gottam Sai Bharath --- docs/ui-roadmap.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/docs/ui-roadmap.md b/docs/ui-roadmap.md index 6bf09fd..92e59c9 100644 --- a/docs/ui-roadmap.md +++ b/docs/ui-roadmap.md @@ -85,3 +85,62 @@ Defer standalone **Policies** (rule catalog with thresholds), **multi-role appro ### Terminology note Treat **policy FAIL** as **do not promote this candidate under this evaluation context** (baseline + window + environment), not “this release ID is permanently blocked everywhere.” + +## Production wireframe direction (external — change → impact → policy → decision) + +This section folds **final wireframe** feedback into the same constraints as **Blueprint alignment**: useful as **layout and component targets**, not as a promise that every block exists on the wire today. + +### Thesis (keep) + +The UI should reinforce **change → impact → policy → decision**, not generic dashboards. Prefer **deepening diff causality and decision clarity** over charts and vanity metrics (already in **Non-goals**). + +### Target section stack (conceptual) + +| Section | Role | FlightDeck today (serve UI) | Next evolution | +|--------|------|----------------------------|----------------| +| Sidebar | Stable nav | `AppShell` | Optional rename **Runs → Evidence** if it helps operators without splitting routes. | +| Release header | Human anchor for the release under review | Overview `?release=` hero; Diff form IDs | Dedicated **`/release/:id`** or shared **`ReleaseHeader`** component fed by timeline + focused release. | +| Block reason banner | Unmissable “why stop” | Diff verdict banner (policy FAIL + reasons) | Optional **single-line primary reason** when server ranks or summarizes reasons. | +| Release twin (OLD vs NEW) | At-a-glance identity change | Pricing model line + rollups (Diff) | Explicit **baseline vs candidate** strip (version/agent/env + model/provider) once data is stable in **`POST /v1/diff`**. | +| Change impact analysis (expandable) | Causal / drill-down | Collapsible pricing/catalog + metric grid | **Structured change list** only when diff payload exposes comparable artifacts (prompt/tools deltas)—no invented causality. | +| Policy evaluation | Gate outcome | Verdict banner + policy reasons | Optional **`PolicyPanel`** extracting banner + evaluated_at for reuse on Actions outcomes. | +| Approvals | Human layer | **Actions** when `promotion_requires_approval` | Not multi-role org charts until backend supports it; keep **request / confirm** truthy UI. | +| Decision | Readable outcome | PASS/FAIL copy + promote CTA | **`DecisionCard`** summarizing verdict + next step (promote / fix / widen evidence). | +| Actions | Mutations | Promote / rollback / request / confirm | Same page; ensure cross-links from Diff retain window/env. | + +### Suggested components (map to repo gradually) + +Names from feedback are **targets** for extraction/refactor—not required file renames in one PR: + +- **`ReleaseHeader`** — consolidate Overview hero + future release route header. +- **`ReleaseTwin`** — thin summary row for baseline vs candidate (model/pricing/version IDs). +- **`DiffList` / change rows** — defer until **`changes[]`** (or equivalent) exists on the API. +- **`PolicyPanel`** — wrapper around policy PASS/FAIL + reasons + timestamp. +- **`ApprovalPanel`** — pending requests + confirm flow (today on Actions). +- **`DecisionCard`** — verdict + recommended action line. + +### Illustrative data shape (not current wire contract) + +A unified front-end model such as: + +```ts +// Illustrative only — do not treat as implemented HTTP schema. +type Release = { + id: string; + status: "blocked" | "ready"; + changes: Change[]; + policies: PolicyResult[]; + approvals: Approval[]; +}; +``` + +…only makes sense after the server can compute **`blocked` vs `ready`** for a **specific evaluation context** (baseline, window, environment) and optionally expose **`changes[]`**. Until then, compose views from **`TimelinePayload`**, **`POST /v1/diff`**, **`GET /v1/runs`**, and promotion APIs **without** implying a single merged **`Release`** document. + +### Hard “don’t” (reasserted) + +- Do **not** add chart-heavy dashboards or random metric walls. +- Do **not** fake approval chains or policy catalogs without API backing. + +### Relation to open UI work (e.g. PR #53 trajectory) + +Recent UI slices already move toward this wireframe: **verdict-first Diff**, **collapsed deep pricing**, **promoted-first Overview**, **copy/filters**, **decision-litmus copy**. Remaining gap is mostly **component extraction** and **release route / twin row**, gated on contracts above. From 5b0900ef32a9822052684bfece0711a6b9371338 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 4 May 2026 16:04:00 +0000 Subject: [PATCH 5/6] feat(web): wireframe-aligned Diff layout (twin, policy, decision) Add OLD vs NEW release twin with env/window context and resolved model line, blocked strip for first policy failure, compact verdict strip, Policy evaluation card with Badge, Decision card with promote CTA on PASS, and rename impact fold to Change impact. Styles + roadmap wireframe note. Rebuild checked-in static bundle. Co-authored-by: Gottam Sai Bharath --- docs/ui-roadmap.md | 4 +- .../server/static/assets/index-B6xFtJ7-.js | 11 -- .../server/static/assets/index-D_rgvuq9.js | 11 ++ ...{index-Dygsz4d1.css => index-DrCTr-qj.css} | 2 +- src/flightdeck/server/static/index.html | 4 +- web/src/index.css | 104 ++++++++++++ web/src/pages/DiffPage.tsx | 151 +++++++++++++----- 7 files changed, 235 insertions(+), 52 deletions(-) delete mode 100644 src/flightdeck/server/static/assets/index-B6xFtJ7-.js create mode 100644 src/flightdeck/server/static/assets/index-D_rgvuq9.js rename src/flightdeck/server/static/assets/{index-Dygsz4d1.css => index-DrCTr-qj.css} (62%) diff --git a/docs/ui-roadmap.md b/docs/ui-roadmap.md index 92e59c9..790b239 100644 --- a/docs/ui-roadmap.md +++ b/docs/ui-roadmap.md @@ -143,4 +143,6 @@ type Release = { ### Relation to open UI work (e.g. PR #53 trajectory) -Recent UI slices already move toward this wireframe: **verdict-first Diff**, **collapsed deep pricing**, **promoted-first Overview**, **copy/filters**, **decision-litmus copy**. Remaining gap is mostly **component extraction** and **release route / twin row**, gated on contracts above. +Recent UI slices move toward this wireframe: **verdict-first Diff**, **collapsed deep pricing**, **promoted-first Overview**, **copy/filters**, **decision-litmus copy**. On **Diff**, the **Release twin** (baseline vs candidate + resolved model line), **blocked strip** (first policy reason), **policy evaluation card**, **decision card** (promote when PASS), and **Change impact** section align layout with **change → impact → policy → decision** without inventing API fields. + +Remaining gap is mostly **component extraction** (`ReleaseHeader`, shared panels) and **release route**, gated on contracts above. diff --git a/src/flightdeck/server/static/assets/index-B6xFtJ7-.js b/src/flightdeck/server/static/assets/index-B6xFtJ7-.js deleted file mode 100644 index 78f8d41..0000000 --- a/src/flightdeck/server/static/assets/index-B6xFtJ7-.js +++ /dev/null @@ -1,11 +0,0 @@ -(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const m of document.querySelectorAll('link[rel="modulepreload"]'))f(m);new MutationObserver(m=>{for(const h of m)if(h.type==="childList")for(const b of h.addedNodes)b.tagName==="LINK"&&b.rel==="modulepreload"&&f(b)}).observe(document,{childList:!0,subtree:!0});function o(m){const h={};return m.integrity&&(h.integrity=m.integrity),m.referrerPolicy&&(h.referrerPolicy=m.referrerPolicy),m.crossOrigin==="use-credentials"?h.credentials="include":m.crossOrigin==="anonymous"?h.credentials="omit":h.credentials="same-origin",h}function f(m){if(m.ep)return;m.ep=!0;const h=o(m);fetch(m.href,h)}})();var Zc={exports:{}},$n={};var Sm;function Yv(){if(Sm)return $n;Sm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(f,m,h){var b=null;if(h!==void 0&&(b=""+h),m.key!==void 0&&(b=""+m.key),"key"in m){h={};for(var j in m)j!=="key"&&(h[j]=m[j])}else h=m;return m=h.ref,{$$typeof:s,type:f,key:b,ref:m!==void 0?m:null,props:h}}return $n.Fragment=r,$n.jsx=o,$n.jsxs=o,$n}var jm;function Gv(){return jm||(jm=1,Zc.exports=Yv()),Zc.exports}var u=Gv(),Kc={exports:{}},ce={};var Nm;function Qv(){if(Nm)return ce;Nm=1;var s=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),f=Symbol.for("react.strict_mode"),m=Symbol.for("react.profiler"),h=Symbol.for("react.consumer"),b=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),O=Symbol.for("react.lazy"),N=Symbol.for("react.activity"),L=Symbol.iterator;function G(g){return g===null||typeof g!="object"?null:(g=L&&g[L]||g["@@iterator"],typeof g=="function"?g:null)}var J={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Q=Object.assign,H={};function Z(g,w,Y){this.props=g,this.context=w,this.refs=H,this.updater=Y||J}Z.prototype.isReactComponent={},Z.prototype.setState=function(g,w){if(typeof g!="object"&&typeof g!="function"&&g!=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,g,w,"setState")},Z.prototype.forceUpdate=function(g){this.updater.enqueueForceUpdate(this,g,"forceUpdate")};function ee(){}ee.prototype=Z.prototype;function I(g,w,Y){this.props=g,this.context=w,this.refs=H,this.updater=Y||J}var ye=I.prototype=new ee;ye.constructor=I,Q(ye,Z.prototype),ye.isPureReactComponent=!0;var re=Array.isArray;function ie(){}var F={H:null,A:null,T:null,S:null},le=Object.prototype.hasOwnProperty;function X(g,w,Y){var k=Y.ref;return{$$typeof:s,type:g,key:w,ref:k!==void 0?k:null,props:Y}}function He(g,w){return X(g.type,w,g.props)}function fe(g){return typeof g=="object"&&g!==null&&g.$$typeof===s}function K(g){var w={"=":"=0",":":"=2"};return"$"+g.replace(/[=:]/g,function(Y){return w[Y]})}var de=/\/+/g;function me(g,w){return typeof g=="object"&&g!==null&&g.key!=null?K(""+g.key):w.toString(36)}function M(g){switch(g.status){case"fulfilled":return g.value;case"rejected":throw g.reason;default:switch(typeof g.status=="string"?g.then(ie,ie):(g.status="pending",g.then(function(w){g.status==="pending"&&(g.status="fulfilled",g.value=w)},function(w){g.status==="pending"&&(g.status="rejected",g.reason=w)})),g.status){case"fulfilled":return g.value;case"rejected":throw g.reason}}throw g}function E(g,w,Y,k,ne){var se=typeof g;(se==="undefined"||se==="boolean")&&(g=null);var Ne=!1;if(g===null)Ne=!0;else switch(se){case"bigint":case"string":case"number":Ne=!0;break;case"object":switch(g.$$typeof){case s:case r:Ne=!0;break;case O:return Ne=g._init,E(Ne(g._payload),w,Y,k,ne)}}if(Ne)return ne=ne(g),Ne=k===""?"."+me(g,0):k,re(ne)?(Y="",Ne!=null&&(Y=Ne.replace(de,"$&/")+"/"),E(ne,w,Y,"",function(B){return B})):ne!=null&&(fe(ne)&&(ne=He(ne,Y+(ne.key==null||g&&g.key===ne.key?"":(""+ne.key).replace(de,"$&/")+"/")+Ne)),w.push(ne)),1;Ne=0;var Ke=k===""?".":k+":";if(re(g))for(var qe=0;qe>>1,xe=E[_e];if(0>>1;_em(Y,W))km(ne,Y)?(E[_e]=ne,E[k]=W,_e=k):(E[_e]=Y,E[w]=W,_e=w);else if(km(ne,W))E[_e]=ne,E[k]=W,_e=k;else break e}}return q}function m(E,q){var W=E.sortIndex-q.sortIndex;return W!==0?W:E.id-q.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var h=performance;s.unstable_now=function(){return h.now()}}else{var b=Date,j=b.now();s.unstable_now=function(){return b.now()-j}}var x=[],y=[],O=1,N=null,L=3,G=!1,J=!1,Q=!1,H=!1,Z=typeof setTimeout=="function"?setTimeout:null,ee=typeof clearTimeout=="function"?clearTimeout:null,I=typeof setImmediate<"u"?setImmediate:null;function ye(E){for(var q=o(y);q!==null;){if(q.callback===null)f(y);else if(q.startTime<=E)f(y),q.sortIndex=q.expirationTime,r(x,q);else break;q=o(y)}}function re(E){if(Q=!1,ye(E),!J)if(o(x)!==null)J=!0,ie||(ie=!0,K());else{var q=o(y);q!==null&&M(re,q.startTime-E)}}var ie=!1,F=-1,le=5,X=-1;function He(){return H?!0:!(s.unstable_now()-XE&&He());){var _e=N.callback;if(typeof _e=="function"){N.callback=null,L=N.priorityLevel;var xe=_e(N.expirationTime<=E);if(E=s.unstable_now(),typeof xe=="function"){N.callback=xe,ye(E),q=!0;break t}N===o(x)&&f(x),ye(E)}else f(x);N=o(x)}if(N!==null)q=!0;else{var g=o(y);g!==null&&M(re,g.startTime-E),q=!1}}break e}finally{N=null,L=W,G=!1}q=void 0}}finally{q?K():ie=!1}}}var K;if(typeof I=="function")K=function(){I(fe)};else if(typeof MessageChannel<"u"){var de=new MessageChannel,me=de.port2;de.port1.onmessage=fe,K=function(){me.postMessage(null)}}else K=function(){Z(fe,0)};function M(E,q){F=Z(function(){E(s.unstable_now())},q)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(E){E.callback=null},s.unstable_forceFrameRate=function(E){0>E||125_e?(E.sortIndex=W,r(y,E),o(x)===null&&E===o(y)&&(Q?(ee(F),F=-1):Q=!0,M(re,W-_e))):(E.sortIndex=xe,r(x,E),J||G||(J=!0,ie||(ie=!0,K()))),E},s.unstable_shouldYield=He,s.unstable_wrapCallback=function(E){var q=L;return function(){var W=L;L=q;try{return E.apply(this,arguments)}finally{L=W}}}})($c)),$c}var Rm;function Vv(){return Rm||(Rm=1,kc.exports=Xv()),kc.exports}var Fc={exports:{}},ct={};var Am;function Zv(){if(Am)return ct;Am=1;var s=rr();function r(x){var y="https://react.dev/errors/"+x;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Fc.exports=Zv(),Fc.exports}var Om;function Jv(){if(Om)return Fn;Om=1;var s=Vv(),r=rr(),o=Kv();function f(e){var t="https://react.dev/errors/"+e;if(1xe||(e.current=_e[xe],_e[xe]=null,xe--)}function Y(e,t){xe++,_e[xe]=e.current,e.current=t}var k=g(null),ne=g(null),se=g(null),Ne=g(null);function Ke(e,t){switch(Y(se,t),Y(ne,e),Y(k,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Zd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Zd(t),e=Kd(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}w(k),Y(k,e)}function qe(){w(k),w(ne),w(se)}function B(e){e.memoizedState!==null&&Y(Ne,e);var t=k.current,l=Kd(t,e.type);t!==l&&(Y(ne,e),Y(k,l))}function pe(e){ne.current===e&&(w(k),w(ne)),Ne.current===e&&(w(Ne),Zn._currentValue=W)}var we,V;function ue(e){if(we===void 0)try{throw Error()}catch(l){var t=l.stack.trim().match(/\n( *(at )?)/);we=t&&t[1]||"",V=-1)":-1n||v[a]!==R[n]){var z=` -`+v[a].replace(" at new "," at ");return e.displayName&&z.includes("")&&(z=z.replace("",e.displayName)),z}while(1<=a&&0<=n);break}}}finally{ve=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?ue(l):""}function Ct(e,t){switch(e.tag){case 26:case 27:case 5:return ue(e.type);case 16:return ue("Lazy");case 13:return e.child!==t&&t!==null?ue("Suspense Fallback"):ue("Suspense");case 19:return ue("SuspenseList");case 0:case 15:return st(e.type,!1);case 11:return st(e.type.render,!1);case 1:return st(e.type,!0);case 31:return ue("Activity");default:return""}}function Pe(e){try{var t="",l=null;do t+=Ct(e,l),l=e,e=e.return;while(e);return t}catch(a){return` -Error generating stack: `+a.message+` -`+a.stack}}var tn=Object.prototype.hasOwnProperty,zu=s.unstable_scheduleCallback,Du=s.unstable_cancelCallback,gh=s.unstable_shouldYield,bh=s.unstable_requestPaint,yt=s.unstable_now,_h=s.unstable_getCurrentPriorityLevel,xr=s.unstable_ImmediatePriority,Sr=s.unstable_UserBlockingPriority,ai=s.unstable_NormalPriority,xh=s.unstable_LowPriority,jr=s.unstable_IdlePriority,Sh=s.log,jh=s.unstable_setDisableYieldValue,ln=null,gt=null;function yl(e){if(typeof Sh=="function"&&jh(e),gt&&typeof gt.setStrictMode=="function")try{gt.setStrictMode(ln,e)}catch{}}var bt=Math.clz32?Math.clz32:Th,Nh=Math.log,Eh=Math.LN2;function Th(e){return e>>>=0,e===0?32:31-(Nh(e)/Eh|0)|0}var ni=256,ii=262144,ui=4194304;function Vl(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function si(e,t,l){var a=e.pendingLanes;if(a===0)return 0;var n=0,i=e.suspendedLanes,c=e.pingedLanes;e=e.warmLanes;var d=a&134217727;return d!==0?(a=d&~i,a!==0?n=Vl(a):(c&=d,c!==0?n=Vl(c):l||(l=d&~e,l!==0&&(n=Vl(l))))):(d=a&~i,d!==0?n=Vl(d):c!==0?n=Vl(c):l||(l=a&~e,l!==0&&(n=Vl(l)))),n===0?0:t!==0&&t!==n&&(t&i)===0&&(i=n&-n,l=t&-t,i>=l||i===32&&(l&4194048)!==0)?t:n}function an(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Rh(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Nr(){var e=ui;return ui<<=1,(ui&62914560)===0&&(ui=4194304),e}function Mu(e){for(var t=[],l=0;31>l;l++)t.push(e);return t}function nn(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ah(e,t,l,a,n,i){var c=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var d=e.entanglements,v=e.expirationTimes,R=e.hiddenUpdates;for(l=c&~l;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var wh=/[\n"\\]/g;function zt(e){return e.replace(wh,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Bu(e,t,l,a,n,i,c,d){e.name="",c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?e.type=c:e.removeAttribute("type"),t!=null?c==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Ot(t)):e.value!==""+Ot(t)&&(e.value=""+Ot(t)):c!=="submit"&&c!=="reset"||e.removeAttribute("value"),t!=null?Yu(e,c,Ot(t)):l!=null?Yu(e,c,Ot(l)):a!=null&&e.removeAttribute("value"),n==null&&i!=null&&(e.defaultChecked=!!i),n!=null&&(e.checked=n&&typeof n!="function"&&typeof n!="symbol"),d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"?e.name=""+Ot(d):e.removeAttribute("name")}function qr(e,t,l,a,n,i,c,d){if(i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(e.type=i),t!=null||l!=null){if(!(i!=="submit"&&i!=="reset"||t!=null)){Lu(e);return}l=l!=null?""+Ot(l):"",t=t!=null?""+Ot(t):l,d||t===e.value||(e.value=t),e.defaultValue=t}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=d?e.checked:!!a,e.defaultChecked=!!a,c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"&&(e.name=c),Lu(e)}function Yu(e,t,l){t==="number"&&fi(e.ownerDocument)===e||e.defaultValue===""+l||(e.defaultValue=""+l)}function ga(e,t,l,a){if(e=e.options,t){t={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Zu=!1;if(Pt)try{var rn={};Object.defineProperty(rn,"passive",{get:function(){Zu=!0}}),window.addEventListener("test",rn,rn),window.removeEventListener("test",rn,rn)}catch{Zu=!1}var bl=null,Ku=null,di=null;function Vr(){if(di)return di;var e,t=Ku,l=t.length,a,n="value"in bl?bl.value:bl.textContent,i=n.length;for(e=0;e=dn),Fr=" ",Wr=!1;function Ir(e,t){switch(e){case"keyup":return cp.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Pr(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Sa=!1;function fp(e,t){switch(e){case"compositionend":return Pr(t);case"keypress":return t.which!==32?null:(Wr=!0,Fr);case"textInput":return e=t.data,e===Fr&&Wr?null:e;default:return null}}function op(e,t){if(Sa)return e==="compositionend"||!Wu&&Ir(e,t)?(e=Vr(),di=Ku=bl=null,Sa=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:l,offset:t-e};e=a}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=cf(l)}}function ff(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?ff(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function of(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=fi(e.document);t instanceof e.HTMLIFrameElement;){try{var l=typeof t.contentWindow.location.href=="string"}catch{l=!1}if(l)e=t.contentWindow;else break;t=fi(e.document)}return t}function es(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var bp=Pt&&"documentMode"in document&&11>=document.documentMode,ja=null,ts=null,vn=null,ls=!1;function df(e,t,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;ls||ja==null||ja!==fi(a)||(a=ja,"selectionStart"in a&&es(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),vn&&pn(vn,a)||(vn=a,a=iu(ts,"onSelect"),0>=c,n-=c,Jt=1<<32-bt(t)+n|l<he?(je=P,P=null):je=P.sibling;var Re=A(S,P,T[he],D);if(Re===null){P===null&&(P=je);break}e&&P&&Re.alternate===null&&t(S,P),_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re,P=je}if(he===T.length)return l(S,P),Ee&&tl(S,he),te;if(P===null){for(;hehe?(je=P,P=null):je=P.sibling;var Gl=A(S,P,Re.value,D);if(Gl===null){P===null&&(P=je);break}e&&P&&Gl.alternate===null&&t(S,P),_=i(Gl,_,he),Te===null?te=Gl:Te.sibling=Gl,Te=Gl,P=je}if(Re.done)return l(S,P),Ee&&tl(S,he),te;if(P===null){for(;!Re.done;he++,Re=T.next())Re=U(S,Re.value,D),Re!==null&&(_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re);return Ee&&tl(S,he),te}for(P=a(P);!Re.done;he++,Re=T.next())Re=C(P,S,he,Re.value,D),Re!==null&&(e&&Re.alternate!==null&&P.delete(Re.key===null?he:Re.key),_=i(Re,_,he),Te===null?te=Re:Te.sibling=Re,Te=Re);return e&&P.forEach(function(Bv){return t(S,Bv)}),Ee&&tl(S,he),te}function Me(S,_,T,D){if(typeof T=="object"&&T!==null&&T.type===Q&&T.key===null&&(T=T.props.children),typeof T=="object"&&T!==null){switch(T.$$typeof){case G:e:{for(var te=T.key;_!==null;){if(_.key===te){if(te=T.type,te===Q){if(_.tag===7){l(S,_.sibling),D=n(_,T.props.children),D.return=S,S=D;break e}}else if(_.elementType===te||typeof te=="object"&&te!==null&&te.$$typeof===le&&ta(te)===_.type){l(S,_.sibling),D=n(_,T.props),Sn(D,T),D.return=S,S=D;break e}l(S,_);break}else t(S,_);_=_.sibling}T.type===Q?(D=Fl(T.props.children,S.mode,D,T.key),D.return=S,S=D):(D=Si(T.type,T.key,T.props,null,S.mode,D),Sn(D,T),D.return=S,S=D)}return c(S);case J:e:{for(te=T.key;_!==null;){if(_.key===te)if(_.tag===4&&_.stateNode.containerInfo===T.containerInfo&&_.stateNode.implementation===T.implementation){l(S,_.sibling),D=n(_,T.children||[]),D.return=S,S=D;break e}else{l(S,_);break}else t(S,_);_=_.sibling}D=rs(T,S.mode,D),D.return=S,S=D}return c(S);case le:return T=ta(T),Me(S,_,T,D)}if(M(T))return $(S,_,T,D);if(K(T)){if(te=K(T),typeof te!="function")throw Error(f(150));return T=te.call(T),ae(S,_,T,D)}if(typeof T.then=="function")return Me(S,_,Ci(T),D);if(T.$$typeof===I)return Me(S,_,Ei(S,T),D);Oi(S,T)}return typeof T=="string"&&T!==""||typeof T=="number"||typeof T=="bigint"?(T=""+T,_!==null&&_.tag===6?(l(S,_.sibling),D=n(_,T),D.return=S,S=D):(l(S,_),D=cs(T,S.mode,D),D.return=S,S=D),c(S)):l(S,_)}return function(S,_,T,D){try{xn=0;var te=Me(S,_,T,D);return wa=null,te}catch(P){if(P===Ma||P===Ri)throw P;var Te=xt(29,P,null,S.mode);return Te.lanes=D,Te.return=S,Te}}}var aa=Uf(!0),Hf=Uf(!1),Nl=!1;function xs(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ss(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function El(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Tl(e,t,l){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(Ae&2)!==0){var n=a.pending;return n===null?t.next=t:(t.next=n.next,n.next=t),a.pending=t,t=xi(e),bf(e,null,l),t}return _i(e,a,t,l),xi(e)}function jn(e,t,l){if(t=t.updateQueue,t!==null&&(t=t.shared,(l&4194048)!==0)){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Tr(e,l)}}function js(e,t){var l=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,i=null;if(l=l.firstBaseUpdate,l!==null){do{var c={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};i===null?n=i=c:i=i.next=c,l=l.next}while(l!==null);i===null?n=i=t:i=i.next=t}else n=i=t;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:i,shared:a.shared,callbacks:a.callbacks},e.updateQueue=l;return}e=l.lastBaseUpdate,e===null?l.firstBaseUpdate=t:e.next=t,l.lastBaseUpdate=t}var Ns=!1;function Nn(){if(Ns){var e=Da;if(e!==null)throw e}}function En(e,t,l,a){Ns=!1;var n=e.updateQueue;Nl=!1;var i=n.firstBaseUpdate,c=n.lastBaseUpdate,d=n.shared.pending;if(d!==null){n.shared.pending=null;var v=d,R=v.next;v.next=null,c===null?i=R:c.next=R,c=v;var z=e.alternate;z!==null&&(z=z.updateQueue,d=z.lastBaseUpdate,d!==c&&(d===null?z.firstBaseUpdate=R:d.next=R,z.lastBaseUpdate=v))}if(i!==null){var U=n.baseState;c=0,z=R=v=null,d=i;do{var A=d.lane&-536870913,C=A!==d.lane;if(C?(Se&A)===A:(a&A)===A){A!==0&&A===za&&(Ns=!0),z!==null&&(z=z.next={lane:0,tag:d.tag,payload:d.payload,callback:null,next:null});e:{var $=e,ae=d;A=t;var Me=l;switch(ae.tag){case 1:if($=ae.payload,typeof $=="function"){U=$.call(Me,U,A);break e}U=$;break e;case 3:$.flags=$.flags&-65537|128;case 0:if($=ae.payload,A=typeof $=="function"?$.call(Me,U,A):$,A==null)break e;U=N({},U,A);break e;case 2:Nl=!0}}A=d.callback,A!==null&&(e.flags|=64,C&&(e.flags|=8192),C=n.callbacks,C===null?n.callbacks=[A]:C.push(A))}else C={lane:A,tag:d.tag,payload:d.payload,callback:d.callback,next:null},z===null?(R=z=C,v=U):z=z.next=C,c|=A;if(d=d.next,d===null){if(d=n.shared.pending,d===null)break;C=d,d=C.next,C.next=null,n.lastBaseUpdate=C,n.shared.pending=null}}while(!0);z===null&&(v=U),n.baseState=v,n.firstBaseUpdate=R,n.lastBaseUpdate=z,i===null&&(n.shared.lanes=0),zl|=c,e.lanes=c,e.memoizedState=U}}function qf(e,t){if(typeof e!="function")throw Error(f(191,e));e.call(t)}function Lf(e,t){var l=e.callbacks;if(l!==null)for(e.callbacks=null,e=0;ei?i:8;var c=E.T,d={};E.T=d,Xs(e,!1,t,l);try{var v=n(),R=E.S;if(R!==null&&R(d,v),v!==null&&typeof v=="object"&&typeof v.then=="function"){var z=Ap(v,a);An(e,t,z,Tt(e))}else An(e,t,a,Tt(e))}catch(U){An(e,t,{then:function(){},status:"rejected",reason:U},Tt())}finally{q.p=i,c!==null&&d.types!==null&&(c.types=d.types),E.T=c}}function wp(){}function Gs(e,t,l,a){if(e.tag!==5)throw Error(f(476));var n=yo(e).queue;vo(e,n,t,W,l===null?wp:function(){return go(e),l(a)})}function yo(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:W,baseState:W,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:W},next:null};var l={};return t.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:il,lastRenderedState:l},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function go(e){var t=yo(e);t.next===null&&(t=e.alternate.memoizedState),An(e,t.next.queue,{},Tt())}function Qs(){return nt(Zn)}function bo(){return Ze().memoizedState}function _o(){return Ze().memoizedState}function Up(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var l=Tt();e=El(l);var a=Tl(t,e,l);a!==null&&(vt(a,t,l),jn(a,t,l)),t={cache:ys()},e.payload=t;return}t=t.return}}function Hp(e,t,l){var a=Tt();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Yi(e)?So(t,l):(l=us(e,t,l,a),l!==null&&(vt(l,e,a),jo(l,t,a)))}function xo(e,t,l){var a=Tt();An(e,t,l,a)}function An(e,t,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Yi(e))So(t,n);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var c=t.lastRenderedState,d=i(c,l);if(n.hasEagerState=!0,n.eagerState=d,_t(d,c))return _i(e,t,n,0),Ue===null&&bi(),!1}catch{}if(l=us(e,t,n,a),l!==null)return vt(l,e,a),jo(l,t,a),!0}return!1}function Xs(e,t,l,a){if(a={lane:2,revertLane:xc(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Yi(e)){if(t)throw Error(f(479))}else t=us(e,l,a,2),t!==null&&vt(t,e,2)}function Yi(e){var t=e.alternate;return e===oe||t!==null&&t===oe}function So(e,t){Ha=Mi=!0;var l=e.pending;l===null?t.next=t:(t.next=l.next,l.next=t),e.pending=t}function jo(e,t,l){if((l&4194048)!==0){var a=t.lanes;a&=e.pendingLanes,l|=a,t.lanes=l,Tr(e,l)}}var Cn={readContext:nt,use:Hi,useCallback:Qe,useContext:Qe,useEffect:Qe,useImperativeHandle:Qe,useLayoutEffect:Qe,useInsertionEffect:Qe,useMemo:Qe,useReducer:Qe,useRef:Qe,useState:Qe,useDebugValue:Qe,useDeferredValue:Qe,useTransition:Qe,useSyncExternalStore:Qe,useId:Qe,useHostTransitionStatus:Qe,useFormState:Qe,useActionState:Qe,useOptimistic:Qe,useMemoCache:Qe,useCacheRefresh:Qe};Cn.useEffectEvent=Qe;var No={readContext:nt,use:Hi,useCallback:function(e,t){return rt().memoizedState=[e,t===void 0?null:t],e},useContext:nt,useEffect:uo,useImperativeHandle:function(e,t,l){l=l!=null?l.concat([e]):null,Li(4194308,4,fo.bind(null,t,e),l)},useLayoutEffect:function(e,t){return Li(4194308,4,e,t)},useInsertionEffect:function(e,t){Li(4,2,e,t)},useMemo:function(e,t){var l=rt();t=t===void 0?null:t;var a=e();if(na){yl(!0);try{e()}finally{yl(!1)}}return l.memoizedState=[a,t],a},useReducer:function(e,t,l){var a=rt();if(l!==void 0){var n=l(t);if(na){yl(!0);try{l(t)}finally{yl(!1)}}}else n=t;return a.memoizedState=a.baseState=n,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},a.queue=e,e=e.dispatch=Hp.bind(null,oe,e),[a.memoizedState,e]},useRef:function(e){var t=rt();return e={current:e},t.memoizedState=e},useState:function(e){e=Hs(e);var t=e.queue,l=xo.bind(null,oe,t);return t.dispatch=l,[e.memoizedState,l]},useDebugValue:Bs,useDeferredValue:function(e,t){var l=rt();return Ys(l,e,t)},useTransition:function(){var e=Hs(!1);return e=vo.bind(null,oe,e.queue,!0,!1),rt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,l){var a=oe,n=rt();if(Ee){if(l===void 0)throw Error(f(407));l=l()}else{if(l=t(),Ue===null)throw Error(f(349));(Se&127)!==0||Vf(a,t,l)}n.memoizedState=l;var i={value:l,getSnapshot:t};return n.queue=i,uo(Kf.bind(null,a,i,e),[e]),a.flags|=2048,La(9,{destroy:void 0},Zf.bind(null,a,i,l,t),null),l},useId:function(){var e=rt(),t=Ue.identifierPrefix;if(Ee){var l=kt,a=Jt;l=(a&~(1<<32-bt(a)-1)).toString(32)+l,t="_"+t+"R_"+l,l=wi++,0<\/script>",i=i.removeChild(i.firstChild);break;case"select":i=typeof a.is=="string"?c.createElement("select",{is:a.is}):c.createElement("select"),a.multiple?i.multiple=!0:a.size&&(i.size=a.size);break;default:i=typeof a.is=="string"?c.createElement(n,{is:a.is}):c.createElement(n)}}i[lt]=t,i[ft]=a;e:for(c=t.child;c!==null;){if(c.tag===5||c.tag===6)i.appendChild(c.stateNode);else if(c.tag!==4&&c.tag!==27&&c.child!==null){c.child.return=c,c=c.child;continue}if(c===t)break e;for(;c.sibling===null;){if(c.return===null||c.return===t)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}t.stateNode=i;e:switch(ut(i,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&sl(t)}}return Be(t),ac(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,l),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==a&&sl(t);else{if(typeof a!="string"&&t.stateNode===null)throw Error(f(166));if(e=se.current,Ca(t)){if(e=t.stateNode,l=t.memoizedProps,a=null,n=at,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}e[lt]=t,e=!!(e.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||Xd(e.nodeValue,l)),e||Sl(t,!0)}else e=uu(e).createTextNode(a),e[lt]=t,t.stateNode=e}return Be(t),null;case 31:if(l=t.memoizedState,e===null||e.memoizedState!==null){if(a=Ca(t),l!==null){if(e===null){if(!a)throw Error(f(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(f(557));e[lt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),e=!1}else l=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=l),e=!0;if(!e)return t.flags&256?(jt(t),t):(jt(t),null);if((t.flags&128)!==0)throw Error(f(558))}return Be(t),null;case 13:if(a=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(n=Ca(t),a!==null&&a.dehydrated!==null){if(e===null){if(!n)throw Error(f(318));if(n=t.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(f(317));n[lt]=t}else Wl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Be(t),n=!1}else n=ms(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),n=!0;if(!n)return t.flags&256?(jt(t),t):(jt(t),null)}return jt(t),(t.flags&128)!==0?(t.lanes=l,t):(l=a!==null,e=e!==null&&e.memoizedState!==null,l&&(a=t.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),i=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(i=a.memoizedState.cachePool.pool),i!==n&&(a.flags|=2048)),l!==e&&l&&(t.child.flags|=8192),Zi(t,t.updateQueue),Be(t),null);case 4:return qe(),e===null&&Ec(t.stateNode.containerInfo),Be(t),null;case 10:return al(t.type),Be(t),null;case 19:if(w(Ve),a=t.memoizedState,a===null)return Be(t),null;if(n=(t.flags&128)!==0,i=a.rendering,i===null)if(n)zn(a,!1);else{if(Xe!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(i=Di(e),i!==null){for(t.flags|=128,zn(a,!1),e=i.updateQueue,t.updateQueue=e,Zi(t,e),t.subtreeFlags=0,e=l,l=t.child;l!==null;)_f(l,e),l=l.sibling;return Y(Ve,Ve.current&1|2),Ee&&tl(t,a.treeForkCount),t.child}e=e.sibling}a.tail!==null&&yt()>Fi&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304)}else{if(!n)if(e=Di(i),e!==null){if(t.flags|=128,n=!0,e=e.updateQueue,t.updateQueue=e,Zi(t,e),zn(a,!0),a.tail===null&&a.tailMode==="hidden"&&!i.alternate&&!Ee)return Be(t),null}else 2*yt()-a.renderingStartTime>Fi&&l!==536870912&&(t.flags|=128,n=!0,zn(a,!1),t.lanes=4194304);a.isBackwards?(i.sibling=t.child,t.child=i):(e=a.last,e!==null?e.sibling=i:t.child=i,a.last=i)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=yt(),e.sibling=null,l=Ve.current,Y(Ve,n?l&1|2:l&1),Ee&&tl(t,a.treeForkCount),e):(Be(t),null);case 22:case 23:return jt(t),Ts(),a=t.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(t.flags|=8192):a&&(t.flags|=8192),a?(l&536870912)!==0&&(t.flags&128)===0&&(Be(t),t.subtreeFlags&6&&(t.flags|=8192)):Be(t),l=t.updateQueue,l!==null&&Zi(t,l.retryQueue),l=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),a=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),a!==l&&(t.flags|=2048),e!==null&&w(ea),null;case 24:return l=null,e!==null&&(l=e.memoizedState.cache),t.memoizedState.cache!==l&&(t.flags|=2048),al(Je),Be(t),null;case 25:return null;case 30:return null}throw Error(f(156,t.tag))}function Gp(e,t){switch(os(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return al(Je),qe(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return pe(t),null;case 31:if(t.memoizedState!==null){if(jt(t),t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(jt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(f(340));Wl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return w(Ve),null;case 4:return qe(),null;case 10:return al(t.type),null;case 22:case 23:return jt(t),Ts(),e!==null&&w(ea),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return al(Je),null;case 25:return null;default:return null}}function ko(e,t){switch(os(t),t.tag){case 3:al(Je),qe();break;case 26:case 27:case 5:pe(t);break;case 4:qe();break;case 31:t.memoizedState!==null&&jt(t);break;case 13:jt(t);break;case 19:w(Ve);break;case 10:al(t.type);break;case 22:case 23:jt(t),Ts(),e!==null&&w(ea);break;case 24:al(Je)}}function Dn(e,t){try{var l=t.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&e)===e){a=void 0;var i=l.create,c=l.inst;a=i(),c.destroy=a}l=l.next}while(l!==n)}}catch(d){Oe(t,t.return,d)}}function Cl(e,t,l){try{var a=t.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var i=n.next;a=i;do{if((a.tag&e)===e){var c=a.inst,d=c.destroy;if(d!==void 0){c.destroy=void 0,n=t;var v=l,R=d;try{R()}catch(z){Oe(n,v,z)}}}a=a.next}while(a!==i)}}catch(z){Oe(t,t.return,z)}}function $o(e){var t=e.updateQueue;if(t!==null){var l=e.stateNode;try{Lf(t,l)}catch(a){Oe(e,e.return,a)}}}function Fo(e,t,l){l.props=ia(e.type,e.memoizedProps),l.state=e.memoizedState;try{l.componentWillUnmount()}catch(a){Oe(e,t,a)}}function Mn(e,t){try{var l=e.ref;if(l!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof l=="function"?e.refCleanup=l(a):l.current=a}}catch(n){Oe(e,t,n)}}function $t(e,t){var l=e.ref,a=e.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){Oe(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){Oe(e,t,n)}else l.current=null}function Wo(e){var t=e.type,l=e.memoizedProps,a=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":l.autoFocus&&a.focus();break e;case"img":l.src?a.src=l.src:l.srcSet&&(a.srcset=l.srcSet)}}catch(n){Oe(e,e.return,n)}}function nc(e,t,l){try{var a=e.stateNode;rv(a,e.type,l,t),a[ft]=t}catch(n){Oe(e,e.return,n)}}function Io(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Hl(e.type)||e.tag===4}function ic(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Io(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&&Hl(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function uc(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(e,t):(t=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,t.appendChild(e),l=l._reactRootContainer,l!=null||t.onclick!==null||(t.onclick=It));else if(a!==4&&(a===27&&Hl(e.type)&&(l=e.stateNode,t=null),e=e.child,e!==null))for(uc(e,t,l),e=e.sibling;e!==null;)uc(e,t,l),e=e.sibling}function Ki(e,t,l){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?l.insertBefore(e,t):l.appendChild(e);else if(a!==4&&(a===27&&Hl(e.type)&&(l=e.stateNode),e=e.child,e!==null))for(Ki(e,t,l),e=e.sibling;e!==null;)Ki(e,t,l),e=e.sibling}function Po(e){var t=e.stateNode,l=e.memoizedProps;try{for(var a=e.type,n=t.attributes;n.length;)t.removeAttributeNode(n[0]);ut(t,a,l),t[lt]=e,t[ft]=l}catch(i){Oe(e,e.return,i)}}var cl=!1,Fe=!1,sc=!1,ed=typeof WeakSet=="function"?WeakSet:Set,tt=null;function Qp(e,t){if(e=e.containerInfo,Ac=mu,e=of(e),es(e)){if("selectionStart"in e)var l={start:e.selectionStart,end:e.selectionEnd};else e:{l=(l=e.ownerDocument)&&l.defaultView||window;var a=l.getSelection&&l.getSelection();if(a&&a.rangeCount!==0){l=a.anchorNode;var n=a.anchorOffset,i=a.focusNode;a=a.focusOffset;try{l.nodeType,i.nodeType}catch{l=null;break e}var c=0,d=-1,v=-1,R=0,z=0,U=e,A=null;t:for(;;){for(var C;U!==l||n!==0&&U.nodeType!==3||(d=c+n),U!==i||a!==0&&U.nodeType!==3||(v=c+a),U.nodeType===3&&(c+=U.nodeValue.length),(C=U.firstChild)!==null;)A=U,U=C;for(;;){if(U===e)break t;if(A===l&&++R===n&&(d=c),A===i&&++z===a&&(v=c),(C=U.nextSibling)!==null)break;U=A,A=U.parentNode}U=C}l=d===-1||v===-1?null:{start:d,end:v}}else l=null}l=l||{start:0,end:0}}else l=null;for(Cc={focusedElem:e,selectionRange:l},mu=!1,tt=t;tt!==null;)if(t=tt,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,tt=e;else for(;tt!==null;){switch(t=tt,i=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(l=0;l title"))),ut(i,a,l),i[lt]=e,et(i),a=i;break e;case"link":var c=um("link","href",n).get(a+(l.href||""));if(c){for(var d=0;dMe&&(c=Me,Me=ae,ae=c);var S=rf(d,ae),_=rf(d,Me);if(S&&_&&(C.rangeCount!==1||C.anchorNode!==S.node||C.anchorOffset!==S.offset||C.focusNode!==_.node||C.focusOffset!==_.offset)){var T=U.createRange();T.setStart(S.node,S.offset),C.removeAllRanges(),ae>Me?(C.addRange(T),C.extend(_.node,_.offset)):(T.setEnd(_.node,_.offset),C.addRange(T))}}}}for(U=[],C=d;C=C.parentNode;)C.nodeType===1&&U.push({element:C,left:C.scrollLeft,top:C.scrollTop});for(typeof d.focus=="function"&&d.focus(),d=0;dl?32:l,E.T=null,l=hc,hc=null;var i=Ml,c=ml;if(We=0,Xa=Ml=null,ml=0,(Ae&6)!==0)throw Error(f(331));var d=Ae;if(Ae|=4,od(i.current),cd(i,i.current,c,l),Ae=d,Bn(0,!1),gt&&typeof gt.onPostCommitFiberRoot=="function")try{gt.onPostCommitFiberRoot(ln,i)}catch{}return!0}finally{q.p=n,E.T=a,Cd(e,t)}}function zd(e,t,l){t=Mt(l,t),t=Js(e.stateNode,t,2),e=Tl(e,t,2),e!==null&&(nn(e,2),Ft(e))}function Oe(e,t,l){if(e.tag===3)zd(e,e,l);else for(;t!==null;){if(t.tag===3){zd(t,e,l);break}else if(t.tag===1){var a=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(Dl===null||!Dl.has(a))){e=Mt(l,e),l=Do(2),a=Tl(t,l,2),a!==null&&(Mo(l,a,t,e),nn(a,2),Ft(a));break}}t=t.return}}function gc(e,t,l){var a=e.pingCache;if(a===null){a=e.pingCache=new Zp;var n=new Set;a.set(t,n)}else n=a.get(t),n===void 0&&(n=new Set,a.set(t,n));n.has(l)||(fc=!0,n.add(l),e=Fp.bind(null,e,t,l),t.then(e,e))}function Fp(e,t,l){var a=e.pingCache;a!==null&&a.delete(t),e.pingedLanes|=e.suspendedLanes&l,e.warmLanes&=~l,Ue===e&&(Se&l)===l&&(Xe===4||Xe===3&&(Se&62914560)===Se&&300>yt()-$i?(Ae&2)===0&&Va(e,0):oc|=l,Qa===Se&&(Qa=0)),Ft(e)}function Dd(e,t){t===0&&(t=Nr()),e=$l(e,t),e!==null&&(nn(e,t),Ft(e))}function Wp(e){var t=e.memoizedState,l=0;t!==null&&(l=t.retryLane),Dd(e,l)}function Ip(e,t){var l=0;switch(e.tag){case 31:case 13:var a=e.stateNode,n=e.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(f(314))}a!==null&&a.delete(t),Dd(e,l)}function Pp(e,t){return zu(e,t)}var lu=null,Ka=null,bc=!1,au=!1,_c=!1,Ul=0;function Ft(e){e!==Ka&&e.next===null&&(Ka===null?lu=Ka=e:Ka=Ka.next=e),au=!0,bc||(bc=!0,tv())}function Bn(e,t){if(!_c&&au){_c=!0;do for(var l=!1,a=lu;a!==null;){if(e!==0){var n=a.pendingLanes;if(n===0)var i=0;else{var c=a.suspendedLanes,d=a.pingedLanes;i=(1<<31-bt(42|e)+1)-1,i&=n&~(c&~d),i=i&201326741?i&201326741|1:i?i|2:0}i!==0&&(l=!0,Hd(a,i))}else i=Se,i=si(a,a===Ue?i:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(i&3)===0||an(a,i)||(l=!0,Hd(a,i));a=a.next}while(l);_c=!1}}function ev(){Md()}function Md(){au=bc=!1;var e=0;Ul!==0&&ov()&&(e=Ul);for(var t=yt(),l=null,a=lu;a!==null;){var n=a.next,i=wd(a,t);i===0?(a.next=null,l===null?lu=n:l.next=n,n===null&&(Ka=l)):(l=a,(e!==0||(i&3)!==0)&&(au=!0)),a=n}We!==0&&We!==5||Bn(e),Ul!==0&&(Ul=0)}function wd(e,t){for(var l=e.suspendedLanes,a=e.pingedLanes,n=e.expirationTimes,i=e.pendingLanes&-62914561;0d)break;var z=v.transferSize,U=v.initiatorType;z&&Vd(U)&&(v=v.responseEnd,c+=z*(v"u"?null:document;function lm(e,t,l){var a=Ja;if(a&&typeof t=="string"&&t){var n=zt(t);n='link[rel="'+e+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),tm.has(n)||(tm.add(n),e={rel:e,crossOrigin:l,href:t},a.querySelector(n)===null&&(t=a.createElement("link"),ut(t,"link",e),et(t),a.head.appendChild(t)))}}function _v(e){hl.D(e),lm("dns-prefetch",e,null)}function xv(e,t){hl.C(e,t),lm("preconnect",e,t)}function Sv(e,t,l){hl.L(e,t,l);var a=Ja;if(a&&e&&t){var n='link[rel="preload"][as="'+zt(t)+'"]';t==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+zt(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+zt(l.imageSizes)+'"]')):n+='[href="'+zt(e)+'"]';var i=n;switch(t){case"style":i=ka(e);break;case"script":i=$a(e)}Bt.has(i)||(e=N({rel:"preload",href:t==="image"&&l&&l.imageSrcSet?void 0:e,as:t},l),Bt.set(i,e),a.querySelector(n)!==null||t==="style"&&a.querySelector(Xn(i))||t==="script"&&a.querySelector(Vn(i))||(t=a.createElement("link"),ut(t,"link",e),et(t),a.head.appendChild(t)))}}function jv(e,t){hl.m(e,t);var l=Ja;if(l&&e){var a=t&&typeof t.as=="string"?t.as:"script",n='link[rel="modulepreload"][as="'+zt(a)+'"][href="'+zt(e)+'"]',i=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":i=$a(e)}if(!Bt.has(i)&&(e=N({rel:"modulepreload",href:e},t),Bt.set(i,e),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(Vn(i)))return}a=l.createElement("link"),ut(a,"link",e),et(a),l.head.appendChild(a)}}}function Nv(e,t,l){hl.S(e,t,l);var a=Ja;if(a&&e){var n=va(a).hoistableStyles,i=ka(e);t=t||"default";var c=n.get(i);if(!c){var d={loading:0,preload:null};if(c=a.querySelector(Xn(i)))d.loading=5;else{e=N({rel:"stylesheet",href:e,"data-precedence":t},l),(l=Bt.get(i))&&Hc(e,l);var v=c=a.createElement("link");et(v),ut(v,"link",e),v._p=new Promise(function(R,z){v.onload=R,v.onerror=z}),v.addEventListener("load",function(){d.loading|=1}),v.addEventListener("error",function(){d.loading|=2}),d.loading|=4,cu(c,t,a)}c={type:"stylesheet",instance:c,count:1,state:d},n.set(i,c)}}}function Ev(e,t){hl.X(e,t);var l=Ja;if(l&&e){var a=va(l).hoistableScripts,n=$a(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),et(i),ut(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function Tv(e,t){hl.M(e,t);var l=Ja;if(l&&e){var a=va(l).hoistableScripts,n=$a(e),i=a.get(n);i||(i=l.querySelector(Vn(n)),i||(e=N({src:e,async:!0,type:"module"},t),(t=Bt.get(n))&&qc(e,t),i=l.createElement("script"),et(i),ut(i,"link",e),l.head.appendChild(i)),i={type:"script",instance:i,count:1,state:null},a.set(n,i))}}function am(e,t,l,a){var n=(n=se.current)?su(n):null;if(!n)throw Error(f(446));switch(e){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(t=ka(l.href),l=va(n).hoistableStyles,a=l.get(t),a||(a={type:"style",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){e=ka(l.href);var i=va(n).hoistableStyles,c=i.get(e);if(c||(n=n.ownerDocument||n,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},i.set(e,c),(i=n.querySelector(Xn(e)))&&!i._p&&(c.instance=i,c.state.loading=5),Bt.has(e)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Bt.set(e,l),i||Rv(n,e,l,c.state))),t&&a===null)throw Error(f(528,""));return c}if(t&&a!==null)throw Error(f(529,""));return null;case"script":return t=l.async,l=l.src,typeof l=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=$a(l),l=va(n).hoistableScripts,a=l.get(t),a||(a={type:"script",instance:null,count:0,state:null},l.set(t,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(f(444,e))}}function ka(e){return'href="'+zt(e)+'"'}function Xn(e){return'link[rel="stylesheet"]['+e+"]"}function nm(e){return N({},e,{"data-precedence":e.precedence,precedence:null})}function Rv(e,t,l,a){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?a.loading=1:(t=e.createElement("link"),a.preload=t,t.addEventListener("load",function(){return a.loading|=1}),t.addEventListener("error",function(){return a.loading|=2}),ut(t,"link",l),et(t),e.head.appendChild(t))}function $a(e){return'[src="'+zt(e)+'"]'}function Vn(e){return"script[async]"+e}function im(e,t,l){if(t.count++,t.instance===null)switch(t.type){case"style":var a=e.querySelector('style[data-href~="'+zt(l.href)+'"]');if(a)return t.instance=a,et(a),a;var n=N({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),et(a),ut(a,"style",n),cu(a,l.precedence,e),t.instance=a;case"stylesheet":n=ka(l.href);var i=e.querySelector(Xn(n));if(i)return t.state.loading|=4,t.instance=i,et(i),i;a=nm(l),(n=Bt.get(n))&&Hc(a,n),i=(e.ownerDocument||e).createElement("link"),et(i);var c=i;return c._p=new Promise(function(d,v){c.onload=d,c.onerror=v}),ut(i,"link",a),t.state.loading|=4,cu(i,l.precedence,e),t.instance=i;case"script":return i=$a(l.src),(n=e.querySelector(Vn(i)))?(t.instance=n,et(n),n):(a=l,(n=Bt.get(i))&&(a=N({},l),qc(a,n)),e=e.ownerDocument||e,n=e.createElement("script"),et(n),ut(n,"link",a),e.head.appendChild(n),t.instance=n);case"void":return null;default:throw Error(f(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(a=t.instance,t.state.loading|=4,cu(a,l.precedence,e));return t.instance}function cu(e,t,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,i=n,c=0;c title"):null)}function Av(e,t,l){if(l===1||t.itemProp!=null)return!1;switch(e){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;return t.rel==="stylesheet"?(e=t.disabled,typeof t.precedence=="string"&&e==null):!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 cm(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function Cv(e,t,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=ka(a.href),i=t.querySelector(Xn(n));if(i){t=i._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=fu.bind(e),t.then(e,e)),l.state.loading|=4,l.instance=i,et(i);return}i=t.ownerDocument||t,a=nm(a),(n=Bt.get(n))&&Hc(a,n),i=i.createElement("link"),et(i);var c=i;c._p=new Promise(function(d,v){c.onload=d,c.onerror=v}),ut(i,"link",a),l.instance=i}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(l,t),(t=l.state.preload)&&(l.state.loading&3)===0&&(e.count++,l=fu.bind(e),t.addEventListener("load",l),t.addEventListener("error",l))}}var Lc=0;function Ov(e,t){return e.stylesheets&&e.count===0&&du(e,e.stylesheets),0Lc?50:800)+t);return e.unsuspend=l,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function fu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)du(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ou=null;function du(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ou=new Map,t.forEach(zv,e),ou=null,fu.call(e))}function zv(e,t){if(!(t.state.loading&4)){var l=ou.get(e);if(l)var a=l.get(null);else{l=new Map,ou.set(e,l);for(var n=e.querySelectorAll("link[data-precedence],style[data-precedence]"),i=0;i"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(r){console.error(r)}}return s(),Jc.exports=Jv(),Jc.exports}var $v=kv();var Dm="popstate";function Mm(s){return typeof s=="object"&&s!=null&&"pathname"in s&&"search"in s&&"hash"in s&&"state"in s&&"key"in s}function Fv(s={}){function r(m,h){let{pathname:b="/",search:j="",hash:x=""}=oa(m.location.hash.substring(1));return!b.startsWith("/")&&!b.startsWith(".")&&(b="/"+b),ar("",{pathname:b,search:j,hash:x},h.state&&h.state.usr||null,h.state&&h.state.key||"default")}function o(m,h){let b=m.document.querySelector("base"),j="";if(b&&b.getAttribute("href")){let x=m.location.href,y=x.indexOf("#");j=y===-1?x:x.slice(0,y)}return j+"#"+(typeof h=="string"?h:ei(h))}function f(m,h){Rt(m.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(h)})`)}return Iv(r,o,f,s)}function Ge(s,r){if(s===!1||s===null||typeof s>"u")throw new Error(r)}function Rt(s,r){if(!s){typeof console<"u"&&console.warn(r);try{throw new Error(r)}catch{}}}function Wv(){return Math.random().toString(36).substring(2,10)}function wm(s,r){return{usr:s.state,key:s.key,idx:r,masked:s.unstable_mask?{pathname:s.pathname,search:s.search,hash:s.hash}:void 0}}function ar(s,r,o=null,f,m){return{pathname:typeof s=="string"?s:s.pathname,search:"",hash:"",...typeof r=="string"?oa(r):r,state:o,key:r&&r.key||f||Wv(),unstable_mask:m}}function ei({pathname:s="/",search:r="",hash:o=""}){return r&&r!=="?"&&(s+=r.charAt(0)==="?"?r:"?"+r),o&&o!=="#"&&(s+=o.charAt(0)==="#"?o:"#"+o),s}function oa(s){let r={};if(s){let o=s.indexOf("#");o>=0&&(r.hash=s.substring(o),s=s.substring(0,o));let f=s.indexOf("?");f>=0&&(r.search=s.substring(f),s=s.substring(0,f)),s&&(r.pathname=s)}return r}function Iv(s,r,o,f={}){let{window:m=document.defaultView,v5Compat:h=!1}=f,b=m.history,j="POP",x=null,y=O();y==null&&(y=0,b.replaceState({...b.state,idx:y},""));function O(){return(b.state||{idx:null}).idx}function N(){j="POP";let H=O(),Z=H==null?null:H-y;y=H,x&&x({action:j,location:Q.location,delta:Z})}function L(H,Z){j="PUSH";let ee=Mm(H)?H:ar(Q.location,H,Z);o&&o(ee,H),y=O()+1;let I=wm(ee,y),ye=Q.createHref(ee.unstable_mask||ee);try{b.pushState(I,"",ye)}catch(re){if(re instanceof DOMException&&re.name==="DataCloneError")throw re;m.location.assign(ye)}h&&x&&x({action:j,location:Q.location,delta:1})}function G(H,Z){j="REPLACE";let ee=Mm(H)?H:ar(Q.location,H,Z);o&&o(ee,H),y=O();let I=wm(ee,y),ye=Q.createHref(ee.unstable_mask||ee);b.replaceState(I,"",ye),h&&x&&x({action:j,location:Q.location,delta:0})}function J(H){return Pv(H)}let Q={get action(){return j},get location(){return s(m,b)},listen(H){if(x)throw new Error("A history only accepts one active listener");return m.addEventListener(Dm,N),x=H,()=>{m.removeEventListener(Dm,N),x=null}},createHref(H){return r(m,H)},createURL:J,encodeLocation(H){let Z=J(H);return{pathname:Z.pathname,search:Z.search,hash:Z.hash}},push:L,replace:G,go(H){return b.go(H)}};return Q}function Pv(s,r=!1){let o="http://localhost";typeof window<"u"&&(o=window.location.origin!=="null"?window.location.origin:window.location.href),Ge(o,"No window.location.(origin|href) available to create URL");let f=typeof s=="string"?s:ei(s);return f=f.replace(/ $/,"%20"),!r&&f.startsWith("//")&&(f=o+f),new URL(f,o)}function Xm(s,r,o="/"){return ey(s,r,o,!1)}function ey(s,r,o,f){let m=typeof r=="string"?oa(r):r,h=vl(m.pathname||"/",o);if(h==null)return null;let b=Vm(s);ty(b);let j=null;for(let x=0;j==null&&x{let O={relativePath:y===void 0?b.path||"":y,caseSensitive:b.caseSensitive===!0,childrenIndex:j,route:b};if(O.relativePath.startsWith("/")){if(!O.relativePath.startsWith(f)&&x)return;Ge(O.relativePath.startsWith(f),`Absolute route path "${O.relativePath}" nested under path "${f}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),O.relativePath=O.relativePath.slice(f.length)}let N=Vt([f,O.relativePath]),L=o.concat(O);b.children&&b.children.length>0&&(Ge(b.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${N}".`),Vm(b.children,r,L,N,x)),!(b.path==null&&!b.index)&&r.push({path:N,score:cy(N,b.index),routesMeta:L})};return s.forEach((b,j)=>{if(b.path===""||!b.path?.includes("?"))h(b,j);else for(let x of Zm(b.path))h(b,j,!0,x)}),r}function Zm(s){let r=s.split("/");if(r.length===0)return[];let[o,...f]=r,m=o.endsWith("?"),h=o.replace(/\?$/,"");if(f.length===0)return m?[h,""]:[h];let b=Zm(f.join("/")),j=[];return j.push(...b.map(x=>x===""?h:[h,x].join("/"))),m&&j.push(...b),j.map(x=>s.startsWith("/")&&x===""?"/":x)}function ty(s){s.sort((r,o)=>r.score!==o.score?o.score-r.score:ry(r.routesMeta.map(f=>f.childrenIndex),o.routesMeta.map(f=>f.childrenIndex)))}var ly=/^:[\w-]+$/,ay=3,ny=2,iy=1,uy=10,sy=-2,Um=s=>s==="*";function cy(s,r){let o=s.split("/"),f=o.length;return o.some(Um)&&(f+=sy),r&&(f+=ny),o.filter(m=>!Um(m)).reduce((m,h)=>m+(ly.test(h)?ay:h===""?iy:uy),f)}function ry(s,r){return s.length===r.length&&s.slice(0,-1).every((f,m)=>f===r[m])?s[s.length-1]-r[r.length-1]:0}function fy(s,r,o=!1){let{routesMeta:f}=s,m={},h="/",b=[];for(let j=0;j{if(O==="*"){let J=j[L]||"";b=h.slice(0,h.length-J.length).replace(/(.)\/+$/,"$1")}const G=j[L];return N&&!G?y[O]=void 0:y[O]=(G||"").replace(/%2F/g,"/"),y},{}),pathname:h,pathnameBase:b,pattern:s}}function oy(s,r=!1,o=!0){Rt(s==="*"||!s.endsWith("*")||s.endsWith("/*"),`Route path "${s}" will be treated as if it were "${s.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${s.replace(/\*$/,"/*")}".`);let f=[],m="^"+s.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(b,j,x,y,O)=>{if(f.push({paramName:j,isOptional:x!=null}),x){let N=O.charAt(y+b.length);return N&&N!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return s.endsWith("*")?(f.push({paramName:"*"}),m+=s==="*"||s==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):o?m+="\\/*$":s!==""&&s!=="/"&&(m+="(?:(?=\\/|$))"),[new RegExp(m,r?void 0:"i"),f]}function dy(s){try{return s.split("/").map(r=>decodeURIComponent(r).replace(/\//g,"%2F")).join("/")}catch(r){return Rt(!1,`The URL path "${s}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${r}).`),s}}function vl(s,r){if(r==="/")return s;if(!s.toLowerCase().startsWith(r.toLowerCase()))return null;let o=r.endsWith("/")?r.length-1:r.length,f=s.charAt(o);return f&&f!=="/"?null:s.slice(o)||"/"}var my=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function hy(s,r="/"){let{pathname:o,search:f="",hash:m=""}=typeof s=="string"?oa(s):s,h;return o?(o=Km(o),o.startsWith("/")?h=Hm(o.substring(1),"/"):h=Hm(o,r)):h=r,{pathname:h,search:yy(f),hash:gy(m)}}function Hm(s,r){let o=Tu(r).split("/");return s.split("/").forEach(m=>{m===".."?o.length>1&&o.pop():m!=="."&&o.push(m)}),o.length>1?o.join("/"):"/"}function Wc(s,r,o,f){return`Cannot include a '${s}' character in a manually specified \`to.${r}\` field [${JSON.stringify(f)}]. Please separate it out to the \`to.${o}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function py(s){return s.filter((r,o)=>o===0||r.route.path&&r.route.path.length>0)}function fr(s){let r=py(s);return r.map((o,f)=>f===r.length-1?o.pathname:o.pathnameBase)}function Ru(s,r,o,f=!1){let m;typeof s=="string"?m=oa(s):(m={...s},Ge(!m.pathname||!m.pathname.includes("?"),Wc("?","pathname","search",m)),Ge(!m.pathname||!m.pathname.includes("#"),Wc("#","pathname","hash",m)),Ge(!m.search||!m.search.includes("#"),Wc("#","search","hash",m)));let h=s===""||m.pathname==="",b=h?"/":m.pathname,j;if(b==null)j=o;else{let N=r.length-1;if(!f&&b.startsWith("..")){let L=b.split("/");for(;L[0]==="..";)L.shift(),N-=1;m.pathname=L.join("/")}j=N>=0?r[N]:"/"}let x=hy(m,j),y=b&&b!=="/"&&b.endsWith("/"),O=(h||b===".")&&o.endsWith("/");return!x.pathname.endsWith("/")&&(y||O)&&(x.pathname+="/"),x}var Km=s=>s.replace(/\/\/+/g,"/"),Vt=s=>Km(s.join("/")),Tu=s=>s.replace(/\/+$/,""),vy=s=>Tu(s).replace(/^\/*/,"/"),yy=s=>!s||s==="?"?"":s.startsWith("?")?s:"?"+s,gy=s=>!s||s==="#"?"":s.startsWith("#")?s:"#"+s,by=class{constructor(s,r,o,f=!1){this.status=s,this.statusText=r||"",this.internal=f,o instanceof Error?(this.data=o.toString(),this.error=o):this.data=o}};function _y(s){return s!=null&&typeof s.status=="number"&&typeof s.statusText=="string"&&typeof s.internal=="boolean"&&"data"in s}function xy(s){let r=s.map(o=>o.route.path).filter(Boolean);return Vt(r)||"/"}var Jm=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function km(s,r){let o=s;if(typeof o!="string"||!my.test(o))return{absoluteURL:void 0,isExternal:!1,to:o};let f=o,m=!1;if(Jm)try{let h=new URL(window.location.href),b=o.startsWith("//")?new URL(h.protocol+o):new URL(o),j=vl(b.pathname,r);b.origin===h.origin&&j!=null?o=j+b.search+b.hash:m=!0}catch{Rt(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:f,isExternal:m,to:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var $m=["POST","PUT","PATCH","DELETE"];new Set($m);var Sy=["GET",...$m];new Set(Sy);var Pa=p.createContext(null);Pa.displayName="DataRouter";var Au=p.createContext(null);Au.displayName="DataRouterState";var Fm=p.createContext(!1);function jy(){return p.useContext(Fm)}var Wm=p.createContext({isTransitioning:!1});Wm.displayName="ViewTransition";var Ny=p.createContext(new Map);Ny.displayName="Fetchers";var Ey=p.createContext(null);Ey.displayName="Await";var At=p.createContext(null);At.displayName="Navigation";var ti=p.createContext(null);ti.displayName="Location";var Zt=p.createContext({outlet:null,matches:[],isDataRoute:!1});Zt.displayName="Route";var or=p.createContext(null);or.displayName="RouteError";var Im="REACT_ROUTER_ERROR",Ty="REDIRECT",Ry="ROUTE_ERROR_RESPONSE";function Ay(s){if(s.startsWith(`${Im}:${Ty}:{`))try{let r=JSON.parse(s.slice(28));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string"&&typeof r.location=="string"&&typeof r.reloadDocument=="boolean"&&typeof r.replace=="boolean")return r}catch{}}function Cy(s){if(s.startsWith(`${Im}:${Ry}:{`))try{let r=JSON.parse(s.slice(40));if(typeof r=="object"&&r&&typeof r.status=="number"&&typeof r.statusText=="string")return new by(r.status,r.statusText,r.data)}catch{}}function Oy(s,{relative:r}={}){Ge(en(),"useHref() may be used only in the context of a component.");let{basename:o,navigator:f}=p.useContext(At),{hash:m,pathname:h,search:b}=li(s,{relative:r}),j=h;return o!=="/"&&(j=h==="/"?o:Vt([o,h])),f.createHref({pathname:j,search:b,hash:m})}function en(){return p.useContext(ti)!=null}function Kt(){return Ge(en(),"useLocation() may be used only in the context of a component."),p.useContext(ti).location}var Pm="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function eh(s){p.useContext(At).static||p.useLayoutEffect(s)}function dr(){let{isDataRoute:s}=p.useContext(Zt);return s?Zy():zy()}function zy(){Ge(en(),"useNavigate() may be used only in the context of a component.");let s=p.useContext(Pa),{basename:r,navigator:o}=p.useContext(At),{matches:f}=p.useContext(Zt),{pathname:m}=Kt(),h=JSON.stringify(fr(f)),b=p.useRef(!1);return eh(()=>{b.current=!0}),p.useCallback((x,y={})=>{if(Rt(b.current,Pm),!b.current)return;if(typeof x=="number"){o.go(x);return}let O=Ru(x,JSON.parse(h),m,y.relative==="path");s==null&&r!=="/"&&(O.pathname=O.pathname==="/"?r:Vt([r,O.pathname])),(y.replace?o.replace:o.push)(O,y.state,y)},[r,o,h,m,s])}var Dy=p.createContext(null);function My(s){let r=p.useContext(Zt).outlet;return p.useMemo(()=>r&&p.createElement(Dy.Provider,{value:s},r),[r,s])}function li(s,{relative:r}={}){let{matches:o}=p.useContext(Zt),{pathname:f}=Kt(),m=JSON.stringify(fr(o));return p.useMemo(()=>Ru(s,JSON.parse(m),f,r==="path"),[s,m,f,r])}function wy(s,r){return th(s,r)}function th(s,r,o){Ge(en(),"useRoutes() may be used only in the context of a component.");let{navigator:f}=p.useContext(At),{matches:m}=p.useContext(Zt),h=m[m.length-1],b=h?h.params:{},j=h?h.pathname:"/",x=h?h.pathnameBase:"/",y=h&&h.route;{let H=y&&y.path||"";ah(j,!y||H.endsWith("*")||H.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${j}" (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 O=Kt(),N;if(r){let H=typeof r=="string"?oa(r):r;Ge(x==="/"||H.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 "${H.pathname}" was given in the \`location\` prop.`),N=H}else N=O;let L=N.pathname||"/",G=L;if(x!=="/"){let H=x.replace(/^\//,"").split("/");G="/"+L.replace(/^\//,"").split("/").slice(H.length).join("/")}let J=Xm(s,{pathname:G});Rt(y||J!=null,`No routes matched location "${N.pathname}${N.search}${N.hash}" `),Rt(J==null||J[J.length-1].route.element!==void 0||J[J.length-1].route.Component!==void 0||J[J.length-1].route.lazy!==void 0,`Matched leaf route at location "${N.pathname}${N.search}${N.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 Q=By(J&&J.map(H=>Object.assign({},H,{params:Object.assign({},b,H.params),pathname:Vt([x,f.encodeLocation?f.encodeLocation(H.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathname]),pathnameBase:H.pathnameBase==="/"?x:Vt([x,f.encodeLocation?f.encodeLocation(H.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathnameBase])})),m,o);return r&&Q?p.createElement(ti.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...N},navigationType:"POP"}},Q):Q}function Uy(){let s=Vy(),r=_y(s)?`${s.status} ${s.statusText}`:s instanceof Error?s.message:JSON.stringify(s),o=s instanceof Error?s.stack:null,f="rgba(200,200,200, 0.5)",m={padding:"0.5rem",backgroundColor:f},h={padding:"2px 4px",backgroundColor:f},b=null;return console.error("Error handled by React Router default ErrorBoundary:",s),b=p.createElement(p.Fragment,null,p.createElement("p",null,"💿 Hey developer 👋"),p.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",p.createElement("code",{style:h},"ErrorBoundary")," or"," ",p.createElement("code",{style:h},"errorElement")," prop on your route.")),p.createElement(p.Fragment,null,p.createElement("h2",null,"Unexpected Application Error!"),p.createElement("h3",{style:{fontStyle:"italic"}},r),o?p.createElement("pre",{style:m},o):null,b)}var Hy=p.createElement(Uy,null),lh=class extends p.Component{constructor(s){super(s),this.state={location:s.location,revalidation:s.revalidation,error:s.error}}static getDerivedStateFromError(s){return{error:s}}static getDerivedStateFromProps(s,r){return r.location!==s.location||r.revalidation!=="idle"&&s.revalidation==="idle"?{error:s.error,location:s.location,revalidation:s.revalidation}:{error:s.error!==void 0?s.error:r.error,location:r.location,revalidation:s.revalidation||r.revalidation}}componentDidCatch(s,r){this.props.onError?this.props.onError(s,r):console.error("React Router caught the following error during render",s)}render(){let s=this.state.error;if(this.context&&typeof s=="object"&&s&&"digest"in s&&typeof s.digest=="string"){const o=Cy(s.digest);o&&(s=o)}let r=s!==void 0?p.createElement(Zt.Provider,{value:this.props.routeContext},p.createElement(or.Provider,{value:s,children:this.props.component})):this.props.children;return this.context?p.createElement(qy,{error:s},r):r}};lh.contextType=Fm;var Ic=new WeakMap;function qy({children:s,error:r}){let{basename:o}=p.useContext(At);if(typeof r=="object"&&r&&"digest"in r&&typeof r.digest=="string"){let f=Ay(r.digest);if(f){let m=Ic.get(r);if(m)throw m;let h=km(f.location,o);if(Jm&&!Ic.get(r))if(h.isExternal||f.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const b=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:f.replace}));throw Ic.set(r,b),b}return p.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return s}function Ly({routeContext:s,match:r,children:o}){let f=p.useContext(Pa);return f&&f.static&&f.staticContext&&(r.route.errorElement||r.route.ErrorBoundary)&&(f.staticContext._deepestRenderedBoundaryId=r.route.id),p.createElement(Zt.Provider,{value:s},o)}function By(s,r=[],o){let f=o?.state;if(s==null){if(!f)return null;if(f.errors)s=f.matches;else if(r.length===0&&!f.initialized&&f.matches.length>0)s=f.matches;else return null}let m=s,h=f?.errors;if(h!=null){let O=m.findIndex(N=>N.route.id&&h?.[N.route.id]!==void 0);Ge(O>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(h).join(",")}`),m=m.slice(0,Math.min(m.length,O+1))}let b=!1,j=-1;if(o&&f){b=f.renderFallback;for(let O=0;O=0?m=m.slice(0,j+1):m=[m[0]];break}}}}let x=o?.onError,y=f&&x?(O,N)=>{x(O,{location:f.location,params:f.matches?.[0]?.params??{},unstable_pattern:xy(f.matches),errorInfo:N})}:void 0;return m.reduceRight((O,N,L)=>{let G,J=!1,Q=null,H=null;f&&(G=h&&N.route.id?h[N.route.id]:void 0,Q=N.route.errorElement||Hy,b&&(j<0&&L===0?(ah("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),J=!0,H=null):j===L&&(J=!0,H=N.route.hydrateFallbackElement||null)));let Z=r.concat(m.slice(0,L+1)),ee=()=>{let I;return G?I=Q:J?I=H:N.route.Component?I=p.createElement(N.route.Component,null):N.route.element?I=N.route.element:I=O,p.createElement(Ly,{match:N,routeContext:{outlet:O,matches:Z,isDataRoute:f!=null},children:I})};return f&&(N.route.ErrorBoundary||N.route.errorElement||L===0)?p.createElement(lh,{location:f.location,revalidation:f.revalidation,component:Q,error:G,children:ee(),routeContext:{outlet:null,matches:Z,isDataRoute:!0},onError:y}):ee()},null)}function mr(s){return`${s} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Yy(s){let r=p.useContext(Pa);return Ge(r,mr(s)),r}function Gy(s){let r=p.useContext(Au);return Ge(r,mr(s)),r}function Qy(s){let r=p.useContext(Zt);return Ge(r,mr(s)),r}function hr(s){let r=Qy(s),o=r.matches[r.matches.length-1];return Ge(o.route.id,`${s} can only be used on routes that contain a unique "id"`),o.route.id}function Xy(){return hr("useRouteId")}function Vy(){let s=p.useContext(or),r=Gy("useRouteError"),o=hr("useRouteError");return s!==void 0?s:r.errors?.[o]}function Zy(){let{router:s}=Yy("useNavigate"),r=hr("useNavigate"),o=p.useRef(!1);return eh(()=>{o.current=!0}),p.useCallback(async(m,h={})=>{Rt(o.current,Pm),o.current&&(typeof m=="number"?await s.navigate(m):await s.navigate(m,{fromRouteId:r,...h}))},[s,r])}var qm={};function ah(s,r,o){!r&&!qm[s]&&(qm[s]=!0,Rt(!1,o))}p.memo(Ky);function Ky({routes:s,future:r,state:o,isStatic:f,onError:m}){return th(s,void 0,{state:o,isStatic:f,onError:m})}function Jy({to:s,replace:r,state:o,relative:f}){Ge(en()," may be used only in the context of a component.");let{static:m}=p.useContext(At);Rt(!m," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:h}=p.useContext(Zt),{pathname:b}=Kt(),j=dr(),x=Ru(s,fr(h),b,f==="path"),y=JSON.stringify(x);return p.useEffect(()=>{j(JSON.parse(y),{replace:r,state:o,relative:f})},[j,y,f,r,o]),null}function ky(s){return My(s.context)}function Xl(s){Ge(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function $y({basename:s="/",children:r=null,location:o,navigationType:f="POP",navigator:m,static:h=!1,unstable_useTransitions:b}){Ge(!en(),"You cannot render a inside another . You should never have more than one in your app.");let j=s.replace(/^\/*/,"/"),x=p.useMemo(()=>({basename:j,navigator:m,static:h,unstable_useTransitions:b,future:{}}),[j,m,h,b]);typeof o=="string"&&(o=oa(o));let{pathname:y="/",search:O="",hash:N="",state:L=null,key:G="default",unstable_mask:J}=o,Q=p.useMemo(()=>{let H=vl(y,j);return H==null?null:{location:{pathname:H,search:O,hash:N,state:L,key:G,unstable_mask:J},navigationType:f}},[j,y,O,N,L,G,f,J]);return Rt(Q!=null,` is not able to match the URL "${y}${O}${N}" because it does not start with the basename, so the won't render anything.`),Q==null?null:p.createElement(At.Provider,{value:x},p.createElement(ti.Provider,{children:r,value:Q}))}function Fy({children:s,location:r}){return wy(nr(s),r)}function nr(s,r=[]){let o=[];return p.Children.forEach(s,(f,m)=>{if(!p.isValidElement(f))return;let h=[...r,m];if(f.type===p.Fragment){o.push.apply(o,nr(f.props.children,h));return}Ge(f.type===Xl,`[${typeof f.type=="string"?f.type:f.type.name}] is not a component. All component children of must be a or `),Ge(!f.props.index||!f.props.children,"An index route cannot have child routes.");let b={id:f.props.id||h.join("-"),caseSensitive:f.props.caseSensitive,element:f.props.element,Component:f.props.Component,index:f.props.index,path:f.props.path,middleware:f.props.middleware,loader:f.props.loader,action:f.props.action,hydrateFallbackElement:f.props.hydrateFallbackElement,HydrateFallback:f.props.HydrateFallback,errorElement:f.props.errorElement,ErrorBoundary:f.props.ErrorBoundary,hasErrorBoundary:f.props.hasErrorBoundary===!0||f.props.ErrorBoundary!=null||f.props.errorElement!=null,shouldRevalidate:f.props.shouldRevalidate,handle:f.props.handle,lazy:f.props.lazy};f.props.children&&(b.children=nr(f.props.children,h)),o.push(b)}),o}var xu="get",Su="application/x-www-form-urlencoded";function Cu(s){return typeof HTMLElement<"u"&&s instanceof HTMLElement}function Wy(s){return Cu(s)&&s.tagName.toLowerCase()==="button"}function Iy(s){return Cu(s)&&s.tagName.toLowerCase()==="form"}function Py(s){return Cu(s)&&s.tagName.toLowerCase()==="input"}function eg(s){return!!(s.metaKey||s.altKey||s.ctrlKey||s.shiftKey)}function tg(s,r){return s.button===0&&(!r||r==="_self")&&!eg(s)}function ir(s=""){return new URLSearchParams(typeof s=="string"||Array.isArray(s)||s instanceof URLSearchParams?s:Object.keys(s).reduce((r,o)=>{let f=s[o];return r.concat(Array.isArray(f)?f.map(m=>[o,m]):[[o,f]])},[]))}function lg(s,r){let o=ir(s);return r&&r.forEach((f,m)=>{o.has(m)||r.getAll(m).forEach(h=>{o.append(m,h)})}),o}var _u=null;function ag(){if(_u===null)try{new FormData(document.createElement("form"),0),_u=!1}catch{_u=!0}return _u}var ng=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Pc(s){return s!=null&&!ng.has(s)?(Rt(!1,`"${s}" is not a valid \`encType\` for \`\`/\`\` and will default to "${Su}"`),null):s}function ig(s,r){let o,f,m,h,b;if(Iy(s)){let j=s.getAttribute("action");f=j?vl(j,r):null,o=s.getAttribute("method")||xu,m=Pc(s.getAttribute("enctype"))||Su,h=new FormData(s)}else if(Wy(s)||Py(s)&&(s.type==="submit"||s.type==="image")){let j=s.form;if(j==null)throw new Error('Cannot submit a + + {detailOpen ? ( +
+ {(() => { + const bp = pricing.baselineProvider.trim(); + const cp = pricing.candidateProvider.trim(); + const bv = pricing.baselineVersion.trim(); + const cv = pricing.candidateVersion.trim(); + const providerSkew = bp.length > 0 && cp.length > 0 && bp !== cp; + const versionSkew = bv.length > 0 && cv.length > 0 && bv !== cv; + if (!providerSkew && !versionSkew) return null; + return ( +

+ {versionSkew ? ( + <> + Imported pricing table versions differ ( + {bv} vs{" "} + {cv}).{" "} + + ) : null} + {providerSkew ? ( + <> + Providers differ ( + {bp} vs{" "} + {cp}).{" "} + + ) : null} + Treat per-1k and catalog lines below as resolved per release; skew can change comparability. +

+ ); + })()} + {pricing.warnings.length > 0 ? ( + <> +

Pricing warnings

+
    + {pricing.warnings.map((w) => ( +
  • {w}
  • + ))} +
+ + ) : null} + {pricing.hints.length > 0 ? ( + <> +

Hints

+
    + {pricing.hints.map((h) => ( +
  • {h}
  • + ))} +
+ + ) : null} + {pricing.catalog && (pricing.catalog.enabled || pricing.catalog.warnings.length > 0) ? ( + <> +

Pricing catalog

+
+ {pricing.catalog.enabled ? ( +

+ Catalog v{pricing.catalog.version ?? "—"} · slots{" "} + {pricing.catalog.baselineSlot ?? "—"} →{" "} + {pricing.catalog.candidateSlot ?? "—"} + {pricing.catalog.baselineCost !== null && + pricing.catalog.candidateCost !== null && + pricing.catalog.deltaCost !== null ? ( + <> +
+ Comparable cost/run: {pricing.catalog.baselineCost.toFixed(6)} →{" "} + {pricing.catalog.candidateCost.toFixed(6)} (Δ{" "} + {pricing.catalog.deltaCost >= 0 ? "+" : ""} + {pricing.catalog.deltaCost.toFixed(6)}) + + ) : null} +

+ ) : ( +

Catalog disabled or incomplete for this diff.

+ )} + {pricing.catalog.warnings.length > 0 ? ( +
    + {pricing.catalog.warnings.map((w) => ( +
  • {w}
  • + ))} +
+ ) : null} +
+ + ) : null} + {pricing.changed && + pricing.prices && + pricing.prices.baselineInput !== null && + pricing.prices.candidateInput !== null && + pricing.prices.baselineOutput !== null && + pricing.prices.candidateOutput !== null ? ( + <> +

+ Per-1k token prices (USD) +

+
+
+
Input / 1k
+
+ {pricing.prices.baselineInput.toFixed(6)} → {pricing.prices.candidateInput.toFixed(6)} +
+
+
+
Output / 1k
+
+ {pricing.prices.baselineOutput.toFixed(6)} → {pricing.prices.candidateOutput.toFixed(6)} +
+
+
+

+ Cost rollups reflect pricing table and model identity; compare with catalog lines above when configured. +

+ + ) : null} +
+ ) : null} + + ); +} diff --git a/web/src/components/diff/DiffReleaseTwin.tsx b/web/src/components/diff/DiffReleaseTwin.tsx new file mode 100644 index 0000000..9a3f624 --- /dev/null +++ b/web/src/components/diff/DiffReleaseTwin.tsx @@ -0,0 +1,48 @@ +import type { PricingInfo } from "./diffPayload"; +import { pricingLine } from "./diffPayload"; + +export function DiffReleaseTwin({ + diffBaseline, + diffCandidate, + diffEnv, + diffWindow, + pricing, +}: { + diffBaseline: string; + diffCandidate: string; + diffEnv: string; + diffWindow: string; + pricing: PricingInfo | null; +}) { + const b = diffBaseline.trim(); + const c = diffCandidate.trim(); + return ( +
+

+ Release comparison +

+
+ Environment {diffEnv.trim() || "—"} · Window {diffWindow.trim() || "—"} +
+
+
+ Baseline (OLD) + + {b !== "" ? b : "—"} + +

{pricingLine(pricing, "baseline")}

+
+
+ → +
+
+ Candidate (NEW) + + {c !== "" ? c : "—"} + +

{pricingLine(pricing, "candidate")}

+
+
+
+ ); +} diff --git a/web/src/components/diff/DiffVerdictStack.tsx b/web/src/components/diff/DiffVerdictStack.tsx new file mode 100644 index 0000000..087a7a3 --- /dev/null +++ b/web/src/components/diff/DiffVerdictStack.tsx @@ -0,0 +1,35 @@ +import type { PolicyView } from "./diffPayload"; + +export function DiffVerdictStack({ policy }: { policy: PolicyView | null }) { + return ( + <> + {policy && !policy.passed && policy.reasons.length > 0 ? ( +
+ Blocked: {policy.reasons[0]} + {policy.reasons.length > 1 ? ( + + (+{policy.reasons.length - 1} more in policy evaluation) + + ) : null} +
+ ) : null} + + {policy ? ( +
+ {policy.passed + ? "Policy PASS — candidate may proceed if you accept the impact below." + : "Policy FAIL — do not promote this candidate for this evaluation."} +
+ ) : ( +
+ No policy block in this diff response — confirm server version and request payload before + treating the outcome as gated. +
+ )} + + ); +} diff --git a/web/src/components/diff/diffPayload.tsx b/web/src/components/diff/diffPayload.tsx new file mode 100644 index 0000000..9ad7f8e --- /dev/null +++ b/web/src/components/diff/diffPayload.tsx @@ -0,0 +1,158 @@ +export type DiffJson = Record; + +export function isRecord(v: unknown): v is Record { + return typeof v === "object" && v !== null; +} + +export type PolicyView = { + passed: boolean; + reasons: string[]; + evaluatedAt: string | null; +}; + +export function pickPolicy(data: DiffJson): PolicyView | null { + const p = data.policy; + if (!isRecord(p)) return null; + const passed = p.passed; + const reasons = p.reasons; + const ev = p.evaluated_at; + return { + passed: passed === true, + reasons: Array.isArray(reasons) ? reasons.filter((x): x is string => typeof x === "string") : [], + evaluatedAt: typeof ev === "string" ? ev : null, + }; +} + +export type CatalogInfo = { + enabled: boolean; + version: string | null; + baselineSlot: string | null; + candidateSlot: string | null; + baselineCost: number | null; + candidateCost: number | null; + deltaCost: number | null; + warnings: string[]; +}; + +export type PricingInfo = { + baselineProvider: string; + baselineVersion: string; + baselineModel: string; + candidateProvider: string; + candidateVersion: string; + candidateModel: string; + changed: boolean; + prices: PricingPrices | null; + warnings: string[]; + hints: string[]; + catalog: CatalogInfo | null; +}; + +export type PricingPrices = { + baselineInput: number | null; + baselineOutput: number | null; + candidateInput: number | null; + candidateOutput: number | null; +}; + +function pickPrices(p: Record): PricingPrices | null { + const block = p.prices; + if (!isRecord(block)) return null; + const numOrNull = (k: string): number | null => + typeof block[k] === "number" && Number.isFinite(block[k]) ? (block[k] as number) : null; + return { + baselineInput: numOrNull("baseline_input_usd_per_1k_tokens"), + baselineOutput: numOrNull("baseline_output_usd_per_1k_tokens"), + candidateInput: numOrNull("candidate_input_usd_per_1k_tokens"), + candidateOutput: numOrNull("candidate_output_usd_per_1k_tokens"), + }; +} + +function pickCatalog(block: Record): CatalogInfo { + const rawW = block.warnings; + const warnings = Array.isArray(rawW) ? rawW.filter((x): x is string => typeof x === "string") : []; + const numOrNull = (k: string): number | null => + typeof block[k] === "number" && Number.isFinite(block[k]) ? (block[k] as number) : null; + const strOrNull = (k: string): string | null => + typeof block[k] === "string" ? (block[k] as string) : null; + return { + enabled: block.enabled === true, + version: strOrNull("catalog_version"), + baselineSlot: strOrNull("baseline_slot_id"), + candidateSlot: strOrNull("candidate_slot_id"), + baselineCost: numOrNull("baseline_cost_per_run_usd"), + candidateCost: numOrNull("candidate_cost_per_run_usd"), + deltaCost: numOrNull("delta_cost_per_run_usd"), + warnings, + }; +} + +export function pickPricing(data: DiffJson): PricingInfo | null { + const p = data.pricing; + if (!isRecord(p)) return null; + const get = (k: string): string => (typeof p[k] === "string" ? (p[k] as string) : ""); + const rawWarnings = p.warnings; + const warnings = Array.isArray(rawWarnings) + ? rawWarnings.filter((x): x is string => typeof x === "string") + : []; + const rawHints = p.hints; + const hints = Array.isArray(rawHints) ? rawHints.filter((x): x is string => typeof x === "string") : []; + const catRaw = p.catalog; + const catalog = isRecord(catRaw) ? pickCatalog(catRaw) : null; + return { + baselineProvider: get("baseline_provider"), + baselineVersion: get("baseline_version"), + baselineModel: get("baseline_model"), + candidateProvider: get("candidate_provider"), + candidateVersion: get("candidate_version"), + candidateModel: get("candidate_model"), + changed: p.pricing_or_model_changed === true, + prices: pickPrices(p), + warnings, + hints, + catalog, + }; +} + +export function pricingLine(pricing: PricingInfo | null, side: "baseline" | "candidate"): string { + if (!pricing) return "—"; + const prov = side === "baseline" ? pricing.baselineProvider : pricing.candidateProvider; + const ver = side === "baseline" ? pricing.baselineVersion : pricing.candidateVersion; + const mod = side === "baseline" ? pricing.baselineModel : pricing.candidateModel; + const parts = [prov.trim(), ver.trim(), mod.trim()].filter(Boolean); + return parts.length > 0 ? parts.join(" · ") : "—"; +} + +export function DiffMetric({ + label, + baseline, + candidate, + delta, + suffix = "", +}: { + label: string; + baseline: string; + candidate: string; + delta?: string; + suffix?: string; +}) { + return ( +
+
{label}
+
+ + B {baseline} + {suffix} + + + → + + + C {candidate} + {suffix} + +
+ {delta ?
{delta}
: null} +
+ ); +} diff --git a/web/src/pages/DiffPage.tsx b/web/src/pages/DiffPage.tsx index 9d94c92..3c2ddae 100644 --- a/web/src/pages/DiffPage.tsx +++ b/web/src/pages/DiffPage.tsx @@ -1,167 +1,24 @@ -import { useEffect, useId, useState } from "react"; +import { useEffect, useState } from "react"; import { Link, useSearchParams } from "react-router-dom"; import { fetchJson } from "../api"; import { JsonPanel } from "../components/JsonPanel"; -import { Badge } from "../components/Badge"; +import { DiffChangeImpact } from "../components/diff/DiffChangeImpact"; +import { DiffDecisionCard } from "../components/diff/DiffDecisionCard"; +import { DiffPolicyPanel } from "../components/diff/DiffPolicyPanel"; +import { DiffReleaseTwin } from "../components/diff/DiffReleaseTwin"; +import { DiffVerdictStack } from "../components/diff/DiffVerdictStack"; +import { + type DiffJson, + isRecord, + pickPolicy, + pickPricing, +} from "../components/diff/diffPayload"; import { UI_READ_ONLY } from "../uiConfig"; import { pickTrimmedSearch, searchParamsFromRecord } from "../urlSearch"; -type DiffJson = Record; - -function isRecord(v: unknown): v is Record { - return typeof v === "object" && v !== null; -} - -function pickPolicy(data: DiffJson): { - passed: boolean; - reasons: string[]; - evaluatedAt: string | null; -} | null { - const p = data.policy; - if (!isRecord(p)) return null; - const passed = p.passed; - const reasons = p.reasons; - const ev = p.evaluated_at; - return { - passed: passed === true, - reasons: Array.isArray(reasons) ? reasons.filter((x): x is string => typeof x === "string") : [], - evaluatedAt: typeof ev === "string" ? ev : null, - }; -} - -type CatalogInfo = { - enabled: boolean; - version: string | null; - baselineSlot: string | null; - candidateSlot: string | null; - baselineCost: number | null; - candidateCost: number | null; - deltaCost: number | null; - warnings: string[]; -}; - -type PricingInfo = { - baselineProvider: string; - baselineVersion: string; - baselineModel: string; - candidateProvider: string; - candidateVersion: string; - candidateModel: string; - changed: boolean; - prices: PricingPrices | null; - warnings: string[]; - hints: string[]; - catalog: CatalogInfo | null; -}; - -type PricingPrices = { - baselineInput: number | null; - baselineOutput: number | null; - candidateInput: number | null; - candidateOutput: number | null; -}; - -function pickPrices(p: Record): PricingPrices | null { - const block = p.prices; - if (!isRecord(block)) return null; - const numOrNull = (k: string): number | null => - typeof block[k] === "number" && Number.isFinite(block[k]) ? (block[k] as number) : null; - return { - baselineInput: numOrNull("baseline_input_usd_per_1k_tokens"), - baselineOutput: numOrNull("baseline_output_usd_per_1k_tokens"), - candidateInput: numOrNull("candidate_input_usd_per_1k_tokens"), - candidateOutput: numOrNull("candidate_output_usd_per_1k_tokens"), - }; -} - -/** - * Coerces the `pricing` block from `/v1/diff` into a typed view. The contract - * is set by the route in `src/flightdeck/server/routes/actions.py`. - */ -function pickCatalog(block: Record): CatalogInfo { - const rawW = block.warnings; - const warnings = Array.isArray(rawW) ? rawW.filter((x): x is string => typeof x === "string") : []; - const numOrNull = (k: string): number | null => - typeof block[k] === "number" && Number.isFinite(block[k]) ? (block[k] as number) : null; - const strOrNull = (k: string): string | null => - typeof block[k] === "string" ? (block[k] as string) : null; - return { - enabled: block.enabled === true, - version: strOrNull("catalog_version"), - baselineSlot: strOrNull("baseline_slot_id"), - candidateSlot: strOrNull("candidate_slot_id"), - baselineCost: numOrNull("baseline_cost_per_run_usd"), - candidateCost: numOrNull("candidate_cost_per_run_usd"), - deltaCost: numOrNull("delta_cost_per_run_usd"), - warnings, - }; -} - -function pickPricing(data: DiffJson): PricingInfo | null { - const p = data.pricing; - if (!isRecord(p)) return null; - const get = (k: string): string => (typeof p[k] === "string" ? (p[k] as string) : ""); - const rawWarnings = p.warnings; - const warnings = Array.isArray(rawWarnings) - ? rawWarnings.filter((x): x is string => typeof x === "string") - : []; - const rawHints = p.hints; - const hints = Array.isArray(rawHints) ? rawHints.filter((x): x is string => typeof x === "string") : []; - const catRaw = p.catalog; - const catalog = isRecord(catRaw) ? pickCatalog(catRaw) : null; - return { - baselineProvider: get("baseline_provider"), - baselineVersion: get("baseline_version"), - baselineModel: get("baseline_model"), - candidateProvider: get("candidate_provider"), - candidateVersion: get("candidate_version"), - candidateModel: get("candidate_model"), - changed: p.pricing_or_model_changed === true, - prices: pickPrices(p), - warnings, - hints, - catalog, - }; -} - -function Metric({ - label, - baseline, - candidate, - delta, - suffix = "", -}: { - label: string; - baseline: string; - candidate: string; - delta?: string; - suffix?: string; -}) { - return ( -
-
{label}
-
- - B {baseline} - {suffix} - - - → - - - C {candidate} - {suffix} - -
- {delta ?
{delta}
: null} -
- ); -} - export function DiffPage() { const [searchParams, setSearchParams] = useSearchParams(); - const pricingPanelId = useId(); - const [pricingDetailOpen, setPricingDetailOpen] = useState(false); + const [diffResultSeq, setDiffResultSeq] = useState(0); const [diffBaseline, setDiffBaseline] = useState(""); const [diffCandidate, setDiffCandidate] = useState(""); const [diffWindow, setDiffWindow] = useState("7d"); @@ -179,10 +36,6 @@ export function DiffPage() { setDiffEnv(e !== "" ? e : "local"); }, [searchParams]); - useEffect(() => { - setPricingDetailOpen(false); - }, [diffOut]); - const runDiff = async () => { setDiffErr(null); setDiffOut(null); @@ -210,6 +63,7 @@ export function DiffPage() { body: JSON.stringify(body), }); setDiffOut(data); + setDiffResultSeq((n) => n + 1); } catch (e) { setDiffErr(String(e)); } finally { @@ -224,19 +78,6 @@ export function DiffPage() { const policy = diffOut ? pickPolicy(diffOut) : null; const pricing = diffOut ? pickPricing(diffOut) : null; - const num = (v: unknown) => (typeof v === "number" && Number.isFinite(v) ? String(v) : "—"); - const pct = (v: unknown) => - typeof v === "number" && Number.isFinite(v) ? `${(v * 100).toFixed(2)}%` : "—"; - - const pricingLine = (side: "baseline" | "candidate") => { - if (!pricing) return "—"; - const prov = side === "baseline" ? pricing.baselineProvider : pricing.candidateProvider; - const ver = side === "baseline" ? pricing.baselineVersion : pricing.candidateVersion; - const mod = side === "baseline" ? pricing.baselineModel : pricing.candidateModel; - const parts = [prov.trim(), ver.trim(), mod.trim()].filter(Boolean); - return parts.length > 0 ? parts.join(" · ") : "—"; - }; - const promoteSearch = !UI_READ_ONLY && diffCandidate.trim() !== "" ? searchParamsFromRecord({ @@ -323,338 +164,22 @@ export function DiffPage() { {diffOut ? ( <> -
-

- Release comparison -

-
- Environment {diffEnv.trim() || "—"} · Window {diffWindow.trim() || "—"} -
-
-
- Baseline (OLD) - - {diffBaseline.trim() !== "" ? diffBaseline.trim() : "—"} - -

{pricingLine("baseline")}

-
-
- → -
-
- Candidate (NEW) - - {diffCandidate.trim() !== "" ? diffCandidate.trim() : "—"} - -

{pricingLine("candidate")}

-
-
-
+ - {policy && !policy.passed && policy.reasons.length > 0 ? ( -
- Blocked: {policy.reasons[0]} - {policy.reasons.length > 1 ? ( - (+{policy.reasons.length - 1} more in policy evaluation) - ) : null} -
- ) : null} - - {policy ? ( -
- {policy.passed ? "Policy PASS — candidate may proceed if you accept the impact below." : "Policy FAIL — do not promote this candidate for this evaluation."} -
- ) : ( -
- No policy block in this diff response — confirm server version and request payload before - treating the outcome as gated. -
- )} - - {policy ? ( -
-
-

- Policy evaluation -

- {policy.passed ? "PASS" : "FAIL"} -
- {policy.evaluatedAt ? ( -

- evaluated_at {policy.evaluatedAt} -

- ) : null} - {policy.reasons.length > 0 ? ( -
    - {policy.reasons.map((r) => ( -
  • {r}
  • - ))} -
- ) : ( -

- {policy.passed - ? "No constraint messages returned (pass with empty reasons)." - : "No reasons listed — inspect raw JSON and server policy."} -

- )} -
- ) : null} + -
-
-

- Decision -

-

- {policy === null - ? "Run diff again after fixing the payload or server configuration." - : policy.passed - ? "Gate passed for this baseline, candidate, window, and environment. Next: promote from Actions if operational checks agree." - : "Gate failed — resolve policy findings or choose a different candidate/baseline before promoting."} -

-
- {!UI_READ_ONLY && policy?.passed === true && promoteSearch !== "" ? ( -
- - Continue to promote - - - Candidate release and window/environment are prefilled; reason is still required on Actions. - -
- ) : null} -
+ {policy ? : null} -
-
-

- Change impact -

-

- Evidence coverage, runtime rollups, and expandable pricing detail — causal drill-down stays here (no invented change rows until the API exposes them). -

-
-
-
-

- Sample coverage -

- {samples ? ( -

- Baseline runs: {num(samples.baseline_runs)} · Candidate runs:{" "} - {num(samples.candidate_runs)} · Confidence:{" "} - {String(samples.confidence ?? "—")} - {typeof samples.confidence_reason === "string" ? ` — ${samples.confidence_reason}` : null} -

- ) : ( -

No sample counts in this response.

- )} -
+ -
-

- Cost and quality rollups -

- {metrics ? ( -
- = 0 ? "+" : ""}${(metrics.delta_cost_per_run_pct * 100).toFixed(2)}% vs baseline)` - : "" - }` - : undefined - } - /> - - -
- ) : ( -

No metrics block in this response.

- )} -
+ -
-
-

- Pricing & model -

- {pricing ? ( -

- - {pricing.baselineProvider}/{pricing.baselineVersion} {pricing.baselineModel} - - - → - - - {pricing.candidateProvider}/{pricing.candidateVersion} {pricing.candidateModel} - - {pricing.changed ? ( - pricing/model changed - ) : ( - unchanged - )} -

- ) : ( -

No pricing block in this response.

- )} - {pricing ? ( - - ) : null} -
- {pricing && pricingDetailOpen ? ( -
- {(() => { - const bp = pricing.baselineProvider.trim(); - const cp = pricing.candidateProvider.trim(); - const bv = pricing.baselineVersion.trim(); - const cv = pricing.candidateVersion.trim(); - const providerSkew = bp.length > 0 && cp.length > 0 && bp !== cp; - const versionSkew = bv.length > 0 && cv.length > 0 && bv !== cv; - if (!providerSkew && !versionSkew) return null; - return ( -

- {versionSkew ? ( - <> - Imported pricing table versions differ ( - {bv} vs{" "} - {cv}).{" "} - - ) : null} - {providerSkew ? ( - <> - Providers differ ( - {bp} vs{" "} - {cp}).{" "} - - ) : null} - Treat per-1k and catalog lines below as resolved per release; skew can change comparability. -

- ); - })()} - {pricing.warnings.length > 0 ? ( - <> -

Pricing warnings

-
    - {pricing.warnings.map((w) => ( -
  • {w}
  • - ))} -
- - ) : null} - {pricing.hints.length > 0 ? ( - <> -

Hints

-
    - {pricing.hints.map((h) => ( -
  • {h}
  • - ))} -
- - ) : null} - {pricing.catalog && (pricing.catalog.enabled || pricing.catalog.warnings.length > 0) ? ( - <> -

Pricing catalog

-
- {pricing.catalog.enabled ? ( -

- Catalog v{pricing.catalog.version ?? "—"} · slots{" "} - {pricing.catalog.baselineSlot ?? "—"} →{" "} - {pricing.catalog.candidateSlot ?? "—"} - {pricing.catalog.baselineCost !== null && - pricing.catalog.candidateCost !== null && - pricing.catalog.deltaCost !== null ? ( - <> -
- Comparable cost/run: {pricing.catalog.baselineCost.toFixed(6)} →{" "} - {pricing.catalog.candidateCost.toFixed(6)} (Δ{" "} - {pricing.catalog.deltaCost >= 0 ? "+" : ""} - {pricing.catalog.deltaCost.toFixed(6)}) - - ) : null} -

- ) : ( -

Catalog disabled or incomplete for this diff.

- )} - {pricing.catalog.warnings.length > 0 ? ( -
    - {pricing.catalog.warnings.map((w) => ( -
  • {w}
  • - ))} -
- ) : null} -
- - ) : null} - {pricing.changed && - pricing.prices && - pricing.prices.baselineInput !== null && - pricing.prices.candidateInput !== null && - pricing.prices.baselineOutput !== null && - pricing.prices.candidateOutput !== null ? ( - <> -

Per-1k token prices (USD)

-
-
-
Input / 1k
-
- {pricing.prices.baselineInput.toFixed(6)} → {pricing.prices.candidateInput.toFixed(6)} -
-
-
-
Output / 1k
-
- {pricing.prices.baselineOutput.toFixed(6)} → {pricing.prices.candidateOutput.toFixed(6)} -
-
-
-

- Cost rollups reflect pricing table and model identity; compare with catalog lines above when - configured. -

- - ) : null} -
- ) : null} -
-
-
) : null} diff --git a/web/src/pages/OverviewPage.tsx b/web/src/pages/OverviewPage.tsx index f0728b9..0a1573d 100644 --- a/web/src/pages/OverviewPage.tsx +++ b/web/src/pages/OverviewPage.tsx @@ -407,7 +407,7 @@ export function OverviewPage() { > {shortId(r.release_id)} - +