@slvr-labs/sdk 0.1.0 → 0.1.2

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.
Files changed (83) hide show
  1. package/README.md +42 -0
  2. package/dist/index.d.mts +2117 -0
  3. package/dist/index.d.ts +1903 -34
  4. package/dist/index.js +3091 -427
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +3035 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +19 -11
  9. package/skills/slvr-bot/SKILL.md +9 -8
  10. package/skills/slvr-bot/references/api.md +8 -0
  11. package/dist/connect.d.ts +0 -47
  12. package/dist/connect.d.ts.map +0 -1
  13. package/dist/connect.js +0 -56
  14. package/dist/connect.js.map +0 -1
  15. package/dist/contracts/autoCommit.d.ts +0 -151
  16. package/dist/contracts/autoCommit.d.ts.map +0 -1
  17. package/dist/contracts/autoCommit.js +0 -426
  18. package/dist/contracts/autoCommit.js.map +0 -1
  19. package/dist/contracts/hub.d.ts +0 -50
  20. package/dist/contracts/hub.d.ts.map +0 -1
  21. package/dist/contracts/hub.js +0 -118
  22. package/dist/contracts/hub.js.map +0 -1
  23. package/dist/contracts/index.d.ts +0 -8
  24. package/dist/contracts/index.d.ts.map +0 -1
  25. package/dist/contracts/index.js +0 -18
  26. package/dist/contracts/index.js.map +0 -1
  27. package/dist/contracts/jackpot.d.ts +0 -21
  28. package/dist/contracts/jackpot.d.ts.map +0 -1
  29. package/dist/contracts/jackpot.js +0 -44
  30. package/dist/contracts/jackpot.js.map +0 -1
  31. package/dist/contracts/lottery.d.ts +0 -256
  32. package/dist/contracts/lottery.d.ts.map +0 -1
  33. package/dist/contracts/lottery.js +0 -767
  34. package/dist/contracts/lottery.js.map +0 -1
  35. package/dist/contracts/registry.d.ts +0 -53
  36. package/dist/contracts/registry.d.ts.map +0 -1
  37. package/dist/contracts/registry.js +0 -143
  38. package/dist/contracts/registry.js.map +0 -1
  39. package/dist/contracts/staking.d.ts +0 -101
  40. package/dist/contracts/staking.d.ts.map +0 -1
  41. package/dist/contracts/staking.js +0 -306
  42. package/dist/contracts/staking.js.map +0 -1
  43. package/dist/contracts/token.d.ts +0 -95
  44. package/dist/contracts/token.d.ts.map +0 -1
  45. package/dist/contracts/token.js +0 -273
  46. package/dist/contracts/token.js.map +0 -1
  47. package/dist/deployments.d.ts +0 -117
  48. package/dist/deployments.d.ts.map +0 -1
  49. package/dist/deployments.js +0 -74
  50. package/dist/deployments.js.map +0 -1
  51. package/dist/errors.d.ts +0 -39
  52. package/dist/errors.d.ts.map +0 -1
  53. package/dist/errors.js +0 -67
  54. package/dist/errors.js.map +0 -1
  55. package/dist/ev.d.ts +0 -123
  56. package/dist/ev.d.ts.map +0 -1
  57. package/dist/ev.js +0 -111
  58. package/dist/ev.js.map +0 -1
  59. package/dist/events.d.ts +0 -418
  60. package/dist/events.d.ts.map +0 -1
  61. package/dist/events.js +0 -87
  62. package/dist/events.js.map +0 -1
  63. package/dist/index.d.ts.map +0 -1
  64. package/dist/oracle.d.ts +0 -48
  65. package/dist/oracle.d.ts.map +0 -1
  66. package/dist/oracle.js +0 -77
  67. package/dist/oracle.js.map +0 -1
  68. package/dist/price.d.ts +0 -52
  69. package/dist/price.d.ts.map +0 -1
  70. package/dist/price.js +0 -78
  71. package/dist/price.js.map +0 -1
  72. package/dist/transaction.d.ts +0 -54
  73. package/dist/transaction.d.ts.map +0 -1
  74. package/dist/transaction.js +0 -105
  75. package/dist/transaction.js.map +0 -1
  76. package/dist/types.d.ts +0 -162
  77. package/dist/types.d.ts.map +0 -1
  78. package/dist/types.js +0 -23
  79. package/dist/types.js.map +0 -1
  80. package/dist/utils.d.ts +0 -58
  81. package/dist/utils.d.ts.map +0 -1
  82. package/dist/utils.js +0 -110
  83. package/dist/utils.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/contracts/lottery.ts","../src/errors.ts","../src/utils.ts","../src/events.ts","../src/contracts/staking.ts","../src/contracts/token.ts","../src/contracts/autoCommit.ts","../src/contracts/hub.ts","../src/contracts/registry.ts","../src/contracts/jackpot.ts","../src/price.ts","../src/oracle.ts","../src/ev.ts","../src/connect.ts","../src/deployments.ts","../src/types.ts","../src/transaction.ts"],"sourcesContent":["import { PublicClient, WalletClient, Address, formatEther } from 'viem';\nimport { SlvrConfig, PriceQuote } from './types';\nimport { SlvrGridLottery } from './contracts/lottery';\nimport { SlvrStaking } from './contracts/staking';\nimport { SlvrToken } from './contracts/token';\nimport { SlvrAutoCommit } from './contracts/autoCommit';\nimport { SlvrHub } from './contracts/hub';\nimport { SlvrGameRegistry } from './contracts/registry';\nimport { SlvrJackpot } from './contracts/jackpot';\nimport { SlvrPrice } from './price';\nimport { ChainlinkPriceFeed } from './oracle';\nimport { computeGridMiningEv, GridMiningEv } from './ev';\nimport { createSlvrClients, ConnectOptions } from './connect';\nimport { robinhood } from './deployments';\nimport { ValidationError } from './errors';\n\n/**\n * Main Slvr SDK class\n * \n * @example\n * ```typescript\n * import { createPublicClient, createWalletClient, http } from 'viem';\n * import { SlvrSDK } from '@slvr-labs/sdk';\n * \n * const publicClient = createPublicClient({\n * chain: robinhoodChain,\n * transport: http(),\n * });\n * \n * const walletClient = createWalletClient({\n * chain: robinhoodChain,\n * transport: http(),\n * account: yourAccount,\n * });\n * \n * const sdk = new SlvrSDK({\n * publicClient,\n * walletClient,\n * addresses: {\n * lottery: '0x...',\n * staking: '0x...',\n * token: '0x...',\n * },\n * });\n * \n * // Get current round\n * const roundId = await sdk.lottery.currentRoundId();\n * \n * // Place a bet\n * await sdk.lottery.bet({\n * roundId,\n * squares: [0, 1, 2],\n * amounts: [1000000000000000000n, 2000000000000000000n, 3000000000000000000n],\n * });\n * ```\n */\nexport class SlvrSDK {\n public readonly lottery: SlvrGridLottery;\n public readonly staking: SlvrStaking;\n public readonly token: SlvrToken;\n public readonly autoCommit?: SlvrAutoCommit;\n public readonly hub?: SlvrHub;\n public readonly registry?: SlvrGameRegistry;\n public readonly jackpot?: SlvrJackpot;\n /** SLVR/ETH spot price reader — present when a `slvrEthPair` address is configured. */\n public readonly price?: SlvrPrice;\n /** Chainlink ETH/USD feed reader — present when a `chainlinkEthUsd` address is configured. */\n public readonly ethUsd?: ChainlinkPriceFeed;\n\n private config: SlvrConfig;\n\n constructor(config: SlvrConfig) {\n this.config = config;\n\n // Initialize core contracts\n this.lottery = new SlvrGridLottery(\n config.publicClient,\n config.walletClient,\n config.addresses.lottery\n );\n\n this.staking = new SlvrStaking(\n config.publicClient,\n config.walletClient,\n config.addresses.staking\n );\n\n this.token = new SlvrToken(\n config.publicClient,\n config.walletClient,\n config.addresses.token\n );\n\n // Initialize optional contracts\n if (config.addresses.autoCommit) {\n this.autoCommit = new SlvrAutoCommit(\n config.publicClient,\n config.walletClient,\n config.addresses.autoCommit\n );\n }\n\n if (config.addresses.hub) {\n this.hub = new SlvrHub(\n config.publicClient,\n config.walletClient,\n config.addresses.hub\n );\n }\n\n if (config.addresses.registry) {\n this.registry = new SlvrGameRegistry(\n config.publicClient,\n config.walletClient,\n config.addresses.registry\n );\n }\n\n if (config.addresses.jackpot) {\n this.jackpot = new SlvrJackpot(\n config.publicClient,\n config.walletClient,\n config.addresses.jackpot\n );\n }\n\n // Price reader needs the pair address; SLVR side is resolved from the token address.\n if (config.addresses.slvrEthPair) {\n this.price = new SlvrPrice(\n config.publicClient,\n config.addresses.slvrEthPair,\n config.addresses.token\n );\n }\n\n // ETH/USD feed (optional; only on chains that have a Chainlink aggregator).\n if (config.addresses.chainlinkEthUsd) {\n this.ethUsd = new ChainlinkPriceFeed(config.publicClient, config.addresses.chainlinkEthUsd);\n }\n }\n\n /**\n * One-line setup: build clients (with Multicall3 batching + resilient transport\n * defaults) and an SDK for a deployment. Pass a `privateKey`/`account` to enable\n * writes; omit it for a read-only SDK.\n *\n * @example\n * ```typescript\n * import { SlvrSDK } from '@slvr-labs/sdk';\n * const sdk = SlvrSDK.connect(); // read-only, Robinhood Chain\n * const bot = SlvrSDK.connect({ privateKey: process.env.PK }); // wallet-backed\n * ```\n */\n static connect(opts: ConnectOptions = {}): SlvrSDK {\n const deployment = opts.deployment ?? robinhood;\n const { publicClient, walletClient } = createSlvrClients(opts);\n return new SlvrSDK({ publicClient, walletClient, addresses: deployment.addresses });\n }\n\n /**\n * Get the public client\n */\n getPublicClient(): PublicClient {\n return this.config.publicClient;\n }\n\n /**\n * Get the wallet client (if available)\n */\n getWalletClient(): WalletClient | undefined {\n return this.config.walletClient;\n }\n\n /**\n * Update the wallet client and reinitialize contracts\n * @param walletClient New wallet client (or undefined to remove)\n */\n setWalletClient(walletClient: WalletClient | undefined): void {\n this.config.walletClient = walletClient;\n \n // Reinitialize contracts with new wallet client\n this.lottery.setWalletClient(walletClient);\n this.staking.setWalletClient(walletClient);\n this.token.setWalletClient(walletClient);\n if (this.autoCommit) {\n this.autoCommit.setWalletClient(walletClient);\n }\n if (this.hub) {\n this.hub.setWalletClient(walletClient);\n }\n if (this.registry) {\n this.registry.setWalletClient(walletClient);\n }\n if (this.jackpot) {\n this.jackpot.setWalletClient(walletClient);\n }\n }\n\n /**\n * Helper: Calculate bet amounts from percentages\n * @param totalAmount Total amount to bet\n * @param percentages Array of percentages (0-100) for each square\n * @returns Array of amounts in wei\n * @throws ValidationError if percentages don't sum to 100 or if totalAmount is invalid\n */\n static calculateBetAmounts(totalAmount: bigint, percentages: number[]): bigint[] {\n if (percentages.length === 0) {\n throw new ValidationError('Percentages array cannot be empty', 'percentages');\n }\n \n const totalPercent = percentages.reduce((sum, p) => sum + p, 0);\n if (Math.abs(totalPercent - 100) > 0.01) {\n throw new ValidationError(`Percentages must sum to 100 (got ${totalPercent})`, 'percentages');\n }\n\n const amounts: bigint[] = [];\n let allocated = 0n;\n\n for (let i = 0; i < percentages.length; i++) {\n const percentage = percentages[i];\n if (percentage === undefined) continue;\n const amount = (totalAmount * BigInt(Math.round(percentage * 100))) / 10000n;\n amounts.push(amount);\n allocated += amount;\n }\n\n // Adjust first amount to account for rounding\n if (allocated !== totalAmount && amounts.length > 0 && amounts[0] !== undefined) {\n amounts[0] += totalAmount - allocated;\n }\n\n return amounts;\n }\n\n /**\n * Helper: Format bigint to human-readable string.\n *\n * `precision` caps the number of decimal places shown; trailing zeros are\n * stripped (like viem's `formatEther`), so `formatToken(1.5e18)` is `\"1.5\"`,\n * not `\"1.5000\"`.\n * @param value Value in wei\n * @param decimals Number of decimals (default 18)\n * @param precision Max decimal places to show (default 4)\n */\n static formatToken(value: bigint, decimals: number = 18, precision: number = 4): string {\n const divisor = BigInt(10 ** decimals);\n const whole = value / divisor;\n const remainder = value % divisor;\n const fractional = (remainder * BigInt(10 ** precision)) / divisor;\n\n if (fractional === 0n) {\n return whole.toString();\n }\n\n const fractionalStr = fractional.toString().padStart(precision, '0').replace(/0+$/, '');\n return fractionalStr ? `${whole}.${fractionalStr}` : whole.toString();\n }\n\n /**\n * Helper: Parse human-readable string to bigint\n * @param value Human-readable value (e.g., \"1.5\")\n * @param decimals Number of decimals (default 18)\n */\n static parseToken(value: string, decimals: number = 18): bigint {\n const parts = value.split('.');\n const whole = BigInt(parts[0] || '0');\n const fractional = parts[1] ? BigInt(parts[1].padEnd(decimals, '0').slice(0, decimals)) : 0n;\n return whole * BigInt(10 ** decimals) + fractional;\n }\n\n /**\n * Helper: Calculate time remaining until round ends\n * @param roundId Round ID\n * @returns Time remaining in seconds, or 0 if round has ended\n */\n async getTimeRemaining(roundId: bigint): Promise<number> {\n // Use the chain's clock, not the local one — device time can drift (and on a\n // local anvil chain diverges hard), which would make this wildly wrong.\n const [roundEnd, block] = await Promise.all([\n this.lottery.roundEnd(roundId),\n this.config.publicClient.getBlock(),\n ]);\n const remaining = roundEnd - block.timestamp;\n return remaining > 0n ? Number(remaining) : 0;\n }\n\n /**\n * Helper: Check if user can claim rewards for a round\n * @param roundId Round ID\n * @param user User address\n * @returns True if user can claim\n */\n async canClaim(roundId: bigint, user: Address): Promise<boolean> {\n const [round, hasClaimed_] = await Promise.all([\n this.lottery.getRound(roundId),\n this.lottery.getHasClaimed(roundId, user),\n ]);\n\n if (!round.resolved || hasClaimed_) {\n return false;\n }\n\n // Check if user has a bet on the winning square\n const userBet = await this.lottery.getUserBet(roundId, round.winningSquare, user);\n return userBet > 0n;\n }\n\n /**\n * Helper: Get user's claimable rounds\n * @param user User address\n * @param startRoundId Start round ID to check from\n * @param endRoundId End round ID to check to\n * @returns Array of round IDs that can be claimed\n */\n async getClaimableRounds(user: Address, startRoundId: bigint, endRoundId: bigint): Promise<bigint[]> {\n const rounds: bigint[] = [];\n for (let roundId = startRoundId; roundId <= endRoundId; roundId++) {\n rounds.push(roundId);\n }\n // Check all rounds concurrently — with a multicall-batching client the\n // underlying reads collapse into a few RPC calls instead of one per round.\n const flags = await Promise.all(rounds.map((roundId) => this.canClaim(roundId, user)));\n return rounds.filter((_, i) => flags[i]);\n }\n\n /**\n * Helper: Compute a game's effective SLVR/sec emission rate.\n *\n * Mirrors SlvrHub._effectiveRatePerSec: the game's weighted share of the global emission stream,\n * i.e. emissionRatePerSec * weightOf(gameId) / totalActiveWeight. NOTE: this does not apply the\n * per-game maxWeightBps ceiling that the contract also enforces; it is the pre-cap weighted rate.\n *\n * Requires both `hub` and `registry` addresses to be configured.\n * @param gameId Registry game id\n * @returns Effective emission rate in SLVR/sec (0 if there is no active weight)\n */\n async effectiveEmissionRate(gameId: bigint): Promise<bigint> {\n if (!this.hub) {\n throw new ValidationError('hub address is required for effectiveEmissionRate', 'hub');\n }\n if (!this.registry) {\n throw new ValidationError('registry address is required for effectiveEmissionRate', 'registry');\n }\n\n const [rate, weight, totalWeight] = await Promise.all([\n this.hub.emissionRatePerSec(),\n this.registry.weightOf(gameId),\n this.registry.totalActiveWeight(),\n ]);\n\n if (totalWeight === 0n) {\n return 0n;\n }\n\n return (rate * weight) / totalWeight;\n }\n\n /**\n * Helper: Get the accrued-but-unminted SLVR emission currently available to a game.\n *\n * Thin pass-through to SlvrHub.pendingEmission. Requires `hub` to be configured.\n * @param gameId Registry game id\n */\n async pendingEmission(gameId: bigint): Promise<bigint> {\n if (!this.hub) {\n throw new ValidationError('hub address is required for pendingEmission', 'hub');\n }\n return await this.hub.pendingEmission(gameId);\n }\n\n /**\n * Helper: current SLVR spot price in ETH (ETH per SLVR).\n *\n * Requires a `slvrEthPair` address to be configured (so `sdk.price` exists).\n * @throws ValidationError if no pair address was configured.\n */\n async getSlvrPriceInEth(): Promise<number> {\n if (!this.price) {\n throw new ValidationError('slvrEthPair address is required for getSlvrPriceInEth', 'slvrEthPair');\n }\n return await this.price.getPriceInEth();\n }\n\n /**\n * Helper: current ETH price in USD from the configured Chainlink feed.\n *\n * Requires a `chainlinkEthUsd` address (so `sdk.ethUsd` exists). This is wired\n * for Robinhood Chain in `deployments.robinhood`; on chains without a feed,\n * supply one or pass `ethUsd` to {@link getSlvrPrice}.\n * @throws ValidationError if no ETH/USD feed was configured.\n */\n async getEthPriceUsd(): Promise<number> {\n if (!this.ethUsd) {\n throw new ValidationError('chainlinkEthUsd address is required for getEthPriceUsd', 'chainlinkEthUsd');\n }\n return await this.ethUsd.getPrice();\n }\n\n /**\n * Helper: current SLVR price in **both ETH and USD**.\n *\n * SLVR/ETH comes from the UniswapV2 pair (`sdk.price`). The USD value uses, in\n * order: an explicit `opts.ethUsd`, else the configured Chainlink ETH/USD feed\n * (`sdk.ethUsd`), else `usd` is `null`.\n *\n * @param opts.ethUsd override the ETH/USD price (e.g. from your own off-chain source)\n * @throws ValidationError if no `slvrEthPair` was configured.\n *\n * @example\n * ```typescript\n * const { eth, usd } = await sdk.getSlvrPrice(); // uses Chainlink feed if configured\n * const q = await sdk.getSlvrPrice({ ethUsd: 1797.35 }); // or supply ETH/USD yourself\n * ```\n */\n async getSlvrPrice(opts?: { ethUsd?: number }): Promise<PriceQuote> {\n if (!this.price) {\n throw new ValidationError('slvrEthPair address is required for getSlvrPrice', 'slvrEthPair');\n }\n const eth = await this.price.getPriceInEth();\n let ethUsd = opts?.ethUsd;\n if (ethUsd === undefined && this.ethUsd) {\n ethUsd = await this.ethUsd.getPrice();\n }\n return { eth, usd: ethUsd !== undefined ? eth * ethUsd : null };\n }\n\n /**\n * Helper: estimate the per-round expected value of grid mining for the given\n * stake, pulling live pot, emission and SLVR price on-chain.\n *\n * This is the SDK-level convenience around {@link computeGridMiningEv}: it reads\n * the round's pot (sum of all squares), the emission target (`slvrPerRound`), the\n * protocol fee (`protocolFeeBps`), and the SLVR price (via `sdk.price`), then\n * returns the full EV breakdown. Any of those can be overridden via `params`.\n *\n * The jackpot pool is **not** auto-read (it isn't exposed as a single call on the\n * live lottery) — pass `jackpotPool` if you want the jackpot term included.\n *\n * @remarks `slvrPerRound` is the emission *target*; actual emission is hub-gated\n * and may be lower, so treat the result as an upper-ish estimate. Requires a\n * configured `slvrEthPair` unless you pass `slvrPriceEth`.\n */\n async estimateRoundEv(params: {\n /** ETH to commit to the round. */\n stake: number;\n /** Round to price. Defaults to the current round. */\n roundId?: bigint;\n /** Value SLVR net of the refining fee (cashing out) vs at full price (holding). Default false. */\n cashOut?: boolean;\n /** ETH in the jackpot pool. Default 0 (jackpot term omitted). */\n jackpotPool?: number;\n /** Jackpot odds (1-in-N). Defaults to the protocol default (625). */\n jackpotOdds?: number;\n /** Override the emission target (SLVR/round). Defaults to `slvrPerRound()`. */\n emissionPerRound?: number;\n /** Override the SLVR price (ETH per SLVR). Defaults to `sdk.price`. */\n slvrPriceEth?: number;\n /** Override the pot (ETH). Defaults to the sum of the round's squares. */\n pot?: number;\n }): Promise<GridMiningEv> {\n const roundId = params.roundId ?? (await this.lottery.currentRoundId());\n\n const [potEth, emissionPerRound, slvrPriceEth, feeBps, jackpotPoolEth] = await Promise.all([\n params.pot !== undefined\n ? Promise.resolve(params.pot)\n : this.lottery\n .getRoundSquares(roundId)\n .then((sqs) => Number(formatEther(sqs.reduce((sum, s) => sum + s.total, 0n)))),\n params.emissionPerRound !== undefined\n ? Promise.resolve(params.emissionPerRound)\n : this.lottery.slvrPerRound().then((v) => Number(formatEther(v))),\n params.slvrPriceEth !== undefined\n ? Promise.resolve(params.slvrPriceEth)\n : this.getSlvrPriceInEth(),\n this.lottery.protocolFeeBps(),\n // Auto-read the jackpot pool (0 if no jackpot is set for the round / read fails).\n params.jackpotPool !== undefined\n ? Promise.resolve(params.jackpotPool)\n : this.getJackpotPool(roundId).then((v) => Number(formatEther(v))).catch(() => 0),\n ]);\n\n return computeGridMiningEv({\n stake: params.stake,\n pot: potEth,\n emissionPerRound,\n slvrPriceEth,\n feeBps,\n cashOut: params.cashOut,\n jackpotPool: jackpotPoolEth,\n jackpotOdds: params.jackpotOdds,\n });\n }\n\n /**\n * Helper: current jackpot pool for a round, in wei (0 if no jackpot is set).\n *\n * Resolves the round's jackpot contract via `getRoundJackpot` and reads its\n * `jackpotPool()`. Defaults to the current round.\n */\n async getJackpotPool(roundId?: bigint): Promise<bigint> {\n const id = roundId ?? (await this.lottery.currentRoundId());\n const jackpotAddress = await this.lottery.getRoundJackpot(id);\n if (jackpotAddress === '0x0000000000000000000000000000000000000000') return 0n;\n return await new SlvrJackpot(this.config.publicClient, undefined, jackpotAddress).jackpotPool();\n }\n}\n\n// Export all types\nexport * from './types';\n\n// Export known deployments + ready-made viem chain\nexport * from './deployments';\n\n// Export expected-value math + SLVR price reader\nexport * from './ev';\nexport { SlvrPrice } from './price';\nexport type { SlvrReserves } from './price';\nexport { ChainlinkPriceFeed } from './oracle';\n\n// Export client factory\nexport { createSlvrClients, chainFromDeployment } from './connect';\nexport type { ConnectOptions, SlvrClients } from './connect';\n\n// Export contract classes\nexport { SlvrGridLottery } from './contracts/lottery';\nexport { SlvrStaking } from './contracts/staking';\nexport { SlvrToken } from './contracts/token';\nexport { SlvrAutoCommit } from './contracts/autoCommit';\nexport { SlvrHub } from './contracts/hub';\nexport { SlvrGameRegistry } from './contracts/registry';\nexport { SlvrJackpot } from './contracts/jackpot';\n\n// Export errors\nexport * from './errors';\n\n// Export utilities\nexport * from './utils';\n\n// Export transaction helpers\nexport * from './transaction';\n\n// Export event utilities\nexport * from './events';\n\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\nimport { RoundInfo, MinerState, BetParams, ClaimParams, ClaimParamsAdvanced } from '../types';\nimport { WalletClientRequiredError, ContractCallError, decodeSlvrRevert } from '../errors';\nimport { validateAddress, validateAmount, validateSquares, validateArrayLengths, waitForTransactionReceipt } from '../utils';\nimport { SlvrGridLotteryEvents, BetPlacedEvent, RoundResolvedEvent } from '../events';\n\n/**\n * SlvrGridLottery contract interface\n */\nexport class SlvrGridLottery {\n private publicClient: PublicClient;\n private walletClient?: WalletClient;\n private address: Address;\n\n // ABI for SlvrGridLottery contract\n private static readonly ABI = parseAbi([\n // View functions\n 'function currentRoundId() view returns (uint256)',\n 'function roundStart(uint256 roundId) view returns (uint256)',\n 'function roundEnd(uint256 roundId) view returns (uint256)',\n 'function roundOpen(uint256 roundId) view returns (bool)',\n // Betting cutoff for a round. This is the timestamp bets stop being accepted,\n // which can be earlier than roundEnd() — gate bots on this, not roundEnd.\n 'function bettingEnd(uint256 roundId) view returns (uint256)',\n 'function getExpectedReward(address account, uint256 roundId) view returns (uint256)',\n 'function latestResolvedRoundId() view returns (uint256)',\n // getRound returns a flat 16-value tuple (no wrapping struct)\n 'function getRound(uint256 roundId) view returns (uint64 requestedAt, bool resolved, bytes32 randomnessId, uint256 randomnessValue, uint8 winningSquare, bool jackpotHit, bool singleMinerRound, address singleMinerWinner, uint256 totalWager, uint256 fee, uint256 winnerTotal, uint256 potForWinners, uint256 slvrForWinners, uint256 payoutMulWad, uint256 slvrMulWad, uint256 totalUnclaimedSlvr)',\n 'function getTotalOnSquare(uint256 roundId, uint8 square) view returns (uint256)',\n 'function getBettorsOnSquare(uint256 roundId, uint8 square) view returns (uint256)',\n 'function getUserBet(uint256 roundId, uint8 square, address bettor) view returns (uint256)',\n 'function getHasClaimed(uint256 roundId, address user) view returns (bool)',\n 'function getMinerState(address account) view returns (uint256 rewardsSlvr, uint256 refinedAccrued, uint256 indexSnapshot, bool hasAccount)',\n 'function getHasAccount(address account) view returns (bool)',\n 'function getDelegate(address user, address delegate) view returns (bool)',\n 'function carryWinnerNativePool() view returns (uint256)',\n 'function carryStakerNativeOwed() view returns (uint256)',\n 'function carryJackpotNativeOwed() view returns (uint256)',\n 'function carrySlvrPool() view returns (uint256)',\n // NOTE: slvrPerRound() still exists as a public var but is NO LONGER the authoritative\n // emission number. Emission is hub-gated (see SlvrHub.pendingEmission / mintReward), so the\n // amount actually minted per round is bounded by the game's streamed emission budget.\n 'function slvrPerRound() view returns (uint256)',\n 'function protocolFeeBps() view returns (uint16)',\n 'function GRID() view returns (uint8)',\n 'function ACCOUNT_DEPOSIT() view returns (uint256)',\n\n // Write functions\n 'function bet(uint256 roundId, uint8[] squares, uint256[] amounts) payable',\n 'function betFor(uint256 roundId, address beneficiary, uint8[] squares, uint256[] amounts) payable',\n 'function claim(uint256 roundId)',\n 'function claimAdvanced((address user, uint256 roundId, address recipientNative, address recipientSlvr, bool bypassFee, bool ethOnly) params)',\n 'function approveDelegate(address delegate)',\n 'function revokeDelegate(address delegate)',\n 'function donateSlvrToJackpot(uint256 amount)',\n 'function addEthToJackpot() payable',\n 'function checkpoint(address account)',\n 'function withdrawUnrefinedSlvr() returns (uint256 totalPayout, uint256 refiningFee)',\n 'function getRoundJackpot(uint256 roundId) view returns (address)',\n\n // Custom errors — so viem can decode reverts (see decodeSlvrRevert / simulateBet)\n 'error InsufficientValue()',\n 'error RoundNotOpen()',\n 'error NotResolved()',\n 'error ResolveRequested()',\n 'error BadClaim()',\n 'error NoAccount()',\n 'error BadAmount()',\n 'error BadSquare()',\n 'error DupSquare()',\n 'error BadArrays()',\n 'error ValueNotSum()',\n 'error MustSumTo100Percent()',\n 'error NotAuthorized()',\n 'error NotCurrentRound()',\n 'error CannotDelegateToSelf()',\n 'error RandomnessNotSettled()',\n 'error TransferFailed()',\n 'error JackpotNotSet()',\n ]);\n\n constructor(publicClient: PublicClient, walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.walletClient = walletClient;\n this.address = address;\n }\n\n /**\n * Update the wallet client\n * @param walletClient New wallet client\n */\n setWalletClient(walletClient: WalletClient | undefined): void {\n this.walletClient = walletClient;\n }\n\n /**\n * Get the current round ID\n */\n async currentRoundId(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'currentRoundId',\n }) as bigint;\n }\n\n /**\n * Get round start time\n */\n async roundStart(roundId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'roundStart',\n args: [roundId],\n }) as bigint;\n }\n\n /**\n * Get round end time\n */\n async roundEnd(roundId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'roundEnd',\n args: [roundId],\n }) as bigint;\n }\n\n /**\n * Check if round is open for betting\n */\n async roundOpen(roundId: bigint): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'roundOpen',\n args: [roundId],\n }) as boolean;\n }\n\n /**\n * Get the betting cutoff timestamp (unix seconds) for a round.\n *\n * Bets are only accepted until this time, which can be earlier than\n * {@link roundEnd}. Bots deciding whether they can still bet should gate on\n * this rather than on `roundEnd`.\n */\n async bettingEnd(roundId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'bettingEnd',\n args: [roundId],\n }) as bigint;\n }\n\n /**\n * Estimate the reward an account would receive for a round, in wei.\n *\n * Thin pass-through to the contract's `getExpectedReward`. Useful for sizing\n * bets or deciding whether a claim is worth the gas.\n */\n async getExpectedReward(account: Address, roundId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getExpectedReward',\n args: [account, roundId],\n }) as bigint;\n }\n\n /**\n * Get the latest resolved round ID (type(uint256).max sentinel when none resolved yet)\n */\n async latestResolvedRoundId(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'latestResolvedRoundId',\n }) as bigint;\n }\n\n /**\n * Get full round information\n */\n async getRound(roundId: bigint): Promise<RoundInfo> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getRound',\n args: [roundId],\n }) as readonly [bigint, boolean, `0x${string}`, bigint, number, boolean, boolean, Address, bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint];\n\n return {\n roundId,\n requestedAt: result[0],\n resolved: result[1],\n randomnessId: result[2],\n randomnessValue: result[3],\n winningSquare: Number(result[4]),\n jackpotHit: result[5],\n singleMinerRound: result[6],\n singleMinerWinner: result[7],\n totalWager: result[8],\n fee: result[9],\n winnerTotal: result[10],\n potForWinners: result[11],\n slvrForWinners: result[12],\n payoutMulWad: result[13],\n slvrMulWad: result[14],\n totalUnclaimedSlvr: result[15],\n };\n }\n\n /**\n * Get a compact, batched snapshot of a round's live state — the fields a bot\n * checks every tick — in one shot. Defaults to the current round.\n *\n * `secondsUntilBettingClose` is computed from the chain's `block.timestamp`\n * (not the local clock), so it's accurate even if your device clock drifts.\n * With a multicall-batching client the reads collapse into ~2 RPC calls.\n */\n async getRoundState(roundId?: bigint): Promise<{\n roundId: bigint;\n open: boolean;\n resolved: boolean;\n bettingEnd: bigint;\n roundEnd: bigint;\n totalWager: bigint;\n winningSquare: number;\n secondsUntilBettingClose: number;\n }> {\n const id = roundId ?? (await this.currentRoundId());\n const [round, open, bettingEnd, roundEnd, block] = await Promise.all([\n this.getRound(id),\n this.roundOpen(id),\n this.bettingEnd(id),\n this.roundEnd(id),\n this.publicClient.getBlock(),\n ]);\n const secondsLeft = Number(bettingEnd - block.timestamp);\n return {\n roundId: id,\n open,\n resolved: round.resolved,\n bettingEnd,\n roundEnd,\n totalWager: round.totalWager,\n winningSquare: round.winningSquare,\n secondsUntilBettingClose: secondsLeft > 0 ? secondsLeft : 0,\n };\n }\n\n /**\n * Get the jackpot contract address for a round (zero address if no jackpot is\n * set). Read that contract's `jackpotPool()` for the pool balance — or use the\n * SDK helper `getJackpotPool(roundId)`.\n */\n async getRoundJackpot(roundId: bigint): Promise<Address> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getRoundJackpot',\n args: [roundId],\n }) as Address;\n }\n\n /**\n * Get total amount bet on a square for a round\n */\n async getTotalOnSquare(roundId: bigint, square: number): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getTotalOnSquare',\n args: [roundId, square],\n }) as bigint;\n }\n\n /**\n * Get number of bettors on a square for a round\n */\n async getBettorsOnSquare(roundId: bigint, square: number): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getBettorsOnSquare',\n args: [roundId, square],\n }) as bigint;\n }\n\n /**\n * Get a user's bet amount on a square for a round\n */\n async getUserBet(roundId: bigint, square: number, bettor: Address): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getUserBet',\n args: [roundId, square, bettor],\n }) as bigint;\n }\n\n /**\n * Check if a user has claimed rewards for a round\n */\n async getHasClaimed(roundId: bigint, user: Address): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getHasClaimed',\n args: [roundId, user],\n }) as boolean;\n }\n\n /**\n * Get miner state for an account\n */\n async getMinerState(account: Address): Promise<MinerState> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getMinerState',\n args: [account],\n }) as readonly [bigint, bigint, bigint, boolean];\n\n return {\n rewardsSlvr: result[0],\n refinedAccrued: result[1],\n indexSnapshot: result[2],\n hasAccount: result[3],\n };\n }\n\n /**\n * Check if an account exists\n */\n async hasAccount(account: Address): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getHasAccount',\n args: [account],\n }) as boolean;\n }\n\n /**\n * Get carry-over winner native pool (when no winners)\n */\n async carryWinnerNativePool(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'carryWinnerNativePool',\n }) as bigint;\n }\n\n /**\n * Get staker rewards that failed to distribute (owed)\n */\n async carryStakerNativeOwed(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'carryStakerNativeOwed',\n }) as bigint;\n }\n\n /**\n * Get jackpot funds that failed to add (owed)\n */\n async carryJackpotNativeOwed(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'carryJackpotNativeOwed',\n }) as bigint;\n }\n\n /**\n * Get carry-over SLVR pool\n */\n async carrySlvrPool(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'carrySlvrPool',\n }) as bigint;\n }\n\n /**\n * Get the configured SLVR-per-round value.\n *\n * NOTE: This is no longer the authoritative emission number. Emission is hub-gated: the amount\n * actually minted each round is bounded by the game's streamed emission budget on SlvrHub\n * (see SlvrHub.pendingEmission / mintReward). Treat this only as the requested/target value.\n */\n async slvrPerRound(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'slvrPerRound',\n }) as bigint;\n }\n\n /**\n * Get protocol fee in basis points\n */\n async protocolFeeBps(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'protocolFeeBps',\n }) as number;\n }\n\n /**\n * Get grid size (should be 25)\n */\n async grid(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'GRID',\n }) as number;\n }\n\n /**\n * Get account deposit amount\n */\n async accountDeposit(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'ACCOUNT_DEPOSIT',\n }) as bigint;\n }\n\n /**\n * Place a bet on the current round\n * Note: The contract will automatically handle account deposit for new accounts.\n * If the beneficiary is a new account, ensure msg.value >= ACCOUNT_DEPOSIT + total bet amount.\n * @param params Bet parameters\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async bet(params: BetParams): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('betting');\n }\n\n const { roundId, squares, amounts, beneficiary, overrides } = params;\n\n // Validate inputs\n if (roundId < 0n) {\n throw new ContractCallError('Round ID must be non-negative');\n }\n validateSquares(squares);\n validateArrayLengths([squares, amounts], ['squares', 'amounts']);\n\n for (const amount of amounts) {\n validateAmount(amount, 'bet amount');\n }\n\n const totalAmount = amounts.reduce((sum, amt) => sum + amt, 0n);\n\n try {\n // Check if account exists, if not, add account deposit to the value sent\n const beneficiaryAddress = beneficiary\n ? validateAddress(beneficiary, 'beneficiary')\n : this.walletClient.account!.address;\n\n const hasAccount_ = await this.hasAccount(beneficiaryAddress);\n const accountDeposit_ = hasAccount_ ? 0n : await this.accountDeposit();\n const totalValue = totalAmount + accountDeposit_;\n const req = beneficiary\n ? { functionName: 'betFor' as const, args: [roundId, beneficiaryAddress, squares, amounts] }\n : { functionName: 'bet' as const, args: [roundId, squares, amounts] };\n\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: req.functionName,\n args: req.args as never,\n value: totalValue,\n account: this.walletClient.account!,\n chain: null,\n ...((overrides ?? {}) as Record<string, unknown>),\n } as never);\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n const revert = decodeSlvrRevert(error);\n if (revert) throw revert;\n throw new ContractCallError(`Failed to place bet: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Preflight a bet with `eth_call` (no transaction sent). Resolves if the bet\n * would succeed; otherwise throws a {@link SlvrRevertError} with the decoded\n * custom error (e.g. `RoundNotOpen`, `InsufficientValue`). Catch reverts before\n * spending gas.\n */\n async simulateBet(params: BetParams): Promise<void> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('simulating a bet');\n }\n const { roundId, squares, amounts, beneficiary } = params;\n validateSquares(squares);\n validateArrayLengths([squares, amounts], ['squares', 'amounts']);\n const totalAmount = amounts.reduce((sum, amt) => sum + amt, 0n);\n const beneficiaryAddress = beneficiary\n ? validateAddress(beneficiary, 'beneficiary')\n : this.walletClient.account!.address;\n const hasAccount_ = await this.hasAccount(beneficiaryAddress);\n const value = totalAmount + (hasAccount_ ? 0n : await this.accountDeposit());\n const req = beneficiary\n ? { functionName: 'betFor' as const, args: [roundId, beneficiaryAddress, squares, amounts] }\n : { functionName: 'bet' as const, args: [roundId, squares, amounts] };\n try {\n await this.publicClient.simulateContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: req.functionName,\n args: req.args as never,\n value,\n account: this.walletClient.account!,\n });\n } catch (error) {\n throw decodeSlvrRevert(error) ?? error;\n }\n }\n\n /**\n * Claim rewards for a round\n * @param params Claim parameters\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async claim(params: ClaimParams): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('claiming');\n }\n\n if (params.roundId < 0n) {\n throw new ContractCallError('Round ID must be non-negative');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'claim',\n args: [params.roundId],\n account: this.walletClient.account!,\n chain: null,\n ...((params.overrides ?? {}) as Record<string, unknown>),\n } as never);\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n const revert = decodeSlvrRevert(error);\n if (revert) throw revert;\n throw new ContractCallError(`Failed to claim rewards: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Advanced claim function covering all claim variants\n * Handles: user vs delegate, native/SLVR recipients, bypassFee, ethOnly\n * @param params Advanced claim parameters\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async claimAdvanced(params: ClaimParamsAdvanced): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('claiming');\n }\n\n if (params.roundId < 0n) {\n throw new ContractCallError('Round ID must be non-negative');\n }\n\n const user = validateAddress(params.user, 'user');\n const recipientNative = params.recipientNative \n ? validateAddress(params.recipientNative, 'recipientNative')\n : '0x0000000000000000000000000000000000000000' as Address;\n const recipientSlvr = params.recipientSlvr\n ? validateAddress(params.recipientSlvr, 'recipientSlvr')\n : '0x0000000000000000000000000000000000000000' as Address;\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'claimAdvanced',\n args: [{\n user,\n roundId: params.roundId,\n recipientNative,\n recipientSlvr,\n bypassFee: params.bypassFee || false,\n ethOnly: params.ethOnly || false,\n }],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to claim rewards: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Batch claim rewards for multiple rounds\n * Note: This sends multiple transactions sequentially. For better UX, consider\n * using a multicall contract or batching in your application layer.\n * @param roundIds Array of round IDs to claim\n * @param user User address to claim for (defaults to wallet client account)\n * @param options Optional configuration\n * @param options.waitForReceipt Whether to wait for each transaction receipt (default: false)\n * @returns Array of transaction hashes\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async batchClaim(\n roundIds: bigint[], \n user?: Address,\n options?: { waitForReceipt?: boolean }\n ): Promise<`0x${string}`[]> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('batch claiming');\n }\n\n if (roundIds.length === 0) {\n throw new ContractCallError('No rounds to claim');\n }\n\n const claimUser = user ? validateAddress(user, 'user') : this.walletClient.account!.address;\n const hashes: `0x${string}`[] = [];\n\n for (const roundId of roundIds) {\n if (roundId < 0n) {\n throw new ContractCallError(`Invalid round ID: ${roundId}`);\n }\n\n try {\n const hash = await this.claimAdvanced({\n user: claimUser,\n roundId,\n });\n\n hashes.push(hash);\n\n // Optionally wait for receipt before proceeding\n if (options?.waitForReceipt) {\n await waitForTransactionReceipt(this.publicClient, hash);\n }\n } catch (error) {\n // If one claim fails, we still return the hashes we've collected so far\n // The caller can decide how to handle partial failures\n throw new ContractCallError(\n `Failed to claim round ${roundId}: ${error instanceof Error ? error.message : String(error)}`,\n error\n );\n }\n }\n\n return hashes;\n }\n\n /**\n * Approve a delegate to claim rewards on your behalf\n */\n async approveDelegate(delegate: Address): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('approving delegate');\n }\n const delegateAddress = validateAddress(delegate, 'delegate');\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'approveDelegate',\n args: [delegateAddress],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Revoke a delegate's approval to claim on your behalf\n */\n async revokeDelegate(delegate: Address): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('revoking delegate');\n }\n const delegateAddress = validateAddress(delegate, 'delegate');\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'revokeDelegate',\n args: [delegateAddress],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Check if a delegate is approved for a user\n */\n async getDelegate(user: Address, delegate: Address): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getDelegate',\n args: [user, delegate],\n }) as boolean;\n }\n\n /**\n * Donate SLVR tokens directly to the jackpot pool.\n * Note: caller must have approved the lottery to spend `amount` of SLVR beforehand.\n */\n async donateSlvrToJackpot(amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('donating to jackpot');\n }\n validateAmount(amount, 'donation amount');\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'donateSlvrToJackpot',\n args: [amount],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Add ETH (native) tokens to the jackpot pool\n * @param value Amount of native ETH to deposit\n */\n async addEthToJackpot(value: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('adding ETH to jackpot');\n }\n validateAmount(value, 'jackpot amount');\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'addEthToJackpot',\n value,\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Withdraw your accumulated mined SLVR (the \"refine and cash out\" path).\n *\n * Settles your miner accrual (auto-checkpoints) and transfers your SLVR out,\n * net of the refining fee. This is the function a mining bot wants to realize\n * SLVR rewards outside of a specific round claim. Reverts if you have nothing to\n * withdraw. The exact `(totalPayout, refiningFee)` are in the emitted `Claimed`\n * event; this returns the transaction hash.\n */\n async withdrawUnrefinedSlvr(): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('withdrawing unrefined SLVR');\n }\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'withdrawUnrefinedSlvr',\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Force on-chain settlement of a miner's refined-reward accrual (lazy\n * \"checkpoint\"). Permissionless — you can checkpoint any account.\n *\n * This only updates accounting (rolls index growth into `refinedAccrued`); it\n * moves no tokens. You rarely need it: `claim` and {@link withdrawUnrefinedSlvr}\n * both checkpoint internally, and the up-to-date figure can be derived off-chain\n * from {@link getMinerState}. Use it when you want state settled without a\n * claim/withdraw — e.g. to make a subsequent `getMinerState` read exact.\n */\n async checkpoint(account: Address): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('checkpointing');\n }\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'checkpoint',\n args: [account],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Get all square data for a round\n */\n async getRoundSquares(roundId: bigint): Promise<Array<{ square: number; total: bigint; bettors: bigint }>> {\n const gridSize = await this.grid();\n const squares = Array.from({ length: gridSize }, (_, i) => i);\n\n // Fast path: batch all 2×gridSize reads into a single multicall. Requires the\n // client's chain to know Multicall3 (robinhoodChain registers it). Falls back\n // to parallel individual reads on any chain/client without it.\n try {\n const contracts = squares.flatMap((sq) => [\n { address: this.address, abi: SlvrGridLottery.ABI, functionName: 'getTotalOnSquare', args: [roundId, sq] },\n { address: this.address, abi: SlvrGridLottery.ABI, functionName: 'getBettorsOnSquare', args: [roundId, sq] },\n ]);\n const res = (await this.publicClient.multicall({\n contracts: contracts as never,\n allowFailure: false,\n })) as bigint[];\n return squares.map((square, i) => ({ square, total: res[i * 2]!, bettors: res[i * 2 + 1]! }));\n } catch {\n const [totals, bettors] = await Promise.all([\n Promise.all(squares.map((sq) => this.getTotalOnSquare(roundId, sq))),\n Promise.all(squares.map((sq) => this.getBettorsOnSquare(roundId, sq))),\n ]);\n return squares.map((square, i) => ({ square, total: totals[i]!, bettors: bettors[i]! }));\n }\n }\n\n /**\n * Get user's bets for a round\n */\n async getUserBets(roundId: bigint, user: Address): Promise<Array<{ square: number; amount: bigint }>> {\n const gridSize = await this.grid();\n const squares = Array.from({ length: gridSize }, (_, i) => i);\n\n // Batch via multicall when available; fall back to parallel reads otherwise.\n let bets: bigint[];\n try {\n const contracts = squares.map((sq) => ({\n address: this.address,\n abi: SlvrGridLottery.ABI,\n functionName: 'getUserBet',\n args: [roundId, sq, user],\n }));\n bets = (await this.publicClient.multicall({ contracts: contracts as never, allowFailure: false })) as bigint[];\n } catch {\n bets = await Promise.all(squares.map((sq) => this.getUserBet(roundId, sq, user)));\n }\n\n return squares\n .map((square, i) => ({ square, amount: bets[i]! }))\n .filter((bet): bet is { square: number; amount: bigint } => bet.amount > 0n);\n }\n\n // ---------------------------------------------------------------------------\n // Reactive helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Wait until a round is resolved, resolving with its final {@link RoundInfo}.\n * Polls `getRound` on an interval — handy for \"bet, then claim once it settles\".\n *\n * @param opts.pollIntervalMs how often to check (default 4000)\n * @param opts.timeoutMs give up after this long (default: wait indefinitely)\n * @throws {Error} if `timeoutMs` elapses before resolution\n */\n async waitForResolution(\n roundId: bigint,\n opts: { pollIntervalMs?: number; timeoutMs?: number } = {}\n ): Promise<RoundInfo> {\n const interval = opts.pollIntervalMs ?? 4000;\n const deadline = opts.timeoutMs !== undefined ? Date.now() + opts.timeoutMs : Infinity;\n for (;;) {\n const round = await this.getRound(roundId);\n if (round.resolved) return round;\n if (Date.now() >= deadline) throw new Error(`round ${roundId} not resolved within ${opts.timeoutMs}ms`);\n await new Promise((r) => setTimeout(r, interval));\n }\n }\n\n /**\n * Subscribe to `RoundResolved` events. Returns an unsubscribe function.\n *\n * @example\n * ```typescript\n * const stop = sdk.lottery.watchRoundResolved((e) => {\n * console.log(`round ${e.roundId} won by square ${e.winningSquare}`);\n * });\n * // later: stop();\n * ```\n */\n watchRoundResolved(\n onResolved: (event: RoundResolvedEvent['args']) => void,\n opts: { onError?: (error: Error) => void } = {}\n ): () => void {\n return this.publicClient.watchContractEvent({\n address: this.address,\n abi: SlvrGridLotteryEvents,\n eventName: 'RoundResolved',\n onLogs: (logs) => {\n for (const log of logs) onResolved((log as unknown as { args: RoundResolvedEvent['args'] }).args);\n },\n onError: opts.onError,\n poll: true,\n });\n }\n\n /**\n * Subscribe to `BetPlaced` events (optionally for one round). Returns an\n * unsubscribe function. Useful for reacting to pot changes in real time.\n */\n watchBets(\n onBet: (event: BetPlacedEvent['args']) => void,\n opts: { roundId?: bigint; onError?: (error: Error) => void } = {}\n ): () => void {\n return this.publicClient.watchContractEvent({\n address: this.address,\n abi: SlvrGridLotteryEvents,\n eventName: 'BetPlaced',\n args: opts.roundId !== undefined ? ({ roundId: opts.roundId } as never) : undefined,\n onLogs: (logs) => {\n for (const log of logs) onBet((log as unknown as { args: BetPlacedEvent['args'] }).args);\n },\n onError: opts.onError,\n poll: true,\n });\n }\n}\n\n","/**\n * Custom error classes for the Slvr SDK\n */\nimport { BaseError, ContractFunctionRevertedError } from 'viem';\n\n/**\n * Base error class for all SDK errors\n */\nexport class SlvrSDKError extends Error {\n constructor(message: string, public readonly code?: string) {\n super(message);\n this.name = 'SlvrSDKError';\n Object.setPrototypeOf(this, SlvrSDKError.prototype);\n }\n}\n\n/**\n * Error thrown when wallet client is required but not provided\n */\nexport class WalletClientRequiredError extends SlvrSDKError {\n constructor(operation: string) {\n super(`Wallet client required for ${operation}`, 'WALLET_CLIENT_REQUIRED');\n this.name = 'WalletClientRequiredError';\n Object.setPrototypeOf(this, WalletClientRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when contract call fails\n */\nexport class ContractCallError extends SlvrSDKError {\n constructor(message: string, public readonly cause?: unknown) {\n super(message, 'CONTRACT_CALL_ERROR');\n this.name = 'ContractCallError';\n Object.setPrototypeOf(this, ContractCallError.prototype);\n }\n}\n\n/**\n * Error thrown when input validation fails\n */\nexport class ValidationError extends SlvrSDKError {\n constructor(message: string, public readonly field?: string) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Error thrown when transaction fails\n */\nexport class TransactionError extends SlvrSDKError {\n constructor(\n message: string,\n public readonly txHash?: `0x${string}`,\n public readonly cause?: unknown\n ) {\n super(message, 'TRANSACTION_ERROR');\n this.name = 'TransactionError';\n Object.setPrototypeOf(this, TransactionError.prototype);\n }\n}\n\n/** Plain-English hints for the protocol's custom revert errors. */\nconst REVERT_HINTS: Record<string, string> = {\n InsufficientValue: 'msg.value did not cover the bet total (+ the one-time account-opening deposit for a new account).',\n RoundNotOpen: 'betting is closed for this round.',\n NotResolved: 'the round is not resolved yet.',\n ResolveRequested: 'the round is already being resolved; betting is closed.',\n BadClaim: 'nothing to claim — no winning bet on this round, or already claimed.',\n NoAccount: 'no miner account for this address yet (place a bet first to open one).',\n BadAmount: 'a zero or invalid amount.',\n BadSquare: 'a square index outside 0–24.',\n DupSquare: 'the same square appears twice in one bet.',\n BadArrays: 'squares and amounts arrays have mismatched lengths.',\n ValueNotSum: 'msg.value does not equal the sum of the bet amounts.',\n MustSumTo100Percent: 'allocation percentages must sum to 100%.',\n NotAuthorized: 'caller is not authorized (not the user or an approved delegate).',\n NotCurrentRound: 'that round is not the current one.',\n CannotDelegateToSelf: 'you cannot delegate to your own address.',\n RandomnessNotSettled: 'randomness for this round has not settled yet.',\n TransferFailed: 'an ETH/token transfer failed.',\n JackpotNotSet: 'no jackpot is configured for this round.',\n};\n\n/**\n * A decoded on-chain revert. `errorName` is the protocol's custom error (e.g.\n * `InsufficientValue`) when it could be decoded from the ABI.\n */\nexport class SlvrRevertError extends SlvrSDKError {\n constructor(\n public readonly errorName: string | undefined,\n message: string,\n public readonly args?: readonly unknown[],\n public readonly cause?: unknown\n ) {\n super(message, 'CONTRACT_REVERT');\n this.name = 'SlvrRevertError';\n Object.setPrototypeOf(this, SlvrRevertError.prototype);\n }\n}\n\n/**\n * Decode a viem contract error into a {@link SlvrRevertError} with the protocol's\n * custom error name and a plain-English hint. Returns `null` if `err` isn't a\n * decodable contract revert (so you can rethrow the original). Useful around\n * `simulateBet`, reads, or any caught write error.\n *\n * @example\n * ```typescript\n * try { await sdk.lottery.simulateBet(params); }\n * catch (e) { const r = decodeSlvrRevert(e); if (r) console.log(r.errorName, r.message); }\n * ```\n */\nexport function decodeSlvrRevert(err: unknown): SlvrRevertError | null {\n if (!(err instanceof BaseError)) return null;\n const revert = err.walk((e) => e instanceof ContractFunctionRevertedError) as\n | ContractFunctionRevertedError\n | undefined;\n if (!revert) return null;\n const data = (revert as unknown as { data?: { errorName?: string; args?: readonly unknown[] } }).data;\n const name = data?.errorName;\n const hint = name ? REVERT_HINTS[name] : undefined;\n const message = name\n ? `Reverted: ${name}${hint ? ` — ${hint}` : ''}`\n : revert.shortMessage || err.shortMessage || 'contract reverted';\n return new SlvrRevertError(name, message, data?.args, err);\n}\n","import { Address, isAddress, getAddress } from 'viem';\nimport { ValidationError } from './errors';\n\n/**\n * Validate and normalize an Ethereum address\n * @param address Address to validate\n * @param fieldName Field name for error message\n * @returns Checksummed address\n * @throws ValidationError if address is invalid\n */\nexport function validateAddress(address: string, fieldName: string = 'address'): Address {\n if (!isAddress(address)) {\n throw new ValidationError(`Invalid ${fieldName}: ${address}`, fieldName);\n }\n return getAddress(address);\n}\n\n/**\n * Validate that an amount is positive\n * @param amount Amount to validate\n * @param fieldName Field name for error message\n * @throws ValidationError if amount is invalid\n */\nexport function validateAmount(amount: bigint, fieldName: string = 'amount'): void {\n if (amount < 0n) {\n throw new ValidationError(`${fieldName} must be non-negative`, fieldName);\n }\n if (amount === 0n) {\n throw new ValidationError(`${fieldName} must be greater than zero`, fieldName);\n }\n}\n\n/**\n * Validate square indices are within valid range\n * @param squares Array of square indices\n * @param gridSize Grid size (default 25)\n * @throws ValidationError if squares are invalid\n */\nexport function validateSquares(squares: number[], gridSize: number = 25): void {\n if (squares.length === 0) {\n throw new ValidationError('At least one square must be provided', 'squares');\n }\n \n for (const square of squares) {\n if (!Number.isInteger(square) || square < 0 || square >= gridSize) {\n throw new ValidationError(\n `Invalid square index: ${square}. Must be between 0 and ${gridSize - 1}`,\n 'squares'\n );\n }\n }\n}\n\n/**\n * Validate that arrays have matching lengths\n * @param arrays Arrays to validate\n * @param fieldNames Field names for error message\n * @throws ValidationError if arrays don't match\n */\nexport function validateArrayLengths(arrays: unknown[][], fieldNames: string[]): void {\n if (arrays.length < 2) {\n return;\n }\n \n const firstLength = arrays[0]?.length ?? 0;\n for (let i = 1; i < arrays.length; i++) {\n const currentArray = arrays[i];\n const currentFieldName = fieldNames[i];\n if (!currentArray || currentArray.length !== firstLength) {\n throw new ValidationError(\n `Array length mismatch: ${fieldNames[0]} has ${firstLength} items, but ${currentFieldName ?? `array ${i}`} has ${currentArray?.length ?? 0} items`,\n currentFieldName\n );\n }\n }\n}\n\n/**\n * Validate basis points (0-10000)\n * @param bps Basis points value\n * @param fieldName Field name for error message\n * @throws ValidationError if bps is invalid\n */\nexport function validateBps(bps: number, fieldName: string = 'bps'): void {\n if (!Number.isInteger(bps) || bps < 0 || bps > 10000) {\n throw new ValidationError(\n `${fieldName} must be an integer between 0 and 10000 (got ${bps})`,\n fieldName\n );\n }\n}\n\n/**\n * Validate that basis points array sums to 10000\n * @param bpsArray Array of basis points\n * @param fieldName Field name for error message\n * @throws ValidationError if bps don't sum to 10000\n */\nexport function validateBpsSum(bpsArray: number[], fieldName: string = 'bpsAlloc'): void {\n const sum = bpsArray.reduce((acc, bps) => acc + bps, 0);\n if (sum !== 10000) {\n throw new ValidationError(\n `${fieldName} must sum to 10000 (got ${sum})`,\n fieldName\n );\n }\n}\n\n/**\n * Wait for transaction receipt with timeout\n * @param publicClient Public client\n * @param hash Transaction hash\n * @param timeout Timeout in milliseconds (default 120000 = 2 minutes)\n * @returns Transaction receipt\n */\nexport async function waitForTransactionReceipt(\n publicClient: { waitForTransactionReceipt?: (args: { hash: `0x${string}`; timeout?: number }) => Promise<unknown> },\n hash: `0x${string}`,\n timeout: number = 120000\n): Promise<unknown> {\n if (!publicClient.waitForTransactionReceipt) {\n throw new Error('Public client does not support waitForTransactionReceipt');\n }\n return await publicClient.waitForTransactionReceipt({ hash, timeout });\n}\n","import { Address, parseAbi, decodeEventLog, Log } from 'viem';\n\n/**\n * Event ABIs for Slvr contracts\n */\nexport const SlvrGridLotteryEvents = parseAbi([\n 'event BetPlaced(uint256 indexed roundId, address indexed beneficiary, uint256 total, uint8[] squares)',\n 'event Claimed(uint256 indexed roundId, address indexed user, uint256 nativeOut, uint256 slvrOut, uint256 refinedOut, uint256 refiningFee)',\n 'event RoundResolved(uint256 indexed roundId, uint8 winningSquare, bool jackpotHit, bool singleMinerRound, address indexed singleMinerWinner, uint256 winnerTotal, uint256 potForWinners, uint256 slvrForWinners, uint256 totalUnclaimedSlvr)',\n 'event RandomnessRequested(uint256 indexed roundId, bytes32 randomnessId)',\n]);\n\n/**\n * Events for the veNFT staker (`SlvrVoteEscrowStaking`). All staking events are\n * keyed by the veNFT `tokenId`; there are no raw-ERC20-amount stake events.\n */\nexport const SlvrStakingEvents = parseAbi([\n 'event Staked(uint256 indexed tokenId, address indexed user, uint256 weight)',\n 'event Unstaked(uint256 indexed tokenId, address indexed user, uint256 weight)',\n 'event RewardClaimed(uint256 indexed tokenId, address indexed user, uint256 amount)',\n 'event RewardDistributed(uint256 amount)',\n 'event Checkpoint(uint256 indexed tokenId, uint256 oldWeight, uint256 newWeight)',\n 'event RewardsSettledOnBurn(uint256 indexed tokenId, address indexed owner, uint256 amount)',\n 'event PendingRewardsClaimed(address indexed user, uint256 amount)',\n]);\n\nexport const SlvrTokenEvents = parseAbi([\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n]);\n\nexport const SlvrAutoCommitEvents = parseAbi([\n 'event PlanConfigured(address indexed user, uint256 nextRoundId, uint32 plays, uint256 amountPerPlay, bool autoClaim)',\n 'event PlanDisabled(address indexed user)',\n 'event PlanCancelled(address indexed user, uint256 refundAmount)',\n 'event Deposited(address indexed user, uint256 amount)',\n 'event Withdrawn(address indexed user, uint256 amount, address to)',\n 'event RoundExecuted(address indexed user, uint256 indexed roundId, uint32 playsRemaining)',\n 'event Claimed(address indexed user, uint256 indexed roundId, uint256 nativeAmount, uint256 addedToBalance)',\n 'event BalanceUpdated(address indexed user, uint256 newBalance, uint256 amountAdded)',\n 'event ExecutorFeePaid(address indexed user, address indexed executor, uint256 fee, uint256 gasUsed)',\n]);\n\n/**\n * Decode a log using the provided ABI\n * @param abi Contract ABI\n * @param log Log to decode\n * @returns Decoded event or null if decoding fails\n */\nexport function decodeEvent<T = unknown>(abi: readonly unknown[], log: Log): T | null {\n try {\n const decoded = decodeEventLog({\n abi,\n data: log.data,\n topics: log.topics,\n });\n return decoded as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Filter and decode events from logs\n * @param abi Contract ABI\n * @param logs Array of logs\n * @param eventName Optional event name to filter by\n * @returns Array of decoded events\n */\nexport function decodeEvents<T = unknown>(\n abi: readonly unknown[],\n logs: Log[],\n eventName?: string\n): T[] {\n const decoded: T[] = [];\n\n for (const log of logs) {\n try {\n const decodedEvent = decodeEvent<T>(abi, log);\n if (decodedEvent) {\n if (!eventName || (decodedEvent as { eventName?: string }).eventName === eventName) {\n decoded.push(decodedEvent);\n }\n }\n } catch {\n // Skip invalid logs\n }\n }\n\n return decoded;\n}\n\n/**\n * BetPlaced event data\n */\nexport interface BetPlacedEvent {\n eventName: 'BetPlaced';\n args: {\n roundId: bigint;\n beneficiary: Address;\n total: bigint;\n squares: readonly number[];\n };\n}\n\n/**\n * Claimed event data\n */\nexport interface ClaimedEvent {\n eventName: 'Claimed';\n args: {\n roundId: bigint;\n user: Address;\n nativeOut: bigint;\n slvrOut: bigint;\n refinedOut: bigint;\n refiningFee: bigint;\n };\n}\n\n/**\n * Round resolved event data\n */\nexport interface RoundResolvedEvent {\n eventName: 'RoundResolved';\n args: {\n roundId: bigint;\n winningSquare: number;\n jackpotHit: boolean;\n singleMinerRound: boolean;\n singleMinerWinner: Address;\n winnerTotal: bigint;\n potForWinners: bigint;\n slvrForWinners: bigint;\n totalUnclaimedSlvr: bigint;\n };\n}\n\n/**\n * RandomnessRequested event data\n */\nexport interface RandomnessRequestedEvent {\n eventName: 'RandomnessRequested';\n args: {\n roundId: bigint;\n randomnessId: `0x${string}`;\n };\n}\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\nimport { StakingInfo } from '../types';\nimport { WalletClientRequiredError, ContractCallError } from '../errors';\n\n/**\n * SlvrVoteEscrowStaking contract interface.\n *\n * This is a veNFT-based staker: stakers deposit a vote-escrow NFT (by tokenId) rather than a raw\n * ERC20 amount. Rewards accrue per unit of the token's tracked weight and are claimed per tokenId.\n */\nexport class SlvrStaking {\n private publicClient: PublicClient;\n private walletClient?: WalletClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n // View functions\n 'function getStakerRewards(uint256 tokenId) view returns (uint256)',\n 'function getTotalWeight() view returns (uint256)',\n 'function rewardPerWeightStored() view returns (uint256)',\n 'function rewardPerWeightPaid(uint256 tokenId) view returns (uint256)',\n 'function balance(uint256 tokenId) view returns (uint256)',\n 'function rewards(uint256 tokenId) view returns (uint256)',\n 'function totalWeight() view returns (uint256)',\n 'function unallocated() view returns (uint256)',\n 'function lastDistributedRoundId() view returns (uint256)',\n 'function LOTTERY() view returns (address)',\n\n // Write functions\n 'function stake(uint256 tokenId)',\n 'function unstake(uint256 tokenId)',\n 'function claimStakerRewards(uint256 tokenId)',\n 'function checkpoint(uint256 tokenId)',\n 'function poke(uint256 tokenId)',\n 'function pokeMany(uint256[] tokenIds)',\n ]);\n\n constructor(publicClient: PublicClient, walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.walletClient = walletClient;\n this.address = address;\n }\n\n /**\n * Update the wallet client\n * @param walletClient New wallet client\n */\n setWalletClient(walletClient: WalletClient | undefined): void {\n this.walletClient = walletClient;\n }\n\n // ---------------------------------------------------------------------------\n // Views\n // ---------------------------------------------------------------------------\n\n /**\n * Get claimable rewards for a staked veNFT tokenId\n */\n async getStakerRewards(tokenId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'getStakerRewards',\n args: [tokenId],\n }) as bigint;\n }\n\n /**\n * Get the total tracked weight across all staked tokens\n */\n async getTotalWeight(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'getTotalWeight',\n }) as bigint;\n }\n\n /**\n * Get the accumulated reward per unit of weight (1e18 precision)\n */\n async rewardPerWeightStored(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'rewardPerWeightStored',\n }) as bigint;\n }\n\n /**\n * Get the last rewardPerWeightStored snapshot recorded for a tokenId\n */\n async rewardPerWeightPaid(tokenId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'rewardPerWeightPaid',\n args: [tokenId],\n }) as bigint;\n }\n\n /**\n * Get the tracked weight (balance) for a staked tokenId\n */\n async balance(tokenId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'balance',\n args: [tokenId],\n }) as bigint;\n }\n\n /**\n * Get the accrued (checkpointed) claimable rewards stored for a tokenId\n */\n async rewards(tokenId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'rewards',\n args: [tokenId],\n }) as bigint;\n }\n\n /**\n * Get the total tracked weight (public storage var)\n */\n async totalWeight(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'totalWeight',\n }) as bigint;\n }\n\n /**\n * Get unallocated rewards (distributed while no weight was staked)\n */\n async unallocated(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'unallocated',\n }) as bigint;\n }\n\n /**\n * Get the last distributed round ID (type(uint256).max sentinel when none)\n */\n async lastDistributedRoundId(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'lastDistributedRoundId',\n }) as bigint;\n }\n\n /**\n * Get the lottery address authorized to distribute rewards\n */\n async lottery(): Promise<Address> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'LOTTERY',\n }) as Address;\n }\n\n /**\n * Get complete staking info for a staked veNFT tokenId\n */\n async getStakingInfo(tokenId: bigint): Promise<StakingInfo> {\n const [totalWeight_, balance_, rewards_, rewardPerWeightStored_] = await Promise.all([\n this.totalWeight(),\n this.balance(tokenId),\n this.getStakerRewards(tokenId),\n this.rewardPerWeightStored(),\n ]);\n\n return {\n totalWeight: totalWeight_,\n balance: balance_,\n rewards: rewards_,\n rewardPerWeightStored: rewardPerWeightStored_,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Writes\n // ---------------------------------------------------------------------------\n\n /**\n * Stake a vote-escrow NFT by tokenId\n * @param tokenId The veNFT token ID to stake\n * @returns Transaction hash\n */\n async stake(tokenId: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('staking');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'stake',\n args: [tokenId],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to stake: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Unstake a vote-escrow NFT by tokenId\n * @param tokenId The veNFT token ID to unstake\n * @returns Transaction hash\n */\n async unstake(tokenId: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('unstaking');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'unstake',\n args: [tokenId],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to unstake: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Claim staker rewards for a tokenId\n * @param tokenId The veNFT token ID to claim rewards for\n * @returns Transaction hash\n */\n async claimStakerRewards(tokenId: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('claiming rewards');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'claimStakerRewards',\n args: [tokenId],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to claim rewards: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Checkpoint a token's reward accounting\n * @param tokenId The veNFT token ID to checkpoint\n * @returns Transaction hash\n */\n async checkpoint(tokenId: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('checkpointing');\n }\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'checkpoint',\n args: [tokenId],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Poke a token to refresh its tracked weight\n * @param tokenId The veNFT token ID to poke\n * @returns Transaction hash\n */\n async poke(tokenId: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('poking');\n }\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'poke',\n args: [tokenId],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n\n /**\n * Poke many tokens to refresh their tracked weight in one call\n * @param tokenIds The veNFT token IDs to poke\n * @returns Transaction hash\n */\n async pokeMany(tokenIds: bigint[]): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('poking');\n }\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrStaking.ABI,\n functionName: 'pokeMany',\n args: [tokenIds],\n account: this.walletClient.account!,\n chain: null,\n });\n }\n}\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\nimport { WalletClientRequiredError, ContractCallError } from '../errors';\nimport { validateAddress, validateAmount } from '../utils';\n\n/**\n * SlvrToken contract interface\n */\nexport class SlvrToken {\n private publicClient: PublicClient;\n private walletClient?: WalletClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n // ERC20 standard functions\n 'function totalSupply() view returns (uint256)',\n 'function balanceOf(address account) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function transferFrom(address from, address to, uint256 amount) returns (bool)',\n \n // SlvrToken specific\n 'function name() view returns (string)',\n 'function symbol() view returns (string)',\n 'function decimals() view returns (uint8)',\n 'function MAX_SUPPLY() view returns (uint256)',\n 'function burn(uint256 amount)',\n 'function burnFrom(address account, uint256 amount)',\n ]);\n\n constructor(publicClient: PublicClient, walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.walletClient = walletClient;\n this.address = address;\n }\n\n /**\n * Update the wallet client\n * @param walletClient New wallet client\n */\n setWalletClient(walletClient: WalletClient | undefined): void {\n this.walletClient = walletClient;\n }\n\n /**\n * Get total supply\n */\n async totalSupply(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'totalSupply',\n });\n }\n\n /**\n * Get balance of an account\n */\n async balanceOf(account: Address): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'balanceOf',\n args: [account],\n });\n }\n\n /**\n * Get allowance\n */\n async allowance(owner: Address, spender: Address): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'allowance',\n args: [owner, spender],\n });\n }\n\n /**\n * Get token name\n */\n async name(): Promise<string> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'name',\n });\n }\n\n /**\n * Get token symbol\n */\n async symbol(): Promise<string> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'symbol',\n });\n }\n\n /**\n * Get token decimals\n */\n async decimals(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'decimals',\n });\n }\n\n /**\n * Get maximum supply\n */\n async maxSupply(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'MAX_SUPPLY',\n });\n }\n\n /**\n * Transfer tokens\n * @param to Recipient address\n * @param amount Amount to transfer\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async transfer(to: Address, amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('transferring');\n }\n\n const recipient = validateAddress(to, 'recipient');\n validateAmount(amount, 'transfer amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'transfer',\n args: [recipient, amount],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to transfer: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Approve spender\n * @param spender Address to approve\n * @param amount Amount to approve\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async approve(spender: Address, amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('approving');\n }\n\n const spenderAddress = validateAddress(spender, 'spender');\n validateAmount(amount, 'approval amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'approve',\n args: [spenderAddress, amount],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to approve: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Transfer from (requires approval)\n * @param from Sender address\n * @param to Recipient address\n * @param amount Amount to transfer\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async transferFrom(from: Address, to: Address, amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('transferFrom');\n }\n\n const fromAddress = validateAddress(from, 'from');\n const toAddress = validateAddress(to, 'to');\n validateAmount(amount, 'transfer amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'transferFrom',\n args: [fromAddress, toAddress, amount],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to transferFrom: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Burn tokens\n * @param amount Amount to burn\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if amount is invalid\n * @throws ContractCallError if contract call fails\n */\n async burn(amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('burning');\n }\n\n validateAmount(amount, 'burn amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'burn',\n args: [amount],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to burn: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Burn tokens from account\n * @param account Account to burn from\n * @param amount Amount to burn\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async burnFrom(account: Address, amount: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('burnFrom');\n }\n\n const accountAddress = validateAddress(account, 'account');\n validateAmount(amount, 'burn amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrToken.ABI,\n functionName: 'burnFrom',\n args: [accountAddress, amount],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to burnFrom: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n}\n\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\nimport { AutoCommitPlan } from '../types';\nimport { WalletClientRequiredError, ContractCallError } from '../errors';\nimport { validateAddress, validateAmount, validateSquares, validateBpsSum, validateArrayLengths } from '../utils';\n\n/**\n * SlvrAutoCommitV2 contract interface\n *\n * V2 economics: executors calling executeFor/claimFor are reimbursed their\n * metered gas (plus a premium, capped at maxFeePerExecution — both owner-tunable\n * within hard ceilings) from the user's plan balance — there is no flat\n * AUTOMATION_FEE and the execution functions are nonpayable. Claimable winning\n * rounds are discovered off-chain and passed in explicitly via claimRounds.\n */\nexport class SlvrAutoCommit {\n private publicClient: PublicClient;\n private walletClient?: WalletClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n // View functions\n 'function planInfo(address user) view returns (bool enabled, uint256 nextRoundId, uint32 playsRemaining, uint256 amountPerPlay, uint256 balance, bool autoClaim, uint8[] squares, uint16[] bpsAlloc, uint256 planStartRoundId)',\n 'function needsExecution(address user) view returns (bool ready, string reason)',\n 'function executedRounds(address user, uint256 roundId) view returns (bool)',\n 'function LOTTERY() view returns (address)',\n 'function UNLIMITED_PLAYS() view returns (uint32)',\n 'function MAX_PLAYS_PER_EXECUTION() view returns (uint32)',\n 'function MAX_CLAIMS_PER_EXECUTION() view returns (uint256)',\n 'function maxFeePerExecution() view returns (uint256)',\n 'function feePremiumBps() view returns (uint16)',\n\n // Write functions\n 'function deposit() payable',\n 'function withdraw(uint256 amount, address to)',\n 'function configurePlan(uint32 plays, uint256 amountPerPlay, uint8[] squares, uint16[] bpsAlloc, bool autoClaim)',\n 'function configurePlanAndDeposit(uint32 plays, uint256 amountPerPlay, uint8[] squares, uint16[] bpsAlloc, bool autoClaim) payable',\n 'function disablePlan()',\n 'function cancelPlan()',\n 'function executeFor(address user, uint32 maxPlays, uint256[] claimRounds)',\n 'function claimFor(address user, uint256[] claimRounds) returns (uint256 claimed)',\n ]);\n\n constructor(publicClient: PublicClient, walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.walletClient = walletClient;\n this.address = address;\n }\n\n /**\n * Update the wallet client\n * @param walletClient New wallet client\n */\n setWalletClient(walletClient: WalletClient | undefined): void {\n this.walletClient = walletClient;\n }\n\n /**\n * Get plan information for a user\n */\n async planInfo(user: Address): Promise<AutoCommitPlan> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'planInfo',\n args: [user],\n });\n\n return {\n enabled: result[0],\n nextRoundId: result[1],\n playsRemaining: Number(result[2]),\n amountPerPlay: result[3],\n balance: result[4],\n autoClaim: result[5],\n squares: (result[6] as unknown as readonly bigint[]).map((s: bigint) => Number(s)),\n bpsAlloc: (result[7] as unknown as readonly bigint[]).map((b: bigint) => Number(b)),\n planStartRoundId: result[8],\n };\n }\n\n /**\n * Check whether a plan is ready to execute, and if not, why\n */\n async needsExecution(user: Address): Promise<{ ready: boolean; reason: string }> {\n const [ready, reason] = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'needsExecution',\n args: [user],\n });\n return { ready, reason };\n }\n\n /**\n * Check whether a specific round has already been executed for a user\n */\n async executedRound(user: Address, roundId: bigint): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'executedRounds',\n args: [user, roundId],\n });\n }\n\n /**\n * Get lottery contract address\n */\n async lottery(): Promise<Address> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'LOTTERY',\n });\n }\n\n /**\n * Get the sentinel plays value meaning \"unlimited plays\"\n */\n async unlimitedPlays(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'UNLIMITED_PLAYS',\n });\n }\n\n /**\n * Get max plays per execution\n */\n async maxPlaysPerExecution(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'MAX_PLAYS_PER_EXECUTION',\n });\n }\n\n /**\n * Get max claim rounds accepted per execution\n */\n async maxClaimsPerExecution(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'MAX_CLAIMS_PER_EXECUTION',\n });\n }\n\n /**\n * Get the current cap on the executor fee reimbursed per execution\n * (owner-tunable within the contract's hard ceiling)\n */\n async maxFeePerExecution(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'maxFeePerExecution',\n });\n }\n\n /**\n * Get the current executor-fee premium in basis points\n * (owner-tunable within the contract's hard ceiling)\n */\n async feePremiumBps(): Promise<number> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'feePremiumBps',\n });\n }\n\n /**\n * Deposit native tokens to auto-commit plan\n * @param value Amount to deposit\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if amount is invalid\n * @throws ContractCallError if contract call fails\n */\n async deposit(value: bigint): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('depositing');\n }\n\n validateAmount(value, 'deposit amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'deposit',\n value,\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to deposit: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Withdraw from auto-commit plan\n * @param amount Amount to withdraw\n * @param to Recipient address\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async withdraw(amount: bigint, to: Address): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('withdrawing');\n }\n\n validateAmount(amount, 'withdraw amount');\n const recipient = validateAddress(to, 'recipient');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'withdraw',\n args: [amount, recipient],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to withdraw: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Configure auto-commit plan\n * @param plays Number of plays (UNLIMITED_PLAYS = 4294967295 for unlimited;\n * forced to unlimited on-chain when autoClaim is true)\n * @param amountPerPlay Amount per play\n * @param squares Square indices to bet on\n * @param bpsAlloc Basis points allocation for each square (must sum to 10000)\n * @param autoClaim Whether the keeper should claim winnings back into the plan balance\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async configurePlan(\n plays: number,\n amountPerPlay: bigint,\n squares: number[],\n bpsAlloc: number[],\n autoClaim: boolean\n ): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('configuring plan');\n }\n\n this.validatePlanConfig(plays, amountPerPlay, squares, bpsAlloc);\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'configurePlan',\n args: [plays, amountPerPlay, squares, bpsAlloc, autoClaim],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to configure plan: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Configure auto-commit plan and deposit funds in a single transaction\n * @param plays Number of plays (see configurePlan)\n * @param amountPerPlay Amount per play\n * @param squares Square indices to bet on\n * @param bpsAlloc Basis points allocation for each square (must sum to 10000)\n * @param autoClaim Whether the keeper should claim winnings back into the plan balance\n * @param value Amount to deposit\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async configurePlanAndDeposit(\n plays: number,\n amountPerPlay: bigint,\n squares: number[],\n bpsAlloc: number[],\n autoClaim: boolean,\n value: bigint\n ): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('configuring plan');\n }\n\n this.validatePlanConfig(plays, amountPerPlay, squares, bpsAlloc);\n validateAmount(value, 'deposit amount');\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'configurePlanAndDeposit',\n args: [plays, amountPerPlay, squares, bpsAlloc, autoClaim],\n value,\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to configure plan: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Disable auto-commit plan\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ContractCallError if contract call fails\n */\n async disablePlan(): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('disabling plan');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'disablePlan',\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to disable plan: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Cancel the plan and refund the entire remaining balance to the caller\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ContractCallError if contract call fails\n */\n async cancelPlan(): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('cancelling plan');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'cancelPlan',\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to cancel plan: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Execute auto-commit plan for a user (anyone can call).\n * The caller is reimbursed metered gas + premium from the user's plan balance.\n * @param user User address\n * @param maxPlays Maximum number of plays to execute\n * @param claimRounds Winning round ids to claim into the plan balance before\n * betting (discovered off-chain; non-claimable entries are no-ops)\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async executeFor(user: Address, maxPlays: number, claimRounds: bigint[] = []): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('executing plan');\n }\n\n const userAddress = validateAddress(user, 'user');\n if (!Number.isInteger(maxPlays) || maxPlays <= 0) {\n throw new ContractCallError('maxPlays must be a positive integer');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'executeFor',\n args: [userAddress, maxPlays, claimRounds],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to execute plan: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n /**\n * Claim winning rounds into a user's plan balance without betting (anyone can\n * call). Useful when the plan balance is too low to bet until winnings land.\n * @param user User address\n * @param claimRounds Winning round ids to claim (discovered off-chain)\n * @returns Transaction hash\n * @throws WalletClientRequiredError if wallet client is not available\n * @throws ValidationError if inputs are invalid\n * @throws ContractCallError if contract call fails\n */\n async claimFor(user: Address, claimRounds: bigint[]): Promise<`0x${string}`> {\n if (!this.walletClient) {\n throw new WalletClientRequiredError('claiming');\n }\n\n const userAddress = validateAddress(user, 'user');\n if (claimRounds.length === 0) {\n throw new ContractCallError('claimRounds must not be empty');\n }\n\n try {\n return await this.walletClient.writeContract({\n address: this.address,\n abi: SlvrAutoCommit.ABI,\n functionName: 'claimFor',\n args: [userAddress, claimRounds],\n account: this.walletClient.account!,\n chain: null,\n });\n } catch (error) {\n if (error instanceof WalletClientRequiredError || error instanceof ContractCallError) {\n throw error;\n }\n throw new ContractCallError(`Failed to claim: ${error instanceof Error ? error.message : String(error)}`, error);\n }\n }\n\n private validatePlanConfig(plays: number, amountPerPlay: bigint, squares: number[], bpsAlloc: number[]): void {\n if (!Number.isInteger(plays) || plays <= 0) {\n throw new ContractCallError('Plays must be a positive integer');\n }\n validateAmount(amountPerPlay, 'amountPerPlay');\n validateSquares(squares);\n validateArrayLengths([squares, bpsAlloc], ['squares', 'bpsAlloc']);\n validateBpsSum(bpsAlloc, 'bpsAlloc');\n }\n}\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\n\n/**\n * SlvrHub contract interface (read-only).\n *\n * The hub is the protocol emission/sink router: it gates per-game SLVR emission, fans many games\n * into one shared veNFT staker stream, and into one shared jackpot. These bindings expose the\n * informational view surface (emission rate, pending emission, sink addresses); the hub's\n * fee-routing writes are keeper/protocol operations and are intentionally not included.\n */\nexport class SlvrHub {\n private publicClient: PublicClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n // View functions\n 'function pendingEmission(uint256 gameId) view returns (uint256)',\n 'function emissionRatePerSec() view returns (uint256)',\n 'function targetSupply() view returns (uint256)',\n 'function maxAccrualSeconds() view returns (uint256)',\n 'function staking() view returns (address)',\n 'function jackpot() view returns (address)',\n 'function stakerSeq() view returns (uint256)',\n 'function pendingStakerRewards() view returns (uint256)',\n ]);\n\n constructor(publicClient: PublicClient, _walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.address = address;\n }\n\n // Read-only module; kept for a uniform module interface.\n setWalletClient(_walletClient: WalletClient | undefined): void {}\n\n // ---------------------------------------------------------------------------\n // Views\n // ---------------------------------------------------------------------------\n\n /**\n * Accrued-but-unminted SLVR emission currently available to a game (its bucket + streamed since\n * last accrual, hard-capped at one maxAccrualSeconds window of the game's effective rate).\n */\n async pendingEmission(gameId: bigint): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'pendingEmission',\n args: [gameId],\n }) as bigint;\n }\n\n /**\n * Base SLVR/sec emission rate across the whole active game set\n */\n async emissionRatePerSec(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'emissionRatePerSec',\n }) as bigint;\n }\n\n /**\n * Soft-cap target supply (0 => use token MAX_SUPPLY)\n */\n async targetSupply(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'targetSupply',\n }) as bigint;\n }\n\n /**\n * Idle-forfeiture window: cap on dt per accrual (seconds)\n */\n async maxAccrualSeconds(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'maxAccrualSeconds',\n }) as bigint;\n }\n\n /**\n * Address of the shared veNFT staking contract\n */\n async staking(): Promise<Address> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'staking',\n }) as Address;\n }\n\n /**\n * Address of the shared jackpot contract\n */\n async jackpot(): Promise<Address> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'jackpot',\n }) as Address;\n }\n\n /**\n * Hub-owned sequential counter used to feed the staking contract's round numbering\n */\n async stakerSeq(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'stakerSeq',\n }) as bigint;\n }\n\n /**\n * Native staker rewards received but not yet flushed to the staking stream\n */\n async pendingStakerRewards(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrHub.ABI,\n functionName: 'pendingStakerRewards',\n }) as bigint;\n }\n}\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\nimport { GameInfo, GameStatus, GameTier } from '../types';\n\n/**\n * SlvrGameRegistry contract interface (read-only surface).\n *\n * Single source of truth for which games exist, their status/tier, and their share of the shared\n * emission stream.\n */\nexport class SlvrGameRegistry {\n private publicClient: PublicClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n 'function gameIdOf(address game) view returns (uint256)',\n 'function gameInfo(uint256 gameId) view returns ((address game, bytes32 gameType, uint8 status, uint8 tier, uint32 emissionWeight, uint16 maxWeightBps, bool exists))',\n 'function isActive(address game) view returns (bool)',\n 'function statusOf(uint256 gameId) view returns (uint8)',\n 'function tierOf(uint256 gameId) view returns (uint8)',\n 'function weightOf(uint256 gameId) view returns (uint32)',\n 'function maxWeightBpsOf(uint256 gameId) view returns (uint16)',\n 'function totalActiveWeight() view returns (uint256)',\n 'function gameCount() view returns (uint256)',\n ]);\n\n constructor(publicClient: PublicClient, _walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.address = address;\n }\n\n /** Read-only contract: no wallet client needed. Kept for a consistent SDK surface. */\n setWalletClient(_walletClient: WalletClient | undefined): void {\n // no-op\n }\n\n /**\n * Registry id for a game address (0 if not registered; ids are 1-based)\n */\n async gameIdOf(game: Address): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'gameIdOf',\n args: [game],\n }) as bigint;\n }\n\n /**\n * Full record for a game id\n */\n async gameInfo(gameId: bigint): Promise<GameInfo> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'gameInfo',\n args: [gameId],\n }) as {\n game: Address;\n gameType: `0x${string}`;\n status: number;\n tier: number;\n emissionWeight: number;\n maxWeightBps: number;\n exists: boolean;\n };\n\n return {\n game: result.game,\n gameType: result.gameType,\n status: result.status as GameStatus,\n tier: result.tier as GameTier,\n emissionWeight: Number(result.emissionWeight),\n maxWeightBps: Number(result.maxWeightBps),\n exists: result.exists,\n };\n }\n\n /**\n * Is this address a registered, Active game?\n */\n async isActive(game: Address): Promise<boolean> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'isActive',\n args: [game],\n }) as boolean;\n }\n\n /**\n * Status enum for a game id\n */\n async statusOf(gameId: bigint): Promise<GameStatus> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'statusOf',\n args: [gameId],\n }) as number;\n return result as GameStatus;\n }\n\n /**\n * Tier enum for a game id\n */\n async tierOf(gameId: bigint): Promise<GameTier> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'tierOf',\n args: [gameId],\n }) as number;\n return result as GameTier;\n }\n\n /**\n * Emission weight (relative share of the global stream) for a game id\n */\n async weightOf(gameId: bigint): Promise<bigint> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'weightOf',\n args: [gameId],\n }) as number;\n return BigInt(result);\n }\n\n /**\n * Max realized-fraction ceiling (bps of 10000) for a game id\n */\n async maxWeightBpsOf(gameId: bigint): Promise<number> {\n const result = await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'maxWeightBpsOf',\n args: [gameId],\n }) as number;\n return Number(result);\n }\n\n /**\n * Sum of emissionWeight across all Active games (denominator for the split)\n */\n async totalActiveWeight(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'totalActiveWeight',\n }) as bigint;\n }\n\n /**\n * Number of registered games\n */\n async gameCount(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrGameRegistry.ABI,\n functionName: 'gameCount',\n }) as bigint;\n }\n}\n","import { Address, parseAbi, PublicClient, WalletClient } from 'viem';\n\n/**\n * SlvrJackpot contract interface (read-only pool surface).\n */\nexport class SlvrJackpot {\n private publicClient: PublicClient;\n private address: Address;\n\n private static readonly ABI = parseAbi([\n 'function jackpotPool() view returns (uint256)',\n 'function jackpotSlvrPool() view returns (uint256)',\n ]);\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n constructor(publicClient: PublicClient, _walletClient: WalletClient | undefined, address: Address) {\n this.publicClient = publicClient;\n this.address = address;\n }\n\n /** Read-only contract: no wallet client needed. Kept for a consistent SDK surface. */\n setWalletClient(_walletClient: WalletClient | undefined): void {\n // no-op\n }\n\n /**\n * Native (ETH) jackpot pool balance\n */\n async jackpotPool(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrJackpot.ABI,\n functionName: 'jackpotPool',\n }) as bigint;\n }\n\n /**\n * SLVR jackpot pool balance\n */\n async jackpotSlvrPool(): Promise<bigint> {\n return await this.publicClient.readContract({\n address: this.address,\n abi: SlvrJackpot.ABI,\n functionName: 'jackpotSlvrPool',\n }) as bigint;\n }\n}\n","import { Address, PublicClient, parseAbi } from 'viem';\n\n/**\n * Reserves of the SLVR/ETH UniswapV2 pair, with the token ordering resolved.\n */\nexport interface SlvrReserves {\n /** SLVR reserve, in wei (18 decimals). */\n slvrReserve: bigint;\n /** ETH (WETH) reserve, in wei (18 decimals). */\n ethReserve: bigint;\n /** Whether SLVR is `token0` in the pair (ordering is resolved for you). */\n token0IsSlvr: boolean;\n}\n\n/**\n * Reads the SLVR price from the SLVR/ETH UniswapV2 pair.\n *\n * Mirrors the web app's price logic: it reads the pair's `getReserves()` and\n * `token0()`, figures out which reserve is SLVR (never assumes ordering), and\n * prices SLVR as `ethReserve / slvrReserve`. Both tokens are 18-decimal, so the\n * raw reserve ratio is already ETH-per-SLVR.\n *\n * This is a **spot** price straight from reserves — no TWAP, no slippage model.\n * Fine for sizing bets and EV estimates; do not use it as an oracle for anything\n * that must resist manipulation.\n *\n * @example\n * ```typescript\n * import { SlvrPrice } from '@slvr-labs/sdk';\n * const price = new SlvrPrice(publicClient, pairAddress, slvrTokenAddress);\n * const ethPerSlvr = await price.getPriceInEth();\n * ```\n */\nexport class SlvrPrice {\n private publicClient: PublicClient;\n private pairAddress: Address;\n private slvrTokenAddress: Address;\n\n private static readonly PAIR_ABI = parseAbi([\n 'function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)',\n 'function token0() view returns (address)',\n ]);\n\n constructor(publicClient: PublicClient, pairAddress: Address, slvrTokenAddress: Address) {\n this.publicClient = publicClient;\n this.pairAddress = pairAddress;\n this.slvrTokenAddress = slvrTokenAddress;\n }\n\n /** Read the pair reserves and resolve which side is SLVR. */\n async getReserves(): Promise<SlvrReserves> {\n const [reserves, token0] = await Promise.all([\n this.publicClient.readContract({\n address: this.pairAddress,\n abi: SlvrPrice.PAIR_ABI,\n functionName: 'getReserves',\n }) as Promise<readonly [bigint, bigint, number]>,\n this.publicClient.readContract({\n address: this.pairAddress,\n abi: SlvrPrice.PAIR_ABI,\n functionName: 'token0',\n }) as Promise<Address>,\n ]);\n\n const token0IsSlvr = token0.toLowerCase() === this.slvrTokenAddress.toLowerCase();\n const slvrReserve = token0IsSlvr ? reserves[0] : reserves[1];\n const ethReserve = token0IsSlvr ? reserves[1] : reserves[0];\n return { slvrReserve, ethReserve, token0IsSlvr };\n }\n\n /**\n * SLVR price in ETH (ETH per SLVR), as a floating-point number.\n * @throws {Error} if the pair has no SLVR liquidity (zero reserve).\n */\n async getPriceInEth(): Promise<number> {\n const { slvrReserve, ethReserve } = await this.getReserves();\n if (slvrReserve === 0n) {\n throw new Error('SLVR/ETH pair has zero SLVR reserve; cannot price');\n }\n return Number(ethReserve) / Number(slvrReserve);\n }\n\n /**\n * SLVR price in ETH as a WAD (1e18-scaled `bigint`), for callers that want to\n * stay in integer math: `priceWad = ethReserve * 1e18 / slvrReserve`.\n * @throws {Error} if the pair has no SLVR liquidity (zero reserve).\n */\n async getPriceInEthWad(): Promise<bigint> {\n const { slvrReserve, ethReserve } = await this.getReserves();\n if (slvrReserve === 0n) {\n throw new Error('SLVR/ETH pair has zero SLVR reserve; cannot price');\n }\n return (ethReserve * 10n ** 18n) / slvrReserve;\n }\n}\n","import { Address, PublicClient, parseAbi } from 'viem';\n\n/**\n * Reads a Chainlink-style price feed (`AggregatorV3Interface`).\n *\n * Works with any standard aggregator — the canonical use here is an **ETH/USD**\n * feed, which lets the SDK convert the pair-derived SLVR/ETH price into USD.\n *\n * Robinhood Chain has a Chainlink ETH/USD feed (`ETH / USD`, 8 decimals), wired\n * into `deployments.robinhood.addresses.chainlinkEthUsd`, so `sdk.ethUsd` and USD\n * prices work out of the box there. On chains without a feed, pass a USD price\n * into {@link SlvrSDK.getSlvrPrice} instead, or wire your own off-chain source.\n *\n * @example\n * ```typescript\n * import { ChainlinkPriceFeed } from '@slvr-labs/sdk';\n * const ethUsd = new ChainlinkPriceFeed(publicClient, ethUsdFeedAddress);\n * const price = await ethUsd.getPrice(); // e.g. 1797.35\n * ```\n */\nexport class ChainlinkPriceFeed {\n private publicClient: PublicClient;\n private feedAddress: Address;\n private maxStalenessSec?: number;\n\n private static readonly ABI = parseAbi([\n 'function decimals() view returns (uint8)',\n 'function latestRoundData() view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)',\n ]);\n\n /**\n * @param publicClient viem public client\n * @param feedAddress the aggregator address\n * @param opts.maxStalenessSec if set, {@link getPrice} throws when the feed's\n * `updatedAt` is older than this many seconds (checked against the local\n * clock). Off by default — enable it only where the local clock is trusted.\n */\n constructor(\n publicClient: PublicClient,\n feedAddress: Address,\n opts?: { maxStalenessSec?: number }\n ) {\n this.publicClient = publicClient;\n this.feedAddress = feedAddress;\n this.maxStalenessSec = opts?.maxStalenessSec;\n }\n\n /** Raw `latestRoundData` answer plus the feed's decimals. */\n async getRoundData(): Promise<{ answer: bigint; decimals: number; updatedAt: bigint }> {\n const [decimals, roundData] = await Promise.all([\n this.publicClient.readContract({\n address: this.feedAddress,\n abi: ChainlinkPriceFeed.ABI,\n functionName: 'decimals',\n }) as Promise<number>,\n this.publicClient.readContract({\n address: this.feedAddress,\n abi: ChainlinkPriceFeed.ABI,\n functionName: 'latestRoundData',\n }) as Promise<readonly [bigint, bigint, bigint, bigint, bigint]>,\n ]);\n return { answer: roundData[1], decimals, updatedAt: roundData[3] };\n }\n\n /**\n * The feed price as a floating-point number (`answer / 10 ** decimals`).\n * @throws {Error} if the answer is non-positive, or (when `maxStalenessSec` is\n * set) if the feed is stale.\n */\n async getPrice(): Promise<number> {\n const { answer, decimals, updatedAt } = await this.getRoundData();\n if (answer <= 0n) {\n throw new Error(`Chainlink feed ${this.feedAddress} returned a non-positive answer`);\n }\n if (this.maxStalenessSec !== undefined) {\n const nowSec = Math.floor(Date.now() / 1000);\n const age = nowSec - Number(updatedAt);\n if (age > this.maxStalenessSec) {\n throw new Error(\n `Chainlink feed ${this.feedAddress} is stale: ${age}s old (max ${this.maxStalenessSec}s)`\n );\n }\n }\n return Number(answer) / 10 ** decimals;\n }\n}\n","/**\n * Expected-value math for SLVR grid mining.\n *\n * This is a direct port of the protocol's \"grid-mining edge\" model — the same\n * math the web calculator uses — so an SDK bot and the site agree.\n *\n * ## The model\n *\n * The winning square each round is chosen **uniformly** at random over the\n * {@link GRID_SIZE}-square grid (`randomnessValue % 25`), independent of how much\n * was wagered where. Wagers only decide how the pot is split *among* the winners.\n *\n * The strategy this models is **grid mining**: spread your stake across the grid\n * in proportion to the current pot so you always hold a `share = stake / pot`\n * slice of whichever square wins. Under that strategy, per round:\n *\n * - **ETH is a wash minus the protocol fee.** The whole pot minus the fee is paid\n * pro-rata to the winning square, and your slice of it equals your slice of the\n * pot — i.e. you get back `(1 - fee) * stake` in expectation. So your ETH cost\n * (\"bleed\") is exactly `feeFraction * stake`.\n * - **SLVR is mined pro-rata:** `slvrMined = share * emissionPerRound`. (Whether a\n * round is \"single-miner\" — winner-take-all SLVR — changes the *variance*, not\n * the mean, so it does not affect EV.)\n * - **Jackpot** pays your `share` of the pool with probability `1 / jackpotOdds`.\n *\n * Net EV per round (in ETH):\n *\n * ```\n * netEth = slvrMined * slvrPriceEth * realize // SLVR value (realize = 1 - refineFee when cashing out)\n * - feeFraction * stake // ETH bleed\n * + (1 / jackpotOdds) * share * jackpotPool\n * ```\n *\n * Because both the SLVR reward and the bleed scale with `stake`, **the edge does\n * not depend on how much you bet** — only on `pot` vs `slvrPriceEth`. A smaller\n * pot means a bigger `share`, so mining is profitable while the pot is *below* the\n * {@link GridMiningEv.breakEvenPot break-even pot}.\n */\n\n/** Grid size — the winning square is `randomnessValue % GRID_SIZE`. */\nexport const GRID_SIZE = 25;\n\n/** Probability any one square wins a round (uniform selection). */\nexport const SINGLE_SQUARE_WIN_PROBABILITY = 1 / GRID_SIZE;\n\n/** Default protocol fee in basis points (10%), taken out of the pot before winners. */\nexport const PROTOCOL_FEE_BPS = 1000;\n\n/** Default SLVR refining fee in basis points (10%), charged when you cash SLVR out to ETH. */\nexport const REFINING_FEE_BPS = 1000;\n\n/** Default jackpot odds — the jackpot fires when `randomnessValue % JACKPOT_ODDS == 0`. */\nexport const JACKPOT_ODDS = 625;\n\n/**\n * Inputs to {@link computeGridMiningEv}. All ETH-denominated values are plain\n * numbers in whole ETH (not wei) and `slvrPriceEth` is ETH per SLVR — use\n * `Number(formatEther(...))` to convert on-chain `bigint` wei.\n */\nexport interface GridMiningEvInput {\n /** ETH you would commit to the round. */\n stake: number;\n /** Total ETH currently wagered in the round (the pot). */\n pot: number;\n /** SLVR minted to the winning square this round (the emission target). */\n emissionPerRound: number;\n /** Price of SLVR in ETH (ETH per SLVR). */\n slvrPriceEth: number;\n /** Protocol fee in bps. Defaults to {@link PROTOCOL_FEE_BPS} (1000 = 10%). */\n feeBps?: number;\n /**\n * If `true`, value mined SLVR net of the refining fee (you intend to cash out\n * to ETH). If `false` (default), value it at full price (you hold/stake it).\n */\n cashOut?: boolean;\n /** Refining fee in bps, applied only when `cashOut` is true. Defaults to {@link REFINING_FEE_BPS}. */\n refineFeeBps?: number;\n /** ETH currently in the jackpot pool. Defaults to 0 (jackpot ignored). */\n jackpotPool?: number;\n /** Jackpot odds (1-in-N per round). Defaults to {@link JACKPOT_ODDS} (625). */\n jackpotOdds?: number;\n}\n\n/** Result of {@link computeGridMiningEv}. All ETH-denominated. */\nexport interface GridMiningEv {\n /** Your fraction of the pot, `stake / pot`. */\n share: number;\n /** ETH lost per round to the protocol fee, `feeFraction * stake`. */\n ethBleed: number;\n /** SLVR mined per round, `share * emissionPerRound`. */\n slvrMined: number;\n /** ETH value of the mined SLVR after the realize factor. */\n slvrValueEth: number;\n /** Expected jackpot contribution per round, in ETH. */\n jackpotEvEth: number;\n /** Net EV per round excluding the jackpot, in ETH. */\n netEthNoJackpot: number;\n /** Net EV per round including the jackpot, in ETH. */\n netEth: number;\n /** Net EV as a fraction of stake (`netEth / stake`) — the per-round edge. */\n edgeRatio: number;\n /** Pot size at which `netEth` crosses zero. Mining is profitable below this. */\n breakEvenPot: number;\n /** SLVR price (ETH) at which `netEth` crosses zero for the current pot. */\n breakEvenSlvrPriceEth: number;\n /** Whether the round is +EV (`netEth > 0`). */\n profitable: boolean;\n}\n\n/**\n * Compute the per-round expected value of grid mining for a given stake, pot,\n * emission and SLVR price. Pure function — does no I/O.\n *\n * @throws {Error} if `stake` or `pot` is not positive.\n *\n * @example\n * ```typescript\n * import { computeGridMiningEv } from '@slvr-labs/sdk';\n *\n * const ev = computeGridMiningEv({\n * stake: 0.1, // 0.1 ETH per round\n * pot: 0.5, // 0.5 ETH in the pot\n * emissionPerRound: 1, // 1 SLVR minted/round\n * slvrPriceEth: 0.0005, // SLVR price in ETH\n * jackpotPool: 5, // 5 ETH jackpot\n * });\n * if (ev.profitable) console.log(`+${ev.netEth} ETH/round, edge ${(ev.edgeRatio * 100).toFixed(1)}%`);\n * ```\n */\nexport function computeGridMiningEv(input: GridMiningEvInput): GridMiningEv {\n const {\n stake,\n pot,\n emissionPerRound,\n slvrPriceEth,\n feeBps = PROTOCOL_FEE_BPS,\n cashOut = false,\n refineFeeBps = REFINING_FEE_BPS,\n jackpotPool = 0,\n jackpotOdds = JACKPOT_ODDS,\n } = input;\n\n if (!(stake > 0)) throw new Error(`stake must be positive (got ${stake})`);\n if (!(pot > 0)) throw new Error(`pot must be positive (got ${pot})`);\n\n const feeFraction = feeBps / 10_000;\n const realize = cashOut ? 1 - refineFeeBps / 10_000 : 1;\n\n const share = stake / pot;\n const ethBleed = feeFraction * stake;\n const slvrMined = share * emissionPerRound;\n const slvrValueEth = slvrMined * slvrPriceEth * realize;\n\n // Jackpot is ignored when odds are non-finite/non-positive or the pool is empty.\n const jackpotEvEth =\n jackpotOdds > 0 && Number.isFinite(jackpotOdds) ? (1 / jackpotOdds) * share * jackpotPool : 0;\n\n const netEthNoJackpot = slvrValueEth - ethBleed;\n const netEth = netEthNoJackpot + jackpotEvEth;\n\n // Solve netEth == 0 for pot and for slvrPriceEth (both independent of stake).\n // netEth = (stake/pot)*(emit*price*realize + jackpotPool/odds) - feeFraction*stake\n const perShareEthReward =\n emissionPerRound * slvrPriceEth * realize +\n (jackpotOdds > 0 && Number.isFinite(jackpotOdds) ? jackpotPool / jackpotOdds : 0);\n const breakEvenPot = feeFraction > 0 ? perShareEthReward / feeFraction : Infinity;\n\n // Solve for the SLVR price that makes netEth == 0 at the current pot.\n const slvrRewardDenom = share * emissionPerRound * realize;\n const breakEvenSlvrPriceEth =\n slvrRewardDenom > 0 ? (ethBleed - jackpotEvEth) / slvrRewardDenom : Infinity;\n\n return {\n share,\n ethBleed,\n slvrMined,\n slvrValueEth,\n jackpotEvEth,\n netEthNoJackpot,\n netEth,\n edgeRatio: netEth / stake,\n breakEvenPot,\n breakEvenSlvrPriceEth,\n profitable: netEth > 0,\n };\n}\n","import {\n Account,\n Chain,\n PublicClient,\n Transport,\n WalletClient,\n createPublicClient,\n createWalletClient,\n defineChain,\n http,\n} from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { SlvrDeployment, robinhood, robinhoodChain } from './deployments';\n\n/**\n * Options for {@link createSlvrClients} / {@link SlvrSDK.connect}.\n */\nexport interface ConnectOptions {\n /** Which deployment to target. Defaults to `robinhood`. */\n deployment?: SlvrDeployment;\n /** RPC URL. Defaults to the deployment's `rpcUrl`. Ignored if `transport` is given. */\n rpcUrl?: string;\n /** A fully-custom viem transport (overrides `rpcUrl`). */\n transport?: Transport;\n /** A private key to build a wallet client from (for sending transactions). */\n privateKey?: `0x${string}`;\n /** …or an already-built viem `Account` (alternative to `privateKey`). */\n account?: Account;\n /** Auto-batch concurrent reads through Multicall3. Defaults to `true`. */\n batchMulticall?: boolean;\n /** viem polling interval (ms) used by event watchers. */\n pollingInterval?: number;\n}\n\n/**\n * Build a viem `Chain` for a deployment. Returns the shipped `robinhoodChain`\n * (which already registers Multicall3) for the Robinhood deployment; otherwise\n * synthesizes one, wiring `multicall3` when the deployment provides it.\n */\nexport function chainFromDeployment(deployment: SlvrDeployment): Chain {\n if (deployment.chainId === robinhood.chainId) return robinhoodChain;\n return defineChain({\n id: deployment.chainId,\n name: deployment.name,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [deployment.rpcUrl] } },\n ...(deployment.blockExplorer\n ? { blockExplorers: { default: { name: 'Explorer', url: deployment.blockExplorer } } }\n : {}),\n ...(deployment.addresses.multicall3\n ? { contracts: { multicall3: { address: deployment.addresses.multicall3 } } }\n : {}),\n });\n}\n\n/** Clients returned by {@link createSlvrClients}. */\nexport interface SlvrClients {\n chain: Chain;\n publicClient: PublicClient;\n /** Present only when a `privateKey` or `account` was supplied. */\n walletClient?: WalletClient;\n}\n\n/**\n * Create ready-to-use viem clients for a Slvr deployment with sensible, resilient\n * defaults — Multicall3 auto-batching, a longer timeout, and retries — so you\n * don't have to hand-tune the transport for a polling bot.\n *\n * @example\n * ```typescript\n * import { createSlvrClients } from '@slvr-labs/sdk';\n * const { publicClient, walletClient } = createSlvrClients({ privateKey: process.env.PRIVATE_KEY });\n * ```\n */\nexport function createSlvrClients(opts: ConnectOptions = {}): SlvrClients {\n const deployment = opts.deployment ?? robinhood;\n const chain = chainFromDeployment(deployment);\n const transport = opts.transport ?? http(opts.rpcUrl ?? deployment.rpcUrl, { timeout: 20_000, retryCount: 3 });\n\n const publicClient = createPublicClient({\n chain,\n transport,\n batch: { multicall: opts.batchMulticall ?? true },\n ...(opts.pollingInterval ? { pollingInterval: opts.pollingInterval } : {}),\n }) as PublicClient;\n\n const account = opts.account ?? (opts.privateKey ? privateKeyToAccount(opts.privateKey) : undefined);\n const walletClient = account\n ? (createWalletClient({ chain, transport, account }) as WalletClient)\n : undefined;\n\n return { chain, publicClient, walletClient };\n}\n","import { Address, defineChain } from 'viem';\n\n/**\n * A known Slvr deployment: chain metadata plus the on-chain addresses the SDK needs.\n *\n * Addresses mirror the canonical values the production interface ships\n * (`interface/config/constants.ts`). `hub`, `registry`, and `jackpot` are only\n * present on deployments that run the emission/sink hub architecture — they are\n * omitted here for deployments that don't, and the corresponding `sdk.hub` /\n * `sdk.registry` / `sdk.jackpot` bindings will be `undefined`.\n */\nexport interface SlvrDeployment {\n /** EVM chain id */\n chainId: number;\n /** Human-readable network name */\n name: string;\n /** Default JSON-RPC endpoint */\n rpcUrl: string;\n /** Block explorer base URL, if any */\n blockExplorer?: string;\n /** Goldsky/hosted subgraph GraphQL endpoint, if any */\n subgraphUrl?: string;\n /** Contract addresses, shaped to drop straight into `new SlvrSDK({ addresses })` */\n addresses: {\n /** SlvrGridLottery */\n lottery: Address;\n /** SlvrVoteEscrowStaking (the veNFT staker) */\n staking: Address;\n /** SlvrToken (ERC20) */\n token: Address;\n /** SlvrAutoCommitV2 (optional) */\n autoCommit?: Address;\n /** SlvrVoteEscrow NFT — needed to approve/own the tokenIds you stake (optional) */\n voteEscrow?: Address;\n /** SLVR/ETH UniswapV2 pair — enables SLVR price reads via `sdk.price` (optional) */\n slvrEthPair?: Address;\n /**\n * Chainlink-style ETH/USD feed — enables USD prices via `sdk.ethUsd` (optional).\n * Absent on deployments (like Robinhood Chain) that have no on-chain feed.\n */\n chainlinkEthUsd?: Address;\n /** Multicall3 — lets the SDK batch multi-square reads into a single RPC call (optional). */\n multicall3?: Address;\n /** SlvrHub emission/sink router (optional; only on hub deployments) */\n hub?: Address;\n /** SlvrGameRegistry (optional; only on hub deployments) */\n registry?: Address;\n /** SlvrJackpot (optional; only on hub deployments) */\n jackpot?: Address;\n };\n}\n\n/**\n * Robinhood Chain mainnet — the canonical production Slvr deployment.\n *\n * Addresses populated from `DeployRobinhood.s.sol` (2026-07-09); `autoCommit`\n * is SlvrAutoCommitV2. The live deployment does not run the hub architecture,\n * so `hub`/`registry`/`jackpot` are intentionally absent.\n */\nexport const robinhood: SlvrDeployment = {\n chainId: 4663,\n name: 'Robinhood Chain',\n rpcUrl: 'https://rpc.mainnet.chain.robinhood.com',\n blockExplorer: 'https://robinhoodchain.blockscout.com/',\n subgraphUrl:\n 'https://api.goldsky.com/api/public/project_cmre158qbffn101xe929tflsk/subgraphs/slvr-robinhood/1.2.0/gn',\n addresses: {\n lottery: '0x284Eb4016305Fa7FbC162Fb68F27227271001c7f',\n staking: '0xaF68598eBd245DC3cB92FF16E9Ba1814DD137200',\n token: '0x791229E3EbD6CFdC3D8157f48722684173C29aD9',\n autoCommit: '0x314c8D5755468224AC60c36FB5494F0D7D5Abb3B',\n voteEscrow: '0xd9b8FBD61033145c5496132153CE675756313B71',\n slvrEthPair: '0xe365b92239097Ed3322131411DbE15a5c4068eff',\n // Chainlink ETH/USD feed (standard AggregatorV3 proxy; \"ETH / USD\", 8 decimals).\n // Verified on-chain. There is also an SVR proxy at\n // 0x5058aDee53b04e374d8bEDbAD634Bc4778F50b22 with identical price data — that\n // one is for protocols integrating Chainlink SVR (OEV recapture); for plain\n // price reads the standard proxy below is the right choice.\n chainlinkEthUsd: '0x78F3556b67E17Df817D51Ef5a990cDaF09E8d3A9',\n // Multicall3 at its canonical cross-chain address (verified deployed on Robinhood Chain).\n multicall3: '0xcA11bde05977b3631167028862bE2a173976CA11',\n },\n};\n\n/**\n * All known Slvr deployments, keyed by a short network slug.\n *\n * @example\n * ```typescript\n * import { deployments } from '@slvr-labs/sdk';\n * const { addresses, rpcUrl } = deployments.robinhood;\n * ```\n */\nexport const deployments = {\n robinhood,\n} as const;\n\n/**\n * A ready-to-use viem `Chain` for Robinhood Chain mainnet, so you don't have to\n * hand-roll `defineChain`.\n *\n * @example\n * ```typescript\n * import { createPublicClient, http } from 'viem';\n * import { robinhoodChain } from '@slvr-labs/sdk';\n *\n * const publicClient = createPublicClient({ chain: robinhoodChain, transport: http() });\n * ```\n */\nexport const robinhoodChain = defineChain({\n id: robinhood.chainId,\n name: robinhood.name,\n nativeCurrency: { decimals: 18, name: 'Ether', symbol: 'ETH' },\n rpcUrls: { default: { http: [robinhood.rpcUrl] } },\n blockExplorers: {\n default: { name: 'Blockscout', url: 'https://robinhoodchain.blockscout.com' },\n },\n // Registering Multicall3 lets viem batch reads: the SDK's multi-square reads\n // become one RPC call, and clients created with `batch: { multicall: true }`\n // auto-batch every concurrent read.\n contracts: {\n multicall3: { address: robinhood.addresses.multicall3! },\n },\n});\n","import { Address, PublicClient, WalletClient } from 'viem';\n\n/**\n * Configuration for the Slvr SDK\n */\nexport interface SlvrConfig {\n /** Public client for read operations */\n publicClient: PublicClient;\n /** Wallet client for write operations (optional, required for transactions) */\n walletClient?: WalletClient;\n /** Contract addresses */\n addresses: {\n lottery: Address;\n staking: Address;\n token: Address;\n autoCommit?: Address;\n /** SlvrHub address (optional, for emission/staker/jackpot stats and keeper/admin ops) */\n hub?: Address;\n /** SlvrGameRegistry address (optional, for game weight/status stats) */\n registry?: Address;\n /** SlvrJackpot address (optional, for jackpot pool reads) */\n jackpot?: Address;\n /** SLVR/ETH UniswapV2 pair address (optional, enables `sdk.price` SLVR price reads) */\n slvrEthPair?: Address;\n /**\n * Chainlink-style ETH/USD price feed address (optional, enables `sdk.ethUsd`\n * and USD-denominated prices). Only set on chains that actually have a feed.\n */\n chainlinkEthUsd?: Address;\n };\n}\n\n/**\n * A SLVR price quote in both ETH and USD.\n */\nexport interface PriceQuote {\n /** Price in ETH (ETH per SLVR). */\n eth: number;\n /** Price in USD, or `null` if no ETH/USD source was available. */\n usd: number | null;\n}\n\n/**\n * Round information\n */\nexport interface RoundInfo {\n roundId: bigint;\n requestedAt: bigint;\n resolved: boolean;\n randomnessId: `0x${string}`;\n randomnessValue: bigint;\n winningSquare: number;\n jackpotHit: boolean;\n singleMinerRound: boolean;\n singleMinerWinner: Address;\n totalWager: bigint;\n fee: bigint;\n winnerTotal: bigint;\n potForWinners: bigint;\n slvrForWinners: bigint;\n payoutMulWad: bigint;\n slvrMulWad: bigint;\n totalUnclaimedSlvr: bigint;\n}\n\n/**\n * Miner state information\n */\nexport interface MinerState {\n rewardsSlvr: bigint;\n refinedAccrued: bigint;\n indexSnapshot: bigint;\n hasAccount: boolean;\n}\n\n/**\n * Treasury state information\n */\nexport interface TreasuryState {\n minerIndex: bigint;\n totalUnclaimed: bigint;\n totalRefined: bigint;\n jackpotPool: bigint;\n}\n\n/**\n * Staking information for a staked veNFT tokenId\n */\nexport interface StakingInfo {\n /** Total tracked weight across all staked tokens */\n totalWeight: bigint;\n /** Tracked weight (balance) of this tokenId */\n balance: bigint;\n /** Claimable rewards for this tokenId */\n rewards: bigint;\n /** Accumulated reward per unit of weight (1e18 precision) */\n rewardPerWeightStored: bigint;\n}\n\n/**\n * AutoCommit plan information\n */\nexport interface AutoCommitPlan {\n enabled: boolean;\n nextRoundId: bigint;\n playsRemaining: number;\n amountPerPlay: bigint;\n balance: bigint;\n autoClaim: boolean;\n squares: number[];\n bpsAlloc: number[];\n planStartRoundId: bigint;\n}\n\n/**\n * Game status in the registry (mirrors ISlvrGameRegistry.Status)\n */\nexport enum GameStatus {\n Pending = 0,\n Active = 1,\n Paused = 2,\n Retired = 3,\n}\n\n/**\n * Game tier in the registry (mirrors ISlvrGameRegistry.Tier)\n */\nexport enum GameTier {\n Core = 0,\n Community = 1,\n Experimental = 2,\n}\n\n/**\n * Full registry record for a game (mirrors ISlvrGameRegistry.GameInfo)\n */\nexport interface GameInfo {\n game: Address;\n gameType: `0x${string}`;\n status: GameStatus;\n tier: GameTier;\n emissionWeight: number;\n maxWeightBps: number;\n exists: boolean;\n}\n\n/**\n * Optional transaction overrides passed through to viem's `writeContract`\n * (e.g. to manage gas or nonce in a high-throughput bot).\n */\nexport interface TxOverrides {\n gas?: bigint;\n nonce?: number;\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n gasPrice?: bigint;\n}\n\n/**\n * Bet parameters\n */\nexport interface BetParams {\n roundId: bigint;\n squares: number[];\n amounts: bigint[];\n beneficiary?: Address;\n /** Optional gas/nonce overrides for the transaction. */\n overrides?: TxOverrides;\n}\n\n/**\n * Claim parameters\n */\nexport interface ClaimParams {\n roundId: bigint;\n /** Optional gas/nonce overrides for the transaction. */\n overrides?: TxOverrides;\n}\n\n/**\n * Advanced claim parameters (unified claim function)\n */\nexport interface ClaimParamsAdvanced {\n user: Address; // User to claim for (must be msg.sender or delegate)\n roundId: bigint; // Round to claim from\n recipientNative?: Address; // Address to receive native (0 = user)\n recipientSlvr?: Address; // Address to receive SLVR (0 = user, or same as recipientNative)\n bypassFee?: boolean; // Skip refining fee (only if recipientSlvr is authorized permanent lock)\n ethOnly?: boolean; // If true, only claim ETH, leave SLVR unrefined in state\n}\n\n","import { PublicClient, WalletClient, Address } from 'viem';\nimport { TransactionError } from './errors';\n\n/**\n * Options for transaction execution\n */\nexport interface TransactionOptions {\n /** Maximum gas to use */\n gas?: bigint;\n /** Gas price (legacy) */\n gasPrice?: bigint;\n /** Max fee per gas (EIP-1559) */\n maxFeePerGas?: bigint;\n /** Max priority fee per gas (EIP-1559) */\n maxPriorityFeePerGas?: bigint;\n /** Whether to wait for transaction receipt */\n waitForReceipt?: boolean;\n /** Timeout for waiting for receipt (milliseconds) */\n receiptTimeout?: number;\n}\n\n/**\n * Estimate gas for a contract write operation\n * @param publicClient Public client\n * @param address Contract address\n * @param abi Contract ABI\n * @param functionName Function name\n * @param args Function arguments\n * @param value Optional value to send\n * @param account Optional account address\n * @returns Estimated gas\n */\nexport async function estimateGas(\n publicClient: PublicClient,\n address: Address,\n abi: readonly unknown[],\n functionName: string,\n args: unknown[],\n value?: bigint,\n account?: Address\n): Promise<bigint> {\n try {\n const estimateParams: any = {\n address,\n abi,\n functionName,\n args,\n };\n if (value !== undefined) {\n estimateParams.value = value;\n }\n if (account !== undefined) {\n estimateParams.account = account;\n }\n const gas = await publicClient.estimateContractGas(estimateParams);\n return gas;\n } catch (error) {\n throw new TransactionError(\n `Failed to estimate gas for ${functionName}: ${error instanceof Error ? error.message : String(error)}`,\n undefined,\n error\n );\n }\n}\n\n/**\n * Wait for transaction receipt with error handling\n * @param publicClient Public client\n * @param hash Transaction hash\n * @param timeout Timeout in milliseconds\n * @returns Transaction receipt\n * @throws TransactionError if transaction fails or times out\n */\nexport async function waitForReceipt(\n publicClient: PublicClient,\n hash: `0x${string}`,\n timeout: number = 120000\n): Promise<unknown> {\n try {\n const receipt = await publicClient.waitForTransactionReceipt({\n hash,\n timeout,\n });\n\n // Check if transaction failed\n if (receipt && typeof receipt === 'object' && 'status' in receipt) {\n if (receipt.status === 'reverted') {\n throw new TransactionError(\n `Transaction reverted: ${hash}`,\n hash\n );\n }\n }\n\n return receipt;\n } catch (error) {\n if (error instanceof TransactionError) {\n throw error;\n }\n throw new TransactionError(\n `Failed to wait for transaction receipt: ${error instanceof Error ? error.message : String(error)}`,\n hash,\n error\n );\n }\n}\n\n/**\n * Execute a contract write with options\n * @param walletClient Wallet client\n * @param publicClient Public client\n * @param address Contract address\n * @param abi Contract ABI\n * @param functionName Function name\n * @param args Function arguments\n * @param options Transaction options\n * @returns Transaction hash or receipt\n */\nexport async function executeTransaction(\n walletClient: WalletClient,\n publicClient: PublicClient,\n address: Address,\n abi: readonly unknown[],\n functionName: string,\n args: unknown[],\n options: TransactionOptions & { value?: bigint } = {}\n): Promise<`0x${string}` | unknown> {\n const {\n gas,\n gasPrice,\n maxFeePerGas,\n maxPriorityFeePerGas,\n waitForReceipt: waitForReceipt_,\n receiptTimeout,\n value,\n } = options;\n\n const writeParams = {\n address,\n abi,\n functionName,\n args,\n account: walletClient.account!,\n chain: null,\n ...(value !== undefined && { value }),\n ...(gas !== undefined && { gas }),\n ...(gasPrice !== undefined && { gasPrice }),\n ...(maxFeePerGas !== undefined && { maxFeePerGas }),\n ...(maxPriorityFeePerGas !== undefined && { maxPriorityFeePerGas }),\n } as Parameters<typeof walletClient.writeContract>[0];\n\n try {\n const hash = await walletClient.writeContract(writeParams);\n\n if (waitForReceipt_) {\n return await waitForReceipt(publicClient, hash, receiptTimeout);\n }\n\n return hash;\n } catch (error) {\n throw new TransactionError(\n `Failed to execute transaction: ${error instanceof Error ? error.message : String(error)}`,\n undefined,\n error\n );\n }\n}\n"],"mappings":";AAAA,SAA8C,mBAAmB;;;ACAjE,SAAkB,YAAAA,iBAA4C;;;ACG9D,SAAS,WAAW,qCAAqC;AAKlD,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA,EACtC,YAAY,SAAiC,MAAe;AAC1D,UAAM,OAAO;AAD8B;AAE3C,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,cAAa,SAAS;AAAA,EACpD;AACF;AAKO,IAAM,4BAAN,MAAM,mCAAkC,aAAa;AAAA,EAC1D,YAAY,WAAmB;AAC7B,UAAM,8BAA8B,SAAS,IAAI,wBAAwB;AACzE,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,2BAA0B,SAAS;AAAA,EACjE;AACF;AAKO,IAAM,oBAAN,MAAM,2BAA0B,aAAa;AAAA,EAClD,YAAY,SAAiC,OAAiB;AAC5D,UAAM,SAAS,qBAAqB;AADO;AAE3C,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,mBAAkB,SAAS;AAAA,EACzD;AACF;AAKO,IAAM,kBAAN,MAAM,yBAAwB,aAAa;AAAA,EAChD,YAAY,SAAiC,OAAgB;AAC3D,UAAM,SAAS,kBAAkB;AADU;AAE3C,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,iBAAgB,SAAS;AAAA,EACvD;AACF;AAKO,IAAM,mBAAN,MAAM,0BAAyB,aAAa;AAAA,EACjD,YACE,SACgB,QACA,OAChB;AACA,UAAM,SAAS,mBAAmB;AAHlB;AACA;AAGhB,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,kBAAiB,SAAS;AAAA,EACxD;AACF;AAGA,IAAM,eAAuC;AAAA,EAC3C,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAMO,IAAM,kBAAN,MAAM,yBAAwB,aAAa;AAAA,EAChD,YACkB,WAChB,SACgB,MACA,OAChB;AACA,UAAM,SAAS,iBAAiB;AALhB;AAEA;AACA;AAGhB,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,iBAAgB,SAAS;AAAA,EACvD;AACF;AAcO,SAAS,iBAAiB,KAAsC;AACrE,MAAI,EAAE,eAAe,WAAY,QAAO;AACxC,QAAM,SAAS,IAAI,KAAK,CAAC,MAAM,aAAa,6BAA6B;AAGzE,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,OAAQ,OAAmF;AACjG,QAAM,OAAO,MAAM;AACnB,QAAM,OAAO,OAAO,aAAa,IAAI,IAAI;AACzC,QAAM,UAAU,OACZ,aAAa,IAAI,GAAG,OAAO,WAAM,IAAI,KAAK,EAAE,KAC5C,OAAO,gBAAgB,IAAI,gBAAgB;AAC/C,SAAO,IAAI,gBAAgB,MAAM,SAAS,MAAM,MAAM,GAAG;AAC3D;;;AChIA,SAAkB,WAAW,kBAAkB;AAUxC,SAAS,gBAAgB,SAAiB,YAAoB,WAAoB;AACvF,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,UAAM,IAAI,gBAAgB,WAAW,SAAS,KAAK,OAAO,IAAI,SAAS;AAAA,EACzE;AACA,SAAO,WAAW,OAAO;AAC3B;AAQO,SAAS,eAAe,QAAgB,YAAoB,UAAgB;AACjF,MAAI,SAAS,IAAI;AACf,UAAM,IAAI,gBAAgB,GAAG,SAAS,yBAAyB,SAAS;AAAA,EAC1E;AACA,MAAI,WAAW,IAAI;AACjB,UAAM,IAAI,gBAAgB,GAAG,SAAS,8BAA8B,SAAS;AAAA,EAC/E;AACF;AAQO,SAAS,gBAAgB,SAAmB,WAAmB,IAAU;AAC9E,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,gBAAgB,wCAAwC,SAAS;AAAA,EAC7E;AAEA,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,KAAK,UAAU,UAAU;AACjE,YAAM,IAAI;AAAA,QACR,yBAAyB,MAAM,2BAA2B,WAAW,CAAC;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,qBAAqB,QAAqB,YAA4B;AACpF,MAAI,OAAO,SAAS,GAAG;AACrB;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,CAAC,GAAG,UAAU;AACzC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,eAAe,OAAO,CAAC;AAC7B,UAAM,mBAAmB,WAAW,CAAC;AACrC,QAAI,CAAC,gBAAgB,aAAa,WAAW,aAAa;AACxD,YAAM,IAAI;AAAA,QACR,0BAA0B,WAAW,CAAC,CAAC,QAAQ,WAAW,eAAe,oBAAoB,SAAS,CAAC,EAAE,QAAQ,cAAc,UAAU,CAAC;AAAA,QAC1I;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,YAAY,KAAa,YAAoB,OAAa;AACxE,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,KAAO;AACpD,UAAM,IAAI;AAAA,MACR,GAAG,SAAS,gDAAgD,GAAG;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,eAAe,UAAoB,YAAoB,YAAkB;AACvF,QAAM,MAAM,SAAS,OAAO,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC;AACtD,MAAI,QAAQ,KAAO;AACjB,UAAM,IAAI;AAAA,MACR,GAAG,SAAS,2BAA2B,GAAG;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACF;AASA,eAAsB,0BACpB,cACA,MACA,UAAkB,MACA;AAClB,MAAI,CAAC,aAAa,2BAA2B;AAC3C,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO,MAAM,aAAa,0BAA0B,EAAE,MAAM,QAAQ,CAAC;AACvE;;;AC5HA,SAAkB,UAAU,sBAA2B;AAKhD,IAAM,wBAAwB,SAAS;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,IAAM,oBAAoB,SAAS;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,kBAAkB,SAAS;AAAA,EACtC;AAAA,EACA;AACF,CAAC;AAEM,IAAM,uBAAuB,SAAS;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAAS,YAAyB,KAAyB,KAAoB;AACpF,MAAI;AACF,UAAM,UAAU,eAAe;AAAA,MAC7B;AAAA,MACA,MAAM,IAAI;AAAA,MACV,QAAQ,IAAI;AAAA,IACd,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,SAAS,aACd,KACA,MACA,WACK;AACL,QAAM,UAAe,CAAC;AAEtB,aAAW,OAAO,MAAM;AACtB,QAAI;AACF,YAAM,eAAe,YAAe,KAAK,GAAG;AAC5C,UAAI,cAAc;AAChB,YAAI,CAAC,aAAc,aAAwC,cAAc,WAAW;AAClF,kBAAQ,KAAK,YAAY;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;;;AHjFO,IAAM,mBAAN,MAAM,iBAAgB;AAAA,EAwE3B,YAAY,cAA4B,cAAwC,SAAkB;AAChG,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,cAA8C;AAC5D,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkC;AACtC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,SAAkC;AACjD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,SAAkC;AAC/C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,SAAmC;AACjD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,SAAkC;AACjD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBAAkB,SAAkB,SAAkC;AAC1E,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAyC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,SAAqC;AAClD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,aAAa,OAAO,CAAC;AAAA,MACrB,UAAU,OAAO,CAAC;AAAA,MAClB,cAAc,OAAO,CAAC;AAAA,MACtB,iBAAiB,OAAO,CAAC;AAAA,MACzB,eAAe,OAAO,OAAO,CAAC,CAAC;AAAA,MAC/B,YAAY,OAAO,CAAC;AAAA,MACpB,kBAAkB,OAAO,CAAC;AAAA,MAC1B,mBAAmB,OAAO,CAAC;AAAA,MAC3B,YAAY,OAAO,CAAC;AAAA,MACpB,KAAK,OAAO,CAAC;AAAA,MACb,aAAa,OAAO,EAAE;AAAA,MACtB,eAAe,OAAO,EAAE;AAAA,MACxB,gBAAgB,OAAO,EAAE;AAAA,MACzB,cAAc,OAAO,EAAE;AAAA,MACvB,YAAY,OAAO,EAAE;AAAA,MACrB,oBAAoB,OAAO,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,cAAc,SASjB;AACD,UAAM,KAAK,WAAY,MAAM,KAAK,eAAe;AACjD,UAAM,CAAC,OAAO,MAAM,YAAY,UAAU,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnE,KAAK,SAAS,EAAE;AAAA,MAChB,KAAK,UAAU,EAAE;AAAA,MACjB,KAAK,WAAW,EAAE;AAAA,MAClB,KAAK,SAAS,EAAE;AAAA,MAChB,KAAK,aAAa,SAAS;AAAA,IAC7B,CAAC;AACD,UAAM,cAAc,OAAO,aAAa,MAAM,SAAS;AACvD,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,eAAe,MAAM;AAAA,MACrB,0BAA0B,cAAc,IAAI,cAAc;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAAgB,SAAmC;AACvD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,SAAiB,QAAiC;AACvE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,SAAiB,QAAiC;AACzE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,SAAiB,QAAgB,QAAkC;AAClF,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,QAAQ,MAAM;AAAA,IAChC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,SAAiB,MAAiC;AACpE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,IAAI;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,SAAuC;AACzD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,MACL,aAAa,OAAO,CAAC;AAAA,MACrB,gBAAgB,OAAO,CAAC;AAAA,MACxB,eAAe,OAAO,CAAC;AAAA,MACvB,YAAY,OAAO,CAAC;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,SAAoC;AACnD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAyC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAyC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,yBAA0C;AAC9C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAiC;AACrC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAgC;AACpC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkC;AACtC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAwB;AAC5B,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkC;AACtC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,IAAI,QAA2C;AACnD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,SAAS;AAAA,IAC/C;AAEA,UAAM,EAAE,SAAS,SAAS,SAAS,aAAa,UAAU,IAAI;AAG9D,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC7D;AACA,oBAAgB,OAAO;AACvB,yBAAqB,CAAC,SAAS,OAAO,GAAG,CAAC,WAAW,SAAS,CAAC;AAE/D,eAAW,UAAU,SAAS;AAC5B,qBAAe,QAAQ,YAAY;AAAA,IACrC;AAEA,UAAM,cAAc,QAAQ,OAAO,CAAC,KAAK,QAAQ,MAAM,KAAK,EAAE;AAE9D,QAAI;AAEF,YAAM,qBAAqB,cACvB,gBAAgB,aAAa,aAAa,IAC1C,KAAK,aAAa,QAAS;AAE/B,YAAM,cAAc,MAAM,KAAK,WAAW,kBAAkB;AAC5D,YAAM,kBAAkB,cAAc,KAAK,MAAM,KAAK,eAAe;AACrE,YAAM,aAAa,cAAc;AACjC,YAAM,MAAM,cACR,EAAE,cAAc,UAAmB,MAAM,CAAC,SAAS,oBAAoB,SAAS,OAAO,EAAE,IACzF,EAAE,cAAc,OAAgB,MAAM,CAAC,SAAS,SAAS,OAAO,EAAE;AAEtE,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,iBAAgB;AAAA,QACrB,cAAc,IAAI;AAAA,QAClB,MAAM,IAAI;AAAA,QACV,OAAO;AAAA,QACP,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,QACP,GAAK,aAAa,CAAC;AAAA,MACrB,CAAU;AAAA,IACZ,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,SAAS,iBAAiB,KAAK;AACrC,UAAI,OAAQ,OAAM;AAClB,YAAM,IAAI,kBAAkB,wBAAwB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACrH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YAAY,QAAkC;AAClD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,kBAAkB;AAAA,IACxD;AACA,UAAM,EAAE,SAAS,SAAS,SAAS,YAAY,IAAI;AACnD,oBAAgB,OAAO;AACvB,yBAAqB,CAAC,SAAS,OAAO,GAAG,CAAC,WAAW,SAAS,CAAC;AAC/D,UAAM,cAAc,QAAQ,OAAO,CAAC,KAAK,QAAQ,MAAM,KAAK,EAAE;AAC9D,UAAM,qBAAqB,cACvB,gBAAgB,aAAa,aAAa,IAC1C,KAAK,aAAa,QAAS;AAC/B,UAAM,cAAc,MAAM,KAAK,WAAW,kBAAkB;AAC5D,UAAM,QAAQ,eAAe,cAAc,KAAK,MAAM,KAAK,eAAe;AAC1E,UAAM,MAAM,cACR,EAAE,cAAc,UAAmB,MAAM,CAAC,SAAS,oBAAoB,SAAS,OAAO,EAAE,IACzF,EAAE,cAAc,OAAgB,MAAM,CAAC,SAAS,SAAS,OAAO,EAAE;AACtE,QAAI;AACF,YAAM,KAAK,aAAa,iBAAiB;AAAA,QACvC,SAAS,KAAK;AAAA,QACd,KAAK,iBAAgB;AAAA,QACrB,cAAc,IAAI;AAAA,QAClB,MAAM,IAAI;AAAA,QACV;AAAA,QACA,SAAS,KAAK,aAAa;AAAA,MAC7B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,iBAAiB,KAAK,KAAK;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,QAA6C;AACvD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,UAAU;AAAA,IAChD;AAEA,QAAI,OAAO,UAAU,IAAI;AACvB,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC7D;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,iBAAgB;AAAA,QACrB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO,OAAO;AAAA,QACrB,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,QACP,GAAK,OAAO,aAAa,CAAC;AAAA,MAC5B,CAAU;AAAA,IACZ,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,SAAS,iBAAiB,KAAK;AACrC,UAAI,OAAQ,OAAM;AAClB,YAAM,IAAI,kBAAkB,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACzH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,cAAc,QAAqD;AACvE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,UAAU;AAAA,IAChD;AAEA,QAAI,OAAO,UAAU,IAAI;AACvB,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC7D;AAEA,UAAM,OAAO,gBAAgB,OAAO,MAAM,MAAM;AAChD,UAAM,kBAAkB,OAAO,kBAC3B,gBAAgB,OAAO,iBAAiB,iBAAiB,IACzD;AACJ,UAAM,gBAAgB,OAAO,gBACzB,gBAAgB,OAAO,eAAe,eAAe,IACrD;AAEJ,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,iBAAgB;AAAA,QACrB,cAAc;AAAA,QACd,MAAM,CAAC;AAAA,UACL;AAAA,UACA,SAAS,OAAO;AAAA,UAChB;AAAA,UACA;AAAA,UACA,WAAW,OAAO,aAAa;AAAA,UAC/B,SAAS,OAAO,WAAW;AAAA,QAC7B,CAAC;AAAA,QACD,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACzH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,WACJ,UACA,MACA,SAC0B;AAC1B,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,gBAAgB;AAAA,IACtD;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI,kBAAkB,oBAAoB;AAAA,IAClD;AAEA,UAAM,YAAY,OAAO,gBAAgB,MAAM,MAAM,IAAI,KAAK,aAAa,QAAS;AACpF,UAAM,SAA0B,CAAC;AAEjC,eAAW,WAAW,UAAU;AAC9B,UAAI,UAAU,IAAI;AAChB,cAAM,IAAI,kBAAkB,qBAAqB,OAAO,EAAE;AAAA,MAC5D;AAEA,UAAI;AACF,cAAM,OAAO,MAAM,KAAK,cAAc;AAAA,UACpC,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAED,eAAO,KAAK,IAAI;AAGhB,YAAI,SAAS,gBAAgB;AAC3B,gBAAM,0BAA0B,KAAK,cAAc,IAAI;AAAA,QACzD;AAAA,MACF,SAAS,OAAO;AAGd,cAAM,IAAI;AAAA,UACR,yBAAyB,OAAO,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC3F;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,UAA2C;AAC/D,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,oBAAoB;AAAA,IAC1D;AACA,UAAM,kBAAkB,gBAAgB,UAAU,UAAU;AAC5D,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,eAAe;AAAA,MACtB,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,UAA2C;AAC9D,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,mBAAmB;AAAA,IACzD;AACA,UAAM,kBAAkB,gBAAgB,UAAU,UAAU;AAC5D,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,eAAe;AAAA,MACtB,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,MAAe,UAAqC;AACpE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAoB,QAAwC;AAChE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,qBAAqB;AAAA,IAC3D;AACA,mBAAe,QAAQ,iBAAiB;AACxC,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,MACb,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,OAAuC;AAC3D,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,uBAAuB;AAAA,IAC7D;AACA,mBAAe,OAAO,gBAAgB;AACtC,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd;AAAA,MACA,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,wBAAgD;AACpD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,4BAA4B;AAAA,IAClE;AACA,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,SAA0C;AACzD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,eAAe;AAAA,IACrD;AACA,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,iBAAgB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,MACd,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,SAAqF;AACzG,UAAM,WAAW,MAAM,KAAK,KAAK;AACjC,UAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC;AAK5D,QAAI;AACF,YAAM,YAAY,QAAQ,QAAQ,CAAC,OAAO;AAAA,QACxC,EAAE,SAAS,KAAK,SAAS,KAAK,iBAAgB,KAAK,cAAc,oBAAoB,MAAM,CAAC,SAAS,EAAE,EAAE;AAAA,QACzG,EAAE,SAAS,KAAK,SAAS,KAAK,iBAAgB,KAAK,cAAc,sBAAsB,MAAM,CAAC,SAAS,EAAE,EAAE;AAAA,MAC7G,CAAC;AACD,YAAM,MAAO,MAAM,KAAK,aAAa,UAAU;AAAA,QAC7C;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AACD,aAAO,QAAQ,IAAI,CAAC,QAAQ,OAAO,EAAE,QAAQ,OAAO,IAAI,IAAI,CAAC,GAAI,SAAS,IAAI,IAAI,IAAI,CAAC,EAAG,EAAE;AAAA,IAC9F,QAAQ;AACN,YAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC1C,QAAQ,IAAI,QAAQ,IAAI,CAAC,OAAO,KAAK,iBAAiB,SAAS,EAAE,CAAC,CAAC;AAAA,QACnE,QAAQ,IAAI,QAAQ,IAAI,CAAC,OAAO,KAAK,mBAAmB,SAAS,EAAE,CAAC,CAAC;AAAA,MACvE,CAAC;AACD,aAAO,QAAQ,IAAI,CAAC,QAAQ,OAAO,EAAE,QAAQ,OAAO,OAAO,CAAC,GAAI,SAAS,QAAQ,CAAC,EAAG,EAAE;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,SAAiB,MAAmE;AACpG,UAAM,WAAW,MAAM,KAAK,KAAK;AACjC,UAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC;AAG5D,QAAI;AACJ,QAAI;AACF,YAAM,YAAY,QAAQ,IAAI,CAAC,QAAQ;AAAA,QACrC,SAAS,KAAK;AAAA,QACd,KAAK,iBAAgB;AAAA,QACrB,cAAc;AAAA,QACd,MAAM,CAAC,SAAS,IAAI,IAAI;AAAA,MAC1B,EAAE;AACF,aAAQ,MAAM,KAAK,aAAa,UAAU,EAAE,WAA+B,cAAc,MAAM,CAAC;AAAA,IAClG,QAAQ;AACN,aAAO,MAAM,QAAQ,IAAI,QAAQ,IAAI,CAAC,OAAO,KAAK,WAAW,SAAS,IAAI,IAAI,CAAC,CAAC;AAAA,IAClF;AAEA,WAAO,QACJ,IAAI,CAAC,QAAQ,OAAO,EAAE,QAAQ,QAAQ,KAAK,CAAC,EAAG,EAAE,EACjD,OAAO,CAAC,QAAmD,IAAI,SAAS,EAAE;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,kBACJ,SACA,OAAwD,CAAC,GACrC;AACpB,UAAM,WAAW,KAAK,kBAAkB;AACxC,UAAM,WAAW,KAAK,cAAc,SAAY,KAAK,IAAI,IAAI,KAAK,YAAY;AAC9E,eAAS;AACP,YAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzC,UAAI,MAAM,SAAU,QAAO;AAC3B,UAAI,KAAK,IAAI,KAAK,SAAU,OAAM,IAAI,MAAM,SAAS,OAAO,wBAAwB,KAAK,SAAS,IAAI;AACtG,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,mBACE,YACA,OAA6C,CAAC,GAClC;AACZ,WAAO,KAAK,aAAa,mBAAmB;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,WAAW;AAAA,MACX,QAAQ,CAAC,SAAS;AAChB,mBAAW,OAAO,KAAM,YAAY,IAAwD,IAAI;AAAA,MAClG;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UACE,OACA,OAA+D,CAAC,GACpD;AACZ,WAAO,KAAK,aAAa,mBAAmB;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,WAAW;AAAA,MACX,MAAM,KAAK,YAAY,SAAa,EAAE,SAAS,KAAK,QAAQ,IAAc;AAAA,MAC1E,QAAQ,CAAC,SAAS;AAChB,mBAAW,OAAO,KAAM,OAAO,IAAoD,IAAI;AAAA,MACzF;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;AAAA;AAx6Ba,iBAMa,MAAMC,UAAS;AAAA;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;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,CAAC;AAtEI,IAAM,kBAAN;;;AITP,SAAkB,YAAAC,iBAA4C;AAUvD,IAAM,eAAN,MAAM,aAAY;AAAA,EA2BvB,YAAY,cAA4B,cAAwC,SAAkB;AAChG,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,cAA8C;AAC5D,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBAAiB,SAAkC;AACvD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkC;AACtC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAyC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,SAAkC;AAC1D,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,SAAkC;AAC9C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,SAAkC;AAC9C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA+B;AACnC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA+B;AACnC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,yBAA0C;AAC9C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA4B;AAChC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,SAAuC;AAC1D,UAAM,CAAC,cAAc,UAAU,UAAU,sBAAsB,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnF,KAAK,YAAY;AAAA,MACjB,KAAK,QAAQ,OAAO;AAAA,MACpB,KAAK,iBAAiB,OAAO;AAAA,MAC7B,KAAK,sBAAsB;AAAA,IAC7B,CAAC;AAED,WAAO;AAAA,MACL,aAAa;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,MACT,uBAAuB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,MAAM,SAAyC;AACnD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,SAAS;AAAA,IAC/C;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,aAAY;AAAA,QACjB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO;AAAA,QACd,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,oBAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACjH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,SAAyC;AACrD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,WAAW;AAAA,IACjD;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,aAAY;AAAA,QACjB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO;AAAA,QACd,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACnH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAmB,SAAyC;AAChE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,kBAAkB;AAAA,IACxD;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,aAAY;AAAA,QACjB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO;AAAA,QACd,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACzH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,SAAyC;AACxD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,eAAe;AAAA,IACrD;AACA,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,MACd,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAK,SAAyC;AAClD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,QAAQ;AAAA,IAC9C;AACA,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,MACd,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,UAA4C;AACzD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,QAAQ;AAAA,IAC9C;AACA,WAAO,MAAM,KAAK,aAAa,cAAc;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,MACd,MAAM,CAAC,QAAQ;AAAA,MACf,SAAS,KAAK,aAAa;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AA/Ta,aAKa,MAAMC,UAAS;AAAA;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAzBI,IAAM,cAAN;;;ACVP,SAAkB,YAAAC,iBAA4C;AAOvD,IAAM,aAAN,MAAM,WAAU;AAAA,EAuBrB,YAAY,cAA4B,cAAwC,SAAkB;AAChG,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,cAA8C;AAC5D,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA+B;AACnC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,SAAmC;AACjD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,OAAgB,SAAmC;AACjE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,OAAO,OAAO;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAwB;AAC5B,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAA0B;AAC9B,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA4B;AAChC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAA6B;AACjC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,WAAU;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,SAAS,IAAa,QAAwC;AAClE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,cAAc;AAAA,IACpD;AAEA,UAAM,YAAY,gBAAgB,IAAI,WAAW;AACjD,mBAAe,QAAQ,iBAAiB;AAExC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,QACd,MAAM,CAAC,WAAW,MAAM;AAAA,QACxB,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACpH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,QAAQ,SAAkB,QAAwC;AACtE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,WAAW;AAAA,IACjD;AAEA,UAAM,iBAAiB,gBAAgB,SAAS,SAAS;AACzD,mBAAe,QAAQ,iBAAiB;AAExC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,QACd,MAAM,CAAC,gBAAgB,MAAM;AAAA,QAC7B,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACnH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,aAAa,MAAe,IAAa,QAAwC;AACrF,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,cAAc;AAAA,IACpD;AAEA,UAAM,cAAc,gBAAgB,MAAM,MAAM;AAChD,UAAM,YAAY,gBAAgB,IAAI,IAAI;AAC1C,mBAAe,QAAQ,iBAAiB;AAExC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,QACd,MAAM,CAAC,aAAa,WAAW,MAAM;AAAA,QACrC,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACxH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAK,QAAwC;AACjD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,SAAS;AAAA,IAC/C;AAEA,mBAAe,QAAQ,aAAa;AAEpC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,QACd,MAAM,CAAC,MAAM;AAAA,QACb,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IAChH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,SAAS,SAAkB,QAAwC;AACvE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,UAAU;AAAA,IAChD;AAEA,UAAM,iBAAiB,gBAAgB,SAAS,SAAS;AACzD,mBAAe,QAAQ,aAAa;AAEpC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,QACd,MAAM,CAAC,gBAAgB,MAAM;AAAA,QAC7B,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACpH;AAAA,EACF;AACF;AA7Ra,WAKa,MAAMC,UAAS;AAAA;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AArBI,IAAM,YAAN;;;ACPP,SAAkB,YAAAC,iBAA4C;AAcvD,IAAM,kBAAN,MAAM,gBAAe;AAAA,EA4B1B,YAAY,cAA4B,cAAwC,SAAkB;AAChG,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,cAA8C;AAC5D,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAwC;AACrD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AAED,WAAO;AAAA,MACL,SAAS,OAAO,CAAC;AAAA,MACjB,aAAa,OAAO,CAAC;AAAA,MACrB,gBAAgB,OAAO,OAAO,CAAC,CAAC;AAAA,MAChC,eAAe,OAAO,CAAC;AAAA,MACvB,SAAS,OAAO,CAAC;AAAA,MACjB,WAAW,OAAO,CAAC;AAAA,MACnB,SAAU,OAAO,CAAC,EAAmC,IAAI,CAAC,MAAc,OAAO,CAAC,CAAC;AAAA,MACjF,UAAW,OAAO,CAAC,EAAmC,IAAI,CAAC,MAAc,OAAO,CAAC,CAAC;AAAA,MAClF,kBAAkB,OAAO,CAAC;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,MAA4D;AAC/E,UAAM,CAAC,OAAO,MAAM,IAAI,MAAM,KAAK,aAAa,aAAa;AAAA,MAC3D,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AACD,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAe,SAAmC;AACpE,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA4B;AAChC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkC;AACtC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAwC;AAC5C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAyC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,qBAAsC;AAC1C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAiC;AACrC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,gBAAe;AAAA,MACpB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,OAAuC;AACnD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,YAAY;AAAA,IAClD;AAEA,mBAAe,OAAO,gBAAgB;AAEtC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd;AAAA,QACA,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACnH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,SAAS,QAAgB,IAAqC;AAClE,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,aAAa;AAAA,IACnD;AAEA,mBAAe,QAAQ,iBAAiB;AACxC,UAAM,YAAY,gBAAgB,IAAI,WAAW;AAEjD,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,MAAM,CAAC,QAAQ,SAAS;AAAA,QACxB,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,uBAAuB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACpH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,cACJ,OACA,eACA,SACA,UACA,WACwB;AACxB,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,kBAAkB;AAAA,IACxD;AAEA,SAAK,mBAAmB,OAAO,eAAe,SAAS,QAAQ;AAE/D,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO,eAAe,SAAS,UAAU,SAAS;AAAA,QACzD,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IAC1H;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,wBACJ,OACA,eACA,SACA,UACA,WACA,OACwB;AACxB,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,kBAAkB;AAAA,IACxD;AAEA,SAAK,mBAAmB,OAAO,eAAe,SAAS,QAAQ;AAC/D,mBAAe,OAAO,gBAAgB;AAEtC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,MAAM,CAAC,OAAO,eAAe,SAAS,UAAU,SAAS;AAAA,QACzD;AAAA,QACA,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IAC1H;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAsC;AAC1C,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,gBAAgB;AAAA,IACtD;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACxH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAqC;AACzC,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,iBAAiB;AAAA,IACvD;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACvH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,WAAW,MAAe,UAAkB,cAAwB,CAAC,GAA2B;AACpG,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,gBAAgB;AAAA,IACtD;AAEA,UAAM,cAAc,gBAAgB,MAAM,MAAM;AAChD,QAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,YAAY,GAAG;AAChD,YAAM,IAAI,kBAAkB,qCAAqC;AAAA,IACnE;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,MAAM,CAAC,aAAa,UAAU,WAAW;AAAA,QACzC,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACxH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,SAAS,MAAe,aAA+C;AAC3E,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,0BAA0B,UAAU;AAAA,IAChD;AAEA,UAAM,cAAc,gBAAgB,MAAM,MAAM;AAChD,QAAI,YAAY,WAAW,GAAG;AAC5B,YAAM,IAAI,kBAAkB,+BAA+B;AAAA,IAC7D;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,cAAc;AAAA,QAC3C,SAAS,KAAK;AAAA,QACd,KAAK,gBAAe;AAAA,QACpB,cAAc;AAAA,QACd,MAAM,CAAC,aAAa,WAAW;AAAA,QAC/B,SAAS,KAAK,aAAa;AAAA,QAC3B,OAAO;AAAA,MACT,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,6BAA6B,iBAAiB,mBAAmB;AACpF,cAAM;AAAA,MACR;AACA,YAAM,IAAI,kBAAkB,oBAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,KAAK;AAAA,IACjH;AAAA,EACF;AAAA,EAEQ,mBAAmB,OAAe,eAAuB,SAAmB,UAA0B;AAC5G,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,SAAS,GAAG;AAC1C,YAAM,IAAI,kBAAkB,kCAAkC;AAAA,IAChE;AACA,mBAAe,eAAe,eAAe;AAC7C,oBAAgB,OAAO;AACvB,yBAAqB,CAAC,SAAS,QAAQ,GAAG,CAAC,WAAW,UAAU,CAAC;AACjE,mBAAe,UAAU,UAAU;AAAA,EACrC;AACF;AArca,gBAKa,MAAMC,UAAS;AAAA;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA1BI,IAAM,iBAAN;;;ACdP,SAAkB,YAAAC,iBAA4C;AAUvD,IAAM,WAAN,MAAM,SAAQ;AAAA,EAgBnB,YAAY,cAA4B,eAAyC,SAAkB;AACjG,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGA,gBAAgB,eAA+C;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhE,MAAM,gBAAgB,QAAiC;AACrD,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAsC;AAC1C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAgC;AACpC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAqC;AACzC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA4B;AAChC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA4B;AAChC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAA6B;AACjC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAwC;AAC5C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,SAAQ;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AArHa,SAIa,MAAMA,UAAS;AAAA;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAdI,IAAM,UAAN;;;ACVP,SAAkB,YAAAC,iBAA4C;AASvD,IAAM,oBAAN,MAAM,kBAAiB;AAAA,EAgB5B,YAAY,cAA4B,eAAyC,SAAkB;AACjG,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGA,gBAAgB,eAA+C;AAAA,EAE/D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAgC;AAC7C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAmC;AAChD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAUD,WAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,MAAM,OAAO;AAAA,MACb,gBAAgB,OAAO,OAAO,cAAc;AAAA,MAC5C,cAAc,OAAO,OAAO,YAAY;AAAA,MACxC,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAiC;AAC9C,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,IAAI;AAAA,IACb,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAqC;AAClD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,QAAmC;AAC9C,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAiC;AAC9C,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AACD,WAAO,OAAO,MAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,QAAiC;AACpD,UAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AACD,WAAO,OAAO,MAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAqC;AACzC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAA6B;AACjC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,kBAAiB;AAAA,MACtB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AAzJa,kBAIa,MAAMA,UAAS;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAdI,IAAM,mBAAN;;;ACTP,SAAkB,YAAAC,iBAA4C;AAKvD,IAAM,eAAN,MAAM,aAAY;AAAA;AAAA,EAUvB,YAAY,cAA4B,eAAyC,SAAkB;AACjG,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGA,gBAAgB,eAA+C;AAAA,EAE/D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAA+B;AACnC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAmC;AACvC,WAAO,MAAM,KAAK,aAAa,aAAa;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,KAAK,aAAY;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AAzCa,aAIa,MAAMA,UAAS;AAAA,EACrC;AAAA,EACA;AACF,CAAC;AAPI,IAAM,cAAN;;;ACLP,SAAgC,YAAAC,iBAAgB;AAiCzC,IAAM,aAAN,MAAM,WAAU;AAAA,EAUrB,YAAY,cAA4B,aAAsB,kBAA2B;AACvF,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAGA,MAAM,cAAqC;AACzC,UAAM,CAAC,UAAU,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC3C,KAAK,aAAa,aAAa;AAAA,QAC7B,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,KAAK,aAAa,aAAa;AAAA,QAC7B,SAAS,KAAK;AAAA,QACd,KAAK,WAAU;AAAA,QACf,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAED,UAAM,eAAe,OAAO,YAAY,MAAM,KAAK,iBAAiB,YAAY;AAChF,UAAM,cAAc,eAAe,SAAS,CAAC,IAAI,SAAS,CAAC;AAC3D,UAAM,aAAa,eAAe,SAAS,CAAC,IAAI,SAAS,CAAC;AAC1D,WAAO,EAAE,aAAa,YAAY,aAAa;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAiC;AACrC,UAAM,EAAE,aAAa,WAAW,IAAI,MAAM,KAAK,YAAY;AAC3D,QAAI,gBAAgB,IAAI;AACtB,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AACA,WAAO,OAAO,UAAU,IAAI,OAAO,WAAW;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAoC;AACxC,UAAM,EAAE,aAAa,WAAW,IAAI,MAAM,KAAK,YAAY;AAC3D,QAAI,gBAAgB,IAAI;AACtB,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AACA,WAAQ,aAAa,OAAO,MAAO;AAAA,EACrC;AACF;AA7Da,WAKa,WAAWA,UAAS;AAAA,EAC1C;AAAA,EACA;AACF,CAAC;AARI,IAAM,YAAN;;;ACjCP,SAAgC,YAAAC,kBAAgB;AAoBzC,IAAM,sBAAN,MAAM,oBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiB9B,YACE,cACA,aACA,MACA;AACA,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,kBAAkB,MAAM;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,eAAiF;AACrF,UAAM,CAAC,UAAU,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9C,KAAK,aAAa,aAAa;AAAA,QAC7B,SAAS,KAAK;AAAA,QACd,KAAK,oBAAmB;AAAA,QACxB,cAAc;AAAA,MAChB,CAAC;AAAA,MACD,KAAK,aAAa,aAAa;AAAA,QAC7B,SAAS,KAAK;AAAA,QACd,KAAK,oBAAmB;AAAA,QACxB,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AACD,WAAO,EAAE,QAAQ,UAAU,CAAC,GAAG,UAAU,WAAW,UAAU,CAAC,EAAE;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAA4B;AAChC,UAAM,EAAE,QAAQ,UAAU,UAAU,IAAI,MAAM,KAAK,aAAa;AAChE,QAAI,UAAU,IAAI;AAChB,YAAM,IAAI,MAAM,kBAAkB,KAAK,WAAW,iCAAiC;AAAA,IACrF;AACA,QAAI,KAAK,oBAAoB,QAAW;AACtC,YAAM,SAAS,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC3C,YAAM,MAAM,SAAS,OAAO,SAAS;AACrC,UAAI,MAAM,KAAK,iBAAiB;AAC9B,cAAM,IAAI;AAAA,UACR,kBAAkB,KAAK,WAAW,cAAc,GAAG,cAAc,KAAK,eAAe;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AACA,WAAO,OAAO,MAAM,IAAI,MAAM;AAAA,EAChC;AACF;AAjEa,oBAKa,MAAMA,WAAS;AAAA,EACrC;AAAA,EACA;AACF,CAAC;AARI,IAAM,qBAAN;;;ACoBA,IAAM,YAAY;AAGlB,IAAM,gCAAgC,IAAI;AAG1C,IAAM,mBAAmB;AAGzB,IAAM,mBAAmB;AAGzB,IAAM,eAAe;AA6ErB,SAAS,oBAAoB,OAAwC;AAC1E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,eAAe;AAAA,IACf,cAAc;AAAA,IACd,cAAc;AAAA,EAChB,IAAI;AAEJ,MAAI,EAAE,QAAQ,GAAI,OAAM,IAAI,MAAM,+BAA+B,KAAK,GAAG;AACzE,MAAI,EAAE,MAAM,GAAI,OAAM,IAAI,MAAM,6BAA6B,GAAG,GAAG;AAEnE,QAAM,cAAc,SAAS;AAC7B,QAAM,UAAU,UAAU,IAAI,eAAe,MAAS;AAEtD,QAAM,QAAQ,QAAQ;AACtB,QAAM,WAAW,cAAc;AAC/B,QAAM,YAAY,QAAQ;AAC1B,QAAM,eAAe,YAAY,eAAe;AAGhD,QAAM,eACJ,cAAc,KAAK,OAAO,SAAS,WAAW,IAAK,IAAI,cAAe,QAAQ,cAAc;AAE9F,QAAM,kBAAkB,eAAe;AACvC,QAAM,SAAS,kBAAkB;AAIjC,QAAM,oBACJ,mBAAmB,eAAe,WACjC,cAAc,KAAK,OAAO,SAAS,WAAW,IAAI,cAAc,cAAc;AACjF,QAAM,eAAe,cAAc,IAAI,oBAAoB,cAAc;AAGzE,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,wBACJ,kBAAkB,KAAK,WAAW,gBAAgB,kBAAkB;AAEtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,SAAS;AAAA,IACpB;AAAA,IACA;AAAA,IACA,YAAY,SAAS;AAAA,EACvB;AACF;;;ACzLA;AAAA,EAME;AAAA,EACA;AAAA,EACA,eAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;;;ACXpC,SAAkB,mBAAmB;AA2D9B,IAAM,YAA4B;AAAA,EACvC,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,aACE;AAAA,EACF,WAAW;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMb,iBAAiB;AAAA;AAAA,IAEjB,YAAY;AAAA,EACd;AACF;AAWO,IAAM,cAAc;AAAA,EACzB;AACF;AAcO,IAAM,iBAAiB,YAAY;AAAA,EACxC,IAAI,UAAU;AAAA,EACd,MAAM,UAAU;AAAA,EAChB,gBAAgB,EAAE,UAAU,IAAI,MAAM,SAAS,QAAQ,MAAM;AAAA,EAC7D,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,MAAM,EAAE,EAAE;AAAA,EACjD,gBAAgB;AAAA,IACd,SAAS,EAAE,MAAM,cAAc,KAAK,wCAAwC;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA,EAIA,WAAW;AAAA,IACT,YAAY,EAAE,SAAS,UAAU,UAAU,WAAY;AAAA,EACzD;AACF,CAAC;;;ADpFM,SAAS,oBAAoB,YAAmC;AACrE,MAAI,WAAW,YAAY,UAAU,QAAS,QAAO;AACrD,SAAOC,aAAY;AAAA,IACjB,IAAI,WAAW;AAAA,IACf,MAAM,WAAW;AAAA,IACjB,gBAAgB,EAAE,UAAU,IAAI,MAAM,SAAS,QAAQ,MAAM;AAAA,IAC7D,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,MAAM,EAAE,EAAE;AAAA,IAClD,GAAI,WAAW,gBACX,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,KAAK,WAAW,cAAc,EAAE,EAAE,IACnF,CAAC;AAAA,IACL,GAAI,WAAW,UAAU,aACrB,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,WAAW,UAAU,WAAW,EAAE,EAAE,IAC1E,CAAC;AAAA,EACP,CAAC;AACH;AAqBO,SAAS,kBAAkB,OAAuB,CAAC,GAAgB;AACxE,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,QAAQ,oBAAoB,UAAU;AAC5C,QAAM,YAAY,KAAK,aAAa,KAAK,KAAK,UAAU,WAAW,QAAQ,EAAE,SAAS,KAAQ,YAAY,EAAE,CAAC;AAE7G,QAAM,eAAe,mBAAmB;AAAA,IACtC;AAAA,IACA;AAAA,IACA,OAAO,EAAE,WAAW,KAAK,kBAAkB,KAAK;AAAA,IAChD,GAAI,KAAK,kBAAkB,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;AAAA,EAC1E,CAAC;AAED,QAAM,UAAU,KAAK,YAAY,KAAK,aAAa,oBAAoB,KAAK,UAAU,IAAI;AAC1F,QAAM,eAAe,UAChB,mBAAmB,EAAE,OAAO,WAAW,QAAQ,CAAC,IACjD;AAEJ,SAAO,EAAE,OAAO,cAAc,aAAa;AAC7C;;;AEyBO,IAAK,aAAL,kBAAKC,gBAAL;AACL,EAAAA,wBAAA,aAAU,KAAV;AACA,EAAAA,wBAAA,YAAS,KAAT;AACA,EAAAA,wBAAA,YAAS,KAAT;AACA,EAAAA,wBAAA,aAAU,KAAV;AAJU,SAAAA;AAAA,GAAA;AAUL,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,eAAY,KAAZ;AACA,EAAAA,oBAAA,kBAAe,KAAf;AAHU,SAAAA;AAAA,GAAA;;;AC/FZ,eAAsB,YACpB,cACA,SACA,KACA,cACA,MACA,OACA,SACiB;AACjB,MAAI;AACF,UAAM,iBAAsB;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,UAAU,QAAW;AACvB,qBAAe,QAAQ;AAAA,IACzB;AACA,QAAI,YAAY,QAAW;AACzB,qBAAe,UAAU;AAAA,IAC3B;AACA,UAAM,MAAM,MAAM,aAAa,oBAAoB,cAAc;AACjE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,8BAA8B,YAAY,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACrG;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAUA,eAAsB,eACpB,cACA,MACA,UAAkB,MACA;AAClB,MAAI;AACF,UAAM,UAAU,MAAM,aAAa,0BAA0B;AAAA,MAC3D;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI,WAAW,OAAO,YAAY,YAAY,YAAY,SAAS;AACjE,UAAI,QAAQ,WAAW,YAAY;AACjC,cAAM,IAAI;AAAA,UACR,yBAAyB,IAAI;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB;AACrC,YAAM;AAAA,IACR;AACA,UAAM,IAAI;AAAA,MACR,2CAA2C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACjG;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAaA,eAAsB,mBACpB,cACA,cACA,SACA,KACA,cACA,MACA,UAAmD,CAAC,GAClB;AAClC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,aAAa;AAAA,IACtB,OAAO;AAAA,IACP,GAAI,UAAU,UAAa,EAAE,MAAM;AAAA,IACnC,GAAI,QAAQ,UAAa,EAAE,IAAI;AAAA,IAC/B,GAAI,aAAa,UAAa,EAAE,SAAS;AAAA,IACzC,GAAI,iBAAiB,UAAa,EAAE,aAAa;AAAA,IACjD,GAAI,yBAAyB,UAAa,EAAE,qBAAqB;AAAA,EACnE;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,aAAa,cAAc,WAAW;AAEzD,QAAI,iBAAiB;AACnB,aAAO,MAAM,eAAe,cAAc,MAAM,cAAc;AAAA,IAChE;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AjB9GO,IAAM,UAAN,MAAM,SAAQ;AAAA,EAenB,YAAY,QAAoB;AAC9B,SAAK,SAAS;AAGd,SAAK,UAAU,IAAI;AAAA,MACjB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO,UAAU;AAAA,IACnB;AAEA,SAAK,UAAU,IAAI;AAAA,MACjB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO,UAAU;AAAA,IACnB;AAEA,SAAK,QAAQ,IAAI;AAAA,MACf,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO,UAAU;AAAA,IACnB;AAGA,QAAI,OAAO,UAAU,YAAY;AAC/B,WAAK,aAAa,IAAI;AAAA,QACpB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,KAAK;AACxB,WAAK,MAAM,IAAI;AAAA,QACb,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,UAAU;AAC7B,WAAK,WAAW,IAAI;AAAA,QAClB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,SAAS;AAC5B,WAAK,UAAU,IAAI;AAAA,QACjB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,aAAa;AAChC,WAAK,QAAQ,IAAI;AAAA,QACf,OAAO;AAAA,QACP,OAAO,UAAU;AAAA,QACjB,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAGA,QAAI,OAAO,UAAU,iBAAiB;AACpC,WAAK,SAAS,IAAI,mBAAmB,OAAO,cAAc,OAAO,UAAU,eAAe;AAAA,IAC5F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,QAAQ,OAAuB,CAAC,GAAY;AACjD,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,EAAE,cAAc,aAAa,IAAI,kBAAkB,IAAI;AAC7D,WAAO,IAAI,SAAQ,EAAE,cAAc,cAAc,WAAW,WAAW,UAAU,CAAC;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAgC;AAC9B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,kBAA4C;AAC1C,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,cAA8C;AAC5D,SAAK,OAAO,eAAe;AAG3B,SAAK,QAAQ,gBAAgB,YAAY;AACzC,SAAK,QAAQ,gBAAgB,YAAY;AACzC,SAAK,MAAM,gBAAgB,YAAY;AACvC,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,gBAAgB,YAAY;AAAA,IAC9C;AACA,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,gBAAgB,YAAY;AAAA,IACvC;AACA,QAAI,KAAK,UAAU;AACjB,WAAK,SAAS,gBAAgB,YAAY;AAAA,IAC5C;AACA,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,gBAAgB,YAAY;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,oBAAoB,aAAqB,aAAiC;AAC/E,QAAI,YAAY,WAAW,GAAG;AAC5B,YAAM,IAAI,gBAAgB,qCAAqC,aAAa;AAAA,IAC9E;AAEA,UAAM,eAAe,YAAY,OAAO,CAAC,KAAK,MAAM,MAAM,GAAG,CAAC;AAC9D,QAAI,KAAK,IAAI,eAAe,GAAG,IAAI,MAAM;AACvC,YAAM,IAAI,gBAAgB,oCAAoC,YAAY,KAAK,aAAa;AAAA,IAC9F;AAEA,UAAM,UAAoB,CAAC;AAC3B,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,YAAM,aAAa,YAAY,CAAC;AAChC,UAAI,eAAe,OAAW;AAC9B,YAAM,SAAU,cAAc,OAAO,KAAK,MAAM,aAAa,GAAG,CAAC,IAAK;AACtE,cAAQ,KAAK,MAAM;AACnB,mBAAa;AAAA,IACf;AAGA,QAAI,cAAc,eAAe,QAAQ,SAAS,KAAK,QAAQ,CAAC,MAAM,QAAW;AAC/E,cAAQ,CAAC,KAAK,cAAc;AAAA,IAC9B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,YAAY,OAAe,WAAmB,IAAI,YAAoB,GAAW;AACtF,UAAM,UAAU,OAAO,MAAM,QAAQ;AACrC,UAAM,QAAQ,QAAQ;AACtB,UAAM,YAAY,QAAQ;AAC1B,UAAM,aAAc,YAAY,OAAO,MAAM,SAAS,IAAK;AAE3D,QAAI,eAAe,IAAI;AACrB,aAAO,MAAM,SAAS;AAAA,IACxB;AAEA,UAAM,gBAAgB,WAAW,SAAS,EAAE,SAAS,WAAW,GAAG,EAAE,QAAQ,OAAO,EAAE;AACtF,WAAO,gBAAgB,GAAG,KAAK,IAAI,aAAa,KAAK,MAAM,SAAS;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,WAAW,OAAe,WAAmB,IAAY;AAC9D,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,UAAM,QAAQ,OAAO,MAAM,CAAC,KAAK,GAAG;AACpC,UAAM,aAAa,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,EAAE,OAAO,UAAU,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC,IAAI;AAC1F,WAAO,QAAQ,OAAO,MAAM,QAAQ,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAiB,SAAkC;AAGvD,UAAM,CAAC,UAAU,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC1C,KAAK,QAAQ,SAAS,OAAO;AAAA,MAC7B,KAAK,OAAO,aAAa,SAAS;AAAA,IACpC,CAAC;AACD,UAAM,YAAY,WAAW,MAAM;AACnC,WAAO,YAAY,KAAK,OAAO,SAAS,IAAI;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,SAAiB,MAAiC;AAC/D,UAAM,CAAC,OAAO,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC7C,KAAK,QAAQ,SAAS,OAAO;AAAA,MAC7B,KAAK,QAAQ,cAAc,SAAS,IAAI;AAAA,IAC1C,CAAC;AAED,QAAI,CAAC,MAAM,YAAY,aAAa;AAClC,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,MAAM,KAAK,QAAQ,WAAW,SAAS,MAAM,eAAe,IAAI;AAChF,WAAO,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAAmB,MAAe,cAAsB,YAAuC;AACnG,UAAM,SAAmB,CAAC;AAC1B,aAAS,UAAU,cAAc,WAAW,YAAY,WAAW;AACjE,aAAO,KAAK,OAAO;AAAA,IACrB;AAGA,UAAM,QAAQ,MAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,SAAS,SAAS,IAAI,CAAC,CAAC;AACrF,WAAO,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,sBAAsB,QAAiC;AAC3D,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,IAAI,gBAAgB,qDAAqD,KAAK;AAAA,IACtF;AACA,QAAI,CAAC,KAAK,UAAU;AAClB,YAAM,IAAI,gBAAgB,0DAA0D,UAAU;AAAA,IAChG;AAEA,UAAM,CAAC,MAAM,QAAQ,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,MACpD,KAAK,IAAI,mBAAmB;AAAA,MAC5B,KAAK,SAAS,SAAS,MAAM;AAAA,MAC7B,KAAK,SAAS,kBAAkB;AAAA,IAClC,CAAC;AAED,QAAI,gBAAgB,IAAI;AACtB,aAAO;AAAA,IACT;AAEA,WAAQ,OAAO,SAAU;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,QAAiC;AACrD,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,IAAI,gBAAgB,+CAA+C,KAAK;AAAA,IAChF;AACA,WAAO,MAAM,KAAK,IAAI,gBAAgB,MAAM;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBAAqC;AACzC,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,gBAAgB,yDAAyD,aAAa;AAAA,IAClG;AACA,WAAO,MAAM,KAAK,MAAM,cAAc;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBAAkC;AACtC,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI,gBAAgB,0DAA0D,iBAAiB;AAAA,IACvG;AACA,WAAO,MAAM,KAAK,OAAO,SAAS;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,aAAa,MAAiD;AAClE,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,gBAAgB,oDAAoD,aAAa;AAAA,IAC7F;AACA,UAAM,MAAM,MAAM,KAAK,MAAM,cAAc;AAC3C,QAAI,SAAS,MAAM;AACnB,QAAI,WAAW,UAAa,KAAK,QAAQ;AACvC,eAAS,MAAM,KAAK,OAAO,SAAS;AAAA,IACtC;AACA,WAAO,EAAE,KAAK,KAAK,WAAW,SAAY,MAAM,SAAS,KAAK;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,gBAAgB,QAiBI;AACxB,UAAM,UAAU,OAAO,WAAY,MAAM,KAAK,QAAQ,eAAe;AAErE,UAAM,CAAC,QAAQ,kBAAkB,cAAc,QAAQ,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,MACzF,OAAO,QAAQ,SACX,QAAQ,QAAQ,OAAO,GAAG,IAC1B,KAAK,QACF,gBAAgB,OAAO,EACvB,KAAK,CAAC,QAAQ,OAAO,YAAY,IAAI,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAAA,MACnF,OAAO,qBAAqB,SACxB,QAAQ,QAAQ,OAAO,gBAAgB,IACvC,KAAK,QAAQ,aAAa,EAAE,KAAK,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC,CAAC;AAAA,MAClE,OAAO,iBAAiB,SACpB,QAAQ,QAAQ,OAAO,YAAY,IACnC,KAAK,kBAAkB;AAAA,MAC3B,KAAK,QAAQ,eAAe;AAAA;AAAA,MAE5B,OAAO,gBAAgB,SACnB,QAAQ,QAAQ,OAAO,WAAW,IAClC,KAAK,eAAe,OAAO,EAAE,KAAK,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,MAAM,CAAC;AAAA,IACpF,CAAC;AAED,WAAO,oBAAoB;AAAA,MACzB,OAAO,OAAO;AAAA,MACd,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,aAAa;AAAA,MACb,aAAa,OAAO;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,SAAmC;AACtD,UAAM,KAAK,WAAY,MAAM,KAAK,QAAQ,eAAe;AACzD,UAAM,iBAAiB,MAAM,KAAK,QAAQ,gBAAgB,EAAE;AAC5D,QAAI,mBAAmB,6CAA8C,QAAO;AAC5E,WAAO,MAAM,IAAI,YAAY,KAAK,OAAO,cAAc,QAAW,cAAc,EAAE,YAAY;AAAA,EAChG;AACF;","names":["parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","parseAbi","defineChain","defineChain","GameStatus","GameTier"]}
package/package.json CHANGED
@@ -1,16 +1,22 @@
1
1
  {
2
2
  "name": "@slvr-labs/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TypeScript SDK for interacting with the Slvr protocol on Robinhood Chain",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "module": "dist/index.js",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "module": "./dist/index.mjs",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.js"
13
- }
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
14
20
  },
15
21
  "files": [
16
22
  "dist",
@@ -20,7 +26,7 @@
20
26
  "LICENSE"
21
27
  ],
22
28
  "scripts": {
23
- "build": "tsc",
29
+ "build": "tsup",
24
30
  "prepublishOnly": "npm run build",
25
31
  "clean": "rm -rf dist",
26
32
  "typecheck": "tsc --noEmit",
@@ -58,7 +64,8 @@
58
64
  "devDependencies": {
59
65
  "@types/node": "^20",
60
66
  "typescript": "^5.0.0",
61
- "vitest": "^2.1.9"
67
+ "vitest": "^2.1.9",
68
+ "tsup": "^8.3.5"
62
69
  },
63
70
  "peerDependencies": {
64
71
  "viem": "^2.0.0"
@@ -67,5 +74,6 @@
67
74
  "viem": {
68
75
  "optional": false
69
76
  }
70
- }
77
+ },
78
+ "sideEffects": false
71
79
  }
