@fantastic.dev/better-stripe 0.11.0 → 0.13.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.
Files changed (168) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +267 -2
  3. package/dist/client/billing/balanceFunding.d.ts +36 -0
  4. package/dist/client/billing/balanceFunding.d.ts.map +1 -0
  5. package/dist/client/billing/balanceFunding.js +107 -0
  6. package/dist/client/billing/balanceFunding.js.map +1 -0
  7. package/dist/client/billing/invoicePreview.d.ts +28 -0
  8. package/dist/client/billing/invoicePreview.d.ts.map +1 -0
  9. package/dist/client/billing/invoicePreview.js +56 -0
  10. package/dist/client/billing/invoicePreview.js.map +1 -0
  11. package/dist/client/charge-currency-format.d.ts +3 -0
  12. package/dist/client/charge-currency-format.d.ts.map +1 -0
  13. package/dist/client/charge-currency-format.js +22 -0
  14. package/dist/client/charge-currency-format.js.map +1 -0
  15. package/dist/client/charge-currency.d.ts +14 -0
  16. package/dist/client/charge-currency.d.ts.map +1 -0
  17. package/dist/client/charge-currency.js +85 -0
  18. package/dist/client/charge-currency.js.map +1 -0
  19. package/dist/client/costRecovery-invoices.d.ts +38 -0
  20. package/dist/client/costRecovery-invoices.d.ts.map +1 -0
  21. package/dist/client/costRecovery-invoices.js +105 -0
  22. package/dist/client/costRecovery-invoices.js.map +1 -0
  23. package/dist/client/costRecovery.d.ts +156 -0
  24. package/dist/client/costRecovery.d.ts.map +1 -0
  25. package/dist/client/costRecovery.js +117 -0
  26. package/dist/client/costRecovery.js.map +1 -0
  27. package/dist/client/index.d.ts +28 -66
  28. package/dist/client/index.d.ts.map +1 -1
  29. package/dist/client/index.js +25 -0
  30. package/dist/client/index.js.map +1 -1
  31. package/dist/client/products/prices.d.ts +3 -2
  32. package/dist/client/products/prices.d.ts.map +1 -1
  33. package/dist/client/products/prices.js +0 -3
  34. package/dist/client/products/prices.js.map +1 -1
  35. package/dist/client/products/products.d.ts +3 -2
  36. package/dist/client/products/products.d.ts.map +1 -1
  37. package/dist/client/products/products.js +0 -3
  38. package/dist/client/products/products.js.map +1 -1
  39. package/dist/client/settlement/processingCosts.d.ts +56 -0
  40. package/dist/client/settlement/processingCosts.d.ts.map +1 -0
  41. package/dist/client/settlement/processingCosts.js +173 -0
  42. package/dist/client/settlement/processingCosts.js.map +1 -0
  43. package/dist/client/utils/webhookEndpoints.d.ts +1 -1
  44. package/dist/client/utils/webhookEndpoints.d.ts.map +1 -1
  45. package/dist/client/utils/webhookEndpoints.js +1 -0
  46. package/dist/client/utils/webhookEndpoints.js.map +1 -1
  47. package/dist/client/webhooks/processors.d.ts.map +1 -1
  48. package/dist/client/webhooks/processors.js +1 -0
  49. package/dist/client/webhooks/processors.js.map +1 -1
  50. package/dist/component/_generated/component.d.ts +322 -0
  51. package/dist/component/_generated/component.d.ts.map +1 -1
  52. package/dist/component/costRecovery/claims.d.ts +68 -0
  53. package/dist/component/costRecovery/claims.d.ts.map +1 -0
  54. package/dist/component/costRecovery/claims.js +92 -0
  55. package/dist/component/costRecovery/claims.js.map +1 -0
  56. package/dist/component/costRecovery/completion.d.ts +39 -0
  57. package/dist/component/costRecovery/completion.d.ts.map +1 -0
  58. package/dist/component/costRecovery/completion.js +69 -0
  59. package/dist/component/costRecovery/completion.js.map +1 -0
  60. package/dist/component/costRecovery/helpers.d.ts +68 -0
  61. package/dist/component/costRecovery/helpers.d.ts.map +1 -0
  62. package/dist/component/costRecovery/helpers.js +71 -0
  63. package/dist/component/costRecovery/helpers.js.map +1 -0
  64. package/dist/component/costRecovery/mutations.d.ts +210 -0
  65. package/dist/component/costRecovery/mutations.d.ts.map +1 -0
  66. package/dist/component/costRecovery/mutations.js +93 -0
  67. package/dist/component/costRecovery/mutations.js.map +1 -0
  68. package/dist/component/costRecovery/queries.d.ts +108 -0
  69. package/dist/component/costRecovery/queries.d.ts.map +1 -0
  70. package/dist/component/costRecovery/queries.js +73 -0
  71. package/dist/component/costRecovery/queries.js.map +1 -0
  72. package/dist/component/costRecovery/reservations.d.ts +95 -0
  73. package/dist/component/costRecovery/reservations.d.ts.map +1 -0
  74. package/dist/component/costRecovery/reservations.js +134 -0
  75. package/dist/component/costRecovery/reservations.js.map +1 -0
  76. package/dist/component/costRecovery/schema.d.ts +382 -0
  77. package/dist/component/costRecovery/schema.d.ts.map +1 -0
  78. package/dist/component/costRecovery/schema.js +115 -0
  79. package/dist/component/costRecovery/schema.js.map +1 -0
  80. package/dist/component/schema.d.ts +135 -0
  81. package/dist/component/schema.js +5 -0
  82. package/dist/component/schema.js.map +1 -1
  83. package/dist/react/components/PriceCard.d.ts +3 -1
  84. package/dist/react/components/PriceCard.d.ts.map +1 -1
  85. package/dist/react/components/PriceCard.js +2 -2
  86. package/dist/react/components/PriceCard.js.map +1 -1
  87. package/dist/react/index.d.ts +1 -0
  88. package/dist/react/index.d.ts.map +1 -1
  89. package/dist/react/index.js +1 -0
  90. package/dist/react/index.js.map +1 -1
  91. package/dist/react/lib/price-helpers.d.ts +4 -6
  92. package/dist/react/lib/price-helpers.d.ts.map +1 -1
  93. package/dist/react/lib/price-helpers.js +16 -9
  94. package/dist/react/lib/price-helpers.js.map +1 -1
  95. package/dist/react/workflows/Collections.d.ts.map +1 -1
  96. package/dist/react/workflows/Collections.js +2 -1
  97. package/dist/react/workflows/Collections.js.map +1 -1
  98. package/dist/react/workflows/PlanPricingEditor.d.ts +4 -0
  99. package/dist/react/workflows/PlanPricingEditor.d.ts.map +1 -1
  100. package/dist/react/workflows/PlanPricingEditor.js +12 -9
  101. package/dist/react/workflows/PlanPricingEditor.js.map +1 -1
  102. package/dist/react/workflows/Refunds.d.ts +14 -3
  103. package/dist/react/workflows/Refunds.d.ts.map +1 -1
  104. package/dist/react/workflows/Refunds.js +58 -16
  105. package/dist/react/workflows/Refunds.js.map +1 -1
  106. package/dist/react/workflows/index.d.ts +3 -1
  107. package/dist/react/workflows/index.d.ts.map +1 -1
  108. package/dist/react/workflows/index.js +2 -1
  109. package/dist/react/workflows/index.js.map +1 -1
  110. package/dist/react/workflows/refund-preview.d.ts +16 -0
  111. package/dist/react/workflows/refund-preview.d.ts.map +1 -0
  112. package/dist/react/workflows/refund-preview.js +38 -0
  113. package/dist/react/workflows/refund-preview.js.map +1 -0
  114. package/docs/react-workflows.md +167 -1
  115. package/package.json +2 -2
  116. package/src/client/billing/balanceFunding.test.ts +257 -0
  117. package/src/client/billing/balanceFunding.ts +183 -0
  118. package/src/client/billing/balanceFundingTransport.test.ts +89 -0
  119. package/src/client/billing/invoicePreview.test.ts +123 -0
  120. package/src/client/billing/invoicePreview.ts +94 -0
  121. package/src/client/billing/invoicePreviewTransport.test.ts +70 -0
  122. package/src/client/charge-currency-format.ts +29 -0
  123. package/src/client/charge-currency.test.ts +113 -0
  124. package/src/client/charge-currency.ts +119 -0
  125. package/src/client/costRecovery-invoices.test.ts +401 -0
  126. package/src/client/costRecovery-invoices.transport.test.ts +107 -0
  127. package/src/client/costRecovery-invoices.ts +144 -0
  128. package/src/client/costRecovery.test.ts +76 -0
  129. package/src/client/costRecovery.ts +254 -0
  130. package/src/client/index.ts +76 -75
  131. package/src/client/products/prices.ts +13 -11
  132. package/src/client/products/products.ts +10 -10
  133. package/src/client/settlement/processingCosts.test.ts +349 -0
  134. package/src/client/settlement/processingCosts.ts +315 -0
  135. package/src/client/settlement/processingCostsTransport.test.ts +135 -0
  136. package/src/client/utils/webhookEndpoints.test.ts +5 -0
  137. package/src/client/utils/webhookEndpoints.ts +1 -0
  138. package/src/client/webhooks/hooks.test.ts +9 -0
  139. package/src/client/webhooks/payout-canceled.integration.test.ts +192 -0
  140. package/src/client/webhooks/processors.ts +1 -0
  141. package/src/component/_generated/api.ts +12 -0
  142. package/src/component/_generated/component.ts +407 -0
  143. package/src/component/cost-recovery.test.ts +344 -0
  144. package/src/component/costRecovery/claims.ts +119 -0
  145. package/src/component/costRecovery/completion.ts +92 -0
  146. package/src/component/costRecovery/helpers.ts +83 -0
  147. package/src/component/costRecovery/mutations.ts +115 -0
  148. package/src/component/costRecovery/queries.ts +88 -0
  149. package/src/component/costRecovery/reservations.ts +164 -0
  150. package/src/component/costRecovery/schema.ts +135 -0
  151. package/src/component/schema.ts +10 -0
  152. package/src/react/components/PayoutSchedule.render.test.tsx +15 -0
  153. package/src/react/components/PriceCard.render.test.tsx +37 -0
  154. package/src/react/components/PriceCard.tsx +9 -1
  155. package/src/react/index.test.ts +5 -0
  156. package/src/react/index.ts +7 -0
  157. package/src/react/lib/price-helpers.test.ts +15 -2
  158. package/src/react/lib/price-helpers.ts +25 -8
  159. package/src/react/workflows/Billing.test.tsx +1 -1
  160. package/src/react/workflows/Collections.test.tsx +36 -0
  161. package/src/react/workflows/Collections.tsx +3 -1
  162. package/src/react/workflows/PlanPricingEditor.currency.test.tsx +164 -0
  163. package/src/react/workflows/PlanPricingEditor.tsx +26 -10
  164. package/src/react/workflows/Refunds.currency.test.tsx +290 -0
  165. package/src/react/workflows/Refunds.tsx +115 -25
  166. package/src/react/workflows/index.ts +8 -1
  167. package/src/react/workflows/refund-preview.test.ts +65 -0
  168. package/src/react/workflows/refund-preview.ts +56 -0
