facturas 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/decimal.ts","../src/services/wsfe.ts","../src/services/wsfe-amounts.ts","../src/services/wsfe-builders.ts"],"sourcesContent":["import { ArcaInputError } from \"../errors\";\n\nconst AMOUNT_SCALE = 100;\nconst EXCHANGE_RATE_SCALE = 1_000_000;\nconst EXCHANGE_RATE_SCALE_BIGINT = 1_000_000n;\nconst PERCENTAGE_SCALE = 100;\n\n// WSFE documents amount fields as 13 integer digits plus 2 decimals.\nconst MAX_ARCA_AMOUNT_MINOR_UNITS = 999_999_999_999_999n;\n// MonCotiz is documented as 4 integer digits plus 6 decimals.\nconst MAX_ARCA_EXCHANGE_RATE_SCALED = 9_999_999_999n;\n// Tributo.Alic is documented as 3 integer digits plus 2 decimals.\nconst MAX_ARCA_PERCENTAGE_HUNDREDTHS = 99_999n;\n\nexport const SUPPORTED_VAT_RATES = [0, 2.5, 5, 10.5, 21, 27] as const;\nexport type SupportedVatRate = (typeof SUPPORTED_VAT_RATES)[number];\n\nconst VAT_RATE_BASIS_POINTS: Record<SupportedVatRate, bigint> = {\n 0: 0n,\n 2.5: 250n,\n 5: 500n,\n 10.5: 1050n,\n 21: 2100n,\n 27: 2700n,\n};\n\nexport function normalizeArcaAmountToMinorUnits(\n value: number,\n field: string\n): bigint {\n return normalizeScaledNumber({\n value,\n field,\n scale: AMOUNT_SCALE,\n maximum: MAX_ARCA_AMOUNT_MINOR_UNITS,\n expected: \"a finite non-negative amount with at most 2 decimal places\",\n });\n}\n\nexport function serializeArcaAmount(value: number, field: string): string {\n return formatScaledInteger(normalizeArcaAmountToMinorUnits(value, field), 2);\n}\n\nexport function serializeArcaMinorUnits(value: number, field: string): string {\n return formatScaledInteger(assertArcaMinorUnits(value, field), 2);\n}\n\nexport function serializeArcaPercentage(value: number, field: string): string {\n const scaled = normalizeScaledNumber({\n value,\n field,\n scale: PERCENTAGE_SCALE,\n maximum: MAX_ARCA_PERCENTAGE_HUNDREDTHS,\n expected: \"a finite non-negative percentage with at most 2 decimal places\",\n });\n return formatScaledInteger(scaled, 2);\n}\n\nexport function serializeArcaExchangeRate(\n value: number | string,\n field: string\n): string {\n const scaled =\n typeof value === \"number\"\n ? normalizeExchangeRateNumber(value, field)\n : normalizeExchangeRateString(value, field);\n\n if (scaled <= 0n || scaled > MAX_ARCA_EXCHANGE_RATE_SCALED) {\n throwInvalidExchangeRate(field);\n }\n\n return formatScaledInteger(scaled, 6, true);\n}\n\nexport function assertArcaMinorUnits(value: number, field: string): bigint {\n if (!(Number.isSafeInteger(value) && value >= 0)) {\n throw new ArcaInputError(\n `${field} must be a non-negative safe integer in currency minor units.`,\n {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected: \"a non-negative safe integer in currency minor units\",\n }\n );\n }\n\n const minorUnits = BigInt(value);\n if (minorUnits > MAX_ARCA_AMOUNT_MINOR_UNITS) {\n throw new ArcaInputError(`${field} exceeds the WSFE amount limit.`, {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected: \"at most 13 integer digits and 2 decimal places\",\n });\n }\n\n return minorUnits;\n}\n\nexport function arcaMinorUnitsToNumber(\n minorUnits: bigint,\n field: string\n): number {\n if (minorUnits < 0n || minorUnits > MAX_ARCA_AMOUNT_MINOR_UNITS) {\n throw new ArcaInputError(`${field} exceeds the WSFE amount limit.`, {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected: \"at most 13 integer digits and 2 decimal places\",\n });\n }\n\n return Number(formatScaledInteger(minorUnits, 2));\n}\n\nexport function calculateVatMinorUnits(\n taxableMinorUnits: bigint,\n vatRate: SupportedVatRate,\n field: string\n): bigint {\n const basisPoints = VAT_RATE_BASIS_POINTS[vatRate];\n if (basisPoints === undefined) {\n throw new ArcaInputError(`${field} is not a supported VAT rate.`, {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field,\n expected: \"one of 0, 2.5, 5, 10.5, 21, or 27\",\n });\n }\n\n return roundHalfEvenRatio(taxableMinorUnits * basisPoints, 10_000n);\n}\n\n/**\n * Divides two non-negative integers and rounds the quotient to the nearest\n * integer, breaking exact ties toward the even neighbour.\n *\n * This is the rounding criterion the WSFE developer manual documents for the\n * service (\"Round Half Even\", section on validation tolerances), so VAT\n * derived here matches what ARCA computes for the same base and rate.\n */\nexport function roundHalfEvenRatio(\n numerator: bigint,\n denominator: bigint\n): bigint {\n if (numerator < 0n || denominator <= 0n) {\n throw new RangeError(\n \"roundHalfEvenRatio requires a non-negative numerator and a positive denominator.\"\n );\n }\n\n const quotient = numerator / denominator;\n const doubledRemainder = (numerator % denominator) * 2n;\n if (doubledRemainder > denominator) {\n return quotient + 1n;\n }\n if (doubledRemainder < denominator) {\n return quotient;\n }\n return quotient % 2n === 0n ? quotient : quotient + 1n;\n}\n\nexport function isWithinArcaTolerance(\n actualMinorUnits: bigint,\n expectedMinorUnits: bigint,\n absoluteCentAllowance = 1\n): boolean {\n const difference = absoluteBigInt(actualMinorUnits - expectedMinorUnits);\n if (difference <= BigInt(Math.max(1, absoluteCentAllowance))) {\n return true;\n }\n\n const comparisonBase = absoluteBigInt(expectedMinorUnits);\n return comparisonBase > 0n && difference * 10_000n <= comparisonBase;\n}\n\nfunction normalizeScaledNumber({\n value,\n field,\n scale,\n maximum,\n expected,\n}: {\n value: number;\n field: string;\n scale: number;\n maximum: bigint;\n expected: string;\n}): bigint {\n if (!(Number.isFinite(value) && value >= 0)) {\n throw new ArcaInputError(`${field} must be ${expected}.`, {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected,\n });\n }\n\n const scaled = value * scale;\n const nearestInteger = Math.round(scaled);\n const representationTolerance = Math.max(\n 1e-9,\n Math.abs(scaled) * Number.EPSILON * 4\n );\n\n if (Math.abs(scaled - nearestInteger) > representationTolerance) {\n throw new ArcaInputError(\n `${field} has more precision than its ARCA field allows.`,\n {\n code: \"ARCA_INPUT_AMOUNT_PRECISION\",\n field,\n expected,\n }\n );\n }\n\n if (!Number.isSafeInteger(nearestInteger)) {\n throw new ArcaInputError(`${field} exceeds the safely supported range.`, {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected,\n });\n }\n\n const normalized = BigInt(nearestInteger);\n if (normalized > maximum) {\n throw new ArcaInputError(`${field} exceeds the ARCA field limit.`, {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field,\n expected,\n });\n }\n\n return normalized;\n}\n\nfunction normalizeExchangeRateNumber(value: number, field: string): bigint {\n if (!(Number.isFinite(value) && value > 0)) {\n throwInvalidExchangeRate(field);\n }\n\n const scaled = value * EXCHANGE_RATE_SCALE;\n const nearestInteger = Math.round(scaled);\n const representationTolerance = Math.max(\n 1e-9,\n Math.abs(scaled) * Number.EPSILON * 4\n );\n\n if (\n Math.abs(scaled - nearestInteger) > representationTolerance ||\n !Number.isSafeInteger(nearestInteger)\n ) {\n throwInvalidExchangeRate(field);\n }\n\n return BigInt(nearestInteger);\n}\n\nfunction normalizeExchangeRateString(value: string, field: string): bigint {\n const match = value.match(/^(0|[1-9]\\d{0,3})(?:\\.(\\d{1,6}))?$/);\n if (!match) {\n throwInvalidExchangeRate(field);\n }\n\n const [, integerPart, fractionPart = \"\"] = match;\n return (\n BigInt(integerPart) * EXCHANGE_RATE_SCALE_BIGINT +\n BigInt(fractionPart.padEnd(6, \"0\"))\n );\n}\n\nfunction throwInvalidExchangeRate(field: string): never {\n throw new ArcaInputError(\n `${field} must be a positive decimal with at most 4 integer and 6 fractional digits.`,\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field,\n expected:\n \"a positive decimal with up to 4 integer and 6 fractional digits\",\n }\n );\n}\n\nfunction formatScaledInteger(\n value: bigint,\n fractionDigits: number,\n trimTrailingZeros = false\n): string {\n const scale = 10n ** BigInt(fractionDigits);\n const integerPart = value / scale;\n const fractionPart = (value % scale).toString().padStart(fractionDigits, \"0\");\n\n if (trimTrailingZeros) {\n const trimmedFraction = fractionPart.replace(/0+$/, \"\");\n return trimmedFraction.length === 0\n ? integerPart.toString()\n : `${integerPart}.${trimmedFraction}`;\n }\n\n return `${integerPart}.${fractionPart}`;\n}\n\nfunction absoluteBigInt(value: bigint): bigint {\n return value < 0n ? -value : value;\n}\n","import {\n ArcaInputError,\n ArcaInvalidSoapResponseError,\n ArcaServiceError,\n ArcaSoapFaultError,\n ArcaTransportError,\n} from \"../errors\";\nimport {\n classifyArcaAuthenticationError,\n classifyArcaAuthenticationIssues,\n createArcaAuthenticationEvidence,\n executeWithAuthenticationRecovery,\n} from \"../internal/authentication\";\nimport {\n isWithinArcaTolerance,\n normalizeArcaAmountToMinorUnits,\n serializeArcaAmount,\n serializeArcaExchangeRate,\n serializeArcaPercentage,\n} from \"../internal/decimal\";\nimport type { ArcaClientConfig, ArcaRepresentedTaxId } from \"../internal/types\";\nimport type { SoapTransport } from \"../soap\";\nimport type { WsaaAuthModule } from \"../wsaa\";\nimport type {\n ArcaAuthorizationIndeterminateReason,\n ArcaAuthorizationOutcome,\n ArcaFiscalIssue,\n ArcaFiscalResultLevel,\n ArcaVoucherLookupResult,\n} from \"./fiscal-evidence\";\n\n/** Accepted public date inputs for WSFE request fields. */\nexport type WsfeDateInput =\n | `${number}${number}${number}${number}-${number}${number}-${number}${number}`\n | `${number}${number}${number}${number}${number}${number}${number}${number}`;\n\n/** An associated voucher referenced by a WSFE invoice request. */\nexport type WsfeAssociatedVoucher = {\n type: number;\n salesPoint: number;\n number: number;\n taxId?: string;\n voucherDate?: WsfeDateInput;\n};\n\n/** An associated period used by WSFE credit/debit notes without associated vouchers. */\nexport type WsfeAssociatedPeriod = {\n startDate: WsfeDateInput;\n endDate: WsfeDateInput;\n};\n\n/** A tax (tributo) item in a WSFE invoice request. */\nexport type WsfeTax = {\n id: number;\n description?: string;\n baseAmount: number;\n rate: number;\n amount: number;\n};\n\n/** A VAT rate (alícuota IVA) item in a WSFE invoice request. */\nexport type WsfeVatRate = {\n id: number;\n baseAmount: number;\n amount: number;\n};\n\n/** An optional field (campo opcional) in a WSFE invoice request. */\nexport type WsfeOptionalField = {\n id: string;\n value: string;\n};\n\n/** A buyer (comprador) in a WSFE invoice request. */\nexport type WsfeBuyer = {\n documentType: number;\n documentNumber: number;\n percentage: number;\n};\n\n/** An activity associated with a WSFE invoice request. */\nexport type WsfeActivity = {\n id: number;\n};\n\n/** Input data for authorizing a WSFE voucher. */\nexport type WsfeVoucherInput = {\n salesPoint: number;\n voucherType: number;\n concept: number;\n documentType: number;\n documentNumber: number;\n receiverVatConditionId: number;\n voucherDate: WsfeDateInput;\n totalAmount: number;\n nonTaxableAmount: number;\n netAmount: number;\n exemptAmount: number;\n taxAmount: number;\n vatAmount: number;\n currencyId: string;\n exchangeRate?: number | string;\n sameCurrencyForeignCancellation?: \"S\" | \"N\";\n serviceStartDate?: WsfeDateInput;\n serviceEndDate?: WsfeDateInput;\n paymentDueDate?: WsfeDateInput;\n associatedVouchers?: WsfeAssociatedVoucher[];\n associatedPeriod?: WsfeAssociatedPeriod;\n taxes?: WsfeTax[];\n vatRates?: WsfeVatRate[];\n optionalFields?: WsfeOptionalField[];\n buyers?: WsfeBuyer[];\n activities?: WsfeActivity[];\n};\n\n/** Input for authorizing a WSFE voucher with an explicit voucher number. */\nexport type WsfeAuthorizeVoucherInput = {\n representedTaxId?: number | string;\n data: WsfeVoucherInput;\n voucherNumber: number;\n forceRefresh?: boolean;\n};\n\n/** Structured evidence from one exact WSFE authorization attempt. */\nexport type WsfeAuthorizationOutcome = ArcaAuthorizationOutcome<\"wsfe\">;\n\n/** A point-of-sale entry returned by {@link WsfeService.getSalesPoints}. */\nexport type WsfeSalesPoint = {\n number: number;\n emissionType?: string;\n blocked?: string;\n deletedSince?: string;\n};\n\n/** Voucher details returned by {@link WsfeService.getVoucherInfo}. */\nexport type WsfeVoucherInfo = {\n voucherNumber: number;\n voucherDate?: string;\n salesPoint?: number;\n voucherType?: number;\n concept?: number;\n documentType?: number;\n documentNumber?: string;\n receiverVatConditionId?: number;\n totalAmount?: number;\n nonTaxableAmount?: number;\n netAmount?: number;\n exemptAmount?: number;\n taxAmount?: number;\n vatAmount?: number;\n currencyId?: string;\n exchangeRate?: number;\n result?: string;\n cae?: string;\n caeExpiry?: string;\n vatRates?: WsfeVatRate[];\n serviceStartDate?: string;\n serviceEndDate?: string;\n paymentDueDate?: string;\n taxes?: WsfeTax[];\n associatedVouchers?: WsfeAssociatedVoucher[];\n raw: Record<string, unknown>;\n};\n\n/** Typed exact-voucher consultation result for WSFE. */\nexport type WsfeVoucherLookupResult = ArcaVoucherLookupResult<\n WsfeVoucherInfo,\n \"wsfe\"\n>;\n\nexport type WsfeCatalogEntry = {\n id: number;\n description: string;\n};\n\nexport type WsfeActivityType = WsfeCatalogEntry & {\n order: number;\n};\n\nexport type WsfeReceiverVatCondition = WsfeCatalogEntry & {\n voucherClass: string;\n};\n\nexport type WsfeCurrencyType = {\n id: string;\n description: string;\n validFrom: string;\n validTo: string;\n};\n\nexport type WsfeServerStatus = {\n appServer: string;\n dbServer: string;\n authServer: string;\n};\n\nexport type WsfeQuotation = {\n currencyId: string;\n rate: number;\n date: string;\n};\n\n/** WSFE electronic invoicing service. */\nexport type WsfeService = {\n /**\n * Issues one exact voucher: a single FECAESolicitar for the caller-owned\n * `voucherNumber`, without transport retries, returning structured evidence\n * (`authorized`, `rejected` or `indeterminate`) instead of throwing.\n */\n issue(input: WsfeAuthorizeVoucherInput): Promise<WsfeAuthorizationOutcome>;\n /** Returns the next available voucher number for the given sales point and type. */\n getNextVoucherNumber(input: {\n representedTaxId?: number | string;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<number>;\n /**\n * @deprecated Use `getNextVoucherNumber()` instead.\n * Returns the next available voucher number, not the last authorized one.\n */\n getLastVoucher(input: {\n representedTaxId?: number | string;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<number>;\n /** Lists all configured points of sale for the taxpayer. */\n getSalesPoints(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeSalesPoint[]>;\n /** Lists voucher types accepted by WSFE. */\n getVoucherTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists document types accepted by WSFE. */\n getDocumentTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists concept types accepted by WSFE. */\n getConceptTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists live ARCA currency identifiers such as PES and DOL, not ISO codes. */\n getCurrencyTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCurrencyType[]>;\n /** Lists VAT rates accepted by WSFE. */\n getVatRates(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists tax types accepted by WSFE. */\n getTaxTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists optional field types accepted by WSFE. */\n getOptionalTypes(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeCatalogEntry[]>;\n /** Lists activities enabled for the taxpayer. */\n getActivities(input: {\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeActivityType[]>;\n /** Lists receiver VAT condition values accepted by WSFE. */\n getReceiverVatConditions(input: {\n representedTaxId?: number | string;\n voucherClass?: string;\n forceRefresh?: boolean;\n }): Promise<WsfeReceiverVatCondition[]>;\n /** Reports WSFE backend status without requiring taxpayer authorization. */\n getServerStatus(): Promise<WsfeServerStatus>;\n /** Returns the exchange rate for a given currency. */\n getQuotation(input: {\n currencyId: string;\n representedTaxId?: number | string;\n forceRefresh?: boolean;\n }): Promise<WsfeQuotation>;\n /** Retrieves details for a specific voucher. Returns `null` if not found. */\n getVoucherInfo(input: {\n representedTaxId?: number | string;\n number: number;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<WsfeVoucherInfo | null>;\n /** Consults one exact voucher and normalizes WSFE error 602 to `not_found`. */\n lookupVoucher(input: {\n representedTaxId?: number | string;\n number: number;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<WsfeVoucherLookupResult>;\n};\n\nexport type CreateWsfeServiceOptions = {\n config: ArcaClientConfig;\n auth: WsaaAuthModule;\n soap: SoapTransport;\n};\n\ntype NormalizedWsfeAssociatedVoucher = Omit<\n WsfeAssociatedVoucher,\n \"voucherDate\"\n> & {\n voucherDate?: string;\n};\n\ntype NormalizedWsfeAssociatedPeriod = {\n startDate: string;\n endDate: string;\n};\n\ntype NormalizedWsfeTax = Omit<WsfeTax, \"baseAmount\" | \"rate\" | \"amount\"> & {\n baseAmount: string;\n rate: string;\n amount: string;\n};\n\ntype NormalizedWsfeVatRate = Omit<WsfeVatRate, \"baseAmount\" | \"amount\"> & {\n baseAmount: string;\n amount: string;\n};\n\ntype NormalizedWsfeVoucherInput = Omit<\n WsfeVoucherInput,\n | \"voucherDate\"\n | \"serviceStartDate\"\n | \"serviceEndDate\"\n | \"paymentDueDate\"\n | \"associatedVouchers\"\n | \"associatedPeriod\"\n | \"totalAmount\"\n | \"nonTaxableAmount\"\n | \"netAmount\"\n | \"exemptAmount\"\n | \"taxAmount\"\n | \"vatAmount\"\n | \"exchangeRate\"\n | \"taxes\"\n | \"vatRates\"\n> & {\n voucherDate: string;\n totalAmount: string;\n nonTaxableAmount: string;\n netAmount: string;\n exemptAmount: string;\n taxAmount: string;\n vatAmount: string;\n exchangeRate?: string;\n serviceStartDate?: string;\n serviceEndDate?: string;\n paymentDueDate?: string;\n associatedVouchers?: NormalizedWsfeAssociatedVoucher[];\n associatedPeriod?: NormalizedWsfeAssociatedPeriod;\n taxes?: NormalizedWsfeTax[];\n vatRates?: NormalizedWsfeVatRate[];\n};\n\n/** Creates a WSFE service instance wired with authentication and SOAP transport. */\nexport function createWsfeService(\n options: CreateWsfeServiceOptions\n): WsfeService {\n async function executeWsfeAuthenticatedRawOperation(\n operation: string,\n input: {\n representedTaxId?: ArcaRepresentedTaxId;\n forceRefresh?: boolean;\n },\n body: Record<string, unknown> = {},\n retries?: number\n ) {\n const auth = await options.auth.login(\"wsfe\", {\n representedTaxId: input.representedTaxId,\n forceRefresh: input.forceRefresh,\n });\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation,\n ...(retries === undefined ? {} : { retries }),\n body: {\n Auth: createWsfeAuth(\n input.representedTaxId ?? options.config.taxId,\n auth.token,\n auth.sign\n ),\n ...body,\n },\n });\n\n return unwrapWsfeOperationEnvelope(operation, response.result);\n }\n\n function executeWsfeAuthenticatedOperation(\n operation: string,\n input: {\n representedTaxId?: ArcaRepresentedTaxId;\n forceRefresh?: boolean;\n },\n body: Record<string, unknown> = {}\n ) {\n return executeWithAuthenticationRecovery({\n service: \"wsfe\",\n operation,\n forceRefresh: input.forceRefresh,\n async execute(forceRefresh) {\n const result = await executeWsfeAuthenticatedRawOperation(\n operation,\n { representedTaxId: input.representedTaxId, forceRefresh },\n body\n );\n throwForWsfeOperationErrors(operation, result);\n return result;\n },\n });\n }\n\n async function executeWsfeOperation(\n operation: string,\n body: Record<string, unknown> = {}\n ) {\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation,\n body,\n });\n\n const result = unwrapWsfeOperationEnvelope(operation, response.result);\n throwForWsfeOperationErrors(operation, result);\n return result;\n }\n\n async function getNextVoucherNumber({\n representedTaxId,\n salesPoint,\n voucherType,\n forceRefresh,\n }: {\n representedTaxId?: number | string;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FECompUltimoAutorizado\",\n {\n representedTaxId,\n forceRefresh,\n },\n {\n PtoVta: salesPoint,\n CbteTipo: voucherType,\n }\n );\n return Number(result.CbteNro ?? 0) + 1;\n }\n\n async function getWsfeCatalog(\n operation: string,\n resultKey: string,\n input: {\n representedTaxId?: ArcaRepresentedTaxId;\n forceRefresh?: boolean;\n }\n ): Promise<WsfeCatalogEntry[]> {\n const result = await executeWsfeAuthenticatedOperation(operation, {\n representedTaxId: input.representedTaxId,\n forceRefresh: input.forceRefresh,\n });\n return getWsfeResultEntries(result, resultKey).map(mapWsfeCatalogEntry);\n }\n\n function issue({\n representedTaxId,\n data,\n voucherNumber,\n forceRefresh,\n }: WsfeAuthorizeVoucherInput): Promise<WsfeAuthorizationOutcome> {\n const normalizedInput = normalizeWsfeVoucherInput(data);\n return executeWsfeAuthorization({\n representedTaxId,\n data: normalizedInput,\n voucherNumber,\n forceRefresh,\n }).then(({ outcome }) => outcome);\n }\n\n async function executeWsfeAuthorization({\n representedTaxId,\n data: normalizedInput,\n voucherNumber,\n forceRefresh,\n }: {\n representedTaxId?: number | string;\n data: NormalizedWsfeVoucherInput;\n voucherNumber: number;\n forceRefresh?: boolean;\n }): Promise<{\n outcome: WsfeAuthorizationOutcome;\n error?: unknown;\n }> {\n const requestData = mapWsfeVoucherInput(normalizedInput, voucherNumber);\n\n try {\n const result = await executeWsfeAuthenticatedRawOperation(\n \"FECAESolicitar\",\n { representedTaxId, forceRefresh },\n {\n FeCAEReq: {\n FeCabReq: {\n CantReg: 1,\n PtoVta: normalizedInput.salesPoint,\n CbteTipo: normalizedInput.voucherType,\n },\n FeDetReq: {\n FECAEDetRequest: requestData,\n },\n },\n },\n 0\n );\n\n return {\n outcome: classifyWsfeAuthorization(result, voucherNumber),\n };\n } catch (error) {\n return {\n outcome: createWsfeIndeterminateOutcome(error),\n error,\n };\n }\n }\n\n function lookupVoucher({\n representedTaxId,\n number,\n salesPoint,\n voucherType,\n forceRefresh,\n }: {\n representedTaxId?: number | string;\n number: number;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<WsfeVoucherLookupResult> {\n return executeWithAuthenticationRecovery({\n service: \"wsfe\",\n operation: \"FECompConsultar\",\n forceRefresh,\n execute: (attemptForceRefresh) =>\n lookupVoucherOnce({\n representedTaxId,\n number,\n salesPoint,\n voucherType,\n forceRefresh: attemptForceRefresh,\n }),\n });\n }\n\n async function lookupVoucherOnce({\n representedTaxId,\n number,\n salesPoint,\n voucherType,\n forceRefresh,\n }: {\n representedTaxId?: number | string;\n number: number;\n salesPoint: number;\n voucherType: number;\n forceRefresh?: boolean;\n }): Promise<WsfeVoucherLookupResult> {\n const operation = \"FECompConsultar\";\n const result = await executeWsfeAuthenticatedRawOperation(\n operation,\n { representedTaxId, forceRefresh },\n {\n FeCompConsReq: {\n CbteNro: number,\n PtoVta: salesPoint,\n CbteTipo: voucherType,\n },\n }\n );\n const errors = extractWsfeGlobalIssues(result, operation);\n\n if (errors.length > 0 && errors.every((issue) => issue.code === \"602\")) {\n return {\n kind: \"not_found\",\n service: \"wsfe\",\n operation,\n errors,\n observations: [],\n raw: result,\n };\n }\n\n if (errors.length > 0) {\n throw createWsfeServiceError(operation, errors);\n }\n\n const raw = toWsfeRecord(result.ResultGet);\n if (!raw) {\n throw new ArcaServiceError(\"WSFE did not return the consulted voucher\", {\n service: \"wsfe\",\n operation,\n });\n }\n\n return {\n kind: \"found\",\n service: \"wsfe\",\n operation,\n voucher: mapWsfeVoucherInfo(raw),\n observations: [],\n raw: result,\n };\n }\n\n return {\n issue,\n getNextVoucherNumber,\n getLastVoucher(input) {\n return getNextVoucherNumber(input);\n },\n async getSalesPoints({ representedTaxId, forceRefresh }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FEParamGetPtosVenta\",\n {\n representedTaxId,\n forceRefresh,\n }\n );\n const rawPoints = (\n result.ResultGet as Record<string, unknown> | undefined\n )?.PtoVenta;\n if (!rawPoints) {\n return [];\n }\n const entries = Array.isArray(rawPoints) ? rawPoints : [rawPoints];\n return entries.map(mapWsfeSalesPoint);\n },\n getVoucherTypes(input) {\n return getWsfeCatalog(\"FEParamGetTiposCbte\", \"CbteTipo\", input);\n },\n getDocumentTypes(input) {\n return getWsfeCatalog(\"FEParamGetTiposDoc\", \"DocTipo\", input);\n },\n getConceptTypes(input) {\n return getWsfeCatalog(\"FEParamGetTiposConcepto\", \"ConceptoTipo\", input);\n },\n async getCurrencyTypes({ representedTaxId, forceRefresh }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FEParamGetTiposMonedas\",\n {\n representedTaxId,\n forceRefresh,\n }\n );\n return getWsfeResultEntries(result, \"Moneda\").map(mapWsfeCurrencyType);\n },\n getVatRates(input) {\n return getWsfeCatalog(\"FEParamGetTiposIva\", \"IvaTipo\", input);\n },\n getTaxTypes(input) {\n return getWsfeCatalog(\"FEParamGetTiposTributos\", \"TributoTipo\", input);\n },\n getOptionalTypes(input) {\n return getWsfeCatalog(\"FEParamGetTiposOpcional\", \"OpcionalTipo\", input);\n },\n async getActivities({ representedTaxId, forceRefresh }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FEParamGetActividades\",\n {\n representedTaxId,\n forceRefresh,\n }\n );\n return getWsfeResultEntries(result, \"ActividadesTipo\").map(\n mapWsfeActivityType\n );\n },\n async getReceiverVatConditions({\n representedTaxId,\n voucherClass,\n forceRefresh,\n }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FEParamGetCondicionIvaReceptor\",\n {\n representedTaxId,\n forceRefresh,\n },\n {\n ...(voucherClass === undefined ? {} : { ClaseCmp: voucherClass }),\n }\n );\n return getWsfeResultEntries(result, \"CondicionIvaReceptor\").map(\n mapWsfeReceiverVatCondition\n );\n },\n async getServerStatus() {\n const result = await executeWsfeOperation(\"FEDummy\");\n return mapWsfeServerStatus(result);\n },\n async getQuotation({ currencyId, representedTaxId, forceRefresh }) {\n const result = await executeWsfeAuthenticatedOperation(\n \"FEParamGetCotizacion\",\n {\n representedTaxId,\n forceRefresh,\n },\n {\n MonId: currencyId,\n }\n );\n const raw =\n (result.ResultGet as Record<string, unknown> | undefined) ?? {};\n return mapWsfeQuotation(raw);\n },\n async getVoucherInfo(input) {\n const lookup = await lookupVoucher(input);\n return lookup.kind === \"found\" ? lookup.voucher : null;\n },\n lookupVoucher,\n };\n}\n\nfunction mapWsfeVoucherInput(\n input: NormalizedWsfeVoucherInput,\n voucherNumber: number\n): Record<string, unknown> {\n const data: Record<string, unknown> = {\n Concepto: input.concept,\n DocTipo: input.documentType,\n DocNro: input.documentNumber,\n CbteDesde: voucherNumber,\n CbteHasta: voucherNumber,\n CbteFch: input.voucherDate,\n ImpTotal: input.totalAmount,\n ImpTotConc: input.nonTaxableAmount,\n ImpNeto: input.netAmount,\n ImpOpEx: input.exemptAmount,\n ImpTrib: input.taxAmount,\n ImpIVA: input.vatAmount,\n MonId: input.currencyId,\n CondicionIVAReceptorId: input.receiverVatConditionId,\n PtoVta: input.salesPoint,\n CbteTipo: input.voucherType,\n };\n\n if (input.exchangeRate !== undefined) {\n data.MonCotiz = input.exchangeRate;\n }\n\n if (\n input.currencyId !== \"PES\" &&\n input.sameCurrencyForeignCancellation !== undefined\n ) {\n data.CanMisMonExt = input.sameCurrencyForeignCancellation;\n }\n\n if (input.serviceStartDate !== undefined) {\n data.FchServDesde = input.serviceStartDate;\n }\n if (input.serviceEndDate !== undefined) {\n data.FchServHasta = input.serviceEndDate;\n }\n if (input.paymentDueDate !== undefined) {\n data.FchVtoPago = input.paymentDueDate;\n }\n\n if (input.associatedVouchers) {\n data.CbtesAsoc = {\n CbteAsoc: input.associatedVouchers.map((v) => ({\n Tipo: v.type,\n PtoVta: v.salesPoint,\n Nro: v.number,\n ...(v.taxId === undefined ? {} : { Cuit: v.taxId }),\n ...(v.voucherDate === undefined ? {} : { CbteFch: v.voucherDate }),\n })),\n };\n }\n\n if (input.associatedPeriod) {\n data.PeriodoAsoc = {\n FchDesde: input.associatedPeriod.startDate,\n FchHasta: input.associatedPeriod.endDate,\n };\n }\n\n if (input.taxes) {\n data.Tributos = {\n Tributo: input.taxes.map((t) => ({\n Id: t.id,\n ...(t.description === undefined ? {} : { Desc: t.description }),\n BaseImp: t.baseAmount,\n Alic: t.rate,\n Importe: t.amount,\n })),\n };\n }\n\n if (input.vatRates) {\n data.Iva = {\n AlicIva: input.vatRates.map((v) => ({\n Id: v.id,\n BaseImp: v.baseAmount,\n Importe: v.amount,\n })),\n };\n }\n\n if (input.optionalFields) {\n data.Opcionales = {\n Opcional: input.optionalFields.map((o) => ({\n Id: o.id,\n Valor: o.value,\n })),\n };\n }\n\n if (input.buyers) {\n data.Compradores = {\n Comprador: input.buyers.map((b) => ({\n DocTipo: b.documentType,\n DocNro: b.documentNumber,\n Porcentaje: b.percentage,\n })),\n };\n }\n\n if (input.activities) {\n data.Actividades = {\n Actividad: input.activities.map((a) => ({\n Id: a.id,\n })),\n };\n }\n\n return data;\n}\n\nexport function normalizeWsfeVoucherInput(\n input: WsfeVoucherInput\n): NormalizedWsfeVoucherInput {\n if (input.receiverVatConditionId === undefined) {\n throw new ArcaInputError(\"receiverVatConditionId is required.\", {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"receiverVatConditionId\",\n expected: \"a receiver VAT condition accepted for the voucher class\",\n });\n }\n\n const {\n voucherDate,\n exchangeRate,\n serviceStartDate,\n serviceEndDate,\n paymentDueDate,\n associatedVouchers,\n associatedPeriod,\n taxes,\n vatRates,\n ...rest\n } = input;\n const normalizedExchangeRate = normalizeWsfeExchangeRate(input, exchangeRate);\n const normalizedAmounts = normalizeAndValidateWsfeAmounts(input);\n\n return {\n ...rest,\n ...normalizedAmounts,\n voucherDate: normalizeWsfeDateInput(voucherDate, \"voucherDate\"),\n ...(normalizedExchangeRate === undefined\n ? {}\n : { exchangeRate: normalizedExchangeRate }),\n ...(serviceStartDate === undefined\n ? {}\n : {\n serviceStartDate: normalizeWsfeDateInput(\n serviceStartDate,\n \"serviceStartDate\"\n ),\n }),\n ...(serviceEndDate === undefined\n ? {}\n : {\n serviceEndDate: normalizeWsfeDateInput(\n serviceEndDate,\n \"serviceEndDate\"\n ),\n }),\n ...(paymentDueDate === undefined\n ? {}\n : {\n paymentDueDate: normalizeWsfeDateInput(\n paymentDueDate,\n \"paymentDueDate\"\n ),\n }),\n ...(associatedVouchers === undefined\n ? {}\n : {\n associatedVouchers: associatedVouchers.map((voucher, index) => {\n const { voucherDate: associatedVoucherDate, ...associatedRest } =\n voucher;\n\n return {\n ...associatedRest,\n ...(associatedVoucherDate === undefined\n ? {}\n : {\n voucherDate: normalizeWsfeDateInput(\n associatedVoucherDate,\n `associatedVouchers[${index}].voucherDate`\n ),\n }),\n };\n }),\n }),\n ...(associatedPeriod === undefined\n ? {}\n : {\n associatedPeriod: {\n startDate: normalizeWsfeDateInput(\n associatedPeriod.startDate,\n \"associatedPeriod.startDate\"\n ),\n endDate: normalizeWsfeDateInput(\n associatedPeriod.endDate,\n \"associatedPeriod.endDate\"\n ),\n },\n }),\n ...(taxes === undefined\n ? {}\n : {\n taxes: taxes.map((tax, index) => ({\n ...tax,\n baseAmount: serializeArcaAmount(\n tax.baseAmount,\n `taxes[${index}].baseAmount`\n ),\n rate: serializeArcaPercentage(tax.rate, `taxes[${index}].rate`),\n amount: serializeArcaAmount(tax.amount, `taxes[${index}].amount`),\n })),\n }),\n ...(vatRates === undefined\n ? {}\n : {\n vatRates: vatRates.map((vatRate, index) => ({\n ...vatRate,\n baseAmount: serializeArcaAmount(\n vatRate.baseAmount,\n `vatRates[${index}].baseAmount`\n ),\n amount: serializeArcaAmount(\n vatRate.amount,\n `vatRates[${index}].amount`\n ),\n })),\n }),\n };\n}\n\nfunction normalizeAndValidateWsfeAmounts(\n input: WsfeVoucherInput\n): Pick<\n NormalizedWsfeVoucherInput,\n | \"totalAmount\"\n | \"nonTaxableAmount\"\n | \"netAmount\"\n | \"exemptAmount\"\n | \"taxAmount\"\n | \"vatAmount\"\n> {\n const totalAmount = normalizeArcaAmountToMinorUnits(\n input.totalAmount,\n \"totalAmount\"\n );\n const nonTaxableAmount = normalizeArcaAmountToMinorUnits(\n input.nonTaxableAmount,\n \"nonTaxableAmount\"\n );\n const netAmount = normalizeArcaAmountToMinorUnits(\n input.netAmount,\n \"netAmount\"\n );\n const exemptAmount = normalizeArcaAmountToMinorUnits(\n input.exemptAmount,\n \"exemptAmount\"\n );\n const taxAmount = normalizeArcaAmountToMinorUnits(\n input.taxAmount,\n \"taxAmount\"\n );\n const vatAmount = normalizeArcaAmountToMinorUnits(\n input.vatAmount,\n \"vatAmount\"\n );\n\n const decomposedTotal =\n nonTaxableAmount + netAmount + exemptAmount + taxAmount + vatAmount;\n assertWsfeAmountMatch(\n totalAmount,\n decomposedTotal,\n \"totalAmount\",\n \"the sum of nonTaxableAmount, netAmount, exemptAmount, taxAmount, and vatAmount\"\n );\n\n const vatRates = input.vatRates ?? [];\n if (vatAmount > 0n && vatRates.length === 0) {\n throw new ArcaInputError(\n \"vatRates is required when vatAmount is greater than zero.\",\n {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"vatRates\",\n expected: \"VAT detail whose amounts reconcile with vatAmount\",\n }\n );\n }\n\n if (vatRates.length > 0) {\n const normalizedVatRates = vatRates.map((vatRate, index) => ({\n baseAmount: normalizeArcaAmountToMinorUnits(\n vatRate.baseAmount,\n `vatRates[${index}].baseAmount`\n ),\n amount: normalizeArcaAmountToMinorUnits(\n vatRate.amount,\n `vatRates[${index}].amount`\n ),\n }));\n const vatRateAmountSum = normalizedVatRates.reduce(\n (sum, vatRate) => sum + vatRate.amount,\n 0n\n );\n const vatRateBaseSum = normalizedVatRates.reduce(\n (sum, vatRate) => sum + vatRate.baseAmount,\n 0n\n );\n\n assertWsfeAmountMatch(\n vatAmount,\n vatRateAmountSum,\n \"vatAmount\",\n \"the sum of vatRates[].amount\",\n vatRates.length\n );\n if (requiresWsfeVatBaseReconciliation(input.voucherType)) {\n assertWsfeAmountMatch(\n netAmount,\n vatRateBaseSum,\n \"netAmount\",\n \"the sum of vatRates[].baseAmount\",\n vatRates.length\n );\n }\n }\n\n const taxes = input.taxes ?? [];\n if (taxAmount > 0n && taxes.length === 0) {\n throw new ArcaInputError(\n \"taxes is required when taxAmount is greater than zero.\",\n {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"taxes\",\n expected: \"tax detail whose amounts reconcile with taxAmount\",\n }\n );\n }\n\n if (taxes.length > 0) {\n const taxAmountSum = taxes.reduce((sum, tax, index) => {\n normalizeArcaAmountToMinorUnits(\n tax.baseAmount,\n `taxes[${index}].baseAmount`\n );\n serializeArcaPercentage(tax.rate, `taxes[${index}].rate`);\n return (\n sum +\n normalizeArcaAmountToMinorUnits(tax.amount, `taxes[${index}].amount`)\n );\n }, 0n);\n\n assertWsfeAmountMatch(\n taxAmount,\n taxAmountSum,\n \"taxAmount\",\n \"the sum of taxes[].amount\",\n taxes.length\n );\n }\n\n return {\n totalAmount: serializeArcaAmount(input.totalAmount, \"totalAmount\"),\n nonTaxableAmount: serializeArcaAmount(\n input.nonTaxableAmount,\n \"nonTaxableAmount\"\n ),\n netAmount: serializeArcaAmount(input.netAmount, \"netAmount\"),\n exemptAmount: serializeArcaAmount(input.exemptAmount, \"exemptAmount\"),\n taxAmount: serializeArcaAmount(input.taxAmount, \"taxAmount\"),\n vatAmount: serializeArcaAmount(input.vatAmount, \"vatAmount\"),\n };\n}\n\nfunction requiresWsfeVatBaseReconciliation(voucherType: number): boolean {\n // WSFE validation 10061 exempts debit/credit notes, class C vouchers,\n // and class A vouchers with the retention legend.\n return ![2, 3, 7, 8, 11, 12, 13, 15, 52, 53].includes(voucherType);\n}\n\nfunction assertWsfeAmountMatch(\n actual: bigint,\n expectedAmount: bigint,\n field: string,\n expectedDescription: string,\n absoluteCentAllowance = 1\n) {\n if (!isWithinArcaTolerance(actual, expectedAmount, absoluteCentAllowance)) {\n throw new ArcaInputError(\n `${field} does not reconcile within ARCA's documented tolerance.`,\n {\n code: \"ARCA_INPUT_AMOUNT_MISMATCH\",\n field,\n expected: `within ARCA tolerance of ${expectedDescription}`,\n }\n );\n }\n}\n\nfunction normalizeWsfeExchangeRate(\n input: Pick<\n WsfeVoucherInput,\n \"currencyId\" | \"sameCurrencyForeignCancellation\"\n >,\n exchangeRate: number | string | undefined\n): string | undefined {\n if (input.currencyId === \"PES\") {\n if (\n exchangeRate !== undefined &&\n serializeArcaExchangeRate(exchangeRate, \"exchangeRate\") !== \"1\"\n ) {\n throw new ArcaInputError(\n \"exchangeRate must be 1 when currencyId is PES.\",\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field: \"exchangeRate\",\n expected: \"1 when currencyId is PES\",\n }\n );\n }\n return \"1\";\n }\n\n if (exchangeRate === undefined) {\n if (input.sameCurrencyForeignCancellation === \"S\") {\n return undefined;\n }\n throw new ArcaInputError(\n \"exchangeRate is required unless sameCurrencyForeignCancellation is S for a foreign-currency voucher.\",\n {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"exchangeRate\",\n expected:\n \"a positive exchange rate unless sameCurrencyForeignCancellation is S\",\n }\n );\n }\n\n return serializeArcaExchangeRate(exchangeRate, \"exchangeRate\");\n}\n\nexport function normalizeWsfeDateInput(\n value: WsfeDateInput,\n fieldName: string\n): string {\n if (typeof value !== \"string\") {\n throw new ArcaInputError(\n `Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,\n {\n code: \"ARCA_INPUT_INVALID_DATE\",\n field: fieldName,\n expected: \"a YYYY-MM-DD or YYYYMMDD calendar date string\",\n }\n );\n }\n\n const normalizedValue = value.trim();\n const afipMatch = normalizedValue.match(/^(\\d{4})(\\d{2})(\\d{2})$/);\n if (afipMatch) {\n const [, year, month, day] = afipMatch;\n assertValidCalendarDate(year, month, day, fieldName);\n return normalizedValue;\n }\n\n const isoMatch = normalizedValue.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (isoMatch) {\n const [, year, month, day] = isoMatch;\n assertValidCalendarDate(year, month, day, fieldName);\n return `${year}${month}${day}`;\n }\n\n throw new ArcaInputError(\n `Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,\n {\n code: \"ARCA_INPUT_INVALID_DATE\",\n field: fieldName,\n expected: \"a YYYY-MM-DD or YYYYMMDD calendar date string\",\n }\n );\n}\n\nfunction assertValidCalendarDate(\n yearInput: string,\n monthInput: string,\n dayInput: string,\n fieldName: string\n) {\n const year = Number(yearInput);\n const month = Number(monthInput);\n const day = Number(dayInput);\n const candidate = new Date(Date.UTC(year, month - 1, day));\n\n if (\n candidate.getUTCFullYear() !== year ||\n candidate.getUTCMonth() !== month - 1 ||\n candidate.getUTCDate() !== day\n ) {\n throw new ArcaInputError(\n `Invalid WSFE ${fieldName}: received a non-existent calendar date`,\n {\n code: \"ARCA_INPUT_INVALID_DATE\",\n field: fieldName,\n expected: \"an existing calendar date\",\n }\n );\n }\n}\n\nfunction mapWsfeSalesPoint(raw: unknown): WsfeSalesPoint {\n const record = raw as Record<string, unknown>;\n return {\n number: Number(record.Nro ?? 0),\n ...(record.EmisionTipo === undefined\n ? {}\n : { emissionType: String(record.EmisionTipo) }),\n ...(record.Bloqueado === undefined\n ? {}\n : { blocked: String(record.Bloqueado) }),\n ...(record.FchBaja === undefined\n ? {}\n : { deletedSince: String(record.FchBaja) }),\n };\n}\n\nfunction mapWsfeCatalogEntry(raw: unknown): WsfeCatalogEntry {\n const record = raw as Record<string, unknown>;\n return {\n id: Number(record.Id ?? 0),\n description: String(record.Desc ?? \"\"),\n };\n}\n\nfunction mapWsfeActivityType(raw: unknown): WsfeActivityType {\n const record = raw as Record<string, unknown>;\n return {\n id: Number(record.Id ?? 0),\n description: String(record.Desc ?? \"\"),\n order: Number(record.Orden ?? 0),\n };\n}\n\nfunction mapWsfeReceiverVatCondition(raw: unknown): WsfeReceiverVatCondition {\n const record = raw as Record<string, unknown>;\n return {\n id: Number(record.Id ?? 0),\n description: String(record.Desc ?? \"\"),\n voucherClass: String(record.Cmp_Clase ?? \"\"),\n };\n}\n\nfunction mapWsfeCurrencyType(raw: unknown): WsfeCurrencyType {\n const record = raw as Record<string, unknown>;\n return {\n id: String(record.Id ?? \"\"),\n description: String(record.Desc ?? \"\"),\n validFrom: String(record.FchDesde ?? \"\"),\n validTo: String(record.FchHasta ?? \"\"),\n };\n}\n\nfunction mapWsfeServerStatus(raw: Record<string, unknown>): WsfeServerStatus {\n return {\n appServer: String(raw.AppServer ?? \"\"),\n dbServer: String(raw.DbServer ?? \"\"),\n authServer: String(raw.AuthServer ?? \"\"),\n };\n}\n\nfunction mapWsfeQuotation(raw: Record<string, unknown>): WsfeQuotation {\n return {\n currencyId: String(raw.MonId ?? \"\"),\n rate: Number(raw.MonCotiz ?? 0),\n date: String(raw.FchCotiz ?? \"\"),\n };\n}\n\nfunction mapWsfeVoucherInfo(raw: Record<string, unknown>): WsfeVoucherInfo {\n const voucher: WsfeVoucherInfo = {\n voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),\n raw,\n };\n\n assignWsfeValue(voucher, \"voucherDate\", normalizeWsfeString(raw.CbteFch));\n assignWsfeValue(voucher, \"salesPoint\", normalizeWsfeNumber(raw.PtoVta));\n assignWsfeValue(voucher, \"voucherType\", normalizeWsfeNumber(raw.CbteTipo));\n assignWsfeValue(voucher, \"concept\", normalizeWsfeNumber(raw.Concepto));\n assignWsfeValue(voucher, \"documentType\", normalizeWsfeNumber(raw.DocTipo));\n assignWsfeValue(voucher, \"documentNumber\", normalizeWsfeString(raw.DocNro));\n assignWsfeValue(\n voucher,\n \"receiverVatConditionId\",\n normalizeWsfeNumber(raw.CondicionIVAReceptorId)\n );\n assignWsfeValue(voucher, \"totalAmount\", normalizeWsfeNumber(raw.ImpTotal));\n assignWsfeValue(\n voucher,\n \"nonTaxableAmount\",\n normalizeWsfeNumber(raw.ImpTotConc)\n );\n assignWsfeValue(voucher, \"netAmount\", normalizeWsfeNumber(raw.ImpNeto));\n assignWsfeValue(voucher, \"exemptAmount\", normalizeWsfeNumber(raw.ImpOpEx));\n assignWsfeValue(voucher, \"taxAmount\", normalizeWsfeNumber(raw.ImpTrib));\n assignWsfeValue(voucher, \"vatAmount\", normalizeWsfeNumber(raw.ImpIVA));\n assignWsfeValue(voucher, \"currencyId\", normalizeWsfeString(raw.MonId));\n assignWsfeValue(voucher, \"exchangeRate\", normalizeWsfeNumber(raw.MonCotiz));\n assignWsfeValue(voucher, \"result\", normalizeWsfeString(raw.Resultado));\n assignWsfeValue(\n voucher,\n \"cae\",\n normalizeWsfeString(raw.CodAutorizacion ?? raw.CAE)\n );\n assignWsfeValue(\n voucher,\n \"caeExpiry\",\n normalizeWsfeString(raw.FchVto ?? raw.CAEFchVto)\n );\n\n assignWsfeValue(\n voucher,\n \"serviceStartDate\",\n normalizeWsfeString(raw.FchServDesde)\n );\n assignWsfeValue(\n voucher,\n \"serviceEndDate\",\n normalizeWsfeString(raw.FchServHasta)\n );\n assignWsfeValue(\n voucher,\n \"paymentDueDate\",\n normalizeWsfeString(raw.FchVtoPago)\n );\n assignWsfeValue(\n voucher,\n \"vatRates\",\n mapWsfeLookupDetails(raw.Iva, \"AlicIva\", mapWsfeLookupVat)\n );\n assignWsfeValue(\n voucher,\n \"taxes\",\n mapWsfeLookupDetails(raw.Tributos, \"Tributo\", mapWsfeLookupTax)\n );\n\n assignWsfeValue(\n voucher,\n \"associatedVouchers\",\n mapWsfeLookupDetails(raw.CbtesAsoc, \"CbteAsoc\", (item) => {\n const type = normalizeWsfeNumber(item.Tipo);\n const salesPoint = normalizeWsfeNumber(item.PtoVta);\n const number = normalizeWsfeNumber(item.Nro);\n if (\n type === undefined ||\n salesPoint === undefined ||\n number === undefined\n ) {\n return undefined;\n }\n return {\n type,\n salesPoint,\n number,\n ...(normalizeWsfeString(item.CbteFch)\n ? { voucherDate: normalizeWsfeString(item.CbteFch) as WsfeDateInput }\n : {}),\n };\n })\n );\n return voucher;\n}\n\n// A missing or malformed detail stays absent; never fabricate zero-valued identity evidence.\nfunction mapWsfeLookupDetails<T>(\n container: unknown,\n key: string,\n map: (row: Record<string, unknown>) => T | undefined\n): T[] | undefined {\n const record = toWsfeRecord(container);\n if (!record || record[key] === undefined) {\n return undefined;\n }\n const rows = Array.isArray(record[key]) ? record[key] : [record[key]];\n const result: T[] = [];\n for (const value of rows) {\n const row = toWsfeRecord(value);\n const mapped = row ? map(row) : undefined;\n if (mapped === undefined) {\n return undefined;\n }\n result.push(mapped);\n }\n return result;\n}\n\nfunction mapWsfeLookupVat(\n row: Record<string, unknown>\n): WsfeVatRate | undefined {\n const id = normalizeWsfeNumber(row.Id);\n const baseAmount = normalizeWsfeNumber(row.BaseImp);\n const amount = normalizeWsfeNumber(row.Importe);\n if (id === undefined || baseAmount === undefined || amount === undefined) {\n return undefined;\n }\n return { id, baseAmount, amount };\n}\n\nfunction mapWsfeLookupTax(row: Record<string, unknown>): WsfeTax | undefined {\n const vat = mapWsfeLookupVat(row);\n const rate = normalizeWsfeNumber(row.Alic);\n if (!vat || rate === undefined) {\n return undefined;\n }\n const description = normalizeWsfeString(row.Desc);\n return {\n ...vat,\n rate,\n ...(description === undefined ? {} : { description }),\n };\n}\n\nfunction createWsfeAuth(\n representedTaxId: number | string,\n token: string,\n sign: string\n) {\n return {\n Token: token,\n Sign: sign,\n Cuit: Number.parseInt(String(representedTaxId), 10),\n };\n}\n\nfunction unwrapWsfeOperationEnvelope(\n operation: string,\n response: Record<string, unknown>\n) {\n const operationResponse = response[`${operation}Response`] as\n | Record<string, unknown>\n | undefined;\n const result = (operationResponse?.[`${operation}Result`] ??\n response[`${operation}Result`] ??\n response) as Record<string, unknown>;\n\n return result;\n}\n\nfunction throwForWsfeOperationErrors(\n operation: string,\n result: Record<string, unknown>\n) {\n const errors = extractWsfeGlobalIssues(result, operation);\n if (errors.length > 0) {\n throw createWsfeServiceError(operation, errors);\n }\n}\n\nfunction normalizeWsfeDetailResponse(result: Record<string, unknown>) {\n const detailResponse = result.FeDetResp as\n | Record<string, unknown>\n | undefined;\n const rawDetail = detailResponse?.FECAEDetResponse;\n\n if (Array.isArray(rawDetail)) {\n return (rawDetail[0] as Record<string, unknown>) ?? {};\n }\n\n return (rawDetail as Record<string, unknown> | undefined) ?? {};\n}\n\nfunction classifyWsfeAuthorization(\n result: Record<string, unknown>,\n voucherNumber: number\n): WsfeAuthorizationOutcome {\n const operation = \"FECAESolicitar\";\n const header = toWsfeRecord(result.FeCabResp) ?? {};\n const detail = normalizeWsfeDetailResponse(result);\n const headerResult = normalizeWsfeResult(header.Resultado);\n const detailResult = normalizeWsfeResult(detail.Resultado);\n const resultCode = detailResult ?? headerResult;\n const resultLevel = getWsfeResultLevel(headerResult, detailResult);\n const cae = normalizeWsfeString(detail.CAE);\n const caeExpiry = normalizeWsfeString(detail.CAEFchVto);\n const errors = extractWsfeGlobalIssues(result, operation, \"header\");\n const observations = extractWsfeObservations(\n detail,\n detailResult === \"R\" ? \"business\" : \"observation\"\n );\n const hasInfrastructureError = errors.some(\n (issue) => issue.category === \"infrastructure\"\n );\n const base = {\n service: \"wsfe\" as const,\n operation,\n results: createWsfeResults(headerResult, detailResult),\n errors,\n observations,\n raw: result,\n };\n const context: WsfeAuthorizationContext = {\n base,\n headerResult,\n detailResult,\n resultCode,\n resultLevel,\n cae,\n caeExpiry,\n };\n\n if (hasContradictoryWsfeResults(context)) {\n return createWsfeStructuredIndeterminate(context, \"contradictory_response\");\n }\n\n const authenticationError = classifyArcaAuthenticationIssues(errors, {\n service: \"wsfe\",\n operation,\n });\n if (\n authenticationError &&\n detailResult === undefined &&\n headerResult !== \"A\" &&\n headerResult !== \"O\" &&\n !cae\n ) {\n return {\n ...createWsfeStructuredIndeterminate(context, \"authentication_rejected\"),\n authentication: createArcaAuthenticationEvidence(authenticationError),\n };\n }\n\n if (hasInfrastructureError) {\n return createWsfeStructuredIndeterminate(context, \"incomplete_response\");\n }\n\n if (isAuthorizedWsfeContext(context)) {\n return {\n ...base,\n kind: \"authorized\",\n result: \"A\",\n resultLevel: \"detail\",\n cae: context.cae,\n caeExpiry: context.caeExpiry,\n voucherNumber,\n };\n }\n\n if (isRejectedWsfeDetailContext(context)) {\n return {\n ...base,\n kind: \"rejected\",\n result: \"R\",\n resultLevel: \"detail\",\n };\n }\n\n if (isRejectedWsfeHeaderContext(context)) {\n return {\n ...base,\n kind: \"rejected\",\n result: \"R\",\n resultLevel: \"header\",\n };\n }\n\n return createWsfeStructuredIndeterminate(\n context,\n hasWsfeCaeContradiction(context)\n ? \"contradictory_response\"\n : \"incomplete_response\"\n );\n}\n\ntype WsfeAuthorizationContext = {\n base: {\n service: \"wsfe\";\n operation: string;\n results: { header?: string; detail?: string };\n errors: ArcaFiscalIssue[];\n observations: ArcaFiscalIssue[];\n raw: Record<string, unknown>;\n };\n headerResult?: string;\n detailResult?: string;\n resultCode?: string;\n resultLevel?: ArcaFiscalResultLevel;\n cae?: string;\n caeExpiry?: string;\n};\n\nfunction getWsfeResultLevel(\n headerResult?: string,\n detailResult?: string\n): ArcaFiscalResultLevel | undefined {\n if (detailResult) {\n return \"detail\";\n }\n return headerResult ? \"header\" : undefined;\n}\n\nfunction hasContradictoryWsfeResults(context: WsfeAuthorizationContext) {\n return Boolean(\n context.headerResult &&\n context.detailResult &&\n context.headerResult !== context.detailResult\n );\n}\n\nfunction isAuthorizedWsfeContext(\n context: WsfeAuthorizationContext\n): context is WsfeAuthorizationContext & { cae: string; caeExpiry: string } {\n return Boolean(\n context.detailResult === \"A\" &&\n context.headerResult !== \"R\" &&\n context.base.errors.length === 0 &&\n context.cae &&\n context.caeExpiry\n );\n}\n\nfunction isRejectedWsfeDetailContext(context: WsfeAuthorizationContext) {\n return (\n context.detailResult === \"R\" && context.headerResult !== \"A\" && !context.cae\n );\n}\n\nfunction isRejectedWsfeHeaderContext(context: WsfeAuthorizationContext) {\n return (\n context.headerResult === \"R\" &&\n context.detailResult === undefined &&\n !context.cae &&\n context.base.errors.length > 0 &&\n context.base.errors.every((issue) => issue.category === \"business\")\n );\n}\n\nfunction hasWsfeCaeContradiction(context: WsfeAuthorizationContext) {\n return (\n (context.resultCode === \"A\" || context.resultCode === \"R\") &&\n Boolean(context.cae)\n );\n}\n\nfunction createWsfeStructuredIndeterminate(\n context: WsfeAuthorizationContext,\n reason: ArcaAuthorizationIndeterminateReason\n): Extract<WsfeAuthorizationOutcome, { kind: \"indeterminate\" }> {\n const outcome: Extract<WsfeAuthorizationOutcome, { kind: \"indeterminate\" }> =\n {\n ...context.base,\n kind: \"indeterminate\",\n reason,\n };\n assignWsfeValue(outcome, \"result\", context.resultCode);\n assignWsfeValue(outcome, \"resultLevel\", context.resultLevel);\n assignWsfeValue(outcome, \"cae\", context.cae);\n assignWsfeValue(outcome, \"caeExpiry\", context.caeExpiry);\n return outcome;\n}\n\nfunction createWsfeResults(headerResult?: string, detailResult?: string) {\n const results: { header?: string; detail?: string } = {};\n assignWsfeValue(results, \"header\", headerResult);\n assignWsfeValue(results, \"detail\", detailResult);\n return results;\n}\n\nfunction createWsfeIndeterminateOutcome(\n error: unknown\n): WsfeAuthorizationOutcome {\n const authenticationError = classifyArcaAuthenticationError(error, {\n service: \"wsfe\",\n operation: \"FECAESolicitar\",\n });\n return {\n kind: \"indeterminate\",\n service: \"wsfe\",\n operation: \"FECAESolicitar\",\n results: {},\n reason: authenticationError\n ? \"authentication_rejected\"\n : getArcaIndeterminateReason(error),\n ...(authenticationError\n ? {\n authentication: createArcaAuthenticationEvidence(authenticationError),\n }\n : {}),\n errors: [],\n observations: [],\n };\n}\n\nfunction getArcaIndeterminateReason(\n error: unknown\n): ArcaAuthorizationIndeterminateReason {\n if (error instanceof ArcaTransportError) {\n return \"transport_error\";\n }\n if (error instanceof ArcaSoapFaultError) {\n return \"soap_fault\";\n }\n if (error instanceof ArcaInvalidSoapResponseError) {\n return \"invalid_response\";\n }\n return \"unexpected_error\";\n}\n\nfunction createWsfeServiceError(operation: string, issues: ArcaFiscalIssue[]) {\n const authenticationError = classifyArcaAuthenticationIssues(issues, {\n service: \"wsfe\",\n operation,\n });\n if (authenticationError) {\n return authenticationError;\n }\n\n const firstIssue = issues[0];\n return new ArcaServiceError(\n firstIssue ? formatWsfeIssue(firstIssue) : \"WSFE returned a service error\",\n {\n service: \"wsfe\",\n operation,\n ...(firstIssue?.code === undefined\n ? {}\n : { serviceCode: firstIssue.code }),\n issues,\n }\n );\n}\n\nfunction extractWsfeGlobalIssues(\n result: Record<string, unknown>,\n operation: string,\n resultLevel?: ArcaFiscalResultLevel\n): ArcaFiscalIssue[] {\n const errorsContainer = toWsfeRecord(result.Errors);\n return normalizeWsfeIssueEntries(errorsContainer?.Err).map((entry) => ({\n service: \"wsfe\",\n operation,\n source: \"error\",\n category:\n operation === \"FECAESolicitar\" &&\n WSFE_AUTHORIZATION_INFRASTRUCTURE_CODES.has(entry.code ?? \"\")\n ? \"infrastructure\"\n : operation === \"FECAESolicitar\"\n ? \"business\"\n : \"unknown\",\n ...(entry.code === undefined ? {} : { code: entry.code }),\n message: entry.message,\n ...(resultLevel === undefined ? {} : { resultLevel }),\n }));\n}\n\nfunction extractWsfeObservations(\n detail: Record<string, unknown>,\n category: ArcaFiscalIssue[\"category\"]\n): ArcaFiscalIssue[] {\n const observationsContainer = toWsfeRecord(detail.Observaciones);\n return normalizeWsfeIssueEntries(observationsContainer?.Obs).map((entry) => ({\n service: \"wsfe\",\n operation: \"FECAESolicitar\",\n source: \"observation\",\n category,\n ...(entry.code === undefined ? {} : { code: entry.code }),\n message: entry.message,\n resultLevel: \"detail\",\n }));\n}\n\nfunction normalizeWsfeIssueEntries(rawErrors: unknown) {\n const entries = Array.isArray(rawErrors)\n ? rawErrors\n : rawErrors\n ? [rawErrors]\n : [];\n\n return entries\n .map((entry) => entry as Record<string, unknown>)\n .map((entry) => {\n const code = entry.Code ?? entry.code;\n const message = entry.Msg ?? entry.msg ?? \"Unknown WSFE error\";\n return {\n ...(code === undefined ? {} : { code: String(code) }),\n message: String(message),\n };\n });\n}\n\nfunction formatWsfeIssue(issue: ArcaFiscalIssue) {\n return issue.code ? `(${issue.code}) ${issue.message}` : issue.message;\n}\n\nfunction normalizeWsfeResult(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const normalized = value.trim().toUpperCase();\n return normalized || undefined;\n}\n\nfunction normalizeWsfeString(value: unknown): string | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n const normalized = String(value).trim();\n return normalized || undefined;\n}\n\nfunction normalizeWsfeNumber(value: unknown): number | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const normalized = Number(value);\n return Number.isFinite(normalized) ? normalized : undefined;\n}\n\nfunction assignWsfeValue<TTarget, TKey extends keyof TTarget>(\n target: TTarget,\n key: TKey,\n value: TTarget[TKey] | undefined\n) {\n if (value !== undefined) {\n target[key] = value;\n }\n}\n\nfunction toWsfeRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nconst WSFE_AUTHORIZATION_INFRASTRUCTURE_CODES = new Set([\n \"500\",\n \"501\",\n \"502\",\n \"600\",\n \"601\",\n]);\n\nfunction getWsfeResultEntries(\n result: Record<string, unknown>,\n key: string\n): Record<string, unknown>[] {\n const rawEntries = (\n result.ResultGet as Record<string, unknown> | undefined\n )?.[key];\n if (!rawEntries) {\n return [];\n }\n\n return (Array.isArray(rawEntries) ? rawEntries : [rawEntries]).map(\n (entry) => entry as Record<string, unknown>\n );\n}\n","import { ARCA_VAT_RATES, type VoucherClass } from \"../constants\";\nimport { ArcaInputError } from \"../errors\";\nimport {\n arcaMinorUnitsToNumber,\n assertArcaMinorUnits,\n roundHalfEvenRatio,\n type SupportedVatRate,\n} from \"../internal/decimal\";\nimport type { WsfeVatRate, WsfeVoucherInput } from \"./wsfe\";\n\nexport type VatRate = SupportedVatRate | \"exempt\" | \"untaxed\";\nexport type VatItem =\n | { net: number; gross?: never; amount?: never; vat: VatRate }\n | { gross: number; net?: never; amount?: never; vat: VatRate };\nexport type AmountItem = {\n amount: number;\n vat?: never;\n net?: never;\n gross?: never;\n};\nexport type IssueAmounts = {\n computedTotal: number;\n sentTotal: number;\n vatAdjustment: number;\n};\n/** The class, not the issuer, fixes the accepted item shape and the arithmetic. */\nexport type WsfeAmountsInput = {\n voucherClass: VoucherClass;\n items: readonly (VatItem | AmountItem)[];\n total?: number;\n};\ntype ExactAmounts = Pick<\n WsfeVoucherInput,\n | \"totalAmount\"\n | \"netAmount\"\n | \"vatAmount\"\n | \"nonTaxableAmount\"\n | \"exemptAmount\"\n | \"taxAmount\"\n | \"vatRates\"\n>;\n\nconst RATES: Record<SupportedVatRate, { id: number; basisPoints: bigint }> = {\n 0: { id: ARCA_VAT_RATES.IVA_0, basisPoints: 0n },\n 2.5: { id: ARCA_VAT_RATES.IVA_2_5, basisPoints: 250n },\n 5: { id: ARCA_VAT_RATES.IVA_5, basisPoints: 500n },\n 10.5: { id: ARCA_VAT_RATES.IVA_10_5, basisPoints: 1050n },\n 21: { id: ARCA_VAT_RATES.IVA_21, basisPoints: 2100n },\n 27: { id: ARCA_VAT_RATES.IVA_27, basisPoints: 2700n },\n};\n\n/**\n * Pure integer money core. Amount fields are exact-API major units.\n * Invoices and credit notes share it: both resolve a class first.\n */\nexport function calculateWsfeAmounts(input: WsfeAmountsInput): {\n data: ExactAmounts;\n amounts: IssueAmounts;\n} {\n if (!Array.isArray(input.items) || input.items.length === 0) {\n invalidItem(\"items\", \"a non-empty array of items\");\n }\n const isVat = input.voucherClass === \"A\" || input.voucherClass === \"B\";\n if (!(isVat || input.voucherClass === \"C\")) {\n invalidItem(\"voucherClass\", \"A, B or C\");\n }\n const totals = collectItems(input.items, isVat);\n let net = totals.net;\n let vat = 0n;\n const { exempt, untaxed, groups } = totals;\n const vatRates: WsfeVatRate[] = [];\n // 10022: totalize by rate before rounding; never round each line.\n for (const [rate, group] of groups) {\n const { id, basisPoints } = RATES[rate];\n const netFromGross = roundHalfEvenRatio(\n group.gross * 10_000n,\n 10_000n + basisPoints\n );\n const base = group.net + netFromGross;\n const tax =\n roundHalfEvenRatio(group.net * basisPoints, 10_000n) +\n group.gross -\n netFromGross;\n if (base === 0n) {\n continue;\n }\n net += base;\n vat += tax;\n vatRates.push({\n id,\n baseAmount: arcaMinorUnitsToNumber(base, \"netAmount\"),\n amount: arcaMinorUnitsToNumber(tax, \"vatAmount\"),\n });\n }\n // 10047: class C has only ImpNeto; 10048: exact header decomposition.\n const computed = net + vat + exempt + untaxed;\n arcaMinorUnitsToNumber(computed, \"totalAmount\");\n const sent =\n input.total === undefined\n ? computed\n : assertArcaMinorUnits(input.total, \"total\");\n const adjustment = sent - computed;\n // 10023: the facade deliberately uses only the absolute cents-per-rate allowance.\n const allowance = BigInt(vatRates.length);\n if (\n adjustment < -allowance ||\n adjustment > allowance ||\n vat + adjustment < 0n\n ) {\n throw new ArcaInputError(\n \"total does not match the computed amount within the VAT allowance.\",\n {\n code: \"ARCA_INPUT_AMOUNT_MISMATCH\",\n field: \"total\",\n expected: `${computed} minor units (at most ${allowance} minor units of VAT adjustment, with non-negative VAT)`,\n }\n );\n }\n return {\n data: {\n totalAmount: arcaMinorUnitsToNumber(sent, \"totalAmount\"),\n netAmount: arcaMinorUnitsToNumber(net, \"netAmount\"),\n vatAmount: arcaMinorUnitsToNumber(vat + adjustment, \"vatAmount\"),\n nonTaxableAmount: arcaMinorUnitsToNumber(untaxed, \"nonTaxableAmount\"),\n exemptAmount: arcaMinorUnitsToNumber(exempt, \"exemptAmount\"),\n taxAmount: 0,\n ...(isVat ? { vatRates } : {}),\n },\n amounts: {\n computedTotal: Number(computed),\n sentTotal: Number(sent),\n vatAdjustment: Number(adjustment),\n },\n };\n}\n\nfunction collectItems(\n items: readonly (VatItem | AmountItem)[],\n isVat: boolean\n) {\n let net = 0n;\n let exempt = 0n;\n let untaxed = 0n;\n const groups = new Map<SupportedVatRate, { net: bigint; gross: bigint }>();\n for (const [index, item] of items.entries()) {\n const path = `items[${index}]`;\n if (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n invalidItem(path, \"an item object\");\n }\n if (!isVat) {\n net += classCAmount(item, path);\n continue;\n }\n const { amount, field, rate } = vatItemAmount(item, path);\n if (rate === \"exempt\") {\n exempt += amount;\n continue;\n }\n if (rate === \"untaxed\") {\n untaxed += amount;\n continue;\n }\n const group = groups.get(rate) ?? { net: 0n, gross: 0n };\n group[field] += amount;\n groups.set(rate, group);\n }\n return { net, exempt, untaxed, groups };\n}\n\nfunction classCAmount(item: VatItem | AmountItem, path: string): bigint {\n if (\"vat\" in item || \"net\" in item || \"gross\" in item) {\n invalidItem(\"items\", \"amount items for a class C voucher\");\n }\n return assertArcaMinorUnits(item.amount as number, `${path}.amount`);\n}\n\nfunction vatItemAmount(item: VatItem | AmountItem, path: string) {\n if (\"amount\" in item || \"net\" in item === \"gross\" in item) {\n invalidItem(\n \"items\",\n \"exactly one of net or gross, and vat, for a class A or B voucher\"\n );\n }\n const field: \"net\" | \"gross\" = \"net\" in item ? \"net\" : \"gross\";\n const amount = assertArcaMinorUnits(\n item[field] as number,\n `${path}.${field}`\n );\n const rate = item.vat;\n if (\n rate !== \"exempt\" &&\n rate !== \"untaxed\" &&\n (typeof rate !== \"number\" || !Object.hasOwn(RATES, rate))\n ) {\n invalidItem(`${path}.vat`, \"0, 2.5, 5, 10.5, 21, 27, exempt, or untaxed\");\n }\n return { amount, field, rate };\n}\n\nfunction invalidItem(field: string, expected: string): never {\n throw new ArcaInputError(`${field} must be ${expected}.`, {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field,\n expected,\n });\n}\n","import { ARCA_CURRENCY_IDS, ARCA_VOUCHER_TYPES } from \"../constants\";\nimport { ArcaInputError } from \"../errors\";\nimport {\n assertArcaMinorUnits,\n calculateVatMinorUnits,\n type SupportedVatRate,\n serializeArcaExchangeRate,\n} from \"../internal/decimal\";\nimport type { WsfeDateInput, WsfeVoucherInput } from \"./wsfe\";\nimport { calculateWsfeAmounts } from \"./wsfe-amounts\";\n\nexport type WsfeBuilderCurrencyInput =\n | {\n currency?: \"ARS\";\n exchangeRate?: never;\n sameCurrencyForeignCancellation?: never;\n }\n | {\n currency: \"USD\";\n exchangeRate: string;\n sameCurrencyForeignCancellation?: false;\n }\n | {\n currency: \"USD\";\n exchangeRate?: never;\n sameCurrencyForeignCancellation: true;\n };\n\nexport type WsfeBuilderVatRate = SupportedVatRate;\n\ntype WsfeInvoiceBuilderBaseInput = {\n salesPoint: number;\n concept: number;\n documentType: number;\n documentNumber: number;\n receiverVatConditionId: number;\n voucherDate: WsfeDateInput;\n serviceStartDate?: WsfeDateInput;\n serviceEndDate?: WsfeDateInput;\n paymentDueDate?: WsfeDateInput;\n};\n\nexport type BuildFacturaBInput = WsfeInvoiceBuilderBaseInput &\n WsfeBuilderCurrencyInput & {\n /** Positive integer currency minor units forming the taxable base. */\n taxableAmount: number;\n vatRate: WsfeBuilderVatRate;\n };\n\nexport type BuildFacturaCInput = WsfeInvoiceBuilderBaseInput &\n WsfeBuilderCurrencyInput & {\n amount: number;\n };\n\n/** Builds a narrow Factura B exact WSFE input from integer currency minor units. */\nexport function buildFacturaB(input: BuildFacturaBInput): WsfeVoucherInput {\n const taxableMinorUnits = assertArcaMinorUnits(\n input.taxableAmount,\n \"taxableAmount\"\n );\n if (taxableMinorUnits === 0n) {\n throw new ArcaInputError(\n \"taxableAmount must be greater than zero for Factura B.\",\n {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field: \"taxableAmount\",\n expected: \"a positive safe integer in currency minor units\",\n }\n );\n }\n\n const vatMinorUnits = calculateVatMinorUnits(\n taxableMinorUnits,\n input.vatRate,\n \"vatRate\"\n );\n if (input.vatRate !== 0 && vatMinorUnits === 0n) {\n throw new ArcaInputError(\n \"taxableAmount is too small to produce VAT at the selected positive vatRate.\",\n {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field: \"taxableAmount\",\n expected:\n \"an amount that rounds to at least one currency minor unit of VAT for a positive vatRate\",\n }\n );\n }\n\n const { data } = calculateWsfeAmounts({\n voucherClass: \"B\",\n items: [{ net: input.taxableAmount, vat: input.vatRate }],\n });\n for (const rate of data.vatRates ?? []) {\n Object.freeze(rate);\n }\n Object.freeze(data.vatRates);\n return Object.freeze({\n ...buildCommonExactInput(input),\n voucherType: ARCA_VOUCHER_TYPES.FACTURA_B,\n ...data,\n });\n}\n\n/** Builds a narrow Factura C exact WSFE input from integer currency minor units. */\nexport function buildFacturaC(input: BuildFacturaCInput): WsfeVoucherInput {\n assertArcaMinorUnits(input.amount, \"amount\");\n const { data } = calculateWsfeAmounts({\n voucherClass: \"C\",\n items: [{ amount: input.amount }],\n });\n return Object.freeze({\n ...buildCommonExactInput(input),\n voucherType: ARCA_VOUCHER_TYPES.FACTURA_C,\n ...data,\n });\n}\n\nfunction buildCommonExactInput(\n input: WsfeInvoiceBuilderBaseInput & WsfeBuilderCurrencyInput\n): Pick<\n WsfeVoucherInput,\n | \"salesPoint\"\n | \"concept\"\n | \"documentType\"\n | \"documentNumber\"\n | \"receiverVatConditionId\"\n | \"voucherDate\"\n | \"currencyId\"\n | \"exchangeRate\"\n | \"sameCurrencyForeignCancellation\"\n | \"serviceStartDate\"\n | \"serviceEndDate\"\n | \"paymentDueDate\"\n> {\n return {\n salesPoint: input.salesPoint,\n concept: input.concept,\n documentType: input.documentType,\n documentNumber: input.documentNumber,\n receiverVatConditionId: input.receiverVatConditionId,\n voucherDate: input.voucherDate,\n ...normalizeBuilderCurrency(input),\n ...(input.serviceStartDate === undefined\n ? {}\n : { serviceStartDate: input.serviceStartDate }),\n ...(input.serviceEndDate === undefined\n ? {}\n : { serviceEndDate: input.serviceEndDate }),\n ...(input.paymentDueDate === undefined\n ? {}\n : { paymentDueDate: input.paymentDueDate }),\n };\n}\n\nfunction normalizeBuilderCurrency(\n input: WsfeBuilderCurrencyInput\n): Pick<\n WsfeVoucherInput,\n \"currencyId\" | \"exchangeRate\" | \"sameCurrencyForeignCancellation\"\n> {\n const unsafeInput = input as {\n currency?: string;\n exchangeRate?: unknown;\n sameCurrencyForeignCancellation?: unknown;\n };\n const currency = unsafeInput.currency ?? \"ARS\";\n\n if (\n unsafeInput.sameCurrencyForeignCancellation !== undefined &&\n typeof unsafeInput.sameCurrencyForeignCancellation !== \"boolean\"\n ) {\n throw new ArcaInputError(\n \"sameCurrencyForeignCancellation must be a boolean when provided.\",\n {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"sameCurrencyForeignCancellation\",\n expected: \"true, false, or omitted\",\n }\n );\n }\n\n if (currency === \"ARS\") {\n if (unsafeInput.exchangeRate !== undefined) {\n throw new ArcaInputError(\n \"exchangeRate must be omitted when currency is ARS.\",\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field: \"exchangeRate\",\n expected: \"omitted when currency is ARS\",\n }\n );\n }\n if (unsafeInput.sameCurrencyForeignCancellation !== undefined) {\n throw new ArcaInputError(\n \"sameCurrencyForeignCancellation applies only when currency is USD.\",\n {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"sameCurrencyForeignCancellation\",\n expected: \"omitted when currency is ARS\",\n }\n );\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.ARS,\n exchangeRate: \"1\",\n };\n }\n\n if (currency !== \"USD\") {\n throw new ArcaInputError(\"currency is not supported by this builder.\", {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"currency\",\n expected: \"ARS or USD\",\n });\n }\n\n if (unsafeInput.sameCurrencyForeignCancellation === true) {\n if (unsafeInput.exchangeRate !== undefined) {\n throw new ArcaInputError(\n \"exchangeRate must be omitted for same-currency foreign cancellation.\",\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field: \"exchangeRate\",\n expected: \"omitted when sameCurrencyForeignCancellation is true\",\n }\n );\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.USD,\n sameCurrencyForeignCancellation: \"S\",\n };\n }\n\n if (typeof unsafeInput.exchangeRate !== \"string\") {\n throw new ArcaInputError(\"exchangeRate is required for USD invoices.\", {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"exchangeRate\",\n expected:\n \"a decimal string unless sameCurrencyForeignCancellation is true\",\n });\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.USD,\n exchangeRate: serializeArcaExchangeRate(\n unsafeInput.exchangeRate,\n \"exchangeRate\"\n ),\n ...(unsafeInput.sameCurrencyForeignCancellation === false\n ? { sameCurrencyForeignCancellation: \"N\" as const }\n : {}),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,IAAM,eAAe;AACrB,IAAM,sBAAsB;AAC5B,IAAM,6BAA6B;AACnC,IAAM,mBAAmB;AAGzB,IAAM,8BAA8B;AAEpC,IAAM,gCAAgC;AAEtC,IAAM,iCAAiC;AAKvC,IAAM,wBAA0D;AAAA,EAC9D,GAAG;AAAA,EACH,KAAK;AAAA,EACL,GAAG;AAAA,EACH,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,SAAS,gCACd,OACA,OACQ;AACR,SAAO,sBAAsB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,SAAS;AAAA,IACT,UAAU;AAAA,EACZ,CAAC;AACH;AAEO,SAAS,oBAAoB,OAAe,OAAuB;AACxE,SAAO,oBAAoB,gCAAgC,OAAO,KAAK,GAAG,CAAC;AAC7E;AAMO,SAAS,wBAAwB,OAAe,OAAuB;AAC5E,QAAM,SAAS,sBAAsB;AAAA,IACnC;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,SAAS;AAAA,IACT,UAAU;AAAA,EACZ,CAAC;AACD,SAAO,oBAAoB,QAAQ,CAAC;AACtC;AAEO,SAAS,0BACd,OACA,OACQ;AACR,QAAM,SACJ,OAAO,UAAU,WACb,4BAA4B,OAAO,KAAK,IACxC,4BAA4B,OAAO,KAAK;AAE9C,MAAI,UAAU,MAAM,SAAS,+BAA+B;AAC1D,6BAAyB,KAAK;AAAA,EAChC;AAEA,SAAO,oBAAoB,QAAQ,GAAG,IAAI;AAC5C;AAEO,SAAS,qBAAqB,OAAe,OAAuB;AACzE,MAAI,EAAE,OAAO,cAAc,KAAK,KAAK,SAAS,IAAI;AAChD,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,OAAO,KAAK;AAC/B,MAAI,aAAa,6BAA6B;AAC5C,UAAM,IAAI,eAAe,GAAG,KAAK,mCAAmC;AAAA,MAClE,MAAM;AAAA,MACN;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,uBACd,YACA,OACQ;AACR,MAAI,aAAa,MAAM,aAAa,6BAA6B;AAC/D,UAAM,IAAI,eAAe,GAAG,KAAK,mCAAmC;AAAA,MAClE,MAAM;AAAA,MACN;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO,OAAO,oBAAoB,YAAY,CAAC,CAAC;AAClD;AAEO,SAAS,uBACd,mBACA,SACA,OACQ;AACR,QAAM,cAAc,sBAAsB,OAAO;AACjD,MAAI,gBAAgB,QAAW;AAC7B,UAAM,IAAI,eAAe,GAAG,KAAK,iCAAiC;AAAA,MAChE,MAAM;AAAA,MACN;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO,mBAAmB,oBAAoB,aAAa,MAAO;AACpE;AAUO,SAAS,mBACd,WACA,aACQ;AACR,MAAI,YAAY,MAAM,eAAe,IAAI;AACvC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,YAAY;AAC7B,QAAM,mBAAoB,YAAY,cAAe;AACrD,MAAI,mBAAmB,aAAa;AAClC,WAAO,WAAW;AAAA,EACpB;AACA,MAAI,mBAAmB,aAAa;AAClC,WAAO;AAAA,EACT;AACA,SAAO,WAAW,OAAO,KAAK,WAAW,WAAW;AACtD;AAEO,SAAS,sBACd,kBACA,oBACA,wBAAwB,GACf;AACT,QAAM,aAAa,eAAe,mBAAmB,kBAAkB;AACvE,MAAI,cAAc,OAAO,KAAK,IAAI,GAAG,qBAAqB,CAAC,GAAG;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,eAAe,kBAAkB;AACxD,SAAO,iBAAiB,MAAM,aAAa,UAAW;AACxD;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMW;AACT,MAAI,EAAE,OAAO,SAAS,KAAK,KAAK,SAAS,IAAI;AAC3C,UAAM,IAAI,eAAe,GAAG,KAAK,YAAY,QAAQ,KAAK;AAAA,MACxD,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,QAAQ;AACvB,QAAM,iBAAiB,KAAK,MAAM,MAAM;AACxC,QAAM,0BAA0B,KAAK;AAAA,IACnC;AAAA,IACA,KAAK,IAAI,MAAM,IAAI,OAAO,UAAU;AAAA,EACtC;AAEA,MAAI,KAAK,IAAI,SAAS,cAAc,IAAI,yBAAyB;AAC/D,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,cAAc,cAAc,GAAG;AACzC,UAAM,IAAI,eAAe,GAAG,KAAK,wCAAwC;AAAA,MACvE,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,OAAO,cAAc;AACxC,MAAI,aAAa,SAAS;AACxB,UAAM,IAAI,eAAe,GAAG,KAAK,kCAAkC;AAAA,MACjE,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,4BAA4B,OAAe,OAAuB;AACzE,MAAI,EAAE,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI;AAC1C,6BAAyB,KAAK;AAAA,EAChC;AAEA,QAAM,SAAS,QAAQ;AACvB,QAAM,iBAAiB,KAAK,MAAM,MAAM;AACxC,QAAM,0BAA0B,KAAK;AAAA,IACnC;AAAA,IACA,KAAK,IAAI,MAAM,IAAI,OAAO,UAAU;AAAA,EACtC;AAEA,MACE,KAAK,IAAI,SAAS,cAAc,IAAI,2BACpC,CAAC,OAAO,cAAc,cAAc,GACpC;AACA,6BAAyB,KAAK;AAAA,EAChC;AAEA,SAAO,OAAO,cAAc;AAC9B;AAEA,SAAS,4BAA4B,OAAe,OAAuB;AACzE,QAAM,QAAQ,MAAM,MAAM,oCAAoC;AAC9D,MAAI,CAAC,OAAO;AACV,6BAAyB,KAAK;AAAA,EAChC;AAEA,QAAM,CAAC,EAAE,aAAa,eAAe,EAAE,IAAI;AAC3C,SACE,OAAO,WAAW,IAAI,6BACtB,OAAO,aAAa,OAAO,GAAG,GAAG,CAAC;AAEtC;AAEA,SAAS,yBAAyB,OAAsB;AACtD,QAAM,IAAI;AAAA,IACR,GAAG,KAAK;AAAA,IACR;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA,UACE;AAAA,IACJ;AAAA,EACF;AACF;AAEA,SAAS,oBACP,OACA,gBACA,oBAAoB,OACZ;AACR,QAAM,QAAQ,OAAO,OAAO,cAAc;AAC1C,QAAM,cAAc,QAAQ;AAC5B,QAAM,gBAAgB,QAAQ,OAAO,SAAS,EAAE,SAAS,gBAAgB,GAAG;AAE5E,MAAI,mBAAmB;AACrB,UAAM,kBAAkB,aAAa,QAAQ,OAAO,EAAE;AACtD,WAAO,gBAAgB,WAAW,IAC9B,YAAY,SAAS,IACrB,GAAG,WAAW,IAAI,eAAe;AAAA,EACvC;AAEA,SAAO,GAAG,WAAW,IAAI,YAAY;AACvC;AAEA,SAAS,eAAe,OAAuB;AAC7C,SAAO,QAAQ,KAAK,CAAC,QAAQ;AAC/B;;;ACqEO,SAAS,kBACd,SACa;AACb,iBAAe,qCACb,WACA,OAIA,OAAgC,CAAC,GACjC,SACA;AACA,UAAM,OAAO,MAAM,QAAQ,KAAK,MAAM,QAAQ;AAAA,MAC5C,kBAAkB,MAAM;AAAA,MACxB,cAAc,MAAM;AAAA,IACtB,CAAC;AACD,UAAM,WAAW,MAAM,QAAQ,KAAK,QAGlC;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,MAC3C,MAAM;AAAA,QACJ,MAAM;AAAA,UACJ,MAAM,oBAAoB,QAAQ,OAAO;AAAA,UACzC,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAED,WAAO,4BAA4B,WAAW,SAAS,MAAM;AAAA,EAC/D;AAEA,WAAS,kCACP,WACA,OAIA,OAAgC,CAAC,GACjC;AACA,WAAO,kCAAkC;AAAA,MACvC,SAAS;AAAA,MACT;AAAA,MACA,cAAc,MAAM;AAAA,MACpB,MAAM,QAAQ,cAAc;AAC1B,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA,EAAE,kBAAkB,MAAM,kBAAkB,aAAa;AAAA,UACzD;AAAA,QACF;AACA,oCAA4B,WAAW,MAAM;AAC7C,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAEA,iBAAe,qBACb,WACA,OAAgC,CAAC,GACjC;AACA,UAAM,WAAW,MAAM,QAAQ,KAAK,QAGlC;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,SAAS,4BAA4B,WAAW,SAAS,MAAM;AACrE,gCAA4B,WAAW,MAAM;AAC7C,WAAO;AAAA,EACT;AAEA,iBAAe,qBAAqB;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKG;AACD,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,IACF;AACA,WAAO,OAAO,OAAO,WAAW,CAAC,IAAI;AAAA,EACvC;AAEA,iBAAe,eACb,WACA,WACA,OAI6B;AAC7B,UAAM,SAAS,MAAM,kCAAkC,WAAW;AAAA,MAChE,kBAAkB,MAAM;AAAA,MACxB,cAAc,MAAM;AAAA,IACtB,CAAC;AACD,WAAO,qBAAqB,QAAQ,SAAS,EAAE,IAAI,mBAAmB;AAAA,EACxE;AAEA,WAAS,MAAM;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAiE;AAC/D,UAAM,kBAAkB,0BAA0B,IAAI;AACtD,WAAO,yBAAyB;AAAA,MAC9B;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,MAAM,OAAO;AAAA,EAClC;AAEA,iBAAe,yBAAyB;AAAA,IACtC;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,GAQG;AACD,UAAM,cAAc,oBAAoB,iBAAiB,aAAa;AAEtE,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA,EAAE,kBAAkB,aAAa;AAAA,QACjC;AAAA,UACE,UAAU;AAAA,YACR,UAAU;AAAA,cACR,SAAS;AAAA,cACT,QAAQ,gBAAgB;AAAA,cACxB,UAAU,gBAAgB;AAAA,YAC5B;AAAA,YACA,UAAU;AAAA,cACR,iBAAiB;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,0BAA0B,QAAQ,aAAa;AAAA,MAC1D;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS,+BAA+B,KAAK;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,WAAS,cAAc;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAMqC;AACnC,WAAO,kCAAkC;AAAA,MACvC,SAAS;AAAA,MACT,WAAW;AAAA,MACX;AAAA,MACA,SAAS,CAAC,wBACR,kBAAkB;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,IACL,CAAC;AAAA,EACH;AAEA,iBAAe,kBAAkB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAMqC;AACnC,UAAM,YAAY;AAClB,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,kBAAkB,aAAa;AAAA,MACjC;AAAA,QACE,eAAe;AAAA,UACb,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,wBAAwB,QAAQ,SAAS;AAExD,QAAI,OAAO,SAAS,KAAK,OAAO,MAAM,CAACA,WAAUA,OAAM,SAAS,KAAK,GAAG;AACtE,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,cAAc,CAAC;AAAA,QACf,KAAK;AAAA,MACP;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,uBAAuB,WAAW,MAAM;AAAA,IAChD;AAEA,UAAM,MAAM,aAAa,OAAO,SAAS;AACzC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,iBAAiB,6CAA6C;AAAA,QACtE,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,SAAS,mBAAmB,GAAG;AAAA,MAC/B,cAAc,CAAC;AAAA,MACf,KAAK;AAAA,IACP;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe,OAAO;AACpB,aAAO,qBAAqB,KAAK;AAAA,IACnC;AAAA,IACA,MAAM,eAAe,EAAE,kBAAkB,aAAa,GAAG;AACvD,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,YACJ,OAAO,WACN;AACH,UAAI,CAAC,WAAW;AACd,eAAO,CAAC;AAAA,MACV;AACA,YAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS;AACjE,aAAO,QAAQ,IAAI,iBAAiB;AAAA,IACtC;AAAA,IACA,gBAAgB,OAAO;AACrB,aAAO,eAAe,uBAAuB,YAAY,KAAK;AAAA,IAChE;AAAA,IACA,iBAAiB,OAAO;AACtB,aAAO,eAAe,sBAAsB,WAAW,KAAK;AAAA,IAC9D;AAAA,IACA,gBAAgB,OAAO;AACrB,aAAO,eAAe,2BAA2B,gBAAgB,KAAK;AAAA,IACxE;AAAA,IACA,MAAM,iBAAiB,EAAE,kBAAkB,aAAa,GAAG;AACzD,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO,qBAAqB,QAAQ,QAAQ,EAAE,IAAI,mBAAmB;AAAA,IACvE;AAAA,IACA,YAAY,OAAO;AACjB,aAAO,eAAe,sBAAsB,WAAW,KAAK;AAAA,IAC9D;AAAA,IACA,YAAY,OAAO;AACjB,aAAO,eAAe,2BAA2B,eAAe,KAAK;AAAA,IACvE;AAAA,IACA,iBAAiB,OAAO;AACtB,aAAO,eAAe,2BAA2B,gBAAgB,KAAK;AAAA,IACxE;AAAA,IACA,MAAM,cAAc,EAAE,kBAAkB,aAAa,GAAG;AACtD,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO,qBAAqB,QAAQ,iBAAiB,EAAE;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,yBAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAAG;AACD,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UACE,GAAI,iBAAiB,SAAY,CAAC,IAAI,EAAE,UAAU,aAAa;AAAA,QACjE;AAAA,MACF;AACA,aAAO,qBAAqB,QAAQ,sBAAsB,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,kBAAkB;AACtB,YAAM,SAAS,MAAM,qBAAqB,SAAS;AACnD,aAAO,oBAAoB,MAAM;AAAA,IACnC;AAAA,IACA,MAAM,aAAa,EAAE,YAAY,kBAAkB,aAAa,GAAG;AACjE,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UACE,OAAO;AAAA,QACT;AAAA,MACF;AACA,YAAM,MACH,OAAO,aAAqD,CAAC;AAChE,aAAO,iBAAiB,GAAG;AAAA,IAC7B;AAAA,IACA,MAAM,eAAe,OAAO;AAC1B,YAAM,SAAS,MAAM,cAAc,KAAK;AACxC,aAAO,OAAO,SAAS,UAAU,OAAO,UAAU;AAAA,IACpD;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oBACP,OACA,eACyB;AACzB,QAAM,OAAgC;AAAA,IACpC,UAAU,MAAM;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,OAAO,MAAM;AAAA,IACb,wBAAwB,MAAM;AAAA,IAC9B,QAAQ,MAAM;AAAA,IACd,UAAU,MAAM;AAAA,EAClB;AAEA,MAAI,MAAM,iBAAiB,QAAW;AACpC,SAAK,WAAW,MAAM;AAAA,EACxB;AAEA,MACE,MAAM,eAAe,SACrB,MAAM,oCAAoC,QAC1C;AACA,SAAK,eAAe,MAAM;AAAA,EAC5B;AAEA,MAAI,MAAM,qBAAqB,QAAW;AACxC,SAAK,eAAe,MAAM;AAAA,EAC5B;AACA,MAAI,MAAM,mBAAmB,QAAW;AACtC,SAAK,eAAe,MAAM;AAAA,EAC5B;AACA,MAAI,MAAM,mBAAmB,QAAW;AACtC,SAAK,aAAa,MAAM;AAAA,EAC1B;AAEA,MAAI,MAAM,oBAAoB;AAC5B,SAAK,YAAY;AAAA,MACf,UAAU,MAAM,mBAAmB,IAAI,CAAC,OAAO;AAAA,QAC7C,MAAM,EAAE;AAAA,QACR,QAAQ,EAAE;AAAA,QACV,KAAK,EAAE;AAAA,QACP,GAAI,EAAE,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM;AAAA,QACjD,GAAI,EAAE,gBAAgB,SAAY,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY;AAAA,MAClE,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,MAAM,kBAAkB;AAC1B,SAAK,cAAc;AAAA,MACjB,UAAU,MAAM,iBAAiB;AAAA,MACjC,UAAU,MAAM,iBAAiB;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,MAAM,OAAO;AACf,SAAK,WAAW;AAAA,MACd,SAAS,MAAM,MAAM,IAAI,CAAC,OAAO;AAAA,QAC/B,IAAI,EAAE;AAAA,QACN,GAAI,EAAE,gBAAgB,SAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY;AAAA,QAC7D,SAAS,EAAE;AAAA,QACX,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,MACb,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,MAAM,UAAU;AAClB,SAAK,MAAM;AAAA,MACT,SAAS,MAAM,SAAS,IAAI,CAAC,OAAO;AAAA,QAClC,IAAI,EAAE;AAAA,QACN,SAAS,EAAE;AAAA,QACX,SAAS,EAAE;AAAA,MACb,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,MAAM,gBAAgB;AACxB,SAAK,aAAa;AAAA,MAChB,UAAU,MAAM,eAAe,IAAI,CAAC,OAAO;AAAA,QACzC,IAAI,EAAE;AAAA,QACN,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ;AAChB,SAAK,cAAc;AAAA,MACjB,WAAW,MAAM,OAAO,IAAI,CAAC,OAAO;AAAA,QAClC,SAAS,EAAE;AAAA,QACX,QAAQ,EAAE;AAAA,QACV,YAAY,EAAE;AAAA,MAChB,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,MAAM,YAAY;AACpB,SAAK,cAAc;AAAA,MACjB,WAAW,MAAM,WAAW,IAAI,CAAC,OAAO;AAAA,QACtC,IAAI,EAAE;AAAA,MACR,EAAE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,0BACd,OAC4B;AAC5B,MAAI,MAAM,2BAA2B,QAAW;AAC9C,UAAM,IAAI,eAAe,uCAAuC;AAAA,MAC9D,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,yBAAyB,0BAA0B,OAAO,YAAY;AAC5E,QAAM,oBAAoB,gCAAgC,KAAK;AAE/D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,aAAa,uBAAuB,aAAa,aAAa;AAAA,IAC9D,GAAI,2BAA2B,SAC3B,CAAC,IACD,EAAE,cAAc,uBAAuB;AAAA,IAC3C,GAAI,qBAAqB,SACrB,CAAC,IACD;AAAA,MACE,kBAAkB;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACJ,GAAI,mBAAmB,SACnB,CAAC,IACD;AAAA,MACE,gBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACJ,GAAI,mBAAmB,SACnB,CAAC,IACD;AAAA,MACE,gBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACJ,GAAI,uBAAuB,SACvB,CAAC,IACD;AAAA,MACE,oBAAoB,mBAAmB,IAAI,CAAC,SAAS,UAAU;AAC7D,cAAM,EAAE,aAAa,uBAAuB,GAAG,eAAe,IAC5D;AAEF,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAI,0BAA0B,SAC1B,CAAC,IACD;AAAA,YACE,aAAa;AAAA,cACX;AAAA,cACA,sBAAsB,KAAK;AAAA,YAC7B;AAAA,UACF;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACJ,GAAI,qBAAqB,SACrB,CAAC,IACD;AAAA,MACE,kBAAkB;AAAA,QAChB,WAAW;AAAA,UACT,iBAAiB;AAAA,UACjB;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,iBAAiB;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACJ,GAAI,UAAU,SACV,CAAC,IACD;AAAA,MACE,OAAO,MAAM,IAAI,CAAC,KAAK,WAAW;AAAA,QAChC,GAAG;AAAA,QACH,YAAY;AAAA,UACV,IAAI;AAAA,UACJ,SAAS,KAAK;AAAA,QAChB;AAAA,QACA,MAAM,wBAAwB,IAAI,MAAM,SAAS,KAAK,QAAQ;AAAA,QAC9D,QAAQ,oBAAoB,IAAI,QAAQ,SAAS,KAAK,UAAU;AAAA,MAClE,EAAE;AAAA,IACJ;AAAA,IACJ,GAAI,aAAa,SACb,CAAC,IACD;AAAA,MACE,UAAU,SAAS,IAAI,CAAC,SAAS,WAAW;AAAA,QAC1C,GAAG;AAAA,QACH,YAAY;AAAA,UACV,QAAQ;AAAA,UACR,YAAY,KAAK;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,UACN,QAAQ;AAAA,UACR,YAAY,KAAK;AAAA,QACnB;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,EACN;AACF;AAEA,SAAS,gCACP,OASA;AACA,QAAM,cAAc;AAAA,IAClB,MAAM;AAAA,IACN;AAAA,EACF;AACA,QAAM,mBAAmB;AAAA,IACvB,MAAM;AAAA,IACN;AAAA,EACF;AACA,QAAM,YAAY;AAAA,IAChB,MAAM;AAAA,IACN;AAAA,EACF;AACA,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN;AAAA,EACF;AACA,QAAM,YAAY;AAAA,IAChB,MAAM;AAAA,IACN;AAAA,EACF;AACA,QAAM,YAAY;AAAA,IAChB,MAAM;AAAA,IACN;AAAA,EACF;AAEA,QAAM,kBACJ,mBAAmB,YAAY,eAAe,YAAY;AAC5D;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,YAAY,CAAC;AACpC,MAAI,YAAY,MAAM,SAAS,WAAW,GAAG;AAC3C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,qBAAqB,SAAS,IAAI,CAAC,SAAS,WAAW;AAAA,MAC3D,YAAY;AAAA,QACV,QAAQ;AAAA,QACR,YAAY,KAAK;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,YAAY,KAAK;AAAA,MACnB;AAAA,IACF,EAAE;AACF,UAAM,mBAAmB,mBAAmB;AAAA,MAC1C,CAAC,KAAK,YAAY,MAAM,QAAQ;AAAA,MAChC;AAAA,IACF;AACA,UAAM,iBAAiB,mBAAmB;AAAA,MACxC,CAAC,KAAK,YAAY,MAAM,QAAQ;AAAA,MAChC;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX;AACA,QAAI,kCAAkC,MAAM,WAAW,GAAG;AACxD;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,SAAS,CAAC;AAC9B,MAAI,YAAY,MAAM,MAAM,WAAW,GAAG;AACxC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,eAAe,MAAM,OAAO,CAAC,KAAK,KAAK,UAAU;AACrD;AAAA,QACE,IAAI;AAAA,QACJ,SAAS,KAAK;AAAA,MAChB;AACA,8BAAwB,IAAI,MAAM,SAAS,KAAK,QAAQ;AACxD,aACE,MACA,gCAAgC,IAAI,QAAQ,SAAS,KAAK,UAAU;AAAA,IAExE,GAAG,EAAE;AAEL;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,oBAAoB,MAAM,aAAa,aAAa;AAAA,IACjE,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA,WAAW,oBAAoB,MAAM,WAAW,WAAW;AAAA,IAC3D,cAAc,oBAAoB,MAAM,cAAc,cAAc;AAAA,IACpE,WAAW,oBAAoB,MAAM,WAAW,WAAW;AAAA,IAC3D,WAAW,oBAAoB,MAAM,WAAW,WAAW;AAAA,EAC7D;AACF;AAEA,SAAS,kCAAkC,aAA8B;AAGvE,SAAO,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,EAAE,SAAS,WAAW;AACnE;AAEA,SAAS,sBACP,QACA,gBACA,OACA,qBACA,wBAAwB,GACxB;AACA,MAAI,CAAC,sBAAsB,QAAQ,gBAAgB,qBAAqB,GAAG;AACzE,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA,UAAU,4BAA4B,mBAAmB;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,0BACP,OAIA,cACoB;AACpB,MAAI,MAAM,eAAe,OAAO;AAC9B,QACE,iBAAiB,UACjB,0BAA0B,cAAc,cAAc,MAAM,KAC5D;AACA,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,QAAW;AAC9B,QAAI,MAAM,oCAAoC,KAAK;AACjD,aAAO;AAAA,IACT;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,SAAO,0BAA0B,cAAc,cAAc;AAC/D;AAEO,SAAS,uBACd,OACA,WACQ;AACR,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI;AAAA,MACR,gBAAgB,SAAS;AAAA,MACzB;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM,KAAK;AACnC,QAAM,YAAY,gBAAgB,MAAM,yBAAyB;AACjE,MAAI,WAAW;AACb,UAAM,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI;AAC7B,4BAAwB,MAAM,OAAO,KAAK,SAAS;AACnD,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,gBAAgB,MAAM,2BAA2B;AAClE,MAAI,UAAU;AACZ,UAAM,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI;AAC7B,4BAAwB,MAAM,OAAO,KAAK,SAAS;AACnD,WAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG;AAAA,EAC9B;AAEA,QAAM,IAAI;AAAA,IACR,gBAAgB,SAAS;AAAA,IACzB;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,SAAS,wBACP,WACA,YACA,UACA,WACA;AACA,QAAM,OAAO,OAAO,SAAS;AAC7B,QAAM,QAAQ,OAAO,UAAU;AAC/B,QAAM,MAAM,OAAO,QAAQ;AAC3B,QAAM,YAAY,IAAI,KAAK,KAAK,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC;AAEzD,MACE,UAAU,eAAe,MAAM,QAC/B,UAAU,YAAY,MAAM,QAAQ,KACpC,UAAU,WAAW,MAAM,KAC3B;AACA,UAAM,IAAI;AAAA,MACR,gBAAgB,SAAS;AAAA,MACzB;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,KAA8B;AACvD,QAAM,SAAS;AACf,SAAO;AAAA,IACL,QAAQ,OAAO,OAAO,OAAO,CAAC;AAAA,IAC9B,GAAI,OAAO,gBAAgB,SACvB,CAAC,IACD,EAAE,cAAc,OAAO,OAAO,WAAW,EAAE;AAAA,IAC/C,GAAI,OAAO,cAAc,SACrB,CAAC,IACD,EAAE,SAAS,OAAO,OAAO,SAAS,EAAE;AAAA,IACxC,GAAI,OAAO,YAAY,SACnB,CAAC,IACD,EAAE,cAAc,OAAO,OAAO,OAAO,EAAE;AAAA,EAC7C;AACF;AAEA,SAAS,oBAAoB,KAAgC;AAC3D,QAAM,SAAS;AACf,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,MAAM,CAAC;AAAA,IACzB,aAAa,OAAO,OAAO,QAAQ,EAAE;AAAA,EACvC;AACF;AAEA,SAAS,oBAAoB,KAAgC;AAC3D,QAAM,SAAS;AACf,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,MAAM,CAAC;AAAA,IACzB,aAAa,OAAO,OAAO,QAAQ,EAAE;AAAA,IACrC,OAAO,OAAO,OAAO,SAAS,CAAC;AAAA,EACjC;AACF;AAEA,SAAS,4BAA4B,KAAwC;AAC3E,QAAM,SAAS;AACf,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,MAAM,CAAC;AAAA,IACzB,aAAa,OAAO,OAAO,QAAQ,EAAE;AAAA,IACrC,cAAc,OAAO,OAAO,aAAa,EAAE;AAAA,EAC7C;AACF;AAEA,SAAS,oBAAoB,KAAgC;AAC3D,QAAM,SAAS;AACf,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,MAAM,EAAE;AAAA,IAC1B,aAAa,OAAO,OAAO,QAAQ,EAAE;AAAA,IACrC,WAAW,OAAO,OAAO,YAAY,EAAE;AAAA,IACvC,SAAS,OAAO,OAAO,YAAY,EAAE;AAAA,EACvC;AACF;AAEA,SAAS,oBAAoB,KAAgD;AAC3E,SAAO;AAAA,IACL,WAAW,OAAO,IAAI,aAAa,EAAE;AAAA,IACrC,UAAU,OAAO,IAAI,YAAY,EAAE;AAAA,IACnC,YAAY,OAAO,IAAI,cAAc,EAAE;AAAA,EACzC;AACF;AAEA,SAAS,iBAAiB,KAA6C;AACrE,SAAO;AAAA,IACL,YAAY,OAAO,IAAI,SAAS,EAAE;AAAA,IAClC,MAAM,OAAO,IAAI,YAAY,CAAC;AAAA,IAC9B,MAAM,OAAO,IAAI,YAAY,EAAE;AAAA,EACjC;AACF;AAEA,SAAS,mBAAmB,KAA+C;AACzE,QAAM,UAA2B;AAAA,IAC/B,eAAe,OAAO,IAAI,aAAa,IAAI,aAAa,CAAC;AAAA,IACzD;AAAA,EACF;AAEA,kBAAgB,SAAS,eAAe,oBAAoB,IAAI,OAAO,CAAC;AACxE,kBAAgB,SAAS,cAAc,oBAAoB,IAAI,MAAM,CAAC;AACtE,kBAAgB,SAAS,eAAe,oBAAoB,IAAI,QAAQ,CAAC;AACzE,kBAAgB,SAAS,WAAW,oBAAoB,IAAI,QAAQ,CAAC;AACrE,kBAAgB,SAAS,gBAAgB,oBAAoB,IAAI,OAAO,CAAC;AACzE,kBAAgB,SAAS,kBAAkB,oBAAoB,IAAI,MAAM,CAAC;AAC1E;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,sBAAsB;AAAA,EAChD;AACA,kBAAgB,SAAS,eAAe,oBAAoB,IAAI,QAAQ,CAAC;AACzE;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,UAAU;AAAA,EACpC;AACA,kBAAgB,SAAS,aAAa,oBAAoB,IAAI,OAAO,CAAC;AACtE,kBAAgB,SAAS,gBAAgB,oBAAoB,IAAI,OAAO,CAAC;AACzE,kBAAgB,SAAS,aAAa,oBAAoB,IAAI,OAAO,CAAC;AACtE,kBAAgB,SAAS,aAAa,oBAAoB,IAAI,MAAM,CAAC;AACrE,kBAAgB,SAAS,cAAc,oBAAoB,IAAI,KAAK,CAAC;AACrE,kBAAgB,SAAS,gBAAgB,oBAAoB,IAAI,QAAQ,CAAC;AAC1E,kBAAgB,SAAS,UAAU,oBAAoB,IAAI,SAAS,CAAC;AACrE;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,mBAAmB,IAAI,GAAG;AAAA,EACpD;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,UAAU,IAAI,SAAS;AAAA,EACjD;AAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,YAAY;AAAA,EACtC;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,YAAY;AAAA,EACtC;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,IAAI,UAAU;AAAA,EACpC;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,qBAAqB,IAAI,KAAK,WAAW,gBAAgB;AAAA,EAC3D;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,qBAAqB,IAAI,UAAU,WAAW,gBAAgB;AAAA,EAChE;AAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA,qBAAqB,IAAI,WAAW,YAAY,CAAC,SAAS;AACxD,YAAM,OAAO,oBAAoB,KAAK,IAAI;AAC1C,YAAM,aAAa,oBAAoB,KAAK,MAAM;AAClD,YAAM,SAAS,oBAAoB,KAAK,GAAG;AAC3C,UACE,SAAS,UACT,eAAe,UACf,WAAW,QACX;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,oBAAoB,KAAK,OAAO,IAChC,EAAE,aAAa,oBAAoB,KAAK,OAAO,EAAmB,IAClE,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGA,SAAS,qBACP,WACA,KACA,KACiB;AACjB,QAAM,SAAS,aAAa,SAAS;AACrC,MAAI,CAAC,UAAU,OAAO,GAAG,MAAM,QAAW;AACxC,WAAO;AAAA,EACT;AACA,QAAM,OAAO,MAAM,QAAQ,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC;AACpE,QAAM,SAAc,CAAC;AACrB,aAAW,SAAS,MAAM;AACxB,UAAM,MAAM,aAAa,KAAK;AAC9B,UAAM,SAAS,MAAM,IAAI,GAAG,IAAI;AAChC,QAAI,WAAW,QAAW;AACxB,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAAS,iBACP,KACyB;AACzB,QAAM,KAAK,oBAAoB,IAAI,EAAE;AACrC,QAAM,aAAa,oBAAoB,IAAI,OAAO;AAClD,QAAM,SAAS,oBAAoB,IAAI,OAAO;AAC9C,MAAI,OAAO,UAAa,eAAe,UAAa,WAAW,QAAW;AACxE,WAAO;AAAA,EACT;AACA,SAAO,EAAE,IAAI,YAAY,OAAO;AAClC;AAEA,SAAS,iBAAiB,KAAmD;AAC3E,QAAM,MAAM,iBAAiB,GAAG;AAChC,QAAM,OAAO,oBAAoB,IAAI,IAAI;AACzC,MAAI,CAAC,OAAO,SAAS,QAAW;AAC9B,WAAO;AAAA,EACT;AACA,QAAM,cAAc,oBAAoB,IAAI,IAAI;AAChD,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,EACrD;AACF;AAEA,SAAS,eACP,kBACA,OACA,MACA;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM,OAAO,SAAS,OAAO,gBAAgB,GAAG,EAAE;AAAA,EACpD;AACF;AAEA,SAAS,4BACP,WACA,UACA;AACA,QAAM,oBAAoB,SAAS,GAAG,SAAS,UAAU;AAGzD,QAAM,SAAU,oBAAoB,GAAG,SAAS,QAAQ,KACtD,SAAS,GAAG,SAAS,QAAQ,KAC7B;AAEF,SAAO;AACT;AAEA,SAAS,4BACP,WACA,QACA;AACA,QAAM,SAAS,wBAAwB,QAAQ,SAAS;AACxD,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,uBAAuB,WAAW,MAAM;AAAA,EAChD;AACF;AAEA,SAAS,4BAA4B,QAAiC;AACpE,QAAM,iBAAiB,OAAO;AAG9B,QAAM,YAAY,gBAAgB;AAElC,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,WAAQ,UAAU,CAAC,KAAiC,CAAC;AAAA,EACvD;AAEA,SAAQ,aAAqD,CAAC;AAChE;AAEA,SAAS,0BACP,QACA,eAC0B;AAC1B,QAAM,YAAY;AAClB,QAAM,SAAS,aAAa,OAAO,SAAS,KAAK,CAAC;AAClD,QAAM,SAAS,4BAA4B,MAAM;AACjD,QAAM,eAAe,oBAAoB,OAAO,SAAS;AACzD,QAAM,eAAe,oBAAoB,OAAO,SAAS;AACzD,QAAM,aAAa,gBAAgB;AACnC,QAAM,cAAc,mBAAmB,cAAc,YAAY;AACjE,QAAM,MAAM,oBAAoB,OAAO,GAAG;AAC1C,QAAM,YAAY,oBAAoB,OAAO,SAAS;AACtD,QAAM,SAAS,wBAAwB,QAAQ,WAAW,QAAQ;AAClE,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,iBAAiB,MAAM,aAAa;AAAA,EACtC;AACA,QAAM,yBAAyB,OAAO;AAAA,IACpC,CAAC,UAAU,MAAM,aAAa;AAAA,EAChC;AACA,QAAM,OAAO;AAAA,IACX,SAAS;AAAA,IACT;AAAA,IACA,SAAS,kBAAkB,cAAc,YAAY;AAAA,IACrD;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP;AACA,QAAM,UAAoC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,4BAA4B,OAAO,GAAG;AACxC,WAAO,kCAAkC,SAAS,wBAAwB;AAAA,EAC5E;AAEA,QAAM,sBAAsB,iCAAiC,QAAQ;AAAA,IACnE,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACD,MACE,uBACA,iBAAiB,UACjB,iBAAiB,OACjB,iBAAiB,OACjB,CAAC,KACD;AACA,WAAO;AAAA,MACL,GAAG,kCAAkC,SAAS,yBAAyB;AAAA,MACvE,gBAAgB,iCAAiC,mBAAmB;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,wBAAwB;AAC1B,WAAO,kCAAkC,SAAS,qBAAqB;AAAA,EACzE;AAEA,MAAI,wBAAwB,OAAO,GAAG;AACpC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,WAAW,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,4BAA4B,OAAO,GAAG;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,IACf;AAAA,EACF;AAEA,MAAI,4BAA4B,OAAO,GAAG;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,wBAAwB,OAAO,IAC3B,2BACA;AAAA,EACN;AACF;AAmBA,SAAS,mBACP,cACA,cACmC;AACnC,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AACA,SAAO,eAAe,WAAW;AACnC;AAEA,SAAS,4BAA4B,SAAmC;AACtE,SAAO;AAAA,IACL,QAAQ,gBACN,QAAQ,gBACR,QAAQ,iBAAiB,QAAQ;AAAA,EACrC;AACF;AAEA,SAAS,wBACP,SAC0E;AAC1E,SAAO;AAAA,IACL,QAAQ,iBAAiB,OACvB,QAAQ,iBAAiB,OACzB,QAAQ,KAAK,OAAO,WAAW,KAC/B,QAAQ,OACR,QAAQ;AAAA,EACZ;AACF;AAEA,SAAS,4BAA4B,SAAmC;AACtE,SACE,QAAQ,iBAAiB,OAAO,QAAQ,iBAAiB,OAAO,CAAC,QAAQ;AAE7E;AAEA,SAAS,4BAA4B,SAAmC;AACtE,SACE,QAAQ,iBAAiB,OACzB,QAAQ,iBAAiB,UACzB,CAAC,QAAQ,OACT,QAAQ,KAAK,OAAO,SAAS,KAC7B,QAAQ,KAAK,OAAO,MAAM,CAAC,UAAU,MAAM,aAAa,UAAU;AAEtE;AAEA,SAAS,wBAAwB,SAAmC;AAClE,UACG,QAAQ,eAAe,OAAO,QAAQ,eAAe,QACtD,QAAQ,QAAQ,GAAG;AAEvB;AAEA,SAAS,kCACP,SACA,QAC8D;AAC9D,QAAM,UACJ;AAAA,IACE,GAAG,QAAQ;AAAA,IACX,MAAM;AAAA,IACN;AAAA,EACF;AACF,kBAAgB,SAAS,UAAU,QAAQ,UAAU;AACrD,kBAAgB,SAAS,eAAe,QAAQ,WAAW;AAC3D,kBAAgB,SAAS,OAAO,QAAQ,GAAG;AAC3C,kBAAgB,SAAS,aAAa,QAAQ,SAAS;AACvD,SAAO;AACT;AAEA,SAAS,kBAAkB,cAAuB,cAAuB;AACvE,QAAM,UAAgD,CAAC;AACvD,kBAAgB,SAAS,UAAU,YAAY;AAC/C,kBAAgB,SAAS,UAAU,YAAY;AAC/C,SAAO;AACT;AAEA,SAAS,+BACP,OAC0B;AAC1B,QAAM,sBAAsB,gCAAgC,OAAO;AAAA,IACjE,SAAS;AAAA,IACT,WAAW;AAAA,EACb,CAAC;AACD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS,CAAC;AAAA,IACV,QAAQ,sBACJ,4BACA,2BAA2B,KAAK;AAAA,IACpC,GAAI,sBACA;AAAA,MACE,gBAAgB,iCAAiC,mBAAmB;AAAA,IACtE,IACA,CAAC;AAAA,IACL,QAAQ,CAAC;AAAA,IACT,cAAc,CAAC;AAAA,EACjB;AACF;AAEA,SAAS,2BACP,OACsC;AACtC,MAAI,iBAAiB,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,8BAA8B;AACjD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,WAAmB,QAA2B;AAC5E,QAAM,sBAAsB,iCAAiC,QAAQ;AAAA,IACnE,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACD,MAAI,qBAAqB;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,CAAC;AAC3B,SAAO,IAAI;AAAA,IACT,aAAa,gBAAgB,UAAU,IAAI;AAAA,IAC3C;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA,GAAI,YAAY,SAAS,SACrB,CAAC,IACD,EAAE,aAAa,WAAW,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,wBACP,QACA,WACA,aACmB;AACnB,QAAM,kBAAkB,aAAa,OAAO,MAAM;AAClD,SAAO,0BAA0B,iBAAiB,GAAG,EAAE,IAAI,CAAC,WAAW;AAAA,IACrE,SAAS;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,IACR,UACE,cAAc,oBACd,wCAAwC,IAAI,MAAM,QAAQ,EAAE,IACxD,mBACA,cAAc,mBACZ,aACA;AAAA,IACR,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,IACvD,SAAS,MAAM;AAAA,IACf,GAAI,gBAAgB,SAAY,CAAC,IAAI,EAAE,YAAY;AAAA,EACrD,EAAE;AACJ;AAEA,SAAS,wBACP,QACA,UACmB;AACnB,QAAM,wBAAwB,aAAa,OAAO,aAAa;AAC/D,SAAO,0BAA0B,uBAAuB,GAAG,EAAE,IAAI,CAAC,WAAW;AAAA,IAC3E,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR;AAAA,IACA,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,IACvD,SAAS,MAAM;AAAA,IACf,aAAa;AAAA,EACf,EAAE;AACJ;AAEA,SAAS,0BAA0B,WAAoB;AACrD,QAAM,UAAU,MAAM,QAAQ,SAAS,IACnC,YACA,YACE,CAAC,SAAS,IACV,CAAC;AAEP,SAAO,QACJ,IAAI,CAAC,UAAU,KAAgC,EAC/C,IAAI,CAAC,UAAU;AACd,UAAM,OAAO,MAAM,QAAQ,MAAM;AACjC,UAAM,UAAU,MAAM,OAAO,MAAM,OAAO;AAC1C,WAAO;AAAA,MACL,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,OAAO,IAAI,EAAE;AAAA,MACnD,SAAS,OAAO,OAAO;AAAA,IACzB;AAAA,EACF,CAAC;AACL;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,MAAM,OAAO,IAAI,MAAM,IAAI,KAAK,MAAM,OAAO,KAAK,MAAM;AACjE;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,SAAO,cAAc;AACvB;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,KAAK,EAAE,KAAK;AACtC,SAAO,cAAc;AACvB;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,MAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,KAAK;AAC/B,SAAO,OAAO,SAAS,UAAU,IAAI,aAAa;AACpD;AAEA,SAAS,gBACP,QACA,KACA,OACA;AACA,MAAI,UAAU,QAAW;AACvB,WAAO,GAAG,IAAI;AAAA,EAChB;AACF;AAEA,SAAS,aAAa,OAAqD;AACzE,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD;AACN;AAEA,IAAM,0CAA0C,oBAAI,IAAI;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,qBACP,QACA,KAC2B;AAC3B,QAAM,aACJ,OAAO,YACL,GAAG;AACP,MAAI,CAAC,YAAY;AACf,WAAO,CAAC;AAAA,EACV;AAEA,UAAQ,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU,GAAG;AAAA,IAC7D,CAAC,UAAU;AAAA,EACb;AACF;;;ACn0DA,IAAM,QAAuE;AAAA,EAC3E,GAAG,EAAE,IAAI,eAAe,OAAO,aAAa,GAAG;AAAA,EAC/C,KAAK,EAAE,IAAI,eAAe,SAAS,aAAa,KAAK;AAAA,EACrD,GAAG,EAAE,IAAI,eAAe,OAAO,aAAa,KAAK;AAAA,EACjD,MAAM,EAAE,IAAI,eAAe,UAAU,aAAa,MAAM;AAAA,EACxD,IAAI,EAAE,IAAI,eAAe,QAAQ,aAAa,MAAM;AAAA,EACpD,IAAI,EAAE,IAAI,eAAe,QAAQ,aAAa,MAAM;AACtD;AAMO,SAAS,qBAAqB,OAGnC;AACA,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM,WAAW,GAAG;AAC3D,gBAAY,SAAS,4BAA4B;AAAA,EACnD;AACA,QAAM,QAAQ,MAAM,iBAAiB,OAAO,MAAM,iBAAiB;AACnE,MAAI,EAAE,SAAS,MAAM,iBAAiB,MAAM;AAC1C,gBAAY,gBAAgB,WAAW;AAAA,EACzC;AACA,QAAM,SAAS,aAAa,MAAM,OAAO,KAAK;AAC9C,MAAI,MAAM,OAAO;AACjB,MAAI,MAAM;AACV,QAAM,EAAE,QAAQ,SAAS,OAAO,IAAI;AACpC,QAAM,WAA0B,CAAC;AAEjC,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAClC,UAAM,EAAE,IAAI,YAAY,IAAI,MAAM,IAAI;AACtC,UAAM,eAAe;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,SAAU;AAAA,IACZ;AACA,UAAM,OAAO,MAAM,MAAM;AACzB,UAAM,MACJ,mBAAmB,MAAM,MAAM,aAAa,MAAO,IACnD,MAAM,QACN;AACF,QAAI,SAAS,IAAI;AACf;AAAA,IACF;AACA,WAAO;AACP,WAAO;AACP,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,YAAY,uBAAuB,MAAM,WAAW;AAAA,MACpD,QAAQ,uBAAuB,KAAK,WAAW;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,MAAM,MAAM,SAAS;AACtC,yBAAuB,UAAU,aAAa;AAC9C,QAAM,OACJ,MAAM,UAAU,SACZ,WACA,qBAAqB,MAAM,OAAO,OAAO;AAC/C,QAAM,aAAa,OAAO;AAE1B,QAAM,YAAY,OAAO,SAAS,MAAM;AACxC,MACE,aAAa,CAAC,aACd,aAAa,aACb,MAAM,aAAa,IACnB;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,GAAG,QAAQ,yBAAyB,SAAS;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,aAAa,uBAAuB,MAAM,aAAa;AAAA,MACvD,WAAW,uBAAuB,KAAK,WAAW;AAAA,MAClD,WAAW,uBAAuB,MAAM,YAAY,WAAW;AAAA,MAC/D,kBAAkB,uBAAuB,SAAS,kBAAkB;AAAA,MACpE,cAAc,uBAAuB,QAAQ,cAAc;AAAA,MAC3D,WAAW;AAAA,MACX,GAAI,QAAQ,EAAE,SAAS,IAAI,CAAC;AAAA,IAC9B;AAAA,IACA,SAAS;AAAA,MACP,eAAe,OAAO,QAAQ;AAAA,MAC9B,WAAW,OAAO,IAAI;AAAA,MACtB,eAAe,OAAO,UAAU;AAAA,IAClC;AAAA,EACF;AACF;AAEA,SAAS,aACP,OACA,OACA;AACA,MAAI,MAAM;AACV,MAAI,SAAS;AACb,MAAI,UAAU;AACd,QAAM,SAAS,oBAAI,IAAsD;AACzE,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,UAAM,OAAO,SAAS,KAAK;AAC3B,QAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GAAG;AACpE,kBAAY,MAAM,gBAAgB;AAAA,IACpC;AACA,QAAI,CAAC,OAAO;AACV,aAAO,aAAa,MAAM,IAAI;AAC9B;AAAA,IACF;AACA,UAAM,EAAE,QAAQ,OAAO,KAAK,IAAI,cAAc,MAAM,IAAI;AACxD,QAAI,SAAS,UAAU;AACrB,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,WAAW;AACtB,iBAAW;AACX;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,IAAI,IAAI,KAAK,EAAE,KAAK,IAAI,OAAO,GAAG;AACvD,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,MAAM,KAAK;AAAA,EACxB;AACA,SAAO,EAAE,KAAK,QAAQ,SAAS,OAAO;AACxC;AAEA,SAAS,aAAa,MAA4B,MAAsB;AACtE,MAAI,SAAS,QAAQ,SAAS,QAAQ,WAAW,MAAM;AACrD,gBAAY,SAAS,oCAAoC;AAAA,EAC3D;AACA,SAAO,qBAAqB,KAAK,QAAkB,GAAG,IAAI,SAAS;AACrE;AAEA,SAAS,cAAc,MAA4B,MAAc;AAC/D,MAAI,YAAY,QAAQ,SAAS,SAAS,WAAW,MAAM;AACzD;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAyB,SAAS,OAAO,QAAQ;AACvD,QAAM,SAAS;AAAA,IACb,KAAK,KAAK;AAAA,IACV,GAAG,IAAI,IAAI,KAAK;AAAA,EAClB;AACA,QAAM,OAAO,KAAK;AAClB,MACE,SAAS,YACT,SAAS,cACR,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO,OAAO,IAAI,IACvD;AACA,gBAAY,GAAG,IAAI,QAAQ,6CAA6C;AAAA,EAC1E;AACA,SAAO,EAAE,QAAQ,OAAO,KAAK;AAC/B;AAEA,SAAS,YAAY,OAAe,UAAyB;AAC3D,QAAM,IAAI,eAAe,GAAG,KAAK,YAAY,QAAQ,KAAK;AAAA,IACxD,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;ACtJO,SAAS,cAAc,OAA6C;AACzE,QAAM,oBAAoB;AAAA,IACxB,MAAM;AAAA,IACN;AAAA,EACF;AACA,MAAI,sBAAsB,IAAI;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EACF;AACA,MAAI,MAAM,YAAY,KAAK,kBAAkB,IAAI;AAC/C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,IAAI,qBAAqB;AAAA,IACpC,cAAc;AAAA,IACd,OAAO,CAAC,EAAE,KAAK,MAAM,eAAe,KAAK,MAAM,QAAQ,CAAC;AAAA,EAC1D,CAAC;AACD,aAAW,QAAQ,KAAK,YAAY,CAAC,GAAG;AACtC,WAAO,OAAO,IAAI;AAAA,EACpB;AACA,SAAO,OAAO,KAAK,QAAQ;AAC3B,SAAO,OAAO,OAAO;AAAA,IACnB,GAAG,sBAAsB,KAAK;AAAA,IAC9B,aAAa,mBAAmB;AAAA,IAChC,GAAG;AAAA,EACL,CAAC;AACH;AAGO,SAAS,cAAc,OAA6C;AACzE,uBAAqB,MAAM,QAAQ,QAAQ;AAC3C,QAAM,EAAE,KAAK,IAAI,qBAAqB;AAAA,IACpC,cAAc;AAAA,IACd,OAAO,CAAC,EAAE,QAAQ,MAAM,OAAO,CAAC;AAAA,EAClC,CAAC;AACD,SAAO,OAAO,OAAO;AAAA,IACnB,GAAG,sBAAsB,KAAK;AAAA,IAC9B,aAAa,mBAAmB;AAAA,IAChC,GAAG;AAAA,EACL,CAAC;AACH;AAEA,SAAS,sBACP,OAeA;AACA,SAAO;AAAA,IACL,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,cAAc,MAAM;AAAA,IACpB,gBAAgB,MAAM;AAAA,IACtB,wBAAwB,MAAM;AAAA,IAC9B,aAAa,MAAM;AAAA,IACnB,GAAG,yBAAyB,KAAK;AAAA,IACjC,GAAI,MAAM,qBAAqB,SAC3B,CAAC,IACD,EAAE,kBAAkB,MAAM,iBAAiB;AAAA,IAC/C,GAAI,MAAM,mBAAmB,SACzB,CAAC,IACD,EAAE,gBAAgB,MAAM,eAAe;AAAA,IAC3C,GAAI,MAAM,mBAAmB,SACzB,CAAC,IACD,EAAE,gBAAgB,MAAM,eAAe;AAAA,EAC7C;AACF;AAEA,SAAS,yBACP,OAIA;AACA,QAAM,cAAc;AAKpB,QAAM,WAAW,YAAY,YAAY;AAEzC,MACE,YAAY,oCAAoC,UAChD,OAAO,YAAY,oCAAoC,WACvD;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,OAAO;AACtB,QAAI,YAAY,iBAAiB,QAAW;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,QAAI,YAAY,oCAAoC,QAAW;AAC7D,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,kBAAkB;AAAA,MAC9B,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,aAAa,OAAO;AACtB,UAAM,IAAI,eAAe,8CAA8C;AAAA,MACrE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,MAAI,YAAY,oCAAoC,MAAM;AACxD,QAAI,YAAY,iBAAiB,QAAW;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,kBAAkB;AAAA,MAC9B,iCAAiC;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,OAAO,YAAY,iBAAiB,UAAU;AAChD,UAAM,IAAI,eAAe,8CAA8C;AAAA,MACrE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UACE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,YAAY,kBAAkB;AAAA,IAC9B,cAAc;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,IACA,GAAI,YAAY,oCAAoC,QAChD,EAAE,iCAAiC,IAAa,IAChD,CAAC;AAAA,EACP;AACF;","names":["issue"]}
@@ -82,21 +82,6 @@ function createArcaAuthenticationEvidence(error) {
82
82
  ...error.providerCode === void 0 ? {} : { providerCode: error.providerCode }
83
83
  };
