diff --git a/frontend/src/components/scanInterface/ParameterCard.tsx b/frontend/src/components/scanInterface/ParameterCard.tsx index cb424603..172b264e 100644 --- a/frontend/src/components/scanInterface/ParameterCard.tsx +++ b/frontend/src/components/scanInterface/ParameterCard.tsx @@ -6,8 +6,12 @@ import { MenuItem, Select, TextField, + ToggleButton, + ToggleButtonGroup, } from "@mui/material"; import { useContext, useMemo } from "react"; +import { useParameter } from "../../hooks/useParameter"; +import { ParameterStoreContext } from "../../contexts/ParameterStoreContext"; import { DeviceInfoContext } from "../../contexts/DeviceInfoContext"; import { ExperimentsContext } from "../../contexts/ExperimentsContext"; import { ParameterDisplayGroupsContext } from "../../contexts/ParameterDisplayGroupsContext"; @@ -17,6 +21,7 @@ import { experimentIdToNamespace, } from "../../utils/experimentUtils"; import { + ScanInputMode, ScanParameterInfo, ScanPattern, scanPatterns, @@ -62,6 +67,7 @@ export const ParameterCard = ({ ); const deviceInfo = useContext(DeviceInfoContext); const experiments = useContext(ExperimentsContext); + const parameterStore = useContext(ParameterStoreContext); // Create a mapping from namespace to experiment display name const namespaceToDisplayName: Record = Object.fromEntries( @@ -138,6 +144,55 @@ export const ParameterCard = ({ ); }, [param, parameterDisplayGroups, deviceInfo]); + const inputMode: ScanInputMode = param.generation.inputMode ?? "startStop"; + + // Live value of the currently selected parameter — used to seed "Center" when + // switching to span/center mode. + const [currentParamValue] = useParameter(param.id); + const currentNumericValue = + typeof currentParamValue === "number" ? currentParamValue : null; + + // Derived quantities for span/center mode. Center and span are reconstructed from + // start/stop on every render, so round away the floating-point reconstruction + // noise (e.g. 0.015099999999996783 for a typed 0.0151) well above the ~16-digit + // float precision but far below any physically meaningful digit. + const roundFloatNoise = (value: number) => Number(value.toPrecision(12)); + const center = roundFloatNoise((param.generation.start + param.generation.stop) / 2); + const span = roundFloatNoise(param.generation.stop - param.generation.start); + + const handleInputModeChange = ( + _: React.MouseEvent, + newMode: ScanInputMode | null, + ) => { + if (!newMode || newMode === inputMode) return; + + if (newMode === "spanCenter") { + // Seed center from the live parameter value when available, otherwise keep the + // midpoint of the existing range. + const newCenter = currentNumericValue !== null ? currentNumericValue : center; + const newSpan = Math.abs(span) || 1; // keep existing span (>0 guard) + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + generation: { + ...param.generation, + inputMode: "spanCenter", + start: newCenter - newSpan / 2, + stop: newCenter + newSpan / 2, + }, + }, + }); + } else { + // Switching back to start/stop: just flip the mode flag; start/stop are already correct. + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { generation: { ...param.generation, inputMode: "startStop" } }, + }); + } + }; + return (
{ - dispatchScanInfoStateUpdate({ - type: "UPDATE_PARAMETER", - index, - payload: { id: e.target.value }, - }); + const newParamId = e.target.value; + + if (inputMode === "spanCenter") { + // Re-centre on the new parameter's live value (if numeric); keep the span. + const rawValue = parameterStore?.get(newParamId); + const newCenter = typeof rawValue === "number" ? rawValue : center; + const currentSpan = Math.abs(span) || 1; + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + id: newParamId, + generation: { + ...param.generation, + start: newCenter - currentSpan / 2, + stop: newCenter + currentSpan / 2, + }, + }, + }); + } else { + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { id: newParamId }, + }); + } }} renderValue={(value) => { const selectedDisplayName = parameterOptions[value]?.displayName; @@ -262,66 +338,149 @@ export const ParameterCard = ({
- - dispatchScanInfoStateUpdate({ - type: "UPDATE_PARAMETER", - index, - payload: { - generation: { - ...param.generation, - start: Number(e.target.value), - }, - }, - }) - } - variant="outlined" - slotProps={{ - input: { - inputProps: { - min: parameterOptions[param.id]?.min, - max: parameterOptions[param.id]?.max, - }, - }, - }} - /> - - dispatchScanInfoStateUpdate({ - type: "UPDATE_PARAMETER", - index, - payload: { - generation: { - ...param.generation, - stop: Number(e.target.value), + onChange={handleInputModeChange} + > + + Start / Stop + + + Center / Span + + + + {inputMode === "spanCenter" ? ( + <> + { + const newCenter = Number(e.target.value); + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + generation: { + ...param.generation, + start: newCenter - span / 2, + stop: newCenter + span / 2, + }, + }, + }); + }} + variant="outlined" + slotProps={{ + input: { + inputProps: { + min: parameterOptions[param.id]?.min, + max: parameterOptions[param.id]?.max, + }, }, - }, - }) - } - variant="outlined" - slotProps={{ - input: { - inputProps: { - min: parameterOptions[param.id]?.min, - max: parameterOptions[param.id]?.max, - }, - }, - }} - /> + }} + /> + { + const newSpan = Math.abs(Number(e.target.value)); + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + generation: { + ...param.generation, + start: center - newSpan / 2, + stop: center + newSpan / 2, + }, + }, + }); + }} + variant="outlined" + slotProps={{ + input: { inputProps: { min: 0 } }, + }} + /> + + ) : ( + <> + + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + generation: { + ...param.generation, + start: Number(e.target.value), + }, + }, + }) + } + variant="outlined" + slotProps={{ + input: { + inputProps: { + min: parameterOptions[param.id]?.min, + max: parameterOptions[param.id]?.max, + }, + }, + }} + /> + + dispatchScanInfoStateUpdate({ + type: "UPDATE_PARAMETER", + index, + payload: { + generation: { + ...param.generation, + stop: Number(e.target.value), + }, + }, + }) + } + variant="outlined" + slotProps={{ + input: { + inputProps: { + min: parameterOptions[param.id]?.min, + max: parameterOptions[param.id]?.max, + }, + }, + }} + /> + + )} + { const { scanInfoState, dispatchScanInfoStateUpdate } = useScanContext(); + const { parameterDisplayGroups } = useContext(ParameterDisplayGroupsContext); const notifications = useNotifications(); const [submitDisabled, setSubmitDisabled] = useState(false); @@ -92,7 +95,10 @@ const ScanInterface = ({ experimentId }: ScanInterfaceProps) => { event.preventDefault(); if (validateForm()) { - submitJob(experimentId, scanInfoState); + const parameterBounds = scanInfoState.parameters.map((param) => + getScanParameterBounds(param, parameterDisplayGroups), + ); + submitJob(experimentId, scanInfoState, parameterBounds); notifications.show("Job submitted", { severity: "success", autoHideDuration: 3000, diff --git a/frontend/src/types/ScanParameterGenerationSpec.ts b/frontend/src/types/ScanParameterGenerationSpec.ts index a3856e34..9adc87c8 100644 --- a/frontend/src/types/ScanParameterGenerationSpec.ts +++ b/frontend/src/types/ScanParameterGenerationSpec.ts @@ -1,8 +1,10 @@ -import { ScanPattern } from "./ScanParameterInfo"; +import { ScanInputMode, ScanPattern } from "./ScanParameterInfo"; export interface ScanParameterGenerationSpec { start: number; stop: number; points: number; pattern: ScanPattern; + /** Controls which pair of fields is shown in the UI. "startStop" is the default. */ + inputMode?: ScanInputMode; } diff --git a/frontend/src/types/ScanParameterInfo.ts b/frontend/src/types/ScanParameterInfo.ts index a8952844..ead8a0d2 100644 --- a/frontend/src/types/ScanParameterInfo.ts +++ b/frontend/src/types/ScanParameterInfo.ts @@ -3,6 +3,9 @@ import { ScanParameterGenerationSpec } from "./ScanParameterGenerationSpec"; export const scanPatterns = ["linear", "scatter", "centred", "forwardReverse"] as const; export type ScanPattern = (typeof scanPatterns)[number]; +export const scanInputModes = ["startStop", "spanCenter"] as const; +export type ScanInputMode = (typeof scanInputModes)[number]; + export interface ScanParameterInfo { id: string; deviceNameOrDisplayGroup: string; diff --git a/frontend/src/utils/scanUtils.ts b/frontend/src/utils/scanUtils.ts index 7c62c343..47474205 100644 --- a/frontend/src/utils/scanUtils.ts +++ b/frontend/src/utils/scanUtils.ts @@ -1,3 +1,42 @@ +import { GroupsByNamespace } from "../hooks/useParameterDisplayGroups"; +import { ScanParameterInfo } from "../types/ScanParameterInfo"; + +export interface ScanParameterBounds { + min: number | null; + max: number | null; +} + +/** + * Looks up the allowed value range of a scan parameter from the display group + * metadata (as provided by the experiment library). + * + * Device and realtime parameters carry no range metadata, so their bounds are null. + * + * @param param - The scan parameter to look up. + * @param parameterDisplayGroups - Display group metadata keyed by "namespace (group)". + * @returns The parameter's min/max bounds, null when unbounded or unknown. + */ +export const getScanParameterBounds = ( + param: ScanParameterInfo, + parameterDisplayGroups: GroupsByNamespace, +): ScanParameterBounds => { + if ( + !param.namespace || + !param.deviceNameOrDisplayGroup || + param.namespace === "Devices" || + param.namespace === "Real Time" + ) { + return { min: null, max: null }; + } + const group = + parameterDisplayGroups[`${param.namespace} (${param.deviceNameOrDisplayGroup})`]; + const metadata = group?.[param.id]; + return { + min: metadata?.min_value ?? null, + max: metadata?.max_value ?? null, + }; +}; + /** * Constructs a unique key for identifying a scanned parameter. * diff --git a/frontend/src/utils/submitJob.ts b/frontend/src/utils/submitJob.ts index b9a10c8f..6567ecc0 100644 --- a/frontend/src/utils/submitJob.ts +++ b/frontend/src/utils/submitJob.ts @@ -3,6 +3,7 @@ import { runMethod } from "../socket"; import { SerializedInteger } from "../types/SerializedObject"; import { ScanPattern } from "../types/ScanParameterInfo"; import { deserialize } from "./deserializer"; +import { ScanParameterBounds } from "./scanUtils"; import { openJobWindow } from "./windowUtils"; interface ScanParameterArgument { @@ -43,9 +44,19 @@ const generateScanValues = ( } }; -export const submitJob = (experimentId: string, scanInfoState: ScanInfoState) => { +const clampToBounds = (value: number, bounds: ScanParameterBounds): number => { + if (bounds.min !== null && value < bounds.min) return bounds.min; + if (bounds.max !== null && value > bounds.max) return bounds.max; + return value; +}; + +export const submitJob = ( + experimentId: string, + scanInfoState: ScanInfoState, + parameterBounds: ScanParameterBounds[] = [], +) => { const scan_parameters = scanInfoState.parameters.map( - ({ namespace, generation, deviceNameOrDisplayGroup, ...rest }) => { + ({ namespace, generation, deviceNameOrDisplayGroup, ...rest }, index) => { const param: ScanParameterArgument = { ...rest }; if (namespace == "Real Time") { delete param.id; @@ -54,9 +65,10 @@ export const submitJob = (experimentId: string, scanInfoState: ScanInfoState) => if (namespace == "Devices") { param.device_name = deviceNameOrDisplayGroup; } + const bounds = parameterBounds[index] ?? { min: null, max: null }; param.values = generateScanValues( - generation.start, - generation.stop, + clampToBounds(generation.start, bounds), + clampToBounds(generation.stop, bounds), generation.points, generation.pattern, ); diff --git a/src/icon/server/api/scheduler_controller.py b/src/icon/server/api/scheduler_controller.py index 66e854b4..305f4e01 100644 --- a/src/icon/server/api/scheduler_controller.py +++ b/src/icon/server/api/scheduler_controller.py @@ -58,6 +58,46 @@ def _resolve_display_name(self, parameter_id: str) -> str: return metadata["display_name"] return parameter_id + @staticmethod + def _clamp_value( + *, + value: float | bool | str, + min_value: float | None, + max_value: float | None, + ) -> float | bool | str: + if isinstance(value, bool) or not isinstance(value, int | float): + return value + if min_value is not None and value < min_value: + return type(value)(min_value) + if max_value is not None and value > max_value: + return type(value)(max_value) + return value + + def _clamp_scan_values_to_bounds( + self, *, scan_parameters: list[ScanParameter] + ) -> None: + """Clamp numeric scan values into their parameter's min/max metadata range. + + Out-of-range values are snapped to the nearest bound so the scan still runs, + restricted to the allowed range. Parameters without metadata (e.g. device + parameters) or without configured bounds are left untouched, as are + non-numeric values (booleans, strings). + """ + for param in scan_parameters: + if isinstance(param, RealtimeParameter): + continue + metadata = self._parameters_controller._all_parameter_metadata.get(param.id) + if metadata is None: + continue + min_value = metadata["min_value"] + max_value = metadata["max_value"] + if min_value is None and max_value is None: + continue + param.values = [ + self._clamp_value(value=value, min_value=min_value, max_value=max_value) + for value in param.values + ] + async def submit_job( self, *, @@ -132,6 +172,7 @@ def to_sqlite_model( ) for param in scan_parameters ] + self._clamp_scan_values_to_bounds(scan_parameters=concretized_params) realtime_params = [ param for param in concretized_params diff --git a/src/icon/server/frontend/assets/index-AX1n__Bd.js b/src/icon/server/frontend/assets/index-AX1n__Bd.js new file mode 100644 index 00000000..d7382ff6 --- /dev/null +++ b/src/icon/server/frontend/assets/index-AX1n__Bd.js @@ -0,0 +1,45 @@ +import{r as xb,a as Sb,b as y,c as ft,j as d,u as zr,S as Eb,d as Cb,B as _b,A as kf,e as wb,f as Et,I as _t,g as jb,h as tf,T as Nv,i as Tb,C as zv,k as Lv,l as ml,m as Db,n as l0,o as Ct,s as qf,p as ge,q as mn,t as Uv,v as la,P as Rb,D as Lr,w as Ef,x as Ab,L as Mb,y as Ob,z as jr,G as Nb,E as Yf,F as zb,H as Tr,J as Dr,K as Rr,M as nf,N as Co,O as Gf,Q as vl,R as Wt,U as _o,V as it,W as ka,X as qa,Y as sa,Z as Lb,_ as Bv,$ as Ub,a0 as ia,a1 as ra,a2 as en,a3 as Ya,a4 as Bb,a5 as i0,a6 as Fe,a7 as Hb,a8 as Vb,a9 as wo,aa as jo,ab as To,ac as kb,ad as Pf,ae as qb,af as Yb,ag as Gb,ah as Pb,ai as Xb,aj as Qb,ak as za}from"./mui-D4RjQ82o.js";import{u as Kb,i as Zb,a as Fb,b as $b,c as Jb,d as Ib,e as Wb,f as ex,g as tx,h as nx,j as ax,k as lx,l as ix}from"./echarts-D1BCANXe.js";import"./zrender-Co-hdh87.js";(function(){const l=document.createElement("link").relList;if(l&&l.supports&&l.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))s(u);new MutationObserver(u=>{for(const f of u)if(f.type==="childList")for(const h of f.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&s(h)}).observe(document,{childList:!0,subtree:!0});function r(u){const f={};return u.integrity&&(f.integrity=u.integrity),u.referrerPolicy&&(f.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?f.credentials="include":u.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function s(u){if(u.ep)return;u.ep=!0;const f=r(u);fetch(u.href,f)}})();var af={exports:{}},mr={},lf={exports:{}},rf={};/** + * @license React + * scheduler.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var r0;function rx(){return r0||(r0=1,(function(a){function l(T,O){var X=T.length;T.push(O);e:for(;0>>1,ne=T[le];if(0>>1;leu(ce,X))Leu(rt,ce)?(T[le]=rt,T[Le]=X,le=Le):(T[le]=ce,T[_e]=X,le=_e);else if(Leu(rt,X))T[le]=rt,T[Le]=X,le=Le;else break e}}return O}function u(T,O){var X=T.sortIndex-O.sortIndex;return X!==0?X:T.id-O.id}if(a.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var f=performance;a.unstable_now=function(){return f.now()}}else{var h=Date,m=h.now();a.unstable_now=function(){return h.now()-m}}var p=[],g=[],b=1,S=null,E=3,C=!1,j=!1,D=!1,R=!1,H=typeof setTimeout=="function"?setTimeout:null,k=typeof clearTimeout=="function"?clearTimeout:null,Q=typeof setImmediate<"u"?setImmediate:null;function Z(T){for(var O=r(g);O!==null;){if(O.callback===null)s(g);else if(O.startTime<=T)s(g),O.sortIndex=O.expirationTime,l(p,O);else break;O=r(g)}}function J(T){if(D=!1,Z(T),!j)if(r(p)!==null)j=!0,A||(A=!0,re());else{var O=r(g);O!==null&&se(J,O.startTime-T)}}var A=!1,N=-1,G=5,ee=-1;function te(){return R?!0:!(a.unstable_now()-eeT&&te());){var le=S.callback;if(typeof le=="function"){S.callback=null,E=S.priorityLevel;var ne=le(S.expirationTime<=T);if(T=a.unstable_now(),typeof ne=="function"){S.callback=ne,Z(T),O=!0;break t}S===r(p)&&s(p),Z(T)}else s(p);S=r(p)}if(S!==null)O=!0;else{var ve=r(g);ve!==null&&se(J,ve.startTime-T),O=!1}}break e}finally{S=null,E=X,C=!1}O=void 0}}finally{O?re():A=!1}}}var re;if(typeof Q=="function")re=function(){Q(ae)};else if(typeof MessageChannel<"u"){var ie=new MessageChannel,I=ie.port2;ie.port1.onmessage=ae,re=function(){I.postMessage(null)}}else re=function(){H(ae,0)};function se(T,O){N=H(function(){T(a.unstable_now())},O)}a.unstable_IdlePriority=5,a.unstable_ImmediatePriority=1,a.unstable_LowPriority=4,a.unstable_NormalPriority=3,a.unstable_Profiling=null,a.unstable_UserBlockingPriority=2,a.unstable_cancelCallback=function(T){T.callback=null},a.unstable_forceFrameRate=function(T){0>T||125le?(T.sortIndex=X,l(g,T),r(p)===null&&T===r(g)&&(D?(k(N),N=-1):D=!0,se(J,X-le))):(T.sortIndex=ne,l(p,T),j||C||(j=!0,A||(A=!0,re()))),T},a.unstable_shouldYield=te,a.unstable_wrapCallback=function(T){var O=E;return function(){var X=E;E=O;try{return T.apply(this,arguments)}finally{E=X}}}})(rf)),rf}var s0;function sx(){return s0||(s0=1,lf.exports=rx()),lf.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var o0;function ox(){if(o0)return mr;o0=1;var a=sx(),l=xb(),r=Sb();function s(e){var t="https://react.dev/errors/"+e;if(1ne||(e.current=le[ne],le[ne]=null,ne--)}function ce(e,t){ne++,le[ne]=e.current,e.current=t}var Le=ve(null),rt=ve(null),Ke=ve(null),vn=ve(null);function Ie(e,t){switch(ce(Ke,t),ce(rt,e),ce(Le,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Op(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Op(t),e=Np(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}_e(Le),ce(Le,e)}function Yt(){_e(Le),_e(rt),_e(Ke)}function dt(e){e.memoizedState!==null&&ce(vn,e);var t=Le.current,n=Np(t,e.type);t!==n&&(ce(rt,e),ce(Le,n))}function yn(e){rt.current===e&&(_e(Le),_e(rt)),vn.current===e&&(_e(vn),ur._currentValue=X)}var xl=Object.prototype.hasOwnProperty,gi=a.unstable_scheduleCallback,gn=a.unstable_cancelCallback,Zo=a.unstable_shouldYield,Fo=a.unstable_requestPaint,Gt=a.unstable_now,$o=a.unstable_getCurrentPriorityLevel,Pr=a.unstable_ImmediatePriority,Xr=a.unstable_UserBlockingPriority,Sl=a.unstable_NormalPriority,Bn=a.unstable_LowPriority,ua=a.unstable_IdlePriority,Qr=a.log,bi=a.unstable_setDisableYieldValue,Lt=null,We=null;function bn(e){if(typeof Qr=="function"&&bi(e),We&&typeof We.setStrictMode=="function")try{We.setStrictMode(Lt,e)}catch{}}var wt=Math.clz32?Math.clz32:Kr,Jo=Math.log,wn=Math.LN2;function Kr(e){return e>>>=0,e===0?32:31-(Jo(e)/wn|0)|0}var Qa=256,Ka=4194304;function Hn(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:case 262144:case 524288:case 1048576:case 2097152:return e&4194048;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 Za(e,t,n){var i=e.pendingLanes;if(i===0)return 0;var o=0,c=e.suspendedLanes,v=e.pingedLanes;e=e.warmLanes;var x=i&134217727;return x!==0?(i=x&~c,i!==0?o=Hn(i):(v&=x,v!==0?o=Hn(v):n||(n=x&~e,n!==0&&(o=Hn(n))))):(x=i&~c,x!==0?o=Hn(x):v!==0?o=Hn(v):n||(n=i&~e,n!==0&&(o=Hn(n)))),o===0?0:t!==0&&t!==o&&(t&c)===0&&(c=o&-o,n=t&-t,c>=n||c===32&&(n&4194048)!==0)?t:o}function jn(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Zr(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 El(){var e=Qa;return Qa<<=1,(Qa&4194048)===0&&(Qa=256),e}function Fr(){var e=Ka;return Ka<<=1,(Ka&62914560)===0&&(Ka=4194304),e}function Cl(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Fa(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function $r(e,t,n,i,o,c){var v=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var x=e.entanglements,_=e.expirationTimes,B=e.hiddenUpdates;for(n=v&~n;0)":-1o||_[i]!==B[o]){var P=` +`+_[i].replace(" at new "," at ");return e.displayName&&P.includes("")&&(P=P.replace("",e.displayName)),P}while(1<=i&&0<=o);break}}}finally{et=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?Ut(n):""}function Jr(e){switch(e.tag){case 26:case 27:case 5:return Ut(e.type);case 16:return Ut("Lazy");case 13:return Ut("Suspense");case 19:return Ut("SuspenseList");case 0:case 15:return fa(e.type,!1);case 11:return fa(e.type.render,!1);case 1:return fa(e.type,!0);case 31:return Ut("Activity");default:return""}}function Ir(e){try{var t="";do t+=Jr(e),e=e.return;while(e);return t}catch(n){return` +Error generating stack: `+n.message+` +`+n.stack}}function nn(e){switch(typeof e){case"bigint":case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Td(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function pg(e){var t=Td(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),i=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var o=n.get,c=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(v){i=""+v,c.call(this,v)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return i},setValue:function(v){i=""+v},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Wr(e){e._valueTracker||(e._valueTracker=pg(e))}function Dd(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),i="";return e&&(i=Td(e)?e.checked?"true":"false":e.value),e=i,e!==n?(t.setValue(e),!0):!1}function es(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var vg=/[\n"\\]/g;function an(e){return e.replace(vg,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Io(e,t,n,i,o,c,v,x){e.name="",v!=null&&typeof v!="function"&&typeof v!="symbol"&&typeof v!="boolean"?e.type=v:e.removeAttribute("type"),t!=null?v==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+nn(t)):e.value!==""+nn(t)&&(e.value=""+nn(t)):v!=="submit"&&v!=="reset"||e.removeAttribute("value"),t!=null?Wo(e,v,nn(t)):n!=null?Wo(e,v,nn(n)):i!=null&&e.removeAttribute("value"),o==null&&c!=null&&(e.defaultChecked=!!c),o!=null&&(e.checked=o&&typeof o!="function"&&typeof o!="symbol"),x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"?e.name=""+nn(x):e.removeAttribute("name")}function Rd(e,t,n,i,o,c,v,x){if(c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"&&(e.type=c),t!=null||n!=null){if(!(c!=="submit"&&c!=="reset"||t!=null))return;n=n!=null?""+nn(n):"",t=t!=null?""+nn(t):n,x||t===e.value||(e.value=t),e.defaultValue=t}i=i??o,i=typeof i!="function"&&typeof i!="symbol"&&!!i,e.checked=x?e.checked:!!i,e.defaultChecked=!!i,v!=null&&typeof v!="function"&&typeof v!="symbol"&&typeof v!="boolean"&&(e.name=v)}function Wo(e,t,n){t==="number"&&es(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function wl(e,t,n,i){if(e=e.options,t){t={};for(var o=0;o"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),lu=!1;if(Gn)try{var Ci={};Object.defineProperty(Ci,"passive",{get:function(){lu=!0}}),window.addEventListener("test",Ci,Ci),window.removeEventListener("test",Ci,Ci)}catch{lu=!1}var da=null,iu=null,ns=null;function Ud(){if(ns)return ns;var e,t=iu,n=t.length,i,o="value"in da?da.value:da.textContent,c=o.length;for(e=0;e=ji),Yd=" ",Gd=!1;function Pd(e,t){switch(e){case"keyup":return Pg.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Xd(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Rl=!1;function Qg(e,t){switch(e){case"compositionend":return Xd(t);case"keypress":return t.which!==32?null:(Gd=!0,Yd);case"textInput":return e=t.data,e===Yd&&Gd?null:e;default:return null}}function Kg(e,t){if(Rl)return e==="compositionend"||!cu&&Pd(e,t)?(e=Ud(),ns=iu=da=null,Rl=!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:n,offset:t-e};e=i}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Wd(n)}}function th(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?th(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function nh(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=es(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=es(e.document)}return t}function hu(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 t1=Gn&&"documentMode"in document&&11>=document.documentMode,Al=null,mu=null,Ai=null,pu=!1;function ah(e,t,n){var i=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;pu||Al==null||Al!==es(i)||(i=Al,"selectionStart"in i&&hu(i)?i={start:i.selectionStart,end:i.selectionEnd}:(i=(i.ownerDocument&&i.ownerDocument.defaultView||window).getSelection(),i={anchorNode:i.anchorNode,anchorOffset:i.anchorOffset,focusNode:i.focusNode,focusOffset:i.focusOffset}),Ai&&Ri(Ai,i)||(Ai=i,i=Qs(mu,"onSelect"),0>=v,o-=v,Xn=1<<32-wt(t)+o|n<c?c:8;var v=T.T,x={};T.T=x,ec(e,!1,t,n);try{var _=o(),B=T.S;if(B!==null&&B(x,_),_!==null&&typeof _=="object"&&typeof _.then=="function"){var P=c1(_,i);Xi(e,t,P,$t(e))}else Xi(e,t,i,$t(e))}catch(F){Xi(e,t,{then:function(){},status:"rejected",reason:F},$t())}finally{O.p=c,T.T=v}}function p1(){}function Iu(e,t,n,i){if(e.tag!==5)throw Error(s(476));var o=lm(e).queue;am(e,o,t,X,n===null?p1:function(){return im(e),n(i)})}function lm(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:X,baseState:X,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fn,lastRenderedState:X},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fn,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function im(e){var t=lm(e).next.queue;Xi(e,t,{},$t())}function Wu(){return At(ur)}function rm(){return pt().memoizedState}function sm(){return pt().memoizedState}function v1(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=$t();e=pa(n);var i=va(t,e,n);i!==null&&(Jt(i,t,n),Vi(i,t,n)),t={cache:Ru()},e.payload=t;return}t=t.return}}function y1(e,t,n){var i=$t();n={lane:i,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null},js(e)?um(t,n):(n=bu(e,t,n,i),n!==null&&(Jt(n,e,i),cm(n,t,i)))}function om(e,t,n){var i=$t();Xi(e,t,n,i)}function Xi(e,t,n,i){var o={lane:i,revertLane:0,action:n,hasEagerState:!1,eagerState:null,next:null};if(js(e))um(t,o);else{var c=e.alternate;if(e.lanes===0&&(c===null||c.lanes===0)&&(c=t.lastRenderedReducer,c!==null))try{var v=t.lastRenderedState,x=c(v,n);if(o.hasEagerState=!0,o.eagerState=x,Xt(x,v))return us(e,t,o,0),Ze===null&&os(),!1}catch{}finally{}if(n=bu(e,t,o,i),n!==null)return Jt(n,e,i),cm(n,t,i),!0}return!1}function ec(e,t,n,i){if(i={lane:2,revertLane:Oc(),action:i,hasEagerState:!1,eagerState:null,next:null},js(e)){if(t)throw Error(s(479))}else t=bu(e,n,i,2),t!==null&&Jt(t,e,2)}function js(e){var t=e.alternate;return e===De||t!==null&&t===De}function um(e,t){kl=xs=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function cm(e,t,n){if((n&4194048)!==0){var i=t.lanes;i&=e.pendingLanes,n|=i,t.lanes=n,Ja(e,n)}}var Ts={readContext:At,use:Es,useCallback:st,useContext:st,useEffect:st,useImperativeHandle:st,useLayoutEffect:st,useInsertionEffect:st,useMemo:st,useReducer:st,useRef:st,useState:st,useDebugValue:st,useDeferredValue:st,useTransition:st,useSyncExternalStore:st,useId:st,useHostTransitionStatus:st,useFormState:st,useActionState:st,useOptimistic:st,useMemoCache:st,useCacheRefresh:st},fm={readContext:At,use:Es,useCallback:function(e,t){return Ht().memoizedState=[e,t===void 0?null:t],e},useContext:At,useEffect:Zh,useImperativeHandle:function(e,t,n){n=n!=null?n.concat([e]):null,ws(4194308,4,Ih.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ws(4194308,4,e,t)},useInsertionEffect:function(e,t){ws(4,2,e,t)},useMemo:function(e,t){var n=Ht();t=t===void 0?null:t;var i=e();if(ul){bn(!0);try{e()}finally{bn(!1)}}return n.memoizedState=[i,t],i},useReducer:function(e,t,n){var i=Ht();if(n!==void 0){var o=n(t);if(ul){bn(!0);try{n(t)}finally{bn(!1)}}}else o=t;return i.memoizedState=i.baseState=o,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:o},i.queue=e,e=e.dispatch=y1.bind(null,De,e),[i.memoizedState,e]},useRef:function(e){var t=Ht();return e={current:e},t.memoizedState=e},useState:function(e){e=Zu(e);var t=e.queue,n=om.bind(null,De,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:$u,useDeferredValue:function(e,t){var n=Ht();return Ju(n,e,t)},useTransition:function(){var e=Zu(!1);return e=am.bind(null,De,e.queue,!0,!1),Ht().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var i=De,o=Ht();if(He){if(n===void 0)throw Error(s(407));n=n()}else{if(n=t(),Ze===null)throw Error(s(349));(ze&124)!==0||Oh(i,t,n)}o.memoizedState=n;var c={value:n,getSnapshot:t};return o.queue=c,Zh(zh.bind(null,i,c,e),[e]),i.flags|=2048,Yl(9,_s(),Nh.bind(null,i,c,n,t),null),n},useId:function(){var e=Ht(),t=Ze.identifierPrefix;if(He){var n=Qn,i=Xn;n=(i&~(1<<32-wt(i)-1)).toString(32)+n,t="«"+t+"R"+n,n=Ss++,0Se?(St=pe,pe=null):St=pe.sibling;var Ue=V(z,pe,U[Se],K);if(Ue===null){pe===null&&(pe=St);break}e&&pe&&Ue.alternate===null&&t(z,pe),M=c(Ue,M,Se),Re===null?oe=Ue:Re.sibling=Ue,Re=Ue,pe=St}if(Se===U.length)return n(z,pe),He&&al(z,Se),oe;if(pe===null){for(;SeSe?(St=pe,pe=null):St=pe.sibling;var Na=V(z,pe,Ue.value,K);if(Na===null){pe===null&&(pe=St);break}e&&pe&&Na.alternate===null&&t(z,pe),M=c(Na,M,Se),Re===null?oe=Na:Re.sibling=Na,Re=Na,pe=St}if(Ue.done)return n(z,pe),He&&al(z,Se),oe;if(pe===null){for(;!Ue.done;Se++,Ue=U.next())Ue=F(z,Ue.value,K),Ue!==null&&(M=c(Ue,M,Se),Re===null?oe=Ue:Re.sibling=Ue,Re=Ue);return He&&al(z,Se),oe}for(pe=i(pe);!Ue.done;Se++,Ue=U.next())Ue=q(pe,z,Se,Ue.value,K),Ue!==null&&(e&&Ue.alternate!==null&&pe.delete(Ue.key===null?Se:Ue.key),M=c(Ue,M,Se),Re===null?oe=Ue:Re.sibling=Ue,Re=Ue);return e&&pe.forEach(function(bb){return t(z,bb)}),He&&al(z,Se),oe}function Xe(z,M,U,K){if(typeof U=="object"&&U!==null&&U.type===j&&U.key===null&&(U=U.props.children),typeof U=="object"&&U!==null){switch(U.$$typeof){case E:e:{for(var oe=U.key;M!==null;){if(M.key===oe){if(oe=U.type,oe===j){if(M.tag===7){n(z,M.sibling),K=o(M,U.props.children),K.return=z,z=K;break e}}else if(M.elementType===oe||typeof oe=="object"&&oe!==null&&oe.$$typeof===G&&hm(oe)===M.type){n(z,M.sibling),K=o(M,U.props),Ki(K,U),K.return=z,z=K;break e}n(z,M);break}else t(z,M);M=M.sibling}U.type===j?(K=tl(U.props.children,z.mode,K,U.key),K.return=z,z=K):(K=fs(U.type,U.key,U.props,null,z.mode,K),Ki(K,U),K.return=z,z=K)}return v(z);case C:e:{for(oe=U.key;M!==null;){if(M.key===oe)if(M.tag===4&&M.stateNode.containerInfo===U.containerInfo&&M.stateNode.implementation===U.implementation){n(z,M.sibling),K=o(M,U.children||[]),K.return=z,z=K;break e}else{n(z,M);break}else t(z,M);M=M.sibling}K=Eu(U,z.mode,K),K.return=z,z=K}return v(z);case G:return oe=U._init,U=oe(U._payload),Xe(z,M,U,K)}if(se(U))return Ee(z,M,U,K);if(re(U)){if(oe=re(U),typeof oe!="function")throw Error(s(150));return U=oe.call(U),xe(z,M,U,K)}if(typeof U.then=="function")return Xe(z,M,Ds(U),K);if(U.$$typeof===Q)return Xe(z,M,ps(z,U),K);Rs(z,U)}return typeof U=="string"&&U!==""||typeof U=="number"||typeof U=="bigint"?(U=""+U,M!==null&&M.tag===6?(n(z,M.sibling),K=o(M,U),K.return=z,z=K):(n(z,M),K=Su(U,z.mode,K),K.return=z,z=K),v(z)):n(z,M)}return function(z,M,U,K){try{Qi=0;var oe=Xe(z,M,U,K);return Gl=null,oe}catch(pe){if(pe===Bi||pe===ys)throw pe;var Re=Qt(29,pe,null,z.mode);return Re.lanes=K,Re.return=z,Re}finally{}}}var Pl=mm(!0),pm=mm(!1),un=ve(null),Rn=null;function ga(e){var t=e.alternate;ce(gt,gt.current&1),ce(un,e),Rn===null&&(t===null||Vl.current!==null||t.memoizedState!==null)&&(Rn=e)}function vm(e){if(e.tag===22){if(ce(gt,gt.current),ce(un,e),Rn===null){var t=e.alternate;t!==null&&t.memoizedState!==null&&(Rn=e)}}else ba()}function ba(){ce(gt,gt.current),ce(un,un.current)}function $n(e){_e(un),Rn===e&&(Rn=null),_e(gt)}var gt=ve(0);function As(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||Pc(n)))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if((t.flags&128)!==0)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function tc(e,t,n,i){t=e.memoizedState,n=n(i,t),n=n==null?t:b({},t,n),e.memoizedState=n,e.lanes===0&&(e.updateQueue.baseState=n)}var nc={enqueueSetState:function(e,t,n){e=e._reactInternals;var i=$t(),o=pa(i);o.payload=t,n!=null&&(o.callback=n),t=va(e,o,i),t!==null&&(Jt(t,e,i),Vi(t,e,i))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var i=$t(),o=pa(i);o.tag=1,o.payload=t,n!=null&&(o.callback=n),t=va(e,o,i),t!==null&&(Jt(t,e,i),Vi(t,e,i))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=$t(),i=pa(n);i.tag=2,t!=null&&(i.callback=t),t=va(e,i,n),t!==null&&(Jt(t,e,n),Vi(t,e,n))}};function ym(e,t,n,i,o,c,v){return e=e.stateNode,typeof e.shouldComponentUpdate=="function"?e.shouldComponentUpdate(i,c,v):t.prototype&&t.prototype.isPureReactComponent?!Ri(n,i)||!Ri(o,c):!0}function gm(e,t,n,i){e=t.state,typeof t.componentWillReceiveProps=="function"&&t.componentWillReceiveProps(n,i),typeof t.UNSAFE_componentWillReceiveProps=="function"&&t.UNSAFE_componentWillReceiveProps(n,i),t.state!==e&&nc.enqueueReplaceState(t,t.state,null)}function cl(e,t){var n=t;if("ref"in t){n={};for(var i in t)i!=="ref"&&(n[i]=t[i])}if(e=e.defaultProps){n===t&&(n=b({},n));for(var o in e)n[o]===void 0&&(n[o]=e[o])}return n}var Ms=typeof reportError=="function"?reportError:function(e){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof e=="object"&&e!==null&&typeof e.message=="string"?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",e);return}console.error(e)};function bm(e){Ms(e)}function xm(e){console.error(e)}function Sm(e){Ms(e)}function Os(e,t){try{var n=e.onUncaughtError;n(t.value,{componentStack:t.stack})}catch(i){setTimeout(function(){throw i})}}function Em(e,t,n){try{var i=e.onCaughtError;i(n.value,{componentStack:n.stack,errorBoundary:t.tag===1?t.stateNode:null})}catch(o){setTimeout(function(){throw o})}}function ac(e,t,n){return n=pa(n),n.tag=3,n.payload={element:null},n.callback=function(){Os(e,t)},n}function Cm(e){return e=pa(e),e.tag=3,e}function _m(e,t,n,i){var o=n.type.getDerivedStateFromError;if(typeof o=="function"){var c=i.value;e.payload=function(){return o(c)},e.callback=function(){Em(t,n,i)}}var v=n.stateNode;v!==null&&typeof v.componentDidCatch=="function"&&(e.callback=function(){Em(t,n,i),typeof o!="function"&&(wa===null?wa=new Set([this]):wa.add(this));var x=i.stack;this.componentDidCatch(i.value,{componentStack:x!==null?x:""})})}function b1(e,t,n,i,o){if(n.flags|=32768,i!==null&&typeof i=="object"&&typeof i.then=="function"){if(t=n.alternate,t!==null&&zi(t,n,o,!0),n=un.current,n!==null){switch(n.tag){case 13:return Rn===null?Tc():n.alternate===null&<===0&&(lt=3),n.flags&=-257,n.flags|=65536,n.lanes=o,i===Ou?n.flags|=16384:(t=n.updateQueue,t===null?n.updateQueue=new Set([i]):t.add(i),Rc(e,i,o)),!1;case 22:return n.flags|=65536,i===Ou?n.flags|=16384:(t=n.updateQueue,t===null?(t={transitions:null,markerInstances:null,retryQueue:new Set([i])},n.updateQueue=t):(n=t.retryQueue,n===null?t.retryQueue=new Set([i]):n.add(i)),Rc(e,i,o)),!1}throw Error(s(435,n.tag))}return Rc(e,i,o),Tc(),!1}if(He)return t=un.current,t!==null?((t.flags&65536)===0&&(t.flags|=256),t.flags|=65536,t.lanes=o,i!==wu&&(e=Error(s(422),{cause:i}),Ni(ln(e,n)))):(i!==wu&&(t=Error(s(423),{cause:i}),Ni(ln(t,n))),e=e.current.alternate,e.flags|=65536,o&=-o,e.lanes|=o,i=ln(i,n),o=ac(e.stateNode,i,o),Lu(e,o),lt!==4&&(lt=2)),!1;var c=Error(s(520),{cause:i});if(c=ln(c,n),er===null?er=[c]:er.push(c),lt!==4&&(lt=2),t===null)return!0;i=ln(i,n),n=t;do{switch(n.tag){case 3:return n.flags|=65536,e=o&-o,n.lanes|=e,e=ac(n.stateNode,i,e),Lu(n,e),!1;case 1:if(t=n.type,c=n.stateNode,(n.flags&128)===0&&(typeof t.getDerivedStateFromError=="function"||c!==null&&typeof c.componentDidCatch=="function"&&(wa===null||!wa.has(c))))return n.flags|=65536,o&=-o,n.lanes|=o,o=Cm(o),_m(o,e,n,i),Lu(n,o),!1}n=n.return}while(n!==null);return!1}var wm=Error(s(461)),bt=!1;function jt(e,t,n,i){t.child=e===null?pm(t,null,n,i):Pl(t,e.child,n,i)}function jm(e,t,n,i,o){n=n.render;var c=t.ref;if("ref"in i){var v={};for(var x in i)x!=="ref"&&(v[x]=i[x])}else v=i;return sl(t),i=ku(e,t,n,v,c,o),x=qu(),e!==null&&!bt?(Yu(e,t,o),Jn(e,t,o)):(He&&x&&Cu(t),t.flags|=1,jt(e,t,i,o),t.child)}function Tm(e,t,n,i,o){if(e===null){var c=n.type;return typeof c=="function"&&!xu(c)&&c.defaultProps===void 0&&n.compare===null?(t.tag=15,t.type=c,Dm(e,t,c,i,o)):(e=fs(n.type,null,i,t,t.mode,o),e.ref=t.ref,e.return=t,t.child=e)}if(c=e.child,!fc(e,o)){var v=c.memoizedProps;if(n=n.compare,n=n!==null?n:Ri,n(v,i)&&e.ref===t.ref)return Jn(e,t,o)}return t.flags|=1,e=Pn(c,i),e.ref=t.ref,e.return=t,t.child=e}function Dm(e,t,n,i,o){if(e!==null){var c=e.memoizedProps;if(Ri(c,i)&&e.ref===t.ref)if(bt=!1,t.pendingProps=i=c,fc(e,o))(e.flags&131072)!==0&&(bt=!0);else return t.lanes=e.lanes,Jn(e,t,o)}return lc(e,t,n,i,o)}function Rm(e,t,n){var i=t.pendingProps,o=i.children,c=e!==null?e.memoizedState:null;if(i.mode==="hidden"){if((t.flags&128)!==0){if(i=c!==null?c.baseLanes|n:n,e!==null){for(o=t.child=e.child,c=0;o!==null;)c=c|o.lanes|o.childLanes,o=o.sibling;t.childLanes=c&~i}else t.childLanes=0,t.child=null;return Am(e,t,i,n)}if((n&536870912)!==0)t.memoizedState={baseLanes:0,cachePool:null},e!==null&&vs(t,c!==null?c.cachePool:null),c!==null?Dh(t,c):Bu(),vm(t);else return t.lanes=t.childLanes=536870912,Am(e,t,c!==null?c.baseLanes|n:n,n)}else c!==null?(vs(t,c.cachePool),Dh(t,c),ba(),t.memoizedState=null):(e!==null&&vs(t,null),Bu(),ba());return jt(e,t,o,n),t.child}function Am(e,t,n,i){var o=Mu();return o=o===null?null:{parent:yt._currentValue,pool:o},t.memoizedState={baseLanes:n,cachePool:o},e!==null&&vs(t,null),Bu(),vm(t),e!==null&&zi(e,t,i,!0),null}function Ns(e,t){var n=t.ref;if(n===null)e!==null&&e.ref!==null&&(t.flags|=4194816);else{if(typeof n!="function"&&typeof n!="object")throw Error(s(284));(e===null||e.ref!==n)&&(t.flags|=4194816)}}function lc(e,t,n,i,o){return sl(t),n=ku(e,t,n,i,void 0,o),i=qu(),e!==null&&!bt?(Yu(e,t,o),Jn(e,t,o)):(He&&i&&Cu(t),t.flags|=1,jt(e,t,n,o),t.child)}function Mm(e,t,n,i,o,c){return sl(t),t.updateQueue=null,n=Ah(t,i,n,o),Rh(e),i=qu(),e!==null&&!bt?(Yu(e,t,c),Jn(e,t,c)):(He&&i&&Cu(t),t.flags|=1,jt(e,t,n,c),t.child)}function Om(e,t,n,i,o){if(sl(t),t.stateNode===null){var c=zl,v=n.contextType;typeof v=="object"&&v!==null&&(c=At(v)),c=new n(i,c),t.memoizedState=c.state!==null&&c.state!==void 0?c.state:null,c.updater=nc,t.stateNode=c,c._reactInternals=t,c=t.stateNode,c.props=i,c.state=t.memoizedState,c.refs={},Nu(t),v=n.contextType,c.context=typeof v=="object"&&v!==null?At(v):zl,c.state=t.memoizedState,v=n.getDerivedStateFromProps,typeof v=="function"&&(tc(t,n,v,i),c.state=t.memoizedState),typeof n.getDerivedStateFromProps=="function"||typeof c.getSnapshotBeforeUpdate=="function"||typeof c.UNSAFE_componentWillMount!="function"&&typeof c.componentWillMount!="function"||(v=c.state,typeof c.componentWillMount=="function"&&c.componentWillMount(),typeof c.UNSAFE_componentWillMount=="function"&&c.UNSAFE_componentWillMount(),v!==c.state&&nc.enqueueReplaceState(c,c.state,null),qi(t,i,c,o),ki(),c.state=t.memoizedState),typeof c.componentDidMount=="function"&&(t.flags|=4194308),i=!0}else if(e===null){c=t.stateNode;var x=t.memoizedProps,_=cl(n,x);c.props=_;var B=c.context,P=n.contextType;v=zl,typeof P=="object"&&P!==null&&(v=At(P));var F=n.getDerivedStateFromProps;P=typeof F=="function"||typeof c.getSnapshotBeforeUpdate=="function",x=t.pendingProps!==x,P||typeof c.UNSAFE_componentWillReceiveProps!="function"&&typeof c.componentWillReceiveProps!="function"||(x||B!==v)&&gm(t,c,i,v),ma=!1;var V=t.memoizedState;c.state=V,qi(t,i,c,o),ki(),B=t.memoizedState,x||V!==B||ma?(typeof F=="function"&&(tc(t,n,F,i),B=t.memoizedState),(_=ma||ym(t,n,_,i,V,B,v))?(P||typeof c.UNSAFE_componentWillMount!="function"&&typeof c.componentWillMount!="function"||(typeof c.componentWillMount=="function"&&c.componentWillMount(),typeof c.UNSAFE_componentWillMount=="function"&&c.UNSAFE_componentWillMount()),typeof c.componentDidMount=="function"&&(t.flags|=4194308)):(typeof c.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=i,t.memoizedState=B),c.props=i,c.state=B,c.context=v,i=_):(typeof c.componentDidMount=="function"&&(t.flags|=4194308),i=!1)}else{c=t.stateNode,zu(e,t),v=t.memoizedProps,P=cl(n,v),c.props=P,F=t.pendingProps,V=c.context,B=n.contextType,_=zl,typeof B=="object"&&B!==null&&(_=At(B)),x=n.getDerivedStateFromProps,(B=typeof x=="function"||typeof c.getSnapshotBeforeUpdate=="function")||typeof c.UNSAFE_componentWillReceiveProps!="function"&&typeof c.componentWillReceiveProps!="function"||(v!==F||V!==_)&&gm(t,c,i,_),ma=!1,V=t.memoizedState,c.state=V,qi(t,i,c,o),ki();var q=t.memoizedState;v!==F||V!==q||ma||e!==null&&e.dependencies!==null&&ms(e.dependencies)?(typeof x=="function"&&(tc(t,n,x,i),q=t.memoizedState),(P=ma||ym(t,n,P,i,V,q,_)||e!==null&&e.dependencies!==null&&ms(e.dependencies))?(B||typeof c.UNSAFE_componentWillUpdate!="function"&&typeof c.componentWillUpdate!="function"||(typeof c.componentWillUpdate=="function"&&c.componentWillUpdate(i,q,_),typeof c.UNSAFE_componentWillUpdate=="function"&&c.UNSAFE_componentWillUpdate(i,q,_)),typeof c.componentDidUpdate=="function"&&(t.flags|=4),typeof c.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof c.componentDidUpdate!="function"||v===e.memoizedProps&&V===e.memoizedState||(t.flags|=4),typeof c.getSnapshotBeforeUpdate!="function"||v===e.memoizedProps&&V===e.memoizedState||(t.flags|=1024),t.memoizedProps=i,t.memoizedState=q),c.props=i,c.state=q,c.context=_,i=P):(typeof c.componentDidUpdate!="function"||v===e.memoizedProps&&V===e.memoizedState||(t.flags|=4),typeof c.getSnapshotBeforeUpdate!="function"||v===e.memoizedProps&&V===e.memoizedState||(t.flags|=1024),i=!1)}return c=i,Ns(e,t),i=(t.flags&128)!==0,c||i?(c=t.stateNode,n=i&&typeof n.getDerivedStateFromError!="function"?null:c.render(),t.flags|=1,e!==null&&i?(t.child=Pl(t,e.child,null,o),t.child=Pl(t,null,n,o)):jt(e,t,n,o),t.memoizedState=c.state,e=t.child):e=Jn(e,t,o),e}function Nm(e,t,n,i){return Oi(),t.flags|=256,jt(e,t,n,i),t.child}var ic={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function rc(e){return{baseLanes:e,cachePool:xh()}}function sc(e,t,n){return e=e!==null?e.childLanes&~n:0,t&&(e|=cn),e}function zm(e,t,n){var i=t.pendingProps,o=!1,c=(t.flags&128)!==0,v;if((v=c)||(v=e!==null&&e.memoizedState===null?!1:(gt.current&2)!==0),v&&(o=!0,t.flags&=-129),v=(t.flags&32)!==0,t.flags&=-33,e===null){if(He){if(o?ga(t):ba(),He){var x=at,_;if(_=x){e:{for(_=x,x=Dn;_.nodeType!==8;){if(!x){x=null;break e}if(_=En(_.nextSibling),_===null){x=null;break e}}x=_}x!==null?(t.memoizedState={dehydrated:x,treeContext:nl!==null?{id:Xn,overflow:Qn}:null,retryLane:536870912,hydrationErrors:null},_=Qt(18,null,null,0),_.stateNode=x,_.return=t,t.child=_,Nt=t,at=null,_=!0):_=!1}_||il(t)}if(x=t.memoizedState,x!==null&&(x=x.dehydrated,x!==null))return Pc(x)?t.lanes=32:t.lanes=536870912,null;$n(t)}return x=i.children,i=i.fallback,o?(ba(),o=t.mode,x=zs({mode:"hidden",children:x},o),i=tl(i,o,n,null),x.return=t,i.return=t,x.sibling=i,t.child=x,o=t.child,o.memoizedState=rc(n),o.childLanes=sc(e,v,n),t.memoizedState=ic,i):(ga(t),oc(t,x))}if(_=e.memoizedState,_!==null&&(x=_.dehydrated,x!==null)){if(c)t.flags&256?(ga(t),t.flags&=-257,t=uc(e,t,n)):t.memoizedState!==null?(ba(),t.child=e.child,t.flags|=128,t=null):(ba(),o=i.fallback,x=t.mode,i=zs({mode:"visible",children:i.children},x),o=tl(o,x,n,null),o.flags|=2,i.return=t,o.return=t,i.sibling=o,t.child=i,Pl(t,e.child,null,n),i=t.child,i.memoizedState=rc(n),i.childLanes=sc(e,v,n),t.memoizedState=ic,t=o);else if(ga(t),Pc(x)){if(v=x.nextSibling&&x.nextSibling.dataset,v)var B=v.dgst;v=B,i=Error(s(419)),i.stack="",i.digest=v,Ni({value:i,source:null,stack:null}),t=uc(e,t,n)}else if(bt||zi(e,t,n,!1),v=(n&e.childLanes)!==0,bt||v){if(v=Ze,v!==null&&(i=n&-n,i=(i&42)!==0?1:xi(i),i=(i&(v.suspendedLanes|n))!==0?0:i,i!==0&&i!==_.retryLane))throw _.retryLane=i,Nl(e,i),Jt(v,e,i),wm;x.data==="$?"||Tc(),t=uc(e,t,n)}else x.data==="$?"?(t.flags|=192,t.child=e.child,t=null):(e=_.treeContext,at=En(x.nextSibling),Nt=t,He=!0,ll=null,Dn=!1,e!==null&&(sn[on++]=Xn,sn[on++]=Qn,sn[on++]=nl,Xn=e.id,Qn=e.overflow,nl=t),t=oc(t,i.children),t.flags|=4096);return t}return o?(ba(),o=i.fallback,x=t.mode,_=e.child,B=_.sibling,i=Pn(_,{mode:"hidden",children:i.children}),i.subtreeFlags=_.subtreeFlags&65011712,B!==null?o=Pn(B,o):(o=tl(o,x,n,null),o.flags|=2),o.return=t,i.return=t,i.sibling=o,t.child=i,i=o,o=t.child,x=e.child.memoizedState,x===null?x=rc(n):(_=x.cachePool,_!==null?(B=yt._currentValue,_=_.parent!==B?{parent:B,pool:B}:_):_=xh(),x={baseLanes:x.baseLanes|n,cachePool:_}),o.memoizedState=x,o.childLanes=sc(e,v,n),t.memoizedState=ic,i):(ga(t),n=e.child,e=n.sibling,n=Pn(n,{mode:"visible",children:i.children}),n.return=t,n.sibling=null,e!==null&&(v=t.deletions,v===null?(t.deletions=[e],t.flags|=16):v.push(e)),t.child=n,t.memoizedState=null,n)}function oc(e,t){return t=zs({mode:"visible",children:t},e.mode),t.return=e,e.child=t}function zs(e,t){return e=Qt(22,e,null,t),e.lanes=0,e.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},e}function uc(e,t,n){return Pl(t,e.child,null,n),e=oc(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function Lm(e,t,n){e.lanes|=t;var i=e.alternate;i!==null&&(i.lanes|=t),Tu(e.return,t,n)}function cc(e,t,n,i,o){var c=e.memoizedState;c===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:i,tail:n,tailMode:o}:(c.isBackwards=t,c.rendering=null,c.renderingStartTime=0,c.last=i,c.tail=n,c.tailMode=o)}function Um(e,t,n){var i=t.pendingProps,o=i.revealOrder,c=i.tail;if(jt(e,t,i.children,n),i=gt.current,(i&2)!==0)i=i&1|2,t.flags|=128;else{if(e!==null&&(e.flags&128)!==0)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Lm(e,n,t);else if(e.tag===19)Lm(e,n,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}i&=1}switch(ce(gt,i),o){case"forwards":for(n=t.child,o=null;n!==null;)e=n.alternate,e!==null&&As(e)===null&&(o=n),n=n.sibling;n=o,n===null?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),cc(t,!1,o,n,c);break;case"backwards":for(n=null,o=t.child,t.child=null;o!==null;){if(e=o.alternate,e!==null&&As(e)===null){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}cc(t,!0,n,null,c);break;case"together":cc(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function Jn(e,t,n){if(e!==null&&(t.dependencies=e.dependencies),_a|=t.lanes,(n&t.childLanes)===0)if(e!==null){if(zi(e,t,n,!1),(n&t.childLanes)===0)return null}else return null;if(e!==null&&t.child!==e.child)throw Error(s(153));if(t.child!==null){for(e=t.child,n=Pn(e,e.pendingProps),t.child=n,n.return=t;e.sibling!==null;)e=e.sibling,n=n.sibling=Pn(e,e.pendingProps),n.return=t;n.sibling=null}return t.child}function fc(e,t){return(e.lanes&t)!==0?!0:(e=e.dependencies,!!(e!==null&&ms(e)))}function x1(e,t,n){switch(t.tag){case 3:Ie(t,t.stateNode.containerInfo),ha(t,yt,e.memoizedState.cache),Oi();break;case 27:case 5:dt(t);break;case 4:Ie(t,t.stateNode.containerInfo);break;case 10:ha(t,t.type,t.memoizedProps.value);break;case 13:var i=t.memoizedState;if(i!==null)return i.dehydrated!==null?(ga(t),t.flags|=128,null):(n&t.child.childLanes)!==0?zm(e,t,n):(ga(t),e=Jn(e,t,n),e!==null?e.sibling:null);ga(t);break;case 19:var o=(e.flags&128)!==0;if(i=(n&t.childLanes)!==0,i||(zi(e,t,n,!1),i=(n&t.childLanes)!==0),o){if(i)return Um(e,t,n);t.flags|=128}if(o=t.memoizedState,o!==null&&(o.rendering=null,o.tail=null,o.lastEffect=null),ce(gt,gt.current),i)break;return null;case 22:case 23:return t.lanes=0,Rm(e,t,n);case 24:ha(t,yt,e.memoizedState.cache)}return Jn(e,t,n)}function Bm(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps)bt=!0;else{if(!fc(e,n)&&(t.flags&128)===0)return bt=!1,x1(e,t,n);bt=(e.flags&131072)!==0}else bt=!1,He&&(t.flags&1048576)!==0&&hh(t,hs,t.index);switch(t.lanes=0,t.tag){case 16:e:{e=t.pendingProps;var i=t.elementType,o=i._init;if(i=o(i._payload),t.type=i,typeof i=="function")xu(i)?(e=cl(i,e),t.tag=1,t=Om(null,t,i,e,n)):(t.tag=0,t=lc(null,t,i,e,n));else{if(i!=null){if(o=i.$$typeof,o===Z){t.tag=11,t=jm(null,t,i,e,n);break e}else if(o===N){t.tag=14,t=Tm(null,t,i,e,n);break e}}throw t=I(i)||i,Error(s(306,t,""))}}return t;case 0:return lc(e,t,t.type,t.pendingProps,n);case 1:return i=t.type,o=cl(i,t.pendingProps),Om(e,t,i,o,n);case 3:e:{if(Ie(t,t.stateNode.containerInfo),e===null)throw Error(s(387));i=t.pendingProps;var c=t.memoizedState;o=c.element,zu(e,t),qi(t,i,null,n);var v=t.memoizedState;if(i=v.cache,ha(t,yt,i),i!==c.cache&&Du(t,[yt],n,!0),ki(),i=v.element,c.isDehydrated)if(c={element:i,isDehydrated:!1,cache:v.cache},t.updateQueue.baseState=c,t.memoizedState=c,t.flags&256){t=Nm(e,t,i,n);break e}else if(i!==o){o=ln(Error(s(424)),t),Ni(o),t=Nm(e,t,i,n);break e}else{switch(e=t.stateNode.containerInfo,e.nodeType){case 9:e=e.body;break;default:e=e.nodeName==="HTML"?e.ownerDocument.body:e}for(at=En(e.firstChild),Nt=t,He=!0,ll=null,Dn=!0,n=pm(t,null,i,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling}else{if(Oi(),i===o){t=Jn(e,t,n);break e}jt(e,t,i,n)}t=t.child}return t;case 26:return Ns(e,t),e===null?(n=qp(t.type,null,t.pendingProps,null))?t.memoizedState=n:He||(n=t.type,e=t.pendingProps,i=Zs(Ke.current).createElement(n),i[$]=t,i[W]=e,Dt(i,n,e),we(i),t.stateNode=i):t.memoizedState=qp(t.type,e.memoizedProps,t.pendingProps,e.memoizedState),null;case 27:return dt(t),e===null&&He&&(i=t.stateNode=Hp(t.type,t.pendingProps,Ke.current),Nt=t,Dn=!0,o=at,Da(t.type)?(Xc=o,at=En(i.firstChild)):at=o),jt(e,t,t.pendingProps.children,n),Ns(e,t),e===null&&(t.flags|=4194304),t.child;case 5:return e===null&&He&&((o=i=at)&&(i=Z1(i,t.type,t.pendingProps,Dn),i!==null?(t.stateNode=i,Nt=t,at=En(i.firstChild),Dn=!1,o=!0):o=!1),o||il(t)),dt(t),o=t.type,c=t.pendingProps,v=e!==null?e.memoizedProps:null,i=c.children,qc(o,c)?i=null:v!==null&&qc(o,v)&&(t.flags|=32),t.memoizedState!==null&&(o=ku(e,t,d1,null,null,n),ur._currentValue=o),Ns(e,t),jt(e,t,i,n),t.child;case 6:return e===null&&He&&((e=n=at)&&(n=F1(n,t.pendingProps,Dn),n!==null?(t.stateNode=n,Nt=t,at=null,e=!0):e=!1),e||il(t)),null;case 13:return zm(e,t,n);case 4:return Ie(t,t.stateNode.containerInfo),i=t.pendingProps,e===null?t.child=Pl(t,null,i,n):jt(e,t,i,n),t.child;case 11:return jm(e,t,t.type,t.pendingProps,n);case 7:return jt(e,t,t.pendingProps,n),t.child;case 8:return jt(e,t,t.pendingProps.children,n),t.child;case 12:return jt(e,t,t.pendingProps.children,n),t.child;case 10:return i=t.pendingProps,ha(t,t.type,i.value),jt(e,t,i.children,n),t.child;case 9:return o=t.type._context,i=t.pendingProps.children,sl(t),o=At(o),i=i(o),t.flags|=1,jt(e,t,i,n),t.child;case 14:return Tm(e,t,t.type,t.pendingProps,n);case 15:return Dm(e,t,t.type,t.pendingProps,n);case 19:return Um(e,t,n);case 31:return i=t.pendingProps,n=t.mode,i={mode:i.mode,children:i.children},e===null?(n=zs(i,n),n.ref=t.ref,t.child=n,n.return=t,t=n):(n=Pn(e.child,i),n.ref=t.ref,t.child=n,n.return=t,t=n),t;case 22:return Rm(e,t,n);case 24:return sl(t),i=At(yt),e===null?(o=Mu(),o===null&&(o=Ze,c=Ru(),o.pooledCache=c,c.refCount++,c!==null&&(o.pooledCacheLanes|=n),o=c),t.memoizedState={parent:i,cache:o},Nu(t),ha(t,yt,o)):((e.lanes&n)!==0&&(zu(e,t),qi(t,null,null,n),ki()),o=e.memoizedState,c=t.memoizedState,o.parent!==i?(o={parent:i,cache:i},t.memoizedState=o,t.lanes===0&&(t.memoizedState=t.updateQueue.baseState=o),ha(t,yt,i)):(i=c.cache,ha(t,yt,i),i!==o.cache&&Du(t,[yt],n,!0))),jt(e,t,t.pendingProps.children,n),t.child;case 29:throw t.pendingProps}throw Error(s(156,t.tag))}function In(e){e.flags|=4}function Hm(e,t){if(t.type!=="stylesheet"||(t.state.loading&4)!==0)e.flags&=-16777217;else if(e.flags|=16777216,!Qp(t)){if(t=un.current,t!==null&&((ze&4194048)===ze?Rn!==null:(ze&62914560)!==ze&&(ze&536870912)===0||t!==Rn))throw Hi=Ou,Sh;e.flags|=8192}}function Ls(e,t){t!==null&&(e.flags|=4),e.flags&16384&&(t=e.tag!==22?Fr():536870912,e.lanes|=t,Zl|=t)}function Zi(e,t){if(!He)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;t!==null;)t.alternate!==null&&(n=t),t=t.sibling;n===null?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var i=null;n!==null;)n.alternate!==null&&(i=n),n=n.sibling;i===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:i.sibling=null}}function tt(e){var t=e.alternate!==null&&e.alternate.child===e.child,n=0,i=0;if(t)for(var o=e.child;o!==null;)n|=o.lanes|o.childLanes,i|=o.subtreeFlags&65011712,i|=o.flags&65011712,o.return=e,o=o.sibling;else for(o=e.child;o!==null;)n|=o.lanes|o.childLanes,i|=o.subtreeFlags,i|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=i,e.childLanes=n,t}function S1(e,t,n){var i=t.pendingProps;switch(_u(t),t.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return tt(t),null;case 1:return tt(t),null;case 3:return n=t.stateNode,i=null,e!==null&&(i=e.memoizedState.cache),t.memoizedState.cache!==i&&(t.flags|=2048),Zn(yt),Yt(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(e===null||e.child===null)&&(Mi(t)?In(t):e===null||e.memoizedState.isDehydrated&&(t.flags&256)===0||(t.flags|=1024,vh())),tt(t),null;case 26:return n=t.memoizedState,e===null?(In(t),n!==null?(tt(t),Hm(t,n)):(tt(t),t.flags&=-16777217)):n?n!==e.memoizedState?(In(t),tt(t),Hm(t,n)):(tt(t),t.flags&=-16777217):(e.memoizedProps!==i&&In(t),tt(t),t.flags&=-16777217),null;case 27:yn(t),n=Ke.current;var o=t.type;if(e!==null&&t.stateNode!=null)e.memoizedProps!==i&&In(t);else{if(!i){if(t.stateNode===null)throw Error(s(166));return tt(t),null}e=Le.current,Mi(t)?mh(t):(e=Hp(o,i,n),t.stateNode=e,In(t))}return tt(t),null;case 5:if(yn(t),n=t.type,e!==null&&t.stateNode!=null)e.memoizedProps!==i&&In(t);else{if(!i){if(t.stateNode===null)throw Error(s(166));return tt(t),null}if(e=Le.current,Mi(t))mh(t);else{switch(o=Zs(Ke.current),e){case 1:e=o.createElementNS("http://www.w3.org/2000/svg",n);break;case 2:e=o.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;default:switch(n){case"svg":e=o.createElementNS("http://www.w3.org/2000/svg",n);break;case"math":e=o.createElementNS("http://www.w3.org/1998/Math/MathML",n);break;case"script":e=o.createElement("div"),e.innerHTML=" - + + diff --git a/tests/server/api/test_scheduler_controller.py b/tests/server/api/test_scheduler_controller.py index b159175d..e0d75d79 100644 --- a/tests/server/api/test_scheduler_controller.py +++ b/tests/server/api/test_scheduler_controller.py @@ -1,7 +1,14 @@ +from typing import Any from unittest.mock import MagicMock, patch import pytest +from icon.server.api.models.parameter_metadata import ParameterMetadata +from icon.server.api.models.scan_parameter import ( + DatabaseParameter, + RealtimeParameter, + ScanParameter, +) from icon.server.api.scheduler_controller import SchedulerController from icon.server.data_access.models.enums import JobRunStatus, JobStatus @@ -122,3 +129,66 @@ def test_cancel_job_cancels_paused_runs( ) else: mock_job_run_repo.update_run_by_id.assert_not_called() + + +def _parameter_metadata( + min_value: float | None, max_value: float | None +) -> ParameterMetadata: + return { + "display_name": "Wait Time", + "unit": "us", + "default_value": 1.0, + "min_value": min_value, + "max_value": max_value, + "allowed_values": None, + } + + +@pytest.mark.parametrize( + ("min_value", "max_value", "values", "expected"), + [ + (0.0, 100.0, [0.0, 50.0, 100.0], [0.0, 50.0, 100.0]), + (0.0, 100.0, [-0.5, 50.0], [0.0, 50.0]), + (0.0, 100.0, [50.0, 100.5], [50.0, 100.0]), + (0.0, 100.0, [-20.0, 50.0, 120.0], [0.0, 50.0, 100.0]), + (None, 100.0, [-1e9, 100.5], [-1e9, 100.0]), + (0.0, None, [-0.5, 1e9], [0.0, 1e9]), + (None, None, [-1e9, 1e9], [-1e9, 1e9]), + # Non-numeric values are left untouched. + (0.0, 100.0, [True, "a string"], [True, "a string"]), + # Clamping preserves the value's type (int stays int). + (0.0, 100.0, [-5, 50, 120], [0, 50, 100]), + ], +) +def test_clamp_scan_values_to_bounds( + min_value: float | None, + max_value: float | None, + values: list[Any], + expected: list[Any], + controller: SchedulerController, +) -> None: + controller._parameters_controller._all_parameter_metadata = { + "wait_time": _parameter_metadata(min_value, max_value) + } + param = DatabaseParameter(id="wait_time", values=values) + scan_parameters: list[ScanParameter] = [param] + + controller._clamp_scan_values_to_bounds(scan_parameters=scan_parameters) + + assert param.values == expected + assert [type(value) for value in param.values] == [ + type(value) for value in expected + ] + + +def test_clamp_scan_values_without_metadata_leaves_values_untouched( + controller: SchedulerController, +) -> None: + controller._parameters_controller._all_parameter_metadata = {} + param = DatabaseParameter(id="unknown_device_param", values=[-1e9, 1e9]) + + controller._clamp_scan_values_to_bounds( + scan_parameters=[param, RealtimeParameter(n_scan_points=0)] + ) + + assert param.values == [-1e9, 1e9]