@jazadev/react-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -0
- package/dist/index.cjs +1988 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +271 -0
- package/dist/index.d.ts +271 -0
- package/dist/index.js +1987 -0
- package/dist/index.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider/JazaProvider.tsx","../src/api/errors.ts","../src/version.ts","../src/api/publicClient.ts","../src/data/dialCodes.ts","../src/utils/helpers.ts","../src/theme/tokens.ts","../src/provider/JazaContext.tsx","../src/sheet/TopUpBottomSheet.tsx","../src/sheet/steps/OfferStep.tsx","../src/components/Icon.tsx","../src/sheet/steps/PaymentStep.tsx","../src/components/PhoneDigitInput.tsx","../src/sheet/CountryPickerSheet.tsx","../src/theme/listStyles.ts","../src/sheet/CurrencyPickerSheet.tsx","../src/sheet/steps/ResultStep.tsx","../src/components/ProcessingSpinner.tsx","../src/widgets/JazaBalanceWidget.tsx","../src/widgets/JazaTopUpButton.tsx"],"sourcesContent":["export { JazaProvider } from './provider/JazaProvider.js';\nexport type { JazaProviderProps } from './provider/JazaProvider.js';\nexport { useJaza } from './provider/JazaContext.js';\nexport type { JazaContextValue, TopUpStep, ResultPhase } from './provider/JazaContext.js';\n\nexport { JazaBalanceWidget } from './widgets/JazaBalanceWidget.js';\nexport type { JazaBalanceWidgetProps } from './widgets/JazaBalanceWidget.js';\nexport { JazaTopUpButton } from './widgets/JazaTopUpButton.js';\nexport type { JazaTopUpButtonProps } from './widgets/JazaTopUpButton.js';\n\nexport { PublicClient } from './api/publicClient.js';\nexport type { PublicClientConfig } from './api/publicClient.js';\nexport { JazaSdkError } from './api/errors.js';\nexport type {\n Bundle,\n CatalogCountry,\n DepositStatus,\n PredictProviderResponse,\n PublicDeposit,\n QuotePaymentResponse,\n TopUpCompleteResult,\n} from './api/types.js';\n\nexport type { JazaTheme, ThemePreference } from './theme/tokens.js';\nexport { lightTheme, darkTheme } from './theme/tokens.js';\n\nexport { DEFAULT_API_BASE_URL, VERSION } from './version.js';\n\nexport {\n buildE164,\n enrichCountries,\n formatCredits,\n formatUsd,\n formatCurrencyAmount,\n formatLocalAmount,\n pickDefaultCurrencyCode,\n isDepositTerminal,\n} from './utils/helpers.js';\nexport type { EnrichedCountry } from './utils/helpers.js';\n\nexport { DIAL_CODES, iso2ToFlag, getDialCode } from './data/dialCodes.js';\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { Appearance } from 'react-native';\nimport { PublicClient } from '../api/publicClient.js';\nimport type {\n Bundle,\n PredictProviderResponse,\n PublicDeposit,\n QuotePaymentResponse,\n TopUpCompleteResult,\n} from '../api/types.js';\nimport {\n buildE164,\n enrichCountries,\n isDepositTerminal,\n pickDefaultCurrencyCode,\n type EnrichedCountry,\n} from '../utils/helpers.js';\nimport {\n resolveTheme,\n type JazaTheme,\n type ThemePreference,\n} from '../theme/tokens.js';\nimport { JazaContext, type ResultPhase, type TopUpStep } from './JazaContext.js';\nimport { TopUpBottomSheet } from '../sheet/TopUpBottomSheet.js';\n\nconst PREDICT_DEBOUNCE_MS = 500;\nconst POLL_INTERVAL_MS = 2000;\nconst POLL_TIMEOUT_MS = 120_000;\n\nexport type JazaProviderProps = {\n publishableKey: string;\n apiBaseUrl?: string;\n getBalance: () => Promise<number>;\n onTopUpComplete?: (result: TopUpCompleteResult) => void;\n theme?: ThemePreference;\n children: ReactNode;\n};\n\nexport function JazaProvider({\n publishableKey,\n apiBaseUrl,\n getBalance,\n onTopUpComplete,\n theme: themePreference = 'system',\n children,\n}: JazaProviderProps) {\n const client = useMemo(\n () => new PublicClient({ publishableKey, apiBaseUrl }),\n [publishableKey, apiBaseUrl],\n );\n\n const [systemScheme, setSystemScheme] = useState<'light' | 'dark' | null>(\n () => {\n const scheme = Appearance.getColorScheme();\n return scheme === 'dark' ? 'dark' : 'light';\n },\n );\n\n useEffect(() => {\n const sub = Appearance.addChangeListener(({ colorScheme }) => {\n setSystemScheme(colorScheme === 'dark' ? 'dark' : 'light');\n });\n return () => sub.remove();\n }, []);\n\n const theme: JazaTheme = useMemo(\n () => resolveTheme(themePreference, systemScheme),\n [themePreference, systemScheme],\n );\n\n const [balance, setBalance] = useState<number | null>(null);\n const [balanceLoading, setBalanceLoading] = useState(false);\n const [balanceError, setBalanceError] = useState<string | null>(null);\n\n const refreshBalance = useCallback(async () => {\n setBalanceLoading(true);\n setBalanceError(null);\n try {\n const value = await getBalance();\n setBalance(value);\n } catch (err) {\n setBalanceError(\n err instanceof Error ? err.message : 'Failed to load balance',\n );\n } finally {\n setBalanceLoading(false);\n }\n }, [getBalance]);\n\n useEffect(() => {\n void refreshBalance();\n }, [refreshBalance]);\n\n const [sheetOpen, setSheetOpen] = useState(false);\n const [step, setStep] = useState<TopUpStep>('offer');\n const [resultPhase, setResultPhase] = useState<ResultPhase>('loading');\n const [topUpToken, setTopUpToken] = useState<string | null>(null);\n\n const [bundles, setBundles] = useState<Bundle[]>([]);\n const [bundlesLoading, setBundlesLoading] = useState(false);\n const [bundlesError, setBundlesError] = useState<string | null>(null);\n const [selectedBundle, setSelectedBundle] = useState<Bundle | null>(null);\n\n const [countries, setCountries] = useState<EnrichedCountry[]>([]);\n const [selectedCountry, setSelectedCountryState] =\n useState<EnrichedCountry | null>(null);\n const [selectedCurrencyCode, setSelectedCurrencyCode] = useState<\n string | null\n >(null);\n\n const [phoneNational, setPhoneNational] = useState('');\n const [predict, setPredict] = useState<PredictProviderResponse | null>(\n null,\n );\n const [predictLoading, setPredictLoading] = useState(false);\n const [predictError, setPredictError] = useState<string | null>(null);\n\n const [quote, setQuote] = useState<QuotePaymentResponse | null>(null);\n const [quoteLoading, setQuoteLoading] = useState(false);\n const [quoteError, setQuoteError] = useState<string | null>(null);\n\n const [deposit, setDeposit] = useState<PublicDeposit | null>(null);\n const [depositError, setDepositError] = useState<string | null>(null);\n const [failureReason, setFailureReason] = useState<string | null>(null);\n\n const predictTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pollTimer = useRef<ReturnType<typeof setInterval> | null>(null);\n const pollStarted = useRef<number | null>(null);\n\n const clearPoll = useCallback(() => {\n if (pollTimer.current) {\n clearInterval(pollTimer.current);\n pollTimer.current = null;\n }\n pollStarted.current = null;\n }, []);\n\n const resetPaymentState = useCallback(() => {\n setPredict(null);\n setPredictError(null);\n setQuote(null);\n setQuoteError(null);\n setDeposit(null);\n setDepositError(null);\n setFailureReason(null);\n setResultPhase('loading');\n }, []);\n\n const setSelectedCountry = useCallback((country: EnrichedCountry | null) => {\n setSelectedCountryState(country);\n setPhoneNational('');\n setPredict(null);\n setPredictError(null);\n if (country && country.currencies.length > 0) {\n const codes = country.currencies.map((c) => c.code);\n setSelectedCurrencyCode(pickDefaultCurrencyCode(codes));\n } else {\n setSelectedCurrencyCode(null);\n }\n }, []);\n\n const loadSessionData = useCallback(async () => {\n setBundlesLoading(true);\n setBundlesError(null);\n try {\n const [bundleList, catalogCountries] = await Promise.all([\n client.listBundles(),\n client.listCountries(),\n ]);\n const active = bundleList\n .filter((b) => b.isActive)\n .sort((a, b) => a.sortOrder - b.sortOrder);\n setBundles(active);\n if (active.length > 0) {\n setSelectedBundle(active[0]!);\n } else {\n setSelectedBundle(null);\n }\n const enriched = enrichCountries(catalogCountries);\n setCountries(enriched);\n if (enriched.length > 0) {\n setSelectedCountryState((prev) => {\n if (prev) return prev;\n return enriched.find((c) => c.iso2 === 'CD') ?? enriched[0]!;\n });\n setSelectedCurrencyCode((prev) => {\n if (prev) return prev;\n const country =\n enriched.find((c) => c.iso2 === 'CD') ?? enriched[0]!;\n const codes = country.currencies.map((c) => c.code);\n return pickDefaultCurrencyCode(codes);\n });\n }\n } catch (err) {\n setBundles([]);\n setSelectedBundle(null);\n setBundlesError(\n err instanceof Error ? err.message : 'Failed to load bundles',\n );\n } finally {\n setBundlesLoading(false);\n }\n }, [client]);\n\n const openTopUp = useCallback(\n async (token: string) => {\n client.setTopUpToken(token);\n setTopUpToken(token);\n setStep('offer');\n resetPaymentState();\n setSelectedCountryState(null);\n setSelectedCurrencyCode(null);\n setPhoneNational('');\n setBundlesError(null);\n // Open sheet immediately — do not block present() on network calls.\n setSheetOpen(true);\n void loadSessionData();\n void refreshBalance();\n },\n [client, loadSessionData, refreshBalance, resetPaymentState],\n );\n\n const closeTopUp = useCallback(() => {\n clearPoll();\n setSheetOpen(false);\n client.setTopUpToken(null);\n setTopUpToken(null);\n setStep('offer');\n resetPaymentState();\n }, [clearPoll, client, resetPaymentState]);\n\n const goToOffer = useCallback(() => {\n clearPoll();\n setStep('offer');\n resetPaymentState();\n }, [clearPoll, resetPaymentState]);\n\n const goToPayment = useCallback(() => {\n setStep('payment');\n resetPaymentState();\n }, [resetPaymentState]);\n\n const startPoll = useCallback(\n (depositId: string, credits: number) => {\n clearPoll();\n pollStarted.current = Date.now();\n pollTimer.current = setInterval(() => {\n void (async () => {\n if (\n pollStarted.current &&\n Date.now() - pollStarted.current > POLL_TIMEOUT_MS\n ) {\n clearPoll();\n setResultPhase('failure');\n setFailureReason('Payment timed out. Please try again.');\n return;\n }\n try {\n const updated = await client.getDeposit(depositId);\n setDeposit(updated);\n if (updated.status === 'COMPLETED') {\n clearPoll();\n setResultPhase('success');\n await refreshBalance();\n onTopUpComplete?.({\n depositId: updated.id,\n credits,\n status: updated.status,\n });\n } else if (isDepositTerminal(updated.status)) {\n clearPoll();\n setResultPhase('failure');\n setFailureReason(\n updated.failureReason ?? `Payment ${updated.status.toLowerCase()}`,\n );\n }\n } catch {\n /* keep polling */\n }\n })();\n }, POLL_INTERVAL_MS);\n },\n [clearPoll, client, onTopUpComplete, refreshBalance],\n );\n\n const submitDeposit = useCallback(async () => {\n if (!selectedBundle || !predict || !quote || !selectedCountry) return;\n const e164 = buildE164(selectedCountry.dialCode, phoneNational);\n setStep('processing');\n setResultPhase('loading');\n setDepositError(null);\n try {\n const created = await client.createDeposit({\n bundleId: selectedBundle.id,\n currencyCode: quote.currencyCode,\n paymentGatewayCode: predict.provider.code,\n phoneNumber: e164,\n });\n setDeposit(created);\n if (created.status === 'COMPLETED') {\n setResultPhase('success');\n await refreshBalance();\n onTopUpComplete?.({\n depositId: created.id,\n credits: created.credits,\n status: created.status,\n });\n return;\n }\n if (isDepositTerminal(created.status)) {\n setResultPhase('failure');\n setFailureReason(\n created.failureReason ?? `Payment ${created.status.toLowerCase()}`,\n );\n return;\n }\n startPoll(created.id, created.credits);\n } catch (err) {\n setResultPhase('failure');\n setDepositError(\n err instanceof Error ? err.message : 'Failed to start payment',\n );\n setFailureReason(\n err instanceof Error ? err.message : 'Failed to start payment',\n );\n }\n }, [\n client,\n onTopUpComplete,\n phoneNational,\n predict,\n quote,\n refreshBalance,\n selectedBundle,\n selectedCountry,\n startPoll,\n ]);\n\n const retryPayment = useCallback(() => {\n clearPoll();\n setStep('payment');\n setResultPhase('loading');\n setDepositError(null);\n setFailureReason(null);\n }, [clearPoll]);\n\n // Debounced predict\n useEffect(() => {\n if (step !== 'payment' || !selectedCountry) return;\n const digits = phoneNational.replace(/\\D/g, '');\n if (digits.length < 6) {\n setPredict(null);\n setPredictError(null);\n return;\n }\n if (predictTimer.current) clearTimeout(predictTimer.current);\n predictTimer.current = setTimeout(() => {\n void (async () => {\n setPredictLoading(true);\n setPredictError(null);\n try {\n const e164 = buildE164(selectedCountry.dialCode, phoneNational);\n const result = await client.predictProvider(e164);\n setPredict(result);\n const codes = result.currencies.map((c) => c.code);\n if (\n selectedCurrencyCode &&\n codes.includes(selectedCurrencyCode)\n ) {\n /* keep selection */\n } else {\n setSelectedCurrencyCode(pickDefaultCurrencyCode(codes));\n }\n } catch (err) {\n setPredict(null);\n setPredictError(\n err instanceof Error ? err.message : 'Could not detect provider',\n );\n } finally {\n setPredictLoading(false);\n }\n })();\n }, PREDICT_DEBOUNCE_MS);\n return () => {\n if (predictTimer.current) clearTimeout(predictTimer.current);\n };\n }, [\n client,\n phoneNational,\n selectedCountry,\n selectedCurrencyCode,\n step,\n ]);\n\n // Quote refresh\n useEffect(() => {\n if (\n step !== 'payment' ||\n !selectedBundle ||\n !predict ||\n !selectedCurrencyCode\n ) {\n setQuote(null);\n return;\n }\n void (async () => {\n setQuoteLoading(true);\n setQuoteError(null);\n try {\n const q = await client.quotePayment({\n bundleId: selectedBundle.id,\n currencyCode: selectedCurrencyCode,\n paymentGatewayCode: predict.provider.code,\n });\n setQuote(q);\n } catch (err) {\n setQuote(null);\n setQuoteError(\n err instanceof Error ? err.message : 'Could not load quote',\n );\n } finally {\n setQuoteLoading(false);\n }\n })();\n }, [client, predict, selectedBundle, selectedCurrencyCode, step]);\n\n useEffect(() => () => clearPoll(), [clearPoll]);\n\n const value = useMemo(\n () => ({\n theme,\n themePreference,\n publishableKey,\n client,\n balance,\n balanceLoading,\n balanceError,\n refreshBalance,\n sheetOpen,\n step,\n resultPhase,\n topUpToken,\n bundles,\n bundlesLoading,\n bundlesError,\n selectedBundle,\n setSelectedBundle,\n countries,\n selectedCountry,\n setSelectedCountry,\n selectedCurrencyCode,\n setSelectedCurrencyCode,\n phoneNational,\n setPhoneNational,\n predict,\n predictLoading,\n predictError,\n quote,\n quoteLoading,\n quoteError,\n deposit,\n depositError,\n failureReason,\n openTopUp,\n closeTopUp,\n goToOffer,\n goToPayment,\n submitDeposit,\n retryPayment,\n onTopUpComplete,\n }),\n [\n theme,\n themePreference,\n publishableKey,\n client,\n balance,\n balanceLoading,\n balanceError,\n refreshBalance,\n sheetOpen,\n step,\n resultPhase,\n topUpToken,\n bundles,\n bundlesLoading,\n bundlesError,\n selectedBundle,\n countries,\n selectedCountry,\n setSelectedCountry,\n selectedCurrencyCode,\n phoneNational,\n predict,\n predictLoading,\n predictError,\n quote,\n quoteLoading,\n quoteError,\n deposit,\n depositError,\n failureReason,\n openTopUp,\n closeTopUp,\n goToOffer,\n goToPayment,\n submitDeposit,\n retryPayment,\n onTopUpComplete,\n ],\n );\n\n return (\n <JazaContext.Provider value={value}>\n {children}\n <TopUpBottomSheet />\n </JazaContext.Provider>\n );\n}\n","export type JazaSdkErrorBody = {\n statusCode?: number;\n message?: string | { message?: string };\n error?: string;\n};\n\nexport class JazaSdkError extends Error {\n readonly statusCode: number;\n readonly code: string;\n readonly raw: unknown;\n\n constructor(statusCode: number, message: string, raw?: unknown) {\n super(message);\n this.name = 'JazaSdkError';\n this.statusCode = statusCode;\n this.code = `HTTP_${statusCode}`;\n this.raw = raw;\n }\n\n static fromResponse(status: number, body: unknown): JazaSdkError {\n let message = `Request failed (${status})`;\n if (typeof body === 'object' && body !== null) {\n const m = (body as JazaSdkErrorBody).message;\n if (typeof m === 'string') {\n message = m;\n } else if (typeof m === 'object' && m?.message) {\n message = m.message;\n }\n }\n return new JazaSdkError(status, message, body);\n }\n}\n","export const VERSION = '0.1.0';\nexport const DEFAULT_API_BASE_URL = 'https://api.jaza.dev';\n","import { JazaSdkError } from './errors.js';\nimport type {\n Bundle,\n CatalogCountry,\n PredictProviderResponse,\n PublicDeposit,\n QuotePaymentResponse,\n} from './types.js';\nimport { DEFAULT_API_BASE_URL, VERSION } from '../version.js';\n\nexport type PublicClientConfig = {\n apiBaseUrl?: string;\n publishableKey: string;\n};\n\nexport class PublicClient {\n private readonly apiBaseUrl: string;\n private readonly publishableKey: string;\n private topUpToken: string | null = null;\n\n constructor(config: PublicClientConfig) {\n this.apiBaseUrl = (config.apiBaseUrl ?? DEFAULT_API_BASE_URL).replace(\n /\\/$/,\n '',\n );\n this.publishableKey = config.publishableKey;\n }\n\n setTopUpToken(token: string | null) {\n this.topUpToken = token;\n }\n\n async listCountries(): Promise<CatalogCountry[]> {\n return this.request<CatalogCountry[]>('GET', '/v1/catalog/countries');\n }\n\n async listBundles(): Promise<Bundle[]> {\n return this.authedRequest<Bundle[]>('GET', '/v1/public/bundles');\n }\n\n async predictProvider(phoneNumber: string): Promise<PredictProviderResponse> {\n return this.authedRequest<PredictProviderResponse>(\n 'POST',\n '/v1/public/payments/predict',\n { phoneNumber },\n );\n }\n\n async quotePayment(body: {\n bundleId: string;\n currencyCode: string;\n paymentGatewayCode: string;\n }): Promise<QuotePaymentResponse> {\n return this.authedRequest<QuotePaymentResponse>(\n 'POST',\n '/v1/public/payments/quote',\n body,\n );\n }\n\n async createDeposit(body: {\n bundleId: string;\n currencyCode: string;\n paymentGatewayCode: string;\n phoneNumber: string;\n idempotencyKey?: string;\n }): Promise<PublicDeposit> {\n return this.authedRequest<PublicDeposit>(\n 'POST',\n '/v1/public/payments/deposits',\n body,\n );\n }\n\n async getDeposit(paymentRequestId: string): Promise<PublicDeposit> {\n return this.authedRequest<PublicDeposit>(\n 'GET',\n `/v1/public/payments/deposits/${paymentRequestId}`,\n );\n }\n\n private async authedRequest<T>(\n method: 'GET' | 'POST',\n path: string,\n body?: unknown,\n ): Promise<T> {\n if (!this.topUpToken) {\n throw new JazaSdkError(401, 'Top-up session token is not set');\n }\n return this.request<T>(method, path, body, this.topUpToken);\n }\n\n private async request<T>(\n method: 'GET' | 'POST',\n path: string,\n body?: unknown,\n token?: string,\n ): Promise<T> {\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'User-Agent': `@jazadev/react-native/${VERSION}`,\n };\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n headers['X-Jaza-Public-Key'] = this.publishableKey;\n }\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n const response = await fetch(`${this.apiBaseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n\n const text = await response.text();\n let parsed: unknown = null;\n if (text) {\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n parsed = { message: text };\n }\n }\n\n if (!response.ok) {\n throw JazaSdkError.fromResponse(response.status, parsed);\n }\n\n return parsed as T;\n }\n}\n","/** ISO 3166-1 alpha-2 → international dial code (Jaza MoMo ecosystem). */\nexport const DIAL_CODES: Record<string, string> = {\n BJ: '229',\n BF: '226',\n CM: '237',\n CI: '225',\n CD: '243',\n CG: '242',\n ET: '251',\n GA: '241',\n GH: '233',\n KE: '254',\n MW: '265',\n MZ: '258',\n NG: '234',\n RW: '250',\n SN: '221',\n SL: '232',\n TZ: '255',\n UG: '256',\n ZM: '260',\n};\n\nexport function iso2ToFlag(iso2: string): string {\n const code = iso2.toUpperCase();\n if (code.length !== 2) return '';\n const points = [...code].map((c) => 0x1f1e6 - 65 + c.charCodeAt(0));\n return String.fromCodePoint(...points);\n}\n\nexport function getDialCode(iso2: string): string | undefined {\n return DIAL_CODES[iso2.toUpperCase()];\n}\n","import { getDialCode, iso2ToFlag } from '../data/dialCodes.js';\nimport type { CatalogCountry } from '../api/types.js';\n\nexport type EnrichedCountry = {\n id: string;\n name: string;\n iso2: string;\n iso3: string;\n dialCode: string;\n flag: string;\n currencies: Array<{ code: string; decimals: number; name: string }>;\n};\n\nexport function enrichCountries(\n countries: CatalogCountry[],\n): EnrichedCountry[] {\n return countries\n .filter((c) => c.isActive && getDialCode(c.iso2))\n .map((c) => {\n const dialCode = getDialCode(c.iso2)!;\n const currencies =\n c.currencies\n ?.map((cc) => cc.currency)\n .filter((cur) => cur?.isActive)\n .map((cur) => ({\n code: cur!.code,\n decimals: cur!.decimals,\n name: cur!.name,\n })) ?? [];\n return {\n id: c.id,\n name: c.name,\n iso2: c.iso2,\n iso3: c.iso3,\n dialCode,\n flag: iso2ToFlag(c.iso2),\n currencies,\n };\n })\n .filter((c) => c.currencies.length > 0)\n .sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport function buildE164(dialCode: string, nationalNumber: string): string {\n const digits = nationalNumber.replace(/\\D/g, '');\n const code = dialCode.replace(/\\D/g, '');\n if (digits.length < 6) {\n throw new Error('Phone number too short');\n }\n return `${code}${digits}`;\n}\n\n/** Prefer local (non-USD) when multiple currencies are supported. */\nexport function pickDefaultCurrencyCode(codes: string[]): string {\n if (codes.length === 0) {\n throw new Error('No currencies available');\n }\n const local = codes.find((c) => c.toUpperCase() !== 'USD');\n return (local ?? codes[0]!).toUpperCase();\n}\n\nexport function isDepositTerminal(\n status: string,\n): status is 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED' {\n return (\n status === 'COMPLETED' ||\n status === 'FAILED' ||\n status === 'EXPIRED' ||\n status === 'CANCELLED'\n );\n}\n\nexport function formatCredits(n: number): string {\n return n.toLocaleString('en-US');\n}\n\nexport function formatUsd(priceUsd: string): string {\n const n = Number(priceUsd);\n if (Number.isNaN(n)) return priceUsd;\n return formatCurrencyAmount(n, 'USD', 2);\n}\n\n/** Fraction digits: USD = 2, every other currency = 0 (MoMo / PawaPay). */\nexport function resolveCurrencyFractionDigits(currencyCode: string): number {\n return currencyCode.toUpperCase() === 'USD' ? 2 : 0;\n}\n\nexport function formatCurrencyAmount(\n amount: string | number,\n currencyCode: string,\n _decimals?: number,\n): string {\n const n = typeof amount === 'string' ? Number(amount) : amount;\n const code = currencyCode.toUpperCase();\n if (Number.isNaN(n)) return `${amount} ${code}`;\n\n const fractionDigits = resolveCurrencyFractionDigits(code);\n\n try {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: code,\n minimumFractionDigits: fractionDigits,\n maximumFractionDigits: fractionDigits,\n }).format(n);\n } catch {\n const grouped = n.toLocaleString('en-US', {\n minimumFractionDigits: fractionDigits,\n maximumFractionDigits: fractionDigits,\n });\n return `${grouped} ${code}`;\n }\n}\n\n/** @deprecated Use formatCurrencyAmount */\nexport function formatLocalAmount(\n amount: string,\n currencyCode: string,\n decimals?: number,\n): string {\n return formatCurrencyAmount(amount, currencyCode, decimals);\n}\n","export type ThemeMode = 'light' | 'dark';\n\nexport type JazaTheme = {\n mode: ThemeMode;\n colors: {\n background: string;\n surface: string;\n surfaceContainer: string;\n surfaceContainerLow: string;\n surfaceContainerHigh: string;\n surfaceContainerHighest: string;\n surfaceVariant: string;\n onSurface: string;\n onSurfaceVariant: string;\n primary: string;\n onPrimary: string;\n primaryContainer: string;\n onPrimaryContainer: string;\n secondaryContainer: string;\n onSecondaryContainer: string;\n outline: string;\n outlineVariant: string;\n error: string;\n success: string;\n overlay: string;\n bundleBorder: string;\n bundleBorderSelected: string;\n bundleBg: string;\n };\n spacing: {\n xs: number;\n sm: number;\n md: number;\n lg: number;\n xl: number;\n gutter: number;\n };\n radius: {\n md: number;\n lg: number;\n xl: number;\n full: number;\n };\n};\n\nconst spacing = { xs: 4, sm: 8, md: 16, lg: 24, xl: 40, gutter: 20 };\nconst radius = { md: 8, lg: 12, xl: 16, full: 9999 };\n\nexport const darkTheme: JazaTheme = {\n mode: 'dark',\n spacing,\n radius,\n colors: {\n background: '#121414',\n surface: '#121414',\n surfaceContainer: '#1e2020',\n surfaceContainerLow: '#1a1c1c',\n surfaceContainerHigh: '#282a2b',\n surfaceContainerHighest: '#333535',\n surfaceVariant: '#333535',\n onSurface: '#e2e2e2',\n onSurfaceVariant: '#bacac5',\n primary: '#57f1db',\n onPrimary: '#003731',\n primaryContainer: '#2dd4bf',\n onPrimaryContainer: '#00574d',\n secondaryContainer: '#00bd85',\n onSecondaryContainer: '#00452e',\n outline: '#859490',\n outlineVariant: '#3c4a46',\n error: '#ffb4ab',\n success: '#45dfa4',\n overlay: 'rgba(12,15,15,0.8)',\n bundleBorder: '#262626',\n bundleBorderSelected: '#2dd4bf',\n bundleBg: '#111111',\n },\n};\n\n/** Checkout UI uses dark palette in both light and dark preference. */\nexport const lightTheme: JazaTheme = {\n ...darkTheme,\n mode: 'light',\n};\n\nexport type ThemePreference = 'light' | 'dark' | 'system';\n\nexport function resolveTheme(\n preference: ThemePreference,\n systemScheme: 'light' | 'dark' | null,\n): JazaTheme {\n if (preference === 'system') {\n return systemScheme === 'dark' ? darkTheme : lightTheme;\n }\n return preference === 'dark' ? darkTheme : lightTheme;\n}\n","import { createContext, useContext } from 'react';\nimport type { PublicClient } from '../api/publicClient.js';\nimport type {\n Bundle,\n PredictProviderResponse,\n PublicDeposit,\n QuotePaymentResponse,\n TopUpCompleteResult,\n} from '../api/types.js';\nimport type { EnrichedCountry } from '../utils/helpers.js';\nimport type { JazaTheme, ThemePreference } from '../theme/tokens.js';\n\nexport type TopUpStep = 'offer' | 'payment' | 'processing';\n\nexport type ResultPhase = 'loading' | 'success' | 'failure';\n\nexport type JazaContextValue = {\n theme: JazaTheme;\n themePreference: ThemePreference;\n publishableKey: string;\n client: PublicClient;\n balance: number | null;\n balanceLoading: boolean;\n balanceError: string | null;\n refreshBalance: () => Promise<void>;\n sheetOpen: boolean;\n step: TopUpStep;\n resultPhase: ResultPhase;\n topUpToken: string | null;\n bundles: Bundle[];\n bundlesLoading: boolean;\n bundlesError: string | null;\n selectedBundle: Bundle | null;\n setSelectedBundle: (b: Bundle | null) => void;\n countries: EnrichedCountry[];\n selectedCountry: EnrichedCountry | null;\n setSelectedCountry: (c: EnrichedCountry | null) => void;\n selectedCurrencyCode: string | null;\n setSelectedCurrencyCode: (code: string | null) => void;\n phoneNational: string;\n setPhoneNational: (v: string) => void;\n predict: PredictProviderResponse | null;\n predictLoading: boolean;\n predictError: string | null;\n quote: QuotePaymentResponse | null;\n quoteLoading: boolean;\n quoteError: string | null;\n deposit: PublicDeposit | null;\n depositError: string | null;\n failureReason: string | null;\n openTopUp: (token: string) => Promise<void>;\n closeTopUp: () => void;\n goToOffer: () => void;\n goToPayment: () => void;\n submitDeposit: () => Promise<void>;\n retryPayment: () => void;\n onTopUpComplete?: (result: TopUpCompleteResult) => void;\n};\n\nexport const JazaContext = createContext<JazaContextValue | null>(null);\n\nexport function useJaza(): JazaContextValue {\n const ctx = useContext(JazaContext);\n if (!ctx) {\n throw new Error('useJaza must be used within JazaProvider');\n }\n return ctx;\n}\n","import { useCallback, useMemo, useRef } from 'react';\nimport { Modal, StyleSheet, View } from 'react-native';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\nimport BottomSheet, {\n BottomSheetBackdrop,\n BottomSheetScrollView,\n type BottomSheetBackdropProps,\n} from '@gorhom/bottom-sheet';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useJaza } from '../provider/JazaContext.js';\nimport { OfferStep } from './steps/OfferStep.js';\nimport { PaymentStep } from './steps/PaymentStep.js';\nimport { ResultStep } from './steps/ResultStep.js';\n\n/**\n * RN Modal hosts the sheet so it reliably appears above Expo Router /\n * react-native-screens native stacks (BottomSheetModal.present() often no-ops).\n */\nexport function TopUpBottomSheet() {\n const { theme, sheetOpen, step, closeTopUp } = useJaza();\n const { colors, spacing } = theme;\n const insets = useSafeAreaInsets();\n const ref = useRef<BottomSheet>(null);\n const snapPoints = useMemo(() => ['92%'], []);\n\n const renderBackdrop = useCallback(\n (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n disappearsOnIndex={-1}\n appearsOnIndex={0}\n opacity={0.6}\n pressBehavior=\"close\"\n />\n ),\n [],\n );\n\n const styles = StyleSheet.create({\n root: {\n flex: 1,\n },\n handle: {\n width: 48,\n height: 4,\n borderRadius: 2,\n backgroundColor: colors.surfaceContainerHighest,\n alignSelf: 'center',\n marginTop: spacing.sm,\n marginBottom: spacing.md,\n },\n content: {\n paddingHorizontal: spacing.gutter,\n paddingBottom: insets.bottom + spacing.xl,\n },\n });\n\n return (\n <Modal\n visible={sheetOpen}\n transparent\n animationType=\"fade\"\n statusBarTranslucent\n onRequestClose={closeTopUp}\n >\n {/* Android: GH root must wrap sheets inside RN Modal */}\n <GestureHandlerRootView style={styles.root}>\n <BottomSheet\n ref={ref}\n index={0}\n snapPoints={snapPoints}\n enablePanDownToClose\n onClose={closeTopUp}\n backdropComponent={renderBackdrop}\n keyboardBehavior=\"interactive\"\n keyboardBlurBehavior=\"restore\"\n android_keyboardInputMode=\"adjustResize\"\n backgroundStyle={{ backgroundColor: colors.surface }}\n handleComponent={() => <View style={styles.handle} />}\n >\n <BottomSheetScrollView\n keyboardShouldPersistTaps=\"handled\"\n contentContainerStyle={styles.content}\n >\n {step === 'offer' ? <OfferStep /> : null}\n {step === 'payment' ? <PaymentStep /> : null}\n {step === 'processing' ? <ResultStep /> : null}\n </BottomSheetScrollView>\n </BottomSheet>\n </GestureHandlerRootView>\n </Modal>\n );\n}\n","import {\n ActivityIndicator,\n Pressable,\n StyleSheet,\n Text,\n View,\n} from 'react-native';\nimport { Icon } from '../../components/Icon.js';\nimport { useJaza } from '../../provider/JazaContext.js';\nimport type { Bundle } from '../../api/types.js';\nimport { formatCredits, formatUsd } from '../../utils/helpers.js';\n\nexport function OfferStep() {\n const {\n theme,\n balance,\n balanceLoading,\n bundles,\n bundlesLoading,\n bundlesError,\n selectedBundle,\n setSelectedBundle,\n goToPayment,\n } = useJaza();\n const { colors, spacing, radius } = theme;\n\n const styles = StyleSheet.create({\n balanceCard: {\n backgroundColor: colors.surfaceContainer,\n borderRadius: radius.xl,\n padding: spacing.md,\n marginBottom: spacing.lg,\n },\n balanceLabel: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n marginBottom: spacing.xs,\n },\n balanceRow: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.sm,\n },\n balanceValue: {\n color: colors.onSurface,\n fontSize: 48,\n fontWeight: '700',\n },\n title: {\n color: colors.onSurface,\n fontSize: 24,\n fontWeight: '600',\n marginBottom: spacing.md,\n },\n bundle: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: spacing.md,\n borderRadius: radius.xl,\n backgroundColor: colors.bundleBg,\n borderWidth: 1,\n borderColor: colors.bundleBorder,\n marginBottom: spacing.sm,\n },\n bundleSelected: {\n borderColor: colors.bundleBorderSelected,\n borderWidth: 2,\n },\n bundleLabel: {\n color: colors.onSurface,\n fontSize: 18,\n fontWeight: '600',\n },\n bundleLabelSelected: {\n color: colors.primaryContainer,\n },\n bundleSub: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n marginTop: 2,\n },\n bundleCredits: {\n color: colors.onSurface,\n fontSize: 18,\n fontWeight: '600',\n },\n bundlePrice: {\n color: colors.onSurfaceVariant,\n fontSize: 12,\n fontFamily: 'monospace',\n },\n cta: {\n backgroundColor: colors.primaryContainer,\n borderRadius: radius.full,\n paddingVertical: spacing.md,\n marginTop: spacing.lg,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: spacing.sm,\n },\n ctaText: {\n color: colors.onPrimaryContainer,\n fontSize: 16,\n fontWeight: '600',\n },\n loading: { padding: spacing.xl, alignItems: 'center' },\n error: {\n color: colors.error,\n fontSize: 14,\n marginBottom: spacing.md,\n lineHeight: 20,\n },\n });\n\n const renderBundle = (bundle: Bundle) => {\n const selected = selectedBundle?.id === bundle.id;\n return (\n <Pressable\n key={bundle.id}\n style={[styles.bundle, selected && styles.bundleSelected]}\n onPress={() => setSelectedBundle(bundle)}\n >\n <View>\n <Text\n style={[styles.bundleLabel, selected && styles.bundleLabelSelected]}\n >\n {bundle.label ?? 'Bundle'}\n </Text>\n <Text style={styles.bundleSub}>\n {formatCredits(bundle.credits)} credits\n </Text>\n </View>\n <View style={{ alignItems: 'flex-end' }}>\n <Text style={styles.bundleCredits}>\n {formatCredits(bundle.credits)}\n </Text>\n <Text style={styles.bundlePrice}>{formatUsd(bundle.priceUsd)} USD</Text>\n </View>\n </Pressable>\n );\n };\n\n return (\n <View>\n <View style={styles.balanceCard}>\n <Text style={styles.balanceLabel}>Current Balance</Text>\n <View style={styles.balanceRow}>\n <Icon name=\"bolt\" size={28} color={colors.primary} />\n {balanceLoading && balance === null ? (\n <ActivityIndicator color={colors.primary} />\n ) : (\n <Text style={styles.balanceValue}>\n {balance !== null ? formatCredits(balance) : '—'}\n </Text>\n )}\n </View>\n </View>\n\n <Text style={styles.title}>Top-up Credits</Text>\n\n {bundlesError ? <Text style={styles.error}>{bundlesError}</Text> : null}\n\n {bundlesLoading ? (\n <View style={styles.loading}>\n <ActivityIndicator color={colors.primary} />\n </View>\n ) : (\n bundles.map(renderBundle)\n )}\n\n {!bundlesLoading && !bundlesError && bundles.length === 0 ? (\n <Text style={styles.error}>No active bundles for this app.</Text>\n ) : null}\n\n <Pressable\n style={styles.cta}\n onPress={goToPayment}\n disabled={!selectedBundle}\n >\n <Text style={styles.ctaText}>\n Continue with {selectedBundle?.label ?? 'bundle'}\n </Text>\n <Icon name=\"arrow-forward\" size={20} color={colors.onPrimaryContainer} />\n </Pressable>\n </View>\n );\n}\n","import MaterialIcons from '@expo/vector-icons/MaterialIcons';\nimport type { ComponentProps } from 'react';\n\ntype IconProps = {\n name: ComponentProps<typeof MaterialIcons>['name'];\n size?: number;\n color: string;\n};\n\nexport function Icon({ name, size = 24, color }: IconProps) {\n return <MaterialIcons name={name} size={size} color={color} />;\n}\n","import { useMemo, useState } from 'react';\nimport {\n ActivityIndicator,\n Pressable,\n StyleSheet,\n Text,\n View,\n} from 'react-native';\nimport { Icon } from '../../components/Icon.js';\nimport { PhoneDigitInput } from '../../components/PhoneDigitInput.js';\nimport { useJaza } from '../../provider/JazaContext.js';\nimport { formatCurrencyAmount, formatUsd } from '../../utils/helpers.js';\nimport { CountryPickerSheet } from '../CountryPickerSheet.js';\nimport { CurrencyPickerSheet } from '../CurrencyPickerSheet.js';\n\nexport function PaymentStep() {\n const {\n theme,\n balance,\n selectedBundle,\n selectedCountry,\n selectedCurrencyCode,\n setSelectedCurrencyCode,\n phoneNational,\n setPhoneNational,\n predict,\n predictLoading,\n predictError,\n quote,\n quoteLoading,\n quoteError,\n goToOffer,\n submitDeposit,\n } = useJaza();\n\n const { colors, spacing, radius } = theme;\n const [countryPickerOpen, setCountryPickerOpen] = useState(false);\n const [currencyPickerOpen, setCurrencyPickerOpen] = useState(false);\n\n const currencyOptions = useMemo(() => {\n if (predict?.currencies?.length) {\n return predict.currencies;\n }\n return selectedCountry?.currencies ?? [];\n }, [predict, selectedCountry]);\n\n const showCurrencyPicker = currencyOptions.length > 1;\n\n const formattedQuote = quote\n ? formatCurrencyAmount(quote.totalLocal, quote.currencyCode)\n : null;\n\n const buyLabel = quote\n ? `Buy ${formattedQuote}`\n : quoteLoading\n ? 'Loading…'\n : selectedBundle\n ? `Buy ${formatUsd(selectedBundle.priceUsd)}`\n : 'Buy';\n\n const styles = StyleSheet.create({\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: spacing.lg,\n },\n headerLeft: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.sm,\n flex: 1,\n },\n backBtn: {\n width: 40,\n height: 40,\n borderRadius: radius.full,\n backgroundColor: colors.surfaceContainer,\n alignItems: 'center',\n justifyContent: 'center',\n },\n headerTitle: {\n color: colors.onSurface,\n fontSize: 24,\n fontWeight: '600',\n flexShrink: 1,\n },\n balanceChip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.xs,\n backgroundColor: colors.surfaceContainer,\n paddingHorizontal: spacing.sm,\n paddingVertical: spacing.xs,\n borderRadius: radius.full,\n },\n balanceChipText: {\n color: colors.primary,\n fontSize: 12,\n fontWeight: '500',\n },\n dialBtn: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.xs,\n },\n dialText: {\n color: colors.primaryContainer,\n fontSize: 22,\n fontWeight: '700',\n },\n providerText: {\n color: colors.primaryContainer,\n fontSize: 14,\n fontWeight: '500',\n marginTop: spacing.sm,\n },\n providerError: {\n color: colors.error,\n fontSize: 14,\n marginTop: spacing.sm,\n },\n payCard: {\n backgroundColor: colors.surfaceContainerLow,\n borderRadius: radius.xl,\n borderWidth: 1,\n borderColor: colors.outlineVariant,\n padding: spacing.md,\n marginTop: spacing.lg,\n },\n payRow: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: spacing.md,\n },\n currencyBtn: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.xs,\n },\n currencyCode: {\n color: colors.primaryContainer,\n fontSize: 18,\n fontWeight: '600',\n },\n amountText: {\n color: colors.onSurface,\n fontSize: 18,\n fontWeight: '600',\n },\n cta: {\n backgroundColor: colors.primaryContainer,\n borderRadius: radius.full,\n paddingVertical: spacing.md,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: spacing.sm,\n },\n ctaDisabled: { opacity: 0.5 },\n ctaText: {\n color: colors.onPrimaryContainer,\n fontSize: 16,\n fontWeight: '600',\n },\n quoteError: {\n color: colors.error,\n fontSize: 12,\n marginBottom: spacing.sm,\n },\n });\n\n const canSubmit =\n !!predict &&\n !!quote &&\n !quoteLoading &&\n !predictLoading &&\n phoneNational.replace(/\\D/g, '').length >= 6;\n\n return (\n <View>\n <View style={styles.header}>\n <View style={styles.headerLeft}>\n <Pressable style={styles.backBtn} onPress={goToOffer}>\n <Icon name=\"arrow-back\" size={22} color={colors.onSurfaceVariant} />\n </Pressable>\n <Text style={styles.headerTitle} numberOfLines={1}>\n {selectedBundle?.label ?? 'Top-up Balance'}\n </Text>\n </View>\n {balance !== null ? (\n <View style={styles.balanceChip}>\n <Icon name=\"bolt\" size={16} color={colors.primary} />\n <Text style={styles.balanceChipText}>{balance.toLocaleString()}</Text>\n </View>\n ) : null}\n </View>\n\n <PhoneDigitInput\n theme={theme}\n value={phoneNational}\n onChangeText={setPhoneNational}\n dialPressable={\n <Pressable\n style={styles.dialBtn}\n onPress={() => setCountryPickerOpen(true)}\n >\n <Text style={styles.dialText}>\n +{selectedCountry?.dialCode ?? '…'}\n </Text>\n <Icon name=\"expand-more\" size={24} color={colors.primaryContainer} />\n </Pressable>\n }\n trailing={\n predict && !predictLoading ? (\n <Icon name=\"check-circle\" size={24} color={colors.primary} />\n ) : predictLoading ? (\n <ActivityIndicator color={colors.primary} size=\"small\" />\n ) : null\n }\n />\n\n {predict ? (\n <Text style={styles.providerText}>{predict.provider.displayName}</Text>\n ) : predictError ? (\n <Text style={styles.providerError}>{predictError}</Text>\n ) : null}\n\n <View style={styles.payCard}>\n <View style={styles.payRow}>\n {showCurrencyPicker ? (\n <Pressable\n style={styles.currencyBtn}\n onPress={() => setCurrencyPickerOpen(true)}\n >\n <Text style={styles.currencyCode}>\n {selectedCurrencyCode ?? '—'}\n </Text>\n <Icon name=\"expand-more\" size={20} color={colors.primaryContainer} />\n </Pressable>\n ) : (\n <Text style={styles.currencyCode}>\n {selectedCurrencyCode ?? quote?.currencyCode ?? 'USD'}\n </Text>\n )}\n <Text style={styles.amountText}>\n {formattedQuote ??\n (selectedBundle ? formatUsd(selectedBundle.priceUsd) : '—')}\n </Text>\n </View>\n {quoteError ? <Text style={styles.quoteError}>{quoteError}</Text> : null}\n <Pressable\n style={[styles.cta, !canSubmit && styles.ctaDisabled]}\n onPress={() => void submitDeposit()}\n disabled={!canSubmit}\n >\n <Icon name=\"lock\" size={18} color={colors.onPrimaryContainer} />\n <Text style={styles.ctaText}>{buyLabel}</Text>\n </Pressable>\n </View>\n\n <CountryPickerSheet\n visible={countryPickerOpen}\n onClose={() => setCountryPickerOpen(false)}\n />\n <CurrencyPickerSheet\n visible={currencyPickerOpen}\n currencies={currencyOptions}\n selectedCode={selectedCurrencyCode}\n onSelect={(code) => {\n setSelectedCurrencyCode(code);\n setCurrencyPickerOpen(false);\n }}\n onClose={() => setCurrencyPickerOpen(false)}\n />\n </View>\n );\n}\n","import type { ReactNode } from 'react';\nimport { useRef, useState } from 'react';\nimport { Pressable, StyleSheet, Text, View } from 'react-native';\nimport { BottomSheetTextInput } from '@gorhom/bottom-sheet';\nimport type { JazaTheme } from '../theme/tokens.js';\n\nconst MAX_DIGITS = 10;\n\nexport type PhoneDigitInputProps = {\n theme: JazaTheme;\n value: string;\n onChangeText: (value: string) => void;\n dialPressable: ReactNode;\n trailing?: ReactNode;\n};\n\nexport function PhoneDigitInput({\n theme,\n value,\n onChangeText,\n dialPressable,\n trailing,\n}: PhoneDigitInputProps) {\n const { colors, spacing } = theme;\n const inputRef = useRef<{ focus: () => void } | null>(null);\n const [focused, setFocused] = useState(false);\n\n const digits = value.replace(/\\D/g, '').slice(0, MAX_DIGITS);\n /** Next empty slot, or last slot when the number is complete. */\n const activeIndex =\n digits.length >= MAX_DIGITS ? MAX_DIGITS - 1 : digits.length;\n\n const styles = StyleSheet.create({\n label: {\n color: colors.onSurfaceVariant,\n fontSize: 12,\n letterSpacing: 0.5,\n marginBottom: spacing.sm,\n textTransform: 'uppercase',\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n width: '100%',\n gap: spacing.sm,\n },\n slots: {\n flex: 1,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n minHeight: 40,\n },\n slot: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n },\n slotChar: {\n fontSize: 22,\n fontWeight: '600',\n color: colors.onSurfaceVariant,\n fontVariant: ['tabular-nums'],\n },\n slotCharFocused: {\n color: colors.primaryContainer,\n },\n hiddenInput: {\n position: 'absolute',\n opacity: 0,\n height: 1,\n width: 1,\n },\n });\n\n const focusInput = () => {\n inputRef.current?.focus();\n };\n\n return (\n <View>\n <Text style={styles.label}>Phone Number</Text>\n <Pressable style={styles.row} onPress={focusInput}>\n {dialPressable}\n <View style={styles.slots} pointerEvents=\"none\">\n {Array.from({ length: MAX_DIGITS }, (_, i) => {\n const char = digits[i];\n const isFocused = focused && i === activeIndex;\n return (\n <View key={i} style={styles.slot}>\n <Text\n style={[\n styles.slotChar,\n isFocused ? styles.slotCharFocused : null,\n ]}\n >\n {char ?? '_'}\n </Text>\n </View>\n );\n })}\n </View>\n {trailing}\n <BottomSheetTextInput\n ref={inputRef as never}\n style={styles.hiddenInput}\n value={digits}\n onChangeText={(text) =>\n onChangeText(text.replace(/\\D/g, '').slice(0, MAX_DIGITS))\n }\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n keyboardType=\"phone-pad\"\n autoComplete=\"tel\"\n textContentType=\"telephoneNumber\"\n maxLength={MAX_DIGITS}\n caretHidden\n />\n </Pressable>\n </View>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n FlatList,\n KeyboardAvoidingView,\n Modal,\n Platform,\n Pressable,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useJaza } from '../provider/JazaContext.js';\nimport { createSelectableRowStyles } from '../theme/listStyles.js';\n\nexport type CountryPickerSheetProps = {\n visible: boolean;\n onClose: () => void;\n};\n\nexport function CountryPickerSheet({\n visible,\n onClose,\n}: CountryPickerSheetProps) {\n const { theme, countries, selectedCountry, setSelectedCountry } = useJaza();\n const { colors, spacing, radius } = theme;\n const insets = useSafeAreaInsets();\n const [query, setQuery] = useState('');\n const rowStyles = createSelectableRowStyles(theme);\n\n useEffect(() => {\n if (!visible) setQuery('');\n }, [visible]);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return countries;\n return countries.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.iso2.toLowerCase().includes(q) ||\n c.dialCode.includes(q),\n );\n }, [countries, query]);\n\n const styles = StyleSheet.create({\n root: {\n flex: 1,\n justifyContent: 'flex-end',\n backgroundColor: colors.overlay,\n },\n sheet: {\n backgroundColor: colors.surface,\n borderTopLeftRadius: radius.xl,\n borderTopRightRadius: radius.xl,\n paddingHorizontal: spacing.gutter,\n paddingTop: spacing.md,\n paddingBottom: Math.max(insets.bottom, spacing.md),\n maxHeight: '85%',\n minHeight: 320,\n },\n handle: {\n width: 48,\n height: 4,\n borderRadius: 2,\n backgroundColor: colors.surfaceContainerHighest,\n alignSelf: 'center',\n marginBottom: spacing.md,\n },\n search: {\n backgroundColor: colors.surfaceContainerHigh,\n borderRadius: radius.lg,\n paddingHorizontal: spacing.md,\n minHeight: 48,\n fontSize: 16,\n lineHeight: 22,\n color: colors.onSurface,\n marginBottom: spacing.md,\n },\n list: {\n flexGrow: 1,\n flexShrink: 1,\n },\n nameRow: {\n flex: 1,\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.md,\n minWidth: 0,\n },\n flag: {\n fontSize: 24,\n flexShrink: 0,\n },\n dial: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n fontFamily: 'monospace',\n flexShrink: 0,\n marginLeft: spacing.sm,\n },\n empty: {\n color: colors.onSurfaceVariant,\n textAlign: 'center',\n paddingVertical: spacing.lg,\n },\n });\n\n return (\n <Modal\n visible={visible}\n transparent\n animationType=\"fade\"\n onRequestClose={onClose}\n >\n <KeyboardAvoidingView\n style={styles.root}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n >\n <Pressable style={StyleSheet.absoluteFill} onPress={onClose} />\n <View style={styles.sheet}>\n <View style={styles.handle} />\n <TextInput\n style={styles.search}\n placeholder=\"Search country\"\n placeholderTextColor={colors.onSurfaceVariant}\n value={query}\n onChangeText={setQuery}\n autoCorrect={false}\n autoCapitalize=\"none\"\n clearButtonMode=\"while-editing\"\n returnKeyType=\"search\"\n />\n <FlatList\n style={styles.list}\n data={filtered}\n keyExtractor={(item) => item.id}\n keyboardShouldPersistTaps=\"handled\"\n keyboardDismissMode=\"on-drag\"\n renderItem={({ item }) => {\n const selected = selectedCountry?.id === item.id;\n return (\n <Pressable\n style={[rowStyles.row, selected && rowStyles.rowSelected]}\n onPress={() => {\n setSelectedCountry(item);\n onClose();\n }}\n >\n <View style={styles.nameRow}>\n <Text style={styles.flag}>{item.flag}</Text>\n <Text\n style={[\n rowStyles.label,\n selected && rowStyles.labelSelected,\n ]}\n numberOfLines={1}\n ellipsizeMode=\"tail\"\n >\n {item.name}\n </Text>\n </View>\n <Text style={styles.dial}>+{item.dialCode}</Text>\n </Pressable>\n );\n }}\n ListEmptyComponent={\n <Text style={styles.empty}>No countries match</Text>\n }\n />\n </View>\n </KeyboardAvoidingView>\n </Modal>\n );\n}\n","import { StyleSheet } from 'react-native';\nimport type { JazaTheme } from './tokens.js';\n\n/** Flat list rows: hairline bottom border; selected = teal label only. */\nexport function createSelectableRowStyles(theme: JazaTheme) {\n const { colors, spacing } = theme;\n return StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingVertical: spacing.md,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: colors.outlineVariant,\n gap: spacing.md,\n },\n rowSelected: {\n borderBottomColor: colors.primaryContainer,\n },\n label: {\n color: colors.onSurface,\n fontSize: 16,\n fontWeight: '500',\n flexShrink: 1,\n },\n labelSelected: {\n color: colors.primaryContainer,\n fontWeight: '600',\n },\n sublabel: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n },\n });\n}\n","import {\n FlatList,\n Modal,\n Pressable,\n StyleSheet,\n Text,\n View,\n} from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { useJaza } from '../provider/JazaContext.js';\nimport { createSelectableRowStyles } from '../theme/listStyles.js';\n\nexport type CurrencyOption = {\n code: string;\n decimals: number;\n};\n\nexport type CurrencyPickerSheetProps = {\n visible: boolean;\n currencies: CurrencyOption[];\n selectedCode: string | null;\n onSelect: (code: string) => void;\n onClose: () => void;\n};\n\nexport function CurrencyPickerSheet({\n visible,\n currencies,\n selectedCode,\n onSelect,\n onClose,\n}: CurrencyPickerSheetProps) {\n const { theme } = useJaza();\n const { colors, spacing, radius } = theme;\n const insets = useSafeAreaInsets();\n const rowStyles = createSelectableRowStyles(theme);\n\n const styles = StyleSheet.create({\n backdrop: {\n flex: 1,\n backgroundColor: colors.overlay,\n justifyContent: 'flex-end',\n },\n sheet: {\n backgroundColor: colors.surface,\n borderTopLeftRadius: radius.xl,\n borderTopRightRadius: radius.xl,\n maxHeight: '50%',\n paddingHorizontal: spacing.gutter,\n paddingTop: spacing.md,\n paddingBottom: insets.bottom + spacing.md,\n },\n handle: {\n width: 48,\n height: 4,\n borderRadius: 2,\n backgroundColor: colors.surfaceContainerHighest,\n alignSelf: 'center',\n marginBottom: spacing.md,\n },\n title: {\n color: colors.onSurface,\n fontSize: 18,\n fontWeight: '600',\n marginBottom: spacing.md,\n },\n });\n\n return (\n <Modal\n visible={visible}\n transparent\n animationType=\"fade\"\n onRequestClose={onClose}\n >\n <Pressable style={styles.backdrop} onPress={onClose}>\n <Pressable style={styles.sheet} onPress={(e) => e.stopPropagation()}>\n <View style={styles.handle} />\n <Text style={styles.title}>Select currency</Text>\n <FlatList\n data={currencies}\n keyExtractor={(item) => item.code}\n keyboardShouldPersistTaps=\"handled\"\n renderItem={({ item }) => {\n const selected = selectedCode === item.code;\n return (\n <Pressable\n style={[rowStyles.row, selected && rowStyles.rowSelected]}\n onPress={() => onSelect(item.code)}\n >\n <Text\n style={[rowStyles.label, selected && rowStyles.labelSelected]}\n >\n {item.code}\n </Text>\n </Pressable>\n );\n }}\n />\n </Pressable>\n </Pressable>\n </Modal>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport {\n Animated,\n Pressable,\n StyleSheet,\n Text,\n View,\n} from 'react-native';\nimport { Icon } from '../../components/Icon.js';\nimport { ProcessingSpinner } from '../../components/ProcessingSpinner.js';\nimport { useJaza } from '../../provider/JazaContext.js';\nimport { formatCredits } from '../../utils/helpers.js';\n\nexport function ResultStep() {\n const {\n theme,\n resultPhase,\n selectedBundle,\n deposit,\n failureReason,\n depositError,\n closeTopUp,\n retryPayment,\n } = useJaza();\n const { colors, spacing, radius } = theme;\n const scale = useRef(new Animated.Value(0)).current;\n\n useEffect(() => {\n if (resultPhase === 'success') {\n scale.setValue(0);\n Animated.spring(scale, {\n toValue: 1,\n useNativeDriver: true,\n friction: 6,\n }).start();\n }\n }, [resultPhase, scale]);\n\n const styles = StyleSheet.create({\n container: {\n alignItems: 'center',\n paddingVertical: spacing.xl,\n },\n spinnerWrap: {\n marginBottom: spacing.lg,\n },\n title: {\n color: colors.onSurface,\n fontSize: 20,\n fontWeight: '600',\n textAlign: 'center',\n },\n titlePulse: {\n opacity: 0.9,\n },\n subtitle: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n marginTop: spacing.xs,\n textAlign: 'center',\n },\n successIcon: {\n width: 80,\n height: 80,\n borderRadius: radius.full,\n backgroundColor: `${colors.success}20`,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: spacing.lg,\n },\n failIcon: {\n width: 80,\n height: 80,\n borderRadius: radius.full,\n backgroundColor: `${colors.error}20`,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: spacing.lg,\n },\n doneBtn: {\n backgroundColor: colors.surfaceContainerHigh,\n borderRadius: radius.full,\n paddingHorizontal: spacing.xl,\n paddingVertical: spacing.sm,\n marginTop: spacing.lg,\n },\n doneText: {\n color: colors.onSurface,\n fontSize: 12,\n fontWeight: '500',\n letterSpacing: 0.5,\n },\n retryBtn: {\n backgroundColor: colors.primaryContainer,\n borderRadius: radius.full,\n paddingHorizontal: spacing.xl,\n paddingVertical: spacing.sm,\n marginTop: spacing.md,\n },\n retryText: {\n color: colors.onPrimaryContainer,\n fontSize: 14,\n fontWeight: '600',\n },\n });\n\n if (resultPhase === 'loading') {\n return (\n <View style={styles.container}>\n <View style={styles.spinnerWrap}>\n <ProcessingSpinner theme={theme} size={64} />\n </View>\n <Text style={[styles.title, styles.titlePulse]}>\n Processing payment...\n </Text>\n <Text style={styles.subtitle}>Please authorize on your device</Text>\n </View>\n );\n }\n\n if (resultPhase === 'failure') {\n return (\n <View style={styles.container}>\n <View style={styles.failIcon}>\n <Icon name=\"error-outline\" size={48} color={colors.error} />\n </View>\n <Text style={styles.title}>Payment failed</Text>\n <Text style={styles.subtitle}>\n {failureReason ?? depositError ?? 'Something went wrong'}\n </Text>\n <Pressable style={styles.retryBtn} onPress={retryPayment}>\n <Text style={styles.retryText}>Try again</Text>\n </Pressable>\n <Pressable style={styles.doneBtn} onPress={closeTopUp}>\n <Text style={styles.doneText}>Dismiss</Text>\n </Pressable>\n </View>\n );\n }\n\n const credits = deposit?.credits ?? selectedBundle?.credits ?? 0;\n\n return (\n <View style={styles.container}>\n <Animated.View style={[styles.successIcon, { transform: [{ scale }] }]}>\n <Icon name=\"check-circle\" size={48} color={colors.success} />\n </Animated.View>\n <Text style={styles.title}>Top-up Successful</Text>\n <Text style={styles.subtitle}>\n {formatCredits(credits)} credits have been added to your balance.\n </Text>\n <Pressable style={styles.doneBtn} onPress={closeTopUp}>\n <Text style={styles.doneText}>Done</Text>\n </Pressable>\n </View>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport { Animated, Easing, StyleSheet, View } from 'react-native';\nimport { Icon } from './Icon.js';\nimport type { JazaTheme } from '../theme/tokens.js';\n\ntype ProcessingSpinnerProps = {\n theme: JazaTheme;\n size?: number;\n};\n\n/**\n * Stitch-style ring spinner with centered lock icon (processing / polling).\n */\nexport function ProcessingSpinner({\n theme,\n size = 64,\n}: ProcessingSpinnerProps) {\n const { colors } = theme;\n const spin = useRef(new Animated.Value(0)).current;\n\n useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(spin, {\n toValue: 1,\n duration: 900,\n easing: Easing.linear,\n useNativeDriver: true,\n }),\n );\n loop.start();\n return () => loop.stop();\n }, [spin]);\n\n const rotate = spin.interpolate({\n inputRange: [0, 1],\n outputRange: ['0deg', '360deg'],\n });\n\n const ring = size;\n const stroke = 4;\n const styles = StyleSheet.create({\n wrap: {\n width: ring,\n height: ring,\n alignItems: 'center',\n justifyContent: 'center',\n },\n ring: {\n position: 'absolute',\n width: ring,\n height: ring,\n borderRadius: ring / 2,\n borderWidth: stroke,\n borderColor: colors.surfaceContainerHighest,\n borderTopColor: colors.primary,\n },\n icon: {\n position: 'absolute',\n alignItems: 'center',\n justifyContent: 'center',\n },\n });\n\n return (\n <View style={styles.wrap}>\n <Animated.View style={[styles.ring, { transform: [{ rotate }] }]} />\n <View style={styles.icon}>\n <Icon name=\"lock\" size={Math.round(size * 0.38)} color={colors.primary} />\n </View>\n </View>\n );\n}\n","import { useEffect } from 'react';\nimport {\n ActivityIndicator,\n StyleSheet,\n Text,\n View,\n type ViewStyle,\n} from 'react-native';\nimport { Icon } from '../components/Icon.js';\nimport { useJaza } from '../provider/JazaContext.js';\nimport { formatCredits } from '../utils/helpers.js';\n\nexport type JazaBalanceWidgetProps = {\n style?: ViewStyle;\n};\n\nexport function JazaBalanceWidget({ style }: JazaBalanceWidgetProps) {\n const { theme, balance, balanceLoading, balanceError, refreshBalance } =\n useJaza();\n const { colors, spacing, radius } = theme;\n\n useEffect(() => {\n void refreshBalance();\n }, [refreshBalance]);\n\n const styles = StyleSheet.create({\n card: {\n backgroundColor: colors.surfaceContainer,\n borderRadius: radius.xl,\n padding: spacing.md,\n ...style,\n },\n label: {\n color: colors.onSurfaceVariant,\n fontSize: 14,\n marginBottom: spacing.xs,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: spacing.sm,\n },\n value: {\n color: colors.onSurface,\n fontSize: 48,\n fontWeight: '700',\n letterSpacing: -1,\n },\n error: {\n color: colors.error,\n fontSize: 14,\n marginTop: spacing.xs,\n },\n });\n\n return (\n <View style={styles.card}>\n <Text style={styles.label}>Current Balance</Text>\n <View style={styles.row}>\n <Icon name=\"bolt\" size={28} color={colors.primary} />\n {balanceLoading && balance === null ? (\n <ActivityIndicator color={colors.primary} />\n ) : (\n <Text style={styles.value}>\n {balance !== null ? formatCredits(balance) : '—'}\n </Text>\n )}\n </View>\n {balanceError ? (\n <Text style={styles.error}>{balanceError}</Text>\n ) : null}\n </View>\n );\n}\n","import { useState } from 'react';\nimport {\n ActivityIndicator,\n Pressable,\n StyleSheet,\n Text,\n type ViewStyle,\n} from 'react-native';\nimport { Icon } from '../components/Icon.js';\nimport { useJaza } from '../provider/JazaContext.js';\n\nexport type JazaTopUpButtonProps = {\n onRequestToken: () => Promise<string>;\n label?: string;\n style?: ViewStyle;\n};\n\nexport function JazaTopUpButton({\n onRequestToken,\n label = 'Top up credits',\n style,\n}: JazaTopUpButtonProps) {\n const { theme, openTopUp } = useJaza();\n const { colors, spacing, radius } = theme;\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const styles = StyleSheet.create({\n button: {\n backgroundColor: colors.primaryContainer,\n borderRadius: radius.full,\n paddingVertical: spacing.md,\n paddingHorizontal: spacing.lg,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: spacing.sm,\n ...style,\n },\n pressed: { opacity: 0.9, transform: [{ scale: 0.98 }] },\n label: {\n color: colors.onPrimaryContainer,\n fontSize: 16,\n fontWeight: '600',\n },\n error: {\n color: colors.error,\n fontSize: 12,\n marginTop: spacing.xs,\n textAlign: 'center',\n },\n });\n\n const handlePress = async () => {\n setError(null);\n setLoading(true);\n try {\n const token = await onRequestToken();\n if (!token?.trim()) {\n throw new Error('Top-up token was empty');\n }\n await openTopUp(token.trim());\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Could not start top-up');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <>\n <Pressable\n style={({ pressed }) => [styles.button, pressed && styles.pressed]}\n onPress={() => void handlePress()}\n disabled={loading}\n >\n {loading ? (\n <ActivityIndicator color={colors.onPrimaryContainer} />\n ) : (\n <>\n <Text style={styles.label}>{label}</Text>\n <Icon name=\"arrow-forward\" size={20} color={colors.onPrimaryContainer} />\n </>\n )}\n </Pressable>\n {error ? <Text style={styles.error}>{error}</Text> : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAOO;AACP,IAAAC,wBAA2B;;;ACFpB,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA,EAKtC,YAAY,YAAoB,SAAiB,KAAe;AAC9D,UAAM,OAAO;AALf,wBAAS;AACT,wBAAS;AACT,wBAAS;AAIP,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,OAAO,QAAQ,UAAU;AAC9B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,OAAO,aAAa,QAAgB,MAA6B;AAC/D,QAAI,UAAU,mBAAmB,MAAM;AACvC,QAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,YAAM,IAAK,KAA0B;AACrC,UAAI,OAAO,MAAM,UAAU;AACzB,kBAAU;AAAA,MACZ,WAAW,OAAO,MAAM,YAAY,GAAG,SAAS;AAC9C,kBAAU,EAAE;AAAA,MACd;AAAA,IACF;AACA,WAAO,IAAI,cAAa,QAAQ,SAAS,IAAI;AAAA,EAC/C;AACF;;;AC/BO,IAAM,UAAU;AAChB,IAAM,uBAAuB;;;ACc7B,IAAM,eAAN,MAAmB;AAAA,EAKxB,YAAY,QAA4B;AAJxC,wBAAiB;AACjB,wBAAiB;AACjB,wBAAQ,cAA4B;AAGlC,SAAK,cAAc,OAAO,cAAc,sBAAsB;AAAA,MAC5D;AAAA,MACA;AAAA,IACF;AACA,SAAK,iBAAiB,OAAO;AAAA,EAC/B;AAAA,EAEA,cAAc,OAAsB;AAClC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,gBAA2C;AAC/C,WAAO,KAAK,QAA0B,OAAO,uBAAuB;AAAA,EACtE;AAAA,EAEA,MAAM,cAAiC;AACrC,WAAO,KAAK,cAAwB,OAAO,oBAAoB;AAAA,EACjE;AAAA,EAEA,MAAM,gBAAgB,aAAuD;AAC3E,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA,EAAE,YAAY;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,MAIe;AAChC,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,MAMO;AACzB,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,kBAAkD;AACjE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,gCAAgC,gBAAgB;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,QACA,MACA,MACY;AACZ,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,aAAa,KAAK,iCAAiC;AAAA,IAC/D;AACA,WAAO,KAAK,QAAW,QAAQ,MAAM,MAAM,KAAK,UAAU;AAAA,EAC5D;AAAA,EAEA,MAAc,QACZ,QACA,MACA,MACA,OACY;AACZ,UAAM,UAAkC;AAAA,MACtC,QAAQ;AAAA,MACR,cAAc,yBAAyB,OAAO;AAAA,IAChD;AACA,QAAI,OAAO;AACT,cAAQ,gBAAgB,UAAU,KAAK;AACvC,cAAQ,mBAAmB,IAAI,KAAK;AAAA,IACtC;AACA,QAAI,SAAS,QAAW;AACtB,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,UAAU,GAAG,IAAI,IAAI;AAAA,MACxD;AAAA,MACA;AAAA,MACA,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,IAC5D,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,SAAkB;AACtB,QAAI,MAAM;AACR,UAAI;AACF,iBAAS,KAAK,MAAM,IAAI;AAAA,MAC1B,QAAQ;AACN,iBAAS,EAAE,SAAS,KAAK;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,aAAa,aAAa,SAAS,QAAQ,MAAM;AAAA,IACzD;AAEA,WAAO;AAAA,EACT;AACF;;;ACnIO,IAAM,aAAqC;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,WAAW,MAAsB;AAC/C,QAAM,OAAO,KAAK,YAAY;AAC9B,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,SAAS,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,MAAM,SAAU,KAAK,EAAE,WAAW,CAAC,CAAC;AAClE,SAAO,OAAO,cAAc,GAAG,MAAM;AACvC;AAEO,SAAS,YAAY,MAAkC;AAC5D,SAAO,WAAW,KAAK,YAAY,CAAC;AACtC;;;ACnBO,SAAS,gBACd,WACmB;AACnB,SAAO,UACJ,OAAO,CAAC,MAAM,EAAE,YAAY,YAAY,EAAE,IAAI,CAAC,EAC/C,IAAI,CAAC,MAAM;AACV,UAAM,WAAW,YAAY,EAAE,IAAI;AACnC,UAAM,aACJ,EAAE,YACE,IAAI,CAAC,OAAO,GAAG,QAAQ,EACxB,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAC7B,IAAI,CAAC,SAAS;AAAA,MACb,MAAM,IAAK;AAAA,MACX,UAAU,IAAK;AAAA,MACf,MAAM,IAAK;AAAA,IACb,EAAE,KAAK,CAAC;AACZ,WAAO;AAAA,MACL,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR;AAAA,MACA,MAAM,WAAW,EAAE,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC,EACrC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAChD;AAEO,SAAS,UAAU,UAAkB,gBAAgC;AAC1E,QAAM,SAAS,eAAe,QAAQ,OAAO,EAAE;AAC/C,QAAM,OAAO,SAAS,QAAQ,OAAO,EAAE;AACvC,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO,GAAG,IAAI,GAAG,MAAM;AACzB;AAGO,SAAS,wBAAwB,OAAyB;AAC/D,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACA,QAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK;AACzD,UAAQ,SAAS,MAAM,CAAC,GAAI,YAAY;AAC1C;AAEO,SAAS,kBACd,QAC4D;AAC5D,SACE,WAAW,eACX,WAAW,YACX,WAAW,aACX,WAAW;AAEf;AAEO,SAAS,cAAc,GAAmB;AAC/C,SAAO,EAAE,eAAe,OAAO;AACjC;AAEO,SAAS,UAAU,UAA0B;AAClD,QAAM,IAAI,OAAO,QAAQ;AACzB,MAAI,OAAO,MAAM,CAAC,EAAG,QAAO;AAC5B,SAAO,qBAAqB,GAAG,OAAO,CAAC;AACzC;AAGO,SAAS,8BAA8B,cAA8B;AAC1E,SAAO,aAAa,YAAY,MAAM,QAAQ,IAAI;AACpD;AAEO,SAAS,qBACd,QACA,cACA,WACQ;AACR,QAAM,IAAI,OAAO,WAAW,WAAW,OAAO,MAAM,IAAI;AACxD,QAAM,OAAO,aAAa,YAAY;AACtC,MAAI,OAAO,MAAM,CAAC,EAAG,QAAO,GAAG,MAAM,IAAI,IAAI;AAE7C,QAAM,iBAAiB,8BAA8B,IAAI;AAEzD,MAAI;AACF,WAAO,IAAI,KAAK,aAAa,SAAS;AAAA,MACpC,OAAO;AAAA,MACP,UAAU;AAAA,MACV,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC,EAAE,OAAO,CAAC;AAAA,EACb,QAAQ;AACN,UAAM,UAAU,EAAE,eAAe,SAAS;AAAA,MACxC,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC;AACD,WAAO,GAAG,OAAO,IAAI,IAAI;AAAA,EAC3B;AACF;AAGO,SAAS,kBACd,QACA,cACA,UACQ;AACR,SAAO,qBAAqB,QAAQ,cAAc,QAAQ;AAC5D;;;AC5EA,IAAM,UAAU,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,QAAQ,GAAG;AACnE,IAAM,SAAS,EAAE,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK;AAE5C,IAAM,YAAuB;AAAA,EAClC,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,IACN,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,yBAAyB;AAAA,IACzB,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,cAAc;AAAA,IACd,sBAAsB;AAAA,IACtB,UAAU;AAAA,EACZ;AACF;AAGO,IAAM,aAAwB;AAAA,EACnC,GAAG;AAAA,EACH,MAAM;AACR;AAIO,SAAS,aACd,YACA,cACW;AACX,MAAI,eAAe,UAAU;AAC3B,WAAO,iBAAiB,SAAS,YAAY;AAAA,EAC/C;AACA,SAAO,eAAe,SAAS,YAAY;AAC7C;;;AC/FA,mBAA0C;AA2DnC,IAAM,kBAAc,4BAAuC,IAAI;AAE/D,SAAS,UAA4B;AAC1C,QAAM,UAAM,yBAAW,WAAW;AAClC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,SAAO;AACT;;;ACnEA,IAAAC,gBAA6C;AAC7C,IAAAC,uBAAwC;AACxC,0CAAuC;AACvC,IAAAC,uBAIO;AACP,IAAAC,yCAAkC;;;ACRlC,0BAMO;;;ACNP,2BAA0B;AAUjB;AADF,SAAS,KAAK,EAAE,MAAM,OAAO,IAAI,MAAM,GAAc;AAC1D,SAAO,4CAAC,qBAAAC,SAAA,EAAc,MAAY,MAAY,OAAc;AAC9D;;;ADkHU,IAAAC,sBAAA;AAjHH,SAAS,YAAY;AAC1B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,QAAQ;AACZ,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AAEpC,QAAM,SAAS,+BAAW,OAAO;AAAA,IAC/B,aAAa;AAAA,MACX,iBAAiB,OAAO;AAAA,MACxB,cAAcA,QAAO;AAAA,MACrB,SAASD,SAAQ;AAAA,MACjB,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,YAAY;AAAA,MACV,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,QAAQ;AAAA,MACN,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,SAASA,SAAQ;AAAA,MACjB,cAAcC,QAAO;AAAA,MACrB,iBAAiB,OAAO;AAAA,MACxB,aAAa;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,cAAcD,SAAQ;AAAA,IACxB;AAAA,IACA,gBAAgB;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,aAAa;AAAA,IACf;AAAA,IACA,aAAa;AAAA,MACX,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO,OAAO;AAAA,IAChB;AAAA,IACA,WAAW;AAAA,MACT,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,eAAe;AAAA,MACb,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,aAAa;AAAA,MACX,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,KAAK;AAAA,MACH,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,iBAAiBD,SAAQ;AAAA,MACzB,WAAWA,SAAQ;AAAA,MACnB,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,SAAS;AAAA,MACP,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,SAAS,EAAE,SAASA,SAAQ,IAAI,YAAY,SAAS;AAAA,IACrD,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,cAAcA,SAAQ;AAAA,MACtB,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AAED,QAAM,eAAe,CAAC,WAAmB;AACvC,UAAM,WAAW,gBAAgB,OAAO,OAAO;AAC/C,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO,CAAC,OAAO,QAAQ,YAAY,OAAO,cAAc;AAAA,QACxD,SAAS,MAAM,kBAAkB,MAAM;AAAA,QAEvC;AAAA,wDAAC,4BACC;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,CAAC,OAAO,aAAa,YAAY,OAAO,mBAAmB;AAAA,gBAEjE,iBAAO,SAAS;AAAA;AAAA,YACnB;AAAA,YACA,8CAAC,4BAAK,OAAO,OAAO,WACjB;AAAA,4BAAc,OAAO,OAAO;AAAA,cAAE;AAAA,eACjC;AAAA,aACF;AAAA,UACA,8CAAC,4BAAK,OAAO,EAAE,YAAY,WAAW,GACpC;AAAA,yDAAC,4BAAK,OAAO,OAAO,eACjB,wBAAc,OAAO,OAAO,GAC/B;AAAA,YACA,8CAAC,4BAAK,OAAO,OAAO,aAAc;AAAA,wBAAU,OAAO,QAAQ;AAAA,cAAE;AAAA,eAAI;AAAA,aACnE;AAAA;AAAA;AAAA,MAnBK,OAAO;AAAA,IAoBd;AAAA,EAEJ;AAEA,SACE,8CAAC,4BACC;AAAA,kDAAC,4BAAK,OAAO,OAAO,aAClB;AAAA,mDAAC,4BAAK,OAAO,OAAO,cAAc,6BAAe;AAAA,MACjD,8CAAC,4BAAK,OAAO,OAAO,YAClB;AAAA,qDAAC,QAAK,MAAK,QAAO,MAAM,IAAI,OAAO,OAAO,SAAS;AAAA,QAClD,kBAAkB,YAAY,OAC7B,6CAAC,yCAAkB,OAAO,OAAO,SAAS,IAE1C,6CAAC,4BAAK,OAAO,OAAO,cACjB,sBAAY,OAAO,cAAc,OAAO,IAAI,UAC/C;AAAA,SAEJ;AAAA,OACF;AAAA,IAEA,6CAAC,4BAAK,OAAO,OAAO,OAAO,4BAAc;AAAA,IAExC,eAAe,6CAAC,4BAAK,OAAO,OAAO,OAAQ,wBAAa,IAAU;AAAA,IAElE,iBACC,6CAAC,4BAAK,OAAO,OAAO,SAClB,uDAAC,yCAAkB,OAAO,OAAO,SAAS,GAC5C,IAEA,QAAQ,IAAI,YAAY;AAAA,IAGzB,CAAC,kBAAkB,CAAC,gBAAgB,QAAQ,WAAW,IACtD,6CAAC,4BAAK,OAAO,OAAO,OAAO,6CAA+B,IACxD;AAAA,IAEJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,SAAS;AAAA,QACT,UAAU,CAAC;AAAA,QAEX;AAAA,wDAAC,4BAAK,OAAO,OAAO,SAAS;AAAA;AAAA,YACZ,gBAAgB,SAAS;AAAA,aAC1C;AAAA,UACA,6CAAC,QAAK,MAAK,iBAAgB,MAAM,IAAI,OAAO,OAAO,oBAAoB;AAAA;AAAA;AAAA,IACzE;AAAA,KACF;AAEJ;;;AE5LA,IAAAE,gBAAkC;AAClC,IAAAC,uBAMO;;;ACNP,IAAAC,gBAAiC;AACjC,IAAAC,uBAAkD;AAClD,0BAAqC;AA8E/B,IAAAC,sBAAA;AA3EN,IAAM,aAAa;AAUZ,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,EAAE,QAAQ,SAAAC,SAAQ,IAAI;AAC5B,QAAM,eAAW,sBAAqC,IAAI;AAC1D,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,KAAK;AAE5C,QAAM,SAAS,MAAM,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,UAAU;AAE3D,QAAM,cACJ,OAAO,UAAU,aAAa,aAAa,IAAI,OAAO;AAExD,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,eAAe;AAAA,MACf,cAAcA,SAAQ;AAAA,MACtB,eAAe;AAAA,IACjB;AAAA,IACA,KAAK;AAAA,MACH,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,WAAW;AAAA,IACb;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,IAClB;AAAA,IACA,UAAU;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,aAAa,CAAC,cAAc;AAAA,IAC9B;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,OAAO;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,aAAa,MAAM;AACvB,aAAS,SAAS,MAAM;AAAA,EAC1B;AAEA,SACE,8CAAC,6BACC;AAAA,iDAAC,6BAAK,OAAO,OAAO,OAAO,0BAAY;AAAA,IACvC,8CAAC,kCAAU,OAAO,OAAO,KAAK,SAAS,YACpC;AAAA;AAAA,MACD,6CAAC,6BAAK,OAAO,OAAO,OAAO,eAAc,QACtC,gBAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,CAAC,GAAG,MAAM;AAC5C,cAAM,OAAO,OAAO,CAAC;AACrB,cAAM,YAAY,WAAW,MAAM;AACnC,eACE,6CAAC,6BAAa,OAAO,OAAO,MAC1B;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO;AAAA,cACP,YAAY,OAAO,kBAAkB;AAAA,YACvC;AAAA,YAEC,kBAAQ;AAAA;AAAA,QACX,KARS,CASX;AAAA,MAEJ,CAAC,GACH;AAAA,MACC;AAAA,MACD;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAO,OAAO;AAAA,UACd,OAAO;AAAA,UACP,cAAc,CAAC,SACb,aAAa,KAAK,QAAQ,OAAO,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC;AAAA,UAE3D,SAAS,MAAM,WAAW,IAAI;AAAA,UAC9B,QAAQ,MAAM,WAAW,KAAK;AAAA,UAC9B,cAAa;AAAA,UACb,cAAa;AAAA,UACb,iBAAgB;AAAA,UAChB,WAAW;AAAA,UACX,aAAW;AAAA;AAAA,MACb;AAAA,OACF;AAAA,KACF;AAEJ;;;ACzHA,IAAAC,gBAA6C;AAC7C,IAAAC,uBAUO;AACP,4CAAkC;;;ACZlC,IAAAC,uBAA2B;AAIpB,SAAS,0BAA0B,OAAkB;AAC1D,QAAM,EAAE,QAAQ,SAAAC,SAAQ,IAAI;AAC5B,SAAO,gCAAW,OAAO;AAAA,IACvB,KAAK;AAAA,MACH,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,iBAAiBA,SAAQ;AAAA,MACzB,mBAAmB,gCAAW;AAAA,MAC9B,mBAAmB,OAAO;AAAA,MAC1B,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,aAAa;AAAA,MACX,mBAAmB,OAAO;AAAA,IAC5B;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,IACA,eAAe;AAAA,MACb,OAAO,OAAO;AAAA,MACd,YAAY;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACR,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;;;ADsFQ,IAAAC,sBAAA;AAnGD,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,EAAE,OAAO,WAAW,iBAAiB,mBAAmB,IAAI,QAAQ;AAC1E,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AACpC,QAAM,aAAS,yDAAkB;AACjC,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAS,EAAE;AACrC,QAAM,YAAY,0BAA0B,KAAK;AAEjD,+BAAU,MAAM;AACd,QAAI,CAAC,QAAS,UAAS,EAAE;AAAA,EAC3B,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,eAAW,uBAAQ,MAAM;AAC7B,UAAM,IAAI,MAAM,KAAK,EAAE,YAAY;AACnC,QAAI,CAAC,EAAG,QAAO;AACf,WAAO,UAAU;AAAA,MACf,CAAC,MACC,EAAE,KAAK,YAAY,EAAE,SAAS,CAAC,KAC/B,EAAE,KAAK,YAAY,EAAE,SAAS,CAAC,KAC/B,EAAE,SAAS,SAAS,CAAC;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,iBAAiB,OAAO;AAAA,IAC1B;AAAA,IACA,OAAO;AAAA,MACL,iBAAiB,OAAO;AAAA,MACxB,qBAAqBA,QAAO;AAAA,MAC5B,sBAAsBA,QAAO;AAAA,MAC7B,mBAAmBD,SAAQ;AAAA,MAC3B,YAAYA,SAAQ;AAAA,MACpB,eAAe,KAAK,IAAI,OAAO,QAAQA,SAAQ,EAAE;AAAA,MACjD,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,IACA,QAAQ;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,OAAO;AAAA,MACxB,WAAW;AAAA,MACX,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,QAAQ;AAAA,MACN,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,mBAAmBD,SAAQ;AAAA,MAC3B,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKA,SAAQ;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAYA,SAAQ;AAAA,IACtB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,WAAW;AAAA,MACX,iBAAiBA,SAAQ;AAAA,IAC3B;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAW;AAAA,MACX,eAAc;AAAA,MACd,gBAAgB;AAAA,MAEhB;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,OAAO;AAAA,UACd,UAAU,8BAAS,OAAO,QAAQ,YAAY;AAAA,UAE9C;AAAA,yDAAC,kCAAU,OAAO,gCAAW,cAAc,SAAS,SAAS;AAAA,YAC7D,8CAAC,6BAAK,OAAO,OAAO,OAClB;AAAA,2DAAC,6BAAK,OAAO,OAAO,QAAQ;AAAA,cAC5B;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,OAAO;AAAA,kBACd,aAAY;AAAA,kBACZ,sBAAsB,OAAO;AAAA,kBAC7B,OAAO;AAAA,kBACP,cAAc;AAAA,kBACd,aAAa;AAAA,kBACb,gBAAe;AAAA,kBACf,iBAAgB;AAAA,kBAChB,eAAc;AAAA;AAAA,cAChB;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,OAAO;AAAA,kBACd,MAAM;AAAA,kBACN,cAAc,CAAC,SAAS,KAAK;AAAA,kBAC7B,2BAA0B;AAAA,kBAC1B,qBAAoB;AAAA,kBACpB,YAAY,CAAC,EAAE,KAAK,MAAM;AACxB,0BAAM,WAAW,iBAAiB,OAAO,KAAK;AAC9C,2BACE;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO,CAAC,UAAU,KAAK,YAAY,UAAU,WAAW;AAAA,wBACxD,SAAS,MAAM;AACb,6CAAmB,IAAI;AACvB,kCAAQ;AAAA,wBACV;AAAA,wBAEA;AAAA,wEAAC,6BAAK,OAAO,OAAO,SAClB;AAAA,yEAAC,6BAAK,OAAO,OAAO,MAAO,eAAK,MAAK;AAAA,4BACrC;AAAA,8BAAC;AAAA;AAAA,gCACC,OAAO;AAAA,kCACL,UAAU;AAAA,kCACV,YAAY,UAAU;AAAA,gCACxB;AAAA,gCACA,eAAe;AAAA,gCACf,eAAc;AAAA,gCAEb,eAAK;AAAA;AAAA,4BACR;AAAA,6BACF;AAAA,0BACA,8CAAC,6BAAK,OAAO,OAAO,MAAM;AAAA;AAAA,4BAAE,KAAK;AAAA,6BAAS;AAAA;AAAA;AAAA,oBAC5C;AAAA,kBAEJ;AAAA,kBACA,oBACE,6CAAC,6BAAK,OAAO,OAAO,OAAO,gCAAkB;AAAA;AAAA,cAEjD;AAAA,eACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;;;AE/KA,IAAAE,uBAOO;AACP,IAAAC,yCAAkC;AAoE1B,IAAAC,sBAAA;AAnDD,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,EAAE,MAAM,IAAI,QAAQ;AAC1B,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AACpC,QAAM,aAAS,0DAAkB;AACjC,QAAM,YAAY,0BAA0B,KAAK;AAEjD,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,UAAU;AAAA,MACR,MAAM;AAAA,MACN,iBAAiB,OAAO;AAAA,MACxB,gBAAgB;AAAA,IAClB;AAAA,IACA,OAAO;AAAA,MACL,iBAAiB,OAAO;AAAA,MACxB,qBAAqBA,QAAO;AAAA,MAC5B,sBAAsBA,QAAO;AAAA,MAC7B,WAAW;AAAA,MACX,mBAAmBD,SAAQ;AAAA,MAC3B,YAAYA,SAAQ;AAAA,MACpB,eAAe,OAAO,SAASA,SAAQ;AAAA,IACzC;AAAA,IACA,QAAQ;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,OAAO;AAAA,MACxB,WAAW;AAAA,MACX,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAcA,SAAQ;AAAA,IACxB;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAW;AAAA,MACX,eAAc;AAAA,MACd,gBAAgB;AAAA,MAEhB,uDAAC,kCAAU,OAAO,OAAO,UAAU,SAAS,SAC1C,wDAAC,kCAAU,OAAO,OAAO,OAAO,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAChE;AAAA,qDAAC,6BAAK,OAAO,OAAO,QAAQ;AAAA,QAC5B,6CAAC,6BAAK,OAAO,OAAO,OAAO,6BAAe;AAAA,QAC1C;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,cAAc,CAAC,SAAS,KAAK;AAAA,YAC7B,2BAA0B;AAAA,YAC1B,YAAY,CAAC,EAAE,KAAK,MAAM;AACxB,oBAAM,WAAW,iBAAiB,KAAK;AACvC,qBACE;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,CAAC,UAAU,KAAK,YAAY,UAAU,WAAW;AAAA,kBACxD,SAAS,MAAM,SAAS,KAAK,IAAI;AAAA,kBAEjC;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO,CAAC,UAAU,OAAO,YAAY,UAAU,aAAa;AAAA,sBAE3D,eAAK;AAAA;AAAA,kBACR;AAAA;AAAA,cACF;AAAA,YAEJ;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA;AAAA,EACF;AAEJ;;;AJgFQ,IAAAE,sBAAA;AAxKD,SAAS,cAAc;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,QAAQ;AAEZ,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AACpC,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAS,KAAK;AAChE,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,wBAAS,KAAK;AAElE,QAAM,sBAAkB,uBAAQ,MAAM;AACpC,QAAI,SAAS,YAAY,QAAQ;AAC/B,aAAO,QAAQ;AAAA,IACjB;AACA,WAAO,iBAAiB,cAAc,CAAC;AAAA,EACzC,GAAG,CAAC,SAAS,eAAe,CAAC;AAE7B,QAAM,qBAAqB,gBAAgB,SAAS;AAEpD,QAAM,iBAAiB,QACnB,qBAAqB,MAAM,YAAY,MAAM,YAAY,IACzD;AAEJ,QAAM,WAAW,QACb,OAAO,cAAc,KACrB,eACE,kBACA,iBACE,OAAO,UAAU,eAAe,QAAQ,CAAC,KACzC;AAER,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,QAAQ;AAAA,MACN,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAcD,SAAQ;AAAA,IACxB;AAAA,IACA,YAAY;AAAA,MACV,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKA,SAAQ;AAAA,MACb,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAcC,QAAO;AAAA,MACrB,iBAAiB,OAAO;AAAA,MACxB,YAAY;AAAA,MACZ,gBAAgB;AAAA,IAClB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,IACA,aAAa;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKD,SAAQ;AAAA,MACb,iBAAiB,OAAO;AAAA,MACxB,mBAAmBA,SAAQ;AAAA,MAC3B,iBAAiBA,SAAQ;AAAA,MACzB,cAAcC,QAAO;AAAA,IACvB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKD,SAAQ;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAWA,SAAQ;AAAA,IACrB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,WAAWA,SAAQ;AAAA,IACrB;AAAA,IACA,SAAS;AAAA,MACP,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,aAAa;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,SAASD,SAAQ;AAAA,MACjB,WAAWA,SAAQ;AAAA,IACrB;AAAA,IACA,QAAQ;AAAA,MACN,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,aAAa;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,YAAY;AAAA,MACV,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,KAAK;AAAA,MACH,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,iBAAiBD,SAAQ;AAAA,MACzB,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,aAAa,EAAE,SAAS,IAAI;AAAA,IAC5B,SAAS;AAAA,MACP,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,YAAY;AAAA,MACV,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,cAAcA,SAAQ;AAAA,IACxB;AAAA,EACF,CAAC;AAED,QAAM,YACJ,CAAC,CAAC,WACF,CAAC,CAAC,SACF,CAAC,gBACD,CAAC,kBACD,cAAc,QAAQ,OAAO,EAAE,EAAE,UAAU;AAE7C,SACE,8CAAC,6BACC;AAAA,kDAAC,6BAAK,OAAO,OAAO,QAClB;AAAA,oDAAC,6BAAK,OAAO,OAAO,YAClB;AAAA,qDAAC,kCAAU,OAAO,OAAO,SAAS,SAAS,WACzC,uDAAC,QAAK,MAAK,cAAa,MAAM,IAAI,OAAO,OAAO,kBAAkB,GACpE;AAAA,QACA,6CAAC,6BAAK,OAAO,OAAO,aAAa,eAAe,GAC7C,0BAAgB,SAAS,kBAC5B;AAAA,SACF;AAAA,MACC,YAAY,OACX,8CAAC,6BAAK,OAAO,OAAO,aAClB;AAAA,qDAAC,QAAK,MAAK,QAAO,MAAM,IAAI,OAAO,OAAO,SAAS;AAAA,QACnD,6CAAC,6BAAK,OAAO,OAAO,iBAAkB,kBAAQ,eAAe,GAAE;AAAA,SACjE,IACE;AAAA,OACN;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,QACP,cAAc;AAAA,QACd,eACE;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO;AAAA,YACd,SAAS,MAAM,qBAAqB,IAAI;AAAA,YAExC;AAAA,4DAAC,6BAAK,OAAO,OAAO,UAAU;AAAA;AAAA,gBAC1B,iBAAiB,YAAY;AAAA,iBACjC;AAAA,cACA,6CAAC,QAAK,MAAK,eAAc,MAAM,IAAI,OAAO,OAAO,kBAAkB;AAAA;AAAA;AAAA,QACrE;AAAA,QAEF,UACE,WAAW,CAAC,iBACV,6CAAC,QAAK,MAAK,gBAAe,MAAM,IAAI,OAAO,OAAO,SAAS,IACzD,iBACF,6CAAC,0CAAkB,OAAO,OAAO,SAAS,MAAK,SAAQ,IACrD;AAAA;AAAA,IAER;AAAA,IAEC,UACC,6CAAC,6BAAK,OAAO,OAAO,cAAe,kBAAQ,SAAS,aAAY,IAC9D,eACF,6CAAC,6BAAK,OAAO,OAAO,eAAgB,wBAAa,IAC/C;AAAA,IAEJ,8CAAC,6BAAK,OAAO,OAAO,SAClB;AAAA,oDAAC,6BAAK,OAAO,OAAO,QACjB;AAAA,6BACC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO;AAAA,YACd,SAAS,MAAM,sBAAsB,IAAI;AAAA,YAEzC;AAAA,2DAAC,6BAAK,OAAO,OAAO,cACjB,kCAAwB,UAC3B;AAAA,cACA,6CAAC,QAAK,MAAK,eAAc,MAAM,IAAI,OAAO,OAAO,kBAAkB;AAAA;AAAA;AAAA,QACrE,IAEA,6CAAC,6BAAK,OAAO,OAAO,cACjB,kCAAwB,OAAO,gBAAgB,OAClD;AAAA,QAEF,6CAAC,6BAAK,OAAO,OAAO,YACjB,6BACE,iBAAiB,UAAU,eAAe,QAAQ,IAAI,WAC3D;AAAA,SACF;AAAA,MACC,aAAa,6CAAC,6BAAK,OAAO,OAAO,YAAa,sBAAW,IAAU;AAAA,MACpE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,CAAC,OAAO,KAAK,CAAC,aAAa,OAAO,WAAW;AAAA,UACpD,SAAS,MAAM,KAAK,cAAc;AAAA,UAClC,UAAU,CAAC;AAAA,UAEX;AAAA,yDAAC,QAAK,MAAK,QAAO,MAAM,IAAI,OAAO,OAAO,oBAAoB;AAAA,YAC9D,6CAAC,6BAAK,OAAO,OAAO,SAAU,oBAAS;AAAA;AAAA;AAAA,MACzC;AAAA,OACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,SAAS,MAAM,qBAAqB,KAAK;AAAA;AAAA,IAC3C;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU,CAAC,SAAS;AAClB,kCAAwB,IAAI;AAC5B,gCAAsB,KAAK;AAAA,QAC7B;AAAA,QACA,SAAS,MAAM,sBAAsB,KAAK;AAAA;AAAA,IAC5C;AAAA,KACF;AAEJ;;;AKtRA,IAAAE,gBAAkC;AAClC,IAAAC,uBAMO;;;ACPP,IAAAC,gBAAkC;AAClC,IAAAC,uBAAmD;AA+D/C,IAAAC,sBAAA;AAnDG,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,OAAO;AACT,GAA2B;AACzB,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAO,sBAAO,IAAI,8BAAS,MAAM,CAAC,CAAC,EAAE;AAE3C,+BAAU,MAAM;AACd,UAAM,OAAO,8BAAS;AAAA,MACpB,8BAAS,OAAO,MAAM;AAAA,QACpB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,4BAAO;AAAA,QACf,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AACA,SAAK,MAAM;AACX,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,SAAS,KAAK,YAAY;AAAA,IAC9B,YAAY,CAAC,GAAG,CAAC;AAAA,IACjB,aAAa,CAAC,QAAQ,QAAQ;AAAA,EAChC,CAAC;AAED,QAAM,OAAO;AACb,QAAM,SAAS;AACf,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc,OAAO;AAAA,MACrB,aAAa;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,MACJ,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;AAED,SACE,8CAAC,6BAAK,OAAO,OAAO,MAClB;AAAA,iDAAC,8BAAS,MAAT,EAAc,OAAO,CAAC,OAAO,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG;AAAA,IAClE,6CAAC,6BAAK,OAAO,OAAO,MAClB,uDAAC,QAAK,MAAK,QAAO,MAAM,KAAK,MAAM,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,GAC1E;AAAA,KACF;AAEJ;;;ADqCM,IAAAC,sBAAA;AA/FC,SAAS,aAAa;AAC3B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,QAAQ;AACZ,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AACpC,QAAM,YAAQ,sBAAO,IAAI,8BAAS,MAAM,CAAC,CAAC,EAAE;AAE5C,+BAAU,MAAM;AACd,QAAI,gBAAgB,WAAW;AAC7B,YAAM,SAAS,CAAC;AAChB,oCAAS,OAAO,OAAO;AAAA,QACrB,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,UAAU;AAAA,MACZ,CAAC,EAAE,MAAM;AAAA,IACX;AAAA,EACF,GAAG,CAAC,aAAa,KAAK,CAAC;AAEvB,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,WAAW;AAAA,MACT,YAAY;AAAA,MACZ,iBAAiBD,SAAQ;AAAA,IAC3B;AAAA,IACA,aAAa;AAAA,MACX,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,IACA,YAAY;AAAA,MACV,SAAS;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,WAAWA,SAAQ;AAAA,MACnB,WAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAcC,QAAO;AAAA,MACrB,iBAAiB,GAAG,OAAO,OAAO;AAAA,MAClC,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAcD,SAAQ;AAAA,IACxB;AAAA,IACA,UAAU;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAcC,QAAO;AAAA,MACrB,iBAAiB,GAAG,OAAO,KAAK;AAAA,MAChC,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,cAAcD,SAAQ;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,mBAAmBD,SAAQ;AAAA,MAC3B,iBAAiBA,SAAQ;AAAA,MACzB,WAAWA,SAAQ;AAAA,IACrB;AAAA,IACA,UAAU;AAAA,MACR,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,IACA,UAAU;AAAA,MACR,iBAAiB,OAAO;AAAA,MACxB,cAAcC,QAAO;AAAA,MACrB,mBAAmBD,SAAQ;AAAA,MAC3B,iBAAiBA,SAAQ;AAAA,MACzB,WAAWA,SAAQ;AAAA,IACrB;AAAA,IACA,WAAW;AAAA,MACT,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AAED,MAAI,gBAAgB,WAAW;AAC7B,WACE,8CAAC,6BAAK,OAAO,OAAO,WAClB;AAAA,mDAAC,6BAAK,OAAO,OAAO,aAClB,uDAAC,qBAAkB,OAAc,MAAM,IAAI,GAC7C;AAAA,MACA,6CAAC,6BAAK,OAAO,CAAC,OAAO,OAAO,OAAO,UAAU,GAAG,mCAEhD;AAAA,MACA,6CAAC,6BAAK,OAAO,OAAO,UAAU,6CAA+B;AAAA,OAC/D;AAAA,EAEJ;AAEA,MAAI,gBAAgB,WAAW;AAC7B,WACE,8CAAC,6BAAK,OAAO,OAAO,WAClB;AAAA,mDAAC,6BAAK,OAAO,OAAO,UAClB,uDAAC,QAAK,MAAK,iBAAgB,MAAM,IAAI,OAAO,OAAO,OAAO,GAC5D;AAAA,MACA,6CAAC,6BAAK,OAAO,OAAO,OAAO,4BAAc;AAAA,MACzC,6CAAC,6BAAK,OAAO,OAAO,UACjB,2BAAiB,gBAAgB,wBACpC;AAAA,MACA,6CAAC,kCAAU,OAAO,OAAO,UAAU,SAAS,cAC1C,uDAAC,6BAAK,OAAO,OAAO,WAAW,uBAAS,GAC1C;AAAA,MACA,6CAAC,kCAAU,OAAO,OAAO,SAAS,SAAS,YACzC,uDAAC,6BAAK,OAAO,OAAO,UAAU,qBAAO,GACvC;AAAA,OACF;AAAA,EAEJ;AAEA,QAAM,UAAU,SAAS,WAAW,gBAAgB,WAAW;AAE/D,SACE,8CAAC,6BAAK,OAAO,OAAO,WAClB;AAAA,iDAAC,8BAAS,MAAT,EAAc,OAAO,CAAC,OAAO,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,GACnE,uDAAC,QAAK,MAAK,gBAAe,MAAM,IAAI,OAAO,OAAO,SAAS,GAC7D;AAAA,IACA,6CAAC,6BAAK,OAAO,OAAO,OAAO,+BAAiB;AAAA,IAC5C,8CAAC,6BAAK,OAAO,OAAO,UACjB;AAAA,oBAAc,OAAO;AAAA,MAAE;AAAA,OAC1B;AAAA,IACA,6CAAC,kCAAU,OAAO,OAAO,SAAS,SAAS,YACzC,uDAAC,6BAAK,OAAO,OAAO,UAAU,kBAAI,GACpC;AAAA,KACF;AAEJ;;;ARjIM,IAAAE,sBAAA;AATC,SAAS,mBAAmB;AACjC,QAAM,EAAE,OAAO,WAAW,MAAM,WAAW,IAAI,QAAQ;AACvD,QAAM,EAAE,QAAQ,SAAAC,SAAQ,IAAI;AAC5B,QAAM,aAAS,0DAAkB;AACjC,QAAM,UAAM,sBAAoB,IAAI;AACpC,QAAM,iBAAa,uBAAQ,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;AAE5C,QAAM,qBAAiB;AAAA,IACrB,CAAC,UACC;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,mBAAmB;AAAA,QACnB,gBAAgB;AAAA,QAChB,SAAS;AAAA,QACT,eAAc;AAAA;AAAA,IAChB;AAAA,IAEF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,gCAAW,OAAO;AAAA,IAC/B,MAAM;AAAA,MACJ,MAAM;AAAA,IACR;AAAA,IACA,QAAQ;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,iBAAiB,OAAO;AAAA,MACxB,WAAW;AAAA,MACX,WAAWA,SAAQ;AAAA,MACnB,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,mBAAmBA,SAAQ;AAAA,MAC3B,eAAe,OAAO,SAASA,SAAQ;AAAA,IACzC;AAAA,EACF,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,aAAW;AAAA,MACX,eAAc;AAAA,MACd,sBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAGhB,uDAAC,8DAAuB,OAAO,OAAO,MACpC;AAAA,QAAC,qBAAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,OAAO;AAAA,UACP;AAAA,UACA,sBAAoB;AAAA,UACpB,SAAS;AAAA,UACT,mBAAmB;AAAA,UACnB,kBAAiB;AAAA,UACjB,sBAAqB;AAAA,UACrB,2BAA0B;AAAA,UAC1B,iBAAiB,EAAE,iBAAiB,OAAO,QAAQ;AAAA,UACnD,iBAAiB,MAAM,6CAAC,6BAAK,OAAO,OAAO,QAAQ;AAAA,UAEnD;AAAA,YAAC;AAAA;AAAA,cACC,2BAA0B;AAAA,cAC1B,uBAAuB,OAAO;AAAA,cAE7B;AAAA,yBAAS,UAAU,6CAAC,aAAU,IAAK;AAAA,gBACnC,SAAS,YAAY,6CAAC,eAAY,IAAK;AAAA,gBACvC,SAAS,eAAe,6CAAC,cAAW,IAAK;AAAA;AAAA;AAAA,UAC5C;AAAA;AAAA,MACF,GACF;AAAA;AAAA,EACF;AAEJ;;;AR4aI,IAAAC,uBAAA;AAxeJ,IAAM,sBAAsB;AAC5B,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AAWjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO,kBAAkB;AAAA,EACzB;AACF,GAAsB;AACpB,QAAM,aAAS;AAAA,IACb,MAAM,IAAI,aAAa,EAAE,gBAAgB,WAAW,CAAC;AAAA,IACrD,CAAC,gBAAgB,UAAU;AAAA,EAC7B;AAEA,QAAM,CAAC,cAAc,eAAe,QAAI;AAAA,IACtC,MAAM;AACJ,YAAM,SAAS,iCAAW,eAAe;AACzC,aAAO,WAAW,SAAS,SAAS;AAAA,IACtC;AAAA,EACF;AAEA,+BAAU,MAAM;AACd,UAAM,MAAM,iCAAW,kBAAkB,CAAC,EAAE,YAAY,MAAM;AAC5D,sBAAgB,gBAAgB,SAAS,SAAS,OAAO;AAAA,IAC3D,CAAC;AACD,WAAO,MAAM,IAAI,OAAO;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,YAAmB;AAAA,IACvB,MAAM,aAAa,iBAAiB,YAAY;AAAA,IAChD,CAAC,iBAAiB,YAAY;AAAA,EAChC;AAEA,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAwB,IAAI;AAC1D,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AAEpE,QAAM,qBAAiB,2BAAY,YAAY;AAC7C,sBAAkB,IAAI;AACtB,oBAAgB,IAAI;AACpB,QAAI;AACF,YAAMC,SAAQ,MAAM,WAAW;AAC/B,iBAAWA,MAAK;AAAA,IAClB,SAAS,KAAK;AACZ;AAAA,QACE,eAAe,QAAQ,IAAI,UAAU;AAAA,MACvC;AAAA,IACF,UAAE;AACA,wBAAkB,KAAK;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,+BAAU,MAAM;AACd,SAAK,eAAe;AAAA,EACtB,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAoB,OAAO;AACnD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAsB,SAAS;AACrE,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAwB,IAAI;AAEhE,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAmB,CAAC,CAAC;AACnD,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AACpE,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAwB,IAAI;AAExE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAA4B,CAAC,CAAC;AAChE,QAAM,CAAC,iBAAiB,uBAAuB,QAC7C,wBAAiC,IAAI;AACvC,QAAM,CAAC,sBAAsB,uBAAuB,QAAI,wBAEtD,IAAI;AAEN,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAS,EAAE;AACrD,QAAM,CAAC,SAAS,UAAU,QAAI;AAAA,IAC5B;AAAA,EACF;AACA,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AAEpE,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAsC,IAAI;AACpE,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAS,KAAK;AACtD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAwB,IAAI;AAEhE,QAAM,CAAC,SAAS,UAAU,QAAI,wBAA+B,IAAI;AACjE,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AACpE,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAwB,IAAI;AAEtE,QAAM,mBAAe,sBAA6C,IAAI;AACtE,QAAM,gBAAY,sBAA8C,IAAI;AACpE,QAAM,kBAAc,sBAAsB,IAAI;AAE9C,QAAM,gBAAY,2BAAY,MAAM;AAClC,QAAI,UAAU,SAAS;AACrB,oBAAc,UAAU,OAAO;AAC/B,gBAAU,UAAU;AAAA,IACtB;AACA,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,CAAC;AAEL,QAAM,wBAAoB,2BAAY,MAAM;AAC1C,eAAW,IAAI;AACf,oBAAgB,IAAI;AACpB,aAAS,IAAI;AACb,kBAAc,IAAI;AAClB,eAAW,IAAI;AACf,oBAAgB,IAAI;AACpB,qBAAiB,IAAI;AACrB,mBAAe,SAAS;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAqB,2BAAY,CAAC,YAAoC;AAC1E,4BAAwB,OAAO;AAC/B,qBAAiB,EAAE;AACnB,eAAW,IAAI;AACf,oBAAgB,IAAI;AACpB,QAAI,WAAW,QAAQ,WAAW,SAAS,GAAG;AAC5C,YAAM,QAAQ,QAAQ,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI;AAClD,8BAAwB,wBAAwB,KAAK,CAAC;AAAA,IACxD,OAAO;AACL,8BAAwB,IAAI;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,sBAAkB,2BAAY,YAAY;AAC9C,sBAAkB,IAAI;AACtB,oBAAgB,IAAI;AACpB,QAAI;AACF,YAAM,CAAC,YAAY,gBAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,QACvD,OAAO,YAAY;AAAA,QACnB,OAAO,cAAc;AAAA,MACvB,CAAC;AACD,YAAM,SAAS,WACZ,OAAO,CAAC,MAAM,EAAE,QAAQ,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC3C,iBAAW,MAAM;AACjB,UAAI,OAAO,SAAS,GAAG;AACrB,0BAAkB,OAAO,CAAC,CAAE;AAAA,MAC9B,OAAO;AACL,0BAAkB,IAAI;AAAA,MACxB;AACA,YAAM,WAAW,gBAAgB,gBAAgB;AACjD,mBAAa,QAAQ;AACrB,UAAI,SAAS,SAAS,GAAG;AACvB,gCAAwB,CAAC,SAAS;AAChC,cAAI,KAAM,QAAO;AACjB,iBAAO,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,SAAS,CAAC;AAAA,QAC5D,CAAC;AACD,gCAAwB,CAAC,SAAS;AAChC,cAAI,KAAM,QAAO;AACjB,gBAAM,UACJ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,SAAS,CAAC;AACrD,gBAAM,QAAQ,QAAQ,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI;AAClD,iBAAO,wBAAwB,KAAK;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,iBAAW,CAAC,CAAC;AACb,wBAAkB,IAAI;AACtB;AAAA,QACE,eAAe,QAAQ,IAAI,UAAU;AAAA,MACvC;AAAA,IACF,UAAE;AACA,wBAAkB,KAAK;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,gBAAY;AAAA,IAChB,OAAO,UAAkB;AACvB,aAAO,cAAc,KAAK;AAC1B,oBAAc,KAAK;AACnB,cAAQ,OAAO;AACf,wBAAkB;AAClB,8BAAwB,IAAI;AAC5B,8BAAwB,IAAI;AAC5B,uBAAiB,EAAE;AACnB,sBAAgB,IAAI;AAEpB,mBAAa,IAAI;AACjB,WAAK,gBAAgB;AACrB,WAAK,eAAe;AAAA,IACtB;AAAA,IACA,CAAC,QAAQ,iBAAiB,gBAAgB,iBAAiB;AAAA,EAC7D;AAEA,QAAM,iBAAa,2BAAY,MAAM;AACnC,cAAU;AACV,iBAAa,KAAK;AAClB,WAAO,cAAc,IAAI;AACzB,kBAAc,IAAI;AAClB,YAAQ,OAAO;AACf,sBAAkB;AAAA,EACpB,GAAG,CAAC,WAAW,QAAQ,iBAAiB,CAAC;AAEzC,QAAM,gBAAY,2BAAY,MAAM;AAClC,cAAU;AACV,YAAQ,OAAO;AACf,sBAAkB;AAAA,EACpB,GAAG,CAAC,WAAW,iBAAiB,CAAC;AAEjC,QAAM,kBAAc,2BAAY,MAAM;AACpC,YAAQ,SAAS;AACjB,sBAAkB;AAAA,EACpB,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,gBAAY;AAAA,IAChB,CAAC,WAAmB,YAAoB;AACtC,gBAAU;AACV,kBAAY,UAAU,KAAK,IAAI;AAC/B,gBAAU,UAAU,YAAY,MAAM;AACpC,cAAM,YAAY;AAChB,cACE,YAAY,WACZ,KAAK,IAAI,IAAI,YAAY,UAAU,iBACnC;AACA,sBAAU;AACV,2BAAe,SAAS;AACxB,6BAAiB,sCAAsC;AACvD;AAAA,UACF;AACA,cAAI;AACF,kBAAM,UAAU,MAAM,OAAO,WAAW,SAAS;AACjD,uBAAW,OAAO;AAClB,gBAAI,QAAQ,WAAW,aAAa;AAClC,wBAAU;AACV,6BAAe,SAAS;AACxB,oBAAM,eAAe;AACrB,gCAAkB;AAAA,gBAChB,WAAW,QAAQ;AAAA,gBACnB;AAAA,gBACA,QAAQ,QAAQ;AAAA,cAClB,CAAC;AAAA,YACH,WAAW,kBAAkB,QAAQ,MAAM,GAAG;AAC5C,wBAAU;AACV,6BAAe,SAAS;AACxB;AAAA,gBACE,QAAQ,iBAAiB,WAAW,QAAQ,OAAO,YAAY,CAAC;AAAA,cAClE;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF,GAAG;AAAA,MACL,GAAG,gBAAgB;AAAA,IACrB;AAAA,IACA,CAAC,WAAW,QAAQ,iBAAiB,cAAc;AAAA,EACrD;AAEA,QAAM,oBAAgB,2BAAY,YAAY;AAC5C,QAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,SAAS,CAAC,gBAAiB;AAC/D,UAAM,OAAO,UAAU,gBAAgB,UAAU,aAAa;AAC9D,YAAQ,YAAY;AACpB,mBAAe,SAAS;AACxB,oBAAgB,IAAI;AACpB,QAAI;AACF,YAAM,UAAU,MAAM,OAAO,cAAc;AAAA,QACzC,UAAU,eAAe;AAAA,QACzB,cAAc,MAAM;AAAA,QACpB,oBAAoB,QAAQ,SAAS;AAAA,QACrC,aAAa;AAAA,MACf,CAAC;AACD,iBAAW,OAAO;AAClB,UAAI,QAAQ,WAAW,aAAa;AAClC,uBAAe,SAAS;AACxB,cAAM,eAAe;AACrB,0BAAkB;AAAA,UAChB,WAAW,QAAQ;AAAA,UACnB,SAAS,QAAQ;AAAA,UACjB,QAAQ,QAAQ;AAAA,QAClB,CAAC;AACD;AAAA,MACF;AACA,UAAI,kBAAkB,QAAQ,MAAM,GAAG;AACrC,uBAAe,SAAS;AACxB;AAAA,UACE,QAAQ,iBAAiB,WAAW,QAAQ,OAAO,YAAY,CAAC;AAAA,QAClE;AACA;AAAA,MACF;AACA,gBAAU,QAAQ,IAAI,QAAQ,OAAO;AAAA,IACvC,SAAS,KAAK;AACZ,qBAAe,SAAS;AACxB;AAAA,QACE,eAAe,QAAQ,IAAI,UAAU;AAAA,MACvC;AACA;AAAA,QACE,eAAe,QAAQ,IAAI,UAAU;AAAA,MACvC;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,mBAAe,2BAAY,MAAM;AACrC,cAAU;AACV,YAAQ,SAAS;AACjB,mBAAe,SAAS;AACxB,oBAAgB,IAAI;AACpB,qBAAiB,IAAI;AAAA,EACvB,GAAG,CAAC,SAAS,CAAC;AAGd,+BAAU,MAAM;AACd,QAAI,SAAS,aAAa,CAAC,gBAAiB;AAC5C,UAAM,SAAS,cAAc,QAAQ,OAAO,EAAE;AAC9C,QAAI,OAAO,SAAS,GAAG;AACrB,iBAAW,IAAI;AACf,sBAAgB,IAAI;AACpB;AAAA,IACF;AACA,QAAI,aAAa,QAAS,cAAa,aAAa,OAAO;AAC3D,iBAAa,UAAU,WAAW,MAAM;AACtC,YAAM,YAAY;AAChB,0BAAkB,IAAI;AACtB,wBAAgB,IAAI;AACpB,YAAI;AACF,gBAAM,OAAO,UAAU,gBAAgB,UAAU,aAAa;AAC9D,gBAAM,SAAS,MAAM,OAAO,gBAAgB,IAAI;AAChD,qBAAW,MAAM;AACjB,gBAAM,QAAQ,OAAO,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI;AACjD,cACE,wBACA,MAAM,SAAS,oBAAoB,GACnC;AAAA,UAEF,OAAO;AACL,oCAAwB,wBAAwB,KAAK,CAAC;AAAA,UACxD;AAAA,QACF,SAAS,KAAK;AACZ,qBAAW,IAAI;AACf;AAAA,YACE,eAAe,QAAQ,IAAI,UAAU;AAAA,UACvC;AAAA,QACF,UAAE;AACA,4BAAkB,KAAK;AAAA,QACzB;AAAA,MACF,GAAG;AAAA,IACL,GAAG,mBAAmB;AACtB,WAAO,MAAM;AACX,UAAI,aAAa,QAAS,cAAa,aAAa,OAAO;AAAA,IAC7D;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,+BAAU,MAAM;AACd,QACE,SAAS,aACT,CAAC,kBACD,CAAC,WACD,CAAC,sBACD;AACA,eAAS,IAAI;AACb;AAAA,IACF;AACA,UAAM,YAAY;AAChB,sBAAgB,IAAI;AACpB,oBAAc,IAAI;AAClB,UAAI;AACF,cAAM,IAAI,MAAM,OAAO,aAAa;AAAA,UAClC,UAAU,eAAe;AAAA,UACzB,cAAc;AAAA,UACd,oBAAoB,QAAQ,SAAS;AAAA,QACvC,CAAC;AACD,iBAAS,CAAC;AAAA,MACZ,SAAS,KAAK;AACZ,iBAAS,IAAI;AACb;AAAA,UACE,eAAe,QAAQ,IAAI,UAAU;AAAA,QACvC;AAAA,MACF,UAAE;AACA,wBAAgB,KAAK;AAAA,MACvB;AAAA,IACF,GAAG;AAAA,EACL,GAAG,CAAC,QAAQ,SAAS,gBAAgB,sBAAsB,IAAI,CAAC;AAEhE,+BAAU,MAAM,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC;AAE9C,QAAM,YAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,+CAAC,YAAY,UAAZ,EAAqB,OACnB;AAAA;AAAA,IACD,8CAAC,oBAAiB;AAAA,KACpB;AAEJ;;;AkB7gBA,IAAAC,gBAA0B;AAC1B,IAAAC,wBAMO;AAkDD,IAAAC,uBAAA;AAzCC,SAAS,kBAAkB,EAAE,MAAM,GAA2B;AACnE,QAAM,EAAE,OAAO,SAAS,gBAAgB,cAAc,eAAe,IACnE,QAAQ;AACV,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AAEpC,+BAAU,MAAM;AACd,SAAK,eAAe;AAAA,EACtB,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,SAAS,iCAAW,OAAO;AAAA,IAC/B,MAAM;AAAA,MACJ,iBAAiB,OAAO;AAAA,MACxB,cAAcA,QAAO;AAAA,MACrB,SAASD,SAAQ;AAAA,MACjB,GAAG;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,cAAcA,SAAQ;AAAA,IACxB;AAAA,IACA,KAAK;AAAA,MACH,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,KAAKA,SAAQ;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,WAAWA,SAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SACE,+CAAC,8BAAK,OAAO,OAAO,MAClB;AAAA,kDAAC,8BAAK,OAAO,OAAO,OAAO,6BAAe;AAAA,IAC1C,+CAAC,8BAAK,OAAO,OAAO,KAClB;AAAA,oDAAC,QAAK,MAAK,QAAO,MAAM,IAAI,OAAO,OAAO,SAAS;AAAA,MAClD,kBAAkB,YAAY,OAC7B,8CAAC,2CAAkB,OAAO,OAAO,SAAS,IAE1C,8CAAC,8BAAK,OAAO,OAAO,OACjB,sBAAY,OAAO,cAAc,OAAO,IAAI,UAC/C;AAAA,OAEJ;AAAA,IACC,eACC,8CAAC,8BAAK,OAAO,OAAO,OAAQ,wBAAa,IACvC;AAAA,KACN;AAEJ;;;ACzEA,IAAAE,iBAAyB;AACzB,IAAAC,wBAMO;AAsEG,IAAAC,uBAAA;AA5DH,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,QAAQ;AAAA,EACR;AACF,GAAyB;AACvB,QAAM,EAAE,OAAO,UAAU,IAAI,QAAQ;AACrC,QAAM,EAAE,QAAQ,SAAAC,UAAS,QAAAC,QAAO,IAAI;AACpC,QAAM,CAAC,SAAS,UAAU,QAAI,yBAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,QAAI,yBAAwB,IAAI;AAEtD,QAAM,SAAS,iCAAW,OAAO;AAAA,IAC/B,QAAQ;AAAA,MACN,iBAAiB,OAAO;AAAA,MACxB,cAAcA,QAAO;AAAA,MACrB,iBAAiBD,SAAQ;AAAA,MACzB,mBAAmBA,SAAQ;AAAA,MAC3B,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,KAAKA,SAAQ;AAAA,MACb,GAAG;AAAA,IACL;AAAA,IACA,SAAS,EAAE,SAAS,KAAK,WAAW,CAAC,EAAE,OAAO,KAAK,CAAC,EAAE;AAAA,IACtD,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,OAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,UAAU;AAAA,MACV,WAAWA,SAAQ;AAAA,MACnB,WAAW;AAAA,IACb;AAAA,EACF,CAAC;AAED,QAAM,cAAc,YAAY;AAC9B,aAAS,IAAI;AACb,eAAW,IAAI;AACf,QAAI;AACF,YAAM,QAAQ,MAAM,eAAe;AACnC,UAAI,CAAC,OAAO,KAAK,GAAG;AAClB,cAAM,IAAI,MAAM,wBAAwB;AAAA,MAC1C;AACA,YAAM,UAAU,MAAM,KAAK,CAAC;AAAA,IAC9B,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,IAAI,UAAU,wBAAwB;AAAA,IACxE,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,SACE,gFACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,CAAC,EAAE,QAAQ,MAAM,CAAC,OAAO,QAAQ,WAAW,OAAO,OAAO;AAAA,QACjE,SAAS,MAAM,KAAK,YAAY;AAAA,QAChC,UAAU;AAAA,QAET,oBACC,8CAAC,2CAAkB,OAAO,OAAO,oBAAoB,IAErD,gFACE;AAAA,wDAAC,8BAAK,OAAO,OAAO,OAAQ,iBAAM;AAAA,UAClC,8CAAC,QAAK,MAAK,iBAAgB,MAAM,IAAI,OAAO,OAAO,oBAAoB;AAAA,WACzE;AAAA;AAAA,IAEJ;AAAA,IACC,QAAQ,8CAAC,8BAAK,OAAO,OAAO,OAAQ,iBAAM,IAAU;AAAA,KACvD;AAEJ;","names":["import_react","import_react_native","import_react","import_react_native","import_bottom_sheet","import_react_native_safe_area_context","MaterialIcons","import_jsx_runtime","spacing","radius","import_react","import_react_native","import_react","import_react_native","import_jsx_runtime","spacing","import_react","import_react_native","import_react_native","spacing","import_jsx_runtime","spacing","radius","import_react_native","import_react_native_safe_area_context","import_jsx_runtime","spacing","radius","import_jsx_runtime","spacing","radius","import_react","import_react_native","import_react","import_react_native","import_jsx_runtime","import_jsx_runtime","spacing","radius","import_jsx_runtime","spacing","BottomSheet","import_jsx_runtime","value","import_react","import_react_native","import_jsx_runtime","spacing","radius","import_react","import_react_native","import_jsx_runtime","spacing","radius"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { ViewStyle } from 'react-native';
|
|
4
|
+
|
|
5
|
+
type Bundle = {
|
|
6
|
+
id: string;
|
|
7
|
+
appId: string;
|
|
8
|
+
label: string | null;
|
|
9
|
+
priceUsd: string;
|
|
10
|
+
credits: number;
|
|
11
|
+
isActive: boolean;
|
|
12
|
+
sortOrder: number;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
};
|
|
16
|
+
type CatalogCurrency = {
|
|
17
|
+
id: string;
|
|
18
|
+
code: string;
|
|
19
|
+
name: string;
|
|
20
|
+
decimals: number;
|
|
21
|
+
isActive: boolean;
|
|
22
|
+
};
|
|
23
|
+
type CatalogCountry = {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
iso2: string;
|
|
27
|
+
iso3: string;
|
|
28
|
+
isActive: boolean;
|
|
29
|
+
currencies?: Array<{
|
|
30
|
+
currency: CatalogCurrency;
|
|
31
|
+
}>;
|
|
32
|
+
paymentGateways?: unknown[];
|
|
33
|
+
};
|
|
34
|
+
type PredictProviderResponse = {
|
|
35
|
+
provider: {
|
|
36
|
+
code: string;
|
|
37
|
+
displayName: string;
|
|
38
|
+
};
|
|
39
|
+
countryIso3: string | null;
|
|
40
|
+
currencies: Array<{
|
|
41
|
+
code: string;
|
|
42
|
+
decimals: number;
|
|
43
|
+
}>;
|
|
44
|
+
defaultCurrencyCode: string;
|
|
45
|
+
};
|
|
46
|
+
type QuotePaymentResponse = {
|
|
47
|
+
bundleId: string;
|
|
48
|
+
credits: number;
|
|
49
|
+
currencyCode: string;
|
|
50
|
+
paymentGatewayCode: string;
|
|
51
|
+
amountUsd: string;
|
|
52
|
+
amountLocal: string;
|
|
53
|
+
feeUsd: string;
|
|
54
|
+
feeLocal: string;
|
|
55
|
+
totalUsd: string;
|
|
56
|
+
totalLocal: string;
|
|
57
|
+
};
|
|
58
|
+
type DepositStatus = 'PENDING' | 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED';
|
|
59
|
+
type PublicDeposit = {
|
|
60
|
+
id: string;
|
|
61
|
+
status: DepositStatus;
|
|
62
|
+
credits: number;
|
|
63
|
+
currencyCode: string | null;
|
|
64
|
+
paymentGatewayCode: string | null;
|
|
65
|
+
amountUsd: string;
|
|
66
|
+
amountLocal: string;
|
|
67
|
+
feeUsd: string;
|
|
68
|
+
feeLocal: string;
|
|
69
|
+
totalUsd: string;
|
|
70
|
+
totalLocal: string;
|
|
71
|
+
bundleId: string | null;
|
|
72
|
+
phoneNumber: string | null;
|
|
73
|
+
providerRef: string | null;
|
|
74
|
+
failureReason: string | null;
|
|
75
|
+
expiresAt: string;
|
|
76
|
+
createdAt: string;
|
|
77
|
+
updatedAt: string;
|
|
78
|
+
};
|
|
79
|
+
type TopUpCompleteResult = {
|
|
80
|
+
depositId: string;
|
|
81
|
+
credits: number;
|
|
82
|
+
status: DepositStatus;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
type ThemeMode = 'light' | 'dark';
|
|
86
|
+
type JazaTheme = {
|
|
87
|
+
mode: ThemeMode;
|
|
88
|
+
colors: {
|
|
89
|
+
background: string;
|
|
90
|
+
surface: string;
|
|
91
|
+
surfaceContainer: string;
|
|
92
|
+
surfaceContainerLow: string;
|
|
93
|
+
surfaceContainerHigh: string;
|
|
94
|
+
surfaceContainerHighest: string;
|
|
95
|
+
surfaceVariant: string;
|
|
96
|
+
onSurface: string;
|
|
97
|
+
onSurfaceVariant: string;
|
|
98
|
+
primary: string;
|
|
99
|
+
onPrimary: string;
|
|
100
|
+
primaryContainer: string;
|
|
101
|
+
onPrimaryContainer: string;
|
|
102
|
+
secondaryContainer: string;
|
|
103
|
+
onSecondaryContainer: string;
|
|
104
|
+
outline: string;
|
|
105
|
+
outlineVariant: string;
|
|
106
|
+
error: string;
|
|
107
|
+
success: string;
|
|
108
|
+
overlay: string;
|
|
109
|
+
bundleBorder: string;
|
|
110
|
+
bundleBorderSelected: string;
|
|
111
|
+
bundleBg: string;
|
|
112
|
+
};
|
|
113
|
+
spacing: {
|
|
114
|
+
xs: number;
|
|
115
|
+
sm: number;
|
|
116
|
+
md: number;
|
|
117
|
+
lg: number;
|
|
118
|
+
xl: number;
|
|
119
|
+
gutter: number;
|
|
120
|
+
};
|
|
121
|
+
radius: {
|
|
122
|
+
md: number;
|
|
123
|
+
lg: number;
|
|
124
|
+
xl: number;
|
|
125
|
+
full: number;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
declare const darkTheme: JazaTheme;
|
|
129
|
+
/** Checkout UI uses dark palette in both light and dark preference. */
|
|
130
|
+
declare const lightTheme: JazaTheme;
|
|
131
|
+
type ThemePreference = 'light' | 'dark' | 'system';
|
|
132
|
+
|
|
133
|
+
type JazaProviderProps = {
|
|
134
|
+
publishableKey: string;
|
|
135
|
+
apiBaseUrl?: string;
|
|
136
|
+
getBalance: () => Promise<number>;
|
|
137
|
+
onTopUpComplete?: (result: TopUpCompleteResult) => void;
|
|
138
|
+
theme?: ThemePreference;
|
|
139
|
+
children: ReactNode;
|
|
140
|
+
};
|
|
141
|
+
declare function JazaProvider({ publishableKey, apiBaseUrl, getBalance, onTopUpComplete, theme: themePreference, children, }: JazaProviderProps): react.JSX.Element;
|
|
142
|
+
|
|
143
|
+
type PublicClientConfig = {
|
|
144
|
+
apiBaseUrl?: string;
|
|
145
|
+
publishableKey: string;
|
|
146
|
+
};
|
|
147
|
+
declare class PublicClient {
|
|
148
|
+
private readonly apiBaseUrl;
|
|
149
|
+
private readonly publishableKey;
|
|
150
|
+
private topUpToken;
|
|
151
|
+
constructor(config: PublicClientConfig);
|
|
152
|
+
setTopUpToken(token: string | null): void;
|
|
153
|
+
listCountries(): Promise<CatalogCountry[]>;
|
|
154
|
+
listBundles(): Promise<Bundle[]>;
|
|
155
|
+
predictProvider(phoneNumber: string): Promise<PredictProviderResponse>;
|
|
156
|
+
quotePayment(body: {
|
|
157
|
+
bundleId: string;
|
|
158
|
+
currencyCode: string;
|
|
159
|
+
paymentGatewayCode: string;
|
|
160
|
+
}): Promise<QuotePaymentResponse>;
|
|
161
|
+
createDeposit(body: {
|
|
162
|
+
bundleId: string;
|
|
163
|
+
currencyCode: string;
|
|
164
|
+
paymentGatewayCode: string;
|
|
165
|
+
phoneNumber: string;
|
|
166
|
+
idempotencyKey?: string;
|
|
167
|
+
}): Promise<PublicDeposit>;
|
|
168
|
+
getDeposit(paymentRequestId: string): Promise<PublicDeposit>;
|
|
169
|
+
private authedRequest;
|
|
170
|
+
private request;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
type EnrichedCountry = {
|
|
174
|
+
id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
iso2: string;
|
|
177
|
+
iso3: string;
|
|
178
|
+
dialCode: string;
|
|
179
|
+
flag: string;
|
|
180
|
+
currencies: Array<{
|
|
181
|
+
code: string;
|
|
182
|
+
decimals: number;
|
|
183
|
+
name: string;
|
|
184
|
+
}>;
|
|
185
|
+
};
|
|
186
|
+
declare function enrichCountries(countries: CatalogCountry[]): EnrichedCountry[];
|
|
187
|
+
declare function buildE164(dialCode: string, nationalNumber: string): string;
|
|
188
|
+
/** Prefer local (non-USD) when multiple currencies are supported. */
|
|
189
|
+
declare function pickDefaultCurrencyCode(codes: string[]): string;
|
|
190
|
+
declare function isDepositTerminal(status: string): status is 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED';
|
|
191
|
+
declare function formatCredits(n: number): string;
|
|
192
|
+
declare function formatUsd(priceUsd: string): string;
|
|
193
|
+
declare function formatCurrencyAmount(amount: string | number, currencyCode: string, _decimals?: number): string;
|
|
194
|
+
/** @deprecated Use formatCurrencyAmount */
|
|
195
|
+
declare function formatLocalAmount(amount: string, currencyCode: string, decimals?: number): string;
|
|
196
|
+
|
|
197
|
+
type TopUpStep = 'offer' | 'payment' | 'processing';
|
|
198
|
+
type ResultPhase = 'loading' | 'success' | 'failure';
|
|
199
|
+
type JazaContextValue = {
|
|
200
|
+
theme: JazaTheme;
|
|
201
|
+
themePreference: ThemePreference;
|
|
202
|
+
publishableKey: string;
|
|
203
|
+
client: PublicClient;
|
|
204
|
+
balance: number | null;
|
|
205
|
+
balanceLoading: boolean;
|
|
206
|
+
balanceError: string | null;
|
|
207
|
+
refreshBalance: () => Promise<void>;
|
|
208
|
+
sheetOpen: boolean;
|
|
209
|
+
step: TopUpStep;
|
|
210
|
+
resultPhase: ResultPhase;
|
|
211
|
+
topUpToken: string | null;
|
|
212
|
+
bundles: Bundle[];
|
|
213
|
+
bundlesLoading: boolean;
|
|
214
|
+
bundlesError: string | null;
|
|
215
|
+
selectedBundle: Bundle | null;
|
|
216
|
+
setSelectedBundle: (b: Bundle | null) => void;
|
|
217
|
+
countries: EnrichedCountry[];
|
|
218
|
+
selectedCountry: EnrichedCountry | null;
|
|
219
|
+
setSelectedCountry: (c: EnrichedCountry | null) => void;
|
|
220
|
+
selectedCurrencyCode: string | null;
|
|
221
|
+
setSelectedCurrencyCode: (code: string | null) => void;
|
|
222
|
+
phoneNational: string;
|
|
223
|
+
setPhoneNational: (v: string) => void;
|
|
224
|
+
predict: PredictProviderResponse | null;
|
|
225
|
+
predictLoading: boolean;
|
|
226
|
+
predictError: string | null;
|
|
227
|
+
quote: QuotePaymentResponse | null;
|
|
228
|
+
quoteLoading: boolean;
|
|
229
|
+
quoteError: string | null;
|
|
230
|
+
deposit: PublicDeposit | null;
|
|
231
|
+
depositError: string | null;
|
|
232
|
+
failureReason: string | null;
|
|
233
|
+
openTopUp: (token: string) => Promise<void>;
|
|
234
|
+
closeTopUp: () => void;
|
|
235
|
+
goToOffer: () => void;
|
|
236
|
+
goToPayment: () => void;
|
|
237
|
+
submitDeposit: () => Promise<void>;
|
|
238
|
+
retryPayment: () => void;
|
|
239
|
+
onTopUpComplete?: (result: TopUpCompleteResult) => void;
|
|
240
|
+
};
|
|
241
|
+
declare function useJaza(): JazaContextValue;
|
|
242
|
+
|
|
243
|
+
type JazaBalanceWidgetProps = {
|
|
244
|
+
style?: ViewStyle;
|
|
245
|
+
};
|
|
246
|
+
declare function JazaBalanceWidget({ style }: JazaBalanceWidgetProps): react.JSX.Element;
|
|
247
|
+
|
|
248
|
+
type JazaTopUpButtonProps = {
|
|
249
|
+
onRequestToken: () => Promise<string>;
|
|
250
|
+
label?: string;
|
|
251
|
+
style?: ViewStyle;
|
|
252
|
+
};
|
|
253
|
+
declare function JazaTopUpButton({ onRequestToken, label, style, }: JazaTopUpButtonProps): react.JSX.Element;
|
|
254
|
+
|
|
255
|
+
declare class JazaSdkError extends Error {
|
|
256
|
+
readonly statusCode: number;
|
|
257
|
+
readonly code: string;
|
|
258
|
+
readonly raw: unknown;
|
|
259
|
+
constructor(statusCode: number, message: string, raw?: unknown);
|
|
260
|
+
static fromResponse(status: number, body: unknown): JazaSdkError;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
declare const VERSION = "0.1.0";
|
|
264
|
+
declare const DEFAULT_API_BASE_URL = "https://api.jaza.dev";
|
|
265
|
+
|
|
266
|
+
/** ISO 3166-1 alpha-2 → international dial code (Jaza MoMo ecosystem). */
|
|
267
|
+
declare const DIAL_CODES: Record<string, string>;
|
|
268
|
+
declare function iso2ToFlag(iso2: string): string;
|
|
269
|
+
declare function getDialCode(iso2: string): string | undefined;
|
|
270
|
+
|
|
271
|
+
export { type Bundle, type CatalogCountry, DEFAULT_API_BASE_URL, DIAL_CODES, type DepositStatus, type EnrichedCountry, JazaBalanceWidget, type JazaBalanceWidgetProps, type JazaContextValue, JazaProvider, type JazaProviderProps, JazaSdkError, type JazaTheme, JazaTopUpButton, type JazaTopUpButtonProps, type PredictProviderResponse, PublicClient, type PublicClientConfig, type PublicDeposit, type QuotePaymentResponse, type ResultPhase, type ThemePreference, type TopUpCompleteResult, type TopUpStep, VERSION, buildE164, darkTheme, enrichCountries, formatCredits, formatCurrencyAmount, formatLocalAmount, formatUsd, getDialCode, isDepositTerminal, iso2ToFlag, lightTheme, pickDefaultCurrencyCode, useJaza };
|