UNPKG

cardano-uri-parser

Version:

A modular, type-safe Cardano URI parser supporting CIP-13, claim, stake, browse, and future authorities.

1 lines 19.5 kB
{"version":3,"sources":["../src/errors.ts","../src/utils/validators.ts","../src/handlers/addr.ts","../src/handlers/block.ts","../src/handlers/browse.ts","../src/handlers/claim.ts","../src/handlers/pay.ts","../src/handlers/stake.ts","../src/handlers/transaction.ts","../src/handlers/default.ts","../src/cardano-uri-parser.ts"],"sourcesContent":["export class CardanoUriError extends Error {\n type: string;\n details?: any;\n\n constructor(type: string, message: string, details?: any) {\n super(message);\n this.name = 'Errors';\n this.type = type;\n this.details = details;\n }\n}","export function isValidHex64(value: string): boolean {\n return /^[0-9a-fA-F]{64}$/.test(value);\n}\n\nexport function isValidBlockHeight(value: string): boolean {\n return /^[0-9]+$/.test(value) && Number(value) >= 0;\n}\n\nexport function isValidMetadataLabel(value: string): boolean {\n return /^[0-9]+$/.test(value);\n}\n\nexport function classifyCardanoAddress(value: string): { valid: boolean; type?: string; is_testnet?: boolean } {\n const is_testnet = value.includes(\"_test\");\n\n if (value.startsWith(\"stake1\") || value.startsWith(\"stake_test1\")) {\n return {valid: value.length === 59 || value.length === 64, type: \"stake\", is_testnet};\n }\n\n if (value.startsWith(\"addr1\")) {\n return {valid: value.length === 103 || value.length === 58, type: \"shelley\", is_testnet};\n }\n\n if (value.startsWith(\"addr_test1\")) {\n return {valid: value.length === 108 || value.length === 63, type: \"shelley\", is_testnet};\n }\n\n if (value.startsWith(\"Ae2\")) {\n return {valid: value.length >= 59 && value.length <= 64, type: \"byron_icarus\", is_testnet};\n }\n\n if (value.startsWith(\"DdzFF\")) {\n return {valid: value.length >= 104 && value.length <= 128, type: \"byron_daedalus\", is_testnet};\n }\n\n const cip105Prefixes = [\n \"drep_vk\", \"drep_script\", \"drep\",\n \"cc_cold_vk\", \"cc_cold_script\", \"cc_cold\",\n \"cc_hot_vk\", \"cc_hot_script\", \"cc_hot\",\n ];\n\n for (const prefix of cip105Prefixes) {\n if (value.startsWith(prefix)) {\n return {valid: true, type: prefix, is_testnet};\n }\n }\n\n return {valid: false};\n}","import {AddressUri} from \"../types\";\nimport {CardanoUriError} from \"../errors\";\nimport {classifyCardanoAddress} from \"../utils/validators\";\n\nexport function handleAddrUri(rest: string[]): AddressUri {\n const address = rest[0];\n if (!address) {\n throw new CardanoUriError(\"MissingRequiredField\", \"Missing address\");\n }\n\n const { valid, type, is_testnet } = classifyCardanoAddress(address);\n\n if (!valid) {\n throw new CardanoUriError('InvalidAddress', 'Invalid Cardano address format');\n }\n\n return {\n type: 'address',\n address,\n address_type: type,\n is_testnet,\n };\n}\n","import { BlockUri } from '../types';\nimport { CardanoUriError } from '../errors';\nimport { isValidHex64, isValidBlockHeight } from '../utils/validators';\n\nexport function handleBlockUri(\n rest: string[],\n queryParams: URLSearchParams\n): BlockUri {\n const hash = queryParams.get('hash');\n const height = queryParams.get('height');\n\n if (!hash && !height) {\n throw new CardanoUriError('MissingRequiredField', 'Block URI must have either hash or height');\n }\n\n if (hash && height) {\n throw new CardanoUriError('InvalidCombination', 'Cannot provide both block hash and height');\n }\n\n if (hash && !isValidHex64(hash)) {\n throw new CardanoUriError('InvalidFormat', 'Invalid block hash format');\n }\n\n if (height && !isValidBlockHeight(height)) {\n throw new CardanoUriError('InvalidFormat', 'Invalid block height format');\n }\n\n return {\n type: 'block',\n block_hash: hash || undefined,\n block_height: height ? Number(height) : undefined\n };\n}\n","import { BrowseUri } from '../types';\nimport { CardanoUriError } from '../errors';\n\nexport function handleBrowseUri(rest: string[], queryParams: URLSearchParams): BrowseUri {\n if (rest.length < 2) {\n throw new CardanoUriError('MissingRequiredField', 'Expected at least scheme and namespaced domain');\n }\n\n const scheme = rest[0];\n const namespacedDomain = rest[1];\n\n if (!/^[a-zA-Z][a-zA-Z0-9+.-]*$/.test(scheme)) {\n throw new CardanoUriError('InvalidScheme', 'Invalid scheme format: ' + scheme);\n }\n\n if (!namespacedDomain.includes('.')) {\n throw new CardanoUriError('InvalidNamespace', 'Invalid namespaced domain format: ' + namespacedDomain);\n }\n\n const appPath = rest.slice(2).join('/');\n\n const qp: Record<string, string> = {};\n queryParams.forEach((value, key) => {\n qp[key] = value;\n });\n\n const reversedDomain = namespacedDomain.split('.').reverse().join('.');\n const queryString = queryParams.toString() ? `?${queryParams.toString()}` : '';\n const fullUrl = `${scheme}://${reversedDomain}/${appPath}${queryString}`;\n\n return {\n type: 'browse',\n scheme,\n namespaced_domain: namespacedDomain,\n app_path: appPath,\n queryParams: qp,\n url: fullUrl\n };\n}\n","import { ClaimUri } from '../types';\nimport { CardanoUriError } from '../errors';\n\nexport function handleClaimUri(rest: string[], queryParams: URLSearchParams): ClaimUri {\n const versionStr = rest[0].replace('v', '');\n const version = Number(versionStr);\n\n if (!versionStr || isNaN(version)) {\n throw new CardanoUriError('MissingRequiredField', 'Missing or invalid version in claim URI');\n }\n\n const faucetUrl = queryParams.get('faucet_url');\n if (!faucetUrl) {\n throw new CardanoUriError('MissingRequiredField', 'faucet_url is required in claim URI');\n }\n\n return {\n type: 'claim',\n version,\n faucet_url: faucetUrl,\n code: queryParams.get('code')\n };\n}\n","import {PayUri} from \"../types\";\nimport {CardanoUriError} from \"../errors\";\nimport {classifyCardanoAddress} from \"../utils/validators\";\n\nexport function handlePayUri(rest: string[], queryParams: URLSearchParams): PayUri {\n const address = rest[0];\n if (!address) {\n throw new CardanoUriError(\"MissingRequiredField\", \"Missing address in pay URI\");\n }\n\n const {valid} = classifyCardanoAddress(address);\n if (!valid) {\n throw new CardanoUriError(\"InvalidAddress\", \"Invalid Cardano address format\");\n }\n\n const result: PayUri = {\n type: \"pay\",\n address,\n };\n\n if (queryParams.has(\"l\")) {\n const lovelace = Number(queryParams.get(\"l\"));\n if (!Number.isInteger(lovelace) || lovelace < 0) {\n throw new CardanoUriError(\"InvalidLovelace\", \"Invalid lovelace amount\");\n }\n result.lovelace = lovelace;\n }\n\n if (queryParams.has(\"i\")) {\n result.paymentId = queryParams.get(\"i\")!;\n }\n\n if (queryParams.has(\"n\")) {\n result.note = decodeURIComponent(queryParams.get(\"n\")!);\n }\n\n if (queryParams.has(\"t\")) {\n const tokensStr = queryParams.get(\"t\")!;\n result.tokens = tokensStr.split(\",\").map((pair) => {\n const [assetId, qtyStr] = pair.split(\"|\");\n if (!assetId.startsWith(\"asset1\") || assetId.length !== 45) {\n throw new CardanoUriError(\"InvalidToken\", `Invalid asset ID: ${assetId}`);\n }\n const quantity = Number(qtyStr);\n if (!Number.isInteger(quantity) || quantity < 0) {\n throw new CardanoUriError(\"InvalidTokenQuantity\", `Invalid quantity for asset: ${assetId}`);\n }\n return {assetId, quantity};\n });\n }\n\n return result;\n}\n","import { StakeUri } from '../types';\nimport { CardanoUriError } from '../errors';\n\nexport function handleStakeUri(_rest: string[], queryParams: URLSearchParams): StakeUri {\n const pools: { [pool_id: string]: number } = {};\n queryParams.forEach((value, key) => {\n if (pools[key] !== undefined) {\n throw new CardanoUriError('HandlerError', `Duplicate pool key: ${key}`);\n }\n pools[key] = Number(value) || 1;\n });\n return {\n type: 'stake',\n pools\n };\n}\n","import { TransactionUri } from '../types';\nimport { CardanoUriError } from '../errors';\nimport { isValidHex64, isValidMetadataLabel } from '../utils/validators';\n\nexport function handleTransactionUri(\n pathParts: string[],\n fragment: string | null\n): TransactionUri {\n const [tx_hash, ...subpaths] = pathParts;\n\n if (!tx_hash) {\n throw new CardanoUriError('MissingRequiredField', 'Missing transaction hash');\n }\n\n if (tx_hash !== 'self' && !isValidHex64(tx_hash)) {\n throw new CardanoUriError('InvalidFormat', 'Invalid transaction hash format');\n }\n\n let metadata: TransactionUri['metadata'] = undefined;\n\n if (subpaths[0] === 'metadata') {\n if (subpaths[1] && !isValidMetadataLabel(subpaths[1])) {\n throw new CardanoUriError('InvalidFormat', 'Invalid metadata label format');\n }\n metadata = subpaths[1] ? { label: subpaths[1] } : {};\n }\n\n const result: TransactionUri = {\n type: 'transaction',\n tx_hash,\n metadata\n };\n\n if (fragment !== null) {\n const index = Number(fragment);\n if (!Number.isInteger(index) || index < 0) {\n throw new CardanoUriError('InvalidFormat', 'Invalid output index fragment');\n }\n result.output_index = index;\n }\n\n return result;\n}\n","import {DefaultUri} from \"../types\";\nimport {CardanoUriError} from \"../errors\";\nimport {classifyCardanoAddress} from \"../utils/validators\";\n\nexport function handleDefaultUri(address: string, queryParams: URLSearchParams): DefaultUri {\n const {valid, type, is_testnet} = classifyCardanoAddress(address);\n\n if (!valid || !type) {\n throw new CardanoUriError(\"InvalidAddress\", \"Provided address is not recognized as valid Cardano address\");\n }\n\n const amountStr = queryParams.get(\"amount\");\n const amount = amountStr ? Number(amountStr) : undefined;\n const era = type.startsWith(\"byron\") ? \"byron\" : \"shelley\";\n const network = is_testnet ? \"testnet\" : \"mainnet\";\n\n return {\n type: \"payment\",\n address,\n amount,\n era,\n network\n };\n}\n","import {handleAddrUri} from \"./handlers/addr\";\nimport {handleBlockUri} from \"./handlers/block\";\nimport {handleBrowseUri} from \"./handlers/browse\";\nimport {handleClaimUri} from \"./handlers/claim\";\nimport {handlePayUri} from \"./handlers/pay\";\nimport {handleStakeUri} from \"./handlers/stake\";\nimport {handleTransactionUri} from \"./handlers/transaction\";\nimport {handleDefaultUri} from \"./handlers/default\";\nimport {CardanoUri} from \"./types\";\nimport {CardanoUriError} from \"./errors\";\n\nexport function parse(uri: string): CardanoUri {\n let url: URL;\n\n try {\n url = new URL(uri);\n } catch {\n throw new CardanoUriError(\"InvalidUri\", \"Invalid URI format\");\n }\n\n if (url.protocol !== \"web+cardano:\") {\n throw new CardanoUriError(\"InvalidScheme\", \"Unsupported scheme: \" + url.protocol);\n }\n\n const authority = url.hostname;\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n const queryParams = url.searchParams;\n\n try {\n switch (authority) {\n case \"addr\":\n return handleAddrUri(pathParts);\n case \"block\":\n return handleBlockUri(pathParts, queryParams);\n case \"browse\":\n return handleBrowseUri(pathParts, queryParams);\n case \"claim\":\n return handleClaimUri(pathParts, queryParams);\n case \"pay\":\n return handlePayUri(pathParts, queryParams);\n case \"stake\":\n return handleStakeUri(pathParts, queryParams);\n case \"transaction\":\n return handleTransactionUri(pathParts, url.hash ? url.hash.slice(1) : null);\n default:\n return handleDefaultUri(authority, queryParams);\n }\n } catch (err) {\n if (err instanceof CardanoUriError) {\n throw err;\n }\n throw new CardanoUriError(\"HandlerError\", \"Error in handler\", {originalError: err});\n }\n}\n\nexport function safeParse(uri: string): CardanoUri | null {\n try {\n return parse(uri);\n } catch {\n return null;\n }\n}\n"],"mappings":";AAAO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAIvC,YAAY,MAAc,SAAiB,SAAe;AACtD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACnB;AACJ;;;ACVO,SAAS,aAAa,OAAwB;AACjD,SAAO,oBAAoB,KAAK,KAAK;AACzC;AAEO,SAAS,mBAAmB,OAAwB;AACvD,SAAO,WAAW,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;AACtD;AAEO,SAAS,qBAAqB,OAAwB;AACzD,SAAO,WAAW,KAAK,KAAK;AAChC;AAEO,SAAS,uBAAuB,OAAwE;AAC3G,QAAM,aAAa,MAAM,SAAS,OAAO;AAEzC,MAAI,MAAM,WAAW,QAAQ,KAAK,MAAM,WAAW,aAAa,GAAG;AAC/D,WAAO,EAAC,OAAO,MAAM,WAAW,MAAM,MAAM,WAAW,IAAI,MAAM,SAAS,WAAU;AAAA,EACxF;AAEA,MAAI,MAAM,WAAW,OAAO,GAAG;AAC3B,WAAO,EAAC,OAAO,MAAM,WAAW,OAAO,MAAM,WAAW,IAAI,MAAM,WAAW,WAAU;AAAA,EAC3F;AAEA,MAAI,MAAM,WAAW,YAAY,GAAG;AAChC,WAAO,EAAC,OAAO,MAAM,WAAW,OAAO,MAAM,WAAW,IAAI,MAAM,WAAW,WAAU;AAAA,EAC3F;AAEA,MAAI,MAAM,WAAW,KAAK,GAAG;AACzB,WAAO,EAAC,OAAO,MAAM,UAAU,MAAM,MAAM,UAAU,IAAI,MAAM,gBAAgB,WAAU;AAAA,EAC7F;AAEA,MAAI,MAAM,WAAW,OAAO,GAAG;AAC3B,WAAO,EAAC,OAAO,MAAM,UAAU,OAAO,MAAM,UAAU,KAAK,MAAM,kBAAkB,WAAU;AAAA,EACjG;AAEA,QAAM,iBAAiB;AAAA,IACnB;AAAA,IAAW;AAAA,IAAe;AAAA,IAC1B;AAAA,IAAc;AAAA,IAAkB;AAAA,IAChC;AAAA,IAAa;AAAA,IAAiB;AAAA,EAClC;AAEA,aAAW,UAAU,gBAAgB;AACjC,QAAI,MAAM,WAAW,MAAM,GAAG;AAC1B,aAAO,EAAC,OAAO,MAAM,MAAM,QAAQ,WAAU;AAAA,IACjD;AAAA,EACJ;AAEA,SAAO,EAAC,OAAO,MAAK;AACxB;;;AC5CO,SAAS,cAAc,MAA4B;AACtD,QAAM,UAAU,KAAK,CAAC;AACtB,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,gBAAgB,wBAAwB,iBAAiB;AAAA,EACvE;AAEA,QAAM,EAAE,OAAO,MAAM,WAAW,IAAI,uBAAuB,OAAO;AAElE,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,gBAAgB,kBAAkB,gCAAgC;AAAA,EAChF;AAEA,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACJ;AACJ;;;AClBO,SAAS,eACZ,MACA,aACQ;AACR,QAAM,OAAO,YAAY,IAAI,MAAM;AACnC,QAAM,SAAS,YAAY,IAAI,QAAQ;AAEvC,MAAI,CAAC,QAAQ,CAAC,QAAQ;AAClB,UAAM,IAAI,gBAAgB,wBAAwB,2CAA2C;AAAA,EACjG;AAEA,MAAI,QAAQ,QAAQ;AAChB,UAAM,IAAI,gBAAgB,sBAAsB,2CAA2C;AAAA,EAC/F;AAEA,MAAI,QAAQ,CAAC,aAAa,IAAI,GAAG;AAC7B,UAAM,IAAI,gBAAgB,iBAAiB,2BAA2B;AAAA,EAC1E;AAEA,MAAI,UAAU,CAAC,mBAAmB,MAAM,GAAG;AACvC,UAAM,IAAI,gBAAgB,iBAAiB,6BAA6B;AAAA,EAC5E;AAEA,SAAO;AAAA,IACH,MAAM;AAAA,IACN,YAAY,QAAQ;AAAA,IACpB,cAAc,SAAS,OAAO,MAAM,IAAI;AAAA,EAC5C;AACJ;;;AC7BO,SAAS,gBAAgB,MAAgB,aAAyC;AACrF,MAAI,KAAK,SAAS,GAAG;AACjB,UAAM,IAAI,gBAAgB,wBAAwB,gDAAgD;AAAA,EACtG;AAEA,QAAM,SAAS,KAAK,CAAC;AACrB,QAAM,mBAAmB,KAAK,CAAC;AAE/B,MAAI,CAAC,4BAA4B,KAAK,MAAM,GAAG;AAC3C,UAAM,IAAI,gBAAgB,iBAAiB,4BAA4B,MAAM;AAAA,EACjF;AAEA,MAAI,CAAC,iBAAiB,SAAS,GAAG,GAAG;AACjC,UAAM,IAAI,gBAAgB,oBAAoB,uCAAuC,gBAAgB;AAAA,EACzG;AAEA,QAAM,UAAU,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAEtC,QAAM,KAA6B,CAAC;AACpC,cAAY,QAAQ,CAAC,OAAO,QAAQ;AAChC,OAAG,GAAG,IAAI;AAAA,EACd,CAAC;AAED,QAAM,iBAAiB,iBAAiB,MAAM,GAAG,EAAE,QAAQ,EAAE,KAAK,GAAG;AACrE,QAAM,cAAc,YAAY,SAAS,IAAI,IAAI,YAAY,SAAS,CAAC,KAAK;AAC5E,QAAM,UAAU,GAAG,MAAM,MAAM,cAAc,IAAI,OAAO,GAAG,WAAW;AAEtE,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA,mBAAmB;AAAA,IACnB,UAAU;AAAA,IACV,aAAa;AAAA,IACb,KAAK;AAAA,EACT;AACJ;;;ACnCO,SAAS,eAAe,MAAgB,aAAwC;AACnF,QAAM,aAAa,KAAK,CAAC,EAAE,QAAQ,KAAK,EAAE;AAC1C,QAAM,UAAU,OAAO,UAAU;AAEjC,MAAI,CAAC,cAAc,MAAM,OAAO,GAAG;AAC/B,UAAM,IAAI,gBAAgB,wBAAwB,yCAAyC;AAAA,EAC/F;AAEA,QAAM,YAAY,YAAY,IAAI,YAAY;AAC9C,MAAI,CAAC,WAAW;AACZ,UAAM,IAAI,gBAAgB,wBAAwB,qCAAqC;AAAA,EAC3F;AAEA,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA,YAAY;AAAA,IACZ,MAAM,YAAY,IAAI,MAAM;AAAA,EAChC;AACJ;;;AClBO,SAAS,aAAa,MAAgB,aAAsC;AAC/E,QAAM,UAAU,KAAK,CAAC;AACtB,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,gBAAgB,wBAAwB,4BAA4B;AAAA,EAClF;AAEA,QAAM,EAAC,MAAK,IAAI,uBAAuB,OAAO;AAC9C,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,gBAAgB,kBAAkB,gCAAgC;AAAA,EAChF;AAEA,QAAM,SAAiB;AAAA,IACnB,MAAM;AAAA,IACN;AAAA,EACJ;AAEA,MAAI,YAAY,IAAI,GAAG,GAAG;AACtB,UAAM,WAAW,OAAO,YAAY,IAAI,GAAG,CAAC;AAC5C,QAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,GAAG;AAC7C,YAAM,IAAI,gBAAgB,mBAAmB,yBAAyB;AAAA,IAC1E;AACA,WAAO,WAAW;AAAA,EACtB;AAEA,MAAI,YAAY,IAAI,GAAG,GAAG;AACtB,WAAO,YAAY,YAAY,IAAI,GAAG;AAAA,EAC1C;AAEA,MAAI,YAAY,IAAI,GAAG,GAAG;AACtB,WAAO,OAAO,mBAAmB,YAAY,IAAI,GAAG,CAAE;AAAA,EAC1D;AAEA,MAAI,YAAY,IAAI,GAAG,GAAG;AACtB,UAAM,YAAY,YAAY,IAAI,GAAG;AACrC,WAAO,SAAS,UAAU,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS;AAC/C,YAAM,CAAC,SAAS,MAAM,IAAI,KAAK,MAAM,GAAG;AACxC,UAAI,CAAC,QAAQ,WAAW,QAAQ,KAAK,QAAQ,WAAW,IAAI;AACxD,cAAM,IAAI,gBAAgB,gBAAgB,qBAAqB,OAAO,EAAE;AAAA,MAC5E;AACA,YAAM,WAAW,OAAO,MAAM;AAC9B,UAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,GAAG;AAC7C,cAAM,IAAI,gBAAgB,wBAAwB,+BAA+B,OAAO,EAAE;AAAA,MAC9F;AACA,aAAO,EAAC,SAAS,SAAQ;AAAA,IAC7B,CAAC;AAAA,EACL;AAEA,SAAO;AACX;;;ACjDO,SAAS,eAAe,OAAiB,aAAwC;AACpF,QAAM,QAAuC,CAAC;AAC9C,cAAY,QAAQ,CAAC,OAAO,QAAQ;AAChC,QAAI,MAAM,GAAG,MAAM,QAAW;AAC1B,YAAM,IAAI,gBAAgB,gBAAgB,uBAAuB,GAAG,EAAE;AAAA,IAC1E;AACA,UAAM,GAAG,IAAI,OAAO,KAAK,KAAK;AAAA,EAClC,CAAC;AACD,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,EACJ;AACJ;;;ACXO,SAAS,qBACZ,WACA,UACc;AACd,QAAM,CAAC,SAAS,GAAG,QAAQ,IAAI;AAE/B,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,gBAAgB,wBAAwB,0BAA0B;AAAA,EAChF;AAEA,MAAI,YAAY,UAAU,CAAC,aAAa,OAAO,GAAG;AAC9C,UAAM,IAAI,gBAAgB,iBAAiB,iCAAiC;AAAA,EAChF;AAEA,MAAI,WAAuC;AAE3C,MAAI,SAAS,CAAC,MAAM,YAAY;AAC5B,QAAI,SAAS,CAAC,KAAK,CAAC,qBAAqB,SAAS,CAAC,CAAC,GAAG;AACnD,YAAM,IAAI,gBAAgB,iBAAiB,+BAA+B;AAAA,IAC9E;AACA,eAAW,SAAS,CAAC,IAAI,EAAE,OAAO,SAAS,CAAC,EAAE,IAAI,CAAC;AAAA,EACvD;AAEA,QAAM,SAAyB;AAAA,IAC3B,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACJ;AAEA,MAAI,aAAa,MAAM;AACnB,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AACvC,YAAM,IAAI,gBAAgB,iBAAiB,+BAA+B;AAAA,IAC9E;AACA,WAAO,eAAe;AAAA,EAC1B;AAEA,SAAO;AACX;;;ACtCO,SAAS,iBAAiB,SAAiB,aAA0C;AACxF,QAAM,EAAC,OAAO,MAAM,WAAU,IAAI,uBAAuB,OAAO;AAEhE,MAAI,CAAC,SAAS,CAAC,MAAM;AACjB,UAAM,IAAI,gBAAgB,kBAAkB,6DAA6D;AAAA,EAC7G;AAEA,QAAM,YAAY,YAAY,IAAI,QAAQ;AAC1C,QAAM,SAAS,YAAY,OAAO,SAAS,IAAI;AAC/C,QAAM,MAAM,KAAK,WAAW,OAAO,IAAI,UAAU;AACjD,QAAM,UAAU,aAAa,YAAY;AAEzC,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;ACZO,SAAS,MAAM,KAAyB;AAC3C,MAAI;AAEJ,MAAI;AACA,UAAM,IAAI,IAAI,GAAG;AAAA,EACrB,QAAQ;AACJ,UAAM,IAAI,gBAAgB,cAAc,oBAAoB;AAAA,EAChE;AAEA,MAAI,IAAI,aAAa,gBAAgB;AACjC,UAAM,IAAI,gBAAgB,iBAAiB,yBAAyB,IAAI,QAAQ;AAAA,EACpF;AAEA,QAAM,YAAY,IAAI;AACtB,QAAM,YAAY,IAAI,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACxD,QAAM,cAAc,IAAI;AAExB,MAAI;AACA,YAAQ,WAAW;AAAA,MACf,KAAK;AACD,eAAO,cAAc,SAAS;AAAA,MAClC,KAAK;AACD,eAAO,eAAe,WAAW,WAAW;AAAA,MAChD,KAAK;AACD,eAAO,gBAAgB,WAAW,WAAW;AAAA,MACjD,KAAK;AACD,eAAO,eAAe,WAAW,WAAW;AAAA,MAChD,KAAK;AACD,eAAO,aAAa,WAAW,WAAW;AAAA,MAC9C,KAAK;AACD,eAAO,eAAe,WAAW,WAAW;AAAA,MAChD,KAAK;AACD,eAAO,qBAAqB,WAAW,IAAI,OAAO,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI;AAAA,MAC9E;AACI,eAAO,iBAAiB,WAAW,WAAW;AAAA,IACtD;AAAA,EACJ,SAAS,KAAK;AACV,QAAI,eAAe,iBAAiB;AAChC,YAAM;AAAA,IACV;AACA,UAAM,IAAI,gBAAgB,gBAAgB,oBAAoB,EAAC,eAAe,IAAG,CAAC;AAAA,EACtF;AACJ;AAEO,SAAS,UAAU,KAAgC;AACtD,MAAI;AACA,WAAO,MAAM,GAAG;AAAA,EACpB,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;","names":[]}