diff --git a/.dockerignore b/.dockerignore index f588793..3f8e9b3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,6 +13,8 @@ cmd/benchmark/reports/ # Go build cache and binaries **/bin/ -**/dist/ **/build/ **/*.out + +# Allow web dist directory (needed for embedding) +!app/web/dist/ diff --git a/APACHE-PROXY-GUIDE.md b/APACHE-PROXY-GUIDE.md index 1fbfb13..37bd4cc 100644 --- a/APACHE-PROXY-GUIDE.md +++ b/APACHE-PROXY-GUIDE.md @@ -1,7 +1,7 @@ # Apache Reverse Proxy Guide for Docker Apps **Complete guide for WebSocket-enabled applications - covers both Plesk and Standard Apache** -**Updated with real-world troubleshooting solutions** +**Updated with real-world troubleshooting solutions and latest Orly relay improvements** ## 🎯 **What This Solves** - WebSocket connection failures (`NS_ERROR_WEBSOCKET_CONNECTION_REFUSED`) @@ -9,24 +9,32 @@ - Docker container proxy configuration - SSL certificate integration - Plesk configuration conflicts and virtual host precedence issues +- **NEW**: WebSocket scheme validation errors (`expected 'ws' got 'wss'`) +- **NEW**: Proxy-friendly relay configuration with enhanced CORS headers +- **NEW**: Improved error handling for malformed client data ## 🐳 **Step 1: Deploy Your Docker Application** -### **For Stella's Orly Relay:** +### **For Stella's Orly Relay (Latest Version with Proxy Improvements):** ```bash -# Pull and run the relay +# Pull and run the relay with enhanced proxy support docker run -d \ - --name stella-relay \ + --name orly-relay \ --restart unless-stopped \ -p 127.0.0.1:7777:7777 \ -v /data/orly-relay:/data \ -e ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx \ -e ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z \ - silberengel/orly-relay:latest + -e ORLY_RELAY_URL=wss://your-domain.com \ + -e ORLY_ACL_MODE=follows \ + -e ORLY_SPIDER_MODE=follows \ + -e ORLY_SPIDER_FREQUENCY=1h \ + -e ORLY_SUBSCRIPTION_ENABLED=false \ + silberengel/next-orly:latest # Test the relay curl -I http://127.0.0.1:7777 -# Should return: HTTP/1.1 426 Upgrade Required +# Should return: HTTP/1.1 200 OK with enhanced CORS headers ``` ### **For Web Apps (like Jumble):** @@ -253,9 +261,40 @@ sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_wstunnel sudo a2enmod rewrite +sudo a2enmod headers sudo systemctl restart apache2 ``` +## πŸ†• **Step 4: Latest Orly Relay Improvements** + +### **Enhanced Proxy Support** +The latest Orly relay includes several proxy improvements: + +1. **Flexible WebSocket Scheme Handling**: Accepts both `ws://` and `wss://` schemes for authentication +2. **Enhanced CORS Headers**: Better compatibility with web applications +3. **Improved Error Handling**: More robust handling of malformed client data +4. **Proxy-Aware Logging**: Better debugging information for proxy setups + +### **Key Environment Variables** +```bash +# Essential for proxy setups +ORLY_RELAY_URL=wss://your-domain.com # Must match your public URL +ORLY_ACL_MODE=follows # Enable follows-based access control +ORLY_SPIDER_MODE=follows # Enable content syncing from other relays +ORLY_SUBSCRIPTION_ENABLED=false # Disable payment requirements +``` + +### **Testing the Enhanced Relay** +```bash +# Test local connectivity +curl -I http://127.0.0.1:7777 + +# Expected response includes enhanced CORS headers: +# Access-Control-Allow-Credentials: true +# Access-Control-Max-Age: 86400 +# Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers +``` + ## ⚑ **Step 4: Alternative - Nginx in Plesk** If Apache keeps giving issues, switch to Nginx in Plesk: @@ -327,13 +366,67 @@ After making changes: ```bash # Essential debugging docker ps | grep relay # Container running? -curl -I http://127.0.0.1:7777 # Local relay (should return 426) +curl -I http://127.0.0.1:7777 # Local relay (should return 200 with CORS headers) apache2ctl -S | grep domain.com # Virtual host precedence grep ProxyPass /etc/apache2/plesk.conf.d/vhosts/domain.conf # Config applied? # WebSocket testing echo '["REQ","test",{}]' | websocat wss://domain.com/ # Root path echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ # /ws/ path + +# Check relay logs for proxy information +docker logs relay-name | grep -i "proxy info" +docker logs relay-name | grep -i "websocket connection" +``` + +## 🚨 **Latest Troubleshooting Solutions** + +### **WebSocket Scheme Validation Errors** +**Problem**: `"HTTP Scheme incorrect: expected 'ws' got 'wss'"` + +**Solution**: Use the latest Orly relay image with enhanced proxy support: +```bash +# Pull the latest image with proxy improvements +docker pull silberengel/next-orly:latest + +# Restart with the latest image +docker stop orly-relay && docker rm orly-relay +# Then run with the configuration above +``` + +### **Malformed Client Data Errors** +**Problem**: `"invalid hex array size, got 2 expect 64"` + +**Solution**: These are client-side issues, not server problems. The latest relay handles them gracefully: +- The relay now sends helpful error messages to clients +- Malformed requests are logged but don't crash the relay +- Normal operations continue despite client errors + +### **Follows ACL Not Working** +**Problem**: Only owners can write, admins can't write + +**Solution**: Ensure proper configuration: +```bash +# Check ACL configuration +docker exec orly-relay env | grep ACL + +# Should show: ORLY_ACL_MODE=follows +# If not, restart with explicit configuration +``` + +### **Spider Not Syncing Content** +**Problem**: Spider enabled but not pulling events + +**Solution**: Check for relay lists and follow events: +```bash +# Check spider status +docker logs orly-relay | grep -i spider + +# Look for relay discovery +docker logs orly-relay | grep -i "relay URLs" + +# Check for follow events +docker logs orly-relay | grep -i "kind.*3" ``` ### **Working Solution (Proven):** @@ -362,3 +455,28 @@ echo '["REQ","test",{}]' | websocat wss://domain.com/ws/ # /ws/ path 2. Use `ws://` proxy for Nostr relays, not `http://` 3. Direct Apache config files are more reliable than Plesk interface 4. Always check virtual host precedence with `apache2ctl -S` +5. **NEW**: Use the latest Orly relay image for better proxy compatibility +6. **NEW**: Enhanced CORS headers improve web app compatibility +7. **NEW**: Flexible WebSocket scheme handling eliminates authentication errors +8. **NEW**: Improved error handling makes the relay more robust + +## πŸŽ‰ **Summary of Latest Improvements** + +### **Enhanced Proxy Support** +- βœ… Flexible WebSocket scheme validation (accepts both `ws://` and `wss://`) +- βœ… Enhanced CORS headers for better web app compatibility +- βœ… Improved error handling for malformed client data +- βœ… Proxy-aware logging for better debugging + +### **Spider and ACL Features** +- βœ… Follows-based access control (`ORLY_ACL_MODE=follows`) +- βœ… Content syncing from other relays (`ORLY_SPIDER_MODE=follows`) +- βœ… No payment requirements (`ORLY_SUBSCRIPTION_ENABLED=false`) + +### **Production Ready** +- βœ… Robust error handling +- βœ… Enhanced logging and debugging +- βœ… Better client compatibility +- βœ… Improved proxy support + +**The latest Orly relay is now fully optimized for proxy environments and provides a much better user experience!** diff --git a/app/config/config.go b/app/config/config.go index 76f8929..f942ae8 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -40,7 +40,7 @@ type C struct { Admins []string `env:"ORLY_ADMINS" usage:"comma-separated list of admin npubs"` Owners []string `env:"ORLY_OWNERS" usage:"comma-separated list of owner npubs, who have full control of the relay for wipe and restart and other functions"` ACLMode string `env:"ORLY_ACL_MODE" usage:"ACL mode: follows,none" default:"none"` - SpiderMode string `env:"ORLY_SPIDER_MODE" usage:"spider mode: none,follow" default:"none"` + SpiderMode string `env:"ORLY_SPIDER_MODE" usage:"spider mode: none,follows" default:"none"` SpiderFrequency time.Duration `env:"ORLY_SPIDER_FREQUENCY" usage:"spider frequency in seconds" default:"1h"` NWCUri string `env:"ORLY_NWC_URI" usage:"NWC (Nostr Wallet Connect) connection string for Lightning payments"` SubscriptionEnabled bool `env:"ORLY_SUBSCRIPTION_ENABLED" default:"false" usage:"enable subscription-based access control requiring payment for non-directory events"` @@ -225,15 +225,14 @@ func EnvKV(cfg any) (m KVSlice) { k := t.Field(i).Tag.Get("env") v := reflect.ValueOf(cfg).Field(i).Interface() var val string - switch v.(type) { + switch v := v.(type) { case string: - val = v.(string) + val = v case int, bool, time.Duration: val = fmt.Sprint(v) case []string: - arr := v.([]string) - if len(arr) > 0 { - val = strings.Join(arr, ",") + if len(v) > 0 { + val = strings.Join(v, ",") } } // this can happen with embedded structs @@ -305,5 +304,4 @@ func PrintHelp(cfg *C, printer io.Writer) { fmt.Fprintf(printer, "\ncurrent configuration:\n\n") PrintEnv(cfg, printer) fmt.Fprintln(printer) - return } diff --git a/app/handle-req.go b/app/handle-req.go index 1251e57..d04dcc7 100644 --- a/app/handle-req.go +++ b/app/handle-req.go @@ -64,7 +64,7 @@ func (l *Listener) HandleReq(msg []byte) (err error) { l.ctx, 30*time.Second, ) defer queryCancel() - + // Collect all events from all filters var allEvents event.S for _, f := range *env.Filters { diff --git a/app/handle-websocket.go b/app/handle-websocket.go index b86cd0c..8254b1f 100644 --- a/app/handle-websocket.go +++ b/app/handle-websocket.go @@ -38,7 +38,9 @@ const ( func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { remote := GetRemoteFromReq(r) - log.T.F("handling websocket connection from %s", remote) + + // Log comprehensive proxy information for debugging + LogProxyInfo(r, "WebSocket connection from "+remote) if len(s.Config.IPWhitelist) > 0 { for _, ip := range s.Config.IPWhitelist { log.T.F("checking IP whitelist: %s", ip) @@ -55,9 +57,14 @@ whitelist: defer cancel() var err error var conn *websocket.Conn - if conn, err = websocket.Accept( - w, r, &websocket.AcceptOptions{OriginPatterns: []string{"*"}}, - ); chk.E(err) { + // Configure WebSocket accept options for proxy compatibility + acceptOptions := &websocket.AcceptOptions{ + OriginPatterns: []string{"*"}, // Allow all origins for proxy compatibility + // Don't check origin when behind a proxy - let the proxy handle it + InsecureSkipVerify: true, + } + + if conn, err = websocket.Accept(w, r, acceptOptions); chk.E(err) { log.E.F("websocket accept failed from %s: %v", remote, err) return } diff --git a/app/helpers.go b/app/helpers.go index c779e4c..f2ded4a 100644 --- a/app/helpers.go +++ b/app/helpers.go @@ -3,6 +3,8 @@ package app import ( "net/http" "strings" + + "lol.mleku.dev/log" ) // GetRemoteFromReq retrieves the originating IP address of the client from @@ -67,3 +69,28 @@ func GetRemoteFromReq(r *http.Request) (rr string) { } return } + +// LogProxyInfo logs comprehensive proxy information for debugging +func LogProxyInfo(r *http.Request, prefix string) { + proxyHeaders := map[string]string{ + "X-Forwarded-For": r.Header.Get("X-Forwarded-For"), + "X-Real-IP": r.Header.Get("X-Real-IP"), + "X-Forwarded-Proto": r.Header.Get("X-Forwarded-Proto"), + "X-Forwarded-Host": r.Header.Get("X-Forwarded-Host"), + "X-Forwarded-Port": r.Header.Get("X-Forwarded-Port"), + "Forwarded": r.Header.Get("Forwarded"), + "Host": r.Header.Get("Host"), + "User-Agent": r.Header.Get("User-Agent"), + } + + var info []string + for header, value := range proxyHeaders { + if value != "" { + info = append(info, header+":"+value) + } + } + + if len(info) > 0 { + log.T.F("%s proxy info: %s", prefix, strings.Join(info, " ")) + } +} diff --git a/app/server.go b/app/server.go index bfbff9c..5ad4c49 100644 --- a/app/server.go +++ b/app/server.go @@ -40,17 +40,24 @@ type Server struct { // Challenge storage for HTTP UI authentication challengeMutex sync.RWMutex challenges map[string][]byte - + paymentProcessor *PaymentProcessor } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Set CORS headers for all responses + // Set comprehensive CORS headers for proxy compatibility w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") - w.Header().Set( - "Access-Control-Allow-Headers", "Content-Type, Authorization", - ) + w.Header().Set("Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept, Authorization, "+ + "X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, X-Real-IP, "+ + "Upgrade, Connection, Sec-WebSocket-Key, Sec-WebSocket-Version, "+ + "Sec-WebSocket-Protocol, Sec-WebSocket-Extensions") + w.Header().Set("Access-Control-Allow-Credentials", "true") + w.Header().Set("Access-Control-Max-Age", "86400") + + // Add proxy-friendly headers + w.Header().Set("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers") // Handle preflight OPTIONS requests if r.Method == "OPTIONS" { @@ -58,6 +65,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + // Log proxy information for debugging (only for WebSocket requests to avoid spam) + if r.Header.Get("Upgrade") == "websocket" { + LogProxyInfo(r, "HTTP request") + } + // If this is a websocket request, only intercept the relay root path. // This allows other websocket paths (e.g., Vite HMR) to be handled by the dev proxy when enabled. if r.Header.Get("Upgrade") == "websocket" { @@ -83,13 +95,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func (s *Server) ServiceURL(req *http.Request) (st string) { + // Get host from various proxy headers host := req.Header.Get("X-Forwarded-Host") + if host == "" { + host = req.Header.Get("Host") + } if host == "" { host = req.Host } + + // Get protocol from various proxy headers proto := req.Header.Get("X-Forwarded-Proto") if proto == "" { - if host == "localhost" { + proto = req.Header.Get("X-Forwarded-Scheme") + } + if proto == "" { + // Check if we're behind a proxy by looking for common proxy headers + hasProxyHeaders := req.Header.Get("X-Forwarded-For") != "" || + req.Header.Get("X-Real-IP") != "" || + req.Header.Get("Forwarded") != "" + + if hasProxyHeaders { + // If we have proxy headers, assume HTTPS/WSS + proto = "wss" + } else if host == "localhost" { proto = "ws" } else if strings.Contains(host, ":") { // has a port number diff --git a/app/web/dist/index-kk1m7jg4.js b/app/web/dist/index-kk1m7jg4.js deleted file mode 100644 index 880a99c..0000000 --- a/app/web/dist/index-kk1m7jg4.js +++ /dev/null @@ -1,161 +0,0 @@ -var gA=Object.create;var{getPrototypeOf:fA,defineProperty:dH,getOwnPropertyNames:hA}=Object;var TA=Object.prototype.hasOwnProperty;var o4=(_,n,T)=>{T=_!=null?gA(fA(_)):{};let Z0=n||!_||!_.__esModule?dH(T,"default",{value:_,enumerable:!0}):T;for(let $ of hA(_))if(!TA.call(Z0,$))dH(Z0,$,{get:()=>_[$],enumerable:!0});return Z0};var L8=(_,n)=>()=>(n||_((n={exports:{}}).exports,n),n.exports);var Z6=L8((EA,WG)=>{(function(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart==="function")__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var _="18.3.1",n=Symbol.for("react.element"),T=Symbol.for("react.portal"),Z0=Symbol.for("react.fragment"),$=Symbol.for("react.strict_mode"),_0=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),s=Symbol.for("react.context"),q0=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),I0=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),y0=Symbol.for("react.lazy"),F1=Symbol.for("react.offscreen"),Y1=Symbol.iterator,z4="@@iterator";function k1(U){if(U===null||typeof U!=="object")return null;var M=Y1&&U[Y1]||U[z4];if(typeof M==="function")return M;return null}var L0={current:null},I1={transition:null},O0={current:null,isBatchingLegacy:!1,didScheduleLegacyUpdate:!1},N0={current:null},i0={},e1=null;function i1(U){e1=U}i0.setExtraStackFrame=function(U){e1=U},i0.getCurrentStack=null,i0.getStackAddendum=function(){var U="";if(e1)U+=e1;var M=i0.getCurrentStack;if(M)U+=M()||"";return U};var Z4=!1,s0=!1,A1=!1,S1=!1,a0=!1,N={ReactCurrentDispatcher:L0,ReactCurrentBatchConfig:I1,ReactCurrentOwner:N0};N.ReactDebugCurrentFrame=i0,N.ReactCurrentActQueue=O0;function y(U){{for(var M=arguments.length,P=new Array(M>1?M-1:0),k=1;k1?M-1:0),k=1;k1){var T1=Array(R1);for(var E1=0;E11){var m1=Array(E1);for(var a1=0;a1 is not supported and will be removed in a future major release. Did you mean to render instead?");return M.Provider},set:function(U0){M.Provider=U0}},_currentValue:{get:function(){return M._currentValue},set:function(U0){M._currentValue=U0}},_currentValue2:{get:function(){return M._currentValue2},set:function(U0){M._currentValue2=U0}},_threadCount:{get:function(){return M._threadCount},set:function(U0){M._threadCount=U0}},Consumer:{get:function(){if(!P)P=!0,l("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?");return M.Consumer}},displayName:{get:function(){return M.displayName},set:function(U0){if(!m)y("Setting `displayName` on Context.Consumer has no effect. You should set it directly on the context with Context.displayName = '%s'.",U0),m=!0}}}),M.Consumer=g0}return M._currentRenderer=null,M._currentRenderer2=null,M}var v4=-1,x8=0,C8=1,t4=2;function O8(U){if(U._status===v4){var M=U._result,P=M();if(P.then(function(g0){if(U._status===x8||U._status===v4){var U0=U;U0._status=C8,U0._result=g0}},function(g0){if(U._status===x8||U._status===v4){var U0=U;U0._status=t4,U0._result=g0}}),U._status===v4){var k=U;k._status=x8,k._result=P}}if(U._status===C8){var m=U._result;if(m===void 0)l(`lazy: Expected the result of a dynamic import() call. Instead received: %s - -Your code should look like: - const MyComponent = lazy(() => import('./MyComponent')) - -Did you accidentally put curly braces around the import?`,m);if(!("default"in m))l(`lazy: Expected the result of a dynamic import() call. Instead received: %s - -Your code should look like: - const MyComponent = lazy(() => import('./MyComponent'))`,m);return m.default}else throw U._result}function g8(U){var M={_status:v4,_result:U},P={$$typeof:y0,_payload:M,_init:O8};{var k,m;Object.defineProperties(P,{defaultProps:{configurable:!0,get:function(){return k},set:function(g0){l("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),k=g0,Object.defineProperty(P,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return m},set:function(g0){l("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),m=g0,Object.defineProperty(P,"propTypes",{enumerable:!0})}}})}return P}function L(U){{if(U!=null&&U.$$typeof===p)l("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...)).");else if(typeof U!=="function")l("forwardRef requires a render function but was given %s.",U===null?"null":typeof U);else if(U.length!==0&&U.length!==2)l("forwardRef render functions accept exactly two parameters: props and ref. %s",U.length===1?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined.");if(U!=null){if(U.defaultProps!=null||U.propTypes!=null)l("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?")}}var M={$$typeof:q0,render:U};{var P;Object.defineProperty(M,"displayName",{enumerable:!1,configurable:!0,get:function(){return P},set:function(k){if(P=k,!U.name&&!U.displayName)U.displayName=k}})}return M}var h=Symbol.for("react.module.reference");function a(U){if(typeof U==="string"||typeof U==="function")return!0;if(U===Z0||U===_0||a0||U===$||U===c||U===I0||S1||U===F1||Z4||s0||A1)return!0;if(typeof U==="object"&&U!==null){if(U.$$typeof===y0||U.$$typeof===p||U.$$typeof===t||U.$$typeof===s||U.$$typeof===q0||U.$$typeof===h||U.getModuleId!==void 0)return!0}return!1}function D0(U,M){if(!a(U))l("memo: The first argument must be a component. Instead received: %s",U===null?"null":typeof U);var P={$$typeof:p,type:U,compare:M===void 0?null:M};{var k;Object.defineProperty(P,"displayName",{enumerable:!1,configurable:!0,get:function(){return k},set:function(m){if(k=m,!U.name&&!U.displayName)U.displayName=m}})}return P}function g(){var U=L0.current;if(U===null)l(`Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: -1. You might have mismatching versions of React and the renderer (such as React DOM) -2. You might be breaking the Rules of Hooks -3. You might have more than one copy of React in the same app -See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.`);return U}function n0(U){var M=g();if(U._context!==void 0){var P=U._context;if(P.Consumer===U)l("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?");else if(P.Provider===U)l("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?")}return M.useContext(U)}function i(U){var M=g();return M.useState(U)}function h0(U,M,P){var k=g();return k.useReducer(U,M,P)}function X1(U){var M=g();return M.useRef(U)}function P1(U,M){var P=g();return P.useEffect(U,M)}function Y(U,M){var P=g();return P.useInsertionEffect(U,M)}function j(U,M){var P=g();return P.useLayoutEffect(U,M)}function v(U,M){var P=g();return P.useCallback(U,M)}function C(U,M){var P=g();return P.useMemo(U,M)}function b(U,M,P){var k=g();return k.useImperativeHandle(U,M,P)}function u(U,M){{var P=g();return P.useDebugValue(U,M)}}function d(){var U=g();return U.useTransition()}function B0(U){var M=g();return M.useDeferredValue(U)}function J0(){var U=g();return U.useId()}function U1(U,M,P){var k=g();return k.useSyncExternalStore(U,M,P)}var r0=0,b0,M0,j0,F0,c0,o1,e4;function c5(){}c5.__reactDisabledLog=!0;function $G(){{if(r0===0){b0=console.log,M0=console.info,j0=console.warn,F0=console.error,c0=console.group,o1=console.groupCollapsed,e4=console.groupEnd;var U={configurable:!0,enumerable:!0,value:c5,writable:!0};Object.defineProperties(console,{info:U,log:U,warn:U,error:U,group:U,groupCollapsed:U,groupEnd:U})}r0++}}function J6(){{if(r0--,r0===0){var U={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:w0({},U,{value:b0}),info:w0({},U,{value:M0}),warn:w0({},U,{value:j0}),error:w0({},U,{value:F0}),group:w0({},U,{value:c0}),groupCollapsed:w0({},U,{value:o1}),groupEnd:w0({},U,{value:e4})})}if(r0<0)l("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var _9=N.ReactCurrentDispatcher,f8;function l5(U,M,P){{if(f8===void 0)try{throw Error()}catch(m){var k=m.stack.trim().match(/\n( *(at )?)/);f8=k&&k[1]||""}return` -`+f8+U}}var o5=!1,Q7;{var B6=typeof WeakMap==="function"?WeakMap:Map;Q7=new B6}function oZ(U,M){if(!U||o5)return"";{var P=Q7.get(U);if(P!==void 0)return P}var k;o5=!0;var m=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var g0;g0=_9.current,_9.current=null,$G();try{if(M){var U0=function(){throw Error()};if(Object.defineProperty(U0.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==="object"&&Reflect.construct){try{Reflect.construct(U0,[])}catch(M1){k=M1}Reflect.construct(U,[],U0)}else{try{U0.call()}catch(M1){k=M1}U.call(U0.prototype)}}else{try{throw Error()}catch(M1){k=M1}U()}}catch(M1){if(M1&&k&&typeof M1.stack==="string"){var v0=M1.stack.split(` -`),G1=k.stack.split(` -`),R1=v0.length-1,T1=G1.length-1;while(R1>=1&&T1>=0&&v0[R1]!==G1[T1])T1--;for(;R1>=1&&T1>=0;R1--,T1--)if(v0[R1]!==G1[T1]){if(R1!==1||T1!==1)do if(R1--,T1--,T1<0||v0[R1]!==G1[T1]){var E1=` -`+v0[R1].replace(" at new "," at ");if(U.displayName&&E1.includes(""))E1=E1.replace("",U.displayName);if(typeof U==="function")Q7.set(U,E1);return E1}while(R1>=1&&T1>=0);break}}}finally{o5=!1,_9.current=g0,J6(),Error.prepareStackTrace=m}var m1=U?U.displayName||U.name:"",a1=m1?l5(m1):"";if(typeof U==="function")Q7.set(U,a1);return a1}function W6(U,M,P){return oZ(U,!1)}function qG(U){var M=U.prototype;return!!(M&&M.isReactComponent)}function s5(U,M,P){if(U==null)return"";if(typeof U==="function")return oZ(U,qG(U));if(typeof U==="string")return l5(U);switch(U){case c:return l5("Suspense");case I0:return l5("SuspenseList")}if(typeof U==="object")switch(U.$$typeof){case q0:return W6(U.render);case p:return s5(U.type,M,P);case y0:{var k=U,m=k._payload,g0=k._init;try{return s5(g0(m),M,P)}catch(U0){}}}return""}var sZ={},U6=N.ReactDebugCurrentFrame;function G7(U){if(U){var M=U._owner,P=s5(U.type,U._source,M?M.type:null);U6.setExtraStackFrame(P)}else U6.setExtraStackFrame(null)}function nZ(U,M,P,k,m){{var g0=Function.call.bind(B8);for(var U0 in U)if(g0(U,U0)){var v0=void 0;try{if(typeof U[U0]!=="function"){var G1=Error((k||"React class")+": "+P+" type `"+U0+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof U[U0]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw G1.name="Invariant Violation",G1}v0=U[U0](M,U0,k,P,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(R1){v0=R1}if(v0&&!(v0 instanceof Error))G7(m),l("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",k||"React class",P,U0,typeof v0),G7(null);if(v0 instanceof Error&&!(v0.message in sZ))sZ[v0.message]=!0,G7(m),l("Failed %s type: %s",P,v0.message),G7(null)}}}function H1(U){if(U){var M=U._owner,P=s5(U.type,U._source,M?M.type:null);i1(P)}else i1(null)}var pZ=!1;function H6(){if(N0.current){var U=_1(N0.current.type);if(U)return` - -Check the render method of \``+U+"`."}return""}function o0(U){if(U!==void 0){var M=U.fileName.replace(/^.*[\\\/]/,""),P=U.lineNumber;return` - -Check your code at `+M+":"+P+"."}return""}function aZ(U){if(U!==null&&U!==void 0)return o0(U.__source);return""}var d4={};function P9(U){var M=H6();if(!M){var P=typeof U==="string"?U:U.displayName||U.name;if(P)M=` - -Check the top-level render call using <`+P+">."}return M}function n5(U,M){if(!U._store||U._store.validated||U.key!=null)return;U._store.validated=!0;var P=P9(M);if(d4[P])return;d4[P]=!0;var k="";if(U&&U._owner&&U._owner!==N0.current)k=" It was passed a child from "+_1(U._owner.type)+".";H1(U),l('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',P,k),H1(null)}function rZ(U,M){if(typeof U!=="object")return;if(v1(U))for(var P=0;P",m=" Did you accidentally export a JSX literal instead of a component?";else U0=typeof U;l("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",U0,m)}var v0=Q4.apply(this,arguments);if(v0==null)return v0;if(k)for(var G1=2;G110)y("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.");k._updatedFibers.clear()}}}var z7=!1,R9=null;function eZ(U){if(R9===null)try{var M=("require"+Math.random()).slice(0,7),P=WG&&WG[M];R9=P.call(WG,"timers").setImmediate}catch(k){R9=function(m){if(z7===!1){if(z7=!0,typeof MessageChannel==="undefined")l("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning.")}var g0=new MessageChannel;g0.port1.onmessage=m,g0.port2.postMessage(void 0)}}return R9(U)}var p5=0,ZX=!1;function XX(U){{var M=p5;if(p5++,O0.current===null)O0.current=[];var P=O0.isBatchingLegacy,k;try{if(O0.isBatchingLegacy=!0,k=U(),!P&&O0.didScheduleLegacyUpdate){var m=O0.current;if(m!==null)O0.didScheduleLegacyUpdate=!1,J7(m)}}catch(m1){throw O5(M),m1}finally{O0.isBatchingLegacy=P}if(k!==null&&typeof k==="object"&&typeof k.then==="function"){var g0=k,U0=!1,v0={then:function(m1,a1){U0=!0,g0.then(function(M1){if(O5(M),p5===0)K7(M1,m1,a1);else m1(M1)},function(M1){O5(M),a1(M1)})}};if(!ZX&&typeof Promise!=="undefined")Promise.resolve().then(function(){}).then(function(){if(!U0)ZX=!0,l("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);")});return v0}else{var G1=k;if(O5(M),p5===0){var R1=O0.current;if(R1!==null)J7(R1),O0.current=null;var T1={then:function(m1,a1){if(O0.current===null)O0.current=[],K7(G1,m1,a1);else m1(G1)}};return T1}else{var E1={then:function(m1,a1){m1(G1)}};return E1}}}}function O5(U){{if(U!==p5-1)l("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");p5=U}}function K7(U,M,P){{var k=O0.current;if(k!==null)try{J7(k),eZ(function(){if(k.length===0)O0.current=null,M(U);else K7(U,M,P)})}catch(m){P(m)}else M(U)}}var a5=!1;function J7(U){if(!a5){a5=!0;var M=0;try{for(;M{(function(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart==="function")__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var _=!1,n=!1,T=5;function Z0(X0,H0){var R0=X0.length;X0.push(H0),t(X0,H0,R0)}function $(X0){return X0.length===0?null:X0[0]}function _0(X0){if(X0.length===0)return null;var H0=X0[0],R0=X0.pop();if(R0!==H0)X0[0]=R0,s(X0,R0,0);return H0}function t(X0,H0,R0){var B1=R0;while(B1>0){var x1=B1-1>>>1,l1=X0[x1];if(q0(l1,H0)>0)X0[x1]=H0,X0[B1]=l1,B1=x1;else return}}function s(X0,H0,R0){var B1=R0,x1=X0.length,l1=x1>>>1;while(B1R0&&(!X0||B8()))break;var B1=a0.callback;if(typeof B1==="function"){a0.callback=null,N=a0.priorityLevel;var x1=a0.expirationTime<=R0,l1=B1(x1);if(R0=uA.unstable_now(),typeof l1==="function")a0.callback=l1;else if(a0===$(s0))_0(s0);x0(R0)}else _0(s0);a0=$(s0)}if(a0!==null)return!0;else{var C1=$(A1);if(C1!==null)k8(u0,C1.startTime-R0);return!1}}function O1(X0,H0){switch(X0){case c:case I0:case p:case y0:case F1:break;default:X0=p}var R0=N;N=X0;try{return H0()}finally{N=R0}}function c1(X0){var H0;switch(N){case c:case I0:case p:H0=p;break;default:H0=N;break}var R0=N;N=H0;try{return X0()}finally{N=R0}}function p1(X0){var H0=N;return function(){var R0=N;N=H0;try{return X0.apply(this,arguments)}finally{N=R0}}}function C0(X0,H0,R0){var B1=uA.unstable_now(),x1;if(typeof R0==="object"&&R0!==null){var l1=R0.delay;if(typeof l1==="number"&&l1>0)x1=B1+l1;else x1=B1}else x1=B1;var C1;switch(X0){case c:C1=N0;break;case I0:C1=i0;break;case F1:C1=Z4;break;case y0:C1=i1;break;case p:default:C1=e1;break}var A4=x1+C1,Z1={id:S1++,callback:H0,priorityLevel:X0,startTime:x1,expirationTime:A4,sortIndex:-1};if(x1>B1){if(Z1.sortIndex=x1,Z0(A1,Z1),$(s0)===null&&Z1===$(A1)){if(Y0)S8();else Y0=!0;k8(u0,x1-B1)}}else if(Z1.sortIndex=A4,Z0(s0,Z1),!l&&!y)l=!0,H4(E0);return Z1}function K4(){}function V4(){if(!l&&!y)l=!0,H4(E0)}function v1(){return $(s0)}function o(X0){X0.callback=null}function F4(){return N}var f1=!1,N1=null,E4=-1,I8=T,_1=-1;function B8(){var X0=uA.unstable_now()-_1;if(X0125){console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported");return}if(X0>0)I8=Math.floor(1000/X0);else I8=T}var n4=function(){if(N1!==null){var X0=uA.unstable_now();_1=X0;var H0=!0,R0=!0;try{R0=N1(H0,X0)}finally{if(R0)X4();else f1=!1,N1=null}}else f1=!1},X4;if(typeof k0==="function")X4=function(){k0(n4)};else if(typeof MessageChannel!=="undefined"){var p4=new MessageChannel,J4=p4.port2;p4.port1.onmessage=n4,X4=function(){J4.postMessage(null)}}else X4=function(){P0(n4,0)};function H4(X0){if(N1=X0,!f1)f1=!0,X4()}function k8(X0,H0){E4=P0(function(){X0(uA.unstable_now())},H0)}function S8(){T0(E4),E4=-1}var a4=h1,Q4=null;if(uA.unstable_IdlePriority=F1,uA.unstable_ImmediatePriority=c,uA.unstable_LowPriority=y0,uA.unstable_NormalPriority=p,uA.unstable_Profiling=Q4,uA.unstable_UserBlockingPriority=I0,uA.unstable_cancelCallback=o,uA.unstable_continueExecution=V4,uA.unstable_forceFrameRate=s4,uA.unstable_getCurrentPriorityLevel=F4,uA.unstable_getFirstCallbackNode=v1,uA.unstable_next=c1,uA.unstable_pauseExecution=K4,uA.unstable_requestPaint=a4,uA.unstable_runWithPriority=O1,uA.unstable_scheduleCallback=C0,uA.unstable_shouldYield=B8,uA.unstable_wrapCallback=p1,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop==="function")__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error)})()});var yH=L8((vA)=>{var iZ=o4(Z6(),1),b1=o4(mH(),1);(function(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!=="undefined"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart==="function")__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var _=iZ.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,n=!1;function T(Z){n=Z}function Z0(Z){if(!n){for(var X=arguments.length,Q=new Array(X>1?X-1:0),G=1;G1?X-1:0),G=1;G2&&(Z[0]==="o"||Z[0]==="O")&&(Z[1]==="n"||Z[1]==="N"))return!0;return!1}function l1(Z,X,Q,G){if(Q!==null&&Q.type===n4)return!1;switch(typeof X){case"function":case"symbol":return!0;case"boolean":{if(G)return!1;if(Q!==null)return!Q.acceptsBooleans;else{var z=Z.toLowerCase().slice(0,5);return z!=="data-"&&z!=="aria-"}}default:return!1}}function C1(Z,X,Q,G){if(X===null||typeof X==="undefined")return!0;if(l1(Z,X,Q,G))return!0;if(G)return!1;if(Q!==null)switch(Q.type){case J4:return!X;case H4:return X===!1;case k8:return isNaN(X);case S8:return isNaN(X)||X<1}return!1}function A4(Z){return Q1.hasOwnProperty(Z)?Q1[Z]:null}function Z1(Z,X,Q,G,z,K,J){this.acceptsBooleans=X===p4||X===J4||X===H4,this.attributeName=G,this.attributeNamespace=z,this.mustUseProperty=Q,this.propertyName=Z,this.type=X,this.sanitizeURL=K,this.removeEmptyString=J}var Q1={},w8=["children","dangerouslySetInnerHTML","defaultValue","defaultChecked","innerHTML","suppressContentEditableWarning","suppressHydrationWarning","style"];w8.forEach(function(Z){Q1[Z]=new Z1(Z,n4,!1,Z,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(Z){var X=Z[0],Q=Z[1];Q1[X]=new Z1(X,X4,!1,Q,null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(Z){Q1[Z]=new Z1(Z,p4,!1,Z.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(Z){Q1[Z]=new Z1(Z,p4,!1,Z,null,!1,!1)}),["allowFullScreen","async","autoFocus","autoPlay","controls","default","defer","disabled","disablePictureInPicture","disableRemotePlayback","formNoValidate","hidden","loop","noModule","noValidate","open","playsInline","readOnly","required","reversed","scoped","seamless","itemScope"].forEach(function(Z){Q1[Z]=new Z1(Z,J4,!1,Z.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(Z){Q1[Z]=new Z1(Z,J4,!0,Z,null,!1,!1)}),["capture","download"].forEach(function(Z){Q1[Z]=new Z1(Z,H4,!1,Z,null,!1,!1)}),["cols","rows","size","span"].forEach(function(Z){Q1[Z]=new Z1(Z,S8,!1,Z,null,!1,!1)}),["rowSpan","start"].forEach(function(Z){Q1[Z]=new Z1(Z,k8,!1,Z.toLowerCase(),null,!1,!1)});var u4=/[\-\:]([a-z])/g,N8=function(Z){return Z[1].toUpperCase()};["accent-height","alignment-baseline","arabic-form","baseline-shift","cap-height","clip-path","clip-rule","color-interpolation","color-interpolation-filters","color-profile","color-rendering","dominant-baseline","enable-background","fill-opacity","fill-rule","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","glyph-name","glyph-orientation-horizontal","glyph-orientation-vertical","horiz-adv-x","horiz-origin-x","image-rendering","letter-spacing","lighting-color","marker-end","marker-mid","marker-start","overline-position","overline-thickness","paint-order","panose-1","pointer-events","rendering-intent","shape-rendering","stop-color","stop-opacity","strikethrough-position","strikethrough-thickness","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-decoration","text-rendering","underline-position","underline-thickness","unicode-bidi","unicode-range","units-per-em","v-alphabetic","v-hanging","v-ideographic","v-mathematical","vector-effect","vert-adv-y","vert-origin-x","vert-origin-y","word-spacing","writing-mode","xmlns:xlink","x-height"].forEach(function(Z){var X=Z.replace(u4,N8);Q1[X]=new Z1(X,X4,!1,Z,null,!1,!1)}),["xlink:actuate","xlink:arcrole","xlink:role","xlink:show","xlink:title","xlink:type"].forEach(function(Z){var X=Z.replace(u4,N8);Q1[X]=new Z1(X,X4,!1,Z,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(Z){var X=Z.replace(u4,N8);Q1[X]=new Z1(X,X4,!1,Z,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(Z){Q1[Z]=new Z1(Z,X4,!1,Z.toLowerCase(),null,!1,!1)});var A9="xlinkHref";Q1[A9]=new Z1("xlinkHref",X4,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(Z){Q1[Z]=new Z1(Z,X4,!1,Z.toLowerCase(),null,!0,!0)});var r4=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i,i5=!1;function w5(Z){if(!i5&&r4.test(Z))i5=!0,$("A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed %s.",JSON.stringify(Z))}function v4(Z,X,Q,G){if(G.mustUseProperty){var z=G.propertyName;return Z[z]}else{if(E4(Q,X),G.sanitizeURL)w5(""+Q);var K=G.attributeName,J=null;if(G.type===H4){if(Z.hasAttribute(K)){var B=Z.getAttribute(K);if(B==="")return!0;if(C1(X,Q,G,!1))return B;if(B===""+Q)return Q;return B}}else if(Z.hasAttribute(K)){if(C1(X,Q,G,!1))return Z.getAttribute(K);if(G.type===J4)return Q;J=Z.getAttribute(K)}if(C1(X,Q,G,!1))return J===null?Q:J;else if(J===""+Q)return Q;else return J}}function x8(Z,X,Q,G){{if(!B1(X))return;if(!Z.hasAttribute(X))return Q===void 0?void 0:null;var z=Z.getAttribute(X);if(E4(Q,X),z===""+Q)return Q;return z}}function C8(Z,X,Q,G){var z=A4(X);if(x1(X,z,G))return;if(C1(X,Q,z,G))Q=null;if(G||z===null){if(B1(X)){var K=X;if(Q===null)Z.removeAttribute(K);else E4(Q,X),Z.setAttribute(K,""+Q)}return}var J=z.mustUseProperty;if(J){var B=z.propertyName;if(Q===null){var W=z.type;Z[B]=W===J4?!1:""}else Z[B]=Q;return}var{attributeName:H,attributeNamespace:q}=z;if(Q===null)Z.removeAttribute(H);else{var w=z.type,I;if(w===J4||w===H4&&Q===!0)I="";else if(E4(Q,H),I=""+Q,z.sanitizeURL)w5(I.toString());if(q)Z.setAttributeNS(q,H,I);else Z.setAttribute(H,I)}}var t4=Symbol.for("react.element"),O8=Symbol.for("react.portal"),g8=Symbol.for("react.fragment"),L=Symbol.for("react.strict_mode"),h=Symbol.for("react.profiler"),a=Symbol.for("react.provider"),D0=Symbol.for("react.context"),g=Symbol.for("react.forward_ref"),n0=Symbol.for("react.suspense"),i=Symbol.for("react.suspense_list"),h0=Symbol.for("react.memo"),X1=Symbol.for("react.lazy"),P1=Symbol.for("react.scope"),Y=Symbol.for("react.debug_trace_mode"),j=Symbol.for("react.offscreen"),v=Symbol.for("react.legacy_hidden"),C=Symbol.for("react.cache"),b=Symbol.for("react.tracing_marker"),u=Symbol.iterator,d="@@iterator";function B0(Z){if(Z===null||typeof Z!=="object")return null;var X=u&&Z[u]||Z[d];if(typeof X==="function")return X;return null}var J0=Object.assign,U1=0,r0,b0,M0,j0,F0,c0,o1;function e4(){}e4.__reactDisabledLog=!0;function c5(){{if(U1===0){r0=console.log,b0=console.info,M0=console.warn,j0=console.error,F0=console.group,c0=console.groupCollapsed,o1=console.groupEnd;var Z={configurable:!0,enumerable:!0,value:e4,writable:!0};Object.defineProperties(console,{info:Z,log:Z,warn:Z,error:Z,group:Z,groupCollapsed:Z,groupEnd:Z})}U1++}}function $G(){{if(U1--,U1===0){var Z={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:J0({},Z,{value:r0}),info:J0({},Z,{value:b0}),warn:J0({},Z,{value:M0}),error:J0({},Z,{value:j0}),group:J0({},Z,{value:F0}),groupCollapsed:J0({},Z,{value:c0}),groupEnd:J0({},Z,{value:o1})})}if(U1<0)$("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var J6=_.ReactCurrentDispatcher,_9;function f8(Z,X,Q){{if(_9===void 0)try{throw Error()}catch(z){var G=z.stack.trim().match(/\n( *(at )?)/);_9=G&&G[1]||""}return` -`+_9+Z}}var l5=!1,o5;{var Q7=typeof WeakMap==="function"?WeakMap:Map;o5=new Q7}function B6(Z,X){if(!Z||l5)return"";{var Q=o5.get(Z);if(Q!==void 0)return Q}var G;l5=!0;var z=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var K;K=J6.current,J6.current=null,c5();try{if(X){var J=function(){throw Error()};if(Object.defineProperty(J.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==="object"&&Reflect.construct){try{Reflect.construct(J,[])}catch(D){G=D}Reflect.construct(Z,[],J)}else{try{J.call()}catch(D){G=D}Z.call(J.prototype)}}else{try{throw Error()}catch(D){G=D}Z()}}catch(D){if(D&&G&&typeof D.stack==="string"){var B=D.stack.split(` -`),W=G.stack.split(` -`),H=B.length-1,q=W.length-1;while(H>=1&&q>=0&&B[H]!==W[q])q--;for(;H>=1&&q>=0;H--,q--)if(B[H]!==W[q]){if(H!==1||q!==1)do if(H--,q--,q<0||B[H]!==W[q]){var w=` -`+B[H].replace(" at new "," at ");if(Z.displayName&&w.includes(""))w=w.replace("",Z.displayName);if(typeof Z==="function")o5.set(Z,w);return w}while(H>=1&&q>=0);break}}}finally{l5=!1,J6.current=K,$G(),Error.prepareStackTrace=z}var I=Z?Z.displayName||Z.name:"",R=I?f8(I):"";if(typeof Z==="function")o5.set(Z,R);return R}function oZ(Z,X,Q){return B6(Z,!0)}function W6(Z,X,Q){return B6(Z,!1)}function qG(Z){var X=Z.prototype;return!!(X&&X.isReactComponent)}function s5(Z,X,Q){if(Z==null)return"";if(typeof Z==="function")return B6(Z,qG(Z));if(typeof Z==="string")return f8(Z);switch(Z){case n0:return f8("Suspense");case i:return f8("SuspenseList")}if(typeof Z==="object")switch(Z.$$typeof){case g:return W6(Z.render);case h0:return s5(Z.type,X,Q);case X1:{var G=Z,z=G._payload,K=G._init;try{return s5(K(z),X,Q)}catch(J){}}}return""}function sZ(Z){var X=Z._debugOwner?Z._debugOwner.type:null,Q=Z._debugSource;switch(Z.tag){case p:return f8(Z.type);case e1:return f8("Lazy");case O0:return f8("Suspense");case s0:return f8("SuspenseList");case t:case q0:case i0:return W6(Z.type);case L0:return W6(Z.type.render);case s:return oZ(Z.type);default:return""}}function U6(Z){try{var X="",Q=Z;do X+=sZ(Q),Q=Q.return;while(Q);return X}catch(G){return` -Error generating stack: `+G.message+` -`+G.stack}}function G7(Z,X,Q){var G=Z.displayName;if(G)return G;var z=X.displayName||X.name||"";return z!==""?Q+"("+z+")":Q}function nZ(Z){return Z.displayName||"Context"}function H1(Z){if(Z==null)return null;if(typeof Z.tag==="number")$("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.");if(typeof Z==="function")return Z.displayName||Z.name||null;if(typeof Z==="string")return Z;switch(Z){case g8:return"Fragment";case O8:return"Portal";case h:return"Profiler";case L:return"StrictMode";case n0:return"Suspense";case i:return"SuspenseList"}if(typeof Z==="object")switch(Z.$$typeof){case D0:var X=Z;return nZ(X)+".Consumer";case a:var Q=Z;return nZ(Q._context)+".Provider";case g:return G7(Z,Z.render,"ForwardRef");case h0:var G=Z.displayName||null;if(G!==null)return G;return H1(Z.type)||"Memo";case X1:{var z=Z,K=z._payload,J=z._init;try{return H1(J(K))}catch(B){return null}}}return null}function pZ(Z,X,Q){var G=X.displayName||X.name||"";return Z.displayName||(G!==""?Q+"("+G+")":Q)}function H6(Z){return Z.displayName||"Context"}function o0(Z){var{tag:X,type:Q}=Z;switch(X){case N:return"Cache";case z4:var G=Q;return H6(G)+".Consumer";case k1:var z=Q;return H6(z._context)+".Provider";case Z4:return"DehydratedFragment";case L0:return pZ(Q,Q.render,"ForwardRef");case F1:return"Fragment";case p:return Q;case I0:return"Portal";case c:return"Root";case y0:return"Text";case e1:return H1(Q);case Y1:if(Q===L)return"StrictMode";return"Mode";case S1:return"Offscreen";case I1:return"Profiler";case A1:return"Scope";case O0:return"Suspense";case s0:return"SuspenseList";case y:return"TracingMarker";case s:case t:case i1:case q0:case N0:case i0:if(typeof Q==="function")return Q.displayName||Q.name||null;if(typeof Q==="string")return Q;break}return null}var aZ=_.ReactDebugCurrentFrame,d4=null,P9=!1;function n5(){{if(d4===null)return null;var Z=d4._debugOwner;if(Z!==null&&typeof Z!=="undefined")return o0(Z)}return null}function rZ(){{if(d4===null)return"";return U6(d4)}}function _4(){aZ.getCurrentStack=null,d4=null,P9=!1}function s1(Z){aZ.getCurrentStack=Z===null?null:rZ,d4=Z,P9=!1}function tZ(){return d4}function F8(Z){P9=Z}function W8(Z){return""+Z}function Q5(Z){switch(typeof Z){case"boolean":case"number":case"string":case"undefined":return Z;case"object":return s4(Z),Z;default:return""}}var YG={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0};function z7(Z,X){{if(!(YG[X.type]||X.onChange||X.onInput||X.readOnly||X.disabled||X.value==null))$("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.");if(!(X.onChange||X.readOnly||X.disabled||X.checked==null))$("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")}}function R9(Z){var{type:X,nodeName:Q}=Z;return Q&&Q.toLowerCase()==="input"&&(X==="checkbox"||X==="radio")}function eZ(Z){return Z._valueTracker}function p5(Z){Z._valueTracker=null}function ZX(Z){var X="";if(!Z)return X;if(R9(Z))X=Z.checked?"true":"false";else X=Z.value;return X}function XX(Z){var X=R9(Z)?"checked":"value",Q=Object.getOwnPropertyDescriptor(Z.constructor.prototype,X);s4(Z[X]);var G=""+Z[X];if(Z.hasOwnProperty(X)||typeof Q==="undefined"||typeof Q.get!=="function"||typeof Q.set!=="function")return;var{get:z,set:K}=Q;Object.defineProperty(Z,X,{configurable:!0,get:function(){return z.call(this)},set:function(B){s4(B),G=""+B,K.call(this,B)}}),Object.defineProperty(Z,X,{enumerable:Q.enumerable});var J={getValue:function(){return G},setValue:function(B){s4(B),G=""+B},stopTracking:function(){p5(Z),delete Z[X]}};return J}function O5(Z){if(eZ(Z))return;Z._valueTracker=XX(Z)}function K7(Z){if(!Z)return!1;var X=eZ(Z);if(!X)return!0;var Q=X.getValue(),G=ZX(Z);if(G!==Q)return X.setValue(G),!0;return!1}function a5(Z){if(Z=Z||(typeof document!=="undefined"?document:void 0),typeof Z==="undefined")return null;try{return Z.activeElement||Z.body}catch(X){return Z.body}}var J7=!1,QX=!1,GX=!1,zX=!1;function KX(Z){var X=Z.type==="checkbox"||Z.type==="radio";return X?Z.checked!=null:Z.value!=null}function U(Z,X){var Q=Z,G=X.checked,z=J0({},X,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:G!=null?G:Q._wrapperState.initialChecked});return z}function M(Z,X){{if(z7("input",X),X.checked!==void 0&&X.defaultChecked!==void 0&&!QX)$("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components",n5()||"A component",X.type),QX=!0;if(X.value!==void 0&&X.defaultValue!==void 0&&!J7)$("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components",n5()||"A component",X.type),J7=!0}var Q=Z,G=X.defaultValue==null?"":X.defaultValue;Q._wrapperState={initialChecked:X.checked!=null?X.checked:X.defaultChecked,initialValue:Q5(X.value!=null?X.value:G),controlled:KX(X)}}function P(Z,X){var Q=Z,G=X.checked;if(G!=null)C8(Q,"checked",G,!1)}function k(Z,X){var Q=Z;{var G=KX(X);if(!Q._wrapperState.controlled&&G&&!zX)$("A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"),zX=!0;if(Q._wrapperState.controlled&&!G&&!GX)$("A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"),GX=!0}P(Z,X);var z=Q5(X.value),K=X.type;if(z!=null){if(K==="number"){if(z===0&&Q.value===""||Q.value!=z)Q.value=W8(z)}else if(Q.value!==W8(z))Q.value=W8(z)}else if(K==="submit"||K==="reset"){Q.removeAttribute("value");return}if(X.hasOwnProperty("value"))v0(Q,X.type,z);else if(X.hasOwnProperty("defaultValue"))v0(Q,X.type,Q5(X.defaultValue));if(X.checked==null&&X.defaultChecked!=null)Q.defaultChecked=!!X.defaultChecked}function m(Z,X,Q){var G=Z;if(X.hasOwnProperty("value")||X.hasOwnProperty("defaultValue")){var z=X.type,K=z==="submit"||z==="reset";if(K&&(X.value===void 0||X.value===null))return;var J=W8(G._wrapperState.initialValue);if(!Q){if(J!==G.value)G.value=J}G.defaultValue=J}var B=G.name;if(B!=="")G.name="";if(G.defaultChecked=!G.defaultChecked,G.defaultChecked=!!G._wrapperState.initialChecked,B!=="")G.name=B}function g0(Z,X){var Q=Z;k(Q,X),U0(Q,X)}function U0(Z,X){var Q=X.name;if(X.type==="radio"&&Q!=null){var G=Z;while(G.parentNode)G=G.parentNode;E4(Q,"name");var z=G.querySelectorAll("input[name="+JSON.stringify(""+Q)+'][type="radio"]');for(var K=0;K.")});else if(X.dangerouslySetInnerHTML!=null){if(!T1)T1=!0,$("Pass a `value` prop if you set dangerouslyInnerHTML so React knows which value should be selected.")}}if(X.selected!=null&&!G1)$("Use the `defaultValue` or `value` props on must be an array if `multiple` is true.%s",Q,B7());else if(!Z.multiple&&G)$("The `%s` prop supplied to