@delopay/sdk 0.230.0 → 0.234.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/dist/{chunk-HNQKUUSW.js → chunk-3NOAX6WN.js} +193 -4
- package/dist/chunk-3NOAX6WN.js.map +1 -0
- package/dist/index.cjs +199 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +133 -2
- package/dist/index.d.ts +133 -2
- package/dist/index.js +15 -1
- package/dist/internal.cjs +199 -3
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +15 -1
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-HNQKUUSW.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/error.ts","../src/resources/apiKeys.ts","../src/resources/authentication.ts","../src/resources/billing.ts","../src/resources/blocklist.ts","../src/resources/connectors.ts","../src/resources/customers.ts","../src/recordCounter.ts","../src/exportDownload.ts","../src/resources/disputes.ts","../src/resources/paypalDisputes.ts","../src/resources/whopResolutionCases.ts","../src/resources/ephemeralKeys.ts","../src/resources/events.ts","../src/resources/fees.ts","../src/resources/mandates.ts","../src/resources/merchantAccounts.ts","../src/resources/paymentLinks.ts","../src/resources/paymentMethods.ts","../src/resources/payments.ts","../src/resources/payouts.ts","../src/resources/poll.ts","../src/resources/profileAcquirers.ts","../src/resources/profiles.ts","../src/resources/projects.ts","../src/resources/refunds.ts","../src/resources/relay.ts","../src/resources/routing.ts","../src/resources/search.ts","../src/resources/shops.ts","../src/resources/stripeConnect.ts","../src/resources/threeDsRules.ts","../src/resources/users.ts","../src/resources/verification.ts","../src/resources/webhooks.ts","../src/resources/analytics.ts","../src/resources/analyticsDashboard.ts","../src/resources/cards.ts","../src/resources/export.ts","../src/resources/featureMatrix.ts","../src/resources/files.ts","../src/resources/forex.ts","../src/resources/regions.ts","../src/resources/availabilityOverrides.ts","../src/resources/sellToRestrictions.ts","../src/resources/buyerBlocklist.ts","../src/resources/checkoutRecovery.ts","../src/resources/costRules.ts","../src/resources/externalRecords.ts","../src/resources/products.ts","../src/resources/invoices.ts","../src/resources/invoiceSettings.ts","../src/resources/processorCosts.ts","../src/resources/checkoutMethods.ts","../src/resources/subscriptions.ts","../src/resources/buyerPortal.ts","../src/resources/audit.ts","../src/resources/settlement.ts","../src/resources/operationLimits.ts","../src/resources/settings.ts","../src/resources/messageTemplates.ts","../src/resources/risk.ts","../src/client.ts","../src/feeProgram.ts","../src/airwallexCard.ts","../src/cardFormStyles.ts","../src/branding.ts","../src/checkoutSession.ts","../src/panes.ts"],"sourcesContent":["/**\n * Error thrown when the Delopay API returns a non-2xx response, or when a\n * timeout or network error occurs.\n *\n * @example\n * ```typescript\n * try {\n * await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * } catch (e) {\n * if (e instanceof DelopayError) {\n * console.error(e.status, e.code, e.requestId, e.message);\n * }\n * }\n * ```\n */\nexport class DelopayError extends Error {\n /** HTTP status code returned by the API, or `0` for timeout/network errors. */\n readonly status: number;\n /** Machine-readable error code returned by the API (e.g. `'HE_00'`). */\n readonly code: string;\n /** Error category (e.g. `'invalid_request'`, `'timeout_error'`). */\n readonly type: string;\n /** Value of the `x-request-id` response header, when present. Include this when contacting support. */\n readonly requestId?: string;\n /**\n * Raw response body (truncated to ~2 KB). Populated when the server returns a\n * non-JSON error body (e.g. an HTML 502 from an upstream proxy) so debugging\n * still has something to go on.\n */\n readonly rawBody?: string;\n /**\n * Structured error context the API attaches under `error.data` for select\n * codes — e.g. `{ retry_after_secs: 248 }` on rate-limit / max-attempt\n * lockouts. Schema is per-code; consult the API reference for the shape.\n */\n readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: string;\n type: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayError';\n this.status = options.status;\n this.code = options.code;\n this.type = options.type;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.rawBody !== undefined) this.rawBody = options.rawBody;\n if (options.data !== undefined) this.data = options.data;\n }\n}\n\n/**\n * Thrown when the API key is missing, invalid, or revoked (HTTP 401).\n *\n * @example\n * ```typescript\n * if (e instanceof DelopayAuthenticationError) {\n * // Prompt user to re-enter their API key.\n * }\n * ```\n */\nexport class DelopayAuthenticationError extends DelopayError {\n constructor(\n message = 'Invalid API key',\n options?: {\n code?: string;\n type?: string;\n requestId?: string;\n rawBody?: string;\n data?: Record<string, unknown>;\n },\n ) {\n super(message, {\n status: 401,\n // Default to the generic \"invalid API key\" code, but let callers pass\n // through the server-reported code (e.g. `UR_05` for unverified-email\n // 401s) so they can differentiate between auth failure reasons.\n code: options?.code || 'AUTH_01',\n type: options?.type || 'authentication_error',\n requestId: options?.requestId,\n rawBody: options?.rawBody,\n data: options?.data,\n });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'DelopayAuthenticationError';\n }\n}\n","import type {\n ApiKeyCreateRequest,\n ApiKeyCreateResponse,\n ApiKeyListConstraints,\n ApiKeyResponse,\n ApiKeyUpdateRequest,\n ApiKeyRevokeResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage API keys for a merchant account. */\nexport class ApiKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new API key for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once only).\n *\n * @example\n * ```typescript\n * const { key_value } = await delopay.apiKeys.create('merch_123', { name: 'Production key' });\n * ```\n */\n async create(merchantId: string, params: ApiKeyCreateRequest): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/api-keys/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve metadata about an API key (does not return the plaintext secret).\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieve(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update an API key's name or expiry.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async update(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke an API key, immediately invalidating it.\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Replace an API key's secret. The key keeps its id, name, scope, shop,\n * origin rule, rate cap and expiry. The old secret stops working\n * immediately, with no grace period, so deploy the new one as part of the\n * same change. Refused with `IR_16` (HTTP 400) while the deployment runs\n * partial authentication; create a new key and revoke the old one instead.\n * `POST /api-keys/{merchantId}/{keyId}/rotate`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to rotate.\n * @returns The key with its new plaintext secret (shown once only).\n *\n * @example\n * ```typescript\n * const { api_key } = await delopay.apiKeys.rotate('merch_123', 'key_abc');\n * ```\n */\n async rotate(merchantId: string, keyId: string): Promise<ApiKeyCreateResponse> {\n return this.request(\n 'POST',\n `/api-keys/${encodeURIComponent(merchantId)}/${encodeURIComponent(keyId)}/rotate`,\n );\n }\n\n /**\n * List all API keys for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of API key metadata objects.\n */\n async list(merchantId: string): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/api-keys/${encodeURIComponent(merchantId)}/list`);\n }\n\n // --- Profile-scoped (shop-level) API keys ---------------------------------\n //\n // JWT-authenticated routes under `/account/{merchantId}/profile/api-keys`.\n // The caller's shop (business profile) comes from the JWT, never from the\n // request, so a shop-scoped user can only mint/list/manage keys pinned to\n // their own shop. Requires a backend with profile-scoped API key support.\n\n /**\n * Create a new API key pinned to the caller's shop (business profile).\n * `POST /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Key creation parameters (name, expiry, etc.).\n * @returns The newly created key including the plaintext secret (shown once\n * only) and the `profile_id` it is pinned to.\n *\n * @example\n * ```typescript\n * const { api_key } = await delopay.apiKeys.createByProfile('merch_123', {\n * name: 'Shop key',\n * expiration: 'never',\n * });\n * ```\n */\n async createByProfile(\n merchantId: string,\n params: ApiKeyCreateRequest,\n ): Promise<ApiKeyCreateResponse> {\n return this.request('POST', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n body: params,\n });\n }\n\n /**\n * List API keys pinned to the caller's shop (business profile) only.\n * `GET /account/{merchantId}/profile/api-keys`\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination constraints (`limit`, `skip`).\n * @returns Array of API key metadata objects belonging to the caller's shop.\n */\n async listByProfile(\n merchantId: string,\n params?: ApiKeyListConstraints,\n ): Promise<ApiKeyResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(merchantId)}/profile/api-keys`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * Retrieve metadata about a shop-pinned API key (does not return the\n * plaintext secret). `GET /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID.\n * @returns The API key metadata.\n */\n async retrieveByProfile(merchantId: string, keyId: string): Promise<ApiKeyResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Update a shop-pinned API key's name, description, or expiry.\n * `POST /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to update.\n * @param params - Fields to update.\n * @returns The updated API key metadata.\n */\n async updateByProfile(\n merchantId: string,\n keyId: string,\n params: ApiKeyUpdateRequest,\n ): Promise<ApiKeyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n { body: params },\n );\n }\n\n /**\n * Revoke a shop-pinned API key, immediately invalidating it.\n * `DELETE /account/{merchantId}/profile/api-keys/{keyId}`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to revoke.\n * @returns Revocation confirmation.\n */\n async revokeByProfile(merchantId: string, keyId: string): Promise<ApiKeyRevokeResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}`,\n );\n }\n\n /**\n * Replace the secret of an API key pinned to the caller's shop. The key\n * keeps its id, name, scope, origin rule, rate cap and expiry. The old\n * secret stops working immediately, with no grace period.\n * `POST /account/{merchantId}/profile/api-keys/{keyId}/rotate`\n *\n * @param merchantId - The merchant account ID.\n * @param keyId - The API key ID to rotate.\n * @returns The key with its new plaintext secret (shown once only).\n */\n async rotateByProfile(merchantId: string, keyId: string): Promise<ApiKeyCreateResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/profile/api-keys/${encodeURIComponent(keyId)}/rotate`,\n );\n }\n}\n","import type { AuthenticationCreateRequest, AuthenticationResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Authentication {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: AuthenticationCreateRequest): Promise<AuthenticationResponse> {\n return this.request('POST', '/authentication', { body: params });\n }\n\n async checkEligibility(authId: string): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility`);\n }\n\n async authenticate(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/authenticate`, {\n body: params,\n });\n }\n\n /** Sync authentication status. `POST /authentication/{merchantId}/{authId}/sync` */\n async sync(\n merchantId: string,\n authId: string,\n params?: Record<string, unknown>,\n ): Promise<AuthenticationResponse> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/sync`,\n { body: params },\n );\n }\n\n /** Redirect after authentication. `POST /authentication/{merchantId}/{authId}/redirect` */\n async redirect(\n merchantId: string,\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(merchantId)}/${encodeURIComponent(authId)}/redirect`,\n { body: params },\n );\n }\n\n /** Enable authn methods token. `POST /authentication/{authId}/enabled-authn-methods-token` */\n async enabledAuthnMethodsToken(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request(\n 'POST',\n `/authentication/${encodeURIComponent(authId)}/enabled-authn-methods-token`,\n {\n body: params,\n },\n );\n }\n\n /** Submit eligibility check. `POST /authentication/{authId}/eligibility-check` */\n async eligibilityCheck(\n authId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/authentication/${encodeURIComponent(authId)}/eligibility-check`, {\n body: params,\n });\n }\n}\n","import type {\n BillingProfileResponse,\n BillingSetupRequest,\n BillingSetupResponse,\n BillingCompleteSetupRequest,\n TopupRequest,\n TopupResponse,\n LedgerResponse,\n LedgerListParams,\n BlockedAttemptListResponse,\n BlockedAttemptListParams,\n AutoRechargeUpdateRequest,\n AllocationTransferRequest,\n AllocationTransferResponse,\n AllocationListResponse,\n AllocationResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Manage per-shop prepaid balance allocations transferred from the host merchant treasury. */\nclass BillingAllocations {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Transfer funds from the host merchant treasury into a shop's allocation.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, target profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferIn(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-in`,\n { body: params },\n );\n }\n\n /**\n * Transfer funds from a shop's allocation back to the host merchant treasury.\n *\n * @param merchantId - The host merchant account ID.\n * @param params - Transfer details (amount, source profile/shop ID).\n * @returns The allocation transfer result.\n */\n async transferOut(\n merchantId: string,\n params: AllocationTransferRequest,\n ): Promise<AllocationTransferResponse> {\n return this.request(\n 'POST',\n `/billing/${encodeURIComponent(merchantId)}/allocations/transfer-out`,\n {\n body: params,\n },\n );\n }\n\n /**\n * List all shop balance allocations for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns List of shop allocations.\n */\n async list(merchantId: string): Promise<AllocationListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/allocations`);\n }\n\n /**\n * Get the balance allocation for a specific shop.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - The shop (business profile) ID.\n * @returns The shop's balance allocation.\n */\n async get(merchantId: string, profileId: string): Promise<AllocationResponse> {\n return this.request(\n 'GET',\n `/billing/${encodeURIComponent(merchantId)}/allocations/${encodeURIComponent(profileId)}`,\n );\n }\n}\n\n/**\n * Manage prepaid billing balances — top-ups, card setup, auto-recharge, and the balance ledger.\n *\n * Delopay deducts a platform fee from the merchant's prepaid balance on every successful payment.\n * Use these endpoints to fund and monitor that balance.\n */\nexport class Billing {\n /** Per-shop balance allocation management for host merchants. */\n readonly allocations: BillingAllocations;\n\n constructor(private readonly request: RequestFn) {\n this.allocations = new BillingAllocations(request);\n }\n\n /**\n * Retrieve a merchant's billing profile (balance, status, auto-recharge config).\n *\n * @param merchantId - The merchant account ID.\n * @returns The billing profile.\n *\n * @example\n * ```typescript\n * const profile = await delopay.billing.getProfile('merch_123');\n * console.log(profile.balance, profile.status);\n * ```\n */\n async getProfile(merchantId: string): Promise<BillingProfileResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Start a Stripe SetupIntent flow to collect a payment card for auto-recharge.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional setup parameters.\n * @returns The Stripe client secret needed to render the card element.\n */\n async setup(merchantId: string, params?: BillingSetupRequest): Promise<BillingSetupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup`, {\n body: params,\n });\n }\n\n /**\n * Confirm card setup after the Stripe SetupIntent completes on the frontend.\n *\n * @param merchantId - The merchant account ID.\n * @param params - The Stripe SetupIntent ID to confirm.\n * @returns The updated billing profile.\n */\n async completeSetup(\n merchantId: string,\n params: BillingCompleteSetupRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/setup/complete`, {\n body: params,\n });\n }\n\n /**\n * Manually top up a merchant's prepaid balance by charging their saved card.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Top-up amount and currency.\n * @returns The top-up result.\n */\n async topup(merchantId: string, params: TopupRequest): Promise<TopupResponse> {\n return this.request('POST', `/billing/${encodeURIComponent(merchantId)}/topup`, {\n body: params,\n });\n }\n\n /**\n * List the balance ledger (credits and debits) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional pagination parameters.\n * @returns The ledger entries.\n */\n async listLedger(merchantId: string, params?: LedgerListParams): Promise<LedgerResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/ledger`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List payment attempts that were blocked by the billing suspension gate\n * (account suspended, setup incomplete, or shop allocation suspended).\n *\n * These attempts never created a payment, so they do not appear in the\n * payments list — this is the only way to retrieve them.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Optional filters (profile, reason, date range) and pagination.\n * @returns The blocked-attempt entries with a total count.\n */\n async listBlockedAttempts(\n merchantId: string,\n params?: BlockedAttemptListParams,\n ): Promise<BlockedAttemptListResponse> {\n return this.request('GET', `/billing/${encodeURIComponent(merchantId)}/blocked-attempts`, {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Update auto-recharge configuration (threshold, top-up amount, enabled flag).\n *\n * @param merchantId - The merchant account ID.\n * @param params - Auto-recharge settings to update.\n * @returns The updated billing profile.\n */\n async updateAutoRecharge(\n merchantId: string,\n params: AutoRechargeUpdateRequest,\n ): Promise<BillingProfileResponse> {\n return this.request('PATCH', `/billing/${encodeURIComponent(merchantId)}/auto-recharge`, {\n body: params,\n });\n }\n}\n","import type { BlocklistAddRequest, BlocklistResponse, BlocklistDataKind } from '../types';\nimport type { RequestFn } from '../client';\n\nexport interface BlocklistListParams {\n data_kind?: BlocklistDataKind | null;\n limit?: number | null;\n offset?: number | null;\n}\n\nexport interface BlocklistToggleParams {\n status: boolean;\n}\n\nexport class Blocklist {\n constructor(private readonly request: RequestFn) {}\n\n async add(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('POST', '/blocklist', { body: params });\n }\n\n async remove(params: BlocklistAddRequest): Promise<BlocklistResponse> {\n return this.request('DELETE', '/blocklist', { body: params });\n }\n\n async list(params?: BlocklistListParams): Promise<BlocklistResponse[]> {\n return this.request('GET', '/blocklist', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n async toggle(params: BlocklistToggleParams): Promise<Record<string, unknown>> {\n return this.request('POST', '/blocklist/toggle', { body: params });\n }\n}\n","import type {\n ConnectorCloneRequest,\n ConnectorHealthResponse,\n EpayoutsCatalogResponse,\n PanesCatalogResponse,\n VaultRoutesApplyRequest,\n VaultRoutesApplyResponse,\n VaultRoutesPreviewRequest,\n VaultRoutesPreviewResponse,\n VaultVerificationResponse,\n VaultVerifyRequest,\n ConnectorCreateRequest,\n ConnectorResponse,\n ConnectorUpdateRequest,\n ConnectorWebhookListResponse,\n ConnectorWebhookRegisterRequest,\n ConnectorWebhookRegisterResponse,\n ConnectorWebhookSyncResponse,\n AirwallexApplePayDomainsRegisterRequest,\n AirwallexApplePayDomainsRegisterResponse,\n StripePaymentMethodDomainsRegisterRequest,\n StripePaymentMethodDomainsRegisterResponse,\n WhopApplePayDomainsRegisterRequest,\n WhopApplePayDomainsRegisterResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Connectors {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ConnectorCreateRequest): Promise<ConnectorResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/connectors`, {\n body: params,\n });\n }\n\n /**\n * One connector account.\n *\n * The credential-bearing fields come back `null` here, whatever is stored:\n * `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data`. They are dropped rather\n * than masked, because an editor that prefills from this response and\n * PATCHes the field back would otherwise save a mask over a live signing\n * secret. Send those fields only when the operator has typed a new value,\n * and omit them entirely otherwise — an omitted field leaves the stored one\n * alone.\n *\n * This is the retrieve path alone. `create` and `update` echo back what the\n * caller sent, and `clone` returns the *copied* secrets — see that method.\n *\n * Because the value is gone, `has_live_webhook_secret` and\n * `has_sandbox_webhook_secret` are what tell a stored webhook signing secret\n * from an unconfigured one. Render those; never infer configuration from the\n * `null` block.\n *\n * `GET /account/{accountId}/connectors/{connectorId}`\n */\n async retrieve(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * The merchant's connector accounts.\n *\n * Never wider than the caller: an API key pinned to one shop lists that\n * shop's connectors only, not every sibling shop's.\n *\n * `GET /account/{accountId}/connectors`\n */\n async list(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/connectors`);\n }\n\n /**\n * The profile-scoped connector list. The merchant-wide `list()` is\n * merchant-gated and 403s for a profile-entity (shop user) JWT; this\n * variant is scoped server-side to the caller's own profile.\n *\n * `GET /account/{accountId}/profile/connectors`\n */\n async listByProfile(accountId: string): Promise<ConnectorResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile/connectors`);\n }\n\n /**\n * Every connector's pane capabilities, as the router itself knows them —\n * which rails a connector supports, and which methods it can publish as a\n * pane with the confirm routing keys each one carries.\n *\n * Capability facts only: no label, sublabel or category comes back. A\n * designer renders a method's copy from its own locale files, keyed by\n * `key`, and takes `payment_method` / `payment_method_type` from here\n * verbatim rather than deriving them client-side.\n *\n * This is what the pane helpers in `src/panes.ts` should be driven from —\n * `paneMethodInfo`, `defaultPane` and `validatePanes` all take a\n * {@link PanesConnectorCatalog} out of this response, so a connector the\n * router starts publishing panes for needs no SDK release.\n *\n * `GET /account/{accountId}/connectors/native-panes/catalog`\n *\n * The path keeps the `native-panes` spelling deliberately. The identifiers\n * were renamed off \"native pane\"; the route was not, and pointing at the\n * backend's new name before it is deployed everywhere would both 404 against\n * un-upgraded replicas mid-rollout and fail `scripts/parity-check.mjs`,\n * which blocks publishing.\n */\n async getPanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/native-panes/catalog`,\n );\n }\n\n /** @deprecated Renamed to {@link getPanesCatalog}. Removed in 0.112.0. */\n async getNativePanesCatalog(accountId: string): Promise<PanesCatalogResponse> {\n return this.getPanesCatalog(accountId);\n }\n\n /**\n * Sweep the merchant's own e-Payouts module and return the rails it\n * actually has enabled. Server-side this makes many upstream calls, so it\n * can take several seconds — show progress.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/epayouts/catalog/sync`\n */\n async syncEpayoutsCatalog(\n accountId: string,\n connectorId: string,\n ): Promise<EpayoutsCatalogResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/epayouts/catalog/sync`,\n );\n }\n\n /**\n * Update a connector account.\n *\n * `connector_webhook_details` **merges** into the stored block key by key:\n * an absent key keeps its stored secret, an explicit value is written, and\n * an explicit empty string clears that secret. Send only the\n * keys the operator typed — padding the other environment's keys with `''`\n * clears a live signing secret and inbound webhooks stop verifying.\n *\n * The other credential-bearing fields — `connector_wallets_details`,\n * `pm_auth_config`, `additional_merchant_data` — are still whole-value\n * replacements: omit them unless you are writing a complete new value.\n *\n * `POST /account/{accountId}/connectors/{connectorId}`\n */\n async update(\n accountId: string,\n connectorId: string,\n params: ConnectorUpdateRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n {\n body: params,\n },\n );\n }\n\n /**\n * Remove a connector account.\n *\n * A shop-scoped role may remove a connector of its own shop — the shop is\n * re-checked server-side — so creating processors and removing them are the\n * same rung of access rather than two.\n *\n * `DELETE /account/{accountId}/connectors/{connectorId}`\n */\n async delete(accountId: string, connectorId: string): Promise<ConnectorResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Clone a connector into another shop (business profile) of the same\n * merchant. `POST /account/{accountId}/connectors/{connectorId}/clone`\n *\n * Credentials are copied server-side, re-encrypted under the same merchant\n * key, so the caller never has to *supply* them — `retrieve` returns `null`\n * for the credential fields, which is what makes a client-side copy\n * impossible in the first place.\n *\n * The response, however, is the unredacted connector: `connector_account_details`\n * is masked, but `connector_webhook_details`, `connector_wallets_details`,\n * `pm_auth_config` and `additional_merchant_data` come back with the copied\n * secrets in them — values this caller never sent. Do not log or echo the\n * response; read `merchant_connector_id` and discard the rest.\n */\n async clone(\n accountId: string,\n connectorId: string,\n params: ConnectorCloneRequest,\n ): Promise<ConnectorResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/clone`,\n { body: params },\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /**\n * Run the configuration checks for a vault (VGS) connector account:\n * credential validity, write-only Collect scope, reachability, environment\n * coherence, route coverage. Read-only but not cheap — it decrypts the\n * vault's management credential and talks to VGS.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/verify`\n */\n async verifyVault(\n accountId: string,\n connectorId: string,\n params: VaultVerifyRequest,\n ): Promise<VaultVerificationResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/verify`,\n { body: params },\n );\n }\n\n /**\n * Compute the route document the vault SHOULD have and diff it against\n * what exists, without writing anything. The returned fingerprints must be\n * echoed byte for byte on {@link Connectors.applyVaultRoutes}.\n *\n * A router without these endpoints answers 404 — render that as \"this\n * build cannot configure routes\", never as \"there is nothing to change\".\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/preview`\n */\n async previewVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesPreviewRequest,\n ): Promise<VaultRoutesPreviewResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/preview`,\n { body: params },\n );\n }\n\n /**\n * Write the routes the merchant just previewed. Both fingerprints come\n * from the preview and are opaque: `expected_current_fingerprint` says the\n * vault has not moved (`null` = \"the preview found no routes\" and is sent\n * as `null`, never omitted), `expected_desired_fingerprint` says the\n * document is still the one on screen. A 409 (`DE_04`) means the vault\n * changed since the preview — nothing was written; preview again.\n *\n * `POST /account/{accountId}/connectors/{connectorId}/vault/routes/apply`\n */\n async applyVaultRoutes(\n accountId: string,\n connectorId: string,\n params: VaultRoutesApplyRequest,\n ): Promise<VaultRoutesApplyResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/vault/routes/apply`,\n { body: params },\n );\n }\n\n /**\n * What the processor says about this connector account: whether it will\n * accept charges, which capabilities are live, and anything it is still\n * waiting on.\n *\n * This is **not** {@link Connectors.verify}. That one asks whether the stored\n * credentials work, by running a test-card authorization; a processor can\n * revoke an account's ability to take payments while the credentials stay\n * perfectly valid, and then a credential check reports healthy while every\n * checkout silently stalls. This asks the account's own status instead, and\n * does not create a payment. By default it reads a scheduler snapshot;\n * `refresh: true` asks for a new probe and `stale` identifies an overdue result.\n * `test_mode` selects the requested environment; `credential_source` identifies\n * a sandbox, live or shared credential set. Not every provider reports chargeability.\n *\n * Connectors with no probe answer `state: 'unknown'` with\n * `unknown_reason: 'connector_not_supported'`, rather than an error — every\n * `'unknown'` carries a reason code you render your own words for. A router\n * without this endpoint answers 404 — render that as \"this build cannot\n * report health\", never as \"healthy\".\n *\n * `GET /account/{accountId}/connectors/{connectorId}/health`\n */\n async health(\n accountId: string,\n connectorId: string,\n options?: { test_mode?: boolean; refresh?: boolean },\n ): Promise<ConnectorHealthResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/connectors/${encodeURIComponent(connectorId)}/health`,\n { query: options },\n );\n }\n\n /** Verify connector credentials. `POST /account/connectors/verify` */\n async verify(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/account/connectors/verify', { body: params });\n }\n\n /**\n * Register a webhook for a connector.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}`\n *\n * @param params - Optional event scope. Defaults to `{ event_type: 'all_events' }`\n * when omitted; pass `{ event_type: { specific_event: '…' } }` to scope\n * to a single event.\n */\n async registerWebhook(\n merchantId: string,\n connectorId: string,\n params?: ConnectorWebhookRegisterRequest,\n ): Promise<ConnectorWebhookRegisterResponse> {\n const path = `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`;\n if (params === undefined) return this.request('POST', path);\n return this.request('POST', path, { body: params });\n }\n\n /**\n * Register checkout/shop domains as Stripe payment method domains, so Apple\n * Pay renders on those pages.\n * `POST /account/{merchantId}/connectors/{connectorId}/stripe/payment-method-domains`\n *\n * Stripe connectors only. One call registers against a single credential set\n * (`environment`, default `'live'`) — call twice to cover live and sandbox.\n * Per-URL outcomes come back in `results`; a missing sandbox credential set\n * is a request-level 400.\n */\n async registerStripePaymentMethodDomains(\n merchantId: string,\n connectorId: string,\n params: StripePaymentMethodDomainsRegisterRequest,\n ): Promise<StripePaymentMethodDomainsRegisterResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/${encodeURIComponent(connectorId)}/stripe/payment-method-domains`,\n { body: params },\n );\n }\n\n /**\n * Register checkout/shop domains as Airwallex Apple Pay domains, so Apple Pay\n * renders on those pages.\n * `POST /account/{merchantId}/connectors/{connectorId}/airwallex/apple-pay-domains`\n *\n * Airwallex connectors only. One call registers against a single credential\n * set (`environment`, default `'live'`) — call twice to cover live and\n * sandbox. Idempotent: a host already on the account comes back\n * `already_registered` without a write.\n */\n async registerAirwallexApplePayDomains(\n merchantId: string,\n connectorId: string,\n params: AirwallexApplePayDomainsRegisterRequest,\n ): Promise<AirwallexApplePayDomainsRegisterResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/${encodeURIComponent(connectorId)}/airwallex/apple-pay-domains`,\n { body: params },\n );\n }\n\n /**\n * Register and verify checkout/shop domains as Whop Apple Pay payment method\n * domains, so Apple Pay renders in Whop's embedded card form on those pages.\n * `POST /account/{merchantId}/connectors/{connectorId}/whop/apple-pay-domains`\n *\n * Whop connectors only. One call registers against a single credential set\n * (`environment`, default `'live'`) — call twice to cover live and sandbox.\n * Idempotent: a host Whop already holds as verified comes back\n * `already_verified` without a write, and a `pending` one is verified again.\n */\n async registerWhopApplePayDomains(\n merchantId: string,\n connectorId: string,\n params: WhopApplePayDomainsRegisterRequest,\n ): Promise<WhopApplePayDomainsRegisterResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/${encodeURIComponent(connectorId)}/whop/apple-pay-domains`,\n { body: params },\n );\n }\n\n /** Get registered webhooks for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */\n async getWebhook(merchantId: string, connectorId: string): Promise<ConnectorWebhookListResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`,\n );\n }\n\n /**\n * Bring an already-registered webhook's event subscription up to date with\n * the events Delopay handles.\n * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/sync-events`\n *\n * A PSP freezes an endpoint's event list at registration time, so an endpoint\n * created before an event type was added never receives it — silently, with\n * no error anywhere. {@link getWebhook} reports the gap as `missing_events`;\n * this repairs it.\n *\n * Unlike re-registering, the endpoints are updated in place: the endpoint id\n * and its signing secret are preserved, so signature verification keeps\n * working across the change. Stripe connectors only; idempotent, so it is\n * safe to call on a schedule or after every deploy.\n *\n * @example\n * ```typescript\n * const sync = await delopay.connectors.syncWebhookEvents('mer_abc', 'mca_xyz');\n * for (const endpoint of sync.endpoints) {\n * if (endpoint.error_message) console.warn(endpoint.connector_webhook_id, endpoint.error_message);\n * else if (endpoint.updated) console.log('subscribed', endpoint.added_events);\n * }\n * ```\n */\n async syncWebhookEvents(\n merchantId: string,\n connectorId: string,\n ): Promise<ConnectorWebhookSyncResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}/sync-events`,\n );\n }\n\n /** List available payment methods. `GET /account/payment-methods` */\n async listPaymentMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/account/payment-methods');\n }\n}\n","import type {\n BuyerInvoiceLink,\n BuyerInvoiceLinkRequest,\n BuyerPortalLinkPage,\n BuyerPortalPageQuery,\n CustomerCreateRequest,\n CustomerResponse,\n CustomerUpdateRequest,\n CustomerListParams,\n CustomerListResponse,\n CustomerListWithCountParams,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Flatten list params for the query string.\n *\n * `profile_ids` must go out as ONE comma-separated value. The client\n * serializes arrays as repeated keys (`?profile_ids=a&profile_ids=b`), and the\n * customers endpoints cannot parse that — the whole request fails, rather than\n * the second id being ignored. So the join happens here, once, instead of at\n * four call sites.\n */\nfunction toQuery(\n params?: CustomerListParams,\n): Record<string, string | number | boolean | undefined> | undefined {\n if (!params) return undefined;\n const { profile_ids, ...rest } = params;\n const query = rest as Record<string, string | number | boolean | undefined>;\n // An empty array means \"no shop filter\", which is the absent key — sending\n // `profile_ids=` would work too, but omitting it keeps the URL honest.\n if (profile_ids && profile_ids.length > 0) {\n query.profile_ids = profile_ids.join(',');\n }\n return query;\n}\n\n/** Create and manage customer profiles. */\nexport class Customers {\n constructor(private readonly request: RequestFn) {}\n\n /** Issue a shop-scoped buyer portal link for this customer. */\n async createPortalLink(\n customerId: string,\n params: BuyerInvoiceLinkRequest,\n options?: RequestExtras,\n ): Promise<BuyerInvoiceLink> {\n return this.request('POST', `/customers/${encodeURIComponent(customerId)}/portal-links`, {\n body: params,\n ...options,\n });\n }\n\n /** List issued grants without disclosing their secret URLs. */\n async listPortalLinks(\n customerId: string,\n params?: BuyerPortalPageQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalLinkPage> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/portal-links`, {\n query: params as Record<string, number | null | undefined>,\n ...options,\n });\n }\n\n async revokePortalLink(\n customerId: string,\n linkId: string,\n options?: RequestExtras,\n ): Promise<void> {\n return this.request(\n 'DELETE',\n `/customers/${encodeURIComponent(customerId)}/portal-links/${encodeURIComponent(linkId)}`,\n { ...options },\n );\n }\n\n /**\n * Create a new customer.\n *\n * @param params - Customer creation parameters (name, email, phone, address, etc.).\n * @returns The created customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.create({\n * email: 'alice@example.com',\n * name: 'Alice Smith',\n * });\n * ```\n */\n async create(params: CustomerCreateRequest): Promise<CustomerResponse> {\n return this.request('POST', '/customers', { body: params });\n }\n\n /**\n * Retrieve a customer by their ID.\n *\n * @param customerId - The unique customer ID.\n * @returns The customer.\n *\n * @example\n * ```typescript\n * const customer = await delopay.customers.retrieve('cus_abc123');\n * ```\n */\n async retrieve(customerId: string): Promise<CustomerResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * Update an existing customer's details.\n *\n * @param customerId - The customer ID to update.\n * @param params - Fields to update (name, email, address, metadata, etc.).\n * @returns The updated customer.\n */\n async update(customerId: string, params: CustomerUpdateRequest): Promise<CustomerResponse> {\n return this.request('POST', `/customers/${encodeURIComponent(customerId)}`, { body: params });\n }\n\n /**\n * Delete a customer and all their saved payment methods.\n *\n * @param customerId - The customer ID to delete.\n * @returns The deleted customer object.\n */\n async delete(customerId: string): Promise<CustomerResponse> {\n return this.request('DELETE', `/customers/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * List customers, optionally filtered by customer id/name/email prefix,\n * shop (`profile_id`), or project (`project_id`).\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n *\n * @example\n * ```typescript\n * // Customers who have transacted in a specific shop.\n * const customers = await delopay.customers.list({ profile_id: 'pro_abc123' });\n *\n * // Several shops at once (unions with profile_id / project_id).\n * const many = await delopay.customers.list({\n * profile_ids: ['pro_abc123', 'pro_def456'],\n * });\n * ```\n */\n async list(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/list', {\n query: toQuery(params),\n });\n }\n\n // --- OLAP extensions (Task 4.6) ---\n\n /**\n * List customers with count. Supports the same `profile_id` / `project_id`\n * shop filters as {@link list}. `GET /customers/list-with-count`\n */\n async listWithCount(params?: CustomerListWithCountParams): Promise<CustomerListResponse> {\n return this.request('GET', '/customers/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /**\n * List customers scoped to the authenticated dashboard user's shop\n * (business profile). The JWT auto-scopes to its own `profile`; an explicit\n * `profile_id` / `project_id` outside that scope is rejected with\n * `AccessForbidden`. `GET /customers/profile/list`\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of customer objects.\n */\n async listByProfile(params?: CustomerListParams): Promise<CustomerResponse[]> {\n return this.request('GET', '/customers/profile/list', {\n query: toQuery(params),\n });\n }\n\n /**\n * Profile-scoped variant of {@link listWithCount}.\n * `GET /customers/profile/list-with-count`\n */\n async listByProfileWithCount(\n params?: CustomerListWithCountParams,\n ): Promise<CustomerListResponse> {\n return this.request('GET', '/customers/profile/list-with-count', {\n query: toQuery(params),\n });\n }\n\n /**\n * Retrieve one customer, scoped to the authenticated dashboard user's shop\n * (business profile). The shop-scoped counterpart of {@link retrieve}, and\n * what makes a shop's own customer list clickable: the list is\n * `ProfileCustomerRead` while {@link retrieve} is merchant-level, so a shop\n * member could see a customer they could not open.\n *\n * A customer belonging to a sibling shop answers `CustomerNotFound` — the\n * same answer as a customer that does not exist, deliberately, so one shop\n * cannot enumerate another's customer ids.\n *\n * `GET /customers/profile/{customerId}`\n *\n * @param customerId - The unique customer ID.\n * @returns The customer, with `profile_ids` narrowed to the caller's own shop.\n */\n async retrieveByProfile(customerId: string): Promise<CustomerResponse> {\n return this.request('GET', `/customers/profile/${encodeURIComponent(customerId)}`);\n }\n\n /**\n * Create a customer from a shop, recording that it belongs to that shop so\n * the shop can see the customer it just created. The shop is taken from the\n * credential; a caller-chosen `customer_id` is rejected.\n *\n * `POST /customers/profile`\n *\n * @param params - The customer to create.\n * @returns The created customer.\n */\n async createByProfile(params: CustomerCreateRequest): Promise<CustomerResponse> {\n return this.request('POST', '/customers/profile', { body: params });\n }\n\n /**\n * Update a customer from a shop, if the customer belongs to that shop.\n * A sibling shop's customer answers `CustomerNotFound`, as with\n * {@link retrieveByProfile}.\n *\n * `POST /customers/profile/{customerId}`\n *\n * @param customerId - The customer ID to update.\n * @param params - Fields to update.\n * @returns The updated customer.\n */\n async updateByProfile(\n customerId: string,\n params: CustomerUpdateRequest,\n ): Promise<CustomerResponse> {\n return this.request('POST', `/customers/profile/${encodeURIComponent(customerId)}`, {\n body: params,\n });\n }\n\n /** List mandates for a customer. `GET /customers/{customerId}/mandates` */\n async listMandates(customerId: string): Promise<Record<string, unknown>[]> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/mandates`);\n }\n\n /**\n * List one customer's mandates, scoped to the caller's shop. Same membership\n * rule as {@link retrieveByProfile}: a sibling shop's customer answers\n * `CustomerNotFound` before any mandate is read.\n *\n * `GET /customers/profile/{customerId}/mandates`\n */\n async listMandatesByProfile(customerId: string): Promise<Record<string, unknown>[]> {\n return this.request('GET', `/customers/profile/${encodeURIComponent(customerId)}/mandates`);\n }\n}\n","/**\n * Incremental record counters for streamed export bodies.\n *\n * An export streams its body and announces, in `X-Delopay-Record-Count`, how\n * many records that body will hold. These count the records actually received,\n * chunk by chunk, so a download can show `receivedRecords` of\n * `expectedRecords` while it runs and the finished file can be held to the\n * announced figure.\n *\n * They work on **bytes**, never on decoded text. Every character they look at —\n * `\"` `\\` `{` `}` `[` `]` and the line break — is ASCII, and no byte of a\n * multi-byte UTF-8 sequence falls in the ASCII range, so a chunk boundary can\n * land anywhere, the middle of a character included, without a decoder having\n * to carry a partial sequence across it.\n */\n\nconst LF = 0x0a;\nconst CR = 0x0d;\nconst QUOTE = 0x22;\nconst BACKSLASH = 0x5c;\nconst OPEN_BRACE = 0x7b;\nconst CLOSE_BRACE = 0x7d;\nconst OPEN_BRACKET = 0x5b;\nconst CLOSE_BRACKET = 0x5d;\n\n/** Counts the records in a body fed to it one chunk at a time. */\nexport interface RecordCounter {\n /** Feed the next chunk of the body, in order. */\n push(chunk: Uint8Array): void;\n /** Records complete in what has been fed so far. */\n readonly records: number;\n /**\n * Whether what has been fed ends where a whole export body ends. A body\n * that stops anywhere else was cut off, whatever its record count says.\n */\n readonly complete: boolean;\n /** Records in the body, once it has ended. Does not change the counter. */\n finish(): number;\n}\n\n/**\n * RFC 4180 CSV with a header line: one record per line, where a field holding\n * `,` `\"` or a line break is quoted and a quote inside it is doubled.\n *\n * A newline inside quotes is part of a field, not the end of a record, so every\n * `\"` toggles \"inside quotes\". A doubled `\"\"` toggles twice and leaves it as it\n * was, which is exactly its meaning. Records are the newlines outside quotes,\n * less one for the header.\n */\nexport class CsvRecordCounter implements RecordCounter {\n private inQuotes = false;\n private newlines = 0;\n /** Whether anything but a line break has arrived since the last newline. */\n private lineHasContent = false;\n\n push(chunk: Uint8Array): void {\n let inQuotes = this.inQuotes;\n let newlines = this.newlines;\n let lineHasContent = this.lineHasContent;\n for (const byte of chunk) {\n if (byte === QUOTE) {\n inQuotes = !inQuotes;\n lineHasContent = true;\n } else if (inQuotes) {\n lineHasContent = true;\n } else if (byte === LF) {\n newlines++;\n lineHasContent = false;\n } else if (byte !== CR) {\n lineHasContent = true;\n }\n }\n this.inQuotes = inQuotes;\n this.newlines = newlines;\n this.lineHasContent = lineHasContent;\n }\n\n get records(): number {\n return Math.max(0, this.newlines - 1);\n }\n\n /**\n * The export writer ends every line — the header and each record — with a\n * newline, so a whole body ends on one, outside quotes. RFC 4180 lets a\n * final line break be omitted, but these bodies never omit it, and without\n * that rule a file cut part-way through its last unquoted field\n * (`pay_1,12` of `pay_1,123`) would count as one more whole record and\n * match the figure it was announced with.\n */\n get complete(): boolean {\n return this.newlines >= 1 && !this.inQuotes && !this.lineHasContent;\n }\n\n /**\n * The records that ended. An unterminated tail is not one of them — see\n * {@link complete}.\n */\n finish(): number {\n return this.records;\n }\n}\n\n/** Before the rows array, inside it, and past its end. */\nconst SEEKING = 0;\nconst COUNTING = 1;\nconst CLOSED = 2;\ntype ArrayState = typeof SEEKING | typeof COUNTING | typeof CLOSED;\n\n/**\n * A JSON object whose rows are an array member — `{\"records\":[…],…}` or\n * `{\"data\":[…],…}`.\n *\n * Counts the elements of the **first** array that is a direct member of the\n * top-level object: each one is counted as it closes back to that array's\n * depth, so a record is counted once it has fully arrived, never on its first\n * byte. Counting stops when that array closes, so an array later in the\n * envelope (inside the echoed `filters`, say) is never mistaken for rows.\n *\n * Strings are tracked with their escapes, so a `}` `]` or `\"` inside a value\n * is text, not structure. Elements are counted when an object or array closes;\n * a bare scalar element is not a record and is not counted.\n */\nexport class JsonArrayRecordCounter implements RecordCounter {\n private depth = 0;\n private inString = false;\n private escaped = false;\n private topIsObject = false;\n private state: ArrayState = SEEKING;\n private count = 0;\n\n push(chunk: Uint8Array): void {\n if (this.state === CLOSED) return;\n let { depth, inString, escaped, topIsObject, count } = this;\n let state: ArrayState = this.state;\n for (const byte of chunk) {\n if (inString) {\n if (escaped) escaped = false;\n else if (byte === BACKSLASH) escaped = true;\n else if (byte === QUOTE) inString = false;\n continue;\n }\n if (byte === QUOTE) {\n inString = true;\n } else if (byte === OPEN_BRACE || byte === OPEN_BRACKET) {\n if (depth === 0 && byte === OPEN_BRACE) topIsObject = true;\n if (byte === OPEN_BRACKET && depth === 1 && topIsObject && state === SEEKING) {\n state = COUNTING;\n }\n depth++;\n } else if (byte === CLOSE_BRACE || byte === CLOSE_BRACKET) {\n depth--;\n if (state === COUNTING) {\n // Depth 2 is the rows array's own level: a value closing back to it\n // is one complete row. Closing to depth 1 is the array itself ending.\n if (depth === 2) count++;\n else if (depth === 1) {\n state = CLOSED;\n break;\n }\n }\n }\n }\n this.depth = depth;\n this.inString = inString;\n this.escaped = escaped;\n this.topIsObject = topIsObject;\n this.state = state;\n this.count = count;\n }\n\n get records(): number {\n return this.count;\n }\n\n /**\n * Whether the rows array has closed. What follows it is checked by parsing\n * the whole document, which a cut-off body fails.\n */\n get complete(): boolean {\n return this.state === CLOSED;\n }\n\n finish(): number {\n return this.count;\n }\n}\n","import { DelopayError } from './error';\nimport type { DownloadProgressEvent, RequestFn, RequestOptions } from './client';\nimport type {\n ExportFormat,\n ExportOptions,\n ExportPresentation,\n ExportProgress,\n ExportTransferOptions,\n} from './types';\nimport { CsvRecordCounter, JsonArrayRecordCounter } from './recordCounter';\nimport type { RecordCounter } from './recordCounter';\n\n/** The header a streamed export announces its record count in. */\nconst RECORD_COUNT_HEADER = 'x-delopay-record-count';\n\n/** The header a PDF export's words travel in. */\nexport const PRESENTATION_HEADER = 'X-Delopay-Export-Presentation';\n\n/**\n * Longest encoded presentation the server reads. A longer one is refused\n * there with `IR_06`; checked here first, so the caller hears it before a\n * request is sent and without a proxy's opinion of a long header in between.\n */\nexport const MAX_PRESENTATION_HEADER = 6 * 1024;\n\n/**\n * `presentation` as the header carries it: base64url, unpadded, of its UTF-8\n * JSON. Rejects with `EXPORT_PRESENTATION_TOO_LARGE` past\n * {@link MAX_PRESENTATION_HEADER}.\n */\nexport function encodePresentation(presentation: ExportPresentation): string {\n const bytes = new TextEncoder().encode(JSON.stringify(presentation));\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n const encoded = btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n if (encoded.length > MAX_PRESENTATION_HEADER) {\n throw new DelopayError(\n `Export presentation is ${encoded.length} bytes encoded; the server reads at most ${MAX_PRESENTATION_HEADER}`,\n {\n status: 0,\n code: 'EXPORT_PRESENTATION_TOO_LARGE',\n type: 'invalid_request',\n data: { encoded_length: encoded.length, max_length: MAX_PRESENTATION_HEADER },\n },\n );\n }\n return encoded;\n}\n\n/**\n * Where a `json` export keeps its rows, and its own count of them.\n *\n * Every list export answers `{\"records\":[…],\"record_count\":N,\"filters\":{…}}`;\n * the disputes workspace answers `{\"data\":[…],\"total_count\":N}`.\n */\nexport interface ExportEnvelopeShape {\n rows: string;\n count: string;\n}\n\n/** `{\"records\":[…],\"record_count\":N,\"filters\":{…}}` — every list export. */\nexport const LIST_ENVELOPE: ExportEnvelopeShape = { rows: 'records', count: 'record_count' };\n\n/** `{\"data\":[…],\"total_count\":N}` — the disputes workspace export. */\nexport const WORKSPACE_ENVELOPE: ExportEnvelopeShape = { rows: 'data', count: 'total_count' };\n\n/** One export request, as the resource method built it. */\nexport interface ExportCall {\n method: string;\n path: string;\n /**\n * The request without its transfer options: filters, headers (`Accept`\n * included) and `responseType`.\n */\n request: RequestOptions;\n format: ExportFormat;\n /** The `json` envelope. Defaults to {@link LIST_ENVELOPE}. */\n envelope?: ExportEnvelopeShape;\n}\n\n/**\n * `X-Delopay-Record-Count` as a count, or `null` when there is none.\n *\n * Only a plain run of digits is a count. Anything else — a value a proxy\n * mangled, two values folded into one — is treated as no announcement rather\n * than guessed at.\n */\nfunction parseRecordCount(header: string | null): number | null {\n if (header === null) return null;\n const trimmed = header.trim();\n if (!/^\\d+$/.test(trimmed)) return null;\n const value = Number(trimmed);\n return Number.isSafeInteger(value) ? value : null;\n}\n\nfunction counterFor(format: ExportFormat): RecordCounter | null {\n if (format === 'csv') return new CsvRecordCounter();\n if (format === 'json') return new JsonArrayRecordCounter();\n return null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** `\" of the N announced\"`, or nothing when the server announced no count. */\nfunction announced(expected: number | null): string {\n return expected === null ? '' : ` of the ${expected} announced`;\n}\n\nfunction incomplete(\n message: string,\n expected: number | null,\n received: number,\n requestId: string | undefined,\n): DelopayError {\n return new DelopayError(message, {\n status: 0,\n code: 'EXPORT_INCOMPLETE',\n type: 'export_incomplete',\n ...(requestId !== undefined ? { requestId } : {}),\n data: { expected_records: expected, received_records: received },\n });\n}\n\n/**\n * Run one export: send it, report its progress, and hold the finished body to\n * the size the server announced before handing it back.\n *\n * The check is the point. These are finance files, and a body that ends short\n * of `X-Delopay-Record-Count` is a file missing rows that would otherwise open,\n * sum and reconcile without a word. It is refused with `EXPORT_INCOMPLETE`\n * rather than returned. For `json` the envelope's own count is held to its\n * rows as well, and a body that is not a whole JSON document is incomplete by\n * definition.\n *\n * `onProgress` hears `preparing` synchronously, before anything is sent — the\n * caller's `async` method runs this far on the call itself.\n */\nexport async function downloadExport<T>(\n request: RequestFn,\n call: ExportCall,\n options: ExportTransferOptions | undefined,\n): Promise<T> {\n const { format } = call;\n const envelope = call.envelope ?? LIST_ENVELOPE;\n const onProgress = options?.onProgress;\n\n let latest: ExportProgress = {\n phase: 'preparing',\n receivedBytes: 0,\n totalBytes: null,\n receivedRecords: 0,\n expectedRecords: null,\n };\n // What the current attempt's headers announced, what its body has\n // delivered, and whether the caller's own listener threw. Kept on an object\n // because the listeners below write it.\n const seen: {\n attempt: number;\n counter: RecordCounter | null;\n expected: number | null;\n requestId: string | undefined;\n listenerError: { error: unknown } | null;\n } = { attempt: -1, counter: null, expected: null, requestId: undefined, listenerError: null };\n\n // A copy each time, so a listener that keeps the snapshots it is given\n // keeps what it was told. What it throws is remembered so it reaches the\n // caller as itself: a `SyntaxError` in a progress bar is not a body that\n // failed to parse.\n const report = (progress: ExportProgress) => {\n latest = progress;\n if (!onProgress) return;\n try {\n onProgress({ ...progress });\n } catch (error) {\n seen.listenerError = { error };\n throw error;\n }\n };\n report(latest);\n\n const onDownloadProgress = (event: DownloadProgressEvent) => {\n if (event.attempt !== seen.attempt) {\n // The headers of a new attempt: a retry starts the body over, so the\n // count does too.\n seen.attempt = event.attempt;\n seen.counter = counterFor(format);\n // A PDF is not counted, so an announced count could only ever fail it.\n seen.expected =\n format === 'pdf' ? null : parseRecordCount(event.headers.get(RECORD_COUNT_HEADER));\n seen.requestId =\n event.headers.get('x-request-id') ?? event.headers.get('x-trace-id') ?? undefined;\n }\n if (event.chunk.byteLength > 0) seen.counter?.push(event.chunk);\n report({\n phase: 'receiving',\n receivedBytes: event.loaded,\n totalBytes: event.total,\n receivedRecords: seen.counter?.records ?? 0,\n expectedRecords: seen.expected,\n });\n };\n\n let result: unknown;\n try {\n result = await request<unknown>(call.method, call.path, {\n ...call.request,\n ...(options?.signal !== undefined ? { signal: options.signal } : {}),\n ...(options?.timeout !== undefined ? { timeout: options.timeout } : {}),\n onDownloadProgress,\n });\n } catch (err) {\n if (seen.listenerError !== null && err === seen.listenerError.error) throw err;\n // The body arrived whole as far as the connection could tell, but it does\n // not parse: it stopped part-way through the document.\n if (format === 'json' && seen.attempt >= 0 && err instanceof SyntaxError) {\n const received = seen.counter?.records ?? 0;\n throw incomplete(\n seen.expected === null\n ? `Export incomplete: the body ended part-way through the JSON document, after ${received} records`\n : `Export incomplete: the server announced ${seen.expected} records, and the body ended part-way through the JSON document after ${received}`,\n seen.expected,\n received,\n seen.requestId,\n );\n }\n throw err;\n }\n\n const { expected, requestId } = seen;\n let received = 0;\n if (format === 'json') {\n // Only the export's own envelope is a JSON export. Anything else — an\n // empty 200, which parses to nothing — delivered no file, and a count of\n // zero records must not be read as a complete empty one.\n const rows = isRecord(result) ? result[envelope.rows] : undefined;\n if (!Array.isArray(rows)) {\n throw incomplete(\n `Export incomplete: the body is not an export envelope with a \"${envelope.rows}\" array, so it carries 0 records${announced(expected)}`,\n expected,\n 0,\n requestId,\n );\n }\n received = rows.length;\n const declared = isRecord(result) ? result[envelope.count] : undefined;\n if (typeof declared === 'number' && declared !== rows.length) {\n throw incomplete(\n `Export incomplete: the file's ${envelope.count} is ${declared}, but it carries ${rows.length} records`,\n declared,\n rows.length,\n requestId,\n );\n }\n } else if (format === 'csv') {\n const counter = seen.counter;\n received = counter?.finish() ?? 0;\n // Checked whether or not a count was announced: every line of an export\n // body ends in a newline, so one that ends anywhere else was cut off.\n if (!counter?.complete) {\n throw incomplete(\n `Export incomplete: the CSV body ended part-way through a line, after ${received} complete records${announced(expected)}`,\n expected,\n received,\n requestId,\n );\n }\n }\n\n if (expected !== null && received !== expected) {\n throw incomplete(\n `Export incomplete: the server announced ${expected} records, and the body carried ${received}`,\n expected,\n received,\n requestId,\n );\n }\n\n report({\n phase: 'done',\n receivedBytes: latest.receivedBytes,\n totalBytes: latest.totalBytes,\n receivedRecords: received,\n expectedRecords: expected,\n });\n return result as T;\n}\n\n/** The media type each format is asked for by name. */\nconst ACCEPT: Record<ExportFormat, string> = {\n csv: 'text/csv',\n json: 'application/json',\n pdf: 'application/pdf',\n};\n\n/**\n * Headers and response handling for one export.\n *\n * The format is negotiated with `Accept`, never a request field. The API's\n * reason is that an export reuses its list's filter model as literally the same\n * type, and several of those are `deny_unknown_fields` — so a `format` key in\n * the query or body is a 400, not an option. That holds for the transactions\n * export too, whose body is the payments list filter.\n *\n * `csv` and `pdf` are not JSON, and the client parses a body as JSON unless it\n * is told otherwise, so a missing `responseType` would be a `SyntaxError` on\n * the first comma rather than a wrong type.\n */\nexport function negotiated(\n options: RequestOptions,\n format: ExportFormat,\n presentation?: ExportPresentation,\n): RequestOptions {\n const headers: Record<string, string> = { ...options.headers, Accept: ACCEPT[format] };\n // Only a PDF prints words; a CSV or JSON file is sent none.\n if (format === 'pdf' && presentation !== undefined) {\n headers[PRESENTATION_HEADER] = encodePresentation(presentation);\n }\n return format === 'json'\n ? { ...options, headers }\n : { ...options, headers, responseType: 'blob' };\n}\n\n/**\n * Send one list export in the format `options` asks for — `json` unless told\n * otherwise — with its progress and its record-count check.\n *\n * `base` is the request as the list would send it: its filters in `body` or\n * `query`, and any header of its own. The format's `Accept` and\n * `responseType` are added here.\n */\nexport function runExport<T>(\n request: RequestFn,\n method: string,\n path: string,\n base: RequestOptions,\n options: ExportOptions | undefined,\n): Promise<T> {\n const format = options?.format ?? 'json';\n return downloadExport<T>(\n request,\n { method, path, request: negotiated(base, format, options?.presentation), format },\n options,\n );\n}\n","import type {\n DisputeResponse,\n DisputeListParams,\n DisputeEvidenceRequest,\n DeleteEvidenceRequest,\n DisputeEvidenceBlock,\n DisputeRefundDeclaration,\n DisputeRefundAssociationRequest,\n DisputeRefundAssociationsResponse,\n DisputeWorkspaceRequest,\n DisputeWorkspaceResponse,\n DisputeWorkspaceFilters,\n DisputeWorkspaceAggregate,\n DisputeWorkspaceExport,\n DynamicWorkspaceExportOptions,\n JsonExportOptions,\n PdfExportOptions,\n} from '../types';\nimport type { RequestFn, RequestOptions } from '../client';\nimport { WORKSPACE_ENVELOPE, downloadExport, negotiated } from '../exportDownload';\n\n/** Workspace filters use CSV values, unlike the transport's repeated-key arrays. */\nfunction workspaceQuery(params?: DisputeWorkspaceRequest): RequestOptions['query'] {\n if (!params) return undefined;\n const { connector, currency, dispute_status, dispute_stage, ...query } = params;\n return {\n ...query,\n ...(connector?.length ? { connector: connector.join(',') } : {}),\n ...(currency?.length ? { currency: currency.join(',') } : {}),\n ...(dispute_status?.length ? { dispute_status: dispute_status.join(',') } : {}),\n ...(dispute_stage?.length ? { dispute_stage: dispute_stage.join(',') } : {}),\n };\n}\n\n/** View and respond to payment disputes and chargebacks. */\nexport class Disputes {\n constructor(private readonly request: RequestFn) {}\n\n /** Read native disputes and provider-only cases once, after shared authorization and filters. */\n async workspace(params?: DisputeWorkspaceRequest): Promise<DisputeWorkspaceResponse> {\n return this.request('GET', '/disputes/workspace', { query: workspaceQuery(params) });\n }\n\n /** Read filter options over the same scoped case set; pagination is ignored. */\n async workspaceFilters(params?: DisputeWorkspaceRequest): Promise<DisputeWorkspaceFilters> {\n return this.request('GET', '/disputes/workspace/filters', { query: workspaceQuery(params) });\n }\n\n /** Count the filtered case set, including unknown outcomes; pagination is ignored. */\n async workspaceAggregate(params?: DisputeWorkspaceRequest): Promise<DisputeWorkspaceAggregate> {\n return this.request('GET', '/disputes/workspace/aggregate', { query: workspaceQuery(params) });\n }\n\n /**\n * Export the complete filtered set, or throw on the server's explicit\n * export-limit refusal. `GET /disputes/workspace/export`\n *\n * The body is streamed, and held to the `X-Delopay-Record-Count` the server\n * announces and to its own `total_count`: a set that arrives short rejects\n * with `EXPORT_INCOMPLETE` rather than resolving. `options` reports the\n * download's progress and takes a signal and an idle timeout — see\n * {@link ExportTransferOptions}.\n *\n * `format: 'pdf'` resolves to the same set laid out as a document (a\n * `Blob`), with the words in `options.presentation` — see\n * {@link ExportPresentation}. This route offers no CSV.\n */\n async workspaceExport(\n params?: DisputeWorkspaceRequest,\n options?: JsonExportOptions,\n ): Promise<DisputeWorkspaceExport>;\n async workspaceExport(\n params: DisputeWorkspaceRequest | undefined,\n options: PdfExportOptions,\n ): Promise<Blob>;\n async workspaceExport(\n params: DisputeWorkspaceRequest | undefined,\n options: DynamicWorkspaceExportOptions,\n ): Promise<DisputeWorkspaceExport | Blob>;\n async workspaceExport(\n params?: DisputeWorkspaceRequest,\n options?: JsonExportOptions | PdfExportOptions | DynamicWorkspaceExportOptions,\n ): Promise<DisputeWorkspaceExport | Blob> {\n const format = options?.format ?? 'json';\n return downloadExport(\n this.request,\n {\n method: 'GET',\n path: '/disputes/workspace/export',\n request: negotiated({ query: workspaceQuery(params) }, format, options?.presentation),\n format,\n envelope: WORKSPACE_ENVELOPE,\n },\n options,\n );\n }\n\n /**\n * Retrieve a dispute by its ID.\n *\n * @param disputeId - The unique dispute ID.\n * @returns The dispute.\n */\n async retrieve(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`);\n }\n\n /** Read declared links and provider-reported refund references. Empty means unknown. */\n async listRefundAssociations(disputeId: string): Promise<DisputeRefundAssociationsResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}/refund-associations`);\n }\n\n /** Declare or clear an allocation against a successful refund of this payment. */\n async setRefundAssociation(\n disputeId: string,\n params: DisputeRefundAssociationRequest,\n ): Promise<DisputeRefundDeclaration> {\n return this.request('PUT', `/disputes/${encodeURIComponent(disputeId)}/refund-associations`, {\n body: params,\n });\n }\n\n /**\n * List disputes, optionally filtered by status, stage, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of disputes.\n */\n async list(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * Accept a dispute, conceding the chargeback to the customer.\n *\n * @param disputeId - The dispute ID to accept.\n * @returns The updated dispute.\n */\n async accept(disputeId: string): Promise<DisputeResponse> {\n return this.request('POST', `/disputes/accept/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Submit evidence to challenge a dispute.\n *\n * @param params - Evidence details and the dispute ID to contest.\n * @returns The updated dispute.\n */\n async submitEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('POST', '/disputes/evidence', { body: params });\n }\n\n /**\n * Attach evidence (e.g. file upload metadata) to a dispute.\n *\n * Uses `PUT /disputes/evidence`.\n */\n async attachEvidence(params: DisputeEvidenceRequest): Promise<DisputeResponse> {\n return this.request('PUT', '/disputes/evidence', { body: params });\n }\n\n /**\n * Retrieve previously stored evidence for a dispute.\n *\n * Returns an ARRAY of file-evidence blocks (this was previously mistyped\n * as the flat submit-request shape). Only file evidence is reported —\n * text evidence is not retrievable once submitted.\n *\n * @param disputeId - The dispute ID.\n * @returns The stored file-evidence blocks.\n */\n async retrieveEvidence(disputeId: string): Promise<DisputeEvidenceBlock[]> {\n return this.request('GET', `/disputes/evidence/${encodeURIComponent(disputeId)}`);\n }\n\n /**\n * Delete submitted evidence for a dispute.\n *\n * @param params - Evidence request body identifying what to delete.\n * @returns The updated dispute.\n */\n async deleteEvidence(params: DeleteEvidenceRequest): Promise<DisputeResponse> {\n return this.request('DELETE', '/disputes/evidence', { body: params });\n }\n\n // --- OLAP extensions (Task 4.4) ---\n\n /** List disputes (profile-scoped). `GET /disputes/profile/list` */\n async listByProfile(params?: DisputeListParams): Promise<DisputeResponse[]> {\n return this.request('GET', '/disputes/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** Get dispute filter options. `GET /disputes/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/filter', { query: params });\n }\n\n /** Get dispute filters (profile-scoped). `GET /disputes/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/filter', { query: params });\n }\n\n /** Get dispute aggregates. `GET /disputes/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/aggregate', { query: params });\n }\n\n /** Get dispute aggregates (profile-scoped). `GET /disputes/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/disputes/profile/aggregate', { query: params });\n }\n\n /**\n * Fetch the latest dispute state from the connector (gateway) and persist it.\n * `GET /disputes/{disputeId}?force_sync=true`\n *\n * The path parameter is the **Delopay dispute id** (`dp_…`). Force-sync asks the\n * backend to pull the dispute from the connector (supported where the connector\n * implements the dispute-sync flow, e.g. Stripe) and update the stored record\n * before returning it.\n *\n * Note: this method previously called `GET /disputes/{id}/fetch`, which is a\n * different backend route — a bulk import keyed by **merchant connector account\n * id** with a required date range — so every call with a dispute id failed.\n */\n async fetchFromConnector(disputeId: string): Promise<DisputeResponse> {\n return this.request('GET', `/disputes/${encodeURIComponent(disputeId)}`, {\n query: { force_sync: 'true' },\n });\n }\n}\n","import type { RequestFn } from '../client';\nimport type {\n PaypalDisputeCase,\n PaypalDisputeListRequest,\n PaypalDisputeImportRequest,\n PaypalDisputeImportResponse,\n PaypalDisputeActionRequest,\n PaypalDisputeActionResponse,\n PaypalDisputeActionRecord,\n PaypalDisputeDocument,\n PaypalDisputeDownloadRequest,\n} from '../types';\n\n/**\n * PayPal seller cases, including external and subscription sales.\n * Every operation honors the caller's connector-account grants.\n */\nexport class PaypalDisputes {\n constructor(private readonly request: RequestFn) {}\n actions(caseId: string, offset = 0): Promise<PaypalDisputeActionRecord[]> {\n return this.request('GET', `/disputes/paypal/cases/${encodeURIComponent(caseId)}/actions`, {\n query: { offset },\n });\n }\n download(caseId: string, documentUrl: string): Promise<PaypalDisputeDocument> {\n const body: PaypalDisputeDownloadRequest = { document_url: documentUrl };\n return this.request(\n 'POST',\n `/disputes/paypal/cases/${encodeURIComponent(caseId)}/documents/download`,\n { body },\n );\n }\n list(params?: PaypalDisputeListRequest): Promise<PaypalDisputeCase[]> {\n return this.request('GET', '/disputes/paypal/cases', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n retrieve(caseId: string, forceSync = false): Promise<PaypalDisputeCase> {\n return this.request('GET', `/disputes/paypal/cases/${encodeURIComponent(caseId)}`, {\n query: { force_sync: forceSync },\n });\n }\n history(caseId: string, offset = 0): Promise<PaypalDisputeCase[]> {\n return this.request('GET', `/disputes/paypal/cases/${encodeURIComponent(caseId)}/history`, {\n query: { offset },\n });\n }\n import(params: PaypalDisputeImportRequest): Promise<PaypalDisputeImportResponse> {\n return this.request('POST', '/disputes/paypal/import', { body: params });\n }\n /** The backend checks current provider permissions and deduplicates request_id.\n * An unknown result requires reconciliation, not a new request ID.\n */\n act(caseId: string, params: PaypalDisputeActionRequest): Promise<PaypalDisputeActionResponse> {\n return this.request('POST', `/disputes/paypal/cases/${encodeURIComponent(caseId)}/actions`, {\n body: params,\n });\n }\n}\n","import type { RequestFn } from '../client';\nimport type {\n WhopResolutionCase,\n WhopResolutionCaseActionRequest,\n WhopResolutionCaseActionResponse,\n WhopResolutionCaseEventList,\n WhopResolutionCaseEventsRequest,\n WhopResolutionCaseList,\n WhopResolutionCaseListRequest,\n WhopResolutionCaseLocator,\n} from '../types';\n\n/**\n * Whop Resolution Center cases: a buyer's claim before any chargeback. Read\n * and answered live through one Whop connector account and environment.\n * Every operation honors the caller's connector-account grants and shop scope.\n */\nexport class WhopResolutionCases {\n constructor(private readonly request: RequestFn) {}\n\n /** GET /disputes/whop/cases — newest first, one Whop page at a time. */\n list(params: WhopResolutionCaseListRequest): Promise<WhopResolutionCaseList> {\n return this.request('GET', '/disputes/whop/cases', {\n query: { ...params },\n });\n }\n\n /** GET /disputes/whop/cases/{case_id} — the case as Whop reports it now. */\n retrieve(caseId: string, locator: WhopResolutionCaseLocator): Promise<WhopResolutionCase> {\n return this.request('GET', `/disputes/whop/cases/${encodeURIComponent(caseId)}`, {\n query: { ...locator },\n });\n }\n\n /** GET /disputes/whop/cases/{case_id}/events — the case timeline, newest first. */\n events(\n caseId: string,\n params: WhopResolutionCaseEventsRequest,\n ): Promise<WhopResolutionCaseEventList> {\n return this.request('GET', `/disputes/whop/cases/${encodeURIComponent(caseId)}/events`, {\n query: { ...params },\n });\n }\n\n /**\n * POST /disputes/whop/cases/{case_id}/actions — accept, deny, reply or\n * request info. `accept` refunds the payment in full at Whop. An `unknown`\n * outcome is retried with the same `request_id`.\n */\n act(\n caseId: string,\n params: WhopResolutionCaseActionRequest,\n ): Promise<WhopResolutionCaseActionResponse> {\n return this.request('POST', `/disputes/whop/cases/${encodeURIComponent(caseId)}/actions`, {\n body: params,\n });\n }\n}\n","import type { EphemeralKeyCreateRequest, EphemeralKeyCreateResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create short-lived ephemeral keys for secure client-side operations.\n *\n * Ephemeral keys grant a mobile or browser client temporary access to a\n * specific customer's data (e.g. to display saved payment methods) without\n * exposing your secret API key.\n *\n * The key is confined to the customer it was minted for, and that is\n * enforced on every customer and payment-method route: a request for another\n * customer — or for a payment method belonging to one — is refused rather\n * than served. Mint one key per customer; do not reuse a key across them.\n */\nexport class EphemeralKeys {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create an ephemeral key scoped to a specific customer.\n *\n * @param params - Customer ID and optional expiry.\n * @returns The ephemeral key with its plaintext secret and expiry timestamp.\n *\n * @example\n * ```typescript\n * const ephKey = await delopay.ephemeralKeys.create({ customer_id: 'cus_123' });\n * // Pass ephKey.secret to your mobile app.\n * ```\n */\n async create(params: EphemeralKeyCreateRequest): Promise<EphemeralKeyCreateResponse> {\n return this.request('POST', '/ephemeral-keys', { body: params });\n }\n\n /**\n * Invalidate an ephemeral key before it expires.\n *\n * @param keyId - The ephemeral key ID to delete.\n * @returns The deleted key object.\n */\n async delete(keyId: string): Promise<EphemeralKeyCreateResponse> {\n return this.request('DELETE', `/ephemeral-keys/${encodeURIComponent(keyId)}`);\n }\n}\n","import type {\n EventListParams,\n EventListResponse,\n EventDeliveryAttemptResponse,\n EventDetailResponse,\n EventManualTriggerRequest,\n EventManualTriggerResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Events {\n constructor(private readonly request: RequestFn) {}\n\n async list(merchantId: string, params?: EventListParams): Promise<EventListResponse> {\n return this.request('POST', `/events/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n async listDeliveryAttempts(\n merchantId: string,\n eventId: string,\n ): Promise<EventDeliveryAttemptResponse[]> {\n return this.request(\n 'GET',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/attempts`,\n );\n }\n\n async retryDelivery(merchantId: string, eventId: string): Promise<EventDetailResponse> {\n return this.request(\n 'POST',\n `/events/${encodeURIComponent(merchantId)}/${encodeURIComponent(eventId)}/retry`,\n );\n }\n\n /**\n * Fire an outgoing webhook event by hand for one object.\n * `POST /events/{merchant_id}/trigger`\n *\n * Not a replay — see {@link EventManualTriggerRequest}. Needs the\n * `WebhookEventTrigger` permission, which is separate from the one that\n * authorizes {@link retryDelivery}, and is JWT-only: a forged payload must\n * be attributable to a person.\n */\n async trigger(\n merchantId: string,\n body: EventManualTriggerRequest,\n ): Promise<EventManualTriggerResponse> {\n return this.request('POST', `/events/${encodeURIComponent(merchantId)}/trigger`, { body });\n }\n\n // --- Profile-scoped listing (Task 4.12) ---\n\n /**\n * List events (profile-scoped). `POST /events/profile/list`\n *\n * Takes the same constraints as {@link list} — it is the same endpoint\n * narrowed to the caller's own shop, so `profile_id` is redundant and\n * ignored there.\n */\n async listByProfile(params?: EventListParams): Promise<EventListResponse> {\n return this.request('POST', '/events/profile/list', { body: params });\n }\n\n /**\n * Fire an outgoing webhook event by hand (profile-scoped).\n * `POST /events/profile/trigger`\n *\n * The shop-user twin of {@link trigger}; the shop is taken from the auth\n * context, so `profile_id` on the body is ignored.\n */\n async triggerByProfile(body: EventManualTriggerRequest): Promise<EventManualTriggerResponse> {\n return this.request('POST', '/events/profile/trigger', { body });\n }\n}\n","import type {\n FeeRulePreviewRequest,\n FeeRulePreviewResponse,\n FeeScheduleCreateRequest,\n FeeScheduleResponse,\n FeeScheduleUpdateRequest,\n PlatformFeeRuleInput,\n PlatformFeeRuleRecord,\n PlatformFeeRuleRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant-scoped fee schedules. Each schedule optionally targets a\n * specific shop (via `shop_id`). Merchants can CRUD their own fee\n * overrides; platform-wide fee programs are administered by Delopay and\n * not exposed here.\n *\n * `fees.rules` manages the merchant-owned Euclid fee-rule program, which takes\n * precedence over the flat schedules above. A program is scoped either to one\n * shop (`profile_id`) or merchant-wide; a shop-scoped program wins for that\n * shop, otherwise the merchant-wide one applies. Build the program with the\n * `feeProgram()` helper.\n */\nexport class Fees {\n /** Merchant-owned Euclid fee-rule program (`/merchant-fees/rules`). */\n readonly rules: FeeRulesManager;\n\n constructor(private readonly request: RequestFn) {\n this.rules = new FeeRulesManager(request);\n }\n\n /**\n * Create a merchant-scoped fee schedule (optionally per-shop).\n *\n * @param params - Fee schedule parameters.\n * @param merchantId - The merchant account ID.\n */\n async create(params: FeeScheduleCreateRequest, merchantId: string): Promise<FeeScheduleResponse> {\n return this.request('POST', '/merchant-fees', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * List the merchant's own fee schedules.\n *\n * @param merchantId - The merchant account ID.\n */\n async list(merchantId: string): Promise<FeeScheduleResponse[]> {\n return this.request('GET', '/merchant-fees/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Update a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n * @param params - Fields to update.\n */\n async update(feeId: string, params: FeeScheduleUpdateRequest): Promise<FeeScheduleResponse> {\n return this.request('PUT', `/merchant-fees/${encodeURIComponent(feeId)}`, { body: params });\n }\n\n /**\n * Delete a merchant-scoped fee schedule.\n *\n * @param feeId - The fee schedule ID.\n */\n async delete(feeId: string): Promise<FeeScheduleResponse> {\n return this.request('DELETE', `/merchant-fees/${encodeURIComponent(feeId)}`);\n }\n}\n\n/**\n * Manages a merchant's Euclid fee-rule programs (merchant-wide or per-shop, one\n * active program per scope). Build the `algorithm` with `feeProgram()`. The SDK\n * injects `fee_owner: 'merchant'`; set `profile_id` on the input to scope a\n * program to a shop.\n */\nexport class FeeRulesManager {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the merchant's fee-rule program (a new active version;\n * the previous version is deactivated server-side).\n *\n * @param params - The program plus optional name / shop scope / validity window.\n * @param merchantId - The merchant account ID.\n */\n async upsert(params: PlatformFeeRuleInput, merchantId: string): Promise<PlatformFeeRuleRecord> {\n const body: PlatformFeeRuleRequest = { ...params, fee_owner: 'merchant' };\n return this.request('PUT', '/merchant-fees/rules', {\n body,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve the active fee-rule program for a scope, or `null` if none.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit for the\n * merchant-wide program; pass a shop id to get that shop's program.\n */\n async retrieve(merchantId: string, profileId?: string): Promise<PlatformFeeRuleRecord | null> {\n return this.request('GET', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Deactivate a fee-rule program (falls back to the flat fee schedules /\n * volume tier). Idempotent.\n *\n * @param merchantId - The merchant account ID.\n * @param profileId - Optional shop (`profile_id`) scope. Omit to target the\n * merchant-wide program; pass a shop id to delete only that shop's program\n * (other shops' programs are left intact).\n */\n async delete(merchantId: string, profileId?: string): Promise<void> {\n await this.request('DELETE', '/merchant-fees/rules', {\n query: { merchant_id: merchantId, profile_id: profileId },\n });\n }\n\n /**\n * Dry-run a candidate fee-rule program against a sample transaction.\n * Returns the matched rule name, whether it fell through, and the computed fee.\n * Does not persist anything.\n *\n * @param input - Candidate program + sample transaction fields.\n * @param merchantId - The merchant account ID.\n */\n async preview(input: FeeRulePreviewRequest, merchantId: string): Promise<FeeRulePreviewResponse> {\n return this.request('POST', '/merchant-fees/rules/preview', {\n body: input,\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type { MandateResponse, MandateRevokedResponse, MandateListParams } from '../types';\nimport type { RequestFn } from '../client';\n\n/** View and revoke recurring payment mandates. */\nexport class Mandates {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a mandate by its ID.\n *\n * @param mandateId - The unique mandate ID.\n * @returns The mandate.\n */\n async retrieve(mandateId: string): Promise<MandateResponse> {\n return this.request('GET', `/mandates/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * Revoke an active mandate, preventing future charges.\n *\n * @param mandateId - The mandate ID to revoke.\n * @returns Revocation confirmation.\n */\n async revoke(mandateId: string): Promise<MandateRevokedResponse> {\n return this.request('POST', `/mandates/revoke/${encodeURIComponent(mandateId)}`);\n }\n\n /**\n * List mandates, optionally filtered by customer or status.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Array of mandates.\n */\n async list(params?: MandateListParams): Promise<MandateResponse[]> {\n return this.request('GET', '/mandates/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n}\n","import type {\n MerchantAccountCreateRequest,\n MerchantAccountResponse,\n MerchantAccountUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class MerchantAccounts {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: MerchantAccountCreateRequest): Promise<MerchantAccountResponse> {\n return this.request('POST', '/accounts', { body: params });\n }\n\n async retrieve(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n async update(\n accountId: string,\n params: MerchantAccountUpdateRequest,\n ): Promise<MerchantAccountResponse> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}`, { body: params });\n }\n\n async delete(accountId: string): Promise<MerchantAccountResponse> {\n return this.request('DELETE', `/accounts/${encodeURIComponent(accountId)}`);\n }\n\n // --- Advanced operations (Task 4.9) ---\n\n /** List all merchant accounts. `GET /accounts/list` */\n async list(): Promise<MerchantAccountResponse[]> {\n return this.request('GET', '/accounts/list');\n }\n\n /** Toggle key-value store for a merchant. `POST /accounts/{accountId}/kv` */\n async toggleKv(accountId: string): Promise<Record<string, unknown>> {\n return this.request('POST', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Get KV status for a merchant. `GET /accounts/{accountId}/kv` */\n async getKvStatus(accountId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/accounts/${encodeURIComponent(accountId)}/kv`);\n }\n\n /** Transfer keys between merchants. `POST /accounts/transfer` */\n async transferKeys(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/accounts/transfer', { body: params });\n }\n}\n","import type {\n CheckoutLinkResolveResponse,\n PaymentLinkResponse,\n PaymentLinkListParams,\n PaymentLinkListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Retrieve and list hosted payment links. */\nexport class PaymentLinks {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Retrieve a payment link by its ID.\n *\n * @param linkId - The unique payment link ID.\n * @returns The payment link details.\n */\n async retrieve(linkId: string): Promise<PaymentLinkResponse> {\n return this.request('GET', `/payment-link/${encodeURIComponent(linkId)}`);\n }\n\n /**\n * The merchant and payment an opaque checkout link opens.\n *\n * A link the API issues today is `/pay/{payment_link_id}`, so it names\n * neither the merchant nor the payment. This answers which ones it means.\n * Unauthenticated, like the checkout render it precedes: no credential is\n * needed or sent beyond what the client already carries. An unknown id is a\n * 404.\n *\n * `GET /payment-link/resolve/{payment_link_id}`\n */\n async resolve(paymentLinkId: string): Promise<CheckoutLinkResolveResponse> {\n return this.request('GET', `/payment-link/resolve/${encodeURIComponent(paymentLinkId)}`);\n }\n\n /**\n * List payment links, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payment links.\n */\n async list(params?: PaymentLinkListParams): Promise<PaymentLinkListResponse> {\n return this.request('POST', '/payment-link/list', { body: params });\n }\n\n /** Initiate (render) a payment link page. `GET /payment-link/{merchantId}/{paymentId}` */\n async initiate(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n\n /** Get payment link status. `GET /payment-link/status/{merchantId}/{paymentId}` */\n async status(merchantId: string, paymentId: string): Promise<Record<string, unknown>> {\n return this.request(\n 'GET',\n `/payment-link/status/${encodeURIComponent(merchantId)}/${encodeURIComponent(paymentId)}`,\n );\n }\n}\n","import type {\n PaymentMethodCreateRequest,\n PaymentMethodResponse,\n PaymentMethodUpdateRequest,\n PaymentMethodListParams,\n PaymentMethodListResponse,\n PaymentMethodDeleteResponse,\n CustomerPaymentMethodsListParams,\n CustomerPaymentMethodsListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage saved payment methods for customers. */\nexport class PaymentMethods {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Save a new payment method (card, bank account, wallet, etc.).\n *\n * @param params - Payment method data including type and card/bank details.\n * @returns The saved payment method.\n *\n * @example\n * ```typescript\n * const pm = await delopay.paymentMethods.create({\n * payment_method: 'card',\n * customer_id: 'cus_123',\n * client_secret: 'cs_...',\n * });\n * ```\n */\n async create(params: PaymentMethodCreateRequest): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods', { body: params });\n }\n\n /**\n * Retrieve a saved payment method by its ID.\n *\n * @param methodId - The payment method ID.\n * @returns The payment method.\n */\n async retrieve(methodId: string): Promise<PaymentMethodResponse> {\n return this.request('GET', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * Update an existing payment method (e.g. update card expiry).\n *\n * @param methodId - The payment method ID to update.\n * @param params - Fields to update (card expiry, holder name, etc.).\n * @returns The updated payment method.\n */\n async update(\n methodId: string,\n params: PaymentMethodUpdateRequest,\n ): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/update`, {\n body: params,\n });\n }\n\n /**\n * Delete a saved payment method.\n *\n * @param methodId - The payment method ID to delete.\n * @returns Deletion confirmation.\n */\n async delete(methodId: string): Promise<PaymentMethodDeleteResponse> {\n return this.request('DELETE', `/payment-methods/${encodeURIComponent(methodId)}`);\n }\n\n /**\n * List the payment methods available for a payment — the discovery endpoint a\n * custom checkout renders its tiles from.\n *\n * Callable with a publishable key plus the payment's `client_secret`, so it\n * runs from the browser. The returned set is already filtered by country,\n * order value and the merchant's availability rules, and each entry carries\n * `display` (name + icon slug) and `amount_limits` (the order values it stays\n * available for) so you do not have to maintain either alongside.\n *\n * This is *not* the customer's saved methods — see {@link listForCustomer}.\n *\n * @param params - `client_secret`, plus optional `country`, `amount` and filters.\n * @returns The methods available for the payment, grouped by payment method.\n *\n * @example\n * ```typescript\n * const { payment_methods } = await delopay.paymentMethods.list({\n * client_secret: 'pay_abc_secret_xyz',\n * country: 'DE',\n * amount: 25000,\n * });\n *\n * for (const group of payment_methods) {\n * for (const method of group.payment_method_types) {\n * // Re-check availability yourself as the cart total changes, instead of\n * // re-listing on every keystroke.\n * const limits = method.amount_limits;\n * const available =\n * !limits ||\n * ((limits.min_amount == null || cartTotal >= limits.min_amount) &&\n * (limits.max_amount == null || cartTotal <= limits.max_amount) &&\n * !limits.excluded_ranges.some(\n * (band) => cartTotal >= band.min_amount && cartTotal <= band.max_amount,\n * ));\n *\n * if (available) render(method.display?.display_name, method.display?.icon_slug);\n * }\n * }\n * ```\n */\n async list(params?: PaymentMethodListParams): Promise<PaymentMethodListResponse> {\n return this.request('GET', '/payment-methods', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /**\n * List all saved payment methods for a customer, optionally filtered.\n *\n * @param customerId - The customer ID.\n * @param params - Optional filters: `client_secret`, `accepted_countries`, `accepted_currencies`,\n * `amount`, `recurring_enabled`, `installment_payment_enabled`, `limit`, `card_networks`.\n * @returns Customer's saved payment methods.\n *\n * @example\n * ```typescript\n * const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(\n * 'cus_123',\n * { accepted_currencies: ['EUR'], amount: 5000 },\n * );\n * ```\n */\n async listForCustomer(\n customerId: string,\n params?: CustomerPaymentMethodsListParams,\n ): Promise<CustomerPaymentMethodsListResponse> {\n return this.request('GET', `/customers/${encodeURIComponent(customerId)}/payment-methods`, {\n query: params as Record<\n string,\n string | number | boolean | (string | number | boolean)[] | null | undefined\n >,\n });\n }\n\n /**\n * Set a payment method as the default for a customer.\n *\n * @param customerId - The customer ID.\n * @param methodId - The payment method ID to set as default.\n * @returns The updated payment method.\n */\n async setDefault(customerId: string, methodId: string): Promise<PaymentMethodResponse> {\n return this.request(\n 'POST',\n `/customers/${encodeURIComponent(customerId)}/payment-methods/${encodeURIComponent(methodId)}/default`,\n );\n }\n\n // --- Advanced operations (Task 3.3) ---\n\n /** Migrate a payment method. `POST /payment-methods/migrate` */\n async migrate(params: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', '/payment-methods/migrate', { body: params });\n }\n\n /** Batch migrate payment methods. `POST /payment-methods/migrate-batch` */\n async migrateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/migrate-batch', { body: params });\n }\n\n /** Batch update payment methods. `POST /payment-methods/update-batch` */\n async updateBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/update-batch', { body: params });\n }\n\n /** Batch retrieve payment methods. `GET /payment-methods/batch` */\n async batchRetrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<PaymentMethodResponse[]> {\n return this.request('GET', '/payment-methods/batch', { query: params });\n }\n\n /** Tokenize a card. `POST /payment-methods/tokenize-card` */\n async tokenizeCard(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card', { body: params });\n }\n\n /** Batch tokenize cards. `POST /payment-methods/tokenize-card-batch` */\n async tokenizeCardBatch(params: Record<string, unknown>[]): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/tokenize-card-batch', { body: params });\n }\n\n /** Initiate payment method collect link flow. `POST /payment-methods/collect` */\n async collect(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/collect', { body: params });\n }\n\n /** Save a payment method. `POST /payment-methods/{methodId}/save` */\n async save(methodId: string, params?: Record<string, unknown>): Promise<PaymentMethodResponse> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/save`, {\n body: params,\n });\n }\n\n /** Create payment method auth link token. `POST /payment-methods/auth/link` */\n async createAuthLink(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/link', { body: params });\n }\n\n /** Exchange payment method auth token. `POST /payment-methods/auth/exchange` */\n async exchangeAuthToken(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payment-methods/auth/exchange', { body: params });\n }\n\n /** Tokenize card using existing PM. `POST /payment-methods/{methodId}/tokenize-card` */\n async tokenizeCardForMethod(\n methodId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payment-methods/${encodeURIComponent(methodId)}/tokenize-card`, {\n body: params,\n });\n }\n}\n","import type {\n PaymentClientContextListResponse,\n PaymentCreateRequest,\n ProductPaymentCreateRequest,\n ProductsPaymentCreateRequest,\n PaymentListFilterConstraints,\n PaymentListFilteredResponse,\n ProfilePaymentListFilterConstraints,\n PaymentListResponse,\n PaymentResponse,\n PaymentProductLines,\n PaymentRetrieveOptions,\n PaymentUpdateRequest,\n PaymentConfirmRequest,\n PaymentCaptureRequest,\n PaymentCancelRequest,\n PaymentListParams,\n PaymentAttemptsListResponse,\n PaymentConnectorSettlementResponse,\n PaymentsDeletePolicyResponse,\n PaymentsDeleteResponse,\n PaymentStatusHistoryResponse,\n PaymentRoutingDecisionsResponse,\n ReplayPlaybackResponse,\n ReplaySliceResponse,\n PaymentListFiltersExt,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage payment intents — create, confirm, capture, cancel, and list payments. */\nexport class Payments {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payment intent.\n *\n * @param params - An explicit amount and currency, or a DeloPay one-time\n * product whose active price supplies both on the server.\n * @param options - Optional per-call extras: extra `headers` (e.g. an\n * `Idempotency-Key` to make the create safe to retry), a `timeout` override,\n * and an `AbortSignal`.\n * @returns The created payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.create(\n * { amount: 5000, currency: 'EUR', customer_id: 'cus_123' },\n * { headers: { 'Idempotency-Key': 'order_1001' } },\n * );\n * ```\n *\n * @example Charge the active default price of a shop-owned product without\n * copying the product to the payment provider:\n * ```typescript\n * const payment = await delopay.payments.create({\n * product_id: 'prd_123',\n * profile_id: 'pro_123',\n * payment_link: true,\n * });\n * ```\n *\n * @example Send `test_mode` to pick the environment per payment, so a staging\n * deploy cannot charge real cards and a forgotten processor toggle cannot\n * swallow production traffic:\n * ```typescript\n * const payment = await delopay.payments.create({\n * amount: 5000,\n * currency: 'EUR',\n * test_mode: process.env.NODE_ENV !== 'production',\n * });\n * ```\n *\n * A payment that pins one connector through `routing` (the `single` form)\n * is now checked against `test_mode` here rather than at confirm: if that\n * connector has no credentials for the environment asked for, create fails\n * instead of handing back a payment whose checkout the buyer cannot\n * complete. `priority` and `volume_split` name several accounts and are\n * still resolved at confirm.\n */\n async create(\n params: PaymentCreateRequest | ProductPaymentCreateRequest | ProductsPaymentCreateRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.request('POST', '/payments', { body: params, ...options });\n }\n\n /**\n * Retrieve a payment by its ID.\n *\n * @param paymentId - The unique payment intent ID.\n * @param options - Optional query flags. `force_sync` reconciles the\n * intent's state with the connector before returning (useful to recover\n * a stuck intent when a webhook was lost). `all_keys_required` forces a\n * connector sync even for intents in early states like\n * `requires_payment_method` that would otherwise return the local\n * snapshot. Both flags work with JWT and API-key authentication.\n * @returns The payment intent.\n *\n * @example\n * ```typescript\n * const payment = await delopay.payments.retrieve('pay_abc123');\n * const synced = await delopay.payments.retrieve('pay_abc123', {\n * force_sync: true,\n * all_keys_required: true,\n * });\n * ```\n */\n async retrieve(paymentId: string, options?: PaymentRetrieveOptions): Promise<PaymentResponse> {\n const path = `/payments/${encodeURIComponent(paymentId)}`;\n if (options === undefined) return this.request('GET', path);\n const query: Record<string, boolean> = {};\n if (options.force_sync !== undefined) query['force_sync'] = options.force_sync;\n if (options.all_keys_required !== undefined) {\n query['all_keys_required'] = options.all_keys_required;\n }\n if (Object.keys(query).length === 0) return this.request('GET', path);\n return this.request('GET', path, { query });\n }\n\n /** Product names and prices as frozen when the payment was created. */\n async productLines(paymentId: string): Promise<PaymentProductLines> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/lines`);\n }\n\n /**\n * List every attempt made on a payment, each with its full failure detail\n * (`error_code` / `error_message`, the Delopay-unified `unified_code` and\n * `unified_message`, and structured `error_details`).\n *\n * Useful for surfacing retries across connectors — e.g. \"attempt 1 stripe →\n * insufficient_funds, attempt 2 adyen → success\".\n *\n * `GET /payments/{paymentId}/attempts`\n *\n * @param paymentId - The payment intent ID whose attempts to list.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n * @returns The attempt list — `size` plus a `data` array of attempts.\n * @throws If the payment does not exist or belongs to another merchant (404).\n *\n * @example\n * ```typescript\n * const { size, data } = await delopay.payments.listAttempts('pay_abc123');\n * for (const attempt of data) {\n * console.log(attempt.status, attempt.unified_message ?? attempt.error_message);\n * }\n * ```\n */\n async listAttempts(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentAttemptsListResponse> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/attempts`, options);\n }\n\n /**\n * The status timeline of a payment: every recorded creation / status\n * transition of the intent and its attempts, refunds and disputes, oldest\n * first. `complete: false` marks timelines partially reconstructed from\n * current records (payments created before the status log existed).\n *\n * @param paymentId - The payment intent ID.\n * @returns The ordered status-history events.\n *\n * @example\n * ```typescript\n * const { events, complete } = await delopay.payments.listStatusHistory('pay_abc123');\n * for (const event of events) {\n * console.log(event.timestamp, event.entity_type, event.status);\n * }\n * ```\n */\n async listStatusHistory(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentStatusHistoryResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/status-history`,\n options,\n );\n }\n\n /**\n * What the payment's rail says about settling each attempt: whether the\n * money is still `pending` in the rail's hands, `available` in its balance\n * (**not** paid out), `paid_out` to a bank — with the payout's date and\n * reference — or came back as `payout_failed`; and, for the rest, which\n * kind of not-knowing applies (`unavailable`, `unknown`, `not_recorded`).\n * See {@link ConnectorSettlementStatus} for the seven values. The same\n * status for the active attempt rides on every list row and retrieve as\n * `connector_settlement_status`, and the list filters on it.\n *\n * Not the hosted-shop settlement API under `settlement.*`, which is host →\n * shop owner and manual; this is acquirer → merchant bank, per payment.\n *\n * Each attempt also carries what the rail itself took for it —\n * `processor_cost_amount` with its own `processor_cost_currency` and\n * `processor_cost_exponent`, the `processor_cost_source` that says how the\n * figure was obtained, the `processor_cost_basis` behind an estimate, and\n * the `connector_method_code` it was priced under. Recorded for **every**\n * merchant, not only those that host shops. Never present an `estimated`\n * cost as an observation, and read an absent `processor_cost_source` as\n * \"nothing was ever written\", which is not the `unavailable` the rail\n * answers with.\n *\n * `GET /payments/{paymentId}/settlement`\n *\n * @param paymentId - The payment intent ID.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n * @returns The attempts this caller may see, oldest first, each with its\n * settlement status.\n * @throws If the payment does not exist (404), or the caller is a\n * profile-scoped (shop) role, who is refused rather than shown a redacted\n * body (403).\n *\n * @example\n * ```typescript\n * const { attempts } = await delopay.payments.settlement('pay_abc123');\n * for (const attempt of attempts) {\n * if (attempt.status === 'paid_out') {\n * console.log(attempt.paid_out_at, attempt.payout_reference);\n * }\n * if (attempt.processor_cost_source === 'estimated') {\n * // Label it an estimate — it was derived from a cost schedule.\n * }\n * }\n * ```\n */\n async settlement(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentConnectorSettlementResponse> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/settlement`, options);\n }\n\n /**\n * Update an existing payment intent before it is confirmed.\n *\n * @param paymentId - The payment intent ID to update.\n * @param params - Fields to update (amount, currency, metadata, etc.).\n * @returns The updated payment intent.\n */\n async update(paymentId: string, params: PaymentUpdateRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}`, { body: params });\n }\n\n /**\n * Confirm a payment intent, triggering authorisation with the selected gateway.\n *\n * @param paymentId - The payment intent ID to confirm.\n * @param params - Confirmation parameters (payment method data, return URL, etc.).\n * @returns The updated payment intent.\n */\n async confirm(paymentId: string, params: PaymentConfirmRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Capture a previously authorised payment.\n *\n * @param paymentId - The payment intent ID to capture.\n * @param params - Optional capture parameters (partial capture amount, etc.).\n * @returns The updated payment intent.\n */\n async capture(paymentId: string, params?: PaymentCaptureRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/capture`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payment intent that has not yet been captured.\n *\n * @param paymentId - The payment intent ID to cancel.\n * @param params - Optional cancellation reason.\n * @returns The updated payment intent.\n */\n async cancel(paymentId: string, params?: PaymentCancelRequest): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel`, {\n body: params,\n });\n }\n\n /**\n * List payment intents, optionally filtered by customer or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal` for cancellation.\n * @returns Paginated list of payment intents.\n *\n * @example\n * ```typescript\n * const { data } = await delopay.payments.list({ customer_id: 'cus_123', limit: 25 });\n * ```\n */\n async list(params?: PaymentListParams, options?: RequestExtras): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * The status timeline of client/device observations captured while the\n * buyer interacted with the payment (checkout opens, confirms, redirect\n * legs, reported client signals), oldest first.\n *\n * `GET /payments/{paymentId}/client-context`\n */\n async listClientContext(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentClientContextListResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/client-context`,\n options,\n );\n }\n\n /**\n * The routing decision recorded behind each attempt of a payment: which rule\n * matched, which candidates routing produced and which filter removed each,\n * which volume bucket was drawn and what the counters read, which\n * configuration version was live.\n *\n * This is the only truthful account of **how the connector was chosen**.\n * `routing_approach` on the payment is seeded on creation and several paths —\n * mandate, pre-routed and pinned-account among them — return before it is\n * overwritten, so it can still read `default_fallback` on a payment that was\n * routed by a rule. Read {@link RoutingDecision.decision_kind} instead.\n *\n * An attempt with `decision: null` simply has no record: the recorder is\n * best-effort, attempts that never reached routing have nothing to record,\n * and attempts predating the record exist in quantity. It is not an error.\n *\n * `GET /payments/{paymentId}/routing-decisions`\n *\n * @param paymentId - The payment intent ID.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n * @returns Every attempt returned for this payment, with its decision.\n *\n * @example\n * ```typescript\n * const { attempts } = await delopay.payments.routingDecisions('pay_abc123');\n * for (const attempt of attempts) {\n * if (!attempt.decision) continue;\n * console.log(attempt.connector, attempt.decision.decision_kind);\n * }\n * ```\n */\n async routingDecisions(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<PaymentRoutingDecisionsResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/routing-decisions`,\n options,\n );\n }\n\n /**\n * Open a playback of the payment's stored checkout recording: the audited\n * act of watching. Answers the manifest — which slices exist, how long the\n * recording runs, whether a pause in it is expected — and the\n * `playback_id` every {@link Payments.replaySlice} call carries.\n *\n * A payment that was never recorded answers `200` with `slices: []` and\n * `session_id: null` — the ordinary case for every payment made before the\n * checkout started recording — not a `404`. `404` means the payment does not\n * exist. Fetch the slices in `sequence` order; a number missing from the\n * list is a gap, not the end.\n *\n * A `POST`, because it writes one audit row: the SDK retries `GET` on its\n * own, and a lost response must not open three playbacks. Calling this\n * again deliberately opens another playback.\n *\n * Requires the `PaymentReplay` permission on a dashboard session in addition\n * to payment read access.\n *\n * `POST /payments/{paymentId}/replay/playback`\n *\n * @param paymentId - The payment intent ID.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n */\n async openReplayPlayback(\n paymentId: string,\n options?: RequestExtras,\n ): Promise<ReplayPlaybackResponse> {\n return this.request(\n 'POST',\n `/payments/${encodeURIComponent(paymentId)}/replay/playback`,\n options,\n );\n }\n\n /**\n * One slice of the payment's stored checkout recording, read against an\n * open playback: the rrweb events the checkout recorded under that number.\n * `playbackId` and the numbers come from {@link Payments.openReplayPlayback};\n * a `playbackId` that names no playback of this payment opened by this\n * caller, and a number the manifest does not list, both answer `404`.\n * Not audited per slice — the playback was.\n *\n * `GET /payments/{paymentId}/replay/playback/{playbackId}/slices/{sequence}`\n *\n * @param paymentId - The payment intent ID.\n * @param playbackId - The playback, from `openReplayPlayback`.\n * @param sequence - The slice number, from the playback's manifest.\n * @param options - Optional per-call extras: extra `headers`, a `timeout`\n * override, and an `AbortSignal`.\n */\n async replaySlice(\n paymentId: string,\n playbackId: string,\n sequence: number,\n options?: RequestExtras,\n ): Promise<ReplaySliceResponse> {\n return this.request(\n 'GET',\n `/payments/${encodeURIComponent(paymentId)}/replay/playback/${encodeURIComponent(playbackId)}/slices/${encodeURIComponent(String(sequence))}`,\n options,\n );\n }\n\n /**\n * Soft-delete a payment. Only payments whose status is in the merchant's\n * delete policy (see {@link Payments.getDeletePolicy}) can be deleted;\n * anything else fails with a precondition error.\n *\n * `DELETE /payments/{paymentId}`\n */\n async delete(paymentId: string, options?: RequestExtras): Promise<PaymentsDeleteResponse> {\n return this.request('DELETE', `/payments/${encodeURIComponent(paymentId)}`, options);\n }\n\n /**\n * The effective deletable-status set for the calling merchant — lets a\n * dashboard show the delete action only where it is allowed.\n *\n * `GET /payments/delete-policy`\n */\n async getDeletePolicy(options?: RequestExtras): Promise<PaymentsDeletePolicyResponse> {\n return this.request('GET', '/payments/delete-policy', options);\n }\n\n // --- Advanced operations (Task 3.2) ---\n\n /** Generate session tokens. `POST /payments/session-tokens` */\n async sessionTokens(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/payments/session-tokens', { body: params });\n }\n\n /** Retrieve payment with gateway credentials. `POST /payments/sync` */\n async sync(params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', '/payments/sync', { body: params });\n }\n\n /** Cancel after partial capture. `POST /payments/{paymentId}/cancel-post-capture` */\n async cancelPostCapture(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/cancel-post-capture`, {\n body: params,\n });\n }\n\n /** Incrementally authorize more funds. `POST /payments/{paymentId}/incremental-authorization` */\n async incrementalAuthorization(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request(\n 'POST',\n `/payments/${encodeURIComponent(paymentId)}/incremental-authorization`,\n {\n body: params,\n },\n );\n }\n\n /** Extend authorization window. `POST /payments/{paymentId}/extend-authorization` */\n async extendAuthorization(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/extend-authorization`, {\n body: params,\n });\n }\n\n /** Complete authorization. `POST /payments/{paymentId}/complete-authorize` */\n async completeAuthorize(\n paymentId: string,\n params?: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/complete-authorize`, {\n body: params,\n });\n }\n\n /** Dynamic tax calculation. `POST /payments/{paymentId}/calculate-tax` */\n async calculateTax(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/calculate-tax`, {\n body: params,\n });\n }\n\n /** Update payment metadata. `POST /payments/{paymentId}/update-metadata` */\n async updateMetadata(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/update-metadata`, {\n body: params,\n });\n }\n\n /** Retrieve extended card info. `GET /payments/{paymentId}/extended-card-info` */\n async extendedCardInfo(paymentId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/extended-card-info`);\n }\n\n // --- OLAP extensions (Task 4.2) ---\n\n /** List payments (profile-scoped). `GET /payments/profile/list` */\n async listByProfile(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments across all shops. `GET /payments/list-all-shops` */\n async listAllShops(params?: PaymentListParams): Promise<PaymentListResponse> {\n return this.request('GET', '/payments/list-all-shops', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payments by filter (POST body). `POST /payments/list` */\n async listByFilter(params: PaymentListFilterConstraints): Promise<PaymentListFilteredResponse> {\n return this.request('POST', '/payments/list', { body: params });\n }\n\n /**\n * List payments by filter, scoped to the caller's profile (the shop-user\n * twin of `listByFilter`). The backend narrows to the profile from the\n * auth context, so `profile_id` / `project_id` must not be sent — and\n * neither may `connector_settlement_status`, which this route refuses\n * (403): a shop-scoped viewer is not shown the settlement state, and the\n * type leaves the key out so it cannot be probed through `total_count`.\n *\n * Not to be confused with {@link Payments.listByProfile}, which is the GET\n * cursor variant and rejects this body.\n *\n * `POST /payments/profile/list`\n */\n async listByProfileFilter(\n params: ProfilePaymentListFilterConstraints,\n options?: RequestExtras,\n ): Promise<PaymentListFilteredResponse> {\n return this.request('POST', '/payments/profile/list', { body: params, ...options });\n }\n\n /** Get payment filter options. `GET /payments/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<PaymentListFiltersExt> {\n return this.request('GET', '/payments/filter', { query: params });\n }\n\n /**\n * Get payment filter options, scoped to the caller's profile.\n * `GET /payments/profile/filter`\n */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<PaymentListFiltersExt> {\n return this.request('GET', '/payments/profile/filter', { query: params });\n }\n\n /** Get payment aggregates. `GET /payments/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/aggregate', { query: params });\n }\n\n /** Get payment aggregates (profile-scoped). `GET /payments/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payments/profile/aggregate', { query: params });\n }\n\n /** Manually update payment status. `PUT /payments/{paymentId}/manual-update` */\n async manualUpdate(paymentId: string, params: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('PUT', `/payments/${encodeURIComponent(paymentId)}/manual-update`, {\n body: params,\n });\n }\n\n /** Approve a payment waiting for review. `POST /payments/{paymentId}/approve` */\n async approve(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/approve`, {\n body: params,\n });\n }\n\n /** Reject a payment waiting for review. `POST /payments/{paymentId}/reject` */\n async reject(paymentId: string, params?: Record<string, unknown>): Promise<PaymentResponse> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/reject`, {\n body: params,\n });\n }\n\n /** Initiate external 3DS authentication. `POST /payments/{paymentId}/3ds/authentication` */\n async threeDsAuthentication(\n paymentId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/payments/${encodeURIComponent(paymentId)}/3ds/authentication`, {\n body: params,\n });\n }\n}\n","import type {\n PayoutCreateRequest,\n PayoutResponse,\n PayoutUpdateRequest,\n PayoutListParams,\n PayoutListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage payouts — fund transfers from merchant to a recipient bank account. */\nexport class Payouts {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new payout.\n *\n * @param params - Payout parameters including amount, currency, and destination.\n * @returns The created payout.\n *\n * @example\n * ```typescript\n * const payout = await delopay.payouts.create({\n * amount: 10000,\n * currency: 'EUR',\n * customer_id: 'cus_123',\n * });\n * ```\n */\n async create(params: PayoutCreateRequest): Promise<PayoutResponse> {\n return this.request('POST', '/payouts/create', { body: params });\n }\n\n /**\n * Retrieve a payout by its ID.\n *\n * @param payoutId - The unique payout ID.\n * @returns The payout.\n */\n async retrieve(payoutId: string): Promise<PayoutResponse> {\n return this.request('GET', `/payouts/${encodeURIComponent(payoutId)}`);\n }\n\n /**\n * Update a payout before it is confirmed.\n *\n * @param payoutId - The payout ID to update.\n * @param params - Fields to update.\n * @returns The updated payout.\n */\n async update(payoutId: string, params: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}`, { body: params });\n }\n\n /**\n * Confirm a payout, triggering the actual transfer.\n *\n * @param payoutId - The payout ID to confirm.\n * @param params - Optional confirmation parameters.\n * @returns The updated payout.\n */\n async confirm(payoutId: string, params?: PayoutUpdateRequest): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/confirm`, {\n body: params,\n });\n }\n\n /**\n * Cancel a payout before it is fulfilled.\n *\n * @param payoutId - The payout ID to cancel.\n * @returns The cancelled payout.\n */\n async cancel(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/cancel`);\n }\n\n /**\n * Mark a payout as fulfilled (manual confirmation of successful transfer).\n *\n * @param payoutId - The payout ID to fulfil.\n * @returns The fulfilled payout.\n */\n async fulfill(payoutId: string): Promise<PayoutResponse> {\n return this.request('POST', `/payouts/${encodeURIComponent(payoutId)}/fulfill`);\n }\n\n /**\n * List payouts, optionally filtered by status or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of payouts.\n */\n async list(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n // --- OLAP extensions (Task 4.5) ---\n\n /** List payouts (profile-scoped). `GET /payouts/profile/list` */\n async listByProfile(params?: PayoutListParams): Promise<PayoutListResponse> {\n return this.request('GET', '/payouts/profile/list', {\n query: params as Record<string, string | number | undefined>,\n });\n }\n\n /** List payouts by filter (POST body). `POST /payouts/list` */\n async listByFilter(params: Record<string, unknown>): Promise<PayoutListResponse> {\n return this.request('POST', '/payouts/list', { body: params });\n }\n\n /** Get payout filter options. `GET /payouts/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/filter', { query: params });\n }\n\n /** Get payout filters (profile-scoped). `GET /payouts/profile/filter` */\n async getFiltersByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/filter', { query: params });\n }\n\n /** Get payout aggregates. `GET /payouts/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/aggregate', { query: params });\n }\n\n /** Get payout aggregates (profile-scoped). `GET /payouts/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/payouts/profile/aggregate', { query: params });\n }\n\n /** Manually update payout status. `PUT /payouts/{payoutId}/manual-update` */\n async manualUpdate(payoutId: string, params: Record<string, unknown>): Promise<PayoutResponse> {\n return this.request('PUT', `/payouts/${encodeURIComponent(payoutId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { PollStatusResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Poll {\n constructor(private readonly request: RequestFn) {}\n\n async getStatus(pollId: string): Promise<PollStatusResponse> {\n return this.request('GET', `/poll/status/${encodeURIComponent(pollId)}`);\n }\n}\n","import type {\n ProfileAcquirerCreateRequest,\n ProfileAcquirerResponse,\n ProfileAcquirerUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ProfileAcquirers {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: ProfileAcquirerCreateRequest): Promise<ProfileAcquirerResponse> {\n return this.request('POST', '/profile-acquirer', { body: params });\n }\n\n async update(\n profileId: string,\n profileAcquirerId: string,\n params: ProfileAcquirerUpdateRequest,\n ): Promise<ProfileAcquirerResponse> {\n return this.request(\n 'POST',\n `/profile-acquirer/${encodeURIComponent(profileId)}/${encodeURIComponent(profileAcquirerId)}`,\n {\n body: params,\n },\n );\n }\n}\n","import type { ProfileCreateRequest, ProfileResponse, ProfileUpdateRequest } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Profiles {\n constructor(private readonly request: RequestFn) {}\n\n async create(accountId: string, params: ProfileCreateRequest): Promise<ProfileResponse> {\n return this.request('POST', `/account/${encodeURIComponent(accountId)}/business-profile`, {\n body: params,\n });\n }\n\n async retrieve(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'GET',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n async list(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/business-profile`);\n }\n\n /**\n * List the business profiles the caller can see at profile scope — the\n * `ProfileAccountRead` twin of `list()` (which needs merchant-level read).\n * A shop-scoped user gets exactly their own shop back.\n *\n * `GET /account/{accountId}/profile`\n */\n async listByProfile(accountId: string): Promise<ProfileResponse[]> {\n return this.request('GET', `/account/${encodeURIComponent(accountId)}/profile`);\n }\n\n async update(\n accountId: string,\n profileId: string,\n params: ProfileUpdateRequest,\n ): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n {\n body: params,\n },\n );\n }\n\n async delete(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'DELETE',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}`,\n );\n }\n\n // --- Advanced operations (Task 4.8) ---\n\n /** Toggle extended card info for a profile. `POST /account/{accountId}/business-profile/{profileId}/toggle-extended-card-info` */\n async toggleExtendedCardInfo(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-extended-card-info`,\n );\n }\n\n /** Toggle connector agnostic MIT. `POST /account/{accountId}/business-profile/{profileId}/toggle-connector-agnostic-mit` */\n async toggleConnectorAgnosticMit(accountId: string, profileId: string): Promise<ProfileResponse> {\n return this.request(\n 'POST',\n `/account/${encodeURIComponent(accountId)}/business-profile/${encodeURIComponent(profileId)}/toggle-connector-agnostic-mit`,\n );\n }\n}\n","import type {\n ProjectCreateRequest,\n ProjectResponse,\n ProjectUpdateRequest,\n ProjectStatsResponse,\n MerchantOverviewResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage projects — optional grouping layers that contain one or more shops. */\nexport class Projects {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a new project under a merchant account.\n *\n * @param params - Project creation parameters (name, description, etc.).\n * @param merchantId - The merchant account ID that owns this project.\n * @returns The created project.\n *\n * @example\n * ```typescript\n * const project = await delopay.projects.create({ name: 'EU Stores' }, 'merch_123');\n * ```\n */\n async create(params: ProjectCreateRequest, merchantId: string): Promise<ProjectResponse> {\n return this.request('POST', '/projects', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Retrieve a project by its ID.\n *\n * @param projectId - The unique project ID.\n * @param merchantId - Optional merchant scope. When provided, sent as\n * `?merchant_id=…` — required by dashboards that authenticate with a JWT\n * spanning multiple merchants and need to disambiguate which one this\n * call applies to. API-key callers can omit it.\n * @returns The project.\n */\n async retrieve(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * Update a project's details.\n *\n * @param projectId - The project ID to update.\n * @param params - Fields to update.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The updated project.\n */\n async update(\n projectId: string,\n params: ProjectUpdateRequest,\n merchantId?: string,\n ): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('PUT', path, { body: params });\n return this.request('PUT', path, { body: params, query: { merchant_id: merchantId } });\n }\n\n /**\n * Delete a project.\n *\n * @param projectId - The project ID to delete.\n * @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.\n * @returns The deleted project object.\n */\n async delete(projectId: string, merchantId?: string): Promise<ProjectResponse> {\n const path = `/projects/${encodeURIComponent(projectId)}`;\n if (merchantId === undefined) return this.request('DELETE', path);\n return this.request('DELETE', path, { query: { merchant_id: merchantId } });\n }\n\n /**\n * List all projects for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of projects.\n */\n async list(merchantId: string): Promise<ProjectResponse[]> {\n return this.request('GET', '/projects/list', {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Get aggregate payment statistics across all projects for a merchant.\n *\n * The response's flat `shops[]` array holds every shop, including shops that\n * belong to no project — those are absent from `projects[].shops[]`, so look\n * a single shop up in `shops[]`. Requires `MerchantAccountRead`; a\n * shop-scoped user should call {@link Shops.stats} instead.\n *\n * @param merchantId - The merchant account ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns Project statistics.\n *\n * @example\n * ```typescript\n * const stats = await delopay.projects.stats('merch_123', 'all');\n * const shop = stats.shops.find((s) => s.shop_id === 'pro_1');\n * ```\n */\n async stats(merchantId: string, period?: StatsPeriod): Promise<ProjectStatsResponse> {\n const query: Record<string, string> = { merchant_id: merchantId };\n if (period !== undefined) query['period'] = String(period);\n return this.request('GET', '/projects/stats', { query });\n }\n\n /**\n * Get a high-level overview (volume, counts, top connectors) for a merchant.\n *\n * @param merchantId - The merchant account ID.\n * @returns Merchant overview data.\n */\n async overview(merchantId: string): Promise<MerchantOverviewResponse> {\n return this.request('GET', '/projects/overview', {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n RefundCreateRequest,\n RefundResponse,\n RefundUpdateRequest,\n RefundListParams,\n RefundListResponse,\n RefundAggregateResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/** Create and manage refunds for completed payments. */\nexport class Refunds {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a refund for a payment.\n *\n * Dashboard-initiated refunds are subject to the caller's operation-limit\n * rule, resolved against the role the request authenticated with. An\n * over-limit refund either fails with `DE_01` (the rule blocks) or with\n * HTTP 409 `DE_06` — the rule requires approval, and `DelopayError.data`\n * carries `PendingApprovalErrorDetails`. No refund exists in either case;\n * `DE_06` names one that a second approver can still let through, via\n * `operationLimits.approve()`.\n *\n * @param params - Refund parameters, including the required `payment_id` and optional amount.\n * @returns The created refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.create({\n * payment_id: 'pay_abc123',\n * amount: 2500, // partial refund of 25.00 EUR\n * });\n * ```\n */\n async create(params: RefundCreateRequest): Promise<RefundResponse> {\n return this.request('POST', '/refunds', { body: params });\n }\n\n /**\n * Retrieve a refund by its ID.\n *\n * @param refundId - The unique refund ID.\n * @returns The refund.\n *\n * @example\n * ```typescript\n * const refund = await delopay.refunds.retrieve('ref_abc123');\n * ```\n */\n async retrieve(refundId: string): Promise<RefundResponse> {\n return this.request('GET', `/refunds/${encodeURIComponent(refundId)}`);\n }\n\n /**\n * Update the reason or metadata on an existing refund.\n *\n * @param refundId - The refund ID to update.\n * @param params - Fields to update (reason, metadata).\n * @returns The updated refund.\n */\n async update(refundId: string, params: RefundUpdateRequest): Promise<RefundResponse> {\n return this.request('POST', `/refunds/${encodeURIComponent(refundId)}`, { body: params });\n }\n\n /**\n * List refunds, optionally filtered by payment, status, or date range.\n *\n * @param params - Optional filter and pagination parameters.\n * @returns Paginated list of refunds.\n */\n async list(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/list', { body: params });\n }\n\n // --- OLAP extensions (Task 4.3) ---\n\n /** List refunds (profile-scoped). `POST /refunds/profile/list` */\n async listByProfile(params?: RefundListParams): Promise<RefundListResponse> {\n return this.request('POST', '/refunds/profile/list', { body: params });\n }\n\n /** Get refund filter options. `GET /refunds/filter` */\n async getFilters(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/refunds/filter', { query: params });\n }\n\n /** Get refund aggregates. `GET /refunds/aggregate` */\n async aggregate(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/aggregate', { query: params });\n }\n\n /** Get refund aggregates (profile-scoped). `GET /refunds/profile/aggregate` */\n async aggregateByProfile(\n params?: Record<string, string | number | undefined>,\n ): Promise<RefundAggregateResponse> {\n return this.request('GET', '/refunds/profile/aggregate', { query: params });\n }\n\n /** Manually update refund status. `PUT /refunds/{refundId}/manual-update` */\n async manualUpdate(refundId: string, params: Record<string, unknown>): Promise<RefundResponse> {\n return this.request('PUT', `/refunds/${encodeURIComponent(refundId)}/manual-update`, {\n body: params,\n });\n }\n}\n","import type { RelayRequest, RelayResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Relay {\n constructor(private readonly request: RequestFn) {}\n\n async create(params: RelayRequest): Promise<RelayResponse> {\n return this.request('POST', '/relay', { body: params });\n }\n\n async retrieve(relayId: string): Promise<RelayResponse> {\n return this.request('GET', `/relay/${encodeURIComponent(relayId)}`);\n }\n}\n","import type {\n CheckoutThemeConversionQuery,\n CheckoutThemeConversionResponse,\n CheckoutThemeProgramRequest,\n CheckoutThemeProgramResponse,\n LinkedRoutingConfigRetrieveResponse,\n MerchantRoutingAlgorithm,\n ProfileDefaultRoutingConfig,\n ProfileDeniedConnectorsResponse,\n RoutableConnectorChoice,\n RoutingActivatePayload,\n RoutingConfigCreateRequest,\n RoutingConfigDeleteResponse,\n RoutingConfigHistoryResponse,\n RoutingConfigUpdateRequest,\n RoutingConnectorCaps,\n RoutingConnectorCapSchedule,\n RoutingConnectorCapScheduleShuffle,\n RoutingDeactivateRequest,\n RoutingDictionary,\n RoutingDictionaryRecord,\n RoutingHistoryParams,\n RoutingVolumeCounters,\n SurchargeRuleRequest,\n SurchargeRuleResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Create and manage payment routing algorithms.\n *\n * Routing rules determine which gateway connector handles each payment based on\n * card type, currency, amount, or custom conditions.\n */\nexport class Routing {\n readonly decision: RoutingDecisionManager;\n /** Merchant-friendly, per-payment-method surcharge rules (no Euclid DSL). */\n readonly surchargeRules: SurchargeRules;\n /** Which stored appearance variant a buyer is shown. Decides a look, never a payment. */\n readonly checkoutThemeRules: CheckoutThemeRules;\n /** Rendered-to-paid conversion per appearance variant and segment. */\n readonly checkoutThemeConversion: CheckoutThemeConversion;\n\n constructor(private readonly request: RequestFn) {\n this.decision = new RoutingDecisionManager(request);\n this.surchargeRules = new SurchargeRules(request);\n this.checkoutThemeRules = new CheckoutThemeRules(request);\n this.checkoutThemeConversion = new CheckoutThemeConversion(request);\n }\n\n /**\n * Create a new routing algorithm.\n *\n * @param params - Routing algorithm definition (rule-based, priority, or volume-based).\n * @returns Metadata record for the created routing configuration. The full\n * algorithm body is not echoed back — use `retrieve(id)` if you need it.\n *\n * @example\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'EU Priority',\n * algorithm: { type: 'priority', data: [{ connector: 'stripe' }] },\n * });\n * ```\n *\n * @example Conditional volume split (advanced): cards → 90% epayouts / 10% stripe.\n * Rules run top-down (first match wins); `defaultSelection` is the fallback.\n * Splits must sum to 100; `amount` conditions are in minor units.\n * ```typescript\n * const config = await delopay.routing.create({\n * name: 'Card split 90/10',\n * profile_id: 'pro_...',\n * algorithm: {\n * type: 'advanced',\n * data: {\n * defaultSelection: { type: 'priority', data: [{ connector: 'stripe' }] },\n * rules: [\n * {\n * name: 'cards',\n * connectorSelection: {\n * type: 'volume_split',\n * data: [\n * { connector: { connector: 'epayouts' }, split: 90 },\n * { connector: { connector: 'stripe' }, split: 10 },\n * ],\n * },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'payment_method',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'card' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * metadata: {},\n * },\n * },\n * });\n * await delopay.routing.activate(config.id);\n * ```\n */\n async create(params: RoutingConfigCreateRequest): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing', { body: params });\n }\n\n /**\n * Retrieve a routing algorithm by its ID.\n *\n * @param algorithmId - The routing algorithm ID.\n * @returns The full routing configuration including the algorithm body.\n */\n async retrieve(algorithmId: string): Promise<MerchantRoutingAlgorithm> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}`);\n }\n\n /**\n * Activate a routing algorithm, making it the active routing strategy.\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param algorithmId - The routing algorithm ID to activate.\n * @param params - Optional activation payload (e.g. `transaction_type`).\n */\n async activate(\n algorithmId: string,\n params: RoutingActivatePayload = {},\n ): Promise<RoutingDictionaryRecord> {\n return this.request('POST', `/routing/${encodeURIComponent(algorithmId)}/activate`, {\n body: params,\n });\n }\n\n /**\n * Deactivate the currently active routing algorithm (falls back to default routing).\n *\n * Always sends a JSON body (default `{}`) so the request carries the\n * `Content-Type: application/json` header that the server requires.\n *\n * @param params - Optional deactivation payload.\n */\n async deactivate(params: RoutingDeactivateRequest = {}): Promise<RoutingDictionaryRecord> {\n return this.request('POST', '/routing/deactivate', { body: params });\n }\n\n /**\n * Edit a static routing configuration.\n *\n * Partial: send only the fields to change. `name`/`description` are\n * metadata-only; `algorithm` is a wholesale rule replacement, validated\n * against the shop exactly as at create. `modified_at` is bumped either way.\n *\n * `PUT /routing/{algorithmId}`\n *\n * @param algorithmId - The routing algorithm ID to edit.\n * @param params - The fields to change (at least one required).\n * @returns The updated routing configuration including the algorithm body.\n */\n async update(\n algorithmId: string,\n params: RoutingConfigUpdateRequest,\n ): Promise<MerchantRoutingAlgorithm> {\n return this.request('PUT', `/routing/${encodeURIComponent(algorithmId)}`, { body: params });\n }\n\n /**\n * Delete a static routing configuration.\n *\n * A soft delete: the configuration disappears from every list and read, but\n * its version history is kept server-side for audit. The live configuration\n * of a shop cannot be deleted — the backend refuses it (400, `IR_16`); deactivate it first.\n * Only `single`, `priority`, `volume_split` and `advanced` payment\n * configurations qualify (400 otherwise).\n *\n * `DELETE /routing/{algorithmId}`\n *\n * @param algorithmId - The routing algorithm to delete.\n */\n async delete(algorithmId: string): Promise<RoutingConfigDeleteResponse> {\n return this.request('DELETE', `/routing/${encodeURIComponent(algorithmId)}`);\n }\n\n /**\n * Every content window a routing configuration has had, oldest first.\n *\n * A configuration's rule can be edited in place, so this is what makes \"which\n * rule decided this payment\" answerable after the fact. Each entry is the rule\n * as it stood between `valid_from` and `valid_until`; the windows of one\n * config abut exactly, with no gap.\n *\n * Paging covers the whole timeline including the live window, so a page never\n * holds more than `limit` entries and the live one — the only entry without a\n * `valid_until` — comes back on exactly one page. Advance `offset` by `limit`;\n * a page past the end is empty, and `total_count` says where that end is\n * without probing for it.\n *\n * `GET /routing/{algorithmId}/history`\n *\n * @param algorithmId - The routing algorithm to read the history of.\n * @param params - Optional paging.\n */\n async history(\n algorithmId: string,\n params: RoutingHistoryParams = {},\n ): Promise<RoutingConfigHistoryResponse> {\n return this.request('GET', `/routing/${encodeURIComponent(algorithmId)}/history`, {\n query: params as Record<string, number | null | undefined>,\n });\n }\n\n /**\n * A shop's per-connector caps, each with its unit and window and how much of\n * the current window is spent (`used`) or held by payments in flight\n * (`reserved`).\n *\n * `GET /routing/connector-caps/{profileId}`\n */\n async connectorCaps(profileId: string): Promise<RoutingConnectorCaps> {\n return this.request('GET', `/routing/connector-caps/${encodeURIComponent(profileId)}`);\n }\n\n /** Read a shop's dated limit overrides. `GET /routing/connector-cap-schedules/{profileId}` */\n async connectorCapSchedules(profileId: string): Promise<RoutingConnectorCapSchedule> {\n return this.request('GET', `/routing/connector-cap-schedules/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Replace a shop's complete schedule using its last-read revision.\n * Remove an entry to cancel it; ordinary configured caps are unchanged.\n * Instants require explicit offsets, and overlapping entries for the same\n * account and unit are refused by the server. Capability preflight refuses\n * unsupported backends before submitting any schedule.\n *\n * `PUT /routing/connector-cap-schedules/{profileId}`\n */\n async setConnectorCapSchedules(\n profileId: string,\n params: RoutingConnectorCapSchedule,\n ): Promise<RoutingConnectorCapSchedule> {\n const caps = await this.connectorCaps(profileId);\n if (!caps.features?.includes('limit_schedules')) {\n throw new Error('Connector limit schedules are unsupported by the serving backend');\n }\n return this.request(\n 'PUT',\n `/routing/connector-cap-schedules/${encodeURIComponent(profileId)}`,\n {\n body: params,\n },\n );\n }\n\n /** Change the drawn value of an active scheduled range; preserves all usage. */\n async shuffleConnectorCapSchedule(\n profileId: string,\n params: RoutingConnectorCapScheduleShuffle,\n ): Promise<RoutingConnectorCaps> {\n const caps = await this.connectorCaps(profileId);\n if (!caps.features?.includes('limit_schedules')) {\n throw new Error('Connector limit schedules are unsupported by the serving backend');\n }\n return this.request(\n 'POST',\n `/routing/connector-cap-schedules/${encodeURIComponent(profileId)}/shuffle`,\n { body: params },\n );\n }\n\n /**\n * The live `routing_volume` counters behind a shop's active advanced\n * program: one per distinct budget the program reads, each with the window\n * it covers, the figure in the pinned threshold currency, and the rules that\n * read it. Lets a merchant see whether a `routing_volume < 50000` rule is at\n * 120 or at 499 today, and support answer why a payment went to the overflow\n * connector.\n *\n * What routing will use right now, not what the shop turned over: the\n * counters are held in Redis only and a lost Redis restarts the window at\n * zero. Read-only; needs the same permission as reading the rules.\n *\n * `GET /routing/volume-counters/{profileId}`\n */\n async volumeCounters(profileId: string): Promise<RoutingVolumeCounters> {\n return this.request('GET', `/routing/volume-counters/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Replace a shop's per-connector caps.\n *\n * Whole-set replacement, not a patch: the list sent becomes the complete set\n * of capped connectors, and an empty list clears them all — which is how\n * acquirer onboarding finishes, the new account ceasing to be a special case.\n * Re-send every other cap with its `unit`, `window` and `currency` as read:\n * an amount cap sent back without its `unit` is refused, because it carries a\n * currency and would otherwise be a payment count.\n *\n * Every account named must belong to this shop; one that does not is refused.\n * So is an amount cap without a `currency`, and a payment cap with one.\n *\n * An account may appear twice — a payment count and a budget — and never\n * twice in one `unit`. Re-send a range with its `limit_max`, or it is stored\n * as its bottom. Never re-send `current_limit` as `set_current_limit`: the\n * value read belongs to the window it was read in, and pinning it into a\n * window that has since reset is a limit nobody chose.\n *\n * `PUT /routing/connector-caps/{profileId}`\n */\n async setConnectorCaps(\n profileId: string,\n params: RoutingConnectorCaps,\n ): Promise<RoutingConnectorCaps> {\n return this.request('PUT', `/routing/connector-caps/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /**\n * List all routing algorithms for the current merchant.\n *\n * @returns The routing dictionary (records + currently active id).\n */\n async list(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing');\n }\n\n /**\n * Connector names denied at routing for a shop (explicit denies plus\n * whitelist-implied exclusions). Read-only; surfaced in the routing builder.\n *\n * `GET /routing/connector-restrictions/{profileId}`\n */\n async connectorRestrictions(profileId: string): Promise<ProfileDeniedConnectorsResponse> {\n return this.request('GET', `/routing/connector-restrictions/${encodeURIComponent(profileId)}`);\n }\n\n // --- Advanced operations (Task 3.4) ---\n\n /** Get active routing config. `GET /routing/active` */\n async getActive(): Promise<LinkedRoutingConfigRetrieveResponse> {\n return this.request('GET', '/routing/active');\n }\n\n /** Update default routing config. `POST /routing/default` */\n async updateDefault(params: Record<string, unknown>): Promise<RoutableConnectorChoice[]> {\n return this.request('POST', '/routing/default', { body: params });\n }\n\n /** Retrieve default config for profiles. `GET /routing/default/profile` */\n async getDefaultProfile(): Promise<RoutableConnectorChoice[] | ProfileDefaultRoutingConfig[]> {\n return this.request('GET', '/routing/default/profile');\n }\n\n /**\n * Retrieve one profile's default config. `GET /routing/default/profile/{profileId}`\n *\n * The narrow counterpart of `getDefaultProfile()`: that one returns every\n * profile of the merchant and needs merchant-level routing read, so a\n * profile-scoped (shop) role could write its own default through\n * `updateDefaultProfile()` but never read it back. This read is gated on\n * profile-level routing read and pinned to the caller's own profile — a shop\n * role asking for a sibling profile is refused.\n */\n async getDefaultForProfile(profileId: string): Promise<ProfileDefaultRoutingConfig> {\n return this.request('GET', `/routing/default/profile/${encodeURIComponent(profileId)}`);\n }\n\n /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */\n async updateDefaultProfile(\n profileId: string,\n params: Record<string, unknown>,\n ): Promise<ProfileDefaultRoutingConfig> {\n return this.request('POST', `/routing/default/profile/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /** List routing configs for profile. `GET /routing/list/profile` */\n async listForProfile(): Promise<RoutingDictionary> {\n return this.request('GET', '/routing/list/profile');\n }\n\n /** Evaluate a routing rule. `POST /routing/rule/evaluate` */\n async evaluateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/evaluate', { body: params });\n }\n\n /** Migrate routing rules for profile. `POST /routing/rule/migrate` */\n async migrateRule(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/rule/migrate', { body: params });\n }\n\n /** Evaluate routing for a payment. `POST /routing/evaluate` */\n async evaluate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/evaluate', { body: params });\n }\n\n /** Update gateway scores for dynamic routing. `POST /routing/feedback` */\n async feedback(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/routing/feedback', { body: params });\n }\n}\n\nclass RoutingDecisionManager {\n constructor(private readonly request: RequestFn) {}\n\n /** Upsert decision manager config. `PUT /routing/decision` */\n async upsert(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision', { body: params });\n }\n\n /** Retrieve decision manager config. `GET /routing/decision` */\n async retrieve(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision');\n }\n\n /** Delete decision manager config. `DELETE /routing/decision` */\n async delete(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision');\n }\n\n /** Upsert surcharge decision config. `PUT /routing/decision/surcharge` */\n async upsertSurcharge(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/routing/decision/surcharge', { body: params });\n }\n\n /** Retrieve surcharge decision config. `GET /routing/decision/surcharge` */\n async retrieveSurcharge(): Promise<Record<string, unknown>> {\n return this.request('GET', '/routing/decision/surcharge');\n }\n\n /** Delete surcharge decision config. `DELETE /routing/decision/surcharge` */\n async deleteSurcharge(): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/routing/decision/surcharge');\n }\n}\n\n/**\n * Merchant-friendly surcharge rules: configure a per-payment-method surcharge\n * (fixed or %) added to the amount the buyer pays — without hand-writing the\n * Euclid DSL. Scope to a shop via `profile_id` (omit for merchant-wide).\n *\n * Distinct from the platform fee (a balance deduction): a surcharge changes what\n * the buyer is charged.\n */\nclass SurchargeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the surcharge program for a scope.\n *\n * `PUT /routing/surcharge/rules`\n *\n * @example\n * ```typescript\n * await delopay.routing.surchargeRules.upsert({\n * surcharges: [\n * { payment_method: 'crypto', surcharge: { rate: { percent: 1.0 } } },\n * { payment_method: 'card', surcharge: { fixed: { amount: 35 } } },\n * ],\n * });\n * ```\n */\n async upsert(params: SurchargeRuleRequest): Promise<SurchargeRuleResponse> {\n return this.request('PUT', '/routing/surcharge/rules', { body: params });\n }\n\n /**\n * Retrieve the active surcharge program for a scope, or `null` when none is set.\n *\n * `GET /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async retrieve(profileId?: string): Promise<SurchargeRuleResponse | null> {\n return this.request('GET', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active surcharge program for a scope.\n *\n * `DELETE /routing/surcharge/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide rule.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/surcharge/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Checkout theme programs: which of a shop's stored appearance variants a buyer\n * is shown.\n *\n * Same engine and same wire format as the advanced routing rules above — a\n * Euclid program whose rules run top-down, first match wins, with\n * `defaultSelection` as the fallback — with the output swapped for a variant\n * name. That is deliberate: the dashboard's routing rule builder can author\n * these without learning a second condition language.\n *\n * **A theme program decides a look and nothing else.** It cannot express which\n * payment methods are offered, what is charged, which provider processes the\n * payment, or whether it succeeds. The allowed dimensions are fixed server-side\n * by the output type — see {@link CheckoutThemeDimension} — so that is a\n * property of the API rather than a convention.\n *\n * Naming a variant the shop has not defined is **not** an error: the checkout\n * falls back to the shop default, exactly as it does for an unknown `?theme=`,\n * because a buyer who cannot pay is worse than a buyer who sees the default\n * look. Such names come back in `warnings` instead, recomputed on every read.\n */\nclass CheckoutThemeRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create or replace the theme program for a scope.\n *\n * `PUT /routing/checkout-theme/rules`\n *\n * Supersedes rather than overwrites: the previous active version is retired\n * and a new one stored, so the record of which look was live when survives.\n * Pass `active: false` to store a revision **without** retiring the live one —\n * that is where a program drafted against a variant you have not built yet\n * belongs.\n *\n * @example A phone in Germany gets the compact look; everyone else the house style.\n * ```typescript\n * await delopay.routing.checkoutThemeRules.upsert({\n * name: 'Autumn targeting',\n * profile_id: 'pro_...',\n * algorithm: {\n * rules: [\n * {\n * name: 'German phones',\n * connectorSelection: { theme: { variant: 'compact' } },\n * statements: [\n * {\n * condition: [\n * {\n * lhs: 'device_class',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'phone' },\n * metadata: {},\n * },\n * {\n * lhs: 'browser_language',\n * comparison: 'equal',\n * value: { type: 'enum_variant', value: 'de' },\n * metadata: {},\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * defaultSelection: { theme: { variant: 'house' } },\n * metadata: {},\n * },\n * });\n * ```\n */\n async upsert(params: CheckoutThemeProgramRequest): Promise<CheckoutThemeProgramResponse> {\n return this.request('PUT', '/routing/checkout-theme/rules', { body: params });\n }\n\n /**\n * Retrieve the active theme program for a scope, or `null` when none is set.\n *\n * `GET /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program. A\n * shop-scoped caller that omits it gets its own shop's program.\n */\n async retrieve(profileId?: string): Promise<CheckoutThemeProgramResponse | null> {\n return this.request('GET', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n\n /**\n * Deactivate the active theme program for a scope. Idempotent.\n *\n * `DELETE /routing/checkout-theme/rules?profile_id={profileId}`\n *\n * Deactivation, not deletion — the stored row is what says which look was\n * live when, and that history cannot be reconstructed after the fact. Shops\n * go back to their default appearance immediately.\n *\n * @param profileId - Shop scope. Omit for the merchant-wide program.\n */\n async delete(profileId?: string): Promise<void> {\n return this.request('DELETE', '/routing/checkout-theme/rules', {\n query: { profile_id: profileId },\n });\n }\n}\n\n/**\n * Rendered-to-paid conversion, per appearance variant and segment.\n *\n * Answers the one question theme targeting exists for: *does variant B convert\n * better than the house style, on phones, in Germany?*\n *\n * **What a rate here means.** The denominator is backend-observed checkout page\n * opens, deduplicated by device within the hosted checkout's cache window, with\n * automated traffic excluded from both sides. It is narrower than \"paints\", and\n * that is deliberate - counting one buyer's refresh as a second render would\n * understate conversion. The exact basis travels with every response in\n * `denominator`, and the ways it is not the whole truth travel in `caveats`.\n *\n * **The server decides what may be concluded, not you.** Rate, Wilson interval,\n * per-cell `verdict` and the variant-vs-default `separates` test are computed\n * once, server-side, and shipped as values. Do not recompute them: the first\n * client that rounds differently tells a merchant a difference is real when the\n * server says it is not.\n */\nclass CheckoutThemeConversion {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Rendered-to-paid conversion for a shop over a window.\n *\n * `GET /routing/checkout-theme/conversion`\n *\n * Requires `CheckoutBranding` read at profile scope - the same permission\n * that governs seeing how a checkout looks.\n *\n * @param params - Window (RFC3339, `start` inclusive / `end` exclusive), the\n * shop, and the dimension to group by.\n *\n * @example Which variant wins on which device, over the last 30 days.\n * ```typescript\n * const report = await delopay.routing.checkoutThemeConversion.retrieve({\n * profile_id: 'pro_...',\n * start: '2026-07-21T00:00:00Z',\n * end: '2026-08-20T00:00:00Z',\n * segment: 'device',\n * });\n *\n * for (const c of report.comparisons) {\n * if (!c.separates) continue; // \"not shown to differ\" - say nothing\n * console.log(`${c.variant} on ${c.segment}: ${c.higher} converts better`);\n * }\n * ```\n */\n async retrieve(params: CheckoutThemeConversionQuery): Promise<CheckoutThemeConversionResponse> {\n return this.request('GET', '/routing/checkout-theme/conversion', {\n query: {\n profile_id: params.profile_id,\n start: params.start,\n end: params.end,\n segment: params.segment,\n },\n });\n }\n}\n","import type { RequestFn } from '../client';\n\n/** Index discriminator returned for each search result group. */\nexport type SearchIndex =\n | 'payment_attempts'\n | 'payment_intents'\n | 'refunds'\n | 'disputes'\n | 'payouts'\n | 'sessionizer_payment_attempts'\n | 'sessionizer_payment_intents'\n | 'sessionizer_refunds'\n | 'sessionizer_disputes'\n | 'routing_rules'\n | 'webhook_events'\n | 'audit_logs'\n | 'subscriptions';\n\nexport type SearchStatus = 'Success' | 'Failure';\n\n/** One result group (per index) in the response array. */\nexport interface SearchGroupResponse {\n count: number;\n index: SearchIndex;\n hits: Record<string, unknown>[];\n status: SearchStatus;\n}\n\n/**\n * The window a global search covers. The documented wire fields are\n * `start_time` (required) and `end_time` (optional — omit it for \"up to\n * now\"); the server also accepts the camelCase spellings as aliases, which\n * earlier SDK versions sent, so both are declared and either compiles.\n * Prefer the snake_case pair: it is what the operation documents.\n */\nexport type SearchTimeRange =\n | { start_time: string; end_time?: string | null }\n /** @deprecated Use `start_time` / `end_time` — the documented wire names. */\n | { startTime: string; endTime?: string | null };\n\nexport interface GlobalSearchRequest {\n query: string;\n filters?: Record<string, unknown>;\n /** Naive ISO 8601 bounds; `end_time` may be omitted. */\n timeRange?: SearchTimeRange;\n /** Wire alias for `timeRange` — the server reads either. */\n time_range?: SearchTimeRange;\n}\n\n/** Global cross-index search. */\nexport class Search {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Search every supported index for `query`.\n * `POST /analytics/search`\n *\n * @example\n * ```typescript\n * const groups = await delopay.search.global({ query: 'pay_abc' });\n * for (const g of groups) console.log(g.index, g.count);\n * ```\n */\n async global(\n params: GlobalSearchRequest,\n options?: { signal?: AbortSignal },\n ): Promise<SearchGroupResponse[]> {\n return this.request('POST', '/analytics/search', {\n body: params,\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n }\n}\n","import type {\n CheckoutBrandingResponse,\n CheckoutBrandingUpdate,\n ShopCreateRequest,\n ShopResponse,\n ShopUpdateRequest,\n GatewayConnectRequest,\n GatewayResponse,\n ProfileLogoUploadResponse,\n ShopStatsResponse,\n StatsPeriod,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/** Manage gateway connections for a specific shop. */\nclass ShopGateways {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Connect a payment gateway to a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param params - Gateway connector credentials and configuration.\n * @returns The created gateway connection.\n */\n async connect(\n merchantId: string,\n shopId: string,\n params: GatewayConnectRequest,\n ): Promise<GatewayResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n { body: params },\n );\n }\n\n /**\n * List all gateway connections for a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns Array of gateway connections.\n */\n async list(merchantId: string, shopId: string): Promise<GatewayResponse[]> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways`,\n );\n }\n\n /**\n * Disconnect a gateway from a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @param gatewayId - The gateway connector ID to remove.\n * @returns The removed gateway connection.\n */\n async disconnect(\n merchantId: string,\n shopId: string,\n gatewayId: string,\n ): Promise<GatewayResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/gateways/${encodeURIComponent(gatewayId)}`,\n );\n }\n}\n\n/**\n * Create and manage shops (business profiles) within a merchant account.\n *\n * Each shop can have its own gateway connections, routing rules, and fee schedules.\n */\nexport class Shops {\n /** Gateway connection management for shops. */\n readonly gateways: ShopGateways;\n\n constructor(private readonly request: RequestFn) {\n this.gateways = new ShopGateways(request);\n }\n\n /**\n * Create a new shop under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @param params - Shop creation parameters (name, etc.).\n * @returns The created shop.\n *\n * @example\n * ```typescript\n * const shop = await delopay.shops.create('merch_123', { shop_name: 'EU Store' });\n * ```\n */\n async create(merchantId: string, params: ShopCreateRequest): Promise<ShopResponse> {\n return this.request('POST', `/shops/${encodeURIComponent(merchantId)}`, { body: params });\n }\n\n /**\n * Retrieve a shop by its ID.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID.\n * @returns The shop.\n */\n async retrieve(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * Update a shop's configuration.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to update.\n * @param params - Fields to update.\n * @returns The updated shop.\n */\n async update(\n merchantId: string,\n shopId: string,\n params: ShopUpdateRequest,\n ): Promise<ShopResponse> {\n return this.request(\n 'PUT',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n { body: params },\n );\n }\n\n /**\n * Delete a shop.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop ID to delete.\n * @returns The deleted shop object.\n */\n async delete(merchantId: string, shopId: string): Promise<ShopResponse> {\n return this.request(\n 'DELETE',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}`,\n );\n }\n\n /**\n * List all shops under a merchant account.\n *\n * @param merchantId - The merchant account ID.\n * @returns Array of shops.\n */\n async list(merchantId: string): Promise<ShopResponse[]> {\n return this.request('GET', `/shops/${encodeURIComponent(merchantId)}`);\n }\n\n /**\n * Successful-order count and revenue for one shop.\n *\n * Unlike `projects.stats()` this needs only `ProfileAccountRead`, so a\n * shop-scoped user can load it for their own shop; merchant-level users can\n * load any shop of their merchant.\n *\n * Revenue comes back FX-converted as `revenue_usd` (USD major units) plus a\n * `revenue_by_currency` breakdown. The legacy `revenue` field is a raw\n * cross-currency minor-unit sum and should not be displayed.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param period - Window in days, or `'all'` for an all-time total.\n * Omitted means the server default of 30 days.\n * @returns The shop's stats over the requested window.\n *\n * @example\n * ```typescript\n * const stats = await delopay.shops.stats('merch_123', 'pro_1', 'all');\n * console.log(stats.orders, stats.revenue_usd);\n * ```\n */\n async stats(\n merchantId: string,\n shopId: string,\n period?: StatsPeriod,\n ): Promise<ShopStatsResponse> {\n const path = `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/stats`;\n if (period === undefined) return this.request('GET', path);\n return this.request('GET', path, { query: { period: String(period) } });\n }\n\n /**\n * Upload a logo file for a shop. The file is stored in Delopay's configured\n * object store and a public HTTPS URL is returned. This method does NOT write\n * the URL into the shop's `payment_link_config.logo` — call\n * `shops.update` afterwards with the returned `logo_url` to persist the change.\n *\n * Accepts PNG, JPEG, WebP or SVG. The file must be ≤ 1 MiB.\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID.\n * @param file - The logo file (Blob / File in browsers).\n * @returns The publicly-reachable URL of the uploaded logo.\n *\n * @example\n * ```typescript\n * const { logo_url } = await delopay.shops.uploadLogo('merch_1', 'pro_1', file);\n * await delopay.shops.update('merch_1', 'pro_1', {\n * payment_link_config: { logo: logo_url },\n * });\n * ```\n */\n async uploadLogo(\n merchantId: string,\n shopId: string,\n file: Blob,\n ): Promise<ProfileLogoUploadResponse> {\n const form = new FormData();\n form.append('file', file);\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/logo`,\n { body: form },\n );\n }\n\n /**\n * Update only the checkout appearance (the `payment_link_config` blob:\n * theme, logo, colours, seller name, SDK layout/rules, DeloPay-branding\n * toggle) of a shop. Applied as a whole-object replace of\n * `payment_link_config`, mirroring the shop-update semantics.\n *\n * Gated on the dedicated `CheckoutBranding` permission, so \"may restyle\n * the checkout\" can be granted without full account/shop write.\n *\n * `POST /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID to restyle.\n * @param params - The new `payment_link_config` blob (full replacement).\n * @returns The saved branding — the same shape `retrieveCheckoutBranding`\n * returns, not the whole shop. A role whose only power is restyling a\n * checkout must not receive the webhook signing key or the card-vault\n * configuration back from a save.\n */\n async updateCheckoutBranding(\n merchantId: string,\n shopId: string,\n params: CheckoutBrandingUpdate,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'POST',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n { body: params, ...options },\n );\n }\n\n /**\n * Read only the checkout appearance of a shop, so the role that may restyle a\n * checkout can load the checkout it may restyle.\n *\n * Gated on `ProfileCheckoutBrandingRead` — the read twin of the\n * `ProfileCheckoutBrandingEdit` guard on `updateCheckoutBranding` above.\n * Prefer this over `shops.retrieve` for the branding editor: `retrieve`\n * returns the whole profile, including the webhook signing key and the\n * card-vault configuration, and needs the shop-read permission for exactly\n * that reason.\n *\n * `GET /shops/{merchantId}/{shopId}/checkout-branding`\n *\n * @param merchantId - The merchant account ID.\n * @param shopId - The shop (business profile) ID whose branding to read.\n * @returns The shop's id, name and stored `payment_link_config`. That config\n * is `null` when the shop has never been styled — the untouched default, not\n * an error, and distinct from a stored-but-empty style.\n */\n async retrieveCheckoutBranding(\n merchantId: string,\n shopId: string,\n options?: RequestExtras,\n ): Promise<CheckoutBrandingResponse> {\n return this.request(\n 'GET',\n `/shops/${encodeURIComponent(merchantId)}/${encodeURIComponent(shopId)}/checkout-branding`,\n options,\n );\n }\n}\n","import type {\n StripeConnectAccountRequest,\n StripeConnectAccountResponse,\n StripeConnectLinkRequest,\n StripeConnectLinkResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class StripeConnect {\n constructor(private readonly request: RequestFn) {}\n\n async createAccount(params: StripeConnectAccountRequest): Promise<StripeConnectAccountResponse> {\n return this.request('POST', '/connector-onboarding/stripe/accounts', { body: params });\n }\n\n async createAccountLink(params: StripeConnectLinkRequest): Promise<StripeConnectLinkResponse> {\n return this.request('POST', '/connector-onboarding/stripe/account-links', { body: params });\n }\n\n // --- Generic connector onboarding (Task 4.11) ---\n\n /** Get onboarding action URL. `POST /connector-onboarding/action-url` */\n async getActionUrl(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/action-url', { body: params });\n }\n\n /** Sync onboarding status. `POST /connector-onboarding/sync` */\n async syncOnboarding(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/sync', { body: params });\n }\n\n /** Reset tracking ID. `POST /connector-onboarding/reset-tracking-id` */\n async resetTrackingId(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/connector-onboarding/reset-tracking-id', { body: params });\n }\n}\n","import type { ThreeDsRuleExecuteRequest, ThreeDsRuleResponse } from '../types';\nimport type { RequestFn } from '../client';\n\nexport class ThreeDsRules {\n constructor(private readonly request: RequestFn) {}\n\n async execute(params: ThreeDsRuleExecuteRequest): Promise<ThreeDsRuleResponse> {\n return this.request('POST', '/three-ds-decision/execute', { body: params });\n }\n}\n","import type {\n RolePaymentVisibilityPolicy,\n SignUpRequest,\n SignUpWithMerchantRequest,\n SignInRequest,\n DashboardOAuthProvider,\n DashboardOAuthProvidersResponse,\n DashboardOAuthStartRequest,\n DashboardOAuthLinkStartRequest,\n DashboardOAuthStartResponse,\n DashboardOAuthCompleteRequest,\n DashboardOAuthDisconnectRequest,\n AuthResponse,\n UserResponse,\n ChangePasswordRequest,\n DeleteAccountRequest,\n ForgotPasswordRequest,\n ResetPasswordRequest,\n SwitchMerchantRequest,\n SwitchProfileRequest,\n ImpersonateEmployeeRequest,\n InviteUsersRequest,\n InviteUsersResponse,\n AddUserRequest,\n AddUserResponse,\n UpdateUserRoleRequest,\n DeleteUserRoleRequest,\n ChangeMemberScopeRequest,\n ChangeMemberScopeResponse,\n UpdateMemberExpiryRequest,\n UpdateMemberExpiryResponse,\n GetUserRoleDetailsResponse,\n TeamMemberDetails,\n ResetTeamMemberPasswordRequest,\n ResetTeamMemberPasswordResponse,\n TotpResponse,\n RecoveryCodesResponse,\n PhoneOtpRequest,\n PhoneOtpResponse,\n PhoneOtpVerifyRequest,\n PhoneOtpVerifyResponse,\n UpdateMetadataRequest,\n SetUserPreferenceRequest,\n UserPreferenceResponse,\n UpdateUserDetailsRequest,\n FromEmailRequest,\n TokenResponse,\n UserInvitation,\n AcceptInvitationsPreAuthRequest,\n VerifyTotpRequest,\n Terminate2faQueryParams,\n ListInvitableRolesParams,\n ListUsersInLineageParams,\n UserInLineage,\n LoginHistoryParams,\n LoginHistoryResponse,\n UserSessionListResponse,\n UserSessionRevokeResponse,\n ParentGroupInfo,\n RoleConnectorGrant,\n UpdateRoleConnectorGrantParams,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Users {\n constructor(private readonly request: RequestFn) {}\n\n async signUp(params: SignUpRequest | SignUpWithMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signup', { body: params });\n }\n\n async signIn(params: SignInRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/signin', { body: params });\n }\n\n /** Providers currently configured for dashboard sign-in. */\n async listOAuthProviders(): Promise<DashboardOAuthProvidersResponse> {\n return this.request('GET', '/user/oauth/providers');\n }\n\n /** Current account's links; disabled providers remain visible. */\n async listLinkedOAuthProviders(): Promise<DashboardOAuthProvidersResponse> {\n return this.request('GET', '/user/oauth/linked');\n }\n\n async startOAuthSignIn(params: DashboardOAuthStartRequest): Promise<DashboardOAuthStartResponse> {\n return this.request('POST', '/user/oauth/start', { body: params });\n }\n\n async startOAuthLink(\n params: DashboardOAuthLinkStartRequest,\n ): Promise<DashboardOAuthStartResponse> {\n return this.request('POST', '/user/oauth/link/start', { body: params });\n }\n\n async completeOAuthSignIn(params: DashboardOAuthCompleteRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/oauth/complete', { body: params });\n }\n\n async completeOAuthLink(params: DashboardOAuthCompleteRequest): Promise<void> {\n return this.request('POST', '/user/oauth/link/complete', { body: params });\n }\n\n async disconnectOAuthProvider(\n provider: DashboardOAuthProvider,\n params: DashboardOAuthDisconnectRequest,\n ): Promise<void> {\n return this.request('DELETE', `/user/oauth/linked/${encodeURIComponent(provider)}`, {\n body: params,\n });\n }\n\n async signOut(): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/signout');\n }\n\n /**\n * Sliding-session refresh: exchange the current (still-valid) login JWT\n * for a fresh one with the same claims and a full lifetime. The backend\n * keeps the session's identity (`jti`), slides `user_session.expires_at`\n * forward and re-sets the `login_token` cookie.\n *\n * Requires a token backed by a revocable session (a `jti` claim). Signin\n * and switch-merchant/-profile tokens have one; **session-less tokens do\n * not and are rejected with 400** — team-impersonation tokens are the\n * case in practice, and they are deliberately tab-scoped and\n * time-bounded rather than renewable. A 400 here is not a dead session:\n * the token remains valid for ordinary calls, it simply cannot slide.\n *\n * Rejected (401) for expired, blacklisted or revoked tokens — refresh can\n * only extend a session that is still alive. Rate-limited server-side\n * (429) to one mint per session per minute; treat a 429 as \"still fresh\n * enough\", not as an error.\n *\n * The returned token is NOT applied to this client automatically — pass\n * it to `setJwtToken()`, or use {@link Delopay.refreshSession} which does\n * both.\n *\n * `POST /user/token/refresh`. Requires a logged-in JWT.\n */\n async refreshToken(): Promise<TokenResponse> {\n return this.request('POST', '/user/token/refresh');\n }\n\n /**\n * Paginated login history for the authenticated user -- IP, User-Agent,\n * country / city / lat-lon (when GeoIP is enabled), success and failure\n * events with their reasons. Strictly scoped to the JWT subject; a user\n * can only see their own activity.\n *\n * `GET /user/me/login-activity`. Requires a logged-in JWT.\n *\n * Returns an empty page when a Delopay admin is impersonating a merchant,\n * so the admin's metadata is not exposed inside the merchant dashboard.\n */\n async listLoginActivity(params?: LoginHistoryParams): Promise<LoginHistoryResponse> {\n if (params === undefined) {\n return this.request('GET', '/user/me/login-activity');\n }\n return this.request('GET', '/user/me/login-activity', {\n query: params as Record<string, number | undefined>,\n });\n }\n\n /**\n * List the authenticated user's currently-active dashboard sessions\n * (one row per minted login JWT that hasn't been revoked or expired).\n *\n * The row matching the JWT making this call has `is_current: true`,\n * which is what lets the dashboard render a \"This device\" tag.\n *\n * `GET /user/me/sessions`. Requires a logged-in JWT. Returns an empty\n * list when a Delopay admin is impersonating a non-admin merchant\n * (same guard as `listLoginActivity`).\n */\n async listActiveSessions(): Promise<UserSessionListResponse> {\n return this.request('GET', '/user/me/sessions');\n }\n\n /**\n * Disconnect one of the authenticated user's sessions. The matching\n * JWT is rejected on its next request — fast-path via Redis, fall back\n * to the persistent `revoked_at` column.\n *\n * Idempotent: revoking an already-revoked or unknown id returns 404,\n * which the caller can treat as success for retry purposes. Revoking\n * a session id that belongs to a different user also returns 404 —\n * the response intentionally doesn't leak whether the id exists.\n *\n * `POST /user/me/sessions/{sessionId}/revoke`.\n */\n async revokeSession(sessionId: string): Promise<UserSessionRevokeResponse> {\n return this.request('POST', `/user/me/sessions/${encodeURIComponent(sessionId)}/revoke`);\n }\n\n async getDetails(): Promise<UserResponse> {\n return this.request('GET', '/user');\n }\n\n async update(params: UpdateUserDetailsRequest): Promise<UserResponse> {\n return this.request('POST', '/user/update', { body: params });\n }\n\n /**\n * Read a preference owned by the logged-in user. Missing keys return value null.\n * Works in both dashboards with a login JWT; API keys and impersonation are rejected.\n * Keys contain 1–128 ASCII letters, digits, dots, underscores or hyphens.\n * Unknown widget IDs and their order are preserved; consumers choose what to render.\n */\n async getPreference(key: string): Promise<UserPreferenceResponse> {\n return this.request('GET', `/user/preferences/${encodeURIComponent(key)}`);\n }\n\n /**\n * Save one own preference: omitted/false if_absent replaces it (last write wins);\n * true preserves an existing object and returns the winner. The JSON object is\n * limited to 16 KiB of compact UTF-8 JSON. For layouts, use one namespaced key\n * per page (e.g. merchant.analytics.payments) and ordered widget IDs per region,\n * without titles, fetched metrics or rendered state. Requires a login JWT.\n */\n async setPreference(\n key: string,\n params: SetUserPreferenceRequest,\n ): Promise<UserPreferenceResponse> {\n return this.request('PUT', `/user/preferences/${encodeURIComponent(key)}`, { body: params });\n }\n\n /**\n * Initialize only a missing preference. Existing objects, including a client\n * reset marker saved with setPreference (for example { reset: true }), win. Render/cache the returned value, which may differ from\n * the proposed value. Safe for migration retries after a lost response.\n * Explicit edits and reset markers use setPreference with no if_absent flag.\n * DELETE removes the key; it leaves no marker and permits initialization again.\n * Requires a login JWT and the same key/object limits as setPreference.\n */\n async initializePreference(\n key: string,\n value: Record<string, unknown>,\n ): Promise<UserPreferenceResponse> {\n return this.request('PUT', `/user/preferences/${encodeURIComponent(key)}`, {\n body: { value, if_absent: true },\n });\n }\n\n /**\n * Remove an own preference. Idempotent; returns value null, without storing a\n * tombstone. Later initialization may import a value again. To suppress legacy\n * migration after a reset, save a client reset-marker object with setPreference.\n * Login JWT only.\n */\n async deletePreference(key: string): Promise<UserPreferenceResponse> {\n return this.request('DELETE', `/user/preferences/${encodeURIComponent(key)}`);\n }\n\n /**\n * RFC 7396 merge-patch the caller's own user-scoped metadata bucket.\n * Returns the full user details, so callers can refresh their context\n * without a second fetch.\n *\n * `PATCH /user/metadata`\n */\n async updateMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/metadata', { body: params });\n }\n\n /**\n * RFC 7396 merge-patch the merchant-scoped metadata bucket shared by\n * every dashboard user of the merchant. Same response contract as\n * {@link Users.updateMetadata}.\n *\n * `PATCH /user/merchant/metadata`\n */\n async updateMerchantMetadata(params: UpdateMetadataRequest): Promise<UserResponse> {\n return this.request('PATCH', '/user/merchant/metadata', { body: params });\n }\n\n /**\n * Permanently delete the caller's account. Requires a fresh password\n * (and a current 6-digit TOTP code if the user has TOTP enrolled). On\n * success all role assignments are removed, the user record is\n * deactivated, and all in-flight sessions are invalidated. The caller\n * should clear local credentials and route to the login page.\n *\n * Returns `InvalidDeleteOperation` when the caller is the sole\n * owner-level admin of an org / merchant / profile -- they must\n * transfer ownership first.\n */\n async deleteAccount(params: DeleteAccountRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/account', { body: params });\n }\n\n async changePassword(params: ChangePasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/change-password', { body: params });\n }\n\n async rotatePassword(params: ResetPasswordRequest): Promise<UserResponse> {\n return this.request('POST', '/user/rotate-password', { body: params });\n }\n\n async forgotPassword(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/forgot-password', { body: params });\n }\n\n /**\n * Commit a password reset.\n *\n * The caller is responsible for obtaining a `SinglePurposeToken` with\n * `purpose: reset_password` via the email-token exchange + TOTP flow\n * (see `fromEmail`, `beginTotp`, `updateTotp`/`verifyTotp`,\n * `generateRecoveryCodes`, `terminate2fa`) and setting it on the client\n * via `setJwtToken` before calling this method. `body.token` must still\n * be the original `EmailToken` from the reset-link URL — the handler\n * decodes it a second time to find the user.\n */\n async resetPassword(params: ResetPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/reset-password', { body: params });\n }\n\n /**\n * Exchange an email-link token (`EmailToken`) for a single-purpose JWT\n * that drives the next step of the flow (TOTP, verify email, accept\n * invitation, etc.). No authentication required.\n *\n * The `token_type` in the response tells you which step to run next.\n */\n async fromEmail(params: FromEmailRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/from-email', { body: params });\n }\n\n async verifyEmail(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/verify-email', { body: params });\n }\n\n async sendVerificationEmail(params: ForgotPasswordRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/verify-email-request', { body: params });\n }\n\n async createMerchant(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/create-merchant', { body: params });\n }\n\n async switchMerchant(params: SwitchMerchantRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/merchant', { body: params });\n }\n\n async switchProfile(params: SwitchProfileRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/switch/profile', { body: params });\n }\n\n async listMerchants(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/merchant');\n }\n\n async listProfiles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/list/profile');\n }\n\n /**\n * Invite team members by email. `POST /user/employees/invite`\n *\n * `project_ids` grants a shop-level role on every shop of each project, once\n * the invitation is accepted. A refusal of `project_ids` is a `UR_23` error whose `data.reason` is one of\n * `project_not_in_merchant`, `role_not_grantable_on_project`,\n * `shop_in_granted_project`, `project_already_granted` or\n * `project_grant_requires_merchant_level`.\n */\n async inviteUsers(params: InviteUsersRequest[]): Promise<InviteUsersResponse[]> {\n return this.request('POST', '/user/employees/invite', { body: params });\n }\n\n /**\n * Add a team member directly, without sending an invite email.\n * `POST /user/employees/add`\n *\n * Unlike `inviteUsers`, the account is active immediately and you hand over\n * the credentials yourself. Omit `password` to have the server generate one\n * and return it once in `password` on the response; supply your own and it is\n * not echoed back. Either way the member must change it on first sign-in.\n *\n * Same role rules as invite: you cannot grant a role above your own, and a\n * shop-scoped caller can only target their own shop. `project_ids` grants a\n * shop-level role on every shop of each project. A refusal of `project_ids` is a `UR_23` error whose `data.reason` is one of\n * `project_not_in_merchant`, `role_not_grantable_on_project`,\n * `shop_in_granted_project`, `project_already_granted` or\n * `project_grant_requires_merchant_level`.\n */\n async addUser(params: AddUserRequest): Promise<AddUserResponse> {\n return this.request('POST', '/user/employees/add', { body: params });\n }\n\n /**\n * Impersonate one of your own team members — `POST /user/employees/impersonate`.\n *\n * Mints a session token **as** the given member, so the dashboard renders\n * exactly what they see (useful for support and role verification). The\n * caller needs the *Impersonation* permission, and the member's role must\n * either rank **strictly below** the caller's\n * (`Profile < Merchant < Organization`), or sit at the caller's own\n * merchant-or-higher level and be **strictly narrower** than the caller's\n * role (grant nothing the caller's role does not, and less in total). The\n * server rejects self-impersonation and cross-merchant targets.\n * `MinimalRoleInfo.can_impersonate` in `listUsersInLineage` answers the same rule\n * per binding, so a UI can offer the action only where it will succeed.\n *\n * A role refusal is a `UR_33` error whose `data.reason` names the rule:\n * `impersonation_target_not_narrower` (the member's role is above, equal to,\n * or not contained in the caller's), or `act_as_token_cannot_impersonate`\n * (the caller is itself signed in as another member — start from your own\n * session).\n *\n * The returned token is tab-scoped by design: open it in a fresh tab (e.g.\n * `/auth/impersonate?token=…`) rather than replacing the caller's own\n * session. No auth cookie is set on the response.\n */\n async impersonateEmployee(params: ImpersonateEmployeeRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/employees/impersonate', { body: params });\n }\n\n async acceptInvitation(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/employees/invite/accept', { body: params });\n }\n\n /**\n * Accept invitations before a session exists.\n *\n * Sign-in issues a `token_type: \"accept_invite\"` step token instead of a\n * session when the caller has no active role yet — every role is still an\n * unaccepted invitation. With that token set via `setJwtToken`, pass the\n * entities from `listInvitations` here; the response is the next step of\n * the sign-in flow (`user_info` for the session, or `force_set_password`\n * first). Rejected when none of the entities carries a pending invitation.\n */\n async acceptInvitationsPreAuth(params: AcceptInvitationsPreAuthRequest): Promise<TokenResponse> {\n return this.request('POST', '/user/employees/invite/accept/pre-auth', { body: params });\n }\n\n /**\n * Accept an invitation via the email-link flow.\n *\n * Caller must already hold a `SinglePurposeToken` with\n * `purpose: accept_invitation_from_email` (obtained via `fromEmail` + any\n * required TOTP step) and have set it on the client via `setJwtToken`.\n * `body.token` must still be the original `EmailToken` from the\n * invite-link URL — the handler decodes it a second time to find the\n * invitee and the entity lineage.\n */\n async acceptInviteFromEmail(params: FromEmailRequest): Promise<AuthResponse> {\n return this.request('POST', '/user/accept-invite-from-email', { body: params });\n }\n\n /**\n * Start TOTP setup (or no-op if already set).\n *\n * Returns the QR-code payload when the user has no TOTP configured yet;\n * returns `{ secret: null }` when the user is already set up (caller\n * should then prompt for a 6-digit code and call `verifyTotp`).\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async beginTotp(): Promise<TotpResponse> {\n return this.request('GET', '/user/2fa/totp/begin');\n }\n\n /**\n * Verify a 6-digit TOTP code for a user whose TOTP is already set up.\n * Marks the code as used in Redis so subsequent flow steps can advance.\n *\n * Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async verifyTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/2fa/totp/verify', { body: params });\n }\n\n async resetTotp(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa/totp/reset');\n }\n\n async generateRecoveryCodes(): Promise<RecoveryCodesResponse> {\n return this.request('GET', '/user/2fa/recovery-code/generate');\n }\n\n async verifyRecoveryCode(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/2fa/recovery-code/verify', { body: params });\n }\n\n async sendPhoneOtp(params: PhoneOtpRequest): Promise<PhoneOtpResponse> {\n return this.request('POST', '/user/phone/send-otp', { body: params });\n }\n\n async verifyPhoneOtp(params: PhoneOtpVerifyRequest): Promise<PhoneOtpVerifyResponse> {\n return this.request('POST', '/user/phone/verify-otp', { body: params });\n }\n\n /**\n * List all roles visible to the caller (predefined + custom).\n *\n * `GET /user/role/list`. With `groups: true` the response is the\n * parent-groups shape: `[{role_id, role_name, entity_type, role_scope,\n * parent_groups: [{name, description, scopes}]}]`; without it, the\n * deprecated flat `groups` shape.\n *\n * Each role carries `managed_centrally: true` when it is a shared role the\n * platform offers this merchant: it can be assigned, but `updateRole`,\n * `deleteRole` and `updateRoleConnectors` refuse it with `UR_71`\n * (`data.reason: 'managed_centrally'`).\n */\n async listRoles(params?: {\n groups?: boolean;\n entity_type?: string;\n }): Promise<Record<string, unknown>[]> {\n if (params === undefined) {\n return this.request('GET', '/user/role/list');\n }\n return this.request('GET', '/user/role/list', {\n query: { groups: params.groups, entity_type: params.entity_type },\n });\n }\n\n /**\n * The roles a member holds, one entry per role. `POST /user/employees`\n *\n * A project-level role carries `project`: it applies to every shop of that\n * project.\n */\n async listUserRoles(params?: Record<string, unknown>): Promise<GetUserRoleDetailsResponse[]> {\n return this.request('POST', '/user/employees', { body: params });\n }\n\n /**\n * The current role's explicit payment-data policy, or `null` when the role\n * retains its pre-control access. A dashboard hint: every API response\n * enforces the same policy on its own. `GET /user/role/payment-visibility`\n */\n async getRolePaymentVisibility(): Promise<RolePaymentVisibilityPolicy | null> {\n return this.request('GET', '/user/role/payment-visibility');\n }\n\n /**\n * Change a team member's role. `POST /user/employees/update-role`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link UpdateUserRoleRequest.profile_id}.\n */\n async updateUserRole(params: UpdateUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/employees/update-role', { body: params });\n }\n\n /**\n * Remove a team member. `DELETE /user/employees/delete`\n *\n * Pass `profile_id` to name the shop when managing a shop's team as a\n * merchant-scoped admin — see {@link DeleteUserRoleRequest.profile_id}. Pass\n * `project_id` instead to remove a project-level role, which the member then\n * loses on every shop of the project.\n */\n async deleteUserRole(params: DeleteUserRoleRequest): Promise<Record<string, unknown>> {\n return this.request('DELETE', '/user/employees/delete', { body: params });\n }\n\n /**\n * Move a team member between a merchant-level role and shop-level roles.\n * `POST /user/employees/change-scope`\n *\n * A merchant-level `role_id` takes no `profile_ids` or `project_ids`; a\n * shop-level one needs at least one shop or project. A project grants the\n * role on every shop of the project, including shops added later. Every\n * earlier merchant-, project- and shop-level binding of the member in your\n * merchant is replaced. When the change takes a scope away, the\n * member's sessions end (`sessions_revoked: true`). Needs a caller at\n * merchant level or above. A refusal is a `UR_23` error whose `data.reason`\n * names the rule; an unknown `role_id` is `UR_22`. The project rules add the\n * reasons `project_not_in_merchant`, `role_not_grantable_on_project`,\n * `shop_in_granted_project`, `project_already_granted` and\n * `project_grant_requires_merchant_level`.\n */\n async changeMemberScope(params: ChangeMemberScopeRequest): Promise<ChangeMemberScopeResponse> {\n return this.request('POST', '/user/employees/change-scope', { body: params });\n }\n\n /**\n * Set or clear when a team member's access to your merchant ends.\n * `POST /user/employees/update-expiry`\n *\n * Every merchant-, shop- and project-level role the member holds in your\n * merchant, accepted or still an invitation, gets the same `expires_at`.\n * From that instant the roles grant nothing: every request, sign-in, token\n * refresh and switch made with them is refused, and `listUsersInLineage`\n * reports the instant in `MinimalRoleInfo.expires_at`. Send `null` to remove\n * the expiry. A shop-level caller reaches only members whose every role is\n * on its own shop. A refusal is a `UR_70` error whose `data` is an\n * {@link AccessExpiryRefusal}.\n */\n async updateMemberExpiry(params: UpdateMemberExpiryRequest): Promise<UpdateMemberExpiryResponse> {\n return this.request('POST', '/user/employees/update-expiry', { body: params });\n }\n\n /**\n * One member of your merchant, with the person fields the member list\n * omits. `GET /user/employees/{user_id}/details`\n *\n * Answers only for a member `listUsersInLineage` shows you. Any other id,\n * unknown or not yours, is a 404 `UR_68` with `data.reason:\n * 'member_not_found'`.\n */\n async getTeamMemberDetails(userId: string): Promise<TeamMemberDetails> {\n return this.request('GET', `/user/employees/${encodeURIComponent(userId)}/details`);\n }\n\n /**\n * Replace a team member's password with a temporary one, returned once.\n * `POST /user/employees/{user_id}/reset-password`\n *\n * Needs the *Users* write permission and the *Impersonation* permission,\n * and the member must be one you could sign in as with\n * `impersonateEmployee`. The member's sessions end, and their next sign-in\n * asks them to choose a new password. Two-factor authentication is left as\n * it is. `TeamMemberDetails.can_reset_password` answers the same rule. A\n * refusal is a `UR_68` error whose `data` is a {@link TeamMemberRefusal}.\n */\n async resetTeamMemberPassword(\n userId: string,\n params: ResetTeamMemberPasswordRequest,\n ): Promise<ResetTeamMemberPasswordResponse> {\n return this.request('POST', `/user/employees/${encodeURIComponent(userId)}/reset-password`, {\n body: params,\n });\n }\n\n /** Sign in via OIDC. `POST /user/oidc` */\n async signInOidc(params: Record<string, unknown>): Promise<AuthResponse> {\n return this.request('POST', '/user/oidc', { body: params });\n }\n\n /** Transfer key. `POST /user/key/transfer` */\n async transferKey(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/key/transfer', { body: params });\n }\n\n /**\n * Invitations still waiting on the caller. `GET /user/list/invitation`\n *\n * Accepts an `accept_invite` step token as well as a session JWT, so it\n * can feed `acceptInvitationsPreAuth` during sign-in. An invitation to a\n * project carries `project_id`; pass it back unchanged when accepting.\n */\n async listInvitations(): Promise<UserInvitation[]> {\n return this.request('GET', '/user/list/invitation');\n }\n\n /** Check 2FA status. `GET /user/2fa` */\n async check2faStatus(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/2fa');\n }\n\n /**\n * Finish first-time TOTP setup: commit the secret generated by `beginTotp`\n * against a 6-digit code from the user's authenticator app.\n *\n * `PUT /user/2fa/totp/verify`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async updateTotp(params: VerifyTotpRequest): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/2fa/totp/verify', { body: params });\n }\n\n /**\n * Complete the TOTP step and advance to the next flow stage (e.g.\n * `reset_password`). Returns a fresh single-purpose token with the\n * next `token_type`.\n *\n * `GET /user/2fa/terminate`. Requires `Authorization: Bearer <SPT{purpose:totp}>`.\n */\n async terminate2fa(query?: Terminate2faQueryParams): Promise<TokenResponse> {\n if (query === undefined) {\n return this.request('GET', '/user/2fa/terminate');\n }\n return this.request('GET', '/user/2fa/terminate', {\n query: query as Record<string, boolean | undefined>,\n });\n }\n\n /** Create auth method. `POST /user/auth` */\n async createAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth', { body: params });\n }\n\n /** Update auth method. `PUT /user/auth` */\n async updateAuthMethod(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PUT', '/user/auth', { body: params });\n }\n\n /** List auth methods. `GET /user/auth/list` */\n async listAuthMethods(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/auth/list');\n }\n\n /** Get auth URL. `GET /user/auth/url` */\n async getAuthUrl(): Promise<Record<string, unknown>> {\n return this.request('GET', '/user/auth/url');\n }\n\n /** Select auth method. `POST /user/auth/select` */\n async selectAuth(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/auth/select', { body: params });\n }\n\n /**\n * List users in lineage.\n *\n * Needs the Users *view* grant now — the response carries colleagues' email\n * addresses, so a role without it is refused rather than handed a roster.\n * A shop-scoped role keeps reading its own shop's members.\n *\n * `GET /user/employees/list`\n */\n async listUsersInLineage(params?: ListUsersInLineageParams): Promise<UserInLineage[]> {\n return this.request('GET', '/user/employees/list', {\n query: params as Record<string, string | undefined> | undefined,\n });\n }\n\n /** Resend invite. `POST /user/resend-invite` */\n async resendInvite(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/resend-invite', { body: params });\n }\n\n /**\n * Get the caller's parent permission groups + scopes.\n *\n * `GET /user/role`\n */\n async getRolePermissions(): Promise<ParentGroupInfo[]> {\n return this.request('GET', '/user/role');\n }\n\n /**\n * List invitable roles. `GET /user/role/list/invite`\n *\n * @param params - Optional query. `entity_type` scopes the role list to a\n * particular entity (e.g. `'merchant'` to list only merchant-scoped roles\n * when inviting employees from the merchant dashboard).\n */\n async listInvitableRoles(params?: ListInvitableRolesParams): Promise<Record<string, unknown>[]> {\n if (params === undefined || params.entity_type === undefined) {\n return this.request('GET', '/user/role/list/invite');\n }\n return this.request('GET', '/user/role/list/invite', {\n query: { entity_type: params.entity_type },\n });\n }\n\n /** List updatable roles. `GET /user/role/list/update` */\n async listUpdatableRoles(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/role/list/update');\n }\n\n /** Get parent list. `GET /user/parent/list` */\n async getParentList(): Promise<Record<string, unknown>[]> {\n return this.request('GET', '/user/parent/list');\n }\n\n /** Create a role. `POST /user/role` */\n async createRole(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/user/role', { body: params });\n }\n\n /** Get role by ID. `GET /user/role/{roleId}` */\n async getRoleById(roleId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /** Update role by ID. `PUT /user/role/{roleId}` */\n async updateRole(\n roleId: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}`, { body: params });\n }\n\n /**\n * Delete a custom role. Predefined roles and roles still assigned to\n * team members are rejected by the backend with a 400.\n *\n * `DELETE /user/role/{roleId}`\n */\n async deleteRole(roleId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/user/role/${encodeURIComponent(roleId)}`);\n }\n\n /**\n * Read which individual connector accounts a role may see.\n *\n * `GET /user/role/{roleId}/connectors`\n *\n * **Check `restricted` before reading `connectors`.** An empty list is\n * ambiguous by itself, so the backend states which case it is: `false` means\n * the role holds no grant and sees whatever its entity and profile scope\n * already allowed. Rendering an empty `connectors` array as \"this role sees\n * nothing\" inverts the meaning.\n *\n * Requires the permission that *edits a role*, not a connector permission.\n */\n async getRoleConnectors(roleId: string): Promise<RoleConnectorGrant> {\n return this.request('GET', `/user/role/${encodeURIComponent(roleId)}/connectors`);\n }\n\n /**\n * Replace the set of connector accounts a role may see.\n *\n * `PUT /user/role/{roleId}/connectors`\n *\n * The call **replaces** the whole set rather than adding to it, so send the\n * complete list every time. An empty `merchant_connector_ids` clears the\n * grant and returns the role to unrestricted.\n *\n * The backend refuses an id that is not a connector account of the caller's\n * own merchant, an `Organization`-scoped role (a connector account belongs to\n * exactly one merchant, so an org-spanning role cannot hold one coherently),\n * and any predefined role (one static entry shared by every tenant).\n *\n * Editing a grant invalidates the role cache and blacklists tokens minted\n * before the edit, so **users holding this role must sign in again**. Worth\n * saying in the UI before the save, not after.\n */\n async updateRoleConnectors(\n roleId: string,\n params: UpdateRoleConnectorGrantParams,\n ): Promise<RoleConnectorGrant> {\n return this.request('PUT', `/user/role/${encodeURIComponent(roleId)}/connectors`, {\n body: params,\n });\n }\n}\n","import type {\n ApplePayVerificationRequest,\n ApplePayVerificationResponse,\n ApplePayVerifiedDomainsResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\nexport class Verification {\n constructor(private readonly request: RequestFn) {}\n\n async registerApplePayDomains(\n merchantId: string,\n params: ApplePayVerificationRequest,\n ): Promise<ApplePayVerificationResponse> {\n return this.request('POST', `/verify/apple-pay/${encodeURIComponent(merchantId)}`, {\n body: params,\n });\n }\n\n async getApplePayVerifiedDomains(\n params: Record<string, string>,\n ): Promise<ApplePayVerifiedDomainsResponse> {\n return this.request('GET', '/verify/applepay-verified-domains', {\n query: params,\n });\n }\n}\n","import type {\n EventType,\n PaymentResponse,\n RefundResponse,\n DisputeResponse,\n MandateResponse,\n PayoutResponse,\n LifecycleWebhook,\n SubscriptionDisputeWebhook,\n SubscriptionWebhookContent,\n ShopRiskEscalationWebhook,\n MerchantInvoiceWebhook,\n} from '../types';\n\n/**\n * The payload of a webhook event, tagged by kind.\n *\n * Mirrors the backend's `{ \"type\": …, \"object\": … }` envelope: `type` names the\n * payload shape and `object` carries it. Narrow on `content.type` to get a\n * fully-typed `object`:\n *\n * ```typescript\n * if (event.content.type === 'payment_details') {\n * event.content.object.payment_id; // typed as PaymentResponse\n * }\n * ```\n */\nexport type WebhookContent =\n | { type: 'payment_details'; object: PaymentResponse }\n | { type: 'refund_details'; object: RefundResponse }\n | { type: 'dispute_details'; object: DisputeResponse }\n | { type: 'mandate_details'; object: MandateResponse }\n | { type: 'payout_details'; object: PayoutResponse }\n | { type: 'subscription_details'; object: SubscriptionWebhookContent }\n | { type: 'shop_risk_details'; object: ShopRiskEscalationWebhook }\n | { type: 'merchant_invoice_details'; object: MerchantInvoiceWebhook };\n\n/**\n * Whether a `subscription_details` payload is a lifecycle snapshot\n * ({@link LifecycleWebhook}) rather than a cycle chargeback or a paid invoice.\n *\n * Three shapes share `content.type`; what marks a lifecycle snapshot on the\n * wire is `transition_id`, which neither of the other two carries. Narrowing\n * on it — rather than on `event_type` — keeps a handler correct for a\n * lifecycle event added after it was written. A payload that fails this check\n * is not yet a paid invoice: test {@link isSubscriptionDisputeWebhook} next.\n *\n * @example\n * ```typescript\n * if (event.content.type === 'subscription_details') {\n * const object = event.content.object;\n * if (isSubscriptionLifecycleWebhook(object)) {\n * object.status; // SubscriptionStatus at the transition\n * object.cancel_at_period_end; // true for a scheduled cancellation\n * } else if (isSubscriptionDisputeWebhook(object)) {\n * object.amount; // what this chargeback took from the cycle\n * } else {\n * object.invoice; // the paid invoice\n * }\n * }\n * ```\n */\nexport function isSubscriptionLifecycleWebhook(\n object: SubscriptionWebhookContent,\n): object is LifecycleWebhook {\n return typeof (object as Partial<LifecycleWebhook>).transition_id === 'string';\n}\n\n/**\n * Whether a `subscription_details` payload is a chargeback against a\n * subscription cycle ({@link SubscriptionDisputeWebhook}, sent as\n * `invoice_disputed`).\n *\n * It is the only `subscription_details` shape that carries\n * `connector_dispute_id`; neither a lifecycle snapshot nor a paid invoice does.\n */\nexport function isSubscriptionDisputeWebhook(\n object: SubscriptionWebhookContent,\n): object is SubscriptionDisputeWebhook {\n return typeof (object as Partial<SubscriptionDisputeWebhook>).connector_dispute_id === 'string';\n}\n\n/**\n * A parsed and verified Delopay webhook event.\n *\n * Matches the signed wire body exactly:\n * `{ merchant_id, event_id, event_type, content: { type, object }, timestamp }`.\n *\n * - `event_type` identifies the event, e.g. `'payment_succeeded'`.\n * - `content.type` tags the payload kind, e.g. `'payment_details'`.\n * - `content.object` is the payload; narrow on `content.type` to type it.\n */\nexport interface WebhookEvent {\n /** ID of the merchant that owns this event. */\n merchant_id: string;\n /** Unique ID for this event (stable across delivery retries). */\n event_id: string;\n /** Event type identifier, e.g. `'payment_succeeded'` or `'refund_succeeded'`. */\n event_type: EventType;\n /** The event payload, tagged by kind. Narrow on `content.type` to type `object`. */\n content: WebhookContent;\n /** ISO 8601 timestamp at which the webhook was sent. */\n timestamp: string;\n}\n\nfunction hexToBytes(hex: string): Uint8Array | null {\n if (hex.length === 0 || hex.length % 2 !== 0) return null;\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = Number.parseInt(hex.slice(i, i + 2), 16);\n if (Number.isNaN(byte)) return null;\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\nexport const Webhooks = {\n /**\n * Verify the signature of an incoming Delopay webhook and return the parsed event.\n *\n * Delopay signs each outgoing webhook with HMAC-SHA512 over the raw request body,\n * using your shop's webhook secret (the *payment response hash key* configured on\n * the shop). The hex-encoded digest is delivered in the `X-Webhook-Signature-512`\n * HTTP header.\n *\n * Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in\n * Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).\n *\n * Available as a static property on the `Delopay` class\n * (`Delopay.webhooks.verify`) and does not require a client instance.\n *\n * @param rawBody - The raw request body. Pass the original bytes (`Uint8Array` /\n * `Buffer`) when possible; if you pass a string, it must be the unmodified UTF-8\n * text of the request body. Do **not** parse it before passing.\n * @param signatureHeader - The value of the `X-Webhook-Signature-512` HTTP header.\n * @param secret - Your shop's webhook signing secret.\n * @returns Promise that resolves to the parsed webhook event.\n * @throws {Error} When the signature header is malformed or does not match the body.\n *\n * @example\n * ```typescript\n * // Express example\n * app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {\n * try {\n * const event = await Delopay.webhooks.verify(\n * req.body, // Buffer from express.raw()\n * req.header('x-webhook-signature-512') ?? '',\n * process.env.DELOPAY_WEBHOOK_SECRET!,\n * );\n * console.log(event.event_type, event.content.object);\n * res.sendStatus(200);\n * } catch {\n * res.status(400).send('Invalid signature');\n * }\n * });\n * ```\n */\n async verify(\n rawBody: string | Uint8Array,\n signatureHeader: string,\n secret: string,\n ): Promise<WebhookEvent> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error(\n 'Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)',\n );\n }\n\n const signatureBytes = hexToBytes(signatureHeader.trim());\n if (!signatureBytes) {\n throw new Error('Invalid webhook signature format');\n }\n\n const encoder = new TextEncoder();\n const bodyBytes = typeof rawBody === 'string' ? encoder.encode(rawBody) : rawBody;\n\n // `TextEncoder.encode` returns `Uint8Array<ArrayBufferLike>` in current lib.dom.d.ts,\n // but `crypto.subtle.*` wants `BufferSource` (backed by `ArrayBuffer`). At runtime the\n // underlying buffer is always an `ArrayBuffer` — cast to quiet the type checker.\n const asBufferSource = (bytes: Uint8Array): BufferSource => bytes as unknown as BufferSource;\n const key = await subtle.importKey(\n 'raw',\n asBufferSource(encoder.encode(secret)),\n { name: 'HMAC', hash: 'SHA-512' },\n false,\n ['verify'],\n );\n\n const valid = await subtle.verify(\n 'HMAC',\n key,\n asBufferSource(signatureBytes),\n asBufferSource(bodyBytes),\n );\n\n if (!valid) {\n throw new Error('Invalid webhook signature');\n }\n\n const bodyText =\n typeof rawBody === 'string' ? rawBody : new TextDecoder('utf-8').decode(rawBody);\n return JSON.parse(bodyText) as WebhookEvent;\n },\n};\n","import type { RequestFn } from '../client';\nimport type {\n AnalyticsScopeRequest,\n AnalyticsScopeResponse,\n ClientAnalyticsRequest,\n DevicesAnalyticsResponse,\n GeoAnalyticsResponse,\n DeviceDrillRequest,\n GeoDrillRequest,\n DrillResponse,\n SubscriptionAnalyticsRequest,\n SubscriptionAnalyticsResponse,\n SubscriptionDrillRequest,\n ScopeDrillRequest,\n AnalyticsExclusionRequest,\n AnalyticsExclusionResponse,\n AnalyticsExclusionsResponse,\n} from '../types';\n\nexport class Analytics {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Scoped, drill-level analytics dashboard for the authenticated merchant\n * (the same engine as the admin portal, pinned server-side to your own\n * merchant). The server ignores `merchant_id` — it always scopes to your\n * merchant, and to your single shop for profile-scoped users — so pass only\n * `project_id` / `shop_id` to drill and the window / `sections` fields.\n * Returns one drill level: the scope's daily series + previous window,\n * processor mix and direct children. Accepts a dashboard session or an API\n * key, including a `statistics_read` key; a shop-bound key reads only its\n * shop. `GET /analytics/scope`\n */\n async scope(params?: AnalyticsScopeRequest): Promise<AnalyticsScopeResponse> {\n return this.request('GET', '/analytics/scope', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Device analytics over the canonical client-context observation per\n * payment (browser/platform families, device classes and models, checkout\n * channel mix, time-to-pay), pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`. Gated on the\n * client-context optimisation-use switch: when it is off the server answers\n * 200 with `enabled: false` and a caveat naming the switch. Accepts an API\n * key like `scope`. `GET /analytics/devices`\n */\n async devices(params?: ClientAnalyticsRequest): Promise<DevicesAnalyticsResponse> {\n return this.request('GET', '/analytics/devices', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Geo analytics over the canonical client-context observation per payment:\n * country totals, city bubbles (IP mode), buyer languages, buyer-local\n * purchase hours and the IP-vs-billing mismatch share. `mode` selects the\n * location claim (`ip` default, `billing`); the two are never coalesced.\n * Same drill, window, gating and API-key contract as `devices`.\n * `GET /analytics/geo`\n */\n async geo(params?: ClientAnalyticsRequest): Promise<GeoAnalyticsResponse> {\n return this.request('GET', '/analytics/geo', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked geo target: a map country (in the\n * active claim mode), optionally narrowed to an IP-resolved city, or one\n * buyer-local heatmap cell (`dow` + `hour`, paid sessions only). Same\n * window/scope/filter and gating contract as `geo`; capped at 50 rows,\n * newest first, with the full match count alongside.\n * `GET /analytics/geo/transactions`\n */\n async geoTransactions(params: GeoDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/geo/transactions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The recent payments behind one clicked device target: exactly one of a\n * browser family, a platform family, an identified device-model label, or\n * a device class. Family/model targets are resolved server-side with the\n * same classifiers the cards use. Same window/scope/filter and gating\n * contract as `devices`; 50 rows per page (`offset` for the next page),\n * newest first, with the full match count alongside.\n * `GET /analytics/devices/transactions`\n */\n async deviceTransactions(params: DeviceDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/devices/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The payments behind one clicked element of the payments dashboard: a\n * processor-donut slice, a payment-method slice, an outcome segment of a\n * series bar, a series bucket, or a breakdown row — combinable, with\n * `target_bucket` narrowing every other target. The outcome mapping is the\n * one the series and donuts are folded with, expanded server-side, so the\n * list is what the clicked number was made of. Rows and the whole-match\n * `summary` carry USD figures converted with the dashboard's own rates.\n * Same window/scope/chip contract as `scope`; sorted per `sort_on` /\n * `sort_by`, `limit` rows (default 50) per page, `offset` for the next.\n * `GET /analytics/scope/transactions`\n */\n async scopeTransactions(params: ScopeDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/scope/transactions', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Subscription analytics over `subscription` and `invoice`: estimated\n * recurring volume, the invoice funnel, movement (new / expansion /\n * contraction / churn), both processor axes, plan mix and the breakdown one\n * level below the scope. Pinned server-side to your own merchant and\n * drillable via `project_id` / `shop_id` exactly like `scope`.\n *\n * Half the figures are **stocks** — a snapshot at the window's end rather\n * than a sum over it — so `est_monthly_volume_usd` and `active` can match\n * across a 7-day and a 30-day window while `billed_volume_usd` does not.\n * Day granularity only. Accepts an API key like `scope`.\n * `GET /analytics/subscriptions`\n */\n async subscriptions(\n params?: SubscriptionAnalyticsRequest,\n ): Promise<SubscriptionAnalyticsResponse> {\n return this.request('GET', '/analytics/subscriptions', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * The billing cycles behind one clicked element of the subscription\n * dashboard: an invoice outcome, a processor slice on either axis, a plan\n * row, a subscription status, a movement component, a series bucket or a\n * breakdown row. Same window/scope/filter contract as `subscriptions`; 50\n * rows per page (`offset` for the next), newest first, with the full match\n * count alongside.\n *\n * A cycle that never reached a payment is listed too — that is what \"still\n * unpaid\" means — and carries its invoice id as `payment_id` with\n * `invoice_id` set to the same value, so you can always tell which you got.\n * `GET /analytics/subscriptions/list`\n */\n async subscriptionsList(params: SubscriptionDrillRequest): Promise<DrillResponse> {\n return this.request('GET', '/analytics/subscriptions/list', {\n // A discriminated union carries no index signature, so the widening\n // goes via `unknown` — the union is the point, and the query builder\n // only ever reads own enumerable keys.\n query: params as unknown as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Every analytics exclusion of the merchant, with the payments each one\n * matched in the lookback window.\n *\n * These rules change what the merchant's own dashboards count. Financial\n * records and transaction lists are never filtered by them.\n *\n * `matched_payments` counts overlap between rules: a payment matched by\n * three rules is counted once by each, so the values are not additive. The\n * envelope's `best_effort` and `lookback_days` apply to every row — matching\n * runs on client signals that may be absent or expired, within that window.\n * `GET /analytics/exclusions`\n */\n async listExclusions(): Promise<AnalyticsExclusionsResponse> {\n return this.request('GET', '/analytics/exclusions');\n }\n\n /**\n * Write a new exclusion. A shop-scoped user must name their own shop in\n * `profile_id`; omitting it applies the rule to every shop of the merchant.\n * Omitting `surfaces` means **all five**, not none.\n * `POST /analytics/exclusions`\n */\n async createExclusion(rule: AnalyticsExclusionRequest): Promise<AnalyticsExclusionResponse> {\n return this.request('POST', '/analytics/exclusions', { body: rule });\n }\n\n /**\n * Replace a stored exclusion **completely**. This is not a patch: every\n * field you leave out reverts to its default rather than keeping its stored\n * value, so send the whole rule — including an explicit `null` for a\n * `profile_id`, `value`, `valid_from`, `valid_until` or `note` you mean to\n * clear, and the full `surfaces` list you mean to keep.\n * `PUT /analytics/exclusions/{id}`\n */\n async updateExclusion(\n id: string,\n rule: AnalyticsExclusionRequest,\n ): Promise<AnalyticsExclusionResponse> {\n return this.request('PUT', `/analytics/exclusions/${encodeURIComponent(id)}`, { body: rule });\n }\n\n /**\n * Delete a stored exclusion. Returns the rule as it was, so a caller can\n * say what it removed. `DELETE /analytics/exclusions/{id}`\n */\n async deleteExclusion(id: string): Promise<AnalyticsExclusionResponse> {\n return this.request('DELETE', `/analytics/exclusions/${encodeURIComponent(id)}`);\n }\n\n /** Global search. `POST /analytics/search` */\n async search(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/search', { body: params });\n }\n\n /** Domain-specific search. `POST /analytics/search/{domain}` */\n async searchDomain(\n domain: string,\n params: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n return this.request('POST', `/analytics/search/${encodeURIComponent(domain)}`, {\n body: params,\n });\n }\n\n /** Get analytics info. `GET /analytics/{domain}/info` */\n async getInfo(domain: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/analytics/${encodeURIComponent(domain)}/info`);\n }\n\n /** Get API event logs. `GET /analytics/api-event-logs` */\n async apiEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/api-event-logs', { query: params });\n }\n\n /** Get SDK event logs. `POST /analytics/sdk-event-logs` */\n async sdkEventLogs(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics/sdk-event-logs', { body: params });\n }\n\n /** Get connector event logs. `GET /analytics/connector-event-logs` */\n async connectorEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/connector-event-logs', { query: params });\n }\n\n /** Get routing event logs. `GET /analytics/routing-event-logs` */\n async routingEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/routing-event-logs', { query: params });\n }\n\n /** Get outgoing webhook event logs. `GET /analytics/outgoing-webhook-event-logs` */\n async outgoingWebhookEventLogs(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics/outgoing-webhook-event-logs', { query: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class AnalyticsDashboard {\n constructor(private readonly request: RequestFn) {}\n\n /** Get analytics dashboard data. `GET /analytics-dashboard` */\n async retrieve(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/analytics-dashboard', { query: params });\n }\n\n /** Generate analytics dashboard report. `POST /analytics-dashboard` */\n async generate(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/analytics-dashboard', { body: params });\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Cards {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a card. `POST /cards/create` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/create', { body: params });\n }\n\n /** Update a card. `POST /cards/update` */\n async update(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/cards/update', { body: params });\n }\n\n /** Retrieve card info by BIN. `GET /cards/{bin}` */\n async retrieve(bin: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/cards/${encodeURIComponent(bin)}`);\n }\n}\n","import type {\n DisputeExportRecord,\n DisputeListParams,\n ExportEnvelope,\n BinaryExportOptions,\n CsvExportOptions,\n DynamicLineExportOptions,\n ExportOptions,\n JsonExportOptions,\n MerchantAuditLogExportRecord,\n MerchantAuditLogListParams,\n PayoutExportRecord,\n PayoutListParams,\n RefundExportRecord,\n RefundListParams,\n PaymentListFilterConstraints,\n ProfilePaymentListFilterConstraints,\n SubscriptionExportRecord,\n SubscriptionListParams,\n TransactionExportRecord,\n TransactionLineExportRecord,\n} from '../types';\nimport type { RequestFn, RequestOptions } from '../client';\nimport { runExport } from '../exportDownload';\n\n/** Query value shape `RequestOptions.query` accepts. */\ntype Query = NonNullable<RequestOptions['query']>;\n\n/**\n * Emit a list as a file.\n *\n * Every method here mirrors one list endpoint and takes **that list's own\n * filters**, unchanged — there is no second filter vocabulary for exports. The\n * shop scope is resolved the same way too, so an export cannot show a shop its\n * list would not: a shop-scoped token exports its own shop, and naming another\n * is refused rather than ignored.\n *\n * Every export is **one read**, not a paged walk, and is bounded at 25,000\n * rows (500 for `pdf`, which is a document rather than a data feed). Over the\n * bound the request is refused with `DE_07 export_row_limit_exceeded` carrying\n * `{entity, max_rows}` — a truncated finance file that reports success is the\n * thing these endpoints exist not to produce. When too many exports are\n * already running the server answers `429` `IR_52` (`export_capacity_busy`);\n * a `GET` export is retried after its `Retry-After` like any other `429`.\n *\n * `csv` and `json` are **streamed**: the server counts the match set, sends\n * that count in `X-Delopay-Record-Count` before the first byte, and writes the\n * rows as it reads them. Each method holds the finished body to that count and\n * rejects with `EXPORT_INCOMPLETE` rather than resolve to a file missing rows —\n * see {@link ExportTransferOptions}, which also carries the download's\n * `onProgress`, `signal` and (idle) `timeout`. `pdf` stays a buffered body.\n *\n * `format` selects an `Accept` header, never a request field: an export reuses\n * its list's filter model as literally the same type, and several of those are\n * `deny_unknown_fields`, so a `format` key would be a 400. It defaults to\n * `json`, which resolves to a typed {@link ExportEnvelope}; `csv` and `pdf`\n * resolve to a `Blob`.\n */\nexport class Export {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Transactions. `POST /export/transactions`\n *\n * The payments `payments.listByFilter` would list for the same body, over the\n * whole match set: same filters, same order, same scope. `limit` and\n * `offset` are ignored — the page is what an export does away with. No time\n * window is required; the row bound refuses an export that matches too much.\n */\n async transactions(\n params?: PaymentListFilterConstraints,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord>>;\n async transactions(\n params: PaymentListFilterConstraints | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async transactions(\n params: PaymentListFilterConstraints | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n async transactions(\n params?: PaymentListFilterConstraints,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob> {\n return runExport(this.request, 'POST', '/export/transactions', { body: params ?? {} }, options);\n }\n\n /**\n * The caller's own shop's transactions.\n * `POST /export/profile/transactions`\n *\n * The shop-scoped twin of {@link Export.transactions}, taking the body\n * `payments.listByProfileFilter` sends and scoped exactly as that list is: to\n * the shop on the token. Gated on the profile-level payment permission, which\n * a shop-scoped role can hold where the merchant-level one cannot. Its rows\n * carry no `connector_settlement_status`, which a shop viewer is not shown.\n */\n async transactionsForProfile(\n params?: ProfilePaymentListFilterConstraints,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord>>;\n async transactionsForProfile(\n params: ProfilePaymentListFilterConstraints | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async transactionsForProfile(\n params: ProfilePaymentListFilterConstraints | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob>;\n async transactionsForProfile(\n params?: ProfilePaymentListFilterConstraints,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<TransactionExportRecord> | Blob> {\n return runExport(\n this.request,\n 'POST',\n '/export/profile/transactions',\n { body: params ?? {} },\n options,\n );\n }\n\n /**\n * Transactions, one row per product line. `POST /export/transactions/lines`\n *\n * The payments {@link Export.transactions} would export for the same body,\n * one row per product line they recorded, plus one `row_kind: 'no_lines'`\n * row for each payment that recorded none — see\n * {@link TransactionLineExportRecord} for how the file reconciles with the\n * per-payment one. `csv` or `json` only: a line export has no PDF form, and\n * the server refuses one with `422`. The row bound applies to the rows.\n */\n async transactionLines(\n params?: PaymentListFilterConstraints,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord>>;\n async transactionLines(\n params: PaymentListFilterConstraints | undefined,\n options: CsvExportOptions,\n ): Promise<Blob>;\n async transactionLines(\n params: PaymentListFilterConstraints | undefined,\n options: DynamicLineExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord> | Blob>;\n async transactionLines(\n params?: PaymentListFilterConstraints,\n options?: JsonExportOptions | CsvExportOptions | DynamicLineExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord> | Blob> {\n return runExport(\n this.request,\n 'POST',\n '/export/transactions/lines',\n { body: params ?? {} },\n options,\n );\n }\n\n /**\n * The caller's own shop's transactions, one row per product line.\n * `POST /export/profile/transactions/lines`\n *\n * The shop-scoped twin of {@link Export.transactionLines}, scoped as\n * {@link Export.transactionsForProfile} is: to the shop on the token.\n */\n async transactionLinesForProfile(\n params?: ProfilePaymentListFilterConstraints,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord>>;\n async transactionLinesForProfile(\n params: ProfilePaymentListFilterConstraints | undefined,\n options: CsvExportOptions,\n ): Promise<Blob>;\n async transactionLinesForProfile(\n params: ProfilePaymentListFilterConstraints | undefined,\n options: DynamicLineExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord> | Blob>;\n async transactionLinesForProfile(\n params?: ProfilePaymentListFilterConstraints,\n options?: JsonExportOptions | CsvExportOptions | DynamicLineExportOptions,\n ): Promise<ExportEnvelope<TransactionLineExportRecord> | Blob> {\n return runExport(\n this.request,\n 'POST',\n '/export/profile/transactions/lines',\n { body: params ?? {} },\n options,\n );\n }\n\n /** Refunds. `POST /refunds/list/export` */\n async refunds(\n params?: RefundListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord>>;\n async refunds(params: RefundListParams | undefined, options: BinaryExportOptions): Promise<Blob>;\n async refunds(\n params: RefundListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob>;\n async refunds(\n params?: RefundListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob> {\n return runExport(this.request, 'POST', '/refunds/list/export', { body: params ?? {} }, options);\n }\n\n /** The caller's own shop's refunds. `POST /refunds/profile/list/export` */\n async refundsForProfile(\n params?: RefundListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord>>;\n async refundsForProfile(\n params: RefundListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async refundsForProfile(\n params: RefundListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob>;\n async refundsForProfile(\n params?: RefundListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<RefundExportRecord> | Blob> {\n return runExport(\n this.request,\n 'POST',\n '/refunds/profile/list/export',\n { body: params ?? {} },\n options,\n );\n }\n\n /** Disputes. `GET /disputes/list/export` */\n async disputes(\n params?: DisputeListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord>>;\n async disputes(\n params: DisputeListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async disputes(\n params: DisputeListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob>;\n async disputes(\n params?: DisputeListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob> {\n return runExport(this.request, 'GET', '/disputes/list/export', queried(params), options);\n }\n\n /** The caller's own shop's disputes. `GET /disputes/profile/list/export` */\n async disputesForProfile(\n params?: DisputeListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord>>;\n async disputesForProfile(\n params: DisputeListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async disputesForProfile(\n params: DisputeListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob>;\n async disputesForProfile(\n params?: DisputeListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<DisputeExportRecord> | Blob> {\n return runExport(\n this.request,\n 'GET',\n '/disputes/profile/list/export',\n queried(params),\n options,\n );\n }\n\n /** Payouts. `POST /payouts/list/export` */\n async payouts(\n params: PayoutListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord>>;\n async payouts(params: PayoutListParams, options: BinaryExportOptions): Promise<Blob>;\n async payouts(\n params: PayoutListParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob>;\n async payouts(\n params: PayoutListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob> {\n return runExport(this.request, 'POST', '/payouts/list/export', { body: params }, options);\n }\n\n /** The caller's own shop's payouts. `POST /payouts/profile/list/export` */\n async payoutsForProfile(\n params: PayoutListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord>>;\n async payoutsForProfile(params: PayoutListParams, options: BinaryExportOptions): Promise<Blob>;\n async payoutsForProfile(\n params: PayoutListParams,\n options: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob>;\n async payoutsForProfile(\n params: PayoutListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<PayoutExportRecord> | Blob> {\n return runExport(\n this.request,\n 'POST',\n '/payouts/profile/list/export',\n { body: params },\n options,\n );\n }\n\n /**\n * Subscriptions. `GET /subscriptions/list/export`\n *\n * `profileId` becomes the `X-Profile-Id` header, exactly as on the list. A\n * shop-scoped token exports its own shop whatever this says.\n */\n async subscriptions(\n profileId: string,\n params?: SubscriptionListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord>>;\n async subscriptions(\n profileId: string,\n params: SubscriptionListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async subscriptions(\n profileId: string,\n params: SubscriptionListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord> | Blob>;\n async subscriptions(\n profileId: string,\n params?: SubscriptionListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<SubscriptionExportRecord> | Blob> {\n return runExport(\n this.request,\n 'GET',\n '/subscriptions/list/export',\n queried(params, { 'X-Profile-Id': profileId }),\n options,\n );\n }\n\n /** Settlement statements. `GET /settlement/statements/export` */\n\n /** One period's settlement lines. `GET /settlement/lines/export` */\n\n /**\n * The merchant's own audit log. `GET /audit/export`\n *\n * Requires a dashboard JWT whose role holds the merchant-level `AuditLog`\n * permission — a shop-scoped role cannot hold it. There is no `merchant_id`\n * parameter: the scope comes from the token.\n */\n async auditLog(\n params?: MerchantAuditLogListParams,\n options?: JsonExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord>>;\n async auditLog(\n params: MerchantAuditLogListParams | undefined,\n options: BinaryExportOptions,\n ): Promise<Blob>;\n async auditLog(\n params: MerchantAuditLogListParams | undefined,\n options: ExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord> | Blob>;\n async auditLog(\n params?: MerchantAuditLogListParams,\n options?: ExportOptions,\n ): Promise<ExportEnvelope<MerchantAuditLogExportRecord> | Blob> {\n return runExport(this.request, 'GET', '/audit/export', queried(params), options);\n }\n}\n\n/** Request options for an export whose filters travel in the query. */\nfunction queried(params: unknown, headers?: Record<string, string>): RequestOptions {\n return { query: (params ?? {}) as Query, ...(headers ? { headers } : {}) };\n}\n","import type { FeatureMatrixResponse } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * What each connector can do: payment methods, capture methods, webhook\n * flows, and whether an unverified webhook is acted on.\n */\nexport class FeatureMatrix {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve the feature matrix. `GET /feature-matrix` */\n async retrieve(): Promise<FeatureMatrixResponse> {\n return this.request('GET', '/feature-matrix');\n }\n\n /**\n * Retrieve the feature matrix scoped to a merchant. Beta connectors\n * are filtered against the merchant's allowlist so the dashboard only\n * surfaces connectors the merchant can actually attach.\n * `GET /feature-matrix/{merchantId}`\n */\n async retrieveForMerchant(merchantId: string): Promise<FeatureMatrixResponse> {\n return this.request('GET', `/feature-matrix/${encodeURIComponent(merchantId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Files {\n constructor(private readonly request: RequestFn) {}\n\n /** Upload a file. `POST /files` */\n async create(params: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', '/files', { body: params });\n }\n\n /** Retrieve/download a file. `GET /files/{fileId}` */\n async retrieve(fileId: string): Promise<Record<string, unknown>> {\n return this.request('GET', `/files/${encodeURIComponent(fileId)}`);\n }\n\n /** Delete a file. `DELETE /files/{fileId}` */\n async delete(fileId: string): Promise<Record<string, unknown>> {\n return this.request('DELETE', `/files/${encodeURIComponent(fileId)}`);\n }\n}\n","import type { RequestFn } from '../client';\n\nexport class Forex {\n constructor(private readonly request: RequestFn) {}\n\n /** Retrieve forex rates. `GET /forex/rates` */\n async getRates(\n params?: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/rates', { query: params });\n }\n\n /** Convert from minor currency. `GET /forex/convert-from-minor` */\n async convertFromMinor(\n params: Record<string, string | number | undefined>,\n ): Promise<Record<string, unknown>> {\n return this.request('GET', '/forex/convert-from-minor', { query: params });\n }\n}\n","import type {\n RegionCreateRequest,\n RegionUpdateRequest,\n RegionResponse,\n RegionSetCountriesRequest,\n RegionCountriesResponse,\n BuiltInRegionGroupResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Custom regions (named country groups) scoped to a shop/profile, used by the\n * geo-aware payment-method availability overrides. Every endpoint is scoped by\n * `profileId`. Admin (`sk_*`) access required.\n */\nexport class Regions {\n constructor(private readonly request: RequestFn) {}\n\n /** Create a region. `POST /regions?profile_id=` */\n async create(profileId: string, params: RegionCreateRequest): Promise<RegionResponse> {\n return this.request('POST', '/regions', {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** List all regions for a profile. `GET /regions/list?profile_id=` */\n async list(profileId: string): Promise<RegionResponse[]> {\n return this.request('GET', '/regions/list', { query: { profile_id: profileId } });\n }\n\n /** List the built-in (global) region groups (EU/EEA/SEPA/LATAM/APAC). `GET /regions/groups` */\n async groups(): Promise<BuiltInRegionGroupResponse[]> {\n return this.request('GET', '/regions/groups');\n }\n\n /** Retrieve a region by id. `GET /regions/{regionId}?profile_id=` */\n async retrieve(regionId: string, profileId: string): Promise<RegionResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Update a region. `PUT /regions/{regionId}?profile_id=` */\n async update(\n regionId: string,\n profileId: string,\n params: RegionUpdateRequest,\n ): Promise<RegionResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n\n /** Delete a region. `DELETE /regions/{regionId}?profile_id=` */\n async delete(regionId: string, profileId: string): Promise<boolean> {\n return this.request('DELETE', `/regions/${encodeURIComponent(regionId)}`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Get the countries that belong to a region. `GET /regions/{regionId}/countries?profile_id=` */\n async getCountries(regionId: string, profileId: string): Promise<RegionCountriesResponse> {\n return this.request('GET', `/regions/${encodeURIComponent(regionId)}/countries`, {\n query: { profile_id: profileId },\n });\n }\n\n /** Replace the full country membership of a region. `PUT /regions/{regionId}/countries?profile_id=` */\n async setCountries(\n regionId: string,\n profileId: string,\n params: RegionSetCountriesRequest,\n ): Promise<RegionCountriesResponse> {\n return this.request('PUT', `/regions/${encodeURIComponent(regionId)}/countries`, {\n body: params,\n query: { profile_id: profileId },\n });\n }\n}\n","import type {\n AvailabilityOverrideCreateRequest,\n AvailabilityOverrideResponse,\n AvailabilityPreviewParams,\n AvailabilityPreviewResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant payment-method availability overrides. Force-show or force-hide a\n * payment method per country/region at global, project, or shop scope, on top\n * of the curated country defaults. Admin (`sk_*`) access required.\n */\nexport class AvailabilityOverrides {\n constructor(private readonly request: RequestFn) {}\n\n /** Create an availability override. `POST /availability-overrides` */\n async create(params: AvailabilityOverrideCreateRequest): Promise<AvailabilityOverrideResponse> {\n return this.request('POST', '/availability-overrides', { body: params });\n }\n\n /** List a merchant's availability overrides. `GET /availability-overrides` */\n async list(merchantId: string): Promise<AvailabilityOverrideResponse[]> {\n return this.request('GET', '/availability-overrides', {\n query: { merchant_id: merchantId },\n });\n }\n\n /** Delete an availability override by id. `DELETE /availability-overrides/{id}` */\n async delete(id: string): Promise<boolean> {\n return this.request('DELETE', `/availability-overrides/${encodeURIComponent(id)}`);\n }\n\n /**\n * Preview the methods a customer in `country` would be shown for a shop —\n * the connector ceiling narrowed by the smart country defaults and the\n * merchant overrides, without an active payment. Pass `amount` + `currency`\n * to also evaluate order-value rules.\n * `GET /availability-overrides/preview`\n */\n async preview(params: AvailabilityPreviewParams): Promise<AvailabilityPreviewResponse> {\n return this.request('GET', '/availability-overrides/preview', {\n query: {\n merchant_id: params.merchant_id,\n profile_id: params.profile_id,\n ...(params.country ? { country: params.country } : {}),\n // `0` is a legitimate order value, so test for presence, not truthiness.\n ...(params.amount !== undefined ? { amount: params.amount } : {}),\n ...(params.currency ? { currency: params.currency } : {}),\n },\n });\n }\n}\n","import type {\n SellToRestrictionCapabilitiesResponse,\n SellToRestrictionDecisionsResponse,\n SellToRestrictionPolicyRequest,\n SellToRestrictionsResponse,\n ShopSellToRestriction,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Sell-to restrictions: the buyer countries a merchant refuses to sell to,\n * merchant-wide and per shop. A refused payment fails with error code `DE_10`.\n *\n * Every route needs a dashboard session. Reading needs the `SellToRestrictions`\n * area at `Read`, overriding a shop needs `Edit` (a shop-scoped role may\n * override only its own shop), and changing the merchant-wide policy needs\n * `Write`.\n */\nexport class SellToRestrictions {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * The merchant-wide policy and every shop's effective policy. A caller\n * scoped to one shop receives that shop alone, and no merchant-wide policy.\n * `GET /sell-to-restrictions`\n */\n async retrieve(): Promise<SellToRestrictionsResponse> {\n return this.request('GET', '/sell-to-restrictions');\n }\n\n /**\n * Replace the merchant-wide policy every shop without an override inherits.\n * The change is recorded in the audit log before it is made.\n * `PUT /sell-to-restrictions/merchant`\n */\n async updateMerchantPolicy(\n params: SellToRestrictionPolicyRequest,\n ): Promise<SellToRestrictionsResponse> {\n return this.request('PUT', '/sell-to-restrictions/merchant', { body: params });\n }\n\n /**\n * Give one shop its own policy, replacing the merchant-wide policy for that\n * shop. An empty `blocked_countries` lifts every restriction for it.\n * `PUT /sell-to-restrictions/shops/{profile_id}`\n */\n async updateShopOverride(\n profileId: string,\n params: SellToRestrictionPolicyRequest,\n ): Promise<ShopSellToRestriction> {\n return this.request('PUT', `/sell-to-restrictions/shops/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n\n /**\n * Remove one shop's override, so it inherits the merchant-wide policy again.\n * Removing an override the shop does not have changes nothing.\n * `DELETE /sell-to-restrictions/shops/{profile_id}`\n */\n async deleteShopOverride(profileId: string): Promise<ShopSellToRestriction> {\n return this.request('DELETE', `/sell-to-restrictions/shops/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Which checks each payment path performs, and how this deployment resolves\n * a buyer's country — read before relying on a restriction for a path.\n * `GET /sell-to-restrictions/capabilities`\n */\n async capabilities(): Promise<SellToRestrictionCapabilitiesResponse> {\n return this.request('GET', '/sell-to-restrictions/capabilities');\n }\n\n /**\n * Why a payment was refused: where, by which signal, for which country and\n * under which policy. A shop-scoped caller sees only refusals in its shop.\n * `GET /sell-to-restrictions/payments/{payment_id}/decisions`\n */\n async listDecisions(paymentId: string): Promise<SellToRestrictionDecisionsResponse> {\n return this.request(\n 'GET',\n `/sell-to-restrictions/payments/${encodeURIComponent(paymentId)}/decisions`,\n );\n }\n}\n","import type {\n BuyerBlocklistEntryCreateRequest,\n BuyerBlocklistEntryDeleteRequest,\n BuyerBlocklistEntryResponse,\n BuyerBlocklistListQuery,\n BuyerBlocklistListResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Buyer blocklist: the buyers a merchant refuses to sell to again, in every\n * shop of the merchant or in one shop. One entry names the buyer by email\n * address, IP address, customer id and device id, at most one of each and at\n * least one in total, and blocks a payment when any one of them matches. A\n * blocked buyer's hosted checkout and confirms fail with error code\n * `DE_14`, and the payments create response marks the buyer with\n * `buyer_blocked` and the entry's `buyer_block_note`. This is not the card\n * blocklist (`client.blocklist`), which is a separate list.\n *\n * Every route needs a dashboard session. Reading needs the `BuyerBlocklist`\n * area at `Read`, adding and removing needs `Write`. A caller scoped to one\n * shop lists, adds and removes that shop's entries only, and never an entry\n * that blocks in every shop.\n */\nexport class BuyerBlocklist {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * One page of blocked buyers, newest first, filtered by scope, by `kind`\n * (the entries that include an identifier of that kind) and by a search\n * over every identifier and the note. Expired entries are not listed.\n * `GET /buyer-blocklist`\n */\n async list(params?: BuyerBlocklistListQuery): Promise<BuyerBlocklistListResponse> {\n return this.request('GET', '/buyer-blocklist', {\n query: params as Record<string, string | number | null | undefined>,\n });\n }\n\n /**\n * Block a buyer in one shop or, without `profile_id`, in every shop of the\n * merchant, named by one or more of `email`, `ip`, `customer_id` and\n * `device_id`. Each identifier is normalised as it is matched; an\n * identifier another entry already names in that scope is refused. The\n * change is recorded in the audit log before it is made.\n * `POST /buyer-blocklist`\n */\n async create(params: BuyerBlocklistEntryCreateRequest): Promise<BuyerBlocklistEntryResponse> {\n return this.request('POST', '/buyer-blocklist', { body: params });\n }\n\n /**\n * Remove an entry, so the buyer can pay again. Payments the entry already\n * refused keep their status. The removal and the optional `reason` are\n * recorded in the audit log before it is made. The route requires a body,\n * so `{}` is sent when no reason is given.\n * `DELETE /buyer-blocklist/{entry_id}`\n */\n async delete(\n entryId: string,\n params?: BuyerBlocklistEntryDeleteRequest,\n ): Promise<BuyerBlocklistEntryResponse> {\n return this.request('DELETE', `/buyer-blocklist/${encodeURIComponent(entryId)}`, {\n body: params ?? {},\n });\n }\n}\n","import type {\n CandidatePreviewRequest,\n CandidatePreviewResponse,\n CheckoutReactivation,\n CheckoutReactivationPreview,\n CheckoutRecoveryStatus,\n CheckoutReminder,\n CheckoutReminderList,\n CheckoutReminderListQuery,\n ManualEmailPreview,\n ManualEmailRequest,\n ReactivateCheckoutRequest,\n TestEmailRequest,\n TestEmailResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Checkout recovery: emails that bring the buyer of an unfinished checkout\n * back to a payable checkout.\n *\n * A shop's automatic reminders are its `checkout_recovery.rule` setting,\n * written with `settings`, and their texts the `checkout_*` message templates,\n * written with `messageTemplates`. This resource reads a checkout's recovery, previews and sends a\n * message by hand, stops a checkout's reminders, previews whom a rule\n * would remind, and reactivates an expired checkout.\n *\n * Reading needs the payment read grant; sending, stopping and testing need\n * the payment write grant. A shop-scoped caller acts on its own shop only.\n * Refusals are `IR_16` (400) with `error.data.reason`.\n */\nexport class CheckoutRecovery {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * A checkout's recovery: whether and when the rule reminds it, every reason\n * it does not, every message about it, and where its link goes. Any payment\n * of the checkout may be named.\n * `GET /checkout-recovery/payments/{payment_id}`\n */\n async retrieve(paymentId: string): Promise<CheckoutRecoveryStatus> {\n return this.request('GET', `/checkout-recovery/payments/${encodeURIComponent(paymentId)}`);\n }\n\n /**\n * No automatic reminder about this checkout from now on.\n * `POST /checkout-recovery/payments/{payment_id}/stop`\n */\n async stop(paymentId: string): Promise<CheckoutRecoveryStatus> {\n return this.request(\n 'POST',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/stop`,\n );\n }\n\n /**\n * Undo `stop`.\n * `POST /checkout-recovery/payments/{payment_id}/resume`\n */\n async resume(paymentId: string): Promise<CheckoutRecoveryStatus> {\n return this.request(\n 'POST',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/resume`,\n );\n }\n\n /**\n * Whether the checkout can be reactivated now, why not when it cannot, and\n * what it would continue: order, amount, the current page's expiry and the\n * validity a reactivation gives. Changes nothing.\n * `GET /checkout-recovery/payments/{payment_id}/reactivation`\n */\n async previewReactivation(paymentId: string): Promise<CheckoutReactivationPreview> {\n return this.request(\n 'GET',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/reactivation`,\n );\n }\n\n /**\n * Continue an expired, unpaid checkout on a new payment for the same order,\n * amount and currency. The payment it replaces is closed first, so the two\n * can never both be charged; nothing is charged and nothing is sent to the\n * buyer. A repeated request answers with the same checkout\n * (`already_active`). Refused (`IR_16`, `error.data.reason` a\n * `ReactivationBlockedReason`, or `invalid_validity`) while the checkout is\n * paid, being paid, awaiting capture or authentication, cancelled or still\n * open, or when no payment method could pay it.\n * `POST /checkout-recovery/payments/{payment_id}/reactivate`\n */\n async reactivate(\n paymentId: string,\n params: ReactivateCheckoutRequest = {},\n ): Promise<CheckoutReactivation> {\n return this.request(\n 'POST',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/reactivate`,\n { body: params },\n );\n }\n\n /**\n * A message by hand as it would be sent now: recipient, sender, text, link\n * and destination, and why it would be refused. Nothing is sent.\n * `POST /checkout-recovery/payments/{payment_id}/email/preview`\n */\n async previewEmail(paymentId: string, params: ManualEmailRequest): Promise<ManualEmailPreview> {\n return this.request(\n 'POST',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/email/preview`,\n { body: params },\n );\n }\n\n /**\n * Send a message by hand, once per `idempotency_key`, composed again from\n * the checkout as it is now. Refused when the checkout was paid or is being\n * paid, was cancelled, the buyer unsubscribed, or no payment method could\n * pay it.\n * `POST /checkout-recovery/payments/{payment_id}/email`\n */\n async sendEmail(paymentId: string, params: ManualEmailRequest): Promise<CheckoutReminder> {\n return this.request(\n 'POST',\n `/checkout-recovery/payments/${encodeURIComponent(paymentId)}/email`,\n { body: params, bodyIdempotencyKey: params.idempotency_key ?? null },\n );\n }\n\n /**\n * Messages to buyers, newest first.\n * `GET /checkout-recovery/reminders`\n */\n async listReminders(params?: CheckoutReminderListQuery): Promise<CheckoutReminderList> {\n if (params) {\n return this.request('GET', '/checkout-recovery/reminders', { query: { ...params } });\n }\n return this.request('GET', '/checkout-recovery/reminders');\n }\n\n /**\n * The shop's recent checkouts judged under a rule (the stored one, or the\n * one given) as if switched on, with every reason. Nothing is sent.\n * `POST /checkout-recovery/candidates`\n */\n async previewCandidates(params: CandidatePreviewRequest = {}): Promise<CandidatePreviewResponse> {\n return this.request('POST', '/checkout-recovery/candidates', { body: params });\n }\n\n /**\n * A reminder with sample values, to the signed-in user's own address.\n * Dashboard sessions only.\n * `POST /checkout-recovery/test-email`\n */\n async sendTestEmail(params: TestEmailRequest): Promise<TestEmailResponse> {\n return this.request('POST', '/checkout-recovery/test-email', { body: params });\n }\n}\n","import type {\n CreateMerchantCostRuleRequest,\n MerchantCostRuleDeleteResponse,\n MerchantCostRuleResponse,\n UpdateMerchantCostRuleRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Merchant cost rules: what a merchant's own goods and partners' shares cost\n * it, as a percentage, a flat amount or both, merchant-wide or for one shop,\n * over a validity window.\n *\n * A rule is a record, not an instruction. It writes no billing ledger entry and\n * moves no money. Its rate, category and scope cannot be edited; a price change\n * is a new rule with a new window.\n *\n * Every route needs a dashboard session for the merchant: listing needs the\n * merchant account read permission, every change the write permission. A\n * shop-scoped session reaches nothing here.\n */\nexport class CostRules {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Every cost rule of the merchant.\n * `GET /cost-rules`\n *\n * @param merchantId - The merchant account ID.\n */\n async list(merchantId: string): Promise<MerchantCostRuleResponse[]> {\n return this.request('GET', '/cost-rules', { query: { merchant_id: merchantId } });\n }\n\n /**\n * Record a cost rule.\n * `POST /cost-rules`\n *\n * @param params - The rule.\n * @param merchantId - The merchant account ID.\n */\n async create(\n params: CreateMerchantCostRuleRequest,\n merchantId: string,\n ): Promise<MerchantCostRuleResponse> {\n return this.request('POST', '/cost-rules', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Close, deactivate or rename a cost rule.\n * `PUT /cost-rules/{rule_id}`\n *\n * @param ruleId - The rule ID.\n * @param params - What to change.\n * @param merchantId - The merchant account ID.\n */\n async update(\n ruleId: string,\n params: UpdateMerchantCostRuleRequest,\n merchantId: string,\n ): Promise<MerchantCostRuleResponse> {\n return this.request('PUT', `/cost-rules/${encodeURIComponent(ruleId)}`, {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Delete a cost rule.\n * `DELETE /cost-rules/{rule_id}`\n *\n * @param ruleId - The rule ID.\n * @param merchantId - The merchant account ID.\n */\n async delete(ruleId: string, merchantId: string): Promise<MerchantCostRuleDeleteResponse> {\n return this.request('DELETE', `/cost-rules/${encodeURIComponent(ruleId)}`, {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n ExternalRecordCapabilities,\n ExternalRecordRequest,\n ExternalRecordResponse,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Out-of-band transitions: what a PSP did that DeloPay never observed.\n *\n * A refund issued in the PSP's own dashboard, a chargeback settled by phone, a\n * payment the rail holds as paid but never sent a usable notification for. The\n * transition is written through the normal path, an outgoing webhook is raised\n * for the shop, and an audit row records who asserted it and why.\n *\n * This asserts a fact about somebody else's money, so it is deliberately\n * expensive to call: the reason is compelled, the PSP's own reference belongs\n * with it, and every record is attributable. It needs a dashboard session with\n * the profile external-record write permission — an API key reaches nothing\n * here.\n */\nexport class ExternalRecords {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Record one out-of-band transition.\n * `POST /external-records`\n *\n * Which kinds a deployment answers for depends on the payment's connector\n * and on which arms are live: an arm that is not served answers `501`, which\n * is a statement about this rail rather than about the request.\n *\n * @param params - What happened, and why it is being recorded.\n */\n async create(params: ExternalRecordRequest): Promise<ExternalRecordResponse> {\n return this.request('POST', '/external-records', { body: params });\n }\n\n /**\n * What this deployment will accept, per kind.\n * `GET /external-records/capabilities`\n *\n * Read it before offering the operator a form. Every kind is listed, so an\n * entry that is not served is distinguishable from a kind this release does\n * not know at all — and `create` says *why* it is not served: a gap\n * (`not_implemented`) or a rule (`not_applicable`). Treating those as the\n * same thing is how a caller ends up waiting for something that will never\n * be built.\n *\n * The answer includes the current merchant's rollout and storage eligibility.\n * Read it for the authenticated merchant when deciding whether to offer an\n * action; do not reuse another merchant's response or a previous session's\n * answer after eligibility may have changed.\n */\n async capabilities(): Promise<ExternalRecordCapabilities> {\n return this.request('GET', '/external-records/capabilities');\n }\n}\n","import type {\n BillingReadinessResponse,\n ProductSalesQuery,\n ProductSalesResponse,\n AddonGroupCreateRequest,\n AddonGroupUpdateRequest,\n BundleDefinition,\n GetSubscriptionItemsResponse,\n ProductCategoryCreateRequest,\n ProductCategoryListQuery,\n ProductCategoryListResponse,\n ProductCategoryReorderRequest,\n ProductCategoryResponse,\n ProductCategoryUpdateRequest,\n ProductAliasCreateRequest,\n ProductConnectorReferenceCreateRequest,\n ProductCreateRequest,\n ProductDeleteRequest,\n ProductDeleteResponse,\n ProductImageUploadResponse,\n ProductImportAcceptRequest,\n ProductImportApplyRequest,\n ProductImportPreviewRequest,\n ProductImportPreviewResponse,\n ProductImportRunListResponse,\n ProductImportRunResponse,\n ProductImportSuggestionsQuery,\n ProductListParams,\n ProductListResponse,\n ProductProviderCreateRequest,\n ProductProviderCreateResponse,\n ProductProviderPushRequest,\n ProductProviderPushResponse,\n ProductProviderSyncBatchRequest,\n ProductProviderSyncBatchResponse,\n ProductProviderSyncResponse,\n ProductPriceCreateRequest,\n ProductPriceUpdateRequest,\n ProductResolveQuery,\n ProductResolveResponse,\n ProductResponse,\n ProductUpdateRequest,\n ProviderAccountListResponse,\n ProviderArchiveOutcome,\n ProviderArchiveRequest,\n ProviderCleanupListResponse,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * A shop's product catalogue: what it sells, and at which prices.\n *\n * **Every route here belongs to one shop**, and the backend resolves it from\n * an `X-Profile-Id` header, answering `IR_04` without one. That is why\n * `profileId` is a required argument on every method rather than something to\n * remember in `options.headers`: a header that can be forgotten is forgotten,\n * and the failure arrives at runtime in a caller's dashboard rather than at\n * their compiler.\n *\n * Two shapes of the catalogue are worth knowing before calling this:\n *\n * * **A product is created with its prices.** The API requires at least one,\n * because a product nobody can be charged for cannot be sold.\n * * **A price is closed, never rewritten.** `updatePrice` changes its label,\n * its default flag and its metadata; the amount, the currency and the\n * billing interval are fixed for the life of the price, so a charge that was\n * made can always be explained by a price that still exists. Charging a new\n * figure means adding a price and archiving the old one.\n * * **Every price route answers with the whole product.** The catalogue's unit\n * is the product: a price means something only beside its siblings, and\n * which one is the default changes the moment another is added. So these\n * methods return `ProductResponse`, and the price that was touched is found\n * in its `prices` — typing them as the price alone let a caller read\n * `result.amount` as a number that is `undefined` at runtime, and mistake\n * the product's id for a price id.\n */\nexport class Products {\n constructor(private readonly request: RequestFn) {}\n\n /** The shop scope every route here takes, as the backend expects it. */\n private scoped(profileId: string, options?: RequestExtras): RequestExtras {\n return { ...options, headers: { 'X-Profile-Id': profileId, ...options?.headers } };\n }\n\n /** Upload a PNG, JPEG or WebP image to the merchant CDN. Save the returned\n * URL in a product create or update request; upload alone changes no product. */\n async uploadImage(\n file: Blob,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductImageUploadResponse> {\n const form = new FormData();\n form.append('file', file);\n return this.request('POST', '/products/images', {\n body: form,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Create a product together with its prices.\n * `POST /products`\n *\n * @param params - The product, with at least one price.\n * @param profileId - The shop the product belongs to.\n */\n async create(\n params: ProductCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', '/products', {\n body: params,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * One page of the shop's catalogue.\n * `GET /products/list`\n *\n * Archived products are returned too unless `status` narrows them away —\n * they are what past charges refer to.\n */\n async list(\n params: ProductListParams | undefined,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductListResponse> {\n return this.request('GET', '/products/list', {\n query: params === undefined ? undefined : { ...params },\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Find the product a name or a connector's id belongs to. Pass exactly one\n * of `alias`, `connector_product_id` and `connector_price_id`; the connector\n * ids need `connector` as well. Archived products resolve too, so a payment\n * that references one is still attributed. No match answers 404.\n * `GET /products/resolve`\n */\n async resolve(\n query: ProductResolveQuery,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResolveResponse> {\n return this.request('GET', '/products/resolve', {\n query: { ...query },\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Retrieve one product with its prices.\n * `GET /products/{product_id}`\n */\n async retrieve(\n productId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('GET', `/products/${encodeURIComponent(productId)}`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * What a product sold in a window, per currency, net of the refunds credited\n * to its lines. Refunds that named no product line are not included.\n * `GET /products/{product_id}/sales`\n *\n * Needs payment read; refused (403) to a caller limited to some connector\n * accounts.\n */\n async sales(\n productId: string,\n query: ProductSalesQuery,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductSalesResponse> {\n return this.request('GET', `/products/${encodeURIComponent(productId)}/sales`, {\n ...this.scoped(profileId, options),\n query: { ...query },\n });\n }\n\n /**\n * Which active prices of the named recurring products can start a\n * subscription on the shop's billing processor account, in the environment\n * the account is in now. `GET /products/billing-readiness`\n *\n * Reads only; subscribing still checks the processor's price before\n * anything is billed. Unknown ids, one-time products and archived prices\n * are left out of the answer.\n *\n * @param productIds - 1 to 100 product ids.\n * @param profileId - The shop the products belong to.\n */\n async billingReadiness(\n productIds: readonly string[],\n profileId: string,\n options?: RequestExtras,\n ): Promise<BillingReadinessResponse> {\n return this.request('GET', '/products/billing-readiness', {\n ...this.scoped(profileId, options),\n // One comma-separated value, as the route reads it — not repeated keys.\n query: { product_ids: productIds.join(',') },\n });\n }\n\n /**\n * Change a product's name, description, image, metadata or category\n * (`category_id: null` makes it uncategorized).\n * `POST /products/{product_id}`\n *\n * Its kind and its prices are not editable here — see the class note.\n */\n async update(\n productId: string,\n params: ProductUpdateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}`, {\n body: params,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Take a product off sale.\n * `POST /products/{product_id}/archive`\n *\n * It stays readable and keeps its prices: a payment made against it has to\n * remain explicable after it is withdrawn.\n */\n async archive(\n productId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/archive`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Put an archived product back on sale.\n * `POST /products/{product_id}/restore`\n */\n async restore(\n productId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/restore`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /** Mark an archived product deleted. Historical payment lines keep\n * their own immutable purchase snapshots, and the catalog row remains stored. */\n async delete(productId: string, profileId: string, options?: RequestExtras): Promise<void> {\n return this.request('DELETE', `/products/${encodeURIComponent(productId)}`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Delete an archived product, then carry out the chosen action at each\n * connected account it is tied to. An account not named in\n * `provider_actions` is kept as it is. A failed provider action does not\n * undo the delete: it is listed by {@link providerCleanups} and retried\n * with {@link providerArchive}.\n * `POST /products/{product_id}/delete`\n */\n async deleteWithProviders(\n productId: string,\n request: ProductDeleteRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductDeleteResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/delete`, {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Add a price to an existing product.\n * `POST /products/{product_id}/prices`\n *\n * This is how a price changes: the new figure is added and the old price is\n * archived, so both remain readable.\n */\n async addPrice(\n productId: string,\n params: ProductPriceCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/prices`, {\n body: params,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Change a price's label, its default flag or its metadata.\n * `POST /products/{product_id}/prices/{price_id}`\n *\n * Not its amount, its currency or its interval: see the class note.\n */\n async updatePrice(\n productId: string,\n priceId: string,\n params: ProductPriceUpdateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/prices/${encodeURIComponent(priceId)}`,\n { body: params, ...this.scoped(profileId, options) },\n );\n }\n\n /**\n * Take one price off sale, leaving the product on it.\n * `POST /products/{product_id}/prices/{price_id}/archive`\n */\n async archivePrice(\n productId: string,\n priceId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/prices/${encodeURIComponent(priceId)}/archive`,\n { ...this.scoped(profileId, options) },\n );\n }\n\n // --- add-on selection groups ---------------------------------------\n\n /**\n * Add a group of optional extras to a one-time product, with how many of\n * them a buyer must and may choose. Each add-on is an active product of kind\n * `addon` in the same shop. Returns the whole product.\n * `POST /products/{product_id}/addon-groups`\n */\n async createAddonGroup(\n productId: string,\n group: AddonGroupCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/addon-groups`, {\n body: group,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Change a group's name, bounds, or the add-ons it offers; a new list\n * replaces the old one whole.\n * `POST /products/{product_id}/addon-groups/{group_id}`\n */\n async updateAddonGroup(\n productId: string,\n groupId: string,\n changes: AddonGroupUpdateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/addon-groups/${encodeURIComponent(groupId)}`,\n { body: changes, ...this.scoped(profileId, options) },\n );\n }\n\n /**\n * Remove a group and what it offered. The add-on products themselves stay.\n * `DELETE /products/{product_id}/addon-groups/{group_id}`\n */\n async deleteAddonGroup(\n productId: string,\n groupId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'DELETE',\n `/products/${encodeURIComponent(productId)}/addon-groups/${encodeURIComponent(groupId)}`,\n { ...this.scoped(profileId, options) },\n );\n }\n\n // --- bundles ---------------------------------------------------------\n\n /**\n * Replace what a bundle contains. Its pricing mode is fixed at creation;\n * past purchases keep their own frozen lines.\n * `POST /products/{product_id}/bundle`\n */\n async replaceBundle(\n productId: string,\n bundle: BundleDefinition,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/bundle`, {\n body: bundle,\n ...this.scoped(profileId, options),\n });\n }\n\n // --- identity: names and connector references ---------------------\n\n /**\n * Add a name the product goes by. A name it already goes by is returned\n * as it is; one another product of the shop goes by is refused.\n * `POST /products/{product_id}/aliases`\n */\n async addAlias(\n productId: string,\n body: ProductAliasCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/aliases`, {\n body,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Remove a name the product goes by. Its current name stays.\n * `POST /products/{product_id}/aliases/{alias_id}/remove`\n */\n async removeAlias(\n productId: string,\n aliasId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/aliases/${encodeURIComponent(aliasId)}/remove`,\n { ...this.scoped(profileId, options) },\n );\n }\n\n /**\n * Tie a connected account's product, or one of its prices, to the product.\n * Recorded as `manual_id`: the ids are not checked against the account.\n * `POST /products/{product_id}/connector-references`\n */\n async addConnectorReference(\n productId: string,\n body: ProductConnectorReferenceCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/connector-references`, {\n body,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Remove a connected account's product or price from the product.\n * `POST /products/{product_id}/connector-references/{reference_id}/remove`\n */\n async removeConnectorReference(\n productId: string,\n referenceId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/connector-references/${encodeURIComponent(referenceId)}/remove`,\n { ...this.scoped(profileId, options) },\n );\n }\n\n /**\n * One bounded page of a connected billing account's products, to pick an\n * existing one to tie to a product. Reads only.\n * `GET /products/import-suggestions`\n */\n async importSuggestions(\n query: ProductImportSuggestionsQuery,\n profileId: string,\n options?: RequestExtras,\n ): Promise<GetSubscriptionItemsResponse[]> {\n return this.request('GET', '/products/import-suggestions', {\n query: { ...query },\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Tie one of a connected account's existing products (or a price of it) to\n * the product, verified against a fresh read of the page it was suggested\n * on — pass the same `limit` and `offset`. Recorded as `map_existing`.\n * `POST /products/{product_id}/connector-references/import`\n */\n async acceptImport(\n productId: string,\n body: ProductImportAcceptRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductResponse> {\n return this.request(\n 'POST',\n `/products/${encodeURIComponent(productId)}/connector-references/import`,\n { body, ...this.scoped(profileId, options) },\n );\n }\n\n // --- categories ------------------------------------------------------\n\n /**\n * Add a category to the shop, at the end of its order. File products under\n * it with `category_id` on `create` or `update`.\n * `POST /products/categories`\n */\n async createCategory(\n body: ProductCategoryCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryResponse> {\n return this.request('POST', '/products/categories', {\n body,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * The shop's categories in order. Archived ones only with\n * `include_archived`; deleted ones never.\n * `GET /products/categories/list`\n */\n async listCategories(\n query: ProductCategoryListQuery | undefined,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryListResponse> {\n return this.request('GET', '/products/categories/list', {\n query: query === undefined ? undefined : { ...query },\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Put the shop's categories in a new order. Name every live category,\n * archived ones included, exactly once. Returns the categories in their new\n * order.\n * `POST /products/categories/reorder`\n */\n async reorderCategories(\n body: ProductCategoryReorderRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryListResponse> {\n return this.request('POST', '/products/categories/reorder', {\n body,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Rename a category.\n * `POST /products/categories/{category_id}`\n */\n async updateCategory(\n categoryId: string,\n changes: ProductCategoryUpdateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryResponse> {\n return this.request('POST', `/products/categories/${encodeURIComponent(categoryId)}`, {\n body: changes,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Mark a category deleted. Its products become uncategorized and no payment\n * changes. Returns the deleted category.\n * `DELETE /products/categories/{category_id}`\n */\n async deleteCategory(\n categoryId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryResponse> {\n return this.request('DELETE', `/products/categories/${encodeURIComponent(categoryId)}`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Keep a category with its products, but file no new product under it.\n * `POST /products/categories/{category_id}/archive`\n */\n async archiveCategory(\n categoryId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryResponse> {\n return this.request('POST', `/products/categories/${encodeURIComponent(categoryId)}/archive`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Let an archived category take products again.\n * `POST /products/categories/{category_id}/restore`\n */\n async restoreCategory(\n categoryId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductCategoryResponse> {\n return this.request('POST', `/products/categories/${encodeURIComponent(categoryId)}/restore`, {\n ...this.scoped(profileId, options),\n });\n }\n\n // --- provider import ---------------------------------------------\n\n /**\n * Read a connected billing account's products and say how each relates to\n * the catalog. Reads only: nothing is written to the provider or the catalog.\n * `POST /products/import/preview`\n */\n async importPreview(\n request: ProductImportPreviewRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductImportPreviewResponse> {\n return this.request('POST', '/products/import/preview', {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Create a product for every new item and add the new prices of every\n * changed one, tied to the provider's ids. Nothing else is edited or\n * removed, except that `options.archived: 'archive'` archives the catalog\n * product of every item the provider no longer offers (by default it is\n * left as it is). Nothing is written to the provider. A failed item is\n * reported with its reason and can be retried by naming it in\n * `connector_product_ids`.\n * `POST /products/import/apply`\n */\n async importApply(\n request: ProductImportApplyRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductImportRunResponse> {\n return this.request('POST', '/products/import/apply', {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * The shop's past imports from one connected account, newest first.\n * `GET /products/import/runs`\n */\n async listImportRuns(\n merchantConnectorId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductImportRunListResponse> {\n return this.request('GET', '/products/import/runs', {\n query: { merchant_connector_id: merchantConnectorId },\n ...this.scoped(profileId, options),\n });\n }\n\n // --- provider sync -----------------------------------------------\n\n /**\n * Compare the product with its copy at every connected account it is tied\n * to. Reads the providers now; an unreadable provider answers `unknown`,\n * never `in_sync`.\n * `GET /products/{product_id}/provider-sync`\n */\n async providerSync(\n productId: string,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductProviderSyncResponse> {\n return this.request('GET', `/products/${encodeURIComponent(productId)}/provider-sync`, {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * {@link providerSync} for 1 to 50 products at once, such as one page of the\n * product list. Unknown ids are left out of the answer.\n * `POST /products/provider-sync`\n */\n async providerSyncBatch(\n request: ProductProviderSyncBatchRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductProviderSyncBatchResponse> {\n return this.request('POST', '/products/provider-sync', {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Write the catalog's state onto one connected account's copy of the\n * product, for the differences a push changes and nothing else. When it\n * would change a difference not named in `confirmed`, nothing is written and\n * the answer carries `confirmation_outdated: true` with the current\n * differences in `result`; `nothing_to_push` answers without a provider\n * write when nothing pushable differs.\n * `POST /products/{product_id}/provider-sync/push`\n */\n async providerPush(\n productId: string,\n request: ProductProviderPushRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductProviderPushResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/provider-sync/push`, {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n // --- provider lifecycle -----------------------------------------\n\n /**\n * The shop's connected accounts the catalog works with, and what each can\n * do: read, create, push, and how a delete can clean up there.\n * `GET /products/provider-accounts`\n */\n async providerAccounts(\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProviderAccountListResponse> {\n return this.request('GET', '/products/provider-accounts', {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Provider clean-ups still to be carried out: deletes whose action at a\n * provider failed, or was recorded and never reached.\n * `GET /products/provider-cleanups`\n */\n async providerCleanups(\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProviderCleanupListResponse> {\n return this.request('GET', '/products/provider-cleanups', {\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Create the product at a connected account it is not at yet. Without\n * `confirmed` nothing is written and the answer holds the plan to review;\n * send the plan's `fingerprint` back as `confirmed` to carry it out. When\n * the plan changed since, nothing is written and the answer carries\n * `confirmation_outdated: true` with the current plan.\n * `POST /products/{product_id}/provider-sync/create`\n */\n async providerCreate(\n productId: string,\n request: ProductProviderCreateRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProductProviderCreateResponse> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/provider-sync/create`, {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n\n /**\n * Archive the product at one connected account, or retry a clean-up that\n * failed after the product was deleted. Existing subscriptions there keep\n * billing; the catalog is not changed.\n * `POST /products/{product_id}/provider-archive`\n */\n async providerArchive(\n productId: string,\n request: ProviderArchiveRequest,\n profileId: string,\n options?: RequestExtras,\n ): Promise<ProviderArchiveOutcome> {\n return this.request('POST', `/products/${encodeURIComponent(productId)}/provider-archive`, {\n body: request,\n ...this.scoped(profileId, options),\n });\n }\n}\n","import type {\n CreateCreditNoteRequest,\n CreateInvoiceRequest,\n InvoiceEmailDelivery,\n InvoiceEmailDeliveryList,\n InvoiceExportParams,\n InvoiceList,\n InvoiceListQuery,\n InvoicePageQuery,\n InvoiceShareLink,\n MerchantInvoiceDocument,\n UpdateInvoiceRequest,\n VoidInvoiceRequest,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * The invoices and credit notes a merchant issues to their buyers.\n *\n * DeloPay renders and stores each document **in the merchant's name**. The\n * seller block comes from the invoice settings (see `invoiceSettings`) and\n * every amount from the source — a paid payment or a paid subscription cycle —\n * so no method here takes a seller, an amount or a quantity, except the\n * optional partial amounts of a credit note, which the API caps at what the\n * line has left.\n *\n * A document is `draft` → `issued` → `voided`. A draft is unnumbered and\n * editable, and deleting it leaves no gap; `finalize` numbers it, freezes it\n * and stores its PDF; an issued document is corrected with a credit note, or\n * voided if it never reached the buyer.\n *\n * Scope comes from the caller: a shop-scoped key or dashboard session sees\n * only its shop, and a merchant-level one narrows with `profile_id` on the\n * list filters. Reading needs the `Invoice` area's read grant; every change\n * needs its write grant.\n *\n * Refusals: `IR_16` (400) for a document in the wrong state or a source that\n * may not be invoiced, `IR_06` (422) for a finalise the document cannot pass,\n * and `DE_13` (409) for a second live invoice of one source. The first two\n * carry `error.data` as a `MerchantInvoiceRefusal`; the last as a\n * `MerchantInvoiceConflict`.\n */\nexport class Invoices {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Create a draft from a paid payment or subscription cycle, and with\n * `finalize: true` issue it in the same call.\n * `POST /invoices`\n *\n * Send an `Idempotency-Key` header in `options.headers` to make this safe to\n * retry: the same key and body return the document it created, in its\n * current state, even after a lost response, and a different body under the\n * same key answers 409. A retry of a `finalize: true` request whose draft\n * was committed but not finalised finalises that draft.\n */\n async create(\n params: CreateInvoiceRequest,\n options?: RequestExtras,\n ): Promise<MerchantInvoiceDocument> {\n return this.request('POST', '/invoices', { body: params, ...options });\n }\n\n /**\n * One page of documents, newest first. List rows carry no `lines` unless\n * `include_lines` is set, and never a `refund` summary.\n * `GET /invoices`\n */\n async list(params?: InvoiceListQuery, options?: RequestExtras): Promise<InvoiceList> {\n return this.request('GET', '/invoices', {\n query: params === undefined ? undefined : { ...params },\n ...options,\n });\n }\n\n /**\n * One page of a payment's invoice and its credit notes, lines included. The\n * page also says whether a merchant of record sold the payment\n * (`merchant_of_record`, which `create` then refuses) and what was refunded\n * (`refunded_amount`, and `refund` on each invoice). Needs the payment read\n * grant as well.\n * `GET /payments/{payment_id}/invoices`\n */\n async listForPayment(\n paymentId: string,\n params?: InvoicePageQuery,\n options?: RequestExtras,\n ): Promise<InvoiceList> {\n return this.request('GET', `/payments/${encodeURIComponent(paymentId)}/invoices`, {\n query: params === undefined ? undefined : { ...params },\n ...options,\n });\n }\n\n /**\n * The documents with a line of one product; a bundle's components count,\n * flagged `included`. Takes the list filters; the product is the path's.\n * `GET /products/{product_id}/invoices`\n */\n async listForProduct(\n productId: string,\n params?: Omit<InvoiceListQuery, 'product_id'>,\n options?: RequestExtras,\n ): Promise<InvoiceList> {\n return this.request('GET', `/products/${encodeURIComponent(productId)}/invoices`, {\n query: params === undefined ? undefined : { ...params },\n ...options,\n });\n }\n\n /**\n * The documents of one period, with the list's filters, as CSV\n * (`text/csv; charset=utf-8`) by default. Amounts are decimal in each\n * document's currency; drafts have an empty number.\n *\n * Another file is asked for with `Accept` in `options.headers`:\n * `application/json` (the rows as `records`, with `record_count` and the\n * filters applied), `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n * (an Excel workbook) or `application/zip` (the stored PDF of every issued or\n * voided document, with the CSV as `invoices.csv`; at most 500 documents).\n * `GET /invoices/export`\n */\n async export(params: InvoiceExportParams, options?: RequestExtras): Promise<Blob> {\n return this.request('GET', '/invoices/export', {\n query: { ...params },\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * One document, lines included.\n * `GET /invoices/{invoice_id}`\n */\n async retrieve(invoiceId: string, options?: RequestExtras): Promise<MerchantInvoiceDocument> {\n return this.request('GET', `/invoices/${encodeURIComponent(invoiceId)}`, { ...options });\n }\n\n /**\n * Edit a draft: its words, buyer, dates and tax treatment, never what was\n * paid. Absent fields stay; `null` clears a clearable one. A document that\n * is not a draft is refused (`not_a_draft`).\n * `PATCH /invoices/{invoice_id}`\n */\n async update(\n invoiceId: string,\n params: UpdateInvoiceRequest,\n options?: RequestExtras,\n ): Promise<MerchantInvoiceDocument> {\n return this.request('PATCH', `/invoices/${encodeURIComponent(invoiceId)}`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Delete a draft. A draft has no number, so nothing leaves a gap; an issued\n * document is refused (`not_a_draft`) — void or credit it instead.\n * `DELETE /invoices/{invoice_id}`\n */\n async delete(invoiceId: string, options?: RequestExtras): Promise<void> {\n return this.request('DELETE', `/invoices/${encodeURIComponent(invoiceId)}`, { ...options });\n }\n\n /**\n * Issue a draft: allocate its number, freeze it and store its PDF. It is\n * immutable afterwards. A document that would be legally incomplete is\n * refused with `IR_06` and a reason (`seller_tax_id_missing`,\n * `line_tax_unexplained`, …) that says what to fix and where.\n * `POST /invoices/{invoice_id}/finalize`\n */\n async finalize(invoiceId: string, options?: RequestExtras): Promise<MerchantInvoiceDocument> {\n return this.request('POST', `/invoices/${encodeURIComponent(invoiceId)}/finalize`, {\n ...options,\n });\n }\n\n /**\n * Withdraw an issued document with a reason; its number stays used. For a\n * document that never reached the buyer — one they hold is corrected with\n * `createCreditNote`. An invoice with live credit notes is refused\n * (`has_credit_notes`).\n * `POST /invoices/{invoice_id}/void`\n */\n async void(\n invoiceId: string,\n params: VoidInvoiceRequest,\n options?: RequestExtras,\n ): Promise<MerchantInvoiceDocument> {\n return this.request('POST', `/invoices/${encodeURIComponent(invoiceId)}/void`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Correct an issued invoice with a credit note: all of what it has left, or\n * the named lines. Returns the **credit note**, not the invoice.\n * `POST /invoices/{invoice_id}/credit-note`\n */\n async createCreditNote(\n invoiceId: string,\n params: CreateCreditNoteRequest,\n options?: RequestExtras,\n ): Promise<MerchantInvoiceDocument> {\n return this.request('POST', `/invoices/${encodeURIComponent(invoiceId)}/credit-note`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * The document as a PDF. An issued document is its stored copy; a draft\n * renders live under a DRAFT banner, and a voided one under a VOIDED banner.\n * `GET /invoices/{invoice_id}/pdf`\n */\n async downloadPdf(invoiceId: string, options?: RequestExtras): Promise<Blob> {\n return this.request('GET', `/invoices/${encodeURIComponent(invoiceId)}/pdf`, {\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * A public link to an issued document's stored PDF, valid for 7 days.\n * **Anyone holding the link can open the document**, without logging in. A\n * document that is not issued is refused (`not_issued`).\n * `POST /invoices/{invoice_id}/share-link`\n */\n async createShareLink(invoiceId: string, options?: RequestExtras): Promise<InvoiceShareLink> {\n return this.request('POST', `/invoices/${encodeURIComponent(invoiceId)}/share-link`, {\n ...options,\n });\n }\n\n /**\n * Mail an issued invoice to the buyer address it carries, its PDF attached,\n * in the document's language. Each call is a new message (the next\n * `revision`) and resolves with what became of it: `sent`, or `failed` with\n * `error_code`. Refused (`IR_16`) with `not_an_invoice` (a credit note),\n * `not_issued`, `no_buyer_email`, `send_in_progress` (an earlier message is\n * queued or being sent) and `send_limit_reached` (5 sends by hand in 24\n * hours). Shops with the `email.invoice_auto_send` setting mail every\n * invoice they issue without this call.\n *\n * The merchant's daily sending limit is **not** a refusal: the call answers\n * with the message `failed` and `error_code: 'merchant_limit_reached'`.\n * Check `status` on the result, not only that the call succeeded.\n * `POST /invoices/{invoice_id}/email`\n */\n async sendEmail(invoiceId: string, options?: RequestExtras): Promise<InvoiceEmailDelivery> {\n return this.request('POST', `/invoices/${encodeURIComponent(invoiceId)}/email`, {\n ...options,\n });\n }\n\n /**\n * Every message about a document to its buyer, automatic and by hand,\n * newest first, with its delivery status. The recipient is masked.\n * `GET /invoices/{invoice_id}/emails`\n */\n async listEmails(invoiceId: string, options?: RequestExtras): Promise<InvoiceEmailDeliveryList> {\n return this.request('GET', `/invoices/${encodeURIComponent(invoiceId)}/emails`, {\n ...options,\n });\n }\n}\n","import type {\n EffectiveInvoiceSettings,\n InvoiceLogoRequest,\n InvoicePreviewRequest,\n InvoiceSettings,\n InvoiceTaxRuleEvaluateRequest,\n InvoiceTaxRuleEvaluation,\n InvoiceTaxRules,\n InvoiceTaxRulesRequest,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * How the merchant's invoices look and are taxed: the merchant default, and\n * each shop's override of it.\n *\n * Every setting resolves shop → merchant default → built-in fallback, and\n * `retrieveEffective` shows the result for one shop with where each value came\n * from. The same two levels hold the tax rules: a shop either inherits the\n * merchant's list or has one of its own that replaces it.\n *\n * **The merchant-level methods need a merchant-level grant** (no shop role\n * holds one), so a shop user may style its own shop and give it tax rules of\n * its own but never change what every shop inherits. The `…ForShop` methods\n * need the `Invoice` area's grant on that shop.\n *\n * Exported as `InvoiceSettingsResource` so the class never shadows the\n * `InvoiceSettings` data type of the same package.\n *\n * An update **replaces every field but the logo**: read, change, and send the\n * whole object back. A field left out is cleared — on a shop that means\n * \"inherit\", on the merchant default \"use the built-in fallback\". The logo has\n * its own methods.\n */\nexport class InvoiceSettingsResource {\n constructor(private readonly request: RequestFn) {}\n\n // --- Settings -------------------------------------------------------------\n\n /**\n * The merchant default.\n * `GET /invoice-settings`\n */\n async retrieve(options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request('GET', '/invoice-settings', { ...options });\n }\n\n /**\n * Replace the merchant default (every field but the logo).\n * `PUT /invoice-settings`\n */\n async update(settings: InvoiceSettings, options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request('PUT', '/invoice-settings', { body: settings, ...options });\n }\n\n /**\n * One shop's override. A `null` field inherits the merchant default.\n * `GET /invoice-settings/profiles/{profile_id}`\n */\n async retrieveForShop(profileId: string, options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request('GET', `/invoice-settings/profiles/${encodeURIComponent(profileId)}`, {\n ...options,\n });\n }\n\n /**\n * Replace one shop's override (every field but the logo).\n * `PUT /invoice-settings/profiles/{profile_id}`\n */\n async updateForShop(\n profileId: string,\n settings: InvoiceSettings,\n options?: RequestExtras,\n ): Promise<InvoiceSettings> {\n return this.request('PUT', `/invoice-settings/profiles/${encodeURIComponent(profileId)}`, {\n body: settings,\n ...options,\n });\n }\n\n /**\n * The settings a shop's next document is finalised with, and where each\n * value came from (`shop`, `merchant` or `default`).\n * `GET /invoice-settings/profiles/{profile_id}/effective`\n */\n async retrieveEffective(\n profileId: string,\n options?: RequestExtras,\n ): Promise<EffectiveInvoiceSettings> {\n return this.request(\n 'GET',\n `/invoice-settings/profiles/${encodeURIComponent(profileId)}/effective`,\n { ...options },\n );\n }\n\n /**\n * A sample invoice PDF rendered from the effective settings with unsaved\n * values laid over them, so a form can show what saving would produce.\n * Writes nothing.\n * `POST /invoice-settings/preview`\n */\n async preview(params: InvoicePreviewRequest, options?: RequestExtras): Promise<Blob> {\n return this.request('POST', '/invoice-settings/preview', {\n body: params,\n responseType: 'blob',\n ...options,\n });\n }\n\n // --- Logo -----------------------------------------------------------------\n\n /**\n * The merchant default's logo image.\n * `GET /invoice-settings/logo`\n */\n async retrieveLogo(options?: RequestExtras): Promise<Blob> {\n return this.request('GET', '/invoice-settings/logo', { responseType: 'blob', ...options });\n }\n\n /**\n * Set the merchant default's logo: PNG or JPEG, at most 1 MB, as base64.\n * `PUT /invoice-settings/logo`\n */\n async updateLogo(params: InvoiceLogoRequest, options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request('PUT', '/invoice-settings/logo', { body: params, ...options });\n }\n\n /**\n * Remove the merchant default's logo.\n * `DELETE /invoice-settings/logo`\n */\n async deleteLogo(options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request('DELETE', '/invoice-settings/logo', { ...options });\n }\n\n /**\n * One shop's own logo image.\n * `GET /invoice-settings/profiles/{profile_id}/logo`\n */\n async retrieveLogoForShop(profileId: string, options?: RequestExtras): Promise<Blob> {\n return this.request('GET', `/invoice-settings/profiles/${encodeURIComponent(profileId)}/logo`, {\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * Set one shop's own logo: PNG or JPEG, at most 1 MB, as base64.\n * `PUT /invoice-settings/profiles/{profile_id}/logo`\n */\n async updateLogoForShop(\n profileId: string,\n params: InvoiceLogoRequest,\n options?: RequestExtras,\n ): Promise<InvoiceSettings> {\n return this.request('PUT', `/invoice-settings/profiles/${encodeURIComponent(profileId)}/logo`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Remove one shop's own logo; the shop then inherits the merchant default's.\n * `DELETE /invoice-settings/profiles/{profile_id}/logo`\n */\n async deleteLogoForShop(profileId: string, options?: RequestExtras): Promise<InvoiceSettings> {\n return this.request(\n 'DELETE',\n `/invoice-settings/profiles/${encodeURIComponent(profileId)}/logo`,\n { ...options },\n );\n }\n\n // --- Tax rules ------------------------------------------------------------\n\n /**\n * The merchant's tax rules, which every shop without a list of its own uses.\n * `GET /invoice-settings/tax-rules`\n */\n async retrieveTaxRules(options?: RequestExtras): Promise<InvoiceTaxRules> {\n return this.request('GET', '/invoice-settings/tax-rules', { ...options });\n }\n\n /**\n * Replace the merchant's whole rule list; the order is the priority.\n * `PUT /invoice-settings/tax-rules`\n */\n async updateTaxRules(\n params: InvoiceTaxRulesRequest,\n options?: RequestExtras,\n ): Promise<InvoiceTaxRules> {\n return this.request('PUT', '/invoice-settings/tax-rules', { body: params, ...options });\n }\n\n /**\n * The rules one shop uses: its own list, or the merchant's it inherits, as\n * `own_rules` says.\n * `GET /invoice-settings/profiles/{profile_id}/tax-rules`\n */\n async retrieveTaxRulesForShop(\n profileId: string,\n options?: RequestExtras,\n ): Promise<InvoiceTaxRules> {\n return this.request(\n 'GET',\n `/invoice-settings/profiles/${encodeURIComponent(profileId)}/tax-rules`,\n { ...options },\n );\n }\n\n /**\n * Give one shop a list of its own, replacing the merchant's for that shop —\n * even when empty, which leaves every line of the shop to the settings'\n * default rate.\n * `PUT /invoice-settings/profiles/{profile_id}/tax-rules`\n */\n async updateTaxRulesForShop(\n profileId: string,\n params: InvoiceTaxRulesRequest,\n options?: RequestExtras,\n ): Promise<InvoiceTaxRules> {\n return this.request(\n 'PUT',\n `/invoice-settings/profiles/${encodeURIComponent(profileId)}/tax-rules`,\n { body: params, ...options },\n );\n }\n\n /**\n * Drop one shop's own list, so it inherits the merchant's again. Returns\n * the list the shop now uses.\n * `DELETE /invoice-settings/profiles/{profile_id}/tax-rules`\n */\n async deleteTaxRulesForShop(\n profileId: string,\n options?: RequestExtras,\n ): Promise<InvoiceTaxRules> {\n return this.request(\n 'DELETE',\n `/invoice-settings/profiles/${encodeURIComponent(profileId)}/tax-rules`,\n { ...options },\n );\n }\n\n /**\n * Which saved rule a buyer and a product tax category would meet, and what\n * the line would be taxed at. Writes nothing.\n * `POST /invoice-settings/tax-rules/evaluate`\n */\n async evaluateTaxRules(\n params: InvoiceTaxRuleEvaluateRequest,\n options?: RequestExtras,\n ): Promise<InvoiceTaxRuleEvaluation> {\n return this.request('POST', '/invoice-settings/tax-rules/evaluate', {\n body: params,\n ...options,\n });\n }\n}\n","import type {\n BulkCreateProcessorCostSchedulesRequest,\n CreateProcessorCostScheduleRequest,\n ProcessorCostScheduleResponse,\n ReplaceProcessorCostScheduleRequest,\n UpdateProcessorCostScheduleRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A merchant's own processor cost schedules: what the processor the merchant\n * brought itself charges it, per connector and — as narrowly as the rate is\n * written — per shop, payment method, method type, card network or the\n * processor's own method code.\n *\n * A schedule prices the rails that report no fee on the payment itself. What\n * it produces is stamped `estimated` on the settlement line, never\n * `reported`, and the rates that priced it are copied onto the line as\n * `processor_cost_basis` so the figure survives the schedule being replaced\n * or deleted.\n *\n * The DeloPay-wide defaults a merchant inherits are DeloPay's own acquirer\n * pricing. They are never listed here, and they are edited through the\n * internal client instead (`DelopayInternal.adminPortal`).\n *\n * A rate is never edited in place: it priced transactions that already\n * happened. {@link ProcessorCosts.update} only closes, deactivates or\n * annotates a schedule; a price change is {@link ProcessorCosts.replace},\n * which closes the old window and opens the successor in one step.\n *\n * Every route takes the merchant account id and needs a dashboard session for\n * that merchant.\n */\nexport class ProcessorCosts {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Every processor cost schedule of the merchant.\n * `GET /processor-costs`\n *\n * @param merchantId - The merchant account ID.\n */\n async list(merchantId: string): Promise<ProcessorCostScheduleResponse[]> {\n return this.request('GET', '/processor-costs', { query: { merchant_id: merchantId } });\n }\n\n /**\n * Record a processor cost schedule.\n * `POST /processor-costs`\n *\n * A `shop_id` that is well formed but not a shop of this merchant is\n * answered `404` and nothing is recorded: a rate scoped to a shop the\n * merchant does not own would price no attempt, leaving every line it was\n * meant to price `unavailable` while the screen showed a configured rate.\n *\n * @param params - The schedule.\n * @param merchantId - The merchant account ID.\n */\n async create(\n params: CreateProcessorCostScheduleRequest,\n merchantId: string,\n ): Promise<ProcessorCostScheduleResponse> {\n return this.request('POST', '/processor-costs', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Record several schedules at once, all or none — copy a price list across\n * methods or shops.\n * `POST /processor-costs/bulk`\n *\n * 1 to 200 entries. Every entry is validated before anything is stored: an\n * invalid one is answered `422` naming its index, and nothing is stored.\n * The answer lists the created schedules in request order.\n *\n * @param params - The schedules.\n * @param merchantId - The merchant account ID.\n */\n async bulkCreate(\n params: BulkCreateProcessorCostSchedulesRequest,\n merchantId: string,\n ): Promise<ProcessorCostScheduleResponse[]> {\n return this.request('POST', '/processor-costs/bulk', {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Close, deactivate or annotate a schedule. The rate is not editable.\n * `PUT /processor-costs/{schedule_id}`\n *\n * @param scheduleId - The schedule ID.\n * @param params - What to change.\n * @param merchantId - The merchant account ID.\n */\n async update(\n scheduleId: string,\n params: UpdateProcessorCostScheduleRequest,\n merchantId: string,\n ): Promise<ProcessorCostScheduleResponse> {\n return this.request('PUT', `/processor-costs/${encodeURIComponent(scheduleId)}`, {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Close a schedule at `effective_from` and open its successor with the same\n * scope and the same end, in one step: no transaction is priced by both\n * rates, and none falls between them.\n * `POST /processor-costs/{schedule_id}/replace`\n *\n * Answers the successor schedule. An `effective_from` outside the old\n * schedule's window, an inactive schedule, or one a concurrent replacement\n * already moved is answered `400` — retry against the schedule as it now\n * stands rather than forcing the write.\n *\n * @param scheduleId - The schedule to replace.\n * @param params - The new rate.\n * @param merchantId - The merchant account ID.\n */\n async replace(\n scheduleId: string,\n params: ReplaceProcessorCostScheduleRequest,\n merchantId: string,\n ): Promise<ProcessorCostScheduleResponse> {\n return this.request('POST', `/processor-costs/${encodeURIComponent(scheduleId)}/replace`, {\n body: params,\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Delete a schedule. Restates nothing: every figure it derived is already\n * stamped on the settlement lines it priced.\n * `DELETE /processor-costs/{schedule_id}`\n *\n * @param scheduleId - The schedule ID.\n * @param merchantId - The merchant account ID.\n */\n async delete(scheduleId: string, merchantId: string): Promise<void> {\n return this.request('DELETE', `/processor-costs/${encodeURIComponent(scheduleId)}`, {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n CheckoutMethodsResetResponse,\n CheckoutMethodsResponse,\n CheckoutMethodsUpdateRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A shop's payment-method layout for the hosted checkout: the express strip,\n * the main list, the \"other payment methods\" list, and each item's overrides\n * (text, translations, icon, look, open target, visibility). One document per\n * shop (business profile), owned by the shop rather than by each connector\n * account. Until a shop saves one, the router derives a layout from the\n * shop's connector accounts and reports `source: 'derived'`.\n *\n * Dashboard JWT (`CheckoutMethods` read / write) or an admin key.\n */\nexport class CheckoutMethods {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * The shop's layout (stored, or derived from its accounts) and every item\n * it may place. `GET /checkout-methods/{profile_id}`\n */\n async retrieve(merchantId: string, profileId: string): Promise<CheckoutMethodsResponse> {\n return this.request('GET', `/checkout-methods/${encodeURIComponent(profileId)}`, {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * The same document as {@link retrieve}, on the route that stays open to a\n * reader of the checkout's appearance while the role's payment-data\n * visibility is restricted. `GET /checkout-methods/{profile_id}/preview`\n */\n async preview(merchantId: string, profileId: string): Promise<CheckoutMethodsResponse> {\n return this.request('GET', `/checkout-methods/${encodeURIComponent(profileId)}/preview`, {\n query: { merchant_id: merchantId },\n });\n }\n\n /**\n * Replace the shop's layout. The router refuses an express item that does\n * not draw its own button, more than two rows of two in the express strip,\n * a title without text, or an item no account of the shop offers.\n * `PUT /checkout-methods/{profile_id}`\n */\n async update(\n merchantId: string,\n profileId: string,\n body: CheckoutMethodsUpdateRequest,\n ): Promise<CheckoutMethodsResponse> {\n return this.request('PUT', `/checkout-methods/${encodeURIComponent(profileId)}`, {\n query: { merchant_id: merchantId },\n body,\n });\n }\n\n /**\n * Delete the stored layout; the shop is back on the derived one.\n * `DELETE /checkout-methods/{profile_id}`\n */\n async reset(merchantId: string, profileId: string): Promise<CheckoutMethodsResetResponse> {\n return this.request('DELETE', `/checkout-methods/${encodeURIComponent(profileId)}`, {\n query: { merchant_id: merchantId },\n });\n }\n}\n","import type {\n BuyerPortalSubscriptionCapabilities,\n NativeShopConfigRequest,\n NativeShopConfigResponse,\n NativeDunningConfigRequest,\n NativeDunningConfigResponse,\n AdoptSubscriptionRequest,\n AdoptSubscriptionResponse,\n CreateSubscriptionRequest,\n CreateAndConfirmSubscriptionRequest,\n ConfirmSubscriptionRequest,\n UpdateSubscriptionRequest,\n PauseSubscriptionRequest,\n ResumeSubscriptionRequest,\n CancelSubscriptionRequest,\n SubscriptionResponse,\n ConfirmSubscriptionResponse,\n PauseSubscriptionResponse,\n ResumeSubscriptionResponse,\n CancelSubscriptionResponse,\n GetSubscriptionItemsResponse,\n GetSubscriptionItemsParams,\n SubscriptionEstimateResponse,\n SubscriptionEstimateParams,\n SubscriptionListParams,\n SubscriptionPaymentLookupRequest,\n SubscriptionPaymentLookupResponse,\n SubscriptionInvoiceListParams,\n SubscriptionInvoiceListResponse,\n SubscriptionBillingProcessorResponse,\n SubscriptionImportApplyRequest,\n SubscriptionImportApplyResponse,\n SubscriptionImportPreviewRequest,\n SubscriptionImportPreviewResponse,\n SubscriptionItemsPage,\n SubscriptionSyncRequest,\n SubscriptionSyncResponse,\n SubscriptionSyncResult,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Subscription endpoints are profile-scoped: the backend requires an\n * `X-Profile-Id` header to resolve the shop / billing processor (`IR_04`\n * otherwise). Pass it through the per-call `options.headers`, e.g.\n * `subscriptions.list(params, { headers: { 'X-Profile-Id': profileId } })`.\n */\nexport class Subscriptions {\n constructor(private readonly request: RequestFn) {}\n\n /** Read native enrollment settings. Pass X-Profile-Id in options.headers. */\n async getNativeConfig(options?: RequestExtras): Promise<NativeShopConfigResponse> {\n return this.request('GET', '/subscriptions/native/config', { ...options });\n }\n\n /** Replace native enrollment settings. Pass X-Profile-Id in options.headers. */\n async updateNativeConfig(\n params: NativeShopConfigRequest,\n options?: RequestExtras,\n ): Promise<NativeShopConfigResponse> {\n return this.request('PUT', '/subscriptions/native/config', { body: params, ...options });\n }\n\n /** Read merchant-wide renewal recovery settings. */\n async getNativeDunning(options?: RequestExtras): Promise<NativeDunningConfigResponse> {\n return this.request('GET', '/subscriptions/native/dunning', { ...options });\n }\n\n async updateNativeDunning(\n params: NativeDunningConfigRequest,\n options?: RequestExtras,\n ): Promise<NativeDunningConfigResponse> {\n return this.request('PUT', '/subscriptions/native/dunning', { body: params, ...options });\n }\n\n /** Read supported actions for an owned subscription. Pass X-Profile-Id in options.headers. */\n async getCapabilities(\n subscriptionId: string,\n options?: RequestExtras,\n ): Promise<BuyerPortalSubscriptionCapabilities> {\n return this.request(\n 'GET',\n `/subscriptions/${encodeURIComponent(subscriptionId)}/capabilities`,\n { ...options },\n );\n }\n\n /**\n * Create and immediately confirm a subscription. `POST /subscriptions`\n *\n * For billing processors that require buyer approval (e.g. PayPal), the\n * response carries a `redirect_url` the customer must be sent to.\n */\n async createAndConfirm(\n params: CreateAndConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', '/subscriptions', { body: params, ...options });\n }\n\n /** Create a subscription without confirming it. `POST /subscriptions/create` */\n async create(\n params: CreateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('POST', '/subscriptions/create', { body: params, ...options });\n }\n\n /**\n * Adopt an existing Creem subscription. `POST /subscriptions/adopt`\n *\n * Requires adoption to be enabled on the deployment and `X-Profile-Id` in\n * options.headers. Adoption charges nothing and emits no invoice or webhook.\n * Repeating the processor subscription ID returns the existing DeloPay ID.\n * Retry when handoff_confirmed is false. That flag confirms persistence,\n * not the merchant's external switch-over: stop processing Creem events in\n * your own integration when handing subsequent events to DeloPay.\n */\n async adopt(\n params: AdoptSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<AdoptSubscriptionResponse> {\n return this.request('POST', '/subscriptions/adopt', { body: params, ...options });\n }\n\n /** Retrieve a subscription by ID. `GET /subscriptions/{subscriptionId}` */\n async retrieve(subscriptionId: string, options?: RequestExtras): Promise<SubscriptionResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}`, {\n ...options,\n });\n }\n\n /**\n * Confirm a previously created subscription. `POST /subscriptions/{subscriptionId}/confirm`\n *\n * Like {@link createAndConfirm}, the response may carry a `redirect_url` for\n * processors that require buyer approval.\n */\n async confirm(\n subscriptionId: string,\n params: ConfirmSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Update a subscription's plan/price. `PUT /subscriptions/{subscriptionId}/update`\n *\n * From the dashboard this counts against the caller's `subscription_change`\n * operation limit; an over-limit call fails with `DE_01` and nothing reaches\n * the processor. Calls made with an API key are not limited.\n */\n async update(\n subscriptionId: string,\n params: UpdateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse> {\n return this.request('PUT', `/subscriptions/${encodeURIComponent(subscriptionId)}/update`, {\n body: params,\n ...options,\n });\n }\n\n /** List subscriptions for the profile. `GET /subscriptions/list` */\n async list(\n params?: SubscriptionListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionResponse[]> {\n return this.request('GET', '/subscriptions/list', {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** Estimate the cost of a subscription before creating it. `GET /subscriptions/estimate` */\n async getEstimate(\n params: SubscriptionEstimateParams,\n options?: RequestExtras,\n ): Promise<SubscriptionEstimateResponse> {\n return this.request('GET', '/subscriptions/estimate', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /** List purchasable subscription items (plans/addons). `GET /subscriptions/items` */\n async getItems(\n params: GetSubscriptionItemsParams,\n options?: RequestExtras,\n ): Promise<GetSubscriptionItemsResponse[]> {\n return this.request('GET', '/subscriptions/items', {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * {@link getItems}, with whether the list is only the first part of what the\n * processor holds. `GET /subscriptions/items`\n *\n * The backend states that in the `X-Delopay-Items-Truncated` response\n * header (Stripe Billing lists its first 100 products), which the plain\n * {@link getItems} cannot return. Without `limit` and `offset` every item\n * the billing account offers is listed, up to 500.\n */\n async getItemsPage(\n params: GetSubscriptionItemsParams,\n options?: RequestExtras,\n ): Promise<SubscriptionItemsPage> {\n let truncated = false;\n const items = await this.request<GetSubscriptionItemsResponse[]>(\n 'GET',\n '/subscriptions/items',\n {\n query: params as unknown as Record<string, string | number | undefined>,\n ...options,\n onDownloadProgress: (event) => {\n // The headers arrive with the first event; a retried request reports\n // them again, and the last attempt is the one the items come from.\n truncated = event.headers.get('x-delopay-items-truncated')?.toLowerCase() === 'true';\n options?.onDownloadProgress?.(event);\n },\n },\n );\n return { items, truncated };\n }\n\n /**\n * Pause a subscription. `POST /subscriptions/{subscriptionId}/pause`\n *\n * From the dashboard this counts against the caller's `subscription_change`\n * operation limit; an over-limit call fails with `DE_01` and nothing reaches\n * the processor. Calls made with an API key are not limited.\n *\n * The body defaults to `{}` so the request still carries\n * `Content-Type: application/json` even when no params are passed — the\n * backend rejects the POST otherwise (\"Unsupported content type\").\n */\n async pause(\n subscriptionId: string,\n params?: PauseSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<PauseSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/pause`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /**\n * Resume a paused subscription. `POST /subscriptions/{subscriptionId}/resume`\n *\n * From the dashboard this counts against the caller's `subscription_change`\n * operation limit; an over-limit call fails with `DE_01` and nothing reaches\n * the processor. Calls made with an API key are not limited.\n */\n async resume(\n subscriptionId: string,\n params?: ResumeSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<ResumeSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/resume`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /**\n * Cancel a subscription. `POST /subscriptions/{subscriptionId}/cancel`\n *\n * A subscription in a state it cannot be cancelled from is refused with\n * `DE_11`; `error.data.reason` then names why (`SubscriptionActionRefusal`).\n *\n * From the dashboard this counts against the caller's `subscription_change`\n * operation limit; an over-limit call fails with `DE_01` and nothing reaches\n * the processor. Calls made with an API key are not limited.\n */\n async cancel(\n subscriptionId: string,\n params?: CancelSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<CancelSubscriptionResponse> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/cancel`, {\n body: params ?? {},\n ...options,\n });\n }\n\n /**\n * Read 1 to 50 subscriptions back from their billing processor and mirror\n * what it reports. `POST /subscriptions/sync`\n *\n * Nothing is written at the processor. A status is mirrored only with the\n * time the processor stamped it with, and never over a newer event already\n * recorded; a plan only with its own stamp. One result per id, in request\n * order; one that fails does not stop the others.\n */\n async sync(\n params: SubscriptionSyncRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionSyncResponse> {\n return this.request('POST', '/subscriptions/sync', { body: params, ...options });\n }\n\n /**\n * Read one subscription back from its billing processor and mirror what it\n * reports, as {@link sync} does, with what the processor reported beside\n * what the mirror now holds. `POST /subscriptions/{subscriptionId}/sync`\n */\n async syncOne(subscriptionId: string, options?: RequestExtras): Promise<SubscriptionSyncResult> {\n return this.request('POST', `/subscriptions/${encodeURIComponent(subscriptionId)}/sync`, {\n ...options,\n });\n }\n\n /**\n * List the subscriptions a billing account holds at its processor, and how\n * each relates to DeloPay's: already held, new (its buyer is a DeloPay\n * customer), needing a customer, ended, or not adoptable here.\n * `POST /subscriptions/import/preview`\n *\n * Reads only; nothing is written here or at the processor. Creem and\n * Stripe Billing can be listed; PayPal cannot, which `capabilities` states\n * (`reason_code: 'listing_unsupported'`).\n */\n async importPreview(\n params: SubscriptionImportPreviewRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionImportPreviewResponse> {\n return this.request('POST', '/subscriptions/import/preview', { body: params, ...options });\n }\n\n /**\n * Take 1 to 25 processor subscriptions over, each through {@link adopt}\n * with every one of its checks, one after another.\n * `POST /subscriptions/import/apply`\n *\n * One result per selection, in request order; one refused does not stop\n * the others.\n */\n async importApply(\n params: SubscriptionImportApplyRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionImportApplyResponse> {\n return this.request('POST', '/subscriptions/import/apply', { body: params, ...options });\n }\n\n /**\n * Resolve which of the given payments were raised by a subscription.\n * `POST /subscriptions/payments/lookup`\n *\n * The linkage exists in one direction only — an invoice points at the payment\n * it settled, and nothing is stamped on the payment — so this is the only way\n * to tell a subscription charge from a one-off one when you are holding a\n * page of payments. In particular, do not use `off_session` or the presence\n * of a mandate: an ordinary saved-card charge sets those identically.\n *\n * Ids that belong to no subscription are **absent** from `links` rather than\n * returned as an error, so match on presence:\n *\n * ```ts\n * const { links } = await subscriptions.lookupPayments(\n * { payment_ids: page.map((p) => p.payment_id) },\n * { headers: { 'X-Profile-Id': profileId } },\n * );\n * const bySubscription = new Map(links.map((l) => [l.payment_id, l]));\n * ```\n *\n * Profile-scoped like every other subscription route, and that matters more\n * here than elsewhere: a `payment_id` is merchant-supplied and only unique\n * within a merchant, so the shop is part of the question, not an\n * optimisation. Pass the profile that owns **the payments** — for a list\n * spanning several shops, group the ids by shop and call once per group.\n *\n * At most 200 ids per call.\n */\n async lookupPayments(\n params: SubscriptionPaymentLookupRequest,\n options?: RequestExtras,\n ): Promise<SubscriptionPaymentLookupResponse> {\n return this.request('POST', '/subscriptions/payments/lookup', { body: params, ...options });\n }\n\n /**\n * One subscription's billing history, newest cycle first.\n * `GET /subscriptions/{subscriptionId}/invoices`\n *\n * {@link retrieve} carries only the *latest* invoice, which is the current\n * cycle — a subscription that has renewed monthly for a year has one of those\n * and twelve of these. Use this wherever a merchant needs to see what a\n * subscription has actually billed, in particular on self-charging processors\n * (Creem, PayPal) where each renewal is charged by the processor and mirrored\n * here rather than raised as a DeloPay payment.\n *\n * Two things to render honestly, both decided rather than incidental:\n *\n * - `amount` is **gross** and `refunded_amount` sits beside it. Do not net\n * them: the difference between the two is not a smaller charge.\n * - A `refunded_amount` of `null` is \"not reported\" and must not render as\n * `0`. Likewise a processor-hosted origination records a bootstrap invoice\n * at `0` before the buyer has paid anything, so a zero amount on such a\n * subscription is a placeholder rather than a free cycle.\n *\n * Profile-scoped like every other subscription route.\n */\n async listInvoices(\n subscriptionId: string,\n params?: SubscriptionInvoiceListParams,\n options?: RequestExtras,\n ): Promise<SubscriptionInvoiceListResponse> {\n return this.request('GET', `/subscriptions/${encodeURIComponent(subscriptionId)}/invoices`, {\n query: params as Record<string, string | number | undefined>,\n ...options,\n });\n }\n\n /**\n * Which billing processor this shop's subscriptions run on.\n * `GET /subscriptions/billing_processor`\n *\n * The same mapping is derivable from the connector inventory\n * (`GET /account/{merchant_id}/connectors`), but that route is gated by a\n * connector-read permission granted independently of subscriptions — so a\n * role authorised to create subscriptions could be unable to learn which\n * processor it was creating them on. This answers under the same\n * authorization as the rest of the subscription API.\n *\n * Reach for it when the client must branch on the processor *before* calling\n * — origination differs by processor, and guessing is destructive. Resolve\n * the shop's `billing_processor_id` first: a shop that runs no subscriptions\n * has none assigned, and this route has no identity to report for it.\n */\n async getBillingProcessor(\n options?: RequestExtras,\n ): Promise<SubscriptionBillingProcessorResponse> {\n return this.request('GET', '/subscriptions/billing_processor', { ...options });\n }\n}\n","import type { RequestExtras, RequestFn } from '../client';\nimport type {\n BuyerInvoiceListQuery,\n BuyerPortalInvoice,\n BuyerPortalInvoicePage,\n BuyerPortalPageQuery,\n BuyerPortalPurchasePage,\n BuyerPortalSession,\n BuyerPortalSubscriptionPage,\n BuyerPortalSubscription,\n BuyerPortalSubscriptionActionRequest,\n BuyerPortalPlanPage,\n BuyerPortalPlanChangeRequest,\n NativeCreateSubscriptionRequest,\n NativeEnrollmentResponse,\n NativeEnrollmentStatusQuery,\n NativeEnrollmentAbandonResponse,\n} from '../types';\n\n/**\n * Buyer access using a customer portal grant, sent in the api-key header.\n * Use a separate client constructed with the portal token, not a merchant secret\n * key or dashboard JWT. The grant determines buyer identity and permitted shops.\n */\nexport class BuyerPortal {\n constructor(private readonly request: RequestFn) {}\n\n async getSession(options?: RequestExtras): Promise<BuyerPortalSession> {\n return this.request('GET', '/buyer-portal/session', { ...options });\n }\n\n async listInvoices(\n params?: BuyerInvoiceListQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalInvoicePage> {\n return this.request('GET', '/buyer-portal/invoices', {\n query: params as Record<string, number | null | undefined>,\n ...options,\n });\n }\n\n async retrieveInvoice(invoiceId: string, options?: RequestExtras): Promise<BuyerPortalInvoice> {\n return this.request('GET', `/buyer-portal/invoices/${encodeURIComponent(invoiceId)}`, {\n ...options,\n });\n }\n\n /** Download the owned, published invoice as PDF bytes. */\n async downloadInvoicePdf(invoiceId: string, options?: RequestExtras): Promise<Blob> {\n return this.request('GET', `/buyer-portal/invoices/${encodeURIComponent(invoiceId)}/pdf`, {\n responseType: 'blob',\n ...options,\n });\n }\n\n async listPurchases(\n params?: BuyerPortalPageQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalPurchasePage> {\n return this.request('GET', '/buyer-portal/purchases', {\n query: params as Record<string, number | null | undefined>,\n ...options,\n });\n }\n\n async listSubscriptions(\n params?: BuyerPortalPageQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalSubscriptionPage> {\n return this.request('GET', '/buyer-portal/subscriptions', {\n query: params as Record<string, number | null | undefined>,\n ...options,\n });\n }\n\n /** Apply an action allowed by the subscription capabilities and portal grant. */\n async actOnSubscription(\n subscriptionId: string,\n params: BuyerPortalSubscriptionActionRequest,\n options?: RequestExtras,\n ): Promise<BuyerPortalSubscription> {\n return this.request(\n 'POST',\n `/buyer-portal/subscriptions/${encodeURIComponent(subscriptionId)}/actions`,\n { body: params, ...options },\n );\n }\n\n async listSubscriptionPlans(\n subscriptionId: string,\n params?: BuyerPortalPageQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalPlanPage> {\n return this.request(\n 'GET',\n `/buyer-portal/subscriptions/${encodeURIComponent(subscriptionId)}/plans`,\n { query: params as Record<string, number | null | undefined>, ...options },\n );\n }\n\n async changeSubscriptionPlan(\n subscriptionId: string,\n params: BuyerPortalPlanChangeRequest,\n options?: RequestExtras,\n ): Promise<BuyerPortalSubscription> {\n return this.request(\n 'POST',\n `/buyer-portal/subscriptions/${encodeURIComponent(subscriptionId)}/change-plan`,\n { body: params, ...options },\n );\n }\n\n async listNativePlans(\n profileId: string,\n params?: BuyerPortalPageQuery,\n options?: RequestExtras,\n ): Promise<BuyerPortalPlanPage> {\n return this.request(\n 'GET',\n `/buyer-portal/subscriptions/native/plans/${encodeURIComponent(profileId)}`,\n { query: params as Record<string, number | null | undefined>, ...options },\n );\n }\n\n /** Retry with the same subscription ID and accepted terms after a lost response. */\n async enrollNative(\n params: NativeCreateSubscriptionRequest,\n options?: RequestExtras,\n ): Promise<NativeEnrollmentResponse> {\n return this.request('POST', '/buyer-portal/subscriptions/native/enroll', {\n body: params,\n ...options,\n });\n }\n\n async getNativeEnrollment(\n subscriptionId: string,\n params: NativeEnrollmentStatusQuery,\n options?: RequestExtras,\n ): Promise<NativeEnrollmentResponse> {\n return this.request(\n 'GET',\n `/buyer-portal/subscriptions/native/enroll/${encodeURIComponent(subscriptionId)}`,\n { query: { profile_id: params.profile_id }, ...options },\n );\n }\n\n async abandonNativeEnrollment(\n subscriptionId: string,\n params: NativeEnrollmentStatusQuery,\n options?: RequestExtras,\n ): Promise<NativeEnrollmentAbandonResponse> {\n return this.request(\n 'POST',\n `/buyer-portal/subscriptions/native/enroll/${encodeURIComponent(subscriptionId)}/abandon`,\n { query: { profile_id: params.profile_id }, ...options },\n );\n }\n}\n","import type {\n MerchantAuditLogListParams,\n MerchantAuditLogListResponse,\n MerchantAuditLogEntry,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A merchant's own audit log — everything changed on their account and their\n * shops, grouped by the sign-in it happened in.\n *\n * Requires a dashboard JWT (`setJwtToken`) whose role holds the `AuditLog`\n * permission; an API key cannot read it. This is deliberate: the log names\n * people, and an API key names no one.\n *\n * There is no `merchant_id` parameter. The scope comes from the token, so this\n * resource cannot be pointed at another merchant — see\n * {@link MerchantAuditLogListParams}.\n */\nexport class Audit {\n constructor(private readonly request: RequestFn) {}\n\n async list(params?: MerchantAuditLogListParams): Promise<MerchantAuditLogListResponse> {\n return this.request('GET', '/audit', {\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * One entry. An id belonging to another merchant answers 404, not 403 — the\n * endpoint does not confirm that an entry it will not serve exists.\n */\n async retrieve(logId: string): Promise<MerchantAuditLogEntry> {\n return this.request('GET', `/audit/${encodeURIComponent(logId)}`);\n }\n}\n","import type {\n NativeSettlementPreviewRequest,\n NativeSettlementPreviewResponse,\n NativeSettlementReportCreateRequest,\n NativeSettlementReport,\n NativeSettlementReportExport,\n NativeSettlementListRequest,\n NativeSettlementReportListResponse,\n NativeSettlementPayoutCreateRequest,\n NativeSettlementPayout,\n NativeSettlementPayoutListResponse,\n NativeSettlementFeeRefreshRequest,\n NativeSettlementFeeRefreshResponse,\n NativeSettlementPdfRequest,\n ProcessorCostEventsRequest,\n ProcessorCostEventsResponse,\n ProcessorCostPeriodRequest,\n ProcessorCostPeriodResponse,\n FeeStatementDetail,\n SettlementBackfillRequest,\n SettlementBackfillResponse,\n SettlementCostParams,\n SettlementCostResponse,\n SettlementCurrentParams,\n SettlementCurrentResponse,\n SettlementLineListParams,\n SettlementLineListResponse,\n SettlementOverviewParams,\n SettlementOverviewResponse,\n SettlementStatementListParams,\n SettlementStatementListResponse,\n ShopFeeConfigParams,\n ShopFeeConfigResponse,\n ShopVisibilityResponse,\n ShopVisibilityUpdateRequest,\n StatementAdjustment,\n StatementAdjustmentCreateRequest,\n StatementAdjustmentListResponse,\n StatementGenerateRequest,\n StatementPayoutUpdateRequest,\n StatementPayoutRecordRequest,\n StatementPayoutListResponse,\n StatementAdvance,\n StatementAdvanceRecordRequest,\n SettlementAdvanceListRequest,\n SettlementAdvanceListResponse,\n StatementPdfParams,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\nfunction exportHeaders(options: RequestExtras | undefined, accept: string): Record<string, string> {\n const headers = new Headers(options?.headers);\n headers.set('Accept', accept);\n const output: Record<string, string> = {};\n headers.forEach((value, key) => {\n output[key] = value;\n });\n return output;\n}\n\n/**\n * Hosted-shop settlement: monthly statements, the live current-period\n * rollup, per-line detail, fee schedules and backfills.\n *\n * Every read takes an explicit `test_mode` — test and live figures must\n * never blend, so the environment lives in the signature rather than in a\n * default. `false` is transmitted, not dropped.\n *\n * Shop-owner responses are redacted server-side: absent platform-fee fields\n * are a permission boundary, not a gap — never re-derive them client-side.\n */\nexport class Settlement {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Read signed refund/dispute processor fees and report availability.\n * Merchant scope and connector grants apply. Empty movements confirm zero\n * only when the source is reported and complete.\n * Supply payment_id without year/month for all history. force_sync reads\n * provider reports for this page; it requires payment_id and limit <= 20,\n * and never issues a payment, refund or dispute action.\n * Omit test_mode for every reporting partition of one payment; period\n * queries default to live. Each source states its reporting partition.\n */\n async listProcessorCostEvents(\n params: ProcessorCostEventsRequest,\n options?: RequestExtras,\n ): Promise<ProcessorCostEventsResponse> {\n return this.request('GET', '/settlement/processor-cost-events', {\n query: {\n profile_id: params.profile_id,\n payment_id: params.payment_id,\n year: params.year,\n month: params.month,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n force_sync: params.force_sync,\n },\n ...options,\n });\n }\n\n /**\n * Per-shop settlement rollup for the host merchant: unpaid totals and the\n * running current period, one row per shop.\n *\n * `GET /settlement/overview`\n */\n async overview(\n params: SettlementOverviewParams,\n options?: RequestExtras,\n ): Promise<SettlementOverviewResponse> {\n return this.request('GET', '/settlement/overview', {\n query: { test_mode: params.test_mode },\n ...options,\n });\n }\n\n /**\n * Live rollup of the current (not yet statemented) period.\n *\n * `GET /settlement/current`\n */\n async current(\n params: SettlementCurrentParams,\n options?: RequestExtras,\n ): Promise<SettlementCurrentResponse> {\n return this.request('GET', '/settlement/current', {\n query: { test_mode: params.test_mode, profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * What a period's payments cost, and what was left over: gross, the\n * platform fee, hosting fees, what the rails took, and the margin, with a\n * per-connector breakdown.\n *\n * Send `year` and `month` together to report one UTC calendar month, or\n * neither for the running month so far.\n *\n * **Host-only.** The response is the host's cost base, which a shop owner\n * must never see, so a profile-scoped caller is refused with a 403 rather\n * than given a redacted shell. Gate the surface on the caller's scope\n * instead of calling it and handling the failure. Connector-restricted\n * roles cannot read this merchant-wide aggregate; fee-event reads retain\n * their connector grants.\n *\n * Two things not to flatten when rendering the result:\n * `margin_usd` is absent — not zero — whenever `margin_quality` is\n * `'unknown'`, and `unlined_captured_attempt_count` (cost definitely\n * missing) means something different from `unlined_unresolved_attempt_count`\n * (mostly ordinary abandonment).\n *\n * `GET /settlement/cost`\n *\n * @example\n * ```typescript\n * const cost = await delopay.settlement.cost({ test_mode: false, year: 2026, month: 7 });\n * if (cost.margin_quality === 'unknown') {\n * // cost.margin_usd is absent — say so, do not render 0.00\n * }\n * ```\n */\n async cost(\n params?: SettlementCostParams,\n options?: RequestExtras,\n ): Promise<SettlementCostResponse> {\n return this.request('GET', '/settlement/cost', {\n query: {\n profile_id: params?.profile_id,\n test_mode: params?.test_mode,\n year: params?.year,\n month: params?.month,\n },\n ...options,\n });\n }\n\n /**\n * What a period's payments cost at the rails, grouped by shop, connector\n * and payment method. Answers for **every** merchant, including one that\n * hosts nobody — it reads the per-attempt settlement record rather than the\n * settlement lines, which exist only where hosting fees are configured.\n *\n * A sibling of {@link Settlement.cost} rather than a widening of it. That\n * endpoint is a profit statement whose revenue term is hosting income, and\n * a merchant who hosts nobody has none. This publishes cost and never\n * margin.\n *\n * Send `year` and `month` together to report one UTC calendar month, or\n * neither for the running month so far.\n *\n * **The response carries no period total, and a caller must not compute\n * one here.** Every figure keeps the unit the rail reported it in, and the\n * unit is part of each bucket's key, so adding two buckets is not addition.\n * Convert caller-side if you need one number, and say which rates you used.\n * The counts are totalled, because a count has no unit.\n *\n * Two distinctions not to flatten when rendering a bucket:\n * `cost_amount` covers `reported_count + estimated_count` attempts out of\n * `attempt_count` and is a lower bound whenever those disagree; and\n * `unavailable_count` (the rail says it has no figure) means something\n * different from `unwritten_count` (a gap in our own recording).\n *\n * **Merchant scope.** A token scoped to a single shop, a role narrowed to\n * specific connector accounts, or a role without the settlement-read\n * permission group is refused `403`: what a rail charged is the merchant's\n * own cost base, and here it is the whole response, so there is nothing\n * coherent to redact down to. Gate the surface on the caller's scope rather\n * than calling it and handling the failure.\n *\n * `GET /settlement/processor-cost`\n *\n * @example\n * ```typescript\n * const period = await delopay.settlement.processorCost({\n * test_mode: false,\n * year: 2026,\n * month: 7,\n * });\n * for (const bucket of period.buckets) {\n * // Each bucket is its own unit — render per bucket, never a sum.\n * console.log(bucket.connector, bucket.cost_amount, bucket.cost_currency);\n * }\n * ```\n */\n async processorCost(\n params?: ProcessorCostPeriodRequest,\n options?: RequestExtras,\n ): Promise<ProcessorCostPeriodResponse> {\n return this.request('GET', '/settlement/processor-cost', {\n query: {\n profile_id: params?.profile_id,\n test_mode: params?.test_mode,\n year: params?.year,\n month: params?.month,\n },\n ...options,\n });\n }\n\n /**\n * List generated settlement statements, newest first.\n *\n * `GET /settlement/statements`\n */\n async listStatements(\n params: SettlementStatementListParams,\n options?: RequestExtras,\n ): Promise<SettlementStatementListResponse> {\n return this.request('GET', '/settlement/statements', {\n query: {\n test_mode: params.test_mode,\n profile_id: params.profile_id,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * One statement with its per-connector/currency breakdown.\n *\n * `GET /settlement/statements/{statementId}`\n */\n async retrieveStatement(\n statementId: string,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}`,\n options,\n );\n }\n\n /**\n * Generate (or regenerate) the statement for one shop and calendar month.\n *\n * `POST /settlement/statements/generate`\n */\n async generateStatement(\n params: StatementGenerateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request('POST', '/settlement/statements/generate', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Record payout progress on a statement (`unpaid` / `partial` / `paid`).\n *\n * Subject to the caller's `settlement_payout` operation limit — a\n * per-operation ceiling, a windowed total, a windowed count, or any\n * combination: an over-limit call fails with `DE_01` and nothing is\n * recorded. There is no approval route out of it — four-eyes needs an\n * executor that can run the operation once somebody says yes, and only\n * refunds have one, so a settlement rule can only block.\n *\n * `POST /settlement/statements/{statementId}/payout`\n */\n async updateStatementPayout(\n statementId: string,\n params: StatementPayoutUpdateRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/payout`,\n { body: params, ...options },\n );\n }\n\n /** Append one external transfer record. Send a stable idempotency_key for safe retries. */\n async recordStatementPayout(\n statementId: string,\n params: StatementPayoutRecordRequest,\n options?: RequestExtras,\n ): Promise<FeeStatementDetail> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/payout`,\n {\n body: params,\n ...options,\n bodyIdempotencyKey: params.idempotency_key ?? null,\n },\n );\n }\n\n /** Read individual transfer records, their signed total, and any overpayment. */\n async listStatementPayouts(\n statementId: string,\n options?: RequestExtras,\n ): Promise<StatementPayoutListResponse> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}/payouts`,\n options,\n );\n }\n\n /** Record a transfer against a shop's month before its statement exists. */\n async recordAdvance(\n params: StatementAdvanceRecordRequest,\n options?: RequestExtras,\n ): Promise<StatementAdvance> {\n return this.request('POST', '/settlement/advances', {\n body: params,\n ...options,\n bodyIdempotencyKey: params.idempotency_key ?? null,\n });\n }\n\n async listAdvances(\n params: SettlementAdvanceListRequest,\n options?: RequestExtras,\n ): Promise<SettlementAdvanceListResponse> {\n return this.request('GET', '/settlement/advances', {\n query: {\n profile_id: params.profile_id,\n year: params.year,\n month: params.month,\n test_mode: params.test_mode,\n },\n ...options,\n });\n }\n\n /**\n * Export a statement as PDF. Returns the raw PDF bytes as a `Blob`, with\n * the same auth, retries and error handling as every other call — persist\n * or object-URL it caller-side.\n *\n * `GET /settlement/statements/{statementId}/pdf`\n *\n * @example\n * ```typescript\n * const pdf = await delopay.settlement.downloadStatementPdf('stmt_1', {\n * currency: 'EUR',\n * include_transactions: true,\n * });\n * const url = URL.createObjectURL(pdf);\n * ```\n */\n async downloadStatementPdf(\n statementId: string,\n params?: StatementPdfParams,\n options?: RequestExtras,\n ): Promise<Blob> {\n return this.request('GET', `/settlement/statements/${encodeURIComponent(statementId)}/pdf`, {\n query: {\n currency: params?.currency,\n include_transactions: params?.include_transactions,\n },\n responseType: 'blob',\n ...options,\n });\n }\n\n /**\n * The individual settled attempts of one shop's calendar month.\n *\n * `GET /settlement/lines`\n */\n async listLines(\n params: SettlementLineListParams,\n options?: RequestExtras,\n ): Promise<SettlementLineListResponse> {\n return this.request('GET', '/settlement/lines', {\n query: {\n profile_id: params.profile_id,\n year: params.year,\n month: params.month,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * The fee schedules that currently apply to a shop.\n *\n * `GET /settlement/fee-config`\n */\n async feeConfig(\n params: ShopFeeConfigParams,\n options?: RequestExtras,\n ): Promise<ShopFeeConfigResponse> {\n return this.request('GET', '/settlement/fee-config', {\n query: { profile_id: params.profile_id },\n ...options,\n });\n }\n\n /**\n * Enqueue a settlement-line backfill over historical attempts. Attempts\n * already covered by a line are always skipped.\n *\n * `POST /settlement/backfill`\n */\n async backfill(\n params?: SettlementBackfillRequest,\n options?: RequestExtras,\n ): Promise<SettlementBackfillResponse> {\n return this.request('POST', '/settlement/backfill', { body: params, ...options });\n }\n\n /**\n * Toggle whether a shop's owner can see their own settlement figures.\n *\n * `POST /settlement/shops/visibility`\n */\n async setShopVisibility(\n params: ShopVisibilityUpdateRequest,\n options?: RequestExtras,\n ): Promise<ShopVisibilityResponse> {\n return this.request('POST', '/settlement/shops/visibility', {\n body: params,\n ...options,\n });\n }\n\n /**\n * Manual adjustments recorded on a statement.\n *\n * `GET /settlement/statements/{statementId}/adjustments`\n */\n async listStatementAdjustments(\n statementId: string,\n options?: RequestExtras,\n ): Promise<StatementAdjustmentListResponse> {\n return this.request(\n 'GET',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n options,\n );\n }\n\n /**\n * Add a manual adjustment to a statement. Positive `amount_usd` charges\n * the shop (reducing their payout); negative credits them.\n *\n * Subject to the caller's `settlement_adjustment` operation limit: an\n * over-limit call fails with `DE_01` and no adjustment is added. Both\n * windows count every add, and a credit counts at its magnitude. A\n * settlement rule can only block — approval is refund-only, for the reason\n * given on `updateStatementPayout()`. When another add by the same user\n * changes the window while this one is being admitted, the call fails with\n * HTTP 412 and nothing is written; retrying the same request is safe.\n *\n * `POST /settlement/statements/{statementId}/adjustments`\n */\n async createStatementAdjustment(\n statementId: string,\n params: StatementAdjustmentCreateRequest,\n options?: RequestExtras,\n ): Promise<StatementAdjustment> {\n return this.request(\n 'POST',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments`,\n { body: params, ...options },\n );\n }\n\n /**\n * Remove a manual adjustment from a statement.\n *\n * The adjustment still counts against the caller's `settlement_adjustment`\n * limit window it was added in: removing it does not give back its count or\n * amount.\n *\n * `DELETE /settlement/statements/{statementId}/adjustments/{adjustmentId}`\n */\n async deleteStatementAdjustment(\n statementId: string,\n adjustmentId: string,\n options?: RequestExtras,\n ): Promise<void> {\n return this.request(\n 'DELETE',\n `/settlement/statements/${encodeURIComponent(statementId)}/adjustments/${encodeURIComponent(adjustmentId)}`,\n options,\n );\n }\n\n /**\n * Calculate a period in its transaction currency. Requires a host-level\n * dashboard JWT and settlement read permission. Profile users and roles\n * restricted to selected connector accounts cannot read this aggregate.\n * Rates apply once to the period total. Unknown or estimated fees keep\n * dependent amounts provisional. Native money values remain integer strings.\n */\n async previewNative(\n params: NativeSettlementPreviewRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementPreviewResponse> {\n return this.request('POST', '/settlement/native/preview', { body: params, ...options });\n }\n\n /**\n * Recalculate and freeze an immutable report version. Requires settlement\n * edit permission. Explicitly allow provisional figures when source fees\n * are incomplete. A report records a calculation and sends no money.\n * Reuse the same idempotency key when retrying the same request.\n */\n async createNativeReport(\n params: NativeSettlementReportCreateRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementReport> {\n return this.request('POST', '/settlement/native/reports', {\n body: params,\n ...options,\n bodyIdempotencyKey: params.idempotency_key,\n });\n }\n\n async retrieveNativeReport(\n reportId: string,\n options?: RequestExtras,\n ): Promise<NativeSettlementReport> {\n return this.request(\n 'GET',\n `/settlement/native/reports/${encodeURIComponent(reportId)}`,\n options,\n );\n }\n\n /** List report summaries without fetching every source row in each saved snapshot. */\n async listNativeReports(\n params: NativeSettlementListRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementReportListResponse> {\n return this.request('GET', '/settlement/native/reports', {\n query: {\n profile_id: params.profile_id,\n currency: params.currency,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /**\n * Record a transfer already made, under settlement write permission and\n * the caller's payout limits. This method never sends money. Native minor\n * units remain strings; negative records must name a same-scope reversal.\n * These records belong to the native ledger, separate from monthly USD\n * statement payouts and advances.\n */\n async recordNativePayout(\n params: NativeSettlementPayoutCreateRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementPayout> {\n return this.request('POST', '/settlement/native/payouts', {\n body: params,\n ...options,\n bodyIdempotencyKey: params.idempotency_key,\n });\n }\n\n async listNativePayouts(\n params: NativeSettlementListRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementPayoutListResponse> {\n return this.request('GET', '/settlement/native/payouts', {\n query: {\n profile_id: params.profile_id,\n currency: params.currency,\n test_mode: params.test_mode,\n limit: params.limit,\n offset: params.offset,\n },\n ...options,\n });\n }\n\n /** Refresh a bounded page of provider fee evidence. Follow next_offset while has_more is true. */\n async refreshNativeFees(\n params: NativeSettlementFeeRefreshRequest,\n options?: RequestExtras,\n ): Promise<NativeSettlementFeeRefreshResponse> {\n return this.request('POST', '/settlement/native/fees/refresh', { body: params, ...options });\n }\n\n async downloadNativeReportPdf(\n reportId: string,\n params?: NativeSettlementPdfRequest,\n options?: RequestExtras,\n ): Promise<Blob> {\n return this.request('GET', `/settlement/native/reports/${encodeURIComponent(reportId)}/pdf`, {\n query: { include_transactions: params?.include_transactions },\n responseType: 'blob',\n ...options,\n });\n }\n\n /** Download the frozen source rows and calculation as CSV. */\n async downloadNativeReportCsv(reportId: string, options?: RequestExtras): Promise<Blob> {\n return this.request(\n 'GET',\n `/settlement/native/reports/${encodeURIComponent(reportId)}/export`,\n {\n ...options,\n headers: exportHeaders(options, 'text/csv'),\n responseType: 'blob',\n },\n );\n }\n\n /** Export the frozen report as JSON, excluding host account-level costs. */\n async exportNativeReportJson(\n reportId: string,\n options?: RequestExtras,\n ): Promise<NativeSettlementReportExport> {\n return this.request(\n 'GET',\n `/settlement/native/reports/${encodeURIComponent(reportId)}/export`,\n {\n ...options,\n headers: exportHeaders(options, 'application/json'),\n },\n );\n }\n}\n","import type {\n DecidePendingOperationRequest,\n OperationLimitRule,\n OperationLimitRuleDeleteResponse,\n OperationLimitRuleListParams,\n OperationLimitSettings,\n OperationLimitUsage,\n OperationLimitUsageParams,\n PendingOperation,\n PendingOperationListParams,\n PendingOperationListResponse,\n UpdateOperationLimitSettingsRequest,\n UpsertOperationLimitRuleRequest,\n} from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Per-operation spending limits: rules scoped to the merchant, a role or a\n * user, the merchant-level enforcement settings, and the approvals inbox.\n * Enforcement resolves the most specific rule: user > role > merchant.\n *\n * A rule set to `require_approval` does not refuse an over-limit operation —\n * it parks it. The original call fails with HTTP 409 `DE_06` carrying\n * `PendingApprovalErrorDetails`, and the operation runs only once a second\n * person approves the request through this inbox.\n *\n * **Refunds only.** Approval needs an executor that can run the operation\n * after the decision, and only refunds have one; every other operation takes\n * `block` alone, which the request type enforces. So every request in this\n * inbox is a refund, and `DE_06` never comes back from any other call — an\n * over-limit settlement adjustment, payout or subscription change fails with\n * `DE_01`.\n */\nexport class OperationLimits {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * List the merchant's limit rules, optionally for one operation.\n *\n * `GET /operation-limits/rules`\n */\n async listRules(\n params?: OperationLimitRuleListParams,\n options?: RequestExtras,\n ): Promise<OperationLimitRule[]> {\n return this.request('GET', '/operation-limits/rules', {\n query: { operation: params?.operation },\n ...options,\n });\n }\n\n /**\n * Create or replace the limit rule for one target. Full-replace upsert:\n * absent limit fields clear that dimension.\n *\n * `PUT /operation-limits/rules`\n */\n async upsertRule(\n params: UpsertOperationLimitRuleRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitRule> {\n return this.request('PUT', '/operation-limits/rules', { body: params, ...options });\n }\n\n /**\n * Delete a limit rule.\n *\n * `DELETE /operation-limits/rules/{ruleId}`\n */\n async deleteRule(\n ruleId: string,\n options?: RequestExtras,\n ): Promise<OperationLimitRuleDeleteResponse> {\n return this.request('DELETE', `/operation-limits/rules/${encodeURIComponent(ruleId)}`, options);\n }\n\n /**\n * The merchant-level enforcement settings. An untouched merchant gets the\n * defaults: rolling window, admins not exempt.\n *\n * `GET /operation-limits/settings`\n */\n async retrieveSettings(options?: RequestExtras): Promise<OperationLimitSettings> {\n return this.request('GET', '/operation-limits/settings', options);\n }\n\n /**\n * The caller's own usage against the limit on one operation: the rule that\n * applies to them, what they have used in the current window and what\n * remains.\n *\n * Refund usage needs merchant-wide refund read and is refused to a role\n * restricted to some connectors: the totals span every shop and connector,\n * as the budget does. Settlement usage needs merchant settlement read.\n *\n * `GET /operation-limits/usage`\n */\n async retrieveUsage(\n params: OperationLimitUsageParams,\n options?: RequestExtras,\n ): Promise<OperationLimitUsage> {\n return this.request('GET', '/operation-limits/usage', {\n query: { operation: params.operation },\n ...options,\n });\n }\n\n /**\n * Update the enforcement settings. Only provided fields change.\n *\n * `PUT /operation-limits/settings`\n */\n async updateSettings(\n params: UpdateOperationLimitSettingsRequest,\n options?: RequestExtras,\n ): Promise<OperationLimitSettings> {\n return this.request('PUT', '/operation-limits/settings', { body: params, ...options });\n }\n\n /**\n * The approvals inbox: over-limit operations waiting on a second person.\n *\n * Both filters default rather than widen. With no `status` the list holds\n * **pending requests only** — approved, rejected and expired ones are\n * reachable only by asking for that status, so a history view must pass one\n * per status. With no `operation` it lists **refunds only**; the list is one\n * operation at a time. `limit` defaults to 100 and is clamped to 1–500.\n *\n * Requests past their `expires_at` are expired before the list is read, so\n * nothing here is shown as actionable when it is not.\n *\n * `GET /operation-limits/approvals`\n */\n async listApprovals(\n params?: PendingOperationListParams,\n options?: RequestExtras,\n ): Promise<PendingOperationListResponse> {\n return this.request('GET', '/operation-limits/approvals', {\n query: {\n operation: params?.operation,\n status: params?.status,\n limit: params?.limit,\n },\n ...options,\n });\n }\n\n /**\n * Approve a parked operation and execute it.\n *\n * Refused for the user who requested it, and for an approver whose own\n * limit would not have covered the operation — the permission is necessary\n * and not sufficient. The requester stays refused while signed in as\n * another team member: that is a `DE_12` error (`approval_decision_refused`)\n * whose `data.reason` is `requester_acting_as_another_member`, and\n * {@link reject} refuses the same way.\n *\n * Approval and execution are two facts. A request that was approved but\n * whose operation then failed comes back `approved` with `execution_error`\n * set and no `result_entity_id`; that is a real outcome, not a partial read.\n *\n * `POST /operation-limits/approvals/{id}/approve`\n */\n async approve(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/approve`, {\n body: params,\n ...options,\n });\n }\n\n /**\n * Reject a parked operation. Nothing is executed and the request is closed.\n *\n * `POST /operation-limits/approvals/{id}/reject`\n */\n async reject(\n id: string,\n params: DecidePendingOperationRequest = {},\n options?: RequestExtras,\n ): Promise<PendingOperation> {\n return this.request('POST', `/operation-limits/approvals/${encodeURIComponent(id)}/reject`, {\n body: params,\n ...options,\n });\n }\n}\n","import type { MerchantSettingsQuery, SettingsResponse, UpdateSettingsRequest } from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * Settings of the caller's merchant, its projects and its shops.\n *\n * One resource for every setting: each is a key with a JSON value, listed with\n * its default, whether a value is stored, its revision and who changed it last.\n * A merchant changes only its own values; values the platform operator sets at\n * the same scope are listed beside them (`authority: 'operator'`) and are\n * read-only here.\n *\n * Every change is recorded in the audit log with the previous and the new\n * value (`entity_type: 'setting'`), so one setting's history is\n * `audit.list({ entity_type: 'setting', entity_id })`.\n *\n * Dashboard (JWT) routes. Reading the merchant's settings needs\n * `MerchantAccountRead`, a shop's `ProfileAccountRead`; each change needs the\n * permission its setting names.\n */\n/** The query string of a merchant-scope call; a null project is omitted. */\nfunction projectQuery(query: MerchantSettingsQuery): Record<string, string> {\n return query.project_id ? { project_id: query.project_id } : {};\n}\n\nexport class Settings {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * The merchant's settings, or one project's.\n *\n * `GET /settings/merchant`\n */\n async retrieveMerchant(query: MerchantSettingsQuery = {}): Promise<SettingsResponse> {\n return this.request('GET', '/settings/merchant', { query: projectQuery(query) });\n }\n\n /**\n * Change the merchant's own settings, or one project's. All changes are\n * applied or none is.\n *\n * `PATCH /settings/merchant`\n */\n async updateMerchant(\n params: UpdateSettingsRequest,\n query: MerchantSettingsQuery = {},\n ): Promise<SettingsResponse> {\n return this.request('PATCH', '/settings/merchant', {\n body: params,\n query: projectQuery(query),\n });\n }\n\n /**\n * One shop's settings.\n *\n * `GET /settings/shops/{profileId}`\n */\n async retrieveShop(profileId: string): Promise<SettingsResponse> {\n return this.request('GET', `/settings/shops/${encodeURIComponent(profileId)}`);\n }\n\n /**\n * Change one shop's own settings.\n *\n * `PATCH /settings/shops/{profileId}`\n */\n async updateShop(profileId: string, params: UpdateSettingsRequest): Promise<SettingsResponse> {\n return this.request('PATCH', `/settings/shops/${encodeURIComponent(profileId)}`, {\n body: params,\n });\n }\n}\n","import type {\n MessageLanguage,\n MessageTemplateDetail,\n MessageTemplateLanguage,\n MessageTemplateList,\n MessageTemplatePreview,\n PreviewMessageTemplateRequest,\n ResetMessageTemplateLanguageQuery,\n SendTestMessageRequest,\n SendTestMessageResponse,\n UpdateMessageTemplateLanguageRequest,\n} from '../types';\nimport type { RequestFn } from '../client';\n\n/**\n * A shop's own texts of the emails it sends its buyers: invoices, renewal\n * recovery and checkout reminders. In each language the shop's text goes\n * before the platform's, which goes before the built-in one.\n *\n * Dashboard (JWT) routes. The shop must belong to the caller's merchant; each\n * template needs the permission of its kind (invoice or payment), read to\n * list, retrieve and preview, write to change, reset and send a test. The\n * list holds only the templates the caller may read. Every change is\n * recorded in the audit log (`entity_type: 'message_template'`, `entity_id:\n * 'shop:<profile_id>:<channel>:<template_id>:<language>'`).\n */\nexport class MessageTemplates {\n constructor(private readonly request: RequestFn) {}\n\n /** `GET /message-templates/shops/{profile_id}` */\n async listShop(profileId: string): Promise<MessageTemplateList> {\n return this.request('GET', `/message-templates/shops/${encodeURIComponent(profileId)}`);\n }\n\n /** `GET /message-templates/shops/{profile_id}/{template_id}` */\n async retrieveShop(profileId: string, templateId: string): Promise<MessageTemplateDetail> {\n return this.request(\n 'GET',\n `/message-templates/shops/${encodeURIComponent(profileId)}/${encodeURIComponent(templateId)}`,\n );\n }\n\n /**\n * Store the shop's text in one language.\n *\n * `PUT /message-templates/shops/{profile_id}/{template_id}/languages/{language}`\n */\n async updateShopLanguage(\n profileId: string,\n templateId: string,\n language: MessageLanguage,\n params: UpdateMessageTemplateLanguageRequest,\n ): Promise<MessageTemplateLanguage> {\n return this.request(\n 'PUT',\n `/message-templates/shops/${encodeURIComponent(profileId)}/${encodeURIComponent(templateId)}/languages/${encodeURIComponent(language)}`,\n { body: params },\n );\n }\n\n /**\n * Remove the shop's text in one language, so the platform's or the built-in\n * text applies.\n *\n * `DELETE /message-templates/shops/{profile_id}/{template_id}/languages/{language}`\n */\n async resetShopLanguage(\n profileId: string,\n templateId: string,\n language: MessageLanguage,\n params: ResetMessageTemplateLanguageQuery = {},\n ): Promise<MessageTemplateLanguage> {\n return this.request(\n 'DELETE',\n `/message-templates/shops/${encodeURIComponent(profileId)}/${encodeURIComponent(templateId)}/languages/${encodeURIComponent(language)}`,\n { query: { expected_revision: params.expected_revision } },\n );\n }\n\n /** `POST /message-templates/shops/{profile_id}/{template_id}/preview` */\n async previewShop(\n profileId: string,\n templateId: string,\n params: PreviewMessageTemplateRequest,\n ): Promise<MessageTemplatePreview> {\n return this.request(\n 'POST',\n `/message-templates/shops/${encodeURIComponent(profileId)}/${encodeURIComponent(templateId)}/preview`,\n {\n body: params,\n },\n );\n }\n\n /**\n * Send the template to the signed-in user's own address.\n *\n * `POST /message-templates/shops/{profile_id}/{template_id}/test`\n */\n async sendShopTest(\n profileId: string,\n templateId: string,\n params: SendTestMessageRequest,\n ): Promise<SendTestMessageResponse> {\n return this.request(\n 'POST',\n `/message-templates/shops/${encodeURIComponent(profileId)}/${encodeURIComponent(templateId)}/test`,\n { body: params },\n );\n }\n}\n","import type { MerchantRisk, ShopRisk } from '../types';\nimport type { RequestExtras, RequestFn } from '../client';\n\n/**\n * Stored shop risk indexes, per connector.\n *\n * Both reads return snapshots and never score on demand, so `computed_at` is\n * the age of the answer rather than the time of the call.\n *\n * The caller's own scope is what bounds the answer, and it is enforced\n * server-side: a profile-scoped role, or an API key pinned to one shop, gets\n * that shop from both endpoints and cannot read or enumerate a sibling's.\n */\nexport class Risk {\n constructor(private readonly request: RequestFn) {}\n\n /**\n * Every shop's stored risk for the caller's merchant, with the worst band\n * across them.\n *\n * `GET /risk`\n */\n async retrieve(options?: RequestExtras): Promise<MerchantRisk> {\n return this.request('GET', '/risk', options);\n }\n\n /**\n * One shop's stored risk index per connector.\n *\n * `GET /risk/shops/{profileId}`\n */\n async retrieveShop(profileId: string, options?: RequestExtras): Promise<ShopRisk> {\n return this.request('GET', `/risk/shops/${encodeURIComponent(profileId)}`, options);\n }\n}\n","import { DelopayError, DelopayAuthenticationError } from './error';\nimport { ApiKeys } from './resources/apiKeys';\nimport { Authentication } from './resources/authentication';\nimport { Billing } from './resources/billing';\nimport { Blocklist } from './resources/blocklist';\nimport { Connectors } from './resources/connectors';\nimport { Customers } from './resources/customers';\nimport { Disputes } from './resources/disputes';\nimport { PaypalDisputes } from './resources/paypalDisputes';\nimport { WhopResolutionCases } from './resources/whopResolutionCases';\nimport { EphemeralKeys } from './resources/ephemeralKeys';\nimport { Events } from './resources/events';\nimport { Fees } from './resources/fees';\nimport { Mandates } from './resources/mandates';\nimport { MerchantAccounts } from './resources/merchantAccounts';\nimport { PaymentLinks } from './resources/paymentLinks';\nimport { PaymentMethods } from './resources/paymentMethods';\nimport { Payments } from './resources/payments';\nimport { Payouts } from './resources/payouts';\nimport { Poll } from './resources/poll';\nimport { ProfileAcquirers } from './resources/profileAcquirers';\nimport { Profiles } from './resources/profiles';\nimport { Projects } from './resources/projects';\nimport { Refunds } from './resources/refunds';\nimport { Relay } from './resources/relay';\nimport { Routing } from './resources/routing';\nimport { Search } from './resources/search';\nimport { Shops } from './resources/shops';\nimport { StripeConnect } from './resources/stripeConnect';\nimport { ThreeDsRules } from './resources/threeDsRules';\nimport { Users } from './resources/users';\nimport { Verification } from './resources/verification';\nimport { Webhooks } from './resources/webhooks';\nimport type { TokenResponse } from './types';\nimport { Analytics } from './resources/analytics';\nimport { AnalyticsDashboard } from './resources/analyticsDashboard';\nimport { Cards } from './resources/cards';\nimport { Export } from './resources/export';\nimport { FeatureMatrix } from './resources/featureMatrix';\nimport { Files } from './resources/files';\nimport { Forex } from './resources/forex';\nimport { Regions } from './resources/regions';\nimport { AvailabilityOverrides } from './resources/availabilityOverrides';\nimport { SellToRestrictions } from './resources/sellToRestrictions';\nimport { BuyerBlocklist } from './resources/buyerBlocklist';\nimport { CheckoutRecovery } from './resources/checkoutRecovery';\nimport { CostRules } from './resources/costRules';\nimport { ExternalRecords } from './resources/externalRecords';\nimport { Products } from './resources/products';\nimport { Invoices } from './resources/invoices';\nimport { InvoiceSettingsResource } from './resources/invoiceSettings';\nimport { ProcessorCosts } from './resources/processorCosts';\nimport { CheckoutMethods } from './resources/checkoutMethods';\nimport { Subscriptions } from './resources/subscriptions';\nimport { BuyerPortal } from './resources/buyerPortal';\nimport { Audit } from './resources/audit';\nimport { Settlement } from './resources/settlement';\nimport { OperationLimits } from './resources/operationLimits';\nimport { Settings } from './resources/settings';\nimport { MessageTemplates } from './resources/messageTemplates';\nimport { Risk } from './resources/risk';\n\nconst PRODUCTION_URL = 'https://api.delopay.net';\nconst SANDBOX_URL = 'https://sandbox.delopay.net';\n\nconst MAX_RAW_BODY_BYTES = 2048;\nconst MAX_RETRY_AFTER_MS = 30_000;\n\nfunction parseRetryAfter(header: string | null): number | null {\n if (!header) return null;\n const trimmed = header.trim();\n const seconds = Number(trimmed);\n if (Number.isFinite(seconds) && seconds >= 0) {\n return Math.min(seconds * 1000, MAX_RETRY_AFTER_MS);\n }\n const date = Date.parse(trimmed);\n if (Number.isFinite(date)) {\n const delta = date - Date.now();\n return delta > 0 ? Math.min(delta, MAX_RETRY_AFTER_MS) : 0;\n }\n return null;\n}\n\nfunction truncateRawBody(raw: string): string | undefined {\n if (!raw) return undefined;\n return raw.length > MAX_RAW_BODY_BYTES ? raw.slice(0, MAX_RAW_BODY_BYTES) + '…' : raw;\n}\n\nfunction findIdempotencyKey(headers: Record<string, string>): string | undefined {\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === 'idempotency-key') return v;\n }\n return undefined;\n}\n\ninterface CombinedSignal {\n signal: AbortSignal;\n dispose: () => void;\n}\n\nfunction noop(): void {\n // Intentionally empty: no listeners registered, nothing to clean up.\n}\n\n/**\n * A `onDownloadProgress` listener threw. Carried out of the transport as-is so\n * the retry logic never mistakes the caller's own failure — a `TypeError` in a\n * progress bar, say — for a network error and downloads the body again.\n */\nclass ListenerFailure {\n constructor(readonly cause: unknown) {}\n}\n\n/**\n * The body stream failed after the headers arrived: the connection dropped, or\n * the server aborted it because it could not finish the body it had started.\n * Surfaced as the transport's ordinary network error, so it is retried on\n * exactly the same terms as a failure before the first byte.\n */\nclass BodyStreamFailure {\n constructor(readonly cause: unknown) {}\n}\n\nfunction abortError(): Error {\n const error = new Error('The operation was aborted');\n error.name = 'AbortError';\n return error;\n}\n\n/** `Content-Length` as a byte count, or `null` when absent or unreadable. */\nfunction parseContentLength(header: string | null): number | null {\n if (header === null || !/^\\s*\\d+\\s*$/.test(header)) return null;\n const value = Number(header);\n return Number.isSafeInteger(value) ? value : null;\n}\n\n/**\n * One `reader.read()`, raced against the request's signal.\n *\n * A conforming `fetch` errors the body stream itself when its signal aborts,\n * but not every stream a runtime or a polyfill hands back does, and a read\n * that never settles would hold a timed-out or cancelled download open for\n * good. The race makes the abort reach the reader either way.\n */\nfunction readChunk(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n signal: AbortSignal,\n): Promise<ReadableStreamReadResult<Uint8Array>> {\n if (signal.aborted) return Promise.reject(abortError());\n return new Promise((resolve, reject) => {\n const onAbort = () => reject(abortError());\n signal.addEventListener('abort', onAbort, { once: true });\n reader.read().then(\n (result) => {\n signal.removeEventListener('abort', onAbort);\n resolve(result);\n },\n (cause: unknown) => {\n signal.removeEventListener('abort', onAbort);\n reject(signal.aborted ? abortError() : new BodyStreamFailure(cause));\n },\n );\n });\n}\n\n/** The chunks as one buffer of exactly `length` bytes. */\nfunction concatChunks(chunks: Uint8Array[], length: number): ArrayBuffer {\n const out = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out.buffer;\n}\n\n/**\n * Read a 2xx body chunk by chunk, reporting each one, and decode it as\n * `responseType` asks — the `onDownloadProgress` path of `request()`.\n *\n * `onActivity` is called when the headers arrive and on every chunk; the\n * caller uses it to restart its idle timer.\n */\nasync function receiveWithProgress(\n response: Response,\n responseType: RequestOptions['responseType'],\n listener: (event: DownloadProgressEvent) => void,\n attempt: number,\n signal: AbortSignal,\n onActivity: () => void,\n): Promise<unknown> {\n const headers = response.headers ?? new Headers();\n const total = parseContentLength(headers.get('content-length'));\n let loaded = 0;\n const notify = (chunk: Uint8Array) => {\n try {\n // A copy: the request resolves to the bytes it read, whatever a\n // listener does with the ones it was shown.\n listener({ loaded, total, chunk: chunk.slice(), headers, attempt });\n } catch (cause) {\n throw new ListenerFailure(cause);\n }\n };\n\n onActivity();\n notify(new Uint8Array(0));\n\n const body = response.body;\n if (!body || typeof body.getReader !== 'function') {\n // No readable stream: a null-body status, or a runtime whose `fetch` does\n // not expose one. The body is read whole, and reported as one chunk.\n if (responseType === 'blob') {\n const blob = await response.blob();\n const bytes = new Uint8Array(await blob.arrayBuffer());\n loaded = bytes.byteLength;\n if (loaded > 0) notify(bytes);\n return blob;\n }\n if (responseType === 'arraybuffer') {\n const buffer = await response.arrayBuffer();\n loaded = buffer.byteLength;\n if (loaded > 0) notify(new Uint8Array(buffer));\n return buffer;\n }\n const text = await response.text();\n const bytes = new TextEncoder().encode(text);\n loaded = bytes.byteLength;\n if (loaded > 0) notify(bytes);\n return text ? JSON.parse(text) : undefined;\n }\n\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n try {\n for (;;) {\n const { done, value } = await readChunk(reader, signal);\n if (done) break;\n if (!value || value.byteLength === 0) continue;\n chunks.push(value);\n loaded += value.byteLength;\n onActivity();\n notify(value);\n }\n } catch (err) {\n // Release the connection rather than leave a half-read body behind it.\n reader.cancel().catch(noop);\n throw err;\n }\n\n const bytes = concatChunks(chunks, loaded);\n if (responseType === 'blob') {\n return new Blob([bytes], { type: headers.get('content-type') ?? '' });\n }\n if (responseType === 'arraybuffer') {\n return bytes;\n }\n const text = new TextDecoder().decode(bytes);\n return text ? JSON.parse(text) : undefined;\n}\n\nfunction combineSignals(signals: AbortSignal[]): CombinedSignal {\n const controller = new AbortController();\n const listeners: { signal: AbortSignal; handler: () => void }[] = [];\n const dispose = () => {\n for (const { signal, handler } of listeners) {\n signal.removeEventListener('abort', handler);\n }\n listeners.length = 0;\n };\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n dispose();\n return { signal: controller.signal, dispose: noop };\n }\n const handler = () => {\n controller.abort(signal.reason);\n dispose();\n };\n signal.addEventListener('abort', handler, { once: true });\n listeners.push({ signal, handler });\n }\n return { signal: controller.signal, dispose };\n}\n\n/**\n * Events emitted by the debug logger.\n * - `request` — about to send a request (`method`, `url`, `path`)\n * - `response` — response received (`status`, `method`, `path`, `requestId?`)\n * - `retry` — about to retry after a transient failure (`attempt`, `maxRetries`, `method`, `path`)\n */\nexport type DelopayLogger = (\n event: 'request' | 'response' | 'retry',\n data: Record<string, unknown>,\n) => void;\n\n/**\n * Configuration options for the Delopay client.\n */\nexport interface DelopayOptions {\n /** Use the sandbox environment (`https://sandbox.delopay.net`). Defaults to `false` (production). */\n sandbox?: boolean;\n /** Override the base URL entirely. Takes precedence over `sandbox`. */\n baseUrl?: string;\n /** Request timeout in milliseconds. Defaults to `30000` (30 seconds). */\n timeout?: number;\n /**\n * Maximum number of automatic retries for transient failures (5xx, timeout, network errors).\n * Retries use exponential backoff. Set to `0` to disable. Defaults to `2`.\n * Only idempotent-safe requests (GET, DELETE, and requests with an `Idempotency-Key` header) are retried.\n */\n maxRetries?: number;\n /** Enable debug logging of requests and responses. Defaults to `false`. */\n debug?: boolean;\n /**\n * Custom logger for debug events (`request`, `response`, `retry`). When omitted,\n * debug output is written to `console.log`. Has no effect unless `debug` is `true`.\n * Useful for routing SDK logs through pino, winston, or similar structured loggers.\n */\n logger?: DelopayLogger;\n}\n\nconst SENSITIVE_QUERY_KEYS = new Set([\n 'client_secret',\n 'ephemeral_key',\n 'api_key',\n 'publishable_key',\n]);\n\n/**\n * Return a copy of `url` with the values of known-sensitive query parameters\n * replaced by `REDACTED`, leaving the rest of the query string intact.\n * Used only to sanitize URLs before they hit debug logs.\n */\nfunction redactUrlForLogging(url: string): string {\n const qIdx = url.indexOf('?');\n if (qIdx === -1) return url;\n const base = url.slice(0, qIdx);\n const query = url.slice(qIdx + 1);\n const parts = query.split('&').map((pair) => {\n const eqIdx = pair.indexOf('=');\n if (eqIdx === -1) return pair;\n const key = pair.slice(0, eqIdx);\n if (SENSITIVE_QUERY_KEYS.has(decodeURIComponent(key).toLowerCase())) {\n return `${key}=REDACTED`;\n }\n return pair;\n });\n return `${base}?${parts.join('&')}`;\n}\n\n/**\n * One step of a response body's download, reported to\n * {@link RequestOptions.onDownloadProgress}.\n */\nexport interface DownloadProgressEvent {\n /** Body bytes received so far on this attempt, `chunk` included. */\n loaded: number;\n /**\n * `Content-Length`, when the response carried one — a buffered body such as\n * a PDF. `null` for a streamed (chunked) body, whose size is not known\n * until it ends. With a compressed transfer it is the compressed size, so\n * `loaded` can pass it.\n */\n total: number | null;\n /**\n * The bytes this event reports. Empty on the first event of an attempt,\n * which fires as soon as the headers arrive, before any of the body.\n * A copy: changing it cannot change the value the request resolves to.\n */\n chunk: Uint8Array;\n /** The response headers, available from the first event on. */\n headers: Headers;\n /**\n * Which attempt this is, from `0`. A retried request reports its body\n * again from the start under the next number, so a listener that\n * accumulates state resets it when this changes.\n */\n attempt: number;\n}\n\n/**\n * Low-level options forwarded to a single HTTP request.\n */\nexport interface RequestOptions {\n /** Request body, serialised as JSON. */\n body?: unknown;\n /**\n * @internal Resource assertion that this operation deduplicates by the JSON\n * body's idempotency_key. Null means that optional key is absent, so the write\n * must not be retried. The transport checks the assertion against the body;\n * it does not send this option or copy a JSON key into an HTTP header.\n */\n bodyIdempotencyKey?: string | null;\n /**\n * Query-string parameters. `undefined` and `null` values are omitted.\n * Array values are emitted as repeated keys (`?tag=a&tag=b`) — not comma-joined.\n */\n query?: Record<\n string,\n string | number | boolean | null | undefined | (string | number | boolean)[]\n >;\n /** Additional HTTP headers merged with the default `api-key` header. */\n headers?: Record<string, string>;\n /**\n * Override the client-level timeout for this request, in milliseconds.\n *\n * Covers the whole request, body included — unless `onDownloadProgress` is\n * set, in which case it is an **idle** timeout: it restarts when the\n * headers arrive and on every chunk of the body, so a long download that\n * keeps making progress is never cut off, and one that stalls still is.\n */\n timeout?: number;\n /**\n * Caller-provided `AbortSignal`. Aborting it cancels the in-flight request and rejects\n * with a `DelopayError` carrying code `'ABORTED'`. Combined with the per-request timeout.\n */\n signal?: AbortSignal;\n /**\n * How to decode a 2xx response body. `'json'` (the default) parses JSON;\n * `'blob'` / `'arraybuffer'` return the raw bytes for binary endpoints\n * such as PDF exports. Error responses are always decoded as JSON and\n * thrown as `DelopayError` regardless of this setting.\n */\n responseType?: 'json' | 'blob' | 'arraybuffer';\n /**\n * Pass `keepalive: true` to let the request outlive its page — e.g.\n * telemetry sent while the document is navigating away. Browsers cap\n * keepalive request bodies at ~64 KiB and reject larger ones.\n */\n keepalive?: boolean;\n /**\n * Report a 2xx response body as it downloads. Called once as soon as the\n * headers arrive (with an empty `chunk` and `loaded: 0`), then once per\n * chunk of the body; the value the request resolves to is decoded from\n * those same bytes, per `responseType`. Error responses are not reported.\n *\n * Setting it turns `timeout` into an idle timeout (see there). A body that\n * fails part-way rejects with the ordinary `NETWORK` error and is retried\n * on the usual terms, starting again under the next `attempt`. A listener\n * that throws rejects the request with that error, unretried.\n */\n onDownloadProgress?: (event: DownloadProgressEvent) => void;\n}\n\nexport type RequestFn = <T>(method: string, path: string, options?: RequestOptions) => Promise<T>;\n\n/**\n * Per-call options that resource methods accept as an optional final argument:\n * extra HTTP headers (e.g. `Idempotency-Key`), a per-request timeout override,\n * an `AbortSignal` for cancellation, and a download-progress listener — the\n * last is what a file download (a statement PDF, a report CSV) reports its\n * bytes through.\n */\nexport type RequestExtras = Pick<\n RequestOptions,\n 'headers' | 'timeout' | 'signal' | 'onDownloadProgress'\n>;\n\n/**\n * Delopay API client.\n *\n * Instantiate once with your API key and reuse across your application.\n * All resource sub-clients (payments, refunds, customers, …) are exposed\n * as properties on the instance.\n *\n * @example\n * ```typescript\n * const delopay = new Delopay('prd_...', { sandbox: false });\n * const payment = await delopay.payments.create({ amount: 5000, currency: 'EUR' });\n * ```\n */\nexport class Delopay {\n /** Utility for verifying incoming webhook signatures (static, no instance needed). */\n static webhooks = Webhooks;\n\n /** The resolved base URL used for all API requests. */\n readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly debug: boolean;\n private readonly logger?: DelopayLogger;\n private jwtToken?: string;\n\n // Merchant-facing\n readonly payments: Payments;\n readonly refunds: Refunds;\n readonly customers: Customers;\n readonly paymentMethods: PaymentMethods;\n readonly paymentLinks: PaymentLinks;\n readonly mandates: Mandates;\n readonly disputes: Disputes;\n readonly paypalDisputes: PaypalDisputes;\n readonly whopResolutionCases: WhopResolutionCases;\n readonly payouts: Payouts;\n readonly ephemeralKeys: EphemeralKeys;\n readonly events: Events;\n readonly poll: Poll;\n\n // Connector / routing\n readonly connectors: Connectors;\n readonly routing: Routing;\n readonly profiles: Profiles;\n readonly shops: Shops;\n readonly profileAcquirers: ProfileAcquirers;\n\n // Authentication & verification\n readonly authentication: Authentication;\n readonly verification: Verification;\n\n // Dashboard / internal\n readonly users: Users;\n readonly apiKeys: ApiKeys;\n readonly billing: Billing;\n readonly blocklist: Blocklist;\n readonly fees: Fees;\n readonly merchantAccounts: MerchantAccounts;\n readonly projects: Projects;\n readonly relay: Relay;\n readonly stripeConnect: StripeConnect;\n readonly threeDsRules: ThreeDsRules;\n /**\n * A merchant's own audit log. Needs a dashboard JWT, not an API key —\n * see {@link Audit}.\n */\n readonly audit: Audit;\n readonly settlement: Settlement;\n readonly operationLimits: OperationLimits;\n /** Every setting of the merchant, its projects and its shops, audited per change. */\n readonly settings: Settings;\n /** A shop's own texts of the emails it sends its buyers. */\n readonly messageTemplates: MessageTemplates;\n readonly risk: Risk;\n\n // New resources (Phases 3-4)\n readonly subscriptions: Subscriptions;\n /** Buyer portal grant access. Construct a separate client with the portal token. */\n readonly buyerPortal: BuyerPortal;\n readonly files: Files;\n readonly export: Export;\n readonly forex: Forex;\n readonly regions: Regions;\n readonly availabilityOverrides: AvailabilityOverrides;\n readonly sellToRestrictions: SellToRestrictions;\n /** Buyers the merchant refuses to sell to again, by email, IP or customer id. */\n readonly buyerBlocklist: BuyerBlocklist;\n readonly checkoutRecovery: CheckoutRecovery;\n readonly costRules: CostRules;\n\n /** Out-of-band transitions a PSP made that DeloPay never observed. */\n readonly externalRecords: ExternalRecords;\n\n /** A shop's product catalogue: what it sells, and at which prices. */\n readonly products: Products;\n /** The invoices and credit notes the merchant issues to its buyers. */\n readonly invoices: Invoices;\n /** How those invoices look and are taxed: the merchant default and each shop's override. */\n readonly invoiceSettings: InvoiceSettingsResource;\n /** What the merchant's own processor charges it — see {@link ProcessorCosts}. */\n readonly processorCosts: ProcessorCosts;\n readonly checkoutMethods: CheckoutMethods;\n readonly analytics: Analytics;\n readonly analyticsDashboard: AnalyticsDashboard;\n readonly featureMatrix: FeatureMatrix;\n readonly cards: Cards;\n readonly search: Search;\n\n /**\n * Create a new Delopay client.\n *\n * @param apiKey - Your Delopay API key (e.g. `prd_...` or `snd_...`).\n * Pass an empty string or omit for JWT-only usage (e.g. dashboard apps).\n * @param options - Optional configuration (sandbox mode, base URL override, timeout).\n */\n constructor(apiKey?: string, options?: DelopayOptions) {\n this.apiKey = apiKey ?? '';\n this.timeout = options?.timeout ?? 30_000;\n this.maxRetries = options?.maxRetries ?? 2;\n this.debug = options?.debug ?? false;\n if (options?.logger !== undefined) this.logger = options.logger;\n\n if (options?.baseUrl !== undefined) {\n this.baseUrl = options.baseUrl;\n } else if (options?.sandbox) {\n this.baseUrl = SANDBOX_URL;\n } else {\n this.baseUrl = PRODUCTION_URL;\n }\n\n const request = this.request.bind(this) as RequestFn;\n\n // JWT auth methods are defined below (setJwtToken / clearJwtToken)\n\n // Merchant-facing\n this.payments = new Payments(request);\n this.refunds = new Refunds(request);\n this.customers = new Customers(request);\n this.paymentMethods = new PaymentMethods(request);\n this.paymentLinks = new PaymentLinks(request);\n this.mandates = new Mandates(request);\n this.disputes = new Disputes(request);\n this.paypalDisputes = new PaypalDisputes(request);\n this.whopResolutionCases = new WhopResolutionCases(request);\n this.payouts = new Payouts(request);\n this.ephemeralKeys = new EphemeralKeys(request);\n this.events = new Events(request);\n this.poll = new Poll(request);\n\n // Connector / routing\n this.connectors = new Connectors(request);\n this.routing = new Routing(request);\n this.profiles = new Profiles(request);\n this.shops = new Shops(request);\n this.profileAcquirers = new ProfileAcquirers(request);\n\n // Authentication & verification\n this.authentication = new Authentication(request);\n this.verification = new Verification(request);\n\n // Dashboard / internal\n this.users = new Users(request);\n this.apiKeys = new ApiKeys(request);\n this.billing = new Billing(request);\n this.blocklist = new Blocklist(request);\n this.fees = new Fees(request);\n this.merchantAccounts = new MerchantAccounts(request);\n this.projects = new Projects(request);\n this.relay = new Relay(request);\n this.stripeConnect = new StripeConnect(request);\n this.threeDsRules = new ThreeDsRules(request);\n this.audit = new Audit(request);\n this.settlement = new Settlement(request);\n this.operationLimits = new OperationLimits(request);\n this.settings = new Settings(request);\n this.messageTemplates = new MessageTemplates(request);\n this.risk = new Risk(request);\n\n // New resources (Phases 3-4)\n this.subscriptions = new Subscriptions(request);\n this.buyerPortal = new BuyerPortal(request);\n this.files = new Files(request);\n this.export = new Export(request);\n this.forex = new Forex(request);\n this.regions = new Regions(request);\n this.availabilityOverrides = new AvailabilityOverrides(request);\n this.sellToRestrictions = new SellToRestrictions(request);\n this.buyerBlocklist = new BuyerBlocklist(request);\n this.checkoutRecovery = new CheckoutRecovery(request);\n this.costRules = new CostRules(request);\n this.externalRecords = new ExternalRecords(request);\n this.products = new Products(request);\n this.invoices = new Invoices(request);\n this.invoiceSettings = new InvoiceSettingsResource(request);\n this.processorCosts = new ProcessorCosts(request);\n this.checkoutMethods = new CheckoutMethods(request);\n this.analytics = new Analytics(request);\n this.analyticsDashboard = new AnalyticsDashboard(request);\n this.featureMatrix = new FeatureMatrix(request);\n this.cards = new Cards(request);\n this.search = new Search(request);\n }\n\n /**\n * Set a JWT token for subsequent requests.\n * When set, requests use `Authorization: Bearer <token>` instead of `api-key`.\n * Useful after `users.signIn()` returns a JWT for dashboard operations.\n */\n setJwtToken(token: string): void {\n this.jwtToken = token;\n }\n\n /**\n * Clear the JWT token, reverting to API key authentication.\n */\n clearJwtToken(): void {\n this.jwtToken = undefined;\n }\n\n /**\n * Refresh the current login JWT (see {@link Users.refreshToken}) and\n * apply the fresh token to this client, so subsequent requests use it.\n * Returns the fresh token for the caller to persist (e.g. session\n * storage) — the backend has already re-set the `login_token` cookie.\n *\n * If the client's auth state changes while the refresh is pending —\n * `clearJwtToken()` on sign-out, or `setJwtToken()` switching to another\n * session — the stale completion is discarded and this rejects with a\n * `session_changed` `DelopayError` (status 0), so the explicit change\n * wins and the caller never persists a token for a session that is gone.\n *\n * Otherwise throws like any other request; in particular a 401 means the\n * session is dead (expired/blacklisted/revoked), a 429 means a refresh\n * was already minted for this session within the last minute, and a 400\n * means this token has no revocable session to slide (no `jti` — team\n * impersonation is the case in practice) and can never be refreshed,\n * though it stays valid for ordinary calls.\n */\n async refreshSession(): Promise<TokenResponse> {\n const originatingToken = this.jwtToken;\n const response = await this.users.refreshToken();\n if (this.jwtToken !== originatingToken) {\n throw new DelopayError(\n 'Auth state changed while the refresh was pending; refreshed token discarded',\n {\n status: 0,\n code: 'session_changed',\n type: 'session_changed',\n },\n );\n }\n this.setJwtToken(response.token);\n return response;\n }\n\n /**\n * Make a raw HTTP request to the Delopay API.\n *\n * You rarely need to call this directly — prefer the typed resource methods.\n * Use it only for endpoints not yet covered by a resource class.\n *\n * @param method - HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).\n * @param path - API path starting with `/` (e.g. `/payments`).\n * @param options - Optional body, query parameters, and headers.\n * @returns Parsed JSON response body typed as `T`.\n * @throws {DelopayAuthenticationError} On 401 responses.\n * @throws {DelopayError} On all other non-2xx responses, timeouts, and network errors.\n */\n async request<T>(method: string, path: string, options?: RequestOptions): Promise<T> {\n let url = `${this.baseUrl}${path}`;\n\n if (options?.query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(options.query)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n if (v !== undefined && v !== null) params.append(key, String(v));\n }\n } else {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) {\n url += `?${qs}`;\n }\n }\n\n let headers: Record<string, string> = {\n ...(this.jwtToken\n ? { Authorization: `Bearer ${this.jwtToken}` }\n : this.apiKey\n ? { 'api-key': this.apiKey }\n : {}),\n ...options?.headers,\n };\n\n // FormData / Blob / ArrayBuffer / URLSearchParams pass through unchanged so callers\n // can send multipart uploads. The runtime (browser or Node 18+ fetch) sets the\n // appropriate Content-Type including the multipart boundary, so we don't touch it.\n const isRawBody =\n options?.body !== undefined &&\n options?.body !== null &&\n (options.body instanceof FormData ||\n options.body instanceof Blob ||\n options.body instanceof ArrayBuffer ||\n options.body instanceof URLSearchParams);\n\n if (options?.body && !isRawBody) {\n headers['Content-Type'] = 'application/json';\n }\n\n // Serialize body once so circular-reference errors surface immediately and big payloads\n // aren't re-stringified on every retry attempt. Raw bodies pass through untouched.\n let serializedBody: BodyInit | undefined;\n if (isRawBody) {\n serializedBody = options?.body as BodyInit;\n } else if (options?.body) {\n serializedBody = JSON.stringify(options.body);\n }\n\n let idempotencyKey = findIdempotencyKey(headers)?.trim();\n if (options && Object.prototype.hasOwnProperty.call(options, 'bodyIdempotencyKey')) {\n const bodyKey = options?.bodyIdempotencyKey;\n const serialized: unknown =\n !isRawBody && typeof serializedBody === 'string' ? JSON.parse(serializedBody) : null;\n const actualKey =\n serialized && typeof serialized === 'object' && !Array.isArray(serialized)\n ? ((serialized as Record<string, unknown>).idempotency_key ?? null)\n : null;\n const suppliedHeaders = Object.keys(headers).filter(\n (name) => name.toLowerCase() === 'idempotency-key',\n );\n if (\n (bodyKey !== null && typeof bodyKey !== 'string') ||\n actualKey !== bodyKey ||\n suppliedHeaders.some(\n (name) => headers[name] !== bodyKey || headers[name]?.trim() !== headers[name],\n )\n ) {\n throw new DelopayError('Request retry keys must match the JSON body key', {\n status: 0,\n code: 'IDEMPOTENCY_KEY_MISMATCH',\n type: 'invalid_request',\n });\n }\n idempotencyKey = bodyKey?.trim();\n // Collapse differently cased copies so fetch cannot combine them into a\n // different header value. Other caller headers remain untouched.\n if (suppliedHeaders.length > 0) {\n headers = {\n ...Object.fromEntries(\n Object.entries(headers).filter(([name]) => name.toLowerCase() !== 'idempotency-key'),\n ),\n 'Idempotency-Key': idempotencyKey ?? '',\n };\n }\n }\n const isRetryable =\n method === 'GET' ||\n method === 'DELETE' ||\n (idempotencyKey !== undefined && idempotencyKey !== '');\n\n const callerSignal = options?.signal;\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n\n const timeoutMs = options?.timeout ?? this.timeout;\n\n let lastError: unknown;\n let retryAfterOverrideMs: number | null = null;\n\n const safeUrl = () => redactUrlForLogging(url);\n const emit = (event: 'request' | 'response' | 'retry', data: Record<string, unknown>) => {\n if (!this.debug) return;\n if (this.logger) {\n this.logger(event, data);\n return;\n }\n if (event === 'request')\n console.log(`[delopay] ${data.method as string} ${data.url as string}`);\n else if (event === 'response')\n console.log(\n `[delopay] ${data.status as number} ${data.method as string} ${data.path as string}`,\n );\n else\n console.log(\n `[delopay] retry ${data.attempt as number}/${data.maxRetries as number} ${data.method as string} ${data.path as string}`,\n );\n };\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const base = Math.min(500 * 2 ** (attempt - 1), 5000);\n // Full jitter: pick uniformly in [0, base) to avoid synchronized retry storms.\n const jittered = Math.random() * base;\n const delay = Math.max(retryAfterOverrideMs ?? 0, jittered);\n retryAfterOverrideMs = null;\n await new Promise((resolve) => setTimeout(resolve, delay));\n emit('retry', { attempt, maxRetries: this.maxRetries, method, path });\n }\n\n const timeoutCtrl = new AbortController();\n let timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);\n // With a progress listener the timeout measures silence, not the whole\n // download: each sign of life restarts it.\n const restartIdleTimer = () => {\n if (timeoutCtrl.signal.aborted) return;\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);\n };\n const combined = combineSignals(\n callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal],\n );\n\n try {\n emit('request', { method, url: safeUrl(), path });\n\n const response = await fetch(url, {\n method,\n headers,\n body: serializedBody,\n signal: combined.signal,\n ...(options?.keepalive !== undefined ? { keepalive: options.keepalive } : {}),\n });\n\n const requestId =\n response.headers?.get('x-request-id') ?? response.headers?.get('x-trace-id') ?? undefined;\n\n emit('response', { status: response.status, method, path, requestId });\n\n if (!response.ok) {\n const rawBody = await response.text().catch(() => '');\n let parsed: Record<string, unknown> = {};\n if (rawBody) {\n try {\n parsed = JSON.parse(rawBody) as Record<string, unknown>;\n } catch {\n // non-JSON error body (HTML from a proxy, truncated stream, etc.) — keep raw\n }\n }\n // API wraps errors as { error: { message, code, type, data? } } — unwrap if present\n const err = (parsed.error as Record<string, unknown>) ?? parsed;\n const message =\n (err.message as string) ?? `Request failed with status ${response.status}`;\n const code = (err.code as string) ?? '';\n const type = (err.error_type as string) ?? (err.type as string) ?? '';\n const data =\n err.data && typeof err.data === 'object' && !Array.isArray(err.data)\n ? (err.data as Record<string, unknown>)\n : undefined;\n const truncatedRaw = truncateRawBody(rawBody);\n\n // A 401 usually means OUR credential (API key / JWT) was rejected —\n // but connector-passthrough errors (`CE_*` / type \"connector\", e.g.\n // a PSP rejecting the merchant's stored Stripe key) propagate the\n // upstream status and are NOT a Delopay authentication failure, so\n // they stay a plain DelopayError instead of triggering the\n // \"re-authenticate\" handling dashboards attach to auth errors.\n const isConnectorPassthrough = type === 'connector' || code.startsWith('CE_');\n if (response.status === 401 && !isConnectorPassthrough) {\n throw new DelopayAuthenticationError(message, {\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n }\n\n const error = new DelopayError(message, {\n status: response.status,\n code,\n type,\n requestId,\n rawBody: truncatedRaw,\n data,\n });\n\n // Retry on 5xx and 429 (rate limit). 4xx other than 429 are not transient.\n const isTransientStatus = response.status >= 500 || response.status === 429;\n if (isTransientStatus && isRetryable && attempt < this.maxRetries) {\n if (response.status === 429) {\n retryAfterOverrideMs = parseRetryAfter(response.headers?.get('retry-after') ?? null);\n }\n lastError = error;\n continue;\n }\n\n throw error;\n }\n\n if (options?.onDownloadProgress) {\n return (await receiveWithProgress(\n response,\n options.responseType,\n options.onDownloadProgress,\n attempt,\n combined.signal,\n restartIdleTimer,\n )) as T;\n }\n if (options?.responseType === 'blob') {\n return (await response.blob()) as T;\n }\n if (options?.responseType === 'arraybuffer') {\n return (await response.arrayBuffer()) as T;\n }\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n } catch (err) {\n if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {\n throw err;\n }\n if (err instanceof ListenerFailure) {\n throw err.cause;\n }\n if (err instanceof BodyStreamFailure) {\n const cause = err.cause;\n const detail =\n cause instanceof Error ? cause.message : String(cause ?? 'body stream failed');\n lastError = new DelopayError(`Network error: ${detail}`, {\n status: 0,\n code: 'NETWORK',\n type: 'network_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n if (err instanceof Error && err.name === 'AbortError') {\n if (callerSignal?.aborted) {\n throw new DelopayError('Request aborted', {\n status: 0,\n code: 'ABORTED',\n type: 'abort_error',\n });\n }\n lastError = new DelopayError('Request timed out', {\n status: 0,\n code: 'TIMEOUT',\n type: 'timeout_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n if (err instanceof TypeError) {\n lastError = new DelopayError(`Network error: ${err.message}`, {\n status: 0,\n code: 'NETWORK',\n type: 'network_error',\n });\n if (isRetryable && attempt < this.maxRetries) continue;\n throw lastError;\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n combined.dispose();\n }\n }\n\n throw lastError;\n }\n\n /**\n * Auto-paginate a list endpoint. Yields items one by one, fetching\n * the next page automatically when the current one is exhausted.\n *\n * Delopay list endpoints use one of two pagination styles, so this helper\n * supports both:\n * - **Offset** (default) — for endpoints like `customers.list` that accept\n * `offset`/`limit`. Each page advances `offset` by the number of items returned.\n * - **Cursor** — for endpoints like `payments.list` and `payouts.list` that page\n * with `starting_after`/`limit` (they ignore `offset`). Pass a `cursor` extractor\n * that returns the id of an item; the next page is requested with\n * `starting_after` set to the last item's id.\n *\n * @param listFn - A function that takes the paging params and returns `{ data: T[] }` or `T[]`.\n * @param params - Additional parameters to pass to every page request.\n * @param options - Page size (number) for offset mode, or `{ pageSize?, cursor? }`.\n * Provide `cursor` to switch to cursor pagination.\n *\n * @example\n * ```typescript\n * // Offset endpoint (customers):\n * for await (const c of delopay.paginate((p) => delopay.customers.list(p))) {\n * console.log(c.customer_id);\n * }\n *\n * // Cursor endpoint (payments): extract the id used as the next cursor.\n * for await (const payment of delopay.paginate(\n * (p) => delopay.payments.list(p),\n * undefined,\n * { cursor: (p) => p.payment_id },\n * )) {\n * console.log(payment.payment_id);\n * }\n * ```\n */\n async *paginate<T, P extends Record<string, unknown>>(\n listFn: (\n params: P & { limit: number; offset?: number; starting_after?: string },\n ) => Promise<{ data: T[] } | T[]>,\n params?: P,\n options?: number | { pageSize?: number; cursor?: (item: T) => string | undefined },\n ): AsyncGenerator<T> {\n const pageSize = typeof options === 'number' ? options : (options?.pageSize ?? 50);\n const cursorOf = typeof options === 'object' ? options.cursor : undefined;\n let offset = 0;\n let after: string | undefined;\n while (true) {\n const page = { ...((params ?? {}) as P), limit: pageSize } as P & {\n limit: number;\n offset?: number;\n starting_after?: string;\n };\n if (cursorOf) {\n if (after !== undefined) page.starting_after = after;\n } else {\n page.offset = offset;\n }\n const result = await listFn(page);\n const items = Array.isArray(result) ? result : result.data;\n if (items.length === 0) break;\n for (const item of items) {\n yield item;\n }\n if (items.length < pageSize) break;\n if (cursorOf) {\n const last = items[items.length - 1];\n if (last === undefined) break;\n after = cursorOf(last);\n if (after === undefined) break;\n } else {\n offset += items.length;\n }\n }\n }\n}\n","import type {\n Connector,\n Currency,\n EuclidComparison,\n EuclidComparisonType,\n EuclidIfStatement,\n EuclidValue,\n PaymentMethod,\n PlatformFeeKind,\n PlatformFeeOutput,\n PlatformFeeProgram,\n PlatformFeeRule,\n} from './types';\n\n/** A single condition leaf in the builder's condition tree. */\nexport interface LeafNode {\n kind: 'leaf';\n lhs: string;\n comparison: EuclidComparisonType;\n value: EuclidValue;\n}\n\n/** An AND (`all`) or OR (`any`) group of condition nodes. */\nexport interface GroupNode {\n kind: 'all' | 'any';\n children: ConditionNode[];\n}\n\nexport type ConditionNode = LeafNode | GroupNode;\n\n/**\n * A condition leaf. Numeric values (amount, merchant_volume) tag as `number`;\n * string values (payment_method, connector, currency, card_network) tag as\n * `enum_variant`.\n */\nexport function leaf(\n lhs: string,\n comparison: EuclidComparisonType,\n value: string | number,\n): LeafNode {\n const tagged: EuclidValue =\n typeof value === 'number' ? { type: 'number', value } : { type: 'enum_variant', value };\n return { kind: 'leaf', lhs, comparison, value: tagged };\n}\n\n/** AND group — all children must match. */\nexport function allOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'all', children };\n}\n\n/** OR group — any child matching is enough. */\nexport function anyOf(...children: ConditionNode[]): GroupNode {\n return { kind: 'any', children };\n}\n\n/**\n * How a rule (or the default) prices a transaction. `fee_type` is inferred:\n * percentage-only → `percentage`, flat-only → `flat`, both → `combined`.\n */\nexport interface FeeSpecInput {\n /** Percentage fee, e.g. `2.5` means 2.5%. */\n percentage?: number;\n /** Flat fee in minor units. */\n flat?: number;\n /** ISO 4217 currency for the flat fee. */\n flatCurrency?: string;\n /** Clamp floor in minor units. */\n min?: number;\n /** Clamp ceiling in minor units. */\n max?: number;\n}\n\n/**\n * Friendly conditions for a rule. Every provided key becomes one condition and\n * they are ANDed together. For dimensions not covered here (payment-method-type\n * keys like `crypto`/`wallet`, metadata, value arrays) use `rawConditions`.\n */\nexport interface FeeRuleConditions {\n paymentMethod?: PaymentMethod;\n connector?: Connector;\n currency?: Currency;\n cardNetwork?: string;\n /**\n * Customer billing-address country. Must be the exact backend `Country` enum\n * variant (PascalCase full name, e.g. `Germany`/`UnitedStatesOfAmerica`), not\n * an ISO code — the engine lowers `billing_country` via case-sensitive\n * `from_str`.\n */\n billingCountry?: string;\n /** `amount == n` (minor units). */\n amountEquals?: number;\n /** `amount > n` (minor units). */\n amountGreaterThan?: number;\n /** `amount < n` (minor units). */\n amountLessThan?: number;\n /**\n * `merchant_volume == n` — the merchant's previous-month volume snapshot\n * (USD minor units). Combine with any other condition, e.g.\n * `{ paymentMethod: 'crypto', merchantVolumeGreaterThan: 1_000_000 }`.\n */\n merchantVolumeEquals?: number;\n /** `merchant_volume > n` (USD minor units). */\n merchantVolumeGreaterThan?: number;\n /** `merchant_volume < n` (USD minor units). */\n merchantVolumeLessThan?: number;\n}\n\nexport interface FeeRuleInput {\n name: string;\n /** Friendly conditions (ANDed). Omit for an always-matching rule (prefer `otherwise`). */\n when?: FeeRuleConditions;\n /** Extra raw conditions ANDed in, for dimensions `when` does not cover. */\n rawConditions?: EuclidComparison[];\n /** Nested AND/OR condition tree. Mutually exclusive with `when`/`rawConditions`. */\n match?: ConditionNode;\n fee: FeeSpecInput;\n}\n\nfunction toFeeOutput(spec: FeeSpecInput): PlatformFeeOutput {\n const hasPct = spec.percentage != null;\n const hasFlat = spec.flat != null;\n const feeType: PlatformFeeKind = hasPct && hasFlat ? 'combined' : hasFlat ? 'flat' : 'percentage';\n return {\n fee_type: feeType,\n percentage_fee: spec.percentage ?? null,\n flat_fee_amount: spec.flat ?? null,\n flat_fee_currency: spec.flatCurrency ?? null,\n min_fee_amount: spec.min ?? null,\n max_fee_amount: spec.max ?? null,\n };\n}\n\nfunction enumCondition(lhs: string, value: string): EuclidComparison {\n return { lhs, comparison: 'equal', value: { type: 'enum_variant', value }, metadata: {} };\n}\n\nfunction numberCondition(\n lhs: string,\n comparison: EuclidComparisonType,\n value: number,\n): EuclidComparison {\n return { lhs, comparison, value: { type: 'number', value }, metadata: {} };\n}\n\nfunction buildConditions(\n when: FeeRuleConditions = {},\n raw: EuclidComparison[] = [],\n): EuclidComparison[] {\n const out: EuclidComparison[] = [];\n if (when.paymentMethod != null) out.push(enumCondition('payment_method', when.paymentMethod));\n if (when.connector != null) out.push(enumCondition('connector', when.connector));\n if (when.currency != null) out.push(enumCondition('currency', when.currency));\n if (when.cardNetwork != null) out.push(enumCondition('card_network', when.cardNetwork));\n if (when.billingCountry != null) out.push(enumCondition('billing_country', when.billingCountry));\n if (when.amountEquals != null) out.push(numberCondition('amount', 'equal', when.amountEquals));\n if (when.amountGreaterThan != null) {\n out.push(numberCondition('amount', 'greater_than', when.amountGreaterThan));\n }\n if (when.amountLessThan != null) {\n out.push(numberCondition('amount', 'less_than', when.amountLessThan));\n }\n if (when.merchantVolumeEquals != null) {\n out.push(numberCondition('merchant_volume', 'equal', when.merchantVolumeEquals));\n }\n if (when.merchantVolumeGreaterThan != null) {\n out.push(numberCondition('merchant_volume', 'greater_than', when.merchantVolumeGreaterThan));\n }\n if (when.merchantVolumeLessThan != null) {\n out.push(numberCondition('merchant_volume', 'less_than', when.merchantVolumeLessThan));\n }\n out.push(...raw);\n return out;\n}\n\nfunction leafToComparison(node: LeafNode): EuclidComparison {\n return { lhs: node.lhs, comparison: node.comparison, value: node.value, metadata: {} };\n}\n\n/**\n * Flatten associativity (nested all-in-all / any-in-any) and collapse\n * single-child groups, so every group child of an `all` is an `any`.\n * @internal\n */\nexport function normalizeNode(node: ConditionNode): ConditionNode {\n if (node.kind === 'leaf') return node;\n const children = node.children.map(normalizeNode);\n const flat: ConditionNode[] = [];\n for (const c of children) {\n if (c.kind === node.kind) flat.push(...c.children);\n else flat.push(c);\n }\n if (flat.length === 1) return flat[0];\n return { kind: node.kind, children: flat };\n}\n\nfunction toStatement(node: ConditionNode): EuclidIfStatement {\n if (node.kind === 'leaf') return { condition: [leafToComparison(node)], nested: null };\n // Unreachable via current callers (encodeStatements strips top-level any); kept for totality.\n if (node.kind === 'any') {\n return { condition: [], nested: node.children.map(toStatement) };\n }\n // 'all': after normalize, group children are all 'any'.\n const leaves = node.children.filter((c): c is LeafNode => c.kind === 'leaf');\n const groups = node.children.filter((c): c is GroupNode => c.kind !== 'leaf');\n const condition = leaves.map(leafToComparison);\n if (groups.length === 0) return { condition, nested: null };\n const [first, ...rest] = groups;\n // `first` is an OR; AND each of its branches with the remaining OR groups.\n const nested = first.children.map((branch) => toStatement(normalizeNode(allOf(branch, ...rest))));\n return { condition, nested };\n}\n\nfunction assertNoEmptyAnyOf(node: ConditionNode): void {\n if (node.kind === 'leaf') return;\n if (node.kind === 'any' && node.children.length === 0) {\n throw new Error('feeProgram: an anyOf() group must have at least one condition');\n }\n node.children.forEach(assertNoEmptyAnyOf);\n}\n\n/**\n * Encode a rule's match (a condition tree) into the engine's `statements[]`.\n * A top-level OR spreads across statements; anything else is a single statement.\n * @internal\n */\nexport function encodeStatements(match: ConditionNode): EuclidIfStatement[] {\n const m = normalizeNode(match);\n if (m.kind === 'any') return m.children.map(toStatement);\n return [toStatement(m)];\n}\n\nfunction comparisonToLeaf(c: EuclidComparison): LeafNode {\n return { kind: 'leaf', lhs: c.lhs, comparison: c.comparison, value: c.value };\n}\n\nfunction statementToNode(stmt: EuclidIfStatement): ConditionNode {\n const leaves = stmt.condition.map(comparisonToLeaf);\n if (stmt.nested && stmt.nested.length > 0) {\n const orNode = anyOf(...stmt.nested.map(statementToNode));\n if (leaves.length === 0) return orNode;\n return allOf(...leaves, orNode);\n }\n return leaves.length === 1 ? leaves[0] : allOf(...leaves);\n}\n\n/**\n * Decode a rule's `statements[]` back into a condition tree.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function ruleMatchToTree(statements: EuclidIfStatement[]): ConditionNode {\n if (statements.length === 1) return normalizeNode(statementToNode(statements[0]));\n return normalizeNode(anyOf(...statements.map(statementToNode)));\n}\n\n/**\n * Decode a stored program into the builder's editable model.\n *\n * Returns a tree that is **logically equivalent** to the source. It is\n * deep-equal to `normalizeNode(input)` only when no `all` group contains two\n * or more `any` groups; where the encoder distributed AND over OR, the decoded\n * shape differs (still equivalent).\n */\nexport function programToTree(program: PlatformFeeProgram): {\n rules: { name: string; match: ConditionNode; fee: PlatformFeeOutput | null }[];\n otherwise: PlatformFeeOutput | null;\n} {\n return {\n rules: program.rules.map((r) => ({\n name: r.name,\n match: ruleMatchToTree(r.statements),\n fee: r.connectorSelection.fee ?? null,\n })),\n otherwise: program.defaultSelection.fee ?? null,\n };\n}\n\n/**\n * Fluent builder for a platform fee-rule program. Emits the exact Euclid wire\n * shape (camelCase tree, tagged values, `metadata: {}` everywhere) so callers\n * never hand-write the AST. Rules are evaluated in order; the first match wins,\n * else `otherwise` (the default selection).\n *\n * @example\n * ```ts\n * const algorithm = feeProgram()\n * .rule({ name: 'crypto', when: { paymentMethod: 'crypto' }, fee: { percentage: 1.0 } })\n * .rule({\n * name: 'card_on_cryptomus',\n * when: { paymentMethod: 'card', connector: 'cryptomus' },\n * fee: { percentage: 2.0 },\n * })\n * .otherwise({ percentage: 3.0 })\n * .build();\n *\n * await delopay.fees.rules.upsert({ algorithm }, merchantId);\n * ```\n */\nexport class FeeProgramBuilder {\n private readonly rules: PlatformFeeRule[] = [];\n private defaultFee: PlatformFeeOutput | null = null;\n\n /** Append a rule. Provided `when`/`rawConditions` are ANDed. */\n rule(input: FeeRuleInput): this {\n if (input.match) assertNoEmptyAnyOf(input.match);\n const statements: PlatformFeeRule['statements'] = input.match\n ? encodeStatements(input.match)\n : [{ condition: buildConditions(input.when, input.rawConditions) }];\n this.rules.push({\n name: input.name,\n connectorSelection: { fee: toFeeOutput(input.fee) },\n statements,\n });\n return this;\n }\n\n /** Set the default selection (applied when no rule matches). */\n otherwise(fee: FeeSpecInput): this {\n this.defaultFee = toFeeOutput(fee);\n return this;\n }\n\n /** Produce the wire-ready program. */\n build(): PlatformFeeProgram {\n return {\n defaultSelection: { fee: this.defaultFee },\n rules: this.rules,\n metadata: {},\n };\n }\n}\n\n/** Start building a platform fee-rule program. See {@link FeeProgramBuilder}. */\nexport function feeProgram(): FeeProgramBuilder {\n return new FeeProgramBuilder();\n}\n","// The Airwallex card form's shape, as one description both renderers read.\n//\n// The buyer's checkout draws this form twice: once for real, mounting one\n// Airwallex iframe per field (`AirwallexCardPane`), and once inert, inside the\n// merchant dashboard's live preview (`PreviewPaymentSurface`). The preview\n// cannot be the real one — mounting a processor's SDK in a dashboard frame is\n// a payment nobody asked to start, and `check-preview-inert.mjs` exists to\n// forbid it — so there are necessarily two renderers of the same form.\n//\n// Two renderers of one form is the drift hazard this file exists to remove. A\n// preview that shows a layout the pane does not produce is worse than no\n// preview at all, because the merchant configures against it and finds out\n// from a buyer. So neither renderer describes the geometry: both read\n// `AIRWALLEX_CARD_LAYOUTS`, and a preset that exists in one and not the other\n// is a TYPE ERROR here rather than a guard finding later — `Record<\n// AirwallexCardPreset, …>` has to name every member of the union.\n//\n// What lives here is geometry and nothing else. Colours, radius, padding and\n// type come from the merchant's own branding tokens, and what happens INSIDE\n// each box belongs to Airwallex.\n\n/**\n * The card layouts the checkout can draw.\n *\n * Presentation only. Every one of them collects the card inside Airwallex's\n * own iframes and confirms the same intent, so the PCI scope, the guards and\n * the return leg are identical whichever the merchant picks — which is what\n * makes this a setting rather than a second rail.\n *\n * `fullFeaturedCard`, Airwallex's own all-in-one element, is deliberately not\n * on this list. It is a different element with a different theming API, and it\n * takes the layout away from us entirely; it needs its own decision, not a\n * seventh row in a list of geometries.\n */\nexport const AIRWALLEX_CARD_PRESETS = [\n 'single_row',\n 'split_fields',\n 'split_fields_labelled',\n 'stacked',\n 'number_expiry_row',\n 'compact',\n] as const;\n\nexport type AirwallexCardPreset = (typeof AIRWALLEX_CARD_PRESETS)[number];\n\n/**\n * A field of the card form, named as Airwallex's `createElement` names it.\n *\n * `card` is the combined element — number, expiry and CVC in one iframe on one\n * line — and it never appears alongside the other three: a layout is either\n * the one element or the trio.\n */\nexport type AirwallexCardField = 'card' | 'cardNumber' | 'expiry' | 'cvc';\n\nexport interface AirwallexCardLayout {\n /**\n * The elements to create, in creation order.\n *\n * Order is load-bearing twice over: `confirm()` is called on the first one\n * (the combined element, or the number field, which coordinates its\n * siblings), and completion advances the caret to the next.\n */\n readonly elements: readonly AirwallexCardField[];\n /**\n * The rows to draw, top to bottom, each naming the fields on it left to\n * right. Fields sharing a row share its width evenly.\n *\n * Every field in `elements` appears exactly once across `rows`, and nothing\n * else does — `airwallexCardLayoutIsCoherent` is that claim, executable.\n */\n readonly rows: readonly (readonly AirwallexCardField[])[];\n /**\n * How a row's width is shared, when sharing it evenly is wrong.\n *\n * **Optional, and absent is the normal case**: a row with no weights splits\n * evenly, which is what every other preset wants — `stacked` is full-width\n * rows, `split_fields`, `split_fields_labelled` and `compact` pair expiry\n * and CVC, which are both short and genuinely want half each, and\n * `single_row` is one element. Only `number_expiry_row` puts two fields of\n * very different lengths on one line, and only it declares weights.\n *\n * Declared as weights rather than widths on purpose. A fixed width is right\n * for exactly the embed width it was tuned against and wrong either side of\n * it; a weight is a ratio and holds at any width. That is not hypothetical\n * — the defect that produced this field was a card-number placeholder\n * clipped at 460px, which no fixed width would have fixed for the merchant\n * whose embed is 380px.\n *\n * A field with no entry weighs 1.\n */\n readonly weights?: Readonly<Partial<Record<AirwallexCardField, number>>>;\n /**\n * Whether this preset captions its fields by default.\n *\n * The merchant can override it (`branding.airwallexLabelStyle`); this is\n * what the preset means when they have not. Captions are always visual: see\n * `AIRWALLEX_LABEL_STYLES`.\n */\n readonly labels: boolean;\n /**\n * `compact` draws one step tighter and one step smaller than the merchant's\n * own `inputSize` and field type size, rather than replacing them — a\n * merchant who chose spacious spacing and this preset gets spacious-minus-\n * one, not the same form as a merchant who chose compact.\n */\n readonly density: 'default' | 'compact';\n}\n\nconst SPLIT: readonly AirwallexCardField[] = ['cardNumber', 'expiry', 'cvc'];\n\n/**\n * Every preset's geometry, and the single source of it.\n *\n * Typed as a total `Record` on purpose. Adding a preset to\n * `AIRWALLEX_CARD_PRESETS` without adding its geometry here does not compile,\n * so the two cannot come apart in the direction that would leave a renderer\n * guessing.\n */\nexport const AIRWALLEX_CARD_LAYOUTS: Record<AirwallexCardPreset, AirwallexCardLayout> = {\n // Airwallex's combined element. One iframe, one row, and the only preset\n // whose insides are not ours to lay out — which is why it carries no\n // captions: there is nothing to caption but the row as a whole.\n single_row: {\n elements: ['card'],\n rows: [['card']],\n labels: false,\n density: 'default',\n },\n // The trio with placeholders carrying the meaning. Shorter than the\n // labelled variant and fine on a wide surface.\n split_fields: {\n elements: SPLIT,\n rows: [['cardNumber'], ['expiry', 'cvc']],\n labels: false,\n density: 'default',\n },\n // The default. The same geometry, captioned — which is what makes it\n // survive a narrow embed, where a bare field row stops being self-evident.\n split_fields_labelled: {\n elements: SPLIT,\n rows: [['cardNumber'], ['expiry', 'cvc']],\n labels: true,\n density: 'default',\n },\n // Every field full width. Expiry and CVC side by side start to crowd below\n // roughly 320px, and this is the layout that does not.\n stacked: {\n elements: SPLIT,\n rows: [['cardNumber'], ['expiry'], ['cvc']],\n labels: true,\n density: 'default',\n },\n // Two rows instead of two-plus-one: shorter than the split forms without\n // the ambiguity of a single combined field.\n //\n // 3:2, not an even split. A card number is nineteen characters and an expiry\n // is five, so halving the row clipped the number's own placeholder at 460px\n // — seen in the preview before this was weighted. The proposal drew it even;\n // the merchant-facing decision was taken on the two drawn side by side and\n // the weighted one was chosen, so do not \"restore\" the even split to match\n // the original mock.\n number_expiry_row: {\n elements: SPLIT,\n rows: [['cardNumber', 'expiry'], ['cvc']],\n weights: { cardNumber: 3, expiry: 2 },\n labels: true,\n density: 'default',\n },\n // Split geometry at reduced density and type size, for a checkout embedded\n // in a page that already has its own chrome.\n compact: {\n elements: SPLIT,\n rows: [['cardNumber'], ['expiry', 'cvc']],\n labels: false,\n density: 'compact',\n },\n};\n\n/**\n * The preset that renders when nobody has chosen one.\n *\n * Not `DEFAULT_BRANDING.airwallexCardPreset`, which is the empty string: the\n * branding field means \"the merchant's choice, in the shop's checkout\n * customizer\", and empty means they have not made one. This is the last step\n * of the resolution, after the connector account's own setting.\n * See `resolveAirwallexCardPreset`.\n */\nexport const AIRWALLEX_CARD_PRESET_FALLBACK: AirwallexCardPreset = 'split_fields_labelled';\n\n/**\n * Which preset the buyer's card form is drawn from.\n *\n * Three sources, in this order, and the order is the migration story:\n *\n * 1. **The shop's branding.** Set in the checkout customizer, empty when the\n * merchant has not been there. Empty rather than pre-filled with the\n * default precisely so that (2) still means something — a branding field\n * that always held a value would silently override every connector\n * account already configured, which is a rendering change no merchant\n * asked for.\n * 2. **The connector account's `integration_style` metadata**, where this\n * setting lived before the customizer existed, projected onto the checkout\n * payload as `card_connector_integration_style`. Still authoritative for\n * every merchant who set it and has not overridden it here. Nothing\n * migrates it; it simply keeps working.\n * 3. **`split_fields_labelled`**, for a shop that has never set either.\n *\n * Step 3 is the one visible change: a shop with nothing configured used to get\n * the combined single row, and now gets the labelled split form.\n *\n * Anything unrecognised at either step falls through rather than failing. The\n * dashboard and the router deploy separately and may already offer a preset\n * this build has not heard of; a card form in the wrong layout is a cosmetic\n * disappointment, and no card form is a lost sale.\n */\nexport function resolveAirwallexCardPreset(\n fromBranding: string | null | undefined,\n fromConnector: string | null | undefined,\n): AirwallexCardPreset {\n return asPreset(fromBranding) ?? asPreset(fromConnector) ?? AIRWALLEX_CARD_PRESET_FALLBACK;\n}\n\n/** The preset named, or `null` for anything this build does not know. */\nexport function asAirwallexCardPreset(value: unknown): AirwallexCardPreset | null {\n return asPreset(value);\n}\n\nfunction asPreset(value: unknown): AirwallexCardPreset | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim().toLowerCase();\n return (AIRWALLEX_CARD_PRESETS as readonly string[]).includes(trimmed)\n ? (trimmed as AirwallexCardPreset)\n : null;\n}\n\n/** The geometry for a preset. Total, by the type of `AIRWALLEX_CARD_LAYOUTS`. */\nexport function airwallexCardLayout(preset: AirwallexCardPreset): AirwallexCardLayout {\n return AIRWALLEX_CARD_LAYOUTS[preset];\n}\n\n/**\n * How much of its row a field takes, relative to its neighbours.\n *\n * `1` unless the layout says otherwise, so a caller can multiply blindly and\n * an unweighted row divides evenly — which is what the CSS did before weights\n * existed, and therefore what every preset but one still gets.\n */\nexport function airwallexCellWeight(\n layout: AirwallexCardLayout,\n field: AirwallexCardField,\n): number {\n const weight = layout.weights?.[field];\n return typeof weight === 'number' && Number.isFinite(weight) && weight > 0 ? weight : 1;\n}\n\n/**\n * Whether a layout's rows draw exactly the elements it creates.\n *\n * The one thing the `Record` type cannot check. An element created with no row\n * to mount into leaves its field permanently pending — the pane's own comment\n * for that case is \"the form would sit on the skeleton until the deadline with\n * no reason given\" — and a row naming a field with no element draws an empty\n * box the buyer can click into and never type in. Both are silent.\n *\n * Executed by the checkout's preview guard over every preset, which is where a\n * new one gets caught.\n */\nexport function airwallexCardLayoutIsCoherent(layout: AirwallexCardLayout): boolean {\n const drawn = layout.rows.flat();\n if (drawn.length !== layout.elements.length) return false;\n return layout.elements.every((field) => drawn.filter((f) => f === field).length === 1);\n}\n\n/**\n * How the field's caption is drawn.\n *\n * Every one of these is **visual only**, and that is not a limitation we chose:\n * `for` cannot cross into a cross-origin iframe, so a `<label>` here would name\n * nothing and focus nothing. The field keeps the accessible name Airwallex\n * gives it inside the frame, and these captions sit beside it as an\n * affordance. The pane ships a caption on exactly these terms today.\n *\n * `''` is not a style — it means \"whatever the preset says\", so that\n * `split_fields` and `split_fields_labelled` keep meaning what they mean while\n * a merchant can still put floating captions on `compact`.\n */\nexport const AIRWALLEX_LABEL_STYLES = ['above', 'inline', 'floating', 'none'] as const;\nexport type AirwallexLabelStyle = (typeof AIRWALLEX_LABEL_STYLES)[number];\n\n/**\n * The caption style actually drawn: the merchant's override, or the preset's\n * own answer to whether it captions at all.\n */\nexport function resolveAirwallexLabelStyle(\n override: string | null | undefined,\n layout: AirwallexCardLayout,\n): AirwallexLabelStyle {\n if (\n typeof override === 'string' &&\n (AIRWALLEX_LABEL_STYLES as readonly string[]).includes(override)\n ) {\n return override as AirwallexLabelStyle;\n }\n return layout.labels ? 'above' : 'none';\n}\n\n/** How the box around each field is drawn. All three are the pane's own CSS. */\nexport const AIRWALLEX_FIELD_CHROMES = ['outlined', 'filled', 'underline'] as const;\nexport type AirwallexFieldChrome = (typeof AIRWALLEX_FIELD_CHROMES)[number];\n\n/**\n * The ring drawn around the focused field.\n *\n * Half of it is the pane's CSS on the container and half is Airwallex's\n * `:focus` bucket inside the frame; they are one control because a ring that\n * appeared on only one side of the iframe boundary would look like a bug.\n */\nexport const AIRWALLEX_FOCUS_RINGS = ['none', 'subtle', 'strong'] as const;\nexport type AirwallexFocusRing = (typeof AIRWALLEX_FOCUS_RINGS)[number];\n\n/**\n * What the browser's autofill highlight is allowed to do to the field.\n *\n * The one control on this list with no workaround from outside the frame:\n * the browser paints its own background on an autofilled input, and only the\n * SDK's `:autofill` bucket reaches it. `system` leaves it alone — the buyer's\n * own browser telling them it filled the field is information, not a style\n * bug — which is why it is the default.\n */\nexport const AIRWALLEX_AUTOFILL_TREATMENTS = ['system', 'brand', 'neutral'] as const;\nexport type AirwallexAutofillTreatment = (typeof AIRWALLEX_AUTOFILL_TREATMENTS)[number];\n\n/** Field type sizes, as the checkout's other size scales are named. */\nexport const AIRWALLEX_FIELD_FONT_SIZES = ['sm', 'md', 'lg'] as const;\nexport type AirwallexFieldFontSize = (typeof AIRWALLEX_FIELD_FONT_SIZES)[number];\n\n/** Field type weights. `medium` is what the pane hardcoded before this existed. */\nexport const AIRWALLEX_FIELD_WEIGHTS = ['regular', 'medium', 'semibold'] as const;\nexport type AirwallexFieldWeight = (typeof AIRWALLEX_FIELD_WEIGHTS)[number];\n\n/** Field type size in px, for the SDK's `base.fontSize`. */\nexport function airwallexFieldFontPx(\n size: AirwallexFieldFontSize,\n density: AirwallexCardLayout['density'],\n): number {\n const base = size === 'sm' ? 14 : size === 'lg' ? 18 : 16;\n // A compact preset draws one step smaller, floored so the field never\n // reaches the size at which iOS zooms the page on focus minus two.\n return density === 'compact' ? Math.max(13, base - 1) : base;\n}\n\n/** Field type weight as a CSS numeric weight, for the SDK's `base.fontWeight`. */\nexport function airwallexFieldWeightValue(weight: AirwallexFieldWeight): number {\n return weight === 'regular' ? 400 : weight === 'semibold' ? 600 : 500;\n}\n\n/**\n * The card networks whose marks the field row can display.\n *\n * **Decorative.** This list does not restrict what Airwallex accepts — that\n * would be `allowedCardNetworks`, which this build deliberately does not set,\n * because narrowing the networks a buyer may pay with is an acceptance change\n * and not a styling one. So the marks say what the merchant claims to take,\n * and it is the merchant's job to keep that true; the dashboard's field hint\n * says so in as many words. Enforcement is its own decision.\n */\nexport const AIRWALLEX_NETWORK_MARKS = ['visa', 'mastercard', 'amex', 'discover'] as const;\nexport type AirwallexNetworkMark = (typeof AIRWALLEX_NETWORK_MARKS)[number];\n","// How the card forms that are not Airwallex's can be styled: Stripe's Payment\n// Element, PayPal Card Fields and NomuPay's COPYandPAY widget.\n//\n// Each processor draws the card inside its own iframes and exposes a\n// different, narrow styling surface, so each gets only the controls that\n// surface actually reaches:\n//\n// - Stripe takes an Appearance object (`theme`, `inputs`, `labels`,\n// `variables`, `rules`, `disableAnimations`) and paints everything inside\n// one iframe itself.\n// - PayPal takes CSS for the text inside each field iframe (`input`, `.valid`,\n// `.invalid`, `:focus`); the box around it is the checkout's own DOM.\n// - COPYandPAY takes `wpwlOptions` (`style`, `showLabels`, `showPlaceholders`,\n// `showCVVHint`, `iframeStyles` for the two placeholders) and renders its\n// `.wpwl-*` classes into the page, where the checkout's CSS styles the box.\n//\n// Every value here is presentation. Nothing narrows the cards a buyer may pay\n// with, and nothing reaches a confirm path. COPYandPAY's `brandDetection` is\n// deliberately absent for that reason: it picks the scheme a co-badged card is\n// charged on, which is the buyer's choice to make, not a style.\n//\n// The box vocabularies (chrome, type size, weight, focus ring) are the\n// Airwallex section's, re-exported under neutral names, so a merchant styling\n// two rails meets the same words and the checkout draws them the same way.\n\nimport {\n AIRWALLEX_FIELD_CHROMES,\n AIRWALLEX_FIELD_FONT_SIZES,\n AIRWALLEX_FIELD_WEIGHTS,\n AIRWALLEX_FOCUS_RINGS,\n} from './airwallexCard';\n\n/** How the box around a field is drawn: `outlined`, `filled` or `underline`. */\nexport const CARD_FIELD_CHROMES = AIRWALLEX_FIELD_CHROMES;\nexport type CardFieldChrome = (typeof CARD_FIELD_CHROMES)[number];\n\n/** Field type size: `sm` 14px, `md` 16px, `lg` 18px. */\nexport const CARD_FIELD_FONT_SIZES = AIRWALLEX_FIELD_FONT_SIZES;\nexport type CardFieldFontSize = (typeof CARD_FIELD_FONT_SIZES)[number];\n\n/** Field type weight: `regular` 400, `medium` 500, `semibold` 600. */\nexport const CARD_FIELD_WEIGHTS = AIRWALLEX_FIELD_WEIGHTS;\nexport type CardFieldWeight = (typeof CARD_FIELD_WEIGHTS)[number];\n\n/** The ring around the focused field: `none`, `subtle` (neutral) or `strong` (brand colour). */\nexport const CARD_FOCUS_RINGS = AIRWALLEX_FOCUS_RINGS;\nexport type CardFocusRing = (typeof CARD_FOCUS_RINGS)[number];\n\n/** A field type size in px. */\nexport function cardFieldFontPx(size: CardFieldFontSize): number {\n return size === 'sm' ? 14 : size === 'lg' ? 18 : 16;\n}\n\n/** A field type weight as a CSS numeric weight. */\nexport function cardFieldWeightValue(weight: CardFieldWeight): number {\n return weight === 'regular' ? 400 : weight === 'semibold' ? 600 : 500;\n}\n\n// --- Stripe Payment Element ---------------------------------------------\n\n/**\n * Stripe's base theme. `auto` is `night` on a dark checkout and `stripe` on a\n * light one, which is what the pane chose before this setting existed. The\n * merchant's colours, font and radius are applied over whichever is picked.\n */\nexport const STRIPE_THEMES = ['auto', 'stripe', 'flat', 'night'] as const;\nexport type StripeTheme = (typeof STRIPE_THEMES)[number];\n\n/** The theme Stripe is actually given. */\nexport function resolveStripeTheme(theme: StripeTheme, dark: boolean): 'stripe' | 'flat' | 'night' {\n if (theme === 'auto') return dark ? 'night' : 'stripe';\n return theme;\n}\n\n/** Stripe's `appearance.inputs`: separate boxes, or one condensed block. */\nexport const STRIPE_INPUT_STYLES = ['spaced', 'condensed'] as const;\nexport type StripeInputStyle = (typeof STRIPE_INPUT_STYLES)[number];\n\n/**\n * Stripe's `appearance.labels`. The checkout-wide `labelStyle: 'hidden'` still\n * wins over either, because hiding is a decision about every form.\n */\nexport const STRIPE_LABEL_PLACEMENTS = ['above', 'floating'] as const;\nexport type StripeLabelPlacement = (typeof STRIPE_LABEL_PLACEMENTS)[number];\n\n/** The space between Stripe's fields and rows. */\nexport const STRIPE_SPACINGS = ['compact', 'comfortable', 'spacious'] as const;\nexport type StripeSpacing = (typeof STRIPE_SPACINGS)[number];\n\n/**\n * Stripe's `spacingUnit` and `gridRowSpacing` for a spacing choice.\n * `comfortable` is the 4px / 12px the pane always sent.\n */\nexport function stripeSpacingValues(spacing: StripeSpacing): {\n spacingUnit: string;\n gridRowSpacing: string;\n} {\n if (spacing === 'compact') return { spacingUnit: '3px', gridRowSpacing: '8px' };\n if (spacing === 'spacious') return { spacingUnit: '5px', gridRowSpacing: '16px' };\n return { spacingUnit: '4px', gridRowSpacing: '12px' };\n}\n\n// --- PayPal Card Fields -------------------------------------------------\n\n/** The PayPal card form's rows: expiry and CVC side by side, or every field full width. */\nexport const PAYPAL_CARD_LAYOUTS = ['split', 'stacked'] as const;\nexport type PaypalCardLayout = (typeof PAYPAL_CARD_LAYOUTS)[number];\n\n/**\n * Captions over PayPal's fields. Visual only: a `<label for>` cannot reach an\n * input inside PayPal's iframe, and the field keeps the name PayPal gives it.\n */\nexport const PAYPAL_LABEL_STYLES = ['above', 'none'] as const;\nexport type PaypalLabelStyle = (typeof PAYPAL_LABEL_STYLES)[number];\n\n// --- NomuPay COPYandPAY -------------------------------------------------\n\n/**\n * COPYandPAY's `style`. `plain` is bare labelled fields; `card` is the\n * widget's card-shaped presentation. `logos` and `none` are not offered:\n * `logos` makes the buyer pick a brand before the fields appear, and `none`\n * drops the widget's own CSS the checkout's field styling builds on.\n */\nexport const NOMUPAY_FORM_STYLES = ['plain', 'card'] as const;\nexport type NomupayFormStyle = (typeof NOMUPAY_FORM_STYLES)[number];\n\n/**\n * Apple Pay's `buttonStyle`. `auto` is `white` on a dark checkout and `black`\n * on a light one, as the widget was configured before this setting existed.\n */\nexport const APPLE_PAY_BUTTON_STYLES = ['auto', 'black', 'white', 'white-outline'] as const;\nexport type ApplePayButtonStyle = (typeof APPLE_PAY_BUTTON_STYLES)[number];\n\nexport function resolveApplePayButtonStyle(\n style: ApplePayButtonStyle,\n dark: boolean,\n): 'black' | 'white' | 'white-outline' {\n if (style === 'auto') return dark ? 'white' : 'black';\n return style;\n}\n\n/** Apple Pay's `buttonType`: the word on the button. Apple's own list. */\nexport const APPLE_PAY_BUTTON_TYPES = [\n 'pay',\n 'plain',\n 'buy',\n 'check-out',\n 'continue',\n 'book',\n 'order',\n 'subscribe',\n 'donate',\n 'contribute',\n 'support',\n 'tip',\n 'add-money',\n 'top-up',\n 'reload',\n 'rent',\n] as const;\nexport type ApplePayButtonType = (typeof APPLE_PAY_BUTTON_TYPES)[number];\n\n/**\n * Google Pay's `buttonColor`. `auto` is `white` on a dark checkout and `black`\n * on a light one; `default` lets Google choose for the buyer's browser.\n */\nexport const GOOGLE_PAY_BUTTON_COLORS = ['auto', 'default', 'black', 'white'] as const;\nexport type GooglePayButtonColor = (typeof GOOGLE_PAY_BUTTON_COLORS)[number];\n\nexport function resolveGooglePayButtonColor(\n color: GooglePayButtonColor,\n dark: boolean,\n): 'default' | 'black' | 'white' {\n if (color === 'auto') return dark ? 'white' : 'black';\n return color;\n}\n\n/** Google Pay's `buttonType`: the word on the button. Google's own list. */\nexport const GOOGLE_PAY_BUTTON_TYPES = [\n 'pay',\n 'plain',\n 'buy',\n 'checkout',\n 'book',\n 'order',\n 'subscribe',\n 'donate',\n] as const;\nexport type GooglePayButtonType = (typeof GOOGLE_PAY_BUTTON_TYPES)[number];\n\n// --- Whop Payment Elements ----------------------------------------------\n//\n// Whop draws its form inside its own frames and takes one `appearance`\n// object: a `theme` of named palettes (no hex), radius `variables`, and\n// per-part `classes` it sanitises against an allowlist. The element itself\n// is chosen by the preset: Whop's Payment Element (every method the account\n// offers, as an accordion or as tiles) or its Card Element (cards only, in\n// two shapes).\n\n/**\n * The Whop card form's shape.\n *\n * - `accordion`: the Payment Element, methods stacked; what the form always was.\n * - `tiles`: the Payment Element with `layout: 'horizontal'`, equal-width tiles.\n * - `card_stacked`: the Card Element, number above expiry and CVC. Cards only.\n * - `card_compact`: the Card Element on one row. Cards only.\n *\n * The two card presets offer no wallet inside the form: Apple Pay and Google\n * Pay are then the shop's own wallet buttons, or absent.\n */\nexport const WHOP_CARD_PRESETS = ['accordion', 'tiles', 'card_stacked', 'card_compact'] as const;\nexport type WhopCardPreset = (typeof WHOP_CARD_PRESETS)[number];\n\n/** The Whop element and layout a preset mounts. */\nexport type WhopCardElement =\n | { element: 'payment'; layout: 'accordion' | 'horizontal' }\n | { element: 'card'; layout: 'stacked' | 'compact' };\n\nexport function whopCardElement(preset: WhopCardPreset): WhopCardElement {\n switch (preset) {\n case 'tiles':\n return { element: 'payment', layout: 'horizontal' };\n case 'card_stacked':\n return { element: 'card', layout: 'stacked' };\n case 'card_compact':\n return { element: 'card', layout: 'compact' };\n default:\n return { element: 'payment', layout: 'accordion' };\n }\n}\n\n/**\n * Whop's `theme.accentColor`: the palette its radios, selected rows and\n * buttons are drawn in. Whop takes a palette name only, never a colour, so\n * `auto` picks the palette nearest the checkout's primary colour\n * (`nearestWhopAccent`).\n */\nexport const WHOP_ACCENT_COLORS = [\n 'auto',\n 'gray',\n 'blue',\n 'indigo',\n 'iris',\n 'violet',\n 'purple',\n 'plum',\n 'pink',\n 'crimson',\n 'ruby',\n 'red',\n 'tomato',\n 'orange',\n 'amber',\n 'yellow',\n 'lime',\n 'grass',\n 'green',\n 'jade',\n 'teal',\n 'cyan',\n 'sky',\n 'mint',\n 'brown',\n 'bronze',\n 'gold',\n] as const;\nexport type WhopAccentColor = (typeof WHOP_ACCENT_COLORS)[number];\n\n/** Each palette's solid step (Radix colour scale step 9, light). */\nconst WHOP_ACCENT_SWATCHES: Readonly<Record<Exclude<WhopAccentColor, 'auto' | 'gray'>, string>> = {\n blue: '#0090ff',\n indigo: '#3e63dd',\n iris: '#5b5bd6',\n violet: '#6e56cf',\n purple: '#8e4ec6',\n plum: '#ab4aba',\n pink: '#d6409f',\n crimson: '#e93d82',\n ruby: '#e54666',\n red: '#e5484d',\n tomato: '#e54d2e',\n orange: '#f76b15',\n amber: '#ffc53d',\n yellow: '#ffe629',\n lime: '#bdee63',\n grass: '#46a758',\n green: '#30a46c',\n jade: '#29a383',\n teal: '#12a594',\n cyan: '#00a2c7',\n sky: '#7ce2fe',\n mint: '#86ead4',\n brown: '#ad7f58',\n bronze: '#a18072',\n gold: '#978365',\n};\n\n/** A palette's solid swatch, for the dashboard's picker. `gray` is neutral. */\nexport function whopAccentSwatch(accent: Exclude<WhopAccentColor, 'auto'>): string {\n return accent === 'gray' ? '#8d8d8d' : WHOP_ACCENT_SWATCHES[accent];\n}\n\nfunction hexRgb(hex: string): [number, number, number] | null {\n const raw = hex.trim().replace(/^#/, '');\n const full = raw.length === 3 ? raw.replace(/./g, (c) => c + c) : raw;\n if (!/^[0-9a-f]{6}$/i.test(full)) return null;\n const n = Number.parseInt(full, 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\n/** OKLab, so \"nearest\" means nearest to the eye rather than in RGB. */\nfunction oklab([r, g, b]: [number, number, number]): [number, number, number] {\n const lin = (c: number) => {\n const v = c / 255;\n return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;\n };\n const [lr, lg, lb] = [lin(r), lin(g), lin(b)];\n const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);\n const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);\n const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);\n return [\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n ];\n}\n\n/**\n * The Whop palette nearest a colour. A colour with almost no chroma (black,\n * white, greys) is `gray`; an unreadable one is `blue`, Whop's own default.\n */\nexport function nearestWhopAccent(hex: string): Exclude<WhopAccentColor, 'auto'> {\n const rgb = hexRgb(hex);\n if (!rgb) return 'blue';\n const [L, a, b] = oklab(rgb);\n if (Math.hypot(a, b) < 0.04) return 'gray';\n let best: Exclude<WhopAccentColor, 'auto' | 'gray'> = 'blue';\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const [name, swatch] of Object.entries(WHOP_ACCENT_SWATCHES) as [\n Exclude<WhopAccentColor, 'auto' | 'gray'>,\n string,\n ][]) {\n const swatchRgb = hexRgb(swatch);\n if (!swatchRgb) continue;\n const [sL, sa, sb] = oklab(swatchRgb);\n // Hue and chroma decide the palette; lightness counts for less, since\n // Whop draws each palette in several steps.\n const distance = Math.hypot((L - sL) * 0.5, a - sa, b - sb);\n if (distance < bestDistance) {\n bestDistance = distance;\n best = name;\n }\n }\n return best;\n}\n\n/** The accent Whop is actually given. */\nexport function resolveWhopAccent(\n accent: WhopAccentColor,\n primaryHex: string,\n): Exclude<WhopAccentColor, 'auto'> {\n return accent === 'auto' ? nearestWhopAccent(primaryHex) : accent;\n}\n\n/** Whop's email field `labelMode`: a caption above the box, or inside it until typed. */\nexport const WHOP_EMAIL_LABELS = ['above', 'floating'] as const;\nexport type WhopEmailLabel = (typeof WHOP_EMAIL_LABELS)[number];\n\n/**\n * Whop's `theme.grayColor`: the neutral scale its borders, muted text and\n * backgrounds are drawn in. `auto` lets Whop match it to the accent.\n */\nexport const WHOP_GRAY_COLORS = [\n 'auto',\n 'gray',\n 'mauve',\n 'slate',\n 'sage',\n 'olive',\n 'sand',\n] as const;\nexport type WhopGrayColor = (typeof WHOP_GRAY_COLORS)[number];\n\n/**\n * How much billing address Whop asks a card for. `minimal` is Whop's\n * minimum for a card: name, country and postal code. `full` asks the\n * complete address in the country's own format, for address checks.\n */\nexport const WHOP_BILLING_DETAILS = ['minimal', 'full'] as const;\nexport type WhopBillingDetails = (typeof WHOP_BILLING_DETAILS)[number];\n\n/**\n * The corners of Whop's form: its fields, the joined card and address groups,\n * the method list and the tiles. `checkout` follows the checkout's own input\n * radius (`radiusInput`); the rest name a radius of the same scale.\n */\nexport const WHOP_RADII = ['checkout', 'square', 'small', 'medium', 'large'] as const;\nexport type WhopRadius = (typeof WHOP_RADII)[number];\n\n/**\n * Whether Whop's fields, groups and method list keep the soft drop shadow\n * Whop draws under them, or lie flat like the checkout's own fields.\n */\nexport const WHOP_SHADOWS = ['none', 'soft'] as const;\nexport type WhopShadow = (typeof WHOP_SHADOWS)[number];\n\n/**\n * How the method list marks the chosen method: Whop's radio dots, the dots\n * with the chosen method tinted in the brand colour, or the tint alone.\n * Tiles always ring the chosen tile.\n */\nexport const WHOP_SELECTIONS = ['radio_tint', 'radio', 'tint'] as const;\nexport type WhopSelection = (typeof WHOP_SELECTIONS)[number];\n\n/** The Whop settings a look sets together. Colours stay the shop's. */\nexport interface WhopLookSettings {\n whopCardPreset: WhopCardPreset;\n // Every look asks Whop's card minimum: a look is a design, and the full\n // address is a separate choice that names no look.\n whopBillingDetails: WhopBillingDetails;\n whopSeparated: boolean;\n whopFieldChrome: CardFieldChrome;\n whopEmailLabel: WhopEmailLabel;\n whopRadius: WhopRadius;\n whopShadow: WhopShadow;\n whopMethodIcons: boolean;\n whopSelection: WhopSelection;\n}\n\n/**\n * Curated looks for the Whop form: each sets the form, the chrome, the\n * captions, the corners, the shadow and how the chosen method is marked, as\n * one choice the dashboard offers before the single settings. `standard` is\n * the default branding's own look.\n */\nexport const WHOP_LOOKS = [\n 'standard',\n 'clean',\n 'whop',\n 'cards',\n 'tiles',\n 'soft',\n 'minimal',\n] as const;\nexport type WhopLook = (typeof WHOP_LOOKS)[number];\n\nexport const WHOP_LOOK_SETTINGS: Readonly<Record<WhopLook, Readonly<WhopLookSettings>>> = {\n // The fewest fields Whop takes a card with, laid out as Stripe's card\n // form: the email, the number above expiry and code, then one group of\n // name, country (preselected) and postal code. Whop refuses a card without\n // any of them. The wallets are the shop's own express buttons.\n standard: {\n whopCardPreset: 'card_stacked',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'outlined',\n whopEmailLabel: 'above',\n whopRadius: 'checkout',\n whopShadow: 'soft',\n whopMethodIcons: true,\n whopSelection: 'radio_tint',\n },\n // Flat fields like the checkout's own, the method list with the chosen\n // method tinted beside its radio.\n clean: {\n whopCardPreset: 'accordion',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'outlined',\n whopEmailLabel: 'above',\n whopRadius: 'checkout',\n whopShadow: 'none',\n whopMethodIcons: true,\n whopSelection: 'radio_tint',\n },\n // Whop's own form: its corners, its soft shadow, its radio dots.\n whop: {\n whopCardPreset: 'accordion',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'outlined',\n whopEmailLabel: 'above',\n whopRadius: 'small',\n whopShadow: 'soft',\n whopMethodIcons: true,\n whopSelection: 'radio',\n },\n // Each method its own raised card, the chosen one tinted, no dots.\n cards: {\n whopCardPreset: 'accordion',\n whopBillingDetails: 'minimal',\n whopSeparated: true,\n whopFieldChrome: 'outlined',\n whopEmailLabel: 'above',\n whopRadius: 'medium',\n whopShadow: 'soft',\n whopMethodIcons: true,\n whopSelection: 'tint',\n },\n // The methods as tiles above the card's fields.\n tiles: {\n whopCardPreset: 'tiles',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'outlined',\n whopEmailLabel: 'above',\n whopRadius: 'checkout',\n whopShadow: 'none',\n whopMethodIcons: true,\n whopSelection: 'radio_tint',\n },\n // Filled fields with the captions inside, round corners.\n soft: {\n whopCardPreset: 'accordion',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'filled',\n whopEmailLabel: 'floating',\n whopRadius: 'large',\n whopShadow: 'none',\n whopMethodIcons: false,\n whopSelection: 'radio_tint',\n },\n // The card alone on one line, underlined, captions inside.\n minimal: {\n whopCardPreset: 'card_compact',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopFieldChrome: 'underline',\n whopEmailLabel: 'floating',\n whopRadius: 'square',\n whopShadow: 'none',\n whopMethodIcons: true,\n whopSelection: 'radio_tint',\n },\n};\n\n/** The look a branding's Whop settings match exactly, or `null` for a custom mix. */\nexport function matchWhopLook(settings: WhopLookSettings): WhopLook | null {\n const keys = Object.keys(WHOP_LOOK_SETTINGS.clean) as (keyof WhopLookSettings)[];\n return (\n WHOP_LOOKS.find((look) =>\n keys.every((key) => WHOP_LOOK_SETTINGS[look][key] === settings[key]),\n ) ?? null\n );\n}\n","// Checkout branding — typed shape, design tokens, palettes, persistence\n// codec, CSS sanitizer, and DOM helpers for `--dp-*` CSS variables.\n//\n// Both delopay-checkout and delopay-control-center consume this module.\n//\n// Persistence: top-level fields own the \"loud\" tokens (logo, theme,\n// payment_button_*, background_colour, etc.). Everything else lives in\n// `sdk_ui_rules.branding` as a nested string-keyed map — booleans and\n// numbers round-trip as strings, the trust-badge list is JSON-stringified.\n\nimport {\n AIRWALLEX_AUTOFILL_TREATMENTS,\n AIRWALLEX_CARD_PRESETS,\n AIRWALLEX_FIELD_CHROMES,\n AIRWALLEX_FIELD_FONT_SIZES,\n AIRWALLEX_FIELD_WEIGHTS,\n AIRWALLEX_FOCUS_RINGS,\n AIRWALLEX_LABEL_STYLES,\n type AirwallexAutofillTreatment,\n type AirwallexCardPreset,\n type AirwallexFieldChrome,\n type AirwallexFieldFontSize,\n type AirwallexFieldWeight,\n type AirwallexFocusRing,\n type AirwallexLabelStyle,\n} from './airwallexCard';\nimport {\n APPLE_PAY_BUTTON_STYLES,\n APPLE_PAY_BUTTON_TYPES,\n CARD_FIELD_CHROMES,\n CARD_FIELD_FONT_SIZES,\n CARD_FIELD_WEIGHTS,\n CARD_FOCUS_RINGS,\n GOOGLE_PAY_BUTTON_COLORS,\n GOOGLE_PAY_BUTTON_TYPES,\n NOMUPAY_FORM_STYLES,\n PAYPAL_CARD_LAYOUTS,\n PAYPAL_LABEL_STYLES,\n STRIPE_INPUT_STYLES,\n STRIPE_LABEL_PLACEMENTS,\n STRIPE_SPACINGS,\n STRIPE_THEMES,\n WHOP_ACCENT_COLORS,\n WHOP_BILLING_DETAILS,\n WHOP_CARD_PRESETS,\n WHOP_EMAIL_LABELS,\n WHOP_GRAY_COLORS,\n WHOP_RADII,\n WHOP_SELECTIONS,\n WHOP_SHADOWS,\n type ApplePayButtonStyle,\n type ApplePayButtonType,\n type CardFieldChrome,\n type CardFieldFontSize,\n type CardFieldWeight,\n type CardFocusRing,\n type GooglePayButtonColor,\n type GooglePayButtonType,\n type NomupayFormStyle,\n type PaypalCardLayout,\n type PaypalLabelStyle,\n type StripeInputStyle,\n type StripeLabelPlacement,\n type StripeSpacing,\n type StripeTheme,\n type WhopAccentColor,\n type WhopBillingDetails,\n type WhopCardPreset,\n type WhopEmailLabel,\n type WhopRadius,\n type WhopSelection,\n type WhopShadow,\n type WhopGrayColor,\n} from './cardFormStyles';\nimport type { VaultFormAppearance } from './types';\n\n// --- Types --------------------------------------------------------------\n\nexport type CornerRadius = 'square' | 'small' | 'medium' | 'large' | 'pill';\n\n// Surfaces and inputs never make sense pill-shaped (a pill input ends up with\n// half-circle ends crammed against text). The form picker only exposes these\n// four; if a stale 'pill' value lands here from older saved data, decode\n// drops it back to 'medium'. Buttons and badges still allow 'pill'.\nexport type NonPillRadius = Exclude<CornerRadius, 'pill'>;\n\n// Spacing scales — split apart so the merchant can independently tune\n// surface padding, vertical rhythm, input height and pay-button height. Used\n// to live as a single `density` enum but that conflated four dimensions.\nexport type SpacingScale = 'compact' | 'comfortable' | 'spacious';\nexport type SizeScale = 'sm' | 'md' | 'lg';\nexport type SurfaceStyle = 'flat' | 'outlined' | 'elevated';\n\nexport type FontFamily =\n | 'inter'\n | 'system'\n | 'serif'\n | 'mono'\n | 'roboto'\n | 'poppins'\n | 'manrope'\n | 'dm-sans'\n | 'space-grotesk'\n | 'plex-sans'\n | 'work-sans'\n | 'open-sans'\n | 'lora'\n | 'playfair'\n | 'plex-mono'\n | 'jetbrains-mono';\n\nexport type FontWeight = 'regular' | 'medium' | 'semibold' | 'bold';\nexport type LayoutStyle = 'compact' | 'split';\nexport type SummaryPosition = 'left' | 'right';\n\n// Stripe Elements only supports two label modes (\"above\" or hidden via the\n// .Label-collapse hack); a \"floating\" label is not a Stripe concept and\n// would only render in our own mock — preview was lying about it. Persisted\n// `'floating'` is silently decoded to `'above'` for back-compat.\nexport type LabelStyle = 'above' | 'hidden';\n\n// Stripe Elements layout. Honored inside the StripeCardPane only — other\n// connector panes stack vertically regardless of this setting.\nexport type PaymentLayout = 'tabs' | 'accordion' | 'spaced_accordion';\n\nexport type LogoShape = 'square' | 'rounded' | 'circle';\nexport type LogoSize = 'sm' | 'md' | 'lg';\n\n// --- Provider surcharge / discount disclosure ---------------------------\n//\n// With surcharges scoped to the provider rather than to the payment method,\n// two tiles on one checkout can cost the buyer different amounts — so the\n// figure has to be legible on the tile, before the choice, not only in the\n// breakdown after it. These control how that figure is painted; whether there\n// is one at all is the router's answer, per pane.\n//\n// Nothing here can invent a figure or change one. A merchant who would rather\n// not disclose per-tile turns it off with `showSurcharge` and keeps the\n// breakdown inside the pane, which is where the disclosure lived before.\n\n// Where the figure sits relative to the tile's label.\n//\n// `inline` follows the label text immediately, so the price reads as part of\n// the name — good for short labels.\n// `trailing` pushes it to the tile's trailing edge on the label's own line: the\n// price reads as a property of the tile, and the tile's height does not change,\n// which matters because most tiles carry no figure at all and a row that grows\n// only for some of them makes the list look ragged.\n// `below` puts it under the sublabel, for merchants whose labels are long\n// enough that a trailing figure would crowd them.\n// `above` puts it over the label as an eyebrow, which is the one position that\n// reads before the method name rather than after it.\nexport type SurchargePosition =\n | 'inline'\n | 'trailing'\n | 'below'\n | 'above'\n | 'cornerStart'\n | 'cornerEnd';\n\n// Where the rows drawn as the wallet's OWN button (Apple Pay / Google Pay with\n// `native_element` applying in this render) are placed.\n//\n// Not within their section — they leave it. Every such row is lifted out of the\n// catalogue into one express strip, and this says where on the payment surface\n// that strip goes:\n//\n// `top` above everything, the custom fields included;\n// `belowFields` under the merchant's custom fields, still above the card form\n// and every section;\n// `belowCard` directly under the card form, above the remaining sections\n// (with no card form in this render, it falls back to\n// `belowFields`);\n// `bottom` under the last section, the last thing offered.\n//\n// The rows keep their own relative order in the strip whichever end it sits at.\n// Decided from the pane's setting for the render context, not from a later\n// fallback to the tile, so a row never moves under the buyer.\nexport type NativeElementPosition = 'top' | 'belowFields' | 'belowCard' | 'bottom';\n\n// How the figure is painted.\n//\n// `plain` is text in the configured colour. `badge` fills the shape with a tint\n// of it. `outline` draws the border only — the middle weight, for a checkout\n// whose tiles are already busy. `solid` fills with the colour itself and writes\n// on it in whichever of black or white reads better, which is the loudest\n// option and the one to reach for when the figure must not be missed.\n// `underline` keeps the text weight of `plain` and adds a rule beneath it.\n// `ribbon` runs the figure diagonally across a corner of the tile — the one\n// treatment that reads before the label rather than beside it, for a merchant\n// steering hard toward a cheaper provider.\nexport type SurchargeStyle = 'plain' | 'badge' | 'outline' | 'solid' | 'underline' | 'ribbon';\n\n// The border drawn around the shapes `badge`, `outline`, `solid` and `ribbon`\n// paint. `outline` draws nothing BUT its border, so `none` there would erase\n// the style rather than restyle it and reads as `thin` instead.\nexport type SurchargeBorderWidth = 'none' | 'thin' | 'medium' | 'thick';\n\n// How that border is drawn. `dashed` and `dotted` read as provisional, which\n// suits a promotional discount; `solid` is the neutral default.\nexport type SurchargeBorderStyle = 'solid' | 'dashed' | 'dotted';\n\n// The figure's type size, relative to the tile's own text.\nexport type SurchargeSize = 'sm' | 'md' | 'lg';\n\n// The corner treatment of the shapes `badge`, `outline` and `solid` draw.\n// Ignored by `plain` and `underline`, which draw no shape.\nexport type SurchargeShape = 'pill' | 'rounded' | 'square';\n\n// How heavily the figure is set.\nexport type SurchargeWeight = 'regular' | 'medium' | 'bold';\n\n// Whether the figure carries an explicit sign.\n//\n// `always` writes `+` on a surcharge and `−` on a discount (U+2212, not a\n// hyphen, so it aligns with the digits). `minusOnly` writes the minus and\n// leaves a surcharge unsigned, which reads as a price rather than as an\n// adjustment. `none` writes neither and leans entirely on the two colours —\n// legible only when a merchant configures one direction, and offered because a\n// merchant who only ever discounts should not have to explain a plus sign.\nexport type SurchargeSign = 'always' | 'minusOnly' | 'none';\n\n// Whether the figure names itself.\n//\n// `amount` is the figure alone. `labelled` prefixes the localized word for the\n// direction (\"Surcharge\" / \"Discount\"), which costs horizontal room and buys a\n// tile nobody has to interpret.\nexport type SurchargeLabelMode = 'amount' | 'labelled';\n\n// WHICH figure the tile prints, and in which order when it prints both.\n//\n// A discount and a surcharge are the same mechanism pointed in opposite\n// directions, but they are not the same message: a saving is something a\n// merchant advertises and a percentage is the persuasive half of it (\"20%\n// off\"), while a fee is something a merchant discloses and the money is the\n// half the buyer actually cares about. So the two directions carry this\n// setting separately — `discountFigure` and `surchargeFigure` — rather than\n// sharing one.\n//\n// The two figures always describe the same money. The router derives the\n// percentage from the charge rather than from the merchant's rule, so a fixed\n// rule states its share of this cart and a taxed rate states the share the\n// buyer actually pays. That is what makes showing either — or both — safe.\nexport type SurchargeFigureMode = 'amount' | 'percent' | 'amountThenPercent' | 'percentThenAmount';\n\n/**\n * Whether the tile has room to print the wording alongside the figure.\n *\n * One pairing says no: the diagonal ribbon at either corner. That band is\n * clipped by the tile it crosses, and the readable length is set by how far the\n * corner is inset — roughly 75px on a standard payment tile, against roughly\n * 107px for a labelled figure at the default size. Printing the word there\n * clips the *figure*, and a half-shown price is worse than a plain one, so the\n * word is what gives way.\n *\n * Exported, and shared by the buyer-facing checkout and the dashboard's live\n * preview, because the two must reach the same answer. A preview that promises\n * a word the checkout will not print is the one failure a preview cannot have.\n */\nexport function surchargeShowsLabel(\n labelMode: SurchargeLabelMode,\n style: SurchargeStyle,\n position: SurchargePosition,\n): boolean {\n if (labelMode !== 'labelled') return false;\n return !(style === 'ribbon' && (position === 'cornerStart' || position === 'cornerEnd'));\n}\n\n/** One of the two things a tile can print. */\nexport type SurchargeFigurePart = 'amount' | 'percent';\n\n/** Exactly what one tile prints, in order. See {@link surchargeFigurePlan}. */\nexport interface SurchargeFigurePlan {\n /** The leading figure. Always present — a tile with nothing to say renders nothing at all. */\n first: SurchargeFigurePart;\n /** The trailing figure, parenthesised by the renderer, or `null` for one figure. */\n second: SurchargeFigurePart | null;\n /** Whether the localized direction word prefixes the whole thing. */\n label: boolean;\n}\n\n/**\n * What one tile prints: which figures, in which order, and whether the word\n * comes with them.\n *\n * One function rather than a rule per surface, because the buyer-facing tile\n * and the dashboard's live preview must reach the same answer. A preview that\n * shows a percentage the checkout will not print — or prints in the other\n * order — is the one failure a preview cannot have.\n *\n * Three things it decides, in order of how much they cost to get wrong:\n *\n * * **No percentage available, no percentage printed.** `percentAvailable` is\n * false when the router sent none, which happens on an order of zero. A\n * merchant who asked for `percent` gets the amount instead — never a blank\n * tile, and never `0%`. This is the fallback the whole design leans on: the\n * amount is exact in every case, so it is what every degradation lands on.\n * * **A corner ribbon prints one figure.** The band crossing a tile's corner\n * is clipped to roughly 75px of readable length; two figures and a word do\n * not fit, and clipping a *price* is worse than showing less of one. It\n * keeps the merchant's leading figure — their own statement of which half\n * matters — and drops the trailing one along with the word.\n * * **Direction picks the setting.** `discountFigure` for a credit,\n * `surchargeFigure` for a charge, because a saving and a fee are not the\n * same message even though they are the same mechanism.\n */\nexport function surchargeFigurePlan(\n branding: Pick<\n CheckoutBranding,\n 'surchargeFigure' | 'discountFigure' | 'surchargeLabel' | 'surchargeStyle' | 'surchargePosition'\n >,\n isDiscount: boolean,\n percentAvailable: boolean,\n): SurchargeFigurePlan {\n const mode = isDiscount ? branding.discountFigure : branding.surchargeFigure;\n const label = surchargeShowsLabel(\n branding.surchargeLabel,\n branding.surchargeStyle,\n branding.surchargePosition,\n );\n\n // Money only, whatever was asked for: there is no second figure to state.\n if (!percentAvailable) return { first: 'amount', second: null, label };\n\n const ordered: Record<SurchargeFigureMode, [SurchargeFigurePart, SurchargeFigurePart | null]> = {\n amount: ['amount', null],\n percent: ['percent', null],\n amountThenPercent: ['amount', 'percent'],\n percentThenAmount: ['percent', 'amount'],\n };\n const [first, second] = ordered[mode];\n\n // The corner ribbon keeps the merchant's leading figure and nothing else.\n // `surchargeShowsLabel` has already dropped the word for the same reason, so\n // this is the same rule applied to the second figure.\n const cornerRibbon =\n branding.surchargeStyle === 'ribbon' &&\n (branding.surchargePosition === 'cornerStart' || branding.surchargePosition === 'cornerEnd');\n\n return { first, second: cornerRibbon ? null : second, label };\n}\n\n/**\n * Black or white, whichever reads better on `color` — for the `solid` style,\n * which writes on the configured colour itself.\n *\n * Picked by contrast rather than by a luminance threshold so the answer is the\n * one WCAG would give, and falls back to white on an unparseable colour, which\n * is what the rest of this module does with a colour it cannot read.\n */\nexport function readableInkOn(color: string): string {\n const onBlack = contrastRatio(color, '#000000');\n const onWhite = contrastRatio(color, '#ffffff');\n if (onBlack === null || onWhite === null) return '#ffffff';\n return onBlack >= onWhite ? '#000000' : '#ffffff';\n}\n\n/** Type size per {@link SurchargeSize}, relative to the tile's own text. */\nconst SURCHARGE_FONT_SIZE: Record<SurchargeSize, string> = {\n sm: '0.6875rem',\n md: '0.8125rem',\n lg: '0.9375rem',\n};\n\n/** Shape padding per {@link SurchargeSize}. Grows with the type. */\nconst SURCHARGE_PAD: Record<SurchargeSize, string> = {\n sm: '1px 6px',\n md: '2px 8px',\n lg: '3px 10px',\n};\n\n/** Corner radius per {@link SurchargeShape}. */\nconst SURCHARGE_RADIUS: Record<SurchargeShape, string> = {\n pill: '999px',\n rounded: '6px',\n square: '0px',\n};\n\n/** Border thickness per {@link SurchargeBorderWidth}. */\nconst SURCHARGE_BORDER_WIDTH: Record<SurchargeBorderWidth, string> = {\n none: '0px',\n thin: '1px',\n medium: '2px',\n thick: '3px',\n};\n\n/** Font weight per {@link SurchargeWeight}. */\nconst SURCHARGE_FONT_WEIGHT: Record<SurchargeWeight, string> = {\n regular: '400',\n medium: '600',\n bold: '700',\n};\n\n/**\n * The values each disclosure axis accepts, in the order a picker should offer\n * them: quietest first, so a merchant scrolling down is turning the figure up.\n *\n * Exported because both the dashboard's picker and this module's decoder need\n * the same list, and a picker offering a value the decoder rejects is a control\n * that silently does nothing.\n */\nexport const SURCHARGE_POSITIONS: readonly SurchargePosition[] = [\n 'trailing',\n 'inline',\n 'below',\n 'above',\n 'cornerStart',\n 'cornerEnd',\n];\n// Ordered as they read down the page, which is the order the dashboard's select\n// offers them in.\nexport const NATIVE_ELEMENT_POSITIONS: readonly NativeElementPosition[] = [\n 'top',\n 'belowFields',\n 'belowCard',\n 'bottom',\n];\nexport const SURCHARGE_STYLES: readonly SurchargeStyle[] = [\n 'plain',\n 'underline',\n 'outline',\n 'badge',\n 'solid',\n 'ribbon',\n];\nexport const SURCHARGE_BORDER_WIDTHS: readonly SurchargeBorderWidth[] = [\n 'none',\n 'thin',\n 'medium',\n 'thick',\n];\nexport const SURCHARGE_BORDER_STYLES: readonly SurchargeBorderStyle[] = [\n 'solid',\n 'dashed',\n 'dotted',\n];\nexport const SURCHARGE_SIZES: readonly SurchargeSize[] = ['sm', 'md', 'lg'];\n\n/**\n * Whether a style draws a shape behind the figure, and therefore whether\n * {@link SurchargeShape} means anything for it.\n *\n * `plain` and `underline` paint text. A dashboard that leaves the corner picker\n * live under them offers a control that changes nothing on screen, which is how\n * a merchant decides the whole panel is broken; one that hides it loses their\n * choice when they switch back. Disabled is the answer, and this is the\n * predicate it needs.\n */\nexport function surchargeStyleDrawsAShape(style: SurchargeStyle): boolean {\n return style === 'badge' || style === 'outline' || style === 'solid';\n}\nexport const SURCHARGE_SHAPES: readonly SurchargeShape[] = ['pill', 'rounded', 'square'];\nexport const SURCHARGE_WEIGHTS: readonly SurchargeWeight[] = ['regular', 'medium', 'bold'];\nexport const SURCHARGE_SIGNS: readonly SurchargeSign[] = ['always', 'minusOnly', 'none'];\nexport const SURCHARGE_LABEL_MODES: readonly SurchargeLabelMode[] = ['amount', 'labelled'];\nexport const SURCHARGE_FIGURE_MODES: readonly SurchargeFigureMode[] = [\n 'amount',\n 'percent',\n 'amountThenPercent',\n 'percentThenAmount',\n];\n\n/**\n * The buyer locales the checkout ships copy for, and therefore the ones a\n * merchant can override.\n *\n * Driven from here rather than restated in the dashboard, so a locale added to\n * the checkout cannot leave the dashboard offering one fewer box than the\n * buyer-facing render reads.\n */\nexport const CHECKOUT_LOCALES = [\n 'en',\n 'de',\n 'fr',\n 'es',\n 'it',\n 'nl',\n // Simplified and traditional are separate dictionaries in the checkout,\n // not region variants: they use different characters, so a merchant who\n // writes one has not written the other.\n 'zh',\n 'zh-Hant',\n 'hi',\n 'ar',\n] as const;\nexport type CheckoutLocale = (typeof CHECKOUT_LOCALES)[number];\n\n/**\n * Locales written right-to-left, for a UI that renders a merchant's override\n * next to the others.\n *\n * A dashboard field holding Arabic needs `dir=\"rtl\"` on the input itself:\n * without it the caret jumps, punctuation lands on the wrong end, and what the\n * merchant types is not what the buyer will see. Exported rather than kept in\n * the dashboard so the buyer-facing checkout and the editor agree on which\n * locales that is.\n */\nexport const RTL_CHECKOUT_LOCALES: readonly CheckoutLocale[] = ['ar'];\n\n/**\n * `dir` for a checkout locale — `'rtl'` for Arabic, `'ltr'` for the rest.\n *\n * Resolved on the **base language**, the same way `checkoutCopy` resolves an\n * override. Comparing the full string looked equivalent and was not: a buyer\n * sending `ar-EG` gets the `ar` copy from `checkoutCopy` and would have got\n * `ltr` from here — Arabic text in a left-to-right layout, which is the exact\n * failure this function exists to prevent. Case is folded for the same reason;\n * `Accept-Language` may arrive as `AR`.\n */\nexport function checkoutLocaleDir(locale: string): 'ltr' | 'rtl' {\n const base = String(locale ?? '')\n .toLowerCase()\n .split('-')[0];\n return (RTL_CHECKOUT_LOCALES as readonly string[]).includes(base) ? 'rtl' : 'ltr';\n}\n\n/**\n * The copy fields a merchant may write once per locale.\n *\n * Each has a flat `<field>` and a `<field>Translations` map beside it. The flat\n * value is what every existing merchant already has and stays authoritative\n * wherever no override is set — which is what makes this additive: a profile\n * saved before translations existed renders exactly as it did, in every locale.\n */\nexport const LOCALIZABLE_COPY_FIELDS = [\n 'headerText',\n 'payButtonLabel',\n 'cardTermsMessage',\n 'footerText',\n] as const;\nexport type LocalizableCopyField = (typeof LOCALIZABLE_COPY_FIELDS)[number];\n\n/** The translations key that belongs to a copy field. */\nexport function copyTranslationsKey(\n field: LocalizableCopyField,\n): `${LocalizableCopyField}Translations` {\n return `${field}Translations`;\n}\n\n/**\n * One piece of merchant copy, in the buyer's locale.\n *\n * Exact locale wins (`de-AT`), then its base language (`de`), then the flat\n * field — the same order `customFieldText` resolves in, because a merchant who\n * has learnt one of these should not have to learn the other.\n *\n * Returning the flat value rather than `''` is the backward-compatibility\n * guarantee: an override is an addition to what a merchant already wrote, never\n * a replacement for it, so an empty or missing map changes nothing.\n */\nexport function checkoutCopy(\n branding: CheckoutBranding,\n field: LocalizableCopyField,\n locale?: string,\n): string {\n const translated = translationFor(branding[copyTranslationsKey(field)], locale);\n return translated ?? branding[field];\n}\n\n/**\n * The merchant's own word for one direction, or `null` to use the checkout's\n * built-in one.\n *\n * `null` rather than a default string because the fallback is *localized* and\n * lives in the buyer-facing bundle — this module has no i18n of its own, and\n * inventing an English default here would print \"Discount\" to a German buyer.\n *\n * A merchant who sets nothing therefore keeps the shipped wording in both\n * languages, which is the intended default and already reads well.\n */\nexport function surchargeWordFor(\n branding: Pick<CheckoutBranding, 'surchargeWordTranslations' | 'discountWordTranslations'>,\n isDiscount: boolean,\n locale?: string,\n): string | null {\n return translationFor(\n isDiscount ? branding.discountWordTranslations : branding.surchargeWordTranslations,\n locale,\n );\n}\n\nexport interface TrustBadge {\n id: string;\n label: string;\n textColor: string;\n backgroundColor: string;\n borderColor: string | null;\n}\n\n// --- Notices -------------------------------------------------\n//\n// A notice is one short reassurance line on the checkout — a line icon and a\n// text — in one of two places. It replaces the trust badges as the default:\n// a badge carries its own three colours, so every theme had to recolour the\n// stock pair (F-BRAND-24) and a dark theme still wore light chips; a notice\n// carries none and is drawn in the checkout's own muted text and accent\n// colour, so it follows whatever palette the merchant picks. Its text is\n// written per locale, which a badge's never was.\n//\n// Persisted JSON-stringified under `sdk_ui_rules.branding.notices`, the same\n// transport as `trustBadges` and `customFields`.\n\n/**\n * Where a notice is drawn.\n *\n * - `summary`: under the order summary in the split layout; under the compact\n * header when there is no summary pane.\n * - `payment`: at the bottom of the payment element, under the pay button.\n */\nexport type NoticeSection = 'summary' | 'payment';\nexport const NOTICE_SECTIONS: readonly NoticeSection[] = ['summary', 'payment'];\n\n/**\n * How many notices one section draws. More than three stops reading as\n * reassurance and starts reading as small print, so the decoder drops the\n * overflow and the editor refuses a fourth.\n */\nexport const NOTICES_PER_SECTION = 3;\n\n/** Longest notice text, per locale. A notice is one line, not a paragraph. */\nexport const NOTICE_LABEL_MAX_LENGTH = 80;\n\n/** The marks a notice can carry, in the order the editor's grid offers them. */\nexport const NOTICE_ICONS = [\n 'lock',\n 'shield',\n 'check',\n 'truck',\n 'package',\n 'refresh',\n 'star',\n 'support',\n 'globe',\n 'tag',\n 'heart',\n 'leaf',\n 'clock',\n 'bank',\n] as const;\nexport type NoticeIcon = (typeof NOTICE_ICONS)[number];\n\n/** What an unknown or missing icon decodes to. */\nexport const NOTICE_ICON_FALLBACK: NoticeIcon = 'check';\n\n/**\n * Each mark as SVG path data on a 24×24 grid, stroked (not filled) with round\n * caps and joins.\n *\n * Kept here rather than drawn twice so the checkout and the customizer's icon\n * grid cannot disagree about what \"shield\" looks like: both render these\n * strings, and a mark added to `NOTICE_ICONS` without paths is a type error.\n * Every shape is a `<path>` — circles, rectangles and polylines included —\n * so a renderer needs one element type and no per-icon template.\n */\nexport const NOTICE_ICON_PATHS: Readonly<Record<NoticeIcon, readonly string[]>> = {\n lock: [\n 'M6 10h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2z',\n 'M8 10V7a4 4 0 0 1 8 0v3',\n ],\n shield: ['M12 3l7 3v6c0 4.2-2.9 7.6-7 9-4.1-1.4-7-4.8-7-9V6z', 'M9 12l2.5 2.5 4-4.5'],\n check: ['M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z', 'M8 12.5l3 3 5-6'],\n truck: [\n 'M3 7.5h10v9H3z',\n 'M13 11h4l3 3v2.5h-7z',\n 'M8.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z',\n 'M18.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z',\n ],\n package: [\n 'M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z',\n 'M12 22V12',\n 'M3.29 7L12 12l8.71-5',\n ],\n refresh: ['M20 12a8 8 0 1 1-2.5-5.8', 'M20 4v5h-5'],\n star: ['m12 3.6 2.6 5.3 5.9.9-4.3 4.1 1 5.8-5.2-2.7-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z'],\n support: [\n 'M5 13v-1a7 7 0 0 1 14 0v1',\n 'M3.5 14.5a1.8 1.8 0 0 1 1.8-1.8H7v5H5.3a1.8 1.8 0 0 1-1.8-1.8z',\n 'M20.5 14.5a1.8 1.8 0 0 0-1.8-1.8H17v5h1.7a1.8 1.8 0 0 0 1.8-1.8z',\n 'M19 17.7v.8a2.5 2.5 0 0 1-2.5 2.5H13',\n ],\n globe: [\n 'M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z',\n 'M3 12h18',\n 'M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18z',\n ],\n tag: ['M11 3H4v7l10 10 7-7z', 'M9.1 7a1.3 1.3 0 1 1-2.6 0a1.3 1.3 0 1 1 2.6 0z'],\n heart: ['M12 20s-7-4.4-7-9.3A3.9 3.9 0 0 1 12 8a3.9 3.9 0 0 1 7 2.7c0 4.9-7 9.3-7 9.3z'],\n leaf: ['M20 4c0 9-5.4 13-9.5 13A4.5 4.5 0 0 1 6 12.5C6 7 12 4 20 4z', 'M4 20c2-4.5 5-7.5 9-9.5'],\n clock: ['M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z', 'M12 7v5l3 2'],\n bank: ['M3 9.5 12 4l9 5.5', 'M5 10v8M9.5 10v8M14.5 10v8M19 10v8', 'M3 20h18'],\n};\n\nexport function isNoticeIcon(value: unknown): value is NoticeIcon {\n return typeof value === 'string' && (NOTICE_ICONS as readonly string[]).includes(value);\n}\n\nexport interface CheckoutNotice {\n /** Stable across edits and drags; `[A-Za-z0-9_-]`, at most 40 characters. */\n id: string;\n section: NoticeSection;\n icon: NoticeIcon;\n /** Default-language text, and what every locale without an override reads. */\n label: string;\n /** Per-locale overrides of `label`; a blank entry means \"use `label`\". */\n labelTranslations: CustomFieldTranslations;\n}\n\n// Merchant-defined checkout inputs. Rendered by the buyer-facing checkout\n// above the payment surface; submitted values land in the payment's\n// `metadata` under each field's `key`. Persisted JSON-stringified under\n// `sdk_ui_rules.branding.customFields` (same transport as trustBadges).\n// `checkbox` is a single opt-in box (terms acceptance, marketing consent),\n// not a multi-select. Its submitted value is always the string `'true'` or\n// `'false'` — never absent — so a merchant can tell \"declined\" from \"never\n// asked\" in the payment's metadata, which is what makes it usable as a\n// consent record. See `CHECKBOX_CHECKED` / `isCheckboxChecked`.\nexport type CustomFieldType = 'text' | 'textarea' | 'password' | 'email' | 'select' | 'checkbox';\n\n// Per-locale overrides ('de', 'en', …). Missing locale falls back to the\n// default-language string on the field itself — see `customFieldText`.\nexport type CustomFieldTranslations = Record<string, string>;\n\nexport interface CustomFieldOption {\n value: string;\n label: string;\n labelTranslations: CustomFieldTranslations;\n}\n\n// --- Conditional visibility ---------------------------------------------\n//\n// A field can be gated on facts the payment already carries when the\n// checkout renders: the intent's `metadata` (which a shop integration fills\n// per product/category — see the WordPress plugin's product metadata), its\n// `currency`, or its `amount`. This is what lets one profile serve a\n// \"Windows key\" order (no fields) and a \"Spotify account\" order (login\n// fields) without two shops.\n//\n// Evaluation is authoritative on the **backend**: `form_payment_link_data`\n// drops non-matching fields from the payload the buyer's browser receives,\n// so merchant metadata never leaves the server and the rules can't be\n// tampered with client-side. The implementation here is the shared\n// specification (and drives the control-center's builder); the Rust mirror\n// in `crates/router/src/core/payment_link/custom_fields.rs` must stay\n// behaviorally identical.\nexport type CustomFieldConditionSource = 'metadata' | 'currency' | 'amount';\n\n// String operators apply to metadata + currency; numeric ones (`gt`…`lte`)\n// apply to amount and to metadata values that parse as numbers.\nexport type CustomFieldOperator =\n | 'equals'\n | 'not_equals'\n | 'contains'\n | 'not_contains'\n | 'starts_with'\n | 'ends_with'\n | 'in'\n | 'not_in'\n | 'exists'\n | 'not_exists'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte';\n\nexport interface CustomFieldCondition {\n // Stable identity for editor list operations (reorder/remove). Not part\n // of the semantics.\n id: string;\n source: CustomFieldConditionSource;\n // Metadata key to read. Ignored (and persisted empty) for currency/amount.\n key: string;\n operator: CustomFieldOperator;\n // Right-hand operand. `in`/`not_in` read it as a comma-separated list;\n // `exists`/`not_exists` ignore it; amount comparisons parse it as an\n // integer in the currency's minor unit (1000 = 10.00).\n value: string;\n}\n\nexport interface CustomFieldVisibility {\n // `always` — unconditional (the default, and what every pre-feature field\n // decodes to). `match` — evaluate `conditions`.\n mode: 'always' | 'match';\n // How to combine multiple conditions.\n match: 'all' | 'any';\n conditions: CustomFieldCondition[];\n}\n\nexport interface CheckoutCustomField {\n // Stable identity for editor list operations (reorder/remove).\n id: string;\n // Metadata key the submitted value is stored under. Must be unique per\n // profile; the editor enforces `CUSTOM_FIELD_KEY_PATTERN`.\n key: string;\n type: CustomFieldType;\n // Default-language copy; `*Translations` maps override per locale.\n label: string;\n labelTranslations: CustomFieldTranslations;\n placeholder: string;\n placeholderTranslations: CustomFieldTranslations;\n helpText: string;\n helpTextTranslations: CustomFieldTranslations;\n required: boolean;\n // Disabled fields stay configured but are neither rendered nor submitted.\n enabled: boolean;\n // Length bounds apply to text/textarea/password/email; null = unbounded.\n minLength: number | null;\n maxLength: number | null;\n // Prefill for text-like fields; for selects, the option `value` selected\n // initially (empty = placeholder \"choose\" state).\n defaultValue: string;\n // Select choices; ignored for other types.\n options: CustomFieldOption[];\n // Conditional display. Always populated by the decoder — fields without a\n // persisted rule decode to `{ mode: 'always', … }`.\n visibility: CustomFieldVisibility;\n}\n\nexport interface CheckoutBranding {\n // Brand identity\n displayName: string;\n logoUrl: string;\n tagline: string;\n showLogo: boolean;\n logoShape: LogoShape;\n logoSize: LogoSize;\n\n // Color tokens\n primary: string;\n background: string;\n surface: string;\n text: string;\n heading: string;\n muted: string;\n border: string;\n accentText: string;\n buttonBackground: string;\n buttonText: string;\n\n // Typography\n fontFamily: FontFamily;\n headingWeight: FontWeight;\n\n // Shape — granular per-element. Surfaces & inputs use a narrower union\n // (no pill) because pill cards/inputs are always wrong; button and badge\n // keep the full `CornerRadius` since pill is a legitimate look there.\n radiusSurface: NonPillRadius;\n radiusInput: NonPillRadius;\n radiusButton: CornerRadius;\n radiusBadge: CornerRadius;\n surfaceStyle: SurfaceStyle;\n\n // Spacing — four independent dimensions.\n surfacePadding: SpacingScale;\n verticalGap: SpacingScale;\n inputSize: SizeScale;\n buttonSize: SizeScale;\n\n // Layout\n layout: LayoutStyle;\n summaryPosition: SummaryPosition;\n showOrderSummary: boolean;\n summaryGradient: boolean;\n showTotal: boolean;\n totalLabel: string;\n showCurrencyCode: boolean;\n showOrderItems: boolean;\n\n // Hosted-checkout exit. It is only drawn when the payment resolves a\n // cancel URL; these fields decide whether and how that destination is shown.\n cancelLinkEnabled: boolean;\n cancelLinkPosition: 'top' | 'bottom';\n cancelLinkStyle: 'link' | 'button';\n\n // Provider surcharge / discount disclosure. `showSurcharge` false hides the\n // per-tile figure entirely; the in-pane breakdown is unaffected, since that\n // one is the merchant's existing legal disclosure rather than a steering\n // signal. The two colours are separate on purpose: a surcharge and a discount\n // are opposite news for the buyer and reading them in one colour is exactly\n // the mistake a minus sign is easy to miss in.\n showSurcharge: boolean;\n surchargePosition: SurchargePosition;\n // Where the express strip of wallet buttons goes on the payment surface.\n // Only rows that actually draw a button are lifted into it; a surface with\n // none has no strip.\n nativeElementPosition: NativeElementPosition;\n // One button per line in that strip, instead of side by side.\n //\n // Off by default, because two wallets on one line is what the strip is for:\n // Apple Pay and Google Pay are one choice made twice, and a buyer is offered\n // at most one of them on any given browser anyway — the second track is\n // usually the card form arriving sooner rather than a second button. On for\n // a merchant who wants each button full width: a wide brand mark, a checkout\n // narrow enough that two tracks crowd, or simply their own taste.\n //\n // The strip already stacks on its own when the surface is too narrow to seat\n // two; this makes it stack at every width.\n nativeElementStacked: boolean;\n surchargeStyle: SurchargeStyle;\n surchargeSize: SurchargeSize;\n surchargeShape: SurchargeShape;\n surchargeBorderWidth: SurchargeBorderWidth;\n surchargeBorderStyle: SurchargeBorderStyle;\n surchargeWeight: SurchargeWeight;\n surchargeSign: SurchargeSign;\n surchargeUppercase: boolean;\n surchargeLabel: SurchargeLabelMode;\n surchargeFigure: SurchargeFigureMode;\n discountFigure: SurchargeFigureMode;\n surchargeWordTranslations: CustomFieldTranslations;\n discountWordTranslations: CustomFieldTranslations;\n surchargeColor: string;\n discountColor: string;\n\n // Trust badges (fully customizable; empty = hide row). No longer a default:\n // new shops start with none and get `notices` instead; a shop that customised\n // its badges keeps them. See `resolveNoticesAndBadges`.\n trustBadges: TrustBadge[];\n\n // Reassurance lines — icon + per-locale text — in the summary and at the\n // bottom of the payment element (empty = none).\n notices: CheckoutNotice[];\n\n // Merchant-defined checkout inputs (empty = no custom fields section).\n customFields: CheckoutCustomField[];\n\n // Where each payment-method section renders, 1-100, lower first.\n methodSectionOrder: MethodSectionOrder;\n\n // The merchant's name for a section, per locale. Empty = use the built-in\n // name, or the id itself for a section with none.\n methodSectionLabels: MethodSectionLabels;\n\n // Copy. All of these are optional in the persisted form: empty string\n // means \"unset\" and consumers should fall back (e.g. payButtonLabel falls\n // back to a localized \"Pay $X\" string).\n headerText: string;\n headerTextTranslations: CustomFieldTranslations;\n payButtonLabel: string;\n payButtonLabelTranslations: CustomFieldTranslations;\n cardTermsMessage: string;\n cardTermsMessageTranslations: CustomFieldTranslations;\n footerText: string;\n footerTextTranslations: CustomFieldTranslations;\n supportEmail: string;\n\n // Stripe Elements behavior. `paymentLayout` only affects what's painted\n // inside Stripe's iframe; non-Stripe connector panes stack vertically\n // regardless. `labelStyle` is also Stripe-iframe scope.\n paymentLayout: PaymentLayout;\n labelStyle: LabelStyle;\n\n // The Airwallex card surface. Scoped to that pane by name because that is\n // the only rail these reach: Stripe's element is themed through its own\n // Appearance API and the vault's fields are our DOM, so a field weight\n // written here would quietly do nothing on either. See `airwallexCard.ts`\n // for the geometry these sit on top of.\n //\n // `airwallexCardPreset` is the only one that can be EMPTY, and that is the\n // hinge of the whole migration: empty means \"the merchant has not chosen\n // here\", which lets the connector account's own `integration_style` keep\n // deciding for every shop configured before this section existed. A default\n // of `split_fields_labelled` on this field would override all of them\n // silently. `resolveAirwallexCardPreset` is the resolution.\n airwallexCardPreset: AirwallexCardPreset | '';\n // Removes the card form from the shop's checkout entirely. Money-affecting\n // and therefore off by default: with this on, no buyer can pay by card.\n airwallexHideCard: boolean;\n // Drops the \"Card\" heading over the Airwallex form. Presentation only, and\n // scoped to this rail because it is this rail's form the merchant is looking\n // at when they turn it off: a shop whose form is the first thing on the\n // checkout has no use for a word naming what the fields obviously are.\n //\n // The section is what loses its NAME, not its disclosure — a surcharge or\n // discount chip on the card rail still renders on that line, because what it\n // says is the money the buyer is about to be charged.\n airwallexHideCardTitle: boolean;\n airwallexFieldChrome: AirwallexFieldChrome;\n // Empty means \"whatever the preset says\" — see `resolveAirwallexLabelStyle`.\n airwallexLabelStyle: AirwallexLabelStyle | '';\n airwallexFieldFontSize: AirwallexFieldFontSize;\n airwallexFieldWeight: AirwallexFieldWeight;\n airwallexFocusRing: AirwallexFocusRing;\n airwallexAutofill: AirwallexAutofillTreatment;\n airwallexValidTint: boolean;\n // Decorative marks, and nothing more — they do not narrow what Airwallex\n // accepts. See `AIRWALLEX_NETWORK_MARKS`.\n airwallexNetworkMarks: boolean;\n\n // The Stripe Payment Element's own look (`cardFormStyles.ts`). Applied over\n // the colour, font and radius tokens above, inside Stripe's iframe.\n stripeTheme: StripeTheme;\n stripeInputs: StripeInputStyle;\n stripeLabels: StripeLabelPlacement;\n stripeSpacing: StripeSpacing;\n stripeFieldFontSize: CardFieldFontSize;\n stripeFieldWeight: CardFieldWeight;\n stripeFocusRing: CardFocusRing;\n stripeDisableAnimations: boolean;\n\n // PayPal Card Fields and Mollie Components. Boxes and captions are our DOM;\n // the type size and weight reach the text inside PayPal's iframes.\n paypalCardLayout: PaypalCardLayout;\n paypalLabelStyle: PaypalLabelStyle;\n paypalFieldChrome: CardFieldChrome;\n mollieFieldChrome: CardFieldChrome;\n paypalFieldFontSize: CardFieldFontSize;\n mollieFieldFontSize: CardFieldFontSize;\n paypalFieldWeight: CardFieldWeight;\n mollieFieldWeight: CardFieldWeight;\n paypalFocusRing: CardFocusRing;\n mollieFocusRing: CardFocusRing;\n paypalValidTint: boolean;\n\n // NomuPay's COPYandPAY widget: `wpwlOptions` for the form, the checkout's\n // CSS on its `.wpwl-*` boxes, and the Apple Pay and Google Pay buttons the\n // same widget draws. `auto` follows the checkout's theme, as before.\n nomupayFormStyle: NomupayFormStyle;\n nomupayShowLabels: boolean;\n nomupayShowPlaceholders: boolean;\n nomupayShowCvvHint: boolean;\n nomupayFieldChrome: CardFieldChrome;\n nomupayFieldFontSize: CardFieldFontSize;\n nomupayFocusRing: CardFocusRing;\n nomupayApplePayButtonStyle: ApplePayButtonStyle;\n nomupayApplePayButtonType: ApplePayButtonType;\n nomupayGooglePayButtonColor: GooglePayButtonColor;\n nomupayGooglePayButtonType: GooglePayButtonType;\n\n // MicroPayment's JSBridge frame: the checkout draws the holder and expiry\n // inputs and the box around the provider's PAN and CVC frames itself, and\n // hands the type size and weight into those frames.\n micropaymentFieldChrome: CardFieldChrome;\n micropaymentFieldFontSize: CardFieldFontSize;\n micropaymentFieldWeight: CardFieldWeight;\n micropaymentFocusRing: CardFocusRing;\n\n // Whop's Payment Elements: the element and layout (`whopCardPreset`), the\n // palette Whop draws its own controls in, and per-part CSS for the boxes,\n // all inside Whop's frames. See `cardFormStyles.ts`.\n whopCardPreset: WhopCardPreset;\n whopAccentColor: WhopAccentColor;\n whopGrayColor: WhopGrayColor;\n whopBillingDetails: WhopBillingDetails;\n // `accordion` only: each method in its own card, with space between.\n whopSeparated: boolean;\n whopEmailLabel: WhopEmailLabel;\n whopFieldChrome: CardFieldChrome;\n // Kept for stored brandings and no longer read: Whop draws the card digits\n // at its own size and weight and marks focus itself, so neither the\n // checkout nor the dashboard uses these three.\n whopFieldFontSize: CardFieldFontSize;\n whopFieldWeight: CardFieldWeight;\n whopFocusRing: CardFocusRing;\n // The corners of Whop's form, its drop shadow, whether the method list\n // shows each method's icon, and how it marks the chosen method.\n whopRadius: WhopRadius;\n whopShadow: WhopShadow;\n whopMethodIcons: boolean;\n whopSelection: WhopSelection;\n\n // Footer\n showPoweredBy: boolean;\n\n // Advanced — raw CSS appended after brand-token CSS variables are\n // applied, so its declarations win cascade order. Sanitized at render\n // time (see `sanitizeCustomCss`); persisted as-typed under\n // `sdk_ui_rules.branding.customCss`.\n customCss: string;\n}\n\n// --- Token maps ---------------------------------------------------------\n\n// Self-hostable font stacks. The buyer-facing checkout bundles these via\n// @fontsource* packages; the variable-font names ('Inter Variable', …) are\n// listed first so the smaller variable file is preferred when bundled.\nconst FONT_STACKS: Record<FontFamily, string> = {\n inter: \"'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif\",\n system:\n \"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif\",\n serif: \"Georgia, 'Times New Roman', serif\",\n mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n roboto: \"'Roboto', system-ui, sans-serif\",\n poppins: \"'Poppins', system-ui, sans-serif\",\n manrope: \"'Manrope Variable', 'Manrope', system-ui, sans-serif\",\n 'dm-sans': \"'DM Sans Variable', 'DM Sans', system-ui, sans-serif\",\n 'space-grotesk': \"'Space Grotesk Variable', 'Space Grotesk', system-ui, sans-serif\",\n 'plex-sans': \"'IBM Plex Sans', system-ui, sans-serif\",\n 'work-sans': \"'Work Sans Variable', 'Work Sans', system-ui, sans-serif\",\n 'open-sans': \"'Open Sans Variable', 'Open Sans', system-ui, sans-serif\",\n lora: \"'Lora Variable', 'Lora', Georgia, serif\",\n playfair: \"'Playfair Display Variable', 'Playfair Display', Georgia, serif\",\n 'plex-mono': \"'IBM Plex Mono', ui-monospace, monospace\",\n 'jetbrains-mono': \"'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, monospace\",\n};\n\nconst RADIUS_PX: Record<CornerRadius, string> = {\n square: '0px',\n small: '6px',\n medium: '12px',\n large: '20px',\n pill: '999px',\n};\n\nconst FONT_WEIGHT_NUMERIC: Record<FontWeight, string> = {\n regular: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n};\n\nconst SURFACE_PAD: Record<SpacingScale, string> = {\n compact: '1rem',\n comfortable: '1.5rem',\n spacious: '2rem',\n};\n\nconst VERTICAL_GAP: Record<SpacingScale, string> = {\n compact: '0.75rem',\n comfortable: '1rem',\n spacious: '1.5rem',\n};\n\nconst INPUT_PAD: Record<SizeScale, string> = {\n sm: '0.5rem 0.75rem',\n md: '0.625rem 0.75rem',\n lg: '0.875rem 0.875rem',\n};\n\nconst BUTTON_PAD: Record<SizeScale, string> = {\n sm: '0.625rem 1rem',\n md: '0.875rem 1.25rem',\n lg: '1.125rem 1.5rem',\n};\n\nexport function fontStack(family: FontFamily): string {\n return FONT_STACKS[family] ?? FONT_STACKS.inter;\n}\n\nexport function radiusValue(radius: CornerRadius): string {\n return RADIUS_PX[radius] ?? RADIUS_PX.medium;\n}\n\nexport function fontWeightValue(weight: FontWeight): string {\n return FONT_WEIGHT_NUMERIC[weight] ?? '600';\n}\n\nexport function surfacePadValue(scale: SpacingScale): string {\n return SURFACE_PAD[scale] ?? SURFACE_PAD.comfortable;\n}\n\nexport function verticalGapValue(scale: SpacingScale): string {\n return VERTICAL_GAP[scale] ?? VERTICAL_GAP.comfortable;\n}\n\nexport function inputPadValue(size: SizeScale): string {\n return INPUT_PAD[size] ?? INPUT_PAD.md;\n}\n\nexport function buttonPadValue(size: SizeScale): string {\n return BUTTON_PAD[size] ?? BUTTON_PAD.md;\n}\n\n/**\n * The look a vault's own card form takes to match a checkout with this\n * branding: pass it to `CheckoutSession.vaultCollectSession`.\n *\n * `danger` is the colour of an invalid field's border. The checkout picks it\n * for contrast on the surface, which this module does not measure, so the\n * caller supplies it.\n */\nexport function vaultFormAppearance(b: CheckoutBranding, danger?: string): VaultFormAppearance {\n return {\n surface: b.surface,\n text: b.text,\n border: b.border,\n accent: b.primary,\n ...(danger ? { danger } : {}),\n font: b.fontFamily,\n radius: b.radiusInput,\n size: b.inputSize,\n labels: b.labelStyle,\n };\n}\n\nexport function logoDimensions(size: LogoSize): { px: number; radius: number } {\n switch (size) {\n case 'sm':\n return { px: 36, radius: 8 };\n case 'lg':\n return { px: 64, radius: 16 };\n case 'md':\n default:\n return { px: 48, radius: 12 };\n }\n}\n\nconst HEX_RE = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;\n\nexport function isHexColor(value: string): boolean {\n return HEX_RE.test(value.trim());\n}\n\n/**\n * A CSS `<hex-color>`: whole token, leading `#` REQUIRED.\n *\n * ⚠️ The `#` is not pedantry here. `applyBrandingVariables` writes branding\n * values into custom properties unchanged (`el.style.setProperty(k, v)`), and\n * a custom property accepts any token stream — it is only interpreted when\n * substituted into a typed property, where `000` is not a colour and the\n * declaration is dropped. So a contrast API that accepted `'000'` would hand\n * back `21` for a pair that renders as nothing at all: approving a palette\n * that never reaches the screen is worse than refusing to judge it.\n */\nconst CSS_HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/**\n * The same shape with the `#` optional, for {@link isDarkSurface} ONLY.\n *\n * That function has stripped an optional hash since it was written, and\n * `'5a5a5a'` is a real colour whose answer is correct — tightening it onto the\n * CSS form would answer correct input wrongly. New API does not inherit the\n * tolerance; the existing caller keeps it.\n */\nconst LENIENT_HEX_RE = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/** `[r, g, b]` in 0–255, or `null` when the token is not a colour. */\nfunction parseHexChannels(value: string, pattern: RegExp): [number, number, number] | null {\n const match = pattern.exec(value.trim());\n if (!match) return null;\n const digits = match[1] as string;\n const full =\n digits.length === 3\n ? digits\n .split('')\n .map((c) => c + c)\n .join('')\n : digits;\n return [\n parseInt(full.slice(0, 2), 16),\n parseInt(full.slice(2, 4), 16),\n parseInt(full.slice(4, 6), 16),\n ];\n}\n\n/** WCAG 2.1 relative luminance (1.4.3), with the sRGB linearisation. */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const [lr, lg, lb] = [r, g, b].map((channel) => {\n const c = channel / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n }) as [number, number, number];\n return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;\n}\n\n/** Minimum contrast for body text — WCAG 2.1 success criterion 1.4.3. */\nexport const WCAG_AA_TEXT = 4.5;\n\n/**\n * Minimum contrast for non-text UI — WCAG 2.1 success criterion 1.4.11.\n * Focus rings, borders, icons carrying meaning.\n */\nexport const WCAG_AA_UI = 3;\n\n/**\n * WCAG 2.1 contrast ratio between two colours, 1–21. Order does not matter.\n *\n * Compare against {@link WCAG_AA_TEXT} or {@link WCAG_AA_UI}:\n *\n * ```ts\n * const ratio = contrastRatio(branding.surface, branding.text);\n * if (ratio === null || ratio < WCAG_AA_TEXT) useDefaultPalette();\n * ```\n *\n * ⚠️ Returns `null` — never a number — when either colour cannot be parsed.\n * That is the load-bearing part of this signature. Every colour bug this API\n * exists to prevent came from a helper answering with a plausible value for\n * something it could not read, and a `0` or a `21` here would be silently\n * believed by exactly the branch that is deciding whether text is legible.\n *\n * Accepts `#rgb` and `#rrggbb` — a CSS `<hex-color>`. ⚠️ A hash-less token is\n * `null`, not a ratio: `applyBrandingVariables` writes branding values into\n * custom properties verbatim, so `'000'` reaches CSS as something that is not a\n * colour. Returning `21` for it would approve a palette that never renders.\n * ({@link isDarkSurface} keeps its historical hash-less tolerance; this is new\n * API and does not inherit it.)\n */\nexport function contrastRatio(a: string, b: string): number | null {\n const first = parseHexChannels(a, CSS_HEX_RE);\n const second = parseHexChannels(b, CSS_HEX_RE);\n if (!first || !second) return null;\n const [x, y] = [relativeLuminance(first), relativeLuminance(second)];\n const lighter = Math.max(x, y);\n const darker = Math.min(x, y);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Crude perceived-luminance check — picks the right Stripe Elements preset\n * (`'night'` vs `'stripe'`) when the merchant has a dark surface.\n *\n * ⚠️ **This is not a readability test. Use {@link contrastRatio} for that.**\n * It is a YIQ luma split at 128, and on real brand colours its verdict and\n * actual legibility are not merely imprecise relative to each other — they can\n * be anti-correlated:\n *\n * | colour | `isDarkSurface` | vs white | |\n * | --- | --- | --- | --- |\n * | `#ff00ff` | `true` | 3.14:1 | fails AA text |\n * | `#00ff00` | `false` | 1.37:1 | fails AA text |\n * | `#0000ff` | `true` | 8.59:1 | passes |\n *\n * A caller picking text colour from this gets the wrong answer on both failing\n * cases. It is kept because choosing a Stripe preset is a legitimate and\n * different question.\n *\n * Inputs that are not a 3-/6-digit hex fall through to \"light\", the safer\n * assumption for the default palette.\n */\nexport function isDarkSurface(color: string): boolean {\n // ⚠️ Was a length check plus `parseInt` plus `Number.isNaN`, which let six\n // values the package's own validator rejects through as \"dark\" — `parseInt`\n // accepts a valid prefix, so `parseInt('0g', 16)` is `0`, not `NaN`. The\n // comment above already promised these fall through to \"light\"; now they do.\n const channels = parseHexChannels(color, LENIENT_HEX_RE);\n if (!channels) return false;\n const [r, g, b] = channels;\n const luma = (r * 299 + g * 587 + b * 114) / 1000;\n return luma < 128;\n}\n\n// --- Defaults -----------------------------------------------------------\n\n// Light-mode DeloPay-branded baseline. Hex values come straight from\n// `design-guidelines/colors.md`:\n// - #1E4FEB is `--color-dp-blue`, the wordmark/icon brand blue\n// - #0A1130 is `--color-dp-blue-dark`, the wordmark navy\n// - the rest are slate-50 / slate-200 / slate-500 / slate-800 from the\n// design system's neutral ramp.\n// Picked for: high contrast, neutral surroundings, brand-blue accents,\n// confident navy CTA. Reads \"fintech\" without feeling cold.\nconst LIGHT_PALETTE = {\n primary: '#1E4FEB',\n background: '#f8fafc',\n surface: '#ffffff',\n text: '#1e293b',\n heading: '#0A1130',\n muted: '#64748b',\n border: '#e2e8f0',\n accentText: '#1E4FEB',\n buttonBackground: '#0A1130',\n buttonText: '#ffffff',\n} as const;\n\nexport const DEFAULT_BADGES: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#047857',\n backgroundColor: '#ecfdf5',\n borderColor: '#a7f3d0',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#1E4FEB',\n backgroundColor: '#eff6ff',\n borderColor: '#bfdbfe',\n },\n];\n\n// Dark-mode equivalents of DEFAULT_BADGES. Dark trust chips need solid hex\n// (the form's color picker only accepts hex), so we pick the design system's\n// success-900 / info-900 backdrops paired with their *-400 foreground tokens.\nexport const DEFAULT_BADGES_DARK: TrustBadge[] = [\n {\n id: 'secure',\n label: 'Secure',\n textColor: '#34d399',\n backgroundColor: '#064e3b',\n borderColor: '#065f46',\n },\n {\n id: 'ssl',\n label: '256-bit SSL',\n textColor: '#60a5fa',\n backgroundColor: '#172554',\n borderColor: '#1e40af',\n },\n];\n\n/**\n * The notices every shop starts with.\n *\n * The same two claims the stock badges made — the payment is secure, the\n * connection is TLS-encrypted — and nothing more. A default is shown on every\n * shop that has not written its own, so it may only say what is true of every\n * shop: \"free shipping\" or \"tax included\" are the merchant's to claim, never\n * ours.\n *\n * `label` is English and there is deliberately no `en` override, so the\n * customizer's Default tab edits what an English buyer reads. The other nine\n * checkout locales are written out, because a German buyer reading \"Secure\n * payment\" is exactly what the badges did wrong.\n */\nexport const DEFAULT_NOTICES: readonly CheckoutNotice[] = [\n {\n id: 'secure',\n section: 'summary',\n icon: 'shield',\n label: 'Secure payment',\n labelTranslations: {\n de: 'Sichere Zahlung',\n fr: 'Paiement sécurisé',\n es: 'Pago seguro',\n it: 'Pagamento sicuro',\n nl: 'Veilig betalen',\n zh: '安全支付',\n 'zh-Hant': '安全付款',\n hi: 'सुरक्षित भुगतान',\n ar: 'دفع آمن',\n },\n },\n {\n id: 'ssl',\n section: 'summary',\n icon: 'lock',\n label: 'Encrypted · 256-bit SSL',\n labelTranslations: {\n de: 'Verschlüsselt · 256-Bit-SSL',\n fr: 'Chiffré · SSL 256 bits',\n es: 'Cifrado · SSL de 256 bits',\n it: 'Crittografato · SSL a 256 bit',\n nl: 'Versleuteld · 256-bit SSL',\n zh: '加密 · 256 位 SSL',\n 'zh-Hant': '加密 · 256 位元 SSL',\n hi: 'एन्क्रिप्टेड · 256-बिट SSL',\n ar: 'مشفّر · SSL بطول 256 بت',\n },\n },\n];\n\n/** A deep copy of `DEFAULT_NOTICES`, safe to edit. */\nexport function defaultNotices(): CheckoutNotice[] {\n return DEFAULT_NOTICES.map(cloneNotice);\n}\n\nexport function cloneNotice(notice: CheckoutNotice): CheckoutNotice {\n return { ...notice, labelTranslations: { ...notice.labelTranslations } };\n}\n\n/** `#rrggbb` → its three channels, or `null` for anything else. */\nfunction hexChannels(hex: string): [number, number, number] | null {\n const raw = /^#([0-9a-f]{6})$/i.exec(hex.trim())?.[1];\n if (!raw) return null;\n return [\n parseInt(raw.slice(0, 2), 16),\n parseInt(raw.slice(2, 4), 16),\n parseInt(raw.slice(4, 6), 16),\n ];\n}\n\n/**\n * Whether a badge colouring is one the dashboard's theme gallery generated.\n *\n * From 2026-09-03 the built-in themes shipped the stock pair recoloured from\n * the theme (control-center `themeBadges`, F-BRAND-24): text = the primary,\n * fill = the surface mixed 8 % towards it, border = mixed 30 %, rounded per\n * channel. Those shops never chose their badge colours either, so they count\n * as stock. The surface is not stored with the badges, so it is recovered:\n * each channel is searched for a surface value that reproduces BOTH the fill\n * and the border — a hand-picked colouring passes that by accident only when\n * the merchant happened to type the exact generated hexes.\n *\n * Frozen on purpose: this recognises what was shipped, so it must not follow\n * any later change to how themes look.\n */\nfunction isThemeTintedBadgeColouring(textColor: string, fill: string, border: string): boolean {\n const primary = hexChannels(textColor);\n const bg = hexChannels(fill);\n const line = hexChannels(border);\n if (!primary || !bg || !line) return false;\n const mixed = (surface: number, to: number, share: number): number =>\n Math.round(surface + (to - surface) * share);\n return primary.every((p, i) => {\n for (let surface = 0; surface <= 255; surface += 1) {\n if (mixed(surface, p, 0.08) === bg[i] && mixed(surface, p, 0.3) === line[i]) return true;\n }\n return false;\n });\n}\n\n/**\n * Whether a badge list is a default DeloPay shipped rather than something the\n * merchant configured.\n *\n * Stock means the two stock badges — `secure` / \"Secure\", then `ssl` /\n * \"256-bit SSL\" — in a colouring DeloPay generated: the light default, the\n * dark default, or a theme colouring (`isThemeTintedBadgeColouring`, the same\n * one on both badges). Anything else was edited: a changed label, an added,\n * removed or reordered badge, a recolour, and an empty list — a merchant who\n * removed both badges chose to show nothing.\n */\nexport function isDefaultBadgeSet(badges: readonly TrustBadge[]): boolean {\n if (badges.length !== DEFAULT_BADGES.length) return false;\n const sameContent = badges.every(\n (badge, i) => badge.id === DEFAULT_BADGES[i]?.id && badge.label === DEFAULT_BADGES[i]?.label,\n );\n if (!sameContent) return false;\n\n const colouring = (set: readonly TrustBadge[]): string =>\n set\n .map((b) => [b.textColor, b.backgroundColor, b.borderColor ?? ''].join('|').toLowerCase())\n .join('/');\n const mine = colouring(badges);\n if (mine === colouring(DEFAULT_BADGES) || mine === colouring(DEFAULT_BADGES_DARK)) return true;\n\n // A theme gave both badges one colouring, border included.\n const [first] = badges;\n const border = first?.borderColor;\n if (!first || !border) return false;\n const same = (a: string | null, b: string): boolean =>\n (a ?? '').toLowerCase() === b.toLowerCase();\n return (\n badges.every(\n (b) =>\n same(b.textColor, first.textColor) &&\n same(b.backgroundColor, first.backgroundColor) &&\n same(b.borderColor, border),\n ) && isThemeTintedBadgeColouring(first.textColor, first.backgroundColor, border)\n );\n}\n\n/**\n * Decide a shop's badges and notices from what it has saved.\n *\n * `null` means the key is absent from what was saved (or unreadable). The\n * rule, in order:\n *\n * 1. Notices saved → they decide; badges are whatever was saved (none if\n * absent). Every save since notices exist writes the key, so from a shop's\n * first save on this is the only branch it takes — which is what makes\n * \"removed every notice\" stick instead of re-migrating to the defaults.\n * 2. No notices, and no badges or the stock badges → the badges go and the\n * default notices come in. This is every shop that never touched its trust\n * row.\n * 3. No notices, and badges the merchant configured → they stay exactly as\n * they are, and no notices are added: a shop that designed its own trust\n * row keeps it, and one that removed it keeps it removed.\n *\n * Decode-time only. Nothing is written until the merchant saves.\n */\nexport function resolveNoticesAndBadges(\n savedBadges: TrustBadge[] | null,\n savedNotices: CheckoutNotice[] | null,\n): { trustBadges: TrustBadge[]; notices: CheckoutNotice[] } {\n if (savedNotices !== null) {\n return { trustBadges: savedBadges ?? [], notices: savedNotices };\n }\n if (savedBadges === null || isDefaultBadgeSet(savedBadges)) {\n return { trustBadges: [], notices: defaultNotices() };\n }\n return { trustBadges: savedBadges, notices: [] };\n}\n\n// --- Method sections: order and captions -------------------------\n//\n// Two branding fields for the checkout's payment-method groups: the order they\n// render in, and the merchant's own name for each. A section's identity is a\n// key, and a key with no caption prints as itself.\n\nconst METHOD_SECTION_ORDER_KEY = 'methodSectionOrder';\nconst METHOD_SECTION_LABELS_KEY = 'methodSectionLabels';\n\n/** Inclusive bounds of one section's order number. */\nexport const MIN_SECTION_ORDER = 1;\nexport const MAX_SECTION_ORDER = 100;\n\n/** Ceiling on one caption. */\nexport const MAX_SECTION_LABEL_LENGTH = 120;\n\nexport interface MethodSectionSpec {\n readonly id: string;\n /** `sections.*` translation key, used when uncaptioned. */\n readonly labelKey: string;\n readonly order: number;\n}\n\n/**\n * Every known section, with its default number. Lower renders first.\n *\n * Array order is also the tie-break between two sections sharing a number, so\n * it is a display order rather than an arbitrary list.\n */\nexport const METHOD_SECTIONS: readonly MethodSectionSpec[] = [\n { id: 'card', labelKey: 'sections.card', order: 10 },\n { id: 'wallet', labelKey: 'sections.wallets', order: 20 },\n { id: 'bnpl', labelKey: 'sections.bnpl', order: 30 },\n { id: 'bank_redirect', labelKey: 'sections.onlineBanking', order: 40 },\n { id: 'bank_transfer', labelKey: 'sections.bankTransfer', order: 45 },\n { id: 'crypto', labelKey: 'sections.cryptocurrency', order: 50 },\n { id: 'game_items', labelKey: 'sections.gameItems', order: 60 },\n { id: 'voucher', labelKey: 'sections.vouchers', order: 70 },\n { id: 'gift_card', labelKey: 'sections.giftCards', order: 75 },\n { id: 'reward', labelKey: 'sections.rewards', order: 80 },\n { id: 'cash', labelKey: 'sections.cash', order: 90 },\n];\n\n/** Ids that mean an existing section under another name. */\nexport const SECTION_ALIASES: Readonly<Record<string, string>> = {\n card_redirect: 'card',\n};\n\n/** Where an id this list does not know goes: last, not first. */\nexport const UNKNOWN_SECTION_ORDER = MAX_SECTION_ORDER;\n\n/** Section id → order number. */\nexport type MethodSectionOrder = Record<string, number>;\n\n/** Section id → locale → the merchant's caption. */\nexport type MethodSectionLabels = Record<string, Record<string, string>>;\n\nexport function canonicalSectionId(category: string): string {\n return SECTION_ALIASES[category] ?? category;\n}\n\nexport function defaultMethodSectionOrder(): MethodSectionOrder {\n const order: MethodSectionOrder = {};\n for (const section of METHOD_SECTIONS) order[section.id] = section.order;\n return order;\n}\n\n/**\n * One order number, validated. `null` for anything that is not an integer in\n * range, so the caller can fall back to the default rather than clamp — a\n * `999` is a mistake, and \"last\" is a guess at what was meant.\n */\nexport function validSectionOrder(raw: unknown): number | null {\n if (typeof raw !== 'number' || !Number.isInteger(raw)) return null;\n if (raw < MIN_SECTION_ORDER || raw > MAX_SECTION_ORDER) return null;\n return raw;\n}\n\n/**\n * The order from a raw bag value. Total, like `decodeBadges`: anything\n * malformed gives the defaults, one bad number costs only its own section, an\n * unknown id is kept so a newer consumer can place it, and an alias folds onto\n * the section it names.\n */\nexport function decodeMethodSectionOrder(raw: string | undefined): MethodSectionOrder {\n const order = defaultMethodSectionOrder();\n if (raw === undefined) return order;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return order;\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return order;\n for (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n const valid = validSectionOrder(value);\n if (valid === null) continue;\n order[canonicalSectionId(key)] = valid;\n }\n return order;\n}\n\nexport function encodeMethodSectionOrder(order: MethodSectionOrder): string {\n return JSON.stringify(order);\n}\n\n/**\n * Captions from a raw bag value. Tolerant for the same reason as the order,\n * and blank strings are dropped so an emptied field round-trips as absence.\n */\nexport function decodeMethodSectionLabels(raw: string | undefined): MethodSectionLabels {\n if (raw === undefined) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return {};\n const labels: MethodSectionLabels = {};\n for (const [section, byLocale] of Object.entries(parsed as Record<string, unknown>)) {\n if (!section || byLocale === null || typeof byLocale !== 'object' || Array.isArray(byLocale)) {\n continue;\n }\n const kept: Record<string, string> = {};\n for (const [locale, text] of Object.entries(byLocale as Record<string, unknown>)) {\n if (typeof text !== 'string') continue;\n const trimmed = text.trim();\n if (!trimmed) continue;\n kept[locale] = trimmed.slice(0, MAX_SECTION_LABEL_LENGTH);\n }\n if (Object.keys(kept).length > 0) labels[canonicalSectionId(section)] = kept;\n }\n return labels;\n}\n\n/**\n * Captions for the bag, or `null` when there are none — so an untouched\n * profile's bag is unchanged by this field existing, as `customFields` does.\n */\nexport function encodeMethodSectionLabels(labels: MethodSectionLabels): string | null {\n const cleaned: MethodSectionLabels = {};\n for (const [section, byLocale] of Object.entries(labels)) {\n const kept: Record<string, string> = {};\n for (const [locale, text] of Object.entries(byLocale)) {\n const trimmed = (text ?? '').trim();\n if (trimmed) kept[locale] = trimmed.slice(0, MAX_SECTION_LABEL_LENGTH);\n }\n if (Object.keys(kept).length > 0) cleaned[section] = kept;\n }\n return Object.keys(cleaned).length > 0 ? JSON.stringify(cleaned) : null;\n}\n\nfunction sectionCatalogueIndex(sectionId: string): number {\n const index = METHOD_SECTIONS.findIndex((section) => section.id === sectionId);\n return index === -1 ? METHOD_SECTIONS.length : index;\n}\n\nexport function sectionOrderOf(order: MethodSectionOrder, category: string): number {\n return order[canonicalSectionId(category)] ?? UNKNOWN_SECTION_ORDER;\n}\n\n/**\n * Compare two section ids: the merchant's number, then this list, then the id.\n *\n * The last two keys are properties of the build rather than of any response,\n * which is what stops two sections on one number swapping between renders.\n */\nexport function compareSections(order: MethodSectionOrder): (a: string, b: string) => number {\n return (a, b) => {\n const left = canonicalSectionId(a);\n const right = canonicalSectionId(b);\n const byOrder = sectionOrderOf(order, left) - sectionOrderOf(order, right);\n if (byOrder !== 0) return byOrder;\n const byCatalogue = sectionCatalogueIndex(left) - sectionCatalogueIndex(right);\n if (byCatalogue !== 0) return byCatalogue;\n return left < right ? -1 : left > right ? 1 : 0;\n };\n}\n\n/**\n * What to print above a section: the merchant's caption for this locale, then\n * their caption in any locale they wrote, then the caller's own name for a\n * section it knows, then the raw id.\n *\n * `translate` must return `undefined` for a key it has no entry for, or step 3\n * swallows the fall-through and prints `sections.<id>`.\n */\nexport function sectionLabel(\n labels: MethodSectionLabels,\n category: string,\n locale: string,\n knownKey: string | undefined,\n translate: (key: string) => string | undefined,\n): string {\n const id = canonicalSectionId(category);\n // `in` rather than `Object.hasOwn`: this package targets a lower `lib` than\n // its consumers, and the map is built by the decoder above.\n if (id in labels) {\n const captions = labels[id] as Record<string, string>;\n // Through `translationFor`, like every other localized branding field: it\n // folds case and walks parent locales, so `de-AT` finds `de`. An exact\n // lookup missed that and fell to the any-caption step below, which returns\n // whichever locale is first in the map — English, for a caption set written\n // `en` then `de`. A German buyer read an English heading.\n // Trimmed: `translationFor` accepts any non-empty string, and a\n // whitespace-only caption is not a caption. The decoder drops those, so\n // this only bites a caller that built the map itself.\n const matched = translationFor(captions, locale)?.trim();\n if (matched) return matched;\n for (const value of Object.values(captions)) {\n const any = value.trim();\n if (any) return any;\n }\n }\n if (knownKey) {\n const translated = translate(knownKey);\n if (translated) return translated;\n }\n return category;\n}\n\n/** Accept either the decoded map or the bag's JSON string. */\nfunction parseSectionOrderLoose(raw: unknown): MethodSectionOrder {\n if (typeof raw === 'string') return decodeMethodSectionOrder(raw);\n if (raw !== null && typeof raw === 'object' && !Array.isArray(raw)) {\n return decodeMethodSectionOrder(JSON.stringify(raw));\n }\n return defaultMethodSectionOrder();\n}\n\n/** Same, for captions. */\nfunction parseSectionLabelsLoose(raw: unknown): MethodSectionLabels {\n if (typeof raw === 'string') return decodeMethodSectionLabels(raw);\n if (raw !== null && typeof raw === 'object' && !Array.isArray(raw)) {\n return decodeMethodSectionLabels(JSON.stringify(raw));\n }\n return {};\n}\n\n/** The `sections.*` key for a known id, or `undefined`. */\nexport function knownSectionLabelKey(category: string): string | undefined {\n const id = canonicalSectionId(category);\n return METHOD_SECTIONS.find((section) => section.id === id)?.labelKey;\n}\n\nconst DEFAULT_BRANDING_BASE: Omit<\n CheckoutBranding,\n | keyof typeof LIGHT_PALETTE\n | 'trustBadges'\n | 'notices'\n | 'customFields'\n | 'methodSectionOrder'\n | 'methodSectionLabels'\n> = {\n displayName: '',\n logoUrl: '',\n tagline: '',\n // Logo + summary gradient OFF by default — an unconfigured DeloPay\n // checkout reads cleaner without a placeholder logo block, and the\n // gradient implies a primary tint the merchant hasn't yet picked.\n showLogo: false,\n logoShape: 'rounded',\n logoSize: 'md',\n\n fontFamily: 'inter',\n headingWeight: 'semibold',\n\n radiusSurface: 'medium',\n radiusInput: 'medium',\n radiusButton: 'medium',\n radiusBadge: 'pill',\n surfaceStyle: 'elevated',\n surfacePadding: 'comfortable',\n verticalGap: 'comfortable',\n inputSize: 'md',\n buttonSize: 'md',\n\n // Disclosure on by default: with provider-scoped pricing the tile is where\n // the buyer chooses between prices, and a price they cannot see is one they\n // find out about on the statement.\n showSurcharge: true,\n surchargePosition: 'trailing',\n // The button is the surface a buyer recognises fastest; it leads its section\n // unless the merchant says otherwise.\n nativeElementPosition: 'top',\n // Side by side — see the field.\n nativeElementStacked: false,\n surchargeStyle: 'badge',\n surchargeSize: 'sm',\n surchargeShape: 'pill',\n surchargeBorderWidth: 'thin',\n surchargeBorderStyle: 'solid',\n surchargeWeight: 'medium',\n surchargeSign: 'always',\n surchargeUppercase: false,\n // Named, not bare. A tile that reads \"-EUR 2.50\" beside a brand name is a\n // number with no subject — buyers read it as the price, not as a change to\n // it. \"Discount -EUR 2.50\" needs no interpreting, and the word is what makes\n // the default configuration legible without the merchant touching anything.\n surchargeLabel: 'labelled',\n // The two directions default differently on purpose, which is the whole\n // reason they are two settings. A fee is something a buyer acts on in money,\n // so it leads with money and says nothing else. A saving is something worth\n // advertising, and the share is the persuasive half of it — \"-5.1% (EUR\n // 2.50)\" sells what \"-EUR 2.50\" merely states, and the amount is still right\n // there beside it.\n surchargeFigure: 'amount',\n discountFigure: 'percentThenAmount',\n // Empty: the checkout's own localized words are the default, in every\n // language it ships. A merchant fills these in only to say it differently.\n surchargeWordTranslations: {},\n discountWordTranslations: {},\n // amber-700 / emerald-700, not the 600s: the `plain` style renders the\n // disclosure as coloured TEXT, so it is bound by `WCAG_AA_TEXT` (4.5) rather\n // than by the 3:1 a coloured shape would be, and the 600s come to 3.19 and\n // 3.77 against the default white surface. These are 5.02 and 5.48, pinned by\n // tests. Far enough apart to read as opposite news at a glance rather than as\n // two shades of \"extra\".\n surchargeColor: '#b45309',\n discountColor: '#047857',\n\n layout: 'split',\n summaryPosition: 'left',\n showOrderSummary: true,\n summaryGradient: false,\n showTotal: true,\n totalLabel: 'Total',\n showCurrencyCode: false,\n showOrderItems: true,\n cancelLinkEnabled: true,\n cancelLinkPosition: 'top',\n cancelLinkStyle: 'link',\n\n // Each flat field keeps its meaning: what the merchant wrote, used in every\n // locale that carries no override. Empty maps therefore change nothing for a\n // profile saved before translations existed.\n headerText: '',\n headerTextTranslations: {},\n payButtonLabel: '',\n payButtonLabelTranslations: {},\n cardTermsMessage: '',\n cardTermsMessageTranslations: {},\n footerText: '',\n footerTextTranslations: {},\n supportEmail: '',\n\n paymentLayout: 'tabs',\n labelStyle: 'above',\n showPoweredBy: true,\n\n // Every one of these defaults to what the Airwallex pane already did before\n // the section existed, so a merchant who never opens it sees no change:\n // empty preset (defer to the connector account), an outlined box, 16px /\n // 500 type, no focus ring, the browser's own autofill highlight, no valid\n // tint, no marks. The single deliberate change of behaviour is not here —\n // it is the fallback at the END of `resolveAirwallexCardPreset`, which\n // moves a shop that configured NOTHING from the combined row to the\n // labelled split form.\n airwallexCardPreset: '',\n // Off. With this on, no buyer can pay by card on the shop.\n airwallexHideCard: false,\n // Off: the section is named, like every other section on the surface.\n airwallexHideCardTitle: false,\n airwallexFieldChrome: 'outlined',\n airwallexLabelStyle: '',\n airwallexFieldFontSize: 'md',\n airwallexFieldWeight: 'medium',\n airwallexFocusRing: 'none',\n airwallexAutofill: 'system',\n airwallexValidTint: false,\n airwallexNetworkMarks: false,\n\n // Every card-form field below starts on what its pane drew before the\n // setting existed, so a merchant who never opens a section sees no change.\n stripeTheme: 'auto',\n stripeInputs: 'spaced',\n stripeLabels: 'above',\n stripeSpacing: 'comfortable',\n stripeFieldFontSize: 'md',\n stripeFieldWeight: 'medium',\n stripeFocusRing: 'strong',\n stripeDisableAnimations: false,\n paypalCardLayout: 'split',\n paypalLabelStyle: 'above',\n paypalFieldChrome: 'outlined',\n mollieFieldChrome: 'outlined',\n paypalFieldFontSize: 'md',\n mollieFieldFontSize: 'md',\n paypalFieldWeight: 'regular',\n mollieFieldWeight: 'regular',\n paypalFocusRing: 'strong',\n mollieFocusRing: 'strong',\n paypalValidTint: false,\n nomupayFormStyle: 'plain',\n nomupayShowLabels: true,\n nomupayShowPlaceholders: true,\n nomupayShowCvvHint: false,\n nomupayFieldChrome: 'outlined',\n nomupayFieldFontSize: 'md',\n nomupayFocusRing: 'none',\n nomupayApplePayButtonStyle: 'auto',\n nomupayApplePayButtonType: 'pay',\n nomupayGooglePayButtonColor: 'auto',\n nomupayGooglePayButtonType: 'pay',\n micropaymentFieldChrome: 'outlined',\n micropaymentFieldFontSize: 'md',\n micropaymentFieldWeight: 'regular',\n micropaymentFocusRing: 'strong',\n whopCardPreset: 'card_stacked',\n whopAccentColor: 'auto',\n whopGrayColor: 'auto',\n whopBillingDetails: 'minimal',\n whopSeparated: false,\n whopEmailLabel: 'above',\n whopFieldChrome: 'outlined',\n whopFieldFontSize: 'md',\n whopFieldWeight: 'regular',\n whopFocusRing: 'strong',\n whopRadius: 'checkout',\n whopShadow: 'soft',\n whopMethodIcons: true,\n whopSelection: 'radio_tint',\n\n customCss: '',\n};\n\nexport const DEFAULT_BRANDING: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n ...LIGHT_PALETTE,\n // No badges by default any more — notices took their place.\n // `DEFAULT_BADGES` stays exported because `isDefaultBadgeSet` still has to\n // recognise the pair on shops saved before.\n trustBadges: [],\n notices: defaultNotices(),\n customFields: [],\n methodSectionOrder: defaultMethodSectionOrder(),\n methodSectionLabels: {},\n};\n\n// Dark counterpart to DEFAULT_BRANDING. Same form-only fields stay empty\n// (logo / display name / tagline / copy) — only visual tokens diverge.\n// Palette mirrors the design-guidelines dark ramp:\n// - background = slate-950, surface = slate-900 → soft contrast.\n// - text = slate-200, heading = slate-50 → AA+ contrast on the surface.\n// - muted = slate-400, border = slate-800 → chrome that fades into the bg.\n// - accentText = primary-400, button bg = brand blue → brand pops on dark\n// where the light theme's near-black navy CTA would disappear.\n// - surfaceStyle = 'flat' because soft drop-shadows don't read on dark\n// surfaces; the existing 'elevated' shadow tokens are tuned for light.\nexport const DEFAULT_BRANDING_DARK: CheckoutBranding = {\n ...DEFAULT_BRANDING_BASE,\n primary: '#1E4FEB',\n background: '#020617',\n surface: '#0f172a',\n text: '#e2e8f0',\n heading: '#f8fafc',\n muted: '#94a3b8',\n border: '#1e293b',\n accentText: '#60a5fa',\n buttonBackground: '#1E4FEB',\n buttonText: '#ffffff',\n surfaceStyle: 'flat',\n // amber-400 / emerald-400: the 700s above are far too dark to read on\n // slate-900, and this pair is the same news in the same order at the light\n // end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.\n surchargeColor: '#fbbf24',\n discountColor: '#34d399',\n trustBadges: [],\n notices: defaultNotices(),\n customFields: [],\n methodSectionOrder: defaultMethodSectionOrder(),\n methodSectionLabels: {},\n};\n\n// Back-compat alias. Prefer `DEFAULT_BRANDING` directly.\nexport function defaultBranding(): CheckoutBranding {\n return cloneBranding(DEFAULT_BRANDING);\n}\n\n// Deep-ish clone — needed because the form mutates state reactively and we\n// don't want shared TrustBadge / CheckoutCustomField object refs across the\n// loaded/edit/default snapshots. Spread is shallow; array elements would\n// otherwise be shared between snapshots, breaking reset.\nexport function cloneBranding(b: CheckoutBranding): CheckoutBranding {\n return {\n ...b,\n trustBadges: b.trustBadges.map((badge) => ({ ...badge })),\n notices: b.notices.map(cloneNotice),\n customFields: b.customFields.map(cloneCustomField),\n methodSectionOrder: { ...b.methodSectionOrder },\n methodSectionLabels: Object.fromEntries(\n Object.entries(b.methodSectionLabels).map(([id, byLocale]) => [id, { ...byLocale }]),\n ),\n // Copied, not shared. A spread alone would leave the clone pointing at the\n // original's maps, and the dashboard edits a clone precisely so the form\n // can be abandoned without touching what is saved.\n surchargeWordTranslations: { ...b.surchargeWordTranslations },\n discountWordTranslations: { ...b.discountWordTranslations },\n headerTextTranslations: { ...b.headerTextTranslations },\n payButtonLabelTranslations: { ...b.payButtonLabelTranslations },\n cardTermsMessageTranslations: { ...b.cardTermsMessageTranslations },\n footerTextTranslations: { ...b.footerTextTranslations },\n };\n}\n\nexport function cloneCustomField(f: CheckoutCustomField): CheckoutCustomField {\n return {\n ...f,\n labelTranslations: { ...f.labelTranslations },\n placeholderTranslations: { ...f.placeholderTranslations },\n helpTextTranslations: { ...f.helpTextTranslations },\n options: f.options.map((o) => ({ ...o, labelTranslations: { ...o.labelTranslations } })),\n visibility: {\n ...f.visibility,\n conditions: f.visibility.conditions.map((c) => ({ ...c })),\n },\n };\n}\n\n// --- Sanitizer ----------------------------------------------------------\n\n// Hard cap on the persisted custom CSS payload. Mirrors the editor's\n// validation; oversized input is dropped to null rather than truncated,\n// since a half-truncated rule is worse than no rule.\nexport const CUSTOM_CSS_MAX_LENGTH = 50_000;\n\n// Strip CSS tokens that turn a stylesheet into a delivery vector before\n// handing the merchant's input to the renderer. The list isn't exhaustive\n// — it's the everyday surface area:\n//\n// - `</style` would let injected text break out of the <style> block and\n// parse as HTML/JS. Replaced with a benign token (not removed) so\n// `</styled-tag` (unlikely but possible inside a content: string)\n// doesn't silently merge into surrounding text.\n// - `@import` would let the merchant pull in a remote stylesheet on\n// every buyer page-load (analytics by side-channel; possible buyer-IP\n// leak).\n// - `expression(…)` was a legacy IE construct that ran JS from CSS.\n// - `behavior:` and `-moz-binding:` ditto for IE/old-Gecko.\n// - `javascript:` URLs in url(...) execute on resource load in some\n// browsers/contexts.\n//\n// Anything else passes through. The merchant can still write whatever\n// declarations they like (background images, gradients, transforms,\n// keyframes, container queries, …).\nexport function sanitizeCustomCss(raw: string | null | undefined): string | null {\n if (typeof raw !== 'string') return null;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n if (trimmed.length > CUSTOM_CSS_MAX_LENGTH) return null;\n\n let out = trimmed;\n out = out.replace(/<\\/style/gi, '<\\\\/style');\n out = out.replace(/@import\\b[^;]*;?/gi, '');\n out = out.replace(/expression\\s*\\(/gi, '/* expression( */');\n out = out.replace(/(^|[^a-z-])behavior\\s*:/gi, '$1/* behavior: */');\n out = out.replace(/-moz-binding\\s*:/gi, '/* -moz-binding: */');\n out = out.replace(/url\\s*\\(\\s*[\"']?\\s*javascript:/gi, 'url(invalid:');\n return out;\n}\n\n// --- Codec --------------------------------------------------------------\n\n// Structural shape the decoder reads. Both `CheckoutDetails` (public buyer\n// payload) and `BusinessPaymentLinkConfig` (merchant config request shape)\n// satisfy this via duck typing — they each fill some of these and leave the\n// rest undefined. `merchant_*` and `seller_*`/`logo` are aliases for the\n// same API field, surfaced under different names by the two payloads.\nexport interface BrandingSource {\n // Identity (one or the other, depending on payload shape)\n merchant_name?: string | null;\n seller_name?: string | null;\n merchant_logo?: string | null;\n logo?: string | null;\n merchant_description?: string | null;\n\n // Visual\n theme?: string | null;\n background_colour?: string | null;\n payment_button_colour?: string | null;\n payment_button_text_colour?: string | null;\n\n // Copy\n payment_form_header_text?: string | null;\n payment_button_text?: string | null;\n custom_message_for_card_terms?: string | null;\n\n // Footer\n branding_visibility?: boolean | null;\n\n // Stripe\n sdk_layout?: string | null;\n payment_form_label_type?: string | null;\n\n // The bag for everything else\n sdk_ui_rules?: Record<string, Record<string, string> | null | undefined> | null;\n}\n\nconst BRANDING_GROUP_KEY = 'branding';\n\nconst ALL_FONT_FAMILIES: readonly FontFamily[] = [\n 'inter',\n 'system',\n 'serif',\n 'mono',\n 'roboto',\n 'poppins',\n 'manrope',\n 'dm-sans',\n 'space-grotesk',\n 'plex-sans',\n 'work-sans',\n 'open-sans',\n 'lora',\n 'playfair',\n 'plex-mono',\n 'jetbrains-mono',\n];\n\nconst ALL_RADII: readonly CornerRadius[] = ['square', 'small', 'medium', 'large', 'pill'];\nconst NON_PILL_RADII: readonly NonPillRadius[] = ['square', 'small', 'medium', 'large'];\n\nfunction pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {\n if (typeof value !== 'string') return fallback;\n return (allowed as readonly string[]).includes(value) ? (value as T) : fallback;\n}\n\n/**\n * `pickEnum` for a field whose \"unset\" state is the empty string.\n *\n * Anything not on the list — absent, blank, or a token this build has not\n * heard of — decodes to `''`, which every consumer reads as \"defer\". That is\n * the difference between this and `pickEnum`: there the unknown becomes a\n * concrete value and starts overriding whatever it was deferring to.\n */\nfunction pickEnumOrEmpty<T extends string>(value: unknown, allowed: readonly T[]): T | '' {\n if (typeof value !== 'string') return '';\n return (allowed as readonly string[]).includes(value) ? (value as T) : '';\n}\n\nfunction parseBool(value: unknown, fallback: boolean): boolean {\n if (typeof value === 'boolean') return value;\n if (value === 'true') return true;\n if (value === 'false') return false;\n return fallback;\n}\n\nfunction s(value: string | null | undefined): string {\n return typeof value === 'string' ? value : '';\n}\n\n// Decode the JSON-encoded trust badges stored under\n// `sdk_ui_rules.branding.trustBadges`. Tolerant: a malformed payload,\n// missing fields, or wrong types fall through to null so the caller can\n// substitute the default badge set. An explicit empty array means \"no\n// badges\" (we honor it — merchants who hide the row need a way to express\n// that).\nexport function decodeBadges(raw: string | undefined): TrustBadge[] | null {\n if (raw === undefined) return null;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return null;\n return parsed\n .filter((b): b is Record<string, unknown> => !!b && typeof b === 'object')\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor: typeof b['textColor'] === 'string' ? (b['textColor'] as string) : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' ? (b['backgroundColor'] as string) : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && b['borderColor']\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n } catch {\n return null;\n }\n}\n\nexport function encodeBadges(badges: TrustBadge[]): string {\n return JSON.stringify(\n badges.map((b) => ({\n id: b.id,\n label: b.label,\n textColor: b.textColor,\n backgroundColor: b.backgroundColor,\n ...(b.borderColor ? { borderColor: b.borderColor } : {}),\n })),\n );\n}\n\n// --- Notices codec --------------------------------------------\n\n/** A notice id is code-shaped: it keys a drag, never a buyer's eyes. */\nconst NOTICE_ID_MAX_LENGTH = 40;\n\nfunction capNoticeText(value: string): string {\n return Array.from(value).slice(0, NOTICE_LABEL_MAX_LENGTH).join('');\n}\n\n/**\n * Normalize a list of notices from any source — the bag, an import file.\n *\n * Total, like `decodeBadges`: every buyer sees these, so a malformed entry\n * degrades to a smaller list, never to a broken page.\n *\n * - not an object → dropped;\n * - unknown section → `summary`; unknown icon → `NOTICE_ICON_FALLBACK`;\n * - id cleaned to `[A-Za-z0-9_-]`, a missing or repeated one replaced, so the\n * editor can track every row across a drag;\n * - text cut to `NOTICE_LABEL_MAX_LENGTH` characters, blank overrides dropped;\n * - a notice with no text in any language → dropped (it would draw an icon\n * with nothing beside it);\n * - past `NOTICES_PER_SECTION` in its section → dropped, first come first\n * kept, so what is stored is what is drawn.\n */\nfunction normalizeNotices(list: readonly unknown[]): CheckoutNotice[] {\n const seen = new Set<string>();\n const perSection = new Map<NoticeSection, number>();\n const out: CheckoutNotice[] = [];\n\n list.forEach((raw, index) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return;\n const src = raw as Record<string, unknown>;\n\n const label = typeof src['label'] === 'string' ? capNoticeText(src['label']) : '';\n const labelTranslations: CustomFieldTranslations = {};\n for (const [locale, text] of Object.entries(parseTranslations(src['labelTranslations']))) {\n labelTranslations[locale] = capNoticeText(text);\n }\n if (label.trim().length === 0 && Object.keys(labelTranslations).length === 0) return;\n\n const section = pickEnum<NoticeSection>(src['section'], NOTICE_SECTIONS, 'summary');\n const used = perSection.get(section) ?? 0;\n if (used >= NOTICES_PER_SECTION) return;\n perSection.set(section, used + 1);\n\n let id =\n typeof src['id'] === 'string'\n ? src['id'].replace(/[^A-Za-z0-9_-]/g, '').slice(0, NOTICE_ID_MAX_LENGTH)\n : '';\n if (!id || seen.has(id)) id = `notice-${index + 1}`;\n while (seen.has(id)) id = `${id}x`;\n seen.add(id);\n\n out.push({\n id,\n section,\n icon: isNoticeIcon(src['icon']) ? src['icon'] : NOTICE_ICON_FALLBACK,\n label,\n labelTranslations,\n });\n });\n\n return out;\n}\n\n/**\n * Decode `sdk_ui_rules.branding.notices`.\n *\n * `null` when the key is absent or not a JSON array — \"this shop has no say\n * about notices\", which `resolveNoticesAndBadges` turns into the migration.\n * An empty array is a say: the merchant removed every notice.\n */\nexport function decodeNotices(raw: string | undefined): CheckoutNotice[] | null {\n if (raw === undefined) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n return Array.isArray(parsed) ? normalizeNotices(parsed) : null;\n}\n\n/** The import file's form: an array inline rather than a JSON string. */\nexport function parseNoticesLoose(raw: unknown): CheckoutNotice[] | null {\n if (typeof raw === 'string') return decodeNotices(raw);\n return Array.isArray(raw) ? normalizeNotices(raw) : null;\n}\n\n/**\n * Encode notices for the bag. Always a JSON array, `[]` included: the key's\n * presence is what tells a later decode that the shop has decided, so it must\n * be written even when there is nothing in it.\n */\nexport function encodeNotices(notices: readonly CheckoutNotice[]): string {\n return JSON.stringify(\n notices.map((n) => {\n const translations = Object.entries(n.labelTranslations).filter(\n ([, text]) => text.trim().length > 0,\n );\n return {\n id: n.id,\n section: n.section,\n icon: n.icon,\n label: n.label,\n ...(translations.length > 0 ? { labelTranslations: Object.fromEntries(translations) } : {}),\n };\n }),\n );\n}\n\n/**\n * A notice's text in the buyer's locale: exact locale, then its base\n * language, then the default text — the order every other piece of merchant\n * copy resolves in (`checkoutCopy`, `customFieldText`).\n *\n * `''` when the notice has no text for this locale: a notice written only in\n * some languages, with no default, is one the merchant shows only in those\n * languages (the POC's \"empty means: not in this language\"). It is not a\n * notice to draw without words — use `shownNotices`, which leaves it out.\n */\nexport function noticeText(notice: CheckoutNotice, locale?: string): string {\n return translationFor(notice.labelTranslations, locale) ?? notice.label;\n}\n\n/**\n * The notices one section draws, in order, capped at `NOTICES_PER_SECTION`.\n * The decoder already caps; this caps again for state that never went through\n * it, such as the customizer's unsaved edits in the live preview.\n */\nexport function noticesIn(\n notices: readonly CheckoutNotice[],\n section: NoticeSection,\n): CheckoutNotice[] {\n return notices.filter((n) => n.section === section).slice(0, NOTICES_PER_SECTION);\n}\n\n/** One notice as a buyer sees it: the notice, and its text in their locale. */\nexport interface ShownNotice {\n notice: CheckoutNotice;\n text: string;\n}\n\n/**\n * What one section draws for a buyer: its notices (capped, as `noticesIn`),\n * each with its text in `locale`, leaving out every notice with no text there.\n *\n * The one place that decides it, so no renderer can draw an icon with nothing\n * beside it. A notice written only in German is simply absent for an English\n * buyer — the cap is applied first, as the decoder applies it, so what a\n * merchant stored in a section is what can ever be drawn from it.\n */\nexport function shownNotices(\n notices: readonly CheckoutNotice[],\n section: NoticeSection,\n locale?: string,\n): ShownNotice[] {\n return noticesIn(notices, section)\n .map((notice) => ({ notice, text: noticeText(notice, locale).trim() }))\n .filter((entry) => entry.text.length > 0);\n}\n\n// --- Custom checkout fields codec ---------------------------------------\n\nexport const CUSTOM_FIELDS_MAX = 20;\n// Metadata keys: start with a letter, then letters/digits/underscore/dash.\n// Keeps keys safe for every downstream metadata consumer (dashboards,\n// exports, PSP forwarding).\nexport const CUSTOM_FIELD_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;\n\nexport const ALL_CUSTOM_FIELD_TYPES: readonly CustomFieldType[] = [\n 'text',\n 'textarea',\n 'password',\n 'email',\n 'select',\n 'checkbox',\n];\n\n// The two values a checkbox field ever submits. Kept as strings because the\n// whole metadata bag is `Record<string, string>` on the wire.\nexport const CHECKBOX_CHECKED = 'true';\nexport const CHECKBOX_UNCHECKED = 'false';\n\n/** Whether a stored/submitted checkbox value counts as ticked. Tolerant of\n * case and padding so a value round-tripped through a shop integration\n * ('True', ' true ') still reads correctly. */\nexport function isCheckboxChecked(value: string | null | undefined): boolean {\n return typeof value === 'string' && value.trim().toLowerCase() === CHECKBOX_CHECKED;\n}\n\n/** Types whose value is free text, so length bounds and a placeholder apply.\n * `select` and `checkbox` are choice controls and have neither. */\nexport function customFieldIsTextLike(type: CustomFieldType): boolean {\n return type !== 'select' && type !== 'checkbox';\n}\n\n// Rule-builder vocabulary. Kept next to the codec so the editor, the\n// evaluator and the Rust mirror all read from one list.\nexport const CUSTOM_FIELD_CONDITIONS_MAX = 10;\n\nexport const ALL_CUSTOM_FIELD_CONDITION_SOURCES: readonly CustomFieldConditionSource[] = [\n 'metadata',\n 'currency',\n 'amount',\n];\n\nexport const ALL_CUSTOM_FIELD_OPERATORS: readonly CustomFieldOperator[] = [\n 'equals',\n 'not_equals',\n 'contains',\n 'not_contains',\n 'starts_with',\n 'ends_with',\n 'in',\n 'not_in',\n 'exists',\n 'not_exists',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n];\n\n// Which operators make sense per source. Currency is a closed 3-letter set,\n// so substring/numeric operators would only ever confuse; amount is numeric,\n// so string operators don't apply. Metadata is free-form and gets all of them.\nexport const CUSTOM_FIELD_OPERATORS_BY_SOURCE: Record<\n CustomFieldConditionSource,\n readonly CustomFieldOperator[]\n> = {\n metadata: ALL_CUSTOM_FIELD_OPERATORS,\n currency: ['equals', 'not_equals', 'in', 'not_in'],\n amount: ['equals', 'not_equals', 'gt', 'gte', 'lt', 'lte'],\n};\n\n// Operators that ignore the right-hand operand — the editor hides the value\n// input for these, and validation must not demand a value.\nexport const CUSTOM_FIELD_VALUELESS_OPERATORS: readonly CustomFieldOperator[] = [\n 'exists',\n 'not_exists',\n];\n\nexport function customFieldOperatorTakesValue(operator: CustomFieldOperator): boolean {\n return !CUSTOM_FIELD_VALUELESS_OPERATORS.includes(operator);\n}\n\n// The operator a condition falls back to when its source changes and the\n// current operator isn't valid for the new source.\nexport function defaultOperatorForSource(source: CustomFieldConditionSource): CustomFieldOperator {\n return CUSTOM_FIELD_OPERATORS_BY_SOURCE[source][0] ?? 'equals';\n}\n\nexport function defaultCustomFieldVisibility(): CustomFieldVisibility {\n return { mode: 'always', match: 'all', conditions: [] };\n}\n\nfunction parseTranslations(raw: unknown): CustomFieldTranslations {\n // The branding bag stores every value as a string, so a map persisted there\n // arrives as JSON; an import file and a custom field carry it inline. Both\n // reach this, and a string that is not JSON is simply not a map.\n let value = raw;\n if (typeof value === 'string') {\n try {\n value = JSON.parse(value) as unknown;\n } catch {\n return {};\n }\n }\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n const out: CustomFieldTranslations = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n // Own properties only: a persisted key of `__proto__` or `constructor`\n // must not reach the object being built, and `Object.entries` already\n // gives own enumerable keys only — the length check is what drops a blank\n // override, which means \"no override\" rather than \"render nothing\".\n if (typeof v === 'string' && v.trim().length > 0) out[k] = v;\n }\n return out;\n}\n\n/**\n * A translations map for the branding bag, or `undefined` when there is\n * nothing to store.\n *\n * Omitting the key rather than writing `{}` keeps the bag of a merchant who\n * never opened the translations strip byte-identical to what it was before\n * these fields existed.\n */\nfunction encodeTranslations(map: CustomFieldTranslations): string | undefined {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? JSON.stringify(Object.fromEntries(entries)) : undefined;\n}\n\n// Normalize one persisted condition. Total: an unusable source/operator\n// falls back rather than dropping the row, so a rule authored by a newer\n// control-center never silently becomes \"always visible\" on an older\n// decoder — it becomes a stricter, still-evaluable rule.\nfunction normalizeCondition(raw: unknown, index: number): CustomFieldCondition | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const c = raw as Record<string, unknown>;\n const source = pickEnum<CustomFieldConditionSource>(\n c['source'],\n ALL_CUSTOM_FIELD_CONDITION_SOURCES,\n 'metadata',\n );\n const allowed = CUSTOM_FIELD_OPERATORS_BY_SOURCE[source];\n const operator = pickEnum<CustomFieldOperator>(\n c['operator'],\n allowed,\n defaultOperatorForSource(source),\n );\n const rawValue = c['value'];\n return {\n id: typeof c['id'] === 'string' && c['id'] ? (c['id'] as string) : `cond-${index}`,\n source,\n // Only metadata conditions carry a key; drop anything else so the\n // encoded form stays canonical.\n key: source === 'metadata' && typeof c['key'] === 'string' ? c['key'].trim() : '',\n operator,\n value:\n typeof rawValue === 'string'\n ? rawValue\n : typeof rawValue === 'number' || typeof rawValue === 'boolean'\n ? String(rawValue)\n : '',\n };\n}\n\nfunction normalizeVisibility(raw: unknown): CustomFieldVisibility {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return defaultCustomFieldVisibility();\n const v = raw as Record<string, unknown>;\n const conditions: CustomFieldCondition[] = Array.isArray(v['conditions'])\n ? (v['conditions'] as unknown[])\n .slice(0, CUSTOM_FIELD_CONDITIONS_MAX)\n .map(normalizeCondition)\n .filter((c): c is CustomFieldCondition => c !== null)\n : [];\n return {\n mode: pickEnum<'always' | 'match'>(v['mode'], ['always', 'match'], 'always'),\n match: pickEnum<'all' | 'any'>(v['match'], ['all', 'any'], 'all'),\n conditions,\n };\n}\n\nfunction parseBoundedInt(raw: unknown): number | null {\n const n = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : NaN;\n if (!Number.isInteger(n) || n < 0) return null;\n return Math.min(n, 5000);\n}\n\n// Normalize one persisted/imported field object. Total: anything malformed\n// falls back per-property; returns null only when there is no usable key.\nfunction normalizeCustomField(raw: unknown, index: number): CheckoutCustomField | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const f = raw as Record<string, unknown>;\n const key = typeof f['key'] === 'string' ? f['key'].trim() : '';\n if (!CUSTOM_FIELD_KEY_PATTERN.test(key)) return null;\n\n const type = pickEnum<CustomFieldType>(f['type'], ALL_CUSTOM_FIELD_TYPES, 'text');\n\n const options: CustomFieldOption[] =\n type === 'select' && Array.isArray(f['options'])\n ? (f['options'] as unknown[])\n .filter((o): o is Record<string, unknown> => !!o && typeof o === 'object')\n .map((o) => {\n const value = typeof o['value'] === 'string' ? o['value'] : '';\n return {\n value,\n label: typeof o['label'] === 'string' && o['label'] ? (o['label'] as string) : value,\n labelTranslations: parseTranslations(o['labelTranslations']),\n };\n })\n .filter((o) => o.value.length > 0)\n : [];\n\n // Length bounds are meaningless for choice controls; drop them at decode\n // so a field switched to checkbox/select can't carry stale bounds that\n // would then be validated against 'true'/'false'.\n const textLike = customFieldIsTextLike(type);\n const minLength = textLike ? parseBoundedInt(f['minLength']) : null;\n const maxLength = textLike ? parseBoundedInt(f['maxLength']) : null;\n\n // A checkbox default is a tick state, not free text: anything that isn't\n // truthy normalizes to unchecked, so the control can never start in a\n // third state.\n const rawDefault = typeof f['defaultValue'] === 'string' ? f['defaultValue'] : '';\n const defaultValue =\n type === 'checkbox'\n ? isCheckboxChecked(rawDefault)\n ? CHECKBOX_CHECKED\n : CHECKBOX_UNCHECKED\n : rawDefault;\n\n return {\n id: typeof f['id'] === 'string' && f['id'] ? (f['id'] as string) : `field-${index}`,\n key,\n type,\n label: typeof f['label'] === 'string' && f['label'] ? (f['label'] as string) : key,\n labelTranslations: parseTranslations(f['labelTranslations']),\n placeholder: typeof f['placeholder'] === 'string' ? (f['placeholder'] as string) : '',\n placeholderTranslations: parseTranslations(f['placeholderTranslations']),\n helpText: typeof f['helpText'] === 'string' ? (f['helpText'] as string) : '',\n helpTextTranslations: parseTranslations(f['helpTextTranslations']),\n required: parseBool(f['required'], false),\n enabled: parseBool(f['enabled'], true),\n minLength,\n // Guard inverted bounds at decode so consumers never see min > max.\n maxLength: maxLength !== null && minLength !== null && maxLength < minLength ? null : maxLength,\n defaultValue,\n options,\n visibility: normalizeVisibility(f['visibility']),\n };\n}\n\n// Parse an array of field objects (already JSON-parsed). Null when the\n// input isn't an array — callers fall back to \"no custom fields\". Duplicate\n// keys keep the first occurrence; the list is capped at CUSTOM_FIELDS_MAX.\nexport function parseCustomFieldsLoose(raw: unknown): CheckoutCustomField[] | null {\n if (!Array.isArray(raw)) return null;\n const seen = new Set<string>();\n const out: CheckoutCustomField[] = [];\n for (let i = 0; i < raw.length && out.length < CUSTOM_FIELDS_MAX; i++) {\n const field = normalizeCustomField(raw[i], i);\n if (!field || seen.has(field.key)) continue;\n seen.add(field.key);\n out.push(field);\n }\n return out;\n}\n\n// Decode the JSON-encoded custom fields stored under\n// `sdk_ui_rules.branding.customFields`. Tolerant like `decodeBadges`:\n// malformed payloads fall through to null.\nexport function decodeCustomFields(raw: string | undefined): CheckoutCustomField[] | null {\n if (raw === undefined) return null;\n try {\n return parseCustomFieldsLoose(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nexport function encodeCustomFields(fields: CheckoutCustomField[]): string {\n const nonEmpty = (m: CustomFieldTranslations): CustomFieldTranslations | undefined => {\n const entries = Object.entries(m).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return JSON.stringify(\n fields.map((f) => ({\n id: f.id,\n key: f.key,\n type: f.type,\n label: f.label,\n ...(nonEmpty(f.labelTranslations)\n ? { labelTranslations: nonEmpty(f.labelTranslations) }\n : {}),\n ...(f.placeholder ? { placeholder: f.placeholder } : {}),\n ...(nonEmpty(f.placeholderTranslations)\n ? { placeholderTranslations: nonEmpty(f.placeholderTranslations) }\n : {}),\n ...(f.helpText ? { helpText: f.helpText } : {}),\n ...(nonEmpty(f.helpTextTranslations)\n ? { helpTextTranslations: nonEmpty(f.helpTextTranslations) }\n : {}),\n ...(f.required ? { required: true } : {}),\n ...(f.enabled ? {} : { enabled: false }),\n // Length bounds only exist for free-text types; a choice control that\n // still carries them is stale state the decoder would drop anyway.\n ...(customFieldIsTextLike(f.type) && f.minLength !== null ? { minLength: f.minLength } : {}),\n ...(customFieldIsTextLike(f.type) && f.maxLength !== null ? { maxLength: f.maxLength } : {}),\n // A checkbox persists only \"starts ticked\"; unticked is the decoder's\n // default, so writing 'false' would be noise on every such field.\n ...(f.type === 'checkbox'\n ? isCheckboxChecked(f.defaultValue)\n ? { defaultValue: CHECKBOX_CHECKED }\n : {}\n : f.defaultValue\n ? { defaultValue: f.defaultValue }\n : {}),\n ...(f.type === 'select' ? { options: f.options } : {}),\n // Omitted for unconditional fields so the stored blob (and every\n // pre-feature payload) stays byte-identical to what it was.\n ...(f.visibility.mode === 'match' ? { visibility: encodeVisibility(f.visibility) } : {}),\n })),\n );\n}\n\nfunction encodeVisibility(v: CustomFieldVisibility): Record<string, unknown> {\n return {\n mode: v.mode,\n match: v.match,\n conditions: v.conditions.map((c) => ({\n id: c.id,\n source: c.source,\n ...(c.source === 'metadata' && c.key ? { key: c.key } : {}),\n operator: c.operator,\n ...(customFieldOperatorTakesValue(c.operator) && c.value ? { value: c.value } : {}),\n })),\n };\n}\n\n// --- Conditional-visibility evaluator -----------------------------------\n\n/** Facts a rule can read. `amount` is in the currency's minor unit (what\n * the payment intent stores); `metadata` values are already flattened to\n * strings by `customFieldContextFromMetadata`. */\nexport interface CustomFieldContext {\n amount: number;\n currency: string;\n metadata: Record<string, string>;\n}\n\n/** Flatten a payment's raw `metadata` object into the string map a rule\n * compares against. Arrays join on `,` so a list-shaped value stays usable\n * with `contains` / `in`; objects fall back to JSON. Mirrors the Rust\n * side's `flatten_metadata`. */\nexport function customFieldContextFromMetadata(raw: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return out;\n for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {\n const flat = flattenMetadataValue(value);\n if (flat !== null) out[key] = flat;\n }\n return out;\n}\n\nfunction flattenMetadataValue(value: unknown): string | null {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) {\n return value\n .map((v) => flattenMetadataValue(v))\n .filter((v): v is string => v !== null)\n .join(',');\n }\n try {\n return JSON.stringify(value);\n } catch {\n return null;\n }\n}\n\n// Case- and whitespace-insensitive: merchants type `Windows` in the builder\n// and the shop sends `windows`. Exact-case matching would be a support\n// ticket generator.\nfunction norm(value: string): string {\n return value.trim().toLowerCase();\n}\n\n// Decimal-float grammar, deliberately narrower than `Number()`.\n//\n// `Number()` accepts radix-prefixed literals — `Number('0x10') === 16` — while\n// the router's Rust mirror uses `f64::from_str`, which rejects them. Left\n// unconstrained, a metadata value of `0x10` would satisfy `gte 5` in the\n// control-center's builder and fail it on the backend: the merchant sees one\n// rule, buyers get another. This regex is `f64::from_str`'s number grammar\n// (sign, digits with optional point, optional exponent); `inf`/`nan` are\n// excluded here rather than by the finiteness check below, which matches\n// Rust filtering them out too.\nconst DECIMAL_NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n// Both implementations compare as f64, so they round identically. Payment\n// amounts in minor units are far below 2^53, where that is lossless.\nfunction numeric(value: string): number | null {\n const trimmed = value.trim();\n if (!DECIMAL_NUMBER_PATTERN.test(trimmed)) return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction splitList(value: string): string[] {\n return value\n .split(',')\n .map((part) => norm(part))\n .filter((part) => part.length > 0);\n}\n\n/** Resolve the left-hand operand. `undefined` means \"the metadata key is\n * absent\" — which only `exists`/`not_exists` distinguish from empty. */\nfunction operandFor(condition: CustomFieldCondition, ctx: CustomFieldContext): string | undefined {\n switch (condition.source) {\n case 'currency':\n return ctx.currency;\n case 'amount':\n return String(ctx.amount);\n case 'metadata':\n return Object.prototype.hasOwnProperty.call(ctx.metadata, condition.key)\n ? ctx.metadata[condition.key]\n : undefined;\n }\n}\n\nexport function evaluateCustomFieldCondition(\n condition: CustomFieldCondition,\n ctx: CustomFieldContext,\n): boolean {\n const raw = operandFor(condition, ctx);\n const actual = raw ?? '';\n const expected = condition.value;\n\n switch (condition.operator) {\n case 'exists':\n return raw !== undefined && raw.trim().length > 0;\n case 'not_exists':\n return raw === undefined || raw.trim().length === 0;\n case 'equals':\n return norm(actual) === norm(expected);\n case 'not_equals':\n return norm(actual) !== norm(expected);\n case 'contains':\n return norm(actual).includes(norm(expected));\n case 'not_contains':\n return !norm(actual).includes(norm(expected));\n case 'starts_with':\n return norm(actual).startsWith(norm(expected));\n case 'ends_with':\n return norm(actual).endsWith(norm(expected));\n case 'in':\n return splitList(expected).includes(norm(actual));\n case 'not_in':\n return !splitList(expected).includes(norm(actual));\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n // Both sides must be numbers. A non-numeric metadata value never\n // matches a numeric comparison (rather than coercing to 0).\n const a = numeric(actual);\n const b = numeric(expected);\n if (a === null || b === null) return false;\n if (condition.operator === 'gt') return a > b;\n if (condition.operator === 'gte') return a >= b;\n if (condition.operator === 'lt') return a < b;\n return a <= b;\n }\n }\n}\n\n/**\n * Whether a field's rule matches the payment.\n *\n * Fail-open in two spots, deliberately: `mode: 'always'` and a `match` rule\n * with no conditions both resolve to visible. A half-authored rule should\n * never silently swallow a field the merchant needs collected — the\n * control-center flags the empty rule as a validation issue instead.\n */\nexport function evaluateCustomFieldVisibility(\n field: CheckoutCustomField,\n ctx: CustomFieldContext,\n): boolean {\n const { mode, match, conditions } = field.visibility;\n if (mode !== 'match' || conditions.length === 0) return true;\n return match === 'any'\n ? conditions.some((c) => evaluateCustomFieldCondition(c, ctx))\n : conditions.every((c) => evaluateCustomFieldCondition(c, ctx));\n}\n\n/** Filter a field list to what the buyer should see for this payment.\n * Disabled fields are dropped here too — the two reasons a field doesn't\n * render are the same to every consumer. */\nexport function visibleCustomFields(\n fields: CheckoutCustomField[],\n ctx: CustomFieldContext,\n): CheckoutCustomField[] {\n return fields.filter((f) => f.enabled && evaluateCustomFieldVisibility(f, ctx));\n}\n\n// Exact-locale-then-base-language lookup. Own-property + string checks so\n// a hostile or odd locale string ('constructor', '__proto__') can never\n// surface a prototype-chain member as a \"translation\".\n/**\n * Look up one locale's override, walking from most to least specific.\n *\n * Two things this does that an exact-then-base lookup did not, both of which\n * became reachable the moment `zh-Hant` joined the locale list:\n *\n * - **Every parent tag, not just the base.** `zh-Hant-TW` now finds a stored\n * `zh-Hant` before falling through to `zh`. Jumping straight to the base\n * skipped the script entirely, so a Taiwanese buyer read the merchant's\n * simplified copy while a `zh-Hant` box sat filled in beside it.\n * - **Case-insensitive keys.** Locale tags are case-insensitive by spec and\n * arrive both ways — `zh-hant` from a hand-written link, `zh-Hant` from the\n * dashboard. A case-sensitive miss looks exactly like \"no translation\".\n *\n * The map's own casing is preserved on write; only the comparison folds.\n */\nfunction translationFor(map: CustomFieldTranslations, locale?: string): string | null {\n if (!locale) return null;\n\n const folded = new Map<string, string>();\n for (const [k, v] of Object.entries(map)) {\n if (typeof v === 'string' && v.length > 0 && !folded.has(k.toLowerCase())) {\n folded.set(k.toLowerCase(), v);\n }\n }\n\n const parts = locale.toLowerCase().split('-');\n for (let i = parts.length; i > 0; i -= 1) {\n const hit = folded.get(parts.slice(0, i).join('-'));\n if (hit) return hit;\n }\n return null;\n}\n\n// Resolve the display string for a field part in a buyer locale.\n// Exact locale wins ('de-AT'), then its base language ('de'), then the\n// field's default-language string; labels finally fall back to the key so\n// a field is never rendered nameless.\nexport function customFieldText(\n field: CheckoutCustomField,\n part: 'label' | 'placeholder' | 'helpText',\n locale?: string,\n): string {\n const map =\n part === 'label'\n ? field.labelTranslations\n : part === 'placeholder'\n ? field.placeholderTranslations\n : field.helpTextTranslations;\n const translated = translationFor(map, locale);\n if (translated) return translated;\n const fallback = field[part];\n if (fallback) return fallback;\n return part === 'label' ? field.key : '';\n}\n\nexport function customFieldOptionLabel(option: CustomFieldOption, locale?: string): string {\n return translationFor(option.labelTranslations, locale) ?? (option.label || option.value);\n}\n\n// Read a branding source into a fully-resolved CheckoutBranding.\n// Flat fields are authoritative when set; the bag fills in everything not\n// reachable via flat columns. Persisted `labelStyle: 'floating'` (legacy\n// \"floating\" mock) decodes to `'above'`.\nexport function decodeBranding(source: BrandingSource | null | undefined): CheckoutBranding {\n if (!source) return cloneBranding(DEFAULT_BRANDING);\n\n const extras: Record<string, string> = (source.sdk_ui_rules?.[BRANDING_GROUP_KEY] ??\n {}) as Record<string, string>;\n\n // Badges and notices are decided together: which one a shop gets depends\n // on what it saved of both.\n const trustRow = resolveNoticesAndBadges(\n decodeBadges(extras['trustBadges']),\n decodeNotices(extras['notices']),\n );\n const decodedCustomFields = decodeCustomFields(extras['customFields']);\n\n // Identity name: public payloads call it `merchant_name`, request payloads\n // call it `seller_name`. Same API field; pick whichever is present.\n const displayName = s(source.merchant_name) || s(source.seller_name);\n const logoUrl = s(source.merchant_logo) || s(source.logo);\n\n // Tagline lives in the bag, but `merchant_description` is its public\n // surface. Either may fill it; bag wins if both are set.\n const tagline = s(extras['tagline']) || s(source.merchant_description);\n\n // Stripe label style: the bag's `labelStyle` is the new source of truth;\n // the legacy flat `payment_form_label_type` is consulted only when the\n // bag is empty. `'floating'` (a legacy preview-only value that Stripe\n // Elements never honored) decodes to `'above'`. `'never'` (legacy API\n // wording) decodes to `'hidden'`.\n const labelStyle: LabelStyle = (() => {\n const fromBag = extras['labelStyle'];\n if (fromBag === 'above' || fromBag === 'hidden') return fromBag;\n if (fromBag === 'floating') return 'above';\n const legacy = source.payment_form_label_type;\n if (legacy === 'above' || legacy === 'floating') return 'above';\n if (legacy === 'hidden' || legacy === 'never') return 'hidden';\n return DEFAULT_BRANDING.labelStyle;\n })();\n\n return {\n displayName,\n logoUrl,\n tagline,\n showLogo: parseBool(extras['showLogo'], DEFAULT_BRANDING.showLogo),\n logoShape: pickEnum<LogoShape>(\n extras['logoShape'],\n ['square', 'rounded', 'circle'],\n DEFAULT_BRANDING.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(extras['logoSize'], ['sm', 'md', 'lg'], DEFAULT_BRANDING.logoSize),\n\n primary: s(source.theme) || DEFAULT_BRANDING.primary,\n background: s(source.background_colour) || DEFAULT_BRANDING.background,\n surface: s(extras['surface']) || DEFAULT_BRANDING.surface,\n text: s(extras['text']) || DEFAULT_BRANDING.text,\n heading: s(extras['heading']) || s(extras['text']) || DEFAULT_BRANDING.heading,\n muted: s(extras['muted']) || DEFAULT_BRANDING.muted,\n border: s(extras['border']) || DEFAULT_BRANDING.border,\n accentText: s(extras['accentText']) || s(source.theme) || DEFAULT_BRANDING.accentText,\n buttonBackground:\n s(source.payment_button_colour) || s(source.theme) || DEFAULT_BRANDING.buttonBackground,\n buttonText: s(source.payment_button_text_colour) || DEFAULT_BRANDING.buttonText,\n\n fontFamily: pickEnum<FontFamily>(\n extras['fontFamily'],\n ALL_FONT_FAMILIES,\n DEFAULT_BRANDING.fontFamily,\n ),\n headingWeight: pickEnum<FontWeight>(\n extras['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n DEFAULT_BRANDING.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n extras['radiusSurface'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(\n extras['radiusInput'],\n NON_PILL_RADII,\n DEFAULT_BRANDING.radiusInput,\n ),\n radiusButton: pickEnum<CornerRadius>(\n extras['radiusButton'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusButton,\n ),\n radiusBadge: pickEnum<CornerRadius>(\n extras['radiusBadge'],\n ALL_RADII,\n DEFAULT_BRANDING.radiusBadge,\n ),\n surfaceStyle: pickEnum<SurfaceStyle>(\n extras['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n DEFAULT_BRANDING.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n extras['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n extras['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n DEFAULT_BRANDING.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(\n extras['inputSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.inputSize,\n ),\n buttonSize: pickEnum<SizeScale>(\n extras['buttonSize'],\n ['sm', 'md', 'lg'],\n DEFAULT_BRANDING.buttonSize,\n ),\n\n showSurcharge: parseBool(extras['showSurcharge'], DEFAULT_BRANDING.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n extras['surchargePosition'],\n SURCHARGE_POSITIONS,\n DEFAULT_BRANDING.surchargePosition,\n ),\n nativeElementStacked: parseBool(\n extras['nativeElementStacked'],\n DEFAULT_BRANDING.nativeElementStacked,\n ),\n nativeElementPosition: pickEnum<NativeElementPosition>(\n extras['nativeElementPosition'],\n NATIVE_ELEMENT_POSITIONS,\n DEFAULT_BRANDING.nativeElementPosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n extras['surchargeStyle'],\n SURCHARGE_STYLES,\n DEFAULT_BRANDING.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n extras['surchargeSize'],\n SURCHARGE_SIZES,\n DEFAULT_BRANDING.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n extras['surchargeShape'],\n SURCHARGE_SHAPES,\n DEFAULT_BRANDING.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n extras['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n DEFAULT_BRANDING.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n extras['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n DEFAULT_BRANDING.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n extras['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n DEFAULT_BRANDING.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n extras['surchargeSign'],\n SURCHARGE_SIGNS,\n DEFAULT_BRANDING.surchargeSign,\n ),\n surchargeUppercase: parseBool(\n extras['surchargeUppercase'],\n DEFAULT_BRANDING.surchargeUppercase,\n ),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n extras['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n DEFAULT_BRANDING.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n extras['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n extras['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n DEFAULT_BRANDING.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(extras['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(extras['discountWordTranslations']),\n headerTextTranslations: parseTranslations(extras['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(extras['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(extras['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(extras['footerTextTranslations']),\n surchargeColor: s(extras['surchargeColor']) || DEFAULT_BRANDING.surchargeColor,\n discountColor: s(extras['discountColor']) || DEFAULT_BRANDING.discountColor,\n\n layout: pickEnum<LayoutStyle>(extras['layout'], ['compact', 'split'], DEFAULT_BRANDING.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n extras['summaryPosition'],\n ['left', 'right'],\n DEFAULT_BRANDING.summaryPosition,\n ),\n showOrderSummary: parseBool(extras['showOrderSummary'], DEFAULT_BRANDING.showOrderSummary),\n summaryGradient: parseBool(extras['summaryGradient'], DEFAULT_BRANDING.summaryGradient),\n showTotal: parseBool(extras['showTotal'], DEFAULT_BRANDING.showTotal),\n totalLabel: s(extras['totalLabel']) || DEFAULT_BRANDING.totalLabel,\n showCurrencyCode: parseBool(extras['showCurrencyCode'], DEFAULT_BRANDING.showCurrencyCode),\n showOrderItems: parseBool(extras['showOrderItems'], DEFAULT_BRANDING.showOrderItems),\n cancelLinkEnabled: parseBool(extras['cancelLinkEnabled'], DEFAULT_BRANDING.cancelLinkEnabled),\n cancelLinkPosition: pickEnum<'top' | 'bottom'>(\n extras['cancelLinkPosition'],\n ['top', 'bottom'],\n DEFAULT_BRANDING.cancelLinkPosition,\n ),\n cancelLinkStyle: pickEnum<'link' | 'button'>(\n extras['cancelLinkStyle'],\n ['link', 'button'],\n DEFAULT_BRANDING.cancelLinkStyle,\n ),\n\n trustBadges: trustRow.trustBadges,\n notices: trustRow.notices,\n customFields: decodedCustomFields ?? [],\n methodSectionOrder: decodeMethodSectionOrder(extras[METHOD_SECTION_ORDER_KEY]),\n methodSectionLabels: decodeMethodSectionLabels(extras[METHOD_SECTION_LABELS_KEY]),\n\n headerText: s(source.payment_form_header_text),\n payButtonLabel: s(source.payment_button_text),\n cardTermsMessage: s(source.custom_message_for_card_terms),\n footerText: s(extras['footerText']),\n supportEmail: s(extras['supportEmail']),\n\n paymentLayout: pickEnum<PaymentLayout>(\n source.sdk_layout,\n ['tabs', 'accordion', 'spaced_accordion'],\n DEFAULT_BRANDING.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: source.branding_visibility !== false,\n\n // The two that can be empty use `pickEnumOrEmpty`, not `pickEnum`: a\n // value this build does not know has to decode to \"unset\" and defer, the\n // same as a key that was never written. Sending it to a concrete default\n // instead would make an older checkout override the connector account of\n // a merchant who picked a preset a newer dashboard offers.\n airwallexCardPreset: pickEnumOrEmpty<AirwallexCardPreset>(\n extras['airwallexCardPreset'],\n AIRWALLEX_CARD_PRESETS,\n ),\n airwallexHideCard: parseBool(extras['airwallexHideCard'], DEFAULT_BRANDING.airwallexHideCard),\n airwallexHideCardTitle: parseBool(\n extras['airwallexHideCardTitle'],\n DEFAULT_BRANDING.airwallexHideCardTitle,\n ),\n airwallexFieldChrome: pickEnum<AirwallexFieldChrome>(\n extras['airwallexFieldChrome'],\n AIRWALLEX_FIELD_CHROMES,\n DEFAULT_BRANDING.airwallexFieldChrome,\n ),\n airwallexLabelStyle: pickEnumOrEmpty<AirwallexLabelStyle>(\n extras['airwallexLabelStyle'],\n AIRWALLEX_LABEL_STYLES,\n ),\n airwallexFieldFontSize: pickEnum<AirwallexFieldFontSize>(\n extras['airwallexFieldFontSize'],\n AIRWALLEX_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.airwallexFieldFontSize,\n ),\n airwallexFieldWeight: pickEnum<AirwallexFieldWeight>(\n extras['airwallexFieldWeight'],\n AIRWALLEX_FIELD_WEIGHTS,\n DEFAULT_BRANDING.airwallexFieldWeight,\n ),\n airwallexFocusRing: pickEnum<AirwallexFocusRing>(\n extras['airwallexFocusRing'],\n AIRWALLEX_FOCUS_RINGS,\n DEFAULT_BRANDING.airwallexFocusRing,\n ),\n airwallexAutofill: pickEnum<AirwallexAutofillTreatment>(\n extras['airwallexAutofill'],\n AIRWALLEX_AUTOFILL_TREATMENTS,\n DEFAULT_BRANDING.airwallexAutofill,\n ),\n airwallexValidTint: parseBool(\n extras['airwallexValidTint'],\n DEFAULT_BRANDING.airwallexValidTint,\n ),\n airwallexNetworkMarks: parseBool(\n extras['airwallexNetworkMarks'],\n DEFAULT_BRANDING.airwallexNetworkMarks,\n ),\n\n stripeTheme: pickEnum<StripeTheme>(\n extras['stripeTheme'],\n STRIPE_THEMES,\n DEFAULT_BRANDING.stripeTheme,\n ),\n stripeInputs: pickEnum<StripeInputStyle>(\n extras['stripeInputs'],\n STRIPE_INPUT_STYLES,\n DEFAULT_BRANDING.stripeInputs,\n ),\n stripeLabels: pickEnum<StripeLabelPlacement>(\n extras['stripeLabels'],\n STRIPE_LABEL_PLACEMENTS,\n DEFAULT_BRANDING.stripeLabels,\n ),\n stripeSpacing: pickEnum<StripeSpacing>(\n extras['stripeSpacing'],\n STRIPE_SPACINGS,\n DEFAULT_BRANDING.stripeSpacing,\n ),\n stripeFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['stripeFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.stripeFieldFontSize,\n ),\n stripeFieldWeight: pickEnum<CardFieldWeight>(\n extras['stripeFieldWeight'],\n CARD_FIELD_WEIGHTS,\n DEFAULT_BRANDING.stripeFieldWeight,\n ),\n stripeFocusRing: pickEnum<CardFocusRing>(\n extras['stripeFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.stripeFocusRing,\n ),\n stripeDisableAnimations: parseBool(\n extras['stripeDisableAnimations'],\n DEFAULT_BRANDING.stripeDisableAnimations,\n ),\n paypalCardLayout: pickEnum<PaypalCardLayout>(\n extras['paypalCardLayout'],\n PAYPAL_CARD_LAYOUTS,\n DEFAULT_BRANDING.paypalCardLayout,\n ),\n paypalLabelStyle: pickEnum<PaypalLabelStyle>(\n extras['paypalLabelStyle'],\n PAYPAL_LABEL_STYLES,\n DEFAULT_BRANDING.paypalLabelStyle,\n ),\n paypalFieldChrome: pickEnum<CardFieldChrome>(\n extras['paypalFieldChrome'],\n CARD_FIELD_CHROMES,\n DEFAULT_BRANDING.paypalFieldChrome,\n ),\n mollieFieldChrome: pickEnum<CardFieldChrome>(\n extras['mollieFieldChrome'],\n CARD_FIELD_CHROMES,\n DEFAULT_BRANDING.mollieFieldChrome,\n ),\n paypalFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['paypalFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.paypalFieldFontSize,\n ),\n mollieFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['mollieFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.mollieFieldFontSize,\n ),\n paypalFieldWeight: pickEnum<CardFieldWeight>(\n extras['paypalFieldWeight'],\n CARD_FIELD_WEIGHTS,\n DEFAULT_BRANDING.paypalFieldWeight,\n ),\n mollieFieldWeight: pickEnum<CardFieldWeight>(\n extras['mollieFieldWeight'],\n CARD_FIELD_WEIGHTS,\n DEFAULT_BRANDING.mollieFieldWeight,\n ),\n paypalFocusRing: pickEnum<CardFocusRing>(\n extras['paypalFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.paypalFocusRing,\n ),\n mollieFocusRing: pickEnum<CardFocusRing>(\n extras['mollieFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.mollieFocusRing,\n ),\n micropaymentFieldChrome: pickEnum<CardFieldChrome>(\n extras['micropaymentFieldChrome'],\n CARD_FIELD_CHROMES,\n DEFAULT_BRANDING.micropaymentFieldChrome,\n ),\n micropaymentFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['micropaymentFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.micropaymentFieldFontSize,\n ),\n micropaymentFieldWeight: pickEnum<CardFieldWeight>(\n extras['micropaymentFieldWeight'],\n CARD_FIELD_WEIGHTS,\n DEFAULT_BRANDING.micropaymentFieldWeight,\n ),\n micropaymentFocusRing: pickEnum<CardFocusRing>(\n extras['micropaymentFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.micropaymentFocusRing,\n ),\n whopCardPreset: pickEnum<WhopCardPreset>(\n extras['whopCardPreset'],\n WHOP_CARD_PRESETS,\n DEFAULT_BRANDING.whopCardPreset,\n ),\n whopAccentColor: pickEnum<WhopAccentColor>(\n extras['whopAccentColor'],\n WHOP_ACCENT_COLORS,\n DEFAULT_BRANDING.whopAccentColor,\n ),\n whopGrayColor: pickEnum<WhopGrayColor>(\n extras['whopGrayColor'],\n WHOP_GRAY_COLORS,\n DEFAULT_BRANDING.whopGrayColor,\n ),\n whopBillingDetails: pickEnum<WhopBillingDetails>(\n extras['whopBillingDetails'],\n WHOP_BILLING_DETAILS,\n DEFAULT_BRANDING.whopBillingDetails,\n ),\n whopSeparated: parseBool(extras['whopSeparated'], DEFAULT_BRANDING.whopSeparated),\n whopEmailLabel: pickEnum<WhopEmailLabel>(\n extras['whopEmailLabel'],\n WHOP_EMAIL_LABELS,\n DEFAULT_BRANDING.whopEmailLabel,\n ),\n whopFieldChrome: pickEnum<CardFieldChrome>(\n extras['whopFieldChrome'],\n CARD_FIELD_CHROMES,\n DEFAULT_BRANDING.whopFieldChrome,\n ),\n whopFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['whopFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.whopFieldFontSize,\n ),\n whopFieldWeight: pickEnum<CardFieldWeight>(\n extras['whopFieldWeight'],\n CARD_FIELD_WEIGHTS,\n DEFAULT_BRANDING.whopFieldWeight,\n ),\n whopFocusRing: pickEnum<CardFocusRing>(\n extras['whopFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.whopFocusRing,\n ),\n whopRadius: pickEnum<WhopRadius>(extras['whopRadius'], WHOP_RADII, DEFAULT_BRANDING.whopRadius),\n whopShadow: pickEnum<WhopShadow>(\n extras['whopShadow'],\n WHOP_SHADOWS,\n DEFAULT_BRANDING.whopShadow,\n ),\n whopMethodIcons: parseBool(extras['whopMethodIcons'], DEFAULT_BRANDING.whopMethodIcons),\n whopSelection: pickEnum<WhopSelection>(\n extras['whopSelection'],\n WHOP_SELECTIONS,\n DEFAULT_BRANDING.whopSelection,\n ),\n paypalValidTint: parseBool(extras['paypalValidTint'], DEFAULT_BRANDING.paypalValidTint),\n nomupayFormStyle: pickEnum<NomupayFormStyle>(\n extras['nomupayFormStyle'],\n NOMUPAY_FORM_STYLES,\n DEFAULT_BRANDING.nomupayFormStyle,\n ),\n nomupayShowLabels: parseBool(extras['nomupayShowLabels'], DEFAULT_BRANDING.nomupayShowLabels),\n nomupayShowPlaceholders: parseBool(\n extras['nomupayShowPlaceholders'],\n DEFAULT_BRANDING.nomupayShowPlaceholders,\n ),\n nomupayShowCvvHint: parseBool(\n extras['nomupayShowCvvHint'],\n DEFAULT_BRANDING.nomupayShowCvvHint,\n ),\n nomupayFieldChrome: pickEnum<CardFieldChrome>(\n extras['nomupayFieldChrome'],\n CARD_FIELD_CHROMES,\n DEFAULT_BRANDING.nomupayFieldChrome,\n ),\n nomupayFieldFontSize: pickEnum<CardFieldFontSize>(\n extras['nomupayFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n DEFAULT_BRANDING.nomupayFieldFontSize,\n ),\n nomupayFocusRing: pickEnum<CardFocusRing>(\n extras['nomupayFocusRing'],\n CARD_FOCUS_RINGS,\n DEFAULT_BRANDING.nomupayFocusRing,\n ),\n nomupayApplePayButtonStyle: pickEnum<ApplePayButtonStyle>(\n extras['nomupayApplePayButtonStyle'],\n APPLE_PAY_BUTTON_STYLES,\n DEFAULT_BRANDING.nomupayApplePayButtonStyle,\n ),\n nomupayApplePayButtonType: pickEnum<ApplePayButtonType>(\n extras['nomupayApplePayButtonType'],\n APPLE_PAY_BUTTON_TYPES,\n DEFAULT_BRANDING.nomupayApplePayButtonType,\n ),\n nomupayGooglePayButtonColor: pickEnum<GooglePayButtonColor>(\n extras['nomupayGooglePayButtonColor'],\n GOOGLE_PAY_BUTTON_COLORS,\n DEFAULT_BRANDING.nomupayGooglePayButtonColor,\n ),\n nomupayGooglePayButtonType: pickEnum<GooglePayButtonType>(\n extras['nomupayGooglePayButtonType'],\n GOOGLE_PAY_BUTTON_TYPES,\n DEFAULT_BRANDING.nomupayGooglePayButtonType,\n ),\n\n customCss: s(extras['customCss']),\n };\n}\n\n// Encoded request shape — the union of fields the encoder fills. Compatible\n// with `BusinessPaymentLinkConfig` / `PaymentLinkConfigRequest` via\n// structural typing on the consumer side.\nexport interface EncodedBranding {\n theme: string;\n logo: string | null;\n seller_name: string | null;\n sdk_layout: PaymentLayout;\n payment_button_text: string | null;\n payment_button_colour: string;\n payment_button_text_colour: string;\n background_colour: string;\n payment_form_header_text: string | null;\n payment_form_label_type: 'above' | 'never';\n custom_message_for_card_terms: string | null;\n sdk_ui_rules: Record<string, Record<string, string>>;\n branding_visibility: boolean;\n}\n\n// Encode a CheckoutBranding into the API request shape. `base` is the\n// existing config (if any) -- preserves bag entries the form doesn't surface\n// (other sdk_ui_rules groups, business_specific_configs, etc.) by spreading\n// it through.\n//\n// `TBase` is constrained to `object | null | undefined` (not\n// `Record<string, unknown>`) so consumers can pass interface-typed values\n// directly. TS interfaces don't get an implicit string index signature, so\n// they don't structurally satisfy `Record<string, unknown>` even when their\n// property values would all unify to `unknown` — `object` admits them\n// without forcing a cast at every call site. We only spread the value, so\n// no index-signature semantics are needed at runtime.\nexport function encodeBranding<TBase extends object | null | undefined>(\n branding: CheckoutBranding,\n base?: TBase,\n): EncodedBranding & (TBase extends object ? TBase : Record<string, never>) {\n const trim = (v: string): string | null => {\n const t = v.trim();\n return t.length > 0 ? t : null;\n };\n\n // We only read one property off `base` and structural typing on `object`\n // doesn't permit index access, so go through `unknown` here.\n const existingRules = ((base as unknown as Record<string, unknown> | undefined)?.[\n 'sdk_ui_rules'\n ] ?? {}) as Record<string, Record<string, string>>;\n const extras: Record<string, string> = {\n surface: branding.surface,\n text: branding.text,\n heading: branding.heading,\n muted: branding.muted,\n border: branding.border,\n accentText: branding.accentText,\n fontFamily: branding.fontFamily,\n headingWeight: branding.headingWeight,\n radiusSurface: branding.radiusSurface,\n radiusInput: branding.radiusInput,\n radiusButton: branding.radiusButton,\n radiusBadge: branding.radiusBadge,\n surfaceStyle: branding.surfaceStyle,\n surfacePadding: branding.surfacePadding,\n verticalGap: branding.verticalGap,\n inputSize: branding.inputSize,\n buttonSize: branding.buttonSize,\n showSurcharge: String(branding.showSurcharge),\n surchargePosition: branding.surchargePosition,\n nativeElementPosition: branding.nativeElementPosition,\n nativeElementStacked: String(branding.nativeElementStacked),\n surchargeStyle: branding.surchargeStyle,\n surchargeSize: branding.surchargeSize,\n surchargeShape: branding.surchargeShape,\n surchargeBorderWidth: branding.surchargeBorderWidth,\n surchargeBorderStyle: branding.surchargeBorderStyle,\n surchargeWeight: branding.surchargeWeight,\n surchargeSign: branding.surchargeSign,\n surchargeUppercase: String(branding.surchargeUppercase),\n surchargeLabel: branding.surchargeLabel,\n surchargeFigure: branding.surchargeFigure,\n discountFigure: branding.discountFigure,\n surchargeColor: branding.surchargeColor,\n discountColor: branding.discountColor,\n layout: branding.layout,\n summaryPosition: branding.summaryPosition,\n showOrderSummary: String(branding.showOrderSummary),\n summaryGradient: String(branding.summaryGradient),\n showTotal: String(branding.showTotal),\n totalLabel: branding.totalLabel,\n showCurrencyCode: String(branding.showCurrencyCode),\n showOrderItems: String(branding.showOrderItems),\n cancelLinkEnabled: String(branding.cancelLinkEnabled),\n cancelLinkPosition: branding.cancelLinkPosition,\n cancelLinkStyle: branding.cancelLinkStyle,\n showLogo: String(branding.showLogo),\n logoShape: branding.logoShape,\n logoSize: branding.logoSize,\n labelStyle: branding.labelStyle,\n // Written unconditionally, empty string included. The encoder REPLACES\n // `sdk_ui_rules.branding` wholesale, so a key it skips is a key it\n // deletes — and here the empty string is a real value (\"no choice made\"),\n // not an absence. Omitting it would be indistinguishable from omitting it\n // by accident, which is how `summaryOrder` was lost.\n airwallexCardPreset: branding.airwallexCardPreset,\n airwallexHideCard: String(branding.airwallexHideCard),\n airwallexHideCardTitle: String(branding.airwallexHideCardTitle),\n airwallexFieldChrome: branding.airwallexFieldChrome,\n airwallexLabelStyle: branding.airwallexLabelStyle,\n airwallexFieldFontSize: branding.airwallexFieldFontSize,\n airwallexFieldWeight: branding.airwallexFieldWeight,\n airwallexFocusRing: branding.airwallexFocusRing,\n airwallexAutofill: branding.airwallexAutofill,\n airwallexValidTint: String(branding.airwallexValidTint),\n airwallexNetworkMarks: String(branding.airwallexNetworkMarks),\n stripeTheme: branding.stripeTheme,\n stripeInputs: branding.stripeInputs,\n stripeLabels: branding.stripeLabels,\n stripeSpacing: branding.stripeSpacing,\n stripeFieldFontSize: branding.stripeFieldFontSize,\n stripeFieldWeight: branding.stripeFieldWeight,\n stripeFocusRing: branding.stripeFocusRing,\n stripeDisableAnimations: String(branding.stripeDisableAnimations),\n paypalCardLayout: branding.paypalCardLayout,\n paypalLabelStyle: branding.paypalLabelStyle,\n paypalFieldChrome: branding.paypalFieldChrome,\n mollieFieldChrome: branding.mollieFieldChrome,\n paypalFieldFontSize: branding.paypalFieldFontSize,\n mollieFieldFontSize: branding.mollieFieldFontSize,\n paypalFieldWeight: branding.paypalFieldWeight,\n mollieFieldWeight: branding.mollieFieldWeight,\n paypalFocusRing: branding.paypalFocusRing,\n mollieFocusRing: branding.mollieFocusRing,\n micropaymentFieldChrome: branding.micropaymentFieldChrome,\n micropaymentFieldFontSize: branding.micropaymentFieldFontSize,\n micropaymentFieldWeight: branding.micropaymentFieldWeight,\n micropaymentFocusRing: branding.micropaymentFocusRing,\n whopCardPreset: branding.whopCardPreset,\n whopAccentColor: branding.whopAccentColor,\n whopGrayColor: branding.whopGrayColor,\n whopBillingDetails: branding.whopBillingDetails,\n whopSeparated: String(branding.whopSeparated),\n whopEmailLabel: branding.whopEmailLabel,\n whopFieldChrome: branding.whopFieldChrome,\n whopFieldFontSize: branding.whopFieldFontSize,\n whopFieldWeight: branding.whopFieldWeight,\n whopFocusRing: branding.whopFocusRing,\n whopRadius: branding.whopRadius,\n whopShadow: branding.whopShadow,\n whopMethodIcons: String(branding.whopMethodIcons),\n whopSelection: branding.whopSelection,\n paypalValidTint: String(branding.paypalValidTint),\n nomupayFormStyle: branding.nomupayFormStyle,\n nomupayShowLabels: String(branding.nomupayShowLabels),\n nomupayShowPlaceholders: String(branding.nomupayShowPlaceholders),\n nomupayShowCvvHint: String(branding.nomupayShowCvvHint),\n nomupayFieldChrome: branding.nomupayFieldChrome,\n nomupayFieldFontSize: branding.nomupayFieldFontSize,\n nomupayFocusRing: branding.nomupayFocusRing,\n nomupayApplePayButtonStyle: branding.nomupayApplePayButtonStyle,\n nomupayApplePayButtonType: branding.nomupayApplePayButtonType,\n nomupayGooglePayButtonColor: branding.nomupayGooglePayButtonColor,\n nomupayGooglePayButtonType: branding.nomupayGooglePayButtonType,\n // Always written, `[]` included — its presence is what stops a later\n // decode from migrating the shop again (`resolveNoticesAndBadges`).\n notices: encodeNotices(branding.notices),\n [METHOD_SECTION_ORDER_KEY]: encodeMethodSectionOrder(branding.methodSectionOrder),\n };\n // Badges only when there are some. Not for tidiness: this group\n // is rebuilt on every save, so a writer that predates notices drops them.\n // Such a writer decodes a missing `trustBadges` to its stock pair and saves\n // that, which decodes here to the default notices again. Had `[]` been\n // written, it would save `[]` back, and `[]` without notices reads as \"the\n // merchant removed the trust row\", so the checkout would show nothing.\n if (branding.trustBadges.length > 0) {\n extras['trustBadges'] = encodeBadges(branding.trustBadges);\n }\n // Written only when there is one, so an untouched profile's bag is unchanged.\n const sectionLabels = encodeMethodSectionLabels(branding.methodSectionLabels);\n if (sectionLabels) extras[METHOD_SECTION_LABELS_KEY] = sectionLabels;\n // Omit the key entirely when there are no fields — decode treats a\n // missing entry the same as an empty list, and the bag stays clean for\n // merchants who never touch the feature.\n if (branding.customFields.length > 0) {\n extras['customFields'] = encodeCustomFields(branding.customFields);\n }\n // Localized copy, each written only when the merchant actually set one, so\n // an untouched profile's bag is unchanged by this feature existing.\n for (const key of [\n 'surchargeWordTranslations',\n 'discountWordTranslations',\n 'headerTextTranslations',\n 'payButtonLabelTranslations',\n 'cardTermsMessageTranslations',\n 'footerTextTranslations',\n ] as const) {\n const encoded = encodeTranslations(branding[key]);\n if (encoded) extras[key] = encoded;\n }\n const tagline = trim(branding.tagline);\n if (tagline) extras['tagline'] = tagline;\n const footer = trim(branding.footerText);\n if (footer) extras['footerText'] = footer;\n const support = trim(branding.supportEmail);\n if (support) extras['supportEmail'] = support;\n // Persist raw — sanitization runs at render time so we keep the merchant's\n // input as-typed (preserves comments, whitespace) and let the checkout\n // strip dangerous tokens consistently across all readers.\n const css = trim(branding.customCss);\n if (css) extras['customCss'] = css;\n\n const nextRules: Record<string, Record<string, string>> = {\n ...existingRules,\n [BRANDING_GROUP_KEY]: extras,\n };\n\n // Map `hidden` back to the legacy `never` token the API's label type\n // enum understands. `floating` no longer exists.\n const legacyLabel: 'above' | 'never' = branding.labelStyle === 'hidden' ? 'never' : 'above';\n\n const flatFields: EncodedBranding = {\n theme: branding.primary,\n logo: trim(branding.logoUrl),\n seller_name: trim(branding.displayName),\n sdk_layout: branding.paymentLayout,\n payment_button_text: trim(branding.payButtonLabel),\n payment_button_colour: branding.buttonBackground,\n payment_button_text_colour: branding.buttonText,\n background_colour: branding.background,\n payment_form_header_text: trim(branding.headerText),\n payment_form_label_type: legacyLabel,\n custom_message_for_card_terms: trim(branding.cardTermsMessage),\n sdk_ui_rules: nextRules,\n branding_visibility: branding.showPoweredBy,\n };\n\n // Spread `base` first to preserve fields the encoder doesn't surface\n // (show_card_terms, show_card_form_by_default, hide_card_nickname_field,\n // enable_button_only_on_form_ready, skip_status_screen,\n // transaction_details, background_image, details_layout,\n // custom_message_for_payment_method_types, payment_link_ui_rules,\n // color_icon_card_cvc_error, is_setup_mandate_flow,\n // enabled_saved_payment_method, display_sdk_only,\n // business_specific_configs, domain_name, allowed_domains).\n return {\n ...base,\n ...flatFields,\n } as EncodedBranding & (TBase extends object ? TBase : Record<string, never>);\n}\n\n// --- Import / Export envelope ------------------------------------------\n\n// Versioned envelope used by the merchant control-center's \"Import /\n// Export\" buttons. Bumping `version` is informational; the importer is\n// graceful and accepts any version (or no envelope at all).\nexport const BRANDING_EXPORT_FORMAT = 'delopay-checkout-branding';\nexport const BRANDING_EXPORT_VERSION = 1;\n\nexport interface BrandingExport {\n format: typeof BRANDING_EXPORT_FORMAT;\n version: number;\n exported_at: string;\n branding: CheckoutBranding;\n}\n\nexport function buildBrandingExport(branding: CheckoutBranding): BrandingExport {\n return {\n format: BRANDING_EXPORT_FORMAT,\n version: BRANDING_EXPORT_VERSION,\n exported_at: new Date().toISOString(),\n branding: cloneBranding(branding),\n };\n}\n\n// Resolve arbitrary JSON into a fully-typed CheckoutBranding. Designed to\n// never throw — every field is independently validated against its type\n// and silently falls back to the light-mode default if missing or\n// malformed:\n// - extra fields the form doesn't know about are ignored,\n// - missing fields inherit defaults,\n// - hex colors that fail the regex stay at the default,\n// - enums outside the allowed set fall back,\n// - a payload with no recognizable shape produces DEFAULT_BRANDING.\n//\n// Accepts either a bare CheckoutBranding object or an envelope produced by\n// `buildBrandingExport()`. The caller (the import handler) only needs to\n// catch JSON.parse errors; everything past that point is total.\nexport function parseImportedBranding(raw: unknown): CheckoutBranding {\n // Unwrap the envelope if present. Don't gate on version — bumping it is\n // informational; this function is the migration layer.\n const root: Record<string, unknown> | null =\n isObject(raw) && isObject(raw['branding'])\n ? (raw['branding'] as Record<string, unknown>)\n : isObject(raw)\n ? raw\n : null;\n\n if (!root) return cloneBranding(DEFAULT_BRANDING);\n\n const dflt = DEFAULT_BRANDING;\n const sStr = (v: unknown, fallback: string): string => (typeof v === 'string' ? v : fallback);\n const sHex = (v: unknown, fallback: string): string =>\n typeof v === 'string' && isHexColor(v) ? v : fallback;\n\n // The same rule as `decodeBranding`: an export made before notices existed\n // carries badges only, and is migrated exactly as a saved shop would be.\n const { trustBadges, notices } = resolveNoticesAndBadges(\n parseTrustBadgesLoose(root['trustBadges']),\n parseNoticesLoose(root['notices']),\n );\n const customFields = parseCustomFieldsLoose(root['customFields']) ?? [];\n\n // `floating` from older exports normalizes to `above`; see decodeBranding.\n const labelStyle: LabelStyle = (() => {\n const v = root['labelStyle'];\n if (v === 'above' || v === 'hidden') return v;\n return dflt.labelStyle;\n })();\n\n return {\n displayName: sStr(root['displayName'], dflt.displayName),\n logoUrl: sStr(root['logoUrl'], dflt.logoUrl),\n tagline: sStr(root['tagline'], dflt.tagline),\n showLogo: parseBool(root['showLogo'], dflt.showLogo),\n logoShape: pickEnum<LogoShape>(\n root['logoShape'],\n ['square', 'rounded', 'circle'],\n dflt.logoShape,\n ),\n logoSize: pickEnum<LogoSize>(root['logoSize'], ['sm', 'md', 'lg'], dflt.logoSize),\n\n primary: sHex(root['primary'], dflt.primary),\n background: sHex(root['background'], dflt.background),\n surface: sHex(root['surface'], dflt.surface),\n text: sHex(root['text'], dflt.text),\n heading: sHex(root['heading'], dflt.heading),\n muted: sHex(root['muted'], dflt.muted),\n border: sHex(root['border'], dflt.border),\n accentText: sHex(root['accentText'], dflt.accentText),\n buttonBackground: sHex(root['buttonBackground'], dflt.buttonBackground),\n buttonText: sHex(root['buttonText'], dflt.buttonText),\n\n fontFamily: pickEnum<FontFamily>(root['fontFamily'], ALL_FONT_FAMILIES, dflt.fontFamily),\n headingWeight: pickEnum<FontWeight>(\n root['headingWeight'],\n ['regular', 'medium', 'semibold', 'bold'],\n dflt.headingWeight,\n ),\n\n radiusSurface: pickEnum<NonPillRadius>(\n root['radiusSurface'],\n NON_PILL_RADII,\n dflt.radiusSurface,\n ),\n radiusInput: pickEnum<NonPillRadius>(root['radiusInput'], NON_PILL_RADII, dflt.radiusInput),\n radiusButton: pickEnum<CornerRadius>(root['radiusButton'], ALL_RADII, dflt.radiusButton),\n radiusBadge: pickEnum<CornerRadius>(root['radiusBadge'], ALL_RADII, dflt.radiusBadge),\n surfaceStyle: pickEnum<SurfaceStyle>(\n root['surfaceStyle'],\n ['flat', 'outlined', 'elevated'],\n dflt.surfaceStyle,\n ),\n surfacePadding: pickEnum<SpacingScale>(\n root['surfacePadding'],\n ['compact', 'comfortable', 'spacious'],\n dflt.surfacePadding,\n ),\n verticalGap: pickEnum<SpacingScale>(\n root['verticalGap'],\n ['compact', 'comfortable', 'spacious'],\n dflt.verticalGap,\n ),\n inputSize: pickEnum<SizeScale>(root['inputSize'], ['sm', 'md', 'lg'], dflt.inputSize),\n buttonSize: pickEnum<SizeScale>(root['buttonSize'], ['sm', 'md', 'lg'], dflt.buttonSize),\n\n showSurcharge: parseBool(root['showSurcharge'], dflt.showSurcharge),\n surchargePosition: pickEnum<SurchargePosition>(\n root['surchargePosition'],\n SURCHARGE_POSITIONS,\n dflt.surchargePosition,\n ),\n nativeElementStacked: parseBool(root['nativeElementStacked'], dflt.nativeElementStacked),\n nativeElementPosition: pickEnum<NativeElementPosition>(\n root['nativeElementPosition'],\n NATIVE_ELEMENT_POSITIONS,\n dflt.nativeElementPosition,\n ),\n surchargeStyle: pickEnum<SurchargeStyle>(\n root['surchargeStyle'],\n SURCHARGE_STYLES,\n dflt.surchargeStyle,\n ),\n surchargeSize: pickEnum<SurchargeSize>(\n root['surchargeSize'],\n SURCHARGE_SIZES,\n dflt.surchargeSize,\n ),\n surchargeShape: pickEnum<SurchargeShape>(\n root['surchargeShape'],\n SURCHARGE_SHAPES,\n dflt.surchargeShape,\n ),\n surchargeBorderWidth: pickEnum<SurchargeBorderWidth>(\n root['surchargeBorderWidth'],\n SURCHARGE_BORDER_WIDTHS,\n dflt.surchargeBorderWidth,\n ),\n surchargeBorderStyle: pickEnum<SurchargeBorderStyle>(\n root['surchargeBorderStyle'],\n SURCHARGE_BORDER_STYLES,\n dflt.surchargeBorderStyle,\n ),\n surchargeWeight: pickEnum<SurchargeWeight>(\n root['surchargeWeight'],\n SURCHARGE_WEIGHTS,\n dflt.surchargeWeight,\n ),\n surchargeSign: pickEnum<SurchargeSign>(\n root['surchargeSign'],\n SURCHARGE_SIGNS,\n dflt.surchargeSign,\n ),\n surchargeUppercase: parseBool(root['surchargeUppercase'], dflt.surchargeUppercase),\n surchargeLabel: pickEnum<SurchargeLabelMode>(\n root['surchargeLabel'],\n SURCHARGE_LABEL_MODES,\n dflt.surchargeLabel,\n ),\n surchargeFigure: pickEnum<SurchargeFigureMode>(\n root['surchargeFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.surchargeFigure,\n ),\n discountFigure: pickEnum<SurchargeFigureMode>(\n root['discountFigure'],\n SURCHARGE_FIGURE_MODES,\n dflt.discountFigure,\n ),\n surchargeWordTranslations: parseTranslations(root['surchargeWordTranslations']),\n discountWordTranslations: parseTranslations(root['discountWordTranslations']),\n headerTextTranslations: parseTranslations(root['headerTextTranslations']),\n payButtonLabelTranslations: parseTranslations(root['payButtonLabelTranslations']),\n cardTermsMessageTranslations: parseTranslations(root['cardTermsMessageTranslations']),\n footerTextTranslations: parseTranslations(root['footerTextTranslations']),\n surchargeColor: sHex(root['surchargeColor'], dflt.surchargeColor),\n discountColor: sHex(root['discountColor'], dflt.discountColor),\n\n layout: pickEnum<LayoutStyle>(root['layout'], ['compact', 'split'], dflt.layout),\n summaryPosition: pickEnum<SummaryPosition>(\n root['summaryPosition'],\n ['left', 'right'],\n dflt.summaryPosition,\n ),\n showOrderSummary: parseBool(root['showOrderSummary'], dflt.showOrderSummary),\n summaryGradient: parseBool(root['summaryGradient'], dflt.summaryGradient),\n showTotal: parseBool(root['showTotal'], dflt.showTotal),\n totalLabel: sStr(root['totalLabel'], dflt.totalLabel),\n showCurrencyCode: parseBool(root['showCurrencyCode'], dflt.showCurrencyCode),\n showOrderItems: parseBool(root['showOrderItems'], dflt.showOrderItems),\n\n trustBadges,\n notices,\n customFields,\n cancelLinkEnabled: parseBool(root['cancelLinkEnabled'], dflt.cancelLinkEnabled),\n cancelLinkPosition: pickEnum<'top' | 'bottom'>(\n root['cancelLinkPosition'],\n ['top', 'bottom'],\n dflt.cancelLinkPosition,\n ),\n cancelLinkStyle: pickEnum<'link' | 'button'>(\n root['cancelLinkStyle'],\n ['link', 'button'],\n dflt.cancelLinkStyle,\n ),\n // An export writes the decoded maps; a hand-written file may carry the\n // JSON strings the bag uses. Both are accepted, and neither is required.\n methodSectionOrder: parseSectionOrderLoose(root[METHOD_SECTION_ORDER_KEY]),\n methodSectionLabels: parseSectionLabelsLoose(root[METHOD_SECTION_LABELS_KEY]),\n\n headerText: sStr(root['headerText'], dflt.headerText),\n payButtonLabel: sStr(root['payButtonLabel'], dflt.payButtonLabel),\n cardTermsMessage: sStr(root['cardTermsMessage'], dflt.cardTermsMessage),\n footerText: sStr(root['footerText'], dflt.footerText),\n supportEmail: sStr(root['supportEmail'], dflt.supportEmail),\n\n paymentLayout: pickEnum<PaymentLayout>(\n root['paymentLayout'],\n ['tabs', 'accordion', 'spaced_accordion'],\n dflt.paymentLayout,\n ),\n labelStyle,\n showPoweredBy: parseBool(root['showPoweredBy'], dflt.showPoweredBy),\n\n // An imported profile that predates this section carries none of these\n // and lands on the defaults — which is to say on \"defer\", so importing an\n // old export into a shop does not take that shop's connector setting\n // away. The one field that would be dangerous to import loosely is the\n // hide switch, and `parseBool` only says true for a literal `true`.\n airwallexCardPreset: pickEnumOrEmpty<AirwallexCardPreset>(\n root['airwallexCardPreset'],\n AIRWALLEX_CARD_PRESETS,\n ),\n airwallexHideCard: parseBool(root['airwallexHideCard'], dflt.airwallexHideCard),\n airwallexHideCardTitle: parseBool(root['airwallexHideCardTitle'], dflt.airwallexHideCardTitle),\n airwallexFieldChrome: pickEnum<AirwallexFieldChrome>(\n root['airwallexFieldChrome'],\n AIRWALLEX_FIELD_CHROMES,\n dflt.airwallexFieldChrome,\n ),\n airwallexLabelStyle: pickEnumOrEmpty<AirwallexLabelStyle>(\n root['airwallexLabelStyle'],\n AIRWALLEX_LABEL_STYLES,\n ),\n airwallexFieldFontSize: pickEnum<AirwallexFieldFontSize>(\n root['airwallexFieldFontSize'],\n AIRWALLEX_FIELD_FONT_SIZES,\n dflt.airwallexFieldFontSize,\n ),\n airwallexFieldWeight: pickEnum<AirwallexFieldWeight>(\n root['airwallexFieldWeight'],\n AIRWALLEX_FIELD_WEIGHTS,\n dflt.airwallexFieldWeight,\n ),\n airwallexFocusRing: pickEnum<AirwallexFocusRing>(\n root['airwallexFocusRing'],\n AIRWALLEX_FOCUS_RINGS,\n dflt.airwallexFocusRing,\n ),\n airwallexAutofill: pickEnum<AirwallexAutofillTreatment>(\n root['airwallexAutofill'],\n AIRWALLEX_AUTOFILL_TREATMENTS,\n dflt.airwallexAutofill,\n ),\n airwallexValidTint: parseBool(root['airwallexValidTint'], dflt.airwallexValidTint),\n airwallexNetworkMarks: parseBool(root['airwallexNetworkMarks'], dflt.airwallexNetworkMarks),\n\n stripeTheme: pickEnum<StripeTheme>(root['stripeTheme'], STRIPE_THEMES, dflt.stripeTheme),\n stripeInputs: pickEnum<StripeInputStyle>(\n root['stripeInputs'],\n STRIPE_INPUT_STYLES,\n dflt.stripeInputs,\n ),\n stripeLabels: pickEnum<StripeLabelPlacement>(\n root['stripeLabels'],\n STRIPE_LABEL_PLACEMENTS,\n dflt.stripeLabels,\n ),\n stripeSpacing: pickEnum<StripeSpacing>(\n root['stripeSpacing'],\n STRIPE_SPACINGS,\n dflt.stripeSpacing,\n ),\n stripeFieldFontSize: pickEnum<CardFieldFontSize>(\n root['stripeFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.stripeFieldFontSize,\n ),\n stripeFieldWeight: pickEnum<CardFieldWeight>(\n root['stripeFieldWeight'],\n CARD_FIELD_WEIGHTS,\n dflt.stripeFieldWeight,\n ),\n stripeFocusRing: pickEnum<CardFocusRing>(\n root['stripeFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.stripeFocusRing,\n ),\n stripeDisableAnimations: parseBool(\n root['stripeDisableAnimations'],\n dflt.stripeDisableAnimations,\n ),\n paypalCardLayout: pickEnum<PaypalCardLayout>(\n root['paypalCardLayout'],\n PAYPAL_CARD_LAYOUTS,\n dflt.paypalCardLayout,\n ),\n paypalLabelStyle: pickEnum<PaypalLabelStyle>(\n root['paypalLabelStyle'],\n PAYPAL_LABEL_STYLES,\n dflt.paypalLabelStyle,\n ),\n paypalFieldChrome: pickEnum<CardFieldChrome>(\n root['paypalFieldChrome'],\n CARD_FIELD_CHROMES,\n dflt.paypalFieldChrome,\n ),\n mollieFieldChrome: pickEnum<CardFieldChrome>(\n root['mollieFieldChrome'],\n CARD_FIELD_CHROMES,\n dflt.mollieFieldChrome,\n ),\n paypalFieldFontSize: pickEnum<CardFieldFontSize>(\n root['paypalFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.paypalFieldFontSize,\n ),\n mollieFieldFontSize: pickEnum<CardFieldFontSize>(\n root['mollieFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.mollieFieldFontSize,\n ),\n paypalFieldWeight: pickEnum<CardFieldWeight>(\n root['paypalFieldWeight'],\n CARD_FIELD_WEIGHTS,\n dflt.paypalFieldWeight,\n ),\n mollieFieldWeight: pickEnum<CardFieldWeight>(\n root['mollieFieldWeight'],\n CARD_FIELD_WEIGHTS,\n dflt.mollieFieldWeight,\n ),\n paypalFocusRing: pickEnum<CardFocusRing>(\n root['paypalFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.paypalFocusRing,\n ),\n mollieFocusRing: pickEnum<CardFocusRing>(\n root['mollieFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.mollieFocusRing,\n ),\n micropaymentFieldChrome: pickEnum<CardFieldChrome>(\n root['micropaymentFieldChrome'],\n CARD_FIELD_CHROMES,\n dflt.micropaymentFieldChrome,\n ),\n micropaymentFieldFontSize: pickEnum<CardFieldFontSize>(\n root['micropaymentFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.micropaymentFieldFontSize,\n ),\n micropaymentFieldWeight: pickEnum<CardFieldWeight>(\n root['micropaymentFieldWeight'],\n CARD_FIELD_WEIGHTS,\n dflt.micropaymentFieldWeight,\n ),\n micropaymentFocusRing: pickEnum<CardFocusRing>(\n root['micropaymentFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.micropaymentFocusRing,\n ),\n whopCardPreset: pickEnum<WhopCardPreset>(\n root['whopCardPreset'],\n WHOP_CARD_PRESETS,\n dflt.whopCardPreset,\n ),\n whopAccentColor: pickEnum<WhopAccentColor>(\n root['whopAccentColor'],\n WHOP_ACCENT_COLORS,\n dflt.whopAccentColor,\n ),\n whopGrayColor: pickEnum<WhopGrayColor>(\n root['whopGrayColor'],\n WHOP_GRAY_COLORS,\n dflt.whopGrayColor,\n ),\n whopBillingDetails: pickEnum<WhopBillingDetails>(\n root['whopBillingDetails'],\n WHOP_BILLING_DETAILS,\n dflt.whopBillingDetails,\n ),\n whopSeparated: parseBool(root['whopSeparated'], dflt.whopSeparated),\n whopEmailLabel: pickEnum<WhopEmailLabel>(\n root['whopEmailLabel'],\n WHOP_EMAIL_LABELS,\n dflt.whopEmailLabel,\n ),\n whopFieldChrome: pickEnum<CardFieldChrome>(\n root['whopFieldChrome'],\n CARD_FIELD_CHROMES,\n dflt.whopFieldChrome,\n ),\n whopFieldFontSize: pickEnum<CardFieldFontSize>(\n root['whopFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.whopFieldFontSize,\n ),\n whopFieldWeight: pickEnum<CardFieldWeight>(\n root['whopFieldWeight'],\n CARD_FIELD_WEIGHTS,\n dflt.whopFieldWeight,\n ),\n whopFocusRing: pickEnum<CardFocusRing>(\n root['whopFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.whopFocusRing,\n ),\n whopRadius: pickEnum<WhopRadius>(root['whopRadius'], WHOP_RADII, dflt.whopRadius),\n whopShadow: pickEnum<WhopShadow>(root['whopShadow'], WHOP_SHADOWS, dflt.whopShadow),\n whopMethodIcons: parseBool(root['whopMethodIcons'], dflt.whopMethodIcons),\n whopSelection: pickEnum<WhopSelection>(\n root['whopSelection'],\n WHOP_SELECTIONS,\n dflt.whopSelection,\n ),\n paypalValidTint: parseBool(root['paypalValidTint'], dflt.paypalValidTint),\n nomupayFormStyle: pickEnum<NomupayFormStyle>(\n root['nomupayFormStyle'],\n NOMUPAY_FORM_STYLES,\n dflt.nomupayFormStyle,\n ),\n nomupayShowLabels: parseBool(root['nomupayShowLabels'], dflt.nomupayShowLabels),\n nomupayShowPlaceholders: parseBool(\n root['nomupayShowPlaceholders'],\n dflt.nomupayShowPlaceholders,\n ),\n nomupayShowCvvHint: parseBool(root['nomupayShowCvvHint'], dflt.nomupayShowCvvHint),\n nomupayFieldChrome: pickEnum<CardFieldChrome>(\n root['nomupayFieldChrome'],\n CARD_FIELD_CHROMES,\n dflt.nomupayFieldChrome,\n ),\n nomupayFieldFontSize: pickEnum<CardFieldFontSize>(\n root['nomupayFieldFontSize'],\n CARD_FIELD_FONT_SIZES,\n dflt.nomupayFieldFontSize,\n ),\n nomupayFocusRing: pickEnum<CardFocusRing>(\n root['nomupayFocusRing'],\n CARD_FOCUS_RINGS,\n dflt.nomupayFocusRing,\n ),\n nomupayApplePayButtonStyle: pickEnum<ApplePayButtonStyle>(\n root['nomupayApplePayButtonStyle'],\n APPLE_PAY_BUTTON_STYLES,\n dflt.nomupayApplePayButtonStyle,\n ),\n nomupayApplePayButtonType: pickEnum<ApplePayButtonType>(\n root['nomupayApplePayButtonType'],\n APPLE_PAY_BUTTON_TYPES,\n dflt.nomupayApplePayButtonType,\n ),\n nomupayGooglePayButtonColor: pickEnum<GooglePayButtonColor>(\n root['nomupayGooglePayButtonColor'],\n GOOGLE_PAY_BUTTON_COLORS,\n dflt.nomupayGooglePayButtonColor,\n ),\n nomupayGooglePayButtonType: pickEnum<GooglePayButtonType>(\n root['nomupayGooglePayButtonType'],\n GOOGLE_PAY_BUTTON_TYPES,\n dflt.nomupayGooglePayButtonType,\n ),\n\n customCss: sStr(root['customCss'], dflt.customCss).slice(0, CUSTOM_CSS_MAX_LENGTH),\n };\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n// Loose trust-badge parser used by the importer. Unlike `decodeBadges`\n// (which reads the JSON-stringified API bag), this accepts an array of\n// objects directly. Returns null when the input isn't an array — the\n// caller falls back to the default badge set; an explicit empty array is\n// honored.\nfunction parseTrustBadgesLoose(raw: unknown): TrustBadge[] | null {\n if (!Array.isArray(raw)) return null;\n return raw\n .filter(isObject)\n .map((b, i) => ({\n id: typeof b['id'] === 'string' && b['id'] ? (b['id'] as string) : `badge-${i}`,\n label: typeof b['label'] === 'string' ? (b['label'] as string) : '',\n textColor:\n typeof b['textColor'] === 'string' && isHexColor(b['textColor'] as string)\n ? (b['textColor'] as string)\n : '#0f172a',\n backgroundColor:\n typeof b['backgroundColor'] === 'string' && isHexColor(b['backgroundColor'] as string)\n ? (b['backgroundColor'] as string)\n : '#f1f5f9',\n borderColor:\n typeof b['borderColor'] === 'string' && isHexColor(b['borderColor'] as string)\n ? (b['borderColor'] as string)\n : null,\n }))\n .filter((b) => b.label.length > 0);\n}\n\n// --- DOM helpers --------------------------------------------------------\n\n// Write branding tokens onto a target element as CSS custom properties.\n// The buyer-facing checkout sets these on `<html>` so every component sees\n// the same set, including Stripe Elements (indirectly via\n// appearance.variables). The merchant control-center's preview component\n// uses an analogous `--p-*` set with `var(--dp-*, fallback)` indirection so\n// a custom-CSS rule like `:root{--dp-primary:red}` overrides the preview\n// without re-typing the whole brand.\nexport function applyBrandingVariables(el: HTMLElement, b: CheckoutBranding): void {\n const set = (k: string, v: string) => {\n el.style.setProperty(k, v);\n };\n\n set('--dp-primary', b.primary);\n set('--dp-bg', b.background);\n set('--dp-surface', b.surface);\n set('--dp-text', b.text);\n set('--dp-heading', b.heading);\n set('--dp-muted', b.muted);\n set('--dp-border', b.border);\n set('--dp-accent-text', b.accentText);\n set('--dp-btn-bg', b.buttonBackground);\n set('--dp-btn-fg', b.buttonText);\n\n set('--dp-radius-surface', radiusValue(b.radiusSurface));\n set('--dp-radius-input', radiusValue(b.radiusInput));\n set('--dp-radius-button', radiusValue(b.radiusButton));\n set('--dp-radius-badge', radiusValue(b.radiusBadge));\n\n set('--dp-font', fontStack(b.fontFamily));\n set('--dp-heading-weight', fontWeightValue(b.headingWeight));\n\n set('--dp-pad-surface', SURFACE_PAD[b.surfacePadding]);\n set('--dp-gap-vertical', VERTICAL_GAP[b.verticalGap]);\n set('--dp-input-pad', INPUT_PAD[b.inputSize]);\n set('--dp-button-pad', BUTTON_PAD[b.buttonSize]);\n\n // Published whatever `showSurcharge` says: the flag decides whether a figure\n // renders, not what colour it would be, and a stylesheet that reads the\n // variable must not get an empty string when the merchant has one configured.\n set('--dp-surcharge', b.surchargeColor);\n set('--dp-discount', b.discountColor);\n // What `solid` writes ON the fill. Computed here rather than in a stylesheet\n // because CSS cannot ask a colour how light it is, and picking one fixed ink\n // would make either a pale amber or a deep emerald unreadable.\n set('--dp-surcharge-ink', readableInkOn(b.surchargeColor));\n set('--dp-discount-ink', readableInkOn(b.discountColor));\n set('--dp-surcharge-size', SURCHARGE_FONT_SIZE[b.surchargeSize]);\n set('--dp-surcharge-pad', SURCHARGE_PAD[b.surchargeSize]);\n set('--dp-surcharge-radius', SURCHARGE_RADIUS[b.surchargeShape]);\n set('--dp-surcharge-weight', SURCHARGE_FONT_WEIGHT[b.surchargeWeight]);\n // `outline` draws nothing BUT its border, so `none` there would erase the\n // style rather than restyle it — it reads as `thin` instead.\n set(\n '--dp-surcharge-border-width',\n SURCHARGE_BORDER_WIDTH[\n b.surchargeStyle === 'outline' && b.surchargeBorderWidth === 'none'\n ? 'thin'\n : b.surchargeBorderWidth\n ],\n );\n set('--dp-surcharge-border-style', b.surchargeBorderStyle);\n\n set('--dp-shadow', shadowFor(b.surfaceStyle));\n set(\n '--dp-surface-border',\n b.surfaceStyle === 'outlined' ? `1px solid ${b.border}` : '1px solid transparent',\n );\n}\n\nexport function shadowFor(style: SurfaceStyle): string {\n switch (style) {\n case 'elevated':\n return '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 32px -12px rgba(15, 23, 42, 0.08)';\n case 'outlined':\n case 'flat':\n default:\n return 'none';\n }\n}\n","import { Delopay } from './client';\nimport type { DelopayLogger, RequestExtras } from './client';\nimport { DelopayError } from './error';\nimport type {\n CheckoutAddonChoiceRequest,\n CheckoutAddonChoiceResponse,\n CheckoutDataResponse,\n ConfirmSubscriptionRequest,\n ConfirmSubscriptionResponse,\n EpayoutsMethodsOptions,\n EpayoutsMethodsResponse,\n MollieApplePaySessionRequest,\n MollieApplePaySessionResponse,\n MicropaymentBankSessionRequest,\n MicropaymentBankSessionResponse,\n EpayoutsPaypalCaptureRequest,\n EpayoutsPaypalCaptureResponse,\n EpayoutsPaypalOrderResponse,\n PaymentAbandonAttemptResponse,\n PaymentConfirmRequest,\n PaymentMethodListResponse,\n PaymentResponse,\n PaymentsPostSessionTokensRequest,\n PaymentsPostSessionTokensResponse,\n PaymentUpdateRequest,\n RecordCheckoutEventRequest,\n RecordCheckoutEventResponse,\n ReplayIngestParams,\n ReplayIngestResponse,\n NomupayCardAuthorizationRequest,\n NomupayCardAuthorizationResponse,\n StripeHostedConfirmRequest,\n SubscriptionCheckoutResponse,\n SubscriptionReturnStatusResponse,\n StripeHostedConfirmResponse,\n EnigmaFormSession,\n VaultCollectSessionParams,\n VaultCollectSessionResponse,\n VaultPaymentMethodRequest,\n VaultPaymentMethodResponse,\n} from './types';\n\n/**\n * A publishable (browser-safe) API key. The template type rejects secret\n * keys (`prd_…` / `snd_…`) at compile time, so a checkout cannot be handed\n * a credential that would reach secret-key routes.\n */\nexport type PublishableKey = `pk_${string}`;\n\n/**\n * Drop any caller-supplied credential headers (case-insensitively), so a\n * route can only ever carry the one credential its family requires — the\n * class's isolation guarantee must hold against per-call `headers` too.\n * Non-credential extras (`Idempotency-Key`, `X-Dp-*`, …) pass through.\n */\nfunction withoutCredentialHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!extra) return {};\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(extra)) {\n const lower = key.toLowerCase();\n if (lower === 'api-key' || lower === 'authorization') continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Drop one header (case-insensitively) from a caller-supplied extras map. */\nfunction withoutHeader(headers: Record<string, string>, name: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === name) continue;\n out[key] = value;\n }\n return out;\n}\n\n/** Configuration for a {@link CheckoutSession}. */\nexport interface CheckoutSessionOptions {\n /** The merchant the payment belongs to. */\n merchantId: string;\n /** The payment this session is about. */\n paymentId: string;\n /**\n * The merchant's publishable key (`pk_prd_…` / `pk_snd_…`), from the\n * checkout payload's `pub_key`. Required for the `/payments/*` and\n * `/payment-methods` calls.\n */\n publishableKey?: PublishableKey;\n /**\n * The payment's client secret, from the checkout payload. Required for\n * every `/payment-link/*` call, and rides along on the payment calls.\n */\n clientSecret?: string;\n /** Override the API base URL (e.g. `/api` behind a same-origin proxy). */\n baseUrl?: string;\n /** Use the sandbox environment. Ignored when `baseUrl` is set. */\n sandbox?: boolean;\n /** Per-request timeout in milliseconds. */\n timeout?: number;\n /** Maximum automatic retries for retryable requests. */\n maxRetries?: number;\n debug?: boolean;\n logger?: DelopayLogger;\n}\n\n/**\n * Buyer-side client for a single hosted-checkout payment.\n *\n * Binds the two browser-safe credentials once — the merchant's publishable\n * key and the payment's client secret — and sends each request with exactly\n * the credential its route expects:\n *\n * - `/payment-link/*` side-channel routes authenticate with\n * `Authorization: Bearer <client_secret>`.\n * - `/payments/*` and `/payment-methods` authenticate with the publishable\n * key in the `api-key` header, with the client secret as query parameter\n * or body field.\n *\n * Neither credential can reach a secret-key route: the publishable key is\n * typed to the `pk_` prefix and the client secret only ever leaves as a\n * bearer token / parameter, never as an `api-key`.\n *\n * @example\n * ```typescript\n * const session = new CheckoutSession({\n * merchantId: checkout.merchant_id,\n * paymentId: checkout.payment_id,\n * publishableKey: checkout.pub_key,\n * clientSecret: checkout.client_secret,\n * });\n * const catalog = await session.epayoutsMethods('de');\n * ```\n */\n/**\n * A `CompressionStream` constructor, as much of it as this module uses.\n *\n * Declared structurally rather than taken from the DOM lib: the global is\n * absent in some runtimes this SDK is dropped into, and a type that asserts it\n * exists would make the feature test look redundant to the next reader.\n */\ntype GzipStreamCtor = new (format: 'gzip') => {\n readable: ReadableStream<Uint8Array>;\n writable: WritableStream<Uint8Array>;\n};\n\n/**\n * Gzip a JSON body, or answer `null` where the runtime cannot.\n *\n * `null` is not a failure — it is the caller's instruction to send the body\n * uncompressed. `CompressionStream` is a global in Node 18+ and in current\n * browsers but is missing from older Safari and from some embedded runtimes,\n * and this SDK carries no runtime dependencies, so there is no polyfill to\n * reach for. Sending plain JSON is always correct; the server reads the\n * encoding off the header it is given.\n *\n * The compressed stream is drained to an `ArrayBuffer` rather than handed to\n * `fetch` as a stream. A streamed request body needs `duplex: 'half'`, cannot\n * be replayed on a retry, and is refused outright together with `keepalive` —\n * which is precisely the case a recorder needs when the page is navigating\n * away.\n */\nasync function gzipJson(value: unknown): Promise<ArrayBuffer | null> {\n const ctor = (globalThis as { CompressionStream?: GzipStreamCtor }).CompressionStream;\n if (typeof ctor !== 'function') return null;\n try {\n const bytes = new TextEncoder().encode(JSON.stringify(value));\n return await new Response(\n new Blob([bytes]).stream().pipeThrough(new ctor('gzip')),\n ).arrayBuffer();\n } catch {\n // A runtime carrying the constructor but unable to run it — no\n // `Blob.prototype.stream`, no `pipeThrough` — is the uncompressed case\n // too. A recording must never cost the caller a payment page.\n return null;\n }\n}\n\nexport class CheckoutSession {\n private readonly client: Delopay;\n private readonly merchantId: string;\n private readonly paymentId: string;\n private readonly publishableKey?: PublishableKey;\n private readonly clientSecret?: string;\n\n constructor(options: CheckoutSessionOptions) {\n this.merchantId = options.merchantId;\n this.paymentId = options.paymentId;\n this.publishableKey = options.publishableKey;\n this.clientSecret = options.clientSecret;\n // Constructed WITHOUT a key: every call attaches its own credential\n // explicitly, so a bearer-authenticated route never carries an api-key\n // header and vice versa.\n this.client = new Delopay('', {\n baseUrl: options.baseUrl,\n sandbox: options.sandbox,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n debug: options.debug,\n logger: options.logger,\n });\n }\n\n private get linkBase(): string {\n return `/payment-link/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`;\n }\n\n /** Headers for the client-secret bearer routes (`/payment-link/*`). */\n private bearerHeaders(extra?: Record<string, string>): Record<string, string> {\n return {\n ...withoutCredentialHeaders(extra),\n Authorization: `Bearer ${this.requireClientSecret()}`,\n };\n }\n\n /** Headers for the publishable-key routes (`/payments/*`, `/payment-methods`). */\n private pkHeaders(extra?: Record<string, string>): Record<string, string> {\n if (!this.publishableKey) {\n throw new DelopayError('This call requires the publishable key', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return { ...withoutCredentialHeaders(extra), 'api-key': this.publishableKey };\n }\n\n private requireClientSecret(): string {\n if (!this.clientSecret) {\n throw new DelopayError('This call requires the payment client secret', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return this.clientSecret;\n }\n\n /**\n * The hosted checkout's bootstrap payload for a one-time payment —\n * `CheckoutDetails` while payable, a status view once settled.\n *\n * Deliberately unauthenticated: a `pay_` link bootstraps before any\n * credential exists, so no credential header is ever attached (caller\n * extras are still stripped of credentials). Core fields and the collection\n * policy are typed; provider-specific fields remain available as unknown.\n *\n * `theme` (a named checkout variant) and `country` are the route's declared\n * query parameters. `country` is a manual override of the buyer country the\n * router otherwise resolves from the client IP — it decides which payment\n * methods the layout shows — as an ISO 3166-1 alpha-2 code, sent uppercased\n * and omitted when empty. `locale` travels as `Accept-Language` — the only\n * channel the backend's locale resolution reads; a `?locale=` query is\n * silently ignored by this route.\n *\n * `GET /payment-link/data/{merchantId}/{paymentId}`\n */\n async fetchCheckoutData(\n params?: { locale?: string; theme?: string; country?: string },\n options?: RequestExtras,\n ): Promise<CheckoutDataResponse> {\n const country = params?.country?.trim().toUpperCase();\n return this.client.request(\n 'GET',\n `/payment-link/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n query: { theme: params?.theme, country: country || undefined },\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(withoutCredentialHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : withoutCredentialHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * The subscription twin of {@link CheckoutSession.fetchCheckoutData}: the\n * bootstrap payload for a `sub_` checkout. Authenticated with the\n * subscription's client secret (construct the session with the `sub_…` id\n * in the `paymentId` slot). `locale` travels as `Accept-Language`, same\n * as {@link CheckoutSession.fetchCheckoutData}.\n *\n * `GET /subscriptions/data/{merchantId}/{subscriptionId}`\n */\n async fetchSubscriptionData(\n params?: { locale?: string },\n options?: RequestExtras,\n ): Promise<SubscriptionCheckoutResponse> {\n return this.client.request(\n 'GET',\n `/subscriptions/data/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n ...options,\n headers: {\n ...(params?.locale\n ? {\n ...withoutHeader(this.bearerHeaders(options?.headers), 'accept-language'),\n 'Accept-Language': params.locale,\n }\n : this.bearerHeaders(options?.headers)),\n },\n },\n );\n }\n\n /**\n * Report buyer/device signals for rails that never reach\n * `/payments/{id}/confirm` (the Stripe SAQ-A rail: raw cards, Apple Pay,\n * Google Pay). Same telemetry contract as\n * {@link CheckoutSession.recordEvent}: sent with `keepalive: true`, and\n * failures resolve instead of rejecting — signals must never block or\n * break a checkout. Unauthenticated by design.\n *\n * `POST /payment-link/client-signals/{merchantId}/{paymentId}`\n */\n async reportClientSignals(\n params: {\n browser_info?: Record<string, unknown>;\n signals: Record<string, unknown>;\n },\n options?: RequestExtras,\n ): Promise<void> {\n try {\n await this.client.request(\n 'POST',\n `/payment-link/client-signals/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n body: params,\n keepalive: true,\n ...options,\n headers: withoutCredentialHeaders(options?.headers),\n },\n );\n } catch {\n // Telemetry: swallowing is the contract, not an oversight.\n }\n }\n\n /**\n * Store one slice of the buyer's checkout recording on our own side.\n * Called by the hosted checkout as the buyer works through the page; the\n * client secret is attached automatically.\n *\n * **Not telemetry semantics, on purpose.** Unlike\n * {@link CheckoutSession.recordEvent}, this rejects with a `DelopayError`\n * like every other payment call, because the recorder has to tell the\n * answers apart: a `400` with code `IR_16` means the backend will not take\n * this recording (recording is off on that deployment, the recording is\n * full, the payment is already recording a different session, or this\n * number is stored with different content) and the recorder must stop; any\n * other `400` is the slice itself being refused; a transport failure may be\n * retried with the **same** bytes under the **same** number, which the\n * backend answers with `duplicate: true`.\n *\n * Pass `keepalive: true` for the last slice of a page that is navigating\n * away (a redirect rail); browsers refuse keepalive bodies over ~64 KiB, so\n * only a small final slice should carry it.\n *\n * Pass `compress: true` to send the slice gzipped. Recorded page events\n * compress heavily, so this is mostly a saving on the buyer's connection. It\n * is opt-in and degrades silently: a runtime without `CompressionStream`\n * sends the same slice uncompressed rather than failing, so a caller never\n * has to feature-test before asking for it.\n *\n * ⚠️ `keepalive` overrides it. Compressing means awaiting a stream read\n * before the request is made, and `keepalive` protects a request only once\n * it has been initiated — so a page torn down mid-compression would drop the\n * final slice altogether. A slice sent with `keepalive` therefore always\n * travels uncompressed, whatever `compress` says. Passing both is allowed and\n * is what a recorder should do: every ordinary slice compresses, and the last\n * one is sent the way that actually arrives.\n *\n * For a precompressed event array, pass `compressed_events` and `gzipBody`.\n * The latter receives the complete JSON request (including the session's\n * client secret) and must return gzip bytes synchronously. Fetch then starts\n * before this method yields, including on a page-navigation slice. A\n * keepalive request is used only when that prepared body is at most 60 KiB.\n *\n * `POST /payments/{paymentId}/replay/slice` (publishable key)\n */\n async storeReplaySlice(\n params: ReplayIngestParams,\n options?: RequestExtras & {\n keepalive?: boolean;\n compress?: boolean;\n /** Gzip a prepared JSON envelope synchronously before the request starts. */\n gzipBody?: (body: Uint8Array) => Uint8Array;\n },\n ): Promise<ReplayIngestResponse> {\n const { keepalive, compress, gzipBody, ...extras } = options ?? {};\n // Built before anything can be compressed, so a missing credential still\n // rejects without a request going out.\n const body = { ...params, client_secret: this.requireClientSecret() };\n const headers = this.pkHeaders(extras.headers);\n // `keepalive` wins over `compress`, and that is a correctness rule rather\n // than a preference. `keepalive` preserves a request only once it has been\n // *initiated*; compressing first means awaiting a stream read, and a page\n // torn down during that await never reaches `fetch()` at all — the final\n // slice is then lost outright, which is the one thing `keepalive` exists to\n // prevent. Losing a slice to save bytes is the wrong trade, so the slice a\n // page is navigating away from travels uncompressed. It is also the\n // smallest one: browsers refuse keepalive bodies over ~64 KiB anyway.\n const encoded = gzipBody?.(new TextEncoder().encode(JSON.stringify(body)));\n const gzipped = encoded\n ? Uint8Array.from(encoded).buffer\n : compress === true && keepalive !== true\n ? await gzipJson(body)\n : null;\n return this.client.request(\n 'POST',\n `/payments/${encodeURIComponent(this.paymentId)}/replay/slice`,\n {\n body: gzipped ?? body,\n ...(keepalive !== undefined\n ? { keepalive: encoded ? keepalive && encoded.byteLength <= 60 * 1024 : keepalive }\n : {}),\n ...extras,\n // `Content-Type` has to be stated for the compressed body: the client\n // only sets it for a body it serialises itself, and the bytes are\n // still JSON — gzip is how they travel, not what they are.\n headers:\n gzipped === null\n ? headers\n : { ...headers, 'Content-Type': 'application/json', 'Content-Encoding': 'gzip' },\n },\n );\n }\n\n /**\n * The status a buyer coming back from the processor's checkout may read:\n * the subscription's status, and whether the processor has reported it yet\n * (`awaiting_processor`). Construct the session with the `sub_…` id in the\n * `paymentId` slot.\n *\n * Authenticated with the return token (`rt`) the return URL carried, sent as\n * `Authorization: Bearer <rt>`. That token reads only this, for a day; it is\n * never the client secret, which this call does not send.\n *\n * `GET /subscriptions/return-status/{merchantId}/{subscriptionId}`\n */\n async subscriptionReturnStatus(\n returnToken: string,\n options?: RequestExtras,\n ): Promise<SubscriptionReturnStatusResponse> {\n if (!returnToken) {\n throw new DelopayError('This call requires the return token (rt) from the return URL', {\n status: 0,\n code: 'MISSING_CREDENTIAL',\n type: 'invalid_request',\n });\n }\n return this.client.request(\n 'GET',\n `/subscriptions/return-status/${encodeURIComponent(this.merchantId)}/${encodeURIComponent(this.paymentId)}`,\n {\n ...options,\n headers: {\n ...withoutCredentialHeaders(options?.headers),\n Authorization: `Bearer ${returnToken}`,\n },\n },\n );\n }\n\n /**\n * Confirm a subscription (PayPal approval rail). The client secret is\n * attached automatically; the shop's profile id travels as the\n * `X-Profile-Id` header the subscription routes require.\n *\n * `POST /subscriptions/{subscriptionId}/confirm` (publishable key)\n */\n async confirmSubscription(\n subscriptionId: string,\n profileId: string,\n params: Omit<ConfirmSubscriptionRequest, 'client_secret'>,\n options?: RequestExtras,\n ): Promise<ConfirmSubscriptionResponse> {\n return this.client.request(\n 'POST',\n `/subscriptions/${encodeURIComponent(subscriptionId)}/confirm`,\n {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n // Strip any caller-supplied x-profile-id first (case-insensitively):\n // Fetch folds duplicate headers into `caller, pro_x`, and the\n // subscription routes must see exactly one profile scope.\n headers: {\n ...withoutHeader(this.pkHeaders(options?.headers), 'x-profile-id'),\n 'X-Profile-Id': profileId,\n },\n },\n );\n }\n\n /**\n * The e-Payouts rail catalog for the buyer's country, plus the set of\n * countries that have at least one vendor.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/epayouts/methods`\n *\n * Pass `{ paypalSdk: true }` from a checkout drawing an experimental PayPal\n * SDK pane to also receive e-Payouts' PayPal client id\n * (`paypal_client_id`, `paypal_currency`); it is present only when `ppal`\n * is among the methods.\n *\n * @param country - Lowercase ISO 3166-1 alpha-2 country code.\n */\n async epayoutsMethods(\n country: string,\n options?: RequestExtras & EpayoutsMethodsOptions,\n ): Promise<EpayoutsMethodsResponse> {\n const { paypalSdk, merchantConnectorId, ...extras } = options ?? {};\n return this.client.request('GET', `${this.linkBase}/epayouts/methods`, {\n query: paypalSdk\n ? {\n cc: country,\n paypal_sdk: 'true',\n ...(merchantConnectorId ? { merchant_connector_id: merchantConnectorId } : {}),\n }\n : { cc: country },\n ...extras,\n headers: this.bearerHeaders(extras.headers),\n });\n }\n\n /**\n * The PayPal order for the payment's e-Payouts access code, from the PayPal\n * SDK's `createOrder` on an experimental PayPal SDK pane — after the payment\n * was confirmed through that pane, which mints the code.\n *\n * The router reads the order off e-Payouts' own PayPal page for the code, so\n * `amount` and `currency` are what e-Payouts charges for it. Repeated calls\n * answer the same order, so a cancelled PayPal popup is retried with the same\n * code. When `captured` is `true` a capture was already reported: create no\n * order and wait for the payment's status instead.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/epayouts/paypal-order`\n */\n async epayoutsPaypalOrder(options?: RequestExtras): Promise<EpayoutsPaypalOrderResponse> {\n return this.client.request('POST', `${this.linkBase}/epayouts/paypal-order`, {\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Report a PayPal order's progress from `onApprove` on an experimental PayPal\n * SDK pane: the approval, before asking PayPal to capture — and capture only\n * once the router has it — then the capture PayPal answered, or a decline.\n * When the approval's answer is lost, do not capture: report `NOT_CAPTURED`\n * instead, which releases an approval the router may have recorded.\n *\n * The router records each on the payment and relays a capture that took money\n * to e-Payouts the way e-Payouts' own PayPal page does. It does not mark the\n * payment paid: that happens only on e-Payouts' notification, so poll the\n * payment's status afterwards. A repeated report is answered, not recorded\n * twice.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/epayouts/paypal-capture`\n */\n async epayoutsPaypalCapture(\n params: EpayoutsPaypalCaptureRequest,\n options?: RequestExtras,\n ): Promise<EpayoutsPaypalCaptureResponse> {\n return this.client.request('POST', `${this.linkBase}/epayouts/paypal-capture`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Record a buyer-side checkout event on the payment's status timeline.\n *\n * Telemetry semantics, built in so callers can genuinely fire-and-forget:\n * the request is sent with `keepalive: true` (it survives the document\n * navigating away, e.g. right before a `window.open`), and transport or\n * server failures resolve to `undefined` instead of rejecting — telemetry\n * must never break a checkout or surface an unhandled rejection. Do not\n * `await` this in a click handler that must stay synchronous.\n *\n * A missing client secret still throws `MISSING_CREDENTIAL`: that is a\n * wiring bug, not a telemetry failure.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/checkout-events`\n */\n async recordEvent(\n params: RecordCheckoutEventRequest,\n options?: RequestExtras,\n ): Promise<RecordCheckoutEventResponse | undefined> {\n const headers = this.bearerHeaders(options?.headers);\n try {\n return await this.client.request('POST', `${this.linkBase}/checkout-events`, {\n body: params,\n keepalive: true,\n ...options,\n headers,\n });\n } catch {\n return undefined;\n }\n }\n\n /** Create a new Apple merchant-validation session for a payable Mollie checkout.\n * Requires a live Mollie validation key even for a test payment; never charges.\n * Browser Origin must match the configured checkout domain.\n */\n async mollieApplePaySession(\n params: MollieApplePaySessionRequest,\n options?: RequestExtras,\n ): Promise<MollieApplePaySessionResponse> {\n return this.client.request('POST', `${this.linkBase}/mollie/apple-pay-session`, {\n ...options,\n body: params,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Prepare MicroPayment transfer instructions or an unsigned SEPA mandate.\n * No debit is approved. Show the returned mandate disclosure before collecting\n * acceptance, then confirm with metadata.micropayment_preparation and, for\n * new SEPA mandates, explicit customer_acceptance. Every SEPA confirm must\n * acknowledge its amount/date notice with metadata.micropayment_prenotified.\n * Echo native_pane_merchant_connector_id and the returned\n * native_pane_quote_generation on confirm. Saved reuse sends\n * recurring_details: { type: 'payment_method_id', data: payment_method_id }\n * with payment_method: 'bank_debit', payment_method_type: 'sepa' and no raw\n * bank data. Only saved off-session preparation may omit quote_generation.\n * Transfer instructions become available only after canonical confirmation.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/micropayment/bank-session`\n */\n async micropaymentBankSession(\n params: MicropaymentBankSessionRequest,\n options?: RequestExtras,\n ): Promise<MicropaymentBankSessionResponse> {\n return this.client.request('POST', `${this.linkBase}/micropayment/bank-session`, {\n ...options,\n body: params,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * A short-lived VGS Collect session for browser-side card capture.\n *\n * **Exactly one refusal means \"this shop has no vault\": a 400 carrying\n * `IR_19`.** Every other refusal means a vault exists and could not be used,\n * and answering it by falling back to the processor's own card pane sends an\n * unprotected card number to the very processor the shop pays to hide it\n * from — the bug this endpoint's error contract exists to prevent.\n *\n * A **404 is not benign.** The router answers it when the shop's vault\n * account cannot be found — the state a shop is left in when its vault\n * connector is deleted while the profile keeps naming the id: it still\n * reports the vault as enabled and still expects its cards cloaked. The same\n * status also covers a payment that does not exist.\n *\n * `params.appearance` asks for a form styled to match the page (Enigma\n * Vault). The answer then carries `height`, the frame height to use. If the\n * vault refuses the styled form the answer is the plain one, without\n * `height`. `params.locale` is the buyer's locale.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/vault/collect-session`\n */\n async vaultCollectSession(\n options?: RequestExtras,\n params?: VaultCollectSessionParams,\n ): Promise<VaultCollectSessionResponse> {\n const look = params?.appearance;\n return this.client.request('GET', `${this.linkBase}/vault/collect-session`, {\n ...options,\n query: {\n locale: params?.locale,\n form_surface: look?.surface,\n form_text: look?.text,\n form_border: look?.border,\n form_accent: look?.accent,\n form_danger: look?.danger,\n form_font: look?.font,\n form_radius: look?.radius,\n form_size: look?.size,\n form_labels: look?.labels,\n },\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Mint the security-code form for a saved card, on a shop whose vault keeps\n * the code itself (Enigma Vault). The buyer re-enters the code into the\n * vault's own form, so it never reaches the checkout; confirm with the saved\n * card's `payment_token` once the form reports it stored.\n *\n * `paymentToken` is the saved card's token from the payment-method list. A\n * VGS shop answers `400`: VGS re-collects the code with Collect.\n *\n * `GET /payment-link/{merchantId}/{paymentId}/vault/security-code-session`\n */\n async vaultSecurityCodeSession(\n paymentToken: string,\n options?: RequestExtras,\n ): Promise<EnigmaFormSession> {\n return this.client.request('GET', `${this.linkBase}/vault/security-code-session`, {\n ...options,\n query: { payment_token: paymentToken },\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Register the aliased card as a payment method and mint the one-shot\n * `payment_token` the confirm call spends.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/vault/payment-method`\n */\n async registerVaultPaymentMethod(\n params: VaultPaymentMethodRequest,\n options?: RequestExtras,\n ): Promise<VaultPaymentMethodResponse> {\n return this.client.request('POST', `${this.linkBase}/vault/payment-method`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Confirm the Stripe card form's PaymentIntent through the router, for a\n * checkout payload with `card_connector_server_confirm: true`. Stripe refuses\n * a Stripe.js confirm of such an intent.\n *\n * Send the PaymentMethod `stripe.createPaymentMethod` produced from the\n * Payment Element (or Express Checkout Element), which needs\n * `paymentMethodCreation: 'manual'` on the Elements instance. A\n * ConfirmationToken is refused with `400`: Stripe will not confirm such an\n * intent with one.\n *\n * The router judges the card's issuing country and the buyer's IP country\n * against the shop's sell-to restrictions before Stripe authorises, and a\n * refusal throws a `DelopayError` with code `DE_10`. A buyer on the\n * merchant's buyer blocklist is refused before any Stripe call with code\n * `DE_14` (`buyer_blocked`, 422), which names no entry. When the answer's\n * `status` is `requires_action`, run `stripe.handleNextAction` with its\n * `client_secret` — safe, because the intent is `confirmation_method=manual`\n * and that secret confirms nothing without the secret key — then call this\n * again without a payment method to finalize.\n *\n * A PaymentMethod rules out what `stripe.createPaymentMethod` cannot\n * produce: Stripe names Amazon Pay and Klarna in the Express Checkout\n * Element, which need `stripe.createConfirmationToken` instead. Neither can\n * be paid through this route, so a caller must not offer them on a\n * server-confirmed intent — mount the Express Checkout Element with those\n * methods `'never'`, as DeloPay's own checkout does. The router drops only\n * the methods its server-side confirm cannot finish at all (BLIK and ACSS\n * pre-authorized debits) from the card form's mount, so the rest of the\n * selection still reaches the element and is the caller's to constrain.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/stripe-confirm`\n */\n async confirmStripeCardForm(\n params: StripeHostedConfirmRequest,\n options?: RequestExtras,\n ): Promise<StripeHostedConfirmResponse> {\n return this.client.request('POST', `${this.linkBase}/stripe-confirm`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Make the buyer's add-on choice while the checkout data answers\n * `type: 'addon_choice'`.\n *\n * Only price ids and quantities are sent; the router prices them from the\n * catalog and judges every selection group's bounds. The payment's lines and\n * amount change together, once: the choice is final afterwards, the same\n * choice sent again answers the same result, and another is refused with\n * `IR_16` — as is a choice once anything could have been charged at the\n * previous amount. Fetch the checkout data again afterwards for the payment\n * methods at the final amount.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/addons`\n */\n async chooseAddons(\n params: CheckoutAddonChoiceRequest,\n options?: RequestExtras,\n ): Promise<CheckoutAddonChoiceResponse> {\n return this.client.request('POST', `${this.linkBase}/addons`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * Ask whether NomuPay's COPYandPAY widget may submit a card, from the\n * form's pre-submit hook.\n *\n * Only for a checkout stamped `NomupayOppwaCheckoutData.submit_grant`: the\n * card form sits beside always-shown wallet buttons of another account, and\n * this answer closes those buttons before it allows the card. `authorized`\n * is `false` when the payment no longer waits for a payment method, or when\n * this is not the attempt's live card-form checkout; when a wallet beside it\n * is already being paid, the route answers an error instead. Submit the\n * widget only on `true`.\n *\n * `POST /payment-link/{merchantId}/{paymentId}/nomupay-card-authorization`\n */\n async nomupayCardAuthorization(\n params: NomupayCardAuthorizationRequest,\n options?: RequestExtras,\n ): Promise<NomupayCardAuthorizationResponse> {\n return this.client.request('POST', `${this.linkBase}/nomupay-card-authorization`, {\n body: params,\n ...options,\n headers: this.bearerHeaders(options?.headers),\n });\n }\n\n /**\n * The payment's current state — status polling for redirect/popup rails.\n *\n * `GET /payments/{paymentId}` (publishable key + client secret)\n */\n async retrievePayment(options?: RequestExtras): Promise<PaymentResponse> {\n return this.client.request('GET', `/payments/${encodeURIComponent(this.paymentId)}`, {\n query: { client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Update the payment before confirmation (e.g. persist custom-field\n * answers as `metadata` on rails that never hit `/confirm`). The client\n * secret is attached automatically.\n *\n * `POST /payments/{paymentId}` (publishable key)\n */\n async updatePayment(\n params: PaymentUpdateRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Confirm the payment. The client secret is attached automatically; pass\n * an `Idempotency-Key` header via `options` to make retries safe.\n *\n * `POST /payments/{paymentId}/confirm` (publishable key)\n */\n async confirmPayment(\n params: PaymentConfirmRequest,\n options?: RequestExtras,\n ): Promise<PaymentResponse> {\n return this.client.request('POST', `/payments/${encodeURIComponent(this.paymentId)}/confirm`, {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n\n /**\n * Mint the processor-side session a browser SDK completes — the PayPal\n * order that PayPal's buttons or Card Fields attach the buyer's choice to.\n * The client secret is attached automatically.\n *\n * For PayPal Card Fields pass `payment_method: 'card'` and the\n * `merchant_connector_id` the checkout was rendered with; the order id comes\n * back in `next_action.next_action_data.order_id` and is what the SDK's\n * `createOrder` returns. The confirm that captures it sends the same order\n * and account as `payment_method_data.card_reference`.\n *\n * Send a distinct `Idempotency-Key` through `options.headers` for each new\n * card submission; reuse it only to retry that same session request. The\n * returned order is bound to this attempt and account. Sessions cannot\n * replace an order while authentication or money processing is unresolved,\n * or after authorization/capture; stale or foreign references are refused.\n *\n * `POST /payments/{paymentId}/post-session-tokens` (publishable key)\n */\n async postSessionTokens(\n params: PaymentsPostSessionTokensRequest,\n options?: RequestExtras,\n ): Promise<PaymentsPostSessionTokensResponse> {\n return this.client.request(\n 'POST',\n `/payments/${encodeURIComponent(this.paymentId)}/post-session-tokens`,\n {\n body: { ...params, client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n },\n );\n }\n\n /**\n * Abandon the attempt the buyer left open on a connector's hosted page\n * (the payment sits in `requires_customer_action`) and open a fresh attempt\n * awaiting a payment method, so the same payment can be confirmed again\n * with another method or connector. Nothing has been authorised on the\n * abandoned attempt; it is voided locally and kept in the attempt history.\n * Idempotent: a payment already in `requires_payment_method` comes back\n * unchanged with `abandoned_attempt_id: null`.\n *\n * `POST /payments/{paymentId}/abandon-attempt` (publishable key + client secret)\n */\n async abandonAttempt(options?: RequestExtras): Promise<PaymentAbandonAttemptResponse> {\n return this.client.request(\n 'POST',\n `/payments/${encodeURIComponent(this.paymentId)}/abandon-attempt`,\n {\n body: { client_secret: this.requireClientSecret() },\n ...options,\n headers: this.pkHeaders(options?.headers),\n },\n );\n }\n\n /**\n * Payment methods available for this payment.\n *\n * `GET /payment-methods` (publishable key + client secret)\n *\n * @param params - Optional filters; `country` is the highest-precedence\n * geo hint, ahead of billing address and IP geolocation.\n */\n async listPaymentMethods(\n params?: { country?: string },\n options?: RequestExtras,\n ): Promise<PaymentMethodListResponse> {\n return this.client.request('GET', '/payment-methods', {\n query: { client_secret: this.requireClientSecret(), country: params?.country },\n ...options,\n headers: this.pkHeaders(options?.headers),\n });\n }\n}\n","// **Payment panes** — merchant-configured payment methods that render as\n// DeloPay-drawn tiles in the embedded checkout instead of inside a connector's\n// own embedded form.\n//\n// Why they exist: Stripe only offers Apple Pay / Google Pay / Link when the\n// *top-level* document's domain is registered as a payment method domain on the\n// merchant's Stripe account. In an embedded iframe that domain is the\n// merchant's shop, not the DeloPay checkout — so the wallet silently\n// disappears. A pane replaces it with our own tile that opens the DeloPay\n// hosted checkout at the top level, in a focused single-method view.\n//\n// Nothing here is Apple-Pay-specific, and since the router published a\n// per-connector capability catalogue nothing here is Stripe-specific either:\n// the feature is \"which of a connector's payment methods render as a pane, and\n// how they look\".\n//\n// This module serves SDK consumers: merchants configuring\n// `metadata.native_panes` on a merchant connector account programmatically\n// (codec), reading the resolved `native_panes` off a checkout payload\n// ({@link PaneView}), or building the focused single-method link that goes\n// behind their own button ({@link focusedCheckoutUrl}).\n//\n// The wire shapes are owned by the router (delopay-backend\n// `crates/router/src/core/payment_link/native_panes.rs`) — `native_panes` in\n// the metadata key, the field names and the enum values are contracts with it\n// and with links already in buyers' hands, so the identifiers here were renamed\n// off \"native pane\" and the wire was not.\n//\n// Capability (which connector may publish which method, on which rail) comes\n// from the router at runtime through `connectors.getPanesCatalog()`, not from a\n// table here.\n\n// Type-only, so this module still emits no imports and can be executed\n// standalone. `types.ts` owns the catalogue's wire shapes because they are\n// generated-spec-paired (`scripts/validate-types.ts`); it imports nothing from\n// here, so the dependency runs one way.\nimport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n PaneNativeElement,\n} from './types';\n\nexport type {\n PaneCapability,\n PaneRail,\n PanesCatalogResponse,\n PanesConnectorCatalog,\n PaneSurcharge,\n PaneView,\n PaneVisibility,\n PaneOpenTarget,\n SurchargeDirection,\n};\n\n// --- Wire types ---------------------------------------------------------\n\n/**\n * The values {@link decodePanes} recognises. Anything else — a value written by\n * a dashboard newer than this SDK — degrades to `always` rather than throwing\n * or dropping the row: an older SDK reading a newer blob is a normal state\n * during a rollout, and a hard failure there takes out a merchant's whole\n * connector config rather than one tile.\n */\nconst PANE_VISIBILITIES: readonly PaneVisibility[] = ['always', 'embedded_only', 'external_only'];\n\n/**\n * `same_page` and `popup` are kept as written; anything else — including the\n * absent key — is the default `tab`, as it always was.\n */\nfunction parseOpenTarget(raw: unknown): PaneOpenTarget {\n return raw === 'popup' || raw === 'same_page' ? raw : 'tab';\n}\n\nfunction parseVisibility(raw: unknown): PaneVisibility {\n return PANE_VISIBILITIES.find((value) => value === raw) ?? 'always';\n}\n\nconst PANE_NATIVE_ELEMENTS: readonly PaneNativeElement[] = [\n 'everywhere',\n 'embedded_only',\n 'external_only',\n];\n\n/**\n * Read a stored row's native-element choice, tolerantly.\n *\n * Absent decodes to `everywhere`, because that is what the router decodes a\n * missing key to (`admin::NativePaneNativeElement` defaults to it): a row\n * written before the field existed means \"the wallet's own button wherever\n * this pane is offered\", which is what the tile was always a stand-in for. An\n * unknown word degrades the same way rather than dropping the row — the\n * router's own decode is lenient for the same rolling-deploy reason.\n */\nfunction parseNativeElement(raw: unknown): PaneNativeElement {\n return PANE_NATIVE_ELEMENTS.find((value) => value === raw) ?? 'everywhere';\n}\n\n/**\n * One pane exactly as the merchant configures it. Persisted (JSON) under\n * `metadata.native_panes` on the merchant connector account.\n *\n * Field names are the wire contract — renaming one is a migration. The router\n * decodes strictly row by row: a row that fails strict decoding (e.g. a\n * wrong-typed field like `display_order: \"3\"`) is dropped whole with a server\n * log, and the remaining rows still render. This SDK's {@link decodePanes} is\n * additionally per-property tolerant — including clamping `display_order` into\n * the router's `i32` range — so a decode→encode round-trip through the SDK\n * repairs a blob the router would partially drop.\n */\nexport interface Pane {\n /** Catalogue key of the promoted method — see {@link paneMethodInfo}. */\n method: string;\n /** Disabled rows keep their tuning but never reach a buyer. */\n enabled: boolean;\n /** Default-language tile label. Empty falls back to the catalogue name. */\n label: string;\n /** Per-locale overrides of `label`, keyed by checkout locale (`de`, `de-AT`). */\n labelTranslations: Record<string, string>;\n /**\n * Secondary line under the label. `null` means \"use the catalogue default\";\n * an empty string means the merchant deliberately hid the line. That\n * distinction is the whole reason this is nullable and `label` is not.\n */\n sublabel: string | null;\n /** Per-locale overrides of `sublabel`. */\n sublabelTranslations: Record<string, string>;\n /** Section the tile groups under. Empty falls back to the catalogue category. */\n category: string;\n /** Built-in icon key — see {@link PANE_ICON_KEYS}. */\n icon: string;\n /** Custom inline SVG. Sanitized server-side before it reaches a buyer; a\n * rejected payload falls back to the built-in `icon`. */\n iconSvg: string;\n /** Lower renders first; ties break on catalogue order. */\n displayOrder: number;\n /** Where the tile is offered — see {@link PaneVisibility}. */\n visibility: PaneVisibility;\n /** How the embedded checkout opens the focused view — see {@link PaneOpenTarget}. */\n openIn: PaneOpenTarget;\n /**\n * Where the wallet's own button replaces this tile — see\n * {@link PaneNativeElement}. Only meaningful on a method whose catalogue\n * entry says {@link PaneCapability.supports_native_element}; the router\n * ignores it elsewhere. `everywhere` is the default and what a row stored\n * before the field existed decodes to.\n */\n nativeElement: PaneNativeElement;\n /** A shipped look instead of the icon (`paypal`, `card`); `''` or absent = none.\n * Optional because a `Pane` built before the field existed must still encode. */\n preset?: string;\n /** The preset's style; `''` or absent = the preset's default. */\n style?: string;\n}\n\n/**\n * Read a resolved tile's placement rule, across every payload version.\n *\n * Prefer this to touching either field. They are independent on the wire — a\n * payload may carry either, both or neither — and each alone loses a placement\n * rule: `embedded_only` cannot express `external_only`, so an `external_only`\n * tile read through it renders inside the merchant iframe the merchant asked\n * to keep it out of; `visibility` is absent on a router that predates it, so\n * an `embedded_only` tile read through it alone renders at top level too,\n * duplicating a method Stripe's own form already offers there.\n *\n * A recognised `visibility` wins. Otherwise the legacy boolean answers: absent\n * (old router) it carries the only placement that router could express, and\n * unrecognised (newer router) the router still sets it under its own fixed\n * rule. Neither path throws, and both degrade toward showing a tile — losing a\n * placement rule, never stranding a method.\n */\nexport function paneViewVisibility(\n view: Pick<PaneView, 'visibility' | 'embedded_only'>,\n): PaneVisibility {\n const declared = PANE_VISIBILITIES.find((value) => value === view.visibility);\n if (declared) return declared;\n return view.embedded_only === true ? 'embedded_only' : 'always';\n}\n\n// --- Catalogue ----------------------------------------------------------\n\n/**\n * A method the frozen Stripe fallback table knows, with the compiled copy the\n * router shipped for it at the time.\n *\n * Only {@link STRIPE_FALLBACK_PANE_METHODS} is typed with this. The live\n * catalogue (`connectors.getPanesCatalog()`) carries capability facts and no\n * copy at all, by design — see {@link PaneCapability}.\n */\nexport interface PaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethod: string;\n /** Confirm routing key. Pass through verbatim; never derive it. */\n paymentMethodType: string;\n /** The focused checkout has to collect a billing country to confirm this. */\n requiresBillingCountry: boolean;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * What this SDK assumes when the router cannot answer.\n *\n * The capability endpoint does not exist on an older router, which answers\n * `connectors.getPanesCatalog()` with a 404.\n * Rather than leaving a caller with nothing, the pane helpers default to\n * exactly the behaviour they had before that endpoint existed: panes on the\n * Stripe connector only, with the method set the router's Stripe catalogue had\n * at the time.\n *\n * **This is a degradation path, not a mirror. Do not keep it in sync by hand,\n * and do not add a connector or a method to it** — that is what this table was\n * before this ticket, and adding to it would quietly rebuild the mirror. A\n * connector the router serves panes for arrives through the endpoint and needs\n * no entry here; a connector that needs an entry here to appear is a connector\n * the router will not deliver panes for anyway.\n *\n * The only reason to touch this list is to correct what Stripe's catalogue\n * looked like *before* the endpoint existed, and that is history, so there is\n * no such reason. Once the endpoint is reachable it is never consulted for a\n * connector the router answered for.\n *\n * The redirect-rail set is deliberately narrow — every entry is a variant the\n * Stripe connector accepts and that needs no extra buyer input beyond a\n * billing country. `eps` / `p24` / `bancontact` are absent because Stripe\n * hard-requires billing fields the focused checkout never collects (a full\n * name for EPS and Bancontact, an email for Przelewy24), so their tiles could\n * never succeed.\n *\n * `defaultLabel` / `defaultSublabel` are the copy the router compiled at that\n * time and are frozen with the rest of the table. Copy for a method the live\n * catalogue reports belongs to the consumer's own locale files, keyed by\n * `key` — the router ships none.\n */\nexport const STRIPE_FALLBACK_PANE_METHODS: readonly PaneMethodInfo[] = [\n {\n key: 'apple_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'apple_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Apple Pay',\n defaultSublabel: 'Pay with Apple Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'apple',\n },\n {\n key: 'google_pay',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'google_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Google Pay',\n defaultSublabel: 'Pay with Google Pay',\n defaultCategory: 'wallet',\n defaultIcon: 'google',\n },\n {\n key: 'link',\n rail: 'wallet',\n paymentMethod: 'wallet',\n paymentMethodType: 'link',\n requiresBillingCountry: false,\n defaultLabel: 'Link',\n defaultSublabel: 'Pay with saved details',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'klarna',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'klarna',\n // Stripe's Klarna needs the buyer's country echoed into the confirm body.\n requiresBillingCountry: true,\n defaultLabel: 'Klarna',\n // NOT the router's current \"Pay later or in 3 instalments\". This table is\n // what a router predating the capability endpoint renders, and that copy\n // only gained the \"3\" in the same release that added the endpoint.\n // Restating the new string here\n // would put copy no reachable router emits in front of a merchant, and\n // would change what the deprecated `nativePaneMethodInfo` has returned\n // since 0.106.0.\n defaultSublabel: 'Pay later or in instalments',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'affirm',\n rail: 'redirect',\n paymentMethod: 'pay_later',\n paymentMethodType: 'affirm',\n requiresBillingCountry: false,\n defaultLabel: 'Affirm',\n defaultSublabel: 'Pay over time',\n defaultCategory: 'bnpl',\n defaultIcon: 'bnpl',\n },\n {\n key: 'ideal',\n rail: 'redirect',\n paymentMethod: 'bank_redirect',\n paymentMethodType: 'ideal',\n requiresBillingCountry: false,\n defaultLabel: 'iDEAL',\n defaultSublabel: 'Pay from your bank',\n defaultCategory: 'bank_redirect',\n defaultIcon: 'bank',\n },\n {\n key: 'alipay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'ali_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Alipay',\n defaultSublabel: 'Pay with Alipay',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'revolut_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'revolut_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Revolut Pay',\n defaultSublabel: 'Pay with Revolut',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n {\n key: 'amazon_pay',\n rail: 'redirect',\n paymentMethod: 'wallet',\n paymentMethodType: 'amazon_pay',\n requiresBillingCountry: false,\n defaultLabel: 'Amazon Pay',\n defaultSublabel: 'Pay with Amazon',\n defaultCategory: 'wallet',\n defaultIcon: 'wallet',\n },\n];\n\n/**\n * {@link STRIPE_FALLBACK_PANE_METHODS} in the shape the live endpoint returns,\n * so every helper below takes one type of catalogue and the degradation path\n * is not a second code path. Derived, not written out: two spellings of one\n * table is exactly the drift this ticket removed.\n */\nexport const STRIPE_FALLBACK_PANE_CATALOG: PanesConnectorCatalog = {\n connector: 'stripe',\n allowed_rails: ['wallet', 'redirect'],\n methods: STRIPE_FALLBACK_PANE_METHODS.map((info) => ({\n key: info.key,\n rail: info.rail,\n payment_method: info.paymentMethod,\n payment_method_type: info.paymentMethodType,\n requires_billing_country: info.requiresBillingCountry,\n })),\n};\n\n/**\n * An empty catalogue — a connector the router does not offer panes for.\n * Exported so callers can express \"asked, and the answer was no\" without\n * reaching for `null` in the middle of a computation.\n */\nexport function emptyPaneCatalog(connector: string): PanesConnectorCatalog {\n return { connector, allowed_rails: [], methods: [] };\n}\n\n/**\n * Pull one connector's entry out of a `connectors.getPanesCatalog()` response.\n *\n * Returns {@link emptyPaneCatalog} for a connector the response does not name:\n * \"the router knows this connector and publishes no panes for it\" and \"the\n * router has never heard of it\" are the same answer to a caller building an\n * editor, and both mean \"offer nothing\".\n */\nexport function paneCatalogFor(\n response: PanesCatalogResponse,\n connector: string,\n): PanesConnectorCatalog {\n return (\n response.connectors.find((entry) => entry.connector === connector) ??\n emptyPaneCatalog(connector)\n );\n}\n\n/**\n * Built-in tile icon keys the buyer-facing checkout ships a glyph for.\n *\n * Reconciled against both ends: every key here has a branch in the checkout's\n * `NativePaneIcon.svelte`, and every `default_icon` the router's catalogue\n * publishes is in this list. An icon key the checkout does not ship falls\n * through to `wallet` there, so a key that drifts in renders as the wrong\n * glyph rather than as nothing.\n */\nexport const PANE_ICON_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bank',\n 'apple',\n 'google',\n 'bnpl',\n 'cash',\n // Brand marks, not category glyphs: the checkout draws PayPal's monogram,\n // Klarna's squircle-K and the Bitcoin mark for these, the same logos the\n // bespoke panes they replace already drew. Listed here so a merchant's own\n // dashboard can offer them; the router decides which one a tile *defaults*\n // to, and a router predating them simply keeps sending the old default.\n 'paypal',\n 'klarna',\n 'crypto',\n];\n\n/**\n * Section keys a pane's tile may group under.\n *\n * Reconciled against the router's actual `default_category` values rather than\n * against what the Stripe table happened to need. `crypto` and `game_items`\n * are router defaults (the Cryptomus/NowPayments and Skinsback catalogues) and\n * were missing here, so a merchant configuring one of those panes was shown a\n * category their editor did not recognise.\n *\n * A custom value is allowed and renders as its own section under that literal\n * text. The buyer-facing checkout translates a subset of these into a section\n * header and falls through to the raw key for the rest — `crypto` and\n * `game_items` are the two it has yet to add.\n */\nexport const PANE_CATEGORY_KEYS: readonly string[] = [\n 'wallet',\n 'card',\n 'bnpl',\n 'bank_redirect',\n 'bank_transfer',\n 'crypto',\n 'game_items',\n 'cash',\n];\n\n/**\n * Mirror of the router's per-connector cap. Counted differently on each side:\n * {@link decodePanes} stops after 12 *decoded* rows (entries with a usable,\n * non-duplicate `method` — junk and duplicate entries don't consume a slot),\n * while the router caps *accepted* panes (enabled, known, deduplicated) at 12\n * — so an oversized hand-written blob may render a pane this decoder drops.\n * Blobs the SDK itself encodes never exceed the cap.\n */\nexport const PANES_MAX = 12;\n\n/**\n * Look a method up in one connector's catalogue.\n *\n * Pass the entry for the connector being configured, from\n * `connectors.getPanesCatalog()` via {@link paneCatalogFor}. The default is\n * the degradation path and only correct for Stripe on a router that predates\n * the endpoint — see {@link STRIPE_FALLBACK_PANE_CATALOG}.\n */\nexport function paneMethodInfo(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneCapability | undefined {\n return catalog.methods.find((info) => info.key === method);\n}\n\n/** Whether this connector may declare a pane on `rail` at all. A wallet pane\n * on a connector outside its `allowed_rails` is refused at save time — the\n * wallet rail rides on Stripe's Express Checkout Element charging the *same*\n * payment intent the embedded checkout holds, which does not generalise. */\nexport function paneRailAllowed(rail: PaneRail, catalog: PanesConnectorCatalog): boolean {\n return catalog.allowed_rails.includes(rail);\n}\n\n/**\n * The methods a caller may actually offer for this connector: the catalogue's\n * own list, minus anything on a rail the connector does not allow.\n *\n * The router should not report such a pair in the first place, but the two\n * fields are independent in the response and a save that crosses them is\n * refused at the API with an error naming the connector and the method. Filter\n * rather than trust, so a merchant never configures a tile the save will\n * bounce.\n */\nexport function offerablePaneMethods(catalog: PanesConnectorCatalog): PaneCapability[] {\n return catalog.methods.filter((info) => paneRailAllowed(info.rail, catalog));\n}\n\n/** Non-copy display defaults for a tile: which built-in glyph and which\n * section heading a new pane starts on. */\nexport interface PaneDisplayDefaults {\n icon: string;\n category: string;\n}\n\n/**\n * Per-method overrides, for the handful whose brand glyph is not what their\n * payment method would suggest. Everything else is derived from the catalogue\n * entry's `payment_method` below, so a connector the SDK has never heard of\n * still gets a sensible tile rather than a blank one.\n *\n * These have to be keyed by method and not by `payment_method`: `wallet` also\n * routes Link, Alipay, Revolut Pay and Amazon Pay, and `pay_later` also routes\n * Affirm — none of which the SDK has a mark for. Getting this wrong is not a\n * cosmetic slip that the next release fixes, because {@link defaultPane}\n * materialises the value and {@link encodePanes} writes it to\n * `metadata.native_panes`, where a stored `icon` outranks the router's\n * `default_icon` for the life of the pane.\n */\nconst DISPLAY_DEFAULTS_BY_KEY: Readonly<Record<string, PaneDisplayDefaults>> = {\n apple_pay: { icon: 'apple', category: 'wallet' },\n google_pay: { icon: 'google', category: 'wallet' },\n paypal: { icon: 'paypal', category: 'wallet' },\n // Both the Klarna connector's own tile and Stripe's Klarna. Affirm stays on\n // the generic `bnpl` glyph — same rail, no mark of its own.\n klarna: { icon: 'klarna', category: 'bnpl' },\n};\n\n/**\n * Derived from the `payment_method` half of the catalogue's routing pair.\n * Every value here reproduces the router's own `default_icon` /\n * `default_category` for the methods it publishes today, so a tile the SDK\n * lays out and a tile the router lays out agree.\n */\nconst DISPLAY_DEFAULTS_BY_PAYMENT_METHOD: Readonly<Record<string, PaneDisplayDefaults>> = {\n wallet: { icon: 'wallet', category: 'wallet' },\n card: { icon: 'card', category: 'card' },\n card_redirect: { icon: 'card', category: 'card' },\n pay_later: { icon: 'bnpl', category: 'bnpl' },\n bank_redirect: { icon: 'bank', category: 'bank_redirect' },\n bank_transfer: { icon: 'bank', category: 'bank_transfer' },\n bank_debit: { icon: 'bank', category: 'bank_transfer' },\n // Cryptomus and NowPayments publish the same `crypto` key on this rail, and\n // the router defaults both to the Bitcoin mark.\n crypto: { icon: 'crypto', category: 'crypto' },\n // Skinsback, which has no mark: the router defaults it to `wallet` too.\n game_items: { icon: 'wallet', category: 'game_items' },\n cash: { icon: 'cash', category: 'cash' },\n voucher: { icon: 'cash', category: 'cash' },\n};\n\nconst DISPLAY_DEFAULTS_FALLBACK: PaneDisplayDefaults = { icon: 'wallet', category: 'wallet' };\n\n/**\n * What a new tile looks like before the merchant designs it.\n *\n * The router serves capability, not presentation, so the glyph and the section\n * come from here and the accompanying text comes from the caller's own locale\n * files. A method with no entry at all still resolves — that is the point of\n * deriving from `payment_method`: a connector added to the router's catalogue\n * tomorrow needs no SDK release to be designable today.\n */\nexport function paneDisplayDefaults(info: PaneCapability | undefined): PaneDisplayDefaults {\n if (!info) return DISPLAY_DEFAULTS_FALLBACK;\n return (\n DISPLAY_DEFAULTS_BY_KEY[info.key] ??\n DISPLAY_DEFAULTS_BY_PAYMENT_METHOD[info.payment_method] ??\n DISPLAY_DEFAULTS_FALLBACK\n );\n}\n\n// --- Validation ---------------------------------------------------------\n\n/**\n * Why a configured pane would not survive a save or a render.\n *\n * - `method_unknown` — the connector's catalogue does not publish this key, so\n * the router drops the row at render.\n * - `rail_not_allowed` — the method's rail is not in the connector's\n * `allowed_rails`; the API refuses this at save time.\n * - `over_cap` — past the router's per-connector cap of {@link PANES_MAX}; the\n * row is stored but never rendered.\n * - `duplicate_method` — an earlier enabled row already claims this method.\n * The router skips disabled rows and then dedupes, so the first *enabled*\n * row renders and every later one is dropped in silence. Reported on the\n * losing rows, never on the one that survives.\n */\nexport type PaneIssueCode = 'method_unknown' | 'rail_not_allowed' | 'over_cap' | 'duplicate_method';\n\nexport interface PaneIssue {\n /** Index into the list handed to {@link validatePanes}. */\n index: number;\n method: string;\n code: PaneIssueCode;\n}\n\n/**\n * Check a configured list against one connector's catalogue, before writing it\n * to `metadata.native_panes`.\n *\n * The API applies the same rules at save time, so this changes where the\n * merchant finds out, not whether they do — and an SDK caller building an\n * editor would otherwise learn it from a bounced request with no row to point\n * at. An empty result means nothing here will be refused or silently dropped.\n */\nexport function validatePanes(\n panes: readonly Pane[],\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): PaneIssue[] {\n const issues: PaneIssue[] = [];\n // Keyed on the catalogue's own key rather than the raw string, because that\n // is what the router dedupes on. Only enabled rows are recorded: a disabled\n // row never reaches the router's `seen` set, so it neither claims a method\n // nor loses to one.\n const claimedBy = new Set<string>();\n panes.forEach((pane, index) => {\n const info = paneMethodInfo(pane.method, catalog);\n if (!info) {\n issues.push({ index, method: pane.method, code: 'method_unknown' });\n } else if (!paneRailAllowed(info.rail, catalog)) {\n issues.push({ index, method: pane.method, code: 'rail_not_allowed' });\n } else if (pane.enabled) {\n // Unknown and rail-refused rows are dropped before the router dedupes,\n // so they cannot claim a key — and reporting two codes for one row would\n // point the merchant at the wrong repair.\n if (claimedBy.has(info.key)) {\n issues.push({ index, method: pane.method, code: 'duplicate_method' });\n } else {\n claimedBy.add(info.key);\n }\n }\n if (index >= PANES_MAX) issues.push({ index, method: pane.method, code: 'over_cap' });\n });\n return issues;\n}\n\n// --- Codec --------------------------------------------------------------\n\n/**\n * A new pane for `method`, with its glyph and section resolved from the\n * connector's catalogue entry rather than from a Stripe-keyed table — so\n * `defaultPane('creem_checkout', catalog)` is a designed tile and not a blank\n * one.\n *\n * Pass the catalogue entry for the connector being configured; the default is\n * the degradation path (see {@link STRIPE_FALLBACK_PANE_CATALOG}). Labels are\n * deliberately left empty: empty means \"use the catalogue default\", which the\n * router resolves at render, and the router ships no copy for a caller to\n * mirror.\n */\nexport function defaultPane(\n method: string,\n catalog: PanesConnectorCatalog = STRIPE_FALLBACK_PANE_CATALOG,\n): Pane {\n const defaults = paneDisplayDefaults(paneMethodInfo(method, catalog));\n return {\n method,\n enabled: true,\n label: '',\n labelTranslations: {},\n sublabel: null,\n sublabelTranslations: {},\n category: defaults.category,\n icon: defaults.icon,\n iconSvg: '',\n displayOrder: 0,\n visibility: 'always',\n openIn: 'tab',\n nativeElement: 'everywhere',\n preset: '',\n style: '',\n };\n}\n\nexport function clonePane(pane: Pane): Pane {\n return {\n ...pane,\n labelTranslations: { ...pane.labelTranslations },\n sublabelTranslations: { ...pane.sublabelTranslations },\n };\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseTranslations(raw: unknown): Record<string, string> {\n if (!isObject(raw)) return {};\n const out: Record<string, string> = {};\n for (const [locale, value] of Object.entries(raw)) {\n if (typeof value === 'string' && value.length > 0) out[locale] = value;\n }\n return out;\n}\n\nfunction str(raw: unknown): string {\n return typeof raw === 'string' ? raw : '';\n}\n\n// The router's wire type is an `i32` (`api_models` `display_order`), and a\n// fractional or out-of-range value fails its strict row decode — dropping the\n// whole row server-side while an SDK round-trip would keep the blob looking\n// healthy. Clamped on BOTH decode and encode so this codec never emits a\n// value the router rejects, regardless of where the number came from.\nconst DISPLAY_ORDER_MIN = -2147483648;\nconst DISPLAY_ORDER_MAX = 2147483647;\n\nfunction clampDisplayOrder(raw: number): number {\n if (!Number.isFinite(raw)) return 0;\n return Math.min(DISPLAY_ORDER_MAX, Math.max(DISPLAY_ORDER_MIN, Math.trunc(raw)));\n}\n\n/**\n * Decode the stored `metadata.native_panes` blob into editor rows.\n *\n * Tolerant like the branding codecs: anything malformed falls back per\n * property, rows without a usable `method` are dropped, duplicates keep the\n * first occurrence — except that an enabled row wins over an earlier disabled\n * one for the same method, because that is the row the router renders — and\n * decoding stops after {@link PANES_MAX} decoded rows (dropped junk/duplicate\n * entries don't consume a slot). That is more forgiving than the router, which\n * drops a strict-decode-failing row whole (keeping the rest) and caps accepted\n * panes rather than decoded rows — see {@link Pane} and {@link PANES_MAX}.\n * Returns `null` when the input is not an array so the caller can distinguish\n * \"never configured\" from \"cleared\".\n */\nexport function decodePanes(raw: unknown): Pane[] | null {\n if (!Array.isArray(raw)) return null;\n const decodeRow = (entry: Record<string, unknown>, method: string): Pane => ({\n method,\n enabled: entry['enabled'] !== false,\n label: str(entry['label']),\n labelTranslations: parseTranslations(entry['label_translations']),\n sublabel: typeof entry['sublabel'] === 'string' ? entry['sublabel'] : null,\n sublabelTranslations: parseTranslations(entry['sublabel_translations']),\n category: str(entry['category']),\n icon: str(entry['icon']),\n iconSvg: str(entry['icon_svg']),\n displayOrder: clampDisplayOrder(Number(entry['display_order'])),\n // Anything unrecognised degrades to `always` rather than dropping the row.\n visibility: parseVisibility(entry['visibility']),\n // Same tolerance: an unknown value degrades to the default `tab`.\n openIn: parseOpenTarget(entry['open_in']),\n nativeElement: parseNativeElement(entry['native_element']),\n preset: str(entry['preset']),\n style: str(entry['style']),\n });\n\n const indexByMethod = new Map<string, number>();\n const out: Pane[] = [];\n for (const entry of raw) {\n if (out.length >= PANES_MAX) break;\n if (!isObject(entry)) continue;\n const method = str(entry['method']).trim();\n if (!method) continue;\n const kept = indexByMethod.get(method);\n if (kept !== undefined) {\n // Duplicate method. Keep the row the ROUTER would render: it skips\n // disabled rows BEFORE deduping (`native_panes.rs`), so where a blob\n // holds both a disabled and an enabled row for one method, buyers see\n // the enabled one. Keeping the disabled row here would show the merchant\n // a pane that is off while it is live, and persist that on the next save.\n const enabled = entry['enabled'] !== false;\n const existing = out[kept];\n if (enabled && existing && !existing.enabled) out[kept] = decodeRow(entry, method);\n continue;\n }\n indexByMethod.set(method, out.length);\n out.push(decodeRow(entry, method));\n }\n return out;\n}\n\n/**\n * Encode editor rows back into the snake_case blob the connector account\n * stores. Empty optional strings are omitted so the metadata stays small and a\n * merchant who typed nothing round-trips as \"use the catalogue default\" rather\n * than as an explicit empty override.\n *\n * `sublabel` is the exception: an explicitly-empty value is preserved (as `\"\"`)\n * because that is how a merchant hides the second line.\n */\nexport function encodePanes(panes: Pane[]): Record<string, unknown>[] {\n const nonEmpty = (map: Record<string, string>): Record<string, string> | undefined => {\n const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n };\n return panes.slice(0, PANES_MAX).map((pane) => {\n const labelTranslations = nonEmpty(pane.labelTranslations);\n const sublabelTranslations = nonEmpty(pane.sublabelTranslations);\n return {\n method: pane.method,\n enabled: pane.enabled,\n ...(pane.label.trim() ? { label: pane.label.trim() } : {}),\n ...(labelTranslations ? { label_translations: labelTranslations } : {}),\n // `null` omits the key entirely (catalogue default wins); `''` is sent\n // as-is because that is how the merchant hides the second line.\n ...(pane.sublabel !== null ? { sublabel: pane.sublabel } : {}),\n ...(sublabelTranslations ? { sublabel_translations: sublabelTranslations } : {}),\n ...(pane.category.trim() ? { category: pane.category.trim() } : {}),\n ...(pane.icon.trim() ? { icon: pane.icon.trim() } : {}),\n ...(pane.iconSvg.trim() ? { icon_svg: pane.iconSvg.trim() } : {}),\n // Clamped on encode too, not only decode: the router's strict i32 row\n // decode drops a row whole for a fractional or out-of-range value, so\n // writing e.g. 3.5 or Date.now() verbatim would silently delete the\n // pane at render while every read surface shows it healthy.\n display_order: clampDisplayOrder(pane.displayOrder),\n // Normalised on encode for the same reason `display_order` is clamped:\n // the router's strict row decode drops a row whole on a value outside\n // its enum, and a caller who built a `Pane` by hand (or in plain JS)\n // never went through `decodePanes`. A decoded pane always holds a valid\n // value, so this is a no-op on the round-trip path.\n visibility: parseVisibility(pane.visibility),\n open_in: parseOpenTarget(pane.openIn),\n // Omitted at the default: `everywhere` is what the router decodes an\n // absent key to, so leaving it out changes nothing — and keeps a blob\n // stored before the field existed byte-identical on re-encode, which\n // is what the wire-compatibility test pins.\n ...(parseNativeElement(pane.nativeElement) === 'everywhere'\n ? {}\n : { native_element: parseNativeElement(pane.nativeElement) }),\n // Absent and blank both mean \"no look\": a pane shaped before the fields\n // existed encodes exactly as it always did.\n ...((pane.preset ?? '').trim() ? { preset: (pane.preset ?? '').trim() } : {}),\n ...((pane.style ?? '').trim() ? { style: (pane.style ?? '').trim() } : {}),\n };\n });\n}\n\n// --- Focused checkout URL ----------------------------------------------\n\n/**\n * A payment link id the hosted checkout serves on its own, as\n * `/pay/{payment_link_id}`: the lowercase, hyphenated UUID the API issues.\n */\nconst OPAQUE_PAYMENT_LINK_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\nexport interface FocusedCheckoutUrlParams {\n /** Base URL of the DeloPay hosted checkout, e.g. `https://checkout.delopay.net`. */\n checkoutBaseUrl: string;\n merchantId: string;\n paymentId: string;\n /**\n * The payment's `payment_link.payment_link_id`. When it is the opaque id the\n * API issues (a lowercase, hyphenated UUID), the link is\n * `/pay/{payment_link_id}`, which names neither the merchant nor the\n * payment. Omitted, or an older `plink_` id, keeps\n * `/pay/{merchantId}/{paymentId}`, which the checkout still serves.\n */\n paymentLinkId?: string | null;\n /** Pane method key to focus on (`apple_pay`, `klarna`, …). */\n method: string;\n /**\n * Connector that owns the tile, forwarded as `connector=`.\n *\n * A bare `pane=` resolves to the **first payable match in server-sorted\n * order**, which is unambiguous only while one connector publishes a given\n * key. Stripe publishes `klarna` and so does the Klarna connector, so a deep\n * link that names neither charges through whichever tile happens to sort\n * first. Name the connector whenever you know it.\n *\n * Optional because links minted before this parameter existed are already in\n * merchants' pages and still have to resolve.\n */\n connector?: string;\n /**\n * Merchant connector ACCOUNT that owns the tile, forwarded as `mca=`.\n *\n * Needed for the same reason `connector` is, one level down: a profile may\n * hold two enabled accounts of one connector, each publishing its own tile,\n * and the two links would otherwise be identical. Only meaningful alongside\n * `connector`.\n */\n merchantConnectorId?: string;\n /** Optional buyer locale, forwarded as `?locale=`. */\n locale?: string;\n /**\n * Set when the merchant's checkout-custom-field answers are already\n * persisted on the payment — forwarded as `cf=1` so the focused view skips\n * asking a second time. Purely a UI hint: the values live on the intent\n * either way, and the backend only accepts the merchant's configured field\n * keys from a client, so a wrongly-set flag can at worst skip an\n * informational prompt. This is the same hint the embedded pane sets when\n * it opens the focused view.\n */\n customFieldsCollected?: boolean;\n}\n\n/**\n * Build the link to the **focused single-method checkout**: the DeloPay hosted\n * checkout rendered with one payment method, one button, no picker.\n *\n * Two callers:\n * - the embedded checkout, which opens this in a new tab when a buyer clicks\n * a pane tile, and\n * - a merchant running their own checkout, who puts it behind their own\n * button — the same mechanism without an iframe.\n *\n * `method` is not limited to configured panes. A configured pane gets the\n * focused one-button view; `card`, `paypal`, `crypto_currency` and the\n * local-methods catalogs (by method key or vendor code) open the checkout\n * pinned to that method. Methods that exist only as a tab inside a connector's\n * own embedded form — iDEAL, Bancontact, P24 and the like, unless promoted to\n * a pane — cannot be isolated, because the connector owns that surface. An\n * unknown or unavailable method is never a dead end: the checkout shows a\n * notice with a visible \"show all payment methods\" action.\n *\n * Pass {@link FocusedCheckoutUrlParams.connector} (and\n * {@link FocusedCheckoutUrlParams.merchantConnectorId}) whenever you know\n * them. Without them the method key alone picks the first payable match, and\n * more than one connector can publish the same key. Omitting them produces\n * exactly the URL this function has always produced, so links already minted\n * are unaffected.\n *\n * Open it **at the top level** (a new tab or a full-page navigation). The whole\n * point is that the top-level domain is the registered payment method domain;\n * rendering it in an iframe puts you back where you started.\n *\n * If you open it with `window.open`, call that **synchronously inside the click\n * handler** or the popup blocker will eat it, and make sure any iframe you\n * render DeloPay in permits popups (`allow-popups`, plus\n * `allow-popups-to-escape-sandbox` under a restrictive `sandbox`).\n */\nexport function focusedCheckoutUrl(params: FocusedCheckoutUrlParams): string {\n const base = params.checkoutBaseUrl.replace(/\\/+$/, '');\n const path =\n params.paymentLinkId && OPAQUE_PAYMENT_LINK_ID.test(params.paymentLinkId)\n ? `${base}/pay/${params.paymentLinkId}`\n : `${base}/pay/${encodeURIComponent(params.merchantId)}/${encodeURIComponent(\n params.paymentId,\n )}`;\n const query = new URLSearchParams({ pane: params.method });\n // Parameter order matches the embedded checkout's own `focusedUrl`\n // (`NativePanesPane.svelte`), so a merchant's deep link and a tile click\n // produce the same string for the same tile. A blank value is treated as\n // absent rather than emitted empty: `connector=` would otherwise read as a\n // connector named \"\" instead of as \"not specified\".\n const connector = params.connector?.trim();\n if (connector) query.set('connector', connector);\n const merchantConnectorId = params.merchantConnectorId?.trim();\n if (merchantConnectorId) query.set('mca', merchantConnectorId);\n if (params.locale) query.set('locale', params.locale);\n if (params.customFieldsCollected) query.set('cf', '1');\n return `${path}?${query.toString()}`;\n}\n\n// --- Buyer-side checkout events ----------------------------------------\n\n/**\n * The closed vocabulary of buyer-side checkout events recorded on the payment's\n * status timeline. Written through\n * `POST /payment-link/{merchant_id}/{payment_id}/checkout-events`, authorized\n * with the payment's `client_secret` as a bearer token.\n *\n * The `native_pane_` prefix is the router's enum on the wire and does not move\n * with the rename — see the module header.\n */\nexport const CHECKOUT_EVENT_KINDS = [\n 'native_pane_selected',\n 'native_pane_tab_opened',\n 'native_pane_tab_blocked',\n 'native_pane_abandoned',\n 'native_pane_returned',\n 'checkout_cancelled',\n] as const;\n\nexport type CheckoutEventKind = (typeof CHECKOUT_EVENT_KINDS)[number];\n\n// --- Deprecated aliases -------------------------------------------------\n//\n// The pre-0.109.0 names, kept so an external `@delopay/sdk` consumer upgrades\n// on their own schedule rather than on ours. **Scheduled for removal in\n// 0.112.0** — see CHANGELOG.md. Nothing in this repo uses them.\n\n/** @deprecated Renamed to {@link Pane}. Removed in 0.112.0. */\nexport type StripeNativePane = Pane;\n/** @deprecated Renamed to {@link PaneView}. Removed in 0.112.0. */\nexport type NativePaneView = PaneView;\n/** @deprecated Renamed to {@link PaneVisibility}. Removed in 0.112.0. */\nexport type NativePaneVisibility = PaneVisibility;\n/** @deprecated Renamed to {@link PaneOpenTarget}. Removed in 0.112.0. */\nexport type NativePaneOpenTarget = PaneOpenTarget;\n/** @deprecated Spelt {@link PaneNativeElement} on the SDK side. Removed in 0.112.0. */\nexport type NativePaneNativeElement = PaneNativeElement;\n/**\n * @deprecated Superseded by {@link PaneMethodInfo}. Removed in 0.112.0.\n *\n * Deliberately **not** an alias of `PaneMethodInfo`: that type gained three\n * required routing fields (`paymentMethod`, `paymentMethodType`,\n * `requiresBillingCountry`), and a consumer who wrote an object literal or a\n * function return against the 0.108 shape would stop compiling on a deprecated\n * name that promises the opposite. This stays the six fields that shape had.\n *\n * `PaneMethodInfo` is structurally assignable to it, so everything this SDK\n * hands back — including {@link nativePaneMethodInfo} — still satisfies it.\n */\nexport interface NativePaneMethodInfo {\n key: string;\n rail: PaneRail;\n /** Catalogue default label, shown as the editor's placeholder. */\n defaultLabel: string;\n /** Catalogue default sub-text. */\n defaultSublabel: string;\n /** Catalogue default section. */\n defaultCategory: string;\n /** Catalogue default icon key. */\n defaultIcon: string;\n}\n\n/**\n * @deprecated Renamed to {@link STRIPE_FALLBACK_PANE_METHODS}, which is a\n * degradation path and not a catalogue mirror. Removed in 0.112.0.\n */\nexport const STRIPE_NATIVE_PANE_METHODS = STRIPE_FALLBACK_PANE_METHODS;\n/** @deprecated Renamed to {@link PANE_ICON_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_ICON_KEYS = PANE_ICON_KEYS;\n/** @deprecated Renamed to {@link PANE_CATEGORY_KEYS}. Removed in 0.112.0. */\nexport const NATIVE_PANE_CATEGORY_KEYS = PANE_CATEGORY_KEYS;\n/** @deprecated Renamed to {@link PANES_MAX}. Removed in 0.112.0. */\nexport const NATIVE_PANES_MAX = PANES_MAX;\n\n/**\n * @deprecated Superseded by {@link paneMethodInfo}, which takes the connector's\n * catalogue and answers for every connector rather than only for Stripe.\n * Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old return type: it answers out of the frozen Stripe table and carries that\n * table's compiled copy, which the live catalogue deliberately does not have.\n */\nexport function nativePaneMethodInfo(method: string): PaneMethodInfo | undefined {\n return STRIPE_FALLBACK_PANE_METHODS.find((info) => info.key === method);\n}\n\n/**\n * @deprecated Superseded by {@link defaultPane}. Removed in 0.112.0.\n *\n * Kept as its own function rather than as an alias because it must keep its\n * old behaviour: it leaves `category` empty and resolves `icon` out of the\n * frozen Stripe table only. `defaultPane` fills both from the connector's\n * catalogue, which is the fix — but a caller on the old name encodes whatever\n * it is handed, and quietly turning a blank field into a stored override is\n * not something a deprecated alias should do to a merchant's saved config.\n */\nexport function defaultNativePane(method: string): Pane {\n const info = nativePaneMethodInfo(method);\n return {\n ...defaultPane(method),\n category: '',\n icon: info?.defaultIcon ?? '',\n };\n}\n\n/** @deprecated Renamed to {@link clonePane}. Removed in 0.112.0. */\nexport const cloneNativePane = clonePane;\n/** @deprecated Renamed to {@link decodePanes}. Removed in 0.112.0. */\nexport const decodeNativePanes = decodePanes;\n/** @deprecated Renamed to {@link encodePanes}. Removed in 0.112.0. */\nexport const encodeNativePanes = encodePanes;\n"],"mappings":";AAeO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAsBtC,YACE,SACA,SAQA;AACA,UAAM,OAAO;AACb,WAAO,eAAe,MAAM,WAAW,SAAS;AAChD,SAAK,OAAO;AACZ,SAAK,SAAS,QAAQ;AACtB,SAAK,OAAO,QAAQ;AACpB,SAAK,OAAO,QAAQ;AACpB,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAYO,IAAM,6BAAN,cAAyC,aAAa;AAAA,EAC3D,YACE,UAAU,mBACV,SAOA;AACA,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIR,MAAM,SAAS,QAAQ;AAAA,MACvB,MAAM,SAAS,QAAQ;AAAA,MACvB,WAAW,SAAS;AAAA,MACpB,SAAS,SAAS;AAAA,MAClB,MAAM,SAAS;AAAA,IACjB,CAAC;AACD,WAAO,eAAe,MAAM,WAAW,SAAS;AAChD,SAAK,OAAO;AAAA,EACd;AACF;;;ACpFO,IAAM,UAAN,MAAc;AAAA,EACnB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclD,MAAM,OAAO,YAAoB,QAA4D;AAC3F,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,UAAU,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,YAAoB,OAAwC;AACzE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,KAAK,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,YACA,OACA,QACyB;AACzB,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,KAAK,CAAC;AAAA,MACxE,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,YAAoB,OAA8C;AAC7E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,KAAK,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,OAAO,YAAoB,OAA8C;AAC7E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,KAAK,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,YAA+C;AACxD,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,UAAU,CAAC,OAAO;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAM,gBACJ,YACA,QAC+B;AAC/B,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,UAAU,CAAC,qBAAqB;AAAA,MACzF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,cACJ,YACA,QAC2B;AAC3B,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,UAAU,CAAC,qBAAqB;AAAA,MACxF,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,kBAAkB,YAAoB,OAAwC;AAClF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,qBAAqB,mBAAmB,KAAK,CAAC;AAAA,IAC1F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,gBACJ,YACA,OACA,QACyB;AACzB,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,qBAAqB,mBAAmB,KAAK,CAAC;AAAA,MACxF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBAAgB,YAAoB,OAA8C;AACtF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,qBAAqB,mBAAmB,KAAK,CAAC;AAAA,IAC1F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,gBAAgB,YAAoB,OAA8C;AACtF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,qBAAqB,mBAAmB,KAAK,CAAC;AAAA,IAC1F;AAAA,EACF;AACF;;;AClOO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,QAAsE;AACjF,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,iBAAiB,QAAiD;AACtE,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,mBAAmB,MAAM,CAAC,cAAc;AAAA,EACzF;AAAA,EAEA,MAAM,aACJ,QACA,QACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,mBAAmB,MAAM,CAAC,iBAAiB;AAAA,MACxF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,KACJ,YACA,QACA,QACiC;AACjC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,mBAAmB,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MAC/E,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SACJ,YACA,QACA,QACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,mBAAmB,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MAC/E,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,yBACJ,QACA,QACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,mBAAmB,mBAAmB,MAAM,CAAC;AAAA,MAC7C;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,iBACJ,QACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,mBAAmB,MAAM,CAAC,sBAAsB;AAAA,MAC7F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACpDA,IAAM,qBAAN,MAAyB;AAAA,EACvB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlD,MAAM,WACJ,YACA,QACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC;AAAA,MAC1C,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,YACJ,YACA,QACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC;AAAA,MAC1C;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,YAAqD;AAC9D,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,UAAU,CAAC,cAAc;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,IAAI,YAAoB,WAAgD;AAC5E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,gBAAgB,mBAAmB,SAAS,CAAC;AAAA,IACzF;AAAA,EACF;AACF;AAQO,IAAM,UAAN,MAAc;AAAA,EAInB,YAA6B,SAAoB;AAApB;AAC3B,SAAK,cAAc,IAAI,mBAAmB,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,WAAW,YAAqD;AACpE,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,UAAU,CAAC,EAAE;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAM,YAAoB,QAA6D;AAC3F,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,UAAU,CAAC,UAAU;AAAA,MAC9E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,YACA,QACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,UAAU,CAAC,mBAAmB;AAAA,MACvF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAM,YAAoB,QAA8C;AAC5E,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,UAAU,CAAC,UAAU;AAAA,MAC9E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,YAAoB,QAAoD;AACvF,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,UAAU,CAAC,WAAW;AAAA,MAC9E,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,oBACJ,YACA,QACqC;AACrC,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,UAAU,CAAC,qBAAqB;AAAA,MACxF,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBACJ,YACA,QACiC;AACjC,WAAO,KAAK,QAAQ,SAAS,YAAY,mBAAmB,UAAU,CAAC,kBAAkB;AAAA,MACvF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACjMO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,IAAI,QAAyD;AACjE,WAAO,KAAK,QAAQ,QAAQ,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAM,OAAO,QAAyD;AACpE,WAAO,KAAK,QAAQ,UAAU,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,KAAK,QAA4D;AACrE,WAAO,KAAK,QAAQ,OAAO,cAAc;AAAA,MACvC,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,QAAiE;AAC5E,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AACF;;;ACNO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,WAAmB,QAA4D;AAC1F,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,SAAS,CAAC,eAAe;AAAA,MAClF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,SAAS,WAAmB,aAAiD;AACjF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAK,WAAiD;AAC1D,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,SAAS,CAAC,aAAa;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,WAAiD;AACnE,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,SAAS,CAAC,qBAAqB;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,MAAM,gBAAgB,WAAkD;AACtE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,sBAAsB,WAAkD;AAC5E,WAAO,KAAK,gBAAgB,SAAS;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,oBACJ,WACA,aACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,OACJ,WACA,aACA,QAC4B;AAC5B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OAAO,WAAmB,aAAiD;AAC/E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,MACJ,WACA,aACA,QAC4B;AAC5B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YACJ,WACA,aACA,QACoC;AACpC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,mBACJ,WACA,aACA,QACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iBACJ,WACA,aACA,QACmC;AACnC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,MAAM,OACJ,WACA,aACA,SACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACvF,EAAE,OAAO,QAAQ;AAAA,IACnB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBACJ,YACA,aACA,QAC2C;AAC3C,UAAM,OAAO,YAAY,mBAAmB,UAAU,CAAC,wBAAwB,mBAAmB,WAAW,CAAC;AAC9G,QAAI,WAAW,OAAW,QAAO,KAAK,QAAQ,QAAQ,IAAI;AAC1D,WAAO,KAAK,QAAQ,QAAQ,MAAM,EAAE,MAAM,OAAO,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,mCACJ,YACA,aACA,QACqD;AACrD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACxF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iCACJ,YACA,aACA,QACmD;AACnD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACxF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,4BACJ,YACA,aACA,QAC8C;AAC9C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,eAAe,mBAAmB,WAAW,CAAC;AAAA,MACxF,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WAAW,YAAoB,aAA4D;AAC/F,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,wBAAwB,mBAAmB,WAAW,CAAC;AAAA,IACnG;AAAA,EACF;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,EA0BA,MAAM,kBACJ,YACA,aACuC;AACvC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,UAAU,CAAC,wBAAwB,mBAAmB,WAAW,CAAC;AAAA,IACnG;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,qBAAyD;AAC7D,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,EACvD;AACF;;;ACzaA,SAAS,QACP,QACmE;AACnE,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,EAAE,aAAa,GAAG,KAAK,IAAI;AACjC,QAAM,QAAQ;AAGd,MAAI,eAAe,YAAY,SAAS,GAAG;AACzC,UAAM,cAAc,YAAY,KAAK,GAAG;AAAA,EAC1C;AACA,SAAO;AACT;AAGO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,iBACJ,YACA,QACA,SAC2B;AAC3B,WAAO,KAAK,QAAQ,QAAQ,cAAc,mBAAmB,UAAU,CAAC,iBAAiB;AAAA,MACvF,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,gBACJ,YACA,QACA,SAC8B;AAC9B,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,UAAU,CAAC,iBAAiB;AAAA,MACtF,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBACJ,YACA,QACA,SACe;AACf,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,UAAU,CAAC,iBAAiB,mBAAmB,MAAM,CAAC;AAAA,MACvF,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,OAAO,QAA0D;AACrE,WAAO,KAAK,QAAQ,QAAQ,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,SAAS,YAA+C;AAC5D,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,UAAU,CAAC,EAAE;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,YAAoB,QAA0D;AACzF,WAAO,KAAK,QAAQ,QAAQ,cAAc,mBAAmB,UAAU,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,YAA+C;AAC1D,WAAO,KAAK,QAAQ,UAAU,cAAc,mBAAmB,UAAU,CAAC,EAAE;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,KAAK,QAA0D;AACnE,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,MAC5C,OAAO,QAAQ,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,QAAqE;AACvF,WAAO,KAAK,QAAQ,OAAO,8BAA8B;AAAA,MACvD,OAAO,QAAQ,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,cAAc,QAA0D;AAC5E,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO,QAAQ,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,uBACJ,QAC+B;AAC/B,WAAO,KAAK,QAAQ,OAAO,sCAAsC;AAAA,MAC/D,OAAO,QAAQ,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,kBAAkB,YAA+C;AACrE,WAAO,KAAK,QAAQ,OAAO,sBAAsB,mBAAmB,UAAU,CAAC,EAAE;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,gBAAgB,QAA0D;AAC9E,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,gBACJ,YACA,QAC2B;AAC3B,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MAClF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,YAAwD;AACzE,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,UAAU,CAAC,WAAW;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,sBAAsB,YAAwD;AAClF,WAAO,KAAK,QAAQ,OAAO,sBAAsB,mBAAmB,UAAU,CAAC,WAAW;AAAA,EAC5F;AACF;;;ACvPA,IAAM,KAAK;AACX,IAAM,KAAK;AACX,IAAM,QAAQ;AACd,IAAM,YAAY;AAClB,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,gBAAgB;AA0Bf,IAAM,mBAAN,MAAgD;AAAA,EAAhD;AACL,SAAQ,WAAW;AACnB,SAAQ,WAAW;AAEnB;AAAA,SAAQ,iBAAiB;AAAA;AAAA,EAEzB,KAAK,OAAyB;AAC5B,QAAI,WAAW,KAAK;AACpB,QAAI,WAAW,KAAK;AACpB,QAAI,iBAAiB,KAAK;AAC1B,eAAW,QAAQ,OAAO;AACxB,UAAI,SAAS,OAAO;AAClB,mBAAW,CAAC;AACZ,yBAAiB;AAAA,MACnB,WAAW,UAAU;AACnB,yBAAiB;AAAA,MACnB,WAAW,SAAS,IAAI;AACtB;AACA,yBAAiB;AAAA,MACnB,WAAW,SAAS,IAAI;AACtB,yBAAiB;AAAA,MACnB;AAAA,IACF;AACA,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,IAAI,UAAkB;AACpB,WAAO,KAAK,IAAI,GAAG,KAAK,WAAW,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAI,WAAoB;AACtB,WAAO,KAAK,YAAY,KAAK,CAAC,KAAK,YAAY,CAAC,KAAK;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AACF;AAGA,IAAM,UAAU;AAChB,IAAM,WAAW;AACjB,IAAM,SAAS;AAiBR,IAAM,yBAAN,MAAsD;AAAA,EAAtD;AACL,SAAQ,QAAQ;AAChB,SAAQ,WAAW;AACnB,SAAQ,UAAU;AAClB,SAAQ,cAAc;AACtB,SAAQ,QAAoB;AAC5B,SAAQ,QAAQ;AAAA;AAAA,EAEhB,KAAK,OAAyB;AAC5B,QAAI,KAAK,UAAU,OAAQ;AAC3B,QAAI,EAAE,OAAO,UAAU,SAAS,aAAa,MAAM,IAAI;AACvD,QAAI,QAAoB,KAAK;AAC7B,eAAW,QAAQ,OAAO;AACxB,UAAI,UAAU;AACZ,YAAI,QAAS,WAAU;AAAA,iBACd,SAAS,UAAW,WAAU;AAAA,iBAC9B,SAAS,MAAO,YAAW;AACpC;AAAA,MACF;AACA,UAAI,SAAS,OAAO;AAClB,mBAAW;AAAA,MACb,WAAW,SAAS,cAAc,SAAS,cAAc;AACvD,YAAI,UAAU,KAAK,SAAS,WAAY,eAAc;AACtD,YAAI,SAAS,gBAAgB,UAAU,KAAK,eAAe,UAAU,SAAS;AAC5E,kBAAQ;AAAA,QACV;AACA;AAAA,MACF,WAAW,SAAS,eAAe,SAAS,eAAe;AACzD;AACA,YAAI,UAAU,UAAU;AAGtB,cAAI,UAAU,EAAG;AAAA,mBACR,UAAU,GAAG;AACpB,oBAAQ;AACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,IAAI,UAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,WAAoB;AACtB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AACF;;;AC5KA,IAAM,sBAAsB;AAGrB,IAAM,sBAAsB;AAO5B,IAAM,0BAA0B,IAAI;AAOpC,SAAS,mBAAmB,cAA0C;AAC3E,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,YAAY,CAAC;AACnE,MAAI,SAAS;AACb,aAAW,QAAQ,MAAO,WAAU,OAAO,aAAa,IAAI;AAC5D,QAAM,UAAU,KAAK,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACtF,MAAI,QAAQ,SAAS,yBAAyB;AAC5C,UAAM,IAAI;AAAA,MACR,0BAA0B,QAAQ,MAAM,4CAA4C,uBAAuB;AAAA,MAC3G;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM,EAAE,gBAAgB,QAAQ,QAAQ,YAAY,wBAAwB;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAcO,IAAM,gBAAqC,EAAE,MAAM,WAAW,OAAO,eAAe;AAGpF,IAAM,qBAA0C,EAAE,MAAM,QAAQ,OAAO,cAAc;AAuB5F,SAAS,iBAAiB,QAAsC;AAC9D,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,QAAQ,KAAK,OAAO,EAAG,QAAO;AACnC,QAAM,QAAQ,OAAO,OAAO;AAC5B,SAAO,OAAO,cAAc,KAAK,IAAI,QAAQ;AAC/C;AAEA,SAAS,WAAW,QAA4C;AAC9D,MAAI,WAAW,MAAO,QAAO,IAAI,iBAAiB;AAClD,MAAI,WAAW,OAAQ,QAAO,IAAI,uBAAuB;AACzD,SAAO;AACT;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGA,SAAS,UAAU,UAAiC;AAClD,SAAO,aAAa,OAAO,KAAK,WAAW,QAAQ;AACrD;AAEA,SAAS,WACP,SACA,UACA,UACA,WACc;AACd,SAAO,IAAI,aAAa,SAAS;AAAA,IAC/B,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,MAAM,EAAE,kBAAkB,UAAU,kBAAkB,SAAS;AAAA,EACjE,CAAC;AACH;AAgBA,eAAsB,eACpB,SACA,MACA,SACY;AACZ,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,aAAa,SAAS;AAE5B,MAAI,SAAyB;AAAA,IAC3B,OAAO;AAAA,IACP,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB;AAIA,QAAM,OAMF,EAAE,SAAS,IAAI,SAAS,MAAM,UAAU,MAAM,WAAW,QAAW,eAAe,KAAK;AAM5F,QAAM,SAAS,CAAC,aAA6B;AAC3C,aAAS;AACT,QAAI,CAAC,WAAY;AACjB,QAAI;AACF,iBAAW,EAAE,GAAG,SAAS,CAAC;AAAA,IAC5B,SAAS,OAAO;AACd,WAAK,gBAAgB,EAAE,MAAM;AAC7B,YAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,MAAM;AAEb,QAAM,qBAAqB,CAAC,UAAiC;AAC3D,QAAI,MAAM,YAAY,KAAK,SAAS;AAGlC,WAAK,UAAU,MAAM;AACrB,WAAK,UAAU,WAAW,MAAM;AAEhC,WAAK,WACH,WAAW,QAAQ,OAAO,iBAAiB,MAAM,QAAQ,IAAI,mBAAmB,CAAC;AACnF,WAAK,YACH,MAAM,QAAQ,IAAI,cAAc,KAAK,MAAM,QAAQ,IAAI,YAAY,KAAK;AAAA,IAC5E;AACA,QAAI,MAAM,MAAM,aAAa,EAAG,MAAK,SAAS,KAAK,MAAM,KAAK;AAC9D,WAAO;AAAA,MACL,OAAO;AAAA,MACP,eAAe,MAAM;AAAA,MACrB,YAAY,MAAM;AAAA,MAClB,iBAAiB,KAAK,SAAS,WAAW;AAAA,MAC1C,iBAAiB,KAAK;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,QAAiB,KAAK,QAAQ,KAAK,MAAM;AAAA,MACtD,GAAG,KAAK;AAAA,MACR,GAAI,SAAS,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MAClE,GAAI,SAAS,YAAY,SAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,MACrE;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,KAAK,kBAAkB,QAAQ,QAAQ,KAAK,cAAc,MAAO,OAAM;AAG3E,QAAI,WAAW,UAAU,KAAK,WAAW,KAAK,eAAe,aAAa;AACxE,YAAMA,YAAW,KAAK,SAAS,WAAW;AAC1C,YAAM;AAAA,QACJ,KAAK,aAAa,OACd,+EAA+EA,SAAQ,aACvF,2CAA2C,KAAK,QAAQ,yEAAyEA,SAAQ;AAAA,QAC7I,KAAK;AAAA,QACLA;AAAA,QACA,KAAK;AAAA,MACP;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,QAAM,EAAE,UAAU,UAAU,IAAI;AAChC,MAAI,WAAW;AACf,MAAI,WAAW,QAAQ;AAIrB,UAAM,OAAO,SAAS,MAAM,IAAI,OAAO,SAAS,IAAI,IAAI;AACxD,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,YAAM;AAAA,QACJ,iEAAiE,SAAS,IAAI,mCAAmC,UAAU,QAAQ,CAAC;AAAA,QACpI;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,eAAW,KAAK;AAChB,UAAM,WAAW,SAAS,MAAM,IAAI,OAAO,SAAS,KAAK,IAAI;AAC7D,QAAI,OAAO,aAAa,YAAY,aAAa,KAAK,QAAQ;AAC5D,YAAM;AAAA,QACJ,iCAAiC,SAAS,KAAK,OAAO,QAAQ,oBAAoB,KAAK,MAAM;AAAA,QAC7F;AAAA,QACA,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,WAAW,OAAO;AAC3B,UAAM,UAAU,KAAK;AACrB,eAAW,SAAS,OAAO,KAAK;AAGhC,QAAI,CAAC,SAAS,UAAU;AACtB,YAAM;AAAA,QACJ,wEAAwE,QAAQ,oBAAoB,UAAU,QAAQ,CAAC;AAAA,QACvH;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,QAAQ,aAAa,UAAU;AAC9C,UAAM;AAAA,MACJ,2CAA2C,QAAQ,kCAAkC,QAAQ;AAAA,MAC7F;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,eAAe,OAAO;AAAA,IACtB,YAAY,OAAO;AAAA,IACnB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB,CAAC;AACD,SAAO;AACT;AAGA,IAAM,SAAuC;AAAA,EAC3C,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAeO,SAAS,WACd,SACA,QACA,cACgB;AAChB,QAAM,UAAkC,EAAE,GAAG,QAAQ,SAAS,QAAQ,OAAO,MAAM,EAAE;AAErF,MAAI,WAAW,SAAS,iBAAiB,QAAW;AAClD,YAAQ,mBAAmB,IAAI,mBAAmB,YAAY;AAAA,EAChE;AACA,SAAO,WAAW,SACd,EAAE,GAAG,SAAS,QAAQ,IACtB,EAAE,GAAG,SAAS,SAAS,cAAc,OAAO;AAClD;AAUO,SAAS,UACd,SACA,QACA,MACA,MACA,SACY;AACZ,QAAM,SAAS,SAAS,UAAU;AAClC,SAAO;AAAA,IACL;AAAA,IACA,EAAE,QAAQ,MAAM,SAAS,WAAW,MAAM,QAAQ,SAAS,YAAY,GAAG,OAAO;AAAA,IACjF;AAAA,EACF;AACF;;;ACnUA,SAAS,eAAe,QAA2D;AACjF,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,EAAE,WAAW,UAAU,gBAAgB,eAAe,GAAG,MAAM,IAAI;AACzE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,WAAW,SAAS,EAAE,WAAW,UAAU,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,IAC9D,GAAI,UAAU,SAAS,EAAE,UAAU,SAAS,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,IAC3D,GAAI,gBAAgB,SAAS,EAAE,gBAAgB,eAAe,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,IAC7E,GAAI,eAAe,SAAS,EAAE,eAAe,cAAc,KAAK,GAAG,EAAE,IAAI,CAAC;AAAA,EAC5E;AACF;AAGO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,UAAU,QAAqE;AACnF,WAAO,KAAK,QAAQ,OAAO,uBAAuB,EAAE,OAAO,eAAe,MAAM,EAAE,CAAC;AAAA,EACrF;AAAA;AAAA,EAGA,MAAM,iBAAiB,QAAoE;AACzF,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,OAAO,eAAe,MAAM,EAAE,CAAC;AAAA,EAC7F;AAAA;AAAA,EAGA,MAAM,mBAAmB,QAAsE;AAC7F,WAAO,KAAK,QAAQ,OAAO,iCAAiC,EAAE,OAAO,eAAe,MAAM,EAAE,CAAC;AAAA,EAC/F;AAAA,EA4BA,MAAM,gBACJ,QACA,SACwC;AACxC,UAAM,SAAS,SAAS,UAAU;AAClC,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS,WAAW,EAAE,OAAO,eAAe,MAAM,EAAE,GAAG,QAAQ,SAAS,YAAY;AAAA,QACpF;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,WAA6C;AAC1D,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,uBAAuB,WAA+D;AAC1F,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,sBAAsB;AAAA,EAC7F;AAAA;AAAA,EAGA,MAAM,qBACJ,WACA,QACmC;AACnC,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,wBAAwB;AAAA,MAC3F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAwD;AACjE,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,WAA6C;AACxD,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,QAA0D;AAC7E,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,QAA0D;AAC7E,WAAO,KAAK,QAAQ,OAAO,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iBAAiB,WAAoD;AACzE,WAAO,KAAK,QAAQ,OAAO,sBAAsB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,QAAyD;AAC5E,WAAO,KAAK,QAAQ,UAAU,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAAwD;AAC1E,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,WACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,oBAAoB,EAAE,OAAO,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,oBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,4BAA4B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,UACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,uBAAuB,EAAE,OAAO,OAAO,CAAC;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,mBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,mBAAmB,WAA6C;AACpE,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACvE,OAAO,EAAE,YAAY,OAAO;AAAA,IAC9B,CAAC;AAAA,EACH;AACF;;;ACjOO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAClD,QAAQ,QAAgB,SAAS,GAAyC;AACxE,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,MAAM,CAAC,YAAY;AAAA,MACzF,OAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EACA,SAAS,QAAgB,aAAqD;AAC5E,UAAM,OAAqC,EAAE,cAAc,YAAY;AACvE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,MAAM,CAAC;AAAA,MACpD,EAAE,KAAK;AAAA,IACT;AAAA,EACF;AAAA,EACA,KAAK,QAAiE;AACpE,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EACA,SAAS,QAAgB,YAAY,OAAmC;AACtE,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,MAAM,CAAC,IAAI;AAAA,MACjF,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EACA,QAAQ,QAAgB,SAAS,GAAiC;AAChE,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,MAAM,CAAC,YAAY;AAAA,MACzF,OAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EACA,OAAO,QAA0E;AAC/E,WAAO,KAAK,QAAQ,QAAQ,2BAA2B,EAAE,MAAM,OAAO,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAIA,IAAI,QAAgB,QAA0E;AAC5F,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,mBAAmB,MAAM,CAAC,YAAY;AAAA,MAC1F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACzCO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,KAAK,QAAwE;AAC3E,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO,EAAE,GAAG,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,SAAS,QAAgB,SAAiE;AACxF,WAAO,KAAK,QAAQ,OAAO,wBAAwB,mBAAmB,MAAM,CAAC,IAAI;AAAA,MAC/E,OAAO,EAAE,GAAG,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,OACE,QACA,QACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,wBAAwB,mBAAmB,MAAM,CAAC,WAAW;AAAA,MACtF,OAAO,EAAE,GAAG,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IACE,QACA,QAC2C;AAC3C,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,mBAAmB,MAAM,CAAC,YAAY;AAAA,MACxF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;AC1CO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclD,MAAM,OAAO,QAAwE;AACnF,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,OAAoD;AAC/D,WAAO,KAAK,QAAQ,UAAU,mBAAmB,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAC9E;AACF;;;ACjCO,IAAM,SAAN,MAAa;AAAA,EAClB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,KAAK,YAAoB,QAAsD;AACnF,WAAO,KAAK,QAAQ,QAAQ,WAAW,mBAAmB,UAAU,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3F;AAAA,EAEA,MAAM,qBACJ,YACA,SACyC;AACzC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,WAAW,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAAoB,SAA+C;AACrF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,WAAW,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,OAAO,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,QACJ,YACA,MACqC;AACrC,WAAO,KAAK,QAAQ,QAAQ,WAAW,mBAAmB,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,cAAc,QAAsD;AACxE,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBAAiB,MAAsE;AAC3F,WAAO,KAAK,QAAQ,QAAQ,2BAA2B,EAAE,KAAK,CAAC;AAAA,EACjE;AACF;;;ACjDO,IAAM,OAAN,MAAW;AAAA,EAIhB,YAA6B,SAAoB;AAApB;AAC3B,SAAK,QAAQ,IAAI,gBAAgB,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,QAAkC,YAAkD;AAC/F,WAAO,KAAK,QAAQ,QAAQ,kBAAkB;AAAA,MAC5C,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAK,YAAoD;AAC7D,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,MAChD,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,OAAe,QAAgE;AAC1F,WAAO,KAAK,QAAQ,OAAO,kBAAkB,mBAAmB,KAAK,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,OAA6C;AACxD,WAAO,KAAK,QAAQ,UAAU,kBAAkB,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAC7E;AACF;AAQO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlD,MAAM,OAAO,QAA8B,YAAoD;AAC7F,UAAM,OAA+B,EAAE,GAAG,QAAQ,WAAW,WAAW;AACxE,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD;AAAA,MACA,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,YAAoB,WAA2D;AAC5F,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO,EAAE,aAAa,YAAY,YAAY,UAAU;AAAA,IAC1D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OAAO,YAAoB,WAAmC;AAClE,UAAM,KAAK,QAAQ,UAAU,wBAAwB;AAAA,MACnD,OAAO,EAAE,aAAa,YAAY,YAAY,UAAU;AAAA,IAC1D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,OAA8B,YAAqD;AAC/F,WAAO,KAAK,QAAQ,QAAQ,gCAAgC;AAAA,MAC1D,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;AC1IO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,SAAS,WAA6C;AAC1D,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,WAAoD;AAC/D,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAwD;AACjE,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;AC/BO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,QAAwE;AACnF,WAAO,KAAK,QAAQ,QAAQ,aAAa,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,SAAS,WAAqD;AAClE,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,OACJ,WACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5F;AAAA,EAEA,MAAM,OAAO,WAAqD;AAChE,WAAO,KAAK,QAAQ,UAAU,aAAa,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC5E;AAAA;AAAA;AAAA,EAKA,MAAM,OAA2C;AAC/C,WAAO,KAAK,QAAQ,OAAO,gBAAgB;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,SAAS,WAAqD;AAClE,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,KAAK;AAAA,EAC7E;AAAA;AAAA,EAGA,MAAM,YAAY,WAAqD;AACrE,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,KAAK;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AACF;;;ACzCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,SAAS,QAA8C;AAC3D,WAAO,KAAK,QAAQ,OAAO,iBAAiB,mBAAmB,MAAM,CAAC,EAAE;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QAAQ,eAA6D;AACzE,WAAO,KAAK,QAAQ,OAAO,yBAAyB,mBAAmB,aAAa,CAAC,EAAE;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAkE;AAC3E,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,SAAS,YAAoB,WAAqD;AACtF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,iBAAiB,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,IAClF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,OAAO,YAAoB,WAAqD;AACpF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,wBAAwB,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,IACzF;AAAA,EACF;AACF;;;ACjDO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBlD,MAAM,OAAO,QAAoE;AAC/E,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,UAAkD;AAC/D,WAAO,KAAK,QAAQ,OAAO,oBAAoB,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,UACA,QACgC;AAChC,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,QAAQ,CAAC,WAAW;AAAA,MACrF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,UAAwD;AACnE,WAAO,KAAK,QAAQ,UAAU,oBAAoB,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EAClF;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2CA,MAAM,KAAK,QAAsE;AAC/E,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,MAC7C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,gBACJ,YACA,QAC6C;AAC7C,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,UAAU,CAAC,oBAAoB;AAAA,MACzF,OAAO;AAAA,IAIT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,YAAoB,UAAkD;AACrF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,UAAU,CAAC,oBAAoB,mBAAmB,QAAQ,CAAC;AAAA,IAC9F;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,QAAiE;AAC7E,WAAO,KAAK,QAAQ,QAAQ,4BAA4B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,aAAa,QAAqE;AACtF,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,YAAY,QAAqE;AACrF,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA,EAGA,MAAM,cACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,0BAA0B,EAAE,OAAO,OAAO,CAAC;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,kBAAkB,QAAqE;AAC3F,WAAO,KAAK,QAAQ,QAAQ,wCAAwC,EAAE,MAAM,OAAO,CAAC;AAAA,EACtF;AAAA;AAAA,EAGA,MAAM,QAAQ,QAAmE;AAC/E,WAAO,KAAK,QAAQ,QAAQ,4BAA4B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,KAAK,UAAkB,QAAkE;AAC7F,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,QAAQ,CAAC,SAAS;AAAA,MACnF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,eAAe,QAAmE;AACtF,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,kBAAkB,QAAmE;AACzF,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,sBACJ,UACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,QAAQ,CAAC,kBAAkB;AAAA,MAC5F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACnMO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgDlD,MAAM,OACJ,QACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,SAAS,WAAmB,SAA4D;AAC5F,UAAM,OAAO,aAAa,mBAAmB,SAAS,CAAC;AACvD,QAAI,YAAY,OAAW,QAAO,KAAK,QAAQ,OAAO,IAAI;AAC1D,UAAM,QAAiC,CAAC;AACxC,QAAI,QAAQ,eAAe,OAAW,OAAM,YAAY,IAAI,QAAQ;AACpE,QAAI,QAAQ,sBAAsB,QAAW;AAC3C,YAAM,mBAAmB,IAAI,QAAQ;AAAA,IACvC;AACA,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO,KAAK,QAAQ,OAAO,IAAI;AACpE,WAAO,KAAK,QAAQ,OAAO,MAAM,EAAE,MAAM,CAAC;AAAA,EAC5C;AAAA;AAAA,EAGA,MAAM,aAAa,WAAiD;AAClE,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,QAAQ;AAAA,EAC/E;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,EA0BA,MAAM,aACJ,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,aAAa,OAAO;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,kBACJ,WACA,SACuC;AACvC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiDA,MAAM,WACJ,WACA,SAC6C;AAC7C,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,eAAe,OAAO;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAAmB,QAAwD;AACtF,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,WAAmB,QAAyD;AACxF,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,WAAmB,QAA0D;AACzF,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAAmB,QAAyD;AACvF,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC/E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,KAAK,QAA4B,SAAuD;AAC5F,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBACJ,WACA,SAC2C;AAC3C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,MAAM,iBACJ,WACA,SAC0C;AAC1C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;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;AAAA,EA2BA,MAAM,mBACJ,WACA,SACiC;AACjC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,YACJ,WACA,YACA,UACA,SAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,oBAAoB,mBAAmB,UAAU,CAAC,WAAW,mBAAmB,OAAO,QAAQ,CAAC,CAAC;AAAA,MAC3I;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAAmB,SAA0D;AACxF,WAAO,KAAK,QAAQ,UAAU,aAAa,mBAAmB,SAAS,CAAC,IAAI,OAAO;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,SAAgE;AACpF,WAAO,KAAK,QAAQ,OAAO,2BAA2B,OAAO;AAAA,EAC/D;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAAmE;AACrF,WAAO,KAAK,QAAQ,QAAQ,4BAA4B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,KAAK,QAA2D;AACpE,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,kBACJ,WACA,QAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,wBAAwB;AAAA,MAC5F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,yBACJ,WACA,QAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,oBACJ,WACA,QAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,yBAAyB;AAAA,MAC7F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBACJ,WACA,QAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,uBAAuB;AAAA,MAC3F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aACJ,WACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,kBAAkB;AAAA,MACtF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,eACJ,WACA,QAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,oBAAoB;AAAA,MACxF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,iBAAiB,WAAqD;AAC1E,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,qBAAqB;AAAA,EAC5F;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAA0D;AAC5E,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,QAA0D;AAC3E,WAAO,KAAK,QAAQ,OAAO,4BAA4B;AAAA,MACrD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,QAA4E;AAC7F,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,oBACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACpF;AAAA;AAAA,EAGA,MAAM,WACJ,QACgC;AAChC,WAAO,KAAK,QAAQ,OAAO,oBAAoB,EAAE,OAAO,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBACJ,QACgC;AAChC,WAAO,KAAK,QAAQ,OAAO,4BAA4B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,UACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,uBAAuB,EAAE,OAAO,OAAO,CAAC;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,mBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC7E;AAAA;AAAA,EAGA,MAAM,aAAa,WAAmB,QAA2D;AAC/F,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,kBAAkB;AAAA,MACrF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAQ,WAAmB,QAA4D;AAC3F,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAO,WAAmB,QAA4D;AAC1F,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC/E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,sBACJ,WACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,uBAAuB;AAAA,MAC3F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACnnBO,IAAM,UAAN,MAAc;AAAA,EACnB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBlD,MAAM,OAAO,QAAsD;AACjE,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,UAA2C;AACxD,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,UAAkB,QAAsD;AACnF,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,UAAkB,QAAuD;AACrF,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,QAAQ,CAAC,YAAY;AAAA,MAC9E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,UAA2C;AACtD,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,QAAQ,CAAC,SAAS;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAQ,UAA2C;AACvD,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,QAAQ,CAAC,UAAU;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAwD;AACjE,WAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,MAC1C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAAwD;AAC1E,WAAO,KAAK,QAAQ,OAAO,yBAAyB;AAAA,MAClD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,QAA8D;AAC/E,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,WACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,mBAAmB,EAAE,OAAO,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,oBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,2BAA2B,EAAE,OAAO,OAAO,CAAC;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,UACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,sBAAsB,EAAE,OAAO,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,mBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,8BAA8B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,aAAa,UAAkB,QAA0D;AAC7F,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,kBAAkB;AAAA,MACnF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;AC/IO,IAAM,OAAN,MAAW;AAAA,EAChB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,UAAU,QAA6C;AAC3D,WAAO,KAAK,QAAQ,OAAO,gBAAgB,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACzE;AACF;;;ACFO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,QAAwE;AACnF,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA,EAEA,MAAM,OACJ,WACA,mBACA,QACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,qBAAqB,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,iBAAiB,CAAC;AAAA,MAC3F;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;ACxBO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,WAAmB,QAAwD;AACtF,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,SAAS,CAAC,qBAAqB;AAAA,MACxF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS,WAAmB,WAA6C;AAC7E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,qBAAqB,mBAAmB,SAAS,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,WAA+C;AACxD,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,SAAS,CAAC,mBAAmB;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,WAA+C;AACjE,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,SAAS,CAAC,UAAU;AAAA,EAChF;AAAA,EAEA,MAAM,OACJ,WACA,WACA,QAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,qBAAqB,mBAAmB,SAAS,CAAC;AAAA,MAC3F;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,WAAmB,WAA6C;AAC3E,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,qBAAqB,mBAAmB,SAAS,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAuB,WAAmB,WAA6C;AAC3F,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,qBAAqB,mBAAmB,SAAS,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,2BAA2B,WAAmB,WAA6C;AAC/F,WAAO,KAAK;AAAA,MACV;AAAA,MACA,YAAY,mBAAmB,SAAS,CAAC,qBAAqB,mBAAmB,SAAS,CAAC;AAAA,IAC7F;AAAA,EACF;AACF;;;AC7DO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAclD,MAAM,OAAO,QAA8B,YAA8C;AACvF,WAAO,KAAK,QAAQ,QAAQ,aAAa;AAAA,MACvC,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,SAAS,WAAmB,YAA+C;AAC/E,UAAM,OAAO,aAAa,mBAAmB,SAAS,CAAC;AACvD,QAAI,eAAe,OAAW,QAAO,KAAK,QAAQ,OAAO,IAAI;AAC7D,WAAO,KAAK,QAAQ,OAAO,MAAM,EAAE,OAAO,EAAE,aAAa,WAAW,EAAE,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,WACA,QACA,YAC0B;AAC1B,UAAM,OAAO,aAAa,mBAAmB,SAAS,CAAC;AACvD,QAAI,eAAe,OAAW,QAAO,KAAK,QAAQ,OAAO,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/E,WAAO,KAAK,QAAQ,OAAO,MAAM,EAAE,MAAM,QAAQ,OAAO,EAAE,aAAa,WAAW,EAAE,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAAmB,YAA+C;AAC7E,UAAM,OAAO,aAAa,mBAAmB,SAAS,CAAC;AACvD,QAAI,eAAe,OAAW,QAAO,KAAK,QAAQ,UAAU,IAAI;AAChE,WAAO,KAAK,QAAQ,UAAU,MAAM,EAAE,OAAO,EAAE,aAAa,WAAW,EAAE,CAAC;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,YAAgD;AACzD,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,MAAM,YAAoB,QAAqD;AACnF,UAAM,QAAgC,EAAE,aAAa,WAAW;AAChE,QAAI,WAAW,OAAW,OAAM,QAAQ,IAAI,OAAO,MAAM;AACzD,WAAO,KAAK,QAAQ,OAAO,mBAAmB,EAAE,MAAM,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,YAAuD;AACpE,WAAO,KAAK,QAAQ,OAAO,sBAAsB;AAAA,MAC/C,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;ACrHO,IAAM,UAAN,MAAc;AAAA,EACnB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBlD,MAAM,OAAO,QAAsD;AACjE,WAAO,KAAK,QAAQ,QAAQ,YAAY,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,SAAS,UAA2C;AACxD,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,UAAkB,QAAsD;AACnF,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,QAAwD;AACjE,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/D;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAAwD;AAC1E,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA;AAAA,EAGA,MAAM,WACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,mBAAmB,EAAE,OAAO,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,UACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,sBAAsB,EAAE,OAAO,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,mBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,8BAA8B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,aAAa,UAAkB,QAA0D;AAC7F,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,kBAAkB;AAAA,MACnF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;AC3GO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,QAA8C;AACzD,WAAO,KAAK,QAAQ,QAAQ,UAAU,EAAE,MAAM,OAAO,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,SAAS,SAAyC;AACtD,WAAO,KAAK,QAAQ,OAAO,UAAU,mBAAmB,OAAO,CAAC,EAAE;AAAA,EACpE;AACF;;;ACqBO,IAAM,UAAN,MAAc;AAAA,EASnB,YAA6B,SAAoB;AAApB;AAC3B,SAAK,WAAW,IAAI,uBAAuB,OAAO;AAClD,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,qBAAqB,IAAI,mBAAmB,OAAO;AACxD,SAAK,0BAA0B,IAAI,wBAAwB,OAAO;AAAA,EACpE;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2DA,MAAM,OAAO,QAAsE;AACjF,WAAO,KAAK,QAAQ,QAAQ,YAAY,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,aAAwD;AACrE,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,WAAW,CAAC,EAAE;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,SACJ,aACA,SAAiC,CAAC,GACA;AAClC,WAAO,KAAK,QAAQ,QAAQ,YAAY,mBAAmB,WAAW,CAAC,aAAa;AAAA,MAClF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,SAAmC,CAAC,GAAqC;AACxF,WAAO,KAAK,QAAQ,QAAQ,uBAAuB,EAAE,MAAM,OAAO,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,OACJ,aACA,QACmC;AACnC,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,WAAW,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,OAAO,aAA2D;AACtE,WAAO,KAAK,QAAQ,UAAU,YAAY,mBAAmB,WAAW,CAAC,EAAE;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,QACJ,aACA,SAA+B,CAAC,GACO;AACvC,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,WAAW,CAAC,YAAY;AAAA,MAChF,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,WAAkD;AACpE,WAAO,KAAK,QAAQ,OAAO,2BAA2B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACvF;AAAA;AAAA,EAGA,MAAM,sBAAsB,WAAyD;AACnF,WAAO,KAAK,QAAQ,OAAO,oCAAoC,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,yBACJ,WACA,QACsC;AACtC,UAAM,OAAO,MAAM,KAAK,cAAc,SAAS;AAC/C,QAAI,CAAC,KAAK,UAAU,SAAS,iBAAiB,GAAG;AAC/C,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA,oCAAoC,mBAAmB,SAAS,CAAC;AAAA,MACjE;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,4BACJ,WACA,QAC+B;AAC/B,UAAM,OAAO,MAAM,KAAK,cAAc,SAAS;AAC/C,QAAI,CAAC,KAAK,UAAU,SAAS,iBAAiB,GAAG;AAC/C,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA,oCAAoC,mBAAmB,SAAS,CAAC;AAAA,MACjE,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,eAAe,WAAmD;AACtE,WAAO,KAAK,QAAQ,OAAO,4BAA4B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,iBACJ,WACA,QAC+B;AAC/B,WAAO,KAAK,QAAQ,OAAO,2BAA2B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACrF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAmC;AACvC,WAAO,KAAK,QAAQ,OAAO,UAAU;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,sBAAsB,WAA6D;AACvF,WAAO,KAAK,QAAQ,OAAO,mCAAmC,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC/F;AAAA;AAAA;AAAA,EAKA,MAAM,YAA0D;AAC9D,WAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAM,cAAc,QAAqE;AACvF,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,oBAAwF;AAC5F,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,qBAAqB,WAAyD;AAClF,WAAO,KAAK,QAAQ,OAAO,4BAA4B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,qBACJ,WACA,QACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,4BAA4B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACvF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,iBAA6C;AACjD,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,EACpD;AAAA;AAAA,EAGA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,YAAY,QAAmE;AACnF,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA;AAAA,EAGA,MAAM,SAAS,QAAmE;AAChF,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,SAAS,QAAmE;AAChF,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AACF;AAEA,IAAM,yBAAN,MAA6B;AAAA,EAC3B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,OAAO,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,WAA6C;AACjD,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,SAA2C;AAC/C,WAAO,KAAK,QAAQ,UAAU,mBAAmB;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,gBAAgB,QAAmE;AACvF,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,oBAAsD;AAC1D,WAAO,KAAK,QAAQ,OAAO,6BAA6B;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,kBAAoD;AACxD,WAAO,KAAK,QAAQ,UAAU,6BAA6B;AAAA,EAC7D;AACF;AAUA,IAAM,iBAAN,MAAqB;AAAA,EACnB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBlD,MAAM,OAAO,QAA8D;AACzE,WAAO,KAAK,QAAQ,OAAO,4BAA4B,EAAE,MAAM,OAAO,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,WAA2D;AACxE,WAAO,KAAK,QAAQ,OAAO,4BAA4B;AAAA,MACrD,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,WAAmC;AAC9C,WAAO,KAAK,QAAQ,UAAU,4BAA4B;AAAA,MACxD,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AACF;AAuBA,IAAM,qBAAN,MAAyB;AAAA,EACvB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiDlD,MAAM,OAAO,QAA4E;AACvF,WAAO,KAAK,QAAQ,OAAO,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAS,WAAkE;AAC/E,WAAO,KAAK,QAAQ,OAAO,iCAAiC;AAAA,MAC1D,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,OAAO,WAAmC;AAC9C,WAAO,KAAK,QAAQ,UAAU,iCAAiC;AAAA,MAC7D,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AACF;AAqBA,IAAM,0BAAN,MAA8B;AAAA,EAC5B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;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;AAAA;AAAA,EA4BlD,MAAM,SAAS,QAAgF;AAC7F,WAAO,KAAK,QAAQ,OAAO,sCAAsC;AAAA,MAC/D,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,OAAO,OAAO;AAAA,QACd,KAAK,OAAO;AAAA,QACZ,SAAS,OAAO;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACtmBO,IAAM,SAAN,MAAa;AAAA,EAClB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYlD,MAAM,OACJ,QACA,SACgC;AAChC,WAAO,KAAK,QAAQ,QAAQ,qBAAqB;AAAA,MAC/C,MAAM;AAAA,MACN,GAAI,SAAS,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACtD,CAAC;AAAA,EACH;AACF;;;ACzDA,IAAM,eAAN,MAAmB;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUlD,MAAM,QACJ,YACA,QACA,QAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MACtE,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KAAK,YAAoB,QAA4C;AACzE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WACJ,YACA,QACA,WAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC,aAAa,mBAAmB,SAAS,CAAC;AAAA,IAClH;AAAA,EACF;AACF;AAOO,IAAM,QAAN,MAAY;AAAA,EAIjB,YAA6B,SAAoB;AAApB;AAC3B,SAAK,WAAW,IAAI,aAAa,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAO,YAAoB,QAAkD;AACjF,WAAO,KAAK,QAAQ,QAAQ,UAAU,mBAAmB,UAAU,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,YAAoB,QAAuC;AACxE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,YACA,QACA,QACuB;AACvB,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MACtE,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,YAAoB,QAAuC;AACtE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,YAA6C;AACtD,WAAO,KAAK,QAAQ,OAAO,UAAU,mBAAmB,UAAU,CAAC,EAAE;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,MAAM,MACJ,YACA,QACA,QAC4B;AAC5B,UAAM,OAAO,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AACnF,QAAI,WAAW,OAAW,QAAO,KAAK,QAAQ,OAAO,IAAI;AACzD,WAAO,KAAK,QAAQ,OAAO,MAAM,EAAE,OAAO,EAAE,QAAQ,OAAO,MAAM,EAAE,EAAE,CAAC;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,WACJ,YACA,QACA,MACoC;AACpC,UAAM,OAAO,IAAI,SAAS;AAC1B,SAAK,OAAO,QAAQ,IAAI;AACxB,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MACtE,EAAE,MAAM,KAAK;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,uBACJ,YACA,QACA,QACA,SACmC;AACnC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MACtE,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,yBACJ,YACA,QACA,SACmC;AACnC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,UAAU,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,MAAM,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;;;ACzRO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,cAAc,QAA4E;AAC9F,WAAO,KAAK,QAAQ,QAAQ,yCAAyC,EAAE,MAAM,OAAO,CAAC;AAAA,EACvF;AAAA,EAEA,MAAM,kBAAkB,QAAsE;AAC5F,WAAO,KAAK,QAAQ,QAAQ,8CAA8C,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,oCAAoC,EAAE,MAAM,OAAO,CAAC;AAAA,EAClF;AAAA;AAAA,EAGA,MAAM,eAAe,QAAmE;AACtF,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,gBAAgB,QAAmE;AACvF,WAAO,KAAK,QAAQ,QAAQ,2CAA2C,EAAE,MAAM,OAAO,CAAC;AAAA,EACzF;AACF;;;AChCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,QAAQ,QAAiE;AAC7E,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AACF;;;ACuDO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,OAAO,QAA0E;AACrF,WAAO,KAAK,QAAQ,QAAQ,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,OAAO,QAA8C;AACzD,WAAO,KAAK,QAAQ,QAAQ,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGA,MAAM,qBAA+D;AACnE,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,EACpD;AAAA;AAAA,EAGA,MAAM,2BAAqE;AACzE,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,EACjD;AAAA,EAEA,MAAM,iBAAiB,QAA0E;AAC/F,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA,EAEA,MAAM,eACJ,QACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,oBAAoB,QAA8D;AACtF,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,kBAAkB,QAAsD;AAC5E,WAAO,KAAK,QAAQ,QAAQ,6BAA6B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3E;AAAA,EAEA,MAAM,wBACJ,UACA,QACe;AACf,WAAO,KAAK,QAAQ,UAAU,sBAAsB,mBAAmB,QAAQ,CAAC,IAAI;AAAA,MAClF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAA4C;AAChD,WAAO,KAAK,QAAQ,QAAQ,eAAe;AAAA,EAC7C;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,EA0BA,MAAM,eAAuC;AAC3C,WAAO,KAAK,QAAQ,QAAQ,qBAAqB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,kBAAkB,QAA4D;AAClF,QAAI,WAAW,QAAW;AACxB,aAAO,KAAK,QAAQ,OAAO,yBAAyB;AAAA,IACtD;AACA,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,qBAAuD;AAC3D,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,cAAc,WAAuD;AACzE,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,mBAAmB,SAAS,CAAC,SAAS;AAAA,EACzF;AAAA,EAEA,MAAM,aAAoC;AACxC,WAAO,KAAK,QAAQ,OAAO,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,OAAO,QAAyD;AACpE,WAAO,KAAK,QAAQ,QAAQ,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,KAA8C;AAChE,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,GAAG,CAAC,EAAE;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,KACA,QACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,GAAG,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,qBACJ,KACA,OACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,GAAG,CAAC,IAAI;AAAA,MACzE,MAAM,EAAE,OAAO,WAAW,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,KAA8C;AACnE,WAAO,KAAK,QAAQ,UAAU,qBAAqB,mBAAmB,GAAG,CAAC,EAAE;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,QAAsD;AACzE,WAAO,KAAK,QAAQ,SAAS,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,uBAAuB,QAAsD;AACjF,WAAO,KAAK,QAAQ,SAAS,2BAA2B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,cAAc,QAAgE;AAClF,WAAO,KAAK,QAAQ,UAAU,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,eAAe,QAAsD;AACzE,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,eAAe,QAAqD;AACxE,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,eAAe,QAAiE;AACpF,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,cAAc,QAAgE;AAClF,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,QAAkD;AAChE,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,YAAY,QAAwD;AACxE,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,sBAAsB,QAAiE;AAC3F,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,eAAe,QAAwD;AAC3E,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,eAAe,QAAsD;AACzE,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,cAAc,QAAqD;AACvE,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,gBAAoD;AACxD,WAAO,KAAK,QAAQ,OAAO,qBAAqB;AAAA,EAClD;AAAA,EAEA,MAAM,eAAmD;AACvD,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAY,QAA8D;AAC9E,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,QAAQ,QAAkD;AAC9D,WAAO,KAAK,QAAQ,QAAQ,uBAAuB,EAAE,MAAM,OAAO,CAAC;AAAA,EACrE;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,EA0BA,MAAM,oBAAoB,QAA4D;AACpF,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAM,iBAAiB,QAAwD;AAC7E,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,yBAAyB,QAAiE;AAC9F,WAAO,KAAK,QAAQ,QAAQ,0CAA0C,EAAE,MAAM,OAAO,CAAC;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,sBAAsB,QAAiD;AAC3E,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAmC;AACvC,WAAO,KAAK,QAAQ,OAAO,sBAAsB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,QAA6D;AAC5E,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,YAA8C;AAClD,WAAO,KAAK,QAAQ,OAAO,sBAAsB;AAAA,EACnD;AAAA,EAEA,MAAM,wBAAwD;AAC5D,WAAO,KAAK,QAAQ,OAAO,kCAAkC;AAAA,EAC/D;AAAA,EAEA,MAAM,mBAAmB,QAAwD;AAC/E,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AAAA,EAEA,MAAM,aAAa,QAAoD;AACrE,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,eAAe,QAAgE;AACnF,WAAO,KAAK,QAAQ,QAAQ,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,UAAU,QAGuB;AACrC,QAAI,WAAW,QAAW;AACxB,aAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,IAC9C;AACA,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,MAC5C,OAAO,EAAE,QAAQ,OAAO,QAAQ,aAAa,OAAO,YAAY;AAAA,IAClE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,QAAyE;AAC3F,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,2BAAwE;AAC5E,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,QAAiE;AACpF,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,eAAe,QAAiE;AACpF,WAAO,KAAK,QAAQ,UAAU,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,kBAAkB,QAAsE;AAC5F,WAAO,KAAK,QAAQ,QAAQ,gCAAgC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,mBAAmB,QAAwE;AAC/F,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,qBAAqB,QAA4C;AACrE,WAAO,KAAK,QAAQ,OAAO,mBAAmB,mBAAmB,MAAM,CAAC,UAAU;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,wBACJ,QACA,QAC0C;AAC1C,WAAO,KAAK,QAAQ,QAAQ,mBAAmB,mBAAmB,MAAM,CAAC,mBAAmB;AAAA,MAC1F,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,WAAW,QAAwD;AACvE,WAAO,KAAK,QAAQ,QAAQ,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,YAAY,QAAmE;AACnF,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBAA6C;AACjD,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,EACpD;AAAA;AAAA,EAGA,MAAM,iBAAmD;AACvD,WAAO,KAAK,QAAQ,OAAO,WAAW;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,QAA6D;AAC5E,WAAO,KAAK,QAAQ,OAAO,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,OAAyD;AAC1E,QAAI,UAAU,QAAW;AACvB,aAAO,KAAK,QAAQ,OAAO,qBAAqB;AAAA,IAClD;AACA,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,iBAAiB,QAAmE;AACxF,WAAO,KAAK,QAAQ,QAAQ,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,iBAAiB,QAAmE;AACxF,WAAO,KAAK,QAAQ,OAAO,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3D;AAAA;AAAA,EAGA,MAAM,kBAAsD;AAC1D,WAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAM,aAA+C;AACnD,WAAO,KAAK,QAAQ,OAAO,gBAAgB;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,WAAW,QAAmE;AAClF,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,mBAAmB,QAA6D;AACpF,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,uBAAuB,EAAE,MAAM,OAAO,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAiD;AACrD,WAAO,KAAK,QAAQ,OAAO,YAAY;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAAmB,QAAuE;AAC9F,QAAI,WAAW,UAAa,OAAO,gBAAgB,QAAW;AAC5D,aAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,IACrD;AACA,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO,EAAE,aAAa,OAAO,YAAY;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,qBAAyD;AAC7D,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,EACrD;AAAA;AAAA,EAGA,MAAM,gBAAoD;AACxD,WAAO,KAAK,QAAQ,OAAO,mBAAmB;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,WAAW,QAAmE;AAClF,WAAO,KAAK,QAAQ,QAAQ,cAAc,EAAE,MAAM,OAAO,CAAC;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,YAAY,QAAkD;AAClE,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACvE;AAAA;AAAA,EAGA,MAAM,WACJ,QACA,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,MAAM,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,QAAkD;AACjE,WAAO,KAAK,QAAQ,UAAU,cAAc,mBAAmB,MAAM,CAAC,EAAE;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,kBAAkB,QAA6C;AACnE,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,MAAM,CAAC,aAAa;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,qBACJ,QACA,QAC6B;AAC7B,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,MAAM,CAAC,eAAe;AAAA,MAChF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;ACxzBO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,wBACJ,YACA,QACuC;AACvC,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MACjF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,2BACJ,QAC0C;AAC1C,WAAO,KAAK,QAAQ,OAAO,qCAAqC;AAAA,MAC9D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;ACoCO,SAAS,+BACd,QAC4B;AAC5B,SAAO,OAAQ,OAAqC,kBAAkB;AACxE;AAUO,SAAS,6BACd,QACsC;AACtC,SAAO,OAAQ,OAA+C,yBAAyB;AACzF;AAyBA,SAAS,WAAW,KAAgC;AAClD,MAAI,IAAI,WAAW,KAAK,IAAI,SAAS,MAAM,EAAG,QAAO;AACrD,QAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,CAAC;AAC3C,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACtC,UAAM,OAAO,OAAO,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACpD,QAAI,OAAO,MAAM,IAAI,EAAG,QAAO;AAC/B,UAAM,IAAI,CAAC,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEO,IAAM,WAAW;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCtB,MAAM,OACJ,SACA,iBACA,QACuB;AACvB,UAAM,SAAS,WAAW,QAAQ;AAClC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBAAiB,WAAW,gBAAgB,KAAK,CAAC;AACxD,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAEA,UAAM,UAAU,IAAI,YAAY;AAChC,UAAM,YAAY,OAAO,YAAY,WAAW,QAAQ,OAAO,OAAO,IAAI;AAK1E,UAAM,iBAAiB,CAAC,UAAoC;AAC5D,UAAM,MAAM,MAAM,OAAO;AAAA,MACvB;AAAA,MACA,eAAe,QAAQ,OAAO,MAAM,CAAC;AAAA,MACrC,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,CAAC,QAAQ;AAAA,IACX;AAEA,UAAM,QAAQ,MAAM,OAAO;AAAA,MACzB;AAAA,MACA;AAAA,MACA,eAAe,cAAc;AAAA,MAC7B,eAAe,SAAS;AAAA,IAC1B;AAEA,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,UAAM,WACJ,OAAO,YAAY,WAAW,UAAU,IAAI,YAAY,OAAO,EAAE,OAAO,OAAO;AACjF,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AACF;;;ACzLO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAalD,MAAM,MAAM,QAAiE;AAC3E,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,MAC7C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,QAAQ,QAAoE;AAChF,WAAO,KAAK,QAAQ,OAAO,sBAAsB;AAAA,MAC/C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,IAAI,QAAgE;AACxE,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBAAgB,QAAiD;AACrE,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,mBAAmB,QAAoD;AAC3E,WAAO,KAAK,QAAQ,OAAO,mCAAmC;AAAA;AAAA;AAAA,MAG5D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,kBAAkB,QAAmD;AACzE,WAAO,KAAK,QAAQ,OAAO,iCAAiC;AAAA;AAAA;AAAA;AAAA,MAI1D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,cACJ,QACwC;AACxC,WAAO,KAAK,QAAQ,OAAO,4BAA4B;AAAA,MACrD,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,kBAAkB,QAA0D;AAChF,WAAO,KAAK,QAAQ,OAAO,iCAAiC;AAAA;AAAA;AAAA;AAAA,MAI1D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,iBAAuD;AAC3D,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,MAAsE;AAC1F,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,KAAK,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBACJ,IACA,MACqC;AACrC,WAAO,KAAK,QAAQ,OAAO,yBAAyB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,IAAiD;AACrE,WAAO,KAAK,QAAQ,UAAU,yBAAyB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACjF;AAAA;AAAA,EAGA,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,aACJ,QACA,QACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,mBAAmB,MAAM,CAAC,IAAI;AAAA,MAC7E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAQ,QAAkD;AAC9D,WAAO,KAAK,QAAQ,OAAO,cAAc,mBAAmB,MAAM,CAAC,OAAO;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,aACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,6BAA6B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,aAAa,QAAmE;AACpF,WAAO,KAAK,QAAQ,QAAQ,6BAA6B,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,mBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,mCAAmC,EAAE,OAAO,OAAO,CAAC;AAAA,EACjF;AAAA;AAAA,EAGA,MAAM,iBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,iCAAiC,EAAE,OAAO,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA,EAGA,MAAM,yBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,0CAA0C,EAAE,OAAO,OAAO,CAAC;AAAA,EACxF;AACF;;;ACvQO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,SACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,wBAAwB,EAAE,OAAO,OAAO,CAAC;AAAA,EACtE;AAAA;AAAA,EAGA,MAAM,SAAS,QAAmE;AAChF,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,EACtE;AACF;;;ACdO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,QAAQ,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,SAAS,KAA+C;AAC5D,WAAO,KAAK,QAAQ,OAAO,UAAU,mBAAmB,GAAG,CAAC,EAAE;AAAA,EAChE;AACF;;;ACuCO,IAAM,SAAN,MAAa;AAAA,EAClB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAsBlD,MAAM,aACJ,QACA,SACyD;AACzD,WAAO,UAAU,KAAK,SAAS,QAAQ,wBAAwB,EAAE,MAAM,UAAU,CAAC,EAAE,GAAG,OAAO;AAAA,EAChG;AAAA,EAwBA,MAAM,uBACJ,QACA,SACyD;AACzD,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAU,CAAC,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAwBA,MAAM,iBACJ,QACA,SAC6D;AAC7D,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAU,CAAC,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAqBA,MAAM,2BACJ,QACA,SAC6D;AAC7D,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAU,CAAC,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAYA,MAAM,QACJ,QACA,SACoD;AACpD,WAAO,UAAU,KAAK,SAAS,QAAQ,wBAAwB,EAAE,MAAM,UAAU,CAAC,EAAE,GAAG,OAAO;AAAA,EAChG;AAAA,EAeA,MAAM,kBACJ,QACA,SACoD;AACpD,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,MAAM,UAAU,CAAC,EAAE;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAeA,MAAM,SACJ,QACA,SACqD;AACrD,WAAO,UAAU,KAAK,SAAS,OAAO,yBAAyB,QAAQ,MAAM,GAAG,OAAO;AAAA,EACzF;AAAA,EAeA,MAAM,mBACJ,QACA,SACqD;AACrD,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EAYA,MAAM,QACJ,QACA,SACoD;AACpD,WAAO,UAAU,KAAK,SAAS,QAAQ,wBAAwB,EAAE,MAAM,OAAO,GAAG,OAAO;AAAA,EAC1F;AAAA,EAYA,MAAM,kBACJ,QACA,SACoD;AACpD,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,MAAM,OAAO;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAuBA,MAAM,cACJ,WACA,QACA,SAC0D;AAC1D,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ,EAAE,gBAAgB,UAAU,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA,EAyBA,MAAM,SACJ,QACA,SAC8D;AAC9D,WAAO,UAAU,KAAK,SAAS,OAAO,iBAAiB,QAAQ,MAAM,GAAG,OAAO;AAAA,EACjF;AACF;AAGA,SAAS,QAAQ,QAAiB,SAAkD;AAClF,SAAO,EAAE,OAAQ,UAAU,CAAC,GAAa,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,EAAG;AAC3E;;;AC7XO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,WAA2C;AAC/C,WAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,YAAoD;AAC5E,WAAO,KAAK,QAAQ,OAAO,mBAAmB,mBAAmB,UAAU,CAAC,EAAE;AAAA,EAChF;AACF;;;ACtBO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,OAAO,QAAmE;AAC9E,WAAO,KAAK,QAAQ,QAAQ,UAAU,EAAE,MAAM,OAAO,CAAC;AAAA,EACxD;AAAA;AAAA,EAGA,MAAM,SAAS,QAAkD;AAC/D,WAAO,KAAK,QAAQ,OAAO,UAAU,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,OAAO,QAAkD;AAC7D,WAAO,KAAK,QAAQ,UAAU,UAAU,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACtE;AACF;;;ACjBO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,SACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,gBAAgB,EAAE,OAAO,OAAO,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGA,MAAM,iBACJ,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,6BAA6B,EAAE,OAAO,OAAO,CAAC;AAAA,EAC3E;AACF;;;ACHO,IAAM,UAAN,MAAc;AAAA,EACnB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,OAAO,WAAmB,QAAsD;AACpF,WAAO,KAAK,QAAQ,QAAQ,YAAY;AAAA,MACtC,MAAM;AAAA,MACN,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,KAAK,WAA8C;AACvD,WAAO,KAAK,QAAQ,OAAO,iBAAiB,EAAE,OAAO,EAAE,YAAY,UAAU,EAAE,CAAC;AAAA,EAClF;AAAA;AAAA,EAGA,MAAM,SAAgD;AACpD,WAAO,KAAK,QAAQ,OAAO,iBAAiB;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAM,SAAS,UAAkB,WAA4C;AAC3E,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,IAAI;AAAA,MACrE,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OACJ,UACA,WACA,QACyB;AACzB,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,IAAI;AAAA,MACrE,MAAM;AAAA,MACN,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAO,UAAkB,WAAqC;AAClE,WAAO,KAAK,QAAQ,UAAU,YAAY,mBAAmB,QAAQ,CAAC,IAAI;AAAA,MACxE,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,UAAkB,WAAqD;AACxF,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,cAAc;AAAA,MAC/E,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aACJ,UACA,WACA,QACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,YAAY,mBAAmB,QAAQ,CAAC,cAAc;AAAA,MAC/E,MAAM;AAAA,MACN,OAAO,EAAE,YAAY,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AACF;;;ACnEO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,OAAO,QAAkF;AAC7F,WAAO,KAAK,QAAQ,QAAQ,2BAA2B,EAAE,MAAM,OAAO,CAAC;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,KAAK,YAA6D;AACtE,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAO,IAA8B;AACzC,WAAO,KAAK,QAAQ,UAAU,2BAA2B,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,QAAyE;AACrF,WAAO,KAAK,QAAQ,OAAO,mCAAmC;AAAA,MAC5D,OAAO;AAAA,QACL,aAAa,OAAO;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA;AAAA,QAEpD,GAAI,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,QAC/D,GAAI,OAAO,WAAW,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,MACzD;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClCO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlD,MAAM,WAAgD;AACpD,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBACJ,QACqC;AACrC,WAAO,KAAK,QAAQ,OAAO,kCAAkC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBACJ,WACA,QACgC;AAChC,WAAO,KAAK,QAAQ,OAAO,+BAA+B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACzF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAmB,WAAmD;AAC1E,WAAO,KAAK,QAAQ,UAAU,+BAA+B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAA+D;AACnE,WAAO,KAAK,QAAQ,OAAO,oCAAoC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAc,WAAgE;AAClF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,kCAAkC,mBAAmB,SAAS,CAAC;AAAA,IACjE;AAAA,EACF;AACF;;;AC5DO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,KAAK,QAAuE;AAChF,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,MAC7C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,QAAgF;AAC3F,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,SACA,QACsC;AACtC,WAAO,KAAK,QAAQ,UAAU,oBAAoB,mBAAmB,OAAO,CAAC,IAAI;AAAA,MAC/E,MAAM,UAAU,CAAC;AAAA,IACnB,CAAC;AAAA,EACH;AACF;;;ACnCO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,SAAS,WAAoD;AACjE,WAAO,KAAK,QAAQ,OAAO,+BAA+B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAK,WAAoD;AAC7D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,WAAoD;AAC/D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAoB,WAAyD;AACjF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,WACJ,WACA,SAAoC,CAAC,GACN;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,MAC5D,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,WAAmB,QAAyD;AAC7F,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,MAC5D,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,WAAmB,QAAuD;AACxF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,SAAS,CAAC;AAAA,MAC5D,EAAE,MAAM,QAAQ,oBAAoB,OAAO,mBAAmB,KAAK;AAAA,IACrE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,QAAmE;AACrF,QAAI,QAAQ;AACV,aAAO,KAAK,QAAQ,OAAO,gCAAgC,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;AAAA,IACrF;AACA,WAAO,KAAK,QAAQ,OAAO,8BAA8B;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB,SAAkC,CAAC,GAAsC;AAC/F,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAc,QAAsD;AACxE,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/E;AACF;;;ACxIO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,KAAK,YAAyD;AAClE,WAAO,KAAK,QAAQ,OAAO,eAAe,EAAE,OAAO,EAAE,aAAa,WAAW,EAAE,CAAC;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,QACA,YACmC;AACnC,WAAO,KAAK,QAAQ,QAAQ,eAAe;AAAA,MACzC,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,QACA,QACA,YACmC;AACnC,WAAO,KAAK,QAAQ,OAAO,eAAe,mBAAmB,MAAM,CAAC,IAAI;AAAA,MACtE,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,QAAgB,YAA6D;AACxF,WAAO,KAAK,QAAQ,UAAU,eAAe,mBAAmB,MAAM,CAAC,IAAI;AAAA,MACzE,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;AC7DO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYlD,MAAM,OAAO,QAAgE;AAC3E,WAAO,KAAK,QAAQ,QAAQ,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,eAAoD;AACxD,WAAO,KAAK,QAAQ,OAAO,gCAAgC;AAAA,EAC7D;AACF;;;ACmBO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAG1C,OAAO,WAAmB,SAAwC;AACxE,WAAO,EAAE,GAAG,SAAS,SAAS,EAAE,gBAAgB,WAAW,GAAG,SAAS,QAAQ,EAAE;AAAA,EACnF;AAAA;AAAA;AAAA,EAIA,MAAM,YACJ,MACA,WACA,SACqC;AACrC,UAAM,OAAO,IAAI,SAAS;AAC1B,SAAK,OAAO,QAAQ,IAAI;AACxB,WAAO,KAAK,QAAQ,QAAQ,oBAAoB;AAAA,MAC9C,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,QACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa;AAAA,MACvC,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KACJ,QACA,WACA,SAC8B;AAC9B,WAAO,KAAK,QAAQ,OAAO,kBAAkB;AAAA,MAC3C,OAAO,WAAW,SAAY,SAAY,EAAE,GAAG,OAAO;AAAA,MACtD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,OACA,WACA,SACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,qBAAqB;AAAA,MAC9C,OAAO,EAAE,GAAG,MAAM;AAAA,MAClB,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SACJ,WACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACvE,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MACJ,WACA,OACA,WACA,SAC+B;AAC/B,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,UAAU;AAAA,MAC7E,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,MACjC,OAAO,EAAE,GAAG,MAAM;AAAA,IACpB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,iBACJ,YACA,WACA,SACmC;AACnC,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA;AAAA,MAEjC,OAAO,EAAE,aAAa,WAAW,KAAK,GAAG,EAAE;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,WACA,QACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACxE,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,WACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QACJ,WACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,MAAM,OAAO,WAAmB,WAAmB,SAAwC;AACzF,WAAO,KAAK,QAAQ,UAAU,aAAa,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAC1E,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBACJ,WACA,SACA,WACA,SACgC;AAChC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC/E,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SACJ,WACA,QACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC/E,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACJ,WACA,SACA,QACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,WAAW,mBAAmB,OAAO,CAAC;AAAA,MAChF,EAAE,MAAM,QAAQ,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aACJ,WACA,SACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,WAAW,mBAAmB,OAAO,CAAC;AAAA,MAChF,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBACJ,WACA,OACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,iBAAiB;AAAA,MACrF,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,WACA,SACA,SACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,iBAAiB,mBAAmB,OAAO,CAAC;AAAA,MACtF,EAAE,MAAM,SAAS,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBACJ,WACA,SACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,iBAAiB,mBAAmB,OAAO,CAAC;AAAA,MACtF,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,WACA,QACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC/E,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SACJ,WACA,MACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,YAAY;AAAA,MAChF;AAAA,MACA,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YACJ,WACA,SACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,YAAY,mBAAmB,OAAO,CAAC;AAAA,MACjF,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBACJ,WACA,MACA,WACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,yBAAyB;AAAA,MAC7F;AAAA,MACA,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,yBACJ,WACA,aACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC,yBAAyB,mBAAmB,WAAW,CAAC;AAAA,MAClG,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,OACA,WACA,SACyC;AACzC,WAAO,KAAK,QAAQ,OAAO,gCAAgC;AAAA,MACzD,OAAO,EAAE,GAAG,MAAM;AAAA,MAClB,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aACJ,WACA,MACA,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C,EAAE,MAAM,GAAG,KAAK,OAAO,WAAW,OAAO,EAAE;AAAA,IAC7C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eACJ,MACA,WACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB;AAAA,MAClD;AAAA,MACA,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,OACA,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,6BAA6B;AAAA,MACtD,OAAO,UAAU,SAAY,SAAY,EAAE,GAAG,MAAM;AAAA,MACpD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,MACA,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,gCAAgC;AAAA,MAC1D;AAAA,MACA,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACJ,YACA,SACA,WACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MACpF,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,YACA,WACA,SACkC;AAClC,WAAO,KAAK,QAAQ,UAAU,wBAAwB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MACtF,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBACJ,YACA,WACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,mBAAmB,UAAU,CAAC,YAAY;AAAA,MAC5F,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBACJ,YACA,WACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,mBAAmB,UAAU,CAAC,YAAY;AAAA,MAC5F,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,SACA,WACA,SACuC;AACvC,WAAO,KAAK,QAAQ,QAAQ,4BAA4B;AAAA,MACtD,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YACJ,SACA,WACA,SACmC;AACnC,WAAO,KAAK,QAAQ,QAAQ,0BAA0B;AAAA,MACpD,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACJ,qBACA,WACA,SACuC;AACvC,WAAO,KAAK,QAAQ,OAAO,yBAAyB;AAAA,MAClD,OAAO,EAAE,uBAAuB,oBAAoB;AAAA,MACpD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aACJ,WACA,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,kBAAkB;AAAA,MACrF,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,SACA,WACA,SAC2C;AAC3C,WAAO,KAAK,QAAQ,QAAQ,2BAA2B;AAAA,MACrD,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,aACJ,WACA,SACA,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,uBAAuB;AAAA,MAC3F,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBACJ,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,WACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,eACJ,WACA,SACA,WACA,SACwC;AACxC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,yBAAyB;AAAA,MAC7F,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBACJ,WACA,SACA,WACA,SACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,qBAAqB;AAAA,MACzF,MAAM;AAAA,MACN,GAAG,KAAK,OAAO,WAAW,OAAO;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;ACjwBO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAalD,MAAM,OACJ,QACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAK,QAA2B,SAA+C;AACnF,WAAO,KAAK,QAAQ,OAAO,aAAa;AAAA,MACtC,OAAO,WAAW,SAAY,SAAY,EAAE,GAAG,OAAO;AAAA,MACtD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,eACJ,WACA,QACA,SACsB;AACtB,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,aAAa;AAAA,MAChF,OAAO,WAAW,SAAY,SAAY,EAAE,GAAG,OAAO;AAAA,MACtD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,WACA,QACA,SACsB;AACtB,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,aAAa;AAAA,MAChF,OAAO,WAAW,SAAY,SAAY,EAAE,GAAG,OAAO;AAAA,MACtD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAO,QAA6B,SAAwC;AAChF,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,MAC7C,OAAO,EAAE,GAAG,OAAO;AAAA,MACnB,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,WAAmB,SAA2D;AAC3F,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,WACA,QACA,SACkC;AAClC,WAAO,KAAK,QAAQ,SAAS,aAAa,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACzE,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,WAAmB,SAAwC;AACtE,WAAO,KAAK,QAAQ,UAAU,aAAa,mBAAmB,SAAS,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,WAAmB,SAA2D;AAC3F,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,aAAa;AAAA,MACjF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KACJ,WACA,QACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,SAAS;AAAA,MAC7E,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,WACA,QACA,SACkC;AAClC,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,gBAAgB;AAAA,MACpF,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,WAAmB,SAAwC;AAC3E,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,QAAQ;AAAA,MAC3E,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,WAAmB,SAAoD;AAC3F,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,eAAe;AAAA,MACnF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,UAAU,WAAmB,SAAwD;AACzF,WAAO,KAAK,QAAQ,QAAQ,aAAa,mBAAmB,SAAS,CAAC,UAAU;AAAA,MAC9E,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,WAAmB,SAA4D;AAC9F,WAAO,KAAK,QAAQ,OAAO,aAAa,mBAAmB,SAAS,CAAC,WAAW;AAAA,MAC9E,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ACxOO,IAAM,0BAAN,MAA8B;AAAA,EACnC,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,SAAS,SAAmD;AAChE,WAAO,KAAK,QAAQ,OAAO,qBAAqB,EAAE,GAAG,QAAQ,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,UAA2B,SAAmD;AACzF,WAAO,KAAK,QAAQ,OAAO,qBAAqB,EAAE,MAAM,UAAU,GAAG,QAAQ,CAAC;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,WAAmB,SAAmD;AAC1F,WAAO,KAAK,QAAQ,OAAO,8BAA8B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACxF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cACJ,WACA,UACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,OAAO,8BAA8B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACxF,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,WACA,SACmC;AACnC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,SAAS,CAAC;AAAA,MAC3D,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAQ,QAA+B,SAAwC;AACnF,WAAO,KAAK,QAAQ,QAAQ,6BAA6B;AAAA,MACvD,MAAM;AAAA,MACN,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,SAAwC;AACzD,WAAO,KAAK,QAAQ,OAAO,0BAA0B,EAAE,cAAc,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,QAA4B,SAAmD;AAC9F,WAAO,KAAK,QAAQ,OAAO,0BAA0B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,SAAmD;AAClE,WAAO,KAAK,QAAQ,UAAU,0BAA0B,EAAE,GAAG,QAAQ,CAAC;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAoB,WAAmB,SAAwC;AACnF,WAAO,KAAK,QAAQ,OAAO,8BAA8B,mBAAmB,SAAS,CAAC,SAAS;AAAA,MAC7F,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACJ,WACA,QACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,OAAO,8BAA8B,mBAAmB,SAAS,CAAC,SAAS;AAAA,MAC7F,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAkB,WAAmB,SAAmD;AAC5F,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,SAAS,CAAC;AAAA,MAC3D,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,SAAmD;AACxE,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACJ,QACA,SAC0B;AAC1B,WAAO,KAAK,QAAQ,OAAO,+BAA+B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,wBACJ,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,SAAS,CAAC;AAAA,MAC3D,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,sBACJ,WACA,QACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,SAAS,CAAC;AAAA,MAC3D,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBACJ,WACA,SAC0B;AAC1B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,SAAS,CAAC;AAAA,MAC3D,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBACJ,QACA,SACmC;AACnC,WAAO,KAAK,QAAQ,QAAQ,wCAAwC;AAAA,MAClE,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;AClOO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,KAAK,YAA8D;AACvE,WAAO,KAAK,QAAQ,OAAO,oBAAoB,EAAE,OAAO,EAAE,aAAa,WAAW,EAAE,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OACJ,QACA,YACwC;AACxC,WAAO,KAAK,QAAQ,QAAQ,oBAAoB;AAAA,MAC9C,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,WACJ,QACA,YAC0C;AAC1C,WAAO,KAAK,QAAQ,QAAQ,yBAAyB;AAAA,MACnD,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,YACA,QACA,YACwC;AACxC,WAAO,KAAK,QAAQ,OAAO,oBAAoB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MAC/E,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,QACJ,YACA,QACA,YACwC;AACxC,WAAO,KAAK,QAAQ,QAAQ,oBAAoB,mBAAmB,UAAU,CAAC,YAAY;AAAA,MACxF,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,YAAoB,YAAmC;AAClE,WAAO,KAAK,QAAQ,UAAU,oBAAoB,mBAAmB,UAAU,CAAC,IAAI;AAAA,MAClF,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;ACnIO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlD,MAAM,SAAS,YAAoB,WAAqD;AACtF,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAC/E,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,YAAoB,WAAqD;AACrF,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,SAAS,CAAC,YAAY;AAAA,MACvF,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,YACA,WACA,MACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,qBAAqB,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAC/E,OAAO,EAAE,aAAa,WAAW;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,YAAoB,WAA0D;AACxF,WAAO,KAAK,QAAQ,UAAU,qBAAqB,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAClF,OAAO,EAAE,aAAa,WAAW;AAAA,IACnC,CAAC;AAAA,EACH;AACF;;;ACpBO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,gBAAgB,SAA4D;AAChF,WAAO,KAAK,QAAQ,OAAO,gCAAgC,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,mBACJ,QACA,SACmC;AACnC,WAAO,KAAK,QAAQ,OAAO,gCAAgC,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACzF;AAAA;AAAA,EAGA,MAAM,iBAAiB,SAA+D;AACpF,WAAO,KAAK,QAAQ,OAAO,iCAAiC,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,oBACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,iCAAiC,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC1F;AAAA;AAAA,EAGA,MAAM,gBACJ,gBACA,SAC8C;AAC9C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,kBAAkB,mBAAmB,cAAc,CAAC;AAAA,MACpD,EAAE,GAAG,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,OACJ,QACA,SAC+B;AAC/B,WAAO,KAAK,QAAQ,QAAQ,yBAAyB,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,MACJ,QACA,SACoC;AACpC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAClF;AAAA;AAAA,EAGA,MAAM,SAAS,gBAAwB,SAAwD;AAC7F,WAAO,KAAK,QAAQ,OAAO,kBAAkB,mBAAmB,cAAc,CAAC,IAAI;AAAA,MACjF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QACJ,gBACA,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,cAAc,CAAC,YAAY;AAAA,MAC1F,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,gBACA,QACA,SAC+B;AAC/B,WAAO,KAAK,QAAQ,OAAO,kBAAkB,mBAAmB,cAAc,CAAC,WAAW;AAAA,MACxF,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,KACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,MAChD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,YACJ,QACA,SACuC;AACvC,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SACJ,QACA,SACyC;AACzC,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,aACJ,QACA,SACgC;AAChC,QAAI,YAAY;AAChB,UAAM,QAAQ,MAAM,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,GAAG;AAAA,QACH,oBAAoB,CAAC,UAAU;AAG7B,sBAAY,MAAM,QAAQ,IAAI,2BAA2B,GAAG,YAAY,MAAM;AAC9E,mBAAS,qBAAqB,KAAK;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,OAAO,UAAU;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,MACJ,gBACA,QACA,SACoC;AACpC,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,cAAc,CAAC,UAAU;AAAA,MACxF,MAAM,UAAU,CAAC;AAAA,MACjB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,gBACA,QACA,SACqC;AACrC,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,cAAc,CAAC,WAAW;AAAA,MACzF,MAAM,UAAU,CAAC;AAAA,MACjB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,OACJ,gBACA,QACA,SACqC;AACrC,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,cAAc,CAAC,WAAW;AAAA,MACzF,MAAM,UAAU,CAAC;AAAA,MACjB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,KACJ,QACA,SACmC;AACnC,WAAO,KAAK,QAAQ,QAAQ,uBAAuB,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,gBAAwB,SAA0D;AAC9F,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,mBAAmB,cAAc,CAAC,SAAS;AAAA,MACvF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,cACJ,QACA,SAC4C;AAC5C,WAAO,KAAK,QAAQ,QAAQ,iCAAiC,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,YACJ,QACA,SAC0C;AAC1C,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACzF;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;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BA,MAAM,eACJ,QACA,SAC4C;AAC5C,WAAO,KAAK,QAAQ,QAAQ,kCAAkC,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC5F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,aACJ,gBACA,QACA,SAC0C;AAC1C,WAAO,KAAK,QAAQ,OAAO,kBAAkB,mBAAmB,cAAc,CAAC,aAAa;AAAA,MAC1F,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,oBACJ,SAC+C;AAC/C,WAAO,KAAK,QAAQ,OAAO,oCAAoC,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC/E;AACF;;;ACjaO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,WAAW,SAAsD;AACrE,WAAO,KAAK,QAAQ,OAAO,yBAAyB,EAAE,GAAG,QAAQ,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,aACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,gBAAgB,WAAmB,SAAsD;AAC7F,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,SAAS,CAAC,IAAI;AAAA,MACpF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,mBAAmB,WAAmB,SAAwC;AAClF,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,SAAS,CAAC,QAAQ;AAAA,MACxF,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cACJ,QACA,SACkC;AAClC,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBACJ,gBACA,QACA,SACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,cAAc,CAAC;AAAA,MACjE,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,sBACJ,gBACA,QACA,SAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,cAAc,CAAC;AAAA,MACjE,EAAE,OAAO,QAAqD,GAAG,QAAQ;AAAA,IAC3E;AAAA,EACF;AAAA,EAEA,MAAM,uBACJ,gBACA,QACA,SACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,+BAA+B,mBAAmB,cAAc,CAAC;AAAA,MACjE,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,gBACJ,WACA,QACA,SAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4CAA4C,mBAAmB,SAAS,CAAC;AAAA,MACzE,EAAE,OAAO,QAAqD,GAAG,QAAQ;AAAA,IAC3E;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aACJ,QACA,SACmC;AACnC,WAAO,KAAK,QAAQ,QAAQ,6CAA6C;AAAA,MACvE,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,oBACJ,gBACA,QACA,SACmC;AACnC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,6CAA6C,mBAAmB,cAAc,CAAC;AAAA,MAC/E,EAAE,OAAO,EAAE,YAAY,OAAO,WAAW,GAAG,GAAG,QAAQ;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,wBACJ,gBACA,QACA,SAC0C;AAC1C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,6CAA6C,mBAAmB,cAAc,CAAC;AAAA,MAC/E,EAAE,OAAO,EAAE,YAAY,OAAO,WAAW,GAAG,GAAG,QAAQ;AAAA,IACzD;AAAA,EACF;AACF;;;AC3IO,IAAM,QAAN,MAAY;AAAA,EACjB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA,EAElD,MAAM,KAAK,QAA4E;AACrF,WAAO,KAAK,QAAQ,OAAO,UAAU;AAAA,MACnC,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,OAA+C;AAC5D,WAAO,KAAK,QAAQ,OAAO,UAAU,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAClE;AACF;;;ACeA,SAAS,cAAc,SAAoC,QAAwC;AACjG,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,UAAQ,IAAI,UAAU,MAAM;AAC5B,QAAM,SAAiC,CAAC;AACxC,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,WAAO,GAAG,IAAI;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAaO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYlD,MAAM,wBACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,qCAAqC;AAAA,MAC9D,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,YAAY,OAAO;AAAA,MACrB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SACJ,QACA,SACqC;AACrC,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO,EAAE,WAAW,OAAO,UAAU;AAAA,MACrC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QACJ,QACA,SACoC;AACpC,WAAO,KAAK,QAAQ,OAAO,uBAAuB;AAAA,MAChD,OAAO,EAAE,WAAW,OAAO,WAAW,YAAY,OAAO,WAAW;AAAA,MACpE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCA,MAAM,KACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,oBAAoB;AAAA,MAC7C,OAAO;AAAA,QACL,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkDA,MAAM,cACJ,QACA,SACsC;AACtC,WAAO,KAAK,QAAQ,OAAO,8BAA8B;AAAA,MACvD,OAAO;AAAA,QACL,YAAY,QAAQ;AAAA,QACpB,WAAW,QAAQ;AAAA,QACnB,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,QACA,SAC0C;AAC1C,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO;AAAA,QACL,WAAW,OAAO;AAAA,QAClB,YAAY,OAAO;AAAA,QACnB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,aACA,SAC6B;AAC7B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,QACA,SAC6B;AAC7B,WAAO,KAAK,QAAQ,QAAQ,mCAAmC;AAAA,MAC7D,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,sBACJ,aACA,QACA,SAC6B;AAC7B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,sBACJ,aACA,QACA,SAC6B;AAC7B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD;AAAA,QACE,MAAM;AAAA,QACN,GAAG;AAAA,QACH,oBAAoB,OAAO,mBAAmB;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,qBACJ,aACA,SACsC;AACtC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cACJ,QACA,SAC2B;AAC3B,WAAO,KAAK,QAAQ,QAAQ,wBAAwB;AAAA,MAClD,MAAM;AAAA,MACN,GAAG;AAAA,MACH,oBAAoB,OAAO,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aACJ,QACA,SACwC;AACxC,WAAO,KAAK,QAAQ,OAAO,wBAAwB;AAAA,MACjD,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,WAAW,OAAO;AAAA,MACpB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,qBACJ,aACA,QACA,SACe;AACf,WAAO,KAAK,QAAQ,OAAO,0BAA0B,mBAAmB,WAAW,CAAC,QAAQ;AAAA,MAC1F,OAAO;AAAA,QACL,UAAU,QAAQ;AAAA,QAClB,sBAAsB,QAAQ;AAAA,MAChC;AAAA,MACA,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UACJ,QACA,SACqC;AACrC,WAAO,KAAK,QAAQ,OAAO,qBAAqB;AAAA,MAC9C,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UACJ,QACA,SACgC;AAChC,WAAO,KAAK,QAAQ,OAAO,0BAA0B;AAAA,MACnD,OAAO,EAAE,YAAY,OAAO,WAAW;AAAA,MACvC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SACJ,QACA,SACqC;AACrC,WAAO,KAAK,QAAQ,QAAQ,wBAAwB,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,gCAAgC;AAAA,MAC1D,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,yBACJ,aACA,SAC0C;AAC1C,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,0BACJ,aACA,QACA,SAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC;AAAA,MACzD,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,0BACJ,aACA,cACA,SACe;AACf,WAAO,KAAK;AAAA,MACV;AAAA,MACA,0BAA0B,mBAAmB,WAAW,CAAC,gBAAgB,mBAAmB,YAAY,CAAC;AAAA,MACzG;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,QACA,SAC0C;AAC1C,WAAO,KAAK,QAAQ,QAAQ,8BAA8B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,mBACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,8BAA8B;AAAA,MACxD,MAAM;AAAA,MACN,GAAG;AAAA,MACH,oBAAoB,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,qBACJ,UACA,SACiC;AACjC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,QAAQ,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBACJ,QACA,SAC6C;AAC7C,WAAO,KAAK,QAAQ,OAAO,8BAA8B;AAAA,MACvD,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,QAAQ,8BAA8B;AAAA,MACxD,MAAM;AAAA,MACN,GAAG;AAAA,MACH,oBAAoB,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBACJ,QACA,SAC6C;AAC7C,WAAO,KAAK,QAAQ,OAAO,8BAA8B;AAAA,MACvD,OAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBACJ,QACA,SAC6C;AAC7C,WAAO,KAAK,QAAQ,QAAQ,mCAAmC,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC7F;AAAA,EAEA,MAAM,wBACJ,UACA,QACA,SACe;AACf,WAAO,KAAK,QAAQ,OAAO,8BAA8B,mBAAmB,QAAQ,CAAC,QAAQ;AAAA,MAC3F,OAAO,EAAE,sBAAsB,QAAQ,qBAAqB;AAAA,MAC5D,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,wBAAwB,UAAkB,SAAwC;AACtF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,QAAQ,CAAC;AAAA,MAC1D;AAAA,QACE,GAAG;AAAA,QACH,SAAS,cAAc,SAAS,UAAU;AAAA,QAC1C,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,uBACJ,UACA,SACuC;AACvC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,8BAA8B,mBAAmB,QAAQ,CAAC;AAAA,MAC1D;AAAA,QACE,GAAG;AAAA,QACH,SAAS,cAAc,SAAS,kBAAkB;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;;;AChoBO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlD,MAAM,UACJ,QACA,SAC+B;AAC/B,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO,EAAE,WAAW,QAAQ,UAAU;AAAA,MACtC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WACJ,QACA,SAC6B;AAC7B,WAAO,KAAK,QAAQ,OAAO,2BAA2B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WACJ,QACA,SAC2C;AAC3C,WAAO,KAAK,QAAQ,UAAU,2BAA2B,mBAAmB,MAAM,CAAC,IAAI,OAAO;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,iBAAiB,SAA0D;AAC/E,WAAO,KAAK,QAAQ,OAAO,8BAA8B,OAAO;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,cACJ,QACA,SAC8B;AAC9B,WAAO,KAAK,QAAQ,OAAO,2BAA2B;AAAA,MACpD,OAAO,EAAE,WAAW,OAAO,UAAU;AAAA,MACrC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eACJ,QACA,SACiC;AACjC,WAAO,KAAK,QAAQ,OAAO,8BAA8B,EAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,cACJ,QACA,SACuC;AACvC,WAAO,KAAK,QAAQ,OAAO,+BAA+B;AAAA,MACxD,OAAO;AAAA,QACL,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,OAAO,QAAQ;AAAA,MACjB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,QACJ,IACA,SAAwC,CAAC,GACzC,SAC2B;AAC3B,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,mBAAmB,EAAE,CAAC,YAAY;AAAA,MAC3F,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OACJ,IACA,SAAwC,CAAC,GACzC,SAC2B;AAC3B,WAAO,KAAK,QAAQ,QAAQ,+BAA+B,mBAAmB,EAAE,CAAC,WAAW;AAAA,MAC1F,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ACxKA,SAAS,aAAa,OAAsD;AAC1E,SAAO,MAAM,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAChE;AAEO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlD,MAAM,iBAAiB,QAA+B,CAAC,GAA8B;AACnF,WAAO,KAAK,QAAQ,OAAO,sBAAsB,EAAE,OAAO,aAAa,KAAK,EAAE,CAAC;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eACJ,QACA,QAA+B,CAAC,GACL;AAC3B,WAAO,KAAK,QAAQ,SAAS,sBAAsB;AAAA,MACjD,MAAM;AAAA,MACN,OAAO,aAAa,KAAK;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,WAA8C;AAC/D,WAAO,KAAK,QAAQ,OAAO,mBAAmB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,WAAmB,QAA0D;AAC5F,WAAO,KAAK,QAAQ,SAAS,mBAAmB,mBAAmB,SAAS,CAAC,IAAI;AAAA,MAC/E,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;AC9CO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGlD,MAAM,SAAS,WAAiD;AAC9D,WAAO,KAAK,QAAQ,OAAO,4BAA4B,mBAAmB,SAAS,CAAC,EAAE;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,aAAa,WAAmB,YAAoD;AACxF,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4BAA4B,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,UAAU,CAAC;AAAA,IAC7F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBACJ,WACA,YACA,UACA,QACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4BAA4B,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,UAAU,CAAC,cAAc,mBAAmB,QAAQ,CAAC;AAAA,MACrI,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,WACA,YACA,UACA,SAA4C,CAAC,GACX;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4BAA4B,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,UAAU,CAAC,cAAc,mBAAmB,QAAQ,CAAC;AAAA,MACrI,EAAE,OAAO,EAAE,mBAAmB,OAAO,kBAAkB,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,YACJ,WACA,YACA,QACiC;AACjC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4BAA4B,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,UAAU,CAAC;AAAA,MAC3F;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aACJ,WACA,YACA,QACkC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,4BAA4B,mBAAmB,SAAS,CAAC,IAAI,mBAAmB,UAAU,CAAC;AAAA,MAC3F,EAAE,MAAM,OAAO;AAAA,IACjB;AAAA,EACF;AACF;;;ACjGO,IAAM,OAAN,MAAW;AAAA,EAChB,YAA6B,SAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlD,MAAM,SAAS,SAAgD;AAC7D,WAAO,KAAK,QAAQ,OAAO,SAAS,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,WAAmB,SAA4C;AAChF,WAAO,KAAK,QAAQ,OAAO,eAAe,mBAAmB,SAAS,CAAC,IAAI,OAAO;AAAA,EACpF;AACF;;;AC4BA,IAAM,iBAAiB;AACvB,IAAM,cAAc;AAEpB,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAE3B,SAAS,gBAAgB,QAAsC;AAC7D,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,UAAU,OAAO,KAAK;AAC5B,QAAM,UAAU,OAAO,OAAO;AAC9B,MAAI,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG;AAC5C,WAAO,KAAK,IAAI,UAAU,KAAM,kBAAkB;AAAA,EACpD;AACA,QAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,MAAI,OAAO,SAAS,IAAI,GAAG;AACzB,UAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,WAAO,QAAQ,IAAI,KAAK,IAAI,OAAO,kBAAkB,IAAI;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAiC;AACxD,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,IAAI,SAAS,qBAAqB,IAAI,MAAM,GAAG,kBAAkB,IAAI,WAAM;AACpF;AAEA,SAAS,mBAAmB,SAAqD;AAC/E,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,OAAO,GAAG;AAC5C,QAAI,EAAE,YAAY,MAAM,kBAAmB,QAAO;AAAA,EACpD;AACA,SAAO;AACT;AAOA,SAAS,OAAa;AAEtB;AAOA,IAAM,kBAAN,MAAsB;AAAA,EACpB,YAAqB,OAAgB;AAAhB;AAAA,EAAiB;AACxC;AAQA,IAAM,oBAAN,MAAwB;AAAA,EACtB,YAAqB,OAAgB;AAAhB;AAAA,EAAiB;AACxC;AAEA,SAAS,aAAoB;AAC3B,QAAM,QAAQ,IAAI,MAAM,2BAA2B;AACnD,QAAM,OAAO;AACb,SAAO;AACT;AAGA,SAAS,mBAAmB,QAAsC;AAChE,MAAI,WAAW,QAAQ,CAAC,cAAc,KAAK,MAAM,EAAG,QAAO;AAC3D,QAAM,QAAQ,OAAO,MAAM;AAC3B,SAAO,OAAO,cAAc,KAAK,IAAI,QAAQ;AAC/C;AAUA,SAAS,UACP,QACA,QAC+C;AAC/C,MAAI,OAAO,QAAS,QAAO,QAAQ,OAAO,WAAW,CAAC;AACtD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,UAAU,MAAM,OAAO,WAAW,CAAC;AACzC,WAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxD,WAAO,KAAK,EAAE;AAAA,MACZ,CAAC,WAAW;AACV,eAAO,oBAAoB,SAAS,OAAO;AAC3C,gBAAQ,MAAM;AAAA,MAChB;AAAA,MACA,CAAC,UAAmB;AAClB,eAAO,oBAAoB,SAAS,OAAO;AAC3C,eAAO,OAAO,UAAU,WAAW,IAAI,IAAI,kBAAkB,KAAK,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAGA,SAAS,aAAa,QAAsB,QAA6B;AACvE,QAAM,MAAM,IAAI,WAAW,MAAM;AACjC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,QAAI,IAAI,OAAO,MAAM;AACrB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO,IAAI;AACb;AASA,eAAe,oBACb,UACA,cACA,UACA,SACA,QACA,YACkB;AAClB,QAAM,UAAU,SAAS,WAAW,IAAI,QAAQ;AAChD,QAAM,QAAQ,mBAAmB,QAAQ,IAAI,gBAAgB,CAAC;AAC9D,MAAI,SAAS;AACb,QAAM,SAAS,CAAC,UAAsB;AACpC,QAAI;AAGF,eAAS,EAAE,QAAQ,OAAO,OAAO,MAAM,MAAM,GAAG,SAAS,QAAQ,CAAC;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,IAAI,gBAAgB,KAAK;AAAA,IACjC;AAAA,EACF;AAEA,aAAW;AACX,SAAO,IAAI,WAAW,CAAC,CAAC;AAExB,QAAM,OAAO,SAAS;AACtB,MAAI,CAAC,QAAQ,OAAO,KAAK,cAAc,YAAY;AAGjD,QAAI,iBAAiB,QAAQ;AAC3B,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAMC,SAAQ,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AACrD,eAASA,OAAM;AACf,UAAI,SAAS,EAAG,QAAOA,MAAK;AAC5B,aAAO;AAAA,IACT;AACA,QAAI,iBAAiB,eAAe;AAClC,YAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,eAAS,OAAO;AAChB,UAAI,SAAS,EAAG,QAAO,IAAI,WAAW,MAAM,CAAC;AAC7C,aAAO;AAAA,IACT;AACA,UAAMC,QAAO,MAAM,SAAS,KAAK;AACjC,UAAMD,SAAQ,IAAI,YAAY,EAAE,OAAOC,KAAI;AAC3C,aAASD,OAAM;AACf,QAAI,SAAS,EAAG,QAAOA,MAAK;AAC5B,WAAOC,QAAO,KAAK,MAAMA,KAAI,IAAI;AAAA,EACnC;AAEA,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAuB,CAAC;AAC9B,MAAI;AACF,eAAS;AACP,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,UAAU,QAAQ,MAAM;AACtD,UAAI,KAAM;AACV,UAAI,CAAC,SAAS,MAAM,eAAe,EAAG;AACtC,aAAO,KAAK,KAAK;AACjB,gBAAU,MAAM;AAChB,iBAAW;AACX,aAAO,KAAK;AAAA,IACd;AAAA,EACF,SAAS,KAAK;AAEZ,WAAO,OAAO,EAAE,MAAM,IAAI;AAC1B,UAAM;AAAA,EACR;AAEA,QAAM,QAAQ,aAAa,QAAQ,MAAM;AACzC,MAAI,iBAAiB,QAAQ;AAC3B,WAAO,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,MAAM,QAAQ,IAAI,cAAc,KAAK,GAAG,CAAC;AAAA,EACtE;AACA,MAAI,iBAAiB,eAAe;AAClC,WAAO;AAAA,EACT;AACA,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAC3C,SAAO,OAAO,KAAK,MAAM,IAAI,IAAI;AACnC;AAEA,SAAS,eAAe,SAAwC;AAC9D,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,YAA4D,CAAC;AACnE,QAAM,UAAU,MAAM;AACpB,eAAW,EAAE,QAAQ,QAAQ,KAAK,WAAW;AAC3C,aAAO,oBAAoB,SAAS,OAAO;AAAA,IAC7C;AACA,cAAU,SAAS;AAAA,EACrB;AACA,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS;AAClB,iBAAW,MAAM,OAAO,MAAM;AAC9B,cAAQ;AACR,aAAO,EAAE,QAAQ,WAAW,QAAQ,SAAS,KAAK;AAAA,IACpD;AACA,UAAM,UAAU,MAAM;AACpB,iBAAW,MAAM,OAAO,MAAM;AAC9B,cAAQ;AAAA,IACV;AACA,WAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxD,cAAU,KAAK,EAAE,QAAQ,QAAQ,CAAC;AAAA,EACpC;AACA,SAAO,EAAE,QAAQ,WAAW,QAAQ,QAAQ;AAC9C;AAuCA,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOD,SAAS,oBAAoB,KAAqB;AAChD,QAAM,OAAO,IAAI,QAAQ,GAAG;AAC5B,MAAI,SAAS,GAAI,QAAO;AACxB,QAAM,OAAO,IAAI,MAAM,GAAG,IAAI;AAC9B,QAAM,QAAQ,IAAI,MAAM,OAAO,CAAC;AAChC,QAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS;AAC3C,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,QAAI,UAAU,GAAI,QAAO;AACzB,UAAM,MAAM,KAAK,MAAM,GAAG,KAAK;AAC/B,QAAI,qBAAqB,IAAI,mBAAmB,GAAG,EAAE,YAAY,CAAC,GAAG;AACnE,aAAO,GAAG,GAAG;AAAA,IACf;AACA,WAAO;AAAA,EACT,CAAC;AACD,SAAO,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,CAAC;AACnC;AA2HO,IAAM,UAAN,MAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuGnB,YAAY,QAAiB,SAA0B;AACrD,SAAK,SAAS,UAAU;AACxB,SAAK,UAAU,SAAS,WAAW;AACnC,SAAK,aAAa,SAAS,cAAc;AACzC,SAAK,QAAQ,SAAS,SAAS;AAC/B,QAAI,SAAS,WAAW,OAAW,MAAK,SAAS,QAAQ;AAEzD,QAAI,SAAS,YAAY,QAAW;AAClC,WAAK,UAAU,QAAQ;AAAA,IACzB,WAAW,SAAS,SAAS;AAC3B,WAAK,UAAU;AAAA,IACjB,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AAEA,UAAM,UAAU,KAAK,QAAQ,KAAK,IAAI;AAKtC,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,YAAY,IAAI,UAAU,OAAO;AACtC,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,eAAe,IAAI,aAAa,OAAO;AAC5C,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,sBAAsB,IAAI,oBAAoB,OAAO;AAC1D,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,gBAAgB,IAAI,cAAc,OAAO;AAC9C,SAAK,SAAS,IAAI,OAAO,OAAO;AAChC,SAAK,OAAO,IAAI,KAAK,OAAO;AAG5B,SAAK,aAAa,IAAI,WAAW,OAAO;AACxC,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,mBAAmB,IAAI,iBAAiB,OAAO;AAGpD,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,eAAe,IAAI,aAAa,OAAO;AAG5C,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,YAAY,IAAI,UAAU,OAAO;AACtC,SAAK,OAAO,IAAI,KAAK,OAAO;AAC5B,SAAK,mBAAmB,IAAI,iBAAiB,OAAO;AACpD,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,gBAAgB,IAAI,cAAc,OAAO;AAC9C,SAAK,eAAe,IAAI,aAAa,OAAO;AAC5C,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,aAAa,IAAI,WAAW,OAAO;AACxC,SAAK,kBAAkB,IAAI,gBAAgB,OAAO;AAClD,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,mBAAmB,IAAI,iBAAiB,OAAO;AACpD,SAAK,OAAO,IAAI,KAAK,OAAO;AAG5B,SAAK,gBAAgB,IAAI,cAAc,OAAO;AAC9C,SAAK,cAAc,IAAI,YAAY,OAAO;AAC1C,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,SAAS,IAAI,OAAO,OAAO;AAChC,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,UAAU,IAAI,QAAQ,OAAO;AAClC,SAAK,wBAAwB,IAAI,sBAAsB,OAAO;AAC9D,SAAK,qBAAqB,IAAI,mBAAmB,OAAO;AACxD,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,mBAAmB,IAAI,iBAAiB,OAAO;AACpD,SAAK,YAAY,IAAI,UAAU,OAAO;AACtC,SAAK,kBAAkB,IAAI,gBAAgB,OAAO;AAClD,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,WAAW,IAAI,SAAS,OAAO;AACpC,SAAK,kBAAkB,IAAI,wBAAwB,OAAO;AAC1D,SAAK,iBAAiB,IAAI,eAAe,OAAO;AAChD,SAAK,kBAAkB,IAAI,gBAAgB,OAAO;AAClD,SAAK,YAAY,IAAI,UAAU,OAAO;AACtC,SAAK,qBAAqB,IAAI,mBAAmB,OAAO;AACxD,SAAK,gBAAgB,IAAI,cAAc,OAAO;AAC9C,SAAK,QAAQ,IAAI,MAAM,OAAO;AAC9B,SAAK,SAAS,IAAI,OAAO,OAAO;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,OAAqB;AAC/B,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAsB;AACpB,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,iBAAyC;AAC7C,UAAM,mBAAmB,KAAK;AAC9B,UAAM,WAAW,MAAM,KAAK,MAAM,aAAa;AAC/C,QAAI,KAAK,aAAa,kBAAkB;AACtC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,SAAK,YAAY,SAAS,KAAK;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,QAAW,QAAgB,MAAc,SAAsC;AACnF,QAAI,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAEhC,QAAI,SAAS,OAAO;AAClB,YAAM,SAAS,IAAI,gBAAgB;AACnC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAK,GAAG;AACxD,YAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,YAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,qBAAW,KAAK,OAAO;AACrB,gBAAI,MAAM,UAAa,MAAM,KAAM,QAAO,OAAO,KAAK,OAAO,CAAC,CAAC;AAAA,UACjE;AAAA,QACF,OAAO;AACL,iBAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AACA,YAAM,KAAK,OAAO,SAAS;AAC3B,UAAI,IAAI;AACN,eAAO,IAAI,EAAE;AAAA,MACf;AAAA,IACF;AAEA,QAAI,UAAkC;AAAA,MACpC,GAAI,KAAK,WACL,EAAE,eAAe,UAAU,KAAK,QAAQ,GAAG,IAC3C,KAAK,SACH,EAAE,WAAW,KAAK,OAAO,IACzB,CAAC;AAAA,MACP,GAAG,SAAS;AAAA,IACd;AAKA,UAAM,YACJ,SAAS,SAAS,UAClB,SAAS,SAAS,SACjB,QAAQ,gBAAgB,YACvB,QAAQ,gBAAgB,QACxB,QAAQ,gBAAgB,eACxB,QAAQ,gBAAgB;AAE5B,QAAI,SAAS,QAAQ,CAAC,WAAW;AAC/B,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAIA,QAAI;AACJ,QAAI,WAAW;AACb,uBAAiB,SAAS;AAAA,IAC5B,WAAW,SAAS,MAAM;AACxB,uBAAiB,KAAK,UAAU,QAAQ,IAAI;AAAA,IAC9C;AAEA,QAAI,iBAAiB,mBAAmB,OAAO,GAAG,KAAK;AACvD,QAAI,WAAW,OAAO,UAAU,eAAe,KAAK,SAAS,oBAAoB,GAAG;AAClF,YAAM,UAAU,SAAS;AACzB,YAAM,aACJ,CAAC,aAAa,OAAO,mBAAmB,WAAW,KAAK,MAAM,cAAc,IAAI;AAClF,YAAM,YACJ,cAAc,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,UAAU,IACnE,WAAuC,mBAAmB,OAC5D;AACN,YAAM,kBAAkB,OAAO,KAAK,OAAO,EAAE;AAAA,QAC3C,CAAC,SAAS,KAAK,YAAY,MAAM;AAAA,MACnC;AACA,UACG,YAAY,QAAQ,OAAO,YAAY,YACxC,cAAc,WACd,gBAAgB;AAAA,QACd,CAAC,SAAS,QAAQ,IAAI,MAAM,WAAW,QAAQ,IAAI,GAAG,KAAK,MAAM,QAAQ,IAAI;AAAA,MAC/E,GACA;AACA,cAAM,IAAI,aAAa,mDAAmD;AAAA,UACxE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA,uBAAiB,SAAS,KAAK;AAG/B,UAAI,gBAAgB,SAAS,GAAG;AAC9B,kBAAU;AAAA,UACR,GAAG,OAAO;AAAA,YACR,OAAO,QAAQ,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,MAAM,KAAK,YAAY,MAAM,iBAAiB;AAAA,UACrF;AAAA,UACA,mBAAmB,kBAAkB;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AACA,UAAM,cACJ,WAAW,SACX,WAAW,YACV,mBAAmB,UAAa,mBAAmB;AAEtD,UAAM,eAAe,SAAS;AAC9B,QAAI,cAAc,SAAS;AACzB,YAAM,IAAI,aAAa,mBAAmB;AAAA,QACxC,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,UAAM,YAAY,SAAS,WAAW,KAAK;AAE3C,QAAI;AACJ,QAAI,uBAAsC;AAE1C,UAAM,UAAU,MAAM,oBAAoB,GAAG;AAC7C,UAAM,OAAO,CAAC,OAAyC,SAAkC;AACvF,UAAI,CAAC,KAAK,MAAO;AACjB,UAAI,KAAK,QAAQ;AACf,aAAK,OAAO,OAAO,IAAI;AACvB;AAAA,MACF;AACA,UAAI,UAAU;AACZ,gBAAQ,IAAI,aAAa,KAAK,MAAgB,IAAI,KAAK,GAAa,EAAE;AAAA,eAC/D,UAAU;AACjB,gBAAQ;AAAA,UACN,aAAa,KAAK,MAAgB,IAAI,KAAK,MAAgB,IAAI,KAAK,IAAc;AAAA,QACpF;AAAA;AAEA,gBAAQ;AAAA,UACN,mBAAmB,KAAK,OAAiB,IAAI,KAAK,UAAoB,IAAI,KAAK,MAAgB,IAAI,KAAK,IAAc;AAAA,QACxH;AAAA,IACJ;AAEA,aAAS,UAAU,GAAG,WAAW,KAAK,YAAY,WAAW;AAC3D,UAAI,UAAU,GAAG;AACf,cAAM,OAAO,KAAK,IAAI,MAAM,MAAM,UAAU,IAAI,GAAI;AAEpD,cAAM,WAAW,KAAK,OAAO,IAAI;AACjC,cAAM,QAAQ,KAAK,IAAI,wBAAwB,GAAG,QAAQ;AAC1D,+BAAuB;AACvB,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AACzD,aAAK,SAAS,EAAE,SAAS,YAAY,KAAK,YAAY,QAAQ,KAAK,CAAC;AAAA,MACtE;AAEA,YAAM,cAAc,IAAI,gBAAgB;AACxC,UAAI,YAAY,WAAW,MAAM,YAAY,MAAM,GAAG,SAAS;AAG/D,YAAM,mBAAmB,MAAM;AAC7B,YAAI,YAAY,OAAO,QAAS;AAChC,qBAAa,SAAS;AACtB,oBAAY,WAAW,MAAM,YAAY,MAAM,GAAG,SAAS;AAAA,MAC7D;AACA,YAAM,WAAW;AAAA,QACf,eAAe,CAAC,YAAY,QAAQ,YAAY,IAAI,CAAC,YAAY,MAAM;AAAA,MACzE;AAEA,UAAI;AACF,aAAK,WAAW,EAAE,QAAQ,KAAK,QAAQ,GAAG,KAAK,CAAC;AAEhD,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,QAAQ,SAAS;AAAA,UACjB,GAAI,SAAS,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,QAC7E,CAAC;AAED,cAAM,YACJ,SAAS,SAAS,IAAI,cAAc,KAAK,SAAS,SAAS,IAAI,YAAY,KAAK;AAElF,aAAK,YAAY,EAAE,QAAQ,SAAS,QAAQ,QAAQ,MAAM,UAAU,CAAC;AAErE,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACpD,cAAI,SAAkC,CAAC;AACvC,cAAI,SAAS;AACX,gBAAI;AACF,uBAAS,KAAK,MAAM,OAAO;AAAA,YAC7B,QAAQ;AAAA,YAER;AAAA,UACF;AAEA,gBAAM,MAAO,OAAO,SAAqC;AACzD,gBAAM,UACH,IAAI,WAAsB,8BAA8B,SAAS,MAAM;AAC1E,gBAAM,OAAQ,IAAI,QAAmB;AACrC,gBAAM,OAAQ,IAAI,cAA0B,IAAI,QAAmB;AACnE,gBAAM,OACJ,IAAI,QAAQ,OAAO,IAAI,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IAAI,IAC9D,IAAI,OACL;AACN,gBAAM,eAAe,gBAAgB,OAAO;AAQ5C,gBAAM,yBAAyB,SAAS,eAAe,KAAK,WAAW,KAAK;AAC5E,cAAI,SAAS,WAAW,OAAO,CAAC,wBAAwB;AACtD,kBAAM,IAAI,2BAA2B,SAAS;AAAA,cAC5C;AAAA,cACA;AAAA,cACA;AAAA,cACA,SAAS;AAAA,cACT;AAAA,YACF,CAAC;AAAA,UACH;AAEA,gBAAM,QAAQ,IAAI,aAAa,SAAS;AAAA,YACtC,QAAQ,SAAS;AAAA,YACjB;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,UACF,CAAC;AAGD,gBAAM,oBAAoB,SAAS,UAAU,OAAO,SAAS,WAAW;AACxE,cAAI,qBAAqB,eAAe,UAAU,KAAK,YAAY;AACjE,gBAAI,SAAS,WAAW,KAAK;AAC3B,qCAAuB,gBAAgB,SAAS,SAAS,IAAI,aAAa,KAAK,IAAI;AAAA,YACrF;AACA,wBAAY;AACZ;AAAA,UACF;AAEA,gBAAM;AAAA,QACR;AAEA,YAAI,SAAS,oBAAoB;AAC/B,iBAAQ,MAAM;AAAA,YACZ;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR;AAAA,YACA,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF;AACA,YAAI,SAAS,iBAAiB,QAAQ;AACpC,iBAAQ,MAAM,SAAS,KAAK;AAAA,QAC9B;AACA,YAAI,SAAS,iBAAiB,eAAe;AAC3C,iBAAQ,MAAM,SAAS,YAAY;AAAA,QACrC;AACA,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAQ,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,MACpC,SAAS,KAAK;AACZ,YAAI,eAAe,gBAAgB,eAAe,4BAA4B;AAC5E,gBAAM;AAAA,QACR;AACA,YAAI,eAAe,iBAAiB;AAClC,gBAAM,IAAI;AAAA,QACZ;AACA,YAAI,eAAe,mBAAmB;AACpC,gBAAM,QAAQ,IAAI;AAClB,gBAAM,SACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,oBAAoB;AAC/E,sBAAY,IAAI,aAAa,kBAAkB,MAAM,IAAI;AAAA,YACvD,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AACD,cAAI,eAAe,UAAU,KAAK,WAAY;AAC9C,gBAAM;AAAA,QACR;AACA,YAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,cAAI,cAAc,SAAS;AACzB,kBAAM,IAAI,aAAa,mBAAmB;AAAA,cACxC,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AACA,sBAAY,IAAI,aAAa,qBAAqB;AAAA,YAChD,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AACD,cAAI,eAAe,UAAU,KAAK,WAAY;AAC9C,gBAAM;AAAA,QACR;AACA,YAAI,eAAe,WAAW;AAC5B,sBAAY,IAAI,aAAa,kBAAkB,IAAI,OAAO,IAAI;AAAA,YAC5D,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UACR,CAAC;AACD,cAAI,eAAe,UAAU,KAAK,WAAY;AAC9C,gBAAM;AAAA,QACR;AACA,cAAM;AAAA,MACR,UAAE;AACA,qBAAa,SAAS;AACtB,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,UAAM;AAAA,EACR;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCA,OAAO,SACL,QAGA,QACA,SACmB;AACnB,UAAM,WAAW,OAAO,YAAY,WAAW,UAAW,SAAS,YAAY;AAC/E,UAAM,WAAW,OAAO,YAAY,WAAW,QAAQ,SAAS;AAChE,QAAI,SAAS;AACb,QAAI;AACJ,WAAO,MAAM;AACX,YAAM,OAAO,EAAE,GAAK,UAAU,CAAC,GAAU,OAAO,SAAS;AAKzD,UAAI,UAAU;AACZ,YAAI,UAAU,OAAW,MAAK,iBAAiB;AAAA,MACjD,OAAO;AACL,aAAK,SAAS;AAAA,MAChB;AACA,YAAM,SAAS,MAAM,OAAO,IAAI;AAChC,YAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,SAAS,OAAO;AACtD,UAAI,MAAM,WAAW,EAAG;AACxB,iBAAW,QAAQ,OAAO;AACxB,cAAM;AAAA,MACR;AACA,UAAI,MAAM,SAAS,SAAU;AAC7B,UAAI,UAAU;AACZ,cAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAI,SAAS,OAAW;AACxB,gBAAQ,SAAS,IAAI;AACrB,YAAI,UAAU,OAAW;AAAA,MAC3B,OAAO;AACL,kBAAU,MAAM;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAAA;AAxnBa,QAEJ,WAAW;;;ACvbb,SAAS,KACd,KACA,YACA,OACU;AACV,QAAM,SACJ,OAAO,UAAU,WAAW,EAAE,MAAM,UAAU,MAAM,IAAI,EAAE,MAAM,gBAAgB,MAAM;AACxF,SAAO,EAAE,MAAM,QAAQ,KAAK,YAAY,OAAO,OAAO;AACxD;AAGO,SAAS,SAAS,UAAsC;AAC7D,SAAO,EAAE,MAAM,OAAO,SAAS;AACjC;AAGO,SAAS,SAAS,UAAsC;AAC7D,SAAO,EAAE,MAAM,OAAO,SAAS;AACjC;AAiEA,SAAS,YAAY,MAAuC;AAC1D,QAAM,SAAS,KAAK,cAAc;AAClC,QAAM,UAAU,KAAK,QAAQ;AAC7B,QAAM,UAA2B,UAAU,UAAU,aAAa,UAAU,SAAS;AACrF,SAAO;AAAA,IACL,UAAU;AAAA,IACV,gBAAgB,KAAK,cAAc;AAAA,IACnC,iBAAiB,KAAK,QAAQ;AAAA,IAC9B,mBAAmB,KAAK,gBAAgB;AAAA,IACxC,gBAAgB,KAAK,OAAO;AAAA,IAC5B,gBAAgB,KAAK,OAAO;AAAA,EAC9B;AACF;AAEA,SAAS,cAAc,KAAa,OAAiC;AACnE,SAAO,EAAE,KAAK,YAAY,SAAS,OAAO,EAAE,MAAM,gBAAgB,MAAM,GAAG,UAAU,CAAC,EAAE;AAC1F;AAEA,SAAS,gBACP,KACA,YACA,OACkB;AAClB,SAAO,EAAE,KAAK,YAAY,OAAO,EAAE,MAAM,UAAU,MAAM,GAAG,UAAU,CAAC,EAAE;AAC3E;AAEA,SAAS,gBACP,OAA0B,CAAC,GAC3B,MAA0B,CAAC,GACP;AACpB,QAAM,MAA0B,CAAC;AACjC,MAAI,KAAK,iBAAiB,KAAM,KAAI,KAAK,cAAc,kBAAkB,KAAK,aAAa,CAAC;AAC5F,MAAI,KAAK,aAAa,KAAM,KAAI,KAAK,cAAc,aAAa,KAAK,SAAS,CAAC;AAC/E,MAAI,KAAK,YAAY,KAAM,KAAI,KAAK,cAAc,YAAY,KAAK,QAAQ,CAAC;AAC5E,MAAI,KAAK,eAAe,KAAM,KAAI,KAAK,cAAc,gBAAgB,KAAK,WAAW,CAAC;AACtF,MAAI,KAAK,kBAAkB,KAAM,KAAI,KAAK,cAAc,mBAAmB,KAAK,cAAc,CAAC;AAC/F,MAAI,KAAK,gBAAgB,KAAM,KAAI,KAAK,gBAAgB,UAAU,SAAS,KAAK,YAAY,CAAC;AAC7F,MAAI,KAAK,qBAAqB,MAAM;AAClC,QAAI,KAAK,gBAAgB,UAAU,gBAAgB,KAAK,iBAAiB,CAAC;AAAA,EAC5E;AACA,MAAI,KAAK,kBAAkB,MAAM;AAC/B,QAAI,KAAK,gBAAgB,UAAU,aAAa,KAAK,cAAc,CAAC;AAAA,EACtE;AACA,MAAI,KAAK,wBAAwB,MAAM;AACrC,QAAI,KAAK,gBAAgB,mBAAmB,SAAS,KAAK,oBAAoB,CAAC;AAAA,EACjF;AACA,MAAI,KAAK,6BAA6B,MAAM;AAC1C,QAAI,KAAK,gBAAgB,mBAAmB,gBAAgB,KAAK,yBAAyB,CAAC;AAAA,EAC7F;AACA,MAAI,KAAK,0BAA0B,MAAM;AACvC,QAAI,KAAK,gBAAgB,mBAAmB,aAAa,KAAK,sBAAsB,CAAC;AAAA,EACvF;AACA,MAAI,KAAK,GAAG,GAAG;AACf,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAkC;AAC1D,SAAO,EAAE,KAAK,KAAK,KAAK,YAAY,KAAK,YAAY,OAAO,KAAK,OAAO,UAAU,CAAC,EAAE;AACvF;AAOO,SAAS,cAAc,MAAoC;AAChE,MAAI,KAAK,SAAS,OAAQ,QAAO;AACjC,QAAM,WAAW,KAAK,SAAS,IAAI,aAAa;AAChD,QAAM,OAAwB,CAAC;AAC/B,aAAW,KAAK,UAAU;AACxB,QAAI,EAAE,SAAS,KAAK,KAAM,MAAK,KAAK,GAAG,EAAE,QAAQ;AAAA,QAC5C,MAAK,KAAK,CAAC;AAAA,EAClB;AACA,MAAI,KAAK,WAAW,EAAG,QAAO,KAAK,CAAC;AACpC,SAAO,EAAE,MAAM,KAAK,MAAM,UAAU,KAAK;AAC3C;AAEA,SAAS,YAAY,MAAwC;AAC3D,MAAI,KAAK,SAAS,OAAQ,QAAO,EAAE,WAAW,CAAC,iBAAiB,IAAI,CAAC,GAAG,QAAQ,KAAK;AAErF,MAAI,KAAK,SAAS,OAAO;AACvB,WAAO,EAAE,WAAW,CAAC,GAAG,QAAQ,KAAK,SAAS,IAAI,WAAW,EAAE;AAAA,EACjE;AAEA,QAAM,SAAS,KAAK,SAAS,OAAO,CAAC,MAAqB,EAAE,SAAS,MAAM;AAC3E,QAAM,SAAS,KAAK,SAAS,OAAO,CAAC,MAAsB,EAAE,SAAS,MAAM;AAC5E,QAAM,YAAY,OAAO,IAAI,gBAAgB;AAC7C,MAAI,OAAO,WAAW,EAAG,QAAO,EAAE,WAAW,QAAQ,KAAK;AAC1D,QAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AAEzB,QAAM,SAAS,MAAM,SAAS,IAAI,CAAC,WAAW,YAAY,cAAc,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;AAChG,SAAO,EAAE,WAAW,OAAO;AAC7B;AAEA,SAAS,mBAAmB,MAA2B;AACrD,MAAI,KAAK,SAAS,OAAQ;AAC1B,MAAI,KAAK,SAAS,SAAS,KAAK,SAAS,WAAW,GAAG;AACrD,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,OAAK,SAAS,QAAQ,kBAAkB;AAC1C;AAOO,SAAS,iBAAiB,OAA2C;AAC1E,QAAM,IAAI,cAAc,KAAK;AAC7B,MAAI,EAAE,SAAS,MAAO,QAAO,EAAE,SAAS,IAAI,WAAW;AACvD,SAAO,CAAC,YAAY,CAAC,CAAC;AACxB;AAEA,SAAS,iBAAiB,GAA+B;AACvD,SAAO,EAAE,MAAM,QAAQ,KAAK,EAAE,KAAK,YAAY,EAAE,YAAY,OAAO,EAAE,MAAM;AAC9E;AAEA,SAAS,gBAAgB,MAAwC;AAC/D,QAAM,SAAS,KAAK,UAAU,IAAI,gBAAgB;AAClD,MAAI,KAAK,UAAU,KAAK,OAAO,SAAS,GAAG;AACzC,UAAM,SAAS,MAAM,GAAG,KAAK,OAAO,IAAI,eAAe,CAAC;AACxD,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,WAAO,MAAM,GAAG,QAAQ,MAAM;AAAA,EAChC;AACA,SAAO,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,MAAM,GAAG,MAAM;AAC1D;AAUO,SAAS,gBAAgB,YAAgD;AAC9E,MAAI,WAAW,WAAW,EAAG,QAAO,cAAc,gBAAgB,WAAW,CAAC,CAAC,CAAC;AAChF,SAAO,cAAc,MAAM,GAAG,WAAW,IAAI,eAAe,CAAC,CAAC;AAChE;AAUO,SAAS,cAAc,SAG5B;AACA,SAAO;AAAA,IACL,OAAO,QAAQ,MAAM,IAAI,CAAC,OAAO;AAAA,MAC/B,MAAM,EAAE;AAAA,MACR,OAAO,gBAAgB,EAAE,UAAU;AAAA,MACnC,KAAK,EAAE,mBAAmB,OAAO;AAAA,IACnC,EAAE;AAAA,IACF,WAAW,QAAQ,iBAAiB,OAAO;AAAA,EAC7C;AACF;AAuBO,IAAM,oBAAN,MAAwB;AAAA,EAAxB;AACL,SAAiB,QAA2B,CAAC;AAC7C,SAAQ,aAAuC;AAAA;AAAA;AAAA,EAG/C,KAAK,OAA2B;AAC9B,QAAI,MAAM,MAAO,oBAAmB,MAAM,KAAK;AAC/C,UAAM,aAA4C,MAAM,QACpD,iBAAiB,MAAM,KAAK,IAC5B,CAAC,EAAE,WAAW,gBAAgB,MAAM,MAAM,MAAM,aAAa,EAAE,CAAC;AACpE,SAAK,MAAM,KAAK;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,oBAAoB,EAAE,KAAK,YAAY,MAAM,GAAG,EAAE;AAAA,MAClD;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,UAAU,KAAyB;AACjC,SAAK,aAAa,YAAY,GAAG;AACjC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAA4B;AAC1B,WAAO;AAAA,MACL,kBAAkB,EAAE,KAAK,KAAK,WAAW;AAAA,MACzC,OAAO,KAAK;AAAA,MACZ,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AACF;AAGO,SAAS,aAAgC;AAC9C,SAAO,IAAI,kBAAkB;AAC/B;;;AChTO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAmEA,IAAM,QAAuC,CAAC,cAAc,UAAU,KAAK;AAUpE,IAAM,yBAA2E;AAAA;AAAA;AAAA;AAAA,EAItF,YAAY;AAAA,IACV,UAAU,CAAC,MAAM;AAAA,IACjB,MAAM,CAAC,CAAC,MAAM,CAAC;AAAA,IACf,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA;AAAA;AAAA,EAGA,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,MAAM,CAAC,CAAC,YAAY,GAAG,CAAC,UAAU,KAAK,CAAC;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA;AAAA;AAAA,EAGA,uBAAuB;AAAA,IACrB,UAAU;AAAA,IACV,MAAM,CAAC,CAAC,YAAY,GAAG,CAAC,UAAU,KAAK,CAAC;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,UAAU;AAAA,IACV,MAAM,CAAC,CAAC,YAAY,GAAG,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC;AAAA,IAC1C,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,mBAAmB;AAAA,IACjB,UAAU;AAAA,IACV,MAAM,CAAC,CAAC,cAAc,QAAQ,GAAG,CAAC,KAAK,CAAC;AAAA,IACxC,SAAS,EAAE,YAAY,GAAG,QAAQ,EAAE;AAAA,IACpC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,UAAU;AAAA,IACV,MAAM,CAAC,CAAC,YAAY,GAAG,CAAC,UAAU,KAAK,CAAC;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAWO,IAAM,iCAAsD;AA4B5D,SAAS,2BACd,cACA,eACqB;AACrB,SAAO,SAAS,YAAY,KAAK,SAAS,aAAa,KAAK;AAC9D;AAGO,SAAS,sBAAsB,OAA4C;AAChF,SAAO,SAAS,KAAK;AACvB;AAEA,SAAS,SAAS,OAA4C;AAC5D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK,EAAE,YAAY;AACzC,SAAQ,uBAA6C,SAAS,OAAO,IAChE,UACD;AACN;AAGO,SAAS,oBAAoB,QAAkD;AACpF,SAAO,uBAAuB,MAAM;AACtC;AASO,SAAS,oBACd,QACA,OACQ;AACR,QAAM,SAAS,OAAO,UAAU,KAAK;AACrC,SAAO,OAAO,WAAW,YAAY,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS;AACxF;AAcO,SAAS,8BAA8B,QAAsC;AAClF,QAAM,QAAQ,OAAO,KAAK,KAAK;AAC/B,MAAI,MAAM,WAAW,OAAO,SAAS,OAAQ,QAAO;AACpD,SAAO,OAAO,SAAS,MAAM,CAAC,UAAU,MAAM,OAAO,CAAC,MAAM,MAAM,KAAK,EAAE,WAAW,CAAC;AACvF;AAeO,IAAM,yBAAyB,CAAC,SAAS,UAAU,YAAY,MAAM;AAOrE,SAAS,2BACd,UACA,QACqB;AACrB,MACE,OAAO,aAAa,YACnB,uBAA6C,SAAS,QAAQ,GAC/D;AACA,WAAO;AAAA,EACT;AACA,SAAO,OAAO,SAAS,UAAU;AACnC;AAGO,IAAM,0BAA0B,CAAC,YAAY,UAAU,WAAW;AAUlE,IAAM,wBAAwB,CAAC,QAAQ,UAAU,QAAQ;AAYzD,IAAM,gCAAgC,CAAC,UAAU,SAAS,SAAS;AAInE,IAAM,6BAA6B,CAAC,MAAM,MAAM,IAAI;AAIpD,IAAM,0BAA0B,CAAC,WAAW,UAAU,UAAU;AAIhE,SAAS,qBACd,MACA,SACQ;AACR,QAAM,OAAO,SAAS,OAAO,KAAK,SAAS,OAAO,KAAK;AAGvD,SAAO,YAAY,YAAY,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI;AAC1D;AAGO,SAAS,0BAA0B,QAAsC;AAC9E,SAAO,WAAW,YAAY,MAAM,WAAW,aAAa,MAAM;AACpE;AAYO,IAAM,0BAA0B,CAAC,QAAQ,cAAc,QAAQ,UAAU;;;AC7UzE,IAAM,qBAAqB;AAI3B,IAAM,wBAAwB;AAI9B,IAAM,qBAAqB;AAI3B,IAAM,mBAAmB;AAIzB,SAAS,gBAAgB,MAAiC;AAC/D,SAAO,SAAS,OAAO,KAAK,SAAS,OAAO,KAAK;AACnD;AAGO,SAAS,qBAAqB,QAAiC;AACpE,SAAO,WAAW,YAAY,MAAM,WAAW,aAAa,MAAM;AACpE;AASO,IAAM,gBAAgB,CAAC,QAAQ,UAAU,QAAQ,OAAO;AAIxD,SAAS,mBAAmB,OAAoB,MAA4C;AACjG,MAAI,UAAU,OAAQ,QAAO,OAAO,UAAU;AAC9C,SAAO;AACT;AAGO,IAAM,sBAAsB,CAAC,UAAU,WAAW;AAOlD,IAAM,0BAA0B,CAAC,SAAS,UAAU;AAIpD,IAAM,kBAAkB,CAAC,WAAW,eAAe,UAAU;AAO7D,SAAS,oBAAoB,SAGlC;AACA,MAAI,YAAY,UAAW,QAAO,EAAE,aAAa,OAAO,gBAAgB,MAAM;AAC9E,MAAI,YAAY,WAAY,QAAO,EAAE,aAAa,OAAO,gBAAgB,OAAO;AAChF,SAAO,EAAE,aAAa,OAAO,gBAAgB,OAAO;AACtD;AAKO,IAAM,sBAAsB,CAAC,SAAS,SAAS;AAO/C,IAAM,sBAAsB,CAAC,SAAS,MAAM;AAW5C,IAAM,sBAAsB,CAAC,SAAS,MAAM;AAO5C,IAAM,0BAA0B,CAAC,QAAQ,SAAS,SAAS,eAAe;AAG1E,SAAS,2BACd,OACA,MACqC;AACrC,MAAI,UAAU,OAAQ,QAAO,OAAO,UAAU;AAC9C,SAAO;AACT;AAGO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOO,IAAM,2BAA2B,CAAC,QAAQ,WAAW,SAAS,OAAO;AAGrE,SAAS,4BACd,OACA,MAC+B;AAC/B,MAAI,UAAU,OAAQ,QAAO,OAAO,UAAU;AAC9C,SAAO;AACT;AAGO,IAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAuBO,IAAM,oBAAoB,CAAC,aAAa,SAAS,gBAAgB,cAAc;AAQ/E,SAAS,gBAAgB,QAAyC;AACvE,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE,SAAS,WAAW,QAAQ,aAAa;AAAA,IACpD,KAAK;AACH,aAAO,EAAE,SAAS,QAAQ,QAAQ,UAAU;AAAA,IAC9C,KAAK;AACH,aAAO,EAAE,SAAS,QAAQ,QAAQ,UAAU;AAAA,IAC9C;AACE,aAAO,EAAE,SAAS,WAAW,QAAQ,YAAY;AAAA,EACrD;AACF;AAQO,IAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,uBAA4F;AAAA,EAChG,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAGO,SAAS,iBAAiB,QAAkD;AACjF,SAAO,WAAW,SAAS,YAAY,qBAAqB,MAAM;AACpE;AAEA,SAAS,OAAO,KAA8C;AAC5D,QAAM,MAAM,IAAI,KAAK,EAAE,QAAQ,MAAM,EAAE;AACvC,QAAM,OAAO,IAAI,WAAW,IAAI,IAAI,QAAQ,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI;AAClE,MAAI,CAAC,iBAAiB,KAAK,IAAI,EAAG,QAAO;AACzC,QAAM,IAAI,OAAO,SAAS,MAAM,EAAE;AAClC,SAAO,CAAE,KAAK,KAAM,KAAM,KAAK,IAAK,KAAK,IAAI,GAAG;AAClD;AAGA,SAAS,MAAM,CAAC,GAAG,GAAG,CAAC,GAAuD;AAC5E,QAAM,MAAM,CAAC,MAAc;AACzB,UAAM,IAAI,IAAI;AACd,WAAO,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,UAAU;AAAA,EAC7D;AACA,QAAM,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5C,QAAM,IAAI,KAAK,KAAK,eAAe,KAAK,eAAe,KAAK,eAAe,EAAE;AAC7E,QAAM,IAAI,KAAK,KAAK,eAAe,KAAK,eAAe,KAAK,eAAe,EAAE;AAC7E,QAAMC,KAAI,KAAK,KAAK,eAAe,KAAK,eAAe,KAAK,eAAe,EAAE;AAC7E,SAAO;AAAA,IACL,eAAe,IAAI,cAAc,IAAI,eAAeA;AAAA,IACpD,eAAe,IAAI,cAAc,IAAI,eAAeA;AAAA,IACpD,eAAe,IAAI,eAAe,IAAI,cAAcA;AAAA,EACtD;AACF;AAMO,SAAS,kBAAkB,KAA+C;AAC/E,QAAM,MAAM,OAAO,GAAG;AACtB,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG;AAC3B,MAAI,KAAK,MAAM,GAAG,CAAC,IAAI,KAAM,QAAO;AACpC,MAAI,OAAkD;AACtD,MAAI,eAAe,OAAO;AAC1B,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,oBAAoB,GAG3D;AACH,UAAM,YAAY,OAAO,MAAM;AAC/B,QAAI,CAAC,UAAW;AAChB,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,MAAM,SAAS;AAGpC,UAAM,WAAW,KAAK,OAAO,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,EAAE;AAC1D,QAAI,WAAW,cAAc;AAC3B,qBAAe;AACf,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,kBACd,QACA,YACkC;AAClC,SAAO,WAAW,SAAS,kBAAkB,UAAU,IAAI;AAC7D;AAGO,IAAM,oBAAoB,CAAC,SAAS,UAAU;AAO9C,IAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,uBAAuB,CAAC,WAAW,MAAM;AAQ/C,IAAM,aAAa,CAAC,YAAY,UAAU,SAAS,UAAU,OAAO;AAOpE,IAAM,eAAe,CAAC,QAAQ,MAAM;AAQpC,IAAM,kBAAkB,CAAC,cAAc,SAAS,MAAM;AAwBtD,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,qBAA6E;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxF,UAAU;AAAA,IACR,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA,EAGA,OAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,MAAM;AAAA,IACJ,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,OAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,OAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,MAAM;AAAA,IACJ,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AAAA;AAAA,EAEA,SAAS;AAAA,IACP,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB;AACF;AAGO,SAAS,cAAc,UAA6C;AACzE,QAAM,OAAO,OAAO,KAAK,mBAAmB,KAAK;AACjD,SACE,WAAW;AAAA,IAAK,CAAC,SACf,KAAK,MAAM,CAAC,QAAQ,mBAAmB,IAAI,EAAE,GAAG,MAAM,SAAS,GAAG,CAAC;AAAA,EACrE,KAAK;AAET;;;AC9RO,SAAS,oBACd,WACA,OACA,UACS;AACT,MAAI,cAAc,WAAY,QAAO;AACrC,SAAO,EAAE,UAAU,aAAa,aAAa,iBAAiB,aAAa;AAC7E;AAwCO,SAAS,oBACd,UAIA,YACA,kBACqB;AACrB,QAAM,OAAO,aAAa,SAAS,iBAAiB,SAAS;AAC7D,QAAM,QAAQ;AAAA,IACZ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAGA,MAAI,CAAC,iBAAkB,QAAO,EAAE,OAAO,UAAU,QAAQ,MAAM,MAAM;AAErE,QAAM,UAA0F;AAAA,IAC9F,QAAQ,CAAC,UAAU,IAAI;AAAA,IACvB,SAAS,CAAC,WAAW,IAAI;AAAA,IACzB,mBAAmB,CAAC,UAAU,SAAS;AAAA,IACvC,mBAAmB,CAAC,WAAW,QAAQ;AAAA,EACzC;AACA,QAAM,CAAC,OAAO,MAAM,IAAI,QAAQ,IAAI;AAKpC,QAAM,eACJ,SAAS,mBAAmB,aAC3B,SAAS,sBAAsB,iBAAiB,SAAS,sBAAsB;AAElF,SAAO,EAAE,OAAO,QAAQ,eAAe,OAAO,QAAQ,MAAM;AAC9D;AAUO,SAAS,cAAc,OAAuB;AACnD,QAAM,UAAU,cAAc,OAAO,SAAS;AAC9C,QAAM,UAAU,cAAc,OAAO,SAAS;AAC9C,MAAI,YAAY,QAAQ,YAAY,KAAM,QAAO;AACjD,SAAO,WAAW,UAAU,YAAY;AAC1C;AAGA,IAAM,sBAAqD;AAAA,EACzD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGA,IAAM,gBAA+C;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGA,IAAM,mBAAmD;AAAA,EACvD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAGA,IAAM,yBAA+D;AAAA,EACnE,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AACT;AAGA,IAAM,wBAAyD;AAAA,EAC7D,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR;AAUO,IAAM,sBAAoD;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,2BAA6D;AAAA,EACxE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,mBAA8C;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,0BAA2D;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,0BAA2D;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,kBAA4C,CAAC,MAAM,MAAM,IAAI;AAYnE,SAAS,0BAA0B,OAAgC;AACxE,SAAO,UAAU,WAAW,UAAU,aAAa,UAAU;AAC/D;AACO,IAAM,mBAA8C,CAAC,QAAQ,WAAW,QAAQ;AAChF,IAAM,oBAAgD,CAAC,WAAW,UAAU,MAAM;AAClF,IAAM,kBAA4C,CAAC,UAAU,aAAa,MAAM;AAChF,IAAM,wBAAuD,CAAC,UAAU,UAAU;AAClF,IAAM,yBAAyD;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaO,IAAM,uBAAkD,CAAC,IAAI;AAY7D,SAAS,kBAAkB,QAA+B;AAC/D,QAAM,OAAO,OAAO,UAAU,EAAE,EAC7B,YAAY,EACZ,MAAM,GAAG,EAAE,CAAC;AACf,SAAQ,qBAA2C,SAAS,IAAI,IAAI,QAAQ;AAC9E;AAUO,IAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,SAAS,oBACd,OACuC;AACvC,SAAO,GAAG,KAAK;AACjB;AAaO,SAAS,aACd,UACA,OACA,QACQ;AACR,QAAM,aAAa,eAAe,SAAS,oBAAoB,KAAK,CAAC,GAAG,MAAM;AAC9E,SAAO,cAAc,SAAS,KAAK;AACrC;AAaO,SAAS,iBACd,UACA,YACA,QACe;AACf,SAAO;AAAA,IACL,aAAa,SAAS,2BAA2B,SAAS;AAAA,IAC1D;AAAA,EACF;AACF;AA+BO,IAAM,kBAA4C,CAAC,WAAW,SAAS;AAOvE,IAAM,sBAAsB;AAG5B,IAAM,0BAA0B;AAGhC,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,uBAAmC;AAYzC,IAAM,oBAAqE;AAAA,EAChF,MAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,sDAAsD,qBAAqB;AAAA,EACpF,OAAO,CAAC,yCAAyC,iBAAiB;AAAA,EAClE,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS,CAAC,4BAA4B,YAAY;AAAA,EAClD,MAAM,CAAC,2EAA2E;AAAA,EAClF,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK,CAAC,wBAAwB,iDAAiD;AAAA,EAC/E,OAAO,CAAC,+EAA+E;AAAA,EACvF,MAAM,CAAC,+DAA+D,yBAAyB;AAAA,EAC/F,OAAO,CAAC,yCAAyC,aAAa;AAAA,EAC9D,MAAM,CAAC,qBAAqB,sCAAsC,UAAU;AAC9E;AAEO,SAAS,aAAa,OAAqC;AAChE,SAAO,OAAO,UAAU,YAAa,aAAmC,SAAS,KAAK;AACxF;AA6XA,IAAM,cAA0C;AAAA,EAC9C,OAAO;AAAA,EACP,QACE;AAAA,EACF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AAAA,EACV,aAAa;AAAA,EACb,kBAAkB;AACpB;AAEA,IAAM,YAA0C;AAAA,EAC9C,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,sBAAkD;AAAA,EACtD,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AACR;AAEA,IAAM,cAA4C;AAAA,EAChD,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,eAA6C;AAAA,EACjD,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,YAAuC;AAAA,EAC3C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,IAAM,aAAwC;AAAA,EAC5C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,UAAU,QAA4B;AACpD,SAAO,YAAY,MAAM,KAAK,YAAY;AAC5C;AAEO,SAAS,YAAY,QAA8B;AACxD,SAAO,UAAU,MAAM,KAAK,UAAU;AACxC;AAEO,SAAS,gBAAgB,QAA4B;AAC1D,SAAO,oBAAoB,MAAM,KAAK;AACxC;AAEO,SAAS,gBAAgB,OAA6B;AAC3D,SAAO,YAAY,KAAK,KAAK,YAAY;AAC3C;AAEO,SAAS,iBAAiB,OAA6B;AAC5D,SAAO,aAAa,KAAK,KAAK,aAAa;AAC7C;AAEO,SAAS,cAAc,MAAyB;AACrD,SAAO,UAAU,IAAI,KAAK,UAAU;AACtC;AAEO,SAAS,eAAe,MAAyB;AACtD,SAAO,WAAW,IAAI,KAAK,WAAW;AACxC;AAUO,SAAS,oBAAoB,GAAqB,QAAsC;AAC7F,SAAO;AAAA,IACL,SAAS,EAAE;AAAA,IACX,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,QAAQ,EAAE;AAAA,IACV,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,EACZ;AACF;AAEO,SAAS,eAAe,MAAgD;AAC7E,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,IAAI,IAAI,QAAQ,EAAE;AAAA,IAC7B,KAAK;AACH,aAAO,EAAE,IAAI,IAAI,QAAQ,GAAG;AAAA,IAC9B,KAAK;AAAA,IACL;AACE,aAAO,EAAE,IAAI,IAAI,QAAQ,GAAG;AAAA,EAChC;AACF;AAEA,IAAM,SAAS;AAER,SAAS,WAAW,OAAwB;AACjD,SAAO,OAAO,KAAK,MAAM,KAAK,CAAC;AACjC;AAaA,IAAM,aAAa;AAUnB,IAAM,iBAAiB;AAGvB,SAAS,iBAAiB,OAAe,SAAkD;AACzF,QAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK,CAAC;AACvC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,MAAM,CAAC;AACtB,QAAM,OACJ,OAAO,WAAW,IACd,OACG,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,IAAI,CAAC,EAChB,KAAK,EAAE,IACV;AACN,SAAO;AAAA,IACL,SAAS,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC7B,SAAS,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC7B,SAAS,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EAC/B;AACF;AAGA,SAAS,kBAAkB,CAAC,GAAG,GAAG,CAAC,GAAqC;AACtE,QAAM,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,YAAY;AAC9C,UAAM,IAAI,UAAU;AACpB,WAAO,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,UAAU;AAAA,EAC7D,CAAC;AACD,SAAO,SAAS,KAAK,SAAS,KAAK,SAAS;AAC9C;AAGO,IAAM,eAAe;AAMrB,IAAM,aAAa;AAyBnB,SAAS,cAAc,GAAW,GAA0B;AACjE,QAAM,QAAQ,iBAAiB,GAAG,UAAU;AAC5C,QAAM,SAAS,iBAAiB,GAAG,UAAU;AAC7C,MAAI,CAAC,SAAS,CAAC,OAAQ,QAAO;AAC9B,QAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,KAAK,GAAG,kBAAkB,MAAM,CAAC;AACnE,QAAM,UAAU,KAAK,IAAI,GAAG,CAAC;AAC7B,QAAM,SAAS,KAAK,IAAI,GAAG,CAAC;AAC5B,UAAQ,UAAU,SAAS,SAAS;AACtC;AAwBO,SAAS,cAAc,OAAwB;AAKpD,QAAM,WAAW,iBAAiB,OAAO,cAAc;AACvD,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI;AAClB,QAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO;AAC7C,SAAO,OAAO;AAChB;AAYA,IAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,YAAY;AACd;AAEO,IAAM,iBAA+B;AAAA,EAC1C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AACF;AAKO,IAAM,sBAAoC;AAAA,EAC/C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AACF;AAgBO,IAAM,kBAA6C;AAAA,EACxD;AAAA,IACE,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,mBAAmB;AAAA,MACjB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,mBAAmB;AAAA,MACjB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AAAA,EACF;AACF;AAGO,SAAS,iBAAmC;AACjD,SAAO,gBAAgB,IAAI,WAAW;AACxC;AAEO,SAAS,YAAY,QAAwC;AAClE,SAAO,EAAE,GAAG,QAAQ,mBAAmB,EAAE,GAAG,OAAO,kBAAkB,EAAE;AACzE;AAGA,SAAS,YAAY,KAA8C;AACjE,QAAM,MAAM,oBAAoB,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC;AACpD,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO;AAAA,IACL,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC5B,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC5B,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EAC9B;AACF;AAiBA,SAAS,4BAA4B,WAAmB,MAAc,QAAyB;AAC7F,QAAM,UAAU,YAAY,SAAS;AACrC,QAAM,KAAK,YAAY,IAAI;AAC3B,QAAM,OAAO,YAAY,MAAM;AAC/B,MAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAM,QAAO;AACrC,QAAM,QAAQ,CAAC,SAAiB,IAAY,UAC1C,KAAK,MAAM,WAAW,KAAK,WAAW,KAAK;AAC7C,SAAO,QAAQ,MAAM,CAAC,GAAG,MAAM;AAC7B,aAAS,UAAU,GAAG,WAAW,KAAK,WAAW,GAAG;AAClD,UAAI,MAAM,SAAS,GAAG,IAAI,MAAM,GAAG,CAAC,KAAK,MAAM,SAAS,GAAG,GAAG,MAAM,KAAK,CAAC,EAAG,QAAO;AAAA,IACtF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAaO,SAAS,kBAAkB,QAAwC;AACxE,MAAI,OAAO,WAAW,eAAe,OAAQ,QAAO;AACpD,QAAM,cAAc,OAAO;AAAA,IACzB,CAAC,OAAO,MAAM,MAAM,OAAO,eAAe,CAAC,GAAG,MAAM,MAAM,UAAU,eAAe,CAAC,GAAG;AAAA,EACzF;AACA,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,YAAY,CAAC,QACjB,IACG,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,eAAe,EAAE,EAAE,KAAK,GAAG,EAAE,YAAY,CAAC,EACxF,KAAK,GAAG;AACb,QAAM,OAAO,UAAU,MAAM;AAC7B,MAAI,SAAS,UAAU,cAAc,KAAK,SAAS,UAAU,mBAAmB,EAAG,QAAO;AAG1F,QAAM,CAAC,KAAK,IAAI;AAChB,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,SAAS,CAAC,OAAQ,QAAO;AAC9B,QAAM,OAAO,CAAC,GAAkB,OAC7B,KAAK,IAAI,YAAY,MAAM,EAAE,YAAY;AAC5C,SACE,OAAO;AAAA,IACL,CAAC,MACC,KAAK,EAAE,WAAW,MAAM,SAAS,KACjC,KAAK,EAAE,iBAAiB,MAAM,eAAe,KAC7C,KAAK,EAAE,aAAa,MAAM;AAAA,EAC9B,KAAK,4BAA4B,MAAM,WAAW,MAAM,iBAAiB,MAAM;AAEnF;AAqBO,SAAS,wBACd,aACA,cAC0D;AAC1D,MAAI,iBAAiB,MAAM;AACzB,WAAO,EAAE,aAAa,eAAe,CAAC,GAAG,SAAS,aAAa;AAAA,EACjE;AACA,MAAI,gBAAgB,QAAQ,kBAAkB,WAAW,GAAG;AAC1D,WAAO,EAAE,aAAa,CAAC,GAAG,SAAS,eAAe,EAAE;AAAA,EACtD;AACA,SAAO,EAAE,aAAa,aAAa,SAAS,CAAC,EAAE;AACjD;AAQA,IAAM,2BAA2B;AACjC,IAAM,4BAA4B;AAG3B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAG1B,IAAM,2BAA2B;AAejC,IAAM,kBAAgD;AAAA,EAC3D,EAAE,IAAI,QAAQ,UAAU,iBAAiB,OAAO,GAAG;AAAA,EACnD,EAAE,IAAI,UAAU,UAAU,oBAAoB,OAAO,GAAG;AAAA,EACxD,EAAE,IAAI,QAAQ,UAAU,iBAAiB,OAAO,GAAG;AAAA,EACnD,EAAE,IAAI,iBAAiB,UAAU,0BAA0B,OAAO,GAAG;AAAA,EACrE,EAAE,IAAI,iBAAiB,UAAU,yBAAyB,OAAO,GAAG;AAAA,EACpE,EAAE,IAAI,UAAU,UAAU,2BAA2B,OAAO,GAAG;AAAA,EAC/D,EAAE,IAAI,cAAc,UAAU,sBAAsB,OAAO,GAAG;AAAA,EAC9D,EAAE,IAAI,WAAW,UAAU,qBAAqB,OAAO,GAAG;AAAA,EAC1D,EAAE,IAAI,aAAa,UAAU,sBAAsB,OAAO,GAAG;AAAA,EAC7D,EAAE,IAAI,UAAU,UAAU,oBAAoB,OAAO,GAAG;AAAA,EACxD,EAAE,IAAI,QAAQ,UAAU,iBAAiB,OAAO,GAAG;AACrD;AAGO,IAAM,kBAAoD;AAAA,EAC/D,eAAe;AACjB;AAGO,IAAM,wBAAwB;AAQ9B,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,gBAAgB,QAAQ,KAAK;AACtC;AAEO,SAAS,4BAAgD;AAC9D,QAAM,QAA4B,CAAC;AACnC,aAAW,WAAW,gBAAiB,OAAM,QAAQ,EAAE,IAAI,QAAQ;AACnE,SAAO;AACT;AAOO,SAAS,kBAAkB,KAA6B;AAC7D,MAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,UAAU,GAAG,EAAG,QAAO;AAC9D,MAAI,MAAM,qBAAqB,MAAM,kBAAmB,QAAO;AAC/D,SAAO;AACT;AAQO,SAAS,yBAAyB,KAA6C;AACpF,QAAM,QAAQ,0BAA0B;AACxC,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO;AACnF,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC5E,UAAM,QAAQ,kBAAkB,KAAK;AACrC,QAAI,UAAU,KAAM;AACpB,UAAM,mBAAmB,GAAG,CAAC,IAAI;AAAA,EACnC;AACA,SAAO;AACT;AAEO,SAAS,yBAAyB,OAAmC;AAC1E,SAAO,KAAK,UAAU,KAAK;AAC7B;AAMO,SAAS,0BAA0B,KAA8C;AACtF,MAAI,QAAQ,OAAW,QAAO,CAAC;AAC/B,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpF,QAAM,SAA8B,CAAC;AACrC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,MAAiC,GAAG;AACnF,QAAI,CAAC,WAAW,aAAa,QAAQ,OAAO,aAAa,YAAY,MAAM,QAAQ,QAAQ,GAAG;AAC5F;AAAA,IACF;AACA,UAAM,OAA+B,CAAC;AACtC,eAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,QAAmC,GAAG;AAChF,UAAI,OAAO,SAAS,SAAU;AAC9B,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,QAAS;AACd,WAAK,MAAM,IAAI,QAAQ,MAAM,GAAG,wBAAwB;AAAA,IAC1D;AACA,QAAI,OAAO,KAAK,IAAI,EAAE,SAAS,EAAG,QAAO,mBAAmB,OAAO,CAAC,IAAI;AAAA,EAC1E;AACA,SAAO;AACT;AAMO,SAAS,0BAA0B,QAA4C;AACpF,QAAM,UAA+B,CAAC;AACtC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,UAAM,OAA+B,CAAC;AACtC,eAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACrD,YAAM,WAAW,QAAQ,IAAI,KAAK;AAClC,UAAI,QAAS,MAAK,MAAM,IAAI,QAAQ,MAAM,GAAG,wBAAwB;AAAA,IACvE;AACA,QAAI,OAAO,KAAK,IAAI,EAAE,SAAS,EAAG,SAAQ,OAAO,IAAI;AAAA,EACvD;AACA,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,KAAK,UAAU,OAAO,IAAI;AACrE;AAEA,SAAS,sBAAsB,WAA2B;AACxD,QAAM,QAAQ,gBAAgB,UAAU,CAAC,YAAY,QAAQ,OAAO,SAAS;AAC7E,SAAO,UAAU,KAAK,gBAAgB,SAAS;AACjD;AAEO,SAAS,eAAe,OAA2B,UAA0B;AAClF,SAAO,MAAM,mBAAmB,QAAQ,CAAC,KAAK;AAChD;AAQO,SAAS,gBAAgB,OAA6D;AAC3F,SAAO,CAAC,GAAG,MAAM;AACf,UAAM,OAAO,mBAAmB,CAAC;AACjC,UAAM,QAAQ,mBAAmB,CAAC;AAClC,UAAM,UAAU,eAAe,OAAO,IAAI,IAAI,eAAe,OAAO,KAAK;AACzE,QAAI,YAAY,EAAG,QAAO;AAC1B,UAAM,cAAc,sBAAsB,IAAI,IAAI,sBAAsB,KAAK;AAC7E,QAAI,gBAAgB,EAAG,QAAO;AAC9B,WAAO,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;AAAA,EAChD;AACF;AAUO,SAAS,aACd,QACA,UACA,QACA,UACA,WACQ;AACR,QAAM,KAAK,mBAAmB,QAAQ;AAGtC,MAAI,MAAM,QAAQ;AAChB,UAAM,WAAW,OAAO,EAAE;AAS1B,UAAM,UAAU,eAAe,UAAU,MAAM,GAAG,KAAK;AACvD,QAAI,QAAS,QAAO;AACpB,eAAW,SAAS,OAAO,OAAO,QAAQ,GAAG;AAC3C,YAAM,MAAM,MAAM,KAAK;AACvB,UAAI,IAAK,QAAO;AAAA,IAClB;AAAA,EACF;AACA,MAAI,UAAU;AACZ,UAAM,aAAa,UAAU,QAAQ;AACrC,QAAI,WAAY,QAAO;AAAA,EACzB;AACA,SAAO;AACT;AAGA,SAAS,uBAAuB,KAAkC;AAChE,MAAI,OAAO,QAAQ,SAAU,QAAO,yBAAyB,GAAG;AAChE,MAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAG;AAClE,WAAO,yBAAyB,KAAK,UAAU,GAAG,CAAC;AAAA,EACrD;AACA,SAAO,0BAA0B;AACnC;AAGA,SAAS,wBAAwB,KAAmC;AAClE,MAAI,OAAO,QAAQ,SAAU,QAAO,0BAA0B,GAAG;AACjE,MAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAG;AAClE,WAAO,0BAA0B,KAAK,UAAU,GAAG,CAAC;AAAA,EACtD;AACA,SAAO,CAAC;AACV;AAGO,SAAS,qBAAqB,UAAsC;AACzE,QAAM,KAAK,mBAAmB,QAAQ;AACtC,SAAO,gBAAgB,KAAK,CAAC,YAAY,QAAQ,OAAO,EAAE,GAAG;AAC/D;AAEA,IAAM,wBAQF;AAAA,EACF,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA;AAAA;AAAA;AAAA,EAIT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EAEV,YAAY;AAAA,EACZ,eAAe;AAAA,EAEf,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,aAAa;AAAA,EACb,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,YAAY;AAAA;AAAA;AAAA;AAAA,EAKZ,eAAe;AAAA,EACf,mBAAmB;AAAA;AAAA;AAAA,EAGnB,uBAAuB;AAAA;AAAA,EAEvB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA;AAAA;AAAA,EAGhB,2BAA2B,CAAC;AAAA,EAC5B,0BAA0B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3B,gBAAgB;AAAA,EAChB,eAAe;AAAA,EAEf,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAKjB,YAAY;AAAA,EACZ,wBAAwB,CAAC;AAAA,EACzB,gBAAgB;AAAA,EAChB,4BAA4B,CAAC;AAAA,EAC7B,kBAAkB;AAAA,EAClB,8BAA8B,CAAC;AAAA,EAC/B,YAAY;AAAA,EACZ,wBAAwB,CAAC;AAAA,EACzB,cAAc;AAAA,EAEd,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUf,qBAAqB;AAAA;AAAA,EAErB,mBAAmB;AAAA;AAAA,EAEnB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA;AAAA;AAAA,EAIvB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,4BAA4B;AAAA,EAC5B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,eAAe;AAAA,EAEf,WAAW;AACb;AAEO,IAAM,mBAAqC;AAAA,EAChD,GAAG;AAAA,EACH,GAAG;AAAA;AAAA;AAAA;AAAA,EAIH,aAAa,CAAC;AAAA,EACd,SAAS,eAAe;AAAA,EACxB,cAAc,CAAC;AAAA,EACf,oBAAoB,0BAA0B;AAAA,EAC9C,qBAAqB,CAAC;AACxB;AAYO,IAAM,wBAA0C;AAAA,EACrD,GAAG;AAAA,EACH,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,cAAc;AAAA;AAAA;AAAA;AAAA,EAId,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,aAAa,CAAC;AAAA,EACd,SAAS,eAAe;AAAA,EACxB,cAAc,CAAC;AAAA,EACf,oBAAoB,0BAA0B;AAAA,EAC9C,qBAAqB,CAAC;AACxB;AAGO,SAAS,kBAAoC;AAClD,SAAO,cAAc,gBAAgB;AACvC;AAMO,SAAS,cAAc,GAAuC;AACnE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,aAAa,EAAE,YAAY,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE;AAAA,IACxD,SAAS,EAAE,QAAQ,IAAI,WAAW;AAAA,IAClC,cAAc,EAAE,aAAa,IAAI,gBAAgB;AAAA,IACjD,oBAAoB,EAAE,GAAG,EAAE,mBAAmB;AAAA,IAC9C,qBAAqB,OAAO;AAAA,MAC1B,OAAO,QAAQ,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,CAAC;AAAA,IACrF;AAAA;AAAA;AAAA;AAAA,IAIA,2BAA2B,EAAE,GAAG,EAAE,0BAA0B;AAAA,IAC5D,0BAA0B,EAAE,GAAG,EAAE,yBAAyB;AAAA,IAC1D,wBAAwB,EAAE,GAAG,EAAE,uBAAuB;AAAA,IACtD,4BAA4B,EAAE,GAAG,EAAE,2BAA2B;AAAA,IAC9D,8BAA8B,EAAE,GAAG,EAAE,6BAA6B;AAAA,IAClE,wBAAwB,EAAE,GAAG,EAAE,uBAAuB;AAAA,EACxD;AACF;AAEO,SAAS,iBAAiB,GAA6C;AAC5E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,mBAAmB,EAAE,GAAG,EAAE,kBAAkB;AAAA,IAC5C,yBAAyB,EAAE,GAAG,EAAE,wBAAwB;AAAA,IACxD,sBAAsB,EAAE,GAAG,EAAE,qBAAqB;AAAA,IAClD,SAAS,EAAE,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,mBAAmB,EAAE,GAAG,EAAE,kBAAkB,EAAE,EAAE;AAAA,IACvF,YAAY;AAAA,MACV,GAAG,EAAE;AAAA,MACL,YAAY,EAAE,WAAW,WAAW,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,IAC3D;AAAA,EACF;AACF;AAOO,IAAM,wBAAwB;AAqB9B,SAAS,kBAAkB,KAA+C;AAC/E,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,SAAS,sBAAuB,QAAO;AAEnD,MAAI,MAAM;AACV,QAAM,IAAI,QAAQ,cAAc,WAAW;AAC3C,QAAM,IAAI,QAAQ,sBAAsB,EAAE;AAC1C,QAAM,IAAI,QAAQ,qBAAqB,mBAAmB;AAC1D,QAAM,IAAI,QAAQ,6BAA6B,mBAAmB;AAClE,QAAM,IAAI,QAAQ,sBAAsB,qBAAqB;AAC7D,QAAM,IAAI,QAAQ,oCAAoC,cAAc;AACpE,SAAO;AACT;AAuCA,IAAM,qBAAqB;AAE3B,IAAM,oBAA2C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,YAAqC,CAAC,UAAU,SAAS,UAAU,SAAS,MAAM;AACxF,IAAM,iBAA2C,CAAC,UAAU,SAAS,UAAU,OAAO;AAEtF,SAAS,SAA2B,OAAgB,SAAuB,UAAgB;AACzF,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAQ,QAA8B,SAAS,KAAK,IAAK,QAAc;AACzE;AAUA,SAAS,gBAAkC,OAAgB,SAA+B;AACxF,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAQ,QAA8B,SAAS,KAAK,IAAK,QAAc;AACzE;AAEA,SAAS,UAAU,OAAgB,UAA4B;AAC7D,MAAI,OAAO,UAAU,UAAW,QAAO;AACvC,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,UAAU,QAAS,QAAO;AAC9B,SAAO;AACT;AAEA,SAAS,EAAE,OAA0C;AACnD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAQO,SAAS,aAAa,KAA8C;AACzE,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AACnC,WAAO,OACJ,OAAO,CAAC,MAAoC,CAAC,CAAC,KAAK,OAAO,MAAM,QAAQ,EACxE,IAAI,CAAC,GAAG,OAAO;AAAA,MACd,IAAI,OAAO,EAAE,IAAI,MAAM,YAAY,EAAE,IAAI,IAAK,EAAE,IAAI,IAAe,SAAS,CAAC;AAAA,MAC7E,OAAO,OAAO,EAAE,OAAO,MAAM,WAAY,EAAE,OAAO,IAAe;AAAA,MACjE,WAAW,OAAO,EAAE,WAAW,MAAM,WAAY,EAAE,WAAW,IAAe;AAAA,MAC7E,iBACE,OAAO,EAAE,iBAAiB,MAAM,WAAY,EAAE,iBAAiB,IAAe;AAAA,MAChF,aACE,OAAO,EAAE,aAAa,MAAM,YAAY,EAAE,aAAa,IAClD,EAAE,aAAa,IAChB;AAAA,IACR,EAAE,EACD,OAAO,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,QAA8B;AACzD,SAAO,KAAK;AAAA,IACV,OAAO,IAAI,CAAC,OAAO;AAAA,MACjB,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,WAAW,EAAE;AAAA,MACb,iBAAiB,EAAE;AAAA,MACnB,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,IACxD,EAAE;AAAA,EACJ;AACF;AAKA,IAAM,uBAAuB;AAE7B,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,KAAK,KAAK,EAAE,MAAM,GAAG,uBAAuB,EAAE,KAAK,EAAE;AACpE;AAkBA,SAAS,iBAAiB,MAA4C;AACpE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,aAAa,oBAAI,IAA2B;AAClD,QAAM,MAAwB,CAAC;AAE/B,OAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,QAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG;AAC3D,UAAM,MAAM;AAEZ,UAAM,QAAQ,OAAO,IAAI,OAAO,MAAM,WAAW,cAAc,IAAI,OAAO,CAAC,IAAI;AAC/E,UAAM,oBAA6C,CAAC;AACpD,eAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,kBAAkB,IAAI,mBAAmB,CAAC,CAAC,GAAG;AACxF,wBAAkB,MAAM,IAAI,cAAc,IAAI;AAAA,IAChD;AACA,QAAI,MAAM,KAAK,EAAE,WAAW,KAAK,OAAO,KAAK,iBAAiB,EAAE,WAAW,EAAG;AAE9E,UAAM,UAAU,SAAwB,IAAI,SAAS,GAAG,iBAAiB,SAAS;AAClF,UAAM,OAAO,WAAW,IAAI,OAAO,KAAK;AACxC,QAAI,QAAQ,oBAAqB;AACjC,eAAW,IAAI,SAAS,OAAO,CAAC;AAEhC,QAAI,KACF,OAAO,IAAI,IAAI,MAAM,WACjB,IAAI,IAAI,EAAE,QAAQ,mBAAmB,EAAE,EAAE,MAAM,GAAG,oBAAoB,IACtE;AACN,QAAI,CAAC,MAAM,KAAK,IAAI,EAAE,EAAG,MAAK,UAAU,QAAQ,CAAC;AACjD,WAAO,KAAK,IAAI,EAAE,EAAG,MAAK,GAAG,EAAE;AAC/B,SAAK,IAAI,EAAE;AAEX,QAAI,KAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA,MAAM,aAAa,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,IAAI;AAAA,MAChD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AASO,SAAS,cAAc,KAAkD;AAC9E,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO,MAAM,QAAQ,MAAM,IAAI,iBAAiB,MAAM,IAAI;AAC5D;AAGO,SAAS,kBAAkB,KAAuC;AACvE,MAAI,OAAO,QAAQ,SAAU,QAAO,cAAc,GAAG;AACrD,SAAO,MAAM,QAAQ,GAAG,IAAI,iBAAiB,GAAG,IAAI;AACtD;AAOO,SAAS,cAAc,SAA4C;AACxE,SAAO,KAAK;AAAA,IACV,QAAQ,IAAI,CAAC,MAAM;AACjB,YAAM,eAAe,OAAO,QAAQ,EAAE,iBAAiB,EAAE;AAAA,QACvD,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,KAAK,EAAE,SAAS;AAAA,MACrC;AACA,aAAO;AAAA,QACL,IAAI,EAAE;AAAA,QACN,SAAS,EAAE;AAAA,QACX,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,QACT,GAAI,aAAa,SAAS,IAAI,EAAE,mBAAmB,OAAO,YAAY,YAAY,EAAE,IAAI,CAAC;AAAA,MAC3F;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAYO,SAAS,WAAW,QAAwB,QAAyB;AAC1E,SAAO,eAAe,OAAO,mBAAmB,MAAM,KAAK,OAAO;AACpE;AAOO,SAAS,UACd,SACA,SACkB;AAClB,SAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE,MAAM,GAAG,mBAAmB;AAClF;AAiBO,SAAS,aACd,SACA,SACA,QACe;AACf,SAAO,UAAU,SAAS,OAAO,EAC9B,IAAI,CAAC,YAAY,EAAE,QAAQ,MAAM,WAAW,QAAQ,MAAM,EAAE,KAAK,EAAE,EAAE,EACrE,OAAO,CAAC,UAAU,MAAM,KAAK,SAAS,CAAC;AAC5C;AAIO,IAAM,oBAAoB;AAI1B,IAAM,2BAA2B;AAEjC,IAAM,yBAAqD;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAK3B,SAAS,kBAAkB,OAA2C;AAC3E,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,YAAY,MAAM;AACrE;AAIO,SAAS,sBAAsB,MAAgC;AACpE,SAAO,SAAS,YAAY,SAAS;AACvC;AAIO,IAAM,8BAA8B;AAEpC,IAAM,qCAA4E;AAAA,EACvF;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,6BAA6D;AAAA,EACxE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,mCAGT;AAAA,EACF,UAAU;AAAA,EACV,UAAU,CAAC,UAAU,cAAc,MAAM,QAAQ;AAAA,EACjD,QAAQ,CAAC,UAAU,cAAc,MAAM,OAAO,MAAM,KAAK;AAC3D;AAIO,IAAM,mCAAmE;AAAA,EAC9E;AAAA,EACA;AACF;AAEO,SAAS,8BAA8B,UAAwC;AACpF,SAAO,CAAC,iCAAiC,SAAS,QAAQ;AAC5D;AAIO,SAAS,yBAAyB,QAAyD;AAChG,SAAO,iCAAiC,MAAM,EAAE,CAAC,KAAK;AACxD;AAEO,SAAS,+BAAsD;AACpE,SAAO,EAAE,MAAM,UAAU,OAAO,OAAO,YAAY,CAAC,EAAE;AACxD;AAEA,SAAS,kBAAkB,KAAuC;AAIhE,MAAI,QAAQ;AACZ,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,cAAQ,KAAK,MAAM,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACA,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACzE,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAgC,GAAG;AAKrE,QAAI,OAAO,MAAM,YAAY,EAAE,KAAK,EAAE,SAAS,EAAG,KAAI,CAAC,IAAI;AAAA,EAC7D;AACA,SAAO;AACT;AAUA,SAAS,mBAAmB,KAAkD;AAC5E,QAAM,UAAU,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;AACzE,SAAO,QAAQ,SAAS,IAAI,KAAK,UAAU,OAAO,YAAY,OAAO,CAAC,IAAI;AAC5E;AAMA,SAAS,mBAAmB,KAAc,OAA4C;AACpF,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAClE,QAAM,IAAI;AACV,QAAM,SAAS;AAAA,IACb,EAAE,QAAQ;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,iCAAiC,MAAM;AACvD,QAAM,WAAW;AAAA,IACf,EAAE,UAAU;AAAA,IACZ;AAAA,IACA,yBAAyB,MAAM;AAAA,EACjC;AACA,QAAM,WAAW,EAAE,OAAO;AAC1B,SAAO;AAAA,IACL,IAAI,OAAO,EAAE,IAAI,MAAM,YAAY,EAAE,IAAI,IAAK,EAAE,IAAI,IAAe,QAAQ,KAAK;AAAA,IAChF;AAAA;AAAA;AAAA,IAGA,KAAK,WAAW,cAAc,OAAO,EAAE,KAAK,MAAM,WAAW,EAAE,KAAK,EAAE,KAAK,IAAI;AAAA,IAC/E;AAAA,IACA,OACE,OAAO,aAAa,WAChB,WACA,OAAO,aAAa,YAAY,OAAO,aAAa,YAClD,OAAO,QAAQ,IACf;AAAA,EACV;AACF;AAEA,SAAS,oBAAoB,KAAqC;AAChE,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO,6BAA6B;AAC/F,QAAM,IAAI;AACV,QAAM,aAAqC,MAAM,QAAQ,EAAE,YAAY,CAAC,IACnE,EAAE,YAAY,EACZ,MAAM,GAAG,2BAA2B,EACpC,IAAI,kBAAkB,EACtB,OAAO,CAAC,MAAiC,MAAM,IAAI,IACtD,CAAC;AACL,SAAO;AAAA,IACL,MAAM,SAA6B,EAAE,MAAM,GAAG,CAAC,UAAU,OAAO,GAAG,QAAQ;AAAA,IAC3E,OAAO,SAAwB,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,GAAG,KAAK;AAAA,IAChE;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,KAA6B;AACpD,QAAM,IAAI,OAAO,QAAQ,WAAW,MAAM,OAAO,QAAQ,WAAW,OAAO,GAAG,IAAI;AAClF,MAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,EAAG,QAAO;AAC1C,SAAO,KAAK,IAAI,GAAG,GAAI;AACzB;AAIA,SAAS,qBAAqB,KAAc,OAA2C;AACrF,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAClE,QAAM,IAAI;AACV,QAAM,MAAM,OAAO,EAAE,KAAK,MAAM,WAAW,EAAE,KAAK,EAAE,KAAK,IAAI;AAC7D,MAAI,CAAC,yBAAyB,KAAK,GAAG,EAAG,QAAO;AAEhD,QAAM,OAAO,SAA0B,EAAE,MAAM,GAAG,wBAAwB,MAAM;AAEhF,QAAM,UACJ,SAAS,YAAY,MAAM,QAAQ,EAAE,SAAS,CAAC,IAC1C,EAAE,SAAS,EACT,OAAO,CAAC,MAAoC,CAAC,CAAC,KAAK,OAAO,MAAM,QAAQ,EACxE,IAAI,CAAC,MAAM;AACV,UAAM,QAAQ,OAAO,EAAE,OAAO,MAAM,WAAW,EAAE,OAAO,IAAI;AAC5D,WAAO;AAAA,MACL;AAAA,MACA,OAAO,OAAO,EAAE,OAAO,MAAM,YAAY,EAAE,OAAO,IAAK,EAAE,OAAO,IAAe;AAAA,MAC/E,mBAAmB,kBAAkB,EAAE,mBAAmB,CAAC;AAAA,IAC7D;AAAA,EACF,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC,IACnC,CAAC;AAKP,QAAM,WAAW,sBAAsB,IAAI;AAC3C,QAAM,YAAY,WAAW,gBAAgB,EAAE,WAAW,CAAC,IAAI;AAC/D,QAAM,YAAY,WAAW,gBAAgB,EAAE,WAAW,CAAC,IAAI;AAK/D,QAAM,aAAa,OAAO,EAAE,cAAc,MAAM,WAAW,EAAE,cAAc,IAAI;AAC/E,QAAM,eACJ,SAAS,aACL,kBAAkB,UAAU,IAC1B,mBACA,qBACF;AAEN,SAAO;AAAA,IACL,IAAI,OAAO,EAAE,IAAI,MAAM,YAAY,EAAE,IAAI,IAAK,EAAE,IAAI,IAAe,SAAS,KAAK;AAAA,IACjF;AAAA,IACA;AAAA,IACA,OAAO,OAAO,EAAE,OAAO,MAAM,YAAY,EAAE,OAAO,IAAK,EAAE,OAAO,IAAe;AAAA,IAC/E,mBAAmB,kBAAkB,EAAE,mBAAmB,CAAC;AAAA,IAC3D,aAAa,OAAO,EAAE,aAAa,MAAM,WAAY,EAAE,aAAa,IAAe;AAAA,IACnF,yBAAyB,kBAAkB,EAAE,yBAAyB,CAAC;AAAA,IACvE,UAAU,OAAO,EAAE,UAAU,MAAM,WAAY,EAAE,UAAU,IAAe;AAAA,IAC1E,sBAAsB,kBAAkB,EAAE,sBAAsB,CAAC;AAAA,IACjE,UAAU,UAAU,EAAE,UAAU,GAAG,KAAK;AAAA,IACxC,SAAS,UAAU,EAAE,SAAS,GAAG,IAAI;AAAA,IACrC;AAAA;AAAA,IAEA,WAAW,cAAc,QAAQ,cAAc,QAAQ,YAAY,YAAY,OAAO;AAAA,IACtF;AAAA,IACA;AAAA,IACA,YAAY,oBAAoB,EAAE,YAAY,CAAC;AAAA,EACjD;AACF;AAKO,SAAS,uBAAuB,KAA4C;AACjF,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO;AAChC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAA6B,CAAC;AACpC,WAAS,IAAI,GAAG,IAAI,IAAI,UAAU,IAAI,SAAS,mBAAmB,KAAK;AACrE,UAAM,QAAQ,qBAAqB,IAAI,CAAC,GAAG,CAAC;AAC5C,QAAI,CAAC,SAAS,KAAK,IAAI,MAAM,GAAG,EAAG;AACnC,SAAK,IAAI,MAAM,GAAG;AAClB,QAAI,KAAK,KAAK;AAAA,EAChB;AACA,SAAO;AACT;AAKO,SAAS,mBAAmB,KAAuD;AACxF,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACF,WAAO,uBAAuB,KAAK,MAAM,GAAG,CAAC;AAAA,EAC/C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,mBAAmB,QAAuC;AACxE,QAAM,WAAW,CAAC,MAAoE;AACpF,UAAM,UAAU,OAAO,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;AACvE,WAAO,QAAQ,SAAS,IAAI,OAAO,YAAY,OAAO,IAAI;AAAA,EAC5D;AACA,SAAO,KAAK;AAAA,IACV,OAAO,IAAI,CAAC,OAAO;AAAA,MACjB,IAAI,EAAE;AAAA,MACN,KAAK,EAAE;AAAA,MACP,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,MACT,GAAI,SAAS,EAAE,iBAAiB,IAC5B,EAAE,mBAAmB,SAAS,EAAE,iBAAiB,EAAE,IACnD,CAAC;AAAA,MACL,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,MACtD,GAAI,SAAS,EAAE,uBAAuB,IAClC,EAAE,yBAAyB,SAAS,EAAE,uBAAuB,EAAE,IAC/D,CAAC;AAAA,MACL,GAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,SAAS,EAAE,oBAAoB,IAC/B,EAAE,sBAAsB,SAAS,EAAE,oBAAoB,EAAE,IACzD,CAAC;AAAA,MACL,GAAI,EAAE,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;AAAA,MACvC,GAAI,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM;AAAA;AAAA;AAAA,MAGtC,GAAI,sBAAsB,EAAE,IAAI,KAAK,EAAE,cAAc,OAAO,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,MAC1F,GAAI,sBAAsB,EAAE,IAAI,KAAK,EAAE,cAAc,OAAO,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA;AAAA;AAAA,MAG1F,GAAI,EAAE,SAAS,aACX,kBAAkB,EAAE,YAAY,IAC9B,EAAE,cAAc,iBAAiB,IACjC,CAAC,IACH,EAAE,eACA,EAAE,cAAc,EAAE,aAAa,IAC/B,CAAC;AAAA,MACP,GAAI,EAAE,SAAS,WAAW,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA;AAAA,MAGpD,GAAI,EAAE,WAAW,SAAS,UAAU,EAAE,YAAY,iBAAiB,EAAE,UAAU,EAAE,IAAI,CAAC;AAAA,IACxF,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,iBAAiB,GAAmD;AAC3E,SAAO;AAAA,IACL,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,YAAY,EAAE,WAAW,IAAI,CAAC,OAAO;AAAA,MACnC,IAAI,EAAE;AAAA,MACN,QAAQ,EAAE;AAAA,MACV,GAAI,EAAE,WAAW,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,MACzD,UAAU,EAAE;AAAA,MACZ,GAAI,8BAA8B,EAAE,QAAQ,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,IACnF,EAAE;AAAA,EACJ;AACF;AAiBO,SAAS,+BAA+B,KAAsC;AACnF,QAAM,MAA8B,CAAC;AACrC,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAClE,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAA8B,GAAG;AACzE,UAAM,OAAO,qBAAqB,KAAK;AACvC,QAAI,SAAS,KAAM,KAAI,GAAG,IAAI;AAAA,EAChC;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,OAA+B;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AAChF,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MACJ,IAAI,CAAC,MAAM,qBAAqB,CAAC,CAAC,EAClC,OAAO,CAAC,MAAmB,MAAM,IAAI,EACrC,KAAK,GAAG;AAAA,EACb;AACA,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,KAAK,OAAuB;AACnC,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;AAYA,IAAM,yBAAyB;AAI/B,SAAS,QAAQ,OAA8B;AAC7C,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,uBAAuB,KAAK,OAAO,EAAG,QAAO;AAClD,QAAM,IAAI,OAAO,OAAO;AACxB,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAEA,SAAS,UAAU,OAAyB;AAC1C,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,EACxB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACrC;AAIA,SAAS,WAAW,WAAiC,KAA6C;AAChG,UAAQ,UAAU,QAAQ;AAAA,IACxB,KAAK;AACH,aAAO,IAAI;AAAA,IACb,KAAK;AACH,aAAO,OAAO,IAAI,MAAM;AAAA,IAC1B,KAAK;AACH,aAAO,OAAO,UAAU,eAAe,KAAK,IAAI,UAAU,UAAU,GAAG,IACnE,IAAI,SAAS,UAAU,GAAG,IAC1B;AAAA,EACR;AACF;AAEO,SAAS,6BACd,WACA,KACS;AACT,QAAM,MAAM,WAAW,WAAW,GAAG;AACrC,QAAM,SAAS,OAAO;AACtB,QAAM,WAAW,UAAU;AAE3B,UAAQ,UAAU,UAAU;AAAA,IAC1B,KAAK;AACH,aAAO,QAAQ,UAAa,IAAI,KAAK,EAAE,SAAS;AAAA,IAClD,KAAK;AACH,aAAO,QAAQ,UAAa,IAAI,KAAK,EAAE,WAAW;AAAA,IACpD,KAAK;AACH,aAAO,KAAK,MAAM,MAAM,KAAK,QAAQ;AAAA,IACvC,KAAK;AACH,aAAO,KAAK,MAAM,MAAM,KAAK,QAAQ;AAAA,IACvC,KAAK;AACH,aAAO,KAAK,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC;AAAA,IAC7C,KAAK;AACH,aAAO,CAAC,KAAK,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC;AAAA,IAC9C,KAAK;AACH,aAAO,KAAK,MAAM,EAAE,WAAW,KAAK,QAAQ,CAAC;AAAA,IAC/C,KAAK;AACH,aAAO,KAAK,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC;AAAA,IAC7C,KAAK;AACH,aAAO,UAAU,QAAQ,EAAE,SAAS,KAAK,MAAM,CAAC;AAAA,IAClD,KAAK;AACH,aAAO,CAAC,UAAU,QAAQ,EAAE,SAAS,KAAK,MAAM,CAAC;AAAA,IACnD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,OAAO;AAGV,YAAM,IAAI,QAAQ,MAAM;AACxB,YAAM,IAAI,QAAQ,QAAQ;AAC1B,UAAI,MAAM,QAAQ,MAAM,KAAM,QAAO;AACrC,UAAI,UAAU,aAAa,KAAM,QAAO,IAAI;AAC5C,UAAI,UAAU,aAAa,MAAO,QAAO,KAAK;AAC9C,UAAI,UAAU,aAAa,KAAM,QAAO,IAAI;AAC5C,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACF;AAUO,SAAS,8BACd,OACA,KACS;AACT,QAAM,EAAE,MAAM,OAAO,WAAW,IAAI,MAAM;AAC1C,MAAI,SAAS,WAAW,WAAW,WAAW,EAAG,QAAO;AACxD,SAAO,UAAU,QACb,WAAW,KAAK,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC,IAC3D,WAAW,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAClE;AAKO,SAAS,oBACd,QACA,KACuB;AACvB,SAAO,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,8BAA8B,GAAG,GAAG,CAAC;AAChF;AAqBA,SAAS,eAAe,KAA8B,QAAgC;AACpF,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,QAAI,OAAO,MAAM,YAAY,EAAE,SAAS,KAAK,CAAC,OAAO,IAAI,EAAE,YAAY,CAAC,GAAG;AACzE,aAAO,IAAI,EAAE,YAAY,GAAG,CAAC;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,QAAQ,OAAO,YAAY,EAAE,MAAM,GAAG;AAC5C,WAAS,IAAI,MAAM,QAAQ,IAAI,GAAG,KAAK,GAAG;AACxC,UAAM,MAAM,OAAO,IAAI,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC;AAClD,QAAI,IAAK,QAAO;AAAA,EAClB;AACA,SAAO;AACT;AAMO,SAAS,gBACd,OACA,MACA,QACQ;AACR,QAAM,MACJ,SAAS,UACL,MAAM,oBACN,SAAS,gBACP,MAAM,0BACN,MAAM;AACd,QAAM,aAAa,eAAe,KAAK,MAAM;AAC7C,MAAI,WAAY,QAAO;AACvB,QAAM,WAAW,MAAM,IAAI;AAC3B,MAAI,SAAU,QAAO;AACrB,SAAO,SAAS,UAAU,MAAM,MAAM;AACxC;AAEO,SAAS,uBAAuB,QAA2B,QAAyB;AACzF,SAAO,eAAe,OAAO,mBAAmB,MAAM,MAAM,OAAO,SAAS,OAAO;AACrF;AAMO,SAAS,eAAe,QAA6D;AAC1F,MAAI,CAAC,OAAQ,QAAO,cAAc,gBAAgB;AAElD,QAAM,SAAkC,OAAO,eAAe,kBAAkB,KAC9E,CAAC;AAIH,QAAM,WAAW;AAAA,IACf,aAAa,OAAO,aAAa,CAAC;AAAA,IAClC,cAAc,OAAO,SAAS,CAAC;AAAA,EACjC;AACA,QAAM,sBAAsB,mBAAmB,OAAO,cAAc,CAAC;AAIrE,QAAM,cAAc,EAAE,OAAO,aAAa,KAAK,EAAE,OAAO,WAAW;AACnE,QAAM,UAAU,EAAE,OAAO,aAAa,KAAK,EAAE,OAAO,IAAI;AAIxD,QAAM,UAAU,EAAE,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,oBAAoB;AAOrE,QAAM,cAA0B,MAAM;AACpC,UAAM,UAAU,OAAO,YAAY;AACnC,QAAI,YAAY,WAAW,YAAY,SAAU,QAAO;AACxD,QAAI,YAAY,WAAY,QAAO;AACnC,UAAM,SAAS,OAAO;AACtB,QAAI,WAAW,WAAW,WAAW,WAAY,QAAO;AACxD,QAAI,WAAW,YAAY,WAAW,QAAS,QAAO;AACtD,WAAO,iBAAiB;AAAA,EAC1B,GAAG;AAEH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,UAAU,OAAO,UAAU,GAAG,iBAAiB,QAAQ;AAAA,IACjE,WAAW;AAAA,MACT,OAAO,WAAW;AAAA,MAClB,CAAC,UAAU,WAAW,QAAQ;AAAA,MAC9B,iBAAiB;AAAA,IACnB;AAAA,IACA,UAAU,SAAmB,OAAO,UAAU,GAAG,CAAC,MAAM,MAAM,IAAI,GAAG,iBAAiB,QAAQ;AAAA,IAE9F,SAAS,EAAE,OAAO,KAAK,KAAK,iBAAiB;AAAA,IAC7C,YAAY,EAAE,OAAO,iBAAiB,KAAK,iBAAiB;AAAA,IAC5D,SAAS,EAAE,OAAO,SAAS,CAAC,KAAK,iBAAiB;AAAA,IAClD,MAAM,EAAE,OAAO,MAAM,CAAC,KAAK,iBAAiB;AAAA,IAC5C,SAAS,EAAE,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,iBAAiB;AAAA,IACvE,OAAO,EAAE,OAAO,OAAO,CAAC,KAAK,iBAAiB;AAAA,IAC9C,QAAQ,EAAE,OAAO,QAAQ,CAAC,KAAK,iBAAiB;AAAA,IAChD,YAAY,EAAE,OAAO,YAAY,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,iBAAiB;AAAA,IAC3E,kBACE,EAAE,OAAO,qBAAqB,KAAK,EAAE,OAAO,KAAK,KAAK,iBAAiB;AAAA,IACzE,YAAY,EAAE,OAAO,0BAA0B,KAAK,iBAAiB;AAAA,IAErE,YAAY;AAAA,MACV,OAAO,YAAY;AAAA,MACnB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB,CAAC,WAAW,UAAU,YAAY,MAAM;AAAA,MACxC,iBAAiB;AAAA,IACnB;AAAA,IAEA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,aAAa;AAAA,MACpB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,cAAc;AAAA,MACrB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,aAAa;AAAA,MACpB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,cAAc;AAAA,MACrB,CAAC,QAAQ,YAAY,UAAU;AAAA,MAC/B,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB,CAAC,WAAW,eAAe,UAAU;AAAA,MACrC,iBAAiB;AAAA,IACnB;AAAA,IACA,aAAa;AAAA,MACX,OAAO,aAAa;AAAA,MACpB,CAAC,WAAW,eAAe,UAAU;AAAA,MACrC,iBAAiB;AAAA,IACnB;AAAA,IACA,WAAW;AAAA,MACT,OAAO,WAAW;AAAA,MAClB,CAAC,MAAM,MAAM,IAAI;AAAA,MACjB,iBAAiB;AAAA,IACnB;AAAA,IACA,YAAY;AAAA,MACV,OAAO,YAAY;AAAA,MACnB,CAAC,MAAM,MAAM,IAAI;AAAA,MACjB,iBAAiB;AAAA,IACnB;AAAA,IAEA,eAAe,UAAU,OAAO,eAAe,GAAG,iBAAiB,aAAa;AAAA,IAChF,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B,iBAAiB;AAAA,IACnB;AAAA,IACA,uBAAuB;AAAA,MACrB,OAAO,uBAAuB;AAAA,MAC9B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,2BAA2B,kBAAkB,OAAO,2BAA2B,CAAC;AAAA,IAChF,0BAA0B,kBAAkB,OAAO,0BAA0B,CAAC;AAAA,IAC9E,wBAAwB,kBAAkB,OAAO,wBAAwB,CAAC;AAAA,IAC1E,4BAA4B,kBAAkB,OAAO,4BAA4B,CAAC;AAAA,IAClF,8BAA8B,kBAAkB,OAAO,8BAA8B,CAAC;AAAA,IACtF,wBAAwB,kBAAkB,OAAO,wBAAwB,CAAC;AAAA,IAC1E,gBAAgB,EAAE,OAAO,gBAAgB,CAAC,KAAK,iBAAiB;AAAA,IAChE,eAAe,EAAE,OAAO,eAAe,CAAC,KAAK,iBAAiB;AAAA,IAE9D,QAAQ,SAAsB,OAAO,QAAQ,GAAG,CAAC,WAAW,OAAO,GAAG,iBAAiB,MAAM;AAAA,IAC7F,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB,CAAC,QAAQ,OAAO;AAAA,MAChB,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB,UAAU,OAAO,kBAAkB,GAAG,iBAAiB,gBAAgB;AAAA,IACzF,iBAAiB,UAAU,OAAO,iBAAiB,GAAG,iBAAiB,eAAe;AAAA,IACtF,WAAW,UAAU,OAAO,WAAW,GAAG,iBAAiB,SAAS;AAAA,IACpE,YAAY,EAAE,OAAO,YAAY,CAAC,KAAK,iBAAiB;AAAA,IACxD,kBAAkB,UAAU,OAAO,kBAAkB,GAAG,iBAAiB,gBAAgB;AAAA,IACzF,gBAAgB,UAAU,OAAO,gBAAgB,GAAG,iBAAiB,cAAc;AAAA,IACnF,mBAAmB,UAAU,OAAO,mBAAmB,GAAG,iBAAiB,iBAAiB;AAAA,IAC5F,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B,CAAC,OAAO,QAAQ;AAAA,MAChB,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB,CAAC,QAAQ,QAAQ;AAAA,MACjB,iBAAiB;AAAA,IACnB;AAAA,IAEA,aAAa,SAAS;AAAA,IACtB,SAAS,SAAS;AAAA,IAClB,cAAc,uBAAuB,CAAC;AAAA,IACtC,oBAAoB,yBAAyB,OAAO,wBAAwB,CAAC;AAAA,IAC7E,qBAAqB,0BAA0B,OAAO,yBAAyB,CAAC;AAAA,IAEhF,YAAY,EAAE,OAAO,wBAAwB;AAAA,IAC7C,gBAAgB,EAAE,OAAO,mBAAmB;AAAA,IAC5C,kBAAkB,EAAE,OAAO,6BAA6B;AAAA,IACxD,YAAY,EAAE,OAAO,YAAY,CAAC;AAAA,IAClC,cAAc,EAAE,OAAO,cAAc,CAAC;AAAA,IAEtC,eAAe;AAAA,MACb,OAAO;AAAA,MACP,CAAC,QAAQ,aAAa,kBAAkB;AAAA,MACxC,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,eAAe,OAAO,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO9C,qBAAqB;AAAA,MACnB,OAAO,qBAAqB;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,mBAAmB,UAAU,OAAO,mBAAmB,GAAG,iBAAiB,iBAAiB;AAAA,IAC5F,wBAAwB;AAAA,MACtB,OAAO,wBAAwB;AAAA,MAC/B,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO,qBAAqB;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,wBAAwB;AAAA,MACtB,OAAO,wBAAwB;AAAA,MAC/B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B,iBAAiB;AAAA,IACnB;AAAA,IACA,uBAAuB;AAAA,MACrB,OAAO,uBAAuB;AAAA,MAC9B,iBAAiB;AAAA,IACnB;AAAA,IAEA,aAAa;AAAA,MACX,OAAO,aAAa;AAAA,MACpB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,cAAc;AAAA,MACrB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,cAAc;AAAA,MACrB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO,qBAAqB;AAAA,MAC5B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,yBAAyB;AAAA,MACvB,OAAO,yBAAyB;AAAA,MAChC,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB;AAAA,MAChB,OAAO,kBAAkB;AAAA,MACzB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB;AAAA,MAChB,OAAO,kBAAkB;AAAA,MACzB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO,qBAAqB;AAAA,MAC5B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO,qBAAqB;AAAA,MAC5B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,yBAAyB;AAAA,MACvB,OAAO,yBAAyB;AAAA,MAChC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,2BAA2B;AAAA,MACzB,OAAO,2BAA2B;AAAA,MAClC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,yBAAyB;AAAA,MACvB,OAAO,yBAAyB;AAAA,MAChC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,uBAAuB;AAAA,MACrB,OAAO,uBAAuB;AAAA,MAC9B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe,UAAU,OAAO,eAAe,GAAG,iBAAiB,aAAa;AAAA,IAChF,gBAAgB;AAAA,MACd,OAAO,gBAAgB;AAAA,MACvB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB;AAAA,MACjB,OAAO,mBAAmB;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,iBAAiB;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,YAAY,SAAqB,OAAO,YAAY,GAAG,YAAY,iBAAiB,UAAU;AAAA,IAC9F,YAAY;AAAA,MACV,OAAO,YAAY;AAAA,MACnB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB,UAAU,OAAO,iBAAiB,GAAG,iBAAiB,eAAe;AAAA,IACtF,eAAe;AAAA,MACb,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,iBAAiB,UAAU,OAAO,iBAAiB,GAAG,iBAAiB,eAAe;AAAA,IACtF,kBAAkB;AAAA,MAChB,OAAO,kBAAkB;AAAA,MACzB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,mBAAmB,UAAU,OAAO,mBAAmB,GAAG,iBAAiB,iBAAiB;AAAA,IAC5F,yBAAyB;AAAA,MACvB,OAAO,yBAAyB;AAAA,MAChC,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B,iBAAiB;AAAA,IACnB;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO,oBAAoB;AAAA,MAC3B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,sBAAsB;AAAA,MACpB,OAAO,sBAAsB;AAAA,MAC7B;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,kBAAkB;AAAA,MAChB,OAAO,kBAAkB;AAAA,MACzB;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,4BAA4B;AAAA,MAC1B,OAAO,4BAA4B;AAAA,MACnC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,2BAA2B;AAAA,MACzB,OAAO,2BAA2B;AAAA,MAClC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,6BAA6B;AAAA,MAC3B,OAAO,6BAA6B;AAAA,MACpC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA,4BAA4B;AAAA,MAC1B,OAAO,4BAA4B;AAAA,MACnC;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IAEA,WAAW,EAAE,OAAO,WAAW,CAAC;AAAA,EAClC;AACF;AAiCO,SAAS,eACd,UACA,MAC0E;AAC1E,QAAM,OAAO,CAAC,MAA6B;AACzC,UAAM,IAAI,EAAE,KAAK;AACjB,WAAO,EAAE,SAAS,IAAI,IAAI;AAAA,EAC5B;AAIA,QAAM,gBAAkB,OACtB,cACF,KAAK,CAAC;AACN,QAAM,SAAiC;AAAA,IACrC,SAAS,SAAS;AAAA,IAClB,MAAM,SAAS;AAAA,IACf,SAAS,SAAS;AAAA,IAClB,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB,YAAY,SAAS;AAAA,IACrB,eAAe,SAAS;AAAA,IACxB,eAAe,SAAS;AAAA,IACxB,aAAa,SAAS;AAAA,IACtB,cAAc,SAAS;AAAA,IACvB,aAAa,SAAS;AAAA,IACtB,cAAc,SAAS;AAAA,IACvB,gBAAgB,SAAS;AAAA,IACzB,aAAa,SAAS;AAAA,IACtB,WAAW,SAAS;AAAA,IACpB,YAAY,SAAS;AAAA,IACrB,eAAe,OAAO,SAAS,aAAa;AAAA,IAC5C,mBAAmB,SAAS;AAAA,IAC5B,uBAAuB,SAAS;AAAA,IAChC,sBAAsB,OAAO,SAAS,oBAAoB;AAAA,IAC1D,gBAAgB,SAAS;AAAA,IACzB,eAAe,SAAS;AAAA,IACxB,gBAAgB,SAAS;AAAA,IACzB,sBAAsB,SAAS;AAAA,IAC/B,sBAAsB,SAAS;AAAA,IAC/B,iBAAiB,SAAS;AAAA,IAC1B,eAAe,SAAS;AAAA,IACxB,oBAAoB,OAAO,SAAS,kBAAkB;AAAA,IACtD,gBAAgB,SAAS;AAAA,IACzB,iBAAiB,SAAS;AAAA,IAC1B,gBAAgB,SAAS;AAAA,IACzB,gBAAgB,SAAS;AAAA,IACzB,eAAe,SAAS;AAAA,IACxB,QAAQ,SAAS;AAAA,IACjB,iBAAiB,SAAS;AAAA,IAC1B,kBAAkB,OAAO,SAAS,gBAAgB;AAAA,IAClD,iBAAiB,OAAO,SAAS,eAAe;AAAA,IAChD,WAAW,OAAO,SAAS,SAAS;AAAA,IACpC,YAAY,SAAS;AAAA,IACrB,kBAAkB,OAAO,SAAS,gBAAgB;AAAA,IAClD,gBAAgB,OAAO,SAAS,cAAc;AAAA,IAC9C,mBAAmB,OAAO,SAAS,iBAAiB;AAAA,IACpD,oBAAoB,SAAS;AAAA,IAC7B,iBAAiB,SAAS;AAAA,IAC1B,UAAU,OAAO,SAAS,QAAQ;AAAA,IAClC,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,IACnB,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMrB,qBAAqB,SAAS;AAAA,IAC9B,mBAAmB,OAAO,SAAS,iBAAiB;AAAA,IACpD,wBAAwB,OAAO,SAAS,sBAAsB;AAAA,IAC9D,sBAAsB,SAAS;AAAA,IAC/B,qBAAqB,SAAS;AAAA,IAC9B,wBAAwB,SAAS;AAAA,IACjC,sBAAsB,SAAS;AAAA,IAC/B,oBAAoB,SAAS;AAAA,IAC7B,mBAAmB,SAAS;AAAA,IAC5B,oBAAoB,OAAO,SAAS,kBAAkB;AAAA,IACtD,uBAAuB,OAAO,SAAS,qBAAqB;AAAA,IAC5D,aAAa,SAAS;AAAA,IACtB,cAAc,SAAS;AAAA,IACvB,cAAc,SAAS;AAAA,IACvB,eAAe,SAAS;AAAA,IACxB,qBAAqB,SAAS;AAAA,IAC9B,mBAAmB,SAAS;AAAA,IAC5B,iBAAiB,SAAS;AAAA,IAC1B,yBAAyB,OAAO,SAAS,uBAAuB;AAAA,IAChE,kBAAkB,SAAS;AAAA,IAC3B,kBAAkB,SAAS;AAAA,IAC3B,mBAAmB,SAAS;AAAA,IAC5B,mBAAmB,SAAS;AAAA,IAC5B,qBAAqB,SAAS;AAAA,IAC9B,qBAAqB,SAAS;AAAA,IAC9B,mBAAmB,SAAS;AAAA,IAC5B,mBAAmB,SAAS;AAAA,IAC5B,iBAAiB,SAAS;AAAA,IAC1B,iBAAiB,SAAS;AAAA,IAC1B,yBAAyB,SAAS;AAAA,IAClC,2BAA2B,SAAS;AAAA,IACpC,yBAAyB,SAAS;AAAA,IAClC,uBAAuB,SAAS;AAAA,IAChC,gBAAgB,SAAS;AAAA,IACzB,iBAAiB,SAAS;AAAA,IAC1B,eAAe,SAAS;AAAA,IACxB,oBAAoB,SAAS;AAAA,IAC7B,eAAe,OAAO,SAAS,aAAa;AAAA,IAC5C,gBAAgB,SAAS;AAAA,IACzB,iBAAiB,SAAS;AAAA,IAC1B,mBAAmB,SAAS;AAAA,IAC5B,iBAAiB,SAAS;AAAA,IAC1B,eAAe,SAAS;AAAA,IACxB,YAAY,SAAS;AAAA,IACrB,YAAY,SAAS;AAAA,IACrB,iBAAiB,OAAO,SAAS,eAAe;AAAA,IAChD,eAAe,SAAS;AAAA,IACxB,iBAAiB,OAAO,SAAS,eAAe;AAAA,IAChD,kBAAkB,SAAS;AAAA,IAC3B,mBAAmB,OAAO,SAAS,iBAAiB;AAAA,IACpD,yBAAyB,OAAO,SAAS,uBAAuB;AAAA,IAChE,oBAAoB,OAAO,SAAS,kBAAkB;AAAA,IACtD,oBAAoB,SAAS;AAAA,IAC7B,sBAAsB,SAAS;AAAA,IAC/B,kBAAkB,SAAS;AAAA,IAC3B,4BAA4B,SAAS;AAAA,IACrC,2BAA2B,SAAS;AAAA,IACpC,6BAA6B,SAAS;AAAA,IACtC,4BAA4B,SAAS;AAAA;AAAA;AAAA,IAGrC,SAAS,cAAc,SAAS,OAAO;AAAA,IACvC,CAAC,wBAAwB,GAAG,yBAAyB,SAAS,kBAAkB;AAAA,EAClF;AAOA,MAAI,SAAS,YAAY,SAAS,GAAG;AACnC,WAAO,aAAa,IAAI,aAAa,SAAS,WAAW;AAAA,EAC3D;AAEA,QAAM,gBAAgB,0BAA0B,SAAS,mBAAmB;AAC5E,MAAI,cAAe,QAAO,yBAAyB,IAAI;AAIvD,MAAI,SAAS,aAAa,SAAS,GAAG;AACpC,WAAO,cAAc,IAAI,mBAAmB,SAAS,YAAY;AAAA,EACnE;AAGA,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAY;AACV,UAAM,UAAU,mBAAmB,SAAS,GAAG,CAAC;AAChD,QAAI,QAAS,QAAO,GAAG,IAAI;AAAA,EAC7B;AACA,QAAM,UAAU,KAAK,SAAS,OAAO;AACrC,MAAI,QAAS,QAAO,SAAS,IAAI;AACjC,QAAM,SAAS,KAAK,SAAS,UAAU;AACvC,MAAI,OAAQ,QAAO,YAAY,IAAI;AACnC,QAAM,UAAU,KAAK,SAAS,YAAY;AAC1C,MAAI,QAAS,QAAO,cAAc,IAAI;AAItC,QAAM,MAAM,KAAK,SAAS,SAAS;AACnC,MAAI,IAAK,QAAO,WAAW,IAAI;AAE/B,QAAM,YAAoD;AAAA,IACxD,GAAG;AAAA,IACH,CAAC,kBAAkB,GAAG;AAAA,EACxB;AAIA,QAAM,cAAiC,SAAS,eAAe,WAAW,UAAU;AAEpF,QAAM,aAA8B;AAAA,IAClC,OAAO,SAAS;AAAA,IAChB,MAAM,KAAK,SAAS,OAAO;AAAA,IAC3B,aAAa,KAAK,SAAS,WAAW;AAAA,IACtC,YAAY,SAAS;AAAA,IACrB,qBAAqB,KAAK,SAAS,cAAc;AAAA,IACjD,uBAAuB,SAAS;AAAA,IAChC,4BAA4B,SAAS;AAAA,IACrC,mBAAmB,SAAS;AAAA,IAC5B,0BAA0B,KAAK,SAAS,UAAU;AAAA,IAClD,yBAAyB;AAAA,IACzB,+BAA+B,KAAK,SAAS,gBAAgB;AAAA,IAC7D,cAAc;AAAA,IACd,qBAAqB,SAAS;AAAA,EAChC;AAUA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAOO,IAAM,yBAAyB;AAC/B,IAAM,0BAA0B;AAShC,SAAS,oBAAoB,UAA4C;AAC9E,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,UAAU,cAAc,QAAQ;AAAA,EAClC;AACF;AAeO,SAAS,sBAAsB,KAAgC;AAGpE,QAAM,OACJ,SAAS,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,IACpC,IAAI,UAAU,IACf,SAAS,GAAG,IACV,MACA;AAER,MAAI,CAAC,KAAM,QAAO,cAAc,gBAAgB;AAEhD,QAAM,OAAO;AACb,QAAM,OAAO,CAAC,GAAY,aAA8B,OAAO,MAAM,WAAW,IAAI;AACpF,QAAM,OAAO,CAAC,GAAY,aACxB,OAAO,MAAM,YAAY,WAAW,CAAC,IAAI,IAAI;AAI/C,QAAM,EAAE,aAAa,QAAQ,IAAI;AAAA,IAC/B,sBAAsB,KAAK,aAAa,CAAC;AAAA,IACzC,kBAAkB,KAAK,SAAS,CAAC;AAAA,EACnC;AACA,QAAM,eAAe,uBAAuB,KAAK,cAAc,CAAC,KAAK,CAAC;AAGtE,QAAM,cAA0B,MAAM;AACpC,UAAM,IAAI,KAAK,YAAY;AAC3B,QAAI,MAAM,WAAW,MAAM,SAAU,QAAO;AAC5C,WAAO,KAAK;AAAA,EACd,GAAG;AAEH,SAAO;AAAA,IACL,aAAa,KAAK,KAAK,aAAa,GAAG,KAAK,WAAW;AAAA,IACvD,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAC3C,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAC3C,UAAU,UAAU,KAAK,UAAU,GAAG,KAAK,QAAQ;AAAA,IACnD,WAAW;AAAA,MACT,KAAK,WAAW;AAAA,MAChB,CAAC,UAAU,WAAW,QAAQ;AAAA,MAC9B,KAAK;AAAA,IACP;AAAA,IACA,UAAU,SAAmB,KAAK,UAAU,GAAG,CAAC,MAAM,MAAM,IAAI,GAAG,KAAK,QAAQ;AAAA,IAEhF,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAC3C,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IACpD,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAC3C,MAAM,KAAK,KAAK,MAAM,GAAG,KAAK,IAAI;AAAA,IAClC,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAC3C,OAAO,KAAK,KAAK,OAAO,GAAG,KAAK,KAAK;AAAA,IACrC,QAAQ,KAAK,KAAK,QAAQ,GAAG,KAAK,MAAM;AAAA,IACxC,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IACpD,kBAAkB,KAAK,KAAK,kBAAkB,GAAG,KAAK,gBAAgB;AAAA,IACtE,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IAEpD,YAAY,SAAqB,KAAK,YAAY,GAAG,mBAAmB,KAAK,UAAU;AAAA,IACvF,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB,CAAC,WAAW,UAAU,YAAY,MAAM;AAAA,MACxC,KAAK;AAAA,IACP;AAAA,IAEA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,aAAa,SAAwB,KAAK,aAAa,GAAG,gBAAgB,KAAK,WAAW;AAAA,IAC1F,cAAc,SAAuB,KAAK,cAAc,GAAG,WAAW,KAAK,YAAY;AAAA,IACvF,aAAa,SAAuB,KAAK,aAAa,GAAG,WAAW,KAAK,WAAW;AAAA,IACpF,cAAc;AAAA,MACZ,KAAK,cAAc;AAAA,MACnB,CAAC,QAAQ,YAAY,UAAU;AAAA,MAC/B,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB,CAAC,WAAW,eAAe,UAAU;AAAA,MACrC,KAAK;AAAA,IACP;AAAA,IACA,aAAa;AAAA,MACX,KAAK,aAAa;AAAA,MAClB,CAAC,WAAW,eAAe,UAAU;AAAA,MACrC,KAAK;AAAA,IACP;AAAA,IACA,WAAW,SAAoB,KAAK,WAAW,GAAG,CAAC,MAAM,MAAM,IAAI,GAAG,KAAK,SAAS;AAAA,IACpF,YAAY,SAAoB,KAAK,YAAY,GAAG,CAAC,MAAM,MAAM,IAAI,GAAG,KAAK,UAAU;AAAA,IAEvF,eAAe,UAAU,KAAK,eAAe,GAAG,KAAK,aAAa;AAAA,IAClE,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,sBAAsB,UAAU,KAAK,sBAAsB,GAAG,KAAK,oBAAoB;AAAA,IACvF,uBAAuB;AAAA,MACrB,KAAK,uBAAuB;AAAA,MAC5B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,sBAAsB;AAAA,MACpB,KAAK,sBAAsB;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,sBAAsB;AAAA,MACpB,KAAK,sBAAsB;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB,UAAU,KAAK,oBAAoB,GAAG,KAAK,kBAAkB;AAAA,IACjF,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,2BAA2B,kBAAkB,KAAK,2BAA2B,CAAC;AAAA,IAC9E,0BAA0B,kBAAkB,KAAK,0BAA0B,CAAC;AAAA,IAC5E,wBAAwB,kBAAkB,KAAK,wBAAwB,CAAC;AAAA,IACxE,4BAA4B,kBAAkB,KAAK,4BAA4B,CAAC;AAAA,IAChF,8BAA8B,kBAAkB,KAAK,8BAA8B,CAAC;AAAA,IACpF,wBAAwB,kBAAkB,KAAK,wBAAwB,CAAC;AAAA,IACxE,gBAAgB,KAAK,KAAK,gBAAgB,GAAG,KAAK,cAAc;AAAA,IAChE,eAAe,KAAK,KAAK,eAAe,GAAG,KAAK,aAAa;AAAA,IAE7D,QAAQ,SAAsB,KAAK,QAAQ,GAAG,CAAC,WAAW,OAAO,GAAG,KAAK,MAAM;AAAA,IAC/E,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB,CAAC,QAAQ,OAAO;AAAA,MAChB,KAAK;AAAA,IACP;AAAA,IACA,kBAAkB,UAAU,KAAK,kBAAkB,GAAG,KAAK,gBAAgB;AAAA,IAC3E,iBAAiB,UAAU,KAAK,iBAAiB,GAAG,KAAK,eAAe;AAAA,IACxE,WAAW,UAAU,KAAK,WAAW,GAAG,KAAK,SAAS;AAAA,IACtD,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IACpD,kBAAkB,UAAU,KAAK,kBAAkB,GAAG,KAAK,gBAAgB;AAAA,IAC3E,gBAAgB,UAAU,KAAK,gBAAgB,GAAG,KAAK,cAAc;AAAA,IAErE;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU,KAAK,mBAAmB,GAAG,KAAK,iBAAiB;AAAA,IAC9E,oBAAoB;AAAA,MAClB,KAAK,oBAAoB;AAAA,MACzB,CAAC,OAAO,QAAQ;AAAA,MAChB,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB,CAAC,QAAQ,QAAQ;AAAA,MACjB,KAAK;AAAA,IACP;AAAA;AAAA;AAAA,IAGA,oBAAoB,uBAAuB,KAAK,wBAAwB,CAAC;AAAA,IACzE,qBAAqB,wBAAwB,KAAK,yBAAyB,CAAC;AAAA,IAE5E,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IACpD,gBAAgB,KAAK,KAAK,gBAAgB,GAAG,KAAK,cAAc;AAAA,IAChE,kBAAkB,KAAK,KAAK,kBAAkB,GAAG,KAAK,gBAAgB;AAAA,IACtE,YAAY,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU;AAAA,IACpD,cAAc,KAAK,KAAK,cAAc,GAAG,KAAK,YAAY;AAAA,IAE1D,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB,CAAC,QAAQ,aAAa,kBAAkB;AAAA,MACxC,KAAK;AAAA,IACP;AAAA,IACA;AAAA,IACA,eAAe,UAAU,KAAK,eAAe,GAAG,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOlE,qBAAqB;AAAA,MACnB,KAAK,qBAAqB;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,mBAAmB,UAAU,KAAK,mBAAmB,GAAG,KAAK,iBAAiB;AAAA,IAC9E,wBAAwB,UAAU,KAAK,wBAAwB,GAAG,KAAK,sBAAsB;AAAA,IAC7F,sBAAsB;AAAA,MACpB,KAAK,sBAAsB;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,qBAAqB;AAAA,MACnB,KAAK,qBAAqB;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,wBAAwB;AAAA,MACtB,KAAK,wBAAwB;AAAA,MAC7B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,sBAAsB;AAAA,MACpB,KAAK,sBAAsB;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB;AAAA,MAClB,KAAK,oBAAoB;AAAA,MACzB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB,UAAU,KAAK,oBAAoB,GAAG,KAAK,kBAAkB;AAAA,IACjF,uBAAuB,UAAU,KAAK,uBAAuB,GAAG,KAAK,qBAAqB;AAAA,IAE1F,aAAa,SAAsB,KAAK,aAAa,GAAG,eAAe,KAAK,WAAW;AAAA,IACvF,cAAc;AAAA,MACZ,KAAK,cAAc;AAAA,MACnB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,cAAc;AAAA,MACZ,KAAK,cAAc;AAAA,MACnB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,qBAAqB;AAAA,MACnB,KAAK,qBAAqB;AAAA,MAC1B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,yBAAyB;AAAA,MACvB,KAAK,yBAAyB;AAAA,MAC9B,KAAK;AAAA,IACP;AAAA,IACA,kBAAkB;AAAA,MAChB,KAAK,kBAAkB;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,kBAAkB;AAAA,MAChB,KAAK,kBAAkB;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,qBAAqB;AAAA,MACnB,KAAK,qBAAqB;AAAA,MAC1B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,qBAAqB;AAAA,MACnB,KAAK,qBAAqB;AAAA,MAC1B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,yBAAyB;AAAA,MACvB,KAAK,yBAAyB;AAAA,MAC9B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,2BAA2B;AAAA,MACzB,KAAK,2BAA2B;AAAA,MAChC;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,yBAAyB;AAAA,MACvB,KAAK,yBAAyB;AAAA,MAC9B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,uBAAuB;AAAA,MACrB,KAAK,uBAAuB;AAAA,MAC5B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB;AAAA,MAClB,KAAK,oBAAoB;AAAA,MACzB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe,UAAU,KAAK,eAAe,GAAG,KAAK,aAAa;AAAA,IAClE,gBAAgB;AAAA,MACd,KAAK,gBAAgB;AAAA,MACrB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB;AAAA,MACjB,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,KAAK,iBAAiB;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,YAAY,SAAqB,KAAK,YAAY,GAAG,YAAY,KAAK,UAAU;AAAA,IAChF,YAAY,SAAqB,KAAK,YAAY,GAAG,cAAc,KAAK,UAAU;AAAA,IAClF,iBAAiB,UAAU,KAAK,iBAAiB,GAAG,KAAK,eAAe;AAAA,IACxE,eAAe;AAAA,MACb,KAAK,eAAe;AAAA,MACpB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB,UAAU,KAAK,iBAAiB,GAAG,KAAK,eAAe;AAAA,IACxE,kBAAkB;AAAA,MAChB,KAAK,kBAAkB;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,mBAAmB,UAAU,KAAK,mBAAmB,GAAG,KAAK,iBAAiB;AAAA,IAC9E,yBAAyB;AAAA,MACvB,KAAK,yBAAyB;AAAA,MAC9B,KAAK;AAAA,IACP;AAAA,IACA,oBAAoB,UAAU,KAAK,oBAAoB,GAAG,KAAK,kBAAkB;AAAA,IACjF,oBAAoB;AAAA,MAClB,KAAK,oBAAoB;AAAA,MACzB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,sBAAsB;AAAA,MACpB,KAAK,sBAAsB;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,kBAAkB;AAAA,MAChB,KAAK,kBAAkB;AAAA,MACvB;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,4BAA4B;AAAA,MAC1B,KAAK,4BAA4B;AAAA,MACjC;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,2BAA2B;AAAA,MACzB,KAAK,2BAA2B;AAAA,MAChC;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,6BAA6B;AAAA,MAC3B,KAAK,6BAA6B;AAAA,MAClC;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA,4BAA4B;AAAA,MAC1B,KAAK,4BAA4B;AAAA,MACjC;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IAEA,WAAW,KAAK,KAAK,WAAW,GAAG,KAAK,SAAS,EAAE,MAAM,GAAG,qBAAqB;AAAA,EACnF;AACF;AAEA,SAAS,SAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAOA,SAAS,sBAAsB,KAAmC;AAChE,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO;AAChC,SAAO,IACJ,OAAO,QAAQ,EACf,IAAI,CAAC,GAAG,OAAO;AAAA,IACd,IAAI,OAAO,EAAE,IAAI,MAAM,YAAY,EAAE,IAAI,IAAK,EAAE,IAAI,IAAe,SAAS,CAAC;AAAA,IAC7E,OAAO,OAAO,EAAE,OAAO,MAAM,WAAY,EAAE,OAAO,IAAe;AAAA,IACjE,WACE,OAAO,EAAE,WAAW,MAAM,YAAY,WAAW,EAAE,WAAW,CAAW,IACpE,EAAE,WAAW,IACd;AAAA,IACN,iBACE,OAAO,EAAE,iBAAiB,MAAM,YAAY,WAAW,EAAE,iBAAiB,CAAW,IAChF,EAAE,iBAAiB,IACpB;AAAA,IACN,aACE,OAAO,EAAE,aAAa,MAAM,YAAY,WAAW,EAAE,aAAa,CAAW,IACxE,EAAE,aAAa,IAChB;AAAA,EACR,EAAE,EACD,OAAO,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC;AACrC;AAWO,SAAS,uBAAuB,IAAiB,GAA2B;AACjF,QAAM,MAAM,CAAC,GAAW,MAAc;AACpC,OAAG,MAAM,YAAY,GAAG,CAAC;AAAA,EAC3B;AAEA,MAAI,gBAAgB,EAAE,OAAO;AAC7B,MAAI,WAAW,EAAE,UAAU;AAC3B,MAAI,gBAAgB,EAAE,OAAO;AAC7B,MAAI,aAAa,EAAE,IAAI;AACvB,MAAI,gBAAgB,EAAE,OAAO;AAC7B,MAAI,cAAc,EAAE,KAAK;AACzB,MAAI,eAAe,EAAE,MAAM;AAC3B,MAAI,oBAAoB,EAAE,UAAU;AACpC,MAAI,eAAe,EAAE,gBAAgB;AACrC,MAAI,eAAe,EAAE,UAAU;AAE/B,MAAI,uBAAuB,YAAY,EAAE,aAAa,CAAC;AACvD,MAAI,qBAAqB,YAAY,EAAE,WAAW,CAAC;AACnD,MAAI,sBAAsB,YAAY,EAAE,YAAY,CAAC;AACrD,MAAI,qBAAqB,YAAY,EAAE,WAAW,CAAC;AAEnD,MAAI,aAAa,UAAU,EAAE,UAAU,CAAC;AACxC,MAAI,uBAAuB,gBAAgB,EAAE,aAAa,CAAC;AAE3D,MAAI,oBAAoB,YAAY,EAAE,cAAc,CAAC;AACrD,MAAI,qBAAqB,aAAa,EAAE,WAAW,CAAC;AACpD,MAAI,kBAAkB,UAAU,EAAE,SAAS,CAAC;AAC5C,MAAI,mBAAmB,WAAW,EAAE,UAAU,CAAC;AAK/C,MAAI,kBAAkB,EAAE,cAAc;AACtC,MAAI,iBAAiB,EAAE,aAAa;AAIpC,MAAI,sBAAsB,cAAc,EAAE,cAAc,CAAC;AACzD,MAAI,qBAAqB,cAAc,EAAE,aAAa,CAAC;AACvD,MAAI,uBAAuB,oBAAoB,EAAE,aAAa,CAAC;AAC/D,MAAI,sBAAsB,cAAc,EAAE,aAAa,CAAC;AACxD,MAAI,yBAAyB,iBAAiB,EAAE,cAAc,CAAC;AAC/D,MAAI,yBAAyB,sBAAsB,EAAE,eAAe,CAAC;AAGrE;AAAA,IACE;AAAA,IACA,uBACE,EAAE,mBAAmB,aAAa,EAAE,yBAAyB,SACzD,SACA,EAAE,oBACR;AAAA,EACF;AACA,MAAI,+BAA+B,EAAE,oBAAoB;AAEzD,MAAI,eAAe,UAAU,EAAE,YAAY,CAAC;AAC5C;AAAA,IACE;AAAA,IACA,EAAE,iBAAiB,aAAa,aAAa,EAAE,MAAM,KAAK;AAAA,EAC5D;AACF;AAEO,SAAS,UAAU,OAA6B;AACrD,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;;;ACrtIA,SAAS,yBAAyB,OAAwD;AACxF,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAM,QAAQ,IAAI,YAAY;AAC9B,QAAI,UAAU,aAAa,UAAU,gBAAiB;AACtD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAGA,SAAS,cAAc,SAAiC,MAAsC;AAC5F,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,IAAI,YAAY,MAAM,KAAM;AAChC,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAuFA,eAAe,SAAS,OAA6C;AACnE,QAAM,OAAQ,WAAsD;AACpE,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,MAAI;AACF,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC;AAC5D,WAAO,MAAM,IAAI;AAAA,MACf,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,IACzD,EAAE,YAAY;AAAA,EAChB,QAAQ;AAIN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAO3B,YAAY,SAAiC;AAC3C,SAAK,aAAa,QAAQ;AAC1B,SAAK,YAAY,QAAQ;AACzB,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,eAAe,QAAQ;AAI5B,SAAK,SAAS,IAAI,QAAQ,IAAI;AAAA,MAC5B,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ;AAAA,MACpB,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,IAAY,WAAmB;AAC7B,WAAO,iBAAiB,mBAAmB,KAAK,UAAU,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;AAAA,EACnG;AAAA;AAAA,EAGQ,cAAc,OAAwD;AAC5E,WAAO;AAAA,MACL,GAAG,yBAAyB,KAAK;AAAA,MACjC,eAAe,UAAU,KAAK,oBAAoB,CAAC;AAAA,IACrD;AAAA,EACF;AAAA;AAAA,EAGQ,UAAU,OAAwD;AACxE,QAAI,CAAC,KAAK,gBAAgB;AACxB,YAAM,IAAI,aAAa,0CAA0C;AAAA,QAC/D,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,WAAO,EAAE,GAAG,yBAAyB,KAAK,GAAG,WAAW,KAAK,eAAe;AAAA,EAC9E;AAAA,EAEQ,sBAA8B;AACpC,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,aAAa,gDAAgD;AAAA,QACrE,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,kBACJ,QACA,SAC+B;AAC/B,UAAM,UAAU,QAAQ,SAAS,KAAK,EAAE,YAAY;AACpD,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,sBAAsB,mBAAmB,KAAK,UAAU,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;AAAA,MAC/F;AAAA,QACE,OAAO,EAAE,OAAO,QAAQ,OAAO,SAAS,WAAW,OAAU;AAAA,QAC7D,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAI,QAAQ,SACR;AAAA,YACE,GAAG,cAAc,yBAAyB,SAAS,OAAO,GAAG,iBAAiB;AAAA,YAC9E,mBAAmB,OAAO;AAAA,UAC5B,IACA,yBAAyB,SAAS,OAAO;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,sBACJ,QACA,SACuC;AACvC,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,uBAAuB,mBAAmB,KAAK,UAAU,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;AAAA,MAChG;AAAA,QACE,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAI,QAAQ,SACR;AAAA,YACE,GAAG,cAAc,KAAK,cAAc,SAAS,OAAO,GAAG,iBAAiB;AAAA,YACxE,mBAAmB,OAAO;AAAA,UAC5B,IACA,KAAK,cAAc,SAAS,OAAO;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,oBACJ,QAIA,SACe;AACf,QAAI;AACF,YAAM,KAAK,OAAO;AAAA,QAChB;AAAA,QACA,gCAAgC,mBAAmB,KAAK,UAAU,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;AAAA,QACzG;AAAA,UACE,MAAM;AAAA,UACN,WAAW;AAAA,UACX,GAAG;AAAA,UACH,SAAS,yBAAyB,SAAS,OAAO;AAAA,QACpD;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4CA,MAAM,iBACJ,QACA,SAM+B;AAC/B,UAAM,EAAE,WAAW,UAAU,UAAU,GAAG,OAAO,IAAI,WAAW,CAAC;AAGjE,UAAM,OAAO,EAAE,GAAG,QAAQ,eAAe,KAAK,oBAAoB,EAAE;AACpE,UAAM,UAAU,KAAK,UAAU,OAAO,OAAO;AAS7C,UAAM,UAAU,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC;AACzE,UAAM,UAAU,UACZ,WAAW,KAAK,OAAO,EAAE,SACzB,aAAa,QAAQ,cAAc,OACjC,MAAM,SAAS,IAAI,IACnB;AACN,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,aAAa,mBAAmB,KAAK,SAAS,CAAC;AAAA,MAC/C;AAAA,QACE,MAAM,WAAW;AAAA,QACjB,GAAI,cAAc,SACd,EAAE,WAAW,UAAU,aAAa,QAAQ,cAAc,KAAK,OAAO,UAAU,IAChF,CAAC;AAAA,QACL,GAAG;AAAA;AAAA;AAAA;AAAA,QAIH,SACE,YAAY,OACR,UACA,EAAE,GAAG,SAAS,gBAAgB,oBAAoB,oBAAoB,OAAO;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,yBACJ,aACA,SAC2C;AAC3C,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,aAAa,gEAAgE;AAAA,QACrF,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,gCAAgC,mBAAmB,KAAK,UAAU,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;AAAA,MACzG;AAAA,QACE,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAG,yBAAyB,SAAS,OAAO;AAAA,UAC5C,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,oBACJ,gBACA,WACA,QACA,SACsC;AACtC,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,kBAAkB,mBAAmB,cAAc,CAAC;AAAA,MACpD;AAAA,QACE,MAAM,EAAE,GAAG,QAAQ,eAAe,KAAK,oBAAoB,EAAE;AAAA,QAC7D,GAAG;AAAA;AAAA;AAAA;AAAA,QAIH,SAAS;AAAA,UACP,GAAG,cAAc,KAAK,UAAU,SAAS,OAAO,GAAG,cAAc;AAAA,UACjE,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,gBACJ,SACA,SACkC;AAClC,UAAM,EAAE,WAAW,qBAAqB,GAAG,OAAO,IAAI,WAAW,CAAC;AAClE,WAAO,KAAK,OAAO,QAAQ,OAAO,GAAG,KAAK,QAAQ,qBAAqB;AAAA,MACrE,OAAO,YACH;AAAA,QACE,IAAI;AAAA,QACJ,YAAY;AAAA,QACZ,GAAI,sBAAsB,EAAE,uBAAuB,oBAAoB,IAAI,CAAC;AAAA,MAC9E,IACA,EAAE,IAAI,QAAQ;AAAA,MAClB,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,OAAO,OAAO;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,oBAAoB,SAA+D;AACvF,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,0BAA0B;AAAA,MAC3E,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,sBACJ,QACA,SACwC;AACxC,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,4BAA4B;AAAA,MAC7E,MAAM;AAAA,MACN,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,YACJ,QACA,SACkD;AAClD,UAAM,UAAU,KAAK,cAAc,SAAS,OAAO;AACnD,QAAI;AACF,aAAO,MAAM,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,oBAAoB;AAAA,QAC3E,MAAM;AAAA,QACN,WAAW;AAAA,QACX,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,sBACJ,QACA,SACwC;AACxC,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,6BAA6B;AAAA,MAC9E,GAAG;AAAA,MACH,MAAM;AAAA,MACN,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,wBACJ,QACA,SAC0C;AAC1C,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,8BAA8B;AAAA,MAC/E,GAAG;AAAA,MACH,MAAM;AAAA,MACN,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,oBACJ,SACA,QACsC;AACtC,UAAM,OAAO,QAAQ;AACrB,WAAO,KAAK,OAAO,QAAQ,OAAO,GAAG,KAAK,QAAQ,0BAA0B;AAAA,MAC1E,GAAG;AAAA,MACH,OAAO;AAAA,QACL,QAAQ,QAAQ;AAAA,QAChB,cAAc,MAAM;AAAA,QACpB,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB,aAAa,MAAM;AAAA,QACnB,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,aAAa,MAAM;AAAA,MACrB;AAAA,MACA,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,yBACJ,cACA,SAC4B;AAC5B,WAAO,KAAK,OAAO,QAAQ,OAAO,GAAG,KAAK,QAAQ,gCAAgC;AAAA,MAChF,GAAG;AAAA,MACH,OAAO,EAAE,eAAe,aAAa;AAAA,MACrC,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,2BACJ,QACA,SACqC;AACrC,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,yBAAyB;AAAA,MAC1E,MAAM;AAAA,MACN,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmCA,MAAM,sBACJ,QACA,SACsC;AACtC,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,mBAAmB;AAAA,MACpE,MAAM;AAAA,MACN,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,aACJ,QACA,SACsC;AACtC,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,WAAW;AAAA,MAC5D,MAAM;AAAA,MACN,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,yBACJ,QACA,SAC2C;AAC3C,WAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG,KAAK,QAAQ,+BAA+B;AAAA,MAChF,MAAM;AAAA,MACN,GAAG;AAAA,MACH,SAAS,KAAK,cAAc,SAAS,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAAgB,SAAmD;AACvE,WAAO,KAAK,OAAO,QAAQ,OAAO,aAAa,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,MACnF,OAAO,EAAE,eAAe,KAAK,oBAAoB,EAAE;AAAA,MACnD,GAAG;AAAA,MACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,QACA,SAC0B;AAC1B,WAAO,KAAK,OAAO,QAAQ,QAAQ,aAAa,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,MACpF,MAAM,EAAE,GAAG,QAAQ,eAAe,KAAK,oBAAoB,EAAE;AAAA,MAC7D,GAAG;AAAA,MACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eACJ,QACA,SAC0B;AAC1B,WAAO,KAAK,OAAO,QAAQ,QAAQ,aAAa,mBAAmB,KAAK,SAAS,CAAC,YAAY;AAAA,MAC5F,MAAM,EAAE,GAAG,QAAQ,eAAe,KAAK,oBAAoB,EAAE;AAAA,MAC7D,GAAG;AAAA,MACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,kBACJ,QACA,SAC4C;AAC5C,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,aAAa,mBAAmB,KAAK,SAAS,CAAC;AAAA,MAC/C;AAAA,QACE,MAAM,EAAE,GAAG,QAAQ,eAAe,KAAK,oBAAoB,EAAE;AAAA,QAC7D,GAAG;AAAA,QACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,eAAe,SAAiE;AACpF,WAAO,KAAK,OAAO;AAAA,MACjB;AAAA,MACA,aAAa,mBAAmB,KAAK,SAAS,CAAC;AAAA,MAC/C;AAAA,QACE,MAAM,EAAE,eAAe,KAAK,oBAAoB,EAAE;AAAA,QAClD,GAAG;AAAA,QACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,mBACJ,QACA,SACoC;AACpC,WAAO,KAAK,OAAO,QAAQ,OAAO,oBAAoB;AAAA,MACpD,OAAO,EAAE,eAAe,KAAK,oBAAoB,GAAG,SAAS,QAAQ,QAAQ;AAAA,MAC7E,GAAG;AAAA,MACH,SAAS,KAAK,UAAU,SAAS,OAAO;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;;;AC/2BA,IAAM,oBAA+C,CAAC,UAAU,iBAAiB,eAAe;AAMhG,SAAS,gBAAgB,KAA8B;AACrD,SAAO,QAAQ,WAAW,QAAQ,cAAc,MAAM;AACxD;AAEA,SAAS,gBAAgB,KAA8B;AACrD,SAAO,kBAAkB,KAAK,CAAC,UAAU,UAAU,GAAG,KAAK;AAC7D;AAEA,IAAM,uBAAqD;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AACF;AAYA,SAAS,mBAAmB,KAAiC;AAC3D,SAAO,qBAAqB,KAAK,CAAC,UAAU,UAAU,GAAG,KAAK;AAChE;AA4EO,SAAS,mBACd,MACgB;AAChB,QAAM,WAAW,kBAAkB,KAAK,CAAC,UAAU,UAAU,KAAK,UAAU;AAC5E,MAAI,SAAU,QAAO;AACrB,SAAO,KAAK,kBAAkB,OAAO,kBAAkB;AACzD;AAiEO,IAAM,+BAA0D;AAAA,EACrE;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA;AAAA,IAEnB,wBAAwB;AAAA,IACxB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AACF;AAQO,IAAM,+BAAsD;AAAA,EACjE,WAAW;AAAA,EACX,eAAe,CAAC,UAAU,UAAU;AAAA,EACpC,SAAS,6BAA6B,IAAI,CAAC,UAAU;AAAA,IACnD,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,IACX,gBAAgB,KAAK;AAAA,IACrB,qBAAqB,KAAK;AAAA,IAC1B,0BAA0B,KAAK;AAAA,EACjC,EAAE;AACJ;AAOO,SAAS,iBAAiB,WAA0C;AACzE,SAAO,EAAE,WAAW,eAAe,CAAC,GAAG,SAAS,CAAC,EAAE;AACrD;AAUO,SAAS,eACd,UACA,WACuB;AACvB,SACE,SAAS,WAAW,KAAK,CAAC,UAAU,MAAM,cAAc,SAAS,KACjE,iBAAiB,SAAS;AAE9B;AAWO,IAAM,iBAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,EACA;AAAA,EACA;AACF;AAgBO,IAAM,qBAAwC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,YAAY;AAUlB,SAAS,eACd,QACA,UAAiC,8BACL;AAC5B,SAAO,QAAQ,QAAQ,KAAK,CAAC,SAAS,KAAK,QAAQ,MAAM;AAC3D;AAMO,SAAS,gBAAgB,MAAgB,SAAyC;AACvF,SAAO,QAAQ,cAAc,SAAS,IAAI;AAC5C;AAYO,SAAS,qBAAqB,SAAkD;AACrF,SAAO,QAAQ,QAAQ,OAAO,CAAC,SAAS,gBAAgB,KAAK,MAAM,OAAO,CAAC;AAC7E;AAuBA,IAAM,0BAAyE;AAAA,EAC7E,WAAW,EAAE,MAAM,SAAS,UAAU,SAAS;AAAA,EAC/C,YAAY,EAAE,MAAM,UAAU,UAAU,SAAS;AAAA,EACjD,QAAQ,EAAE,MAAM,UAAU,UAAU,SAAS;AAAA;AAAA;AAAA,EAG7C,QAAQ,EAAE,MAAM,UAAU,UAAU,OAAO;AAC7C;AAQA,IAAM,qCAAoF;AAAA,EACxF,QAAQ,EAAE,MAAM,UAAU,UAAU,SAAS;AAAA,EAC7C,MAAM,EAAE,MAAM,QAAQ,UAAU,OAAO;AAAA,EACvC,eAAe,EAAE,MAAM,QAAQ,UAAU,OAAO;AAAA,EAChD,WAAW,EAAE,MAAM,QAAQ,UAAU,OAAO;AAAA,EAC5C,eAAe,EAAE,MAAM,QAAQ,UAAU,gBAAgB;AAAA,EACzD,eAAe,EAAE,MAAM,QAAQ,UAAU,gBAAgB;AAAA,EACzD,YAAY,EAAE,MAAM,QAAQ,UAAU,gBAAgB;AAAA;AAAA;AAAA,EAGtD,QAAQ,EAAE,MAAM,UAAU,UAAU,SAAS;AAAA;AAAA,EAE7C,YAAY,EAAE,MAAM,UAAU,UAAU,aAAa;AAAA,EACrD,MAAM,EAAE,MAAM,QAAQ,UAAU,OAAO;AAAA,EACvC,SAAS,EAAE,MAAM,QAAQ,UAAU,OAAO;AAC5C;AAEA,IAAM,4BAAiD,EAAE,MAAM,UAAU,UAAU,SAAS;AAWrF,SAAS,oBAAoB,MAAuD;AACzF,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,wBAAwB,KAAK,GAAG,KAChC,mCAAmC,KAAK,cAAc,KACtD;AAEJ;AAoCO,SAAS,cACd,OACA,UAAiC,8BACpB;AACb,QAAM,SAAsB,CAAC;AAK7B,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,UAAM,OAAO,eAAe,KAAK,QAAQ,OAAO;AAChD,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,EAAE,OAAO,QAAQ,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAAA,IACpE,WAAW,CAAC,gBAAgB,KAAK,MAAM,OAAO,GAAG;AAC/C,aAAO,KAAK,EAAE,OAAO,QAAQ,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAAA,IACtE,WAAW,KAAK,SAAS;AAIvB,UAAI,UAAU,IAAI,KAAK,GAAG,GAAG;AAC3B,eAAO,KAAK,EAAE,OAAO,QAAQ,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAAA,MACtE,OAAO;AACL,kBAAU,IAAI,KAAK,GAAG;AAAA,MACxB;AAAA,IACF;AACA,QAAI,SAAS,UAAW,QAAO,KAAK,EAAE,OAAO,QAAQ,KAAK,QAAQ,MAAM,WAAW,CAAC;AAAA,EACtF,CAAC;AACD,SAAO;AACT;AAgBO,SAAS,YACd,QACA,UAAiC,8BAC3B;AACN,QAAM,WAAW,oBAAoB,eAAe,QAAQ,OAAO,CAAC;AACpE,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT,OAAO;AAAA,IACP,mBAAmB,CAAC;AAAA,IACpB,UAAU;AAAA,IACV,sBAAsB,CAAC;AAAA,IACvB,UAAU,SAAS;AAAA,IACnB,MAAM,SAAS;AAAA,IACf,SAAS;AAAA,IACT,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACF;AAEO,SAAS,UAAU,MAAkB;AAC1C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,mBAAmB,EAAE,GAAG,KAAK,kBAAkB;AAAA,IAC/C,sBAAsB,EAAE,GAAG,KAAK,qBAAqB;AAAA,EACvD;AACF;AAEA,SAASC,UAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAASC,mBAAkB,KAAsC;AAC/D,MAAI,CAACD,UAAS,GAAG,EAAG,QAAO,CAAC;AAC5B,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,QAAQ,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AACjD,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,KAAI,MAAM,IAAI;AAAA,EACnE;AACA,SAAO;AACT;AAEA,SAAS,IAAI,KAAsB;AACjC,SAAO,OAAO,QAAQ,WAAW,MAAM;AACzC;AAOA,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAE1B,SAAS,kBAAkB,KAAqB;AAC9C,MAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,SAAO,KAAK,IAAI,mBAAmB,KAAK,IAAI,mBAAmB,KAAK,MAAM,GAAG,CAAC,CAAC;AACjF;AAgBO,SAAS,YAAY,KAA6B;AACvD,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO;AAChC,QAAM,YAAY,CAAC,OAAgC,YAA0B;AAAA,IAC3E;AAAA,IACA,SAAS,MAAM,SAAS,MAAM;AAAA,IAC9B,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,IACzB,mBAAmBC,mBAAkB,MAAM,oBAAoB,CAAC;AAAA,IAChE,UAAU,OAAO,MAAM,UAAU,MAAM,WAAW,MAAM,UAAU,IAAI;AAAA,IACtE,sBAAsBA,mBAAkB,MAAM,uBAAuB,CAAC;AAAA,IACtE,UAAU,IAAI,MAAM,UAAU,CAAC;AAAA,IAC/B,MAAM,IAAI,MAAM,MAAM,CAAC;AAAA,IACvB,SAAS,IAAI,MAAM,UAAU,CAAC;AAAA,IAC9B,cAAc,kBAAkB,OAAO,MAAM,eAAe,CAAC,CAAC;AAAA;AAAA,IAE9D,YAAY,gBAAgB,MAAM,YAAY,CAAC;AAAA;AAAA,IAE/C,QAAQ,gBAAgB,MAAM,SAAS,CAAC;AAAA,IACxC,eAAe,mBAAmB,MAAM,gBAAgB,CAAC;AAAA,IACzD,QAAQ,IAAI,MAAM,QAAQ,CAAC;AAAA,IAC3B,OAAO,IAAI,MAAM,OAAO,CAAC;AAAA,EAC3B;AAEA,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,QAAM,MAAc,CAAC;AACrB,aAAW,SAAS,KAAK;AACvB,QAAI,IAAI,UAAU,UAAW;AAC7B,QAAI,CAACD,UAAS,KAAK,EAAG;AACtB,UAAM,SAAS,IAAI,MAAM,QAAQ,CAAC,EAAE,KAAK;AACzC,QAAI,CAAC,OAAQ;AACb,UAAM,OAAO,cAAc,IAAI,MAAM;AACrC,QAAI,SAAS,QAAW;AAMtB,YAAM,UAAU,MAAM,SAAS,MAAM;AACrC,YAAM,WAAW,IAAI,IAAI;AACzB,UAAI,WAAW,YAAY,CAAC,SAAS,QAAS,KAAI,IAAI,IAAI,UAAU,OAAO,MAAM;AACjF;AAAA,IACF;AACA,kBAAc,IAAI,QAAQ,IAAI,MAAM;AACpC,QAAI,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,EACnC;AACA,SAAO;AACT;AAWO,SAAS,YAAY,OAA0C;AACpE,QAAM,WAAW,CAAC,QAAoE;AACpF,UAAM,UAAU,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;AACzE,WAAO,QAAQ,SAAS,IAAI,OAAO,YAAY,OAAO,IAAI;AAAA,EAC5D;AACA,SAAO,MAAM,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC,SAAS;AAC7C,UAAM,oBAAoB,SAAS,KAAK,iBAAiB;AACzD,UAAM,uBAAuB,SAAS,KAAK,oBAAoB;AAC/D,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,GAAI,KAAK,MAAM,KAAK,IAAI,EAAE,OAAO,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC;AAAA,MACxD,GAAI,oBAAoB,EAAE,oBAAoB,kBAAkB,IAAI,CAAC;AAAA;AAAA;AAAA,MAGrE,GAAI,KAAK,aAAa,OAAO,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MAC5D,GAAI,uBAAuB,EAAE,uBAAuB,qBAAqB,IAAI,CAAC;AAAA,MAC9E,GAAI,KAAK,SAAS,KAAK,IAAI,EAAE,UAAU,KAAK,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,MACjE,GAAI,KAAK,KAAK,KAAK,IAAI,EAAE,MAAM,KAAK,KAAK,KAAK,EAAE,IAAI,CAAC;AAAA,MACrD,GAAI,KAAK,QAAQ,KAAK,IAAI,EAAE,UAAU,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,MAK/D,eAAe,kBAAkB,KAAK,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMlD,YAAY,gBAAgB,KAAK,UAAU;AAAA,MAC3C,SAAS,gBAAgB,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAKpC,GAAI,mBAAmB,KAAK,aAAa,MAAM,eAC3C,CAAC,IACD,EAAE,gBAAgB,mBAAmB,KAAK,aAAa,EAAE;AAAA;AAAA;AAAA,MAG7D,IAAK,KAAK,UAAU,IAAI,KAAK,IAAI,EAAE,SAAS,KAAK,UAAU,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,MAC3E,IAAK,KAAK,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,KAAK,SAAS,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,IAC1E;AAAA,EACF,CAAC;AACH;AAQA,IAAM,yBAAyB;AAwFxB,SAAS,mBAAmB,QAA0C;AAC3E,QAAM,OAAO,OAAO,gBAAgB,QAAQ,QAAQ,EAAE;AACtD,QAAM,OACJ,OAAO,iBAAiB,uBAAuB,KAAK,OAAO,aAAa,IACpE,GAAG,IAAI,QAAQ,OAAO,aAAa,KACnC,GAAG,IAAI,QAAQ,mBAAmB,OAAO,UAAU,CAAC,IAAI;AAAA,IACtD,OAAO;AAAA,EACT,CAAC;AACP,QAAM,QAAQ,IAAI,gBAAgB,EAAE,MAAM,OAAO,OAAO,CAAC;AAMzD,QAAM,YAAY,OAAO,WAAW,KAAK;AACzC,MAAI,UAAW,OAAM,IAAI,aAAa,SAAS;AAC/C,QAAM,sBAAsB,OAAO,qBAAqB,KAAK;AAC7D,MAAI,oBAAqB,OAAM,IAAI,OAAO,mBAAmB;AAC7D,MAAI,OAAO,OAAQ,OAAM,IAAI,UAAU,OAAO,MAAM;AACpD,MAAI,OAAO,sBAAuB,OAAM,IAAI,MAAM,GAAG;AACrD,SAAO,GAAG,IAAI,IAAI,MAAM,SAAS,CAAC;AACpC;AAaO,IAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiDO,IAAM,6BAA6B;AAEnC,IAAM,wBAAwB;AAE9B,IAAM,4BAA4B;AAElC,IAAM,mBAAmB;AAWzB,SAAS,qBAAqB,QAA4C;AAC/E,SAAO,6BAA6B,KAAK,CAAC,SAAS,KAAK,QAAQ,MAAM;AACxE;AAYO,SAAS,kBAAkB,QAAsB;AACtD,QAAM,OAAO,qBAAqB,MAAM;AACxC,SAAO;AAAA,IACL,GAAG,YAAY,MAAM;AAAA,IACrB,UAAU;AAAA,IACV,MAAM,MAAM,eAAe;AAAA,EAC7B;AACF;AAGO,IAAM,kBAAkB;AAExB,IAAM,oBAAoB;AAE1B,IAAM,oBAAoB;","names":["received","bytes","text","s","isObject","parseTranslations"]}
|