@@ -68,17 +68,18 @@ with `publicClient.waitForTransactionReceipt`.
68
68
 
69
69
  ## Recipe: read the current round
70
70
 
71
+ The one-call, per-tick snapshot most bots want (batched; `secondsUntilBettingClose`
72
+ uses chain time, not your local clock):
73
+
71
74
  ```typescript
72
- const roundId = await sdk.lottery.currentRoundId();
73
- const [open, squares] = await Promise.all([
74
- sdk.lottery.roundOpen(roundId),
75
- sdk.lottery.getRoundSquares(roundId), // [{ square, total, bettors }] × 25
76
- ]);
77
- const pot = squares.reduce((sum, s) => sum + s.total, 0n);
75
+ const s = await sdk.lottery.getRoundState(); // current round by default
76
+ // { roundId, open, resolved, bettingEnd, roundEnd, totalWager (pot), winningSquare, secondsUntilBettingClose }
77
+ if (s.open && s.secondsUntilBettingClose > 10) { /* enough time to bet */ }
78
78
  ```
79
79
 
80
- Gate "can I still bet?" on **`bettingEnd(roundId)`** (a unix-seconds timestamp),
81
- not on `roundEnd` betting can close before the round ends.
80
+ Need the per-square breakdown? `getRoundSquares(roundId)` returns `[{ square,
81
+ total, bettors }] × 25`. Gate "can I still bet?" on **`bettingEnd`** (or
82
+ `secondsUntilBettingClose`), not on `roundEnd` — betting closes first.
82
83
 