@@ -0,0 +1,14 @@
1
+ export type ChargeCurrencyMetadata = {
2
+ currency: string;
3
+ apiDecimals: 0 | 2;
4
+ displayDecimals: 0 | 2;
5
+ };
6
+ /** Metadata does not establish account/country/payment-method support. */
7
+ export declare function getChargeCurrencyMetadata(currency: string): ChargeCurrencyMetadata | null;
8
+ /** Parse a nonnegative ASCII decimal exactly. Invalid input is never rounded. */
9
+ export declare function parseChargeAmount(value: string, currency: string): number | null;
10
+ /** Exact ASCII decimal for charge inputs; invalid source units stay unavailable. */
11
+ export declare function chargeAmountToDecimal(amount: number, currency: string): string | null;
12
+ /** Format signed integer charge units without floating-point division. */
13
+ export declare function formatChargeAmount(amount: number, currency: string, locale?: string): string;
14
+ //# sourceMappingURL=charge-currency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charge-currency.d.ts","sourceRoot":"","sources":["../../src/client/charge-currency.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC;CACxB,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GACf,sBAAsB,GAAG,IAAI,CAU/B;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CASf;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAef;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAU,GACf,MAAM,CAiBR"}
@@ -0,0 +1,85 @@
1
+ /** Stripe charge/Price units. These are not payout or Global Payouts rules. */
2
+ import { renderCurrencyUnits } from "./charge-currency-format.js";
3
+ const zeroDecimal = new Set([
4
+ "bif",
5
+ "clp",
6
+ "djf",
7
+ "gnf",
8
+ "jpy",
9
+ "kmf",
10
+ "krw",
11
+ "mga",
12
+ "pyg",
13
+ "rwf",
14
+ "vnd",
15
+ "vuv",
16
+ "xaf",
17
+ "xof",
18
+ "xpf",
19
+ ]);
20
+ const unsupportedPrecision = new Set([
21
+ "bhd",
22
+ "clf",
23
+ "iqd",
24
+ "jod",
25
+ "kwd",
26
+ "lyd",
27
+ "omr",
28
+ "tnd",
29
+ "uyw",
30
+ ]);
31
+ const currencyIntl = Intl;
32
+ const knownCurrencies = new Set((currencyIntl.supportedValuesOf?.("currency") ?? []).map((code) => code.toLowerCase()));
33
+ /** Metadata does not establish account/country/payment-method support. */
34
+ export function getChargeCurrencyMetadata(currency) {
35
+ const code = currency.toLowerCase();
36
+ if (!knownCurrencies.has(code) || unsupportedPrecision.has(code))
37
+ return null;
38
+ if (zeroDecimal.has(code))
39
+ return { currency: code, apiDecimals: 0, displayDecimals: 0 };
40
+ return {
41
+ currency: code,
42
+ apiDecimals: 2,
43
+ displayDecimals: code === "isk" || code === "ugx" ? 0 : 2,
44
+ };
45
+ }
46
+ /** Parse a nonnegative ASCII decimal exactly. Invalid input is never rounded. */
47
+ export function parseChargeAmount(value, currency) {
48
+ const metadata = getChargeCurrencyMetadata(currency);
49
+ if (!metadata || !/^\d+(?:\.\d+)?$/.test(value))
50
+ return null;
51
+ const [whole, fraction = ""] = value.split(".");
52
+ if (fraction.length > metadata.displayDecimals)
53
+ return null;
54
+ const units = BigInt(whole) * 10n ** BigInt(metadata.apiDecimals) +
55
+ BigInt(fraction.padEnd(metadata.apiDecimals, "0") || "0");
56
+ return units <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(units) : null;
57
+ }
58
+ /** Exact ASCII decimal for charge inputs; invalid source units stay unavailable. */
59
+ export function chargeAmountToDecimal(amount, currency) {
60
+ const metadata = getChargeCurrencyMetadata(currency);
61
+ if (!metadata ||
62
+ !Number.isSafeInteger(amount) ||
63
+ amount < 0 ||
64
+ (metadata.displayDecimals === 0 &&
65
+ amount % 10 ** metadata.apiDecimals !== 0))
66
+ return null;
67
+ const units = BigInt(amount);
68
+ const scale = 10n ** BigInt(metadata.apiDecimals);
69
+ const whole = (units / scale).toString();
70
+ if (metadata.displayDecimals === 0)
71
+ return whole;
72
+ return `${whole}.${(units % scale).toString().padStart(metadata.apiDecimals, "0")}`;
73
+ }
74
+ /** Format signed integer charge units without floating-point division. */
75
+ export function formatChargeAmount(amount, currency, locale = "en-US") {
76
+ const metadata = getChargeCurrencyMetadata(currency);
77
+ if (!metadata ||
78
+ !Number.isSafeInteger(amount) ||
79
+ (metadata.displayDecimals === 0 &&
80
+ amount % 10 ** metadata.apiDecimals !== 0)) {
81
+ throw new RangeError("Invalid charge amount or unsupported currency");
82
+ }
83
+ return renderCurrencyUnits(amount, metadata.currency, metadata.apiDecimals, metadata.displayDecimals, locale);
84
+ }
85
+ //# sourceMappingURL=charge-currency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charge-currency.js","sourceRoot":"","sources":["../../src/client/charge-currency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type Stripe from "stripe";
2
+ import type { RecoveryGroup, RecoveryScope } from "./costRecovery.js";
3
+ export type RecoveryInvoiceOptions = RecoveryScope & {
4
+ groupKey: string;
5
+ };
6
+ /** One immutable item per sealed group. Host serializes provider operations per group. */
7
+ export declare function attachRecoveryInvoice(stripe: Stripe, group: RecoveryGroup | null, opts: RecoveryInvoiceOptions, bind: (invoiceItemId: string) => Promise<RecoveryGroup>, create?: boolean): Promise<{
8
+ group: RecoveryGroup;
9
+ invoiceItemId: string;
10
+ invoiceStatus: Stripe.Invoice.Status | null;
11
+ }>;
12
+ /** Refuse ambiguous cash/credit or multi-payment allocations instead of inventing economics. */
13
+ export declare function readInvoiceFunding(stripe: Stripe, group: RecoveryGroup): Promise<{
14
+ status: "not_ready";
15
+ paymentIntentId: string;
16
+ reason: import("./index.js").ProcessingCostNotReadyReason;
17
+ } | {
18
+ status: "ready";
19
+ paymentIntentId: string;
20
+ chargeId: string;
21
+ currency: string;
22
+ gross: number;
23
+ metadata: Record<string, string>;
24
+ processingFee: number;
25
+ refundFeeAdjustment: number;
26
+ disputeFeeAdjustment: number;
27
+ netFees: number;
28
+ refundedPrincipal: number;
29
+ disputedPrincipal: number;
30
+ principalReturned: number;
31
+ refunds: import("./index.js").ProcessingCostRecord[];
32
+ disputes: import("./index.js").ProcessingCostRecord[];
33
+ transactions: import("./index.js").ProcessingCostTransaction[];
34
+ } | {
35
+ status: "not_ready";
36
+ reason: "invoice_funding_allocation_required";
37
+ }>;
38
+ //# sourceMappingURL=costRecovery-invoices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costRecovery-invoices.d.ts","sourceRoot":"","sources":["../../src/client/costRecovery-invoices.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAK1E,0FAA0F;AAC1F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,IAAI,EAAE,sBAAsB,EAC5B,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,EACvD,MAAM,UAAO;;;;GAmFd;AAED,gGAAgG;AAChG,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;YA8B/D,WAAW;YACX,qCAAqC;GAYlD"}
@@ -0,0 +1,105 @@
1
+ import { getProcessingCostContext } from "./settlement/processingCosts.js";
2
+ const marker = "bsRecoveryGroup";
3
+ const id = (value) => typeof value === "string" ? value : value?.id;
4
+ /** One immutable item per sealed group. Host serializes provider operations per group. */
5
+ export async function attachRecoveryInvoice(stripe, group, opts, bind, create = true) {
6
+ if (!group ||
7
+ group.groupKey !== opts.groupKey ||
8
+ group.sourceKind !== "invoice" ||
9
+ group.accountId !== opts.accountId ||
10
+ group.scopeKey !== opts.scopeKey ||
11
+ group.currency !== opts.currency)
12
+ throw new Error("Recovery invoice scope does not match the authorized group.");
13
+ if (group.status === "open" ||
14
+ (create && ["released", "releasing"].includes(group.status)))
15
+ throw new Error("Invoice recovery group must be sealed and active.");
16
+ const invoice = await stripe.invoices.retrieve(group.sourceId);
17
+ if (invoice.id !== group.sourceId ||
18
+ invoice.customer_account !== group.accountId)
19
+ throw new Error("Recovery invoice ownership does not match.");
20
+ if (invoice.currency !== group.currency)
21
+ throw new Error("Recovery invoice currency does not match.");
22
+ let found;
23
+ for await (const item of stripe.invoiceItems.list({
24
+ invoice: invoice.id,
25
+ limit: 100,
26
+ })) {
27
+ if (item.metadata?.[marker] !== group._id)
28
+ continue;
29
+ if (found)
30
+ throw new Error("Duplicate recovery invoice items require reconciliation.");
31
+ if (id(item.invoice) !== invoice.id ||
32
+ item.customer_account !== group.accountId ||
33
+ item.currency !== group.currency ||
34
+ item.amount !== group.amount ||
35
+ item.discountable ||
36
+ (group.invoiceItemId && group.invoiceItemId !== item.id))
37
+ throw new Error("Recovery invoice item economics or identity do not match.");
38
+ found = item;
39
+ }
40
+ if (!found) {
41
+ if (group.invoiceItemId)
42
+ throw new Error("Bound recovery invoice item is missing; reconcile before retrying.");
43
+ if (!create)
44
+ throw new Error("Recovery invoice item is missing; no collection can be confirmed.");
45
+ if (group.status !== "sealed")
46
+ throw new Error("New recovery items require a sealed, uncompleted group.");
47
+ if (invoice.status !== "draft")
48
+ throw new Error("New recovery items require a draft invoice.");
49
+ found = await stripe.invoiceItems.create({
50
+ invoice: invoice.id,
51
+ customer_account: group.accountId,
52
+ currency: group.currency,
53
+ amount: group.amount,
54
+ discountable: false,
55
+ description: "Refund and dispute cost adjustment",
56
+ metadata: { [marker]: group._id },
57
+ }, { idempotencyKey: `better-stripe:recovery:${group._id}` });
58
+ }
59
+ const bound = group.invoiceItemId === found.id ? group : await bind(found.id);
60
+ return {
61
+ group: bound,
62
+ invoiceItemId: found.id,
63
+ invoiceStatus: invoice.status,
64
+ };
65
+ }
66
+ /** Refuse ambiguous cash/credit or multi-payment allocations instead of inventing economics. */
67
+ export async function readInvoiceFunding(stripe, group) {
68
+ const invoice = await stripe.invoices.retrieve(group.sourceId);
69
+ if (invoice.customer_account !== group.accountId ||
70
+ invoice.currency !== group.currency ||
71
+ invoice.status !== "paid")
72
+ throw new Error("Invoice funding ownership, currency or paid state does not match.");
73
+ const payments = [];
74
+ for await (const payment of stripe.invoicePayments.list({
75
+ invoice: group.sourceId,
76
+ limit: 100,
77
+ })) {
78
+ if (id(payment.invoice) !== group.sourceId ||
79
+ payment.currency !== group.currency)
80
+ throw new Error("Invoice payment identity or currency does not match.");
81
+ if (payment.status === "paid")
82
+ payments.push(payment);
83
+ }
84
+ const payment = payments[0];
85
+ if (payments.length !== 1 ||
86
+ payment?.payment.type !== "payment_intent" ||
87
+ !payment.payment.payment_intent ||
88
+ payment.amount_paid !== invoice.amount_paid)
89
+ return {
90
+ status: "not_ready",
91
+ reason: "invoice_funding_allocation_required",
92
+ };
93
+ const cost = await getProcessingCostContext(stripe, {
94
+ paymentIntentId: id(payment.payment.payment_intent),
95
+ });
96
+ if (cost.status === "not_ready")
97
+ return cost;
98
+ if (cost.currency !== group.currency || cost.gross !== invoice.amount_paid)
99
+ return {
100
+ status: "not_ready",
101
+ reason: "invoice_funding_allocation_required",
102
+ };
103
+ return cost;
104
+ }
105
+ //# sourceMappingURL=costRecovery-invoices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costRecovery-invoices.js","sourceRoot":"","sources":["../../src/client/costRecovery-invoices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import type Stripe from "stripe";
2
+ import type { Component, RunCtx } from "./helpers.js";
3
+ export type RecoveryScope = {
4
+ accountId: string;
5
+ scopeKey: string;
6
+ currency: string;
7
+ };
8
+ export type RecoveryObservation = RecoveryScope & {
9
+ claimKey: string;
10
+ sourceChargeId: string;
11
+ sourceGross: number;
12
+ sourceProcessingFee: number;
13
+ amountDue: number;
14
+ revision: number;
15
+ };
16
+ export type RecoveryClaim = RecoveryObservation & {
17
+ _id: string;
18
+ _creationTime: number;
19
+ collectedAmount: number;
20
+ reservedAmount: number;
21
+ outstanding: number;
22
+ sign: "positive" | "negative" | "zero";
23
+ };
24
+ export type RecoveryBalance = RecoveryScope & {
25
+ amountDue: number;
26
+ collectedAmount: number;
27
+ reservedAmount: number;
28
+ outstanding: number;
29
+ activeGroupKey?: string;
30
+ };
31
+ export type RecoveryGroupOptions = RecoveryScope & {
32
+ groupKey: string;
33
+ maxDebit: number;
34
+ maxCredit: number;
35
+ } & ({
36
+ sourceKind: "settlement";
37
+ sourceId: string;
38
+ sourceGross: number;
39
+ sourceProcessingFee: number;
40
+ } | {
41
+ sourceKind: "invoice";
42
+ sourceId: string;
43
+ sourceGross?: number;
44
+ sourceProcessingFee?: number;
45
+ });
46
+ export type RecoveryGroup = RecoveryGroupOptions & {
47
+ _id: string;
48
+ _creationTime: number;
49
+ amount: number;
50
+ pendingOperations: number;
51
+ invoiceItemId?: string;
52
+ invoiceFunding?: {
53
+ sourceChargeId: string;
54
+ sourceGross: number;
55
+ sourceProcessingFee: number;
56
+ };
57
+ status: "open" | "sealed" | "collecting" | "releasing" | "collected" | "released";
58
+ };
59
+ export type RecoveryReservation = {
60
+ _id: string;
61
+ _creationTime: number;
62
+ operationKey: string;
63
+ groupKey: string;
64
+ amount: number;
65
+ limit: number;
66
+ allocations: {
67
+ claimId: string;
68
+ claimKey: string;
69
+ amount: number;
70
+ }[];
71
+ status: "reserved" | "collected" | "released" | "empty";
72
+ };
73
+ /** Host authorizes policy and scope. Provider methods verify invoice outcomes. */
74
+ export declare class CostRecoveryClient {
75
+ private readonly component;
76
+ private readonly provider?;
77
+ constructor(component: Component, provider?: (() => Stripe) | undefined);
78
+ private mutate;
79
+ private query;
80
+ /** Host authorizes the account, scope and invoice group; call from an action. */
81
+ attachInvoice(ctx: RunCtx, opts: RecoveryScope & {
82
+ groupKey: string;
83
+ }): Promise<{
84
+ group: RecoveryGroup;
85
+ invoiceItemId: string;
86
+ invoiceStatus: Stripe.Invoice.Status | null;
87
+ }>;
88
+ /** Re-read Stripe; keep unpaid items reserved. Repeat until isDone after terminal outcomes. */
89
+ reconcileInvoice(ctx: RunCtx, opts: RecoveryScope & {
90
+ groupKey: string;
91
+ releaseUncollectible?: boolean;
92
+ }): Promise<{
93
+ isDone: boolean;
94
+ group: RecoveryGroup;
95
+ invoiceItemId: string;
96
+ invoiceStatus: Stripe.Invoice.Status | null;
97
+ }>;
98
+ /** Reconcile a returned funding charge without changing the original cost claims. */
99
+ rollbackInvoice(ctx: RunCtx, opts: RecoveryScope & {
100
+ groupKey: string;
101
+ revision: number;
102
+ }): Promise<{
103
+ status: "not_ready";
104
+ paymentIntentId: string;
105
+ reason: import("./index.js").ProcessingCostNotReadyReason;
106
+ } | {
107
+ status: "ready";
108
+ claim: RecoveryClaim;
109
+ } | {
110
+ status: "not_ready";
111
+ reason: "invoice_funding_allocation_required";
112
+ }>;
113
+ recordClaim(ctx: RunCtx, opts: RecoveryObservation): Promise<RecoveryClaim>;
114
+ reserve(ctx: RunCtx, opts: RecoveryGroupOptions & {
115
+ operationKey: string;
116
+ limit?: number;
117
+ }): Promise<{
118
+ reservation: RecoveryReservation;
119
+ group: RecoveryGroup;
120
+ }>;
121
+ seal(ctx: RunCtx, opts: {
122
+ groupKey: string;
123
+ }): Promise<RecoveryGroup>;
124
+ finish(ctx: RunCtx, opts: {
125
+ groupKey: string;
126
+ outcome: "collect" | "release";
127
+ limit?: number;
128
+ }): Promise<{
129
+ group: RecoveryGroup;
130
+ isDone: boolean;
131
+ }>;
132
+ rollback(ctx: RunCtx, opts: {
133
+ groupKey: string;
134
+ returnedPrincipal: number;
135
+ revision: number;
136
+ }): Promise<RecoveryClaim>;
137
+ balance(ctx: RunCtx, opts: RecoveryScope): Promise<RecoveryBalance>;
138
+ listClaims(ctx: RunCtx, opts: RecoveryScope & {
139
+ limit?: number;
140
+ cursor?: string | null;
141
+ }): Promise<{
142
+ page: RecoveryClaim[];
143
+ continueCursor: string;
144
+ isDone: boolean;
145
+ }>;
146
+ getClaim(ctx: RunCtx, opts: {
147
+ claimKey: string;
148
+ }): Promise<RecoveryClaim | null>;
149
+ getGroup(ctx: RunCtx, opts: {
150
+ groupKey: string;
151
+ }): Promise<RecoveryGroup | null>;
152
+ getReservation(ctx: RunCtx, opts: {
153
+ operationKey: string;
154
+ }): Promise<RecoveryReservation | null>;
155
+ }
156
+ //# sourceMappingURL=costRecovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costRecovery.d.ts","sourceRoot":"","sources":["../../src/client/costRecovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAKjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtD,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;CACxC,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,CACE;IACE,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,GACD;IACE,UAAU,EAAE,SAAS,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CACJ,CAAC;AACJ,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,MAAM,EACJ,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;CAC7E,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrE,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;CACzD,CAAC;AACF,kFAAkF;AAClF,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAF5B,YACmB,SAAS,EAAE,SAAS,EACpB,QAAQ,CAAC,GAAE,MAAM,MAAM,aAAA,EACtC;YACU,MAAM;YAWN,KAAK;IAUnB,iFAAiF;IAC3E,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;;;;OAc1E;IACD,+FAA+F;IACzF,gBAAgB,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAAE;;;;;OA6B3E;IACD,qFAAqF;IAC/E,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;;;;;gBA+BlD,OAAO;;;;;OAOlB;IACD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,0BAEjD;IACD,OAAO,CACL,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,oBAAoB,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;qBAGtD,mBAAmB;eACzB,aAAa;OAEvB;IACD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,0BAE3C;IACD,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;eAE9C,aAAa;gBAAU,OAAO;OAK3D;IACD,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,0BAGxE;IACD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,4BAEvC;IACD,UAAU,CACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;cAIxD,aAAa,EAAE;wBACL,MAAM;gBACd,OAAO;OAKlB;IACD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,iCAE/C;IACD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,iCAE/C;IACD,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,uCAEzD;CACF"}
@@ -0,0 +1,117 @@
1
+ import { readInvoiceFunding, attachRecoveryInvoice, } from "./costRecovery-invoices.js";
2
+ import { runMutationOrThrow } from "./helpers.js";
3
+ import { componentRef } from "./webhooks/helpers.js";
4
+ /** Host authorizes policy and scope. Provider methods verify invoice outcomes. */
5
+ export class CostRecoveryClient {
6
+ component;
7
+ provider;
8
+ constructor(component, provider) {
9
+ this.component = component;
10
+ this.provider = provider;
11
+ }
12
+ async mutate(ctx, path, args) {
13
+ return (await runMutationOrThrow(ctx, componentRef(this.component, `costRecovery/${path}`), args));
14
+ }
15
+ async query(ctx, path, args) {
16
+ return (await ctx.runQuery(componentRef(this.component, `costRecovery/queries/${path}`), args));
17
+ }
18
+ /** Host authorizes the account, scope and invoice group; call from an action. */
19
+ async attachInvoice(ctx, opts) {
20
+ if (!this.provider)
21
+ throw new Error("Invoice recovery requires a Stripe client.");
22
+ const group = await this.getGroup(ctx, { groupKey: opts.groupKey });
23
+ return attachRecoveryInvoice(this.provider(), group, opts, (invoiceItemId) => this.mutate(ctx, "mutations/bindInvoiceItem", {
24
+ groupKey: opts.groupKey,
25
+ invoiceItemId,
26
+ }));
27
+ }
28
+ /** Re-read Stripe; keep unpaid items reserved. Repeat until isDone after terminal outcomes. */
29
+ async reconcileInvoice(ctx, opts) {
30
+ if (!this.provider)
31
+ throw new Error("Invoice recovery requires a Stripe client.");
32
+ const group = await this.getGroup(ctx, { groupKey: opts.groupKey });
33
+ const receipt = await attachRecoveryInvoice(this.provider(), group, opts, (invoiceItemId) => this.mutate(ctx, "mutations/bindInvoiceItem", {
34
+ groupKey: opts.groupKey,
35
+ invoiceItemId,
36
+ }), false);
37
+ const outcome = receipt.invoiceStatus === "paid"
38
+ ? "collect"
39
+ : receipt.invoiceStatus === "void" ||
40
+ (receipt.invoiceStatus === "uncollectible" &&
41
+ opts.releaseUncollectible === true)
42
+ ? "release"
43
+ : null;
44
+ if (!outcome)
45
+ return { ...receipt, isDone: false };
46
+ return {
47
+ ...receipt,
48
+ ...(await this.finish(ctx, { groupKey: opts.groupKey, outcome })),
49
+ };
50
+ }
51
+ /** Reconcile a returned funding charge without changing the original cost claims. */
52
+ async rollbackInvoice(ctx, opts) {
53
+ if (!this.provider)
54
+ throw new Error("Invoice recovery requires a Stripe client.");
55
+ const stripe = this.provider();
56
+ const group = await this.getGroup(ctx, { groupKey: opts.groupKey });
57
+ const receipt = await attachRecoveryInvoice(stripe, group, opts, (invoiceItemId) => this.mutate(ctx, "mutations/bindInvoiceItem", {
58
+ groupKey: opts.groupKey,
59
+ invoiceItemId,
60
+ }), false);
61
+ if (receipt.group.status !== "collected" ||
62
+ receipt.invoiceStatus !== "paid")
63
+ throw new Error("Invoice rollback requires verified collection.");
64
+ const cost = await readInvoiceFunding(stripe, receipt.group);
65
+ if (cost.status === "not_ready")
66
+ return cost;
67
+ await this.mutate(ctx, "mutations/bindInvoiceFunding", {
68
+ groupKey: opts.groupKey,
69
+ sourceChargeId: cost.chargeId,
70
+ sourceGross: cost.gross,
71
+ sourceProcessingFee: cost.processingFee,
72
+ });
73
+ return {
74
+ status: "ready",
75
+ claim: await this.rollback(ctx, {
76
+ groupKey: opts.groupKey,
77
+ returnedPrincipal: cost.principalReturned,
78
+ revision: opts.revision,
79
+ }),
80
+ };
81
+ }
82
+ recordClaim(ctx, opts) {
83
+ return this.mutate(ctx, "mutations/record", opts);
84
+ }
85
+ reserve(ctx, opts) {
86
+ return this.mutate(ctx, "mutations/reserve", opts);
87
+ }
88
+ seal(ctx, opts) {
89
+ return this.mutate(ctx, "mutations/seal", opts);
90
+ }
91
+ finish(ctx, opts) {
92
+ return this.mutate(ctx, "mutations/finish", opts);
93
+ }
94
+ rollback(ctx, opts) {
95
+ return this.mutate(ctx, "mutations/rollback", opts);
96
+ }
97
+ balance(ctx, opts) {
98
+ return this.query(ctx, "balance", opts);
99
+ }
100
+ listClaims(ctx, opts) {
101
+ const { limit, cursor, ...scope } = opts;
102
+ return this.query(ctx, "listClaims", {
103
+ ...scope,
104
+ paginationOpts: { numItems: limit ?? 25, cursor: cursor ?? null },
105
+ });
106
+ }
107
+ getClaim(ctx, opts) {
108
+ return this.query(ctx, "claim", opts);
109
+ }
110
+ getGroup(ctx, opts) {
111
+ return this.query(ctx, "group", opts);
112
+ }
113
+ getReservation(ctx, opts) {
114
+ return this.query(ctx, "reservation", opts);
115
+ }
116
+ }
117
+ //# sourceMappingURL=costRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costRecovery.js","sourceRoot":"","sources":["../../src/client/costRecovery.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAuErD,kFAAkF;AAClF,MAAM,OAAO,kBAAkB;IAEV,SAAS;IACT,QAAQ;IAF3B,YACmB,SAAoB,EACpB,QAAuB;yBADvB,SAAS;wBACT,QAAQ;IACxB,CAAC;IACI,KAAK,CAAC,MAAM,CAClB,GAAW,EACX,IAAY,EACZ,IAA6B;QAE7B,OAAO,CAAC,MAAM,kBAAkB,CAC9B,GAAG,EACH,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC,EACpD,IAAI,CACL,CAAM,CAAC;IACV,CAAC;IACO,KAAK,CAAC,KAAK,CACjB,GAAW,EACX,IAAY,EACZ,IAA6B;QAE7B,OAAO,CAAC,MAAM,GAAG,CAAC,QAAQ,CACxB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,wBAAwB,IAAI,EAAE,CAAC,EAC5D,IAAI,CACL,CAAM,CAAC;IACV,CAAC;IACD,iFAAiF;IACjF,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,IAA0C;QACzE,IAAI,CAAC,IAAI,CAAC,QAAQ;YAChB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,OAAO,qBAAqB,CAC1B,IAAI,CAAC,QAAQ,EAAE,EACf,KAAK,EACL,IAAI,EACJ,CAAC,aAAa,EAAE,EAAE,CAChB,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,2BAA2B,EAAE;YAC3D,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,aAAa;SACd,CAAC,CACL,CAAC;IACJ,CAAC;IACD,+FAA+F;IAC/F,KAAK,CAAC,gBAAgB,CACpB,GAAW,EACX,IAA0E;QAE1E,IAAI,CAAC,IAAI,CAAC,QAAQ;YAChB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CACzC,IAAI,CAAC,QAAQ,EAAE,EACf,KAAK,EACL,IAAI,EACJ,CAAC,aAAa,EAAE,EAAE,CAChB,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,2BAA2B,EAAE;YAC3D,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,aAAa;SACd,CAAC,EACJ,KAAK,CACN,CAAC;QACF,MAAM,OAAO,GACX,OAAO,CAAC,aAAa,KAAK,MAAM;YAC9B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,aAAa,KAAK,MAAM;gBAC9B,CAAC,OAAO,CAAC,aAAa,KAAK,eAAe;oBACxC,IAAI,CAAC,oBAAoB,KAAK,IAAI,CAAC;gBACvC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC;QACb,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACnD,OAAO;YACL,GAAG,OAAO;YACV,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;SAClE,CAAC;IACJ,CAAC;IACD,qFAAqF;IACrF,KAAK,CAAC,eAAe,CACnB,GAAW,EACX,IAA4D;QAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ;YAChB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,MAAM,qBAAqB,CACzC,MAAM,EACN,KAAK,EACL,IAAI,EACJ,CAAC,aAAa,EAAE,EAAE,CAChB,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,2BAA2B,EAAE;YAC3D,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,aAAa;SACd,CAAC,EACJ,KAAK,CACN,CAAC;QACF,IACE,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW;YACpC,OAAO,CAAC,aAAa,KAAK,MAAM;YAEhC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7D,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,8BAA8B,EAAE;YACpE,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,QAAQ;YAC7B,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,mBAAmB,EAAE,IAAI,CAAC,aAAa;SACxC,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,OAAgB;YACxB,KAAK,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAC9B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC;SACH,CAAC;IACJ,CAAC;IACD,WAAW,CAAC,GAAW,EAAE,IAAyB;QAChD,OAAO,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,CACL,GAAW,EACX,IAAqE;QAErE,OAAO,IAAI,CAAC,MAAM,CAGf,GAAG,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,IAA0B;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,CACJ,GAAW,EACX,IAA0E;QAE1E,OAAO,IAAI,CAAC,MAAM,CAChB,GAAG,EACH,kBAAkB,EAClB,IAAI,CACL,CAAC;IACJ,CAAC;IACD,QAAQ,CACN,GAAW,EACX,IAAuE;QAEvE,OAAO,IAAI,CAAC,MAAM,CAAgB,GAAG,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,GAAW,EAAE,IAAmB;QACtC,OAAO,IAAI,CAAC,KAAK,CAAkB,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,UAAU,CACR,GAAW,EACX,IAAgE;QAEhE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAId,GAAG,EAAE,YAAY,EAAE;YACpB,GAAG,KAAK;YACR,cAAc,EAAE,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE;SAClE,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,GAAW,EAAE,IAA0B;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAuB,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,QAAQ,CAAC,GAAW,EAAE,IAA0B;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAuB,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,cAAc,CAAC,GAAW,EAAE,IAA8B;QACxD,OAAO,IAAI,CAAC,KAAK,CAA6B,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IAC1E,CAAC;CACF"}