diff --git a/app/src/components/navbar/PointsNavBar.tsx b/app/src/components/navbar/PointsNavBar.tsx index 905bd2fb5..1e2f3a621 100644 --- a/app/src/components/navbar/PointsNavBar.tsx +++ b/app/src/components/navbar/PointsNavBar.tsx @@ -39,7 +39,7 @@ export const PointsNavBar = (props: NativeStackHeaderProps) => { color={black} fontSize={15} fontWeight="500" - fontFamily="DIN OT" + fontFamily="DINOT-Medium" textAlign="center" style={{ letterSpacing: 0.6, diff --git a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/api/SelfSdk.android.kt b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/api/SelfSdk.android.kt index 3f9b78563..65f60fb66 100644 --- a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/api/SelfSdk.android.kt +++ b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/api/SelfSdk.android.kt @@ -108,8 +108,8 @@ actual class SelfSdk private constructor( ) { when (resultCode) { Activity.RESULT_OK -> { - // Success val resultDataJson = data?.getStringExtra(SelfVerificationActivity.EXTRA_RESULT_DATA) + val resultType = data?.getStringExtra(SelfVerificationActivity.EXTRA_RESULT_TYPE) if (resultDataJson != null) { try { val result = deserializeResult(resultDataJson) @@ -122,6 +122,10 @@ actual class SelfSdk private constructor( ), ) } + } else if (resultType != null) { + callback.onSuccess( + VerificationResult(success = true, type = resultType), + ) } else { callback.onFailure( SelfSdkError( diff --git a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt index 943440bc3..f1378037a 100644 --- a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt +++ b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt @@ -11,6 +11,7 @@ import kotlinx.serialization.json.jsonPrimitive import xyz.self.sdk.bridge.BridgeDomain import xyz.self.sdk.bridge.BridgeHandler import xyz.self.sdk.bridge.BridgeHandlerException +import xyz.self.sdk.webview.SelfVerificationActivity /** * Android implementation of lifecycle bridge handler. @@ -72,16 +73,16 @@ class LifecycleBridgeHandler( if (type != null) { // Flat lifecycle payload (e.g. { type: "proofRequested" }) — treat as success - intent.putExtra("xyz.self.sdk.RESULT_TYPE", type) + intent.putExtra(SelfVerificationActivity.EXTRA_RESULT_TYPE, type) activity.setResult(Activity.RESULT_OK, intent) } else if (success && data != null) { // Success result - intent.putExtra("xyz.self.sdk.RESULT_DATA", data) + intent.putExtra(SelfVerificationActivity.EXTRA_RESULT_DATA, data) activity.setResult(Activity.RESULT_OK, intent) } else if (!success && errorCode != null) { // Error result - intent.putExtra("xyz.self.sdk.ERROR_CODE", errorCode) - intent.putExtra("xyz.self.sdk.ERROR_MESSAGE", errorMessage ?: "Unknown error") + intent.putExtra(SelfVerificationActivity.EXTRA_ERROR_CODE, errorCode) + intent.putExtra(SelfVerificationActivity.EXTRA_ERROR_MESSAGE, errorMessage ?: "Unknown error") activity.setResult(Activity.RESULT_FIRST_USER, intent) } else { // Cancelled or invalid result diff --git a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/SelfVerificationActivity.kt b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/SelfVerificationActivity.kt index 887285fc9..2de024419 100644 --- a/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/SelfVerificationActivity.kt +++ b/packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/SelfVerificationActivity.kt @@ -121,6 +121,7 @@ class SelfVerificationActivity : AppCompatActivity() { // Result extras const val EXTRA_RESULT_DATA = "xyz.self.sdk.RESULT_DATA" + const val EXTRA_RESULT_TYPE = "xyz.self.sdk.RESULT_TYPE" const val EXTRA_ERROR_CODE = "xyz.self.sdk.ERROR_CODE" const val EXTRA_ERROR_MESSAGE = "xyz.self.sdk.ERROR_MESSAGE" } diff --git a/packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/api/SelfSdkCallback.kt b/packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/api/SelfSdkCallback.kt index 9df676819..4b8fa3bc3 100644 --- a/packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/api/SelfSdkCallback.kt +++ b/packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/api/SelfSdkCallback.kt @@ -9,6 +9,7 @@ import kotlinx.serialization.Serializable @Serializable data class VerificationResult( val success: Boolean, + val type: String? = null, val userId: String? = null, val verificationId: String? = null, val proof: String? = null, diff --git a/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/api/SelfSdk.ios.kt b/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/api/SelfSdk.ios.kt index 27e66ff6e..f3813641d 100644 --- a/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/api/SelfSdk.ios.kt +++ b/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/api/SelfSdk.ios.kt @@ -5,11 +5,14 @@ package xyz.self.sdk.api import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.coroutines.runBlocking import platform.UIKit.UIApplication import platform.UIKit.UIModalPresentationFullScreen import platform.UIKit.UIViewController import platform.UIKit.UIWindow import platform.UIKit.UIWindowScene +import platform.darwin.dispatch_async +import platform.darwin.dispatch_get_main_queue import xyz.self.sdk.bridge.MessageRouter import xyz.self.sdk.handlers.AnalyticsBridgeHandler import xyz.self.sdk.handlers.BiometricBridgeHandler @@ -72,9 +75,24 @@ actual class SelfSdk private constructor( // Create lifecycle handler with callback and dismiss wiring val lifecycleHandler = LifecycleBridgeHandler() - lifecycleHandler.pendingCallback = callback - lifecycleHandler.dismissAction = { - pendingCallback = null + var dismissViewController: UIViewController? = null + runBlocking { + lifecycleHandler.configure( + callback = callback, + dismiss = { + dispatch_async(dispatch_get_main_queue()) { + val viewController = dismissViewController + if (viewController == null) { + pendingCallback = null + return@dispatch_async + } + + viewController.dismissViewControllerAnimated(true) { + pendingCallback = null + } + } + }, + ) } // Register all iOS bridge handlers @@ -91,13 +109,7 @@ actual class SelfSdk private constructor( ?: throw IllegalStateException("WebView provider not configured. Call SelfSdkSwift.configure() first.") ).getViewController() sdkVC.setModalPresentationStyle(UIModalPresentationFullScreen) - - // Wire up dismiss action to dismiss the VC - lifecycleHandler.dismissAction = { - sdkVC.dismissViewControllerAnimated(true) { - pendingCallback = null - } - } + dismissViewController = sdkVC val topVC = findTopViewController() if (topVC == null) { diff --git a/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt b/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt index 648965db5..15954908c 100644 --- a/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt +++ b/packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt @@ -4,6 +4,8 @@ package xyz.self.sdk.handlers +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.jsonPrimitive @@ -17,8 +19,24 @@ import xyz.self.sdk.bridge.BridgeHandlerException class LifecycleBridgeHandler : BridgeHandler { override val domain = BridgeDomain.LIFECYCLE - internal var pendingCallback: SelfSdkCallback? = null - internal var dismissAction: (() -> Unit)? = null + private val mutex = Mutex() + private var pendingCallback: SelfSdkCallback? = null + private var dismissAction: (() -> Unit)? = null + + private data class LifecycleState( + val callback: SelfSdkCallback?, + val dismiss: (() -> Unit)?, + ) + + internal suspend fun configure( + callback: SelfSdkCallback?, + dismiss: (() -> Unit)?, + ) { + mutex.withLock { + pendingCallback = callback + dismissAction = dismiss + } + } override suspend fun handle( method: String, @@ -36,14 +54,27 @@ class LifecycleBridgeHandler : BridgeHandler { private fun ready(): JsonElement? = null - private fun dismiss(): JsonElement? { - pendingCallback?.onCancelled() - pendingCallback = null - dismissAction?.invoke() + private suspend fun consumeLifecycleState(): LifecycleState = + mutex.withLock { + val state = + LifecycleState( + callback = pendingCallback, + dismiss = dismissAction, + ) + pendingCallback = null + dismissAction = null + state + } + + private suspend fun dismiss(): JsonElement? { + val state = consumeLifecycleState() + state.callback?.onCancelled() + state.dismiss?.invoke() return null } - private fun setResult(params: Map): JsonElement? { + private suspend fun setResult(params: Map): JsonElement? { + val state = consumeLifecycleState() val type = params["type"]?.jsonPrimitive?.content val success = params["success"]?.jsonPrimitive?.content?.toBoolean() ?: false val data = params["data"]?.toString() @@ -51,16 +82,17 @@ class LifecycleBridgeHandler : BridgeHandler { val errorMessage = params["errorMessage"]?.jsonPrimitive?.content if (type != null) { - // Flat lifecycle payload (e.g. { type: "proofRequested" }) — treat as success - pendingCallback?.onSuccess( - VerificationResult(success = true), + // Flat lifecycle payload is a protocol-level success signal. + // `type` communicates what completed (e.g. proofRequested). + state.callback?.onSuccess( + VerificationResult(success = true, type = type), ) } else if (success && data != null) { try { val result = Json.decodeFromString(VerificationResult.serializer(), data) - pendingCallback?.onSuccess(result) + state.callback?.onSuccess(result) } catch (e: Exception) { - pendingCallback?.onFailure( + state.callback?.onFailure( SelfSdkError( code = "PARSE_ERROR", message = "Failed to parse verification result: ${e.message}", @@ -68,18 +100,17 @@ class LifecycleBridgeHandler : BridgeHandler { ) } } else if (!success && errorCode != null) { - pendingCallback?.onFailure( + state.callback?.onFailure( SelfSdkError( code = errorCode, message = errorMessage ?: "Unknown error", ), ) } else { - pendingCallback?.onCancelled() + state.callback?.onCancelled() } - pendingCallback = null - dismissAction?.invoke() + state.dismiss?.invoke() return null } } diff --git a/packages/rn-sdk/HANDOFF.md b/packages/rn-sdk/HANDOFF.md index 3101f29ba..8516d393e 100644 --- a/packages/rn-sdk/HANDOFF.md +++ b/packages/rn-sdk/HANDOFF.md @@ -18,8 +18,8 @@ Host App ├─ LifecycleHandler (init, ready, close, error, success) ├─ BiometricHandler (authenticate, isAvailable) ├─ KeychainHandler (get, set, remove) - ├─ NfcHandler (scan, cancelScan, isSupported) - └─ CameraHandler (isAvailable, scanMRZ — stub) + ├─ NfcHandler (scan + APDU exchange, cancelScan, isSupported) + └─ CameraHandler (isAvailable, scanMRZ via native module) ``` ### File List @@ -32,12 +32,12 @@ Host App | `src/handlers/LifecycleHandler.ts` | ~70 | App lifecycle + verification callbacks | | `src/handlers/BiometricHandler.ts` | ~60 | Biometric auth via react-native-biometrics | | `src/handlers/KeychainHandler.ts` | ~65 | Secure storage via react-native-keychain | -| `src/handlers/NfcHandler.ts` | ~130 | NFC tag reading via react-native-nfc-manager | -| `src/handlers/CameraHandler.ts` | ~25 | Camera stub (isAvailable, scanMRZ not yet impl) | +| `src/handlers/NfcHandler.ts` | ~180 | NFC tag reading + APDU exchange via react-native-nfc-manager | +| `src/handlers/CameraHandler.ts` | ~90 | MRZ scanning via native SelfMRZScannerModule / MRZScannerModule | | `src/handlers/index.ts` | ~30 | Handler factory (createHandlers) | | `src/index.ts` | ~5 | Public exports | | **Total source** | **~715** | | -| **Tests (8 files)** | **~880** | 59 tests | +| **Tests (8 files)** | **~950** | 64 tests | ### Dependencies @@ -85,31 +85,40 @@ into their platform build: ### NFC Scan Return Shape -The webview-bridge spec expects `nfc.scan` to return raw APDU response -bytes. Our implementation returns a higher-level object: +The NFC handler returns tag metadata plus optional APDU exchange results: ```typescript -{ connected: true, tagId: string | null, techType: string, params: {...} } +{ + connected: true, + tagId: string | null, + techType: string, + params: {...}, + apduResponses?: string[] // hex-encoded responses when apduCommands are provided +} ``` -**Justification:** `react-native-nfc-manager` provides tag discovery and -technology negotiation but does not expose raw APDU transceive at the -`getTag()` level without additional low-level calls. The current shape -gives the web layer enough information to confirm a tag was found and -proceed with the verification flow. When APDU command exchange is needed, -a `transceive` method should be added to `NfcHandler` that wraps -`NfcManager.transceive()`. +When `params.apduCommands` (array of hex strings) is provided, the handler +iterates through each command, calls `NfcManager.transceive()`, and returns +hex-encoded response bytes in `apduResponses`. Progress events are emitted +at `apdu_exchange` (70%) and `apdu_complete` (90%). --- -## Deferred Decision +## Camera / MRZ Implementation -**Camera / MRZ scanning** — `CameraHandler.scanMRZ` throws -`NOT_IMPLEMENTED`. A full implementation requires choosing a camera -library (`react-native-vision-camera` is the modern choice) plus an -OCR/MRZ parsing layer. `isAvailable` currently returns `true` -unconditionally. This should be wired to a real permission check once -a camera library is chosen. +`CameraHandler` loads the native MRZ scanner module at init time, +checking for `SelfMRZScannerModule` (preferred) or `MRZScannerModule` +(fallback) from React Native's `NativeModules`. + +- `isAvailable()` returns whether a native MRZ module was found. +- `scanMRZ()` calls `scanner.startScanning()`, normalizes the result + (extracts `documentNumber`, `dateOfBirth`, `dateOfExpiry`, plus optional + `documentType` and `countryCode`), and throws `MRZ_SCAN_FAILED` on + scanner errors or `MRZ_SCAN_INVALID_RESULT` if required fields are missing. +- If no native module is present, `scanMRZ()` throws `NOT_AVAILABLE`. + +The host app must provide a native MRZ scanner module (e.g., via +`react-native-vision-camera` + OCR) that exposes `startScanning()`. --- @@ -119,7 +128,7 @@ a camera library is chosen. ```bash cd packages/rn-sdk -npx vitest run # 59 tests across 8 files +npx vitest run # 64 tests across 8 files ``` ### Device Testing Checklist @@ -180,16 +189,15 @@ import { SelfVerification } from '@selfxyz/rn-sdk'; | Lifecycle handler | Done | init, ready, close, error, success | | Biometric handler | Done | authenticate, isAvailable via react-native-biometrics | | Keychain handler | Done | get, set, remove via react-native-keychain | -| NFC handler | Done | scan, cancelScan, isSupported via react-native-nfc-manager | +| NFC handler | Done | scan + APDU exchange, cancelScan, isSupported via react-native-nfc-manager | | iOS asset path | Done | Absolute path via react-native-fs, relative fallback | | Android asset path | Done | `file:///android_asset/` | | Dev server override | Done | `devServerUrl` prop | -| Camera / MRZ scan | Stub | `isAvailable` hardcoded true, `scanMRZ` throws NOT_IMPLEMENTED | +| Camera / MRZ scan | Done | scanMRZ via native SelfMRZScannerModule with result normalization | ## Known Limitations -- Camera `scanMRZ` is a stub — needs camera library + OCR (see Deferred Decision) -- NFC returns tag metadata, not raw APDU bytes (see Spec Deviation) -- `CameraHandler.isAvailable` returns `true` unconditionally +- Camera/MRZ requires host app to provide a native MRZ scanner module (`SelfMRZScannerModule` or `MRZScannerModule`) - No retry/reconnect logic for WebView crashes - Asset bundling requires manual platform setup by the host app +- Physical-device validation breadth for NFC/APDU and camera across host apps is still limited diff --git a/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js b/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js new file mode 100644 index 000000000..510ddb0ff --- /dev/null +++ b/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js @@ -0,0 +1,79 @@ +function n2(i,s){for(var u=0;ud[f]})}}}return Object.freeze(Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}))}(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const f of document.querySelectorAll('link[rel="modulepreload"]'))d(f);new MutationObserver(f=>{for(const h of f)if(h.type==="childList")for(const v of h.addedNodes)v.tagName==="LINK"&&v.rel==="modulepreload"&&d(v)}).observe(document,{childList:!0,subtree:!0});function u(f){const h={};return f.integrity&&(h.integrity=f.integrity),f.referrerPolicy&&(h.referrerPolicy=f.referrerPolicy),f.crossOrigin==="use-credentials"?h.credentials="include":f.crossOrigin==="anonymous"?h.credentials="omit":h.credentials="same-origin",h}function d(f){if(f.ep)return;f.ep=!0;const h=u(f);fetch(f.href,h)}})();function I1(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var Es={exports:{}},ii={},Ts={exports:{}},ne={},Kc;function r2(){if(Kc)return ne;Kc=1;/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var i=Symbol.for("react.element"),s=Symbol.for("react.portal"),u=Symbol.for("react.fragment"),d=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),h=Symbol.for("react.provider"),v=Symbol.for("react.context"),k=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),L=Symbol.for("react.memo"),R=Symbol.for("react.lazy"),E=Symbol.iterator;function _(C){return C===null||typeof C!="object"?null:(C=E&&C[E]||C["@@iterator"],typeof C=="function"?C:null)}var O={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},b=Object.assign,A={};function I(C,D,te){this.props=C,this.context=D,this.refs=A,this.updater=te||O}I.prototype.isReactComponent={},I.prototype.setState=function(C,D){if(typeof C!="object"&&typeof C!="function"&&C!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,C,D,"setState")},I.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function J(){}J.prototype=I.prototype;function X(C,D,te){this.props=C,this.context=D,this.refs=A,this.updater=te||O}var ee=X.prototype=new J;ee.constructor=X,b(ee,I.prototype),ee.isPureReactComponent=!0;var ue=Array.isArray,Ee=Object.prototype.hasOwnProperty,Ie={current:null},Ge={key:!0,ref:!0,__self:!0,__source:!0};function Ne(C,D,te){var re,le={},se=null,he=null;if(D!=null)for(re in D.ref!==void 0&&(he=D.ref),D.key!==void 0&&(se=""+D.key),D)Ee.call(D,re)&&!Ge.hasOwnProperty(re)&&(le[re]=D[re]);var ce=arguments.length-2;if(ce===1)le.children=te;else if(1>>1,D=z[C];if(0>>1;Cf(le,W))sef(he,le)?(z[C]=he,z[se]=W,C=se):(z[C]=le,z[re]=W,C=re);else if(sef(he,W))z[C]=he,z[se]=W,C=se;else break e}}return Y}function f(z,Y){var W=z.sortIndex-Y.sortIndex;return W!==0?W:z.id-Y.id}if(typeof performance=="object"&&typeof performance.now=="function"){var h=performance;i.unstable_now=function(){return h.now()}}else{var v=Date,k=v.now();i.unstable_now=function(){return v.now()-k}}var w=[],L=[],R=1,E=null,_=3,O=!1,b=!1,A=!1,I=typeof setTimeout=="function"?setTimeout:null,J=typeof clearTimeout=="function"?clearTimeout:null,X=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function ee(z){for(var Y=u(L);Y!==null;){if(Y.callback===null)d(L);else if(Y.startTime<=z)d(L),Y.sortIndex=Y.expirationTime,s(w,Y);else break;Y=u(L)}}function ue(z){if(A=!1,ee(z),!b)if(u(w)!==null)b=!0,ot(Ee);else{var Y=u(L);Y!==null&&ke(ue,Y.startTime-z)}}function Ee(z,Y){b=!1,A&&(A=!1,J(Ne),Ne=-1),O=!0;var W=_;try{for(ee(Y),E=u(w);E!==null&&(!(E.expirationTime>Y)||z&&!wt());){var C=E.callback;if(typeof C=="function"){E.callback=null,_=E.priorityLevel;var D=C(E.expirationTime<=Y);Y=i.unstable_now(),typeof D=="function"?E.callback=D:E===u(w)&&d(w),ee(Y)}else d(w);E=u(w)}if(E!==null)var te=!0;else{var re=u(L);re!==null&&ke(ue,re.startTime-Y),te=!1}return te}finally{E=null,_=W,O=!1}}var Ie=!1,Ge=null,Ne=-1,tt=5,Ze=-1;function wt(){return!(i.unstable_now()-Zez||125C?(z.sortIndex=W,s(L,z),u(w)===null&&z===u(L)&&(A?(J(Ne),Ne=-1):A=!0,ke(ue,W-C))):(z.sortIndex=D,s(w,z),b||O||(b=!0,ot(Ee))),z},i.unstable_shouldYield=wt,i.unstable_wrapCallback=function(z){var Y=_;return function(){var W=_;_=Y;try{return z.apply(this,arguments)}finally{_=W}}}})(Is)),Is}var Xc;function a2(){return Xc||(Xc=1,Rs.exports=s2()),Rs.exports}/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var e1;function u2(){if(e1)return dt;e1=1;var i=Hs(),s=a2();function u(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),w=Object.prototype.hasOwnProperty,L=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,R={},E={};function _(e){return w.call(E,e)?!0:w.call(R,e)?!1:L.test(e)?E[e]=!0:(R[e]=!0,!1)}function O(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function b(e,t,n,r){if(t===null||typeof t>"u"||O(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function A(e,t,n,r,o,l,c){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=l,this.removeEmptyString=c}var I={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){I[e]=new A(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];I[t]=new A(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){I[e]=new A(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){I[e]=new A(e,2,!1,e,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".split(" ").forEach(function(e){I[e]=new A(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){I[e]=new A(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){I[e]=new A(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){I[e]=new A(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){I[e]=new A(e,5,!1,e.toLowerCase(),null,!1,!1)});var J=/[\-:]([a-z])/g;function X(e){return e[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".split(" ").forEach(function(e){var t=e.replace(J,X);I[t]=new A(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(J,X);I[t]=new A(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(J,X);I[t]=new A(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){I[e]=new A(e,1,!1,e.toLowerCase(),null,!1,!1)}),I.xlinkHref=new A("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){I[e]=new A(e,1,!1,e.toLowerCase(),null,!0,!0)});function ee(e,t,n,r){var o=I.hasOwnProperty(t)?I[t]:null;(o!==null?o.type!==0:r||!(2p||o[c]!==l[p]){var g=` +`+o[c].replace(" at new "," at ");return e.displayName&&g.includes("")&&(g=g.replace("",e.displayName)),g}while(1<=c&&0<=p);break}}}finally{te=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?D(e):""}function le(e){switch(e.tag){case 5:return D(e.type);case 16:return D("Lazy");case 13:return D("Suspense");case 19:return D("SuspenseList");case 0:case 2:case 15:return e=re(e.type,!1),e;case 11:return e=re(e.type.render,!1),e;case 1:return e=re(e.type,!0),e;default:return""}}function se(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Ge:return"Fragment";case Ie:return"Portal";case tt:return"Profiler";case Ne:return"StrictMode";case nt:return"Suspense";case Nt:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case wt:return(e.displayName||"Context")+".Consumer";case Ze:return(e._context.displayName||"Context")+".Provider";case Ue:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Wt:return t=e.displayName||null,t!==null?t:se(e.type)||"Memo";case ot:t=e._payload,e=e._init;try{return se(e(t))}catch{}}return null}function he(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return se(t);case 8:return t===Ne?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function ce(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ce(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function pt(e){var t=Ce(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var o=n.get,l=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(c){r=""+c,l.call(this,c)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(c){r=""+c},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function di(e){e._valueTracker||(e._valueTracker=pt(e))}function ea(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Ce(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function fi(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}}function No(e,t){var n=t.checked;return W({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function ta(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=ce(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function na(e,t){t=t.checked,t!=null&&ee(e,"checked",t,!1)}function Mo(e,t){na(e,t);var n=ce(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?_o(e,t.type,n):t.hasOwnProperty("defaultValue")&&_o(e,t.type,ce(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function ra(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function _o(e,t,n){(t!=="number"||fi(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var Cr=Array.isArray;function $n(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o"+t.valueOf().toString()+"",t=pi.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function xr(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var wr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},od=["Webkit","ms","Moz","O"];Object.keys(wr).forEach(function(e){od.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),wr[t]=wr[e]})});function ua(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||wr.hasOwnProperty(e)&&wr[e]?(""+t).trim():t+"px"}function ca(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,o=ua(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}var ld=W({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Oo(e,t){if(t){if(ld[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(u(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(u(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(u(61))}if(t.style!=null&&typeof t.style!="object")throw Error(u(62))}}function zo(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Fo=null;function Uo(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Wo=null,Gn=null,Zn=null;function da(e){if(e=Hr(e)){if(typeof Wo!="function")throw Error(u(280));var t=e.stateNode;t&&(t=Bi(t),Wo(e.stateNode,e.type,t))}}function fa(e){Gn?Zn?Zn.push(e):Zn=[e]:Gn=e}function pa(){if(Gn){var e=Gn,t=Zn;if(Zn=Gn=null,da(e),t)for(e=0;e>>=0,e===0?32:31-(yd(e)/vd|0)|0}var vi=64,Ci=4194304;function Er(e){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: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 e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function xi(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,o=e.suspendedLanes,l=e.pingedLanes,c=n&268435455;if(c!==0){var p=c&~o;p!==0?r=Er(p):(l&=c,l!==0&&(r=Er(l)))}else c=n&~o,c!==0?r=Er(c):l!==0&&(r=Er(l));if(r===0)return 0;if(t!==0&&t!==r&&(t&o)===0&&(o=r&-r,l=t&-t,o>=l||o===16&&(l&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Tr(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Mt(t),e[t]=n}function Sd(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=_r),Wa=" ",ba=!1;function Ha(e,t){switch(e){case"keyup":return Yd.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Va(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Yn=!1;function Jd(e,t){switch(e){case"compositionend":return Va(t);case"keypress":return t.which!==32?null:(ba=!0,Wa);case"textInput":return e=t.data,e===Wa&&ba?null:e;default:return null}}function Xd(e,t){if(Yn)return e==="compositionend"||!ol&&Ha(e,t)?(e=Aa(),Ei=Xo=dn=null,Yn=!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=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=qa(n)}}function Xa(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Xa(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function eu(){for(var e=window,t=fi();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=fi(e.document)}return t}function al(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")}function uf(e){var t=eu(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Xa(n.ownerDocument.documentElement,n)){if(r!==null&&al(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var o=n.textContent.length,l=Math.min(r.start,o);r=r.end===void 0?l:Math.min(r.end,o),!e.extend&&l>r&&(o=r,r=l,l=o),o=Ja(n,l);var c=Ja(n,r);o&&c&&(e.rangeCount!==1||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==c.node||e.focusOffset!==c.offset)&&(t=t.createRange(),t.setStart(o.node,o.offset),e.removeAllRanges(),l>r?(e.addRange(t),e.extend(c.node,c.offset)):(t.setEnd(c.node,c.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,qn=null,ul=null,zr=null,cl=!1;function tu(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;cl||qn==null||qn!==fi(r)||(r=qn,"selectionStart"in r&&al(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),zr&&Or(zr,r)||(zr=r,r=Mi(ul,"onSelect"),0nr||(e.current=Sl[nr],Sl[nr]=null,nr--)}function me(e,t){nr++,Sl[nr]=e.current,e.current=t}var mn={},Ke=hn(mn),lt=hn(!1),Pn=mn;function rr(e,t){var n=e.type.contextTypes;if(!n)return mn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o={},l;for(l in n)o[l]=t[l];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function st(e){return e=e.childContextTypes,e!=null}function Oi(){ve(lt),ve(Ke)}function gu(e,t,n){if(Ke.current!==mn)throw Error(u(168));me(Ke,t),me(lt,n)}function yu(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var o in r)if(!(o in t))throw Error(u(108,he(e)||"Unknown",o));return W({},n,r)}function zi(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||mn,Pn=Ke.current,me(Ke,e),me(lt,lt.current),!0}function vu(e,t,n){var r=e.stateNode;if(!r)throw Error(u(169));n?(e=yu(e,t,Pn),r.__reactInternalMemoizedMergedChildContext=e,ve(lt),ve(Ke),me(Ke,e)):ve(lt),me(lt,n)}var qt=null,Fi=!1,kl=!1;function Cu(e){qt===null?qt=[e]:qt.push(e)}function wf(e){Fi=!0,Cu(e)}function gn(){if(!kl&&qt!==null){kl=!0;var e=0,t=de;try{var n=qt;for(de=1;e>=c,o-=c,Jt=1<<32-Mt(t)+o|n<q?(Oe=Q,Q=null):Oe=Q.sibling;var ae=P(x,Q,S[q],B);if(ae===null){Q===null&&(Q=Oe);break}e&&Q&&ae.alternate===null&&t(x,Q),y=l(ae,y,q),K===null?G=ae:K.sibling=ae,K=ae,Q=Oe}if(q===S.length)return n(x,Q),xe&&Nn(x,q),G;if(Q===null){for(;qq?(Oe=Q,Q=null):Oe=Q.sibling;var En=P(x,Q,ae.value,B);if(En===null){Q===null&&(Q=Oe);break}e&&Q&&En.alternate===null&&t(x,Q),y=l(En,y,q),K===null?G=En:K.sibling=En,K=En,Q=Oe}if(ae.done)return n(x,Q),xe&&Nn(x,q),G;if(Q===null){for(;!ae.done;q++,ae=S.next())ae=M(x,ae.value,B),ae!==null&&(y=l(ae,y,q),K===null?G=ae:K.sibling=ae,K=ae);return xe&&Nn(x,q),G}for(Q=r(x,Q);!ae.done;q++,ae=S.next())ae=F(Q,x,q,ae.value,B),ae!==null&&(e&&ae.alternate!==null&&Q.delete(ae.key===null?q:ae.key),y=l(ae,y,q),K===null?G=ae:K.sibling=ae,K=ae);return e&&Q.forEach(function(t2){return t(x,t2)}),xe&&Nn(x,q),G}function Le(x,y,S,B){if(typeof S=="object"&&S!==null&&S.type===Ge&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case Ee:e:{for(var G=S.key,K=y;K!==null;){if(K.key===G){if(G=S.type,G===Ge){if(K.tag===7){n(x,K.sibling),y=o(K,S.props.children),y.return=x,x=y;break e}}else if(K.elementType===G||typeof G=="object"&&G!==null&&G.$$typeof===ot&&Eu(G)===K.type){n(x,K.sibling),y=o(K,S.props),y.ref=Vr(x,K,S),y.return=x,x=y;break e}n(x,K);break}else t(x,K);K=K.sibling}S.type===Ge?(y=Un(S.props.children,x.mode,B,S.key),y.return=x,x=y):(B=ho(S.type,S.key,S.props,null,x.mode,B),B.ref=Vr(x,y,S),B.return=x,x=B)}return c(x);case Ie:e:{for(K=S.key;y!==null;){if(y.key===K)if(y.tag===4&&y.stateNode.containerInfo===S.containerInfo&&y.stateNode.implementation===S.implementation){n(x,y.sibling),y=o(y,S.children||[]),y.return=x,x=y;break e}else{n(x,y);break}else t(x,y);y=y.sibling}y=xs(S,x.mode,B),y.return=x,x=y}return c(x);case ot:return K=S._init,Le(x,y,K(S._payload),B)}if(Cr(S))return H(x,y,S,B);if(Y(S))return $(x,y,S,B);Hi(x,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,y!==null&&y.tag===6?(n(x,y.sibling),y=o(y,S),y.return=x,x=y):(n(x,y),y=Cs(S,x.mode,B),y.return=x,x=y),c(x)):n(x,y)}return Le}var sr=Tu(!0),Lu=Tu(!1),Vi=hn(null),$i=null,ar=null,Il=null;function Pl(){Il=ar=$i=null}function Dl(e){var t=Vi.current;ve(Vi),e._currentValue=t}function Nl(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function ur(e,t){$i=e,Il=ar=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(at=!0),e.firstContext=null)}function jt(e){var t=e._currentValue;if(Il!==e)if(e={context:e,memoizedValue:t,next:null},ar===null){if($i===null)throw Error(u(308));ar=e,$i.dependencies={lanes:0,firstContext:e}}else ar=ar.next=e;return t}var Mn=null;function Ml(e){Mn===null?Mn=[e]:Mn.push(e)}function Ru(e,t,n,r){var o=t.interleaved;return o===null?(n.next=n,Ml(t)):(n.next=o.next,o.next=n),t.interleaved=n,en(e,r)}function en(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var yn=!1;function _l(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Iu(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function tn(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function vn(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,(oe&2)!==0){var o=r.pending;return o===null?t.next=t:(t.next=o.next,o.next=t),r.pending=t,en(e,n)}return o=r.interleaved,o===null?(t.next=t,Ml(r)):(t.next=o.next,o.next=t),r.interleaved=t,en(e,n)}function Gi(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Ko(e,n)}}function Pu(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var o=null,l=null;if(n=n.firstBaseUpdate,n!==null){do{var c={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};l===null?o=l=c:l=l.next=c,n=n.next}while(n!==null);l===null?o=l=t:l=l.next=t}else o=l=t;n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:l,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Zi(e,t,n,r){var o=e.updateQueue;yn=!1;var l=o.firstBaseUpdate,c=o.lastBaseUpdate,p=o.shared.pending;if(p!==null){o.shared.pending=null;var g=p,j=g.next;g.next=null,c===null?l=j:c.next=j,c=g;var N=e.alternate;N!==null&&(N=N.updateQueue,p=N.lastBaseUpdate,p!==c&&(p===null?N.firstBaseUpdate=j:p.next=j,N.lastBaseUpdate=g))}if(l!==null){var M=o.baseState;c=0,N=j=g=null,p=l;do{var P=p.lane,F=p.eventTime;if((r&P)===P){N!==null&&(N=N.next={eventTime:F,lane:0,tag:p.tag,payload:p.payload,callback:p.callback,next:null});e:{var H=e,$=p;switch(P=t,F=n,$.tag){case 1:if(H=$.payload,typeof H=="function"){M=H.call(F,M,P);break e}M=H;break e;case 3:H.flags=H.flags&-65537|128;case 0:if(H=$.payload,P=typeof H=="function"?H.call(F,M,P):H,P==null)break e;M=W({},M,P);break e;case 2:yn=!0}}p.callback!==null&&p.lane!==0&&(e.flags|=64,P=o.effects,P===null?o.effects=[p]:P.push(p))}else F={eventTime:F,lane:P,tag:p.tag,payload:p.payload,callback:p.callback,next:null},N===null?(j=N=F,g=M):N=N.next=F,c|=P;if(p=p.next,p===null){if(p=o.shared.pending,p===null)break;P=p,p=P.next,P.next=null,o.lastBaseUpdate=P,o.shared.pending=null}}while(!0);if(N===null&&(g=M),o.baseState=g,o.firstBaseUpdate=j,o.lastBaseUpdate=N,t=o.shared.interleaved,t!==null){o=t;do c|=o.lane,o=o.next;while(o!==t)}else l===null&&(o.shared.lanes=0);Bn|=c,e.lanes=c,e.memoizedState=M}}function Du(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=Fl.transition;Fl.transition={};try{e(!1),t()}finally{de=n,Fl.transition=r}}function Yu(){return Et().memoizedState}function Ef(e,t,n){var r=Sn(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},qu(e))Ju(t,n);else if(n=Ru(e,t,n,r),n!==null){var o=it();Ft(n,e,r,o),Xu(n,t,r)}}function Tf(e,t,n){var r=Sn(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(qu(e))Ju(t,o);else{var l=e.alternate;if(e.lanes===0&&(l===null||l.lanes===0)&&(l=t.lastRenderedReducer,l!==null))try{var c=t.lastRenderedState,p=l(c,n);if(o.hasEagerState=!0,o.eagerState=p,_t(p,c)){var g=t.interleaved;g===null?(o.next=o,Ml(t)):(o.next=g.next,g.next=o),t.interleaved=o;return}}catch{}finally{}n=Ru(e,t,o,r),n!==null&&(o=it(),Ft(n,e,r,o),Xu(n,t,r))}}function qu(e){var t=e.alternate;return e===Se||t!==null&&t===Se}function Ju(e,t){Kr=Yi=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Xu(e,t,n){if((n&4194240)!==0){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Ko(e,n)}}var Xi={readContext:jt,useCallback:Qe,useContext:Qe,useEffect:Qe,useImperativeHandle:Qe,useInsertionEffect:Qe,useLayoutEffect:Qe,useMemo:Qe,useReducer:Qe,useRef:Qe,useState:Qe,useDebugValue:Qe,useDeferredValue:Qe,useTransition:Qe,useMutableSource:Qe,useSyncExternalStore:Qe,useId:Qe,unstable_isNewReconciler:!1},Lf={readContext:jt,useCallback:function(e,t){return $t().memoizedState=[e,t===void 0?null:t],e},useContext:jt,useEffect:bu,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,qi(4194308,4,$u.bind(null,t,e),n)},useLayoutEffect:function(e,t){return qi(4194308,4,e,t)},useInsertionEffect:function(e,t){return qi(4,2,e,t)},useMemo:function(e,t){var n=$t();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=$t();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Ef.bind(null,Se,e),[r.memoizedState,e]},useRef:function(e){var t=$t();return e={current:e},t.memoizedState=e},useState:Uu,useDebugValue:Gl,useDeferredValue:function(e){return $t().memoizedState=e},useTransition:function(){var e=Uu(!1),t=e[0];return e=jf.bind(null,e[1]),$t().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=Se,o=$t();if(xe){if(n===void 0)throw Error(u(407));n=n()}else{if(n=t(),Be===null)throw Error(u(349));(An&30)!==0||Au(r,t,n)}o.memoizedState=n;var l={value:n,getSnapshot:t};return o.queue=l,bu(Ou.bind(null,r,l,e),[e]),r.flags|=2048,qr(9,Bu.bind(null,r,l,n,t),void 0,null),n},useId:function(){var e=$t(),t=Be.identifierPrefix;if(xe){var n=Xt,r=Jt;n=(r&~(1<<32-Mt(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Qr++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),n==="select"&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[Ht]=t,e[br]=r,Cc(e,t,!1,!1),t.stateNode=e;e:{switch(c=zo(n,r),n){case"dialog":ye("cancel",e),ye("close",e),o=r;break;case"iframe":case"object":case"embed":ye("load",e),o=r;break;case"video":case"audio":for(o=0;ohr&&(t.flags|=128,r=!0,Jr(l,!1),t.lanes=4194304)}else{if(!r)if(e=Ki(c),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),Jr(l,!0),l.tail===null&&l.tailMode==="hidden"&&!c.alternate&&!xe)return Ye(t),null}else 2*Te()-l.renderingStartTime>hr&&n!==1073741824&&(t.flags|=128,r=!0,Jr(l,!1),t.lanes=4194304);l.isBackwards?(c.sibling=t.child,t.child=c):(n=l.last,n!==null?n.sibling=c:t.child=c,l.last=c)}return l.tail!==null?(t=l.tail,l.rendering=t,l.tail=t.sibling,l.renderingStartTime=Te(),t.sibling=null,n=we.current,me(we,r?n&1|2:n&1),t):(Ye(t),null);case 22:case 23:return gs(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&(t.mode&1)!==0?(yt&1073741824)!==0&&(Ye(t),t.subtreeFlags&6&&(t.flags|=8192)):Ye(t),null;case 24:return null;case 25:return null}throw Error(u(156,t.tag))}function Af(e,t){switch(El(t),t.tag){case 1:return st(t.type)&&Oi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return cr(),ve(lt),ve(Ke),zl(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return Bl(t),null;case 13:if(ve(we),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(u(340));lr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ve(we),null;case 4:return cr(),null;case 10:return Dl(t.type._context),null;case 22:case 23:return gs(),null;case 24:return null;default:return null}}var ro=!1,qe=!1,Bf=typeof WeakSet=="function"?WeakSet:Set,U=null;function fr(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){je(e,t,r)}else n.current=null}function is(e,t,n){try{n()}catch(r){je(e,t,r)}}var Sc=!1;function Of(e,t){if(gl=ki,e=eu(),al(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var o=r.anchorOffset,l=r.focusNode;r=r.focusOffset;try{n.nodeType,l.nodeType}catch{n=null;break e}var c=0,p=-1,g=-1,j=0,N=0,M=e,P=null;t:for(;;){for(var F;M!==n||o!==0&&M.nodeType!==3||(p=c+o),M!==l||r!==0&&M.nodeType!==3||(g=c+r),M.nodeType===3&&(c+=M.nodeValue.length),(F=M.firstChild)!==null;)P=M,M=F;for(;;){if(M===e)break t;if(P===n&&++j===o&&(p=c),P===l&&++N===r&&(g=c),(F=M.nextSibling)!==null)break;M=P,P=M.parentNode}M=F}n=p===-1||g===-1?null:{start:p,end:g}}else n=null}n=n||{start:0,end:0}}else n=null;for(yl={focusedElem:e,selectionRange:n},ki=!1,U=t;U!==null;)if(t=U,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,U=e;else for(;U!==null;){t=U;try{var H=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(H!==null){var $=H.memoizedProps,Le=H.memoizedState,x=t.stateNode,y=x.getSnapshotBeforeUpdate(t.elementType===t.type?$:Bt(t.type,$),Le);x.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var S=t.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(u(163))}}catch(B){je(t,t.return,B)}if(e=t.sibling,e!==null){e.return=t.return,U=e;break}U=t.return}return H=Sc,Sc=!1,H}function Xr(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var o=r=r.next;do{if((o.tag&e)===e){var l=o.destroy;o.destroy=void 0,l!==void 0&&is(t,n,l)}o=o.next}while(o!==r)}}function io(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function os(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function kc(e){var t=e.alternate;t!==null&&(e.alternate=null,kc(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Ht],delete t[br],delete t[wl],delete t[Cf],delete t[xf])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function jc(e){return e.tag===5||e.tag===3||e.tag===4}function Ec(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||jc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function ls(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Ai));else if(r!==4&&(e=e.child,e!==null))for(ls(e,t,n),e=e.sibling;e!==null;)ls(e,t,n),e=e.sibling}function ss(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(ss(e,t,n),e=e.sibling;e!==null;)ss(e,t,n),e=e.sibling}var We=null,Ot=!1;function Cn(e,t,n){for(n=n.child;n!==null;)Tc(e,t,n),n=n.sibling}function Tc(e,t,n){if(bt&&typeof bt.onCommitFiberUnmount=="function")try{bt.onCommitFiberUnmount(yi,n)}catch{}switch(n.tag){case 5:qe||fr(n,t);case 6:var r=We,o=Ot;We=null,Cn(e,t,n),We=r,Ot=o,We!==null&&(Ot?(e=We,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):We.removeChild(n.stateNode));break;case 18:We!==null&&(Ot?(e=We,n=n.stateNode,e.nodeType===8?xl(e.parentNode,n):e.nodeType===1&&xl(e,n),Dr(e)):xl(We,n.stateNode));break;case 4:r=We,o=Ot,We=n.stateNode.containerInfo,Ot=!0,Cn(e,t,n),We=r,Ot=o;break;case 0:case 11:case 14:case 15:if(!qe&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){o=r=r.next;do{var l=o,c=l.destroy;l=l.tag,c!==void 0&&((l&2)!==0||(l&4)!==0)&&is(n,t,c),o=o.next}while(o!==r)}Cn(e,t,n);break;case 1:if(!qe&&(fr(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(p){je(n,t,p)}Cn(e,t,n);break;case 21:Cn(e,t,n);break;case 22:n.mode&1?(qe=(r=qe)||n.memoizedState!==null,Cn(e,t,n),qe=r):Cn(e,t,n);break;default:Cn(e,t,n)}}function Lc(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new Bf),t.forEach(function(r){var o=Gf.bind(null,e,r);n.has(r)||(n.add(r),r.then(o,o))})}}function zt(e,t){var n=t.deletions;if(n!==null)for(var r=0;ro&&(o=c),r&=~l}if(r=o,r=Te()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Ff(r/1960))-r,10e?16:e,wn===null)var r=!1;else{if(e=wn,wn=null,uo=0,(oe&6)!==0)throw Error(u(331));var o=oe;for(oe|=4,U=e.current;U!==null;){var l=U,c=l.child;if((U.flags&16)!==0){var p=l.deletions;if(p!==null){for(var g=0;gTe()-cs?zn(e,0):us|=n),ct(e,t)}function Uc(e,t){t===0&&((e.mode&1)===0?t=1:(t=Ci,Ci<<=1,(Ci&130023424)===0&&(Ci=4194304)));var n=it();e=en(e,t),e!==null&&(Tr(e,t,n),ct(e,n))}function $f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Uc(e,n)}function Gf(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;o!==null&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(u(314))}r!==null&&r.delete(t),Uc(e,n)}var Wc;Wc=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||lt.current)at=!0;else{if((e.lanes&n)===0&&(t.flags&128)===0)return at=!1,Mf(e,t,n);at=(e.flags&131072)!==0}else at=!1,xe&&(t.flags&1048576)!==0&&xu(t,Wi,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;no(e,t),e=t.pendingProps;var o=rr(t,Ke.current);ur(t,n),o=Wl(null,t,r,e,o,n);var l=bl();return t.flags|=1,typeof o=="object"&&o!==null&&typeof o.render=="function"&&o.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,st(r)?(l=!0,zi(t)):l=!1,t.memoizedState=o.state!==null&&o.state!==void 0?o.state:null,_l(t),o.updater=eo,t.stateNode=o,o._reactInternals=t,Kl(t,r,e,n),t=Jl(null,t,r,!0,l,n)):(t.tag=0,xe&&l&&jl(t),rt(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(no(e,t),e=t.pendingProps,o=r._init,r=o(r._payload),t.type=r,o=t.tag=Kf(r),e=Bt(r,e),o){case 0:t=ql(null,t,r,e,n);break e;case 1:t=pc(null,t,r,e,n);break e;case 11:t=ac(null,t,r,e,n);break e;case 14:t=uc(null,t,r,Bt(r.type,e),n);break e}throw Error(u(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Bt(r,o),ql(e,t,r,o,n);case 1:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Bt(r,o),pc(e,t,r,o,n);case 3:e:{if(hc(t),e===null)throw Error(u(387));r=t.pendingProps,l=t.memoizedState,o=l.element,Iu(e,t),Zi(t,r,null,n);var c=t.memoizedState;if(r=c.element,l.isDehydrated)if(l={element:r,isDehydrated:!1,cache:c.cache,pendingSuspenseBoundaries:c.pendingSuspenseBoundaries,transitions:c.transitions},t.updateQueue.baseState=l,t.memoizedState=l,t.flags&256){o=dr(Error(u(423)),t),t=mc(e,t,r,n,o);break e}else if(r!==o){o=dr(Error(u(424)),t),t=mc(e,t,r,n,o);break e}else for(gt=pn(t.stateNode.containerInfo.firstChild),mt=t,xe=!0,At=null,n=Lu(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(lr(),r===o){t=nn(e,t,n);break e}rt(e,t,r,n)}t=t.child}return t;case 5:return Nu(t),e===null&&Ll(t),r=t.type,o=t.pendingProps,l=e!==null?e.memoizedProps:null,c=o.children,vl(r,o)?c=null:l!==null&&vl(r,l)&&(t.flags|=32),fc(e,t),rt(e,t,c,n),t.child;case 6:return e===null&&Ll(t),null;case 13:return gc(e,t,n);case 4:return Al(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=sr(t,null,r,n):rt(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Bt(r,o),ac(e,t,r,o,n);case 7:return rt(e,t,t.pendingProps,n),t.child;case 8:return rt(e,t,t.pendingProps.children,n),t.child;case 12:return rt(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,l=t.memoizedProps,c=o.value,me(Vi,r._currentValue),r._currentValue=c,l!==null)if(_t(l.value,c)){if(l.children===o.children&&!lt.current){t=nn(e,t,n);break e}}else for(l=t.child,l!==null&&(l.return=t);l!==null;){var p=l.dependencies;if(p!==null){c=l.child;for(var g=p.firstContext;g!==null;){if(g.context===r){if(l.tag===1){g=tn(-1,n&-n),g.tag=2;var j=l.updateQueue;if(j!==null){j=j.shared;var N=j.pending;N===null?g.next=g:(g.next=N.next,N.next=g),j.pending=g}}l.lanes|=n,g=l.alternate,g!==null&&(g.lanes|=n),Nl(l.return,n,t),p.lanes|=n;break}g=g.next}}else if(l.tag===10)c=l.type===t.type?null:l.child;else if(l.tag===18){if(c=l.return,c===null)throw Error(u(341));c.lanes|=n,p=c.alternate,p!==null&&(p.lanes|=n),Nl(c,n,t),c=l.sibling}else c=l.child;if(c!==null)c.return=l;else for(c=l;c!==null;){if(c===t){c=null;break}if(l=c.sibling,l!==null){l.return=c.return,c=l;break}c=c.return}l=c}rt(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,ur(t,n),o=jt(o),r=r(o),t.flags|=1,rt(e,t,r,n),t.child;case 14:return r=t.type,o=Bt(r,t.pendingProps),o=Bt(r.type,o),uc(e,t,r,o,n);case 15:return cc(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Bt(r,o),no(e,t),t.tag=1,st(r)?(e=!0,zi(t)):e=!1,ur(t,n),tc(t,r,o),Kl(t,r,o,n),Jl(null,t,r,!0,e,n);case 19:return vc(e,t,n);case 22:return dc(e,t,n)}throw Error(u(156,t.tag))};function bc(e,t){return wa(e,t)}function Zf(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Lt(e,t,n,r){return new Zf(e,t,n,r)}function vs(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Kf(e){if(typeof e=="function")return vs(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Ue)return 11;if(e===Wt)return 14}return 2}function jn(e,t){var n=e.alternate;return n===null?(n=Lt(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function ho(e,t,n,r,o,l){var c=2;if(r=e,typeof e=="function")vs(e)&&(c=1);else if(typeof e=="string")c=5;else e:switch(e){case Ge:return Un(n.children,o,l,t);case Ne:c=8,o|=8;break;case tt:return e=Lt(12,n,t,o|2),e.elementType=tt,e.lanes=l,e;case nt:return e=Lt(13,n,t,o),e.elementType=nt,e.lanes=l,e;case Nt:return e=Lt(19,n,t,o),e.elementType=Nt,e.lanes=l,e;case ke:return mo(n,o,l,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Ze:c=10;break e;case wt:c=9;break e;case Ue:c=11;break e;case Wt:c=14;break e;case ot:c=16,r=null;break e}throw Error(u(130,e==null?e:typeof e,""))}return t=Lt(c,n,t,o),t.elementType=e,t.type=r,t.lanes=l,t}function Un(e,t,n,r){return e=Lt(7,e,r,t),e.lanes=n,e}function mo(e,t,n,r){return e=Lt(22,e,r,t),e.elementType=ke,e.lanes=n,e.stateNode={isHidden:!1},e}function Cs(e,t,n){return e=Lt(6,e,null,t),e.lanes=n,e}function xs(e,t,n){return t=Lt(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Qf(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Zo(0),this.expirationTimes=Zo(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Zo(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function ws(e,t,n,r,o,l,c,p,g){return e=new Qf(e,t,n,p,g),t===1?(t=1,l===!0&&(t|=8)):t=0,l=Lt(3,null,null,t),e.current=l,l.stateNode=e,l.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},_l(l),e}function Yf(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(s){console.error(s)}}return i(),Ls.exports=u2(),Ls.exports}var n1;function c2(){if(n1)return So;n1=1;var i=D1();return So.createRoot=i.createRoot,So.hydrateRoot=i.hydrateRoot,So}var d2=c2();const f2=I1(d2);D1();/** + * @remix-run/router v1.23.2 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function li(){return li=Object.assign?Object.assign.bind():function(i){for(var s=1;s"u")throw new Error(s)}function Vs(i,s){if(!i){typeof console<"u"&&console.warn(s);try{throw new Error(s)}catch{}}}function h2(){return Math.random().toString(36).substr(2,8)}function i1(i,s){return{usr:i.state,key:i.key,idx:s}}function Bs(i,s,u,d){return u===void 0&&(u=null),li({pathname:typeof i=="string"?i:i.pathname,search:"",hash:""},typeof s=="string"?vr(s):s,{state:u,key:s&&s.key||d||h2()})}function N1(i){let{pathname:s="/",search:u="",hash:d=""}=i;return u&&u!=="?"&&(s+=u.charAt(0)==="?"?u:"?"+u),d&&d!=="#"&&(s+=d.charAt(0)==="#"?d:"#"+d),s}function vr(i){let s={};if(i){let u=i.indexOf("#");u>=0&&(s.hash=i.substr(u),i=i.substr(0,u));let d=i.indexOf("?");d>=0&&(s.search=i.substr(d),i=i.substr(0,d)),i&&(s.pathname=i)}return s}function m2(i,s,u,d){d===void 0&&(d={});let{window:f=document.defaultView,v5Compat:h=!1}=d,v=f.history,k=Ln.Pop,w=null,L=R();L==null&&(L=0,v.replaceState(li({},v.state,{idx:L}),""));function R(){return(v.state||{idx:null}).idx}function E(){k=Ln.Pop;let I=R(),J=I==null?null:I-L;L=I,w&&w({action:k,location:A.location,delta:J})}function _(I,J){k=Ln.Push;let X=Bs(A.location,I,J);L=R()+1;let ee=i1(X,L),ue=A.createHref(X);try{v.pushState(ee,"",ue)}catch(Ee){if(Ee instanceof DOMException&&Ee.name==="DataCloneError")throw Ee;f.location.assign(ue)}h&&w&&w({action:k,location:A.location,delta:1})}function O(I,J){k=Ln.Replace;let X=Bs(A.location,I,J);L=R();let ee=i1(X,L),ue=A.createHref(X);v.replaceState(ee,"",ue),h&&w&&w({action:k,location:A.location,delta:0})}function b(I){let J=f.location.origin!=="null"?f.location.origin:f.location.href,X=typeof I=="string"?I:N1(I);return X=X.replace(/ $/,"%20"),De(J,"No window.location.(origin|href) available to create URL for href: "+X),new URL(X,J)}let A={get action(){return k},get location(){return i(f,v)},listen(I){if(w)throw new Error("A history only accepts one active listener");return f.addEventListener(r1,E),w=I,()=>{f.removeEventListener(r1,E),w=null}},createHref(I){return s(f,I)},createURL:b,encodeLocation(I){let J=b(I);return{pathname:J.pathname,search:J.search,hash:J.hash}},push:_,replace:O,go(I){return v.go(I)}};return A}var o1;(function(i){i.data="data",i.deferred="deferred",i.redirect="redirect",i.error="error"})(o1||(o1={}));function g2(i,s,u){return u===void 0&&(u="/"),y2(i,s,u)}function y2(i,s,u,d){let f=typeof s=="string"?vr(s):s,h=A1(f.pathname||"/",u);if(h==null)return null;let v=M1(i);v2(v);let k=null;for(let w=0;k==null&&w{let w={relativePath:k===void 0?h.path||"":k,caseSensitive:h.caseSensitive===!0,childrenIndex:v,route:h};w.relativePath.startsWith("/")&&(De(w.relativePath.startsWith(d),'Absolute route path "'+w.relativePath+'" nested under path '+('"'+d+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),w.relativePath=w.relativePath.slice(d.length));let L=Hn([d,w.relativePath]),R=u.concat(w);h.children&&h.children.length>0&&(De(h.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+L+'".')),M1(h.children,s,R,L)),!(h.path==null&&!h.index)&&s.push({path:L,score:E2(L,h.index),routesMeta:R})};return i.forEach((h,v)=>{var k;if(h.path===""||!((k=h.path)!=null&&k.includes("?")))f(h,v);else for(let w of _1(h.path))f(h,v,w)}),s}function _1(i){let s=i.split("/");if(s.length===0)return[];let[u,...d]=s,f=u.endsWith("?"),h=u.replace(/\?$/,"");if(d.length===0)return f?[h,""]:[h];let v=_1(d.join("/")),k=[];return k.push(...v.map(w=>w===""?h:[h,w].join("/"))),f&&k.push(...v),k.map(w=>i.startsWith("/")&&w===""?"/":w)}function v2(i){i.sort((s,u)=>s.score!==u.score?u.score-s.score:T2(s.routesMeta.map(d=>d.childrenIndex),u.routesMeta.map(d=>d.childrenIndex)))}const C2=/^:[\w-]+$/,x2=3,w2=2,S2=1,k2=10,j2=-2,l1=i=>i==="*";function E2(i,s){let u=i.split("/"),d=u.length;return u.some(l1)&&(d+=j2),s&&(d+=w2),u.filter(f=>!l1(f)).reduce((f,h)=>f+(C2.test(h)?x2:h===""?S2:k2),d)}function T2(i,s){return i.length===s.length&&i.slice(0,-1).every((d,f)=>d===s[f])?i[i.length-1]-s[s.length-1]:0}function L2(i,s,u){let{routesMeta:d}=i,f={},h="/",v=[];for(let k=0;k{let{paramName:_,isOptional:O}=R;if(_==="*"){let A=k[E]||"";v=h.slice(0,h.length-A.length).replace(/(.)\/+$/,"$1")}const b=k[E];return O&&!b?L[_]=void 0:L[_]=(b||"").replace(/%2F/g,"/"),L},{}),pathname:h,pathnameBase:v,pattern:i}}function I2(i,s,u){s===void 0&&(s=!1),u===void 0&&(u=!0),Vs(i==="*"||!i.endsWith("*")||i.endsWith("/*"),'Route path "'+i+'" will be treated as if it were '+('"'+i.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+i.replace(/\*$/,"/*")+'".'));let d=[],f="^"+i.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(v,k,w)=>(d.push({paramName:k,isOptional:w!=null}),w?"/?([^\\/]+)?":"/([^\\/]+)"));return i.endsWith("*")?(d.push({paramName:"*"}),f+=i==="*"||i==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):u?f+="\\/*$":i!==""&&i!=="/"&&(f+="(?:(?=\\/|$))"),[new RegExp(f,s?void 0:"i"),d]}function P2(i){try{return i.split("/").map(s=>decodeURIComponent(s).replace(/\//g,"%2F")).join("/")}catch(s){return Vs(!1,'The URL path "'+i+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+s+").")),i}}function A1(i,s){if(s==="/")return i;if(!i.toLowerCase().startsWith(s.toLowerCase()))return null;let u=s.endsWith("/")?s.length-1:s.length,d=i.charAt(u);return d&&d!=="/"?null:i.slice(u)||"/"}const D2=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,N2=i=>D2.test(i);function M2(i,s){s===void 0&&(s="/");let{pathname:u,search:d="",hash:f=""}=typeof i=="string"?vr(i):i,h;if(u)if(N2(u))h=u;else{if(u.includes("//")){let v=u;u=u.replace(/\/\/+/g,"/"),Vs(!1,"Pathnames cannot have embedded double slashes - normalizing "+(v+" -> "+u))}u.startsWith("/")?h=s1(u.substring(1),"/"):h=s1(u,s)}else h=s;return{pathname:h,search:B2(d),hash:O2(f)}}function s1(i,s){let u=s.replace(/\/+$/,"").split("/");return i.split("/").forEach(f=>{f===".."?u.length>1&&u.pop():f!=="."&&u.push(f)}),u.length>1?u.join("/"):"/"}function Ps(i,s,u,d){return"Cannot include a '"+i+"' character in a manually specified "+("`to."+s+"` field ["+JSON.stringify(d)+"]. Please separate it out to the ")+("`to."+u+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function _2(i){return i.filter((s,u)=>u===0||s.route.path&&s.route.path.length>0)}function B1(i,s){let u=_2(i);return s?u.map((d,f)=>f===u.length-1?d.pathname:d.pathnameBase):u.map(d=>d.pathnameBase)}function O1(i,s,u,d){d===void 0&&(d=!1);let f;typeof i=="string"?f=vr(i):(f=li({},i),De(!f.pathname||!f.pathname.includes("?"),Ps("?","pathname","search",f)),De(!f.pathname||!f.pathname.includes("#"),Ps("#","pathname","hash",f)),De(!f.search||!f.search.includes("#"),Ps("#","search","hash",f)));let h=i===""||f.pathname==="",v=h?"/":f.pathname,k;if(v==null)k=u;else{let E=s.length-1;if(!d&&v.startsWith("..")){let _=v.split("/");for(;_[0]==="..";)_.shift(),E-=1;f.pathname=_.join("/")}k=E>=0?s[E]:"/"}let w=M2(f,k),L=v&&v!=="/"&&v.endsWith("/"),R=(h||v===".")&&u.endsWith("/");return!w.pathname.endsWith("/")&&(L||R)&&(w.pathname+="/"),w}const Hn=i=>i.join("/").replace(/\/\/+/g,"/"),A2=i=>i.replace(/\/+$/,"").replace(/^\/*/,"/"),B2=i=>!i||i==="?"?"":i.startsWith("?")?i:"?"+i,O2=i=>!i||i==="#"?"":i.startsWith("#")?i:"#"+i;function z2(i){return i!=null&&typeof i.status=="number"&&typeof i.statusText=="string"&&typeof i.internal=="boolean"&&"data"in i}const z1=["post","put","patch","delete"];new Set(z1);const F2=["get",...z1];new Set(F2);/** + * React Router v6.30.3 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function si(){return si=Object.assign?Object.assign.bind():function(i){for(var s=1;s{k.current=!0}),T.useCallback(function(L,R){if(R===void 0&&(R={}),!k.current)return;if(typeof L=="number"){d.go(L);return}let E=O1(L,JSON.parse(v),h,R.relative==="path");i==null&&s!=="/"&&(E.pathname=E.pathname==="/"?s:Hn([s,E.pathname])),(R.replace?d.replace:d.push)(E,R.state,R)},[s,d,v,h,i])}function b2(i,s){return H2(i,s)}function H2(i,s,u,d){ui()||De(!1);let{navigator:f}=T.useContext(ai),{matches:h}=T.useContext(Vn),v=h[h.length-1],k=v?v.params:{};v&&v.pathname;let w=v?v.pathnameBase:"/";v&&v.route;let L=ln(),R;if(s){var E;let I=typeof s=="string"?vr(s):s;w==="/"||(E=I.pathname)!=null&&E.startsWith(w)||De(!1),R=I}else R=L;let _=R.pathname||"/",O=_;if(w!=="/"){let I=w.replace(/^\//,"").split("/");O="/"+_.replace(/^\//,"").split("/").slice(I.length).join("/")}let b=g2(i,{pathname:O}),A=K2(b&&b.map(I=>Object.assign({},I,{params:Object.assign({},k,I.params),pathname:Hn([w,f.encodeLocation?f.encodeLocation(I.pathname).pathname:I.pathname]),pathnameBase:I.pathnameBase==="/"?w:Hn([w,f.encodeLocation?f.encodeLocation(I.pathnameBase).pathname:I.pathnameBase])})),h,u,d);return s&&A?T.createElement(Lo.Provider,{value:{location:si({pathname:"/",search:"",hash:"",state:null,key:"default"},R),navigationType:Ln.Pop}},A):A}function V2(){let i=J2(),s=z2(i)?i.status+" "+i.statusText:i instanceof Error?i.message:JSON.stringify(i),u=i instanceof Error?i.stack:null,f={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return T.createElement(T.Fragment,null,T.createElement("h2",null,"Unexpected Application Error!"),T.createElement("h3",{style:{fontStyle:"italic"}},s),u?T.createElement("pre",{style:f},u):null,null)}const $2=T.createElement(V2,null);class G2 extends T.Component{constructor(s){super(s),this.state={location:s.location,revalidation:s.revalidation,error:s.error}}static getDerivedStateFromError(s){return{error:s}}static getDerivedStateFromProps(s,u){return u.location!==s.location||u.revalidation!=="idle"&&s.revalidation==="idle"?{error:s.error,location:s.location,revalidation:s.revalidation}:{error:s.error!==void 0?s.error:u.error,location:u.location,revalidation:s.revalidation||u.revalidation}}componentDidCatch(s,u){console.error("React Router caught the following error during render",s,u)}render(){return this.state.error!==void 0?T.createElement(Vn.Provider,{value:this.props.routeContext},T.createElement(F1.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function Z2(i){let{routeContext:s,match:u,children:d}=i,f=T.useContext($s);return f&&f.static&&f.staticContext&&(u.route.errorElement||u.route.ErrorBoundary)&&(f.staticContext._deepestRenderedBoundaryId=u.route.id),T.createElement(Vn.Provider,{value:s},d)}function K2(i,s,u,d){var f;if(s===void 0&&(s=[]),u===void 0&&(u=null),d===void 0&&(d=null),i==null){var h;if(!u)return null;if(u.errors)i=u.matches;else if((h=d)!=null&&h.v7_partialHydration&&s.length===0&&!u.initialized&&u.matches.length>0)i=u.matches;else return null}let v=i,k=(f=u)==null?void 0:f.errors;if(k!=null){let R=v.findIndex(E=>E.route.id&&(k==null?void 0:k[E.route.id])!==void 0);R>=0||De(!1),v=v.slice(0,Math.min(v.length,R+1))}let w=!1,L=-1;if(u&&d&&d.v7_partialHydration)for(let R=0;R=0?v=v.slice(0,L+1):v=[v[0]];break}}}return v.reduceRight((R,E,_)=>{let O,b=!1,A=null,I=null;u&&(O=k&&E.route.id?k[E.route.id]:void 0,A=E.route.errorElement||$2,w&&(L<0&&_===0?(ep("route-fallback"),b=!0,I=null):L===_&&(b=!0,I=E.route.hydrateFallbackElement||null)));let J=s.concat(v.slice(0,_+1)),X=()=>{let ee;return O?ee=A:b?ee=I:E.route.Component?ee=T.createElement(E.route.Component,null):E.route.element?ee=E.route.element:ee=R,T.createElement(Z2,{match:E,routeContext:{outlet:R,matches:J,isDataRoute:u!=null},children:ee})};return u&&(E.route.ErrorBoundary||E.route.errorElement||_===0)?T.createElement(G2,{location:u.location,revalidation:u.revalidation,component:A,error:O,children:X(),routeContext:{outlet:null,matches:J,isDataRoute:!0}}):X()},null)}var W1=(function(i){return i.UseBlocker="useBlocker",i.UseRevalidator="useRevalidator",i.UseNavigateStable="useNavigate",i})(W1||{}),b1=(function(i){return i.UseBlocker="useBlocker",i.UseLoaderData="useLoaderData",i.UseActionData="useActionData",i.UseRouteError="useRouteError",i.UseNavigation="useNavigation",i.UseRouteLoaderData="useRouteLoaderData",i.UseMatches="useMatches",i.UseRevalidator="useRevalidator",i.UseNavigateStable="useNavigate",i.UseRouteId="useRouteId",i})(b1||{});function Q2(i){let s=T.useContext($s);return s||De(!1),s}function Y2(i){let s=T.useContext(U2);return s||De(!1),s}function q2(i){let s=T.useContext(Vn);return s||De(!1),s}function H1(i){let s=q2(),u=s.matches[s.matches.length-1];return u.route.id||De(!1),u.route.id}function J2(){var i;let s=T.useContext(F1),u=Y2(),d=H1();return s!==void 0?s:(i=u.errors)==null?void 0:i[d]}function X2(){let{router:i}=Q2(W1.UseNavigateStable),s=H1(b1.UseNavigateStable),u=T.useRef(!1);return U1(()=>{u.current=!0}),T.useCallback(function(f,h){h===void 0&&(h={}),u.current&&(typeof f=="number"?i.navigate(f):i.navigate(f,si({fromRouteId:s},h)))},[i,s])}const a1={};function ep(i,s,u){a1[i]||(a1[i]=!0)}function tp(i,s){i==null||i.v7_startTransition,i==null||i.v7_relativeSplatPath}function np(i){let{to:s,replace:u,state:d,relative:f}=i;ui()||De(!1);let{future:h,static:v}=T.useContext(ai),{matches:k}=T.useContext(Vn),{pathname:w}=ln(),L=Dt(),R=O1(s,B1(k,h.v7_relativeSplatPath),w,f==="path"),E=JSON.stringify(R);return T.useEffect(()=>L(JSON.parse(E),{replace:u,state:d,relative:f}),[L,E,f,u,d]),null}function xt(i){De(!1)}function rp(i){let{basename:s="/",children:u=null,location:d,navigationType:f=Ln.Pop,navigator:h,static:v=!1,future:k}=i;ui()&&De(!1);let w=s.replace(/^\/*/,"/"),L=T.useMemo(()=>({basename:w,navigator:h,static:v,future:si({v7_relativeSplatPath:!1},k)}),[w,k,h,v]);typeof d=="string"&&(d=vr(d));let{pathname:R="/",search:E="",hash:_="",state:O=null,key:b="default"}=d,A=T.useMemo(()=>{let I=A1(R,w);return I==null?null:{location:{pathname:I,search:E,hash:_,state:O,key:b},navigationType:f}},[w,R,E,_,O,b,f]);return A==null?null:T.createElement(ai.Provider,{value:L},T.createElement(Lo.Provider,{children:u,value:A}))}function ip(i){let{children:s,location:u}=i;return b2(Os(s),u)}new Promise(()=>{});function Os(i,s){s===void 0&&(s=[]);let u=[];return T.Children.forEach(i,(d,f)=>{if(!T.isValidElement(d))return;let h=[...s,f];if(d.type===T.Fragment){u.push.apply(u,Os(d.props.children,h));return}d.type!==xt&&De(!1),!d.props.index||!d.props.children||De(!1);let v={id:d.props.id||h.join("-"),caseSensitive:d.props.caseSensitive,element:d.props.element,Component:d.props.Component,index:d.props.index,path:d.props.path,loader:d.props.loader,action:d.props.action,errorElement:d.props.errorElement,ErrorBoundary:d.props.ErrorBoundary,hasErrorBoundary:d.props.ErrorBoundary!=null||d.props.errorElement!=null,shouldRevalidate:d.props.shouldRevalidate,handle:d.props.handle,lazy:d.props.lazy};d.props.children&&(v.children=Os(d.props.children,h)),u.push(v)}),u}/** + * React Router DOM v6.30.3 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */const op="6";try{window.__reactRouterVersion=op}catch{}const lp="startTransition",u1=l2[lp];function sp(i){let{basename:s,children:u,future:d,window:f}=i,h=T.useRef();h.current==null&&(h.current=p2({window:f,v5Compat:!0}));let v=h.current,[k,w]=T.useState({action:v.action,location:v.location}),{v7_startTransition:L}=d||{},R=T.useCallback(E=>{L&&u1?u1(()=>w(E)):w(E)},[w,L]);return T.useLayoutEffect(()=>v.listen(R),[v,R]),T.useEffect(()=>tp(d),[d]),T.createElement(rp,{basename:s,children:u,location:k.location,navigationType:k.action,navigator:v,future:d})}var c1;(function(i){i.UseScrollRestoration="useScrollRestoration",i.UseSubmit="useSubmit",i.UseSubmitFetcher="useSubmitFetcher",i.UseFetcher="useFetcher",i.useViewTransitionState="useViewTransitionState"})(c1||(c1={}));var d1;(function(i){i.UseFetcher="useFetcher",i.UseFetchers="useFetchers",i.UseScrollRestoration="useScrollRestoration"})(d1||(d1={}));var ap=12e4;function up(i){return{scan(s){const{signal:u,...d}=s,f=i.request("nfc","scan",d,ap);if(u){const h=()=>{i.fire("nfc","cancelScan",{sessionId:d.sessionId})};if(u.aborted)return i.fire("nfc","cancelScan",{sessionId:d.sessionId}),Promise.reject(new DOMException("Aborted","AbortError"));u.addEventListener("abort",h,{once:!0}),f.finally(()=>u.removeEventListener("abort",h))}return f}}}function cp(i,s){return i.on("nfc","scanProgress",s)}function dp(i){return{async hash(s,u="sha256"){const f={sha256:"SHA-256"}[u];if(!f)throw new Error(`Unsupported hash algorithm: ${u}`);const h=new Uint8Array(s).buffer,v=await crypto.subtle.digest(f,h);return new Uint8Array(v)},async sign(s,u){const d=fp(s),f=await i.request("crypto","sign",{data:d,keyRef:u});return pp(f.signature)}}}function fp(i){let s="";for(let u=0;u{const u=indexedDB.open(mp,gp);u.onupgradeneeded=()=>{const d=u.result;d.objectStoreNames.contains(oi)||d.createObjectStore(oi),d.objectStoreNames.contains(To)||d.createObjectStore(To)},u.onsuccess=()=>i(u.result),u.onerror=()=>s(u.error)})}function h1(i,s,u){return new Promise((d,f)=>{const v=i.transaction(s,"readonly").objectStore(s).get(u);v.onsuccess=()=>d(v.result),v.onerror=()=>f(v.error)})}function m1(i,s,u,d){return new Promise((f,h)=>{const k=i.transaction(s,"readwrite").objectStore(s).put(d,u);k.onsuccess=()=>f(),k.onerror=()=>h(k.error)})}function vp(i,s,u){return new Promise((d,f)=>{const v=i.transaction(s,"readwrite").objectStore(s).delete(u);v.onsuccess=()=>d(),v.onerror=()=>f(v.error)})}function Cp(){let i=null;function s(){return i||(i=yp()),i}return{async loadDocumentCatalog(){const u=await s();return await h1(u,To,f1)??{documents:[]}},async saveDocumentCatalog(u){const d=await s();await m1(d,To,f1,p1(u))},async loadDocumentById(u){const d=await s();return await h1(d,oi,u)??null},async saveDocument(u,d){const f=await s();await m1(f,oi,u,p1(d))},async deleteDocument(u){const d=await s();await vp(d,oi,u)}}}function xp(i){return{async get(s){const u=await i.request("secureStorage","get",{key:s});return(u==null?void 0:u.value)??null},async set(s,u){await i.request("secureStorage","set",{key:s,value:u})},async remove(s){await i.request("secureStorage","remove",{key:s})}}}function wp(i){const{endpoint:s,debug:u=!1}={};function d(f){u&&console.log("[Analytics]",f),s&&fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)}).catch(()=>{})}return{trackEvent(f,h){d({type:"event",event:f,...h,timestamp:Date.now()})},trackNfcEvent(f,h){d({type:"nfc_event",name:f,...h,timestamp:Date.now()})},logNFCEvent(f,h,v,k){d({type:"nfc_log",level:f,message:h,context:v,details:k,timestamp:Date.now()})}}}function Sp(){return{trigger(){}}}var kp={DocumentCamera:"/onboarding/camera",DocumentOnboarding:"/onboarding",CountryPicker:"/onboarding/country",IDPicker:"/onboarding/id-type",DocumentNFCScan:"/onboarding/nfc",ManageDocuments:"/documents",Home:"/",AccountVerifiedSuccess:"/account/verified",AccountRecoveryChoice:"/account/recovery",SaveRecoveryPhrase:"/account/recovery/phrase",ComingSoon:"/coming-soon",DocumentDataNotFound:"/error/no-data",Settings:"/settings"};function jp(i,s){return{goBack:s,goTo(u,d){const f=kp[u];if(!f){console.warn(`[Navigation] Unknown route: ${u}`);return}i(f)}}}function Ep(i){return{ready(){i.fire("lifecycle","ready",{})},dismiss(){i.fire("lifecycle","dismiss",{})},async setResult(s){await i.request("lifecycle","setResult",s)}}}function Tp(i){return{async authenticate(s){return i.request("biometrics","authenticate",s)},async isAvailable(){return i.request("biometrics","isAvailable",{})},async getBiometryType(){return i.request("biometrics","getBiometryType",{})}}}function Lp(i){return{async scanMRZ(){return i.request("camera","scanMRZ",{})},async isAvailable(){return i.request("camera","isAvailable",{})}}}const Ve=[];for(let i=0;i<256;++i)Ve.push((i+256).toString(16).slice(1));function Rp(i,s=0){return(Ve[i[s+0]]+Ve[i[s+1]]+Ve[i[s+2]]+Ve[i[s+3]]+"-"+Ve[i[s+4]]+Ve[i[s+5]]+"-"+Ve[i[s+6]]+Ve[i[s+7]]+"-"+Ve[i[s+8]]+Ve[i[s+9]]+"-"+Ve[i[s+10]]+Ve[i[s+11]]+Ve[i[s+12]]+Ve[i[s+13]]+Ve[i[s+14]]+Ve[i[s+15]]).toLowerCase()}let Ds;const Ip=new Uint8Array(16);function Pp(){if(!Ds){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");Ds=crypto.getRandomValues.bind(crypto)}return Ds(Ip)}const Dp=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),g1={randomUUID:Dp};function y1(i,s,u){var f;if(g1.randomUUID&&!i)return g1.randomUUID();i=i||{};const d=i.random??((f=i.rng)==null?void 0:f.call(i))??Pp();if(d.length<16)throw new Error("Random bytes length must be >= 16");return d[6]=d[6]&15|64,d[8]=d[8]&63|128,Rp(d)}var zs=1,Np=3e4,Mp=["nfc","biometrics","secureStorage","camera","crypto","haptic","analytics","lifecycle","documents","navigation"],_p=["request","response","event"],Pt=class extends Error{constructor(i){super(i),this.name="ValidationError"}};function Gs(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function Ro(i,s){if(typeof i[s]!="string")throw new Pt(`Missing or invalid field: ${s} (expected string)`)}function v1(i,s){if(typeof i[s]!="number")throw new Pt(`Missing or invalid field: ${s} (expected number)`)}function C1(i){let s;try{s=JSON.parse(i)}catch{throw new Pt("Invalid JSON")}if(!Gs(s))throw new Pt("Message must be an object");const u=s.type;if(!_p.includes(u))throw new Pt(`Invalid message type: ${String(u)}`);if(v1(s,"version"),s.version!==zs)throw new Pt(`Unsupported protocol version: ${s.version}`);Ro(s,"id"),v1(s,"timestamp");const d=s.domain;if(!Mp.includes(d))throw new Pt(`Invalid domain: ${String(d)}`);switch(u){case"request":return Ap(s);case"response":return Bp(s);case"event":return Op(s);default:throw new Pt(`Unknown message type: ${String(u)}`)}}function Ap(i){if(Ro(i,"method"),!Gs(i.params))throw new Pt("Request params must be an object");return i}function Bp(i){if(Ro(i,"requestId"),typeof i.success!="boolean")throw new Pt("Response success must be a boolean");if(!i.success&&i.error){if(!Gs(i.error))throw new Pt("Response error must be an object");if(typeof i.error.code!="string"||typeof i.error.message!="string")throw new Pt("Response error must have code and message strings")}return i}function Op(i){return Ro(i,"event"),i}function zp(i){return i.type==="response"}function Fp(i){return i.type==="event"}var Up=class{constructor(i={}){this.pending=new Map,this.listeners=new Map,this.destroyed=!1,this.debug=i.debug??!1,this.transport=i.transport??this.detectTransport(),globalThis.SelfNativeBridge=this}detectTransport(){var i,s,u,d,f;return(i=globalThis.SelfNativeAndroid)!=null&&i.postMessage?globalThis.SelfNativeAndroid:typeof window<"u"&&((d=(u=(s=window.webkit)==null?void 0:s.messageHandlers)==null?void 0:u.SelfNativeIOS)!=null&&d.postMessage)?window.webkit.messageHandlers.SelfNativeIOS:typeof window<"u"&&((f=window.ReactNativeWebView)!=null&&f.postMessage)?window.ReactNativeWebView:null}log(...i){this.debug&&console.log("[WebViewBridge]",...i)}send(i){if(this.destroyed)throw new Error("Bridge has been destroyed");const s=JSON.stringify(i);if(this.log("→",i.domain,i.method,i.params),!this.transport){this.log("No native transport available, message dropped");return}this.transport.postMessage(s)}request(i,s,u={},d=Np){if(this.destroyed)return Promise.reject(new Error("Bridge has been destroyed"));const f=y1(),h={type:"request",version:zs,id:f,domain:i,method:s,params:u,timestamp:Date.now()};return new Promise((v,k)=>{const w=setTimeout(()=>{this.pending.delete(f),k(new Error(`Bridge request timed out: ${i}.${s} (${d}ms)`))},d);this.pending.set(f,{resolve:v,reject:k,timeout:w}),this.send(h)})}fire(i,s,u={}){const d=y1(),f={type:"request",version:zs,id:d,domain:i,method:s,params:u,timestamp:Date.now()};this.send(f)}on(i,s,u){const d=`${i}:${s}`;return this.listeners.has(d)||this.listeners.set(d,new Set),this.listeners.get(d).add(u),()=>{const f=this.listeners.get(d);f&&(f.delete(u),f.size===0&&this.listeners.delete(d))}}_handleResponse(i){this.log("← response",i.substring(0,200));try{const s=C1(i);if(!zp(s)){this.log("Expected response, got:",s.type);return}this.resolveResponse(s)}catch(s){this.log("Failed to parse response:",s)}}_handleEvent(i){this.log("← event",i.substring(0,200));try{const s=C1(i);if(!Fp(s)){this.log("Expected event, got:",s.type);return}this.dispatchEvent(s)}catch(s){this.log("Failed to parse event:",s)}}resolveResponse(i){const s=this.pending.get(i.requestId);if(!s){this.log("No pending request for:",i.requestId);return}if(clearTimeout(s.timeout),this.pending.delete(i.requestId),i.success)s.resolve(i.data);else{const u=i.error??{code:"UNKNOWN",message:"Unknown error"},d=new Error(u.message);d.code=u.code,u.details&&(d.details=u.details),s.reject(d)}}dispatchEvent(i){const s=`${i.domain}:${i.event}`,u=this.listeners.get(s);if(u)for(const d of u)try{d(i.data)}catch(f){this.log("Event handler error:",f)}}get isConnected(){return this.transport!==null}get pendingCount(){return this.pending.size}destroy(){this.destroyed=!0;for(const[i,s]of this.pending)clearTimeout(s.timeout),s.reject(new Error("Bridge destroyed")),this.pending.delete(i);this.listeners.clear(),globalThis.SelfNativeBridge===this&&(globalThis.SelfNativeBridge=void 0)}};const V1=T.createContext(null);function Zs(){const i=T.useContext(V1);if(!i)throw new Error("useBridge must be used within a BridgeProvider");return i}const Wp=({children:i})=>{const s=T.useMemo(()=>new Up({debug:!1}),[]);return a.jsx(V1.Provider,{value:s,children:i})},$1=T.createContext(null);function Qt(){const i=T.useContext($1);if(!i)throw new Error("useSelfClient must be used within a SelfClientProvider");return i}const bp=({children:i})=>{const s=Zs(),u=Dt(),d=T.useMemo(()=>{const f=Ep(s);return{scanner:up(s),crypto:dp(s),auth:hp(s),documents:Cp(),storage:xp(s),analytics:wp(),lifecycle:f,navigation:jp(h=>u(h),()=>u(-1)),haptic:Sp(),biometrics:Tp(s),camera:Lp(s)}},[s,u]);return T.useEffect(()=>{d.lifecycle.ready()},[d.lifecycle]),a.jsx($1.Provider,{value:d,children:i})},m={white:"#FFFFFF",black:"#000000",blue50:"#EFF6FF",blue100:"#DBEAFE",blue600:"#2563EB",slate50:"#F8FAFC",slate200:"#E2E8F0",slate300:"#CBD5E1",slate400:"#94A3B8",slate500:"#64748B",slate600:"#475569",slate800:"#1E293B",gray50:"#F9FAFB",gray200:"#E5E7EB",gray300:"#D1D5DB",gray400:"#9CA3AF",gray500:"#6B7280",gray700:"#374151",gray9193a2:"#9193A2",gray747474:"#747474",zinc600:"#52525B",zinc800:"#27272A",indigo950:"#1E1B4B",amber600:"#D97706",green500:"#22C55E",green600:"#16A34A",red500:"#EF4444",selfEmerald:"#00ffb6",purple600:"#7857ED"},Re={xs:4,sm:8,md:16,lg:24},Hp={dinOT:{web:"DIN OT",native:"DINOT-Medium"},advercase:{web:"Advercase",native:"Advercase-Regular"},ibmPlexMono:{web:"IBM Plex Mono",native:"IBMPlexMono-Regular"},sfPro:{web:"SF Pro",native:"SFPro"},sfMono:{web:"SF Mono, Courier New, monospace",native:"SFMono"}},pe={xxs:10,xs:12,sm:14,base:15,md:16,ml:18,lg:20,xl:24,xxl:32},Z={regular:"400",medium:"500",semibold:"600",bold:"700"},Vp={tight:1.2,normal:1.5,relaxed:1.75};function $p(i){const s={};for(const[u,d]of Object.entries(Hp))s[u]=d[i];return{fontFamily:s,fontSize:pe,fontWeight:Z,lineHeight:Vp}}const G1=$p("web"),Xe=G1,V=G1.fontFamily,et=({onPress:i,variant:s,text:u,icon:d,disabled:f=!1,fullWidth:h=!1,onLongPress:v})=>{const[k,w]=T.useState(!1),L=T.useRef(null),R=T.useRef(!1);(s==="primary-icon-label"||s==="secondary-icon-label")&&(!u||!d)&&console.warn(`Button: variant "${s}" requires both text and icon props`),(s==="primary-icon"||s==="secondary-icon")&&!d&&console.warn(`Button: variant "${s}" requires icon prop`),(s==="primary-no-icon"||s==="secondary-label")&&!u&&console.warn(`Button: variant "${s}" requires text prop`),(s==="mega-primary"||s==="mega-secondary")&&(!u||!d)&&console.warn(`Button: variant "${s}" requires both text and icon props`),(s==="primary-stacked"||s==="secondary-stacked")&&(!u||!d)&&console.warn(`Button: variant "${s}" requires both text and icon props`);const E=T.useCallback(()=>{w(!0),R.current=!1,v&&(L.current=setTimeout(()=>{R.current=!0,v()},500))},[v]),_=T.useCallback(()=>{w(!1),L.current&&(clearTimeout(L.current),L.current=null)},[]),O=T.useCallback(()=>{w(!1),L.current&&(clearTimeout(L.current),L.current=null)},[]),b=T.useCallback(()=>{R.current||i()},[i]),A={...Je.base,...Je[s],...s==="primary-stacked"||s==="secondary-stacked"?Je.stackedBase:{},...h?Je.fullWidth:{},...f?Je.disabled:{},...k?Je.pressed:{}},I={...Je.text,...Je[`${s}Text`],...f?Je.disabledText:{}},J=()=>{switch(s){case"primary-icon":case"secondary-icon":return a.jsx("span",{style:Je.iconWrapper,children:d&&d({size:29,color:s==="primary-icon"?m.white:m.black})});case"primary-icon-label":case"secondary-icon-label":case"mega-primary":case"mega-secondary":return a.jsxs("span",{style:Je.iconLabelContainer,children:[a.jsx("span",{style:Je.iconWrapper,children:d&&d({size:36,color:s.includes("primary")?m.white:m.black})}),a.jsx("span",{style:I,children:u})]});case"primary-no-icon":case"secondary-label":return a.jsx("span",{style:I,children:u});case"primary-stacked":return a.jsxs("span",{style:Je.stackedContainer,children:[a.jsx("span",{style:Je.stackedIconWrapperPrimary,children:d&&d({size:36,color:m.white})}),a.jsx("span",{style:I,children:u})]});case"secondary-stacked":return a.jsxs("span",{style:Je.stackedContainer,children:[a.jsx("span",{style:Je.stackedIconWrapperSecondary,children:d&&d({size:36,color:m.blue600})}),a.jsx("span",{style:I,children:u})]});default:return null}};return a.jsx("button",{type:"button",style:A,onClick:b,onMouseDown:E,onMouseUp:_,onMouseLeave:O,disabled:f,children:J()})},Je={base:{display:"inline-flex",alignItems:"center",justifyContent:"center",borderRadius:60,flexDirection:"row",cursor:"pointer",padding:0,margin:0,background:"none",border:"none",outline:"none",fontFamily:"inherit",transition:"opacity 0.15s ease, transform 0.15s ease"},pressed:{opacity:.75,transform:"scale(0.993)"},"primary-icon":{backgroundColor:m.black,borderWidth:1,borderStyle:"solid",borderColor:m.gray700,width:46,height:46},"primary-icon-label":{backgroundColor:m.black,borderWidth:1,borderStyle:"solid",borderColor:m.gray700,paddingLeft:14,paddingRight:14,paddingTop:8,paddingBottom:8,minHeight:46},"primary-no-icon":{backgroundColor:m.black,borderWidth:1,borderStyle:"solid",borderColor:m.gray700,paddingLeft:14,paddingRight:14,paddingTop:8,paddingBottom:8,minHeight:46},"secondary-icon":{backgroundColor:m.white,borderWidth:1,borderStyle:"solid",borderColor:m.gray200,width:46,height:46},"secondary-icon-label":{backgroundColor:m.white,borderWidth:1,borderStyle:"solid",borderColor:m.gray200,paddingLeft:14,paddingRight:14,paddingTop:8,paddingBottom:8,minHeight:46},"secondary-label":{backgroundColor:m.white,borderWidth:1,borderStyle:"solid",borderColor:m.gray200,paddingLeft:14,paddingRight:14,paddingTop:8,paddingBottom:8,minHeight:46},"mega-primary":{backgroundColor:m.black,borderWidth:1,borderStyle:"solid",borderColor:m.gray700,paddingLeft:20,paddingRight:20,paddingTop:12,paddingBottom:12,minHeight:60,borderRadius:5},"mega-secondary":{backgroundColor:m.white,borderWidth:1,borderStyle:"solid",borderColor:m.gray200,paddingLeft:20,paddingRight:20,paddingTop:12,paddingBottom:12,minHeight:60,borderRadius:5},"primary-stacked":{backgroundColor:"transparent",borderWidth:0,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0},"secondary-stacked":{backgroundColor:"transparent",borderWidth:0,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0},stackedBase:{flexDirection:"column"},fullWidth:{width:"100%"},disabled:{opacity:.5,cursor:"not-allowed"},text:{fontWeight:500,fontFamily:"DIN OT, sans-serif"},"primary-iconText":{color:m.white,fontSize:16},"primary-icon-labelText":{color:m.white,fontSize:16},"primary-no-iconText":{color:m.white,fontSize:16},"secondary-iconText":{color:m.black,fontSize:16},"secondary-icon-labelText":{color:m.black,fontSize:16},"secondary-labelText":{color:m.black,fontSize:16},"mega-primaryText":{color:m.white,fontSize:18},"mega-secondaryText":{color:m.black,fontSize:18},"primary-stackedText":{color:m.slate800,fontSize:14},"secondary-stackedText":{color:m.slate800,fontSize:14},disabledText:{opacity:.7},iconLabelContainer:{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:10},iconWrapper:{display:"inline-flex",width:24,height:24,alignItems:"center",justifyContent:"center"},stackedContainer:{display:"inline-flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:10},stackedIconWrapperPrimary:{display:"inline-flex",width:64,height:64,borderRadius:32,backgroundColor:m.black,borderWidth:1,borderStyle:"solid",borderColor:m.gray700,alignItems:"center",justifyContent:"center"},stackedIconWrapperSecondary:{display:"inline-flex",width:64,height:64,borderRadius:32,backgroundColor:m.slate50,borderWidth:1,borderStyle:"solid",borderColor:m.slate200,alignItems:"center",justifyContent:"center"}},Fe=({size:i=29,children:s})=>a.jsx("svg",{width:i,height:i,viewBox:"0 0 29 29",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s}),Z1=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M14.5 7V22M7 14.5H22",stroke:s,strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}),Ks=({size:i=32,color:s="#D1D5DB"})=>a.jsxs("svg",{width:i,height:i,viewBox:"0 0 32 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[a.jsx("path",{d:"M16.0044 12.28H16C13.9455 12.28 12.28 13.9455 12.28 16V16.0044C12.28 18.0589 13.9455 19.7244 16 19.7244H16.0044C18.0589 19.7244 19.7244 18.0589 19.7244 16.0044V16C19.7244 13.9455 18.0589 12.28 16.0044 12.28Z",fill:s}),a.jsx("path",{d:"M8.70222 12.5556C8.70222 10.3467 10.4933 8.55556 12.7022 8.55556H20.4267L28.9822 0H7.65333L0 7.65333V20.2444H8.70222V12.5511V12.5556Z",fill:s}),a.jsx("path",{d:"M23.2978 11.7244V19.1511C23.2978 21.36 21.5067 23.1511 19.2978 23.1511H11.8711L3.01778 32.0044H24.3467L32 24.3511V11.7289H23.2978V11.7244Z",fill:s}),a.jsx("rect",{width:"32",height:"32"})]}),Gp=({size:i=18,color:s="#FFFFFF"})=>a.jsxs("svg",{width:i,height:i,viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[a.jsx("path",{d:"M9.0025 6.9075H9C7.84434 6.9075 6.9075 7.84434 6.9075 9V9.0025C6.9075 10.1582 7.84434 11.095 9 11.095H9.0025C10.1582 11.095 11.095 10.1582 11.095 9.0025V9C11.095 7.84434 10.1582 6.9075 9.0025 6.9075Z",fill:s}),a.jsx("path",{d:"M4.895 7.0625C4.895 5.82 5.9025 4.8125 7.145 4.8125H11.49L16.3025 0H4.305L0 4.305V11.3875H4.895V7.06V7.0625Z",fill:s}),a.jsx("path",{d:"M13.105 6.595V10.7725C13.105 12.015 12.0975 13.0225 10.855 13.0225H6.6775L1.6975 18.0025H13.695L18 13.6975V6.5975H13.105V6.595Z",fill:s}),a.jsx("rect",{width:"18",height:"18"})]}),Zp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M14.5 3L17.5 10L25 10L19 15L21 22L14.5 18L8 22L10 15L4 10L11.5 10L14.5 3Z",fill:s})}),Kp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M13.5117 25.4697C13.2324 25.4697 12.9961 25.391 12.8027 25.2334C12.6094 25.083 12.4805 24.8682 12.416 24.5889L11.8574 22.2256C11.6497 22.154 11.4456 22.0788 11.2451 22C11.0446 21.9212 10.8548 21.8389 10.6758 21.7529L8.61328 23.0205C8.37695 23.1637 8.13346 23.2246 7.88281 23.2031C7.63932 23.1816 7.4209 23.0742 7.22754 22.8809L5.85254 21.5059C5.65918 21.3125 5.54818 21.0869 5.51953 20.8291C5.49805 20.5713 5.56608 20.3278 5.72363 20.0986L6.98047 18.0469C6.89453 17.8607 6.81217 17.6709 6.7334 17.4775C6.65462 17.2842 6.58659 17.0908 6.5293 16.8975L4.14453 16.3281C3.86523 16.2708 3.65039 16.1455 3.5 15.9521C3.34961 15.7588 3.27441 15.5225 3.27441 15.2432V13.2988C3.27441 13.0267 3.34961 12.7939 3.5 12.6006C3.65039 12.4072 3.86523 12.2819 4.14453 12.2246L6.50781 11.6553C6.57227 11.4333 6.64388 11.2256 6.72266 11.0322C6.80859 10.8389 6.88737 10.6562 6.95898 10.4844L5.70215 8.40039C5.5446 8.17122 5.47656 7.9349 5.49805 7.69141C5.51953 7.44076 5.63053 7.21875 5.83105 7.02539L7.22754 5.63965C7.42806 5.45345 7.6429 5.34603 7.87207 5.31738C8.1084 5.28874 8.34473 5.34245 8.58105 5.47852L10.665 6.76758C10.8441 6.67448 11.0339 6.58854 11.2344 6.50977C11.4421 6.42383 11.6497 6.34505 11.8574 6.27344L12.416 3.89941C12.4805 3.62728 12.6094 3.41243 12.8027 3.25488C12.9961 3.09733 13.2324 3.01855 13.5117 3.01855H15.4883C15.7676 3.01855 16.0039 3.09733 16.1973 3.25488C16.3906 3.41243 16.516 3.62728 16.5732 3.89941L17.1318 6.29492C17.3538 6.36654 17.5615 6.44173 17.7549 6.52051C17.9554 6.59928 18.1416 6.68522 18.3135 6.77832L20.4189 5.47852C20.6553 5.34245 20.888 5.29232 21.1172 5.32812C21.3464 5.35677 21.5612 5.46061 21.7617 5.63965L23.1689 7.02539C23.3695 7.21875 23.4769 7.44076 23.4912 7.69141C23.5127 7.9349 23.4482 8.17122 23.2979 8.40039L22.0303 10.4844C22.1019 10.6562 22.1771 10.8389 22.2559 11.0322C22.3418 11.2256 22.4206 11.4333 22.4922 11.6553L24.8555 12.2246C25.1276 12.2819 25.3389 12.4072 25.4893 12.6006C25.6468 12.7939 25.7256 13.0267 25.7256 13.2988V15.2432C25.7256 15.5225 25.6468 15.7588 25.4893 15.9521C25.3389 16.1455 25.1276 16.2708 24.8555 16.3281L22.4707 16.8975C22.4062 17.0908 22.3346 17.2842 22.2559 17.4775C22.1842 17.6709 22.1019 17.8607 22.0088 18.0469L23.2764 20.0986C23.4339 20.3278 23.4984 20.5713 23.4697 20.8291C23.4482 21.0869 23.3408 21.3125 23.1475 21.5059L21.7617 22.8809C21.5684 23.0742 21.3464 23.1816 21.0957 23.2031C20.8522 23.2246 20.6159 23.1637 20.3867 23.0205L18.3135 21.7529C18.1344 21.8389 17.9447 21.9212 17.7441 22C17.5436 22.0788 17.3395 22.154 17.1318 22.2256L16.5732 24.5889C16.516 24.8682 16.3906 25.083 16.1973 25.2334C16.0039 25.391 15.7676 25.4697 15.4883 25.4697H13.5117ZM14.5 18.0361C15.1947 18.0361 15.8285 17.8643 16.4014 17.5205C16.9814 17.1768 17.4398 16.7184 17.7764 16.1455C18.1201 15.5654 18.292 14.9281 18.292 14.2334C18.292 13.5387 18.1201 12.9085 17.7764 12.3428C17.4398 11.7699 16.9814 11.3115 16.4014 10.9678C15.8285 10.624 15.1947 10.4521 14.5 10.4521C13.8053 10.4521 13.1715 10.624 12.5986 10.9678C12.0257 11.3115 11.5674 11.7699 11.2236 12.3428C10.8799 12.9085 10.708 13.5387 10.708 14.2334C10.708 14.9281 10.8763 15.5654 11.2129 16.1455C11.5566 16.7184 12.015 17.1768 12.5879 17.5205C13.168 17.8643 13.8053 18.0361 14.5 18.0361Z",fill:s})}),Qs=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M3.08594 14.5039C3.08594 14.0039 3.26172 13.5859 3.61328 13.25L11.2305 5.63281C11.4102 5.45312 11.6016 5.32031 11.8047 5.23438C12.0156 5.14062 12.2227 5.09375 12.4258 5.09375C12.9258 5.09375 13.3281 5.25 13.6328 5.5625C13.9453 5.86719 14.1016 6.24609 14.1016 6.69922C14.1016 6.95703 14.0508 7.1875 13.9492 7.39062C13.8555 7.58594 13.7305 7.76172 13.5742 7.91797L10.9492 10.5547L7.07031 14.1172L6.34375 13.0508L10.9023 12.8047H24.1445C24.6758 12.8047 25.1016 12.9609 25.4219 13.2734C25.7422 13.5859 25.9023 13.9961 25.9023 14.5039C25.9023 15.0117 25.7422 15.4219 25.4219 15.7344C25.1016 16.0469 24.6758 16.2031 24.1445 16.2031H10.9023L6.34375 15.957L7.07031 14.8906L10.9492 18.4531L13.5742 21.0781C13.7305 21.2344 13.8555 21.4141 13.9492 21.6172C14.0508 21.8125 14.1016 22.0391 14.1016 22.2969C14.1016 22.75 13.9453 23.1289 13.6328 23.4336C13.3281 23.7461 12.9258 23.9023 12.4258 23.9023C11.9961 23.9023 11.6016 23.7266 11.2422 23.375L3.61328 15.7578C3.26172 15.4141 3.08594 14.9961 3.08594 14.5039Z",fill:s})}),ci=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M5.30094 23.7383C5.07437 23.5117 4.92203 23.2461 4.8439 22.9414C4.77359 22.6289 4.7775 22.3242 4.85562 22.0273C4.93375 21.7227 5.07828 21.4648 5.28922 21.2539L11.9806 14.5508L5.28922 7.85938C5.07828 7.64844 4.93375 7.39062 4.85562 7.08594C4.78531 6.78125 4.78531 6.47656 4.85562 6.17188C4.93375 5.86719 5.08219 5.60156 5.30094 5.375C5.5275 5.14062 5.79312 4.98828 6.09781 4.91797C6.41031 4.84766 6.7189 4.84766 7.02359 4.91797C7.32828 4.98828 7.59 5.13281 7.80875 5.35156L14.5002 12.0312L21.1798 5.35156C21.3986 5.13281 21.6603 4.98828 21.965 4.91797C22.2697 4.83984 22.5705 4.83984 22.8673 4.91797C23.172 4.99609 23.4416 5.14844 23.6759 5.375C23.9025 5.60156 24.0548 5.86719 24.133 6.17188C24.2111 6.47656 24.2111 6.78125 24.133 7.08594C24.0627 7.38281 23.9181 7.64453 23.6994 7.87109L17.0197 14.5508L23.6994 21.2422C23.9181 21.4609 24.0627 21.7227 24.133 22.0273C24.2033 22.332 24.1994 22.6367 24.1212 22.9414C24.0509 23.2461 23.9025 23.5117 23.6759 23.7383C23.4494 23.9648 23.1837 24.1133 22.8791 24.1836C22.5744 24.2617 22.2697 24.2656 21.965 24.1953C21.6603 24.125 21.3986 23.9766 21.1798 23.75L14.5002 17.0703L7.80875 23.7617C7.59 23.9727 7.32828 24.1133 7.02359 24.1836C6.72672 24.2617 6.42203 24.2617 6.10953 24.1836C5.80484 24.1133 5.53531 23.9648 5.30094 23.7383Z",fill:s})}),x1=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M22.5039 14.5391C22.5039 14.8281 22.4453 15.0977 22.3281 15.3477C22.2188 15.5898 22.043 15.8281 21.8008 16.0625L12.9531 24.7344C12.5938 25.0938 12.1562 25.2734 11.6406 25.2734C11.3047 25.2734 10.9922 25.1875 10.7031 25.0156C10.4141 24.8516 10.1836 24.6289 10.0117 24.3477C9.84766 24.0664 9.76562 23.7539 9.76562 23.4102C9.76562 22.8945 9.96484 22.4336 10.3633 22.0273L18.0859 14.5273L10.3633 7.03906C9.96484 6.64844 9.76562 6.19141 9.76562 5.66797C9.76562 5.32422 9.84766 5.01172 10.0117 4.73047C10.1836 4.44922 10.4141 4.22656 10.7031 4.0625C10.9922 3.89062 11.3047 3.80469 11.6406 3.80469C12.1562 3.80469 12.5938 3.98047 12.9531 4.33203L21.8008 13.0039C22.043 13.2383 22.2188 13.4805 22.3281 13.7305C22.4375 13.9727 22.4961 14.2422 22.5039 14.5391Z",fill:s})}),Qp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M8.78125 26.2227C7.84375 26.2227 7.13281 25.9727 6.64844 25.4727C6.17188 24.9727 5.93359 24.2148 5.93359 23.1992V14.4922C5.93359 13.4844 6.17188 12.7344 6.64844 12.2422C7.13281 11.7422 7.84375 11.4922 8.78125 11.4922H20.207C21.1445 11.4922 21.8516 11.7422 22.3281 12.2422C22.8125 12.7344 23.0547 13.4844 23.0547 14.4922V23.1992C23.0547 24.2148 22.8125 24.9727 22.3281 25.4727C21.8516 25.9727 21.1445 26.2227 20.207 26.2227H8.78125ZM8.24219 12.6172V8.83203C8.24219 7.43359 8.52344 6.24609 9.08594 5.26953C9.65625 4.28516 10.4141 3.53516 11.3594 3.01953C12.3047 2.50391 13.3477 2.24609 14.4883 2.24609C15.6367 2.24609 16.6836 2.50391 17.6289 3.01953C18.5742 3.53516 19.3281 4.28516 19.8906 5.26953C20.4609 6.24609 20.7461 7.43359 20.7461 8.83203V12.6172H17.9688V8.67969C17.9688 7.89062 17.8125 7.21875 17.5 6.66406C17.1875 6.10156 16.7656 5.67188 16.2344 5.375C15.7109 5.07812 15.1289 4.92969 14.4883 4.92969C13.8477 4.92969 13.2656 5.07812 12.7422 5.375C12.2188 5.67188 11.8008 6.10156 11.4883 6.66406C11.1836 7.21875 11.0312 7.89062 11.0312 8.67969V12.6172H8.24219Z",fill:s})}),Yp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M7.70312 27.457C6.36719 27.457 5.34375 27.1055 4.63281 26.4023C3.92188 25.6992 3.56641 24.6797 3.56641 23.3438V12.0938C3.56641 10.7656 3.92188 9.75 4.63281 9.04688C5.34375 8.33594 6.36719 7.98047 7.70312 7.98047H10.8789V11.0039H8.03125C7.5625 11.0039 7.20312 11.125 6.95312 11.3672C6.71094 11.6016 6.58984 11.9688 6.58984 12.4688V22.9805C6.58984 23.4727 6.71094 23.8359 6.95312 24.0703C7.20312 24.3125 7.5625 24.4336 8.03125 24.4336H20.9453C21.4141 24.4336 21.7734 24.3125 22.0234 24.0703C22.2734 23.8359 22.3984 23.4727 22.3984 22.9805V12.4688C22.3984 11.9688 22.2734 11.6016 22.0234 11.3672C21.7734 11.125 21.4141 11.0039 20.9453 11.0039H18.1094V7.98047H21.2852C22.6211 7.98047 23.6445 8.33594 24.3555 9.04688C25.0664 9.75 25.4219 10.7656 25.4219 12.0938V23.3438C25.4219 24.6719 25.0664 25.6875 24.3555 26.3906C23.6445 27.1016 22.6211 27.457 21.2852 27.457H7.70312ZM14.4883 17.8359C14.1133 17.8359 13.793 17.7031 13.5273 17.4375C13.2695 17.1719 13.1406 16.8555 13.1406 16.4883V5.08594L13.2578 3.36328L12.6367 4.27734L11.2305 5.77734C10.9883 6.03516 10.6914 6.16406 10.3398 6.16406C10.0273 6.16406 9.75391 6.05859 9.51953 5.84766C9.28516 5.63672 9.16797 5.36719 9.16797 5.03906C9.16797 4.73438 9.28906 4.45703 9.53125 4.20703L13.4219 0.480469C13.6016 0.300781 13.7773 0.175781 13.9492 0.105469C14.1289 0.0351562 14.3086 0 14.4883 0C14.6758 0 14.8555 0.0351562 15.0273 0.105469C15.207 0.175781 15.3867 0.300781 15.5664 0.480469L19.457 4.20703C19.6992 4.45703 19.8203 4.73438 19.8203 5.03906C19.8203 5.36719 19.6992 5.63672 19.457 5.84766C19.2227 6.05859 18.9531 6.16406 18.6484 6.16406C18.2969 6.16406 18 6.03516 17.7578 5.77734L16.3398 4.27734L15.7305 3.36328L15.8477 5.08594V16.4883C15.8477 16.8555 15.7148 17.1719 15.4492 17.4375C15.1914 17.7031 14.8711 17.8359 14.4883 17.8359Z",fill:s})}),qp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M6.15625 27.6289C5.58594 27.6289 5.13281 27.4766 4.79688 27.1719C4.46094 26.875 4.27344 26.5039 4.23438 26.0586C4.19531 25.6133 4.33203 25.1797 4.64453 24.7578C4.80859 24.5391 4.99219 24.2734 5.19531 23.9609C5.40625 23.6484 5.60938 23.3281 5.80469 23C6.00781 22.6641 6.1875 22.3594 6.34375 22.0859C5.14062 21.4453 4.09766 20.6484 3.21484 19.6953C2.33203 18.7422 1.64844 17.6836 1.16406 16.5195C0.679688 15.3477 0.4375 14.1211 0.4375 12.8398C0.4375 11.2617 0.800781 9.78516 1.52734 8.41016C2.25391 7.02734 3.25781 5.81641 4.53906 4.77734C5.82812 3.73828 7.32031 2.92578 9.01562 2.33984C10.7188 1.75391 12.5469 1.46094 14.5 1.46094C16.4531 1.46094 18.2773 1.75391 19.9727 2.33984C21.6758 2.92578 23.1719 3.73828 24.4609 4.77734C25.75 5.81641 26.7539 7.02734 27.4727 8.41016C28.1992 9.78516 28.5625 11.2617 28.5625 12.8398C28.5625 14.1289 28.3242 15.3477 27.8477 16.4961C27.3711 17.6445 26.6953 18.6914 25.8203 19.6367C24.9453 20.5742 23.8984 21.3867 22.6797 22.0742C21.4688 22.7539 20.1211 23.2773 18.6367 23.6445C17.1523 24.0117 15.5625 24.1914 13.8672 24.1836C12.9922 24.8164 12.0664 25.3906 11.0898 25.9062C10.1133 26.4297 9.1875 26.8477 8.3125 27.1602C7.4375 27.4727 6.71875 27.6289 6.15625 27.6289ZM7.85547 24.5C8.18359 24.3594 8.61328 24.1289 9.14453 23.8086C9.68359 23.4961 10.2383 23.1484 10.8086 22.7656C11.3789 22.375 11.8906 22.0078 12.3438 21.6641C12.5938 21.4609 12.8242 21.3203 13.0352 21.2422C13.2461 21.1641 13.4805 21.125 13.7383 21.125C13.8945 21.125 14.0352 21.1289 14.1602 21.1367C14.293 21.1367 14.4062 21.1367 14.5 21.1367C16.0234 21.1367 17.4492 20.9219 18.7773 20.4922C20.1055 20.0547 21.2695 19.457 22.2695 18.6992C23.2773 17.9414 24.0625 17.0625 24.625 16.0625C25.1953 15.0547 25.4805 13.9805 25.4805 12.8398C25.4805 11.6914 25.1953 10.6172 24.625 9.61719C24.0625 8.61719 23.2773 7.73828 22.2695 6.98047C21.2695 6.21484 20.1055 5.61719 18.7773 5.1875C17.4492 4.75 16.0234 4.53125 14.5 4.53125C12.9766 4.53125 11.5508 4.75 10.2227 5.1875C8.89453 5.61719 7.72656 6.21484 6.71875 6.98047C5.71875 7.73828 4.93359 8.61719 4.36328 9.61719C3.80078 10.6172 3.51953 11.6914 3.51953 12.8398C3.51953 13.8164 3.73438 14.75 4.16406 15.6406C4.59375 16.5234 5.21094 17.3359 6.01562 18.0781C6.82812 18.8125 7.80469 19.4492 8.94531 19.9883C9.32031 20.1758 9.55469 20.418 9.64844 20.7148C9.75 21.0039 9.70312 21.332 9.50781 21.6992C9.26562 22.1367 8.96484 22.5977 8.60547 23.082C8.24609 23.5664 7.94141 23.9648 7.69141 24.2773C7.61328 24.3789 7.58984 24.4492 7.62109 24.4883C7.66016 24.5352 7.73828 24.5391 7.85547 24.5Z",fill:s})}),Jp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M2.13672 17.457C1.19141 16.5117 0.714844 15.539 0.707031 14.539C0.707031 13.539 1.17578 12.5664 2.11328 11.6211L11.5938 2.15232C12.5312 1.20701 13.5 0.738255 14.5 0.746068C15.5078 0.75388 16.4844 1.23044 17.4297 2.17576L26.8633 11.6093C27.8086 12.5547 28.2812 13.5312 28.2812 14.539C28.2891 15.539 27.8203 16.5078 26.875 17.4453L17.418 26.914C16.4727 27.8593 15.5 28.3281 14.5 28.3203C13.5 28.3203 12.5234 27.8437 11.5703 26.8906L2.13672 17.457ZM13.2109 20.4101C13.4688 20.4101 13.7031 20.3515 13.9141 20.2343C14.1328 20.1093 14.3203 19.9336 14.4766 19.707L19.9258 11.3867C20.0195 11.2383 20.0938 11.0859 20.1484 10.9297C20.2109 10.7734 20.2422 10.6211 20.2422 10.4726C20.2422 10.1133 20.1055 9.81638 19.832 9.58201C19.5664 9.34763 19.2578 9.23044 18.9062 9.23044C18.4453 9.23044 18.0586 9.48044 17.7461 9.98044L13.1875 17.2343L11.1367 14.7265C10.9805 14.5312 10.8164 14.3906 10.6445 14.3047C10.4805 14.2187 10.2891 14.1758 10.0703 14.1758C9.71875 14.1758 9.41406 14.3047 9.15625 14.5625C8.89844 14.8125 8.76953 15.1172 8.76953 15.4765C8.76953 15.6484 8.80078 15.8125 8.86328 15.9687C8.92578 16.125 9.02344 16.2851 9.15625 16.4492L11.8984 19.7304C12.0859 19.957 12.2852 20.1289 12.4961 20.2461C12.707 20.3554 12.9453 20.4101 13.2109 20.4101Z",fill:s})}),Io=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M14.4883 26.9141C12.793 26.9141 11.1992 26.5898 9.70703 25.9414C8.21484 25.3008 6.89844 24.4102 5.75781 23.2695C4.61719 22.1367 3.72266 20.8242 3.07422 19.332C2.43359 17.8398 2.11328 16.2422 2.11328 14.5391C2.11328 12.8438 2.43359 11.25 3.07422 9.75781C3.72266 8.26562 4.61328 6.94922 5.74609 5.80859C6.88672 4.66797 8.20312 3.77734 9.69531 3.13672C11.1953 2.48828 12.793 2.16406 14.4883 2.16406C16.1836 2.16406 17.7773 2.48828 19.2695 3.13672C20.7695 3.77734 22.0859 4.66797 23.2188 5.80859C24.3594 6.94922 25.2539 8.26562 25.9023 9.75781C26.5508 11.25 26.875 12.8438 26.875 14.5391C26.875 16.2422 26.5508 17.8398 25.9023 19.332C25.2539 20.8242 24.3594 22.1367 23.2188 23.2695C22.0859 24.4102 20.7734 25.3008 19.2812 25.9414C17.7891 26.5898 16.1914 26.9141 14.4883 26.9141ZM14.4883 23.832C15.7773 23.832 16.9844 23.5898 18.1094 23.1055C19.2344 22.6289 20.2227 21.9688 21.0742 21.125C21.9258 20.2734 22.5898 19.2852 23.0664 18.1602C23.5508 17.0352 23.793 15.8281 23.793 14.5391C23.793 13.25 23.5508 12.0469 23.0664 10.9297C22.582 9.80469 21.9141 8.81641 21.0625 7.96484C20.2188 7.11328 19.2344 6.44922 18.1094 5.97266C16.9844 5.48828 15.7773 5.24609 14.4883 5.24609C13.1992 5.24609 11.9922 5.48828 10.8672 5.97266C9.75 6.44922 8.76562 7.11328 7.91406 7.96484C7.0625 8.81641 6.39844 9.80469 5.92188 10.9297C5.44531 12.0469 5.20703 13.25 5.20703 14.5391C5.20703 15.8281 5.44531 17.0352 5.92188 18.1602C6.39844 19.2852 7.0625 20.2734 7.91406 21.125C8.76562 21.9688 9.75391 22.6289 10.8789 23.1055C12.0039 23.5898 13.207 23.832 14.4883 23.832ZM14.1953 16.7188C13.25 16.7188 12.7773 16.3359 12.7773 15.5703C12.7773 15.5547 12.7773 15.543 12.7773 15.5352C12.7773 15.5195 12.7773 15.5039 12.7773 15.4883C12.7773 15.0273 12.9062 14.6406 13.1641 14.3281C13.4219 14.0156 13.7578 13.7148 14.1719 13.4258C14.6406 13.1055 14.9961 12.8398 15.2383 12.6289C15.4805 12.4102 15.6016 12.1367 15.6016 11.8086C15.6016 11.4961 15.4805 11.2344 15.2383 11.0234C14.9961 10.8125 14.6875 10.707 14.3125 10.707C14.125 10.707 13.9492 10.7383 13.7852 10.8008C13.6211 10.8555 13.4648 10.9414 13.3164 11.0586C13.1758 11.1758 13.043 11.3281 12.918 11.5156L12.7891 11.7031C12.6562 11.875 12.5 12.0039 12.3203 12.0898C12.1406 12.1758 11.9336 12.2188 11.6992 12.2188C11.3789 12.2188 11.1094 12.1172 10.8906 11.9141C10.6797 11.7031 10.5742 11.4375 10.5742 11.1172C10.5742 11 10.5859 10.8867 10.6094 10.7773C10.6328 10.668 10.668 10.5586 10.7148 10.4492C10.9336 9.88672 11.3789 9.41797 12.0508 9.04297C12.7305 8.66016 13.5703 8.46875 14.5703 8.46875C15.3203 8.46875 15.9961 8.59766 16.5977 8.85547C17.207 9.11328 17.6914 9.48047 18.0508 9.95703C18.418 10.4336 18.6016 10.9961 18.6016 11.6445C18.6016 12.293 18.4453 12.8125 18.1328 13.2031C17.8203 13.5938 17.3672 13.9805 16.7734 14.3633C16.4375 14.5742 16.1602 14.7852 15.9414 14.9961C15.7227 15.1992 15.5898 15.4336 15.543 15.6992C15.543 15.7148 15.5391 15.7383 15.5312 15.7695C15.5312 15.793 15.5273 15.8125 15.5195 15.8281C15.4805 16.0859 15.3398 16.3008 15.0977 16.4727C14.8633 16.6367 14.5625 16.7188 14.1953 16.7188ZM14.1836 20.4805C13.7461 20.4805 13.375 20.3516 13.0703 20.0938C12.7734 19.8281 12.625 19.4883 12.625 19.0742C12.625 18.6523 12.7734 18.3125 13.0703 18.0547C13.375 17.7969 13.7461 17.668 14.1836 17.668C14.6289 17.668 15 17.7969 15.2969 18.0547C15.5938 18.3125 15.7422 18.6523 15.7422 19.0742C15.7422 19.4961 15.5938 19.8359 15.2969 20.0938C15 20.3516 14.6289 20.4805 14.1836 20.4805Z",fill:s})}),Xp=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M8.03125 13.0039C7.79688 13.0039 7.62891 12.9375 7.52734 12.8047C7.43359 12.6719 7.40625 12.5273 7.44531 12.3711C7.48438 12.207 7.58984 12.082 7.76172 11.9961L15.3906 8.375C15.6016 8.27344 15.7891 8.25781 15.9531 8.32812C16.125 8.39062 16.2422 8.50781 16.3047 8.67969C16.375 8.84375 16.3594 9.03125 16.2578 9.24219L12.6719 16.8828C12.5938 17.0547 12.4727 17.1602 12.3086 17.1992C12.1523 17.2383 12.0078 17.2109 11.875 17.1172C11.7422 17.0156 11.6758 16.8438 11.6758 16.6016L11.6641 13.2617C11.6641 13.0898 11.582 13.0039 11.418 13.0039H8.03125ZM3.05078 12.3359C3.05078 11.0469 3.29297 9.83984 3.77734 8.71484C4.26172 7.58203 4.93359 6.58594 5.79297 5.72656C6.65234 4.86719 7.64453 4.19531 8.76953 3.71094C9.90234 3.22656 11.1133 2.98438 12.4023 2.98438C13.6914 2.98438 14.8984 3.22656 16.0234 3.71094C17.1562 4.19531 18.1523 4.86719 19.0117 5.72656C19.8711 6.58594 20.543 7.58203 21.0273 8.71484C21.5117 9.83984 21.7539 11.0469 21.7539 12.3359C21.7539 13.4062 21.582 14.4219 21.2383 15.3828C20.9023 16.3438 20.4336 17.2148 19.832 17.9961L25.5625 23.7617C25.6875 23.8867 25.7812 24.0312 25.8438 24.1953C25.9141 24.3594 25.9492 24.5352 25.9492 24.7227C25.9492 24.9805 25.8906 25.2148 25.7734 25.4258C25.6641 25.6367 25.5078 25.8008 25.3047 25.918C25.1016 26.043 24.8672 26.1055 24.6016 26.1055C24.4141 26.1055 24.2344 26.0703 24.0625 26C23.8984 25.9375 23.7461 25.8398 23.6055 25.707L17.8398 19.9297C17.0742 20.4766 16.2305 20.9062 15.3086 21.2188C14.3867 21.5312 13.418 21.6875 12.4023 21.6875C11.1133 21.6875 9.90234 21.4453 8.76953 20.9609C7.64453 20.4766 6.65234 19.8047 5.79297 18.9453C4.93359 18.0859 4.26172 17.0938 3.77734 15.9688C3.29297 14.8359 3.05078 13.625 3.05078 12.3359ZM5.05469 12.3359C5.05469 13.3516 5.24219 14.3047 5.61719 15.1953C6 16.0781 6.52734 16.8555 7.19922 17.5273C7.87891 18.1992 8.66016 18.7266 9.54297 19.1094C10.4336 19.4922 11.3867 19.6836 12.4023 19.6836C13.418 19.6836 14.3672 19.4922 15.25 19.1094C16.1406 18.7266 16.9219 18.1992 17.5938 17.5273C18.2656 16.8555 18.793 16.0781 19.1758 15.1953C19.5586 14.3047 19.75 13.3516 19.75 12.3359C19.75 11.3203 19.5586 10.3711 19.1758 9.48828C18.793 8.59766 18.2656 7.81641 17.5938 7.14453C16.9219 6.46484 16.1406 5.9375 15.25 5.5625C14.3672 5.17969 13.418 4.98828 12.4023 4.98828C11.3867 4.98828 10.4336 5.17969 9.54297 5.5625C8.66016 5.9375 7.87891 6.46484 7.19922 7.14453C6.52734 7.81641 6 8.59766 5.61719 9.48828C5.24219 10.3711 5.05469 11.3203 5.05469 12.3359Z",fill:s})}),e0=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M10.9375 26.1289C10.4375 26.1289 10.0156 26.0781 9.67188 25.9766C9.32812 25.875 9.02344 25.7227 8.75781 25.5195C8.49219 25.3242 8.23047 25.0898 7.97266 24.8164L3.42578 19.8008C3.16797 19.5195 2.96875 19.2578 2.82812 19.0156C2.6875 18.7656 2.58984 18.5039 2.53516 18.2305C2.48047 17.9492 2.45312 17.6133 2.45312 17.2227V11.8672C2.45312 11.4766 2.48047 11.1406 2.53516 10.8594C2.58984 10.5781 2.6875 10.3164 2.82812 10.0742C2.96875 9.83203 3.16797 9.57031 3.42578 9.28906L7.97266 4.27344C8.23047 3.99219 8.49219 3.75391 8.75781 3.55859C9.02344 3.36328 9.32812 3.21484 9.67188 3.11328C10.0156 3.00391 10.4375 2.94922 10.9375 2.94922H18.0508C18.543 2.94922 18.9609 3.00391 19.3047 3.11328C19.6562 3.21484 19.9648 3.36328 20.2305 3.55859C20.4961 3.75391 20.7578 3.99219 21.0156 4.27344L25.5625 9.28906C25.8203 9.57031 26.0195 9.83203 26.1602 10.0742C26.3008 10.3164 26.3984 10.5781 26.4531 10.8594C26.5078 11.1406 26.5352 11.4766 26.5352 11.8672V17.2227C26.5352 17.6133 26.5078 17.9492 26.4531 18.2305C26.3984 18.5039 26.3008 18.7656 26.1602 19.0156C26.0195 19.2578 25.8203 19.5195 25.5625 19.8008L21.0156 24.8164C20.7578 25.0898 20.4961 25.3242 20.2305 25.5195C19.9648 25.7227 19.6562 25.875 19.3047 25.9766C18.9609 26.0781 18.543 26.1289 18.0508 26.1289H10.9375ZM14.5 16.7188C15.1094 16.7188 15.418 16.3984 15.4258 15.7578L15.6016 9.38281C15.6094 9.07812 15.5039 8.82422 15.2852 8.62109C15.0742 8.41016 14.8086 8.30469 14.4883 8.30469C14.1602 8.30469 13.8906 8.40625 13.6797 8.60938C13.4766 8.8125 13.3789 9.06641 13.3867 9.37109L13.5391 15.7578C13.5547 16.3984 13.875 16.7188 14.5 16.7188ZM14.5 20.6445C14.8516 20.6445 15.1562 20.5234 15.4141 20.2812C15.6797 20.0391 15.8125 19.7422 15.8125 19.3906C15.8125 19.0391 15.6797 18.7422 15.4141 18.5C15.1562 18.25 14.8516 18.125 14.5 18.125C14.1406 18.125 13.832 18.25 13.5742 18.5C13.3164 18.75 13.1875 19.0469 13.1875 19.3906C13.1875 19.7422 13.3164 20.0391 13.5742 20.2812C13.8398 20.5234 14.1484 20.6445 14.5 20.6445Z",fill:s})}),t0=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M23.1562 23.7734H7.01953C6.01953 23.7734 5.09375 23.6055 4.24219 23.2695C3.39062 22.9336 2.64453 22.4766 2.00391 21.8984C1.37109 21.3125 0.878906 20.6367 0.527344 19.8711C0.175781 19.1055 0 18.293 0 17.4336C0 16.4805 0.171875 15.6016 0.515625 14.7969C0.867188 13.9922 1.36328 13.3242 2.00391 12.793C2.65234 12.2617 3.41797 11.9258 4.30078 11.7852C4.31641 10.9648 4.50391 10.2266 4.86328 9.57031C5.22266 8.90625 5.69531 8.35938 6.28125 7.92969C6.86719 7.49219 7.51562 7.20312 8.22656 7.0625C8.94531 6.91406 9.66406 6.94531 10.3828 7.15625C10.8516 6.46875 11.4141 5.84375 12.0703 5.28125C12.7344 4.71094 13.4922 4.25781 14.3438 3.92188C15.2031 3.57812 16.1641 3.40625 17.2266 3.40625C18.4297 3.40625 19.5469 3.62891 20.5781 4.07422C21.6172 4.51172 22.5234 5.13672 23.2969 5.94922C24.0781 6.75391 24.6836 7.70703 25.1133 8.80859C25.543 9.90234 25.7578 11.1016 25.7578 12.4062C26.5234 12.7266 27.1836 13.168 27.7383 13.7305C28.293 14.2852 28.7188 14.9258 29.0156 15.6523C29.3125 16.3711 29.4609 17.1406 29.4609 17.9609C29.4609 18.7656 29.3008 19.5195 28.9805 20.2227C28.6602 20.9258 28.2109 21.543 27.6328 22.0742C27.0625 22.6055 26.3945 23.0195 25.6289 23.3164C24.8633 23.6211 24.0391 23.7734 23.1562 23.7734ZM21.3633 14.9492C21.3633 14.2852 21.2031 13.6797 20.8828 13.1328C20.5625 12.5859 20.1289 12.1523 19.582 11.832C19.043 11.5117 18.4414 11.3516 17.7773 11.3516C17.0195 11.3516 16.332 11.5625 15.7148 11.9844C15.1055 12.3984 14.668 12.957 14.4023 13.6602H8.83594C8.70312 13.6602 8.58203 13.7109 8.47266 13.8125L7.53516 14.75C7.48047 14.8047 7.45312 14.8711 7.45312 14.9492C7.45312 15.0195 7.48047 15.0859 7.53516 15.1484L9.30469 16.9297C9.36719 17 9.4375 17.0352 9.51562 17.0352C9.59375 17.0352 9.66016 17 9.71484 16.9297L10.8164 15.8164L12.3398 17.3516C12.3867 17.4141 12.4453 17.4414 12.5156 17.4336C12.5938 17.4258 12.668 17.3906 12.7383 17.3281L14.25 15.8281C14.5938 16.7031 15.0742 17.375 15.6914 17.8438C16.3086 18.3047 17.0039 18.5352 17.7773 18.5352C18.4336 18.5352 19.0352 18.375 19.582 18.0547C20.1289 17.7344 20.5625 17.3047 20.8828 16.7656C21.2031 16.2188 21.3633 15.6133 21.3633 14.9492ZM19.6406 14.9375C19.6406 15.2422 19.5312 15.5039 19.3125 15.7227C19.0938 15.9336 18.8359 16.0391 18.5391 16.0391C18.2188 16.0391 17.9531 15.9336 17.7422 15.7227C17.5312 15.5039 17.4258 15.2422 17.4258 14.9375C17.4258 14.6328 17.5312 14.375 17.7422 14.1641C17.9531 13.9453 18.2188 13.8359 18.5391 13.8359C18.8359 13.8359 19.0938 13.9414 19.3125 14.1523C19.5312 14.3633 19.6406 14.625 19.6406 14.9375Z",fill:s})}),n0=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M8.93359 16.332C8.61328 16.332 8.34375 16.2227 8.125 16.0039C7.90625 15.7852 7.79688 15.5156 7.79688 15.1953C7.79688 14.875 7.90625 14.6055 8.125 14.3867C8.34375 14.168 8.61328 14.0586 8.93359 14.0586H13.3516V7.90625C13.3516 7.59375 13.4609 7.32812 13.6797 7.10938C13.8984 6.89062 14.168 6.78125 14.4883 6.78125C14.8086 6.78125 15.0781 6.89062 15.2969 7.10938C15.5156 7.32812 15.625 7.59375 15.625 7.90625V15.1953C15.625 15.5156 15.5156 15.7852 15.2969 16.0039C15.0781 16.2227 14.8086 16.332 14.4883 16.332H8.93359ZM14.4883 26.9141C12.793 26.9141 11.1992 26.5898 9.70703 25.9414C8.21484 25.3008 6.89844 24.4102 5.75781 23.2695C4.61719 22.1367 3.72266 20.8242 3.07422 19.332C2.43359 17.8398 2.11328 16.2422 2.11328 14.5391C2.11328 12.8438 2.43359 11.25 3.07422 9.75781C3.72266 8.26562 4.61328 6.94922 5.74609 5.80859C6.88672 4.66797 8.20312 3.77734 9.69531 3.13672C11.1953 2.48828 12.793 2.16406 14.4883 2.16406C16.1836 2.16406 17.7773 2.48828 19.2695 3.13672C20.7695 3.77734 22.0859 4.66797 23.2188 5.80859C24.3594 6.94922 25.2539 8.26562 25.9023 9.75781C26.5508 11.25 26.875 12.8438 26.875 14.5391C26.875 16.2422 26.5508 17.8398 25.9023 19.332C25.2539 20.8242 24.3594 22.1367 23.2188 23.2695C22.0859 24.4102 20.7734 25.3008 19.2812 25.9414C17.7891 26.5898 16.1914 26.9141 14.4883 26.9141ZM14.4883 23.832C15.7773 23.832 16.9844 23.5898 18.1094 23.1055C19.2344 22.6289 20.2227 21.9688 21.0742 21.125C21.9258 20.2734 22.5898 19.2852 23.0664 18.1602C23.5508 17.0352 23.793 15.8281 23.793 14.5391C23.793 13.25 23.5508 12.0469 23.0664 10.9297C22.582 9.80469 21.9141 8.81641 21.0625 7.96484C20.2188 7.11328 19.2344 6.44922 18.1094 5.97266C16.9844 5.48828 15.7773 5.24609 14.4883 5.24609C13.1992 5.24609 11.9922 5.48828 10.8672 5.97266C9.75 6.44922 8.76562 7.11328 7.91406 7.96484C7.0625 8.81641 6.39844 9.80469 5.92188 10.9297C5.44531 12.0469 5.20703 13.25 5.20703 14.5391C5.20703 15.8281 5.44531 17.0352 5.92188 18.1602C6.39844 19.2852 7.0625 20.2734 7.91406 21.125C8.76562 21.9688 9.75391 22.6289 10.8789 23.1055C12.0039 23.5898 13.207 23.832 14.4883 23.832Z",fill:s})}),r0=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M3.27344 6.5C2.89844 6.5 2.57812 6.36328 2.3125 6.08984C2.05469 5.80859 1.92578 5.48828 1.92578 5.12891C1.92578 4.75391 2.05469 4.43359 2.3125 4.16797C2.57812 3.89453 2.89844 3.75781 3.27344 3.75781H16.4922C16.875 3.75781 17.1953 3.89453 17.4531 4.16797C17.7109 4.43359 17.8398 4.75391 17.8398 5.12891C17.8398 5.49609 17.7109 5.81641 17.4531 6.08984C17.1953 6.36328 16.875 6.5 16.4922 6.5H3.27344ZM21.0859 6.5C20.7188 6.5 20.4023 6.36328 20.1367 6.08984C19.8789 5.80859 19.75 5.48828 19.75 5.12891C19.75 4.75391 19.8789 4.43359 20.1367 4.16797C20.3945 3.89453 20.7109 3.75781 21.0859 3.75781H25.7148C26.0977 3.75781 26.418 3.89453 26.6758 4.16797C26.9414 4.43359 27.0742 4.75391 27.0742 5.12891C27.0742 5.49609 26.9414 5.81641 26.6758 6.08984C26.418 6.36328 26.0977 6.5 25.7148 6.5H21.0859ZM3.27344 12.6523C2.90625 12.6523 2.58984 12.5117 2.32422 12.2305C2.05859 11.9492 1.92578 11.6289 1.92578 11.2695C1.92578 10.8945 2.05469 10.5742 2.3125 10.3086C2.57812 10.0352 2.89844 9.89844 3.27344 9.89844H5.07812C5.46094 9.89844 5.78125 10.0312 6.03906 10.2969C6.29688 10.5625 6.42578 10.8867 6.42578 11.2695C6.42578 11.6367 6.29297 11.9609 6.02734 12.2422C5.76953 12.5156 5.45312 12.6523 5.07812 12.6523H3.27344ZM9.67188 12.6523C9.29688 12.6523 8.97656 12.5117 8.71094 12.2305C8.45312 11.9492 8.32422 11.6289 8.32422 11.2695C8.32422 10.8945 8.45312 10.5742 8.71094 10.3086C8.97656 10.0352 9.29688 9.89844 9.67188 9.89844H15.4023C15.7852 9.89844 16.1055 10.0312 16.3633 10.2969C16.6211 10.5625 16.75 10.8867 16.75 11.2695C16.75 11.6367 16.6172 11.9609 16.3516 12.2422C16.0938 12.5156 15.7773 12.6523 15.4023 12.6523H9.67188ZM19.9961 12.6523C19.6211 12.6523 19.3008 12.5117 19.0352 12.2305C18.7773 11.9492 18.6484 11.6289 18.6484 11.2695C18.6484 10.8945 18.7773 10.5742 19.0352 10.3086C19.3008 10.0352 19.6211 9.89844 19.9961 9.89844H25.7266C26.1094 9.89844 26.4297 10.0312 26.6875 10.2969C26.9453 10.5625 27.0742 10.8867 27.0742 11.2695C27.0742 11.6367 26.9414 11.9609 26.6758 12.2422C26.418 12.5156 26.1016 12.6523 25.7266 12.6523H19.9961ZM3.27344 18.8047C2.89844 18.8047 2.57812 18.668 2.3125 18.3945C2.05469 18.1133 1.92578 17.7891 1.92578 17.4219C1.92578 17.0391 2.05469 16.7148 2.3125 16.4492C2.57812 16.1836 2.89844 16.0508 3.27344 16.0508H7.91406C8.28906 16.0508 8.60547 16.1875 8.86328 16.4609C9.12109 16.7266 9.25 17.0469 9.25 17.4219C9.25 17.7812 9.11719 18.1016 8.85156 18.3828C8.59375 18.6641 8.28125 18.8047 7.91406 18.8047H3.27344ZM12.5078 18.8047C12.125 18.8047 11.8008 18.668 11.5352 18.3945C11.2773 18.1133 11.1484 17.7891 11.1484 17.4219C11.1484 17.0391 11.2773 16.7148 11.5352 16.4492C11.8008 16.1836 12.125 16.0508 12.5078 16.0508H25.7266C26.1016 16.0508 26.418 16.1875 26.6758 16.4609C26.9414 16.7266 27.0742 17.0469 27.0742 17.4219C27.0742 17.7812 26.9414 18.1016 26.6758 18.3828C26.418 18.6641 26.1016 18.8047 25.7266 18.8047H12.5078ZM3.27344 24.9336C2.89844 24.9336 2.57812 24.7969 2.3125 24.5234C2.05469 24.25 1.92578 23.9297 1.92578 23.5625C1.92578 23.1875 2.05469 22.8633 2.3125 22.5898C2.57812 22.3164 2.89844 22.1797 3.27344 22.1797H15.2734C15.6484 22.1797 15.9648 22.3164 16.2227 22.5898C16.4883 22.8555 16.6211 23.1797 16.6211 23.5625C16.6211 23.9297 16.4883 24.25 16.2227 24.5234C15.9648 24.7969 15.6484 24.9336 15.2734 24.9336H3.27344Z",fill:s})}),i0=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M14.5 26C11.8 26 9.5 25.1 7.6 23.3C5.7 21.5 4.75 19.3 4.75 16.75C4.75 14.2 5.7 12 7.6 10.2C9.5 8.4 11.8 7.5 14.5 7.5C17.2 7.5 19.5 8.4 21.4 10.2C23.3 12 24.25 14.2 24.25 16.75C24.25 19.3 23.3 21.5 21.4 23.3C19.5 25.1 17.2 26 14.5 26ZM14.5 21C14.8 21 15.05 20.9 15.25 20.7C15.45 20.5 15.55 20.25 15.55 19.95V16.5C15.55 16.2 15.45 15.95 15.25 15.75C15.05 15.55 14.8 15.45 14.5 15.45C14.2 15.45 13.95 15.55 13.75 15.75C13.55 15.95 13.45 16.2 13.45 16.5V19.95C13.45 20.25 13.55 20.5 13.75 20.7C13.95 20.9 14.2 21 14.5 21ZM14.5 13.5C14.8 13.5 15.05 13.4 15.25 13.2C15.45 13 15.55 12.75 15.55 12.45C15.55 12.15 15.45 11.9 15.25 11.7C15.05 11.5 14.8 11.4 14.5 11.4C14.2 11.4 13.95 11.5 13.75 11.7C13.55 11.9 13.45 12.15 13.45 12.45C13.45 12.75 13.55 13 13.75 13.2C13.95 13.4 14.2 13.5 14.5 13.5Z",fill:s})}),Ys=({size:i=29,color:s="#000000"})=>a.jsx(Fe,{size:i,children:a.jsx("path",{d:"M13.2 19.5L20.5 12.2C20.7 12 20.95 11.9 21.25 11.9C21.55 11.9 21.8 12 22 12.2C22.2 12.4 22.3 12.65 22.3 12.95C22.3 13.25 22.2 13.5 22 13.7L14.1 21.6C13.9 21.8 13.65 21.9 13.35 21.9C13.05 21.9 12.8 21.8 12.6 21.6L7.7 16.7C7.5 16.5 7.4 16.25 7.4 15.95C7.4 15.65 7.5 15.4 7.7 15.2C7.9 15 8.15 14.9 8.45 14.9C8.75 14.9 9 15 9.2 15.2L13.2 19.5ZM14.5 26C11.8 26 9.5 25.1 7.6 23.3C5.7 21.5 4.75 19.3 4.75 16.75C4.75 14.2 5.7 12 7.6 10.2C9.5 8.4 11.8 7.5 14.5 7.5C17.2 7.5 19.5 8.4 21.4 10.2C23.3 12 24.25 14.2 24.25 16.75C24.25 19.3 23.3 21.5 21.4 23.3C19.5 25.1 17.2 26 14.5 26Z",fill:s})}),o0=({variant:i,closeButton:s})=>i==="escape-title-single-action"&&s?a.jsx(et,{...s,variant:"secondary-icon"}):null,l0=({title:i,shouldTruncate:s})=>{const u=s?{...yr.title,...yr.titleFlexible}:yr.title;return a.jsx("span",{style:u,title:i,children:i})},s0=({primaryButton:i,secondaryButton:s})=>a.jsxs("div",{style:yr.actions,children:[s&&a.jsx(et,{...s}),a.jsx(et,{...i})]}),Fs=i=>{const{variant:s,title:u,primaryButton:d,containerStyle:f}=i,h="secondaryButton"in i?i.secondaryButton:void 0,v="closeButton"in i?i.closeButton:void 0,L=!!(d||h||s==="escape-title-single-action"&&v);return a.jsx("div",{style:{...yr.container,...f},children:a.jsxs("div",{style:yr.content,children:[a.jsx(o0,{variant:s,closeButton:v}),a.jsx(l0,{title:u,shouldTruncate:L}),a.jsx(s0,{primaryButton:d,secondaryButton:h})]})})},yr={container:{paddingTop:8,paddingBottom:16,paddingLeft:20,paddingRight:20},content:{display:"flex",flexDirection:"row",alignItems:"center",gap:10,width:"100%"},title:{fontSize:28,fontFamily:"Advercase",fontWeight:"400",color:m.black,letterSpacing:1},titleFlexible:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},actions:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"flex-end",gap:10,flexShrink:0,minHeight:46}},Po=i=>{const{variant:s="Primary",escapeIcon:u,infoIcon:d,onEscape:f,onPressInfo:h}=i,v="label"in i?i.label:void 0,k=s==="Reverse",w=s==="Simple_Dialogue",L=k?m.white:m.black,[R,E]=T.useState(!1),[_,O]=T.useState(!1);return a.jsx("div",{style:Zt.container,children:a.jsxs("div",{style:Zt.content,children:[w?a.jsx(et,{variant:"secondary-icon",icon:u,onPress:f}):a.jsx("button",{type:"button",style:{...Zt.iconButton,...R?Zt.iconButtonPressed:{}},onClick:f,onMouseDown:()=>E(!0),onMouseUp:()=>E(!1),onMouseLeave:()=>E(!1),children:u({size:29,color:L})}),w?a.jsx("div",{style:Zt.labelContainer}):a.jsx("div",{style:Zt.labelContainer,children:a.jsx("span",{style:{...Zt.label,color:L},children:v==null?void 0:v.toUpperCase()})}),!w&&d?a.jsx("button",{type:"button",style:{...Zt.iconButton,..._?Zt.iconButtonPressed:{}},onClick:h,onMouseDown:()=>O(!0),onMouseUp:()=>O(!1),onMouseLeave:()=>O(!1),children:d({size:29,color:k?m.white:m.blue600})}):a.jsx("div",{style:Zt.iconButton})]})})},Zt={container:{display:"flex",paddingTop:10,paddingBottom:10,paddingLeft:20,paddingRight:20,width:"100%"},content:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:10,width:"100%"},iconButton:{display:"flex",width:46,height:46,alignItems:"center",justifyContent:"center",borderRadius:60,background:"none",border:"none",cursor:"pointer",padding:0},iconButtonPressed:{opacity:.75,transform:"scale(0.993)"},labelContainer:{display:"flex",flex:1,alignItems:"center",justifyContent:"center",minWidth:0,paddingLeft:10,paddingRight:10},label:{fontSize:pe.base,fontFamily:V.dinOT,fontWeight:Z.medium,textAlign:"center",letterSpacing:.6,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}},K1=({size:i=68,color:s=m.black,accentColor:u=m.selfEmerald,backgroundColor:d=m.white,withoutBackground:f=!1})=>f?a.jsxs("svg",{width:i,height:i,viewBox:"0 0 26 26",fill:"none",preserveAspectRatio:"xMidYMid meet",children:[a.jsxs("g",{clipPath:"url(#clip0_9441_13613)",children:[a.jsx("path",{d:"M12.9964 16.0225H13C14.6692 16.0225 16.0225 14.6692 16.0225 13V12.9964C16.0225 11.3271 14.6692 9.97385 13 9.97385H12.9964C11.3271 9.97385 9.97385 11.3271 9.97385 12.9964V13C9.97385 14.6692 11.3271 16.0225 12.9964 16.0225Z",fill:u}),a.jsx("path",{d:"M18.9294 15.7986C18.9294 17.5933 17.4742 19.0486 15.6794 19.0486H9.40333L2.45194 26H19.7817L26 19.7817V9.55139H18.9294V15.8022V15.7986Z",fill:s}),a.jsx("path",{d:"M7.07035 16.4736V10.4395C7.07035 8.64474 8.52563 7.18947 10.3204 7.18947H16.3545L23.5479 -0.0038681H6.21813L-0.000204086 6.21447V16.47H7.07035V16.4736Z",fill:s})]}),a.jsx("defs",{children:a.jsx("clipPath",{id:"clip0_9441_13613",children:a.jsx("rect",{width:i,height:i,fill:"white",transform:"matrix(-1 0 0 -1 26 26)"})})})]}):a.jsxs("svg",{width:i,height:i,viewBox:"0 0 68 68",fill:"none",preserveAspectRatio:"xMidYMid meet",children:[a.jsx("rect",{x:"0.5",y:"0.5",width:"67",height:"67",rx:"11.5",fill:d}),a.jsx("rect",{x:"0.5",y:"0.5",width:"67",height:"67",rx:"11.5",stroke:d}),a.jsx("path",{d:"M26.8881 30.4342C26.8881 28.1484 28.7415 26.2949 31.0274 26.2949H39.0208L47.8743 17.4414H25.8027L17.8828 25.3612V38.3908H26.8881V30.4296V30.4342Z",fill:s}),a.jsx("path",{d:"M41.994 29.5781V37.2634C41.994 39.5492 40.1405 41.4027 37.8547 41.4027H30.1694L21.0078 50.5643H43.0794L50.9993 42.6445V29.5827H41.994V29.5781Z",fill:s}),a.jsx("path",{d:"M34.0024 30H33.9976C31.7898 30 30 31.7898 30 33.9976V34.0024C30 36.2102 31.7898 38 33.9976 38H34.0024C36.2102 38 38 36.2102 38 34.0024V33.9976C38 31.7898 36.2102 30 34.0024 30Z",fill:u})]}),w1=i=>{const[s,u]=T.useState(!1),d=()=>{switch(i.variant){case"menu-item":return a.jsxs("div",{style:fe.iconContainer,children:[a.jsx("div",{style:fe.iconWrapper,children:i.icon}),a.jsxs("div",{style:fe.textContainer,children:[a.jsx("span",{style:fe.label,children:i.label}),a.jsx("span",{style:fe.description,children:i.description})]}),a.jsx("div",{style:fe.rightIconWrapper,children:a.jsx(x1,{size:16,color:m.black})})]});case"points":return a.jsxs("div",{style:fe.iconContainer,children:[a.jsx("div",{style:fe.iconWrapper,children:i.icon}),a.jsxs("div",{style:fe.textContainer,children:[a.jsx("span",{style:fe.label,children:i.label}),a.jsx("span",{style:fe.description,children:i.description})]}),a.jsx("div",{style:fe.pointsContainer,children:a.jsx("span",{style:fe.pointsText,children:i.pointsChange})})]});case"read-only":return a.jsxs("div",{style:fe.readOnlyContainer,children:[a.jsx("span",{style:fe.readOnlyLabel,children:i.label}),a.jsx("span",{style:fe.readOnlyValue,children:i.value})]});case"proof-history":return a.jsxs("div",{style:fe.iconContainer,children:[i.icon&&a.jsx("div",{style:fe.proofHistoryIconWrapper,children:i.icon}),a.jsxs("div",{style:fe.textContainer,children:[a.jsx("span",{style:fe.label,children:i.label}),a.jsx("span",{style:fe.description,children:i.description})]}),a.jsx("div",{style:fe.rightIconWrapper,children:a.jsx(x1,{size:16,color:m.black})})]});case"document-detail":return a.jsxs("div",{style:fe.documentDetailContainer,children:[a.jsx("span",{style:fe.label,children:i.label}),i.description&&a.jsx("span",{style:fe.description,children:i.description})]})}},f={...fe.container,...i.variant==="read-only"?fe.readOnlyHeight:fe.fullHeight,...s?{opacity:.75}:{}};return i.onPress!==void 0?a.jsx("button",{type:"button",style:{...fe.buttonReset,...f},onClick:i.onPress,onMouseDown:()=>u(!0),onMouseUp:()=>u(!1),onMouseLeave:()=>u(!1),children:d()}):a.jsx("div",{style:f,children:d()})},fe={buttonReset:{background:"none",border:"none",cursor:"pointer",textAlign:"left",padding:0,width:"100%"},container:{display:"flex",flexDirection:"column",width:"100%",paddingTop:16,paddingBottom:16,paddingLeft:0,paddingRight:0},fullHeight:{minHeight:75},readOnlyHeight:{minHeight:55},iconContainer:{display:"flex",flexDirection:"row",alignItems:"center",gap:Re.md,width:"100%"},iconWrapper:{display:"flex",width:32,alignItems:"center",justifyContent:"center"},rightIconWrapper:{display:"flex",width:32,alignItems:"center",justifyContent:"center"},proofHistoryIconWrapper:{display:"flex",width:46,height:46,borderRadius:3,backgroundColor:m.purple600,alignItems:"center",justifyContent:"center"},textContainer:{display:"flex",flexDirection:"column",flex:1,gap:Re.xs},label:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.md,color:m.black,lineHeight:`${pe.md*1.375}px`},description:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.sm,color:m.slate500,lineHeight:`${pe.sm*1.43}px`},pointsContainer:{display:"flex",flexDirection:"row",alignItems:"center",alignSelf:"stretch"},pointsText:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.md,color:m.black,textAlign:"right"},readOnlyContainer:{display:"flex",flexDirection:"row",alignItems:"center",gap:2,width:"100%"},readOnlyLabel:{flex:1,fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:18,color:m.black,lineHeight:"18px"},readOnlyValue:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:18,color:m.slate500,lineHeight:"18px"},documentDetailContainer:{display:"flex",flexDirection:"column",gap:Re.xs,width:"100%"}},a0=({title:i,variant:s="default",children:u,disableScroll:d=!1})=>{const f=s==="apps";return d?a.jsxs("div",{style:Rt.containerNoScroll,children:[i&&a.jsx("div",{style:Rt.titleContainer,children:a.jsx("span",{style:f?Rt.titleTextApps:Rt.titleTextDefault,children:i})}),a.jsx("div",{style:f?Rt.contentApps:Rt.contentDefault,children:u})]}):a.jsxs("div",{style:Rt.container,children:[i&&a.jsx("div",{style:Rt.titleContainer,children:a.jsx("span",{style:f?Rt.titleTextApps:Rt.titleTextDefault,children:i})}),a.jsx("div",{style:f?Rt.scrollContentApps:Rt.scrollContentDefault,children:u})]})},Rt={container:{display:"flex",flexDirection:"column",width:"100%",flex:1,overflow:"auto"},containerNoScroll:{display:"flex",flexDirection:"column",width:"100%"},titleContainer:{width:"100%",paddingBottom:12},titleTextDefault:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.md,color:m.black,lineHeight:`${pe.md}px`},titleTextApps:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.lg,color:m.black,lineHeight:`${pe.lg}px`},scrollContentDefault:{display:"flex",flexDirection:"column",flex:1,gap:0},scrollContentApps:{display:"flex",flexDirection:"column",flex:1,gap:16},contentDefault:{display:"flex",flexDirection:"column",gap:0,width:"100%"},contentApps:{display:"flex",flexDirection:"column",gap:16,width:"100%"}},S1=({icon:i,label:s})=>a.jsxs("div",{style:Ns.container,children:[a.jsx("div",{style:Ns.iconContainer,children:i}),a.jsx("span",{style:Ns.label,children:s})]}),Ns={container:{display:"flex",flexDirection:"row",alignItems:"center",gap:12,paddingTop:12,paddingBottom:12,paddingLeft:0,paddingRight:0},iconContainer:{display:"flex",width:24,height:24},label:{flex:1,fontFamily:V.dinOT,fontSize:pe.md,fontWeight:Z.medium,color:m.black,lineHeight:"16px"}},k1=({title:i,children:s})=>a.jsxs("div",{style:Ms.container,children:[i&&a.jsx("div",{style:Ms.titleContainer,children:a.jsx("span",{style:Ms.titleText,children:i})}),s]}),Ms={container:{display:"flex",flexDirection:"column",width:"100%"},titleContainer:{display:"flex",width:"100%"},titleText:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:12,lineHeight:"12px",letterSpacing:.48,textTransform:"uppercase",color:m.black}},Us=60,qs=({variant:i,icon:s,iconContainer:u,heading:d,subHeading:f,appName:h,onDismiss:v,onPress:k})=>{const w=i==="CTA_dismissable"||i==="CTA_urgent_dismissable",L=i==="AppCTA",R=i==="CTA"||i==="CTA_dismissable",E=i==="CTA_urgent_dismissable",_={...vt.container,...u0[i]},O={...vt.iconContainer,...E?vt.iconContainerUrgent:{},...R?vt.iconContainerCTA:{},...u},b=E?vt.headingUrgent:vt.heading,A=E?vt.subHeadingUrgent:vt.subHeading,I=E?m.white:m.slate400;return a.jsxs("div",{style:_,children:[w&&v&&a.jsx("button",{type:"button",onClick:v,style:vt.dismissButton,children:a.jsx(ci,{size:22,color:I})}),a.jsxs("button",{type:"button",onClick:k,style:vt.content,children:[s&&a.jsx("div",{style:O,children:s({size:L?Us:36,color:E?m.red500:m.white})}),a.jsxs("div",{style:vt.textContainer,children:[a.jsx("span",{style:b,children:d}),f&&a.jsx("span",{style:A,children:f})]}),L&&h&&a.jsx("div",{style:vt.appNameContainer,children:a.jsx("span",{style:vt.appName,children:h})})]})]})},u0={CTA:{padding:20,backgroundColor:m.blue50,borderColor:m.blue100,borderWidth:1,borderStyle:"solid"},AppCTA:{padding:20,backgroundColor:m.white},CTA_dismissable:{padding:20,paddingTop:12,backgroundColor:m.white},CTA_urgent_dismissable:{padding:20,paddingTop:12,backgroundColor:m.red500}},vt={container:{borderRadius:16,backgroundColor:m.white,overflow:"hidden",width:"100%",position:"relative"},content:{display:"flex",flexDirection:"row",alignItems:"flex-start",gap:12,background:"none",border:"none",cursor:"pointer",padding:0,width:"100%",textAlign:"left"},iconContainer:{display:"flex",width:Us,height:Us,alignItems:"center",justifyContent:"center",borderRadius:14,overflow:"hidden",flexShrink:0},iconContainerUrgent:{backgroundColor:m.white},iconContainerCTA:{backgroundColor:m.blue600},textContainer:{display:"flex",flexDirection:"column",flex:1,alignSelf:"center",gap:4},appNameContainer:{display:"flex",alignItems:"flex-end",justifyContent:"flex-start"},appName:{fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.xxs,color:m.slate600,textTransform:"uppercase",textAlign:"right"},heading:{fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.md,color:m.black,width:"100%",overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",display:"block"},headingUrgent:{fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.md,color:m.white,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",display:"block"},subHeading:{fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.sm,color:m.slate600,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",display:"block"},subHeadingUrgent:{fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.sm,color:m.white,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",display:"block"},dismissButton:{position:"absolute",top:12,right:12,width:24,height:24,display:"flex",alignItems:"center",justifyContent:"center",zIndex:10,background:"none",border:"none",cursor:"pointer",padding:0}},Q1=({heading:i,subheading:s,buttons:u})=>a.jsxs("div",{style:Wn.container,children:[a.jsxs("div",{style:Wn.header,children:[a.jsx("span",{style:Wn.heading,children:i}),s&&a.jsx("span",{style:Wn.subheading,children:s})]}),a.jsx("div",{style:Wn.buttonsOuterContainer,children:a.jsx("div",{style:Wn.buttonsContainer,children:u.map((d,f)=>a.jsx("div",{style:Wn.buttonWrapper,children:a.jsx(et,{...d})},f))})})]}),Wn={container:{display:"flex",flexDirection:"column",borderWidth:1,borderStyle:"solid",alignContent:"center",borderColor:m.slate200,borderRadius:10,backgroundColor:m.white,paddingLeft:16,paddingRight:16,paddingTop:36,paddingBottom:36,width:"100%",boxSizing:"border-box"},header:{display:"flex",flexDirection:"column",marginBottom:16,gap:4},heading:{textAlign:"center",fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.ml,color:m.black},subheading:{textAlign:"center",fontFamily:V.dinOT,fontWeight:Z.regular,fontSize:pe.md,color:m.slate600},buttonsOuterContainer:{display:"flex",width:"100%",alignItems:"center",justifyContent:"center",marginTop:16},buttonsContainer:{display:"flex",flexDirection:"row",flexWrap:"wrap",rowGap:36,columnGap:36,maxWidth:260,justifyContent:"flex-start"},buttonWrapper:{display:"flex",width:112,flexDirection:"column",alignItems:"center"}},c0=({onDismiss:i,onChangeText:s,placeholder:u="Text...",value:d})=>{const[f,h]=T.useState(""),[v,k]=T.useState(!1),w=d!==void 0,L=w?d:f,R=L.length>0,E=O=>{const b=O.target.value;w||h(b),s==null||s(b)},_=()=>{w||h(""),s==null||s(""),i==null||i()};return a.jsxs("div",{style:{...bn.container,...v?bn.containerFocused:{}},children:[a.jsxs("div",{style:bn.contentContainer,children:[a.jsx(Xp,{size:22,color:m.black}),a.jsx("input",{type:"text",style:bn.input,placeholder:u,value:L,onChange:E,onFocus:()=>k(!0),onBlur:()=>k(!1)})]}),a.jsx("button",{type:"button",disabled:!R,onClick:_,style:{...bn.dismissButton,...R?{}:bn.dismissButtonHidden},children:a.jsx("div",{style:bn.dismissIconContainer,children:a.jsx(ci,{size:14,color:m.white})})})]})},bn={container:{backgroundColor:m.white,border:`1px solid ${m.white}`,borderRadius:44,paddingLeft:12,paddingRight:12,paddingTop:10,paddingBottom:10,display:"flex",flexDirection:"row",alignItems:"center",overflow:"hidden",width:"100%",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)",boxSizing:"border-box"},containerFocused:{boxShadow:"1px 2px 4px rgba(0, 0, 0, 0.2)"},contentContainer:{display:"flex",flexDirection:"row",alignItems:"center",gap:10,flex:1},input:{flex:1,fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:pe.md,color:m.black,padding:0,margin:0,border:"none",outline:"none",background:"transparent"},dismissButton:{display:"flex",alignItems:"center",justifyContent:"center",background:"none",border:"none",padding:0,cursor:"pointer"},dismissIconContainer:{width:22,height:22,borderRadius:11,backgroundColor:m.gray400,display:"flex",alignItems:"center",justifyContent:"center"},dismissButtonHidden:{opacity:0,pointerEvents:"none",visibility:"hidden"}},Do=i=>i==="unverified-id"?"unverified":i,d0=new Set(["unverified","unverified-id","pending","inactive","expired"]),f0=new Set(["passport","eu-id","id-card","drivers-license","aadhaar"]),p0=i=>{switch(Do(i)){case"unverified":return"Prove Your Self";case"pending":return"Identity Under Review";case"inactive":return"Inactive ID";case"expired":return"Expired ID";case"passport":return"Passport";case"eu-id":return"EU ID";case"id-card":return"ID Card";case"drivers-license":return"Drivers License";case"aadhaar":return"Indian Aadhaar";case"dev-passport":return"Dev Passport";default:return"Prove Your Self"}},h0=i=>{switch(Do(i)){case"unverified":return"No identity found";case"pending":return"No identity found";case"inactive":return"Restore account to reactivate";case"expired":return"Time to register a valid copy";case"passport":return"Verified Passport";case"eu-id":return"Verified EU ID";case"id-card":return"Verified ID";case"drivers-license":return"Verified Drivers License";case"aadhaar":return"Verified Indian Aadhaar ID";case"dev-passport":return"Self Developer Passport";default:return"No identity found"}},m0=()=>a.jsx("div",{style:{position:"absolute",bottom:0,left:0,width:"100%",height:2,background:"linear-gradient(to left, #00418A 0%, #0077FF 25%, #01BFFF 50%, #01FFB2 77.4%, #00418A 100%)"}}),g0=()=>a.jsx("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",background:"linear-gradient(to right, #000000 0%, #343434 100%)"}}),Ws=({label:i,color:s,backgroundColor:u})=>a.jsx("div",{style:{display:"inline-flex",alignItems:"center",justifyContent:"center",paddingLeft:8,paddingRight:8,paddingTop:4,paddingBottom:4,borderRadius:4,backgroundColor:u},children:a.jsx("span",{style:{fontFamily:V.dinOT,fontSize:9,fontWeight:Z.medium,color:s,textTransform:"uppercase",letterSpacing:.9},children:i})}),y0=({level:i})=>i==="hi"?a.jsx(Ws,{label:"HI-SECURITY",color:m.white,backgroundColor:m.green600}):a.jsx(Ws,{label:"STANDARD",color:m.white,backgroundColor:m.blue600}),v0=i=>{switch(Do(i)){case"pending":return{label:"PENDING",color:m.white,backgroundColor:m.amber600};case"inactive":return{label:"INACTIVE ID",color:m.white,backgroundColor:m.red500};case"expired":return{label:"EXPIRED ID",color:m.white,backgroundColor:m.zinc800};default:return null}},j1=({variant:i="unverified",title:s,subtitle:u,walletAddress:d,footerTitle:f,securityLevel:h,flagImageSrc:v,backgroundImageSrc:k,onAction:w,actionLabel:L})=>{const R=Do(i),E=s||p0(R),_=u||h0(R),O=f0.has(R),b=d0.has(R),A=R==="dev-passport",I=R==="inactive"||R==="expired",J=O||A,X=O||A,ee=v0(R);return a.jsxs("div",{style:{...ge.container,...ge.containerWithShadow},children:[a.jsxs("div",{style:{...ge.header,...A?ge.headerWithSolidBorder:{},...b&&!I?{borderBottom:`2px solid ${m.slate300}`}:{}},children:[J&&a.jsx(g0,{}),a.jsx("div",{style:ge.contentRow,children:a.jsxs("div",{style:ge.logoAndTextContainer,children:[O&&v?a.jsx("img",{src:v,style:ge.flagImage,alt:"Country flag"}):A?a.jsx("div",{style:ge.devIconContainer,children:a.jsx(Gp,{size:18,color:m.white})}):a.jsx(Ks,{size:32,color:I?m.red500:m.gray300}),a.jsxs("div",{style:ge.textContainer,children:[a.jsx("span",{style:{...ge.title,...J?ge.titleWhite:{},...I?{color:m.red500}:{}},children:E}),a.jsx("div",{style:ge.subtitleContainer,children:a.jsx("span",{style:{...ge.subtitle,...J?ge.subtitleGray:{}},children:_})})]})]})}),!A&&!O&&a.jsx(m0,{})]}),a.jsxs("div",{style:{...ge.body,...X?A?ge.bodyDevPassport:ge.bodyDark:{}},children:[k&&a.jsx("img",{src:k,style:ge.backgroundImage,alt:""}),(d||f)&&a.jsxs("div",{style:ge.footerOverlay,children:[d&&a.jsx("span",{style:ge.walletAddress,children:d}),f&&a.jsx("span",{style:ge.footerTitle,children:f})]}),O&&h&&a.jsx("div",{style:ge.badgeContainer,children:a.jsx(y0,{level:h})}),ee&&a.jsx("div",{style:ge.badgeContainer,children:a.jsx(Ws,{label:ee.label,color:ee.color,backgroundColor:ee.backgroundColor})}),R==="unverified"&&a.jsx("div",{style:ge.actionContainer,children:a.jsx("button",{type:"button",onClick:w,style:ge.actionButton,children:a.jsx("span",{style:ge.actionButtonText,children:L||"Register a new ID"})})})]})]})},ge={container:{display:"flex",flexDirection:"column",borderRadius:12,border:`1px solid ${m.gray200}`,overflow:"hidden",width:353,height:224},containerWithShadow:{boxShadow:"0px 4px 14px rgba(0, 0, 0, 0.15)"},flagImage:{width:48,height:32,borderRadius:2,objectFit:"cover",flexShrink:0},header:{display:"flex",backgroundColor:m.white,paddingLeft:14,paddingRight:14,paddingTop:14,paddingBottom:14,height:67,justifyContent:"center",position:"relative",boxSizing:"border-box",flexShrink:0},headerWithSolidBorder:{borderBottom:`2px solid ${m.gray747474}`},devIconContainer:{display:"flex",backgroundColor:m.zinc600,width:48,height:32,borderRadius:2,alignItems:"center",justifyContent:"center",flexShrink:0},contentRow:{display:"flex",flexDirection:"row",alignItems:"center",gap:10,position:"relative",zIndex:1},logoAndTextContainer:{display:"flex",flexDirection:"row",alignItems:"center",gap:12,flex:1,minWidth:0},textContainer:{display:"flex",flexDirection:"column",gap:2,justifyContent:"center",flex:1,minWidth:0},title:{fontFamily:V.dinOT,fontSize:20,fontWeight:Z.medium,color:m.black,textTransform:"uppercase",lineHeight:"22px",overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"},titleWhite:{color:m.white},subtitleContainer:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"flex-start",paddingLeft:1},subtitle:{fontFamily:V.dinOT,fontSize:7,fontWeight:Z.medium,color:m.gray400,textTransform:"uppercase",letterSpacing:.7,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis"},subtitleGray:{color:m.gray9193a2},body:{display:"flex",flexDirection:"column",backgroundColor:m.white,flex:1,padding:14,position:"relative",overflow:"hidden"},bodyDark:{backgroundColor:m.black},bodyDevPassport:{backgroundColor:m.indigo950},backgroundImage:{position:"absolute",top:0,left:0,width:"100%",height:"100%",objectFit:"cover"},footerOverlay:{display:"flex",flexDirection:"column",position:"absolute",bottom:14,left:14,gap:4,zIndex:1},walletAddress:{fontFamily:V.sfMono,fontSize:10,fontWeight:Z.regular,color:m.white},footerTitle:{fontFamily:V.dinOT,fontSize:15,fontWeight:Z.medium,color:m.white,textTransform:"uppercase",letterSpacing:.6},badgeContainer:{position:"absolute",bottom:14,right:14,zIndex:1},actionContainer:{display:"flex",flex:1,alignItems:"center",justifyContent:"flex-end",paddingBottom:0,zIndex:1},actionButton:{display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:38,borderRadius:10,border:`1px solid ${m.gray200}`,backgroundColor:m.white,cursor:"pointer",padding:0},actionButtonText:{fontFamily:V.dinOT,fontSize:16,fontWeight:Z.medium,color:m.black}},C0=(i,s=4,u=4)=>i.length<=s+u?i:`${i.slice(0,s)}..${i.slice(-u)}`,x0=i=>{const s=new Date(i),u=String(s.getMonth()+1).padStart(2,"0"),d=String(s.getDate()).padStart(2,"0"),f=s.getFullYear(),h=`${u}/${d}/${f}`;let v=s.getHours();const k=String(s.getMinutes()).padStart(2,"0"),w=v>=12?"PM":"AM";v=v%12||12;const L=`${v}:${k} ${w}`;return{date:h,time:L}},w0=({label:i,icon:s,isBlurred:u,onInfoPress:d})=>a.jsx("div",{style:{...ie.itemContainer,...u?ie.blurred:{}},children:a.jsxs("div",{style:ie.itemContent,children:[a.jsx("div",{style:ie.itemIconContainer,children:s}),a.jsx("div",{style:ie.itemTextContainer,children:a.jsx("span",{style:ie.itemLabel,children:i})}),a.jsx("button",{type:"button",style:ie.itemChevronContainer,onClick:d,disabled:!d,children:a.jsx(i0,{size:16,color:u?m.slate400:m.blue600})})]})}),S0=({variant:i,appIcon:s,appName:u,appEndpoint:d,timestamp:f,walletAddress:h,items:v,backgroundPattern:k})=>{const w=i==="loading",L=i==="receipt",{date:R,time:E}=x0(f),_=(i==="default"||i==="receipt")&&!!h,O=w?a.jsx("div",{style:ie.itemIconPlaceholder,children:a.jsx("span",{style:ie.itemIconPlaceholderText,children:"𝘞"})}):a.jsx(Ys,{size:12,color:m.green500}),b=L?`${u} was granted access to the following information from your verified Passport.`:`${u} is requesting access to the following information from your verified Passport.`;return a.jsxs("div",{style:ie.container,children:[a.jsxs("div",{style:ie.headerSection,children:[k&&a.jsx("div",{style:ie.backgroundPatternContainer,children:k}),a.jsxs("div",{style:ie.headerContent,children:[a.jsx("div",{style:{...ie.appIconWrapper,...w?ie.appIconWrapperLoading:{}},children:s}),a.jsxs("div",{style:{...ie.reviewTextContainer,...w?ie.blurred:{}},children:[a.jsx("div",{style:ie.reviewTitleContainer,children:a.jsx("span",{style:ie.appTitleText,children:u})}),a.jsx("span",{style:ie.appEndpoint,children:d})]}),a.jsx("div",{style:{...ie.requestPromptContainer,...w?ie.blurred:{}},children:a.jsx("span",{style:ie.requestPromptText,children:b})})]})]}),_&&h&&a.jsx("div",{style:{...ie.walletSection,...L?ie.walletSectionReceipt:{}},children:a.jsxs("div",{style:ie.walletContent,children:[a.jsx("span",{style:ie.walletLabel,children:"Wallet:"}),a.jsx("span",{style:ie.walletAddress,children:C0(h)})]})}),a.jsx("div",{style:ie.dateSection,children:a.jsx("div",{style:ie.dateContent,children:a.jsxs("div",{style:{...ie.dateTextContainer,...w?ie.blurred:{}},children:[a.jsx("span",{style:ie.dateText,children:"Proof requested"}),a.jsx("span",{style:ie.dateText,children:R}),a.jsx("span",{style:ie.dateText,children:E})]})})}),a.jsx("div",{style:ie.itemsSection,children:v.map((A,I)=>a.jsx(w0,{label:A.label,icon:A.icon||O,isBlurred:w,onInfoPress:A.onInfoPress},I))})]})},ie={container:{display:"flex",flexDirection:"column",border:`1px solid ${m.slate200}`,borderRadius:10,overflow:"hidden",boxShadow:"0px 44px 68px rgba(0, 0, 0, 0.25)"},headerSection:{display:"flex",flexDirection:"column",backgroundColor:m.white,position:"relative"},backgroundPatternContainer:{position:"absolute",top:-100,left:0,right:0,bottom:0,opacity:.2,overflow:"hidden"},headerContent:{display:"flex",flexDirection:"column",paddingLeft:40,paddingRight:40,paddingTop:40,paddingBottom:30,gap:20,alignItems:"center"},appIconWrapper:{display:"flex",alignItems:"center",justifyContent:"center",width:70,height:70,borderRadius:8,overflow:"hidden"},appIconWrapperLoading:{backgroundColor:m.slate200},reviewTextContainer:{display:"flex",flexDirection:"column",gap:6,alignItems:"center",width:"100%"},reviewTitleContainer:{display:"flex",flexDirection:"column",gap:2,alignItems:"center",width:"100%"},appTitleText:{fontFamily:V.advercase,fontSize:28,fontWeight:Z.regular,color:m.black,textAlign:"center",letterSpacing:1},appEndpoint:{fontFamily:V.ibmPlexMono,fontSize:pe.xxs,fontWeight:Z.medium,color:m.slate400,textTransform:"uppercase",letterSpacing:1},requestPromptContainer:{width:"100%"},requestPromptText:{fontFamily:V.dinOT,fontSize:pe.sm,fontWeight:Z.medium,color:m.slate600,textAlign:"center",display:"block"},walletSection:{display:"flex",flexDirection:"column",backgroundColor:m.black},walletSectionReceipt:{backgroundColor:m.blue600},walletContent:{display:"flex",flexDirection:"row",paddingLeft:40,paddingRight:40,paddingTop:10,paddingBottom:10,alignItems:"center",justifyContent:"center",gap:8},walletLabel:{fontFamily:V.ibmPlexMono,fontSize:pe.xxs,fontWeight:Z.medium,color:m.white,textTransform:"uppercase",letterSpacing:1},walletAddress:{fontFamily:V.ibmPlexMono,fontSize:pe.xxs,fontWeight:Z.medium,color:m.white,textTransform:"uppercase",letterSpacing:1},dateSection:{display:"flex",flexDirection:"column",backgroundColor:m.slate50,borderTop:`1px solid ${m.slate200}`,borderBottom:`1px solid ${m.slate200}`},dateContent:{display:"flex",flexDirection:"column",paddingLeft:40,paddingRight:40,paddingTop:10,paddingBottom:10},dateTextContainer:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8},dateText:{fontFamily:V.ibmPlexMono,fontSize:pe.xxs,fontWeight:Z.medium,color:m.slate400,textTransform:"uppercase",letterSpacing:1},itemsSection:{display:"flex",flexDirection:"column",backgroundColor:m.white},itemContainer:{paddingLeft:10,paddingRight:10},itemContent:{display:"flex",flexDirection:"row",paddingTop:16,paddingBottom:16,alignItems:"center",gap:16},itemIconContainer:{display:"flex",alignItems:"center",justifyContent:"center",width:32},itemIconPlaceholder:{display:"flex",alignItems:"center",justifyContent:"center"},itemIconPlaceholderText:{fontFamily:V.sfPro,fontSize:pe.xs,fontWeight:Z.bold,color:m.slate400,textAlign:"center"},itemTextContainer:{display:"flex",flex:1,gap:4},itemLabel:{fontFamily:V.ibmPlexMono,fontSize:pe.xxs,fontWeight:Z.medium,color:m.black,textTransform:"uppercase",letterSpacing:1},itemChevronContainer:{display:"flex",alignItems:"center",justifyContent:"center",width:32,background:"none",border:"none",cursor:"pointer",padding:0},blurred:{filter:"blur(7px)",WebkitFilter:"blur(7px)",userSelect:"none",WebkitUserSelect:"none"}},k0=i=>i===0?"00":i>=1e3?i.toString():i.toString().padStart(4,"0"),j0=i=>i?"Earn Self Points":"Earn your first points",E0=({points:i,showDetails:s=!1,dateLabel:u,incomingPoints:d,expectedDays:f,onButtonPress:h})=>{const v=i>0,k=()=>{const E=v?u||"":"no points yet";return a.jsxs("div",{style:He.header,children:[a.jsx("span",{style:He.headerLabel,children:"Self Points"}),a.jsx("span",{style:He.headerLabel,children:E})]})},w=()=>{const E=!s;return a.jsxs("div",{style:He.pointsSection,children:[a.jsxs("div",{style:He.pointsDisplay,children:[a.jsx("div",{style:He.selfLogoContainer,children:a.jsx(K1,{size:38,withoutBackground:!0,color:m.black,accentColor:m.black})}),a.jsx("span",{style:He.pointsNumber,children:k0(i)})]}),E&&h&&a.jsx(et,{variant:"secondary-label",text:j0(v),onPress:h,fullWidth:!0})]})},L=()=>a.jsx("div",{style:He.descriptionContainer,children:a.jsx("span",{style:He.description,children:"Earn points by referring friends, disclosing proof requests, and more."})}),R=(E,_)=>a.jsxs("div",{style:He.footer,children:[a.jsx(n0,{size:16,color:m.black}),a.jsx("span",{style:He.footerPoints,children:E}),a.jsx("span",{style:He.footerText,children:"incoming points"}),a.jsx("span",{style:He.footerExpected,children:"Expected in"}),a.jsx("span",{style:He.footerExpected,children:_}),a.jsx("span",{style:He.footerExpected,children:"days"})]});return a.jsxs("div",{style:He.container,children:[a.jsxs("div",{style:He.content,children:[k(),w(),s&&L()]}),s&&d!==void 0&&f!==void 0&&R(d,f)]})},He={container:{display:"flex",flexDirection:"column",backgroundColor:m.white,border:`1px solid ${m.blue100}`,borderRadius:18,width:343,overflow:"hidden"},content:{display:"flex",flexDirection:"column",padding:16,gap:10},header:{display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"flex-start"},headerLabel:{fontFamily:V.ibmPlexMono,fontWeight:Z.medium,fontSize:10,color:m.black,textTransform:"uppercase",letterSpacing:1,lineHeight:"10px"},pointsSection:{display:"flex",flexDirection:"column",gap:10,width:"100%"},pointsDisplay:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center",gap:12,width:"100%"},pointsNumber:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:62,color:m.black,letterSpacing:-1,lineHeight:"62px"},descriptionContainer:{display:"flex",paddingLeft:40,paddingRight:40,paddingTop:0,paddingBottom:0,gap:10,alignItems:"center",justifyContent:"center",width:"100%"},description:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:14,color:m.slate500,textAlign:"center"},footer:{display:"flex",flexDirection:"row",borderTop:`1px solid ${m.blue100}`,paddingLeft:20,paddingRight:20,paddingTop:10,paddingBottom:10,alignItems:"center",gap:4},footerPoints:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:14,color:m.black},footerText:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:14,color:m.black,flex:1},footerExpected:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:14,color:m.blue600},selfLogoContainer:{display:"flex",width:38,height:38,alignItems:"center",justifyContent:"center",paddingTop:8}},T0=({onPress:i,image:s,title:u,linkText:d})=>{const[f,h]=T.useState(!1);return a.jsxs("button",{type:"button",style:{...Tn.card,...f?Tn.cardPressed:{}},onClick:i,onMouseDown:()=>h(!0),onMouseUp:()=>h(!1),onMouseLeave:()=>h(!1),children:[a.jsxs("div",{style:Tn.imageContainer,children:[s&&a.jsx("img",{src:s,style:Tn.image,alt:""}),a.jsx("div",{style:Tn.starIcon,children:a.jsx(Zp,{size:24,color:m.black})})]}),a.jsxs("div",{style:Tn.content,children:[a.jsx("span",{style:Tn.title,children:u}),a.jsx("span",{style:Tn.link,children:d})]})]})},Tn={card:{display:"flex",flexDirection:"column",backgroundColor:m.slate50,borderRadius:18,border:`1px solid ${m.slate200}`,overflow:"hidden",width:"100%",cursor:"pointer",padding:0,textAlign:"left"},cardPressed:{opacity:.75},imageContainer:{display:"flex",height:170,borderBottom:`1px solid ${m.slate200}`,position:"relative",backgroundColor:m.white},image:{position:"absolute",left:66,top:5,width:322,height:164,objectFit:"cover"},starIcon:{position:"absolute",left:16,top:16},content:{display:"flex",flexDirection:"column",padding:16,paddingBottom:32,gap:10},title:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:16,color:m.black},link:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:16,color:m.blue600}},L0=({referralImage:i,onPress:s})=>a.jsxs("div",{style:ko.container,children:[a.jsxs("div",{style:ko.header,children:[a.jsx("span",{style:ko.title,children:"Earn"}),a.jsx("span",{style:ko.description,children:"Earn rewards by referring friends, disclosing eligible proof requests, and more."})]}),a.jsx(T0,{onPress:s,image:i,title:"Refer friends and earn rewards",linkText:"Refer now"})]}),ko={container:{display:"flex",flexDirection:"column",gap:16,width:"100%"},header:{display:"flex",flexDirection:"column",gap:4,width:"100%"},title:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:20,color:m.black},description:{fontFamily:V.dinOT,fontWeight:Z.medium,fontSize:16,color:m.slate500}},R0=({icon:i,title:s,subtitle:u,containerStyle:d})=>a.jsx("div",{style:{...gr.container,...d},children:a.jsxs("div",{style:gr.content,children:[a.jsx("div",{style:gr.iconContainer,children:i}),a.jsxs("div",{style:gr.textContainer,children:[a.jsx("span",{style:gr.title,children:s}),a.jsx("span",{style:gr.subtitle,children:u})]})]})}),gr={container:{display:"flex",flexDirection:"column",backgroundColor:m.white,border:`1px solid ${m.gray200}`,borderRadius:14,height:67,overflow:"hidden"},content:{display:"flex",flexDirection:"row",alignItems:"center",gap:10,paddingLeft:14,paddingRight:14,paddingTop:14,paddingBottom:14,height:"100%"},iconContainer:{display:"flex",width:48,height:32,alignItems:"center",justifyContent:"center"},textContainer:{display:"flex",flex:1,flexDirection:"column",gap:4,justifyContent:"center"},title:{fontFamily:V.dinOT,fontSize:20,fontWeight:Z.medium,color:m.black,lineHeight:"22px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},subtitle:{fontFamily:V.dinOT,fontSize:7,fontWeight:Z.medium,color:m.gray400,textTransform:"uppercase",letterSpacing:.7,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},I0=({source:i,loop:s=!0,autoPlay:u=!0,width:d=60,height:f=60,style:h})=>{let v;try{v=require("lottie-react").default}catch{return a.jsx("div",{style:{width:d,height:f,...h}})}const k=typeof i=="string";return a.jsx(v,{animationData:k?void 0:i,path:k?i:void 0,loop:s,autoplay:u,style:{width:d,height:f,...h}})},Y1=({variant:i,title:s,description:u,animationSource:d,loopAnimation:f,buttonText:h,secondaryButtonText:v,onButtonPress:k,onSecondaryPress:w,icon:L,footerText:R})=>{const E=f!==void 0?f:i==="loading";return a.jsxs("div",{style:ft.container,children:[a.jsx("div",{style:ft.topSection,children:a.jsx("div",{style:ft.animationContainer,children:d?a.jsx(I0,{source:d,loop:E,autoPlay:!0,width:160,height:160}):L?a.jsx("div",{style:ft.iconWrapper,children:L}):null})}),a.jsxs("div",{style:ft.bottomSection,children:[a.jsxs("div",{style:ft.contentArea,children:[a.jsx("span",{style:ft.title,children:s}),a.jsx("span",{style:ft.description,children:u}),R&&a.jsx("span",{style:ft.footerText,children:R})]}),(h||v)&&a.jsxs("div",{style:ft.buttonArea,children:[h&&a.jsx("button",{type:"button",style:ft.primaryButton,onClick:k,children:a.jsx("span",{style:ft.primaryButtonText,children:h})}),v&&a.jsx("button",{type:"button",style:ft.secondaryButton,onClick:w,children:a.jsx("span",{style:ft.secondaryButtonText,children:v})})]})]})]})},ft={container:{display:"flex",flexDirection:"column",flex:1,minHeight:0},topSection:{display:"flex",flexGrow:1,backgroundColor:m.black,alignItems:"center",justifyContent:"center",padding:20,borderTopLeftRadius:30,borderTopRightRadius:30,overflow:"hidden",marginTop:12},animationContainer:{display:"flex",alignItems:"center",justifyContent:"center",width:160,height:160},iconWrapper:{display:"flex",alignItems:"center",justifyContent:"center"},bottomSection:{display:"flex",flexDirection:"column",backgroundColor:m.white,paddingTop:40,paddingLeft:20,paddingRight:20,paddingBottom:20},contentArea:{display:"flex",flexDirection:"column",gap:10,paddingLeft:10,paddingRight:10,marginBottom:20},title:{fontFamily:V.advercase,fontSize:38,fontWeight:Z.regular,color:m.black,lineHeight:"47px"},description:{fontFamily:V.dinOT,fontSize:18,fontWeight:Z.regular,color:m.slate500,lineHeight:"23px",textAlign:"left"},footerText:{fontFamily:V.dinOT,fontSize:15,fontWeight:Z.regular,color:m.slate500,textAlign:"center",fontStyle:"italic",marginTop:8},buttonArea:{display:"flex",flexDirection:"column",gap:12,paddingLeft:20,paddingRight:20,paddingBottom:24},primaryButton:{display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:52,borderRadius:100,border:"none",backgroundColor:m.black,cursor:"pointer",padding:0},primaryButtonText:{fontFamily:V.dinOT,fontSize:18,fontWeight:Z.medium,color:"#FFFBEB"},secondaryButton:{display:"flex",alignItems:"center",justifyContent:"center",width:"100%",height:52,borderRadius:100,border:`1px solid ${m.slate600}`,backgroundColor:"transparent",cursor:"pointer",padding:0},secondaryButtonText:{fontFamily:V.dinOT,fontSize:18,fontWeight:Z.medium,color:m.white}},P0=` +@keyframes euclid-proof-spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} +`;if(typeof document<"u"){const i=document.createElement("style");i.textContent=P0,document.head.appendChild(i)}const D0=` +@keyframes euclid-empty-spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} +`;if(typeof document<"u"){const i="euclid-empty-state-keyframes";if(!document.getElementById(i)){const s=document.createElement("style");s.id=i,s.textContent=D0,document.head.appendChild(s)}}const jo=({children:i,size:s="default",color:u=m.black,textAlign:d,style:f})=>{const h=s==="large";return a.jsx("span",{style:{fontFamily:V.advercase,fontSize:h?38:28,lineHeight:h?"47px":"35px",fontWeight:Z.regular,color:u,letterSpacing:1,...d?{textAlign:d}:{},...f},children:i})},Eo=({children:i,color:s=m.slate500,textAlign:u="center",style:d})=>a.jsx("span",{style:{fontFamily:V.dinOT,fontSize:18,lineHeight:"23px",fontWeight:Z.regular,color:s,textAlign:u,...d},children:i}),on=({children:i,color:s=m.slate500,fontSize:u=16,textAlign:d,style:f})=>a.jsx("span",{style:{fontFamily:V.dinOT,fontSize:u,fontWeight:Z.regular,color:s,...d?{textAlign:d}:{},...f},children:i}),q1=({children:i,color:s=m.slate400,textAlign:u="center",style:d})=>a.jsx("span",{style:{fontFamily:V.dinOT,fontSize:14,lineHeight:"18px",fontWeight:Z.regular,color:s,textAlign:u,...d},children:i}),N0=[{countryCode:"Loading Countries..."},{countryCode:"Narnia"},{countryCode:"Middle Earth"},{countryCode:"Europa"},{countryCode:"Mars Congressional Republic"}],E1=(i,s)=>{s(i)},J1=({countries:i,isLoading:s,onCountrySelect:u,onClose:d,onInfoPress:f,suggestionCountryCode:h,showSuggestion:v=!1,showInfoIcon:k=!0,renderFlag:w,getCountryName:L,searchValue:R,onSearchChange:E,containerStyle:_,insets:O})=>{const b=T.useCallback(()=>{d==null||d()},[d]),A=T.useCallback(()=>{f==null||f()},[f]),I=T.useMemo(()=>{if(!R||R.trim()==="")return i;const X=R.toLowerCase();return i.filter(ee=>{const ue=L(ee.countryCode);return ee.countryCode.toLowerCase()===X||ue.toLowerCase().includes(X)})},[i,R,L]),J=s?N0:I;return a.jsxs("div",{style:{...It.container,..._,paddingTop:O.top},children:[a.jsx(Po,{variant:"Primary",label:"GETTING STARTED",escapeIcon:({size:X,color:ee})=>a.jsx(ci,{size:X,color:ee}),infoIcon:k?({size:X,color:ee})=>a.jsx(Io,{size:X,color:ee}):void 0,onEscape:b,onPressInfo:A}),a.jsxs("div",{style:It.content,children:[a.jsxs("div",{style:It.header,children:[a.jsx("span",{style:It.title,children:"Select the country that issued your ID"}),a.jsx("span",{style:It.subtitle,children:"Self has support for over 300 ID types. You can select the type of ID in the next step"})]}),v&&h&&a.jsx(k1,{title:"COUNTRY SUGGESTION",children:a.jsx("div",{style:It.suggestionSection,children:a.jsx("button",{onClick:()=>E1(h,u),style:It.countryButton,children:a.jsx(S1,{icon:w(h,24),label:L(h)})})})}),a.jsx(k1,{title:"SELECT AN ISSUING COUNTRY",children:a.jsxs("div",{style:It.countryList,children:[J.map(X=>a.jsxs("button",{disabled:s,onClick:()=>E1(X.countryCode,u),style:{...It.countryButton,...s?It.countryButtonLoading:{}},children:[a.jsx(S1,{icon:w(X.countryCode,24),label:L(X.countryCode)}),s&&a.jsx("div",{style:It.blurOverlay})]},X.countryCode)),a.jsx("div",{style:{marginBottom:bs.bottom+bs.height}})]})})]}),a.jsx("div",{style:It.searchBarContainer,children:a.jsx(c0,{placeholder:"Search countries",value:R,onChangeText:E})})]})};J1.statusBar={hidden:!1,style:"dark"};const bs={bottom:48,height:48},It={container:{display:"flex",flexDirection:"column",flex:1,backgroundColor:m.gray50,position:"relative"},content:{display:"flex",flexDirection:"column",flex:1,paddingLeft:20,paddingRight:20,overflowY:"auto"},header:{display:"flex",flexDirection:"column",paddingTop:20,paddingBottom:20,gap:12},title:{fontFamily:V.advercase,fontSize:28,fontWeight:Xe.fontWeight.regular,color:m.black,letterSpacing:1,lineHeight:"35px"},subtitle:{fontFamily:V.dinOT,fontSize:Xe.fontSize.md,fontWeight:Xe.fontWeight.medium,color:m.gray500,lineHeight:"21px"},suggestionSection:{paddingBottom:20},countryList:{display:"flex",flexDirection:"column"},countryButton:{background:"none",border:"none",padding:0,cursor:"pointer",textAlign:"left",width:"100%",position:"relative"},countryButtonLoading:{paddingLeft:6,paddingRight:6,cursor:"default"},blurOverlay:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(255, 255, 255, 0.7)",backdropFilter:"blur(4px)"},searchBarContainer:{position:"absolute",bottom:bs.bottom,left:20,right:20}},M0=({apps:i,onExploreAppsPress:s})=>a.jsxs("div",{style:Ut.section,children:[a.jsxs("div",{style:Ut.appsSectionHeader,children:[a.jsx("span",{style:Ut.appsSectionTitle,children:"Explore Self Apps"}),a.jsx("span",{style:Ut.appsSectionDescription,children:"Discover apps using Self to verify humanity."})]}),a.jsx("div",{style:Ut.appsListContainer,children:i.map((u,d)=>a.jsx(qs,{variant:"AppCTA",...u},d))}),s&&a.jsx(et,{variant:"secondary-label",text:"Explore more Self Apps",onPress:s,fullWidth:!0})]}),_0=({buttons:i})=>a.jsx(Q1,{heading:"Community",subheading:"Connect with Self",buttons:i}),X1=({idCard:i,pointsCardProps:s,showAddIdCTA:u=!1,onAddIdPress:d,onEarnPointsPress:f,onReferralPress:h,referralImage:v,apps:k=[],onExploreAppsPress:w,communityButtons:L=[],topNavigationPrimaryButton:R,topNavigationSecondaryButton:E,insets:_})=>{const O={variant:"primary-icon",icon:()=>null,onPress:()=>{}};return a.jsxs("div",{style:{...Ut.container,paddingTop:_.top},children:[a.jsx("div",{style:Ut.header,children:E?a.jsx(Fs,{title:"Self",variant:"title-two-buttons",primaryButton:R||O,secondaryButton:E}):a.jsx(Fs,{title:"Self",variant:"title-one-button",primaryButton:R||O})}),a.jsx("div",{style:Ut.scrollView,children:a.jsxs("div",{style:Ut.scrollContent,children:[a.jsxs("div",{style:Ut.cardSection,children:[i&&(i.onPress?a.jsx("button",{onClick:i.onPress,style:Ut.pressableButton,children:a.jsx(j1,{...i})}):a.jsx(j1,{...i})),a.jsx(E0,{...s,onButtonPress:f}),u&&a.jsx(qs,{variant:"CTA",heading:"Add your first ID",subHeading:"Verify your identity",onPress:d||(()=>{})})]}),a.jsx(L0,{referralImage:v,onPress:h}),k.length>0&&a.jsx(M0,{apps:k,onExploreAppsPress:w}),L.length>0&&a.jsx(_0,{buttons:L})]})})]})};X1.statusBar={hidden:!1,style:"dark"};const Ut={container:{display:"flex",flexDirection:"column",flex:1,backgroundColor:m.slate50},header:{backgroundColor:m.slate50},scrollView:{flex:1,overflowY:"auto"},scrollContent:{display:"flex",flexDirection:"column",paddingLeft:20,paddingRight:20,paddingTop:20,paddingBottom:50,gap:42},cardSection:{display:"flex",flexDirection:"column",gap:24,width:"100%"},section:{display:"flex",flexDirection:"column",gap:16,width:"100%"},appsSectionHeader:{display:"flex",flexDirection:"column",gap:8,width:"100%"},appsSectionTitle:{fontFamily:V.dinOT,fontWeight:Xe.fontWeight.medium,fontSize:20,color:m.black},appsSectionDescription:{fontFamily:V.dinOT,fontWeight:Xe.fontWeight.medium,fontSize:16,color:m.slate500},appsListContainer:{display:"flex",flexDirection:"column",gap:16,width:"100%"},pressableButton:{background:"none",border:"none",padding:0,cursor:"pointer",textAlign:"left"}},ed=({variant:i,onClose:s,onConfirm:u,appIcon:d,appName:f,appEndpoint:h,timestamp:v,walletAddress:k,items:w,insets:L})=>{const R=i==="default"&&u,E=i==="loading";return a.jsxs("div",{style:{..._s.container,paddingTop:L.top},children:[a.jsx(Fs,{variant:"title-one-button",title:"Proof Requested",primaryButton:{variant:"secondary-icon",icon:({size:_,color:O})=>a.jsx(ci,{size:_,color:O}),onPress:s}}),a.jsxs("div",{style:_s.content,children:[a.jsx("div",{style:_s.proofRequestContainer,children:a.jsx(S0,{variant:i,appIcon:d,appName:f,appEndpoint:h,timestamp:v,walletAddress:k,items:w})}),R&&a.jsx(et,{variant:"primary-icon-label",text:"Long press to confirm",icon:({size:_,color:O})=>a.jsx(Jp,{size:_,color:O}),onPress:()=>{},onLongPress:u,fullWidth:!0}),E&&a.jsx(et,{variant:"secondary-label",text:"Loading proof request",onPress:()=>{},fullWidth:!0})]})]})};ed.statusBar={hidden:!1,style:"dark"};const _s={container:{flex:1,display:"flex",flexDirection:"column",backgroundColor:m.slate50},content:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",paddingLeft:20,paddingRight:20,paddingBottom:50,gap:28},proofRequestContainer:{display:"flex",justifyContent:"center",alignItems:"center"}},A0=(i,s)=>{s(i)},td=({countryCode:i,idTypes:s,onIDTypeSelect:u,onBack:d,onInfoPress:f,onNotListedPress:h,renderFlag:v,renderIDTypeIcon:k,containerStyle:w,insets:L})=>{const R=T.useCallback(()=>{d==null||d()},[d]),E=T.useCallback(()=>{f==null||f()},[f]),_=T.useCallback(()=>{h==null||h()},[h]);return a.jsxs("div",{style:{...ze.container,...w,paddingTop:L.top},children:[a.jsx(Po,{variant:"Primary",label:"GETTING STARTED",escapeIcon:({size:O,color:b})=>a.jsx(Qs,{size:O,color:b}),infoIcon:({size:O,color:b})=>a.jsx(Io,{size:O,color:b}),onEscape:R,onPressInfo:E}),a.jsxs("div",{style:ze.content,children:[a.jsxs("div",{style:ze.visualizationSection,children:[a.jsxs("div",{style:ze.iconFlow,children:[a.jsx("div",{style:ze.flagContainer,children:v(i,44)}),a.jsx(Z1,{size:18,color:m.gray400}),a.jsx("div",{style:ze.selfLogoContainer,children:a.jsx("div",{style:ze.selfLogoInner,children:a.jsx(Ks,{size:26,color:m.white})})})]}),a.jsxs("div",{style:ze.instructionContainer,children:[a.jsxs("span",{style:ze.title,children:["Select an ID",` +`,"type to register"]}),a.jsx("div",{style:ze.subtitleContainer,children:a.jsx("span",{style:ze.subtitle,children:"Be sure to have your document ready to scan"})})]})]}),a.jsx("div",{style:ze.idOptionsSection,children:a.jsxs("div",{style:ze.idOptionsScrollView,children:[a.jsx("span",{style:ze.sectionLabel,children:"ID OPTIONS"}),a.jsx("div",{style:ze.idTypesList,children:s.map(O=>a.jsx("button",{onClick:()=>A0(O,u),style:ze.idTypeButton,children:a.jsx(R0,{icon:k(O),title:O.title,subtitle:O.subtitle})},O.id))}),a.jsx("button",{onClick:_,style:ze.footerButton,children:a.jsx("span",{style:ze.footerButtonText,children:"Don't see your ID type?"})})]})})]})]})};td.statusBar={hidden:!1,style:"dark"};const ze={container:{display:"flex",flexDirection:"column",flex:1,backgroundColor:m.gray50},content:{display:"flex",flexDirection:"column",flex:1,paddingLeft:20,paddingRight:20},visualizationSection:{display:"flex",flex:1,flexDirection:"column",alignItems:"center",justifyContent:"center",gap:30},iconFlow:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10},flagContainer:{display:"flex",width:44,height:44,alignItems:"center",justifyContent:"center"},selfLogoContainer:{display:"flex",width:46,height:46,backgroundColor:m.black,borderRadius:3,alignItems:"center",justifyContent:"center",overflow:"hidden",padding:10},selfLogoInner:{width:26,height:26,transform:"rotate(180deg)"},instructionContainer:{display:"flex",flexDirection:"column",gap:16,alignItems:"center",width:"100%"},title:{fontFamily:V.advercase,fontSize:28,fontWeight:Xe.fontWeight.regular,color:m.black,textAlign:"center",letterSpacing:1,lineHeight:"33px",whiteSpace:"pre-line"},subtitleContainer:{paddingLeft:80,paddingRight:80,width:"100%"},subtitle:{fontFamily:V.dinOT,fontSize:Xe.fontSize.ml,fontWeight:Xe.fontWeight.medium,color:m.black,textAlign:"center",lineHeight:"22px",display:"block"},idOptionsSection:{paddingBottom:30},idOptionsScrollView:{maxHeight:320,overflowY:"auto"},sectionLabel:{fontFamily:V.dinOT,fontSize:12,fontWeight:Xe.fontWeight.medium,color:m.black,textTransform:"uppercase",letterSpacing:.48,marginBottom:12,display:"block"},idTypesList:{display:"flex",flexDirection:"column",gap:10,marginBottom:12},idTypeButton:{background:"none",border:"none",padding:0,cursor:"pointer",textAlign:"left",width:"100%"},footerButton:{display:"flex",backgroundColor:m.white,border:`1px solid ${m.gray200}`,borderRadius:60,height:48,alignItems:"center",justifyContent:"center",paddingLeft:18,paddingRight:18,marginTop:2,cursor:"pointer",width:"100%"},footerButtonText:{fontFamily:V.dinOT,fontSize:Xe.fontSize.md,fontWeight:Xe.fontWeight.medium,color:m.blue600,textAlign:"center"}},nd=({countryCode:i,title:s="Coming soon",subtitle:u,description:d,onBack:f,onInfoPress:h,onSignUpPress:v,onSeeListPress:k,renderFlag:w,containerStyle:L,insets:R})=>{const E=T.useCallback(()=>{f==null||f()},[f]),_=T.useCallback(()=>{h==null||h()},[h]),O=T.useCallback(()=>{v==null||v()},[v]),b=T.useCallback(()=>{k==null||k()},[k]);return a.jsxs("div",{style:{...Ct.container,...L,paddingTop:R.top},children:[a.jsx(Po,{variant:"Primary",label:"GETTING STARTED",escapeIcon:({size:A,color:I})=>a.jsx(Qs,{size:A,color:I}),infoIcon:({size:A,color:I})=>a.jsx(Io,{size:A,color:I}),onEscape:E,onPressInfo:_}),a.jsxs("div",{style:Ct.content,children:[a.jsxs("div",{style:Ct.centeredContent,children:[a.jsxs("div",{style:Ct.iconFlow,children:[a.jsx("div",{style:Ct.flagContainer,children:w(i,44)}),a.jsx(Z1,{size:18,color:m.gray400}),a.jsx("div",{style:Ct.selfLogoContainer,children:a.jsx("div",{style:Ct.selfLogoInner,children:a.jsx(Ks,{size:26,color:m.white})})})]}),a.jsxs("div",{style:Ct.textSection,children:[a.jsx("span",{style:Ct.title,children:s}),a.jsxs("div",{style:Ct.textContent,children:[a.jsx("span",{style:Ct.subtitle,children:u}),a.jsx("span",{style:Ct.description,children:d})]})]})]}),a.jsxs("div",{style:Ct.buttonsSection,children:[a.jsx(et,{variant:"primary-no-icon",text:"Sign up for updates",onPress:O,fullWidth:!0}),a.jsx(et,{variant:"secondary-label",text:"See list of supported IDs",onPress:b,fullWidth:!0})]})]})]})};nd.statusBar={hidden:!1,style:"dark"};const Ct={container:{display:"flex",flexDirection:"column",flex:1,backgroundColor:m.gray50},content:{display:"flex",flexDirection:"column",flex:1,paddingLeft:20,paddingRight:20,justifyContent:"space-between"},centeredContent:{display:"flex",flex:1,flexDirection:"column",alignItems:"center",justifyContent:"center",gap:30,paddingLeft:10,paddingRight:10},iconFlow:{display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10},flagContainer:{display:"flex",width:44,height:44,alignItems:"center",justifyContent:"center"},selfLogoContainer:{display:"flex",width:46,height:46,backgroundColor:m.black,borderRadius:3,alignItems:"center",justifyContent:"center",overflow:"hidden",padding:10},selfLogoInner:{width:26,height:26,transform:"rotate(180deg)"},textSection:{display:"flex",flexDirection:"column",gap:12,alignItems:"center",width:"100%"},title:{fontFamily:V.advercase,fontSize:28,fontWeight:Xe.fontWeight.regular,color:m.black,textAlign:"center",letterSpacing:1},textContent:{display:"flex",flexDirection:"column",gap:8,alignItems:"center",width:"100%"},subtitle:{fontFamily:V.dinOT,fontSize:Xe.fontSize.ml,fontWeight:Xe.fontWeight.medium,color:m.black,textAlign:"center"},description:{fontFamily:V.dinOT,fontSize:Xe.fontSize.md,fontWeight:Xe.fontWeight.medium,color:m.gray500,textAlign:"center"},buttonsSection:{display:"flex",flexDirection:"column",gap:12,paddingBottom:30}},rd=({escapeIcon:i,infoIcon:s,onClose:u,isBackupEnabled:d,CTAs:f,sections:h,connectHeading:v,connectSubheading:k,connectButtons:w,bottomSectionItems:L,showBackupInfoBox:R,insets:E})=>{const[_,O]=T.useState(!1),b=()=>{O(I=>!I)},A=()=>{O(!1)};return a.jsxs("div",{style:{...Kt.container,paddingTop:E.top},children:[a.jsx("div",{style:{...Kt.header,paddingTop:E.top},children:a.jsx(Po,{variant:"Primary",label:"Settings",escapeIcon:i,infoIcon:s,onEscape:u,onPressInfo:b})}),a.jsxs("div",{style:Kt.contentWrapper,children:[a.jsx("div",{style:Kt.scrollView,children:a.jsx("div",{style:Kt.scrollContent,children:a.jsxs("div",{style:Kt.contentContainer,children:[R&&a.jsx("div",{style:Kt.backupInfoPlaceholder,children:a.jsxs("span",{children:["Backup ",d?"enabled":"disabled"]})}),f.length>0&&a.jsx("div",{style:Kt.CTAsContainer,children:f.map((I,J)=>a.jsx(qs,{variant:"CTA",icon:I.icon,heading:I.label,subHeading:I.description,onPress:I.onPress},J))}),h.map((I,J)=>a.jsx(a0,{title:I.title,disableScroll:!0,children:I.items.map(({icon:X,label:ee,description:ue,onPress:Ee},Ie)=>a.jsx(w1,{variant:"menu-item",icon:X({size:24,color:m.black}),label:ee,description:ue,onPress:Ee},Ie))},J)),w.length>0&&a.jsx(Q1,{heading:v,subheading:k,buttons:w}),L.length>0&&a.jsx("div",{style:Kt.bottomSectionItemsContainer,children:L.map((I,J)=>a.jsx(w1,{variant:"read-only",label:I.label,value:I.description||"",onPress:I.onPress},J))})]})})}),_&&a.jsx("div",{style:Kt.blurOverlay,onClick:A})]})]})};rd.statusBar={hidden:!1,style:"dark"};const Kt={container:{display:"flex",flexDirection:"column",flex:1,backgroundColor:m.white},header:{position:"absolute",top:0,left:0,right:0,backgroundColor:m.white,zIndex:10},contentWrapper:{display:"flex",flexDirection:"column",flex:1,position:"relative"},scrollView:{flex:1,overflowY:"auto"},scrollContent:{paddingLeft:20,paddingRight:20,paddingTop:80,paddingBottom:40},blurOverlay:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(255, 255, 255, 0.7)",backdropFilter:"blur(12px)"},contentContainer:{display:"flex",flexDirection:"column",gap:24,width:"100%"},CTAsContainer:{display:"flex",flexDirection:"column",gap:Re.md},bottomSectionItemsContainer:{paddingTop:Re.md},backupInfoPlaceholder:{display:"flex",padding:16,backgroundColor:m.slate50,borderRadius:12}},B0=["p","i"],O0=["p"],z0=["p","i"],F0=["p","i"],U0=["p","i"],W0=["p","i"],b0=["p","i"],H0=["p","i"],V0=["p","i"],$0=["p","i"],G0=["p","i"],Z0=["p","i"],K0=["p","i"],Q0=["p","i"],Y0=["p","i"],q0=["p","i"],J0=["p","i"],X0=["p","i"],e5=["p","i"],t5=["p","i"],n5=["p","i"],r5=["p","i"],i5=["p","i"],o5=["p","i"],l5=["p","i"],s5=["p","i"],a5=["p","i"],u5=["p","i"],c5=["p","i"],d5=["p","i"],f5=["p","i"],p5=["p","i"],h5=["p","i"],m5=["p","i"],g5=["p","i"],y5=["p","i"],v5=["p","i"],C5=["p","i"],x5=["p","i"],w5=["p","i"],S5=["p","i"],k5=["p","i"],j5=["p","i"],E5=["p","i"],T5=["p","i"],L5=["p","i"],R5=["p","i"],I5=["p","i"],P5=["p","i"],D5=["p","i"],N5=["p","i"],M5=["p","i"],_5=["p","i"],A5=["p","i"],B5=["p","i"],O5=["p","i"],z5=["p","i"],F5=["p","i"],U5=["p","i"],W5=["p","i"],b5=["p","i"],H5=["p","i"],V5=["p","i"],$5=["p","i"],G5=["p","i"],Z5=[],K5=["p","i"],Q5=["p","i"],Y5=["p","i"],q5=["p","i"],J5=["p","i"],X5=["p","i"],e4=["p","i"],t4=["p","i"],n4=["p","i"],r4=["p","i"],i4=["p","i"],o4=["p","i"],l4=["p","i"],s4=["p","i"],a4=["p","i"],u4=["p","i"],c4=["p","i"],d4=["p","i"],f4=["p","i"],p4=["p","i"],h4=["p","i"],m4=["p","i"],g4=["p","i"],y4=["p","i"],v4=["p","i"],C4=["p","i"],x4=["p","i"],w4=["p","i"],S4=["p","i"],k4=["p","i"],j4=["p","i"],E4=["p","i"],T4=["p","i"],L4=["p","i"],R4=["p","i"],I4=["p","i"],P4=["p","i"],D4=["p","i"],N4=["p","a"],M4=["p","i"],_4=["p","i"],A4=["p","i"],B4=["p","i"],O4=["p","i"],z4=["p","i"],F4=["p","i"],U4=["p","i"],W4=["p","i"],b4=["p","i"],H4=["p","i"],V4=["p","i"],$4=["p","i"],G4=["p","i"],Z4=["p","i"],K4=["p","i"],Q4=["p","i"],Y4=["p","i"],q4=["p","i"],J4=["p","i"],X4=["p","i"],eh=["p","i"],th=["p","i"],nh=["p","i"],rh=["p","i"],ih=["p","i"],oh=["p","i"],lh=["p","i"],sh=["p","i"],ah=["p","i"],uh=["p","i"],ch=["p","i"],dh=["p","i"],fh=["p","i"],ph=["p","i"],hh=["p","i"],mh=["p","i"],gh=["p","i"],yh=["p","i"],vh=["p","i"],Ch=["p","i"],xh=["p","i"],wh=["p","i"],Sh=["p","i"],kh=["p","i"],jh=["p","i"],Eh=["p","i"],Th=["p","i"],Lh=["p","i"],Rh=["p","i"],Ih=["p","i"],Ph=["p","i"],Dh=["p","i"],Nh=["p","i"],Mh=["p","i"],_h=["p","i"],Ah=["p","i"],Bh=["p","i"],Oh=["p","i"],zh=["p","i"],Fh=["p","i"],Uh=["p","i"],Wh=["p","i"],bh=["p","i"],Hh=["p","i"],Vh=["p","i"],$h=["p","i"],Gh=["p","i"],Zh=["p","i"],Kh=["p","i"],Qh=["p","i"],Yh=["p","i"],qh=["p","i"],Jh=["p","i"],Xh=["p","i"],e3=["p","i"],t3=["p","i"],n3=["p","i"],r3=["p","i"],i3=["p","i"],o3=["p","i"],l3=["p","i"],s3=["p","i"],a3=["p","i"],u3=["p","i"],c3=["p","i"],d3=["p","i"],f3=["p","i"],p3=["p","i"],h3=["p","i"],m3=["p","i"],g3=["p","i"],y3=["p","i"],v3=["p","i"],C3=["p","i"],x3=["p","i"],w3=["p","i"],S3=["p","i"],k3=["p","i"],j3=["p","i"],E3=["p","i"],T3=["p","i"],L3=["p","i"],R3=["p","i"],I3=["p","i"],P3=["p","i"],D3=["p","i"],N3=["p","i"],M3=["p","i"],_3=["p","i"],A3=["p","i"],B3=["p","i"],O3=["p","i"],z3=["p","i"],F3=["p","i"],U3=["p","i"],W3=["p","i"],b3=["p","i"],H3=["p","i"],V3=["p","i"],$3=["p","i"],G3=["p","i"],Z3=["p","i"],K3=["p","i"],Q3=["p","i"],Y3=["p","i"],q3=["p","i"],J3=["p","i"],X3=["p","i"],e8=["p","i"],t8=["p","i"],n8=["p","i"],r8=["p","i"],i8=["p","i"],o8=["p","i"],l8=["p","i"],s8=["p","i"],a8=["p","i"],u8=["p","i"],c8=["p","i"],d8=["p","i"],f8=["p","i"],p8=["p","i"],h8=["p","i"],m8=["p","i"],g8=["p","i"],y8=["p","i"],v8=["p","i"],C8={ABW:B0,AFG:O0,AGO:z0,AIA:F0,ALA:U0,ALB:W0,AND:b0,ARE:H0,ARG:V0,ARM:$0,ASM:G0,ATA:Z0,ATF:K0,ATG:Q0,AUS:Y0,AUT:q0,AZE:J0,BDI:X0,BEL:e5,BEN:t5,BES:n5,BFA:r5,BGD:i5,BGR:o5,BHR:l5,BHS:s5,BIH:a5,BLM:u5,BLR:c5,BLZ:d5,BMU:f5,BOL:p5,BRA:h5,BRB:m5,BRN:g5,BTN:y5,BVT:v5,BWA:C5,CAF:x5,CAN:w5,CCK:S5,CHE:k5,CHL:j5,CHN:E5,CIV:T5,CMR:L5,COD:R5,COG:I5,COK:P5,COL:D5,COM:N5,CPV:M5,CRI:_5,CUB:A5,CUW:B5,CXR:O5,CYM:z5,CYP:F5,CZE:U5,"D<<":["p","i"],DJI:W5,DMA:b5,DNK:H5,DOM:V5,DZA:$5,ECU:G5,EGY:Z5,ERI:K5,ESH:Q5,ESP:Y5,EST:q5,ETH:J5,EUE:X5,FIN:e4,FJI:t4,FLK:n4,FRA:r4,FRO:i4,FSM:o4,GAB:l4,GBR:s4,GEO:a4,GGY:u4,GHA:c4,GIB:d4,GIN:f4,GLP:p4,GMB:h4,GNB:m4,GNQ:g4,GRC:y4,GRD:v4,GRL:C4,GTM:x4,GUF:w4,GUM:S4,GUY:k4,HKG:j4,HMD:E4,HND:T4,HRV:L4,HTI:R4,HUN:I4,IDN:P4,IMN:D4,IND:N4,IOT:M4,IRL:_4,IRN:A4,IRQ:B4,ISL:O4,ISR:z4,ITA:F4,JAM:U4,JEY:W4,JOR:b4,JPN:H4,KAZ:V4,KEN:$4,KGZ:G4,KHM:Z4,KIR:K4,KNA:Q4,KOR:Y4,KWT:q4,LAO:J4,LBN:X4,LBR:eh,LBY:th,LCA:nh,LIE:rh,LKA:ih,LSO:oh,LTU:lh,LUX:sh,LVA:ah,MAC:uh,MAF:ch,MAR:dh,MCO:fh,MDA:ph,MDG:hh,MDV:mh,MEX:gh,MHL:yh,MKD:vh,MLI:Ch,MLT:xh,MMR:wh,MNE:Sh,MNG:kh,MNP:jh,MOZ:Eh,MRT:Th,MSR:Lh,MTQ:Rh,MUS:Ih,MWI:Ph,MYS:Dh,MYT:Nh,NAM:Mh,NCL:_h,NER:Ah,NFK:Bh,NGA:Oh,NIC:zh,NIU:Fh,NLD:Uh,NOR:Wh,NPL:bh,NRU:Hh,NZL:Vh,OMN:$h,PAK:Gh,PAN:Zh,PCN:Kh,PER:Qh,PHL:Yh,PLW:qh,PNG:Jh,POL:Xh,PRI:e3,PRK:t3,PRT:n3,PRY:r3,PSE:i3,PYF:o3,QAT:l3,REU:s3,ROU:a3,RUS:u3,RWA:c3,SAU:d3,SDN:f3,SEN:p3,SGP:h3,SGS:m3,SHN:g3,SJM:y3,SLB:v3,SLE:C3,SLV:x3,SMR:w3,SOM:S3,SPM:k3,SRB:j3,SSD:E3,STP:T3,SUR:L3,SVK:R3,SVN:I3,SWE:P3,SWZ:D3,SXM:N3,SYC:M3,SYR:_3,TCA:A3,TCD:B3,TGO:O3,THA:z3,TJK:F3,TKL:U3,TKM:W3,TLS:b3,TON:H3,TTO:V3,TUN:$3,TUR:G3,TUV:Z3,TWN:K3,TZA:Q3,UGA:Y3,UKR:q3,UMI:J3,UNO:X3,URY:e8,USA:t8,UZB:n8,VAT:r8,VCT:i8,VEN:o8,VGB:l8,VIR:s8,VNM:a8,VUT:u8,WLF:c8,WSM:d8,XCE:f8,XOM:p8,XPO:h8,YEM:m8,ZAF:g8,ZMB:y8,ZWE:v8},x8={ABW:"AW",AFG:"AF",AGO:"AO",AIA:"AI",ALA:"AX",ALB:"AL",AND:"AD",ARE:"AE",ARG:"AR",ARM:"AM",ASM:"AS",ATA:"AQ",ATF:"TF",ATG:"AG",AUS:"AU",AUT:"AT",AZE:"AZ",BDI:"BI",BEL:"BE",BEN:"BJ",BES:"BQ",BFA:"BF",BGD:"BD",BGR:"BG",BHR:"BH",BHS:"BS",BIH:"BA",BLM:"BL",BLR:"BY",BLZ:"BZ",BMU:"BM",BOL:"BO",BRA:"BR",BRB:"BB",BRN:"BN",BTN:"BT",BVT:"BV",BWA:"BW",CAF:"CF",CAN:"CA",CCK:"CC",CHE:"CH",CHL:"CL",CHN:"CN",CIV:"CI",CMR:"CM",COD:"CD",COG:"CG",COK:"CK",COL:"CO",COM:"KM",CPV:"CV",CRI:"CR",CUB:"CU",CUW:"CW",CXR:"CX",CYM:"KY",CYP:"CY",CZE:"CZ",DJI:"DJ",DMA:"DM",DNK:"DK",DOM:"DO",DZA:"DZ",ECU:"EC",EGY:"EG",ERI:"ER",ESH:"EH",ESP:"ES",EST:"EE",ETH:"ET",FIN:"FI",FJI:"FJ",FLK:"FK",FRA:"FR",FRO:"FO",FSM:"FM",GAB:"GA",GBR:"GB",GEO:"GE",GGY:"GG",GHA:"GH",GIB:"GI",GIN:"GN",GLP:"GP",GMB:"GM",GNB:"GW",GNQ:"GQ",GRC:"GR",GRD:"GD",GRL:"GL",GTM:"GT",GUF:"GF",GUM:"GU",GUY:"GY",HKG:"HK",HMD:"HM",HND:"HN",HRV:"HR",HTI:"HT",HUN:"HU",IDN:"ID",IMN:"IM",IND:"IN",IOT:"IO",IRL:"IE",IRN:"IR",IRQ:"IQ",ISL:"IS",ISR:"IL",ITA:"IT",JAM:"JM",JEY:"JE",JOR:"JO",JPN:"JP",KAZ:"KZ",KEN:"KE",KGZ:"KG",KHM:"KH",KIR:"KI",KNA:"KN",KOR:"KR",KWT:"KW",LAO:"LA",LBN:"LB",LBR:"LR",LBY:"LY",LCA:"LC",LIE:"LI",LKA:"LK",LSO:"LS",LTU:"LT",LUX:"LU",LVA:"LV",MAC:"MO",MAF:"MF",MAR:"MA",MCO:"MC",MDA:"MD",MDG:"MG",MDV:"MV",MEX:"MX",MHL:"MH",MKD:"MK",MLI:"ML",MLT:"MT",MMR:"MM",MNE:"ME",MNG:"MN",MNP:"MP",MOZ:"MZ",MRT:"MR",MSR:"MS",MTQ:"MQ",MUS:"MU",MWI:"MW",MYS:"MY",MYT:"YT",NAM:"NA",NCL:"NC",NER:"NE",NFK:"NF",NGA:"NG",NIC:"NI",NIU:"NU",NLD:"NL",NOR:"NO",NPL:"NP",NRU:"NR",NZL:"NZ",OMN:"OM",PAK:"PK",PAN:"PA",PCN:"PN",PER:"PE",PHL:"PH",PLW:"PW",PNG:"PG",POL:"PL",PRI:"PR",PRK:"KP",PRT:"PT",PRY:"PY",PSE:"PS",PYF:"PF",QAT:"QA",REU:"RE",ROU:"RO",RUS:"RU",RWA:"RW",SAU:"SA",SDN:"SD",SEN:"SN",SGP:"SG",SGS:"GS",SHN:"SH",SJM:"SJ",SLB:"SB",SLE:"SL",SLV:"SV",SMR:"SM",SOM:"SO",SPM:"PM",SRB:"RS",SSD:"SS",STP:"ST",SUR:"SR",SVK:"SK",SVN:"SI",SWE:"SE",SWZ:"SZ",SXM:"SX",SYC:"SC",SYR:"SY",TCA:"TC",TCD:"TD",TGO:"TG",THA:"TH",TJK:"TJ",TKL:"TK",TKM:"TM",TLS:"TL",TON:"TO",TTO:"TT",TUN:"TN",TUR:"TR",TUV:"TV",TWN:"TW",TZA:"TZ",UGA:"UG",UKR:"UA",UMI:"UM",URY:"UY",USA:"US",UZB:"UZ",VAT:"VA",VCT:"VC",VEN:"VE",VGB:"VG",VIR:"VI",VNM:"VN",VUT:"VU",WLF:"WF",WSM:"WS",YEM:"YE",ZAF:"ZA",ZMB:"ZM",ZWE:"ZW"},id=i=>x8[i]??i.slice(0,2),w8=i=>String.fromCodePoint(...i.toUpperCase().split("").map(s=>127462+s.charCodeAt(0)-65)),Js=i=>{try{const u=new Intl.DisplayNames(["en"],{type:"region"}).of(id(i));if(u&&u!==i)return u}catch{}return i},Xs=(i,s)=>a.jsx("span",{style:{fontSize:s*.8,lineHeight:1},children:w8(id(i))}),T1=C8,S8=()=>{const i=Dt(),{analytics:s,haptic:u}=Qt(),[d,f]=T.useState(""),h=T.useMemo(()=>Object.keys(T1).map(k=>({countryCode:k})),[]),v=T.useCallback(k=>{u.trigger("selection");const w=T1[k];w&&w.length>0?(s.trackEvent("document_country_selected",{countryCode:k}),i("/onboarding/id-type",{state:{countryCode:k,documentTypes:w}})):i("/coming-soon",{state:{countryCode:k}})},[i,s,u]);return a.jsx(J1,{insets:{top:0,bottom:0},countries:h,isLoading:!1,onCountrySelect:v,onClose:()=>i("/"),renderFlag:Xs,getCountryName:Js,searchValue:d,onSearchChange:f})},k8=i=>{switch(i){case"p":return{id:"p",title:"Passport",subtitle:"Verified Biometric Passport"};case"i":return{id:"i",title:"ID Card",subtitle:"Verified Biometric ID card"};case"a":return{id:"a",title:"Aadhaar",subtitle:"Verified mAadhaar QR code"};case"kyc":return{id:"kyc",title:"Other IDs",subtitle:"National ID, Driver's License etc."};default:return{id:i,title:"Unknown Document",subtitle:""}}},j8=i=>{const s=i.id==="p"?"🛂":i.id==="i"?"🪪":i.id==="a"?"🆔":"📄";return a.jsx("span",{style:{fontSize:24},children:s})},E8=()=>{const i=Dt(),s=ln(),{analytics:u,haptic:d}=Qt(),{countryCode:f="",documentTypes:h=[]}=s.state||{},v=h.map(k8),k=T.useCallback(w=>{if(d.trigger("selection"),u.trackEvent("document_type_selected",{documentType:w.id,countryCode:f}),w.id==="kyc"){i("/coming-soon",{state:{countryCode:f,documentCategory:"kyc"}});return}i("/onboarding/camera",{state:{countryCode:f,documentType:w.id}})},[i,u,d,f]);return a.jsx(td,{insets:{top:0,bottom:0},countryCode:f,countryName:Js(f),idTypes:v,onIDTypeSelect:k,onBack:()=>i(-1),renderFlag:Xs,renderIDTypeIcon:j8})},T8=()=>{const i=Dt(),s=ln(),u=Zs(),{analytics:d,haptic:f}=Qt(),{countryCode:h="",documentType:v="p"}=s.state||{},[k,w]=T.useState(!1),[L,R]=T.useState(null),E=v==="i"?"Scan your ID card":"Scan your passport",_=T.useCallback(async()=>{w(!0),R(null),d.trackEvent("camera_mrz_scan_started",{documentType:v,countryCode:h});try{const b=await u.request("camera","scanMRZ",{documentType:v,countryCode:h});f.trigger("success"),d.trackEvent("camera_mrz_scan_success"),i("/onboarding/nfc",{state:{countryCode:h,documentType:v,passportNumber:b.passportNumber,dateOfBirth:b.dateOfBirth,dateOfExpiry:b.dateOfExpiry}})}catch(b){const A=b instanceof Error?b.message:"MRZ scan failed";R(A),d.trackEvent("camera_mrz_scan_failed",{error:A})}finally{w(!1)}},[u,i,d,f,v,h]);T.useEffect(()=>{_()},[_]);const O=T.useCallback(()=>{d.trackEvent("camera_screen_closed"),i("/")},[i,d]);return a.jsxs("div",{style:{display:"flex",flexDirection:"column",flex:1,height:"100vh",backgroundColor:m.white},children:[a.jsxs("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:m.black,position:"relative"},children:[a.jsx("button",{onClick:O,style:{position:"absolute",top:Re.md,right:Re.md,background:"none",border:"none",cursor:"pointer",padding:Re.sm},children:a.jsx(ci,{size:24,color:m.white})}),k?a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.md},children:[a.jsx("div",{style:{width:32,height:32,border:`3px solid ${m.slate400}`,borderTopColor:m.white,borderRadius:"50%",animation:"spin 0.8s linear infinite"}}),a.jsx(on,{color:m.white,children:"Scanning MRZ..."})]}):L?a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.md,padding:`0 ${Re.lg}px`},children:[a.jsx(on,{color:m.red500,textAlign:"center",fontSize:18,children:"Scan failed"}),a.jsx(on,{color:m.slate400,textAlign:"center",children:L}),a.jsx(et,{variant:"primary-no-icon",text:"Try Again",onPress:_})]}):null]}),a.jsxs("div",{style:{padding:Re.lg,display:"flex",flexDirection:"column",alignItems:"center",gap:Re.md},children:[a.jsx(jo,{textAlign:"center",children:E}),a.jsxs("div",{style:{display:"flex",gap:Re.md,alignItems:"flex-start"},children:[a.jsx("div",{style:{paddingTop:4},children:a.jsx("span",{style:{fontSize:32},children:"📷"})}),a.jsxs("div",{style:{flex:1},children:[a.jsx(on,{color:m.slate800,children:"Open to the photograph page"}),a.jsx(Eo,{children:"Hold the camera steady over the text at the bottom of the page (MRZ lines)."})]})]}),a.jsx(q1,{textAlign:"center",style:{textTransform:"uppercase",letterSpacing:.44},children:"Self will not capture an image of your ID."}),a.jsx("div",{style:{width:"100%"},children:a.jsx(et,{variant:"secondary-label",text:"Cancel",onPress:O,fullWidth:!0})})]})]})},$e=[];for(let i=0;i<256;++i)$e.push((i+256).toString(16).slice(1));function L8(i,s=0){return($e[i[s+0]]+$e[i[s+1]]+$e[i[s+2]]+$e[i[s+3]]+"-"+$e[i[s+4]]+$e[i[s+5]]+"-"+$e[i[s+6]]+$e[i[s+7]]+"-"+$e[i[s+8]]+$e[i[s+9]]+"-"+$e[i[s+10]]+$e[i[s+11]]+$e[i[s+12]]+$e[i[s+13]]+$e[i[s+14]]+$e[i[s+15]]).toLowerCase()}let As;const R8=new Uint8Array(16);function I8(){if(!As){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");As=crypto.getRandomValues.bind(crypto)}return As(R8)}const P8=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),L1={randomUUID:P8};function D8(i,s,u){var f;if(L1.randomUUID&&!i)return L1.randomUUID();i=i||{};const d=i.random??((f=i.rng)==null?void 0:f.call(i))??I8();if(d.length<16)throw new Error("Random bytes length must be >= 16");return d[6]=d[6]&15|64,d[8]=d[8]&63|128,L8(d)}const N8=()=>{const i=Dt(),s=ln(),u=Zs(),{scanner:d,analytics:f,haptic:h,documents:v}=Qt(),{countryCode:k="",documentType:w="p",passportNumber:L="",dateOfBirth:R="",dateOfExpiry:E=""}=s.state||{},[_,O]=T.useState("idle"),[b,A]=T.useState(null),[I,J]=T.useState(0),[X,ee]=T.useState(null),ue=T.useRef(null),Ee=T.useRef(D8());T.useEffect(()=>cp(u,tt=>{A(tt.message??tt.step),J(tt.percent)}),[u]);const Ie=T.useCallback(async()=>{var tt;O("scanning"),ee(null),A(null),J(0),ue.current=new AbortController;const Ne=Date.now();f.trackEvent("nfc_scan_started",{sessionId:Ee.current,documentType:w,countryCode:k});try{const Ze=await d.scan({passportNumber:L,dateOfBirth:R,dateOfExpiry:E,sessionId:Ee.current,signal:ue.current.signal}),wt=(Date.now()-Ne)/1e3;if(f.trackEvent("nfc_scan_success",{duration_seconds:wt}),h.trigger("success"),O("success"),Ze&&typeof Ze=="object"){const Ue=Ze.passportData;if(Ue&&typeof Ue=="object"){const nt=Ue.contentHash??Ee.current;await v.saveDocument(nt,Ue)}}setTimeout(()=>{i("/onboarding/confirm")},700)}catch(Ze){if((tt=ue.current)!=null&&tt.signal.aborted)return;const wt=Ze instanceof Error?Ze.message:"NFC scan failed",Ue=(Date.now()-Ne)/1e3;f.trackEvent("nfc_scan_failed",{error:wt,duration_seconds:Ue}),ee(wt),O("error")}},[d,f,h,v,i,L,R,E,w,k]),Ge=T.useCallback(()=>{var Ne;(Ne=ue.current)==null||Ne.abort(),f.trackEvent("nfc_scan_cancelled"),i("/")},[i,f]);return a.jsxs("div",{style:{display:"flex",flexDirection:"column",flex:1,height:"100vh",backgroundColor:m.white},children:[a.jsx("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:m.slate50,borderBottomLeftRadius:24,borderBottomRightRadius:24},children:_==="scanning"?a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.md},children:[a.jsx("div",{style:{width:32,height:32,border:`3px solid ${m.slate200}`,borderTopColor:m.black,borderRadius:"50%",animation:"spin 0.8s linear infinite"}}),a.jsx(on,{color:m.black,children:b??"Hold your device against the ID chip..."}),I>0&&a.jsx("div",{style:{width:200,height:4,backgroundColor:m.slate200,borderRadius:2,overflow:"hidden"},children:a.jsx("div",{style:{width:`${I}%`,height:"100%",backgroundColor:m.blue600,borderRadius:2,transition:"width 0.3s ease"}})})]}):_==="success"?a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.sm},children:[a.jsx("span",{style:{fontSize:64},children:"✅"}),a.jsx(on,{color:m.black,fontSize:18,children:"Scan complete"})]}):_==="error"?a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.sm,padding:`0 ${Re.lg}px`},children:[a.jsx("span",{style:{fontSize:48},children:"⚠️"}),a.jsx(on,{color:m.red500,textAlign:"center",children:X})]}):a.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:Re.sm},children:[a.jsx("span",{style:{fontSize:64},children:"📱"}),a.jsx(on,{color:m.slate500,children:"Ready to scan NFC chip"})]})}),a.jsxs("div",{style:{padding:Re.lg,display:"flex",flexDirection:"column",gap:Re.md,backgroundColor:m.white},children:[_==="scanning"?a.jsxs(a.Fragment,{children:[a.jsx(jo,{textAlign:"center",children:"Ready to scan"}),a.jsx(Eo,{textAlign:"center",children:"Hold your device near the NFC tag and stop moving when it vibrates."})]}):_==="error"?a.jsxs(a.Fragment,{children:[a.jsx(jo,{textAlign:"center",children:"Scan failed"}),a.jsx(Eo,{textAlign:"center",children:"Please try again. Make sure your document's chip is near your phone."}),a.jsx(et,{variant:"primary-no-icon",text:"Try Again",onPress:Ie,fullWidth:!0})]}):a.jsxs(a.Fragment,{children:[a.jsx(jo,{textAlign:"center",children:"Verify your ID"}),a.jsx(on,{color:m.slate800,textAlign:"center",children:"Find the RFID chip in your ID"}),a.jsx(Eo,{textAlign:"center",children:"Place your phone against the chip and keep it still until the sensor reads it."}),a.jsx(q1,{textAlign:"center",style:{textTransform:"uppercase",letterSpacing:.44},children:"Self does not store this information."}),a.jsx(et,{variant:"primary-no-icon",text:"Start Scan",onPress:Ie,fullWidth:!0})]}),a.jsx(et,{variant:"secondary-label",text:"Cancel",onPress:Ge,fullWidth:!0})]})]})},M8=()=>{const i=Dt(),{analytics:s,haptic:u,lifecycle:d}=Qt();T.useEffect(()=>{u.trigger("success")},[u]);const f=T.useCallback(async()=>{u.trigger("selection"),s.trackEvent("ownership_confirmed");try{await d.setResult({type:"documentOwnershipConfirmed"})}catch(h){const v=h instanceof Error?h.message:"Unknown error";s.trackEvent("proving_process_error",{error:v})}i("/")},[i,s,u,d]);return a.jsx(Y1,{variant:"success",title:"Confirm your identity",description:"By continuing, you certify that this passport, biometric ID or Aadhaar card belongs to you and is not stolen or forged. Once registered with Self, this document will be permanently linked to your identity and can't be linked to another one.",buttonText:"Confirm",onButtonPress:f,icon:a.jsx(Ys,{size:64,color:m.green500})})},_8=i=>{switch(i){case"passport":return"passport";case"id_card":return"id-card";case"aadhaar":return"aadhaar";default:return"unverified-id"}},A8=i=>{switch(i){case"passport":return"Passport";case"id_card":return"ID Card";case"aadhaar":return"Aadhaar";default:return i}},B8=()=>{const i=Dt(),{documents:s,analytics:u,haptic:d}=Qt(),[f,h]=T.useState(null),[v,k]=T.useState(!0),w=T.useCallback(async()=>{try{const O=await s.loadDocumentCatalog();h(O)}catch{h({documents:[]})}finally{k(!1)}},[s]);T.useEffect(()=>{w()},[w]);const L=f&&f.documents.length>0,R=L?f.documents[0]:void 0,E=T.useCallback(()=>{d.trigger("selection"),u.trackEvent("home_add_document_pressed"),i("/onboarding/country")},[i,d,u]),_=T.useCallback(()=>{d.trigger("selection"),i("/settings")},[i,d]);return v?a.jsx("div",{style:{display:"flex",flex:1,alignItems:"center",justifyContent:"center",height:"100vh"},children:a.jsx("div",{style:{width:32,height:32,border:"3px solid #E2E8F0",borderTopColor:"#000000",borderRadius:"50%",animation:"spin 0.8s linear infinite"}})}):a.jsx(X1,{insets:{top:0,bottom:0},idCard:R?{variant:_8(R.documentCategory),title:A8(R.documentCategory),subtitle:R.isRegistered?"Registered":"Pending registration"}:void 0,pointsCardProps:{points:0},showAddIdCTA:!L,onAddIdPress:E,topNavigationPrimaryButton:{variant:"secondary-icon",icon:({size:O,color:b})=>a.jsx(Kp,{size:O,color:b}),onPress:_}})},O8="proofRequested",z8=["Age verification","Nationality","Document validity"];function F8(i){return i.replace(/[_-]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,s=>s.toUpperCase())}function U8(i){const s=new URLSearchParams(i),u=s.get("proofItems");if(u){const f=u.split(",").map(h=>decodeURIComponent(h).trim()).filter(Boolean);if(f.length>0)return f}const d=s.get("disclosures");if(d){const f=d.split(",").map(h=>F8(decodeURIComponent(h))).filter(Boolean);if(f.length>0)return f}return null}const W8=()=>{const i=Dt(),s=ln(),u=s.state??{},{analytics:d,haptic:f,lifecycle:h}=Qt(),[v,k]=T.useState(!1),w=T.useMemo(()=>{const A=new URLSearchParams(s.search);return u.requestType??A.get("resultType")??O8},[s.search,u.requestType]),L=T.useMemo(()=>Array.isArray(u.proofItems)&&u.proofItems.length>0?u.proofItems:U8(s.search)??z8,[s.search,u.proofItems]),R=T.useMemo(()=>{const A=new URLSearchParams(s.search);return u.appName??A.get("appName")??"Verification"},[s.search,u.appName]),E=T.useMemo(()=>{const A=new URLSearchParams(s.search);return u.appEndpoint??A.get("appEndpoint")??""},[s.search,u.appEndpoint]),_=T.useMemo(()=>{if(typeof u.timestamp=="number")return u.timestamp;const A=new URLSearchParams(s.search).get("timestamp"),I=A?Number(A):Number.NaN;return Number.isFinite(I)?I:Date.now()},[s.search,u.timestamp]),O=T.useCallback(async()=>{f.trigger("selection"),d.trackEvent("prove_verify_pressed"),k(!0);try{await h.setResult({type:w}),i("/proving/result",{state:{success:!0}})}catch(A){const I=A instanceof Error?A.message:"Proving failed";d.trackEvent("prove_verify_failed",{error:I}),i("/proving/result",{state:{success:!1,error:I}})}finally{k(!1)}},[i,d,f,h,w]),b=T.useCallback(()=>{f.trigger("selection"),i("/")},[i,f]);return a.jsx(ed,{insets:{top:0,bottom:0},variant:v?"loading":"default",onClose:b,onConfirm:O,appIcon:a.jsx(K1,{size:40}),appName:R,appEndpoint:E,timestamp:_,items:L.map(A=>({label:A}))})},R1=()=>{const i=Dt(),s=ln(),{haptic:u}=Qt(),{success:d=!0,error:f}=s.state||{},h=T.useCallback(()=>{u.trigger("selection"),i("/")},[i,u]);return a.jsx(Y1,{variant:d?"success":"fail",title:d?"ID Verified":"Verification Failed",description:d?"Your document's information is now protected by Self ID. Just scan a participating partner's QR code to prove your identity.":f??"Something went wrong during verification. Please try again.",buttonText:"Continue",onButtonPress:h,icon:d?a.jsx(Ys,{size:64,color:m.green500}):a.jsx(e0,{size:64,color:m.red500})})},b8=()=>{const i=Dt(),{analytics:s,haptic:u,lifecycle:d}=Qt(),f=T.useCallback(()=>{u.trigger("selection"),i("/")},[i,u]),h=T.useCallback(async()=>{u.trigger("selection"),s.trackEvent("settings_dismiss_pressed"),d.dismiss()},[u,s,d]);return a.jsx(rd,{insets:{top:0,bottom:0},escapeIcon:({size:v,color:k})=>a.jsx(Qs,{size:v,color:k}),infoIcon:({size:v,color:k})=>a.jsx(Io,{size:v,color:k}),onClose:f,showBackupInfoBox:!1,isBackupEnabled:!1,CTAs:[],sections:[{title:"Account",items:[{icon:r0,label:"View document info",description:"View your stored document details",onPress:()=>i("/coming-soon")},{icon:Qp,label:"Recovery phrase",description:"View your recovery phrase",onPress:()=>i("/coming-soon")},{icon:t0,label:"Cloud backup",description:"Manage your cloud backup",onPress:()=>i("/coming-soon")}]},{title:"Support",items:[{icon:qp,label:"Get support",description:"Contact us for help",onPress:()=>i("/coming-soon")},{icon:Yp,label:"Share Self",description:"Share Self with friends",onPress:()=>i("/coming-soon")}]}],connectHeading:"",connectSubheading:"",connectButtons:[],bottomSectionItems:[{label:"Close Self",onPress:h}]})},H8=()=>{const i=Dt(),s=ln(),{analytics:u,haptic:d}=Qt(),{countryCode:f="",documentType:h}=s.state||{},v=h==="i"?"ID Cards":h==="p"?"Passports":"",k=T.useCallback(()=>{d.trigger("selection"),u.trackEvent("coming_soon_dismissed"),i("/")},[i,d,u]),w=T.useCallback(()=>{d.trigger("selection"),u.trackEvent("coming_soon_notify_me"),i("/")},[i,d,u]);return a.jsx(nd,{insets:{top:0,bottom:0},countryCode:f,countryName:Js(f),subtitle:v?`We're working to roll out support for ${v}.`:"We're working to roll out support for this feature.",description:"If you'd like to be notified when this becomes available, let us know.",onSignUpPress:w,onBack:k,renderFlag:Xs})},V8=()=>a.jsx(sp,{children:a.jsx(bp,{children:a.jsxs(ip,{children:[a.jsx(xt,{path:"/",element:a.jsx(B8,{})}),a.jsx(xt,{path:"/onboarding/country",element:a.jsx(S8,{})}),a.jsx(xt,{path:"/onboarding/id-type",element:a.jsx(E8,{})}),a.jsx(xt,{path:"/onboarding/camera",element:a.jsx(T8,{})}),a.jsx(xt,{path:"/onboarding/nfc",element:a.jsx(N8,{})}),a.jsx(xt,{path:"/onboarding/confirm",element:a.jsx(M8,{})}),a.jsx(xt,{path:"/proving",element:a.jsx(W8,{})}),a.jsx(xt,{path:"/proving/result",element:a.jsx(R1,{})}),a.jsx(xt,{path:"/settings",element:a.jsx(b8,{})}),a.jsx(xt,{path:"/account/verified",element:a.jsx(R1,{})}),a.jsx(xt,{path:"/coming-soon",element:a.jsx(H8,{})}),a.jsx(xt,{path:"*",element:a.jsx(np,{to:"/",replace:!0})})]})})});f2.createRoot(document.getElementById("root")).render(a.jsx(P1.StrictMode,{children:a.jsx("div",{style:{display:"flex",flex:1,height:"100vh",width:"100%"},children:a.jsx(Wp,{children:a.jsx(V8,{})})})})); +//# sourceMappingURL=index-BZlxLbn7.js.map diff --git a/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js.map b/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js.map new file mode 100644 index 000000000..d778eb32d --- /dev/null +++ b/packages/rn-sdk/assets/self-wallet/assets/index-BZlxLbn7.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index-BZlxLbn7.js","sources":["../../node_modules/react/cjs/react.production.min.js","../../node_modules/react/index.js","../../node_modules/react/cjs/react-jsx-runtime.production.min.js","../../node_modules/react/jsx-runtime.js","../../node_modules/scheduler/cjs/scheduler.production.min.js","../../node_modules/scheduler/index.js","../../node_modules/react-dom/cjs/react-dom.production.min.js","../../node_modules/react-dom/index.js","../../node_modules/react-dom/client.js","../../node_modules/@remix-run/router/dist/router.js","../../node_modules/react-router/dist/index.js","../../node_modules/react-router-dom/dist/index.js","../../../webview-bridge/dist/adapters.js","../../../webview-bridge/node_modules/uuid/dist/esm-browser/stringify.js","../../../webview-bridge/node_modules/uuid/dist/esm-browser/rng.js","../../../webview-bridge/node_modules/uuid/dist/esm-browser/native.js","../../../webview-bridge/node_modules/uuid/dist/esm-browser/v4.js","../../../webview-bridge/dist/index.js","../../src/providers/BridgeProvider.tsx","../../src/providers/SelfClientProvider.tsx","../../node_modules/@selfxyz/euclid-core/dist/theme/colors.js","../../node_modules/@selfxyz/euclid-core/dist/theme/spacing.js","../../node_modules/@selfxyz/euclid-core/dist/theme/typography.js","../../node_modules/@selfxyz/euclid-web/dist/theme/index.js","../../node_modules/@selfxyz/euclid-web/dist/components/Button.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/BaseIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/PlusIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/IDCardLogoIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/DevPassportIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/StarFillIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/GearIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/LeftArrowIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/XIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/ChevronRightIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/LockIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/ShareIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/ChatStrokeIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/CheckDiamondIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/QuestionCircleStrokeIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/SearchLocationIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/WarningOctagonIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/CloudKeyIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/ClockIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/DocumentDetailsIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/InfoCircleIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/icons/CheckCircleIcon.js","../../node_modules/@selfxyz/euclid-web/dist/components/TopNavigation.js","../../node_modules/@selfxyz/euclid-web/dist/components/TopNavigationDialogue.js","../../node_modules/@selfxyz/euclid-web/dist/components/SelfLogo.js","../../node_modules/@selfxyz/euclid-web/dist/components/DetailedTableViewCell.js","../../node_modules/@selfxyz/euclid-web/dist/components/DetailedTableView.js","../../node_modules/@selfxyz/euclid-web/dist/components/TableViewCell.js","../../node_modules/@selfxyz/euclid-web/dist/components/TableView.js","../../node_modules/@selfxyz/euclid-web/dist/components/content-cards/ContentCardCTA.js","../../node_modules/@selfxyz/euclid-web/dist/components/content-cards/ContentCardGrid.js","../../node_modules/@selfxyz/euclid-web/dist/components/SearchField.js","../../node_modules/@selfxyz/euclid-web/dist/components/id-card/IDCard.js","../../node_modules/@selfxyz/euclid-web/dist/components/ProofRequest.js","../../node_modules/@selfxyz/euclid-web/dist/components/SelfPointsCard.js","../../node_modules/@selfxyz/euclid-web/dist/components/TileCard.js","../../node_modules/@selfxyz/euclid-web/dist/components/EarnPointsTile.js","../../node_modules/@selfxyz/euclid-web/dist/components/IDTypeCard.js","../../node_modules/@selfxyz/euclid-web/dist/components/LottieAnimation.js","../../node_modules/@selfxyz/euclid-web/dist/components/StatusState.js","../../node_modules/@selfxyz/euclid-web/dist/components/ProofButton.js","../../node_modules/@selfxyz/euclid-web/dist/components/EmptyState.js","../../node_modules/@selfxyz/euclid-web/dist/components/typography/Title.js","../../node_modules/@selfxyz/euclid-web/dist/components/typography/Description.js","../../node_modules/@selfxyz/euclid-web/dist/components/typography/BodyText.js","../../node_modules/@selfxyz/euclid-web/dist/components/typography/Caption.js","../../node_modules/@selfxyz/euclid-web/dist/screens/CountryPickerScreen.js","../../node_modules/@selfxyz/euclid-web/dist/screens/HomeScreen.js","../../node_modules/@selfxyz/euclid-web/dist/screens/ProofRequestScreen.js","../../node_modules/@selfxyz/euclid-web/dist/screens/IDTypeScreen.js","../../node_modules/@selfxyz/euclid-web/dist/screens/ComingSoonScreen.js","../../node_modules/@selfxyz/euclid-web/dist/screens/SettingsViewScreen.js","../../src/utils/countryFlags.tsx","../../src/screens/onboarding/CountryPickerScreen.tsx","../../src/screens/onboarding/IDSelectionScreen.tsx","../../src/screens/onboarding/DocumentCameraScreen.tsx","../../node_modules/uuid/dist/esm-browser/stringify.js","../../node_modules/uuid/dist/esm-browser/rng.js","../../node_modules/uuid/dist/esm-browser/native.js","../../node_modules/uuid/dist/esm-browser/v4.js","../../src/screens/onboarding/DocumentNFCScreen.tsx","../../src/screens/onboarding/ConfirmIdentificationScreen.tsx","../../src/screens/home/HomeScreen.tsx","../../src/screens/proving/ProvingScreen.tsx","../../src/screens/proving/VerificationResultScreen.tsx","../../src/screens/account/SettingsScreen.tsx","../../src/screens/ComingSoonScreen.tsx","../../src/App.tsx","../../src/main.tsx"],"sourcesContent":["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1>>1,e=a[d];if(0>>1;dg(C,c))ng(x,C)?(a[d]=x,a[n]=c,d=n):(a[d]=C,a[m]=c,d=m);else if(ng(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if(\"object\"===typeof performance&&\"function\"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D=\"function\"===typeof setTimeout?setTimeout:null,E=\"function\"===typeof clearTimeout?clearTimeout:null,F=\"undefined\"!==typeof setImmediate?setImmediate:null;\n\"undefined\"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if(\"function\"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Qa||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n'use strict';var aa=require(\"react\"),ca=require(\"scheduler\");function p(a){for(var b=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=1;cb}return!1}function v(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}var z={};\n\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){z[a]=new v(a,0,!1,a,null,!1,!1)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var b=a[0];z[b]=new v(b,1,!1,a[1],null,!1,!1)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){z[a]=new v(a,2,!1,a.toLowerCase(),null,!1,!1)});\n[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){z[a]=new v(a,2,!1,a,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\".split(\" \").forEach(function(a){z[a]=new v(a,3,!1,a.toLowerCase(),null,!1,!1)});\n[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){z[a]=new v(a,3,!0,a,null,!1,!1)});[\"capture\",\"download\"].forEach(function(a){z[a]=new v(a,4,!1,a,null,!1,!1)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){z[a]=new v(a,6,!1,a,null,!1,!1)});[\"rowSpan\",\"start\"].forEach(function(a){z[a]=new v(a,5,!1,a.toLowerCase(),null,!1,!1)});var ra=/[\\-:]([a-z])/g;function sa(a){return a[1].toUpperCase()}\n\"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\".split(\" \").forEach(function(a){var b=a.replace(ra,\nsa);z[b]=new v(b,1,!1,a,null,!1,!1)});\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,\"http://www.w3.org/1999/xlink\",!1,!1)});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,\"http://www.w3.org/XML/1998/namespace\",!1,!1)});[\"tabIndex\",\"crossOrigin\"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!1,!1)});\nz.xlinkHref=new v(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0,!1);[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!0,!0)});\nfunction ta(a,b,c,d){var e=z.hasOwnProperty(b)?z[b]:null;if(null!==e?0!==e.type:d||!(2h||e[g]!==f[h]){var k=\"\\n\"+e[g].replace(\" at new \",\" at \");a.displayName&&k.includes(\"\")&&(k=k.replace(\"\",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{Na=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:\"\")?Ma(a):\"\"}\nfunction Pa(a){switch(a.tag){case 5:return Ma(a.type);case 16:return Ma(\"Lazy\");case 13:return Ma(\"Suspense\");case 19:return Ma(\"SuspenseList\");case 0:case 2:case 15:return a=Oa(a.type,!1),a;case 11:return a=Oa(a.type.render,!1),a;case 1:return a=Oa(a.type,!0),a;default:return\"\"}}\nfunction Qa(a){if(null==a)return null;if(\"function\"===typeof a)return a.displayName||a.name||null;if(\"string\"===typeof a)return a;switch(a){case ya:return\"Fragment\";case wa:return\"Portal\";case Aa:return\"Profiler\";case za:return\"StrictMode\";case Ea:return\"Suspense\";case Fa:return\"SuspenseList\"}if(\"object\"===typeof a)switch(a.$$typeof){case Ca:return(a.displayName||\"Context\")+\".Consumer\";case Ba:return(a._context.displayName||\"Context\")+\".Provider\";case Da:var b=a.render;a=a.displayName;a||(a=b.displayName||\nb.name||\"\",a=\"\"!==a?\"ForwardRef(\"+a+\")\":\"ForwardRef\");return a;case Ga:return b=a.displayName||null,null!==b?b:Qa(a.type)||\"Memo\";case Ha:b=a._payload;a=a._init;try{return Qa(a(b))}catch(c){}}return null}\nfunction Ra(a){var b=a.type;switch(a.tag){case 24:return\"Cache\";case 9:return(b.displayName||\"Context\")+\".Consumer\";case 10:return(b._context.displayName||\"Context\")+\".Provider\";case 18:return\"DehydratedFragment\";case 11:return a=b.render,a=a.displayName||a.name||\"\",b.displayName||(\"\"!==a?\"ForwardRef(\"+a+\")\":\"ForwardRef\");case 7:return\"Fragment\";case 5:return b;case 4:return\"Portal\";case 3:return\"Root\";case 6:return\"Text\";case 16:return Qa(b);case 8:return b===za?\"StrictMode\":\"Mode\";case 22:return\"Offscreen\";\ncase 12:return\"Profiler\";case 21:return\"Scope\";case 13:return\"Suspense\";case 19:return\"SuspenseList\";case 25:return\"TracingMarker\";case 1:case 0:case 17:case 2:case 14:case 15:if(\"function\"===typeof b)return b.displayName||b.name||null;if(\"string\"===typeof b)return b}return null}function Sa(a){switch(typeof a){case \"boolean\":case \"number\":case \"string\":case \"undefined\":return a;case \"object\":return a;default:return\"\"}}\nfunction Ta(a){var b=a.type;return(a=a.nodeName)&&\"input\"===a.toLowerCase()&&(\"checkbox\"===b||\"radio\"===b)}\nfunction Ua(a){var b=Ta(a)?\"checked\":\"value\",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=\"\"+a[b];if(!a.hasOwnProperty(b)&&\"undefined\"!==typeof c&&\"function\"===typeof c.get&&\"function\"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=\"\"+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=\"\"+a},stopTracking:function(){a._valueTracker=\nnull;delete a[b]}}}}function Va(a){a._valueTracker||(a._valueTracker=Ua(a))}function Wa(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d=\"\";a&&(d=Ta(a)?a.checked?\"true\":\"false\":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Xa(a){a=a||(\"undefined\"!==typeof document?document:void 0);if(\"undefined\"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}\nfunction Ya(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Za(a,b){var c=null==b.defaultValue?\"\":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Sa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:\"checkbox\"===b.type||\"radio\"===b.type?null!=b.checked:null!=b.value}}function ab(a,b){b=b.checked;null!=b&&ta(a,\"checked\",b,!1)}\nfunction bb(a,b){ab(a,b);var c=Sa(b.value),d=b.type;if(null!=c)if(\"number\"===d){if(0===c&&\"\"===a.value||a.value!=c)a.value=\"\"+c}else a.value!==\"\"+c&&(a.value=\"\"+c);else if(\"submit\"===d||\"reset\"===d){a.removeAttribute(\"value\");return}b.hasOwnProperty(\"value\")?cb(a,b.type,c):b.hasOwnProperty(\"defaultValue\")&&cb(a,b.type,Sa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}\nfunction db(a,b,c){if(b.hasOwnProperty(\"value\")||b.hasOwnProperty(\"defaultValue\")){var d=b.type;if(!(\"submit\"!==d&&\"reset\"!==d||void 0!==b.value&&null!==b.value))return;b=\"\"+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;\"\"!==c&&(a.name=\"\");a.defaultChecked=!!a._wrapperState.initialChecked;\"\"!==c&&(a.name=c)}\nfunction cb(a,b,c){if(\"number\"!==b||Xa(a.ownerDocument)!==a)null==c?a.defaultValue=\"\"+a._wrapperState.initialValue:a.defaultValue!==\"\"+c&&(a.defaultValue=\"\"+c)}var eb=Array.isArray;\nfunction fb(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e\"+b.valueOf().toString()+\"\";for(b=mb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction ob(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}\nvar pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,\nzoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=[\"Webkit\",\"ms\",\"Moz\",\"O\"];Object.keys(pb).forEach(function(a){qb.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);pb[b]=pb[a]})});function rb(a,b,c){return null==b||\"boolean\"===typeof b||\"\"===b?\"\":c||\"number\"!==typeof b||0===b||pb.hasOwnProperty(a)&&pb[a]?(\"\"+b).trim():b+\"px\"}\nfunction sb(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf(\"--\"),e=rb(c,b[c],d);\"float\"===c&&(c=\"cssFloat\");d?a.setProperty(c,e):a[c]=e}}var tb=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});\nfunction ub(a,b){if(b){if(tb[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(p(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(p(60));if(\"object\"!==typeof b.dangerouslySetInnerHTML||!(\"__html\"in b.dangerouslySetInnerHTML))throw Error(p(61));}if(null!=b.style&&\"object\"!==typeof b.style)throw Error(p(62));}}\nfunction vb(a,b){if(-1===a.indexOf(\"-\"))return\"string\"===typeof b.is;switch(a){case \"annotation-xml\":case \"color-profile\":case \"font-face\":case \"font-face-src\":case \"font-face-uri\":case \"font-face-format\":case \"font-face-name\":case \"missing-glyph\":return!1;default:return!0}}var wb=null;function xb(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}var yb=null,zb=null,Ab=null;\nfunction Bb(a){if(a=Cb(a)){if(\"function\"!==typeof yb)throw Error(p(280));var b=a.stateNode;b&&(b=Db(b),yb(a.stateNode,a.type,b))}}function Eb(a){zb?Ab?Ab.push(a):Ab=[a]:zb=a}function Fb(){if(zb){var a=zb,b=Ab;Ab=zb=null;Bb(a);if(b)for(a=0;a>>=0;return 0===a?32:31-(pc(a)/qc|0)|0}var rc=64,sc=4194304;\nfunction tc(a){switch(a&-a){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: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 a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;\ndefault:return a}}function uc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=tc(h):(f&=g,0!==f&&(d=tc(f)))}else g=c&~e,0!==g?d=tc(g):0!==f&&(d=tc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0c;c++)b.push(a);return b}\nfunction Ac(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-oc(b);a[b]=c}function Bc(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0=be),ee=String.fromCharCode(32),fe=!1;\nfunction ge(a,b){switch(a){case \"keyup\":return-1!==$d.indexOf(b.keyCode);case \"keydown\":return 229!==b.keyCode;case \"keypress\":case \"mousedown\":case \"focusout\":return!0;default:return!1}}function he(a){a=a.detail;return\"object\"===typeof a&&\"data\"in a?a.data:null}var ie=!1;function je(a,b){switch(a){case \"compositionend\":return he(b);case \"keypress\":if(32!==b.which)return null;fe=!0;return ee;case \"textInput\":return a=b.data,a===ee&&fe?null:a;default:return null}}\nfunction ke(a,b){if(ie)return\"compositionend\"===a||!ae&&ge(a,b)?(a=nd(),md=ld=kd=null,ie=!1,a):null;switch(a){case \"paste\":return null;case \"keypress\":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Je(c)}}function Le(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Le(a,b.parentNode):\"contains\"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}\nfunction Me(){for(var a=window,b=Xa();b instanceof a.HTMLIFrameElement;){try{var c=\"string\"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Xa(a.document)}return b}function Ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&(\"input\"===b&&(\"text\"===a.type||\"search\"===a.type||\"tel\"===a.type||\"url\"===a.type||\"password\"===a.type)||\"textarea\"===b||\"true\"===a.contentEditable)}\nfunction Oe(a){var b=Me(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Le(c.ownerDocument.documentElement,c)){if(null!==d&&Ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),\"selectionStart\"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ke(c,f);var g=Ke(c,\nd);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});\"function\"===typeof c.focus&&c.focus();for(c=0;c=document.documentMode,Qe=null,Re=null,Se=null,Te=!1;\nfunction Ue(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Te||null==Qe||Qe!==Xa(d)||(d=Qe,\"selectionStart\"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re,\"onSelect\"),0Tf||(a.current=Sf[Tf],Sf[Tf]=null,Tf--)}function G(a,b){Tf++;Sf[Tf]=a.current;a.current=b}var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a,b){var c=a.type.contextTypes;if(!c)return Vf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}\nfunction Zf(a){a=a.childContextTypes;return null!==a&&void 0!==a}function $f(){E(Wf);E(H)}function ag(a,b,c){if(H.current!==Vf)throw Error(p(168));G(H,b);G(Wf,c)}function bg(a,b,c){var d=a.stateNode;b=b.childContextTypes;if(\"function\"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(p(108,Ra(a)||\"Unknown\",e));return A({},c,d)}\nfunction cg(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Vf;Xf=H.current;G(H,a);G(Wf,Wf.current);return!0}function dg(a,b,c){var d=a.stateNode;if(!d)throw Error(p(169));c?(a=bg(a,b,Xf),d.__reactInternalMemoizedMergedChildContext=a,E(Wf),E(H),G(H,a)):E(Wf);G(Wf,c)}var eg=null,fg=!1,gg=!1;function hg(a){null===eg?eg=[a]:eg.push(a)}function ig(a){fg=!0;hg(a)}\nfunction jg(){if(!gg&&null!==eg){gg=!0;var a=0,b=C;try{var c=eg;for(C=1;a>=g;e-=g;rg=1<<32-oc(b)+e|c<w?(x=u,u=null):x=u.sibling;var n=r(e,u,h[w],k);if(null===n){null===u&&(u=x);break}a&&u&&null===n.alternate&&b(e,u);g=f(n,g,w);null===m?l=n:m.sibling=n;m=n;u=x}if(w===h.length)return c(e,u),I&&tg(e,w),l;if(null===u){for(;ww?(x=m,m=null):x=m.sibling;var t=r(e,m,n.value,k);if(null===t){null===m&&(m=x);break}a&&m&&null===t.alternate&&b(e,m);g=f(t,g,w);null===u?l=t:u.sibling=t;u=t;m=x}if(n.done)return c(e,\nm),I&&tg(e,w),l;if(null===m){for(;!n.done;w++,n=h.next())n=q(e,n.value,k),null!==n&&(g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);I&&tg(e,w);return l}for(m=d(e,m);!n.done;w++,n=h.next())n=y(m,e,w,n.value,k),null!==n&&(a&&null!==n.alternate&&m.delete(null===n.key?w:n.key),g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);a&&m.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function J(a,d,f,h){\"object\"===typeof f&&null!==f&&f.type===ya&&null===f.key&&(f=f.props.children);if(\"object\"===typeof f&&null!==f){switch(f.$$typeof){case va:a:{for(var k=\nf.key,l=d;null!==l;){if(l.key===k){k=f.type;if(k===ya){if(7===l.tag){c(a,l.sibling);d=e(l,f.props.children);d.return=a;a=d;break a}}else if(l.elementType===k||\"object\"===typeof k&&null!==k&&k.$$typeof===Ha&&Ng(k)===l.type){c(a,l.sibling);d=e(l,f.props);d.ref=Lg(a,l,f);d.return=a;a=d;break a}c(a,l);break}else b(a,l);l=l.sibling}f.type===ya?(d=Tg(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=Rg(f.type,f.key,f.props,null,a.mode,h),h.ref=Lg(a,d,f),h.return=a,a=h)}return g(a);case wa:a:{for(l=f.key;null!==\nd;){if(d.key===l)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=Sg(f,a.mode,h);d.return=a;a=d}return g(a);case Ha:return l=f._init,J(a,d,l(f._payload),h)}if(eb(f))return n(a,d,f,h);if(Ka(f))return t(a,d,f,h);Mg(a,f)}return\"string\"===typeof f&&\"\"!==f||\"number\"===typeof f?(f=\"\"+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):\n(c(a,d),d=Qg(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return J}var Ug=Og(!0),Vg=Og(!1),Wg=Uf(null),Xg=null,Yg=null,Zg=null;function $g(){Zg=Yg=Xg=null}function ah(a){var b=Wg.current;E(Wg);a._currentValue=b}function bh(a,b,c){for(;null!==a;){var d=a.alternate;(a.childLanes&b)!==b?(a.childLanes|=b,null!==d&&(d.childLanes|=b)):null!==d&&(d.childLanes&b)!==b&&(d.childLanes|=b);if(a===c)break;a=a.return}}\nfunction ch(a,b){Xg=a;Zg=Yg=null;a=a.dependencies;null!==a&&null!==a.firstContext&&(0!==(a.lanes&b)&&(dh=!0),a.firstContext=null)}function eh(a){var b=a._currentValue;if(Zg!==a)if(a={context:a,memoizedValue:b,next:null},null===Yg){if(null===Xg)throw Error(p(308));Yg=a;Xg.dependencies={lanes:0,firstContext:a}}else Yg=Yg.next=a;return b}var fh=null;function gh(a){null===fh?fh=[a]:fh.push(a)}\nfunction hh(a,b,c,d){var e=b.interleaved;null===e?(c.next=c,gh(b)):(c.next=e.next,e.next=c);b.interleaved=c;return ih(a,d)}function ih(a,b){a.lanes|=b;var c=a.alternate;null!==c&&(c.lanes|=b);c=a;for(a=a.return;null!==a;)a.childLanes|=b,c=a.alternate,null!==c&&(c.childLanes|=b),c=a,a=a.return;return 3===c.tag?c.stateNode:null}var jh=!1;function kh(a){a.updateQueue={baseState:a.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}\nfunction lh(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,firstBaseUpdate:a.firstBaseUpdate,lastBaseUpdate:a.lastBaseUpdate,shared:a.shared,effects:a.effects})}function mh(a,b){return{eventTime:a,lane:b,tag:0,payload:null,callback:null,next:null}}\nfunction nh(a,b,c){var d=a.updateQueue;if(null===d)return null;d=d.shared;if(0!==(K&2)){var e=d.pending;null===e?b.next=b:(b.next=e.next,e.next=b);d.pending=b;return ih(a,c)}e=d.interleaved;null===e?(b.next=b,gh(d)):(b.next=e.next,e.next=b);d.interleaved=b;return ih(a,c)}function oh(a,b,c){b=b.updateQueue;if(null!==b&&(b=b.shared,0!==(c&4194240))){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nfunction ph(a,b){var c=a.updateQueue,d=a.alternate;if(null!==d&&(d=d.updateQueue,c===d)){var e=null,f=null;c=c.firstBaseUpdate;if(null!==c){do{var g={eventTime:c.eventTime,lane:c.lane,tag:c.tag,payload:c.payload,callback:c.callback,next:null};null===f?e=f=g:f=f.next=g;c=c.next}while(null!==c);null===f?e=f=b:f=f.next=b}else e=f=b;c={baseState:d.baseState,firstBaseUpdate:e,lastBaseUpdate:f,shared:d.shared,effects:d.effects};a.updateQueue=c;return}a=c.lastBaseUpdate;null===a?c.firstBaseUpdate=b:a.next=\nb;c.lastBaseUpdate=b}\nfunction qh(a,b,c,d){var e=a.updateQueue;jh=!1;var f=e.firstBaseUpdate,g=e.lastBaseUpdate,h=e.shared.pending;if(null!==h){e.shared.pending=null;var k=h,l=k.next;k.next=null;null===g?f=l:g.next=l;g=k;var m=a.alternate;null!==m&&(m=m.updateQueue,h=m.lastBaseUpdate,h!==g&&(null===h?m.firstBaseUpdate=l:h.next=l,m.lastBaseUpdate=k))}if(null!==f){var q=e.baseState;g=0;m=l=k=null;h=f;do{var r=h.lane,y=h.eventTime;if((d&r)===r){null!==m&&(m=m.next={eventTime:y,lane:0,tag:h.tag,payload:h.payload,callback:h.callback,\nnext:null});a:{var n=a,t=h;r=b;y=c;switch(t.tag){case 1:n=t.payload;if(\"function\"===typeof n){q=n.call(y,q,r);break a}q=n;break a;case 3:n.flags=n.flags&-65537|128;case 0:n=t.payload;r=\"function\"===typeof n?n.call(y,q,r):n;if(null===r||void 0===r)break a;q=A({},q,r);break a;case 2:jh=!0}}null!==h.callback&&0!==h.lane&&(a.flags|=64,r=e.effects,null===r?e.effects=[h]:r.push(h))}else y={eventTime:y,lane:r,tag:h.tag,payload:h.payload,callback:h.callback,next:null},null===m?(l=m=y,k=q):m=m.next=y,g|=r;\nh=h.next;if(null===h)if(h=e.shared.pending,null===h)break;else r=h,h=r.next,r.next=null,e.lastBaseUpdate=r,e.shared.pending=null}while(1);null===m&&(k=q);e.baseState=k;e.firstBaseUpdate=l;e.lastBaseUpdate=m;b=e.shared.interleaved;if(null!==b){e=b;do g|=e.lane,e=e.next;while(e!==b)}else null===f&&(e.shared.lanes=0);rh|=g;a.lanes=g;a.memoizedState=q}}\nfunction sh(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;bc?c:4;a(!0);var d=Gh.transition;Gh.transition={};try{a(!1),b()}finally{C=c,Gh.transition=d}}function wi(){return Uh().memoizedState}\nfunction xi(a,b,c){var d=yi(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(zi(a))Ai(b,c);else if(c=hh(a,b,c,d),null!==c){var e=R();gi(c,a,d,e);Bi(c,b,d)}}\nfunction ii(a,b,c){var d=yi(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(zi(a))Ai(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(He(h,g)){var k=b.interleaved;null===k?(e.next=e,gh(b)):(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(l){}finally{}c=hh(a,b,e,d);null!==c&&(e=R(),gi(c,a,d,e),Bi(c,b,d))}}\nfunction zi(a){var b=a.alternate;return a===M||null!==b&&b===M}function Ai(a,b){Jh=Ih=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function Bi(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nvar Rh={readContext:eh,useCallback:P,useContext:P,useEffect:P,useImperativeHandle:P,useInsertionEffect:P,useLayoutEffect:P,useMemo:P,useReducer:P,useRef:P,useState:P,useDebugValue:P,useDeferredValue:P,useTransition:P,useMutableSource:P,useSyncExternalStore:P,useId:P,unstable_isNewReconciler:!1},Oh={readContext:eh,useCallback:function(a,b){Th().memoizedState=[a,void 0===b?null:b];return a},useContext:eh,useEffect:mi,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ki(4194308,\n4,pi.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ki(4194308,4,a,b)},useInsertionEffect:function(a,b){return ki(4,2,a,b)},useMemo:function(a,b){var c=Th();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=Th();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=xi.bind(null,M,a);return[d.memoizedState,a]},useRef:function(a){var b=\nTh();a={current:a};return b.memoizedState=a},useState:hi,useDebugValue:ri,useDeferredValue:function(a){return Th().memoizedState=a},useTransition:function(){var a=hi(!1),b=a[0];a=vi.bind(null,a[1]);Th().memoizedState=a;return[b,a]},useMutableSource:function(){},useSyncExternalStore:function(a,b,c){var d=M,e=Th();if(I){if(void 0===c)throw Error(p(407));c=c()}else{c=b();if(null===Q)throw Error(p(349));0!==(Hh&30)||di(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;mi(ai.bind(null,d,\nf,a),[a]);d.flags|=2048;bi(9,ci.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=Th(),b=Q.identifierPrefix;if(I){var c=sg;var d=rg;c=(d&~(1<<32-oc(d)-1)).toString(32)+c;b=\":\"+b+\"R\"+c;c=Kh++;0\\x3c/script>\",a=a.removeChild(a.firstChild)):\n\"string\"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),\"select\"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Of]=b;a[Pf]=d;zj(a,b,!1,!1);b.stateNode=a;a:{g=vb(c,d);switch(c){case \"dialog\":D(\"cancel\",a);D(\"close\",a);e=d;break;case \"iframe\":case \"object\":case \"embed\":D(\"load\",a);e=d;break;case \"video\":case \"audio\":for(e=0;eGj&&(b.flags|=128,d=!0,Dj(f,!1),b.lanes=4194304)}else{if(!d)if(a=Ch(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Dj(f,!0),null===f.tail&&\"hidden\"===f.tailMode&&!g.alternate&&!I)return S(b),null}else 2*B()-f.renderingStartTime>Gj&&1073741824!==c&&(b.flags|=128,d=!0,Dj(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering=\nb,f.tail=b.sibling,f.renderingStartTime=B(),b.sibling=null,c=L.current,G(L,d?c&1|2:c&1),b;S(b);return null;case 22:case 23:return Hj(),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(fj&1073741824)&&(S(b),b.subtreeFlags&6&&(b.flags|=8192)):S(b),null;case 24:return null;case 25:return null}throw Error(p(156,b.tag));}\nfunction Ij(a,b){wg(b);switch(b.tag){case 1:return Zf(b.type)&&$f(),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return zh(),E(Wf),E(H),Eh(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return Bh(b),null;case 13:E(L);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(p(340));Ig()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return E(L),null;case 4:return zh(),null;case 10:return ah(b.type._context),null;case 22:case 23:return Hj(),\nnull;case 24:return null;default:return null}}var Jj=!1,U=!1,Kj=\"function\"===typeof WeakSet?WeakSet:Set,V=null;function Lj(a,b){var c=a.ref;if(null!==c)if(\"function\"===typeof c)try{c(null)}catch(d){W(a,b,d)}else c.current=null}function Mj(a,b,c){try{c()}catch(d){W(a,b,d)}}var Nj=!1;\nfunction Oj(a,b){Cf=dd;a=Me();if(Ne(a)){if(\"selectionStart\"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(F){c=null;break a}var g=0,h=-1,k=-1,l=0,m=0,q=a,r=null;b:for(;;){for(var y;;){q!==c||0!==e&&3!==q.nodeType||(h=g+e);q!==f||0!==d&&3!==q.nodeType||(k=g+d);3===q.nodeType&&(g+=\nq.nodeValue.length);if(null===(y=q.firstChild))break;r=q;q=y}for(;;){if(q===a)break b;r===c&&++l===e&&(h=g);r===f&&++m===d&&(k=g);if(null!==(y=q.nextSibling))break;q=r;r=q.parentNode}q=y}c=-1===h||-1===k?null:{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Df={focusedElem:a,selectionRange:c};dd=!1;for(V=b;null!==V;)if(b=V,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,V=a;else for(;null!==V;){b=V;try{var n=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break;\ncase 1:if(null!==n){var t=n.memoizedProps,J=n.memoizedState,x=b.stateNode,w=x.getSnapshotBeforeUpdate(b.elementType===b.type?t:Ci(b.type,t),J);x.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var u=b.stateNode.containerInfo;1===u.nodeType?u.textContent=\"\":9===u.nodeType&&u.documentElement&&u.removeChild(u.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p(163));}}catch(F){W(b,b.return,F)}a=b.sibling;if(null!==a){a.return=b.return;V=a;break}V=b.return}n=Nj;Nj=!1;return n}\nfunction Pj(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&Mj(b,c,f)}e=e.next}while(e!==d)}}function Qj(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Rj(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}\"function\"===typeof b?b(a):b.current=a}}\nfunction Sj(a){var b=a.alternate;null!==b&&(a.alternate=null,Sj(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Of],delete b[Pf],delete b[of],delete b[Qf],delete b[Rf]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Tj(a){return 5===a.tag||3===a.tag||4===a.tag}\nfunction Uj(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Tj(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}}\nfunction Vj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Bf));else if(4!==d&&(a=a.child,null!==a))for(Vj(a,b,c),a=a.sibling;null!==a;)Vj(a,b,c),a=a.sibling}\nfunction Wj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Wj(a,b,c),a=a.sibling;null!==a;)Wj(a,b,c),a=a.sibling}var X=null,Xj=!1;function Yj(a,b,c){for(c=c.child;null!==c;)Zj(a,b,c),c=c.sibling}\nfunction Zj(a,b,c){if(lc&&\"function\"===typeof lc.onCommitFiberUnmount)try{lc.onCommitFiberUnmount(kc,c)}catch(h){}switch(c.tag){case 5:U||Lj(c,b);case 6:var d=X,e=Xj;X=null;Yj(a,b,c);X=d;Xj=e;null!==X&&(Xj?(a=X,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):X.removeChild(c.stateNode));break;case 18:null!==X&&(Xj?(a=X,c=c.stateNode,8===a.nodeType?Kf(a.parentNode,c):1===a.nodeType&&Kf(a,c),bd(a)):Kf(X,c.stateNode));break;case 4:d=X;e=Xj;X=c.stateNode.containerInfo;Xj=!0;\nYj(a,b,c);X=d;Xj=e;break;case 0:case 11:case 14:case 15:if(!U&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?Mj(c,b,g):0!==(f&4)&&Mj(c,b,g));e=e.next}while(e!==d)}Yj(a,b,c);break;case 1:if(!U&&(Lj(c,b),d=c.stateNode,\"function\"===typeof d.componentWillUnmount))try{d.props=c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){W(c,b,h)}Yj(a,b,c);break;case 21:Yj(a,b,c);break;case 22:c.mode&1?(U=(d=U)||null!==\nc.memoizedState,Yj(a,b,c),U=d):Yj(a,b,c);break;default:Yj(a,b,c)}}function ak(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Kj);b.forEach(function(b){var d=bk.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}\nfunction ck(a,b){var c=b.deletions;if(null!==c)for(var d=0;de&&(e=g);d&=~f}d=e;d=B()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*lk(d/1960))-d;if(10a?16:a;if(null===wk)var d=!1;else{a=wk;wk=null;xk=0;if(0!==(K&6))throw Error(p(331));var e=K;K|=4;for(V=a.current;null!==V;){var f=V,g=f.child;if(0!==(V.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;kB()-fk?Kk(a,0):rk|=c);Dk(a,b)}function Yk(a,b){0===b&&(0===(a.mode&1)?b=1:(b=sc,sc<<=1,0===(sc&130023424)&&(sc=4194304)));var c=R();a=ih(a,b);null!==a&&(Ac(a,b,c),Dk(a,c))}function uj(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Yk(a,c)}\nfunction bk(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);break;case 19:d=a.stateNode;break;default:throw Error(p(314));}null!==d&&d.delete(b);Yk(a,c)}var Vk;\nVk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||Wf.current)dh=!0;else{if(0===(a.lanes&c)&&0===(b.flags&128))return dh=!1,yj(a,b,c);dh=0!==(a.flags&131072)?!0:!1}else dh=!1,I&&0!==(b.flags&1048576)&&ug(b,ng,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;ij(a,b);a=b.pendingProps;var e=Yf(b,H.current);ch(b,c);e=Nh(null,b,d,a,e,c);var f=Sh();b.flags|=1;\"object\"===typeof e&&null!==e&&\"function\"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue=\nnull,Zf(d)?(f=!0,cg(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,kh(b),e.updater=Ei,b.stateNode=e,e._reactInternals=b,Ii(b,d,a,c),b=jj(null,b,d,!0,f,c)):(b.tag=0,I&&f&&vg(b),Xi(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{ij(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=Zk(d);a=Ci(d,a);switch(e){case 0:b=cj(null,b,d,a,c);break a;case 1:b=hj(null,b,d,a,c);break a;case 11:b=Yi(null,b,d,a,c);break a;case 14:b=$i(null,b,d,Ci(d.type,a),c);break a}throw Error(p(306,\nd,\"\"));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Ci(d,e),cj(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Ci(d,e),hj(a,b,d,e,c);case 3:a:{kj(b);if(null===a)throw Error(p(387));d=b.pendingProps;f=b.memoizedState;e=f.element;lh(a,b);qh(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState=\nf,b.memoizedState=f,b.flags&256){e=Ji(Error(p(423)),b);b=lj(a,b,d,c,e);break a}else if(d!==e){e=Ji(Error(p(424)),b);b=lj(a,b,d,c,e);break a}else for(yg=Lf(b.stateNode.containerInfo.firstChild),xg=b,I=!0,zg=null,c=Vg(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Ig();if(d===e){b=Zi(a,b,c);break a}Xi(a,b,d,c)}b=b.child}return b;case 5:return Ah(b),null===a&&Eg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Ef(d,e)?g=null:null!==f&&Ef(d,f)&&(b.flags|=32),\ngj(a,b),Xi(a,b,g,c),b.child;case 6:return null===a&&Eg(b),null;case 13:return oj(a,b,c);case 4:return yh(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Ug(b,null,d,c):Xi(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Ci(d,e),Yi(a,b,d,e,c);case 7:return Xi(a,b,b.pendingProps,c),b.child;case 8:return Xi(a,b,b.pendingProps.children,c),b.child;case 12:return Xi(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps;\ng=e.value;G(Wg,d._currentValue);d._currentValue=g;if(null!==f)if(He(f.value,g)){if(f.children===e.children&&!Wf.current){b=Zi(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=mh(-1,c&-c);k.tag=2;var l=f.updateQueue;if(null!==l){l=l.shared;var m=l.pending;null===m?k.next=k:(k.next=m.next,m.next=k);l.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);bh(f.return,\nc,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===f.tag){g=f.return;if(null===g)throw Error(p(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);bh(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}Xi(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,ch(b,c),e=eh(e),d=d(e),b.flags|=1,Xi(a,b,d,c),\nb.child;case 14:return d=b.type,e=Ci(d,b.pendingProps),e=Ci(d.type,e),$i(a,b,d,e,c);case 15:return bj(a,b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Ci(d,e),ij(a,b),b.tag=1,Zf(d)?(a=!0,cg(b)):a=!1,ch(b,c),Gi(b,d,e),Ii(b,d,e,c),jj(null,b,d,!0,a,c);case 19:return xj(a,b,c);case 22:return dj(a,b,c)}throw Error(p(156,b.tag));};function Fk(a,b){return ac(a,b)}\nfunction $k(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function Bg(a,b,c,d){return new $k(a,b,c,d)}function aj(a){a=a.prototype;return!(!a||!a.isReactComponent)}\nfunction Zk(a){if(\"function\"===typeof a)return aj(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Da)return 11;if(a===Ga)return 14}return 2}\nfunction Pg(a,b){var c=a.alternate;null===c?(c=Bg(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};\nc.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}\nfunction Rg(a,b,c,d,e,f){var g=2;d=a;if(\"function\"===typeof a)aj(a)&&(g=1);else if(\"string\"===typeof a)g=5;else a:switch(a){case ya:return Tg(c.children,e,f,b);case za:g=8;e|=8;break;case Aa:return a=Bg(12,c,b,e|2),a.elementType=Aa,a.lanes=f,a;case Ea:return a=Bg(13,c,b,e),a.elementType=Ea,a.lanes=f,a;case Fa:return a=Bg(19,c,b,e),a.elementType=Fa,a.lanes=f,a;case Ia:return pj(c,e,f,b);default:if(\"object\"===typeof a&&null!==a)switch(a.$$typeof){case Ba:g=10;break a;case Ca:g=9;break a;case Da:g=11;\nbreak a;case Ga:g=14;break a;case Ha:g=16;d=null;break a}throw Error(p(130,null==a?a:typeof a,\"\"));}b=Bg(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function Tg(a,b,c,d){a=Bg(7,a,d,b);a.lanes=c;return a}function pj(a,b,c,d){a=Bg(22,a,d,b);a.elementType=Ia;a.lanes=c;a.stateNode={isHidden:!1};return a}function Qg(a,b,c){a=Bg(6,a,null,b);a.lanes=c;return a}\nfunction Sg(a,b,c){b=Bg(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}\nfunction al(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=0;this.eventTimes=zc(0);this.expirationTimes=zc(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=zc(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData=\nnull}function bl(a,b,c,d,e,f,g,h,k){a=new al(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=Bg(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,pendingSuspenseBoundaries:null};kh(f);return a}function cl(a,b,c){var d=3 createMemoryLocation(entry, typeof entry === \"string\" ? null : entry.state, index === 0 ? \"default\" : undefined));\n let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex);\n let action = Action.Pop;\n let listener = null;\n function clampIndex(n) {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation() {\n return entries[index];\n }\n function createMemoryLocation(to, state, key) {\n if (state === void 0) {\n state = null;\n }\n let location = createLocation(entries ? getCurrentLocation().pathname : \"/\", to, state, key);\n warning(location.pathname.charAt(0) === \"/\", \"relative pathnames are not supported in memory history: \" + JSON.stringify(to));\n return location;\n }\n function createHref(to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n let history = {\n get index() {\n return index;\n },\n get action() {\n return action;\n },\n get location() {\n return getCurrentLocation();\n },\n createHref,\n createURL(to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation(to) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\"\n };\n },\n push(to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({\n action,\n location: nextLocation,\n delta: 1\n });\n }\n },\n replace(to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({\n action,\n location: nextLocation,\n delta: 0\n });\n }\n },\n go(delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({\n action,\n location: nextLocation,\n delta\n });\n }\n },\n listen(fn) {\n listener = fn;\n return () => {\n listener = null;\n };\n }\n };\n return history;\n}\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */\nfunction createBrowserHistory(options) {\n if (options === void 0) {\n options = {};\n }\n function createBrowserLocation(window, globalHistory) {\n let {\n pathname,\n search,\n hash\n } = window.location;\n return createLocation(\"\", {\n pathname,\n search,\n hash\n },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || \"default\");\n }\n function createBrowserHref(window, to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options);\n}\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */\nfunction createHashHistory(options) {\n if (options === void 0) {\n options = {};\n }\n function createHashLocation(window, globalHistory) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n } = parsePath(window.location.hash.substr(1));\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route () since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n return createLocation(\"\", {\n pathname,\n search,\n hash\n },\n // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || \"default\");\n }\n function createHashHref(window, to) {\n let base = window.document.querySelector(\"base\");\n let href = \"\";\n if (base && base.getAttribute(\"href\")) {\n let url = window.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n function validateHashLocation(location, to) {\n warning(location.pathname.charAt(0) === \"/\", \"relative pathnames are not supported in hash history.push(\" + JSON.stringify(to) + \")\");\n }\n return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options);\n}\nfunction invariant(value, message) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\nfunction warning(cond, message) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience, so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n/**\n * For browser-based histories, we combine the state and key into an object\n */\nfunction getHistoryState(location, index) {\n return {\n usr: location.state,\n key: location.key,\n idx: index\n };\n}\n/**\n * Creates a Location object with a unique key from the given Path\n */\nfunction createLocation(current, to, state, key) {\n if (state === void 0) {\n state = null;\n }\n let location = _extends({\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\"\n }, typeof to === \"string\" ? parsePath(to) : to, {\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: to && to.key || key || createKey()\n });\n return location;\n}\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */\nfunction createPath(_ref) {\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\"\n } = _ref;\n if (search && search !== \"?\") pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\") pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */\nfunction parsePath(path) {\n let parsedPath = {};\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n if (path) {\n parsedPath.pathname = path;\n }\n }\n return parsedPath;\n}\nfunction getUrlBasedHistory(getLocation, createHref, validateLocation, options) {\n if (options === void 0) {\n options = {};\n }\n let {\n window = document.defaultView,\n v5Compat = false\n } = options;\n let globalHistory = window.history;\n let action = Action.Pop;\n let listener = null;\n let index = getIndex();\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState(_extends({}, globalHistory.state, {\n idx: index\n }), \"\");\n }\n function getIndex() {\n let state = globalHistory.state || {\n idx: null\n };\n return state.idx;\n }\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({\n action,\n location: history.location,\n delta\n });\n }\n }\n function push(to, state) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window.location.assign(url);\n }\n if (v5Compat && listener) {\n listener({\n action,\n location: history.location,\n delta: 1\n });\n }\n }\n function replace(to, state) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n if (v5Compat && listener) {\n listener({\n action,\n location: history.location,\n delta: 0\n });\n }\n }\n function createURL(to) {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base = window.location.origin !== \"null\" ? window.location.origin : window.location.href;\n let href = typeof to === \"string\" ? to : createPath(to);\n // Treating this as a full URL will strip any trailing spaces so we need to\n // pre-encode them since they might be part of a matching splat param from\n // an ancestor route\n href = href.replace(/ $/, \"%20\");\n invariant(base, \"No window.location.(origin|href) available to create URL for href: \" + href);\n return new URL(href, base);\n }\n let history = {\n get action() {\n return action;\n },\n get location() {\n return getLocation(window, globalHistory);\n },\n listen(fn) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n return () => {\n window.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref(to) {\n return createHref(window, to);\n },\n createURL,\n encodeLocation(to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash\n };\n },\n push,\n replace,\n go(n) {\n return globalHistory.go(n);\n }\n };\n return history;\n}\n//#endregion\n\nvar ResultType;\n(function (ResultType) {\n ResultType[\"data\"] = \"data\";\n ResultType[\"deferred\"] = \"deferred\";\n ResultType[\"redirect\"] = \"redirect\";\n ResultType[\"error\"] = \"error\";\n})(ResultType || (ResultType = {}));\nconst immutableRouteKeys = new Set([\"lazy\", \"caseSensitive\", \"path\", \"id\", \"index\", \"children\"]);\nfunction isIndexRoute(route) {\n return route.index === true;\n}\n// Walk the route tree generating unique IDs where necessary, so we are working\n// solely with AgnosticDataRouteObject's within the Router\nfunction convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) {\n if (parentPath === void 0) {\n parentPath = [];\n }\n if (manifest === void 0) {\n manifest = {};\n }\n return routes.map((route, index) => {\n let treePath = [...parentPath, String(index)];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(route.index !== true || !route.children, \"Cannot specify children on an index route\");\n invariant(!manifest[id], \"Found a route id collision on id \\\"\" + id + \"\\\". Route \" + \"id's must be globally unique within Data Router usages\");\n if (isIndexRoute(route)) {\n let indexRoute = _extends({}, route, mapRouteProperties(route), {\n id\n });\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute = _extends({}, route, mapRouteProperties(route), {\n id,\n children: undefined\n });\n manifest[id] = pathOrLayoutRoute;\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(route.children, mapRouteProperties, treePath, manifest);\n }\n return pathOrLayoutRoute;\n }\n });\n}\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/v6/utils/match-routes\n */\nfunction matchRoutes(routes, locationArg, basename) {\n if (basename === void 0) {\n basename = \"/\";\n }\n return matchRoutesImpl(routes, locationArg, basename, false);\n}\nfunction matchRoutesImpl(routes, locationArg, basename, allowPartial) {\n let location = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n let pathname = stripBasename(location.pathname || \"/\", basename);\n if (pathname == null) {\n return null;\n }\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n let matches = null;\n for (let i = 0; matches == null && i < branches.length; ++i) {\n // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n let decoded = decodePath(pathname);\n matches = matchRouteBranch(branches[i], decoded, allowPartial);\n }\n return matches;\n}\nfunction convertRouteMatchToUiMatch(match, loaderData) {\n let {\n route,\n pathname,\n params\n } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle\n };\n}\nfunction flattenRoutes(routes, branches, parentsMeta, parentPath) {\n if (branches === void 0) {\n branches = [];\n }\n if (parentsMeta === void 0) {\n parentsMeta = [];\n }\n if (parentPath === void 0) {\n parentPath = \"\";\n }\n let flattenRoute = (route, index, relativePath) => {\n let meta = {\n relativePath: relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route\n };\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(meta.relativePath.startsWith(parentPath), \"Absolute route path \\\"\" + meta.relativePath + \"\\\" nested under path \" + (\"\\\"\" + parentPath + \"\\\" is not valid. An absolute child route path \") + \"must start with the combined path of all its parent routes.\");\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n let path = joinPaths([parentPath, meta.relativePath]);\n let routesMeta = parentsMeta.concat(meta);\n // Add the children before adding this route to the array, so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(\n // Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true, \"Index routes must not have child routes. Please remove \" + (\"all child routes from route path \\\"\" + path + \"\\\".\"));\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta\n });\n };\n routes.forEach((route, index) => {\n var _route$path;\n // coarse-grain check for optional params\n if (route.path === \"\" || !((_route$path = route.path) != null && _route$path.includes(\"?\"))) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)) {\n flattenRoute(route, index, exploded);\n }\n }\n });\n return branches;\n}\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */\nfunction explodeOptionalSegments(path) {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n let [first, ...rest] = segments;\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [required, \"\"] : [required];\n }\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n let result = [];\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children, so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explode _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(...restExploded.map(subpath => subpath === \"\" ? required : [required, subpath].join(\"/\")));\n // Then, if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n // for absolute paths, ensure `/` instead of empty segment\n return result.map(exploded => path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded);\n}\nfunction rankRouteBranches(branches) {\n branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first\n : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex)));\n}\nconst paramRe = /^:[\\w-]+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = s => s === \"*\";\nfunction computeScore(path, index) {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n if (index) {\n initialScore += indexRouteValue;\n }\n return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === \"\" ? emptySegmentValue : staticSegmentValue), initialScore);\n}\nfunction compareIndexes(a, b) {\n let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);\n return siblings ?\n // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1] :\n // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\nfunction matchRouteBranch(branch, pathname, allowPartial) {\n if (allowPartial === void 0) {\n allowPartial = false;\n }\n let {\n routesMeta\n } = branch;\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches = [];\n for (let i = 0; i < routesMeta.length; ++i) {\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname = matchedPathname === \"/\" ? pathname : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath({\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end\n }, remainingPathname);\n let route = meta.route;\n if (!match && end && allowPartial && !routesMeta[routesMeta.length - 1].route.index) {\n match = matchPath({\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end: false\n }, remainingPathname);\n }\n if (!match) {\n return null;\n }\n Object.assign(matchedParams, match.params);\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams,\n pathname: joinPaths([matchedPathname, match.pathname]),\n pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])),\n route\n });\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);\n }\n }\n return matches;\n}\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/v6/utils/generate-path\n */\nfunction generatePath(originalPath, params) {\n if (params === void 0) {\n params = {};\n }\n let path = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(false, \"Route path \\\"\" + path + \"\\\" will be treated as if it were \" + (\"\\\"\" + path.replace(/\\*$/, \"/*\") + \"\\\" because the `*` character must \") + \"always follow a `/` in the pattern. To get rid of this warning, \" + (\"please change the route path to \\\"\" + path.replace(/\\*$/, \"/*\") + \"\\\".\"));\n path = path.replace(/\\*$/, \"/*\");\n }\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n const stringify = p => p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n const segments = path.split(/\\/+/).map((segment, index, array) => {\n const isLastSegment = index === array.length - 1;\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\";\n // Apply the splat\n return stringify(params[star]);\n }\n const keyMatch = segment.match(/^:([\\w-]+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key];\n invariant(optional === \"?\" || param != null, \"Missing \\\":\" + key + \"\\\" param\");\n return stringify(param);\n }\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })\n // Remove empty segments\n .filter(segment => !!segment);\n return prefix + segments.join(\"/\");\n}\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/v6/utils/match-path\n */\nfunction matchPath(pattern, pathname) {\n if (typeof pattern === \"string\") {\n pattern = {\n path: pattern,\n caseSensitive: false,\n end: true\n };\n }\n let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);\n let match = pathname.match(matcher);\n if (!match) return null;\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params = compiledParams.reduce((memo, _ref, index) => {\n let {\n paramName,\n isOptional\n } = _ref;\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\\/+$/, \"$1\");\n }\n const value = captureGroups[index];\n if (isOptional && !value) {\n memo[paramName] = undefined;\n } else {\n memo[paramName] = (value || \"\").replace(/%2F/g, \"/\");\n }\n return memo;\n }, {});\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern\n };\n}\nfunction compilePath(path, caseSensitive, end) {\n if (caseSensitive === void 0) {\n caseSensitive = false;\n }\n if (end === void 0) {\n end = true;\n }\n warning(path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"), \"Route path \\\"\" + path + \"\\\" will be treated as if it were \" + (\"\\\"\" + path.replace(/\\*$/, \"/*\") + \"\\\" because the `*` character must \") + \"always follow a `/` in the pattern. To get rid of this warning, \" + (\"please change the route path to \\\"\" + path.replace(/\\*$/, \"/*\") + \"\\\".\"));\n let params = [];\n let regexpSource = \"^\" + path.replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^${}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(/\\/:([\\w-]+)(\\?)?/g, (_, paramName, isOptional) => {\n params.push({\n paramName,\n isOptional: isOptional != null\n });\n return isOptional ? \"/?([^\\\\/]+)?\" : \"/([^\\\\/]+)\";\n });\n if (path.endsWith(\"*\")) {\n params.push({\n paramName: \"*\"\n });\n regexpSource += path === \"*\" || path === \"/*\" ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex, so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else ;\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n return [matcher, params];\n}\nfunction decodePath(value) {\n try {\n return value.split(\"/\").map(v => decodeURIComponent(v).replace(/\\//g, \"%2F\")).join(\"/\");\n } catch (error) {\n warning(false, \"The URL path \\\"\" + value + \"\\\" could not be decoded because it is is a \" + \"malformed URL segment. This is probably due to a bad percent \" + (\"encoding (\" + error + \").\"));\n return value;\n }\n}\n/**\n * @private\n */\nfunction stripBasename(pathname, basename) {\n if (basename === \"/\") return pathname;\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\") ? basename.length - 1 : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n return pathname.slice(startIndex) || \"/\";\n}\nconst ABSOLUTE_URL_REGEX$1 = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\nconst isAbsoluteUrl = url => ABSOLUTE_URL_REGEX$1.test(url);\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/v6/utils/resolve-path\n */\nfunction resolvePath(to, fromPathname) {\n if (fromPathname === void 0) {\n fromPathname = \"/\";\n }\n let {\n pathname: toPathname,\n search = \"\",\n hash = \"\"\n } = typeof to === \"string\" ? parsePath(to) : to;\n let pathname;\n if (toPathname) {\n if (isAbsoluteUrl(toPathname)) {\n pathname = toPathname;\n } else {\n if (toPathname.includes(\"//\")) {\n let oldPathname = toPathname;\n toPathname = toPathname.replace(/\\/\\/+/g, \"/\");\n warning(false, \"Pathnames cannot have embedded double slashes - normalizing \" + (oldPathname + \" -> \" + toPathname));\n }\n if (toPathname.startsWith(\"/\")) {\n pathname = resolvePathname(toPathname.substring(1), \"/\");\n } else {\n pathname = resolvePathname(toPathname, fromPathname);\n }\n }\n } else {\n pathname = fromPathname;\n }\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash)\n };\n}\nfunction resolvePathname(relativePath, fromPathname) {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n relativeSegments.forEach(segment => {\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\nfunction getInvalidPathError(char, field, dest, path) {\n return \"Cannot include a '\" + char + \"' character in a manually specified \" + (\"`to.\" + field + \"` field [\" + JSON.stringify(path) + \"]. Please separate it out to the \") + (\"`to.\" + dest + \"` field. Alternatively you may provide the full path as \") + \"a string in and the router will parse it for you.\";\n}\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * \n * \n * \n *\n * \n * \n * }> // <-- Does not contribute\n * // <-- Does not contribute\n * \n * \n */\nfunction getPathContributingMatches(matches) {\n return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);\n}\n// Return the array of pathnames for the current route matches - used to\n// generate the routePathnames input for resolveTo()\nfunction getResolveToMatches(matches, v7_relativeSplatPath) {\n let pathMatches = getPathContributingMatches(matches);\n // When v7_relativeSplatPath is enabled, use the full pathname for the leaf\n // match so we include splat values for \".\" links. See:\n // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329\n if (v7_relativeSplatPath) {\n return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);\n }\n return pathMatches.map(match => match.pathnameBase);\n}\n/**\n * @private\n */\nfunction resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {\n if (isPathRelative === void 0) {\n isPathRelative = false;\n }\n let to;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = _extends({}, toArg);\n invariant(!to.pathname || !to.pathname.includes(\"?\"), getInvalidPathError(\"?\", \"pathname\", \"search\", to));\n invariant(!to.pathname || !to.pathname.includes(\"#\"), getInvalidPathError(\"#\", \"pathname\", \"hash\", to));\n invariant(!to.search || !to.search.includes(\"#\"), getInvalidPathError(\"#\", \"search\", \"hash\", to));\n }\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n let from;\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n // With relative=\"route\" (the default), each leading .. segment means\n // \"go up one route\" instead of \"go up one URL segment\". This is a key\n // difference from how works and a major reason we call this a\n // \"to\" value instead of a \"href\".\n if (!isPathRelative && toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n while (toSegments[0] === \"..\") {\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n to.pathname = toSegments.join(\"/\");\n }\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n let path = resolvePath(to, from);\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash = toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash = (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (!path.pathname.endsWith(\"/\") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {\n path.pathname += \"/\";\n }\n return path;\n}\n/**\n * @private\n */\nfunction getToPathname(to) {\n // Empty strings should be treated the same as / paths\n return to === \"\" || to.pathname === \"\" ? \"/\" : typeof to === \"string\" ? parsePath(to).pathname : to.pathname;\n}\n/**\n * @private\n */\nconst joinPaths = paths => paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n/**\n * @private\n */\nconst normalizePathname = pathname => pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n/**\n * @private\n */\nconst normalizeSearch = search => !search || search === \"?\" ? \"\" : search.startsWith(\"?\") ? search : \"?\" + search;\n/**\n * @private\n */\nconst normalizeHash = hash => !hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n *\n * @deprecated The `json` method is deprecated in favor of returning raw objects.\n * This method will be removed in v7.\n */\nconst json = function json(data, init) {\n if (init === void 0) {\n init = {};\n }\n let responseInit = typeof init === \"number\" ? {\n status: init\n } : init;\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n return new Response(JSON.stringify(data), _extends({}, responseInit, {\n headers\n }));\n};\nclass DataWithResponseInit {\n constructor(data, init) {\n this.type = \"DataWithResponseInit\";\n this.data = data;\n this.init = init || null;\n }\n}\n/**\n * Create \"responses\" that contain `status`/`headers` without forcing\n * serialization into an actual `Response` - used by Remix single fetch\n */\nfunction data(data, init) {\n return new DataWithResponseInit(data, typeof init === \"number\" ? {\n status: init\n } : init);\n}\nclass AbortedDeferredError extends Error {}\nclass DeferredData {\n constructor(data, responseInit) {\n this.pendingKeysSet = new Set();\n this.subscribers = new Set();\n this.deferredKeys = [];\n invariant(data && typeof data === \"object\" && !Array.isArray(data), \"defer() only accepts plain objects\");\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject;\n this.abortPromise = new Promise((_, r) => reject = r);\n this.controller = new AbortController();\n let onAbort = () => reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = () => this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n this.data = Object.entries(data).reduce((acc, _ref2) => {\n let [key, value] = _ref2;\n return Object.assign(acc, {\n [key]: this.trackPromise(key, value)\n });\n }, {});\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n this.init = responseInit;\n }\n trackPromise(key, value) {\n if (!(value instanceof Promise)) {\n return value;\n }\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, undefined, data), error => this.onSettle(promise, key, error));\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(() => {});\n Object.defineProperty(promise, \"_tracked\", {\n get: () => true\n });\n return promise;\n }\n onSettle(promise, key, error, data) {\n if (this.controller.signal.aborted && error instanceof AbortedDeferredError) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", {\n get: () => error\n });\n return Promise.reject(error);\n }\n this.pendingKeysSet.delete(key);\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error(\"Deferred data for key \\\"\" + key + \"\\\" resolved/rejected with `undefined`, \" + \"you must resolve/reject with a value or `null`.\");\n Object.defineProperty(promise, \"_error\", {\n get: () => undefinedError\n });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", {\n get: () => error\n });\n this.emit(false, key);\n return Promise.reject(error);\n }\n Object.defineProperty(promise, \"_data\", {\n get: () => data\n });\n this.emit(false, key);\n return data;\n }\n emit(aborted, settledKey) {\n this.subscribers.forEach(subscriber => subscriber(aborted, settledKey));\n }\n subscribe(fn) {\n this.subscribers.add(fn);\n return () => this.subscribers.delete(fn);\n }\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n async resolveData(signal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = () => this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise(resolve => {\n this.subscribe(aborted => {\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n get unwrappedData() {\n invariant(this.data !== null && this.done, \"Can only unwrap data on initialized and settled deferreds\");\n return Object.entries(this.data).reduce((acc, _ref3) => {\n let [key, value] = _ref3;\n return Object.assign(acc, {\n [key]: unwrapTrackedPromise(value)\n });\n }, {});\n }\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\nfunction isTrackedPromise(value) {\n return value instanceof Promise && value._tracked === true;\n}\nfunction unwrapTrackedPromise(value) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\n/**\n * @deprecated The `defer` method is deprecated in favor of returning raw\n * objects. This method will be removed in v7.\n */\nconst defer = function defer(data, init) {\n if (init === void 0) {\n init = {};\n }\n let responseInit = typeof init === \"number\" ? {\n status: init\n } : init;\n return new DeferredData(data, responseInit);\n};\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nconst redirect = function redirect(url, init) {\n if (init === void 0) {\n init = 302;\n }\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = {\n status: responseInit\n };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n return new Response(null, _extends({}, responseInit, {\n headers\n }));\n};\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nconst redirectDocument = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n/**\n * A redirect response that will perform a `history.replaceState` instead of a\n * `history.pushState` for client-side navigation redirects.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */\nconst replace = (url, init) => {\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Replace\", \"true\");\n return response;\n};\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n *\n * We don't export the class for public use since it's an implementation\n * detail, but we export the interface above so folks can build their own\n * abstractions around instances via isRouteErrorResponse()\n */\nclass ErrorResponseImpl {\n constructor(status, statusText, data, internal) {\n if (internal === void 0) {\n internal = false;\n }\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */\nfunction isRouteErrorResponse(error) {\n return error != null && typeof error.status === \"number\" && typeof error.statusText === \"string\" && typeof error.internal === \"boolean\" && \"data\" in error;\n}\n\nconst validMutationMethodsArr = [\"post\", \"put\", \"patch\", \"delete\"];\nconst validMutationMethods = new Set(validMutationMethodsArr);\nconst validRequestMethodsArr = [\"get\", ...validMutationMethodsArr];\nconst validRequestMethods = new Set(validRequestMethodsArr);\nconst redirectStatusCodes = new Set([301, 302, 303, 307, 308]);\nconst redirectPreserveMethodStatusCodes = new Set([307, 308]);\nconst IDLE_NAVIGATION = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n};\nconst IDLE_FETCHER = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n};\nconst IDLE_BLOCKER = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined\n};\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\nconst defaultMapRouteProperties = route => ({\n hasErrorBoundary: Boolean(route.hasErrorBoundary)\n});\nconst TRANSITIONS_STORAGE_KEY = \"remix-router-transitions\";\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Create a router and listen to history POP navigations\n */\nfunction createRouter(init) {\n const routerWindow = init.window ? init.window : typeof window !== \"undefined\" ? window : undefined;\n const isBrowser = typeof routerWindow !== \"undefined\" && typeof routerWindow.document !== \"undefined\" && typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n invariant(init.routes.length > 0, \"You must provide a non-empty routes array to createRouter\");\n let mapRouteProperties;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = route => ({\n hasErrorBoundary: detectErrorBoundary(route)\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Routes keyed by ID\n let manifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest);\n let inFlightDataRoutes;\n let basename = init.basename || \"/\";\n let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;\n let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;\n // Config driven behavior flags\n let future = _extends({\n v7_fetcherPersist: false,\n v7_normalizeFormMethod: false,\n v7_partialHydration: false,\n v7_prependBasename: false,\n v7_relativeSplatPath: false,\n v7_skipActionErrorRevalidation: false\n }, init.future);\n // Cleanup function for history\n let unlistenHistory = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialMatchesIsFOW = false;\n let initialErrors = null;\n if (initialMatches == null && !patchRoutesOnNavigationImpl) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname\n });\n let {\n matches,\n route\n } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = {\n [route.id]: error\n };\n }\n // In SPA apps, if the user provided a patchRoutesOnNavigation implementation and\n // our initial match is a splat route, clear them out so we run through lazy\n // discovery on hydration in case there's a more accurate lazy route match.\n // In SSR apps (with `hydrationData`), we expect that the server will send\n // up the proper matched routes so we don't want to run lazy discovery on\n // initial hydration and want to hydrate into the splat route.\n if (initialMatches && !init.hydrationData) {\n let fogOfWar = checkFogOfWar(initialMatches, dataRoutes, init.history.location.pathname);\n if (fogOfWar.active) {\n initialMatches = null;\n }\n }\n let initialized;\n if (!initialMatches) {\n initialized = false;\n initialMatches = [];\n // If partial hydration and fog of war is enabled, we will be running\n // `patchRoutesOnNavigation` during hydration so include any partial matches as\n // the initial matches so we can properly render `HydrateFallback`'s\n if (future.v7_partialHydration) {\n let fogOfWar = checkFogOfWar(null, dataRoutes, init.history.location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n initialMatchesIsFOW = true;\n initialMatches = fogOfWar.matches;\n }\n }\n } else if (initialMatches.some(m => m.route.lazy)) {\n // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n initialized = false;\n } else if (!initialMatches.some(m => m.route.loader)) {\n // If we've got no loaders to run, then we're good to go\n initialized = true;\n } else if (future.v7_partialHydration) {\n // If partial hydration is enabled, we're initialized so long as we were\n // provided with hydrationData for every route with a loader, and no loaders\n // were marked for explicit hydration\n let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;\n let errors = init.hydrationData ? init.hydrationData.errors : null;\n // If errors exist, don't consider routes below the boundary\n if (errors) {\n let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined);\n initialized = initialMatches.slice(0, idx + 1).every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));\n } else {\n initialized = initialMatches.every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));\n }\n } else {\n // Without partial hydration - we're initialized if we were provided any\n // hydrationData - which is expected to be complete\n initialized = init.hydrationData != null;\n }\n let router;\n let state = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: init.hydrationData && init.hydrationData.loaderData || {},\n actionData: init.hydrationData && init.hydrationData.actionData || null,\n errors: init.hydrationData && init.hydrationData.errors || initialErrors,\n fetchers: new Map(),\n blockers: new Map()\n };\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction = Action.Pop;\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n // AbortController for the active navigation\n let pendingNavigationController;\n // Should the current navigation enable document.startViewTransition?\n let pendingViewTransitionEnabled = false;\n // Store applied view transitions so we can apply them on POP\n let appliedViewTransitions = new Map();\n // Cleanup function for persisting applied transitions to sessionStorage\n let removePageHideEventListener = null;\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes = [];\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads = new Set();\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n // Ref-count mounted fetchers so we know when it's ok to clean them up\n let activeFetchers = new Map();\n // Fetchers that have requested a delete when using v7_fetcherPersist,\n // they'll be officially removed after they return to idle\n let deletedFetchers = new Set();\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let unblockBlockerHistoryUpdate = undefined;\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen(_ref => {\n let {\n action: historyAction,\n location,\n delta\n } = _ref;\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (unblockBlockerHistoryUpdate) {\n unblockBlockerHistoryUpdate();\n unblockBlockerHistoryUpdate = undefined;\n return;\n }\n warning(blockerFunctions.size === 0 || delta != null, \"You are trying to use a blocker on a POP navigation to a location \" + \"that was not created by @remix-run/router. This will fail silently in \" + \"production. This can happen if you are navigating outside the router \" + \"via `window.history.pushState`/`window.location.hash` instead of using \" + \"router navigation APIs. This can also happen if you are using \" + \"createHashRouter and the user manually changes the URL.\");\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction\n });\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n let nextHistoryUpdatePromise = new Promise(resolve => {\n unblockBlockerHistoryUpdate = resolve;\n });\n init.history.go(delta * -1);\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location\n });\n // Re-do the same POP navigation we just blocked, after the url\n // restoration is also complete. See:\n // https://github.com/remix-run/react-router/issues/11613\n nextHistoryUpdatePromise.then(() => init.history.go(delta));\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({\n blockers\n });\n }\n });\n return;\n }\n return startNavigation(historyAction, location);\n });\n if (isBrowser) {\n // FIXME: This feels gross. How can we cleanup the lines between\n // scrollRestoration/appliedTransitions persistance?\n restoreAppliedTransitions(routerWindow, appliedViewTransitions);\n let _saveAppliedTransitions = () => persistAppliedTransitions(routerWindow, appliedViewTransitions);\n routerWindow.addEventListener(\"pagehide\", _saveAppliedTransitions);\n removePageHideEventListener = () => routerWindow.removeEventListener(\"pagehide\", _saveAppliedTransitions);\n }\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(Action.Pop, state.location, {\n initialHydration: true\n });\n }\n return router;\n }\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n if (removePageHideEventListener) {\n removePageHideEventListener();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key) => deleteFetcher(key));\n state.blockers.forEach((_, key) => deleteBlocker(key));\n }\n // Subscribe to state updates for the router\n function subscribe(fn) {\n subscribers.add(fn);\n return () => subscribers.delete(fn);\n }\n // Update our state and notify the calling context of the change\n function updateState(newState, opts) {\n if (opts === void 0) {\n opts = {};\n }\n state = _extends({}, state, newState);\n // Prep fetcher cleanup so we can tell the UI which fetcher data entries\n // can be removed\n let completedFetchers = [];\n let deletedFetchersKeys = [];\n if (future.v7_fetcherPersist) {\n state.fetchers.forEach((fetcher, key) => {\n if (fetcher.state === \"idle\") {\n if (deletedFetchers.has(key)) {\n // Unmounted from the UI and can be totally removed\n deletedFetchersKeys.push(key);\n } else {\n // Returned to idle but still mounted in the UI, so semi-remains for\n // revalidations and such\n completedFetchers.push(key);\n }\n }\n });\n }\n // Remove any lingering deleted fetchers that have already been removed\n // from state.fetchers\n deletedFetchers.forEach(key => {\n if (!state.fetchers.has(key) && !fetchControllers.has(key)) {\n deletedFetchersKeys.push(key);\n }\n });\n // Iterate over a local copy so that if flushSync is used and we end up\n // removing and adding a new subscriber due to the useCallback dependencies,\n // we don't get ourselves into a loop calling the new subscriber immediately\n [...subscribers].forEach(subscriber => subscriber(state, {\n deletedFetchers: deletedFetchersKeys,\n viewTransitionOpts: opts.viewTransitionOpts,\n flushSync: opts.flushSync === true\n }));\n // Remove idle fetchers from state since we only care about in-flight fetchers.\n if (future.v7_fetcherPersist) {\n completedFetchers.forEach(key => state.fetchers.delete(key));\n deletedFetchersKeys.forEach(key => deleteFetcher(key));\n } else {\n // We already called deleteFetcher() on these, can remove them from this\n // Set now that we've handed the keys off to the data layer\n deletedFetchersKeys.forEach(key => deletedFetchers.delete(key));\n }\n }\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(location, newState, _temp) {\n var _location$state, _location$state2;\n let {\n flushSync\n } = _temp === void 0 ? {} : _temp;\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === \"loading\" && ((_location$state = location.state) == null ? void 0 : _location$state._isRedirect) !== true;\n let actionData;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k) => blockers.set(k, IDLE_BLOCKER));\n }\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;\n // Commit any in-flight routes at the end of the HMR revalidation \"navigation\"\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n if (isUninterruptedRevalidation) ; else if (pendingAction === Action.Pop) ; else if (pendingAction === Action.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === Action.Replace) {\n init.history.replace(location, location.state);\n }\n let viewTransitionOpts;\n // On POP, enable transitions if they were enabled on the original navigation\n if (pendingAction === Action.Pop) {\n // Forward takes precedence so they behave like the original navigation\n let priorPaths = appliedViewTransitions.get(state.location.pathname);\n if (priorPaths && priorPaths.has(location.pathname)) {\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n } else if (appliedViewTransitions.has(location.pathname)) {\n // If we don't have a previous forward nav, assume we're popping back to\n // the new location and enable if that location previously enabled\n viewTransitionOpts = {\n currentLocation: location,\n nextLocation: state.location\n };\n }\n } else if (pendingViewTransitionEnabled) {\n // Store the applied transition on PUSH/REPLACE\n let toPaths = appliedViewTransitions.get(state.location.pathname);\n if (toPaths) {\n toPaths.add(location.pathname);\n } else {\n toPaths = new Set([location.pathname]);\n appliedViewTransitions.set(state.location.pathname, toPaths);\n }\n viewTransitionOpts = {\n currentLocation: state.location,\n nextLocation: location\n };\n }\n updateState(_extends({}, newState, {\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches),\n preventScrollReset,\n blockers\n }), {\n viewTransitionOpts,\n flushSync: flushSync === true\n });\n // Reset stateful navigation vars\n pendingAction = Action.Pop;\n pendingPreventScrollReset = false;\n pendingViewTransitionEnabled = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n }\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(to, opts) {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, to, future.v7_relativeSplatPath, opts == null ? void 0 : opts.fromRouteId, opts == null ? void 0 : opts.relative);\n let {\n path,\n submission,\n error\n } = normalizeNavigateOptions(future.v7_normalizeFormMethod, false, normalizedPath, opts);\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation));\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n let historyAction = Action.Push;\n if (userReplace === true) {\n historyAction = Action.Replace;\n } else if (userReplace === false) ; else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = Action.Replace;\n }\n let preventScrollReset = opts && \"preventScrollReset\" in opts ? opts.preventScrollReset === true : undefined;\n let flushSync = (opts && opts.flushSync) === true;\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n });\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed() {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset() {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({\n blockers\n });\n }\n });\n return;\n }\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace,\n enableViewTransition: opts && opts.viewTransition,\n flushSync\n });\n }\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({\n revalidation: \"loading\"\n });\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true\n });\n return;\n }\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(pendingAction || state.historyAction, state.navigation.location, {\n overrideNavigation: state.navigation,\n // Proxy through any rending view transition\n enableViewTransition: pendingViewTransitionEnabled === true\n });\n }\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(historyAction, location, opts) {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n pendingViewTransitionEnabled = (opts && opts.enableViewTransition) === true;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = opts != null && opts.initialHydration && state.matches && state.matches.length > 0 && !initialMatchesIsFOW ?\n // `matchRoutes()` has already been called if we're in here via `router.initialize()`\n state.matches : matchRoutes(routesToUse, location, basename);\n let flushSync = (opts && opts.flushSync) === true;\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial hydration will always\n // be \"same hash\". For example, on /page#hash and submit a
\n // which will default to a navigation to /page\n if (matches && state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {\n completeNavigation(location, {\n matches\n }, {\n flushSync\n });\n return;\n }\n let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let {\n error,\n notFoundMatches,\n route\n } = handleNavigational404(location.pathname);\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n }, {\n flushSync\n });\n return;\n }\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);\n let pendingActionResult;\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingActionResult = [findNearestBoundary(matches).route.id, {\n type: ResultType.error,\n error: opts.pendingError\n }];\n } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {\n // Call action if we received an action submission\n let actionResult = await handleAction(request, location, opts.submission, matches, fogOfWar.active, {\n replace: opts.replace,\n flushSync\n });\n if (actionResult.shortCircuited) {\n return;\n }\n // If we received a 404 from handleAction, it's because we couldn't lazily\n // discover the destination route so we don't want to call loaders\n if (actionResult.pendingActionResult) {\n let [routeId, result] = actionResult.pendingActionResult;\n if (isErrorResult(result) && isRouteErrorResponse(result.error) && result.error.status === 404) {\n pendingNavigationController = null;\n completeNavigation(location, {\n matches: actionResult.matches,\n loaderData: {},\n errors: {\n [routeId]: result.error\n }\n });\n return;\n }\n }\n matches = actionResult.matches || matches;\n pendingActionResult = actionResult.pendingActionResult;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n flushSync = false;\n // No need to do fog of war matching again on loader execution\n fogOfWar.active = false;\n // Create a GET request for the loaders\n request = createClientSideRequest(init.history, request.url, request.signal);\n }\n // Call loaders\n let {\n shortCircuited,\n matches: updatedMatches,\n loaderData,\n errors\n } = await handleLoaders(request, location, matches, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult);\n if (shortCircuited) {\n return;\n }\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n completeNavigation(location, _extends({\n matches: updatedMatches || matches\n }, getActionDataForCommit(pendingActionResult), {\n loaderData,\n errors\n }));\n }\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(request, location, submission, matches, isFogOfWar, opts) {\n if (opts === void 0) {\n opts = {};\n }\n interruptActiveLoads();\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({\n navigation\n }, {\n flushSync: opts.flushSync === true\n });\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(matches, location.pathname, request.signal);\n if (discoverResult.type === \"aborted\") {\n return {\n shortCircuited: true\n };\n } else if (discoverResult.type === \"error\") {\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n pendingActionResult: [boundaryId, {\n type: ResultType.error,\n error: discoverResult.error\n }]\n };\n } else if (!discoverResult.matches) {\n let {\n notFoundMatches,\n error,\n route\n } = handleNavigational404(location.pathname);\n return {\n matches: notFoundMatches,\n pendingActionResult: [route.id, {\n type: ResultType.error,\n error\n }]\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n // Call our action and get the result\n let result;\n let actionMatch = getTargetMatch(matches, location);\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id\n })\n };\n } else {\n let results = await callDataStrategy(\"action\", state, request, [actionMatch], matches, null);\n result = results[actionMatch.route.id];\n if (request.signal.aborted) {\n return {\n shortCircuited: true\n };\n }\n }\n if (isRedirectResult(result)) {\n let replace;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n let location = normalizeRedirectLocation(result.response.headers.get(\"Location\"), new URL(request.url), basename, init.history);\n replace = location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(request, result, true, {\n submission,\n replace\n });\n return {\n shortCircuited: true\n };\n }\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, {\n type: \"defer-action\"\n });\n }\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n // By default, all submissions to the current location are REPLACE\n // navigations, but if the action threw an error that'll be rendered in\n // an errorElement, we fall back to PUSH so that the user can use the\n // back button to get back to the pre-submission form location to try\n // again\n if ((opts && opts.replace) !== true) {\n pendingAction = Action.Push;\n }\n return {\n matches,\n pendingActionResult: [boundaryMatch.route.id, result]\n };\n }\n return {\n matches,\n pendingActionResult: [actionMatch.route.id, result]\n };\n }\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult) {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n // If we have partialHydration enabled, then don't update the state for the\n // initial data load since it's not a \"navigation\"\n let shouldUpdateNavigationState = !isUninterruptedRevalidation && (!future.v7_partialHydration || !initialHydration);\n // When fog of war is enabled, we enter our `loading` state earlier so we\n // can discover new routes during the `loading` state. We skip this if\n // we've already run actions since we would have done our matching already.\n // If the children() function threw then, we want to proceed with the\n // partial matches it discovered.\n if (isFogOfWar) {\n if (shouldUpdateNavigationState) {\n let actionData = getUpdatedActionData(pendingActionResult);\n updateState(_extends({\n navigation: loadingNavigation\n }, actionData !== undefined ? {\n actionData\n } : {}), {\n flushSync\n });\n }\n let discoverResult = await discoverRoutes(matches, location.pathname, request.signal);\n if (discoverResult.type === \"aborted\") {\n return {\n shortCircuited: true\n };\n } else if (discoverResult.type === \"error\") {\n let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;\n return {\n matches: discoverResult.partialMatches,\n loaderData: {},\n errors: {\n [boundaryId]: discoverResult.error\n }\n };\n } else if (!discoverResult.matches) {\n let {\n error,\n notFoundMatches,\n route\n } = handleNavigational404(location.pathname);\n return {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n };\n } else {\n matches = discoverResult.matches;\n }\n }\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, future.v7_partialHydration && initialHydration === true, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult);\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds(routeId => !(matches && matches.some(m => m.route.id === routeId)) || matchesToLoad && matchesToLoad.some(m => m.route.id === routeId));\n pendingNavigationLoadId = ++incrementingLoadId;\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(location, _extends({\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {\n [pendingActionResult[0]]: pendingActionResult[1].error\n } : null\n }, getActionDataForCommit(pendingActionResult), updatedFetchers ? {\n fetchers: new Map(state.fetchers)\n } : {}), {\n flushSync\n });\n return {\n shortCircuited: true\n };\n }\n if (shouldUpdateNavigationState) {\n let updates = {};\n if (!isFogOfWar) {\n // Only update navigation/actionNData if we didn't already do it above\n updates.navigation = loadingNavigation;\n let actionData = getUpdatedActionData(pendingActionResult);\n if (actionData !== undefined) {\n updates.actionData = actionData;\n }\n }\n if (revalidatingFetchers.length > 0) {\n updates.fetchers = getUpdatedRevalidatingFetchers(revalidatingFetchers);\n }\n updateState(updates, {\n flushSync\n });\n }\n revalidatingFetchers.forEach(rf => {\n abortFetcher(rf.key);\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(f => abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\"abort\", abortPendingFetchRevalidations);\n }\n let {\n loaderResults,\n fetcherResults\n } = await callLoadersAndMaybeResolveData(state, matches, matchesToLoad, revalidatingFetchers, request);\n if (request.signal.aborted) {\n return {\n shortCircuited: true\n };\n }\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\"abort\", abortPendingFetchRevalidations);\n }\n revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key));\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(loaderResults);\n if (redirect) {\n await startRedirectNavigation(request, redirect.result, true, {\n replace\n });\n return {\n shortCircuited: true\n };\n }\n redirect = findRedirect(fetcherResults);\n if (redirect) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n fetchRedirectIds.add(redirect.key);\n await startRedirectNavigation(request, redirect.result, true, {\n replace\n });\n return {\n shortCircuited: true\n };\n }\n // Process and commit output from loaders\n let {\n loaderData,\n errors\n } = processLoaderData(state, matches, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds);\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId) => {\n deferredData.subscribe(aborted => {\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n // Preserve SSR errors during partial hydration\n if (future.v7_partialHydration && initialHydration && state.errors) {\n errors = _extends({}, state.errors, errors);\n }\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n return _extends({\n matches,\n loaderData,\n errors\n }, shouldUpdateFetchers ? {\n fetchers: new Map(state.fetchers)\n } : {});\n }\n function getUpdatedActionData(pendingActionResult) {\n if (pendingActionResult && !isErrorResult(pendingActionResult[1])) {\n // This is cast to `any` currently because `RouteData`uses any and it\n // would be a breaking change to use any.\n // TODO: v7 - change `RouteData` to use `unknown` instead of `any`\n return {\n [pendingActionResult[0]]: pendingActionResult[1].data\n };\n } else if (state.actionData) {\n if (Object.keys(state.actionData).length === 0) {\n return null;\n } else {\n return state.actionData;\n }\n }\n }\n function getUpdatedRevalidatingFetchers(revalidatingFetchers) {\n revalidatingFetchers.forEach(rf => {\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(undefined, fetcher ? fetcher.data : undefined);\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n return new Map(state.fetchers);\n }\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(key, routeId, href, opts) {\n if (isServer) {\n throw new Error(\"router.fetch() was called during the server render, but it shouldn't be. \" + \"You are likely calling a useFetcher() method in the body of your component. \" + \"Try moving it to a useEffect or a callback.\");\n }\n abortFetcher(key);\n let flushSync = (opts && opts.flushSync) === true;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative);\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n let fogOfWar = checkFogOfWar(matches, routesToUse, normalizedPath);\n if (fogOfWar.active && fogOfWar.matches) {\n matches = fogOfWar.matches;\n }\n if (!matches) {\n setFetcherError(key, routeId, getInternalRouterError(404, {\n pathname: normalizedPath\n }), {\n flushSync\n });\n return;\n }\n let {\n path,\n submission,\n error\n } = normalizeNavigateOptions(future.v7_normalizeFormMethod, true, normalizedPath, opts);\n if (error) {\n setFetcherError(key, routeId, error, {\n flushSync\n });\n return;\n }\n let match = getTargetMatch(matches, path);\n let preventScrollReset = (opts && opts.preventScrollReset) === true;\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);\n return;\n }\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, {\n routeId,\n path\n });\n handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);\n }\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n function detectAndHandle405Error(m) {\n if (!m.route.action && !m.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId\n });\n setFetcherError(key, routeId, error, {\n flushSync\n });\n return true;\n }\n return false;\n }\n if (!isFogOfWar && detectAndHandle405Error(match)) {\n return;\n }\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), {\n flushSync\n });\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(requestMatches, new URL(fetchRequest.url).pathname, fetchRequest.signal, key);\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, {\n flushSync\n });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(key, routeId, getInternalRouterError(404, {\n pathname: path\n }), {\n flushSync\n });\n return;\n } else {\n requestMatches = discoverResult.matches;\n match = getTargetMatch(requestMatches, path);\n if (detectAndHandle405Error(match)) {\n return;\n }\n }\n }\n // Call the action for the fetcher\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let actionResults = await callDataStrategy(\"action\", state, fetchRequest, [match], requestMatches, key);\n let actionResult = actionResults[match.route.id];\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n // When using v7_fetcherPersist, we don't want errors bubbling up to the UI\n // or redirects processed for unmounted fetchers so we just revert them to\n // idle\n if (future.v7_fetcherPersist && deletedFetchers.has(key)) {\n if (isRedirectResult(actionResult) || isErrorResult(actionResult)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // Let SuccessResult's fall through for revalidation\n } else {\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n updateFetcherState(key, getLoadingFetcher(submission));\n return startRedirectNavigation(fetchRequest, actionResult, false, {\n fetcherSubmission: submission,\n preventScrollReset\n });\n }\n }\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n }\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, {\n type: \"defer-action\"\n });\n }\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches = state.navigation.state !== \"idle\" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;\n invariant(matches, \"Didn't find any matches after fetcher action\");\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, false, future.v7_skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, [match.route.id, actionResult]);\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers.filter(rf => rf.key !== key).forEach(rf => {\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined);\n state.fetchers.set(staleKey, revalidatingFetcher);\n abortFetcher(staleKey);\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n updateState({\n fetchers: new Map(state.fetchers)\n });\n let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach(rf => abortFetcher(rf.key));\n abortController.signal.addEventListener(\"abort\", abortPendingFetchRevalidations);\n let {\n loaderResults,\n fetcherResults\n } = await callLoadersAndMaybeResolveData(state, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);\n if (abortController.signal.aborted) {\n return;\n }\n abortController.signal.removeEventListener(\"abort\", abortPendingFetchRevalidations);\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));\n let redirect = findRedirect(loaderResults);\n if (redirect) {\n return startRedirectNavigation(revalidationRequest, redirect.result, false, {\n preventScrollReset\n });\n }\n redirect = findRedirect(fetcherResults);\n if (redirect) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n fetchRedirectIds.add(redirect.key);\n return startRedirectNavigation(revalidationRequest, redirect.result, false, {\n preventScrollReset\n });\n }\n // Process and commit output from loaders\n let {\n loaderData,\n errors\n } = processLoaderData(state, matches, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n abortStaleFetchLoads(loadId);\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (state.navigation.state === \"loading\" && loadId > pendingNavigationLoadId) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers)\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState({\n errors,\n loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors),\n fetchers: new Map(state.fetchers)\n });\n isRevalidationRequired = false;\n }\n }\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {\n let existingFetcher = state.fetchers.get(key);\n updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), {\n flushSync\n });\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);\n if (isFogOfWar) {\n let discoverResult = await discoverRoutes(matches, new URL(fetchRequest.url).pathname, fetchRequest.signal, key);\n if (discoverResult.type === \"aborted\") {\n return;\n } else if (discoverResult.type === \"error\") {\n setFetcherError(key, routeId, discoverResult.error, {\n flushSync\n });\n return;\n } else if (!discoverResult.matches) {\n setFetcherError(key, routeId, getInternalRouterError(404, {\n pathname: path\n }), {\n flushSync\n });\n return;\n } else {\n matches = discoverResult.matches;\n match = getTargetMatch(matches, path);\n }\n }\n // Call the loader for this fetcher route match\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let results = await callDataStrategy(\"loader\", state, fetchRequest, [match], matches, key);\n let result = results[match.route.id];\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result = (await resolveDeferredData(result, fetchRequest.signal, true)) || result;\n }\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n if (fetchRequest.signal.aborted) {\n return;\n }\n // We don't want errors bubbling up or redirects followed for unmounted\n // fetchers, so short circuit here if it was removed from the UI\n if (deletedFetchers.has(key)) {\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n }\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n updateFetcherState(key, getDoneFetcher(undefined));\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(fetchRequest, result, false, {\n preventScrollReset\n });\n return;\n }\n }\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n setFetcherError(key, routeId, result.error);\n return;\n }\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n // Put the fetcher back into an idle state\n updateFetcherState(key, getDoneFetcher(result.data));\n }\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */\n async function startRedirectNavigation(request, redirect, isNavigation, _temp2) {\n let {\n submission,\n fetcherSubmission,\n preventScrollReset,\n replace\n } = _temp2 === void 0 ? {} : _temp2;\n if (redirect.response.headers.has(\"X-Remix-Revalidate\")) {\n isRevalidationRequired = true;\n }\n let location = redirect.response.headers.get(\"Location\");\n invariant(location, \"Expected a Location header on the redirect Response\");\n location = normalizeRedirectLocation(location, new URL(request.url), basename, init.history);\n let redirectLocation = createLocation(state.location, location, {\n _isRedirect: true\n });\n if (isBrowser) {\n let isDocumentReload = false;\n if (redirect.response.headers.has(\"X-Remix-Reload-Document\")) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(location)) {\n const url = init.history.createURL(location);\n isDocumentReload =\n // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin ||\n // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(location);\n } else {\n routerWindow.location.assign(location);\n }\n return;\n }\n }\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n let redirectHistoryAction = replace === true || redirect.response.headers.has(\"X-Remix-Replace\") ? Action.Replace : Action.Push;\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let {\n formMethod,\n formAction,\n formEncType\n } = state.navigation;\n if (!submission && !fetcherSubmission && formMethod && formAction && formEncType) {\n submission = getSubmissionFromNavigation(state.navigation);\n }\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n let activeSubmission = submission || fetcherSubmission;\n if (redirectPreserveMethodStatusCodes.has(redirect.response.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: _extends({}, activeSubmission, {\n formAction: location\n }),\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined\n });\n } else {\n // If we have a navigation submission, we will preserve it through the\n // redirect navigation\n let overrideNavigation = getLoadingNavigation(redirectLocation, submission);\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Send fetcher submissions through for shouldRevalidate\n fetcherSubmission,\n // Preserve these flags across redirects\n preventScrollReset: preventScrollReset || pendingPreventScrollReset,\n enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined\n });\n }\n }\n // Utility wrapper for calling dataStrategy client-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(type, state, request, matchesToLoad, matches, fetcherKey) {\n let results;\n let dataResults = {};\n try {\n results = await callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties);\n } catch (e) {\n // If the outer dataStrategy method throws, just return the error for all\n // matches - and it'll naturally bubble to the root\n matchesToLoad.forEach(m => {\n dataResults[m.route.id] = {\n type: ResultType.error,\n error: e\n };\n });\n return dataResults;\n }\n for (let [routeId, result] of Object.entries(results)) {\n if (isRedirectDataStrategyResultResult(result)) {\n let response = result.result;\n dataResults[routeId] = {\n type: ResultType.redirect,\n response: normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, future.v7_relativeSplatPath)\n };\n } else {\n dataResults[routeId] = await convertDataStrategyResultToDataResult(result);\n }\n }\n return dataResults;\n }\n async function callLoadersAndMaybeResolveData(state, matches, matchesToLoad, fetchersToLoad, request) {\n let currentMatches = state.matches;\n // Kick off loaders and fetchers in parallel\n let loaderResultsPromise = callDataStrategy(\"loader\", state, request, matchesToLoad, matches, null);\n let fetcherResultsPromise = Promise.all(fetchersToLoad.map(async f => {\n if (f.matches && f.match && f.controller) {\n let results = await callDataStrategy(\"loader\", state, createClientSideRequest(init.history, f.path, f.controller.signal), [f.match], f.matches, f.key);\n let result = results[f.match.route.id];\n // Fetcher results are keyed by fetcher key from here on out, not routeId\n return {\n [f.key]: result\n };\n } else {\n return Promise.resolve({\n [f.key]: {\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path\n })\n }\n });\n }\n }));\n let loaderResults = await loaderResultsPromise;\n let fetcherResults = (await fetcherResultsPromise).reduce((acc, r) => Object.assign(acc, r), {});\n await Promise.all([resolveNavigationDeferredResults(matches, loaderResults, request.signal, currentMatches, state.loaderData), resolveFetcherDeferredResults(matches, fetcherResults, fetchersToLoad)]);\n return {\n loaderResults,\n fetcherResults\n };\n }\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key) => {\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.add(key);\n }\n abortFetcher(key);\n });\n }\n function updateFetcherState(key, fetcher, opts) {\n if (opts === void 0) {\n opts = {};\n }\n state.fetchers.set(key, fetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n }, {\n flushSync: (opts && opts.flushSync) === true\n });\n }\n function setFetcherError(key, routeId, error, opts) {\n if (opts === void 0) {\n opts = {};\n }\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error\n },\n fetchers: new Map(state.fetchers)\n }, {\n flushSync: (opts && opts.flushSync) === true\n });\n }\n function getFetcher(key) {\n activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);\n // If this fetcher was previously marked for deletion, unmark it since we\n // have a new instance\n if (deletedFetchers.has(key)) {\n deletedFetchers.delete(key);\n }\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n function deleteFetcher(key) {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (fetchControllers.has(key) && !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n // If we opted into the flag we can clear this now since we're calling\n // deleteFetcher() at the end of updateState() and we've already handed the\n // deleted fetcher keys off to the data layer.\n // If not, we're eagerly calling deleteFetcher() and we need to keep this\n // Set populated until the next updateState call, and we'll clear\n // `deletedFetchers` then\n if (future.v7_fetcherPersist) {\n deletedFetchers.delete(key);\n }\n cancelledFetcherLoads.delete(key);\n state.fetchers.delete(key);\n }\n function deleteFetcherAndUpdateState(key) {\n let count = (activeFetchers.get(key) || 0) - 1;\n if (count <= 0) {\n activeFetchers.delete(key);\n deletedFetchers.add(key);\n if (!future.v7_fetcherPersist) {\n deleteFetcher(key);\n }\n } else {\n activeFetchers.set(key, count);\n }\n updateState({\n fetchers: new Map(state.fetchers)\n });\n }\n function abortFetcher(key) {\n let controller = fetchControllers.get(key);\n if (controller) {\n controller.abort();\n fetchControllers.delete(key);\n }\n }\n function markFetchersDone(keys) {\n for (let key of keys) {\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n function markFetchRedirectsDone() {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, \"Expected fetcher: \" + key);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n function abortStaleFetchLoads(landedId) {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds) {\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, \"Expected fetcher: \" + key);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n function getBlocker(key, fn) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n return blocker;\n }\n function deleteBlocker(key) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key, newBlocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(blocker.state === \"unblocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"proceeding\" || blocker.state === \"blocked\" && newBlocker.state === \"unblocked\" || blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\", \"Invalid blocker state transition: \" + blocker.state + \" -> \" + newBlocker.state);\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({\n blockers\n });\n }\n function shouldBlockNavigation(_ref2) {\n let {\n currentLocation,\n nextLocation,\n historyAction\n } = _ref2;\n if (blockerFunctions.size === 0) {\n return;\n }\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({\n currentLocation,\n nextLocation,\n historyAction\n })) {\n return blockerKey;\n }\n }\n function handleNavigational404(pathname) {\n let error = getInternalRouterError(404, {\n pathname\n });\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let {\n matches,\n route\n } = getShortCircuitMatches(routesToUse);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n return {\n notFoundMatches: matches,\n route,\n error\n };\n }\n function cancelActiveDeferreds(predicate) {\n let cancelledRouteIds = [];\n activeDeferreds.forEach((dfd, routeId) => {\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the component\n function enableScrollRestoration(positions, getPosition, getKey) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered \n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({\n restoreScrollPosition: y\n });\n }\n }\n return () => {\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n function getScrollKey(location, matches) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(location, matches.map(m => convertRouteMatchToUiMatch(m, state.loaderData)));\n return key || location.key;\n }\n return location.key;\n }\n function saveScrollPosition(location, matches) {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n function getSavedScrollPosition(location, matches) {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n function checkFogOfWar(matches, routesToUse, pathname) {\n if (patchRoutesOnNavigationImpl) {\n if (!matches) {\n let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true);\n return {\n active: true,\n matches: fogMatches || []\n };\n } else {\n if (Object.keys(matches[0].params).length > 0) {\n // If we matched a dynamic param or a splat, it might only be because\n // we haven't yet discovered other routes that would match with a\n // higher score. Call patchRoutesOnNavigation just to be sure\n let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);\n return {\n active: true,\n matches: partialMatches\n };\n }\n }\n }\n return {\n active: false,\n matches: null\n };\n }\n async function discoverRoutes(matches, pathname, signal, fetcherKey) {\n if (!patchRoutesOnNavigationImpl) {\n return {\n type: \"success\",\n matches\n };\n }\n let partialMatches = matches;\n while (true) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let localManifest = manifest;\n try {\n await patchRoutesOnNavigationImpl({\n signal,\n path: pathname,\n matches: partialMatches,\n fetcherKey,\n patch: (routeId, children) => {\n if (signal.aborted) return;\n patchRoutesImpl(routeId, children, routesToUse, localManifest, mapRouteProperties);\n }\n });\n } catch (e) {\n return {\n type: \"error\",\n error: e,\n partialMatches\n };\n } finally {\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity so when we `updateState` at the end of\n // this navigation/fetch `router.routes` will be a new identity and\n // trigger a re-run of memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR && !signal.aborted) {\n dataRoutes = [...dataRoutes];\n }\n }\n if (signal.aborted) {\n return {\n type: \"aborted\"\n };\n }\n let newMatches = matchRoutes(routesToUse, pathname, basename);\n if (newMatches) {\n return {\n type: \"success\",\n matches: newMatches\n };\n }\n let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);\n // Avoid loops if the second pass results in the same partial matches\n if (!newPartialMatches || partialMatches.length === newPartialMatches.length && partialMatches.every((m, i) => m.route.id === newPartialMatches[i].route.id)) {\n return {\n type: \"success\",\n matches: null\n };\n }\n partialMatches = newPartialMatches;\n }\n }\n function _internalSetRoutes(newRoutes) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest);\n }\n function patchRoutes(routeId, children) {\n let isNonHMR = inFlightDataRoutes == null;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties);\n // If we are not in the middle of an HMR revalidation and we changed the\n // routes, provide a new identity and trigger a reflow via `updateState`\n // to re-run memoized `router.routes` dependencies.\n // HMR will already update the identity and reflow when it lands\n // `inFlightDataRoutes` in `completeNavigation`\n if (isNonHMR) {\n dataRoutes = [...dataRoutes];\n updateState({});\n }\n }\n router = {\n get basename() {\n return basename;\n },\n get future() {\n return future;\n },\n get state() {\n return state;\n },\n get routes() {\n return dataRoutes;\n },\n get window() {\n return routerWindow;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: to => init.history.createHref(to),\n encodeLocation: to => init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher: deleteFetcherAndUpdateState,\n dispose,\n getBlocker,\n deleteBlocker,\n patchRoutes,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes\n };\n return router;\n}\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\nconst UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\nfunction createStaticHandler(routes, opts) {\n invariant(routes.length > 0, \"You must provide a non-empty routes array to createStaticHandler\");\n let manifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties;\n if (opts != null && opts.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts != null && opts.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = route => ({\n hasErrorBoundary: detectErrorBoundary(route)\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Config driven behavior flags\n let future = _extends({\n v7_relativeSplatPath: false,\n v7_throwAbortReason: false\n }, opts ? opts.future : null);\n let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest);\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n *\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n * - `opts.skipLoaderErrorBubbling` is an optional parameter that will prevent\n * the bubbling of errors which allows single-fetch-type implementations\n * where the client will handle the bubbling and we may need to return data\n * for the handling route\n */\n async function query(request, _temp3) {\n let {\n requestContext,\n skipLoaderErrorBubbling,\n dataStrategy\n } = _temp3 === void 0 ? {} : _temp3;\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, {\n method\n });\n let {\n matches: methodNotAllowedMatches,\n route\n } = getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, {\n pathname: location.pathname\n });\n let {\n matches: notFoundMatches,\n route\n } = getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n }\n let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, skipLoaderErrorBubbling === true, null);\n if (isResponse(result)) {\n return result;\n }\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return _extends({\n location,\n basename\n }, result);\n }\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n *\n * - `opts.routeId` allows you to specify the specific route handler to call.\n * If not provided the handler will determine the proper route by matching\n * against `request.url`\n * - `opts.requestContext` is an optional server context that will be passed\n * to actions/loaders in the `context` parameter\n */\n async function queryRoute(request, _temp4) {\n let {\n routeId,\n requestContext,\n dataStrategy\n } = _temp4 === void 0 ? {} : _temp4;\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, {\n method\n });\n } else if (!matches) {\n throw getInternalRouterError(404, {\n pathname: location.pathname\n });\n }\n let match = routeId ? matches.find(m => m.route.id === routeId) : getTargetMatch(matches, location);\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, {\n pathname: location.pathname\n });\n }\n let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, false, match);\n if (isResponse(result)) {\n return result;\n }\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n if (result.loaderData) {\n var _result$activeDeferre;\n let data = Object.values(result.loaderData)[0];\n if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n return undefined;\n }\n async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch) {\n invariant(request.signal, \"query()/queryRoute() requests must contain an AbortController signal\");\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch != null);\n return result;\n }\n let result = await loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch);\n return isResponse(result) ? result : _extends({}, result, {\n actionData: null,\n actionHeaders: {}\n });\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction for a\n // `queryRoute` call, we throw the `DataStrategyResult` to bail out early\n // and then return or throw the raw Response here accordingly\n if (isDataStrategyResult(e) && isResponse(e.result)) {\n if (e.type === ResultType.error) {\n throw e.result;\n }\n return e.result;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {\n let result;\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error\n };\n } else {\n let results = await callDataStrategy(\"action\", request, [actionMatch], matches, isRouteRequest, requestContext, dataStrategy);\n result = results[actionMatch.route.id];\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n }\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.response.status,\n headers: {\n Location: result.response.headers.get(\"Location\")\n }\n });\n }\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, {\n type: \"defer-action\"\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error\n };\n }\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n return {\n matches: [actionMatch],\n loaderData: {},\n actionData: {\n [actionMatch.route.id]: result.data\n },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n }\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal\n });\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);\n let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);\n // action status codes take precedence over loader status codes\n return _extends({}, context, {\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,\n actionData: null,\n actionHeaders: _extends({}, result.headers ? {\n [actionMatch.route.id]: result.headers\n } : {})\n });\n }\n let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null);\n return _extends({}, context, {\n actionData: {\n [actionMatch.route.id]: result.data\n }\n }, result.statusCode ? {\n statusCode: result.statusCode\n } : {}, {\n actionHeaders: result.headers ? {\n [actionMatch.route.id]: result.headers\n } : {}\n });\n }\n async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {\n let isRouteRequest = routeMatch != null;\n // Short circuit if we have no loaders to run (queryRoute())\n if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch == null ? void 0 : routeMatch.route.id\n });\n }\n let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches;\n let matchesToLoad = requestMatches.filter(m => m.route.loader || m.route.lazy);\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce((acc, m) => Object.assign(acc, {\n [m.route.id]: null\n }), {}),\n errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {\n [pendingActionResult[0]]: pendingActionResult[1].error\n } : null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null\n };\n }\n let results = await callDataStrategy(\"loader\", request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy);\n if (request.signal.aborted) {\n throwStaticHandlerAbortedError(request, isRouteRequest, future);\n }\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling);\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(matchesToLoad.map(match => match.route.id));\n matches.forEach(match => {\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n return _extends({}, context, {\n matches,\n activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null\n });\n }\n // Utility wrapper for calling dataStrategy server-side without having to\n // pass around the manifest, mapRouteProperties, etc.\n async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy) {\n let results = await callDataStrategyImpl(dataStrategy || defaultDataStrategy, type, null, request, matchesToLoad, matches, null, manifest, mapRouteProperties, requestContext);\n let dataResults = {};\n await Promise.all(matches.map(async match => {\n if (!(match.route.id in results)) {\n return;\n }\n let result = results[match.route.id];\n if (isRedirectDataStrategyResultResult(result)) {\n let response = result.result;\n // Throw redirects and let the server handle them with an HTTP redirect\n throw normalizeRelativeRoutingRedirectResponse(response, request, match.route.id, matches, basename, future.v7_relativeSplatPath);\n }\n if (isResponse(result.result) && isRouteRequest) {\n // For SSR single-route requests, we want to hand Responses back\n // directly without unwrapping\n throw result;\n }\n dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);\n }));\n return dataResults;\n }\n return {\n dataRoutes,\n query,\n queryRoute\n };\n}\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */\nfunction getStaticContextFromError(routes, context, error) {\n let newContext = _extends({}, context, {\n statusCode: isRouteErrorResponse(error) ? error.status : 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error\n }\n });\n return newContext;\n}\nfunction throwStaticHandlerAbortedError(request, isRouteRequest, future) {\n if (future.v7_throwAbortReason && request.signal.reason !== undefined) {\n throw request.signal.reason;\n }\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(method + \"() call aborted: \" + request.method + \" \" + request.url);\n}\nfunction isSubmissionNavigation(opts) {\n return opts != null && (\"formData\" in opts && opts.formData != null || \"body\" in opts && opts.body !== undefined);\n}\nfunction normalizeTo(location, matches, basename, prependBasename, to, v7_relativeSplatPath, fromRouteId, relative) {\n let contextualMatches;\n let activeRouteMatch;\n if (fromRouteId) {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route\n contextualMatches = [];\n for (let match of matches) {\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n // Resolve the relative path\n let path = resolveTo(to ? to : \".\", getResolveToMatches(contextualMatches, v7_relativeSplatPath), stripBasename(location.pathname, basename) || location.pathname, relative === \"path\");\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n // Account for `?index` params when routing to the current location\n if ((to == null || to === \"\" || to === \".\") && activeRouteMatch) {\n let nakedIndex = hasNakedIndexQuery(path.search);\n if (activeRouteMatch.route.index && !nakedIndex) {\n // Add one when we're targeting an index route\n path.search = path.search ? path.search.replace(/^\\?/, \"?index&\") : \"?index\";\n } else if (!activeRouteMatch.route.index && nakedIndex) {\n // Remove existing ones when we're not\n let params = new URLSearchParams(path.search);\n let indexValues = params.getAll(\"index\");\n params.delete(\"index\");\n indexValues.filter(v => v).forEach(v => params.append(\"index\", v));\n let qs = params.toString();\n path.search = qs ? \"?\" + qs : \"\";\n }\n }\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n return createPath(path);\n}\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return {\n path\n };\n }\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, {\n method: opts.formMethod\n })\n };\n }\n let getInvalidBodyError = () => ({\n path,\n error: getInternalRouterError(400, {\n type: \"invalid-body\"\n })\n });\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod ? rawFormMethod.toUpperCase() : rawFormMethod.toLowerCase();\n let formAction = stripHashFromPath(path);\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n let text = typeof opts.body === \"string\" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ?\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce((acc, _ref3) => {\n let [name, value] = _ref3;\n return \"\" + acc + name + \"=\" + value + \"\\n\";\n }, \"\") : String(opts.body);\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text\n }\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n try {\n let json = typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined\n }\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n invariant(typeof FormData === \"function\", \"FormData is not available in this environment\");\n let searchParams;\n let formData;\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n let submission = {\n formMethod,\n formAction,\n formEncType: opts && opts.formEncType || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined\n };\n if (isMutationMethod(submission.formMethod)) {\n return {\n path,\n submission\n };\n }\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = \"?\" + searchParams;\n return {\n path: createPath(parsedPath),\n submission\n };\n}\n// Filter out all routes at/below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(matches, boundaryId, includeBoundary) {\n if (includeBoundary === void 0) {\n includeBoundary = false;\n }\n let index = matches.findIndex(m => m.route.id === boundaryId);\n if (index >= 0) {\n return matches.slice(0, includeBoundary ? index + 1 : index);\n }\n return matches;\n}\nfunction getMatchesToLoad(history, state, matches, submission, location, initialHydration, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {\n let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryMatches = matches;\n if (initialHydration && state.errors) {\n // On initial hydration, only consider matches up to _and including_ the boundary.\n // This is inclusive to handle cases where a server loader ran successfully,\n // a child server loader bubbled up to this route, but this route has\n // `clientLoader.hydrate` so we want to still run the `clientLoader` so that\n // we have a complete version of `loaderData`\n boundaryMatches = getLoaderMatchesUntilBoundary(matches, Object.keys(state.errors)[0], true);\n } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {\n // If an action threw an error, we call loaders up to, but not including the\n // boundary\n boundaryMatches = getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]);\n }\n // Don't revalidate loaders by default after action 4xx/5xx responses\n // when the flag is enabled. They can still opt-into revalidation via\n // `shouldRevalidate` via `actionResult`\n let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : undefined;\n let shouldSkipRevalidation = skipActionErrorRevalidation && actionStatus && actionStatus >= 400;\n let navigationMatches = boundaryMatches.filter((match, index) => {\n let {\n route\n } = match;\n if (route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n if (route.loader == null) {\n return false;\n }\n if (initialHydration) {\n return shouldLoadRouteOnHydration(route, state.loaderData, state.errors);\n }\n // Always call the loader on new route instances and pending defer cancellations\n if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) {\n return true;\n }\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n return shouldRevalidateLoader(match, _extends({\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params\n }, submission, {\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation ? false :\n // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search ||\n // Search params affect all loaders\n currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch)\n }));\n });\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers = [];\n fetchLoadMatches.forEach((f, key) => {\n // Don't revalidate:\n // - on initial hydration (shouldn't be any fetchers then anyway)\n // - if fetcher won't be present in the subsequent render\n // - no longer matches the URL (v7_fetcherPersist=false)\n // - was unmounted but persisted due to v7_fetcherPersist=true\n if (initialHydration || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {\n return;\n }\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null\n });\n return;\n }\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.has(key)) {\n // Always mark for revalidation if the fetcher was cancelled\n cancelledFetcherLoads.delete(key);\n shouldRevalidate = true;\n } else if (fetcher && fetcher.state !== \"idle\" && fetcher.data === undefined) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params\n }, submission, {\n actionResult,\n actionStatus,\n defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired\n }));\n }\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController()\n });\n }\n });\n return [navigationMatches, revalidatingFetchers];\n}\nfunction shouldLoadRouteOnHydration(route, loaderData, errors) {\n // We dunno if we have a loader - gotta find out!\n if (route.lazy) {\n return true;\n }\n // No loader, nothing to initialize\n if (!route.loader) {\n return false;\n }\n let hasData = loaderData != null && loaderData[route.id] !== undefined;\n let hasError = errors != null && errors[route.id] !== undefined;\n // Don't run if we error'd during SSR\n if (!hasData && hasError) {\n return false;\n }\n // Explicitly opting-in to running on hydration\n if (typeof route.loader === \"function\" && route.loader.hydrate === true) {\n return true;\n }\n // Otherwise, run if we're not yet initialized with anything\n return !hasData && !hasError;\n}\nfunction isNewLoader(currentLoaderData, currentMatch, match) {\n let isNew =\n // [a] -> [a, b]\n !currentMatch ||\n // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\nfunction isNewRouteInstance(currentMatch, match) {\n let currentPath = currentMatch.route.path;\n return (\n // param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname ||\n // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n currentPath != null && currentPath.endsWith(\"*\") && currentMatch.params[\"*\"] !== match.params[\"*\"]\n );\n}\nfunction shouldRevalidateLoader(loaderMatch, arg) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n return arg.defaultShouldRevalidate;\n}\nfunction patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) {\n var _childrenToPatch;\n let childrenToPatch;\n if (routeId) {\n let route = manifest[routeId];\n invariant(route, \"No route found to patch children into: routeId = \" + routeId);\n if (!route.children) {\n route.children = [];\n }\n childrenToPatch = route.children;\n } else {\n childrenToPatch = routesToUse;\n }\n // Don't patch in routes we already know about so that `patch` is idempotent\n // to simplify user-land code. This is useful because we re-call the\n // `patchRoutesOnNavigation` function for matched routes with params.\n let uniqueChildren = children.filter(newRoute => !childrenToPatch.some(existingRoute => isSameRoute(newRoute, existingRoute)));\n let newRoutes = convertRoutesToDataRoutes(uniqueChildren, mapRouteProperties, [routeId || \"_\", \"patch\", String(((_childrenToPatch = childrenToPatch) == null ? void 0 : _childrenToPatch.length) || \"0\")], manifest);\n childrenToPatch.push(...newRoutes);\n}\nfunction isSameRoute(newRoute, existingRoute) {\n // Most optimal check is by id\n if (\"id\" in newRoute && \"id\" in existingRoute && newRoute.id === existingRoute.id) {\n return true;\n }\n // Second is by pathing differences\n if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {\n return false;\n }\n // Pathless layout routes are trickier since we need to check children.\n // If they have no children then they're the same as far as we can tell\n if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {\n return true;\n }\n // Otherwise, we look to see if every child in the new route is already\n // represented in the existing route's children\n return newRoute.children.every((aChild, i) => {\n var _existingRoute$childr;\n return (_existingRoute$childr = existingRoute.children) == null ? void 0 : _existingRoute$childr.some(bChild => isSameRoute(aChild, bChild));\n });\n}\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */\nasync function loadLazyRouteModule(route, mapRouteProperties, manifest) {\n if (!route.lazy) {\n return;\n }\n let lazyRoute = await route.lazy();\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates = {};\n for (let lazyRouteProperty in lazyRoute) {\n let staticRouteValue = routeToUpdate[lazyRouteProperty];\n let isPropertyStaticallyDefined = staticRouteValue !== undefined &&\n // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n warning(!isPropertyStaticallyDefined, \"Route \\\"\" + routeToUpdate.id + \"\\\" has a static property \\\"\" + lazyRouteProperty + \"\\\" \" + \"defined but its lazy function is also returning a value for this property. \" + (\"The lazy route property \\\"\" + lazyRouteProperty + \"\\\" will be ignored.\"));\n if (!isPropertyStaticallyDefined && !immutableRouteKeys.has(lazyRouteProperty)) {\n routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty];\n }\n }\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), {\n lazy: undefined\n }));\n}\n// Default implementation of `dataStrategy` which fetches all loaders in parallel\nasync function defaultDataStrategy(_ref4) {\n let {\n matches\n } = _ref4;\n let matchesToLoad = matches.filter(m => m.shouldLoad);\n let results = await Promise.all(matchesToLoad.map(m => m.resolve()));\n return results.reduce((acc, result, i) => Object.assign(acc, {\n [matchesToLoad[i].route.id]: result\n }), {});\n}\nasync function callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties, requestContext) {\n let loadRouteDefinitionsPromises = matches.map(m => m.route.lazy ? loadLazyRouteModule(m.route, mapRouteProperties, manifest) : undefined);\n let dsMatches = matches.map((match, i) => {\n let loadRoutePromise = loadRouteDefinitionsPromises[i];\n let shouldLoad = matchesToLoad.some(m => m.route.id === match.route.id);\n // `resolve` encapsulates route.lazy(), executing the loader/action,\n // and mapping return values/thrown errors to a `DataStrategyResult`. Users\n // can pass a callback to take fine-grained control over the execution\n // of the loader/action\n let resolve = async handlerOverride => {\n if (handlerOverride && request.method === \"GET\" && (match.route.lazy || match.route.loader)) {\n shouldLoad = true;\n }\n return shouldLoad ? callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, requestContext) : Promise.resolve({\n type: ResultType.data,\n result: undefined\n });\n };\n return _extends({}, match, {\n shouldLoad,\n resolve\n });\n });\n // Send all matches here to allow for a middleware-type implementation.\n // handler will be a no-op for unneeded routes and we filter those results\n // back out below.\n let results = await dataStrategyImpl({\n matches: dsMatches,\n request,\n params: matches[0].params,\n fetcherKey,\n context: requestContext\n });\n // Wait for all routes to load here but 'swallow the error since we want\n // it to bubble up from the `await loadRoutePromise` in `callLoaderOrAction` -\n // called from `match.resolve()`\n try {\n await Promise.all(loadRouteDefinitionsPromises);\n } catch (e) {\n // No-op\n }\n return results;\n}\n// Default logic for calling a loader/action is the user has no specified a dataStrategy\nasync function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {\n let result;\n let onReject;\n let runHandler = handler => {\n // Setup a promise we can race against so that abort signals short circuit\n let reject;\n // This will never resolve so safe to type it as Promise to\n // satisfy the function return value\n let abortPromise = new Promise((_, r) => reject = r);\n onReject = () => reject();\n request.signal.addEventListener(\"abort\", onReject);\n let actualHandler = ctx => {\n if (typeof handler !== \"function\") {\n return Promise.reject(new Error(\"You cannot call the handler for a route which defines a boolean \" + (\"\\\"\" + type + \"\\\" [routeId: \" + match.route.id + \"]\")));\n }\n return handler({\n request,\n params: match.params,\n context: staticContext\n }, ...(ctx !== undefined ? [ctx] : []));\n };\n let handlerPromise = (async () => {\n try {\n let val = await (handlerOverride ? handlerOverride(ctx => actualHandler(ctx)) : actualHandler());\n return {\n type: \"data\",\n result: val\n };\n } catch (e) {\n return {\n type: \"error\",\n result: e\n };\n }\n })();\n return Promise.race([handlerPromise, abortPromise]);\n };\n try {\n let handler = match.route[type];\n // If we have a route.lazy promise, await that first\n if (loadRoutePromise) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let handlerError;\n let [value] = await Promise.all([\n // If the handler throws, don't let it immediately bubble out,\n // since we need to let the lazy() execution finish so we know if this\n // route has a boundary that can handle the error\n runHandler(handler).catch(e => {\n handlerError = e;\n }), loadRoutePromise]);\n if (handlerError !== undefined) {\n throw handlerError;\n }\n result = value;\n } else {\n // Load lazy route module, then run any returned handler\n await loadRoutePromise;\n handler = match.route[type];\n if (handler) {\n // Handler still runs even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return {\n type: ResultType.data,\n result: undefined\n };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname\n });\n } else {\n result = await runHandler(handler);\n }\n invariant(result.result !== undefined, \"You defined \" + (type === \"action\" ? \"an action\" : \"a loader\") + \" for route \" + (\"\\\"\" + match.route.id + \"\\\" but didn't return anything from your `\" + type + \"` \") + \"function. Please return a value or `null`.\");\n } catch (e) {\n // We should already be catching and converting normal handler executions to\n // DataStrategyResults and returning them, so anything that throws here is an\n // unexpected error we still need to wrap\n return {\n type: ResultType.error,\n result: e\n };\n } finally {\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n return result;\n}\nasync function convertDataStrategyResultToDataResult(dataStrategyResult) {\n let {\n result,\n type\n } = dataStrategyResult;\n if (isResponse(result)) {\n let data;\n try {\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n if (result.body == null) {\n data = null;\n } else {\n data = await result.json();\n }\n } else {\n data = await result.text();\n }\n } catch (e) {\n return {\n type: ResultType.error,\n error: e\n };\n }\n if (type === ResultType.error) {\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(result.status, result.statusText, data),\n statusCode: result.status,\n headers: result.headers\n };\n }\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers\n };\n }\n if (type === ResultType.error) {\n if (isDataWithResponseInit(result)) {\n var _result$init3, _result$init4;\n if (result.data instanceof Error) {\n var _result$init, _result$init2;\n return {\n type: ResultType.error,\n error: result.data,\n statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status,\n headers: (_result$init2 = result.init) != null && _result$init2.headers ? new Headers(result.init.headers) : undefined\n };\n }\n // Convert thrown data() to ErrorResponse instances\n return {\n type: ResultType.error,\n error: new ErrorResponseImpl(((_result$init3 = result.init) == null ? void 0 : _result$init3.status) || 500, undefined, result.data),\n statusCode: isRouteErrorResponse(result) ? result.status : undefined,\n headers: (_result$init4 = result.init) != null && _result$init4.headers ? new Headers(result.init.headers) : undefined\n };\n }\n return {\n type: ResultType.error,\n error: result,\n statusCode: isRouteErrorResponse(result) ? result.status : undefined\n };\n }\n if (isDeferredData(result)) {\n var _result$init5, _result$init6;\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: (_result$init5 = result.init) == null ? void 0 : _result$init5.status,\n headers: ((_result$init6 = result.init) == null ? void 0 : _result$init6.headers) && new Headers(result.init.headers)\n };\n }\n if (isDataWithResponseInit(result)) {\n var _result$init7, _result$init8;\n return {\n type: ResultType.data,\n data: result.data,\n statusCode: (_result$init7 = result.init) == null ? void 0 : _result$init7.status,\n headers: (_result$init8 = result.init) != null && _result$init8.headers ? new Headers(result.init.headers) : undefined\n };\n }\n return {\n type: ResultType.data,\n data: result\n };\n}\n// Support relative routing in internal redirects\nfunction normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, v7_relativeSplatPath) {\n let location = response.headers.get(\"Location\");\n invariant(location, \"Redirects returned/thrown from loaders/actions must have a Location header\");\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n let trimmedMatches = matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1);\n location = normalizeTo(new URL(request.url), trimmedMatches, basename, true, location, v7_relativeSplatPath);\n response.headers.set(\"Location\", location);\n }\n return response;\n}\nfunction normalizeRedirectLocation(location, currentUrl, basename, historyInstance) {\n // Match Chrome's behavior:\n // https://github.com/chromium/chromium/blob/216dbeb61db0c667e62082e5f5400a32d6983df3/content/public/common/url_utils.cc#L82\n let invalidProtocols = [\"about:\", \"blob:\", \"chrome:\", \"chrome-untrusted:\", \"content:\", \"data:\", \"devtools:\", \"file:\", \"filesystem:\",\n // eslint-disable-next-line no-script-url\n \"javascript:\"];\n if (ABSOLUTE_URL_REGEX.test(location)) {\n // Strip off the protocol+origin for same-origin + same-basename absolute redirects\n let normalizedLocation = location;\n let url = normalizedLocation.startsWith(\"//\") ? new URL(currentUrl.protocol + normalizedLocation) : new URL(normalizedLocation);\n if (invalidProtocols.includes(url.protocol)) {\n throw new Error(\"Invalid redirect location\");\n }\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n return url.pathname + url.search + url.hash;\n }\n }\n try {\n let url = historyInstance.createURL(location);\n if (invalidProtocols.includes(url.protocol)) {\n throw new Error(\"Invalid redirect location\");\n }\n } catch (e) {}\n return location;\n}\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(history, location, signal, submission) {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init = {\n signal\n };\n if (submission && isMutationMethod(submission.formMethod)) {\n let {\n formMethod,\n formEncType\n } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n if (formEncType === \"application/json\") {\n init.headers = new Headers({\n \"Content-Type\": formEncType\n });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (formEncType === \"application/x-www-form-urlencoded\" && submission.formData) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n return new Request(url, init);\n}\nfunction convertFormDataToSearchParams(formData) {\n let searchParams = new URLSearchParams();\n for (let [key, value] of formData.entries()) {\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n return searchParams;\n}\nfunction convertSearchParamsToFormData(searchParams) {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()) {\n formData.append(key, value);\n }\n return formData;\n}\nfunction processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) {\n // Fill in loaderData/errors from our loaders\n let loaderData = {};\n let errors = null;\n let statusCode;\n let foundError = false;\n let loaderHeaders = {};\n let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined;\n // Process loader results into state.loaderData/state.errors\n matches.forEach(match => {\n if (!(match.route.id in results)) {\n return;\n }\n let id = match.route.id;\n let result = results[id];\n invariant(!isRedirectResult(result), \"Cannot handle redirect results in processLoaderData\");\n if (isErrorResult(result)) {\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError !== undefined) {\n error = pendingError;\n pendingError = undefined;\n }\n errors = errors || {};\n if (skipLoaderErrorBubbling) {\n errors[id] = error;\n } else {\n // Look upwards from the matched route for the closest ancestor error\n // boundary, defaulting to the root match. Prefer higher error values\n // if lower errors bubble to the same boundary\n let boundaryMatch = findNearestBoundary(matches, id);\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n }\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode != null && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n loaderData[id] = result.data;\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n }\n });\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError !== undefined && pendingActionResult) {\n errors = {\n [pendingActionResult[0]]: pendingError\n };\n loaderData[pendingActionResult[0]] = undefined;\n }\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders\n };\n}\nfunction processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) {\n let {\n loaderData,\n errors\n } = processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble\n );\n // Process results from our revalidating fetchers\n revalidatingFetchers.forEach(rf => {\n let {\n key,\n match,\n controller\n } = rf;\n let result = fetcherResults[key];\n invariant(result, \"Did not find corresponding fetcher result\");\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n // Nothing to do for aborted fetchers\n return;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = _extends({}, errors, {\n [boundaryMatch.route.id]: result.error\n });\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n });\n return {\n loaderData,\n errors\n };\n}\nfunction mergeLoaderData(loaderData, newLoaderData, matches, errors) {\n let mergedLoaderData = _extends({}, newLoaderData);\n for (let match of matches) {\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n if (errors && errors.hasOwnProperty(id)) {\n // Don't keep any loader data below the boundary\n break;\n }\n }\n return mergedLoaderData;\n}\nfunction getActionDataForCommit(pendingActionResult) {\n if (!pendingActionResult) {\n return {};\n }\n return isErrorResult(pendingActionResult[1]) ? {\n // Clear out prior actionData on errors\n actionData: {}\n } : {\n actionData: {\n [pendingActionResult[0]]: pendingActionResult[1].data\n }\n };\n}\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(matches, routeId) {\n let eligibleMatches = routeId ? matches.slice(0, matches.findIndex(m => m.route.id === routeId) + 1) : [...matches];\n return eligibleMatches.reverse().find(m => m.route.hasErrorBoundary === true) || matches[0];\n}\nfunction getShortCircuitMatches(routes) {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route = routes.length === 1 ? routes[0] : routes.find(r => r.index || !r.path || r.path === \"/\") || {\n id: \"__shim-error-route__\"\n };\n return {\n matches: [{\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route\n }],\n route\n };\n}\nfunction getInternalRouterError(status, _temp5) {\n let {\n pathname,\n routeId,\n method,\n type,\n message\n } = _temp5 === void 0 ? {} : _temp5;\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n if (status === 400) {\n statusText = \"Bad Request\";\n if (method && pathname && routeId) {\n errorMessage = \"You made a \" + method + \" request to \\\"\" + pathname + \"\\\" but \" + (\"did not provide a `loader` for route \\\"\" + routeId + \"\\\", \") + \"so there is no way to handle the request.\";\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = \"Route \\\"\" + routeId + \"\\\" does not match URL \\\"\" + pathname + \"\\\"\";\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = \"No route matches URL \\\"\" + pathname + \"\\\"\";\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage = \"You made a \" + method.toUpperCase() + \" request to \\\"\" + pathname + \"\\\" but \" + (\"did not provide an `action` for route \\\"\" + routeId + \"\\\", \") + \"so there is no way to handle the request.\";\n } else if (method) {\n errorMessage = \"Invalid request method \\\"\" + method.toUpperCase() + \"\\\"\";\n }\n }\n return new ErrorResponseImpl(status || 500, statusText, new Error(errorMessage), true);\n}\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(results) {\n let entries = Object.entries(results);\n for (let i = entries.length - 1; i >= 0; i--) {\n let [key, result] = entries[i];\n if (isRedirectResult(result)) {\n return {\n key,\n result\n };\n }\n }\n}\nfunction stripHashFromPath(path) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath(_extends({}, parsedPath, {\n hash: \"\"\n }));\n}\nfunction isHashChangeOnly(a, b) {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\nfunction isDataStrategyResult(result) {\n return result != null && typeof result === \"object\" && \"type\" in result && \"result\" in result && (result.type === ResultType.data || result.type === ResultType.error);\n}\nfunction isRedirectDataStrategyResultResult(result) {\n return isResponse(result.result) && redirectStatusCodes.has(result.result.status);\n}\nfunction isDeferredResult(result) {\n return result.type === ResultType.deferred;\n}\nfunction isErrorResult(result) {\n return result.type === ResultType.error;\n}\nfunction isRedirectResult(result) {\n return (result && result.type) === ResultType.redirect;\n}\nfunction isDataWithResponseInit(value) {\n return typeof value === \"object\" && value != null && \"type\" in value && \"data\" in value && \"init\" in value && value.type === \"DataWithResponseInit\";\n}\nfunction isDeferredData(value) {\n let deferred = value;\n return deferred && typeof deferred === \"object\" && typeof deferred.data === \"object\" && typeof deferred.subscribe === \"function\" && typeof deferred.cancel === \"function\" && typeof deferred.resolveData === \"function\";\n}\nfunction isResponse(value) {\n return value != null && typeof value.status === \"number\" && typeof value.statusText === \"string\" && typeof value.headers === \"object\" && typeof value.body !== \"undefined\";\n}\nfunction isRedirectResponse(result) {\n if (!isResponse(result)) {\n return false;\n }\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\nfunction isValidMethod(method) {\n return validRequestMethods.has(method.toLowerCase());\n}\nfunction isMutationMethod(method) {\n return validMutationMethods.has(method.toLowerCase());\n}\nasync function resolveNavigationDeferredResults(matches, results, signal, currentMatches, currentLoaderData) {\n let entries = Object.entries(results);\n for (let index = 0; index < entries.length; index++) {\n let [routeId, result] = entries[index];\n let match = matches.find(m => (m == null ? void 0 : m.route.id) === routeId);\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n let currentMatch = currentMatches.find(m => m.route.id === match.route.id);\n let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n if (isDeferredResult(result) && isRevalidatingLoader) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n await resolveDeferredData(result, signal, false).then(result => {\n if (result) {\n results[routeId] = result;\n }\n });\n }\n }\n}\nasync function resolveFetcherDeferredResults(matches, results, revalidatingFetchers) {\n for (let index = 0; index < revalidatingFetchers.length; index++) {\n let {\n key,\n routeId,\n controller\n } = revalidatingFetchers[index];\n let result = results[key];\n let match = matches.find(m => (m == null ? void 0 : m.route.id) === routeId);\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n if (isDeferredResult(result)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n invariant(controller, \"Expected an AbortController for revalidating fetcher deferred result\");\n await resolveDeferredData(result, controller.signal, true).then(result => {\n if (result) {\n results[key] = result;\n }\n });\n }\n }\n}\nasync function resolveDeferredData(result, signal, unwrap) {\n if (unwrap === void 0) {\n unwrap = false;\n }\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e\n };\n }\n }\n return {\n type: ResultType.data,\n data: result.deferredData.data\n };\n}\nfunction hasNakedIndexQuery(search) {\n return new URLSearchParams(search).getAll(\"index\").some(v => v === \"\");\n}\nfunction getTargetMatch(matches, location) {\n let search = typeof location === \"string\" ? parsePath(location).search : location.search;\n if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || \"\")) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\nfunction getSubmissionFromNavigation(navigation) {\n let {\n formMethod,\n formAction,\n formEncType,\n text,\n formData,\n json\n } = navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined\n };\n }\n}\nfunction getLoadingNavigation(location, submission) {\n if (submission) {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n } else {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n };\n return navigation;\n }\n}\nfunction getSubmittingNavigation(location, submission) {\n let navigation = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n}\nfunction getLoadingFetcher(submission, data) {\n if (submission) {\n let fetcher = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data\n };\n return fetcher;\n } else {\n let fetcher = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data\n };\n return fetcher;\n }\n}\nfunction getSubmittingFetcher(submission, existingFetcher) {\n let fetcher = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined\n };\n return fetcher;\n}\nfunction getDoneFetcher(data) {\n let fetcher = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data\n };\n return fetcher;\n}\nfunction restoreAppliedTransitions(_window, transitions) {\n try {\n let sessionPositions = _window.sessionStorage.getItem(TRANSITIONS_STORAGE_KEY);\n if (sessionPositions) {\n let json = JSON.parse(sessionPositions);\n for (let [k, v] of Object.entries(json || {})) {\n if (v && Array.isArray(v)) {\n transitions.set(k, new Set(v || []));\n }\n }\n }\n } catch (e) {\n // no-op, use default empty object\n }\n}\nfunction persistAppliedTransitions(_window, transitions) {\n if (transitions.size > 0) {\n let json = {};\n for (let [k, v] of transitions) {\n json[k] = [...v];\n }\n try {\n _window.sessionStorage.setItem(TRANSITIONS_STORAGE_KEY, JSON.stringify(json));\n } catch (error) {\n warning(false, \"Failed to save applied view transitions in sessionStorage (\" + error + \").\");\n }\n }\n}\n//#endregion\n\nexport { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, decodePath as UNSAFE_decodePath, getResolveToMatches as UNSAFE_getResolveToMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, data, defer, generatePath, getStaticContextFromError, getToPathname, isDataWithResponseInit, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, replace, resolvePath, resolveTo, stripBasename };\n//# sourceMappingURL=router.js.map\n","/**\n * React Router v6.30.3\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */\nimport * as React from 'react';\nimport { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_decodePath, UNSAFE_getResolveToMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, UNSAFE_convertRouteMatchToUiMatch, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';\nexport { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, replace, resolvePath } from '@remix-run/router';\n\nfunction _extends() {\n _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return _extends.apply(this, arguments);\n}\n\n// Create react-specific types from the agnostic types in @remix-run/router to\n// export from react-router\nconst DataRouterContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterContext.displayName = \"DataRouter\";\n}\nconst DataRouterStateContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterStateContext.displayName = \"DataRouterState\";\n}\nconst AwaitContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n AwaitContext.displayName = \"Await\";\n}\n\n/**\n * A Navigator is a \"location changer\"; it's how you get to different locations.\n *\n * Every history instance conforms to the Navigator interface, but the\n * distinction is useful primarily when it comes to the low-level `` API\n * where both the location and a navigator must be provided separately in order\n * to avoid \"tearing\" that may occur in a suspense-enabled app if the action\n * and/or location were to be read directly from the history instance.\n */\n\nconst NavigationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n NavigationContext.displayName = \"Navigation\";\n}\nconst LocationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n LocationContext.displayName = \"Location\";\n}\nconst RouteContext = /*#__PURE__*/React.createContext({\n outlet: null,\n matches: [],\n isDataRoute: false\n});\nif (process.env.NODE_ENV !== \"production\") {\n RouteContext.displayName = \"Route\";\n}\nconst RouteErrorContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n RouteErrorContext.displayName = \"RouteError\";\n}\n\n/**\n * Returns the full href for the given \"to\" value. This is useful for building\n * custom links that are also accessible and preserve right-click behavior.\n *\n * @see https://reactrouter.com/v6/hooks/use-href\n */\nfunction useHref(to, _temp) {\n let {\n relative\n } = _temp === void 0 ? {} : _temp;\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useHref() may be used only in the context of a component.\") : UNSAFE_invariant(false) : void 0;\n let {\n basename,\n navigator\n } = React.useContext(NavigationContext);\n let {\n hash,\n pathname,\n search\n } = useResolvedPath(to, {\n relative\n });\n let joinedPathname = pathname;\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to creating the href. If this is a root navigation, then just use the raw\n // basename which allows the basename to have full control over the presence\n // of a trailing slash on root links\n if (basename !== \"/\") {\n joinedPathname = pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n }\n return navigator.createHref({\n pathname: joinedPathname,\n search,\n hash\n });\n}\n\n/**\n * Returns true if this component is a descendant of a ``.\n *\n * @see https://reactrouter.com/v6/hooks/use-in-router-context\n */\nfunction useInRouterContext() {\n return React.useContext(LocationContext) != null;\n}\n\n/**\n * Returns the current location object, which represents the current URL in web\n * browsers.\n *\n * Note: If you're using this it may mean you're doing some of your own\n * \"routing\" in your app, and we'd like to know what your use case is. We may\n * be able to provide something higher-level to better suit your needs.\n *\n * @see https://reactrouter.com/v6/hooks/use-location\n */\nfunction useLocation() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useLocation() may be used only in the context of a component.\") : UNSAFE_invariant(false) : void 0;\n return React.useContext(LocationContext).location;\n}\n\n/**\n * Returns the current navigation action which describes how the router came to\n * the current location, either by a pop, push, or replace on the history stack.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigation-type\n */\nfunction useNavigationType() {\n return React.useContext(LocationContext).navigationType;\n}\n\n/**\n * Returns a PathMatch object if the given pattern matches the current URL.\n * This is useful for components that need to know \"active\" state, e.g.\n * ``.\n *\n * @see https://reactrouter.com/v6/hooks/use-match\n */\nfunction useMatch(pattern) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useMatch() may be used only in the context of a component.\") : UNSAFE_invariant(false) : void 0;\n let {\n pathname\n } = useLocation();\n return React.useMemo(() => matchPath(pattern, UNSAFE_decodePath(pathname)), [pathname, pattern]);\n}\n\n/**\n * The interface for the navigate() function returned from useNavigate().\n */\n\nconst navigateEffectWarning = \"You should call navigate() in a React.useEffect(), not when \" + \"your component is first rendered.\";\n\n// Mute warnings for calls to useNavigate in SSR environments\nfunction useIsomorphicLayoutEffect(cb) {\n let isStatic = React.useContext(NavigationContext).static;\n if (!isStatic) {\n // We should be able to get rid of this once react 18.3 is released\n // See: https://github.com/facebook/react/pull/26395\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useLayoutEffect(cb);\n }\n}\n\n/**\n * Returns an imperative method for changing the location. Used by ``s, but\n * may also be used by other elements to change the location.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigate\n */\nfunction useNavigate() {\n let {\n isDataRoute\n } = React.useContext(RouteContext);\n // Conditional usage is OK here because the usage of a data router is static\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return isDataRoute ? useNavigateStable() : useNavigateUnstable();\n}\nfunction useNavigateUnstable() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useNavigate() may be used only in the context of a component.\") : UNSAFE_invariant(false) : void 0;\n let dataRouterContext = React.useContext(DataRouterContext);\n let {\n basename,\n future,\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our history listener yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n navigator.go(to);\n return;\n }\n let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === \"path\");\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to handing off to history (but only if we're not in a data router,\n // otherwise it'll prepend the basename inside of the router).\n // If this is a root navigation, then we navigate to the raw basename\n // which allows the basename to have full control over the presence of a\n // trailing slash on root links\n if (dataRouterContext == null && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);\n }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);\n return navigate;\n}\nconst OutletContext = /*#__PURE__*/React.createContext(null);\n\n/**\n * Returns the context (if provided) for the child route at this level of the route\n * hierarchy.\n * @see https://reactrouter.com/v6/hooks/use-outlet-context\n */\nfunction useOutletContext() {\n return React.useContext(OutletContext);\n}\n\n/**\n * Returns the element for the child route at this level of the route\n * hierarchy. Used internally by `` to render child routes.\n *\n * @see https://reactrouter.com/v6/hooks/use-outlet\n */\nfunction useOutlet(context) {\n let outlet = React.useContext(RouteContext).outlet;\n if (outlet) {\n return /*#__PURE__*/React.createElement(OutletContext.Provider, {\n value: context\n }, outlet);\n }\n return outlet;\n}\n\n/**\n * Returns an object of key/value pairs of the dynamic params from the current\n * URL that were matched by the route path.\n *\n * @see https://reactrouter.com/v6/hooks/use-params\n */\nfunction useParams() {\n let {\n matches\n } = React.useContext(RouteContext);\n let routeMatch = matches[matches.length - 1];\n return routeMatch ? routeMatch.params : {};\n}\n\n/**\n * Resolves the pathname of the given `to` value against the current location.\n *\n * @see https://reactrouter.com/v6/hooks/use-resolved-path\n */\nfunction useResolvedPath(to, _temp2) {\n let {\n relative\n } = _temp2 === void 0 ? {} : _temp2;\n let {\n future\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === \"path\"), [to, routePathnamesJson, locationPathname, relative]);\n}\n\n/**\n * Returns the element of the route that matched the current location, prepared\n * with the correct context to render the remainder of the route tree. Route\n * elements in the tree must render an `` to render their child route's\n * element.\n *\n * @see https://reactrouter.com/v6/hooks/use-routes\n */\nfunction useRoutes(routes, locationArg) {\n return useRoutesImpl(routes, locationArg);\n}\n\n// Internal implementation with accept optional param for RouterProvider usage\nfunction useRoutesImpl(routes, locationArg, dataRouterState, future) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useRoutes() may be used only in the context of a component.\") : UNSAFE_invariant(false) : void 0;\n let {\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches: parentMatches\n } = React.useContext(RouteContext);\n let routeMatch = parentMatches[parentMatches.length - 1];\n let parentParams = routeMatch ? routeMatch.params : {};\n let parentPathname = routeMatch ? routeMatch.pathname : \"/\";\n let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : \"/\";\n let parentRoute = routeMatch && routeMatch.route;\n if (process.env.NODE_ENV !== \"production\") {\n // You won't get a warning about 2 different under a \n // without a trailing *, but this is a best-effort warning anyway since we\n // cannot even give the warning unless they land at the parent route.\n //\n // Example:\n //\n // \n // {/* This route path MUST end with /* because otherwise\n // it will never match /blog/post/123 */}\n // } />\n // } />\n // \n //\n // function Blog() {\n // return (\n // \n // } />\n // \n // );\n // }\n let parentPath = parentRoute && parentRoute.path || \"\";\n warningOnce(parentPathname, !parentRoute || parentPath.endsWith(\"*\"), \"You rendered descendant (or called `useRoutes()`) at \" + (\"\\\"\" + parentPathname + \"\\\" (under ) but the \") + \"parent route path has no trailing \\\"*\\\". This means if you navigate \" + \"deeper, the parent won't match anymore and therefore the child \" + \"routes will never render.\\n\\n\" + (\"Please change the parent to .\"));\n }\n let locationFromContext = useLocation();\n let location;\n if (locationArg) {\n var _parsedLocationArg$pa;\n let parsedLocationArg = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n !(parentPathnameBase === \"/\" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"When overriding the location using `` or `useRoutes(routes, location)`, \" + \"the location pathname must begin with the portion of the URL pathname that was \" + (\"matched by all parent routes. The current pathname base is \\\"\" + parentPathnameBase + \"\\\" \") + (\"but pathname \\\"\" + parsedLocationArg.pathname + \"\\\" was given in the `location` prop.\")) : UNSAFE_invariant(false) : void 0;\n location = parsedLocationArg;\n } else {\n location = locationFromContext;\n }\n let pathname = location.pathname || \"/\";\n let remainingPathname = pathname;\n if (parentPathnameBase !== \"/\") {\n // Determine the remaining pathname by removing the # of URL segments the\n // parentPathnameBase has, instead of removing based on character count.\n // This is because we can't guarantee that incoming/outgoing encodings/\n // decodings will match exactly.\n // We decode paths before matching on a per-segment basis with\n // decodeURIComponent(), but we re-encode pathnames via `new URL()` so they\n // match what `window.location.pathname` would reflect. Those don't 100%\n // align when it comes to encoded URI characters such as % and &.\n //\n // So we may end up with:\n // pathname: \"/descendant/a%25b/match\"\n // parentPathnameBase: \"/descendant/a%b\"\n //\n // And the direct substring removal approach won't work :/\n let parentSegments = parentPathnameBase.replace(/^\\//, \"\").split(\"/\");\n let segments = pathname.replace(/^\\//, \"\").split(\"/\");\n remainingPathname = \"/\" + segments.slice(parentSegments.length).join(\"/\");\n }\n let matches = matchRoutes(routes, {\n pathname: remainingPathname\n });\n if (process.env.NODE_ENV !== \"production\") {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(parentRoute || matches != null, \"No routes matched location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \") : void 0;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(matches == null || matches[matches.length - 1].route.element !== undefined || matches[matches.length - 1].route.Component !== undefined || matches[matches.length - 1].route.lazy !== undefined, \"Matched leaf route at location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \" + \"does not have an element or Component. This means it will render an with a \" + \"null value by default resulting in an \\\"empty\\\" page.\") : void 0;\n }\n let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {\n params: Object.assign({}, parentParams, match.params),\n pathname: joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]),\n pathnameBase: match.pathnameBase === \"/\" ? parentPathnameBase : joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])\n })), parentMatches, dataRouterState, future);\n\n // When a user passes in a `locationArg`, the associated routes need to\n // be wrapped in a new `LocationContext.Provider` in order for `useLocation`\n // to use the scoped location instead of the global location.\n if (locationArg && renderedMatches) {\n return /*#__PURE__*/React.createElement(LocationContext.Provider, {\n value: {\n location: _extends({\n pathname: \"/\",\n search: \"\",\n hash: \"\",\n state: null,\n key: \"default\"\n }, location),\n navigationType: Action.Pop\n }\n }, renderedMatches);\n }\n return renderedMatches;\n}\nfunction DefaultErrorComponent() {\n let error = useRouteError();\n let message = isRouteErrorResponse(error) ? error.status + \" \" + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);\n let stack = error instanceof Error ? error.stack : null;\n let lightgrey = \"rgba(200,200,200, 0.5)\";\n let preStyles = {\n padding: \"0.5rem\",\n backgroundColor: lightgrey\n };\n let codeStyles = {\n padding: \"2px 4px\",\n backgroundColor: lightgrey\n };\n let devInfo = null;\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Error handled by React Router default ErrorBoundary:\", error);\n devInfo = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"p\", null, \"\\uD83D\\uDCBF Hey developer \\uD83D\\uDC4B\"), /*#__PURE__*/React.createElement(\"p\", null, \"You can provide a way better UX than this when your app throws errors by providing your own \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"ErrorBoundary\"), \" or\", \" \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"errorElement\"), \" prop on your route.\"));\n }\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"h2\", null, \"Unexpected Application Error!\"), /*#__PURE__*/React.createElement(\"h3\", {\n style: {\n fontStyle: \"italic\"\n }\n }, message), stack ? /*#__PURE__*/React.createElement(\"pre\", {\n style: preStyles\n }, stack) : null, devInfo);\n}\nconst defaultErrorElement = /*#__PURE__*/React.createElement(DefaultErrorComponent, null);\nclass RenderErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n location: props.location,\n revalidation: props.revalidation,\n error: props.error\n };\n }\n static getDerivedStateFromError(error) {\n return {\n error: error\n };\n }\n static getDerivedStateFromProps(props, state) {\n // When we get into an error state, the user will likely click \"back\" to the\n // previous page that didn't have an error. Because this wraps the entire\n // application, that will have no effect--the error page continues to display.\n // This gives us a mechanism to recover from the error when the location changes.\n //\n // Whether we're in an error state or not, we update the location in state\n // so that when we are in an error state, it gets reset when a new location\n // comes in and the user recovers from the error.\n if (state.location !== props.location || state.revalidation !== \"idle\" && props.revalidation === \"idle\") {\n return {\n error: props.error,\n location: props.location,\n revalidation: props.revalidation\n };\n }\n\n // If we're not changing locations, preserve the location but still surface\n // any new errors that may come through. We retain the existing error, we do\n // this because the error provided from the app state may be cleared without\n // the location changing.\n return {\n error: props.error !== undefined ? props.error : state.error,\n location: state.location,\n revalidation: props.revalidation || state.revalidation\n };\n }\n componentDidCatch(error, errorInfo) {\n console.error(\"React Router caught the following error during render\", error, errorInfo);\n }\n render() {\n return this.state.error !== undefined ? /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: this.props.routeContext\n }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {\n value: this.state.error,\n children: this.props.component\n })) : this.props.children;\n }\n}\nfunction RenderedRoute(_ref) {\n let {\n routeContext,\n match,\n children\n } = _ref;\n let dataRouterContext = React.useContext(DataRouterContext);\n\n // Track how deep we got in our render pass to emulate SSR componentDidCatch\n // in a DataStaticRouter\n if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {\n dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;\n }\n return /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: routeContext\n }, children);\n}\nfunction _renderMatches(matches, parentMatches, dataRouterState, future) {\n var _dataRouterState;\n if (parentMatches === void 0) {\n parentMatches = [];\n }\n if (dataRouterState === void 0) {\n dataRouterState = null;\n }\n if (future === void 0) {\n future = null;\n }\n if (matches == null) {\n var _future;\n if (!dataRouterState) {\n return null;\n }\n if (dataRouterState.errors) {\n // Don't bail if we have data router errors so we can render them in the\n // boundary. Use the pre-matched (or shimmed) matches\n matches = dataRouterState.matches;\n } else if ((_future = future) != null && _future.v7_partialHydration && parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {\n // Don't bail if we're initializing with partial hydration and we have\n // router matches. That means we're actively running `patchRoutesOnNavigation`\n // so we should render down the partial matches to the appropriate\n // `HydrateFallback`. We only do this if `parentMatches` is empty so it\n // only impacts the root matches for `RouterProvider` and no descendant\n // ``\n matches = dataRouterState.matches;\n } else {\n return null;\n }\n }\n let renderedMatches = matches;\n\n // If we have data errors, trim matches to the highest error boundary\n let errors = (_dataRouterState = dataRouterState) == null ? void 0 : _dataRouterState.errors;\n if (errors != null) {\n let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]) !== undefined);\n !(errorIndex >= 0) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"Could not find a matching route for errors on route IDs: \" + Object.keys(errors).join(\",\")) : UNSAFE_invariant(false) : void 0;\n renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));\n }\n\n // If we're in a partial hydration mode, detect if we need to render down to\n // a given HydrateFallback while we load the rest of the hydration data\n let renderFallback = false;\n let fallbackIndex = -1;\n if (dataRouterState && future && future.v7_partialHydration) {\n for (let i = 0; i < renderedMatches.length; i++) {\n let match = renderedMatches[i];\n // Track the deepest fallback up until the first route without data\n if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {\n fallbackIndex = i;\n }\n if (match.route.id) {\n let {\n loaderData,\n errors\n } = dataRouterState;\n let needsToRunLoader = match.route.loader && loaderData[match.route.id] === undefined && (!errors || errors[match.route.id] === undefined);\n if (match.route.lazy || needsToRunLoader) {\n // We found the first route that's not ready to render (waiting on\n // lazy, or has a loader that hasn't run yet). Flag that we need to\n // render a fallback and render up until the appropriate fallback\n renderFallback = true;\n if (fallbackIndex >= 0) {\n renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);\n } else {\n renderedMatches = [renderedMatches[0]];\n }\n break;\n }\n }\n }\n }\n return renderedMatches.reduceRight((outlet, match, index) => {\n // Only data routers handle errors/fallbacks\n let error;\n let shouldRenderHydrateFallback = false;\n let errorElement = null;\n let hydrateFallbackElement = null;\n if (dataRouterState) {\n error = errors && match.route.id ? errors[match.route.id] : undefined;\n errorElement = match.route.errorElement || defaultErrorElement;\n if (renderFallback) {\n if (fallbackIndex < 0 && index === 0) {\n warningOnce(\"route-fallback\", false, \"No `HydrateFallback` element provided to render during initial hydration\");\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = null;\n } else if (fallbackIndex === index) {\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = match.route.hydrateFallbackElement || null;\n }\n }\n }\n let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));\n let getChildren = () => {\n let children;\n if (error) {\n children = errorElement;\n } else if (shouldRenderHydrateFallback) {\n children = hydrateFallbackElement;\n } else if (match.route.Component) {\n // Note: This is a de-optimized path since React won't re-use the\n // ReactElement since it's identity changes with each new\n // React.createElement call. We keep this so folks can use\n // `` in `` but generally `Component`\n // usage is only advised in `RouterProvider` when we can convert it to\n // `element` ahead of time.\n children = /*#__PURE__*/React.createElement(match.route.Component, null);\n } else if (match.route.element) {\n children = match.route.element;\n } else {\n children = outlet;\n }\n return /*#__PURE__*/React.createElement(RenderedRoute, {\n match: match,\n routeContext: {\n outlet,\n matches,\n isDataRoute: dataRouterState != null\n },\n children: children\n });\n };\n // Only wrap in an error boundary within data router usages when we have an\n // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to\n // an ancestor ErrorBoundary/errorElement\n return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {\n location: dataRouterState.location,\n revalidation: dataRouterState.revalidation,\n component: errorElement,\n error: error,\n children: getChildren(),\n routeContext: {\n outlet: null,\n matches,\n isDataRoute: true\n }\n }) : getChildren();\n }, null);\n}\nvar DataRouterHook = /*#__PURE__*/function (DataRouterHook) {\n DataRouterHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterHook[\"UseNavigateStable\"] = \"useNavigate\";\n return DataRouterHook;\n}(DataRouterHook || {});\nvar DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {\n DataRouterStateHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterStateHook[\"UseLoaderData\"] = \"useLoaderData\";\n DataRouterStateHook[\"UseActionData\"] = \"useActionData\";\n DataRouterStateHook[\"UseRouteError\"] = \"useRouteError\";\n DataRouterStateHook[\"UseNavigation\"] = \"useNavigation\";\n DataRouterStateHook[\"UseRouteLoaderData\"] = \"useRouteLoaderData\";\n DataRouterStateHook[\"UseMatches\"] = \"useMatches\";\n DataRouterStateHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterStateHook[\"UseNavigateStable\"] = \"useNavigate\";\n DataRouterStateHook[\"UseRouteId\"] = \"useRouteId\";\n return DataRouterStateHook;\n}(DataRouterStateHook || {});\nfunction getDataRouterConsoleError(hookName) {\n return hookName + \" must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.\";\n}\nfunction useDataRouterContext(hookName) {\n let ctx = React.useContext(DataRouterContext);\n !ctx ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return ctx;\n}\nfunction useDataRouterState(hookName) {\n let state = React.useContext(DataRouterStateContext);\n !state ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return state;\n}\nfunction useRouteContext(hookName) {\n let route = React.useContext(RouteContext);\n !route ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return route;\n}\n\n// Internal version with hookName-aware debugging\nfunction useCurrentRouteId(hookName) {\n let route = useRouteContext(hookName);\n let thisRoute = route.matches[route.matches.length - 1];\n !thisRoute.route.id ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, hookName + \" can only be used on routes that contain a unique \\\"id\\\"\") : UNSAFE_invariant(false) : void 0;\n return thisRoute.route.id;\n}\n\n/**\n * Returns the ID for the nearest contextual route\n */\nfunction useRouteId() {\n return useCurrentRouteId(DataRouterStateHook.UseRouteId);\n}\n\n/**\n * Returns the current navigation, defaulting to an \"idle\" navigation when\n * no navigation is in progress\n */\nfunction useNavigation() {\n let state = useDataRouterState(DataRouterStateHook.UseNavigation);\n return state.navigation;\n}\n\n/**\n * Returns a revalidate function for manually triggering revalidation, as well\n * as the current state of any manual revalidations\n */\nfunction useRevalidator() {\n let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);\n let state = useDataRouterState(DataRouterStateHook.UseRevalidator);\n return React.useMemo(() => ({\n revalidate: dataRouterContext.router.revalidate,\n state: state.revalidation\n }), [dataRouterContext.router.revalidate, state.revalidation]);\n}\n\n/**\n * Returns the active route matches, useful for accessing loaderData for\n * parent/child routes or the route \"handle\" property\n */\nfunction useMatches() {\n let {\n matches,\n loaderData\n } = useDataRouterState(DataRouterStateHook.UseMatches);\n return React.useMemo(() => matches.map(m => UNSAFE_convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);\n}\n\n/**\n * Returns the loader data for the nearest ancestor Route loader\n */\nfunction useLoaderData() {\n let state = useDataRouterState(DataRouterStateHook.UseLoaderData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n if (state.errors && state.errors[routeId] != null) {\n console.error(\"You cannot `useLoaderData` in an errorElement (routeId: \" + routeId + \")\");\n return undefined;\n }\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the loaderData for the given routeId\n */\nfunction useRouteLoaderData(routeId) {\n let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the action data for the nearest ancestor Route action\n */\nfunction useActionData() {\n let state = useDataRouterState(DataRouterStateHook.UseActionData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n return state.actionData ? state.actionData[routeId] : undefined;\n}\n\n/**\n * Returns the nearest ancestor Route error, which could be a loader/action\n * error or a render error. This is intended to be called from your\n * ErrorBoundary/errorElement to display a proper error message.\n */\nfunction useRouteError() {\n var _state$errors;\n let error = React.useContext(RouteErrorContext);\n let state = useDataRouterState(DataRouterStateHook.UseRouteError);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);\n\n // If this was a render error, we put it in a RouteError context inside\n // of RenderErrorBoundary\n if (error !== undefined) {\n return error;\n }\n\n // Otherwise look for errors from our data router state\n return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];\n}\n\n/**\n * Returns the happy-path data from the nearest ancestor `` value\n */\nfunction useAsyncValue() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._data;\n}\n\n/**\n * Returns the error from the nearest ancestor `` value\n */\nfunction useAsyncError() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._error;\n}\nlet blockerId = 0;\n\n/**\n * Allow the application to block navigations within the SPA and present the\n * user a confirmation dialog to confirm the navigation. Mostly used to avoid\n * using half-filled form data. This does not handle hard-reloads or\n * cross-origin navigations.\n */\nfunction useBlocker(shouldBlock) {\n let {\n router,\n basename\n } = useDataRouterContext(DataRouterHook.UseBlocker);\n let state = useDataRouterState(DataRouterStateHook.UseBlocker);\n let [blockerKey, setBlockerKey] = React.useState(\"\");\n let blockerFunction = React.useCallback(arg => {\n if (typeof shouldBlock !== \"function\") {\n return !!shouldBlock;\n }\n if (basename === \"/\") {\n return shouldBlock(arg);\n }\n\n // If they provided us a function and we've got an active basename, strip\n // it from the locations we expose to the user to match the behavior of\n // useLocation\n let {\n currentLocation,\n nextLocation,\n historyAction\n } = arg;\n return shouldBlock({\n currentLocation: _extends({}, currentLocation, {\n pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname\n }),\n nextLocation: _extends({}, nextLocation, {\n pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname\n }),\n historyAction\n });\n }, [basename, shouldBlock]);\n\n // This effect is in charge of blocker key assignment and deletion (which is\n // tightly coupled to the key)\n React.useEffect(() => {\n let key = String(++blockerId);\n setBlockerKey(key);\n return () => router.deleteBlocker(key);\n }, [router]);\n\n // This effect handles assigning the blockerFunction. This is to handle\n // unstable blocker function identities, and happens only after the prior\n // effect so we don't get an orphaned blockerFunction in the router with a\n // key of \"\". Until then we just have the IDLE_BLOCKER.\n React.useEffect(() => {\n if (blockerKey !== \"\") {\n router.getBlocker(blockerKey, blockerFunction);\n }\n }, [router, blockerKey, blockerFunction]);\n\n // Prefer the blocker from `state` not `router.state` since DataRouterContext\n // is memoized so this ensures we update on blocker state updates\n return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;\n}\n\n/**\n * Stable version of useNavigate that is used when we are in the context of\n * a RouterProvider.\n */\nfunction useNavigateStable() {\n let {\n router\n } = useDataRouterContext(DataRouterHook.UseNavigateStable);\n let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our router subscriber yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n router.navigate(to);\n } else {\n router.navigate(to, _extends({\n fromRouteId: id\n }, options));\n }\n }, [router, id]);\n return navigate;\n}\nconst alreadyWarned$1 = {};\nfunction warningOnce(key, cond, message) {\n if (!cond && !alreadyWarned$1[key]) {\n alreadyWarned$1[key] = true;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, message) : void 0;\n }\n}\n\nconst alreadyWarned = {};\nfunction warnOnce(key, message) {\n if (process.env.NODE_ENV !== \"production\" && !alreadyWarned[message]) {\n alreadyWarned[message] = true;\n console.warn(message);\n }\n}\nconst logDeprecation = (flag, msg, link) => warnOnce(flag, \"\\u26A0\\uFE0F React Router Future Flag Warning: \" + msg + \". \" + (\"You can use the `\" + flag + \"` future flag to opt-in early. \") + (\"For more information, see \" + link + \".\"));\nfunction logV6DeprecationWarnings(renderFuture, routerFuture) {\n if ((renderFuture == null ? void 0 : renderFuture.v7_startTransition) === undefined) {\n logDeprecation(\"v7_startTransition\", \"React Router will begin wrapping state updates in `React.startTransition` in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_starttransition\");\n }\n if ((renderFuture == null ? void 0 : renderFuture.v7_relativeSplatPath) === undefined && (!routerFuture || routerFuture.v7_relativeSplatPath === undefined)) {\n logDeprecation(\"v7_relativeSplatPath\", \"Relative route resolution within Splat routes is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath\");\n }\n if (routerFuture) {\n if (routerFuture.v7_fetcherPersist === undefined) {\n logDeprecation(\"v7_fetcherPersist\", \"The persistence behavior of fetchers is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_fetcherpersist\");\n }\n if (routerFuture.v7_normalizeFormMethod === undefined) {\n logDeprecation(\"v7_normalizeFormMethod\", \"Casing of `formMethod` fields is being normalized to uppercase in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_normalizeformmethod\");\n }\n if (routerFuture.v7_partialHydration === undefined) {\n logDeprecation(\"v7_partialHydration\", \"`RouterProvider` hydration behavior is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_partialhydration\");\n }\n if (routerFuture.v7_skipActionErrorRevalidation === undefined) {\n logDeprecation(\"v7_skipActionErrorRevalidation\", \"The revalidation behavior after 4xx/5xx `action` responses is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_skipactionerrorrevalidation\");\n }\n }\n}\n\n/**\n Webpack + React 17 fails to compile on any of the following because webpack\n complains that `startTransition` doesn't exist in `React`:\n * import { startTransition } from \"react\"\n * import * as React from from \"react\";\n \"startTransition\" in React ? React.startTransition(() => setState()) : setState()\n * import * as React from from \"react\";\n \"startTransition\" in React ? React[\"startTransition\"](() => setState()) : setState()\n\n Moving it to a constant such as the following solves the Webpack/React 17 issue:\n * import * as React from from \"react\";\n const START_TRANSITION = \"startTransition\";\n START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()\n\n However, that introduces webpack/terser minification issues in production builds\n in React 18 where minification/obfuscation ends up removing the call of\n React.startTransition entirely from the first half of the ternary. Grabbing\n this exported reference once up front resolves that issue.\n\n See https://github.com/remix-run/react-router/issues/10579\n*/\nconst START_TRANSITION = \"startTransition\";\nconst startTransitionImpl = React[START_TRANSITION];\n\n/**\n * Given a Remix Router instance, render the appropriate UI\n */\nfunction RouterProvider(_ref) {\n let {\n fallbackElement,\n router,\n future\n } = _ref;\n let [state, setStateImpl] = React.useState(router.state);\n let {\n v7_startTransition\n } = future || {};\n let setState = React.useCallback(newState => {\n if (v7_startTransition && startTransitionImpl) {\n startTransitionImpl(() => setStateImpl(newState));\n } else {\n setStateImpl(newState);\n }\n }, [setStateImpl, v7_startTransition]);\n\n // Need to use a layout effect here so we are subscribed early enough to\n // pick up on any render-driven redirects/navigations (useEffect/)\n React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);\n React.useEffect(() => {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, \"`` is deprecated when using \" + \"`v7_partialHydration`, use a `HydrateFallback` component instead\") : void 0;\n // Only log this once on initial mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n let navigator = React.useMemo(() => {\n return {\n createHref: router.createHref,\n encodeLocation: router.encodeLocation,\n go: n => router.navigate(n),\n push: (to, state, opts) => router.navigate(to, {\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n }),\n replace: (to, state, opts) => router.navigate(to, {\n replace: true,\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n })\n };\n }, [router]);\n let basename = router.basename || \"/\";\n let dataRouterContext = React.useMemo(() => ({\n router,\n navigator,\n static: false,\n basename\n }), [router, navigator, basename]);\n React.useEffect(() => logV6DeprecationWarnings(future, router.future), [router, future]);\n\n // The fragment and {null} here are important! We need them to keep React 18's\n // useId happy when we are server-rendering since we may have a - + +
diff --git a/packages/rn-sdk/src/__tests__/CameraHandler.test.ts b/packages/rn-sdk/src/__tests__/CameraHandler.test.ts index 84566ac14..17559bf1b 100644 --- a/packages/rn-sdk/src/__tests__/CameraHandler.test.ts +++ b/packages/rn-sdk/src/__tests__/CameraHandler.test.ts @@ -2,23 +2,68 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +const { startScanning } = vi.hoisted(() => ({ + startScanning: vi.fn(), +})); + +vi.mock('react-native', () => ({ + NativeModules: { + SelfMRZScannerModule: { + startScanning, + }, + }, +})); + import { CameraHandler } from '../handlers/CameraHandler'; describe('CameraHandler', () => { const handler = new CameraHandler(); + beforeEach(() => { + vi.clearAllMocks(); + }); + it('has domain "camera"', () => { expect(handler.domain).toBe('camera'); }); - it('isAvailable returns true', async () => { + it('isAvailable returns true when native MRZ module is present', async () => { const result = await handler.handle('isAvailable', {}); expect(result).toBe(true); }); - it('scanMRZ throws NOT_IMPLEMENTED', async () => { - await expect(handler.handle('scanMRZ', {})).rejects.toThrow('MRZ scan not yet implemented'); + it('scanMRZ returns normalized MRZ data', async () => { + startScanning.mockResolvedValue({ + data: { + documentNumber: 'L898902C3', + birthDate: '740812', + expiryDate: '120415', + documentType: 'P', + countryCode: 'UTO', + }, + }); + + await expect(handler.handle('scanMRZ', {})).resolves.toEqual({ + documentNumber: 'L898902C3', + dateOfBirth: '740812', + dateOfExpiry: '120415', + documentType: 'P', + countryCode: 'UTO', + }); + }); + + it('scanMRZ throws MRZ_SCAN_FAILED when native scanner rejects', async () => { + startScanning.mockRejectedValue(new Error('Camera permission denied')); + + try { + await handler.handle('scanMRZ', {}); + expect.unreachable('Should have thrown'); + } catch (err: unknown) { + expect((err as { code: string }).code).toBe('MRZ_SCAN_FAILED'); + expect((err as Error).message).toBe('MRZ scan failed'); + } }); it('unknown method throws METHOD_NOT_FOUND', async () => { diff --git a/packages/rn-sdk/src/__tests__/NfcHandler.test.ts b/packages/rn-sdk/src/__tests__/NfcHandler.test.ts index 90c10ca51..cd217c3ca 100644 --- a/packages/rn-sdk/src/__tests__/NfcHandler.test.ts +++ b/packages/rn-sdk/src/__tests__/NfcHandler.test.ts @@ -18,6 +18,7 @@ function createMockNfc() { start: vi.fn(), requestTechnology: vi.fn(), getTag: vi.fn(), + transceive: vi.fn(), cancelTechnologyRequest: vi.fn(), }; const tech: NfcTechEnum = { @@ -79,6 +80,7 @@ describe('NfcHandler', () => { (mockNfc.manager.start as ReturnType).mockResolvedValue(undefined); (mockNfc.manager.requestTechnology as ReturnType).mockResolvedValue(undefined); (mockNfc.manager.getTag as ReturnType).mockResolvedValue({ id: 'tag-123' }); + (mockNfc.manager.transceive as ReturnType).mockResolvedValue([0x90, 0x00]); (mockNfc.manager.cancelTechnologyRequest as ReturnType).mockResolvedValue(undefined); }); @@ -123,6 +125,29 @@ describe('NfcHandler', () => { }); }); + it('returns APDU responses when apduCommands are provided', async () => { + (mockNfc.manager.transceive as ReturnType).mockResolvedValueOnce([0x90, 0x00]); + (mockNfc.manager.transceive as ReturnType).mockResolvedValueOnce([0x6A, 0x82]); + + const result = await handler.handle('scan', { + apduCommands: ['00A4040007A0000002471001', '00B0000000'], + }) as Record; + + expect(result.apduResponses).toEqual(['9000', '6A82']); + expect(mockNfc.manager.transceive).toHaveBeenCalledTimes(2); + }); + + it('throws NFC_APDU_NOT_SUPPORTED when transceive is unavailable', async () => { + delete (mockNfc.manager as Partial).transceive; + + try { + await handler.handle('scan', { apduCommands: ['00A4040000'] }); + expect.unreachable('Should have thrown'); + } catch (err: unknown) { + expect((err as { code: string }).code).toBe('NFC_APDU_NOT_SUPPORTED'); + } + }); + it('throws NFC_SCAN_FAILED on NFC error', async () => { (mockNfc.manager.requestTechnology as ReturnType).mockRejectedValue( new Error('NFC tag lost'), diff --git a/packages/rn-sdk/src/handlers/CameraHandler.ts b/packages/rn-sdk/src/handlers/CameraHandler.ts index e74eb7472..bafb9c3e5 100644 --- a/packages/rn-sdk/src/handlers/CameraHandler.ts +++ b/packages/rn-sdk/src/handlers/CameraHandler.ts @@ -5,19 +5,98 @@ import type { BridgeDomain } from '../bridge/types'; import type { BridgeHandler } from '../bridge/types'; import { BridgeHandlerError } from '../bridge/types'; +import { NativeModules } from 'react-native'; + +interface MrzScannerModule { + startScanning: () => Promise; +} + +interface MrzScanData { + documentNumber: string; + dateOfBirth: string; + dateOfExpiry: string; + documentType?: string; + countryCode?: string; +} + +function loadMrzScannerModule(): MrzScannerModule | null { + const nativeModules = NativeModules as Record; + const scanner = + (nativeModules.SelfMRZScannerModule as MrzScannerModule | undefined) ?? + (nativeModules.MRZScannerModule as MrzScannerModule | undefined); + return scanner ?? null; +} + +function normalizeMrzScanResult(result: unknown): MrzScanData { + const root = (result ?? {}) as Record; + const payload = (root.data ?? root) as Record; + + const documentNumber = + typeof payload.documentNumber === 'string' + ? payload.documentNumber + : typeof payload.passportNumber === 'string' + ? payload.passportNumber + : ''; + const dateOfBirth = + typeof payload.dateOfBirth === 'string' + ? payload.dateOfBirth + : typeof payload.birthDate === 'string' + ? payload.birthDate + : ''; + const dateOfExpiry = + typeof payload.dateOfExpiry === 'string' + ? payload.dateOfExpiry + : typeof payload.expiryDate === 'string' + ? payload.expiryDate + : ''; + const documentType = typeof payload.documentType === 'string' ? payload.documentType : undefined; + const countryCode = typeof payload.countryCode === 'string' ? payload.countryCode : undefined; + + if (!documentNumber || !dateOfBirth || !dateOfExpiry) { + throw new BridgeHandlerError( + 'MRZ_SCAN_INVALID_RESULT', + 'MRZ scan returned incomplete data', + ); + } + + return { + documentNumber, + dateOfBirth, + dateOfExpiry, + documentType, + countryCode, + }; +} export class CameraHandler implements BridgeHandler { readonly domain: BridgeDomain = 'camera'; async handle(method: string, _params: Record): Promise { + const scanner = loadMrzScannerModule(); + switch (method) { case 'isAvailable': - return true; + return scanner !== null && typeof scanner.startScanning === 'function'; case 'scanMRZ': - throw new BridgeHandlerError( - 'NOT_IMPLEMENTED', - 'MRZ scan not yet implemented', - ); + if (!scanner || typeof scanner.startScanning !== 'function') { + throw new BridgeHandlerError( + 'NOT_AVAILABLE', + 'MRZ scanner module is not installed', + ); + } + + try { + const result = await scanner.startScanning(); + return normalizeMrzScanResult(result); + } catch (err) { + if (err instanceof BridgeHandlerError) { + throw err; + } + throw new BridgeHandlerError( + 'MRZ_SCAN_FAILED', + 'MRZ scan failed', + ); + } default: throw new BridgeHandlerError('METHOD_NOT_FOUND', `Unknown camera method: ${method}`); } diff --git a/packages/rn-sdk/src/handlers/NfcHandler.ts b/packages/rn-sdk/src/handlers/NfcHandler.ts index 8c00b9220..d2d76b293 100644 --- a/packages/rn-sdk/src/handlers/NfcHandler.ts +++ b/packages/rn-sdk/src/handlers/NfcHandler.ts @@ -2,8 +2,6 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import { Platform } from 'react-native'; - import type { BridgeDomain } from '../bridge/types'; import type { BridgeHandler } from '../bridge/types'; import { BridgeHandlerError } from '../bridge/types'; @@ -14,6 +12,7 @@ export interface NfcManagerModule { start(): Promise; requestTechnology(tech: string): Promise; getTag(): Promise<{ id?: string } | null>; + transceive?(command: number[]): Promise; cancelTechnologyRequest(): Promise; } @@ -27,6 +26,28 @@ interface NfcDeps { tech: NfcTechEnum; } +function parseApduCommand(hexCommand: string): number[] { + const normalized = hexCommand.trim().replace(/\s+/g, '').toUpperCase(); + if (!/^[0-9A-F]+$/.test(normalized) || normalized.length % 2 !== 0) { + throw new BridgeHandlerError( + 'INVALID_PARAMS', + `Invalid APDU hex command: ${hexCommand}`, + ); + } + + const bytes: number[] = []; + for (let i = 0; i < normalized.length; i += 2) { + bytes.push(Number.parseInt(normalized.slice(i, i + 2), 16)); + } + return bytes; +} + +function toHex(bytes: number[]): string { + return bytes + .map((value) => value.toString(16).padStart(2, '0').toUpperCase()) + .join(''); +} + function loadNfc(): NfcDeps | undefined { try { const mod = require('react-native-nfc-manager'); @@ -83,7 +104,7 @@ export class NfcHandler implements BridgeHandler { await manager.start(); this.pushProgress('waiting_for_tag', 10); - const nfcTech = Platform.OS === 'ios' ? tech.IsoDep : tech.IsoDep; + const nfcTech = tech.IsoDep; await manager.requestTechnology(nfcTech); this.pushProgress('tag_discovered', 30); @@ -91,13 +112,39 @@ export class NfcHandler implements BridgeHandler { const tag = await manager.getTag(); this.pushProgress('connected', 50); + const apduCommands = Array.isArray(params.apduCommands) + ? params.apduCommands.filter((entry): entry is string => typeof entry === 'string') + : []; + let apduResponses: string[] | undefined; + if (apduCommands.length > 0) { + if (typeof manager.transceive !== 'function') { + throw new BridgeHandlerError( + 'NFC_APDU_NOT_SUPPORTED', + 'NFC transceive is not supported by the installed nfc manager', + ); + } + + this.pushProgress('apdu_exchange', 70); + apduResponses = []; + for (const command of apduCommands) { + const commandBytes = parseApduCommand(command); + const responseBytes = await manager.transceive(commandBytes); + apduResponses.push(toHex(responseBytes)); + } + this.pushProgress('apdu_complete', 90); + } + return { connected: true, tagId: tag?.id ?? null, techType: nfcTech, - params, + apduResponses, }; } catch (err) { + if (err instanceof BridgeHandlerError) { + this.pushProgress('error', 0); + throw err; + } this.pushProgress('error', 0); throw new BridgeHandlerError( 'NFC_SCAN_FAILED', diff --git a/packages/webview-app/src/fonts.css b/packages/webview-app/src/fonts.css index fcce8ea73..d5fc06444 100644 --- a/packages/webview-app/src/fonts.css +++ b/packages/webview-app/src/fonts.css @@ -1,25 +1,25 @@ @font-face { - font-family: 'Advercase'; + font-family: 'Advercase-Regular'; src: url('/fonts/Advercase-Regular.otf') format('opentype'); font-display: swap; } @font-face { - font-family: 'DIN OT'; + font-family: 'DINOT-Bold'; src: url('/fonts/DINOT-Bold.otf') format('opentype'); font-weight: 700; font-display: swap; } @font-face { - font-family: 'DIN OT'; + font-family: 'DINOT-Medium'; src: url('/fonts/DINOT-Medium.otf') format('opentype'); font-weight: 500; font-display: swap; } @font-face { - font-family: 'IBM Plex Mono'; + font-family: 'IBMPlexMono-Regular'; src: url('/fonts/IBMPlexMono-Regular.otf') format('opentype'); font-display: swap; } diff --git a/packages/webview-app/src/providers/SelfClientProvider.tsx b/packages/webview-app/src/providers/SelfClientProvider.tsx index 6be34c672..bad0865a5 100644 --- a/packages/webview-app/src/providers/SelfClientProvider.tsx +++ b/packages/webview-app/src/providers/SelfClientProvider.tsx @@ -13,7 +13,7 @@ import { consoleAnalyticsAdapter, bridgeLifecycleAdapter, webNavigationAdapter, - bridgeHapticAdapter, + noOpHapticAdapter, bridgeBiometricsAdapter, bridgeCameraAdapter, } from '@selfxyz/webview-bridge/adapters'; @@ -64,6 +64,7 @@ export const SelfClientProvider: React.FC<{ children: React.ReactNode }> = ({ const adapters = useMemo(() => { const lifecycle = bridgeLifecycleAdapter(bridge); + return { scanner: bridgeNFCScannerAdapter(bridge), crypto: bridgeCryptoAdapter(bridge), @@ -76,7 +77,7 @@ export const SelfClientProvider: React.FC<{ children: React.ReactNode }> = ({ (path: string) => navigate(path), () => navigate(-1), ), - haptic: bridgeHapticAdapter(bridge), + haptic: noOpHapticAdapter(), biometrics: bridgeBiometricsAdapter(bridge), camera: bridgeCameraAdapter(bridge), }; diff --git a/packages/webview-app/src/screens/onboarding/DocumentCameraScreen.tsx b/packages/webview-app/src/screens/onboarding/DocumentCameraScreen.tsx index 88076cf12..d7eca43e4 100644 --- a/packages/webview-app/src/screens/onboarding/DocumentCameraScreen.tsx +++ b/packages/webview-app/src/screens/onboarding/DocumentCameraScreen.tsx @@ -46,7 +46,7 @@ export const DocumentCameraScreen: React.FC = () => { try { const result = await bridge.request<{ - passportNumber: string; + documentNumber: string; dateOfBirth: string; dateOfExpiry: string; }>('camera', 'scanMRZ', { documentType, countryCode }); @@ -58,7 +58,7 @@ export const DocumentCameraScreen: React.FC = () => { state: { countryCode, documentType, - passportNumber: result.passportNumber, + passportNumber: result.documentNumber, dateOfBirth: result.dateOfBirth, dateOfExpiry: result.dateOfExpiry, }, diff --git a/packages/webview-app/src/screens/proving/ProvingScreen.tsx b/packages/webview-app/src/screens/proving/ProvingScreen.tsx index 866da1145..8b4815f13 100644 --- a/packages/webview-app/src/screens/proving/ProvingScreen.tsx +++ b/packages/webview-app/src/screens/proving/ProvingScreen.tsx @@ -2,17 +2,128 @@ // SPDX-License-Identifier: BUSL-1.1 // NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE. -import React, { useCallback, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import React, { useCallback, useMemo, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; import { ProofRequestScreen, SelfLogo } from '@selfxyz/euclid-web'; import { useSelfClient } from '../../providers/SelfClientProvider'; +const DEFAULT_REQUEST_TYPE = 'proofRequested'; +const ALLOWED_REQUEST_TYPES = new Set([ + 'proofRequested', + 'documentOwnershipConfirmed', +]); +const DEFAULT_PROOF_ITEMS = [ + 'Age verification', + 'Nationality', + 'Document validity', +]; + +interface ProvingScreenLocationState { + requestType?: string; + proofItems?: string[]; + appName?: string; + appEndpoint?: string; + timestamp?: number; +} + +function titleCaseDisclosure(disclosure: string): string { + return disclosure + .replace(/[_-]+/g, ' ') + .replace(/\s+/g, ' ') + .trim() + .replace(/\b\w/g, (match) => match.toUpperCase()); +} + +function normalizeRequestType(value: string | null | undefined): string { + if (!value) return DEFAULT_REQUEST_TYPE; + return ALLOWED_REQUEST_TYPES.has(value) ? value : DEFAULT_REQUEST_TYPE; +} + +function normalizeAppEndpoint(value: string | null | undefined): string { + if (!value) return ''; + + try { + const endpoint = new URL(value); + const isHttps = endpoint.protocol === 'https:'; + const isLocalHttp = + endpoint.protocol === 'http:' && + (endpoint.hostname === 'localhost' || endpoint.hostname === '127.0.0.1'); + + if (!isHttps && !isLocalHttp) { + return ''; + } + + return endpoint.host; + } catch { + return ''; + } +} + +function parseProofItems(search: string): string[] | null { + const params = new URLSearchParams(search); + const proofItems = params.get('proofItems'); + if (proofItems) { + const items = proofItems + .split(',') + .map((item) => item.trim()) + .filter(Boolean); + if (items.length > 0) return items; + } + + const disclosures = params.get('disclosures'); + if (disclosures) { + const items = disclosures + .split(',') + .map((item) => titleCaseDisclosure(item)) + .filter(Boolean); + if (items.length > 0) return items; + } + + return null; +} + export const ProvingScreen: React.FC = () => { const navigate = useNavigate(); + const location = useLocation(); + const locationState = (location.state ?? {}) as ProvingScreenLocationState; const { analytics, haptic, lifecycle } = useSelfClient(); const [proving, setProving] = useState(false); + const requestType = useMemo(() => { + const params = new URLSearchParams(location.search); + return normalizeRequestType( + locationState.requestType ?? + params.get('resultType'), + ); + }, [location.search, locationState.requestType]); + + const proofItems = useMemo(() => { + if (Array.isArray(locationState.proofItems) && locationState.proofItems.length > 0) { + return locationState.proofItems; + } + return parseProofItems(location.search) ?? DEFAULT_PROOF_ITEMS; + }, [location.search, locationState.proofItems]); + + const appName = useMemo(() => { + const params = new URLSearchParams(location.search); + return locationState.appName ?? params.get('appName') ?? 'Verification'; + }, [location.search, locationState.appName]); + + const appEndpoint = useMemo(() => { + const params = new URLSearchParams(location.search); + return normalizeAppEndpoint( + locationState.appEndpoint ?? params.get('appEndpoint'), + ); + }, [location.search, locationState.appEndpoint]); + + const timestamp = useMemo(() => { + if (typeof locationState.timestamp === 'number') return locationState.timestamp; + const queryTimestamp = new URLSearchParams(location.search).get('timestamp'); + const parsed = queryTimestamp ? Number(queryTimestamp) : Number.NaN; + return Number.isFinite(parsed) ? parsed : Date.now(); + }, [location.search, locationState.timestamp]); + const onVerify = useCallback(async () => { haptic.trigger('selection'); analytics.trackEvent('prove_verify_pressed'); @@ -20,7 +131,7 @@ export const ProvingScreen: React.FC = () => { try { await lifecycle.setResult({ - type: 'proofRequested', + type: requestType, }); navigate('/proving/result', { state: { success: true } }); @@ -33,7 +144,7 @@ export const ProvingScreen: React.FC = () => { } finally { setProving(false); } - }, [navigate, analytics, haptic, lifecycle]); + }, [navigate, analytics, haptic, lifecycle, requestType]); const onCancel = useCallback(() => { haptic.trigger('selection'); @@ -47,14 +158,10 @@ export const ProvingScreen: React.FC = () => { onClose={onCancel} onConfirm={onVerify} appIcon={} - appName="Verification" - appEndpoint="" - timestamp={Date.now()} - items={[ - { label: 'Age verification' }, - { label: 'Nationality' }, - { label: 'Document validity' }, - ]} + appName={appName} + appEndpoint={appEndpoint} + timestamp={timestamp} + items={proofItems.map((label) => ({ label }))} /> ); }; diff --git a/packages/webview-app/vite.config.ts b/packages/webview-app/vite.config.ts index 9fc75a31e..06078b32a 100644 --- a/packages/webview-app/vite.config.ts +++ b/packages/webview-app/vite.config.ts @@ -6,10 +6,11 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ + base: './', plugins: [react()], define: { global: 'globalThis' }, build: { - target: ['chrome90', 'safari15'], + target: ['chrome90', 'safari15.4'], rollupOptions: { output: { manualChunks: undefined } }, assetsInlineLimit: 102400, outDir: 'dist', diff --git a/packages/webview-bridge/src/adapters/documents-web.ts b/packages/webview-bridge/src/adapters/documents-web.ts index 26f7b4cac..9132097f5 100644 --- a/packages/webview-bridge/src/adapters/documents-web.ts +++ b/packages/webview-bridge/src/adapters/documents-web.ts @@ -10,6 +10,13 @@ const DOCUMENTS_STORE = 'documents'; const CATALOG_STORE = 'catalog'; const CATALOG_KEY = 'current'; +function cloneForStorage(value: T): T { + if (typeof globalThis.structuredClone === 'function') { + return globalThis.structuredClone(value); + } + return JSON.parse(JSON.stringify(value)) as T; +} + function openDB(): Promise { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); @@ -84,7 +91,7 @@ export function indexedDBDocumentsAdapter(): BridgeDocumentsAdapter { async saveDocumentCatalog(catalog: unknown): Promise { const db = await getDB(); - await txPut(db, CATALOG_STORE, CATALOG_KEY, structuredClone(catalog)); + await txPut(db, CATALOG_STORE, CATALOG_KEY, cloneForStorage(catalog)); }, async loadDocumentById(id: string): Promise { @@ -95,7 +102,7 @@ export function indexedDBDocumentsAdapter(): BridgeDocumentsAdapter { async saveDocument(id: string, data: unknown): Promise { const db = await getDB(); - await txPut(db, DOCUMENTS_STORE, id, structuredClone(data)); + await txPut(db, DOCUMENTS_STORE, id, cloneForStorage(data)); }, async deleteDocument(id: string): Promise { diff --git a/packages/webview-bridge/src/adapters/haptic.ts b/packages/webview-bridge/src/adapters/haptic.ts index ecf52789c..587fb2a02 100644 --- a/packages/webview-bridge/src/adapters/haptic.ts +++ b/packages/webview-bridge/src/adapters/haptic.ts @@ -17,3 +17,9 @@ export function bridgeHapticAdapter( }, }; } + +export function noOpHapticAdapter(): BridgeHapticAdapter { + return { + trigger(): void {}, + }; +} diff --git a/packages/webview-bridge/src/adapters/index.ts b/packages/webview-bridge/src/adapters/index.ts index 32476a8a2..db82cde80 100644 --- a/packages/webview-bridge/src/adapters/index.ts +++ b/packages/webview-bridge/src/adapters/index.ts @@ -23,7 +23,7 @@ export type { BridgeAnalyticsAdapter } from './analytics'; export { consoleAnalyticsAdapter } from './analytics-web'; export type { ConsoleAnalyticsOptions } from './analytics-web'; -export { bridgeHapticAdapter } from './haptic'; +export { bridgeHapticAdapter, noOpHapticAdapter } from './haptic'; export type { BridgeHapticAdapter } from './haptic'; export { webNavigationAdapter } from './navigation'; diff --git a/specs/HANDOFF.md b/specs/HANDOFF.md index 9999ba837..358fecbe3 100644 --- a/specs/HANDOFF.md +++ b/specs/HANDOFF.md @@ -1,135 +1,70 @@ -# Handoff: Person 1-2-3 PR Review Reconciliation +# SDK Implementation — Follow-Up Tracker -> Branch: `feat/person1-2-3-implementation` -> Review date: 2026-02-19 -> Scope: Documentation reconciliation against `origin/main..HEAD` and current codebase state. +> Branch: `justin/kmp-wrap-up-evi-handoff-work` +> Last updated: 2026-02-23 +> Prior review: 2026-02-19 (`feat/person1-2-3-implementation`) -## What This PR Delivers +## What Was Delivered -- New bridge + WebView packages are implemented and present: - - `@selfxyz/webview-bridge` - - `@selfxyz/webview-app` -- Native shell expansion is implemented across KMP + Swift: - - iOS provider + handler chain is present (beyond original 3-handler plan) - - Android handler set remains focused on core native needs -- RN shell package is implemented: - - `@selfxyz/rn-sdk` with component, router, handlers, asset strategy, tests, and a package handoff doc -- Integration sample package is implemented: - - `@selfxyz/kmp-minipay-sample` with launch flow and result handling +Five new packages, all implemented. Validation status: -## Package Inventory Added In This Branch +| Package | Tests | Status | +| ----------------------------- | -------------------- | ------ | +| `@selfxyz/webview-bridge` | 63/63 | Done | +| `@selfxyz/webview-app` | — (build-verified) | Done | +| `@selfxyz/rn-sdk` | 64/64 | Done | +| `@selfxyz/self-sdk-swift` | — (compile-verified) | Done | +| `@selfxyz/kmp-minipay-sample` | — (scaffold) | Done | -- `packages/webview-bridge/` -- `packages/webview-app/` -- `packages/self-sdk-swift/` -- `packages/rn-sdk/` -- `packages/kmp-minipay-sample/` +KMP SDK: `compileKotlinIosSimulatorArm64` + `jvmTest` passing. iOS Maestro launch: 1 test, 0 failures. -## Person 1 (WebView + Bridge) +Chunk completion: 23/30 done, 3 partial, 1 skipped, 2 superseded, 1 deferred. See [WAVE-PLAN.md](./WAVE-PLAN.md) for details. -### Delivered +## Open Follow-Up Items -- Bridge protocol, adapters, schema, mocks, and tests are implemented in `packages/webview-bridge/`. -- WebView app shell/screens/provider wiring are implemented in `packages/webview-app/`. +### P1 — Validation Gaps -### Remaining / Follow-Up +| Item | Owner | Context | +| ----------------------------------------- | ---------- | ----------------------------------------------------------------------------------- | +| Physical-device NFC E2E (Android + iOS) | Person 2/3 | No in-repo evidence of real passport scans through any shell. Highest-priority gap. | +| Physical-device camera/MRZ validation | Person 2/5 | RN SDK CameraHandler calls native module but untested on device. | +| KMP test app validation on both platforms | Person 2 | Compile-verified only; no runtime validation captured. | +| Integration validation in Self Wallet app | Person 5 | `SelfVerification` component not yet wired into Self Wallet. | -- Correctness gap: fallback wiring consistency in `SelfClientProvider`: - - haptic currently bridges native (`bridgeHapticAdapter`) instead of no-op fallback - - crypto path is hybrid (`hash` via Web Crypto + `sign` via native bridge) -- Dynamic proving request values remain hardcoded and should be sourced/configured by request context. +### P2 — Correctness / Consistency -## Person 2 (Native Shells) +| Item | Owner | Context | +| ---------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Consolidate duplicated fallback adapters | Person 4 | ~150 LOC duplicated across `webview-bridge/adapters/` and `mobile-sdk-alpha/adapters/browser/` (analytics, documents, haptic). `mobile-sdk-alpha` is canonical owner; bridge copies are transitional. | +| Source dynamic proving request values from request context | Person 1 | `ProvingScreen` now accepts params but default values are still hardcoded. Config should flow from `SelfSdk.launch(request)`. | +| Expose `generateKey()`/`getPublicKey()` in `BridgeCryptoAdapter` | Person 1/4 | Methods exist in iOS native handler (`CryptoBridgeHandler.kt`) and bridge protocol types (`CryptoMethod`), but the `BridgeCryptoAdapter` interface in `webview-bridge/adapters/crypto.ts` only exposes `hash()` and `sign()`. WebView client code cannot call key management methods. | -### Delivered +### P3 — Publishing / Packaging -- iOS chain (2G-2K scope) is implemented with handler/provider registration in KMP + Swift package. -- Android shell + handlers remain implemented and integrated. +| Item | Owner | Context | +| ---------------------------------------------- | -------- | --------------------------------------------------------------------------------- | +| npm publish `@selfxyz/rn-sdk` | Person 5 | Package is implemented but not published. | +| Production artifact builds (AAR + XCFramework) | Person 2 | KMP SDK packaging for distribution not finalized. | +| Self Wallet migration to `SelfVerification` | Person 5 | Phase 2 — Self Wallet replaces native verification screens with SDK WebView flow. | -### Remaining / Follow-Up +### Deferred (Phase 2) -- **iOS lifecycle flat payload bug (P1):** `LifecycleBridgeHandler.kt` requires both `success` and `data` fields to classify a result as success, but WebView sends flat payloads like `{ type: 'proofRequested' }`. All iOS completion callbacks are misclassified as cancellations. See `packages/webview-app/src/screens/proving/ProvingScreen.tsx` and `.../ConfirmIdentificationScreen.tsx` for the call sites. -- **iOS lifecycle race condition:** `dismiss()` and `setResult()` in `LifecycleBridgeHandler.kt` share `pendingCallback` and `dismissAction` on `Dispatchers.Default` (thread pool) with no synchronization. Concurrent invocation can double-fire callbacks. Fix: route to `Dispatchers.Main` or protect with `Mutex`. -- **iOS dev server port mismatch:** `WebViewProviderImpl.swift` hardcodes `localhost:3000` for debug builds, but Vite dev server runs on `5173` (matching Android). Minor — dev-only. -- Public API finalization and validation remain partially open: - - cross-platform behavior alignment and explicit platform contract documentation - - device-level validation coverage and integration hardening -- iOS handler scope expanded beyond initial plan; this needs explicit architectural sign-off. +| Item | Chunk | Context | +| ---------------------------- | ----- | ---------------------------------------------------------------------------------------------------- | +| iOS Camera MRZ Handler (KMP) | 2L | Camera/MRZ on iOS via KMP deferred to Phase 2. RN SDK has its own implementation via native modules. | -## Person 3 (Integrations) +## Resolved Decisions (Reference) -### Delivered +These decisions were made during this PR cycle. They are now documented in [SDK-OVERVIEW.md](./SDK-OVERVIEW.md) and do not need further action: -- MiniPay sample project scaffold exists and wires verification launch + result flow. - -### Remaining / Follow-Up - -- End-to-end physical device validation is still required (especially NFC path and failure modes). -- Integration polish/error handling should be validated against real SDK outcomes, not only scaffolding. - -## Person 4 (SDK Core) - -### Delivered - -- Browser/web fallback adapter implementations are present. -- Browser entry and exports are in place and consumed by WebView-oriented clients. - -### Remaining / Follow-Up - -- Ownership consolidation decision is needed for duplicated web fallback adapters: - - `packages/webview-bridge/src/adapters/` - - `packages/mobile-sdk-alpha/src/adapters/browser/` - -## Person 5 (RN SDK) Reconciliation - -Source reconciled from: `packages/rn-sdk/HANDOFF.md` - -### Implemented (confirmed) - -- `SelfVerification` component and `MessageRouter` -- Biometric, keychain, lifecycle handlers -- NFC handler -- Asset loading paths and `devServerUrl` override -- Test coverage for handlers/router/asset-loading behavior - -### Carry-Forward Risks / Gaps - -- **Asset paths break production WebView (P1):** `rn-sdk/assets/self-wallet/index.html` uses absolute paths (`src="/assets/..."`) that resolve to `file:///assets/...` on device instead of the bundle directory. Fix: add `base: './'` to `packages/webview-app/vite.config.ts` and rebuild. -- NFC spec deviation: - - current return is tag metadata flow, not raw APDU exchange path -- Camera/MRZ: - - `scanMRZ` is still `NOT_IMPLEMENTED` -- Both NFC and Camera/MRZ should be prioritized before broad production rollout. - -## Cross-Workstream Findings - -- Duplicate fallback adapters exist in both bridge and core packages; consolidation is required. -- Person 1 fallback wiring is inconsistent with intended web-first model (haptic + crypto behavior). -- iOS handler scope expanded (9 handlers) while Android keeps web fallbacks for those domains, creating platform asymmetry that needs explicit decision and documentation. -- `WAVE-PLAN` aggregate status values were stale and need replacement with reconciled counts. -- **`structuredClone` compat:** `documents-web.ts` calls `structuredClone()` which is unavailable on Safari 15.0–15.3 / iOS 15.0–15.3 WKWebView. Vite build target is `safari15`. Either bump target to `safari15.4` or add a `JSON.parse(JSON.stringify())` fallback. -- **Font-family name drift:** `webview-app/src/fonts.css` introduces new font names, but `mobile-sdk-alpha/src/constants/fonts.ts`, `app/tamagui.config.ts`, and `app/web/fonts.css` still reference old names (`Advercase-Regular`, `DINOT-Bold`, etc.). Affected code silently falls back to system fonts. - -## Stale / Descoped / Superseded Items - -- 2D/2E are superseded by 2G-2K implementation path. -- 4D remains optional/skipped. -- 2L remains deferred (Phase 2). +- **Hybrid crypto contract:** `hash()` in WebView, `sign()`/`generateKey()`/`getPublicKey()` native. +- **Fallback adapter ownership:** `mobile-sdk-alpha` is canonical; `webview-bridge` copies are transitional. +- **Platform asymmetry:** Android = 5-handler normative minimum, iOS = 9-handler compatibility superset. Signed off. +- **iOS lifecycle fixes:** Flat payload handling, Mutex synchronization, debug port 5173 — all implemented. ## Suggested Follow-Up PR Order -1. **Fix runtime-breaking bugs:** - - iOS lifecycle flat payload misclassification (all completions fire as cancellations) - - iOS lifecycle race condition (`dismiss`/`setResult` concurrency) - - RN SDK absolute asset paths (production WebView load failure) -2. **Resolve correctness gaps impacting runtime consistency:** - - Person 1 fallback wiring (haptic + crypto) and adapter ownership decision - - `structuredClone` Safari 15.0–15.3 compat in `documents-web.ts` -3. **Resolve high-risk native capability gaps:** - - RN SDK NFC/APDU path and Camera/MRZ implementation decision -4. **Resolve platform policy and API consistency:** - - iOS/Android handler asymmetry documentation + API contract finalization - - Font-family name alignment across webview-app, mobile-sdk-alpha, and app - - iOS dev server port alignment (`3000` → `5173`) -5. **Complete validation and integration hardening:** - - Device E2E coverage for MiniPay and cross-platform verification outcomes +1. **Physical-device validation** — NFC E2E on Android + iOS with real passports (unblocks confidence for everything else) +2. **Correctness cleanup** — Adapter consolidation, dynamic proving config, crypto adapter interface gap +3. **Publishing** — npm publish rn-sdk, finalize AAR/XCFramework packaging +4. **Self Wallet migration** — Wire `SelfVerification` into the main app (Phase 2) diff --git a/specs/README.md b/specs/README.md index d602c6674..89723c50d 100644 --- a/specs/README.md +++ b/specs/README.md @@ -33,11 +33,11 @@ Each workstream has two files: `OVERVIEW.md` (stable orientation) and `SPEC.md` | Workstream | Overview | Implementation Spec | Status | | -------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------- | -| Person 1 — WebView UI + Bridge | [OVERVIEW](./person1-webview/OVERVIEW.md) | [SPEC](./person1-webview/SPEC.md) | 4/5 chunks done, 1E in progress | -| Person 2 — Native Shells (KMP + Swift) | [OVERVIEW](./person2-native-shells/OVERVIEW.md) | [SPEC](./person2-native-shells/SPEC.md) | 3 done, 2 superseded, 1 in progress, 5 pending | -| Person 3 — Integrations | [OVERVIEW](./person3-integrations/OVERVIEW.md) | [MiniPay Spec](./person3-integrations/SPEC-MINIPAY-SAMPLE.md) | 0/3 chunks done | -| Person 4 — SDK Core | [OVERVIEW](./person4-sdk-core/OVERVIEW.md) | [SPEC](./person4-sdk-core/SPEC.md) | 4/5 active chunks done (4D skipped), 4F pending | -| Person 5 — RN SDK | [OVERVIEW](./person5-rn-sdk/OVERVIEW.md) | [SPEC](./person5-rn-sdk/SPEC.md) | 0/4 chunks done | +| Person 1 — WebView UI + Bridge | [OVERVIEW](./person1-webview/OVERVIEW.md) | [SPEC](./person1-webview/SPEC.md) | 28/29 done, 1 pending (dynamic proving config) | +| Person 2 — Native Shells (KMP + Swift) | [OVERVIEW](./person2-native-shells/OVERVIEW.md) | [SPEC](./person2-native-shells/SPEC.md) | 27/28 done, 1 pending (KMP test app validation) | +| Person 3 — Integrations | [OVERVIEW](./person3-integrations/OVERVIEW.md) | [MiniPay Spec](./person3-integrations/SPEC-MINIPAY-SAMPLE.md) | 25/26 done, 1 pending (physical-device NFC E2E) | +| Person 4 — SDK Core | [OVERVIEW](./person4-sdk-core/OVERVIEW.md) | [SPEC](./person4-sdk-core/SPEC.md) | 23/25 done, 2 pending (adapter dedup, crypto) | +| Person 5 — RN SDK | [OVERVIEW](./person5-rn-sdk/OVERVIEW.md) | [SPEC](./person5-rn-sdk/SPEC.md) | 21/23 done, 2 pending (wallet integration, npm) | ## Reading Order diff --git a/specs/SDK-OVERVIEW.md b/specs/SDK-OVERVIEW.md index 44fcce73b..ae13626aa 100644 --- a/specs/SDK-OVERVIEW.md +++ b/specs/SDK-OVERVIEW.md @@ -1,6 +1,6 @@ # Self SDK — Architecture Specification -> Last updated: 2026-02-17 +> Last updated: 2026-02-23 > Owner: Self Engineering > Status: Active @@ -13,19 +13,19 @@ ## Status Checklist - [x] Architecture finalized (WebView engine + two native shells) -- [x] Bridge protocol defined and tested (62 tests pass) +- [x] Bridge protocol defined and tested (63 tests pass) - [x] Protocol compatibility policy defined (fail closed on version mismatch) - [x] WebView UI screens built (10 screens, routing works) - [x] WebView engine core working (275+ tests pass, XState proving machine) - [x] Android native shell implemented (5 handlers, WebView host, Activity) - [x] Delete 3 unnecessary Android handlers (documents, analytics, haptic); crypto standalone handler deleted but crypto domain still routed natively for signing/key-gen -- [ ] iOS native shell implemented (Swift providers via PR #1762, not yet merged) -- [ ] Biometrics bridge adapter (domain defined, no adapter implementation) -- [ ] Camera bridge adapter wiring in webview-app -- [ ] Web fallback adapters (IndexedDB for docs, Web Crypto for hashing) +- [x] iOS native shell implemented (provider-based chain present in repo; merge/publish track separately) +- [x] Biometrics bridge adapter wired in webview-app +- [x] Camera bridge adapter wiring in webview-app +- [x] Web fallback adapters (IndexedDB for docs, Web Crypto for hashing) - [x] Browser entry point with zero RN transitive imports -- [ ] RN SDK (`SelfVerification` component — does not exist yet) -- [ ] MiniPay sample integration +- [x] RN SDK (`SelfVerification` component + handlers) implemented +- [x] MiniPay sample integration scaffold + launch/result wiring implemented - [x] Canonical `VerificationResult` contract locked in specs (legacy fields disallowed) - [ ] Dynamic proof request items (currently hardcoded in ProvingScreen) - [ ] MRZ data confirmation screen (PR #1767, not yet merged) @@ -119,16 +119,16 @@ ## Module Table -| Module | Location | Language | What It Does | Status | % Done | Action Needed | -| ----------------------- | ---------------------------- | ---------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | -| **WebView Engine** | `packages/mobile-sdk-alpha/` | TypeScript | Proving machine (XState), stores (Zustand), adapter interfaces, 105 source files | 275+ tests pass, RN adapters built | **80%** | Browser entry point with zero RN imports. Web fallback adapters (IndexedDB, Web Crypto). Finish decoupling core from RN peer deps | -| **WebView UI** | `packages/webview-app/` | TypeScript (React) | 10 screens: home, country, ID, camera, NFC, confirm, proving, result, settings, coming-soon | All screens render, routing works, bridge integration wired | **75%** | Biometrics + camera adapter wiring. Dynamic proof request items. Wire SelfClientProvider to web fallback adapters | -| **Bridge Protocol** | `packages/webview-bridge/` | TypeScript | JSON messaging, 10 domains, 9 adapters, timeout/error handling, mock transport | 62 tests pass, production-ready protocol | **80%** | Add biometrics adapter (domain defined, no implementation). Web fallback adapters for documents/storage | -| **Kotlin Native Shell** | `packages/kmp-sdk/` | Kotlin | Android: 5 handlers + WebView host + Activity. iOS: stubs (Swift providers in PR #1762) | Android fully implemented, iOS stubs | **70%** | iOS: implement via Swift provider pattern | -| **Swift Providers** | `packages/self-sdk-swift/` | Swift | iOS native implementations: NFC, biometrics, secure storage, WebView hosting | In PR #1762 (not merged) | **30%** | Merge PR #1762. Complete NFC + biometrics + secure storage + lifecycle providers | -| **RN Native Shell** | `packages/rn-sdk/` — **NEW** | React Native | `SelfVerification` WebView wrapper, 5 native handler bridges | Does not exist | **0%** | Create thin wrapper: ~200-300 LOC, same bridge protocol as KMP | -| **Shared Utilities** | `common/` | TypeScript | Poseidon, Merkle trees, passport parsing, certificates, 150+ files, 88+ exports | Production, 98% browser-compatible | **95%** | No changes needed. Only 2 files require Node.js (optional) | -| **Self Wallet App** | `app/` | React Native (v0.76.9) | Full wallet: documents, NFC, proving, KYC, recovery, settings, Turnkey wallet | Production (v2.9.16) | **N/A** | Test environment for SDK. Eventually migrates to `SelfVerification` | +| Module | Location | Language | What It Does | Status | % Done | Action Needed | +| ----------------------- | ---------------------------- | ---------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------ | +| **WebView Engine** | `packages/mobile-sdk-alpha/` | TypeScript | Proving machine (XState), stores (Zustand), adapter interfaces, 105 source files | Browser/RN paths and fallback adapters implemented | **85%** | Consolidate fallback adapter ownership cleanup and finish remaining decoupling from RN peer deps | +| **WebView UI** | `packages/webview-app/` | TypeScript (React) | 10 screens: home, country, ID, camera, NFC, confirm, proving, result, settings, coming-soon | All screens render, routing works, bridge integration wired | **85%** | Dynamic proof request items are still hardcoded and need request-context sourcing | +| **Bridge Protocol** | `packages/webview-bridge/` | TypeScript | JSON messaging, 10 domains, 9 adapters, timeout/error handling, mock transport | 63+ tests pass, protocol stable | **85%** | Complete adapter de-duplication with engine-owned web fallbacks | +| **Kotlin Native Shell** | `packages/kmp-sdk/` | Kotlin | Android: 5 handlers + WebView host + Activity. iOS: provider-backed handler chain | Android and iOS implementations present | **85%** | Complete physical-device validation matrix (NFC success/failure on both platforms) | +| **Swift Providers** | `packages/self-sdk-swift/` | Swift | iOS native implementations: NFC, biometrics, secure storage, WebView hosting | Implemented in repo and wired through KMP iOS | **80%** | Final artifact/packaging readiness and physical-device validation | +| **RN Native Shell** | `packages/rn-sdk/` — **NEW** | React Native | `SelfVerification` WebView wrapper, 5 native handler bridges | Implemented with tests, asset strategy, and APDU-capable NFC | **85%** | Expand real-device integration validation coverage in host apps | +| **Shared Utilities** | `common/` | TypeScript | Poseidon, Merkle trees, passport parsing, certificates, 150+ files, 88+ exports | Production, 98% browser-compatible | **95%** | No changes needed. Only 2 files require Node.js (optional) | +| **Self Wallet App** | `app/` | React Native (v0.76.9) | Full wallet: documents, NFC, proving, KYC, recovery, settings, Turnkey wallet | Production (v2.9.16) | **N/A** | Test environment for SDK. Eventually migrates to `SelfVerification` | ## Decision Matrix @@ -165,10 +165,20 @@ > **Web fallback adapter ownership:** Two packages provide adapters, at different layers: > -> - **`mobile-sdk-alpha` (`src/adapters/browser/`)** — Engine-level adapters that satisfy the `Adapters` interface (e.g., `createIndexedDBDocumentsAdapter`, `createWebCryptoAdapter`). These are what `SelfClientProvider` in `webview-app` wires up. **This is the canonical source for web fallback implementations.** +> - **`mobile-sdk-alpha` (`src/adapters/browser/`)** — Engine-level adapters that satisfy the `Adapters` interface (e.g., `createIndexedDBDocumentsAdapter`, `createWebCryptoAdapter`). **This is the canonical source for web fallback implementations.** > - **`webview-bridge`** — Bridge-level adapters that translate between the bridge protocol and the engine adapters (e.g., `NfcBridgeAdapter` calls `bridge.request('nfc', 'scan', ...)`). For capabilities that don't need native (documents, crypto hash, analytics), the bridge adapter is a thin pass-through to the engine adapter. > > Rule: if a capability runs entirely in the WebView, the engine adapter in `mobile-sdk-alpha` owns the implementation. The bridge package provides the messaging plumbing, not the business logic. +> +> **Current transitional state (2026-02-23):** `webview-app` still imports web fallback helpers from `webview-bridge` for some domains. This is accepted short-term, but those helpers must remain behavior-compatible with engine adapters until consolidation is complete. + +### Platform Asymmetry Contract (Signed 2026-02-23) + +- **Normative minimum contract (all shells):** `nfc`, `camera`, `biometrics`, `secureStorage`, `lifecycle`, and native `crypto` methods (`sign`, `generateKey`, `getPublicKey`). +- **Android KMP:** Implements the normative minimum (5 handlers + native crypto routing). +- **iOS KMP:** Implements a compatibility superset (registers additional `documents`, `analytics`, `haptic`, and `crypto` handlers). +- **Sign-off rule:** iOS superset handlers are compatibility shims only; they must not become the authoritative implementation for domains designated as WebView fallbacks. +- **Cross-platform invariant:** host app callback semantics and `VerificationResult` contract must be identical regardless of shell or platform. ## Impact Summary diff --git a/specs/WAVE-PLAN.md b/specs/WAVE-PLAN.md index ea8f0f3bd..d9609c18c 100644 --- a/specs/WAVE-PLAN.md +++ b/specs/WAVE-PLAN.md @@ -1,6 +1,6 @@ # Execution Wave Plan -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Project: [SDK-OVERVIEW.md](./SDK-OVERVIEW.md) Cross-workstream chunk execution plan for parallel AI agent work via `claude --remote`. @@ -46,14 +46,17 @@ A **wave** is a batch of chunks that can execute in parallel because they have n | **3C** | **Person 3 (Integrations)** | **Polish + Error Handling** | **S** | **Partial** | 3B | | 2L | Person 2 (Native Shells) | Camera MRZ Handler (iOS) | S | Deferred (Phase 2) | 2J | -**Totals (reconciled 2026-02-19):** 30 chunks — 23 done, 3 partial (1E, 2F, 3C), 1 skipped (4D optional), 2 superseded (2D/2E → 2G-2K), 1 deferred (2L Phase 2). +**Totals (reconciled 2026-02-23):** 30 chunks — 23 done, 3 partial (1E, 2F, 3C), 1 skipped (4D optional), 2 superseded (2D/2E → 2G-2K), 1 deferred (2L Phase 2). **Remaining to close:** 4 items (3 partial + 1 deferred). -## Reconciliation Notes (2026-02-19) +## Reconciliation Notes (2026-02-23) - This file now reflects post-implementation reconciliation, not just pre-execution planning. - The older aggregate summary (`11 done / 13 pending`) was stale and has been replaced by audited counts. -- Partial items are blocked on correctness/validation decisions rather than missing package scaffolding. +- Decision/documentation blockers from the 2026-02-19 handoff are now reconciled: + - hybrid crypto + fallback ownership decisions are explicit + - iOS/Android asymmetry contract is documented and signed off +- Remaining partials are now primarily validation/outcome gaps (physical-device NFC E2E), plus residual implementation cleanup (fallback adapter de-duplication + dynamic proving request config). - Key carry-forward risks are tracked in `specs/HANDOFF.md`. ## Execution Waves diff --git a/specs/handoff-p1-fixes/SECURITY-HARDENING.md b/specs/handoff-p1-fixes/SECURITY-HARDENING.md new file mode 100644 index 000000000..3bdd7f2b8 --- /dev/null +++ b/specs/handoff-p1-fixes/SECURITY-HARDENING.md @@ -0,0 +1,115 @@ +# SDK Security Hardening — Follow-up Spec + +> Last updated: 2026-02-25 +> Source: Bot review feedback on PR #1785 (kmp-wrap-up-evi-handoff-work) +> Status: Pending + +## Status Checklist + +| Chunk | Description | Priority | Status | +|-------|-------------|----------|--------| +| 1 | APDU command allowlisting | High | Not started | +| 2 | NFC transceive timeout (iOS) | Medium | Not started | +| 3 | Redact sensitive data from error messages | Medium | Not started | +| 4 | LifecycleBridgeHandler type+error handling | Low | Not started | +| 5 | NFC return payload — minimize PII surface | Low | Not started | +| 6 | Person 4 crypto tracking | Low | Not started | + +## Context + +PR #1785 wraps up the KMP/EVI handoff work. Automated reviewers (CodeRabbit, Codex) flagged several security hardening items. The quick fixes were already addressed in the PR's feedback commits. This spec tracks the remaining items that need follow-up work. + +## Chunks + +### Chunk 1: APDU Command Allowlisting + +**Priority:** High +**Files:** `packages/rn-sdk/src/handlers/NfcHandler.ts`, `packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/handlers/NfcBridgeHandler.kt` + +`params.apduCommands` from the WebView layer is forwarded directly to `NfcManager.transceive()` with no validation. A compromised or malicious WebView payload could issue arbitrary APDUs against any NFC-capable card in range (payment cards, access cards — not just passports). + +**Required work:** +- Define an allowlist of valid APDU command prefixes for eMRTD reading (SELECT, READ BINARY, GET CHALLENGE, EXTERNAL AUTHENTICATE, etc.) +- Reject commands that don't match the allowlist before calling `transceive()` +- Apply the same validation in both RN and KMP handlers +- Add tests for rejected commands + +### Chunk 2: NFC Transceive Timeout (iOS) + +**Priority:** Medium +**Files:** `packages/rn-sdk/src/handlers/NfcHandler.ts` + +`react-native-nfc-manager` has no per-call timeout for `transceive()`. On iOS, a stuck chip or broken connection can hang the scan indefinitely with no way to recover. + +**Required work:** +- Wrap `transceive()` calls in a `Promise.race` with a configurable timeout (e.g., 10s per command) +- On timeout, throw `NFC_TIMEOUT` error and clean up the NFC session +- On Android, investigate using `NfcManager.setTimeout()` for native-level timeout +- Add tests for timeout behavior + +### Chunk 3: Redact Sensitive Data from Error Messages + +**Priority:** Medium +**Files:** `packages/rn-sdk/src/handlers/NfcHandler.ts` + +Line 34 includes the raw hex command in the error message: `Invalid APDU hex command: ${hexCommand}`. For passport-reading flows, APDU command bytes can encode key-derivation material from MRZ data. Any upstream `catch` that logs `err.message` would leak that material. + +**Required work:** +- Replace `${hexCommand}` with a truncated/masked version (e.g., first 4 chars + `...`) or remove it entirely +- Audit other error paths in NFC/Camera handlers for similar PII leakage + +### Chunk 4: LifecycleBridgeHandler — Type + Error Handling + +**Priority:** Low +**Files:** `packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/handlers/LifecycleBridgeHandler.kt` + +When `type != null` (line 84-89), the handler unconditionally creates `VerificationResult(success = true, type = type)` and ignores `success`, `errorCode`, and `errorMessage` params. The current comment says this is intentional ("flat lifecycle payload is a protocol-level success signal"), but if a future caller sends `{ type: "error", success: false, errorCode: "..." }`, error fields would be silently dropped. + +**Required work:** +- Decide if `type` should always imply success, or if type+error combinations are valid +- If type-only is intentional, add a brief comment or assertion making this explicit +- If type+error is valid, update the branching logic to respect `success` when `type` is present + +### Chunk 5: NFC Return Payload — Minimize PII Surface + +**Priority:** Low +**Files:** `packages/rn-sdk/src/handlers/NfcHandler.ts`, `packages/rn-sdk/HANDOFF.md` + +The NFC scan returns `tagId` (passport chip UID — a unique persistent identifier, PII under GDPR) and `apduResponses` in hex (can encode raw Data Groups: MRZ text, face image, fingerprints). These pass back to the WebView and risk being logged or persisted inadvertently. + +**Required work:** +- Evaluate whether `tagId` is needed by the WebView layer; if not, stop returning it +- Add data-handling guidance to HANDOFF.md for `tagId` and `apduResponses` +- Also fix HANDOFF.md line 95 which shows `params: {...}` in the NFC return shape but the code no longer returns params + +### Chunk 6: Person 4 Crypto Tracking + +**Priority:** Low +**Files:** `specs/person4-sdk-core/` + +The Person 4 workstream has pending crypto work. In a zero-knowledge/passport-verification SDK, partially-wired crypto paths can degrade security guarantees. This needs a tracking issue or explicit deferral decision. + +**Required work:** +- Review current Person 4 crypto status +- Open a tracked issue if work is outstanding, or add an explicit note that it's deferred + +## Validation + +For chunks 1-3 and 5: +```bash +cd packages/rn-sdk && npx vitest run +``` + +For chunk 4: +```bash +cd packages/kmp-sdk && ./gradlew :shared:jvmTest +``` + +## Definition of Done + +- [ ] Chunk 1: APDU allowlist implemented and tested in both RN and KMP +- [ ] Chunk 2: Transceive timeout implemented and tested +- [ ] Chunk 3: Sensitive data redacted from all NFC/Camera error messages +- [ ] Chunk 4: LifecycleBridgeHandler type+error behavior decided and documented +- [ ] Chunk 5: NFC return payload minimized, HANDOFF.md updated +- [ ] Chunk 6: Person 4 crypto tracked or explicitly deferred diff --git a/specs/person-1-2-3-pr-review.md b/specs/person-1-2-3-pr-review.md deleted file mode 100644 index 31a40ff1a..000000000 --- a/specs/person-1-2-3-pr-review.md +++ /dev/null @@ -1,147 +0,0 @@ -# Plan: Person 1-2-3 PR Review + Handoff - -## Branch - -- `feat/person1-2-3-implementation` - -## Goal - -- Freeze implementation on this branch. -- Produce an accurate merge handoff by reconciling spec status vs actual code. -- Update planning/checklist docs to reflect reality and isolate follow-up work. -- Capture already-established cross-workstream findings so handoff output is actionable, not only procedural. - -## Scope - -- Review-only against current branch changes. -- No implementation code changes. -- No commits or pushes. - -## Procedure vs Findings - -- This document is both: -- A procedural checklist for the review pass. -- A findings-aware plan that must carry forward known cross-workstream issues into output artifacts. -- If any known finding below cannot be validated during audit, mark it `Unknown (carry forward)` with explicit rationale. - -## Package Inventory Created In This PR - -- `@selfxyz/webview-bridge` -- `@selfxyz/webview-app` -- `@selfxyz/self-sdk-swift` -- `@selfxyz/rn-sdk` -- `@selfxyz/kmp-minipay-sample` - -## Known Findings Snapshot (As Of 2026-02-19) - -- Duplicate web fallback adapters exist in both `webview-bridge/src/adapters/` and `packages/mobile-sdk-alpha/src/adapters/browser/` for IndexedDB docs, Web Crypto, console analytics, and no-op haptic; `SelfClientProvider` currently imports from `webview-bridge`. A follow-up consolidation/ownership decision is required. -- Person 1 wiring gap: haptic is bridged to native instead of no-op fallback, and crypto adapter behavior is hybrid. This is a correctness follow-up item, not just cleanup. -- iOS handler scope expanded beyond original plan (9 handlers shipped vs 3 originally planned), including documents, crypto, analytics, and haptic; Android currently uses web fallbacks for these areas. Platform asymmetry requires an explicit product/architecture decision. -- `specs/WAVE-PLAN.md` status counts are stale: current summary text (for example, "11 done / 13 pending") does not match implementation progress; audit should update to a code-evidenced count (currently believed closer to ~23 done / ~4 remaining). -- RN SDK highest-risk carry-forward items are the NFC deviation (metadata vs raw APDU path) and camera/MRZ stub (`NOT_IMPLEMENTED`); these should be prioritized in follow-up sequencing. - -## Inputs to Audit - -- `specs/WAVE-PLAN.md` -- `specs/person1-webview/OVERVIEW.md` -- `specs/person1-webview/SPEC.md` -- `specs/person2-native-shells/OVERVIEW.md` -- `specs/person2-native-shells/SPEC.md` -- `specs/person3-integrations/OVERVIEW.md` -- `specs/person3-integrations/SPEC-MINIPAY-SAMPLE.md` -- `specs/person4-sdk-core/OVERVIEW.md` -- `specs/person4-sdk-core/SPEC.md` -- `specs/person5-rn-sdk/OVERVIEW.md` -- `specs/person5-rn-sdk/SPEC.md` -- `packages/rn-sdk/HANDOFF.md` -- `git diff --stat origin/main..HEAD` - -## Audit Method - -1. Build chunk inventory from each spec and overview. -2. Reconcile `packages/rn-sdk/HANDOFF.md` claims against current branch changes. -3. For RN SDK, validate each item in: - -- `What Is Implemented` -- `Known Limitations` -- `Spec Deviation` -- `Deferred Decision` - and map each to one of the status rubric labels with code evidence. - -4. Verify changed files from `origin/main..HEAD` for each claimed chunk. -5. Spot-check representative code paths per chunk (not just filenames). -6. Classify each chunk with one of: - -- `Done (code present)` -- `Partial (code present, validation/integration pending)` -- `Pending (not implemented)` -- `Superseded/Descoped (stale item)` -- `Unknown (carry forward)` - -7. Prefer carry-forward when evidence is ambiguous. -8. Ensure Known Findings Snapshot items are either: - -- Confirmed with evidence and reflected in outputs, or -- Explicitly marked carry-forward with owner + next PR target. - -## Output Artifacts - -1. Create `specs/HANDOFF.md` with: - -- What This PR Delivers -- Remaining Work (Follow-Up PRs) -- Person 1 to Person 5 sections -- RN SDK reconciliation subsection sourced from `packages/rn-sdk/HANDOFF.md` (implemented, deviations, deferred decisions, limitations) -- Cross-workstream findings subsection covering: -- Duplicate fallback adapters decision -- Person 1 crypto/haptic wiring correction -- iOS vs Android handler asymmetry decision -- Stale/Descoped Items -- Suggested Follow-Up PR Order - -2. Update checklist accuracy in: - -- `specs/person1-webview/OVERVIEW.md` -- `specs/person2-native-shells/OVERVIEW.md` -- `specs/person3-integrations/OVERVIEW.md` -- `specs/person4-sdk-core/OVERVIEW.md` -- `specs/person5-rn-sdk/OVERVIEW.md` - -3. Update cross-workstream status in: - -- `specs/WAVE-PLAN.md` -- Replace stale aggregate counts with audit-verified totals and date-stamped note. - -## Status Rubric (Important) - -- `Done` requires implementation evidence in this branch. -- `Partial` when implementation exists but spec-required runtime validation is not confirmed. -- `Pending` when no implementation evidence exists. -- `Superseded/Descoped` when work item was replaced by later spec direction. -- `Unknown` defaults to carry-forward in `HANDOFF.md`. - -## Editing Rules - -- Documentation-only edits. -- Do not alter production/test implementation files. -- Preserve historical context, but mark stale statements explicitly. -- Prefer explicit dates and branch name in handoff text. - -## Review Checklist Before Finalizing Docs - -- Every changed chunk has a classification. -- `packages/rn-sdk/HANDOFF.md` has been reviewed and reconciled with `specs/HANDOFF.md`. -- Every RN SDK handoff claim is either confirmed with evidence or explicitly marked carry-forward. -- Duplicate fallback adapters are explicitly addressed (decision made or carry-forward item created). -- Person 1 crypto/haptic wiring gap is explicitly addressed (fixed status or carry-forward item created). -- iOS handler asymmetry is explicitly addressed (decision made or carry-forward item created). -- `specs/WAVE-PLAN.md` totals are updated to match audit evidence (with explicit date). -- Every stale checklist item is either removed, struck through, or annotated. -- `HANDOFF.md` includes concrete follow-up items, not generic placeholders. -- Follow-up PR order reflects dependency chain, not calendar preference. - -## Suggested Follow-Up PR Ordering Logic - -1. Close correctness gaps that impact runtime integration first. -2. Then complete validation/device coverage. -3. Then cleanup/spec debt and optional improvements. diff --git a/specs/person1-webview/OVERVIEW.md b/specs/person1-webview/OVERVIEW.md index fb5af3072..5c515e453 100644 --- a/specs/person1-webview/OVERVIEW.md +++ b/specs/person1-webview/OVERVIEW.md @@ -1,6 +1,6 @@ # Person 1: WebView UI + Bridge — Workstream Overview -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Owner: Person 1 (WebView UI + Bridge) > Project: [../SDK-OVERVIEW.md](../SDK-OVERVIEW.md) > Implementation: [SPEC.md](./SPEC.md) @@ -14,7 +14,7 @@ ## Status -- [x] Bridge protocol types and `WebViewBridge` class (62 tests pass) +- [x] Bridge protocol types and `WebViewBridge` class (63 tests pass) - [x] Bridge adapters: NFC, auth, storage, lifecycle, crypto (sign + hash) - [x] Web fallback adapters: IndexedDB documents, Web Crypto, console analytics, navigation, haptic - [x] Mock transport (`MockNativeBridge`) for testing @@ -23,9 +23,8 @@ - [x] BridgeProvider and SelfClientProvider wired - [x] Biometrics bridge adapter wired in `SelfClientProvider` - [x] Camera bridge adapter wired in `SelfClientProvider` -- [ ] Fallback wiring correctness gap remains: - - `haptic` currently uses native bridge trigger instead of web no-op - - `crypto` is hybrid (`hash` web, `sign` bridge) and needs explicit contract decision +- [x] Fallback wiring reconciled in `SelfClientProvider` (`haptic` uses web no-op) +- [x] Hybrid crypto contract signed off (`hash` in WebView, `sign` via native bridge) - [ ] Dynamic proof request items are still hardcoded in `ProvingScreen` ## What You Own diff --git a/specs/person1-webview/SPEC.md b/specs/person1-webview/SPEC.md index 0034f5f51..50178edce 100644 --- a/specs/person1-webview/SPEC.md +++ b/specs/person1-webview/SPEC.md @@ -34,7 +34,7 @@ The Self Wallet is a monolithic React Native app where all logic, NFC, proving, | Area | Issue | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `packages/webview-bridge/` | Prototype existed but needed rebuild with proper structure. Now mostly done (62 tests). Missing: biometrics adapter, camera adapter wiring. | +| `packages/webview-bridge/` | Implemented with current protocol/adapters and validated by tests (63 tests passing). | | `packages/webview-app/` | Screens built, routing works. Missing: biometrics + camera adapter wiring, web fallback adapters not all connected in SelfClientProvider. | | Web fallback adapters | IndexedDB documents adapter, Web Crypto hashing adapter, and console analytics adapter exist in bridge package but need wiring in webview-app. | @@ -1333,7 +1333,7 @@ Chunk 1F: Bridge Package (no deps — start here) | Chunk | Description | Size | Status | | ----- | ------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------- | -| 1F | Bridge Package | L | **Done** — 62 tests pass, all adapters implemented except biometrics | +| 1F | Bridge Package | L | **Done** — 63 tests pass, bridge package and adapters implemented | | 1B | Onboarding Screens | M | **Done** — all 5 screens render | | 1C | Proving + Result Screens | M | **Done** — screens render, proving wired | | 1D | Remaining Screens | S | **Done** — home, settings, coming-soon render | @@ -1353,7 +1353,7 @@ ls packages/webview-app/dist/index.html # file must exist # After all chunks: # 1. vite dev serves all 10 routes without console errors # 2. vite build produces dist/ with index.html + bundle -# 3. Bridge package: 62+ tests pass +# 3. Bridge package: 63+ tests pass # 4. Manual: load dist/index.html in a WebView host (Android/iOS test app) # and confirm lifecycle.ready() fires, screens navigate, NFC scan starts ``` diff --git a/specs/person2-native-shells/OVERVIEW.md b/specs/person2-native-shells/OVERVIEW.md index 0e3704c6f..135efe17c 100644 --- a/specs/person2-native-shells/OVERVIEW.md +++ b/specs/person2-native-shells/OVERVIEW.md @@ -1,6 +1,6 @@ # Person 2: Native Shells (KMP SDK + Swift Providers) — Workstream Overview -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Owner: Person 2 (Native Shells) > Project: [../SDK-OVERVIEW.md](../SDK-OVERVIEW.md) > Implementation: [SPEC.md](./SPEC.md) @@ -21,8 +21,9 @@ - [x] Delete 4 unnecessary Android handlers (documents, crypto, analytics, haptic — 511 LOC) - [x] iOS Swift providers are implemented and wired (NFC, Biometrics, Lifecycle, WebView host + additional providers) - [x] `SelfSdk.launch()` flow is implemented on iOS +- [x] Shared KMP validation baseline captured (`:shared:compileKotlinIosSimulatorArm64` + `:shared:jvmTest` successful) - [ ] KMP test app validation on both platforms remains a follow-up validation task -- [ ] Platform contract alignment is still open (iOS expanded domains vs Android web fallbacks) +- [x] Platform asymmetry contract documented and signed off (iOS 9-handler superset vs Android 5-handler core set) - [x] MiniPay sample integration is wired (`SelfSdk.launch()` call path present) ## What You Own @@ -75,7 +76,7 @@ You build the native shells that sit between the host app and the bridge protoco │ webview-app Vite bundle │ └─────────────────────────────────┘ -* iOS implementation now registers 9 handlers (NFC, Camera, Biometrics, SecureStorage, Lifecycle, Documents, Crypto, Analytics, Haptic); Android remains focused on 5 core native handlers. This asymmetry is implemented and needs explicit policy documentation. +* iOS implementation now registers 9 handlers (NFC, Camera, Biometrics, SecureStorage, Lifecycle, Documents, Crypto, Analytics, Haptic); Android remains focused on 5 core native handlers. This asymmetry is now explicitly accepted as a compatibility superset contract: Android is the normative minimum, iOS extra handlers must remain behavior-compatible and non-authoritative for web-fallback domains. ``` ## Dependencies diff --git a/specs/person3-integrations/OVERVIEW.md b/specs/person3-integrations/OVERVIEW.md index 91a7e0a5f..5d7b0a511 100644 --- a/specs/person3-integrations/OVERVIEW.md +++ b/specs/person3-integrations/OVERVIEW.md @@ -1,6 +1,6 @@ # Person 3: Integration Samples — Workstream Overview -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Owner: Person 3 (Integrations) > Project: [../SDK-OVERVIEW.md](../SDK-OVERVIEW.md) > Implementation: [SPEC-MINIPAY-SAMPLE.md](./SPEC-MINIPAY-SAMPLE.md) @@ -17,9 +17,14 @@ - [x] MiniPay sample project scaffolded (`packages/kmp-minipay-sample/`) - [x] Android: home screen + SDK launch + result screen wiring present - [x] iOS: Compose Multiplatform launch path is present +- [x] Integration hardening paths are implemented in sample result UX (error-code to user-message mapping) +- [x] Non-device validation evidence captured: + - `@selfxyz/rn-sdk` tests: all passing at merge time (includes NFC failure modes and APDU path handling; see CI checks) + - `@selfxyz/webview-bridge` tests: all passing at merge time (see CI checks) + - iOS launch E2E artifact: `app/maestro-results.xml` (1 test, 0 failures, 19s on iPhone 16 simulator) - [ ] End-to-end: NFC scan on physical device through sample app still requires validation -Overall: **Partial** — sample implementation exists and launch wiring is in place; device-level verification validation remains. +Overall: **Partial** — implementation and non-device validation are in place; final physical-device NFC verification outcomes remain the blocking gap. ## What You Own diff --git a/specs/person4-sdk-core/OVERVIEW.md b/specs/person4-sdk-core/OVERVIEW.md index 886e2a749..ec76d8000 100644 --- a/specs/person4-sdk-core/OVERVIEW.md +++ b/specs/person4-sdk-core/OVERVIEW.md @@ -1,6 +1,6 @@ # Person 4: SDK Core Adaptation — Workstream Overview -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Owner: Person 4 (SDK Core) > Project: [../SDK-OVERVIEW.md](../SDK-OVERVIEW.md) > Implementation: [SPEC.md](./SPEC.md) @@ -21,8 +21,10 @@ - [x] WebView Lifecycle Events (Chunk 4C — Done) - [x] Conditional SelfApp Store (Chunk 4E — Done) - [x] Web Fallback Adapter Implementations (Chunk 4F — Done) -- [ ] Duplicate fallback ownership remains unresolved (`mobile-sdk-alpha` vs `webview-bridge`) -- [ ] Final contract for web-only fallback vs bridge routing (crypto/haptic behavior) still needs explicit decision +- [x] Fallback ownership decision documented (`mobile-sdk-alpha` owns WebView-only fallback logic) +- [x] Web-only fallback vs bridge-routing contract documented (hybrid crypto + no-op haptic) +- [ ] Implementation consolidation still pending (bridge-layer fallback duplicates not yet fully removed) +- [ ] `generateKey()`/`getPublicKey()` not exposed in `BridgeCryptoAdapter` interface — methods exist in iOS native handler and bridge protocol types but unreachable from WebView client code ## What You Own diff --git a/specs/person5-rn-sdk/OVERVIEW.md b/specs/person5-rn-sdk/OVERVIEW.md index 1b5dfa44a..bf764c729 100644 --- a/specs/person5-rn-sdk/OVERVIEW.md +++ b/specs/person5-rn-sdk/OVERVIEW.md @@ -1,6 +1,6 @@ # Person 5: RN Native Shell — Workstream Overview -> Last updated: 2026-02-19 +> Last updated: 2026-02-23 > Owner: Person 5 (RN SDK) > Project: [../SDK-OVERVIEW.md](../SDK-OVERVIEW.md) > Implementation: [SPEC.md](./SPEC.md) @@ -19,10 +19,12 @@ - [x] `MessageRouter` dispatching bridge messages to handlers is implemented - [x] 5 native handler bridges are implemented (NFC, Camera, Biometrics, Keychain, Lifecycle) - [x] Asset loading strategy is implemented for iOS + Android, including dev override +- [x] NFC handler supports APDU command exchange (`apduCommands` -> `apduResponses`) +- [x] Camera MRZ bridge is implemented against native scanner modules - [ ] Integration validation in Self Wallet app is still a follow-up validation task - [ ] npm publish (`@selfxyz/rn-sdk`) not completed in this branch -**Overall: Partial** — package implementation is present; highest-risk carry-forward items are NFC APDU-path deviation and camera/MRZ stub. +**Overall: Partial** — package implementation is present; highest-risk carry-forward item is breadth of physical-device integration validation across host apps. ## What You Own