83
84
  ## Recipe: place a bet
84
85
 
@@ -52,6 +52,7 @@ new SlvrSDK({ publicClient, walletClient?, addresses })
52
52
  Reads:
53
53
  - `currentRoundId()`, `roundStart(id)`, `roundEnd(id)`, `roundOpen(id)`, `bettingEnd(id)`, `latestResolvedRoundId()`.
54
54
  - `getRound(id): Promise<RoundInfo>` — flat struct: `{ roundId, requestedAt, resolved, randomnessId, randomnessValue, winningSquare, jackpotHit, singleMinerRound, singleMinerWinner, totalWager, fee, winnerTotal, potForWinners, slvrForWinners, payoutMulWad, slvrMulWad, totalUnclaimedSlvr }`.
55
+ - `getRoundState(id?): Promise<{ roundId, open, resolved, bettingEnd, roundEnd, totalWager, winningSquare, secondsUntilBettingClose }>` — batched per-tick snapshot; countdown uses `block.timestamp`. Defaults to current round.
55
56
  - `getTotalOnSquare(id, square)`, `getBettorsOnSquare(id, square)`, `getUserBet(id, square, bettor)`, `getHasClaimed(id, user)`, `hasAccount(account)`, `getDelegate(user, delegate)`.
56
57
  - `getExpectedReward(account, id)` — estimated reward (wei).