84
84
  }
85
- function createArcaAuthenticationErrorFromEvidence(evidence, context) {
86
- return new ArcaAuthenticationError(
87
- formatAuthenticationMessage(
88
- context.service,
89
- context.operation,
90
- evidence.reason
91
- ),
92
- {
93
- reason: evidence.reason,
94
- service: context.service,
95
- operation: context.operation,
96
- ...evidence.providerCode === void 0 ? {} : { providerCode: evidence.providerCode }
97
- }
98
- );
99
- }
100
85
  async function executeWithAuthenticationRecovery(options) {
101
86
  const executeAttempt = async (forceRefresh) => {
102
87
  try {
@@ -189,7 +174,6 @@ export {
189
174
  classifyArcaAuthenticationError,
190
175
  classifyArcaAuthenticationIssues,
191
176
  createArcaAuthenticationEvidence,
192
- createArcaAuthenticationErrorFromEvidence,
193
177
  executeWithAuthenticationRecovery
194
178
  };
195
- //# sourceMappingURL=chunk-4QVFXT35.mjs.map
179
+ //# sourceMappingURL=chunk-UDX6HLAU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/authentication.ts"],"sourcesContent":["import {\n ArcaAuthenticationError,\n type ArcaAuthenticationReason,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthenticationEvidence,\n ArcaFiscalIssue,\n} from \"../services/fiscal-evidence\";\nimport type { ArcaServiceName } from \"./types\";\n\ntype AuthenticationContext = {\n service: ArcaServiceName;\n operation: string;\n};\n\ntype AuthenticationCandidate = AuthenticationContext & {\n providerCode?: string | number;\n message?: string;\n cause?: unknown;\n};\n\ntype AuthenticationRecoveryOptions<T> = AuthenticationContext & {\n forceRefresh?: boolean;\n allowRetry?: boolean;\n execute(forceRefresh?: boolean): Promise<T>;\n};\n\nconst WSFE_AUTHENTICATION_CODES: Readonly<\n Record<string, ArcaAuthenticationReason>\n> = {\n \"600\": \"invalid_token\",\n \"601\": \"missing_relationship\",\n};\n\n/** Classifies one safe provider code/message pair without inspecting object graphs. */\nexport function classifyArcaAuthenticationCandidate(\n candidate: AuthenticationCandidate\n): ArcaAuthenticationError | undefined {\n const providerCode = normalizeProviderCode(candidate.providerCode);\n const reason =\n getStructuredAuthenticationReason(candidate.service, providerCode) ??\n getTextAuthenticationReason(candidate.message);\n\n if (!reason) {\n return undefined;\n }\n\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(candidate.service, candidate.operation, reason),\n {\n reason,\n service: candidate.service,\n operation: candidate.operation,\n ...(providerCode === undefined ? {} : { providerCode }),\n ...(candidate.cause === undefined ? {} : { cause: candidate.cause }),\n }\n );\n}\n\n/** Classifies supported public ARCA errors while ignoring arbitrary errors and causes. */\nexport function classifyArcaAuthenticationError(\n error: unknown,\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n if (isArcaAuthenticationError(error)) {\n return error;\n }\n\n if (error instanceof ArcaSoapFaultError) {\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.faultCode,\n message: error.message,\n cause: error,\n });\n }\n\n if (error instanceof ArcaServiceError) {\n const issueError = classifyArcaAuthenticationIssues(\n error.issues ?? [],\n context\n );\n if (issueError) {\n return new ArcaAuthenticationError(issueError.message, {\n reason: issueError.reason,\n service: issueError.service,\n operation: issueError.operation,\n ...(issueError.providerCode === undefined\n ? {}\n : { providerCode: issueError.providerCode }),\n cause: error,\n });\n }\n\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.serviceCode,\n message: error.message,\n cause: error,\n });\n }\n\n return undefined;\n}\n\n/** Classifies structured service issues in provider order. */\nexport function classifyArcaAuthenticationIssues(\n issues: readonly ArcaFiscalIssue[],\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n for (const issue of issues) {\n const authenticationError = classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: issue.code,\n message: issue.message,\n });\n if (authenticationError) {\n return authenticationError;\n }\n }\n return undefined;\n}\n\n/** Converts the public error to safe serializable exact-attempt evidence. */\nexport function createArcaAuthenticationEvidence(\n error: ArcaAuthenticationError\n): ArcaAuthenticationEvidence {\n return {\n code: \"ARCA_AUTHENTICATION_ERROR\",\n reason: error.reason,\n ...(error.providerCode === undefined\n ? {}\n : { providerCode: error.providerCode }),\n };\n}\n\n/** Recreates the throwable contract from safe exact-attempt evidence. */\nexport function createArcaAuthenticationErrorFromEvidence(\n evidence: ArcaAuthenticationEvidence,\n context: AuthenticationContext\n): ArcaAuthenticationError {\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(\n context.service,\n context.operation,\n evidence.reason\n ),\n {\n reason: evidence.reason,\n service: context.service,\n operation: context.operation,\n ...(evidence.providerCode === undefined\n ? {}\n : { providerCode: evidence.providerCode }),\n }\n );\n}\n\n/** Runs one convenience operation and permits one proven-safe forced refresh. */\nexport async function executeWithAuthenticationRecovery<T>(\n options: AuthenticationRecoveryOptions<T>\n): Promise<T> {\n const executeAttempt = async (forceRefresh?: boolean): Promise<T> => {\n try {\n return await options.execute(forceRefresh);\n } catch (error) {\n throw classifyArcaAuthenticationError(error, options) ?? error;\n }\n };\n\n try {\n return await executeAttempt(options.forceRefresh);\n } catch (error) {\n const allowRetry =\n options.allowRetry !== false && options.forceRefresh !== true;\n if (!(allowRetry && isArcaAuthenticationError(error))) {\n throw error;\n }\n return executeAttempt(true);\n }\n}\n\nfunction getStructuredAuthenticationReason(\n service: ArcaServiceName,\n providerCode: string | number | undefined\n): ArcaAuthenticationReason | undefined {\n if (service !== \"wsfe\" || providerCode === undefined) {\n return undefined;\n }\n return WSFE_AUTHENTICATION_CODES[String(providerCode).trim()];\n}\n\nfunction getTextAuthenticationReason(\n message: string | undefined\n): ArcaAuthenticationReason | undefined {\n if (!message) {\n return undefined;\n }\n const normalized = normalizeAuthenticationText(message);\n\n if (\n includesWholePhrase(\n normalized,\n \"no aparecio cuit en lista de relaciones\"\n ) ||\n includesWholePhrase(normalized, \"cuit representada no incluida en token\")\n ) {\n return \"missing_relationship\";\n }\n if (includesWholePhrase(normalized, \"computador no autorizado\")) {\n return \"unauthorized_computer\";\n }\n if (\n includesWholePhrase(normalized, \"validaciondetoken\") ||\n includesWholePhrase(normalized, \"token vencido\") ||\n includesWholePhrase(normalized, \"no se corresponden token y firma\")\n ) {\n return \"invalid_token\";\n }\n if (\n includesWholePhrase(normalized, \"no autorizado a acceder al servicio\") ||\n includesWholePhrase(normalized, \"no autorizado a acceder a los servicios\")\n ) {\n return \"authentication_rejected\";\n }\n return undefined;\n}\n\nfunction normalizeAuthenticationText(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction includesWholePhrase(value: string, phrase: string): boolean {\n let searchFrom = 0;\n while (searchFrom <= value.length - phrase.length) {\n const index = value.indexOf(phrase, searchFrom);\n if (index < 0) {\n return false;\n }\n const before = value[index - 1];\n const after = value[index + phrase.length];\n if (!(isWordCharacter(before) || isWordCharacter(after))) {\n return true;\n }\n searchFrom = index + phrase.length;\n }\n return false;\n}\n\nfunction isWordCharacter(value: string | undefined): boolean {\n return value !== undefined && /[a-z0-9]/.test(value);\n}\n\nfunction normalizeProviderCode(\n providerCode: string | number | undefined\n): string | number | undefined {\n if (typeof providerCode === \"number\") {\n return Number.isFinite(providerCode) ? providerCode : undefined;\n }\n if (typeof providerCode === \"string\") {\n const normalized = providerCode.trim();\n return normalized || undefined;\n }\n return undefined;\n}\n\nfunction formatAuthenticationMessage(\n service: ArcaServiceName,\n operation: string,\n reason: ArcaAuthenticationReason\n): string {\n const descriptions: Record<ArcaAuthenticationReason, string> = {\n invalid_token: \"the token or signature was rejected\",\n unauthorized_computer: \"the certificate or computer is not authorized\",\n missing_relationship: \"the represented taxpayer relationship is missing\",\n authentication_rejected: \"the service denied authenticated access\",\n };\n return `ARCA rejected authentication for ${service}.${operation}: ${descriptions[reason]}.`;\n}\n"],"mappings":";;;;;;;;AA8BA,IAAM,4BAEF;AAAA,EACF,OAAO;AAAA,EACP,OAAO;AACT;AAGO,SAAS,oCACd,WACqC;AACrC,QAAM,eAAe,sBAAsB,UAAU,YAAY;AACjE,QAAM,SACJ,kCAAkC,UAAU,SAAS,YAAY,KACjE,4BAA4B,UAAU,OAAO;AAE/C,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,SAAO,IAAI;AAAA,IACT,4BAA4B,UAAU,SAAS,UAAU,WAAW,MAAM;AAAA,IAC1E;AAAA,MACE;AAAA,MACA,SAAS,UAAU;AAAA,MACnB,WAAW,UAAU;AAAA,MACrB,GAAI,iBAAiB,SAAY,CAAC,IAAI,EAAE,aAAa;AAAA,MACrD,GAAI,UAAU,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,UAAU,MAAM;AAAA,IACpE;AAAA,EACF;AACF;AAGO,SAAS,gCACd,OACA,SACqC;AACrC,MAAI,0BAA0B,KAAK,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,iBAAiB,oBAAoB;AACvC,WAAO,oCAAoC;AAAA,MACzC,GAAG;AAAA,MACH,cAAc,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,MACf,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,MAAI,iBAAiB,kBAAkB;AACrC,UAAM,aAAa;AAAA,MACjB,MAAM,UAAU,CAAC;AAAA,MACjB;AAAA,IACF;AACA,QAAI,YAAY;AACd,aAAO,IAAI,wBAAwB,WAAW,SAAS;AAAA,QACrD,QAAQ,WAAW;AAAA,QACnB,SAAS,WAAW;AAAA,QACpB,WAAW,WAAW;AAAA,QACtB,GAAI,WAAW,iBAAiB,SAC5B,CAAC,IACD,EAAE,cAAc,WAAW,aAAa;AAAA,QAC5C,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO,oCAAoC;AAAA,MACzC,GAAG;AAAA,MACH,cAAc,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,MACf,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAGO,SAAS,iCACd,QACA,SACqC;AACrC,aAAW,SAAS,QAAQ;AAC1B,UAAM,sBAAsB,oCAAoC;AAAA,MAC9D,GAAG;AAAA,MACH,cAAc,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,IACjB,CAAC;AACD,QAAI,qBAAqB;AACvB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,iCACd,OAC4B;AAC5B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,iBAAiB,SACvB,CAAC,IACD,EAAE,cAAc,MAAM,aAAa;AAAA,EACzC;AACF;AAGO,SAAS,0CACd,UACA,SACyB;AACzB,SAAO,IAAI;AAAA,IACT;AAAA,MACE,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,QAAQ,SAAS;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ;AAAA,MACnB,GAAI,SAAS,iBAAiB,SAC1B,CAAC,IACD,EAAE,cAAc,SAAS,aAAa;AAAA,IAC5C;AAAA,EACF;AACF;AAGA,eAAsB,kCACpB,SACY;AACZ,QAAM,iBAAiB,OAAO,iBAAuC;AACnE,QAAI;AACF,aAAO,MAAM,QAAQ,QAAQ,YAAY;AAAA,IAC3C,SAAS,OAAO;AACd,YAAM,gCAAgC,OAAO,OAAO,KAAK;AAAA,IAC3D;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,eAAe,QAAQ,YAAY;AAAA,EAClD,SAAS,OAAO;AACd,UAAM,aACJ,QAAQ,eAAe,SAAS,QAAQ,iBAAiB;AAC3D,QAAI,EAAE,cAAc,0BAA0B,KAAK,IAAI;AACrD,YAAM;AAAA,IACR;AACA,WAAO,eAAe,IAAI;AAAA,EAC5B;AACF;AAEA,SAAS,kCACP,SACA,cACsC;AACtC,MAAI,YAAY,UAAU,iBAAiB,QAAW;AACpD,WAAO;AAAA,EACT;AACA,SAAO,0BAA0B,OAAO,YAAY,EAAE,KAAK,CAAC;AAC9D;AAEA,SAAS,4BACP,SACsC;AACtC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,QAAM,aAAa,4BAA4B,OAAO;AAEtD,MACE;AAAA,IACE;AAAA,IACA;AAAA,EACF,KACA,oBAAoB,YAAY,wCAAwC,GACxE;AACA,WAAO;AAAA,EACT;AACA,MAAI,oBAAoB,YAAY,0BAA0B,GAAG;AAC/D,WAAO;AAAA,EACT;AACA,MACE,oBAAoB,YAAY,mBAAmB,KACnD,oBAAoB,YAAY,eAAe,KAC/C,oBAAoB,YAAY,kCAAkC,GAClE;AACA,WAAO;AAAA,EACT;AACA,MACE,oBAAoB,YAAY,qCAAqC,KACrE,oBAAoB,YAAY,yCAAyC,GACzE;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,4BAA4B,OAAuB;AAC1D,SAAO,MACJ,UAAU,KAAK,EACf,QAAQ,WAAC,kBAAc,IAAE,GAAE,EAAE,EAC7B,YAAY,EACZ,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEA,SAAS,oBAAoB,OAAe,QAAyB;AACnE,MAAI,aAAa;AACjB,SAAO,cAAc,MAAM,SAAS,OAAO,QAAQ;AACjD,UAAM,QAAQ,MAAM,QAAQ,QAAQ,UAAU;AAC9C,QAAI,QAAQ,GAAG;AACb,aAAO;AAAA,IACT;AACA,UAAM,SAAS,MAAM,QAAQ,CAAC;AAC9B,UAAM,QAAQ,MAAM,QAAQ,OAAO,MAAM;AACzC,QAAI,EAAE,gBAAgB,MAAM,KAAK,gBAAgB,KAAK,IAAI;AACxD,aAAO;AAAA,IACT;AACA,iBAAa,QAAQ,OAAO;AAAA,EAC9B;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAoC;AAC3D,SAAO,UAAU,UAAa,WAAW,KAAK,KAAK;AACrD;AAEA,SAAS,sBACP,cAC6B;AAC7B,MAAI,OAAO,iBAAiB,UAAU;AACpC,WAAO,OAAO,SAAS,YAAY,IAAI,eAAe;AAAA,EACxD;AACA,MAAI,OAAO,iBAAiB,UAAU;AACpC,UAAM,aAAa,aAAa,KAAK;AACrC,WAAO,cAAc;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,4BACP,SACA,WACA,QACQ;AACR,QAAM,eAAyD;AAAA,IAC7D,eAAe;AAAA,IACf,uBAAuB;AAAA,IACvB,sBAAsB;AAAA,IACtB,yBAAyB;AAAA,EAC3B;AACA,SAAO,oCAAoC,OAAO,IAAI,SAAS,KAAK,aAAa,MAAM,CAAC;AAC1F;","names":[]}
1
+ {"version":3,"sources":["../src/internal/authentication.ts"],"sourcesContent":["import {\n ArcaAuthenticationError,\n type ArcaAuthenticationReason,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthenticationEvidence,\n ArcaFiscalIssue,\n} from \"../services/fiscal-evidence\";\nimport type { ArcaServiceName } from \"./types\";\n\ntype AuthenticationContext = {\n service: ArcaServiceName;\n operation: string;\n};\n\ntype AuthenticationCandidate = AuthenticationContext & {\n providerCode?: string | number;\n message?: string;\n cause?: unknown;\n};\n\ntype AuthenticationRecoveryOptions<T> = AuthenticationContext & {\n forceRefresh?: boolean;\n allowRetry?: boolean;\n execute(forceRefresh?: boolean): Promise<T>;\n};\n\nconst WSFE_AUTHENTICATION_CODES: Readonly<\n Record<string, ArcaAuthenticationReason>\n> = {\n \"600\": \"invalid_token\",\n \"601\": \"missing_relationship\",\n};\n\n/** Classifies one safe provider code/message pair without inspecting object graphs. */\nexport function classifyArcaAuthenticationCandidate(\n candidate: AuthenticationCandidate\n): ArcaAuthenticationError | undefined {\n const providerCode = normalizeProviderCode(candidate.providerCode);\n const reason =\n getStructuredAuthenticationReason(candidate.service, providerCode) ??\n getTextAuthenticationReason(candidate.message);\n\n if (!reason) {\n return undefined;\n }\n\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(candidate.service, candidate.operation, reason),\n {\n reason,\n service: candidate.service,\n operation: candidate.operation,\n ...(providerCode === undefined ? {} : { providerCode }),\n ...(candidate.cause === undefined ? {} : { cause: candidate.cause }),\n }\n );\n}\n\n/** Classifies supported public ARCA errors while ignoring arbitrary errors and causes. */\nexport function classifyArcaAuthenticationError(\n error: unknown,\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n if (isArcaAuthenticationError(error)) {\n return error;\n }\n\n if (error instanceof ArcaSoapFaultError) {\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.faultCode,\n message: error.message,\n cause: error,\n });\n }\n\n if (error instanceof ArcaServiceError) {\n const issueError = classifyArcaAuthenticationIssues(\n error.issues ?? [],\n context\n );\n if (issueError) {\n return new ArcaAuthenticationError(issueError.message, {\n reason: issueError.reason,\n service: issueError.service,\n operation: issueError.operation,\n ...(issueError.providerCode === undefined\n ? {}\n : { providerCode: issueError.providerCode }),\n cause: error,\n });\n }\n\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.serviceCode,\n message: error.message,\n cause: error,\n });\n }\n\n return undefined;\n}\n\n/** Classifies structured service issues in provider order. */\nexport function classifyArcaAuthenticationIssues(\n issues: readonly ArcaFiscalIssue[],\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n for (const issue of issues) {\n const authenticationError = classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: issue.code,\n message: issue.message,\n });\n if (authenticationError) {\n return authenticationError;\n }\n }\n return undefined;\n}\n\n/** Converts the public error to safe serializable exact-attempt evidence. */\nexport function createArcaAuthenticationEvidence(\n error: ArcaAuthenticationError\n): ArcaAuthenticationEvidence {\n return {\n code: \"ARCA_AUTHENTICATION_ERROR\",\n reason: error.reason,\n ...(error.providerCode === undefined\n ? {}\n : { providerCode: error.providerCode }),\n };\n}\n\n/** Recreates the throwable contract from safe exact-attempt evidence. */\nexport function createArcaAuthenticationErrorFromEvidence(\n evidence: ArcaAuthenticationEvidence,\n context: AuthenticationContext\n): ArcaAuthenticationError {\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(\n context.service,\n context.operation,\n evidence.reason\n ),\n {\n reason: evidence.reason,\n service: context.service,\n operation: context.operation,\n ...(evidence.providerCode === undefined\n ? {}\n : { providerCode: evidence.providerCode }),\n }\n );\n}\n\n/** Runs one convenience operation and permits one proven-safe forced refresh. */\nexport async function executeWithAuthenticationRecovery<T>(\n options: AuthenticationRecoveryOptions<T>\n): Promise<T> {\n const executeAttempt = async (forceRefresh?: boolean): Promise<T> => {\n try {\n return await options.execute(forceRefresh);\n } catch (error) {\n throw classifyArcaAuthenticationError(error, options) ?? error;\n }\n };\n\n try {\n return await executeAttempt(options.forceRefresh);\n } catch (error) {\n const allowRetry =\n options.allowRetry !== false && options.forceRefresh !== true;\n if (!(allowRetry && isArcaAuthenticationError(error))) {\n throw error;\n }\n return executeAttempt(true);\n }\n}\n\nfunction getStructuredAuthenticationReason(\n service: ArcaServiceName,\n providerCode: string | number | undefined\n): ArcaAuthenticationReason | undefined {\n if (service !== \"wsfe\" || providerCode === undefined) {\n return undefined;\n }\n return WSFE_AUTHENTICATION_CODES[String(providerCode).trim()];\n}\n\nfunction getTextAuthenticationReason(\n message: string | undefined\n): ArcaAuthenticationReason | undefined {\n if (!message) {\n return undefined;\n }\n const normalized = normalizeAuthenticationText(message);\n\n if (\n includesWholePhrase(\n normalized,\n \"no aparecio cuit en lista de relaciones\"\n ) ||\n includesWholePhrase(normalized, \"cuit representada no incluida en token\")\n ) {\n return \"missing_relationship\";\n }\n if (includesWholePhrase(normalized, \"computador no autorizado\")) {\n return \"unauthorized_computer\";\n }\n if (\n includesWholePhrase(normalized, \"validaciondetoken\") ||\n includesWholePhrase(normalized, \"token vencido\") ||\n includesWholePhrase(normalized, \"no se corresponden token y firma\")\n ) {\n return \"invalid_token\";\n }\n if (\n includesWholePhrase(normalized, \"no autorizado a acceder al servicio\") ||\n includesWholePhrase(normalized, \"no autorizado a acceder a los servicios\")\n ) {\n return \"authentication_rejected\";\n }\n return undefined;\n}\n\nfunction normalizeAuthenticationText(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction includesWholePhrase(value: string, phrase: string): boolean {\n let searchFrom = 0;\n while (searchFrom <= value.length - phrase.length) {\n const index = value.indexOf(phrase, searchFrom);\n if (index < 0) {\n return false;\n }\n const before = value[index - 1];\n const after = value[index + phrase.length];\n if (!(isWordCharacter(before) || isWordCharacter(after))) {\n return true;\n }\n searchFrom = index + phrase.length;\n }\n return false;\n}\n\nfunction isWordCharacter(value: string | undefined): boolean {\n return value !== undefined && /[a-z0-9]/.test(value);\n}\n\nfunction normalizeProviderCode(\n providerCode: string | number | undefined\n): string | number | undefined {\n if (typeof providerCode === \"number\") {\n return Number.isFinite(providerCode) ? providerCode : undefined;\n }\n if (typeof providerCode === \"string\") {\n const normalized = providerCode.trim();\n return normalized || undefined;\n }\n return undefined;\n}\n\nfunction formatAuthenticationMessage(\n service: ArcaServiceName,\n operation: string,\n reason: ArcaAuthenticationReason\n): string {\n const descriptions: Record<ArcaAuthenticationReason, string> = {\n invalid_token: \"the token or signature was rejected\",\n unauthorized_computer: \"the certificate or computer is not authorized\",\n missing_relationship: \"the represented taxpayer relationship is missing\",\n authentication_rejected: \"the service denied authenticated access\",\n };\n return `ARCA rejected authentication for ${service}.${operation}: ${descriptions[reason]}.`;\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -2,14 +2,14 @@ import { f as ArcaEnvironment, g as ArcaClientOptions, h as ArcaClientConfig, i
2
2
  export { e as ArcaAuthCredentials, d as ArcaAuthOptions, k as ArcaLogLevel, l as ArcaLoggerConfig, m as ArcaPadronServiceName, n as ArcaRepresentedTaxId, A as ArcaServiceName, o as ArcaServiceTarget, c as ArcaWsaaServiceId, p as ArcaWsaaSessionKey } from './types-BiznC1-X.js';
3
3
  import { PadronService } from './padron.js';
4
4
  export { CreatePadronServiceOptions, PadronTaxIdLookupResult, PadronTaxpayerResult, createPadronService } from './padron.js';
5
- import { S as SupportedVatRate, W as WsfeVoucherInput, a as WsfeVoucherInfo, b as WsfeDateInput, c as WsfeService } from './wsfe-DF0jAE2k.js';
6
- export { B as BuildFacturaBInput, d as BuildFacturaCInput, C as CreateWsfeServiceOptions, e as WsfeActivity, f as WsfeActivityType, g as WsfeAssociatedPeriod, h as WsfeAssociatedVoucher, i as WsfeAuthorizationOutcome, j as WsfeAuthorizationResult, k as WsfeAuthorizeVoucherInput, l as WsfeBuilderCurrencyInput, m as WsfeBuilderVatRate, n as WsfeBuyer, o as WsfeCatalogEntry, p as WsfeCurrencyType, q as WsfeOptionalField, r as WsfeQuotation, s as WsfeReceiverVatCondition, t as WsfeSalesPoint, u as WsfeServerStatus, v as WsfeTax, w as WsfeVatRate, x as WsfeVoucherLookupResult, y as buildFacturaB, z as buildFacturaC, A as createWsfeService } from './wsfe-DF0jAE2k.js';
7
5
  import { VoucherClass, ReceiverCondition } from './constants.js';
8
6
  export { ARCA_FINAL_CONSUMER_IDENTIFICATION_THRESHOLD_MINOR_UNITS, ARCA_INVOICE_CLASS_BY_ISSUER, ARCA_ISSUER_CONDITION_IDS, ARCA_RECEIVER_CONDITION_IDS, IssuerCondition } from './constants.js';
9
7
  import { A as ArcaAuthorizationOutcome, a as ArcaFiscalIssue, b as ArcaSafeErrorMetadata } from './fiscal-evidence-DBzakqBE.js';
10
8
  export { c as ArcaAuthenticationError, d as ArcaAuthenticationErrorOptions, e as ArcaAuthenticationEvidence, f as ArcaAuthenticationReason, g as ArcaAuthorizationIndeterminateReason, h as ArcaConfigurationError, i as ArcaError, j as ArcaFiscalResultLevel, k as ArcaFiscalResults, l as ArcaFiscalService, m as ArcaInputError, n as ArcaInputErrorCode, o as ArcaInputErrorOptions, p as ArcaInvalidSoapResponseError, q as ArcaServiceError, r as ArcaSoapFaultError, s as ArcaTransportError, t as ArcaVoucherLookupResult, u as isArcaAuthenticationError, v as toArcaSafeErrorMetadata } from './fiscal-evidence-DBzakqBE.js';
9
+ import { S as SupportedVatRate, W as WsfeVoucherInput, a as WsfeVoucherInfo, b as WsfeDateInput, c as WsfeService } from './wsfe-DDY9E1GJ.js';
10
+ export { B as BuildFacturaBInput, d as BuildFacturaCInput, C as CreateWsfeServiceOptions, e as WsfeActivity, f as WsfeActivityType, g as WsfeAssociatedPeriod, h as WsfeAssociatedVoucher, i as WsfeAuthorizationOutcome, j as WsfeAuthorizeVoucherInput, k as WsfeBuilderCurrencyInput, l as WsfeBuilderVatRate, m as WsfeBuyer, n as WsfeCatalogEntry, o as WsfeCurrencyType, p as WsfeOptionalField, q as WsfeQuotation, r as WsfeReceiverVatCondition, s as WsfeSalesPoint, t as WsfeServerStatus, u as WsfeTax, v as WsfeVatRate, w as WsfeVoucherLookupResult, x as buildFacturaB, y as buildFacturaC, z as createWsfeService } from './wsfe-DDY9E1GJ.js';
11
11
  import { WsmtxcaService } from './wsmtxca.js';
12
- export { CreateWsmtxcaServiceOptions, WsmtxcaAuthorizationOutcome, WsmtxcaAuthorizationResult, WsmtxcaAuthorizeVoucherInput, WsmtxcaLastAuthorizedVoucherResult, WsmtxcaSalesPoint, WsmtxcaSalesPointsResult, WsmtxcaVoucherInfo, WsmtxcaVoucherLookupOutcome, WsmtxcaVoucherLookupResult, createWsmtxcaService } from './wsmtxca.js';
12
+ export { CreateWsmtxcaServiceOptions, WsmtxcaAuthorizationOutcome, WsmtxcaAuthorizeVoucherInput, WsmtxcaLastAuthorizedVoucherResult, WsmtxcaSalesPoint, WsmtxcaSalesPointsResult, WsmtxcaVoucherInfo, WsmtxcaVoucherLookupOutcome, WsmtxcaVoucherLookupResult, createWsmtxcaService } from './wsmtxca.js';
13
13
  import './index-CVGQyyYM.js';
14
14
 
15
15
  type VatRate = SupportedVatRate | "exempt" | "untaxed";
@@ -101,6 +101,16 @@ type IssuedVoucher = VoucherCoordinates & {
101
101
  caeExpiry: string;
102
102
  amounts: IssueAmounts;
103
103
  };
104
+ /**
105
+ * What issue() would send, derived with zero I/O. The voucher number is absent
106
+ * because it is only known when the number is reserved at issuance.
107
+ */
108
+ type IssuePreview = {
109
+ voucherClass: VoucherClass;
110
+ voucherType: number;
111
+ amounts: IssueAmounts;
112
+ request: WsfeVoucherInput;
113
+ };
104
114
  type WithRaw<T, O extends IssueOptions> = T & (true extends NonNullable<O["include"]>["raw"] ? {
105
115
  raw?: Record<string, unknown>;
106
116
  } : unknown);
@@ -186,13 +196,40 @@ type IssueInput = IssueCommon & ({
186
196
  items: readonly AmountItem[];
187
197
  });
188
198
 
199
+ /**
200
+ * The credited lines and, at most, the note's own sales point and date.
201
+ * Class, receiver, currency, concept and service dates come from the original.
202
+ *
203
+ * The mode is explicit: `items` credits the chosen lines, `all: true` credits
204
+ * the whole original. A forgotten field never credits the whole invoice.
205
+ */
206
+ type CreditNoteInput = {
207
+ /** The authorized invoice the note corrects. */
208
+ for: VoucherCoordinates;
209
+ salesPoint?: number;
210
+ date?: WsfeDateInput;
211
+ } & ({
212
+ items: IssueInput["items"];
213
+ total?: number;
214
+ all?: never;
215
+ } | {
216
+ all: true;
217
+ items?: never;
218
+ total?: never;
219
+ });
220
+
189
221
  type VouchersService = {
190
- /** Creates a full credit note associated to an authorized A, B or C invoice. */
191
- cancel<O extends IssueOptions & {
192
- date?: WsfeDateInput;
193
- } = {
222
+ /**
223
+ * Issues a credit note against an authorized A, B or C invoice. The note
224
+ * credits the chosen `items`, or the whole original with `all: true`.
225
+ *
226
+ * Everything except the credited lines, the note's sales point and its date
227
+ * comes from the original: class, receiver, currency, concept and service
228
+ * dates. ARCA has no cancellation; both modes write a real fiscal document.
229
+ */
230
+ issueCreditNote<O extends IssueOptions = {
194
231
  include?: never;
195
- }>(target: VoucherCoordinates, options?: O): Promise<IssueOutcome<O>>;
232
+ }>(input: CreditNoteInput, options?: O): Promise<IssueOutcome<O>>;
196
233
  /**
197
234
  * Configure a store and pass idempotencyKey to recover retries after a crash.
198
235
  *
@@ -203,6 +240,17 @@ type VouchersService = {
203
240
  issue<O extends IssueOptions = {
204
241
  include?: never;
205
242
  }>(input: IssueInput, options?: O): Promise<IssueOutcome<O>>;
243
+ /**
244
+ * Derives what issue() would send for the same input, with no I/O at all:
245
+ * no store, no WSAA, no SOAP and no next-number read.
246
+ *
247
+ * It throws every input error issue() throws before its first call, so a
248
+ * caller that previews and then issues sees no new local error.
249
+ */
250
+ preview(input: IssueInput, options?: PreviewOptions): IssuePreview;
251
+ };
252
+ type PreviewOptions = {
253
+ representedTaxId?: number | string;
206
254
  };
207
255
 
208
256
  /** Immutable, credential-free operational view of an ARCA client configuration. */
@@ -218,8 +266,10 @@ type ArcaClient = {
218
266
  readonly config: ArcaClientConfigView;
219
267
  /** Issues an invoice from business input. Idempotent with a store and key. */
220
268
  issue: VouchersService["issue"];
221
- /** Issues a full credit note against an authorized invoice. */
222
- cancel: VouchersService["cancel"];
269
+ /** Derives what issue() would send for the same input, with no I/O. */
270
+ preview: VouchersService["preview"];
271
+ /** Issues a credit note against an authorized invoice, partial or full. */
272
+ issueCreditNote: VouchersService["issueCreditNote"];
223
273
  wsfe: WsfeService;
224
274
  wsmtxca: WsmtxcaService;
225
275
  padron: PadronService;
@@ -227,7 +277,7 @@ type ArcaClient = {
227
277
  /**
228
278
  * Creates an ARCA client from the given configuration.
229
279
  * Validates the config, wires WSAA authentication and SOAP transport,
230
- * and returns an object with `issue()`, `cancel()` and the `.wsfe`, `.wsmtxca`, and `.padron` service modules.
280
+ * and returns an object with `issue()`, `preview()`, `issueCreditNote()` and the `.wsfe`, `.wsmtxca`, and `.padron` service modules.
231
281
  *
232
282
  * @throws {ArcaConfigurationError} When the config is missing or invalid.
233
283
  */
@@ -296,4 +346,4 @@ declare function createRedisStore(client: RedisClient, options?: {
296
346
 
297
347
  declare function createMemoryWsaaSessionStore(): ArcaWsaaSessionStore;
298
348
 
299
- export { ARCA_ENVIRONMENTS, ARCA_ENV_VARIABLES, type AmountItem, ArcaAuthorizationOutcome, type ArcaClient, ArcaClientOptions as ArcaClientConfig, type ArcaClientConfigView, ArcaEnvironment, ArcaFiscalIssue, ArcaSafeErrorMetadata, ArcaStore, ArcaWsaaSessionStore, type CreateArcaClientConfigFromEnvOptions, type IssueAmounts, type IssueCommon, type IssueInput, type IssueOptions, type IssueOutcome, type IssuedVoucher, PadronService, type Receiver, ReceiverCondition, type VatItem, type VatRate, VoucherClass, type VoucherCoordinates, type VoucherSummary, type VouchersService, WsfeDateInput, type WsfeIdentityMatch, WsfeService, WsfeVoucherInfo, WsfeVoucherInput, WsmtxcaService, assertArcaClientConfig, createArcaClient, createArcaClientConfigFromEnv, createFileStore, createMemoryStore, createMemoryWsaaSessionStore, createPostgresStore, createRedisStore, matchWsfeVoucherIdentity, resolveArcaEnvironment };
349
+ export { ARCA_ENVIRONMENTS, ARCA_ENV_VARIABLES, type AmountItem, ArcaAuthorizationOutcome, type ArcaClient, ArcaClientOptions as ArcaClientConfig, type ArcaClientConfigView, ArcaEnvironment, ArcaFiscalIssue, ArcaSafeErrorMetadata, ArcaStore, ArcaWsaaSessionStore, type CreateArcaClientConfigFromEnvOptions, type CreditNoteInput, type IssueAmounts, type IssueCommon, type IssueInput, type IssueOptions, type IssueOutcome, type IssuePreview, type IssuedVoucher, PadronService, type Receiver, ReceiverCondition, type VatItem, type VatRate, VoucherClass, type VoucherCoordinates, type VoucherSummary, type VouchersService, WsfeDateInput, type WsfeIdentityMatch, WsfeService, WsfeVoucherInfo, WsfeVoucherInput, WsmtxcaService, assertArcaClientConfig, createArcaClient, createArcaClientConfigFromEnv, createFileStore, createMemoryStore, createMemoryWsaaSessionStore, createPostgresStore, createRedisStore, matchWsfeVoucherIdentity, resolveArcaEnvironment };