57
58
  - `getMinerState(account): Promise<MinerState>` — `{ rewardsSlvr, refinedAccrued, indexSnapshot, hasAccount }`.
@@ -69,6 +70,13 @@ Writes:
69
70
  - `donateSlvrToJackpot(amount)`, `addEthToJackpot(value)`.
70
71
  - `withdrawUnrefinedSlvr()` — cash out mined SLVR (net of refining fee).
71
72
  - `checkpoint(account)` — force-settle miner accrual (rarely needed; claim/withdraw do it).
73
+ - `getRoundJackpot(id)` — the round's jackpot contract address (zero if none).
74
+
75
+ Preflight & errors:
76
+ - `simulateBet(params)` — `eth_call` preflight; throws a typed `SlvrRevertError` on revert (no tx sent).
77
+ - `bet`/`claim` accept `overrides?: TxOverrides` ({ gas, nonce, maxFeePerGas, … }) and decode reverts into `SlvrRevertError`.
78
+ - `decodeSlvrRevert(err): SlvrRevertError | null` — decode any caught contract error (has `.errorName`, e.g. `InsufficientValue`, `RoundNotOpen`).
79
+ - SDK: `getJackpotPool(id?)` → jackpot pool wei (0 if none); `estimateRoundEv` reads it automatically.
72
80
 
73
81
  Reactive (prefer over polling):
74
82
  - `waitForResolution(roundId, { pollIntervalMs?, timeoutMs? }): Promise<RoundInfo>` — resolves when the round settles.