@openrails/billing-ui 0.249.0 → 0.250.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 (148) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +13 -13
  3. package/dist/account/account-billing.d.ts +2 -2
  4. package/dist/account/cancel-dialog.d.ts +2 -2
  5. package/dist/account/change-card-dialog.d.ts +2 -2
  6. package/dist/account/payment-history.d.ts +2 -2
  7. package/dist/account/payment-methods-panel.d.ts +2 -2
  8. package/dist/account/section.d.ts +2 -2
  9. package/dist/account/subscriptions-panel.d.ts +2 -2
  10. package/dist/admin/context.d.ts +2 -2
  11. package/dist/admin/lib/queries.d.ts +1 -1
  12. package/dist/admin/messages.d.ts +3 -3
  13. package/dist/admin/pages/catalog/psp-links.d.ts +1 -1
  14. package/dist/admin/theme.d.ts +2 -2
  15. package/dist/admin/types.d.ts +2 -2
  16. package/dist/{admin-attempts-lAoW-Urd.js → admin-attempts-DxRHTODq.js} +8 -8
  17. package/dist/{admin-attempts-lAoW-Urd.js.map → admin-attempts-DxRHTODq.js.map} +1 -1
  18. package/dist/{admin-auth-DQGHtt0j.js → admin-auth-CiuZ-Hlm.js} +2 -2
  19. package/dist/{admin-auth-DQGHtt0j.js.map → admin-auth-CiuZ-Hlm.js.map} +1 -1
  20. package/dist/{admin-badge-DR5-1qd8.js → admin-badge-VCGbnfiN.js} +2 -2
  21. package/dist/{admin-badge-DR5-1qd8.js.map → admin-badge-VCGbnfiN.js.map} +1 -1
  22. package/dist/{admin-button-CTL3DgOt.js → admin-button-Oip73Plq.js} +2 -2
  23. package/dist/{admin-button-CTL3DgOt.js.map → admin-button-Oip73Plq.js.map} +1 -1
  24. package/dist/{admin-capabilities-BuigAgtm.js → admin-capabilities-BGv7oG8v.js} +2 -2
  25. package/dist/{admin-capabilities-BuigAgtm.js.map → admin-capabilities-BGv7oG8v.js.map} +1 -1
  26. package/dist/{admin-card-bzAks3-3.js → admin-card-DGbi6ZHZ.js} +2 -2
  27. package/dist/{admin-card-bzAks3-3.js.map → admin-card-DGbi6ZHZ.js.map} +1 -1
  28. package/dist/{admin-catalog-CK6CM9I2.js → admin-catalog-3pPEAuDY.js} +19 -19
  29. package/dist/{admin-catalog-CK6CM9I2.js.map → admin-catalog-3pPEAuDY.js.map} +1 -1
  30. package/dist/{admin-customers-D8u5gq3M.js → admin-customers-cnKMEV4q.js} +6 -6
  31. package/dist/{admin-customers-D8u5gq3M.js.map → admin-customers-cnKMEV4q.js.map} +1 -1
  32. package/dist/{admin-dashboard-DqqFjOzq.js → admin-dashboard-DfSsUyo-.js} +14 -14
  33. package/dist/{admin-dashboard-DqqFjOzq.js.map → admin-dashboard-DfSsUyo-.js.map} +1 -1
  34. package/dist/{admin-data-table-qfXLOFmN.js → admin-data-table-CgeWv__T.js} +6 -6
  35. package/dist/{admin-data-table-qfXLOFmN.js.map → admin-data-table-CgeWv__T.js.map} +1 -1
  36. package/dist/{admin-detail-X82kR2f7.js → admin-detail-BATuJjVs.js} +12 -12
  37. package/dist/{admin-detail-X82kR2f7.js.map → admin-detail-BATuJjVs.js.map} +1 -1
  38. package/dist/{admin-detail-DUAJQg8G.js → admin-detail-Cq59e14B.js} +15 -15
  39. package/dist/{admin-detail-DUAJQg8G.js.map → admin-detail-Cq59e14B.js.map} +1 -1
  40. package/dist/{admin-detail-BHe51ma9.js → admin-detail-DG-YaHhS.js} +11 -11
  41. package/dist/{admin-detail-BHe51ma9.js.map → admin-detail-DG-YaHhS.js.map} +1 -1
  42. package/dist/{admin-detail-CGOyqs7s.js → admin-detail-Dc7rU4mM.js} +15 -15
  43. package/dist/{admin-detail-CGOyqs7s.js.map → admin-detail-Dc7rU4mM.js.map} +1 -1
  44. package/dist/{admin-dialog-BjuKI5Hp.js → admin-dialog-Ffx95AIT.js} +3 -3
  45. package/dist/{admin-dialog-BjuKI5Hp.js.map → admin-dialog-Ffx95AIT.js.map} +1 -1
  46. package/dist/{admin-dom-uMmZzRvU.js → admin-dom-lnNSQ7ke.js} +4 -4
  47. package/dist/{admin-dom-uMmZzRvU.js.map → admin-dom-lnNSQ7ke.js.map} +1 -1
  48. package/dist/{admin-dropdown-menu-BW1D_h6s.js → admin-dropdown-menu-CCiW4-oz.js} +2 -2
  49. package/dist/{admin-dropdown-menu-BW1D_h6s.js.map → admin-dropdown-menu-CCiW4-oz.js.map} +1 -1
  50. package/dist/{admin-fact-card-DO_fHosg.js → admin-fact-card-D6mZgxpN.js} +2 -2
  51. package/dist/{admin-fact-card-DO_fHosg.js.map → admin-fact-card-D6mZgxpN.js.map} +1 -1
  52. package/dist/{admin-health-B4jN2LwR.js → admin-health-CvJX9prw.js} +13 -13
  53. package/dist/{admin-health-B4jN2LwR.js.map → admin-health-CvJX9prw.js.map} +1 -1
  54. package/dist/{admin-input-CcfQfJFN.js → admin-input-DO5lvCLL.js} +2 -2
  55. package/dist/{admin-input-CcfQfJFN.js.map → admin-input-DO5lvCLL.js.map} +1 -1
  56. package/dist/{admin-label-BiEN5cjb.js → admin-label-BzJpr3lg.js} +2 -2
  57. package/dist/{admin-label-BiEN5cjb.js.map → admin-label-BzJpr3lg.js.map} +1 -1
  58. package/dist/{admin-linked-table-row-BsaUruCN.js → admin-linked-table-row-5vFb6rXY.js} +4 -4
  59. package/dist/{admin-linked-table-row-BsaUruCN.js.map → admin-linked-table-row-5vFb6rXY.js.map} +1 -1
  60. package/dist/{admin-metering-COFcSPQy.js → admin-metering-BksTFRRP.js} +14 -14
  61. package/dist/{admin-metering-COFcSPQy.js.map → admin-metering-BksTFRRP.js.map} +1 -1
  62. package/dist/{admin-ops-B3mcr76u.js → admin-ops-Ch2-BmUp.js} +11 -11
  63. package/dist/{admin-ops-B3mcr76u.js.map → admin-ops-Ch2-BmUp.js.map} +1 -1
  64. package/dist/{admin-orders-dxC99Idl.js → admin-orders-8XzHf7b-.js} +8 -8
  65. package/dist/{admin-orders-dxC99Idl.js.map → admin-orders-8XzHf7b-.js.map} +1 -1
  66. package/dist/{admin-payments-Bs7HSfP0.js → admin-payments-pNLNIU0X.js} +9 -9
  67. package/dist/{admin-payments-Bs7HSfP0.js.map → admin-payments-pNLNIU0X.js.map} +1 -1
  68. package/dist/{admin-price-detail-DRquxpA9.js → admin-price-detail-BeGDPxKX.js} +11 -11
  69. package/dist/admin-price-detail-BeGDPxKX.js.map +1 -0
  70. package/dist/{admin-price-wizard-CI7K-2Nz.js → admin-price-wizard-ferZSTfO.js} +7 -7
  71. package/dist/{admin-price-wizard-CI7K-2Nz.js.map → admin-price-wizard-ferZSTfO.js.map} +1 -1
  72. package/dist/{admin-range-picker-Dr2M1EZr.js → admin-range-picker-DaIvC1oC.js} +5 -5
  73. package/dist/{admin-range-picker-Dr2M1EZr.js.map → admin-range-picker-DaIvC1oC.js.map} +1 -1
  74. package/dist/{admin-reports-CywKLiSA.js → admin-reports-CA-cnNur.js} +8 -8
  75. package/dist/{admin-reports-CywKLiSA.js.map → admin-reports-CA-cnNur.js.map} +1 -1
  76. package/dist/{admin-select-DBgprVW6.js → admin-select-CUXvh6j1.js} +2 -2
  77. package/dist/{admin-select-DBgprVW6.js.map → admin-select-CUXvh6j1.js.map} +1 -1
  78. package/dist/{admin-settings-Bmoy95uO.js → admin-settings-C6eWFkDn.js} +16 -16
  79. package/dist/{admin-settings-Bmoy95uO.js.map → admin-settings-C6eWFkDn.js.map} +1 -1
  80. package/dist/{admin-skeleton-DsM7crYi.js → admin-skeleton-DEY3Q8Dg.js} +2 -2
  81. package/dist/{admin-skeleton-DsM7crYi.js.map → admin-skeleton-DEY3Q8Dg.js.map} +1 -1
  82. package/dist/{admin-status-badge-BFPgo71d.js → admin-status-badge-CwqIU8tK.js} +2 -2
  83. package/dist/{admin-status-badge-BFPgo71d.js.map → admin-status-badge-CwqIU8tK.js.map} +1 -1
  84. package/dist/{admin-subscriptions-CLYc_HEV.js → admin-subscriptions-lJG_EzMe.js} +9 -9
  85. package/dist/{admin-subscriptions-CLYc_HEV.js.map → admin-subscriptions-lJG_EzMe.js.map} +1 -1
  86. package/dist/{admin-switch-BJUxLCsa.js → admin-switch-S4g_ppaU.js} +2 -2
  87. package/dist/{admin-switch-BJUxLCsa.js.map → admin-switch-S4g_ppaU.js.map} +1 -1
  88. package/dist/{admin-table-CH9TrXJf.js → admin-table-CWhiCb9d.js} +2 -2
  89. package/dist/{admin-table-CH9TrXJf.js.map → admin-table-CWhiCb9d.js.map} +1 -1
  90. package/dist/{admin-tabs-528FJMjt.js → admin-tabs-Cjm5a6UJ.js} +2 -2
  91. package/dist/{admin-tabs-528FJMjt.js.map → admin-tabs-Cjm5a6UJ.js.map} +1 -1
  92. package/dist/{admin-textarea-DEz38RaI.js → admin-textarea-DK1Fq31x.js} +2 -2
  93. package/dist/{admin-textarea-DEz38RaI.js.map → admin-textarea-DK1Fq31x.js.map} +1 -1
  94. package/dist/{admin-typed-confirm-dialog-DU7m9-O7.js → admin-typed-confirm-dialog-BloZvFPA.js} +6 -6
  95. package/dist/{admin-typed-confirm-dialog-DU7m9-O7.js.map → admin-typed-confirm-dialog-BloZvFPA.js.map} +1 -1
  96. package/dist/{admin-utils-BK4Vh1o_.js → admin-utils-DnVY5fYd.js} +3 -3
  97. package/dist/admin-utils-DnVY5fYd.js.map +1 -0
  98. package/dist/{admin-widget-viz-Da48c-Zf.js → admin-widget-viz-RCkxUspL.js} +8 -8
  99. package/dist/{admin-widget-viz-Da48c-Zf.js.map → admin-widget-viz-RCkxUspL.js.map} +1 -1
  100. package/dist/admin.js +31 -31
  101. package/dist/admin.js.map +1 -1
  102. package/dist/appearance.d.ts +7 -7
  103. package/dist/buy-button.d.ts +3 -3
  104. package/dist/cart.d.ts +4 -4
  105. package/dist/client/client.d.ts +4 -4
  106. package/dist/client/generated/error-codes.d.ts +1 -1
  107. package/dist/client/generated/routes.d.ts +4 -4
  108. package/dist/client/generated/wire.d.ts +37 -40
  109. package/dist/client/types.d.ts +12 -17
  110. package/dist/{client-rFrCMrkn.js → client-HWr09qpX.js} +11 -13
  111. package/dist/client-HWr09qpX.js.map +1 -0
  112. package/dist/client.js +1 -1
  113. package/dist/embedded-payment.d.ts +25 -0
  114. package/dist/{hooks-B1TffejB.js → hooks-D9MR20BY.js} +2 -2
  115. package/dist/hooks-D9MR20BY.js.map +1 -0
  116. package/dist/index.d.ts +4 -4
  117. package/dist/index.js +69 -69
  118. package/dist/index.js.map +1 -1
  119. package/dist/locales/de.js +1 -1
  120. package/dist/locales/de.js.map +1 -1
  121. package/dist/locales/en.d.ts +1 -1
  122. package/dist/locales/en.js +1 -1
  123. package/dist/locales/en.js.map +1 -1
  124. package/dist/locales/es.js +1 -1
  125. package/dist/locales/es.js.map +1 -1
  126. package/dist/locales/ja.js +1 -1
  127. package/dist/locales/ja.js.map +1 -1
  128. package/dist/locales/ko.js +1 -1
  129. package/dist/locales/ko.js.map +1 -1
  130. package/dist/locales/zh.js +1 -1
  131. package/dist/locales/zh.js.map +1 -1
  132. package/dist/modal.d.ts +8 -8
  133. package/dist/{order-checkout.d.ts → order-payment.d.ts} +4 -4
  134. package/dist/product-list.d.ts +3 -3
  135. package/dist/psp.d.ts +2 -2
  136. package/dist/react/provider.d.ts +3 -3
  137. package/dist/react.js +1 -1
  138. package/dist/save-payment-method.d.ts +2 -2
  139. package/dist/scope-context.d.ts +4 -4
  140. package/dist/scope.d.ts +2 -2
  141. package/dist/tokenized-card-form.d.ts +2 -2
  142. package/docs/payment-form-contract.md +3 -3
  143. package/package.json +2 -2
  144. package/dist/admin-price-detail-DRquxpA9.js.map +0 -1
  145. package/dist/admin-utils-BK4Vh1o_.js.map +0 -1
  146. package/dist/client-rFrCMrkn.js.map +0 -1
  147. package/dist/embedded-checkout.d.ts +0 -25
  148. package/dist/hooks-B1TffejB.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"admin-metering-COFcSPQy.js","names":[],"sources":["../src/admin/pages/catalog/metering-model.ts","../src/admin/pages/catalog/meter-form.tsx","../src/admin/pages/catalog/rate-card-editor.tsx","../src/admin/pages/catalog/metering.tsx"],"sourcesContent":["import type {\n Allowance,\n Meter,\n MeterRateCard,\n RatePrice,\n} from \"#orck/client/generated/wire\"\nimport type {\n DefaultUsageRateCardRequest,\n UsageMeterRequest,\n} from \"#orck/admin/lib/api/endpoints\"\nimport {\n currencyScale,\n formatNativeAmount,\n nativeAmountFromInput,\n nativeAmountToInput,\n supportedCurrencies,\n} from \"#orck/admin/lib/format\"\n\nexport interface KeyValueRow {\n key: string\n value: string\n}\n\nexport interface MatrixCellRow {\n key: string\n unitAmount: string\n maximumAmount: string\n}\n\nexport interface TierRow {\n upTo: string\n unitAmount: string\n flatAmount: string\n}\n\nexport interface MeterFormValues {\n key: string\n eventType: string\n aggregation: \"sum\" | \"count\"\n valueProperty: string\n unit: string\n groupBy: KeyValueRow[]\n}\n\nexport type AllowanceMode = \"none\" | \"included\"\n\nexport interface RateCardFormValues {\n productId: string\n model: \"per_unit\" | \"tiered\" | \"package\" | \"dynamic\"\n currency: string\n unitAmount: string\n divideBy: string\n round: \"half_up\" | \"up\" | \"down\"\n maximumAmount: string\n matrixEnabled: boolean\n matrixDimension: string\n matrixCells: MatrixCellRow[]\n tierMode: \"graduated\"\n tiers: TierRow[]\n packageAmount: string\n packageSize: string\n freeUnits: string\n filters: KeyValueRow[]\n allowanceMode: AllowanceMode\n allowanceIncluded: string\n}\n\nexport class RateCardFormError extends Error {\n readonly fieldId: string\n\n constructor(fieldId: string, message: string) {\n super(message)\n this.name = \"RateCardFormError\"\n this.fieldId = fieldId\n }\n}\n\nexport type MeterCollectionState =\n \"loading\" | \"permission\" | \"error\" | \"empty\" | \"ready\"\n\nexport function meterCollectionState(params: {\n pending: boolean\n error?: { status?: number } | null\n count: number\n}): MeterCollectionState {\n if (params.pending) return \"loading\"\n if (params.error?.status === 403) return \"permission\"\n if (params.error) return \"error\"\n if (params.count === 0) return \"empty\"\n return \"ready\"\n}\n\nexport function normalizeMeterKey(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^[-_]+|[-_]+$/g, \"\")\n}\n\nexport function meterFormValues(meter?: Meter): MeterFormValues {\n return {\n key: meter?.key ?? \"\",\n eventType: meter?.event_type ?? \"\",\n aggregation: meter?.aggregation === \"count\" ? \"count\" : \"sum\",\n valueProperty: meter?.value_property ?? \"\",\n unit: meter?.unit ?? \"\",\n groupBy: Object.entries(meter?.group_by ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n }\n}\n\nexport function buildMeterRequest(values: MeterFormValues): {\n key: string\n meter: UsageMeterRequest\n} {\n const key = normalizeMeterKey(values.key)\n if (!key) throw new Error(\"Enter a meter key.\")\n const eventType = values.eventType.trim()\n const valueProperty = values.valueProperty.trim()\n if (values.aggregation === \"sum\" && !valueProperty) {\n throw new Error(\"Sum meters require a value property.\")\n }\n const groupBy = rowsToMap(values.groupBy, \"group\")\n return {\n key,\n meter: {\n event_type: eventType,\n aggregation: values.aggregation,\n value_property: values.aggregation === \"sum\" ? valueProperty : \"\",\n unit: values.unit.trim() || undefined,\n group_by: groupBy,\n },\n }\n}\n\nexport function rateCardFormValues(\n card?: Pick<\n MeterRateCard,\n \"product_id\" | \"filter\" | \"price\" | \"allowance\"\n > | null\n): RateCardFormValues {\n const price = card?.price\n const matrix = price?.per_unit?.matrix\n const allowance = card?.allowance\n const allowanceMode: AllowanceMode =\n allowance?.included !== undefined ? \"included\" : \"none\"\n const currency = price?.currency ?? \"USD\"\n return {\n productId: card?.product_id ?? \"\",\n model: price?.model && price.model !== \"flat\" ? price.model : \"per_unit\",\n currency,\n unitAmount: moneyToInput(currency, price?.per_unit?.unit_amount),\n divideBy: integerToInput(price?.per_unit?.divide_by, \"1\"),\n round: price?.per_unit?.round ?? \"half_up\",\n maximumAmount: moneyToInput(currency, price?.per_unit?.maximum_amount),\n matrixEnabled: Boolean(matrix),\n matrixDimension: matrix?.dimension ?? \"\",\n matrixCells: Object.entries(matrix?.cells ?? {}).map(([key, cell]) => ({\n key,\n unitAmount: moneyToInput(currency, cell.unit_amount),\n maximumAmount: moneyToInput(currency, cell.maximum_amount),\n })),\n tierMode: \"graduated\",\n tiers: (\n price?.tiered?.tiers ?? [\n { up_to: null, unit_amount: \"0\", flat_amount: \"0\" },\n ]\n ).map((tier) => ({\n upTo: tier.up_to === null ? \"\" : String(tier.up_to),\n unitAmount: moneyToInput(currency, tier.unit_amount),\n flatAmount: moneyToInput(currency, tier.flat_amount),\n })),\n packageAmount: moneyToInput(currency, price?.package?.amount),\n packageSize: integerToInput(price?.package?.package_size, \"1\"),\n freeUnits: integerToInput(price?.package?.free_units),\n filters: Object.entries(card?.filter ?? {}).map(([key, values]) => ({\n key,\n value: values.join(\", \"),\n })),\n allowanceMode,\n allowanceIncluded: integerToInput(allowance?.included),\n }\n}\n\nexport function buildRateCardRequest(\n values: RateCardFormValues\n): DefaultUsageRateCardRequest {\n if (!values.productId) rateCardError(\"rate-product\", \"Select a product.\")\n const currency = values.currency.trim().toUpperCase()\n if (currencyScale(currency) === undefined) {\n rateCardError(\n \"rate-currency\",\n `Use a supported currency: ${supportedCurrencies.join(\", \")}.`\n )\n }\n\n const price = buildPrice(values, currency)\n const allowance = values.model === \"dynamic\" ? undefined : buildAllowance(values)\n return {\n product_id: values.productId,\n filter: filterRowsToMap(values.filters),\n price,\n ...(allowance ? { allowance } : {}),\n }\n}\n\nfunction buildPrice(values: RateCardFormValues, currency: string): RatePrice {\n if (values.model === \"dynamic\") return { model: \"dynamic\", currency }\n if (values.model === \"per_unit\") {\n const divideBy = positiveInteger(\n values.divideBy,\n \"Divisor\",\n \"rate-divide-by\"\n )\n const maximumAmount = optionalMoney(\n currency,\n values.maximumAmount,\n \"Maximum amount\",\n \"rate-maximum\"\n )\n if (values.matrixEnabled) {\n const dimension = values.matrixDimension.trim()\n if (!dimension) {\n rateCardError(\"matrix-dimension\", \"Select a matrix dimension.\")\n }\n if (values.matrixCells.length === 0) {\n rateCardError(\"matrix-add-cell\", \"Add at least one matrix cell.\")\n }\n const cells: NonNullable<\n NonNullable<RatePrice[\"per_unit\"]>[\"matrix\"]\n >[\"cells\"] = {}\n for (const [index, row] of values.matrixCells.entries()) {\n const key = row.key.trim()\n const fieldPrefix = `matrix-cell-${index}`\n if (!key) {\n rateCardError(\n `${fieldPrefix}-value`,\n \"Each matrix cell needs a value.\"\n )\n }\n if (cells[key]) {\n rateCardError(\n `${fieldPrefix}-value`,\n `Duplicate matrix value “${key}”.`\n )\n }\n cells[key] = {\n unit_amount: requiredMoney(\n currency,\n row.unitAmount,\n `Price for ${key}`,\n `${fieldPrefix}-unit-price`,\n true\n ),\n ...(optionalMoney(\n currency,\n row.maximumAmount,\n `Maximum for ${key}`,\n `${fieldPrefix}-maximum`\n ) !== \"0\"\n ? {\n maximum_amount: optionalMoney(\n currency,\n row.maximumAmount,\n `Maximum for ${key}`,\n `${fieldPrefix}-maximum`\n ),\n }\n : {}),\n }\n }\n return {\n model: \"per_unit\",\n currency,\n per_unit: {\n divide_by: divideBy,\n round: values.round,\n ...(maximumAmount !== \"0\" ? { maximum_amount: maximumAmount } : {}),\n matrix: { dimension, cells },\n },\n }\n }\n return {\n model: \"per_unit\",\n currency,\n per_unit: {\n unit_amount: requiredMoney(\n currency,\n values.unitAmount,\n \"Unit price\",\n \"rate-unit-amount\",\n true\n ),\n divide_by: divideBy,\n round: values.round,\n ...(maximumAmount !== \"0\" ? { maximum_amount: maximumAmount } : {}),\n },\n }\n }\n\n if (values.model === \"tiered\") {\n if (values.tiers.length === 0) {\n rateCardError(\"tier-add\", \"Add at least one tier.\")\n }\n const tiers = values.tiers.map((row, index) => {\n const last = index === values.tiers.length - 1\n const upTo = row.upTo.trim()\n if (last && upTo) {\n rateCardError(\n `tier-${index}-limit`,\n \"The final tier must be unbounded.\"\n )\n }\n if (!last && !upTo) {\n rateCardError(\n `tier-${index}-limit`,\n \"Only the final tier can be unbounded.\"\n )\n }\n return {\n up_to: last\n ? null\n : positiveInteger(\n upTo,\n `Tier ${index + 1} limit`,\n `tier-${index}-limit`\n ),\n unit_amount: requiredMoney(\n currency,\n row.unitAmount,\n `Tier ${index + 1} unit price`,\n `tier-${index}-unit-price`,\n true\n ),\n flat_amount: optionalMoney(\n currency,\n row.flatAmount,\n `Tier ${index + 1} flat amount`,\n `tier-${index}-flat-amount`\n ),\n }\n })\n for (let index = 1; index < tiers.length - 1; index += 1) {\n if ((tiers[index].up_to ?? 0) <= (tiers[index - 1].up_to ?? 0)) {\n rateCardError(`tier-${index}-limit`, \"Tier limits must increase.\")\n }\n }\n return {\n model: \"tiered\",\n currency,\n tiered: { mode: values.tierMode, tiers },\n }\n }\n\n return {\n model: \"package\",\n currency,\n package: {\n amount: requiredMoney(\n currency,\n values.packageAmount,\n \"Package price\",\n \"package-amount\"\n ),\n package_size: positiveInteger(\n values.packageSize,\n \"Package size\",\n \"package-size\"\n ),\n free_units: optionalWhole(values.freeUnits, \"Free units\", \"package-free\"),\n },\n }\n}\n\nfunction buildAllowance(values: RateCardFormValues): Allowance | undefined {\n if (values.allowanceMode === \"none\") return undefined\n return {\n included: optionalWhole(\n values.allowanceIncluded,\n \"Included allowance\",\n \"allowance-included\"\n ),\n }\n}\n\nfunction rowsToMap(rows: KeyValueRow[], name: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const row of rows) {\n const key = row.key.trim()\n const value = row.value.trim()\n if (!key || !value) throw new Error(`Each ${name} row needs both fields.`)\n if (result[key]) throw new Error(`Duplicate ${name} key “${key}”.`)\n result[key] = value\n }\n return result\n}\n\nfunction filterRowsToMap(rows: KeyValueRow[]): Record<string, string[]> {\n const result: Record<string, string[]> = {}\n for (const [index, row] of rows.entries()) {\n const key = row.key.trim()\n const values = [\n ...new Set(row.value.split(\",\").map((value) => value.trim())),\n ].filter(Boolean)\n if (!key) {\n rateCardError(\n `filter-${index}-dimension`,\n \"Select a dimension for this filter.\"\n )\n }\n if (values.length === 0) {\n rateCardError(\n `filter-${index}-values`,\n \"Enter at least one value for this filter.\"\n )\n }\n if (result[key]) {\n rateCardError(\n `filter-${index}-dimension`,\n `Duplicate filter dimension “${key}”.`\n )\n }\n result[key] = values\n }\n return result\n}\n\nfunction requiredMoney(\n currency: string,\n value: string,\n label: string,\n fieldId: string,\n allowZero = false\n): string {\n const amount = nativeAmountFromInput(value, currency)\n if (\n amount === null ||\n BigInt(amount) < 0n ||\n (!allowZero && BigInt(amount) === 0n)\n ) {\n rateCardError(\n fieldId,\n `${label} must be ${allowZero ? \"zero or more\" : \"greater than zero\"}.`\n )\n }\n return amount\n}\n\nfunction optionalMoney(\n currency: string,\n value: string,\n label: string,\n fieldId: string\n): string {\n if (!value.trim()) return \"0\"\n return requiredMoney(currency, value, label, fieldId, true)\n}\n\nfunction positiveInteger(\n value: string,\n label: string,\n fieldId: string\n): number {\n const amount = Number(value)\n if (!Number.isSafeInteger(amount) || amount <= 0) {\n rateCardError(fieldId, `${label} must be a positive whole number.`)\n }\n return amount\n}\n\nfunction optionalWhole(value: string, label: string, fieldId: string): number {\n if (!value.trim()) return 0\n const amount = Number(value)\n if (!Number.isSafeInteger(amount) || amount < 0) {\n rateCardError(fieldId, `${label} must be zero or a positive whole number.`)\n }\n return amount\n}\n\nfunction rateCardError(fieldId: string, message: string): never {\n throw new RateCardFormError(fieldId, message)\n}\n\nfunction moneyToInput(currency: string, value?: string): string {\n return value && value !== \"0\" ? nativeAmountToInput(value, currency) : \"\"\n}\n\nfunction integerToInput(value?: number, fallback = \"\"): string {\n return value ? String(value) : fallback\n}\n\nexport function summarizeRateCard(card?: MeterRateCard | null): string {\n if (!card) return \"Not priced\"\n const { price } = card\n const currency = price.currency ?? \"\"\n if (price.model === \"dynamic\") return `Event amount · ${currency}`\n if (price.model === \"per_unit\" && price.per_unit) {\n if (price.per_unit.matrix) {\n return `${Object.keys(price.per_unit.matrix.cells ?? {}).length} matrix rates · ${currency}`\n }\n return `${formatNativeAmount(price.per_unit.unit_amount ?? \"0\", currency)} per ${price.per_unit.divide_by || 1} units`\n }\n if (price.model === \"tiered\" && price.tiered) {\n return `${price.tiered.tiers?.length ?? 0} ${price.tiered.mode} tiers · ${currency}`\n }\n if (price.model === \"package\" && price.package) {\n return `${formatNativeAmount(price.package.amount ?? \"0\", currency)} per ${(price.package.package_size ?? 1).toLocaleString()} units`\n }\n return `Unsupported price · ${currency}`\n}\n\n// meterDefinitionLocked says why a meter's definition cannot change, given\n// whether this deployment accepts catalog writes.\nexport function meterDefinitionLocked(\n meter: Meter,\n writesAllowed: boolean\n): string | null {\n if (!writesAllowed) return \"Catalog updates are disabled.\"\n if (meter.has_activity) return \"Meter definitions lock after the first event.\"\n return null\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Add01Icon, Delete02Icon, Edit02Icon } from \"@hugeicons/core-free-icons\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\n\nimport { FormFieldErrors } from \"#orck/admin/components/form-field-errors\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport type { Meter } from \"#orck/client/generated/wire\"\nimport { DIALOG_FORM } from \"#orck/admin/lib/dialog-width\"\n\nimport {\n buildMeterRequest,\n meterDefinitionLocked,\n meterFormValues,\n} from \"./metering-model\"\n\nexport function MeterFormDialog({\n meter,\n writesAllowed,\n}: {\n meter?: Meter\n writesAllowed: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [submitError, setSubmitError] = React.useState(\"\")\n const queryClient = useQueryClient()\n const save = useMutation(adminMutations.putUsageMeter(queryClient))\n const locked = meter ? meterDefinitionLocked(meter, writesAllowed) : null\n const form = useForm({\n defaultValues: meterFormValues(meter),\n onSubmit: async ({ value }) => {\n setSubmitError(\"\")\n try {\n const request = buildMeterRequest(value)\n // The revision this form read: a meter another edit changed since is\n // refused, and a new one must still be new.\n request.meter.expected_revision = meter?.revision ?? 0\n await save.mutateAsync(request)\n toast.success(meter ? \"Meter updated\" : \"Meter created\")\n setOpen(false)\n form.reset()\n } catch (error) {\n if (error instanceof Error && !(\"status\" in error)) {\n setSubmitError(error.message)\n return\n }\n toastApiError(error, meter ? \"Update meter\" : \"Create meter\")\n }\n },\n })\n\n if (locked) {\n return (\n <Button variant=\"outline\" size=\"sm\" disabled title={locked}>\n <HugeiconsIcon icon={Edit02Icon} className=\"size-4\" />\n <AdminMessage id={\"Edit definition\"} />\n </Button>\n )\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n setSubmitError(\"\")\n if (!next) form.reset()\n }}\n >\n <DialogTrigger\n render={\n <Button variant={meter ? \"outline\" : \"default\"} size=\"sm\">\n <HugeiconsIcon\n icon={meter ? Edit02Icon : Add01Icon}\n className=\"size-4\"\n />\n {meter ? \"Edit definition\" : \"Create meter\"}\n </Button>\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <form\n className=\"grid gap-5\"\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <DialogHeader>\n <DialogTitle>{meter ? \"Edit meter\" : \"Create meter\"}</DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Define the event fields OpenRails will aggregate. Your host still reports each event through the usage API.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"grid gap-4\">\n <form.Field\n name=\"key\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a meter key.\",\n }}\n >\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-key\")}>\n <AdminMessage id={\"Key\"} />\n </Label>\n <Input\n id={adminId(\"meter-key\")}\n value={field.state.value}\n onChange={(event) => field.handleChange(event.target.value)}\n onBlur={field.handleBlur}\n disabled={Boolean(meter)}\n placeholder={adminText(\"api-tokens\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Stable identifier. It cannot be renamed after creation.\"\n }\n />\n </p>\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <form.Field name=\"eventType\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-event-type\")}>\n <AdminMessage id={\"Event type\"} />\n </Label>\n <Input\n id={adminId(\"meter-event-type\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"token.used\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"Leave blank to use the meter key.\"} />\n </p>\n </div>\n )}\n </form.Field>\n <form.Field name=\"unit\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-unit\")}>\n <AdminMessage id={\"Unit\"} />\n </Label>\n <Input\n id={adminId(\"meter-unit\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"tokens\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Human-readable quantity shown in billing.\"}\n />\n </p>\n </div>\n )}\n </form.Field>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <form.Field name=\"aggregation\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-aggregation\")}>\n <AdminMessage id={\"Aggregation\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"sum\" | \"count\")\n }\n >\n <SelectTrigger\n id={adminId(\"meter-aggregation\")}\n className=\"w-full\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"sum\">\n <AdminMessage id={\"Sum a numeric field\"} />\n </SelectItem>\n <SelectItem value=\"count\">\n <AdminMessage id={\"Count events\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.aggregation}>\n {(aggregation) =>\n aggregation === \"sum\" ? (\n <form.Field\n name=\"valueProperty\"\n validators={{\n onBlur: ({ value }) =>\n value.trim()\n ? undefined\n : \"Sum meters require a value property.\",\n }}\n >\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-value-property\")}>\n <AdminMessage id={\"Value property\"} />\n </Label>\n <Input\n id={adminId(\"meter-value-property\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n onBlur={field.handleBlur}\n placeholder={adminText(\"tokens\")}\n autoComplete=\"off\"\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n ) : (\n <div className=\"self-end rounded-lg bg-muted/50 px-3 py-2 text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Count uses one unit for every matching event.\"}\n />\n </div>\n )\n }\n </form.Subscribe>\n </div>\n\n <form.Field name=\"groupBy\" mode=\"array\">\n {(field) => (\n <fieldset className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <Label>\n <AdminMessage id={\"Dimensions\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Register event properties used by filters or matrix rates.\"\n }\n />\n </p>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => field.pushValue({ key: \"\", value: \"\" })}\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add dimension\"} />\n </Button>\n </div>\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid grid-cols-[1fr_1fr_auto] gap-2\"\n >\n <Input\n aria-label={`Dimension ${index + 1} name`}\n value={row.key}\n onChange={(event) =>\n form.setFieldValue(\n `groupBy[${index}].key`,\n event.target.value\n )\n }\n placeholder={adminText(\"model\")}\n autoComplete=\"off\"\n />\n <Input\n aria-label={`Dimension ${index + 1} property`}\n value={row.value}\n onChange={(event) =>\n form.setFieldValue(\n `groupBy[${index}].value`,\n event.target.value\n )\n }\n placeholder={adminText(\"metadata.model\")}\n autoComplete=\"off\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Remove dimension ${index + 1}`}\n onClick={() => field.removeValue(index)}\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n </Button>\n </div>\n ))}\n </fieldset>\n )}\n </form.Field>\n </div>\n\n {submitError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {submitError}\n </p>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <form.Subscribe selector={(state) => state.isSubmitting}>\n {(submitting) => (\n <Button type=\"submit\" disabled={submitting || save.isPending}>\n {submitting || save.isPending ? \"Saving…\" : \"Save meter\"}\n </Button>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Add01Icon,\n Delete02Icon,\n Edit02Icon,\n Money03Icon,\n} from \"@hugeicons/core-free-icons\"\nimport {\n useForm,\n type FormAsyncValidateOrFn,\n type FormValidateOrFn,\n type ReactFormExtendedApi,\n} from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\nimport { Link } from \"#orck/admin/router\"\n\nimport { useConfirm } from \"#orck/admin/lib/confirm\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport { Switch } from \"#orck/admin/components/ui/switch\"\nimport type { Meter, Product } from \"#orck/client/generated/wire\"\nimport type { DefaultUsageRateCardRequest } from \"#orck/admin/lib/api/endpoints\"\nimport { DIALOG_WIDE } from \"#orck/admin/lib/dialog-width\"\n\nimport {\n buildRateCardRequest,\n RateCardFormError,\n rateCardFormValues,\n summarizeRateCard,\n} from \"./metering-model\"\n\ninterface FormIssue {\n fieldId: string\n message: string\n}\n\nconst RateCardIssueContext = React.createContext<FormIssue | null>(null)\n\nexport function RateCardEditor({\n meter,\n writesAllowed = false,\n products,\n productsPending = false,\n productsError = false,\n productsForbidden = false,\n}: {\n meter: Meter\n writesAllowed?: boolean\n products: Product[]\n productsPending?: boolean\n productsError?: boolean\n productsForbidden?: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [submitError, setSubmitError] = React.useState<FormIssue | null>(null)\n const confirm = useConfirm()\n const queryClient = useQueryClient()\n const saveDefault = useMutation(\n adminMutations.putDefaultUsageRateCard(queryClient)\n )\n const activeProducts = products.filter((product) => !product.archived)\n const existing = meter.rate_card\n const savePending = saveDefault.isPending\n const form = useForm({\n defaultValues: rateCardFormValues(existing),\n onSubmit: async ({ value }) => {\n setSubmitError(null)\n try {\n const rateCard = buildRateCardRequest(value)\n if (\n existing &&\n !(await confirm({\n title: \"Replace the default rate?\",\n description:\n \"Amounts already charged do not change. New events use the new rate; admitted work keeps its pinned rate.\",\n confirmLabel: \"Replace rate\",\n cancelLabel: \"Keep current rate\",\n }))\n )\n return\n await persist(rateCard)\n } catch (error) {\n if (error instanceof RateCardFormError) {\n setSubmitError({\n fieldId: error.fieldId,\n message: error.message,\n })\n requestAnimationFrame(() => {\n document.getElementById(adminId(error.fieldId))?.focus()\n })\n return\n }\n toastApiError(error, \"Save rate card\")\n }\n },\n })\n\n const persist = async (rateCard: DefaultUsageRateCardRequest) => {\n try {\n await saveDefault.mutateAsync({ meter, rateCard })\n toast.success(existing ? \"Default rate replaced\" : \"Default rate added\")\n setOpen(false)\n } catch (error) {\n toastApiError(error, \"Save default rate\")\n }\n }\n\n if (!writesAllowed || !meter.billing_supported) {\n return null\n }\n\n return (\n <RateCardIssueContext.Provider value={submitError}>\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n setSubmitError(null)\n if (!next) form.reset()\n }}\n >\n <DialogTrigger\n render={\n <Button variant={existing ? \"outline\" : \"default\"} size=\"sm\">\n <HugeiconsIcon\n icon={existing ? Edit02Icon : Money03Icon}\n className=\"size-4\"\n />\n {existing ? \"Edit default rate\" : \"Add default rate\"}\n </Button>\n }\n />\n <DialogContent\n className={`${DIALOG_WIDE} max-h-[calc(100dvh-2rem)] overflow-y-auto`}\n >\n <form\n className=\"grid gap-6\"\n onChange={() => setSubmitError(null)}\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <DialogHeader>\n <DialogTitle>\n {existing ? \"Edit default rate\" : \"Add default rate\"}\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Set the price that charges every customer's usage as it is recorded. Money is entered in major currency units.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n\n <section className=\"grid gap-4\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Product and model\"} />\n </h3>\n {productsPending ? (\n <div className=\"rounded-lg bg-muted/50 p-3 text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading products…\"} />\n </div>\n ) : productsError ? (\n <div\n role=\"alert\"\n className=\"rounded-lg bg-muted/50 p-3 text-sm text-destructive\"\n >\n {productsForbidden\n ? \"Your role cannot read products for this merchant.\"\n : \"Products could not be loaded. Close this form and try again.\"}\n </div>\n ) : activeProducts.length === 0 ? (\n <div className=\"rounded-lg bg-muted/50 p-3 text-sm\">\n <p>\n <AdminMessage id={\"No active products are available.\"} />\n </p>\n <Link\n className=\"text-primary underline underline-offset-3\"\n to=\"/catalog\"\n >\n <AdminMessage id={\"Create or activate a product first\"} />\n </Link>\n </div>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"productId\">\n {(field) => (\n <div className=\"grid gap-1.5 sm:col-span-2\">\n <Label htmlFor={adminId(\"rate-product\")}>\n <AdminMessage id={\"Product\"} />\n </Label>\n <Select\n value={field.state.value || null}\n onValueChange={(value) =>\n field.handleChange(value ?? \"\")\n }\n >\n <SelectTrigger\n id={adminId(\"rate-product\")}\n className=\"w-full\"\n {...fieldIssueProps(\"rate-product\", submitError)}\n >\n <SelectValue\n placeholder={adminText(\"Select product\")}\n />\n </SelectTrigger>\n <SelectContent>\n {activeProducts.map((product) => (\n <SelectItem key={product.id} value={product.id}>\n {product.display_name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId=\"rate-product\" />\n </div>\n )}\n </form.Field>\n <form.Field name=\"currency\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"rate-currency\")}>\n <AdminMessage id={\"Currency\"} />\n </Label>\n <Input\n id={adminId(\"rate-currency\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value.toUpperCase())\n }\n maxLength={3}\n placeholder={adminText(\"USD\")}\n className=\"uppercase\"\n autoComplete=\"off\"\n {...fieldIssueProps(\"rate-currency\", submitError)}\n />\n <FieldIssue fieldId=\"rate-currency\" />\n </div>\n )}\n </form.Field>\n <PricingModelField form={form} meter={meter} />\n </div>\n )}\n </section>\n\n <form.Subscribe selector={(state) => state.values.model}>\n {(model) => (\n <section className=\"grid gap-4 border-t pt-5\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Rate\"} />\n </h3>\n {model === \"per_unit\" && (\n <PerUnitFields form={form} meter={meter} />\n )}\n {model === \"tiered\" && <TieredFields form={form} />}\n {model === \"package\" && <PackageFields form={form} />}\n {model === \"dynamic\" && (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Charge each event’s stated amount when it reports positive units. Missing amounts or zero units charge nothing.\"} />\n </p>\n )}\n </section>\n )}\n </form.Subscribe>\n\n <FilterFields form={form} meter={meter} />\n <form.Subscribe selector={(state) => state.values.model}>\n {(model) => model !== \"dynamic\" && <AllowanceFields form={form} />}\n </form.Subscribe>\n\n <form.Subscribe selector={(state) => state.values}>\n {(values) => <RateSummary values={values} />}\n </form.Subscribe>\n\n {submitError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {submitError.message}\n </p>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <Button\n type=\"submit\"\n disabled={\n savePending ||\n productsPending ||\n productsError ||\n activeProducts.length === 0\n }\n >\n {savePending\n ? \"Saving…\"\n : existing\n ? \"Review replacement\"\n : \"Save default rate\"}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </RateCardIssueContext.Provider>\n )\n}\n\ntype RateCardFormValuesCompat = ReturnType<typeof rateCardFormValues>\ntype RateCardValidator = FormValidateOrFn<RateCardFormValuesCompat> | undefined\ntype RateCardAsyncValidator =\n FormAsyncValidateOrFn<RateCardFormValuesCompat> | undefined\ntype MeteringForm = ReactFormExtendedApi<\n RateCardFormValuesCompat,\n RateCardValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardAsyncValidator,\n unknown\n>\n\nfunction PricingModelField({\n form,\n meter,\n}: {\n form: MeteringForm\n meter: Meter\n}) {\n const { id: adminId } = useAdminUI()\n return (\n <form.Field name=\"model\">\n {(field) => (\n <div className=\"grid gap-1.5 sm:col-span-3\">\n <Label htmlFor={adminId(\"rate-model\")}>\n <AdminMessage id={\"Pricing model\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"per_unit\" | \"tiered\" | \"package\" | \"dynamic\")\n }\n >\n <SelectTrigger id={adminId(\"rate-model\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"per_unit\">\n <AdminMessage id={\"Per unit\"} />\n </SelectItem>\n <SelectItem value=\"tiered\">\n <AdminMessage id={\"Tiered\"} />\n </SelectItem>\n <SelectItem value=\"package\">\n <AdminMessage id={\"Package\"} />\n </SelectItem>\n <SelectItem value=\"dynamic\" disabled={meter.aggregation !== \"sum\"}>\n <AdminMessage id={\"Dynamic (event amount)\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n )\n}\n\nfunction PerUnitFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n return (\n <>\n <form.Field name=\"matrixEnabled\">\n {(field) => (\n <div className=\"flex items-center justify-between gap-4 rounded-lg bg-muted/50 px-3 py-2.5\">\n <div>\n <Label htmlFor={adminId(\"rate-matrix\")}>\n <AdminMessage id={\"Use matrix rates\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Price each value of one registered dimension separately.\"\n }\n />\n </p>\n </div>\n <Switch\n id={adminId(\"rate-matrix\")}\n checked={field.state.value}\n onCheckedChange={field.handleChange}\n disabled={Object.keys(meter.group_by ?? {}).length === 0}\n />\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.matrixEnabled}>\n {(matrixEnabled) =>\n matrixEnabled ? (\n <MatrixFields form={form} meter={meter} />\n ) : (\n <form.Field name=\"unitAmount\">\n {(field) => (\n <MoneyField\n id={\"rate-unit-amount\"}\n label={adminText(\"Price per divisor\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder=\"0.0025\"\n />\n )}\n </form.Field>\n )\n }\n </form.Subscribe>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"divideBy\">\n {(field) => (\n <TextField\n id={\"rate-divide-by\"}\n label={adminText(\"Divisor\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1\"\n />\n )}\n </form.Field>\n <form.Field name=\"round\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"rate-round\")}>\n <AdminMessage id={\"Rounding\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"half_up\" | \"up\" | \"down\")\n }\n >\n <SelectTrigger id={adminId(\"rate-round\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"half_up\">\n <AdminMessage id={\"Nearest\"} />\n </SelectItem>\n <SelectItem value=\"up\">\n <AdminMessage id={\"Up\"} />\n </SelectItem>\n <SelectItem value=\"down\">\n <AdminMessage id={\"Down\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Field name=\"maximumAmount\">\n {(field) => (\n <MoneyField\n id={\"rate-maximum\"}\n label={adminText(\"Period maximum\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder={adminText(\"No maximum\")}\n />\n )}\n </form.Field>\n </div>\n </>\n )\n}\n\nfunction MatrixFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n const formIssue = React.useContext(RateCardIssueContext)\n return (\n <>\n <form.Field name=\"matrixDimension\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"matrix-dimension\")}>\n <AdminMessage id={\"Dimension\"} />\n </Label>\n <Select\n value={field.state.value || null}\n onValueChange={(value) => field.handleChange(value ?? \"\")}\n >\n <SelectTrigger\n id={adminId(\"matrix-dimension\")}\n className=\"w-full\"\n {...fieldIssueProps(\"matrix-dimension\", formIssue)}\n >\n <SelectValue placeholder={adminText(\"Select dimension\")} />\n </SelectTrigger>\n <SelectContent>\n {Object.keys(meter.group_by ?? {}).map((key) => (\n <SelectItem key={key} value={key}>\n {key}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId=\"matrix-dimension\" />\n </div>\n )}\n </form.Field>\n <form.Field name=\"matrixCells\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <Label>\n <AdminMessage id={\"Matrix cells\"} />\n </Label>\n <Button\n id={adminId(\"matrix-add-cell\")}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n field.pushValue({\n key: \"\",\n unitAmount: \"\",\n maximumAmount: \"\",\n })\n }\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add cell\"} />\n </Button>\n </div>\n <FieldIssue fieldId=\"matrix-add-cell\" />\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_1fr_1fr_auto]\">\n <span>\n <AdminMessage id=\"Value\" />\n </span>\n <span>\n <AdminMessage id=\"Unit price\" />\n </span>\n <span>\n <AdminMessage id=\"Maximum\" />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_1fr_1fr_auto]\"\n >\n <RowTextField\n id={`matrix-cell-${index}-value`}\n label={adminText(\"Value\")}\n value={row.key}\n onChange={(value) =>\n form.setFieldValue(`matrixCells[${index}].key`, value)\n }\n placeholder={adminText(\"gpt-5\")}\n />\n <RowTextField\n id={`matrix-cell-${index}-unit-price`}\n label={adminText(\"Unit price\")}\n value={row.unitAmount}\n onChange={(value) =>\n form.setFieldValue(\n `matrixCells[${index}].unitAmount`,\n value\n )\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Price\")}\n />\n <RowTextField\n id={`matrix-cell-${index}-maximum`}\n label={adminText(\"Maximum\")}\n value={row.maximumAmount}\n onChange={(value) =>\n form.setFieldValue(\n `matrixCells[${index}].maximumAmount`,\n value\n )\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Maximum\")}\n />\n <RemoveRowButton\n label={`Remove matrix cell ${index + 1}`}\n onClick={() => field.removeValue(index)}\n />\n </div>\n ))}\n </div>\n )}\n </form.Field>\n </>\n )\n}\n\nfunction TieredFields({ form }: { form: MeteringForm }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n return (\n <>\n <form.Field name=\"tiers\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <Label>\n <AdminMessage id={\"Tiers\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Leave the final limit blank for the unbounded tier.\"}\n />\n </p>\n </div>\n <Button\n id={adminId(\"tier-add\")}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n field.pushValue({ upTo: \"\", unitAmount: \"\", flatAmount: \"\" })\n }\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add tier\"} />\n </Button>\n </div>\n <FieldIssue fieldId=\"tier-add\" />\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_1fr_1fr_auto]\">\n <span>\n <AdminMessage id={\"Upper limit\"} />\n </span>\n <span>\n <AdminMessage id={\"Unit price\"} />\n </span>\n <span>\n <AdminMessage id={\"Flat amount\"} />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_1fr_1fr_auto]\"\n >\n <RowTextField\n id={`tier-${index}-limit`}\n label={adminText(\"Upper limit\")}\n value={row.upTo}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].upTo`, value)\n }\n inputMode=\"numeric\"\n placeholder={\n index === field.state.value.length - 1\n ? \"No limit\"\n : \"Up to\"\n }\n />\n <RowTextField\n id={`tier-${index}-unit-price`}\n label={adminText(\"Unit price\")}\n value={row.unitAmount}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].unitAmount`, value)\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Unit price\")}\n />\n <RowTextField\n id={`tier-${index}-flat-amount`}\n label={adminText(\"Flat amount\")}\n value={row.flatAmount}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].flatAmount`, value)\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Flat amount\")}\n />\n <RemoveRowButton\n label={`Remove tier ${index + 1}`}\n onClick={() => field.removeValue(index)}\n disabled={field.state.value.length === 1}\n />\n </div>\n ))}\n </div>\n )}\n </form.Field>\n </>\n )\n}\n\nfunction PackageFields({ form }: { form: MeteringForm }) {\n const { text: adminText } = useAdminUI()\n\n return (\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"packageAmount\">\n {(field) => (\n <MoneyField\n id={\"package-amount\"}\n label={adminText(\"Package price\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder=\"10.00\"\n />\n )}\n </form.Field>\n <form.Field name=\"packageSize\">\n {(field) => (\n <TextField\n id={\"package-size\"}\n label={adminText(\"Units per package\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1000\"\n />\n )}\n </form.Field>\n <form.Field name=\"freeUnits\">\n {(field) => (\n <TextField\n id={\"package-free\"}\n label={adminText(\"Free units\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"0\"\n />\n )}\n </form.Field>\n </div>\n )\n}\n\nfunction FilterFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n const formIssue = React.useContext(RateCardIssueContext)\n return (\n <section className=\"grid gap-3 border-t pt-5\">\n <div>\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Event filters\"} />\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Optional. Only events with one of the listed dimension values are rated.\"\n }\n />\n </p>\n </div>\n <form.Field name=\"filters\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_2fr_auto]\">\n <span>\n <AdminMessage id={\"Dimension\"} />\n </span>\n <span>\n <AdminMessage id={\"Values\"} />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_2fr_auto]\"\n >\n <div className=\"grid gap-1.5\">\n <Label\n htmlFor={adminId(`filter-${index}-dimension`)}\n className=\"text-xs text-muted-foreground sm:sr-only\"\n >\n <AdminMessage id={\"Dimension\"} />\n </Label>\n <Select\n value={row.key || null}\n onValueChange={(value) =>\n form.setFieldValue(`filters[${index}].key`, value ?? \"\")\n }\n >\n <SelectTrigger\n id={adminId(`filter-${index}-dimension`)}\n className=\"w-full\"\n {...fieldIssueProps(\n `filter-${index}-dimension`,\n formIssue\n )}\n >\n <SelectValue placeholder={adminText(\"Dimension\")} />\n </SelectTrigger>\n <SelectContent>\n {Object.keys(meter.group_by ?? {}).map((key) => (\n <SelectItem key={key} value={key}>\n {key}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId={`filter-${index}-dimension`} />\n </div>\n <RowTextField\n id={`filter-${index}-values`}\n label={adminText(\"Values\")}\n value={row.value}\n onChange={(value) =>\n form.setFieldValue(`filters[${index}].value`, value)\n }\n placeholder={adminText(\"eu, us\")}\n />\n <RemoveRowButton\n label={`Remove filter ${index + 1}`}\n onClick={() => field.removeValue(index)}\n />\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-fit\"\n disabled={Object.keys(meter.group_by ?? {}).length === 0}\n onClick={() => field.pushValue({ key: \"\", value: \"\" })}\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add filter\"} />\n </Button>\n </div>\n )}\n </form.Field>\n </section>\n )\n}\n\nfunction AllowanceFields({ form }: { form: MeteringForm }) {\n const { id: adminId, text: adminText } = useAdminUI()\n return (\n <section className=\"grid gap-4 border-t pt-5\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Allowance\"} />\n </h3>\n <form.Field name=\"allowanceMode\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"allowance-mode\")}>\n <AdminMessage id={\"Included usage\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"none\" | \"included\")\n }\n >\n <SelectTrigger id={adminId(\"allowance-mode\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">\n <AdminMessage id=\"No allowance\" />\n </SelectItem>\n <SelectItem value=\"included\">\n <AdminMessage id=\"Fixed included units\" />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.allowanceMode}>\n {(mode) =>\n mode === \"included\" ? (\n <form.Field name=\"allowanceIncluded\">\n {(field) => (\n <TextField\n id={\"allowance-included\"}\n label={adminText(\"Included units per period\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1000\"\n />\n )}\n </form.Field>\n ) : null\n }\n </form.Subscribe>\n </section>\n )\n}\n\nfunction RateSummary({ values }: { values: RateCardFormValuesCompat }) {\n let summary = \"Complete the required fields to preview this rate.\"\n try {\n const request = buildRateCardRequest(values)\n summary = summarizeRateCard({\n price: request.price,\n } as Meter[\"rate_card\"])\n if (request.allowance?.included !== undefined) {\n summary += ` · ${request.allowance.included.toLocaleString()} included`\n }\n } catch {\n // Incomplete form state is expected while editing.\n }\n return (\n <section className=\"rounded-lg bg-muted/50 px-3 py-2.5\" aria-live=\"polite\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n <AdminMessage id={\"Rate preview\"} />\n </p>\n <p className=\"mt-1 text-sm font-medium tabular-nums\">{summary}</p>\n </section>\n )\n}\n\nfunction TextField({\n id,\n label,\n value,\n onChange,\n placeholder,\n inputMode,\n}: {\n id: string\n label: string\n value: string\n onChange: (value: string) => void\n placeholder?: string\n inputMode?: \"numeric\" | \"decimal\"\n}) {\n const { id: adminId } = useAdminUI()\n\n const issue = useRateCardIssue(id)\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(id)}>{label}</Label>\n <Input\n id={adminId(id)}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n inputMode={inputMode}\n autoComplete=\"off\"\n {...fieldIssueProps(id, issue ? { fieldId: id, message: issue } : null)}\n />\n <FieldIssue fieldId={id} />\n </div>\n )\n}\n\nfunction MoneyField(props: React.ComponentProps<typeof TextField>) {\n return <TextField {...props} inputMode=\"decimal\" />\n}\n\nfunction RowTextField({\n id,\n label,\n value,\n onChange,\n placeholder,\n inputMode,\n}: {\n id: string\n label: string\n value: string\n onChange: (value: string) => void\n placeholder?: string\n inputMode?: \"numeric\" | \"decimal\"\n}) {\n const { id: adminId } = useAdminUI()\n\n const issue = useRateCardIssue(id)\n return (\n <div className=\"grid gap-1.5\">\n <Label\n htmlFor={adminId(id)}\n className=\"text-xs text-muted-foreground sm:sr-only\"\n >\n {label}\n </Label>\n <Input\n id={adminId(id)}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n inputMode={inputMode}\n autoComplete=\"off\"\n {...fieldIssueProps(id, issue ? { fieldId: id, message: issue } : null)}\n />\n <FieldIssue fieldId={id} />\n </div>\n )\n}\n\nfunction useRateCardIssue(fieldId: string): string | undefined {\n const issue = React.useContext(RateCardIssueContext)\n return issue?.fieldId === fieldId ? issue.message : undefined\n}\n\nfunction fieldIssueProps(fieldId: string, issue: FormIssue | null) {\n const invalid = issue?.fieldId === fieldId\n return {\n \"aria-invalid\": invalid || undefined,\n \"aria-describedby\": invalid ? `${fieldId}-error` : undefined,\n }\n}\n\nfunction FieldIssue({ fieldId }: { fieldId: string }) {\n const { id: adminId } = useAdminUI()\n\n const message = useRateCardIssue(fieldId)\n if (!message) return null\n return (\n <p id={adminId(`${fieldId}-error`)} className=\"text-xs text-destructive\">\n {message}\n </p>\n )\n}\n\nfunction RemoveRowButton({\n label,\n onClick,\n disabled,\n}: {\n label: string\n onClick: () => void\n disabled?: boolean\n}) {\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className=\"self-end\"\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n </Button>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Activity01Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n Delete02Icon,\n InformationCircleIcon,\n Search01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\nimport { Link, useNavigate, useParams } from \"#orck/admin/router\"\n\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { useConfirm } from \"#orck/admin/lib/confirm\"\nimport { useCursorPages } from \"#orck/admin/lib/cursor-pages\"\nimport { LinkedTableRow } from \"#orck/admin/components/linked-table-row\"\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Skeleton } from \"#orck/admin/components/ui/skeleton\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"#orck/admin/components/ui/table\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport type { Meter } from \"#orck/client/generated/wire\"\nimport { formatDate } from \"#orck/admin/lib/format\"\n\nimport { useCatalogWrites } from \"#orck/admin/lib/capabilities\"\n\nimport { MeterFormDialog } from \"./meter-form\"\nimport {\n meterCollectionState,\n meterDefinitionLocked,\n summarizeRateCard,\n} from \"./metering-model\"\nimport { RateCardEditor } from \"./rate-card-editor\"\n\nconst PAGE_SIZE = 200\n\nexport function CatalogMeteringPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const [search, setSearch] = React.useState(\"\")\n const pages = useCursorPages(\"\", PAGE_SIZE)\n const { data, isPending, error, refetch } = useQuery(\n adminQueries.usageMeters(pages.size, pages.cursor)\n )\n const writesAllowed = useCatalogWrites()\n const meters = data?.data ?? []\n const normalizedSearch = search.trim().toLowerCase()\n const filtered = normalizedSearch\n ? meters.filter((meter) =>\n [\n meter.key,\n meter.event_type,\n meter.aggregation,\n meter.unit,\n meter.rate_card?.product_key,\n ].some((value) => value?.toLowerCase().includes(normalizedSearch))\n )\n : meters\n const state = meterCollectionState({\n pending: isPending,\n error: error instanceof ApiError ? error : error ? { status: 500 } : null,\n count: meters.length,\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-5\">\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div className=\"max-w-2xl\">\n <h1 className=\"text-2xl font-semibold tracking-tight text-balance\">\n <AdminMessage id={\"Metering\"} />\n </h1>\n <p className=\"mt-1 text-sm text-pretty text-muted-foreground\">\n <AdminMessage\n id={\n \"Define usage streams and the default rates charged when usage is recorded. Applications report the events separately.\"\n }\n />\n </p>\n </div>\n {writesAllowed && state !== \"permission\" && (\n <MeterFormDialog writesAllowed />\n )}\n </div>\n\n {data && !writesAllowed && (\n <ReadOnlyNotice>\n <AdminMessage\n id={\n \"Catalog updates are disabled. Meter definitions and rates are visible here; changes require the host operator.\"\n }\n />\n </ReadOnlyNotice>\n )}\n\n {state === \"loading\" ? (\n <MeteringSkeleton />\n ) : state === \"permission\" ? (\n <PageMessage\n title={adminText(\"Metering access is restricted\")}\n description={adminText(\n \"Your role does not have permission to read the merchant catalog.\"\n )}\n />\n ) : state === \"error\" ? (\n <PageMessage\n title={adminText(\"Metering could not be loaded\")}\n description={adminText(\n \"Try again. If the problem continues, check the OpenRails API logs.\"\n )}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refetch()}>\n <AdminMessage id={\"Try again\"} />\n </Button>\n }\n />\n ) : state === \"empty\" ? (\n <PageMessage\n title={adminText(\"No usage meters yet\")}\n description={adminText(\n \"Create a meter to describe the events your application will report and bill.\"\n )}\n action={writesAllowed ? <MeterFormDialog writesAllowed /> : undefined}\n />\n ) : (\n <>\n <div className=\"relative w-full sm:max-w-xs\">\n <HugeiconsIcon\n icon={Search01Icon}\n className=\"absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n className=\"pl-8\"\n placeholder={adminText(\"Filter this page…\")}\n aria-label={adminText(\"Filter meters on this page\")}\n />\n </div>\n <div className=\"max-w-full overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Meter\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Event\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Aggregation\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Default price\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Activity\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Last event\"} />\n </TableHead>\n <TableHead>\n <span className=\"sr-only\">\n <AdminMessage id={\"Open\"} />\n </span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {filtered.map((meter) => (\n <MeterRow key={meter.key} meter={meter} />\n ))}\n {filtered.length === 0 && (\n <TableRow>\n <TableCell\n colSpan={9}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No meters on this page match “\"} />\n {search}”.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isPending}\n sizes={[100, 200, 500]}\n />\n </>\n )}\n </div>\n )\n}\n\nfunction MeterRow({ meter }: { meter: Meter }) {\n return (\n <LinkedTableRow to={`/catalog/metering/${encodeURIComponent(meter.key)}`}>\n <TableCell>\n <Link\n className=\"font-medium underline-offset-3 hover:underline\"\n to={`/catalog/metering/${encodeURIComponent(meter.key)}`}\n >\n {meter.key}\n </Link>\n {meter.unit && (\n <p className=\"text-xs text-muted-foreground\">{meter.unit}</p>\n )}\n </TableCell>\n <TableCell>{meter.event_type}</TableCell>\n <TableCell>\n <Badge variant=\"secondary\">{meter.aggregation}</Badge>\n </TableCell>\n <TableCell className=\"font-medium tabular-nums\">\n {summarizeRateCard(meter.rate_card)}\n </TableCell>\n <TableCell>{meter.rate_card?.product_key ?? \"—\"}</TableCell>\n <TableCell>\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n <span\n className={`size-1.5 rounded-full ${meter.has_activity ? \"bg-settled\" : \"bg-muted-foreground/50\"}`}\n />\n {meter.has_activity ? \"Active\" : \"No events\"}\n </span>\n </TableCell>\n <TableCell className=\"text-muted-foreground tabular-nums\">\n {formatDate(meter.last_event_at)}\n </TableCell>\n <TableCell className=\"text-right\">\n <HugeiconsIcon\n icon={ArrowRight01Icon}\n className=\"ml-auto size-4 text-muted-foreground\"\n />\n </TableCell>\n </LinkedTableRow>\n )\n}\n\nexport function MeterDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { key = \"\" } = useParams()\n const meterKey = key\n const navigate = useNavigate()\n const meterQuery = useQuery(adminQueries.usageMeter(meterKey))\n const writesAllowed = useCatalogWrites()\n const productsQuery = useQuery(\n adminQueries.allProducts({ errorAction: \"Load products for metering\" })\n )\n\n if (meterQuery.isPending) return <MeterDetailSkeleton />\n if (meterQuery.error) {\n const notFound =\n meterQuery.error instanceof ApiError && meterQuery.error.status === 404\n const forbidden =\n meterQuery.error instanceof ApiError && meterQuery.error.status === 403\n return (\n <PageMessage\n title={\n forbidden\n ? \"Metering access is restricted\"\n : notFound\n ? \"Meter not found\"\n : \"Meter could not be loaded\"\n }\n description={\n forbidden\n ? \"Your role does not have permission to read this meter.\"\n : notFound\n ? \"This meter does not exist in the active merchant catalog.\"\n : \"Try loading the meter again.\"\n }\n action={\n forbidden ? undefined : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n notFound\n ? navigate(\"/catalog/metering\")\n : void meterQuery.refetch()\n }\n >\n {notFound ? \"Back to metering\" : \"Try again\"}\n </Button>\n )\n }\n />\n )\n }\n const meter = meterQuery.data\n if (!meter) return null\n const definitionLock = meterDefinitionLocked(meter, writesAllowed)\n\n return (\n <div className=\"flex min-w-0 flex-col gap-8\">\n <header className=\"flex flex-wrap items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => navigate(\"/catalog/metering\")}\n aria-label={adminText(\"Back to metering\")}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4\" />\n </Button>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"truncate text-xl font-semibold tracking-tight\">\n {meter.key}\n </h1>\n {!writesAllowed && (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"read-only\"} />\n </Badge>\n )}\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {meter.event_type} · {meter.aggregation}\n {meter.unit ? ` · ${meter.unit}` : \"\"}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <MeterFormDialog meter={meter} writesAllowed={writesAllowed} />\n <RateCardEditor\n meter={meter}\n writesAllowed={writesAllowed}\n products={productsQuery.data?.data ?? []}\n productsPending={productsQuery.isPending}\n productsError={Boolean(productsQuery.error)}\n productsForbidden={\n productsQuery.error instanceof ApiError &&\n productsQuery.error.status === 403\n }\n />\n </div>\n </header>\n\n {!writesAllowed && (\n <ReadOnlyNotice>\n <AdminMessage\n id={\"Catalog updates are disabled. The console is read-only.\"}\n />\n </ReadOnlyNotice>\n )}\n\n <section className=\"grid gap-4\">\n <div>\n <h2 className=\"text-base font-semibold\">\n <AdminMessage id={\"Event contract\"} />\n </h2>\n <p className=\"mt-1 max-w-3xl text-sm text-pretty text-muted-foreground\">\n <AdminMessage\n id={\n \"Creating this meter does not send events. The host application must report idempotent usage to\"\n }\n />{\" \"}\n <code className=\"text-foreground\">\n <AdminMessage id={\"/app/usage-events\"} />\n </code>\n <AdminMessage id={\" with this shape.\"} />\n </p>\n </div>\n <dl className=\"grid gap-x-8 gap-y-4 border-y py-4 sm:grid-cols-2 lg:grid-cols-4\">\n <ContractFact\n label={adminText(\"Event type\")}\n value={meter.event_type}\n />\n <ContractFact\n label={adminText(\"Aggregation\")}\n value={\n meter.aggregation === \"sum\"\n ? `Sum ${meter.value_property}`\n : \"Count each event\"\n }\n />\n <ContractFact label={adminText(\"Meter key\")} value={meter.key} />\n <ContractFact\n label={adminText(\"Billing support\")}\n value={meter.billing_supported ? \"Supported\" : \"Read only\"}\n />\n {Object.entries(meter.group_by ?? {}).map(([name, property]) => (\n <ContractFact\n key={name}\n label={`Dimension: ${name}`}\n value={property}\n />\n ))}\n </dl>\n {definitionLock && writesAllowed && (\n <p className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <HugeiconsIcon icon={Activity01Icon} className=\"size-4\" />\n {definitionLock}\n </p>\n )}\n </section>\n\n <DefaultRateSection meter={meter} writesAllowed={writesAllowed} />\n </div>\n )\n}\n\nfunction DefaultRateSection({\n meter,\n writesAllowed,\n}: {\n meter: Meter\n writesAllowed: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText } = useAdminUI()\n\n const confirm = useConfirm()\n const queryClient = useQueryClient()\n const remove = useMutation(\n adminMutations.deleteDefaultUsageRateCard(queryClient)\n )\n const card = meter.rate_card\n const handleDelete = async () => {\n const removing = await confirm({\n title: \"Remove the default rate?\",\n description:\n \"New usage for this meter will stop being rated after removal. Billed usage orders and accrued amounts remain unchanged.\",\n confirmLabel: \"Remove default\",\n cancelLabel: \"Keep rate\",\n tone: \"destructive\",\n })\n if (!removing) return\n try {\n await remove.mutateAsync(meter)\n toast.success(\"Default rate removed\")\n } catch (error) {\n toastApiError(error, \"Remove default rate\")\n }\n }\n return (\n <section className=\"grid gap-4 border-t pt-7\">\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-base font-semibold\">\n <AdminMessage id={\"Default rate\"} />\n </h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n <AdminMessage id={\"Used for every customer.\"} />\n </p>\n </div>\n {card && writesAllowed && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={remove.isPending}\n onClick={() => void handleDelete()}\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n {remove.isPending ? \"Removing…\" : \"Remove default\"}\n </Button>\n )}\n </div>\n {!meter.billing_supported ? (\n <ReadOnlyNotice>\n <AdminMessage\n id={\n \"This meter uses an aggregation that the billing engine cannot rate.\"\n }\n />\n </ReadOnlyNotice>\n ) : !card ? (\n <p className=\"border-y py-6 text-sm text-muted-foreground\">\n <AdminMessage\n id={\n \"No default rate. Usage is recorded but is not billed by this meter.\"\n }\n />\n </p>\n ) : (\n <dl className=\"grid gap-x-8 gap-y-4 border-y py-4 sm:grid-cols-2 lg:grid-cols-4\">\n <ContractFact\n label={adminText(\"Price\")}\n value={summarizeRateCard(card)}\n />\n <ContractFact label={adminText(\"Product\")} value={card.product_key} />\n <ContractFact\n label={adminText(\"Model\")}\n value={card.price.model.replace(\"_\", \" \")}\n />\n <ContractFact\n label={adminText(\"Filter\")}\n value={\n Object.keys(card.filter ?? {}).length\n ? Object.entries(card.filter ?? {})\n .map(([key, values]) => `${key}: ${values.join(\", \")}`)\n .join(\" · \")\n : \"All matching events\"\n }\n />\n <ContractFact\n label={adminText(\"Allowance\")}\n value={\n card.allowance?.included !== undefined\n ? `${card.allowance.included.toLocaleString()} included`\n : \"None\"\n }\n />\n <ContractFact\n label={adminText(\"Updated\")}\n value={formatDate(card.updated_at)}\n />\n </dl>\n )}\n </section>\n )\n}\n\nfunction ContractFact({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"min-w-0\">\n <dt className=\"text-xs text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 text-sm font-medium break-words tabular-nums\">\n {value || \"—\"}\n </dd>\n </div>\n )\n}\n\nfunction ReadOnlyNotice({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg bg-muted/50 px-3 py-2.5 text-sm text-muted-foreground\">\n <HugeiconsIcon\n icon={InformationCircleIcon}\n className=\"mt-0.5 size-4 shrink-0\"\n />\n <p>{children}</p>\n </div>\n )\n}\n\nfunction PageMessage({\n title,\n description,\n action,\n}: {\n title: string\n description: string\n action?: React.ReactNode\n}) {\n return (\n <div className=\"flex flex-col items-start gap-3 border-y py-10\">\n <div>\n <h2 className=\"text-sm font-medium\">{title}</h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">{description}</p>\n </div>\n {action}\n </div>\n )\n}\n\nfunction MeteringSkeleton() {\n return (\n <div className=\"grid gap-3\">\n <Skeleton className=\"h-8 w-64\" />\n {Array.from({ length: 5 }).map((_, index) => (\n <Skeleton key={index} className=\"h-11 w-full\" />\n ))}\n </div>\n )\n}\n\nfunction MeterDetailSkeleton() {\n return (\n <div className=\"grid gap-6\">\n <Skeleton className=\"h-10 w-72\" />\n <Skeleton className=\"h-28 w-full\" />\n <Skeleton className=\"h-36 w-full\" />\n <Skeleton className=\"h-40 w-full\" />\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"admin-metering-BksTFRRP.js","names":[],"sources":["../src/admin/pages/catalog/metering-model.ts","../src/admin/pages/catalog/meter-form.tsx","../src/admin/pages/catalog/rate-card-editor.tsx","../src/admin/pages/catalog/metering.tsx"],"sourcesContent":["import type {\n Allowance,\n Meter,\n MeterRateCard,\n RatePrice,\n} from \"#orck/client/generated/wire\"\nimport type {\n DefaultUsageRateCardRequest,\n UsageMeterRequest,\n} from \"#orck/admin/lib/api/endpoints\"\nimport {\n currencyScale,\n formatNativeAmount,\n nativeAmountFromInput,\n nativeAmountToInput,\n supportedCurrencies,\n} from \"#orck/admin/lib/format\"\n\nexport interface KeyValueRow {\n key: string\n value: string\n}\n\nexport interface MatrixCellRow {\n key: string\n unitAmount: string\n maximumAmount: string\n}\n\nexport interface TierRow {\n upTo: string\n unitAmount: string\n flatAmount: string\n}\n\nexport interface MeterFormValues {\n key: string\n eventType: string\n aggregation: \"sum\" | \"count\"\n valueProperty: string\n unit: string\n groupBy: KeyValueRow[]\n}\n\nexport type AllowanceMode = \"none\" | \"included\"\n\nexport interface RateCardFormValues {\n productId: string\n model: \"per_unit\" | \"tiered\" | \"package\" | \"dynamic\"\n currency: string\n unitAmount: string\n divideBy: string\n round: \"half_up\" | \"up\" | \"down\"\n maximumAmount: string\n matrixEnabled: boolean\n matrixDimension: string\n matrixCells: MatrixCellRow[]\n tierMode: \"graduated\"\n tiers: TierRow[]\n packageAmount: string\n packageSize: string\n freeUnits: string\n filters: KeyValueRow[]\n allowanceMode: AllowanceMode\n allowanceIncluded: string\n}\n\nexport class RateCardFormError extends Error {\n readonly fieldId: string\n\n constructor(fieldId: string, message: string) {\n super(message)\n this.name = \"RateCardFormError\"\n this.fieldId = fieldId\n }\n}\n\nexport type MeterCollectionState =\n \"loading\" | \"permission\" | \"error\" | \"empty\" | \"ready\"\n\nexport function meterCollectionState(params: {\n pending: boolean\n error?: { status?: number } | null\n count: number\n}): MeterCollectionState {\n if (params.pending) return \"loading\"\n if (params.error?.status === 403) return \"permission\"\n if (params.error) return \"error\"\n if (params.count === 0) return \"empty\"\n return \"ready\"\n}\n\nexport function normalizeMeterKey(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^[-_]+|[-_]+$/g, \"\")\n}\n\nexport function meterFormValues(meter?: Meter): MeterFormValues {\n return {\n key: meter?.key ?? \"\",\n eventType: meter?.event_type ?? \"\",\n aggregation: meter?.aggregation === \"count\" ? \"count\" : \"sum\",\n valueProperty: meter?.value_property ?? \"\",\n unit: meter?.unit ?? \"\",\n groupBy: Object.entries(meter?.group_by ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n }\n}\n\nexport function buildMeterRequest(values: MeterFormValues): {\n key: string\n meter: UsageMeterRequest\n} {\n const key = normalizeMeterKey(values.key)\n if (!key) throw new Error(\"Enter a meter key.\")\n const eventType = values.eventType.trim()\n const valueProperty = values.valueProperty.trim()\n if (values.aggregation === \"sum\" && !valueProperty) {\n throw new Error(\"Sum meters require a value property.\")\n }\n const groupBy = rowsToMap(values.groupBy, \"group\")\n return {\n key,\n meter: {\n event_type: eventType,\n aggregation: values.aggregation,\n value_property: values.aggregation === \"sum\" ? valueProperty : \"\",\n unit: values.unit.trim() || undefined,\n group_by: groupBy,\n },\n }\n}\n\nexport function rateCardFormValues(\n card?: Pick<\n MeterRateCard,\n \"product_id\" | \"filter\" | \"price\" | \"allowance\"\n > | null\n): RateCardFormValues {\n const price = card?.price\n const matrix = price?.per_unit?.matrix\n const allowance = card?.allowance\n const allowanceMode: AllowanceMode =\n allowance?.included !== undefined ? \"included\" : \"none\"\n const currency = price?.currency ?? \"USD\"\n return {\n productId: card?.product_id ?? \"\",\n model: price?.model && price.model !== \"flat\" ? price.model : \"per_unit\",\n currency,\n unitAmount: moneyToInput(currency, price?.per_unit?.unit_amount),\n divideBy: integerToInput(price?.per_unit?.divide_by, \"1\"),\n round: price?.per_unit?.round ?? \"half_up\",\n maximumAmount: moneyToInput(currency, price?.per_unit?.maximum_amount),\n matrixEnabled: Boolean(matrix),\n matrixDimension: matrix?.dimension ?? \"\",\n matrixCells: Object.entries(matrix?.cells ?? {}).map(([key, cell]) => ({\n key,\n unitAmount: moneyToInput(currency, cell.unit_amount),\n maximumAmount: moneyToInput(currency, cell.maximum_amount),\n })),\n tierMode: \"graduated\",\n tiers: (\n price?.tiered?.tiers ?? [\n { up_to: null, unit_amount: \"0\", flat_amount: \"0\" },\n ]\n ).map((tier) => ({\n upTo: tier.up_to === null ? \"\" : String(tier.up_to),\n unitAmount: moneyToInput(currency, tier.unit_amount),\n flatAmount: moneyToInput(currency, tier.flat_amount),\n })),\n packageAmount: moneyToInput(currency, price?.package?.amount),\n packageSize: integerToInput(price?.package?.package_size, \"1\"),\n freeUnits: integerToInput(price?.package?.free_units),\n filters: Object.entries(card?.filter ?? {}).map(([key, values]) => ({\n key,\n value: values.join(\", \"),\n })),\n allowanceMode,\n allowanceIncluded: integerToInput(allowance?.included),\n }\n}\n\nexport function buildRateCardRequest(\n values: RateCardFormValues\n): DefaultUsageRateCardRequest {\n if (!values.productId) rateCardError(\"rate-product\", \"Select a product.\")\n const currency = values.currency.trim().toUpperCase()\n if (currencyScale(currency) === undefined) {\n rateCardError(\n \"rate-currency\",\n `Use a supported currency: ${supportedCurrencies.join(\", \")}.`\n )\n }\n\n const price = buildPrice(values, currency)\n const allowance = values.model === \"dynamic\" ? undefined : buildAllowance(values)\n return {\n product_id: values.productId,\n filter: filterRowsToMap(values.filters),\n price,\n ...(allowance ? { allowance } : {}),\n }\n}\n\nfunction buildPrice(values: RateCardFormValues, currency: string): RatePrice {\n if (values.model === \"dynamic\") return { model: \"dynamic\", currency }\n if (values.model === \"per_unit\") {\n const divideBy = positiveInteger(\n values.divideBy,\n \"Divisor\",\n \"rate-divide-by\"\n )\n const maximumAmount = optionalMoney(\n currency,\n values.maximumAmount,\n \"Maximum amount\",\n \"rate-maximum\"\n )\n if (values.matrixEnabled) {\n const dimension = values.matrixDimension.trim()\n if (!dimension) {\n rateCardError(\"matrix-dimension\", \"Select a matrix dimension.\")\n }\n if (values.matrixCells.length === 0) {\n rateCardError(\"matrix-add-cell\", \"Add at least one matrix cell.\")\n }\n const cells: NonNullable<\n NonNullable<RatePrice[\"per_unit\"]>[\"matrix\"]\n >[\"cells\"] = {}\n for (const [index, row] of values.matrixCells.entries()) {\n const key = row.key.trim()\n const fieldPrefix = `matrix-cell-${index}`\n if (!key) {\n rateCardError(\n `${fieldPrefix}-value`,\n \"Each matrix cell needs a value.\"\n )\n }\n if (cells[key]) {\n rateCardError(\n `${fieldPrefix}-value`,\n `Duplicate matrix value “${key}”.`\n )\n }\n cells[key] = {\n unit_amount: requiredMoney(\n currency,\n row.unitAmount,\n `Price for ${key}`,\n `${fieldPrefix}-unit-price`,\n true\n ),\n ...(optionalMoney(\n currency,\n row.maximumAmount,\n `Maximum for ${key}`,\n `${fieldPrefix}-maximum`\n ) !== \"0\"\n ? {\n maximum_amount: optionalMoney(\n currency,\n row.maximumAmount,\n `Maximum for ${key}`,\n `${fieldPrefix}-maximum`\n ),\n }\n : {}),\n }\n }\n return {\n model: \"per_unit\",\n currency,\n per_unit: {\n divide_by: divideBy,\n round: values.round,\n ...(maximumAmount !== \"0\" ? { maximum_amount: maximumAmount } : {}),\n matrix: { dimension, cells },\n },\n }\n }\n return {\n model: \"per_unit\",\n currency,\n per_unit: {\n unit_amount: requiredMoney(\n currency,\n values.unitAmount,\n \"Unit price\",\n \"rate-unit-amount\",\n true\n ),\n divide_by: divideBy,\n round: values.round,\n ...(maximumAmount !== \"0\" ? { maximum_amount: maximumAmount } : {}),\n },\n }\n }\n\n if (values.model === \"tiered\") {\n if (values.tiers.length === 0) {\n rateCardError(\"tier-add\", \"Add at least one tier.\")\n }\n const tiers = values.tiers.map((row, index) => {\n const last = index === values.tiers.length - 1\n const upTo = row.upTo.trim()\n if (last && upTo) {\n rateCardError(\n `tier-${index}-limit`,\n \"The final tier must be unbounded.\"\n )\n }\n if (!last && !upTo) {\n rateCardError(\n `tier-${index}-limit`,\n \"Only the final tier can be unbounded.\"\n )\n }\n return {\n up_to: last\n ? null\n : positiveInteger(\n upTo,\n `Tier ${index + 1} limit`,\n `tier-${index}-limit`\n ),\n unit_amount: requiredMoney(\n currency,\n row.unitAmount,\n `Tier ${index + 1} unit price`,\n `tier-${index}-unit-price`,\n true\n ),\n flat_amount: optionalMoney(\n currency,\n row.flatAmount,\n `Tier ${index + 1} flat amount`,\n `tier-${index}-flat-amount`\n ),\n }\n })\n for (let index = 1; index < tiers.length - 1; index += 1) {\n if ((tiers[index].up_to ?? 0) <= (tiers[index - 1].up_to ?? 0)) {\n rateCardError(`tier-${index}-limit`, \"Tier limits must increase.\")\n }\n }\n return {\n model: \"tiered\",\n currency,\n tiered: { mode: values.tierMode, tiers },\n }\n }\n\n return {\n model: \"package\",\n currency,\n package: {\n amount: requiredMoney(\n currency,\n values.packageAmount,\n \"Package price\",\n \"package-amount\"\n ),\n package_size: positiveInteger(\n values.packageSize,\n \"Package size\",\n \"package-size\"\n ),\n free_units: optionalWhole(values.freeUnits, \"Free units\", \"package-free\"),\n },\n }\n}\n\nfunction buildAllowance(values: RateCardFormValues): Allowance | undefined {\n if (values.allowanceMode === \"none\") return undefined\n return {\n included: optionalWhole(\n values.allowanceIncluded,\n \"Included allowance\",\n \"allowance-included\"\n ),\n }\n}\n\nfunction rowsToMap(rows: KeyValueRow[], name: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const row of rows) {\n const key = row.key.trim()\n const value = row.value.trim()\n if (!key || !value) throw new Error(`Each ${name} row needs both fields.`)\n if (result[key]) throw new Error(`Duplicate ${name} key “${key}”.`)\n result[key] = value\n }\n return result\n}\n\nfunction filterRowsToMap(rows: KeyValueRow[]): Record<string, string[]> {\n const result: Record<string, string[]> = {}\n for (const [index, row] of rows.entries()) {\n const key = row.key.trim()\n const values = [\n ...new Set(row.value.split(\",\").map((value) => value.trim())),\n ].filter(Boolean)\n if (!key) {\n rateCardError(\n `filter-${index}-dimension`,\n \"Select a dimension for this filter.\"\n )\n }\n if (values.length === 0) {\n rateCardError(\n `filter-${index}-values`,\n \"Enter at least one value for this filter.\"\n )\n }\n if (result[key]) {\n rateCardError(\n `filter-${index}-dimension`,\n `Duplicate filter dimension “${key}”.`\n )\n }\n result[key] = values\n }\n return result\n}\n\nfunction requiredMoney(\n currency: string,\n value: string,\n label: string,\n fieldId: string,\n allowZero = false\n): string {\n const amount = nativeAmountFromInput(value, currency)\n if (\n amount === null ||\n BigInt(amount) < 0n ||\n (!allowZero && BigInt(amount) === 0n)\n ) {\n rateCardError(\n fieldId,\n `${label} must be ${allowZero ? \"zero or more\" : \"greater than zero\"}.`\n )\n }\n return amount\n}\n\nfunction optionalMoney(\n currency: string,\n value: string,\n label: string,\n fieldId: string\n): string {\n if (!value.trim()) return \"0\"\n return requiredMoney(currency, value, label, fieldId, true)\n}\n\nfunction positiveInteger(\n value: string,\n label: string,\n fieldId: string\n): number {\n const amount = Number(value)\n if (!Number.isSafeInteger(amount) || amount <= 0) {\n rateCardError(fieldId, `${label} must be a positive whole number.`)\n }\n return amount\n}\n\nfunction optionalWhole(value: string, label: string, fieldId: string): number {\n if (!value.trim()) return 0\n const amount = Number(value)\n if (!Number.isSafeInteger(amount) || amount < 0) {\n rateCardError(fieldId, `${label} must be zero or a positive whole number.`)\n }\n return amount\n}\n\nfunction rateCardError(fieldId: string, message: string): never {\n throw new RateCardFormError(fieldId, message)\n}\n\nfunction moneyToInput(currency: string, value?: string): string {\n return value && value !== \"0\" ? nativeAmountToInput(value, currency) : \"\"\n}\n\nfunction integerToInput(value?: number, fallback = \"\"): string {\n return value ? String(value) : fallback\n}\n\nexport function summarizeRateCard(card?: MeterRateCard | null): string {\n if (!card) return \"Not priced\"\n const { price } = card\n const currency = price.currency ?? \"\"\n if (price.model === \"dynamic\") return `Event amount · ${currency}`\n if (price.model === \"per_unit\" && price.per_unit) {\n if (price.per_unit.matrix) {\n return `${Object.keys(price.per_unit.matrix.cells ?? {}).length} matrix rates · ${currency}`\n }\n return `${formatNativeAmount(price.per_unit.unit_amount ?? \"0\", currency)} per ${price.per_unit.divide_by || 1} units`\n }\n if (price.model === \"tiered\" && price.tiered) {\n return `${price.tiered.tiers?.length ?? 0} ${price.tiered.mode} tiers · ${currency}`\n }\n if (price.model === \"package\" && price.package) {\n return `${formatNativeAmount(price.package.amount ?? \"0\", currency)} per ${(price.package.package_size ?? 1).toLocaleString()} units`\n }\n return `Unsupported price · ${currency}`\n}\n\n// meterDefinitionLocked says why a meter's definition cannot change, given\n// whether this deployment accepts catalog writes.\nexport function meterDefinitionLocked(\n meter: Meter,\n writesAllowed: boolean\n): string | null {\n if (!writesAllowed) return \"Catalog updates are disabled.\"\n if (meter.has_activity) return \"Meter definitions lock after the first event.\"\n return null\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Add01Icon, Delete02Icon, Edit02Icon } from \"@hugeicons/core-free-icons\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\n\nimport { FormFieldErrors } from \"#orck/admin/components/form-field-errors\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport type { Meter } from \"#orck/client/generated/wire\"\nimport { DIALOG_FORM } from \"#orck/admin/lib/dialog-width\"\n\nimport {\n buildMeterRequest,\n meterDefinitionLocked,\n meterFormValues,\n} from \"./metering-model\"\n\nexport function MeterFormDialog({\n meter,\n writesAllowed,\n}: {\n meter?: Meter\n writesAllowed: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [submitError, setSubmitError] = React.useState(\"\")\n const queryClient = useQueryClient()\n const save = useMutation(adminMutations.putUsageMeter(queryClient))\n const locked = meter ? meterDefinitionLocked(meter, writesAllowed) : null\n const form = useForm({\n defaultValues: meterFormValues(meter),\n onSubmit: async ({ value }) => {\n setSubmitError(\"\")\n try {\n const request = buildMeterRequest(value)\n // The revision this form read: a meter another edit changed since is\n // refused, and a new one must still be new.\n request.meter.expected_revision = meter?.revision ?? 0\n await save.mutateAsync(request)\n toast.success(meter ? \"Meter updated\" : \"Meter created\")\n setOpen(false)\n form.reset()\n } catch (error) {\n if (error instanceof Error && !(\"status\" in error)) {\n setSubmitError(error.message)\n return\n }\n toastApiError(error, meter ? \"Update meter\" : \"Create meter\")\n }\n },\n })\n\n if (locked) {\n return (\n <Button variant=\"outline\" size=\"sm\" disabled title={locked}>\n <HugeiconsIcon icon={Edit02Icon} className=\"size-4\" />\n <AdminMessage id={\"Edit definition\"} />\n </Button>\n )\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n setSubmitError(\"\")\n if (!next) form.reset()\n }}\n >\n <DialogTrigger\n render={\n <Button variant={meter ? \"outline\" : \"default\"} size=\"sm\">\n <HugeiconsIcon\n icon={meter ? Edit02Icon : Add01Icon}\n className=\"size-4\"\n />\n {meter ? \"Edit definition\" : \"Create meter\"}\n </Button>\n }\n />\n <DialogContent className={DIALOG_FORM}>\n <form\n className=\"grid gap-5\"\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <DialogHeader>\n <DialogTitle>{meter ? \"Edit meter\" : \"Create meter\"}</DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Define the event fields OpenRails will aggregate. Your host still reports each event through the usage API.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"grid gap-4\">\n <form.Field\n name=\"key\"\n validators={{\n onBlur: ({ value }) =>\n value.trim() ? undefined : \"Enter a meter key.\",\n }}\n >\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-key\")}>\n <AdminMessage id={\"Key\"} />\n </Label>\n <Input\n id={adminId(\"meter-key\")}\n value={field.state.value}\n onChange={(event) => field.handleChange(event.target.value)}\n onBlur={field.handleBlur}\n disabled={Boolean(meter)}\n placeholder={adminText(\"api-tokens\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Stable identifier. It cannot be renamed after creation.\"\n }\n />\n </p>\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <form.Field name=\"eventType\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-event-type\")}>\n <AdminMessage id={\"Event type\"} />\n </Label>\n <Input\n id={adminId(\"meter-event-type\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"token.used\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage id={\"Leave blank to use the meter key.\"} />\n </p>\n </div>\n )}\n </form.Field>\n <form.Field name=\"unit\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-unit\")}>\n <AdminMessage id={\"Unit\"} />\n </Label>\n <Input\n id={adminId(\"meter-unit\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n placeholder={adminText(\"tokens\")}\n autoComplete=\"off\"\n />\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Human-readable quantity shown in billing.\"}\n />\n </p>\n </div>\n )}\n </form.Field>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <form.Field name=\"aggregation\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-aggregation\")}>\n <AdminMessage id={\"Aggregation\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"sum\" | \"count\")\n }\n >\n <SelectTrigger\n id={adminId(\"meter-aggregation\")}\n className=\"w-full\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"sum\">\n <AdminMessage id={\"Sum a numeric field\"} />\n </SelectItem>\n <SelectItem value=\"count\">\n <AdminMessage id={\"Count events\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.aggregation}>\n {(aggregation) =>\n aggregation === \"sum\" ? (\n <form.Field\n name=\"valueProperty\"\n validators={{\n onBlur: ({ value }) =>\n value.trim()\n ? undefined\n : \"Sum meters require a value property.\",\n }}\n >\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"meter-value-property\")}>\n <AdminMessage id={\"Value property\"} />\n </Label>\n <Input\n id={adminId(\"meter-value-property\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value)\n }\n onBlur={field.handleBlur}\n placeholder={adminText(\"tokens\")}\n autoComplete=\"off\"\n />\n <FormFieldErrors errors={field.state.meta.errors} />\n </div>\n )}\n </form.Field>\n ) : (\n <div className=\"self-end rounded-lg bg-muted/50 px-3 py-2 text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Count uses one unit for every matching event.\"}\n />\n </div>\n )\n }\n </form.Subscribe>\n </div>\n\n <form.Field name=\"groupBy\" mode=\"array\">\n {(field) => (\n <fieldset className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <Label>\n <AdminMessage id={\"Dimensions\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Register event properties used by filters or matrix rates.\"\n }\n />\n </p>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => field.pushValue({ key: \"\", value: \"\" })}\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add dimension\"} />\n </Button>\n </div>\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid grid-cols-[1fr_1fr_auto] gap-2\"\n >\n <Input\n aria-label={`Dimension ${index + 1} name`}\n value={row.key}\n onChange={(event) =>\n form.setFieldValue(\n `groupBy[${index}].key`,\n event.target.value\n )\n }\n placeholder={adminText(\"model\")}\n autoComplete=\"off\"\n />\n <Input\n aria-label={`Dimension ${index + 1} property`}\n value={row.value}\n onChange={(event) =>\n form.setFieldValue(\n `groupBy[${index}].value`,\n event.target.value\n )\n }\n placeholder={adminText(\"metadata.model\")}\n autoComplete=\"off\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Remove dimension ${index + 1}`}\n onClick={() => field.removeValue(index)}\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n </Button>\n </div>\n ))}\n </fieldset>\n )}\n </form.Field>\n </div>\n\n {submitError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {submitError}\n </p>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <form.Subscribe selector={(state) => state.isSubmitting}>\n {(submitting) => (\n <Button type=\"submit\" disabled={submitting || save.isPending}>\n {submitting || save.isPending ? \"Saving…\" : \"Save meter\"}\n </Button>\n )}\n </form.Subscribe>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Add01Icon,\n Delete02Icon,\n Edit02Icon,\n Money03Icon,\n} from \"@hugeicons/core-free-icons\"\nimport {\n useForm,\n type FormAsyncValidateOrFn,\n type FormValidateOrFn,\n type ReactFormExtendedApi,\n} from \"@tanstack/react-form\"\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\nimport { Link } from \"#orck/admin/router\"\n\nimport { useConfirm } from \"#orck/admin/lib/confirm\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"#orck/admin/components/ui/dialog\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Label } from \"#orck/admin/components/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\nimport { Switch } from \"#orck/admin/components/ui/switch\"\nimport type { Meter, Product } from \"#orck/client/generated/wire\"\nimport type { DefaultUsageRateCardRequest } from \"#orck/admin/lib/api/endpoints\"\nimport { DIALOG_WIDE } from \"#orck/admin/lib/dialog-width\"\n\nimport {\n buildRateCardRequest,\n RateCardFormError,\n rateCardFormValues,\n summarizeRateCard,\n} from \"./metering-model\"\n\ninterface FormIssue {\n fieldId: string\n message: string\n}\n\nconst RateCardIssueContext = React.createContext<FormIssue | null>(null)\n\nexport function RateCardEditor({\n meter,\n writesAllowed = false,\n products,\n productsPending = false,\n productsError = false,\n productsForbidden = false,\n}: {\n meter: Meter\n writesAllowed?: boolean\n products: Product[]\n productsPending?: boolean\n productsError?: boolean\n productsForbidden?: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { id: adminId, text: adminText } = useAdminUI()\n\n const [open, setOpen] = React.useState(false)\n const [submitError, setSubmitError] = React.useState<FormIssue | null>(null)\n const confirm = useConfirm()\n const queryClient = useQueryClient()\n const saveDefault = useMutation(\n adminMutations.putDefaultUsageRateCard(queryClient)\n )\n const activeProducts = products.filter((product) => !product.archived)\n const existing = meter.rate_card\n const savePending = saveDefault.isPending\n const form = useForm({\n defaultValues: rateCardFormValues(existing),\n onSubmit: async ({ value }) => {\n setSubmitError(null)\n try {\n const rateCard = buildRateCardRequest(value)\n if (\n existing &&\n !(await confirm({\n title: \"Replace the default rate?\",\n description:\n \"Amounts already charged do not change. New events use the new rate; admitted work keeps its pinned rate.\",\n confirmLabel: \"Replace rate\",\n cancelLabel: \"Keep current rate\",\n }))\n )\n return\n await persist(rateCard)\n } catch (error) {\n if (error instanceof RateCardFormError) {\n setSubmitError({\n fieldId: error.fieldId,\n message: error.message,\n })\n requestAnimationFrame(() => {\n document.getElementById(adminId(error.fieldId))?.focus()\n })\n return\n }\n toastApiError(error, \"Save rate card\")\n }\n },\n })\n\n const persist = async (rateCard: DefaultUsageRateCardRequest) => {\n try {\n await saveDefault.mutateAsync({ meter, rateCard })\n toast.success(existing ? \"Default rate replaced\" : \"Default rate added\")\n setOpen(false)\n } catch (error) {\n toastApiError(error, \"Save default rate\")\n }\n }\n\n if (!writesAllowed || !meter.billing_supported) {\n return null\n }\n\n return (\n <RateCardIssueContext.Provider value={submitError}>\n <Dialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next)\n setSubmitError(null)\n if (!next) form.reset()\n }}\n >\n <DialogTrigger\n render={\n <Button variant={existing ? \"outline\" : \"default\"} size=\"sm\">\n <HugeiconsIcon\n icon={existing ? Edit02Icon : Money03Icon}\n className=\"size-4\"\n />\n {existing ? \"Edit default rate\" : \"Add default rate\"}\n </Button>\n }\n />\n <DialogContent\n className={`${DIALOG_WIDE} max-h-[calc(100dvh-2rem)] overflow-y-auto`}\n >\n <form\n className=\"grid gap-6\"\n onChange={() => setSubmitError(null)}\n onSubmit={(event) => {\n event.preventDefault()\n event.stopPropagation()\n void form.handleSubmit()\n }}\n >\n <DialogHeader>\n <DialogTitle>\n {existing ? \"Edit default rate\" : \"Add default rate\"}\n </DialogTitle>\n <DialogDescription>\n <AdminMessage\n id={\n \"Set the price that charges every customer's usage as it is recorded. Money is entered in major currency units.\"\n }\n />\n </DialogDescription>\n </DialogHeader>\n\n <section className=\"grid gap-4\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Product and model\"} />\n </h3>\n {productsPending ? (\n <div className=\"rounded-lg bg-muted/50 p-3 text-sm text-muted-foreground\">\n <AdminMessage id={\"Loading products…\"} />\n </div>\n ) : productsError ? (\n <div\n role=\"alert\"\n className=\"rounded-lg bg-muted/50 p-3 text-sm text-destructive\"\n >\n {productsForbidden\n ? \"Your role cannot read products for this merchant.\"\n : \"Products could not be loaded. Close this form and try again.\"}\n </div>\n ) : activeProducts.length === 0 ? (\n <div className=\"rounded-lg bg-muted/50 p-3 text-sm\">\n <p>\n <AdminMessage id={\"No active products are available.\"} />\n </p>\n <Link\n className=\"text-primary underline underline-offset-3\"\n to=\"/catalog\"\n >\n <AdminMessage id={\"Create or activate a product first\"} />\n </Link>\n </div>\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"productId\">\n {(field) => (\n <div className=\"grid gap-1.5 sm:col-span-2\">\n <Label htmlFor={adminId(\"rate-product\")}>\n <AdminMessage id={\"Product\"} />\n </Label>\n <Select\n value={field.state.value || null}\n onValueChange={(value) =>\n field.handleChange(value ?? \"\")\n }\n >\n <SelectTrigger\n id={adminId(\"rate-product\")}\n className=\"w-full\"\n {...fieldIssueProps(\"rate-product\", submitError)}\n >\n <SelectValue\n placeholder={adminText(\"Select product\")}\n />\n </SelectTrigger>\n <SelectContent>\n {activeProducts.map((product) => (\n <SelectItem key={product.id} value={product.id}>\n {product.display_name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId=\"rate-product\" />\n </div>\n )}\n </form.Field>\n <form.Field name=\"currency\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"rate-currency\")}>\n <AdminMessage id={\"Currency\"} />\n </Label>\n <Input\n id={adminId(\"rate-currency\")}\n value={field.state.value}\n onChange={(event) =>\n field.handleChange(event.target.value.toUpperCase())\n }\n maxLength={3}\n placeholder={adminText(\"USD\")}\n className=\"uppercase\"\n autoComplete=\"off\"\n {...fieldIssueProps(\"rate-currency\", submitError)}\n />\n <FieldIssue fieldId=\"rate-currency\" />\n </div>\n )}\n </form.Field>\n <PricingModelField form={form} meter={meter} />\n </div>\n )}\n </section>\n\n <form.Subscribe selector={(state) => state.values.model}>\n {(model) => (\n <section className=\"grid gap-4 border-t pt-5\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Rate\"} />\n </h3>\n {model === \"per_unit\" && (\n <PerUnitFields form={form} meter={meter} />\n )}\n {model === \"tiered\" && <TieredFields form={form} />}\n {model === \"package\" && <PackageFields form={form} />}\n {model === \"dynamic\" && (\n <p className=\"text-sm text-muted-foreground\">\n <AdminMessage id={\"Charge each event’s stated amount when it reports positive units. Missing amounts or zero units charge nothing.\"} />\n </p>\n )}\n </section>\n )}\n </form.Subscribe>\n\n <FilterFields form={form} meter={meter} />\n <form.Subscribe selector={(state) => state.values.model}>\n {(model) => model !== \"dynamic\" && <AllowanceFields form={form} />}\n </form.Subscribe>\n\n <form.Subscribe selector={(state) => state.values}>\n {(values) => <RateSummary values={values} />}\n </form.Subscribe>\n\n {submitError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {submitError.message}\n </p>\n )}\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n >\n <AdminMessage id={\"Cancel\"} />\n </Button>\n <Button\n type=\"submit\"\n disabled={\n savePending ||\n productsPending ||\n productsError ||\n activeProducts.length === 0\n }\n >\n {savePending\n ? \"Saving…\"\n : existing\n ? \"Review replacement\"\n : \"Save default rate\"}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </RateCardIssueContext.Provider>\n )\n}\n\ntype RateCardFormValuesCompat = ReturnType<typeof rateCardFormValues>\ntype RateCardValidator = FormValidateOrFn<RateCardFormValuesCompat> | undefined\ntype RateCardAsyncValidator =\n FormAsyncValidateOrFn<RateCardFormValuesCompat> | undefined\ntype MeteringForm = ReactFormExtendedApi<\n RateCardFormValuesCompat,\n RateCardValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardValidator,\n RateCardAsyncValidator,\n RateCardAsyncValidator,\n unknown\n>\n\nfunction PricingModelField({\n form,\n meter,\n}: {\n form: MeteringForm\n meter: Meter\n}) {\n const { id: adminId } = useAdminUI()\n return (\n <form.Field name=\"model\">\n {(field) => (\n <div className=\"grid gap-1.5 sm:col-span-3\">\n <Label htmlFor={adminId(\"rate-model\")}>\n <AdminMessage id={\"Pricing model\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"per_unit\" | \"tiered\" | \"package\" | \"dynamic\")\n }\n >\n <SelectTrigger id={adminId(\"rate-model\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"per_unit\">\n <AdminMessage id={\"Per unit\"} />\n </SelectItem>\n <SelectItem value=\"tiered\">\n <AdminMessage id={\"Tiered\"} />\n </SelectItem>\n <SelectItem value=\"package\">\n <AdminMessage id={\"Package\"} />\n </SelectItem>\n <SelectItem value=\"dynamic\" disabled={meter.aggregation !== \"sum\"}>\n <AdminMessage id={\"Dynamic (event amount)\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n )\n}\n\nfunction PerUnitFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n return (\n <>\n <form.Field name=\"matrixEnabled\">\n {(field) => (\n <div className=\"flex items-center justify-between gap-4 rounded-lg bg-muted/50 px-3 py-2.5\">\n <div>\n <Label htmlFor={adminId(\"rate-matrix\")}>\n <AdminMessage id={\"Use matrix rates\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Price each value of one registered dimension separately.\"\n }\n />\n </p>\n </div>\n <Switch\n id={adminId(\"rate-matrix\")}\n checked={field.state.value}\n onCheckedChange={field.handleChange}\n disabled={Object.keys(meter.group_by ?? {}).length === 0}\n />\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.matrixEnabled}>\n {(matrixEnabled) =>\n matrixEnabled ? (\n <MatrixFields form={form} meter={meter} />\n ) : (\n <form.Field name=\"unitAmount\">\n {(field) => (\n <MoneyField\n id={\"rate-unit-amount\"}\n label={adminText(\"Price per divisor\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder=\"0.0025\"\n />\n )}\n </form.Field>\n )\n }\n </form.Subscribe>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"divideBy\">\n {(field) => (\n <TextField\n id={\"rate-divide-by\"}\n label={adminText(\"Divisor\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1\"\n />\n )}\n </form.Field>\n <form.Field name=\"round\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"rate-round\")}>\n <AdminMessage id={\"Rounding\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"half_up\" | \"up\" | \"down\")\n }\n >\n <SelectTrigger id={adminId(\"rate-round\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"half_up\">\n <AdminMessage id={\"Nearest\"} />\n </SelectItem>\n <SelectItem value=\"up\">\n <AdminMessage id={\"Up\"} />\n </SelectItem>\n <SelectItem value=\"down\">\n <AdminMessage id={\"Down\"} />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Field name=\"maximumAmount\">\n {(field) => (\n <MoneyField\n id={\"rate-maximum\"}\n label={adminText(\"Period maximum\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder={adminText(\"No maximum\")}\n />\n )}\n </form.Field>\n </div>\n </>\n )\n}\n\nfunction MatrixFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n const formIssue = React.useContext(RateCardIssueContext)\n return (\n <>\n <form.Field name=\"matrixDimension\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"matrix-dimension\")}>\n <AdminMessage id={\"Dimension\"} />\n </Label>\n <Select\n value={field.state.value || null}\n onValueChange={(value) => field.handleChange(value ?? \"\")}\n >\n <SelectTrigger\n id={adminId(\"matrix-dimension\")}\n className=\"w-full\"\n {...fieldIssueProps(\"matrix-dimension\", formIssue)}\n >\n <SelectValue placeholder={adminText(\"Select dimension\")} />\n </SelectTrigger>\n <SelectContent>\n {Object.keys(meter.group_by ?? {}).map((key) => (\n <SelectItem key={key} value={key}>\n {key}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId=\"matrix-dimension\" />\n </div>\n )}\n </form.Field>\n <form.Field name=\"matrixCells\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <Label>\n <AdminMessage id={\"Matrix cells\"} />\n </Label>\n <Button\n id={adminId(\"matrix-add-cell\")}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n field.pushValue({\n key: \"\",\n unitAmount: \"\",\n maximumAmount: \"\",\n })\n }\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add cell\"} />\n </Button>\n </div>\n <FieldIssue fieldId=\"matrix-add-cell\" />\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_1fr_1fr_auto]\">\n <span>\n <AdminMessage id=\"Value\" />\n </span>\n <span>\n <AdminMessage id=\"Unit price\" />\n </span>\n <span>\n <AdminMessage id=\"Maximum\" />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_1fr_1fr_auto]\"\n >\n <RowTextField\n id={`matrix-cell-${index}-value`}\n label={adminText(\"Value\")}\n value={row.key}\n onChange={(value) =>\n form.setFieldValue(`matrixCells[${index}].key`, value)\n }\n placeholder={adminText(\"gpt-5\")}\n />\n <RowTextField\n id={`matrix-cell-${index}-unit-price`}\n label={adminText(\"Unit price\")}\n value={row.unitAmount}\n onChange={(value) =>\n form.setFieldValue(\n `matrixCells[${index}].unitAmount`,\n value\n )\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Price\")}\n />\n <RowTextField\n id={`matrix-cell-${index}-maximum`}\n label={adminText(\"Maximum\")}\n value={row.maximumAmount}\n onChange={(value) =>\n form.setFieldValue(\n `matrixCells[${index}].maximumAmount`,\n value\n )\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Maximum\")}\n />\n <RemoveRowButton\n label={`Remove matrix cell ${index + 1}`}\n onClick={() => field.removeValue(index)}\n />\n </div>\n ))}\n </div>\n )}\n </form.Field>\n </>\n )\n}\n\nfunction TieredFields({ form }: { form: MeteringForm }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n return (\n <>\n <form.Field name=\"tiers\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <Label>\n <AdminMessage id={\"Tiers\"} />\n </Label>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\"Leave the final limit blank for the unbounded tier.\"}\n />\n </p>\n </div>\n <Button\n id={adminId(\"tier-add\")}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n field.pushValue({ upTo: \"\", unitAmount: \"\", flatAmount: \"\" })\n }\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add tier\"} />\n </Button>\n </div>\n <FieldIssue fieldId=\"tier-add\" />\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_1fr_1fr_auto]\">\n <span>\n <AdminMessage id={\"Upper limit\"} />\n </span>\n <span>\n <AdminMessage id={\"Unit price\"} />\n </span>\n <span>\n <AdminMessage id={\"Flat amount\"} />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_1fr_1fr_auto]\"\n >\n <RowTextField\n id={`tier-${index}-limit`}\n label={adminText(\"Upper limit\")}\n value={row.upTo}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].upTo`, value)\n }\n inputMode=\"numeric\"\n placeholder={\n index === field.state.value.length - 1\n ? \"No limit\"\n : \"Up to\"\n }\n />\n <RowTextField\n id={`tier-${index}-unit-price`}\n label={adminText(\"Unit price\")}\n value={row.unitAmount}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].unitAmount`, value)\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Unit price\")}\n />\n <RowTextField\n id={`tier-${index}-flat-amount`}\n label={adminText(\"Flat amount\")}\n value={row.flatAmount}\n onChange={(value) =>\n form.setFieldValue(`tiers[${index}].flatAmount`, value)\n }\n inputMode=\"decimal\"\n placeholder={adminText(\"Flat amount\")}\n />\n <RemoveRowButton\n label={`Remove tier ${index + 1}`}\n onClick={() => field.removeValue(index)}\n disabled={field.state.value.length === 1}\n />\n </div>\n ))}\n </div>\n )}\n </form.Field>\n </>\n )\n}\n\nfunction PackageFields({ form }: { form: MeteringForm }) {\n const { text: adminText } = useAdminUI()\n\n return (\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <form.Field name=\"packageAmount\">\n {(field) => (\n <MoneyField\n id={\"package-amount\"}\n label={adminText(\"Package price\")}\n value={field.state.value}\n onChange={field.handleChange}\n placeholder=\"10.00\"\n />\n )}\n </form.Field>\n <form.Field name=\"packageSize\">\n {(field) => (\n <TextField\n id={\"package-size\"}\n label={adminText(\"Units per package\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1000\"\n />\n )}\n </form.Field>\n <form.Field name=\"freeUnits\">\n {(field) => (\n <TextField\n id={\"package-free\"}\n label={adminText(\"Free units\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"0\"\n />\n )}\n </form.Field>\n </div>\n )\n}\n\nfunction FilterFields({ form, meter }: { form: MeteringForm; meter: Meter }) {\n const { id: adminId, text: adminText } = useAdminUI()\n\n const formIssue = React.useContext(RateCardIssueContext)\n return (\n <section className=\"grid gap-3 border-t pt-5\">\n <div>\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Event filters\"} />\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n <AdminMessage\n id={\n \"Optional. Only events with one of the listed dimension values are rated.\"\n }\n />\n </p>\n </div>\n <form.Field name=\"filters\" mode=\"array\">\n {(field) => (\n <div className=\"grid gap-2\">\n {field.state.value.length > 0 && (\n <div className=\"hidden gap-2 px-0.5 text-xs text-muted-foreground sm:grid sm:grid-cols-[1fr_2fr_auto]\">\n <span>\n <AdminMessage id={\"Dimension\"} />\n </span>\n <span>\n <AdminMessage id={\"Values\"} />\n </span>\n <span className=\"size-8\" aria-hidden=\"true\" />\n </div>\n )}\n {field.state.value.map((row, index) => (\n <div\n key={index}\n className=\"grid gap-2 sm:grid-cols-[1fr_2fr_auto]\"\n >\n <div className=\"grid gap-1.5\">\n <Label\n htmlFor={adminId(`filter-${index}-dimension`)}\n className=\"text-xs text-muted-foreground sm:sr-only\"\n >\n <AdminMessage id={\"Dimension\"} />\n </Label>\n <Select\n value={row.key || null}\n onValueChange={(value) =>\n form.setFieldValue(`filters[${index}].key`, value ?? \"\")\n }\n >\n <SelectTrigger\n id={adminId(`filter-${index}-dimension`)}\n className=\"w-full\"\n {...fieldIssueProps(\n `filter-${index}-dimension`,\n formIssue\n )}\n >\n <SelectValue placeholder={adminText(\"Dimension\")} />\n </SelectTrigger>\n <SelectContent>\n {Object.keys(meter.group_by ?? {}).map((key) => (\n <SelectItem key={key} value={key}>\n {key}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldIssue fieldId={`filter-${index}-dimension`} />\n </div>\n <RowTextField\n id={`filter-${index}-values`}\n label={adminText(\"Values\")}\n value={row.value}\n onChange={(value) =>\n form.setFieldValue(`filters[${index}].value`, value)\n }\n placeholder={adminText(\"eu, us\")}\n />\n <RemoveRowButton\n label={`Remove filter ${index + 1}`}\n onClick={() => field.removeValue(index)}\n />\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-fit\"\n disabled={Object.keys(meter.group_by ?? {}).length === 0}\n onClick={() => field.pushValue({ key: \"\", value: \"\" })}\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <AdminMessage id={\"Add filter\"} />\n </Button>\n </div>\n )}\n </form.Field>\n </section>\n )\n}\n\nfunction AllowanceFields({ form }: { form: MeteringForm }) {\n const { id: adminId, text: adminText } = useAdminUI()\n return (\n <section className=\"grid gap-4 border-t pt-5\">\n <h3 className=\"text-sm font-medium\">\n <AdminMessage id={\"Allowance\"} />\n </h3>\n <form.Field name=\"allowanceMode\">\n {(field) => (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(\"allowance-mode\")}>\n <AdminMessage id={\"Included usage\"} />\n </Label>\n <Select\n value={field.state.value}\n onValueChange={(value) =>\n field.handleChange(value as \"none\" | \"included\")\n }\n >\n <SelectTrigger id={adminId(\"allowance-mode\")} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">\n <AdminMessage id=\"No allowance\" />\n </SelectItem>\n <SelectItem value=\"included\">\n <AdminMessage id=\"Fixed included units\" />\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </form.Field>\n <form.Subscribe selector={(state) => state.values.allowanceMode}>\n {(mode) =>\n mode === \"included\" ? (\n <form.Field name=\"allowanceIncluded\">\n {(field) => (\n <TextField\n id={\"allowance-included\"}\n label={adminText(\"Included units per period\")}\n value={field.state.value}\n onChange={field.handleChange}\n inputMode=\"numeric\"\n placeholder=\"1000\"\n />\n )}\n </form.Field>\n ) : null\n }\n </form.Subscribe>\n </section>\n )\n}\n\nfunction RateSummary({ values }: { values: RateCardFormValuesCompat }) {\n let summary = \"Complete the required fields to preview this rate.\"\n try {\n const request = buildRateCardRequest(values)\n summary = summarizeRateCard({\n price: request.price,\n } as Meter[\"rate_card\"])\n if (request.allowance?.included !== undefined) {\n summary += ` · ${request.allowance.included.toLocaleString()} included`\n }\n } catch {\n // Incomplete form state is expected while editing.\n }\n return (\n <section className=\"rounded-lg bg-muted/50 px-3 py-2.5\" aria-live=\"polite\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n <AdminMessage id={\"Rate preview\"} />\n </p>\n <p className=\"mt-1 text-sm font-medium tabular-nums\">{summary}</p>\n </section>\n )\n}\n\nfunction TextField({\n id,\n label,\n value,\n onChange,\n placeholder,\n inputMode,\n}: {\n id: string\n label: string\n value: string\n onChange: (value: string) => void\n placeholder?: string\n inputMode?: \"numeric\" | \"decimal\"\n}) {\n const { id: adminId } = useAdminUI()\n\n const issue = useRateCardIssue(id)\n return (\n <div className=\"grid gap-1.5\">\n <Label htmlFor={adminId(id)}>{label}</Label>\n <Input\n id={adminId(id)}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n inputMode={inputMode}\n autoComplete=\"off\"\n {...fieldIssueProps(id, issue ? { fieldId: id, message: issue } : null)}\n />\n <FieldIssue fieldId={id} />\n </div>\n )\n}\n\nfunction MoneyField(props: React.ComponentProps<typeof TextField>) {\n return <TextField {...props} inputMode=\"decimal\" />\n}\n\nfunction RowTextField({\n id,\n label,\n value,\n onChange,\n placeholder,\n inputMode,\n}: {\n id: string\n label: string\n value: string\n onChange: (value: string) => void\n placeholder?: string\n inputMode?: \"numeric\" | \"decimal\"\n}) {\n const { id: adminId } = useAdminUI()\n\n const issue = useRateCardIssue(id)\n return (\n <div className=\"grid gap-1.5\">\n <Label\n htmlFor={adminId(id)}\n className=\"text-xs text-muted-foreground sm:sr-only\"\n >\n {label}\n </Label>\n <Input\n id={adminId(id)}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n placeholder={placeholder}\n inputMode={inputMode}\n autoComplete=\"off\"\n {...fieldIssueProps(id, issue ? { fieldId: id, message: issue } : null)}\n />\n <FieldIssue fieldId={id} />\n </div>\n )\n}\n\nfunction useRateCardIssue(fieldId: string): string | undefined {\n const issue = React.useContext(RateCardIssueContext)\n return issue?.fieldId === fieldId ? issue.message : undefined\n}\n\nfunction fieldIssueProps(fieldId: string, issue: FormIssue | null) {\n const invalid = issue?.fieldId === fieldId\n return {\n \"aria-invalid\": invalid || undefined,\n \"aria-describedby\": invalid ? `${fieldId}-error` : undefined,\n }\n}\n\nfunction FieldIssue({ fieldId }: { fieldId: string }) {\n const { id: adminId } = useAdminUI()\n\n const message = useRateCardIssue(fieldId)\n if (!message) return null\n return (\n <p id={adminId(`${fieldId}-error`)} className=\"text-xs text-destructive\">\n {message}\n </p>\n )\n}\n\nfunction RemoveRowButton({\n label,\n onClick,\n disabled,\n}: {\n label: string\n onClick: () => void\n disabled?: boolean\n}) {\n return (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className=\"self-end\"\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n </Button>\n )\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Activity01Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n Delete02Icon,\n InformationCircleIcon,\n Search01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\"\nimport * as React from \"react\"\nimport { Link, useNavigate, useParams } from \"#orck/admin/router\"\n\nimport { CursorPager } from \"#orck/admin/components/cursor-pager\"\nimport { useConfirm } from \"#orck/admin/lib/confirm\"\nimport { useCursorPages } from \"#orck/admin/lib/cursor-pages\"\nimport { LinkedTableRow } from \"#orck/admin/components/linked-table-row\"\nimport { Badge } from \"#orck/admin/components/ui/badge\"\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport { Skeleton } from \"#orck/admin/components/ui/skeleton\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"#orck/admin/components/ui/table\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport type { Meter } from \"#orck/client/generated/wire\"\nimport { formatDate } from \"#orck/admin/lib/format\"\n\nimport { useCatalogWrites } from \"#orck/admin/lib/capabilities\"\n\nimport { MeterFormDialog } from \"./meter-form\"\nimport {\n meterCollectionState,\n meterDefinitionLocked,\n summarizeRateCard,\n} from \"./metering-model\"\nimport { RateCardEditor } from \"./rate-card-editor\"\n\nconst PAGE_SIZE = 200\n\nexport function CatalogMeteringPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const [search, setSearch] = React.useState(\"\")\n const pages = useCursorPages(\"\", PAGE_SIZE)\n const { data, isPending, error, refetch } = useQuery(\n adminQueries.usageMeters(pages.size, pages.cursor)\n )\n const writesAllowed = useCatalogWrites()\n const meters = data?.data ?? []\n const normalizedSearch = search.trim().toLowerCase()\n const filtered = normalizedSearch\n ? meters.filter((meter) =>\n [\n meter.key,\n meter.event_type,\n meter.aggregation,\n meter.unit,\n meter.rate_card?.product_key,\n ].some((value) => value?.toLowerCase().includes(normalizedSearch))\n )\n : meters\n const state = meterCollectionState({\n pending: isPending,\n error: error instanceof ApiError ? error : error ? { status: 500 } : null,\n count: meters.length,\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-5\">\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div className=\"max-w-2xl\">\n <h1 className=\"text-2xl font-semibold tracking-tight text-balance\">\n <AdminMessage id={\"Metering\"} />\n </h1>\n <p className=\"mt-1 text-sm text-pretty text-muted-foreground\">\n <AdminMessage\n id={\n \"Define usage streams and the default rates charged when usage is recorded. Applications report the events separately.\"\n }\n />\n </p>\n </div>\n {writesAllowed && state !== \"permission\" && (\n <MeterFormDialog writesAllowed />\n )}\n </div>\n\n {data && !writesAllowed && (\n <ReadOnlyNotice>\n <AdminMessage\n id={\n \"Catalog updates are disabled. Meter definitions and rates are visible here; changes require the host operator.\"\n }\n />\n </ReadOnlyNotice>\n )}\n\n {state === \"loading\" ? (\n <MeteringSkeleton />\n ) : state === \"permission\" ? (\n <PageMessage\n title={adminText(\"Metering access is restricted\")}\n description={adminText(\n \"Your role does not have permission to read the merchant catalog.\"\n )}\n />\n ) : state === \"error\" ? (\n <PageMessage\n title={adminText(\"Metering could not be loaded\")}\n description={adminText(\n \"Try again. If the problem continues, check the OpenRails API logs.\"\n )}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refetch()}>\n <AdminMessage id={\"Try again\"} />\n </Button>\n }\n />\n ) : state === \"empty\" ? (\n <PageMessage\n title={adminText(\"No usage meters yet\")}\n description={adminText(\n \"Create a meter to describe the events your application will report and bill.\"\n )}\n action={writesAllowed ? <MeterFormDialog writesAllowed /> : undefined}\n />\n ) : (\n <>\n <div className=\"relative w-full sm:max-w-xs\">\n <HugeiconsIcon\n icon={Search01Icon}\n className=\"absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n className=\"pl-8\"\n placeholder={adminText(\"Filter this page…\")}\n aria-label={adminText(\"Filter meters on this page\")}\n />\n </div>\n <div className=\"max-w-full overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Meter\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Event\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Aggregation\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Default price\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Product\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Activity\"} />\n </TableHead>\n <TableHead className=\"text-muted-foreground\">\n <AdminMessage id={\"Last event\"} />\n </TableHead>\n <TableHead>\n <span className=\"sr-only\">\n <AdminMessage id={\"Open\"} />\n </span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {filtered.map((meter) => (\n <MeterRow key={meter.key} meter={meter} />\n ))}\n {filtered.length === 0 && (\n <TableRow>\n <TableCell\n colSpan={9}\n className=\"h-24 text-center text-muted-foreground\"\n >\n <AdminMessage id={\"No meters on this page match “\"} />\n {search}”.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n pages={pages}\n rows={data?.data?.length ?? 0}\n nextCursor={data?.next_cursor}\n busy={isPending}\n sizes={[100, 200, 500]}\n />\n </>\n )}\n </div>\n )\n}\n\nfunction MeterRow({ meter }: { meter: Meter }) {\n return (\n <LinkedTableRow to={`/catalog/metering/${encodeURIComponent(meter.key)}`}>\n <TableCell>\n <Link\n className=\"font-medium underline-offset-3 hover:underline\"\n to={`/catalog/metering/${encodeURIComponent(meter.key)}`}\n >\n {meter.key}\n </Link>\n {meter.unit && (\n <p className=\"text-xs text-muted-foreground\">{meter.unit}</p>\n )}\n </TableCell>\n <TableCell>{meter.event_type}</TableCell>\n <TableCell>\n <Badge variant=\"secondary\">{meter.aggregation}</Badge>\n </TableCell>\n <TableCell className=\"font-medium tabular-nums\">\n {summarizeRateCard(meter.rate_card)}\n </TableCell>\n <TableCell>{meter.rate_card?.product_key ?? \"—\"}</TableCell>\n <TableCell>\n <span className=\"inline-flex items-center gap-1.5 text-sm\">\n <span\n className={`size-1.5 rounded-full ${meter.has_activity ? \"bg-settled\" : \"bg-muted-foreground/50\"}`}\n />\n {meter.has_activity ? \"Active\" : \"No events\"}\n </span>\n </TableCell>\n <TableCell className=\"text-muted-foreground tabular-nums\">\n {formatDate(meter.last_event_at)}\n </TableCell>\n <TableCell className=\"text-right\">\n <HugeiconsIcon\n icon={ArrowRight01Icon}\n className=\"ml-auto size-4 text-muted-foreground\"\n />\n </TableCell>\n </LinkedTableRow>\n )\n}\n\nexport function MeterDetailPage() {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const { key = \"\" } = useParams()\n const meterKey = key\n const navigate = useNavigate()\n const meterQuery = useQuery(adminQueries.usageMeter(meterKey))\n const writesAllowed = useCatalogWrites()\n const productsQuery = useQuery(\n adminQueries.allProducts({ errorAction: \"Load products for metering\" })\n )\n\n if (meterQuery.isPending) return <MeterDetailSkeleton />\n if (meterQuery.error) {\n const notFound =\n meterQuery.error instanceof ApiError && meterQuery.error.status === 404\n const forbidden =\n meterQuery.error instanceof ApiError && meterQuery.error.status === 403\n return (\n <PageMessage\n title={\n forbidden\n ? \"Metering access is restricted\"\n : notFound\n ? \"Meter not found\"\n : \"Meter could not be loaded\"\n }\n description={\n forbidden\n ? \"Your role does not have permission to read this meter.\"\n : notFound\n ? \"This meter does not exist in the active merchant catalog.\"\n : \"Try loading the meter again.\"\n }\n action={\n forbidden ? undefined : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n notFound\n ? navigate(\"/catalog/metering\")\n : void meterQuery.refetch()\n }\n >\n {notFound ? \"Back to metering\" : \"Try again\"}\n </Button>\n )\n }\n />\n )\n }\n const meter = meterQuery.data\n if (!meter) return null\n const definitionLock = meterDefinitionLocked(meter, writesAllowed)\n\n return (\n <div className=\"flex min-w-0 flex-col gap-8\">\n <header className=\"flex flex-wrap items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => navigate(\"/catalog/metering\")}\n aria-label={adminText(\"Back to metering\")}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4\" />\n </Button>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"truncate text-xl font-semibold tracking-tight\">\n {meter.key}\n </h1>\n {!writesAllowed && (\n <Badge variant=\"secondary\">\n <AdminMessage id={\"read-only\"} />\n </Badge>\n )}\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {meter.event_type} · {meter.aggregation}\n {meter.unit ? ` · ${meter.unit}` : \"\"}\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <MeterFormDialog meter={meter} writesAllowed={writesAllowed} />\n <RateCardEditor\n meter={meter}\n writesAllowed={writesAllowed}\n products={productsQuery.data?.data ?? []}\n productsPending={productsQuery.isPending}\n productsError={Boolean(productsQuery.error)}\n productsForbidden={\n productsQuery.error instanceof ApiError &&\n productsQuery.error.status === 403\n }\n />\n </div>\n </header>\n\n {!writesAllowed && (\n <ReadOnlyNotice>\n <AdminMessage\n id={\"Catalog updates are disabled. The console is read-only.\"}\n />\n </ReadOnlyNotice>\n )}\n\n <section className=\"grid gap-4\">\n <div>\n <h2 className=\"text-base font-semibold\">\n <AdminMessage id={\"Event contract\"} />\n </h2>\n <p className=\"mt-1 max-w-3xl text-sm text-pretty text-muted-foreground\">\n <AdminMessage\n id={\n \"Creating this meter does not send events. The host application must report idempotent usage to\"\n }\n />{\" \"}\n <code className=\"text-foreground\">\n <AdminMessage id={\"/app/usage-events\"} />\n </code>\n <AdminMessage id={\" with this shape.\"} />\n </p>\n </div>\n <dl className=\"grid gap-x-8 gap-y-4 border-y py-4 sm:grid-cols-2 lg:grid-cols-4\">\n <ContractFact\n label={adminText(\"Event type\")}\n value={meter.event_type}\n />\n <ContractFact\n label={adminText(\"Aggregation\")}\n value={\n meter.aggregation === \"sum\"\n ? `Sum ${meter.value_property}`\n : \"Count each event\"\n }\n />\n <ContractFact label={adminText(\"Meter key\")} value={meter.key} />\n <ContractFact\n label={adminText(\"Billing support\")}\n value={meter.billing_supported ? \"Supported\" : \"Read only\"}\n />\n {Object.entries(meter.group_by ?? {}).map(([name, property]) => (\n <ContractFact\n key={name}\n label={`Dimension: ${name}`}\n value={property}\n />\n ))}\n </dl>\n {definitionLock && writesAllowed && (\n <p className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <HugeiconsIcon icon={Activity01Icon} className=\"size-4\" />\n {definitionLock}\n </p>\n )}\n </section>\n\n <DefaultRateSection meter={meter} writesAllowed={writesAllowed} />\n </div>\n )\n}\n\nfunction DefaultRateSection({\n meter,\n writesAllowed,\n}: {\n meter: Meter\n writesAllowed: boolean\n}) {\n const { toast, toastApiError, adminMutations } = useAdminServices()\n\n const { text: adminText } = useAdminUI()\n\n const confirm = useConfirm()\n const queryClient = useQueryClient()\n const remove = useMutation(\n adminMutations.deleteDefaultUsageRateCard(queryClient)\n )\n const card = meter.rate_card\n const handleDelete = async () => {\n const removing = await confirm({\n title: \"Remove the default rate?\",\n description:\n \"New usage for this meter will stop being rated after removal. Billed usage orders and accrued amounts remain unchanged.\",\n confirmLabel: \"Remove default\",\n cancelLabel: \"Keep rate\",\n tone: \"destructive\",\n })\n if (!removing) return\n try {\n await remove.mutateAsync(meter)\n toast.success(\"Default rate removed\")\n } catch (error) {\n toastApiError(error, \"Remove default rate\")\n }\n }\n return (\n <section className=\"grid gap-4 border-t pt-7\">\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-base font-semibold\">\n <AdminMessage id={\"Default rate\"} />\n </h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n <AdminMessage id={\"Used for every customer.\"} />\n </p>\n </div>\n {card && writesAllowed && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={remove.isPending}\n onClick={() => void handleDelete()}\n >\n <HugeiconsIcon icon={Delete02Icon} className=\"size-4\" />\n {remove.isPending ? \"Removing…\" : \"Remove default\"}\n </Button>\n )}\n </div>\n {!meter.billing_supported ? (\n <ReadOnlyNotice>\n <AdminMessage\n id={\n \"This meter uses an aggregation that the billing engine cannot rate.\"\n }\n />\n </ReadOnlyNotice>\n ) : !card ? (\n <p className=\"border-y py-6 text-sm text-muted-foreground\">\n <AdminMessage\n id={\n \"No default rate. Usage is recorded but is not billed by this meter.\"\n }\n />\n </p>\n ) : (\n <dl className=\"grid gap-x-8 gap-y-4 border-y py-4 sm:grid-cols-2 lg:grid-cols-4\">\n <ContractFact\n label={adminText(\"Price\")}\n value={summarizeRateCard(card)}\n />\n <ContractFact label={adminText(\"Product\")} value={card.product_key} />\n <ContractFact\n label={adminText(\"Model\")}\n value={card.price.model.replace(\"_\", \" \")}\n />\n <ContractFact\n label={adminText(\"Filter\")}\n value={\n Object.keys(card.filter ?? {}).length\n ? Object.entries(card.filter ?? {})\n .map(([key, values]) => `${key}: ${values.join(\", \")}`)\n .join(\" · \")\n : \"All matching events\"\n }\n />\n <ContractFact\n label={adminText(\"Allowance\")}\n value={\n card.allowance?.included !== undefined\n ? `${card.allowance.included.toLocaleString()} included`\n : \"None\"\n }\n />\n <ContractFact\n label={adminText(\"Updated\")}\n value={formatDate(card.updated_at)}\n />\n </dl>\n )}\n </section>\n )\n}\n\nfunction ContractFact({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"min-w-0\">\n <dt className=\"text-xs text-muted-foreground\">{label}</dt>\n <dd className=\"mt-1 text-sm font-medium break-words tabular-nums\">\n {value || \"—\"}\n </dd>\n </div>\n )\n}\n\nfunction ReadOnlyNotice({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2 rounded-lg bg-muted/50 px-3 py-2.5 text-sm text-muted-foreground\">\n <HugeiconsIcon\n icon={InformationCircleIcon}\n className=\"mt-0.5 size-4 shrink-0\"\n />\n <p>{children}</p>\n </div>\n )\n}\n\nfunction PageMessage({\n title,\n description,\n action,\n}: {\n title: string\n description: string\n action?: React.ReactNode\n}) {\n return (\n <div className=\"flex flex-col items-start gap-3 border-y py-10\">\n <div>\n <h2 className=\"text-sm font-medium\">{title}</h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">{description}</p>\n </div>\n {action}\n </div>\n )\n}\n\nfunction MeteringSkeleton() {\n return (\n <div className=\"grid gap-3\">\n <Skeleton className=\"h-8 w-64\" />\n {Array.from({ length: 5 }).map((_, index) => (\n <Skeleton key={index} className=\"h-11 w-full\" />\n ))}\n </div>\n )\n}\n\nfunction MeterDetailSkeleton() {\n return (\n <div className=\"grid gap-6\">\n <Skeleton className=\"h-10 w-72\" />\n <Skeleton className=\"h-28 w-full\" />\n <Skeleton className=\"h-36 w-full\" />\n <Skeleton className=\"h-40 w-full\" />\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmEA,IAAa,KAAb,cAAuC,MAAM;CAC3C;CAEA,YAAY,GAAiB,GAAiB;EAG5C,AAFA,MAAM,CAAO,GACb,KAAK,OAAO,qBACZ,KAAK,UAAU;CACjB;AACF;AAKA,SAAgB,GAAqB,GAIZ;CAKvB,OAJI,EAAO,UAAgB,YACvB,EAAO,OAAO,WAAW,MAAY,eACrC,EAAO,QAAc,UACrB,EAAO,UAAU,IAAU,UACxB;AACT;AAEA,SAAgB,GAAkB,GAAuB;CACvD,OAAO,EACJ,KAAK,CAAC,CACN,YAAY,CAAC,CACb,QAAQ,iBAAiB,GAAG,CAAC,CAC7B,QAAQ,kBAAkB,EAAE;AACjC;AAEA,SAAgB,GAAgB,GAAgC;CAC9D,OAAO;EACL,KAAK,GAAO,OAAO;EACnB,WAAW,GAAO,cAAc;EAChC,aAAa,GAAO,gBAAgB,UAAU,UAAU;EACxD,eAAe,GAAO,kBAAkB;EACxC,MAAM,GAAO,QAAQ;EACrB,SAAS,OAAO,QAAQ,GAAO,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAK,QAAY;GACpE;GACA;EACF,EAAE;CACJ;AACF;AAEA,SAAgB,GAAkB,GAGhC;CACA,IAAM,IAAM,GAAkB,EAAO,GAAG;CACxC,IAAI,CAAC,GAAK,MAAU,MAAM,oBAAoB;CAC9C,IAAM,IAAY,EAAO,UAAU,KAAK,GAClC,IAAgB,EAAO,cAAc,KAAK;CAChD,IAAI,EAAO,gBAAgB,SAAS,CAAC,GACnC,MAAU,MAAM,sCAAsC;CAExD,IAAM,IAAU,GAAU,EAAO,SAAS,OAAO;CACjD,OAAO;EACL;EACA,OAAO;GACL,YAAY;GACZ,aAAa,EAAO;GACpB,gBAAgB,EAAO,gBAAgB,QAAQ,IAAgB;GAC/D,MAAM,EAAO,KAAK,KAAK,KAAK,KAAA;GAC5B,UAAU;EACZ;CACF;AACF;AAEA,SAAgB,GACd,GAIoB;CACpB,IAAM,IAAQ,GAAM,OACd,IAAS,GAAO,UAAU,QAC1B,IAAY,GAAM,WAClB,IACJ,GAAW,aAAa,KAAA,IAAyB,SAAb,YAChC,IAAW,GAAO,YAAY;CACpC,OAAO;EACL,WAAW,GAAM,cAAc;EAC/B,OAAO,GAAO,SAAS,EAAM,UAAU,SAAS,EAAM,QAAQ;EAC9D;EACA,YAAY,EAAa,GAAU,GAAO,UAAU,WAAW;EAC/D,UAAU,EAAe,GAAO,UAAU,WAAW,GAAG;EACxD,OAAO,GAAO,UAAU,SAAS;EACjC,eAAe,EAAa,GAAU,GAAO,UAAU,cAAc;EACrE,eAAe,EAAQ;EACvB,iBAAiB,GAAQ,aAAa;EACtC,aAAa,OAAO,QAAQ,GAAQ,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAK,QAAW;GACrE;GACA,YAAY,EAAa,GAAU,EAAK,WAAW;GACnD,eAAe,EAAa,GAAU,EAAK,cAAc;EAC3D,EAAE;EACF,UAAU;EACV,QACE,GAAO,QAAQ,SAAS,CACtB;GAAE,OAAO;GAAM,aAAa;GAAK,aAAa;EAAI,CACpD,EAAA,CACA,KAAK,OAAU;GACf,MAAM,EAAK,UAAU,OAAO,KAAK,OAAO,EAAK,KAAK;GAClD,YAAY,EAAa,GAAU,EAAK,WAAW;GACnD,YAAY,EAAa,GAAU,EAAK,WAAW;EACrD,EAAE;EACF,eAAe,EAAa,GAAU,GAAO,SAAS,MAAM;EAC5D,aAAa,EAAe,GAAO,SAAS,cAAc,GAAG;EAC7D,WAAW,EAAe,GAAO,SAAS,UAAU;EACpD,SAAS,OAAO,QAAQ,GAAM,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAK,QAAa;GAClE;GACA,OAAO,EAAO,KAAK,IAAI;EACzB,EAAE;EACF;EACA,mBAAmB,EAAe,GAAW,QAAQ;CACvD;AACF;AAEA,SAAgB,GACd,GAC6B;CAC7B,AAAK,EAAO,aAAW,EAAc,gBAAgB,mBAAmB;CACxE,IAAM,IAAW,EAAO,SAAS,KAAK,CAAC,CAAC,YAAY;CACpD,AAAI,EAAc,CAAQ,MAAM,KAAA,KAC9B,EACE,iBACA,6BAA6B,EAAoB,KAAK,IAAI,EAAE,EAC9D;CAGF,IAAM,IAAQ,GAAW,GAAQ,CAAQ,GACnC,IAAY,EAAO,UAAU,YAAY,KAAA,IAAY,GAAe,CAAM;CAChF,OAAO;EACL,YAAY,EAAO;EACnB,QAAQ,GAAgB,EAAO,OAAO;EACtC;EACA,GAAI,IAAY,EAAE,aAAU,IAAI,CAAC;CACnC;AACF;AAEA,SAAS,GAAW,GAA4B,GAA6B;CAC3E,IAAI,EAAO,UAAU,WAAW,OAAO;EAAE,OAAO;EAAW;CAAS;CACpE,IAAI,EAAO,UAAU,YAAY;EAC/B,IAAM,IAAW,GACf,EAAO,UACP,WACA,gBACF,GACM,IAAgB,EACpB,GACA,EAAO,eACP,kBACA,cACF;EACA,IAAI,EAAO,eAAe;GACxB,IAAM,IAAY,EAAO,gBAAgB,KAAK;GAI9C,AAHK,KACH,EAAc,oBAAoB,4BAA4B,GAE5D,EAAO,YAAY,WAAW,KAChC,EAAc,mBAAmB,+BAA+B;GAElE,IAAM,IAEO,CAAC;GACd,KAAK,IAAM,CAAC,GAAO,MAAQ,EAAO,YAAY,QAAQ,GAAG;IACvD,IAAM,IAAM,EAAI,IAAI,KAAK,GACnB,IAAc,eAAe;IAanC,AAZK,KACH,EACE,GAAG,EAAY,SACf,iCACF,GAEE,EAAM,MACR,EACE,GAAG,EAAY,SACf,2BAA2B,EAAI,GACjC,GAEF,EAAM,KAAO;KACX,aAAa,EACX,GACA,EAAI,YACJ,aAAa,KACb,GAAG,EAAY,cACf,EACF;KACA,GAAI,EACF,GACA,EAAI,eACJ,eAAe,KACf,GAAG,EAAY,SACjB,MAAM,MASF,CAAC,IARD,EACE,gBAAgB,EACd,GACA,EAAI,eACJ,eAAe,KACf,GAAG,EAAY,SACjB,EACF;IAEN;GACF;GACA,OAAO;IACL,OAAO;IACP;IACA,UAAU;KACR,WAAW;KACX,OAAO,EAAO;KACd,GAAI,MAAkB,MAA0C,CAAC,IAArC,EAAE,gBAAgB,EAAc;KAC5D,QAAQ;MAAE;MAAW;KAAM;IAC7B;GACF;EACF;EACA,OAAO;GACL,OAAO;GACP;GACA,UAAU;IACR,aAAa,EACX,GACA,EAAO,YACP,cACA,oBACA,EACF;IACA,WAAW;IACX,OAAO,EAAO;IACd,GAAI,MAAkB,MAA0C,CAAC,IAArC,EAAE,gBAAgB,EAAc;GAC9D;EACF;CACF;CAEA,IAAI,EAAO,UAAU,UAAU;EAC7B,AAAI,EAAO,MAAM,WAAW,KAC1B,EAAc,YAAY,wBAAwB;EAEpD,IAAM,IAAQ,EAAO,MAAM,KAAK,GAAK,MAAU;GAC7C,IAAM,IAAO,MAAU,EAAO,MAAM,SAAS,GACvC,IAAO,EAAI,KAAK,KAAK;GAa3B,OAZI,KAAQ,KACV,EACE,QAAQ,EAAM,SACd,mCACF,GAEE,CAAC,KAAQ,CAAC,KACZ,EACE,QAAQ,EAAM,SACd,uCACF,GAEK;IACL,OAAO,IACH,OACA,GACE,GACA,QAAQ,IAAQ,EAAE,SAClB,QAAQ,EAAM,OAChB;IACJ,aAAa,EACX,GACA,EAAI,YACJ,QAAQ,IAAQ,EAAE,cAClB,QAAQ,EAAM,cACd,EACF;IACA,aAAa,EACX,GACA,EAAI,YACJ,QAAQ,IAAQ,EAAE,eAClB,QAAQ,EAAM,aAChB;GACF;EACF,CAAC;EACD,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAM,SAAS,GAAG,KAAS,GACrD,CAAK,EAAM,EAAM,CAAC,SAAS,OAAO,EAAM,IAAQ,EAAE,CAAC,SAAS,MAC1D,EAAc,QAAQ,EAAM,SAAS,4BAA4B;EAGrE,OAAO;GACL,OAAO;GACP;GACA,QAAQ;IAAE,MAAM,EAAO;IAAU;GAAM;EACzC;CACF;CAEA,OAAO;EACL,OAAO;EACP;EACA,SAAS;GACP,QAAQ,EACN,GACA,EAAO,eACP,iBACA,gBACF;GACA,cAAc,GACZ,EAAO,aACP,gBACA,cACF;GACA,YAAY,GAAc,EAAO,WAAW,cAAc,cAAc;EAC1E;CACF;AACF;AAEA,SAAS,GAAe,GAAmD;CACrE,MAAO,kBAAkB,QAC7B,OAAO,EACL,UAAU,GACR,EAAO,mBACP,sBACA,oBACF,EACF;AACF;AAEA,SAAS,GAAU,GAAqB,GAAsC;CAC5E,IAAM,IAAiC,CAAC;CACxC,KAAK,IAAM,KAAO,GAAM;EACtB,IAAM,IAAM,EAAI,IAAI,KAAK,GACnB,IAAQ,EAAI,MAAM,KAAK;EAC7B,IAAI,CAAC,KAAO,CAAC,GAAO,MAAU,MAAM,QAAQ,EAAK,wBAAwB;EACzE,IAAI,EAAO,IAAM,MAAU,MAAM,aAAa,EAAK,QAAQ,EAAI,GAAG;EAClE,EAAO,KAAO;CAChB;CACA,OAAO;AACT;AAEA,SAAS,GAAgB,GAA+C;CACtE,IAAM,IAAmC,CAAC;CAC1C,KAAK,IAAM,CAAC,GAAO,MAAQ,EAAK,QAAQ,GAAG;EACzC,IAAM,IAAM,EAAI,IAAI,KAAK,GACnB,IAAS,CACb,GAAG,IAAI,IAAI,EAAI,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,MAAU,EAAM,KAAK,CAAC,CAAC,CAC9D,CAAC,CAAC,OAAO,OAAO;EAmBhB,AAlBK,KACH,EACE,UAAU,EAAM,aAChB,qCACF,GAEE,EAAO,WAAW,KACpB,EACE,UAAU,EAAM,UAChB,2CACF,GAEE,EAAO,MACT,EACE,UAAU,EAAM,aAChB,+BAA+B,EAAI,GACrC,GAEF,EAAO,KAAO;CAChB;CACA,OAAO;AACT;AAEA,SAAS,EACP,GACA,GACA,GACA,GACA,IAAY,IACJ;CACR,IAAM,IAAS,EAAsB,GAAO,CAAQ;CAWpD,QATE,MAAW,QACX,OAAO,CAAM,IAAI,MAChB,CAAC,KAAa,OAAO,CAAM,MAAM,OAElC,EACE,GACA,GAAG,EAAM,WAAW,IAAY,iBAAiB,oBAAoB,EACvE,GAEK;AACT;AAEA,SAAS,EACP,GACA,GACA,GACA,GACQ;CAER,OADK,EAAM,KAAK,IACT,EAAc,GAAU,GAAO,GAAO,GAAS,EAAI,IADhC;AAE5B;AAEA,SAAS,GACP,GACA,GACA,GACQ;CACR,IAAM,IAAS,OAAO,CAAK;CAI3B,QAHI,CAAC,OAAO,cAAc,CAAM,KAAK,KAAU,MAC7C,EAAc,GAAS,GAAG,EAAM,kCAAkC,GAE7D;AACT;AAEA,SAAS,GAAc,GAAe,GAAe,GAAyB;CAC5E,IAAI,CAAC,EAAM,KAAK,GAAG,OAAO;CAC1B,IAAM,IAAS,OAAO,CAAK;CAI3B,QAHI,CAAC,OAAO,cAAc,CAAM,KAAK,IAAS,MAC5C,EAAc,GAAS,GAAG,EAAM,0CAA0C,GAErE;AACT;AAEA,SAAS,EAAc,GAAiB,GAAwB;CAC9D,MAAM,IAAI,GAAkB,GAAS,CAAO;AAC9C;AAEA,SAAS,EAAa,GAAkB,GAAwB;CAC9D,OAAO,KAAS,MAAU,MAAM,EAAoB,GAAO,CAAQ,IAAI;AACzE;AAEA,SAAS,EAAe,GAAgB,IAAW,IAAY;CAC7D,OAAO,IAAQ,OAAO,CAAK,IAAI;AACjC;AAEA,SAAgB,GAAkB,GAAqC;CACrE,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,EAAE,aAAU,GACZ,IAAW,EAAM,YAAY;CAcnC,OAbI,EAAM,UAAU,YAAkB,kBAAkB,MACpD,EAAM,UAAU,cAAc,EAAM,WAClC,EAAM,SAAS,SACV,GAAG,OAAO,KAAK,EAAM,SAAS,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,kBAAkB,MAE7E,GAAG,EAAmB,EAAM,SAAS,eAAe,KAAK,CAAQ,EAAE,OAAO,EAAM,SAAS,aAAa,EAAE,UAE7G,EAAM,UAAU,YAAY,EAAM,SAC7B,GAAG,EAAM,OAAO,OAAO,UAAU,EAAE,GAAG,EAAM,OAAO,KAAK,WAAW,MAExE,EAAM,UAAU,aAAa,EAAM,UAC9B,GAAG,EAAmB,EAAM,QAAQ,UAAU,KAAK,CAAQ,EAAE,QAAQ,EAAM,QAAQ,gBAAgB,EAAA,CAAG,eAAe,EAAE,UAEzH,uBAAuB;AAChC;AAIA,SAAgB,GACd,GACA,GACe;CAGf,OAFK,IACD,EAAM,eAAqB,kDACxB,OAFoB;AAG7B;;;ACteA,SAAgB,GAAgB,EAC9B,UACA,oBAIC;CACD,IAAM,EAAE,UAAO,kBAAe,sBAAmB,EAAiB,GAE5D,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW,GAE9C,CAAC,GAAM,KAAW,EAAM,SAAS,EAAK,GACtC,CAAC,GAAa,KAAkB,EAAM,SAAS,EAAE,GACjD,IAAc,GAAe,GAC7B,IAAO,GAAY,EAAe,cAAc,CAAW,CAAC,GAC5D,IAAS,IAAQ,GAAsB,GAAO,CAAa,IAAI,MAC/D,IAAO,GAAQ;EACnB,eAAe,GAAgB,CAAK;EACpC,UAAU,OAAO,EAAE,eAAY;GAC7B,EAAe,EAAE;GACjB,IAAI;IACF,IAAM,IAAU,GAAkB,CAAK;IAOvC,AAJA,EAAQ,MAAM,oBAAoB,GAAO,YAAY,GACrD,MAAM,EAAK,YAAY,CAAO,GAC9B,EAAM,QAAQ,IAAQ,kBAAkB,eAAe,GACvD,EAAQ,EAAK,GACb,EAAK,MAAM;GACb,SAAS,GAAO;IACd,IAAI,aAAiB,SAAS,EAAE,YAAY,IAAQ;KAClD,EAAe,EAAM,OAAO;KAC5B;IACF;IACA,EAAc,GAAO,IAAQ,iBAAiB,cAAc;GAC9D;EACF;CACF,CAAC;CAWD,OATI,IAEA,kBAAC,GAAD;EAAQ,SAAQ;EAAU,MAAK;EAAK,UAAA;EAAS,OAAO;EAApD,UAAA,CACE,kBAAC,GAAD;GAAe,MAAM;GAAY,WAAU;EAAU,CAAA,GACrD,kBAAC,GAAD,EAAc,IAAI,kBAAoB,CAAA,CAChC;MAKV,kBAAC,IAAD;EACQ;EACN,eAAe,MAAS;GAGtB,AAFA,EAAQ,CAAI,GACZ,EAAe,EAAE,GACZ,KAAM,EAAK,MAAM;EACxB;EANF,UAAA,CAQE,kBAAC,IAAD,EACE,QACE,kBAAC,GAAD;GAAQ,SAAS,IAAQ,YAAY;GAAW,MAAK;GAArD,UAAA,CACE,kBAAC,GAAD;IACE,MAAM,IAAQ,IAAa;IAC3B,WAAU;GACX,CAAA,GACA,IAAQ,oBAAoB,cACvB;EAEX,CAAA,EAAA,CAAA,GACD,kBAAC,IAAD;GAAe,WAAW;GACxB,UAAA,kBAAC,QAAD;IACE,WAAU;IACV,WAAW,MAAU;KAGnB,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAU,aAAa;IACzB;IANF,UAAA;KAQE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAc,IAAQ,eAAe,eAA4B,CAAA,GACjE,kBAAC,IAAD,EAAA,UACE,kBAAC,GAAD,EACE,IACE,8GAEH,CAAA,EACgB,CAAA,CACP,EAAA,CAAA;KAEd,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACE,kBAAC,EAAK,OAAN;QACE,MAAK;QACL,YAAY,EACV,SAAS,EAAE,eACT,EAAM,KAAK,IAAI,KAAA,IAAY,qBAC/B;QAEE,WAAA,MACA,kBAAC,OAAD;SAAK,WAAU;SAAf,UAAA;UACE,kBAAC,GAAD;WAAO,SAAS,EAAQ,WAAW;WACjC,UAAA,kBAAC,GAAD,EAAc,IAAI,MAAQ,CAAA;UACrB,CAAA;UACP,kBAAC,GAAD;WACE,IAAI,EAAQ,WAAW;WACvB,OAAO,EAAM,MAAM;WACnB,WAAW,MAAU,EAAM,aAAa,EAAM,OAAO,KAAK;WAC1D,QAAQ,EAAM;WACd,UAAU,EAAQ;WAClB,aAAa,EAAU,YAAY;WACnC,cAAa;UACd,CAAA;UACD,kBAAC,KAAD;WAAG,WAAU;WACX,UAAA,kBAAC,GAAD,EACE,IACE,0DAEH,CAAA;UACA,CAAA;UACH,kBAAC,GAAD,EAAiB,QAAQ,EAAM,MAAM,KAAK,OAAS,CAAA;SAChD;;OAEG,CAAA;OAEZ,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAAC,EAAK,OAAN;SAAY,MAAK;SACb,WAAA,MACA,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA;WACE,kBAAC,GAAD;YAAO,SAAS,EAAQ,kBAAkB;YACxC,UAAA,kBAAC,GAAD,EAAc,IAAI,aAAe,CAAA;WAC5B,CAAA;WACP,kBAAC,GAAD;YACE,IAAI,EAAQ,kBAAkB;YAC9B,OAAO,EAAM,MAAM;YACnB,WAAW,MACT,EAAM,aAAa,EAAM,OAAO,KAAK;YAEvC,aAAa,EAAU,YAAY;YACnC,cAAa;WACd,CAAA;WACD,kBAAC,KAAD;YAAG,WAAU;YACX,UAAA,kBAAC,GAAD,EAAc,IAAI,oCAAsC,CAAA;WACvD,CAAA;UACA;;QAEG,CAAA,GACZ,kBAAC,EAAK,OAAN;SAAY,MAAK;SACb,WAAA,MACA,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA;WACE,kBAAC,GAAD;YAAO,SAAS,EAAQ,YAAY;YAClC,UAAA,kBAAC,GAAD,EAAc,IAAI,OAAS,CAAA;WACtB,CAAA;WACP,kBAAC,GAAD;YACE,IAAI,EAAQ,YAAY;YACxB,OAAO,EAAM,MAAM;YACnB,WAAW,MACT,EAAM,aAAa,EAAM,OAAO,KAAK;YAEvC,aAAa,EAAU,QAAQ;YAC/B,cAAa;WACd,CAAA;WACD,kBAAC,KAAD;YAAG,WAAU;YACX,UAAA,kBAAC,GAAD,EACE,IAAI,4CACL,CAAA;WACA,CAAA;UACA;;QAEG,CAAA,CACT;;OAEL,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAAC,EAAK,OAAN;SAAY,MAAK;SACb,WAAA,MACA,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA,CACE,kBAAC,GAAD;WAAO,SAAS,EAAQ,mBAAmB;WACzC,UAAA,kBAAC,GAAD,EAAc,IAAI,cAAgB,CAAA;UAC7B,CAAA,GACP,kBAAC,GAAD;WACE,OAAO,EAAM,MAAM;WACnB,gBAAgB,MACd,EAAM,aAAa,CAAwB;WAH/C,UAAA,CAME,kBAAC,GAAD;YACE,IAAI,EAAQ,mBAAmB;YAC/B,WAAU;YAEV,UAAA,kBAAC,GAAD,CAAc,CAAA;WACD,CAAA,GACf,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;YAAY,OAAM;YAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,sBAAwB,CAAA;WAChC,CAAA,GACZ,kBAAC,GAAD;YAAY,OAAM;YAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,eAAiB,CAAA;WACzB,CAAA,CACC,EAAA,CAAA,CACT;UACL,CAAA,CAAA;;QAEG,CAAA,GACZ,kBAAC,EAAK,WAAN;SAAgB,WAAW,MAAU,EAAM,OAAO;SAC9C,WAAA,MACA,MAAgB,QACd,kBAAC,EAAK,OAAN;UACE,MAAK;UACL,YAAY,EACV,SAAS,EAAE,eACT,EAAM,KAAK,IACP,KAAA,IACA,uCACR;UAEE,WAAA,MACA,kBAAC,OAAD;WAAK,WAAU;WAAf,UAAA;YACE,kBAAC,GAAD;aAAO,SAAS,EAAQ,sBAAsB;aAC5C,UAAA,kBAAC,GAAD,EAAc,IAAI,iBAAmB,CAAA;YAChC,CAAA;YACP,kBAAC,GAAD;aACE,IAAI,EAAQ,sBAAsB;aAClC,OAAO,EAAM,MAAM;aACnB,WAAW,MACT,EAAM,aAAa,EAAM,OAAO,KAAK;aAEvC,QAAQ,EAAM;aACd,aAAa,EAAU,QAAQ;aAC/B,cAAa;YACd,CAAA;YACD,kBAAC,GAAD,EAAiB,QAAQ,EAAM,MAAM,KAAK,OAAS,CAAA;WAChD;;SAEG,CAAA,IAEZ,kBAAC,OAAD;UAAK,WAAU;UACb,UAAA,kBAAC,GAAD,EACE,IAAI,gDACL,CAAA;SACE,CAAA;QAGK,CAAA,CACb;;OAEL,kBAAC,EAAK,OAAN;QAAY,MAAK;QAAU,MAAK;QAC5B,WAAA,MACA,kBAAC,YAAD;SAAU,WAAU;SAApB,UAAA,CACE,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,aAAe,CAAA,EAC5B,CAAA,GACP,kBAAC,KAAD;WAAG,WAAU;WACX,UAAA,kBAAC,GAAD,EACE,IACE,6DAEH,CAAA;UACA,CAAA,CACA,EAAA,CAAA,GACL,kBAAC,GAAD;WACE,MAAK;WACL,SAAQ;WACR,MAAK;WACL,eAAe,EAAM,UAAU;YAAE,KAAK;YAAI,OAAO;WAAG,CAAC;WAJvD,UAAA,CAME,kBAAC,GAAD;YAAe,MAAM;YAAW,WAAU;WAAU,CAAA,GACpD,kBAAC,GAAD,EAAc,IAAI,gBAAkB,CAAA,CAC9B;UACL,CAAA,CAAA;SACJ,CAAA,GAAA,EAAM,MAAM,MAAM,KAAK,GAAK,MAC3B,kBAAC,OAAD;UAEE,WAAU;UAFZ,UAAA;WAIE,kBAAC,GAAD;YACE,cAAY,aAAa,IAAQ,EAAE;YACnC,OAAO,EAAI;YACX,WAAW,MACT,EAAK,cACH,WAAW,EAAM,QACjB,EAAM,OAAO,KACf;YAEF,aAAa,EAAU,OAAO;YAC9B,cAAa;WACd,CAAA;WACD,kBAAC,GAAD;YACE,cAAY,aAAa,IAAQ,EAAE;YACnC,OAAO,EAAI;YACX,WAAW,MACT,EAAK,cACH,WAAW,EAAM,UACjB,EAAM,OAAO,KACf;YAEF,aAAa,EAAU,gBAAgB;YACvC,cAAa;WACd,CAAA;WACD,kBAAC,GAAD;YACE,MAAK;YACL,SAAQ;YACR,MAAK;YACL,cAAY,oBAAoB,IAAQ;YACxC,eAAe,EAAM,YAAY,CAAK;YAEtC,UAAA,kBAAC,GAAD;aAAe,MAAM;aAAc,WAAU;YAAU,CAAA;WACjD,CAAA;UACL;SApCE,GAAA,CAoCF,CACN,CACO;;OAEF,CAAA;MACT;;KAEJ,KACC,kBAAC,KAAD;MAAG,MAAK;MAAQ,WAAU;MACvB,UAAA;KACA,CAAA;KAEL,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MACE,MAAK;MACL,SAAQ;MACR,eAAe,EAAQ,EAAK;MAE5B,UAAA,kBAAC,GAAD,EAAc,IAAI,SAAW,CAAA;KACvB,CAAA,GACR,kBAAC,EAAK,WAAN;MAAgB,WAAW,MAAU,EAAM;MACvC,WAAA,MACA,kBAAC,GAAD;OAAQ,MAAK;OAAS,UAAU,KAAc,EAAK;OAChD,UAAA,KAAc,EAAK,YAAY,YAAY;MACtC,CAAA;KAEI,CAAA,CACJ,EAAA,CAAA;IACV;;EACO,CAAA,CACT;;AAEZ;;;AC/TA,IAAM,IAAuB,EAAM,cAAgC,IAAI;AAEvE,SAAgB,GAAe,EAC7B,UACA,mBAAgB,IAChB,aACA,qBAAkB,IAClB,mBAAgB,IAChB,uBAAoB,MAQnB;CACD,IAAM,EAAE,UAAO,kBAAe,sBAAmB,EAAiB,GAE5D,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW,GAE9C,CAAC,GAAM,KAAW,EAAM,SAAS,EAAK,GACtC,CAAC,GAAa,KAAkB,EAAM,SAA2B,IAAI,GACrE,KAAU,EAAW,GACrB,KAAc,GAAe,GAC7B,IAAc,GAClB,EAAe,wBAAwB,EAAW,CACpD,GACM,IAAiB,EAAS,QAAQ,MAAY,CAAC,EAAQ,QAAQ,GAC/D,IAAW,EAAM,WACjB,KAAc,EAAY,WAC1B,IAAO,GAAQ;EACnB,eAAe,GAAmB,CAAQ;EAC1C,UAAU,OAAO,EAAE,eAAY;GAC7B,EAAe,IAAI;GACnB,IAAI;IACF,IAAM,IAAW,GAAqB,CAAK;IAC3C,IACE,KACA,CAAE,MAAM,GAAQ;KACd,OAAO;KACP,aACE;KACF,cAAc;KACd,aAAa;IACf,CAAC,GAED;IACF,MAAM,GAAQ,CAAQ;GACxB,SAAS,GAAO;IACd,IAAI,aAAiB,IAAmB;KAKtC,AAJA,EAAe;MACb,SAAS,EAAM;MACf,SAAS,EAAM;KACjB,CAAC,GACD,4BAA4B;MAC1B,SAAS,eAAe,EAAQ,EAAM,OAAO,CAAC,CAAC,EAAE,MAAM;KACzD,CAAC;KACD;IACF;IACA,EAAc,GAAO,gBAAgB;GACvC;EACF;CACF,CAAC,GAEK,KAAU,OAAO,MAA0C;EAC/D,IAAI;GAGF,AAFA,MAAM,EAAY,YAAY;IAAE;IAAO;GAAS,CAAC,GACjD,EAAM,QAAQ,IAAW,0BAA0B,oBAAoB,GACvE,EAAQ,EAAK;EACf,SAAS,GAAO;GACd,EAAc,GAAO,mBAAmB;EAC1C;CACF;CAMA,OAJI,CAAC,KAAiB,CAAC,EAAM,oBACpB,OAIP,kBAAC,EAAqB,UAAtB;EAA+B,OAAO;EACpC,UAAA,kBAAC,IAAD;GACQ;GACN,eAAe,MAAS;IAGtB,AAFA,EAAQ,CAAI,GACZ,EAAe,IAAI,GACd,KAAM,EAAK,MAAM;GACxB;GANF,UAAA,CAQE,kBAAC,IAAD,EACE,QACE,kBAAC,GAAD;IAAQ,SAAS,IAAW,YAAY;IAAW,MAAK;IAAxD,UAAA,CACE,kBAAC,GAAD;KACE,MAAM,IAAW,IAAa;KAC9B,WAAU;IACX,CAAA,GACA,IAAW,sBAAsB,kBAC5B;GAEX,CAAA,EAAA,CAAA,GACD,kBAAC,IAAD;IACE,WAAW,GAAG,GAAY;IAE1B,UAAA,kBAAC,QAAD;KACE,WAAU;KACV,gBAAgB,EAAe,IAAI;KACnC,WAAW,MAAU;MAGnB,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAU,aAAa;KACzB;KAPF,UAAA;MASE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UACG,IAAW,sBAAsB,mBACvB,CAAA,GACb,kBAAC,IAAD,EAAA,UACE,kBAAC,GAAD,EACE,IACE,iHAEH,CAAA,EACgB,CAAA,CACP,EAAA,CAAA;MAEd,kBAAC,WAAD;OAAS,WAAU;OAAnB,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;QACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,oBAAsB,CAAA;OACtC,CAAA,GACH,IACC,kBAAC,OAAD;QAAK,WAAU;QACb,UAAA,kBAAC,GAAD,EAAc,IAAI,oBAAsB,CAAA;OACrC,CAAA,IACH,IACF,kBAAC,OAAD;QACE,MAAK;QACL,WAAU;QAET,UAAA,IACG,sDACA;OACD,CAAA,IACH,EAAe,WAAW,IAC5B,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAAC,KAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,oCAAsC,CAAA,EACvD,CAAA,GACH,kBAAC,GAAD;SACE,WAAU;SACV,IAAG;SAEH,UAAA,kBAAC,GAAD,EAAc,IAAI,qCAAuC,CAAA;QACrD,CAAA,CACH;OAEL,CAAA,IAAA,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA;SACE,kBAAC,EAAK,OAAN;UAAY,MAAK;UACb,WAAA,MACA,kBAAC,OAAD;WAAK,WAAU;WAAf,UAAA;YACE,kBAAC,GAAD;aAAO,SAAS,EAAQ,cAAc;aACpC,UAAA,kBAAC,GAAD,EAAc,IAAI,UAAY,CAAA;YACzB,CAAA;YACP,kBAAC,GAAD;aACE,OAAO,EAAM,MAAM,SAAS;aAC5B,gBAAgB,MACd,EAAM,aAAa,KAAS,EAAE;aAHlC,UAAA,CAME,kBAAC,GAAD;cACE,IAAI,EAAQ,cAAc;cAC1B,WAAU;cACV,GAAI,EAAgB,gBAAgB,CAAW;cAE/C,UAAA,kBAAC,GAAD,EACE,aAAa,EAAU,gBAAgB,EACxC,CAAA;aACY,CAAA,GACf,kBAAC,GAAD,EAAA,UACG,EAAe,KAAK,MACnB,kBAAC,GAAD;cAA6B,OAAO,EAAQ;cACzC,UAAA,EAAQ;aACC,GAFK,EAAQ,EAEb,CACb,EACY,CAAA,CACT;;YACR,kBAAC,GAAD,EAAY,SAAQ,eAAgB,CAAA;WACjC;;SAEG,CAAA;SACZ,kBAAC,EAAK,OAAN;UAAY,MAAK;UACb,WAAA,MACA,kBAAC,OAAD;WAAK,WAAU;WAAf,UAAA;YACE,kBAAC,GAAD;aAAO,SAAS,EAAQ,eAAe;aACrC,UAAA,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA;YAC1B,CAAA;YACP,kBAAC,GAAD;aACE,IAAI,EAAQ,eAAe;aAC3B,OAAO,EAAM,MAAM;aACnB,WAAW,MACT,EAAM,aAAa,EAAM,OAAO,MAAM,YAAY,CAAC;aAErD,WAAW;aACX,aAAa,EAAU,KAAK;aAC5B,WAAU;aACV,cAAa;aACb,GAAI,EAAgB,iBAAiB,CAAW;YACjD,CAAA;YACD,kBAAC,GAAD,EAAY,SAAQ,gBAAiB,CAAA;WAClC;;SAEG,CAAA;SACZ,kBAAC,IAAD;UAAyB;UAAa;SAAQ,CAAA;QAC3C;OAEA,CAAA,CAAA;;MAET,kBAAC,EAAK,WAAN;OAAgB,WAAW,MAAU,EAAM,OAAO;OAC9C,WAAA,MACA,kBAAC,WAAD;QAAS,WAAU;QAAnB,UAAA;SACE,kBAAC,MAAD;UAAI,WAAU;UACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,OAAS,CAAA;SACzB,CAAA;SACH,MAAU,cACT,kBAAC,IAAD;UAAqB;UAAa;SAAQ,CAAA;SAE3C,MAAU,YAAY,kBAAC,IAAD,EAAoB,QAAO,CAAA;SACjD,MAAU,aAAa,kBAAC,IAAD,EAAqB,QAAO,CAAA;SACnD,MAAU,aACT,kBAAC,KAAD;UAAG,WAAU;UACX,UAAA,kBAAC,GAAD,EAAc,IAAI,kHAAoH,CAAA;SACrI,CAAA;QAEE;;MAEG,CAAA;MAEhB,kBAAC,IAAD;OAAoB;OAAa;MAAQ,CAAA;MACzC,kBAAC,EAAK,WAAN;OAAgB,WAAW,MAAU,EAAM,OAAO;OAC9C,WAAA,MAAU,MAAU,aAAa,kBAAC,IAAD,EAAuB,QAAO,CAAA;MACnD,CAAA;MAEhB,kBAAC,EAAK,WAAN;OAAgB,WAAW,MAAU,EAAM;OACvC,WAAA,MAAW,kBAAC,IAAD,EAAqB,UAAS,CAAA;MAC7B,CAAA;MAEf,KACC,kBAAC,KAAD;OAAG,MAAK;OAAQ,WAAU;OACvB,UAAA,EAAY;MACZ,CAAA;MAEL,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OACE,MAAK;OACL,SAAQ;OACR,eAAe,EAAQ,EAAK;OAE5B,UAAA,kBAAC,GAAD,EAAc,IAAI,SAAW,CAAA;MACvB,CAAA,GACR,kBAAC,GAAD;OACE,MAAK;OACL,UACE,MACA,KACA,KACA,EAAe,WAAW;OAG3B,UAAA,KACG,YACA,IACE,uBACA;MACA,CAAA,CACI,EAAA,CAAA;KACV;;GACO,CAAA,CACT;;CACqB,CAAA;AAEnC;AAqBA,SAAS,GAAkB,EACzB,SACA,YAIC;CACD,IAAM,EAAE,IAAI,MAAY,EAAW;CACnC,OACE,kBAAC,EAAK,OAAN;EAAY,MAAK;EACb,WAAA,MACA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,GAAD;IAAO,SAAS,EAAQ,YAAY;IAClC,UAAA,kBAAC,GAAD,EAAc,IAAI,gBAAkB,CAAA;GAC/B,CAAA,GACP,kBAAC,GAAD;IACE,OAAO,EAAM,MAAM;IACnB,gBAAgB,MACd,EAAM,aAAa,CAAsD;IAH7E,UAAA,CAME,kBAAC,GAAD;KAAe,IAAI,EAAQ,YAAY;KAAG,WAAU;KAClD,UAAA,kBAAC,GAAD,CAAc,CAAA;IACD,CAAA,GACf,kBAAC,GAAD,EAAA,UAAA;KACE,kBAAC,GAAD;MAAY,OAAM;MAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA;KACrB,CAAA;KACZ,kBAAC,GAAD;MAAY,OAAM;MAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,SAAW,CAAA;KACnB,CAAA;KACZ,kBAAC,GAAD;MAAY,OAAM;MAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,UAAY,CAAA;KACpB,CAAA;KACZ,kBAAC,GAAD;MAAY,OAAM;MAAU,UAAU,EAAM,gBAAgB;MAC1D,UAAA,kBAAC,GAAD,EAAc,IAAI,yBAA2B,CAAA;KACnC,CAAA;IACC,EAAA,CAAA,CACT;GACL,CAAA,CAAA;;CAEG,CAAA;AAEhB;AAEA,SAAS,GAAc,EAAE,SAAM,YAA+C;CAC5E,IAAM,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW;CAEpD,OACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,EAAK,OAAN;GAAY,MAAK;GACb,WAAA,MACA,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;KAAO,SAAS,EAAQ,aAAa;KACnC,UAAA,kBAAC,GAAD,EAAc,IAAI,mBAAqB,CAAA;IAClC,CAAA,GACP,kBAAC,KAAD;KAAG,WAAU;KACX,UAAA,kBAAC,GAAD,EACE,IACE,2DAEH,CAAA;IACA,CAAA,CACA,EAAA,CAAA,GACL,kBAAC,IAAD;KACE,IAAI,EAAQ,aAAa;KACzB,SAAS,EAAM,MAAM;KACrB,iBAAiB,EAAM;KACvB,UAAU,OAAO,KAAK,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW;IACxD,CAAA,CACE;;EAEG,CAAA;EACZ,kBAAC,EAAK,WAAN;GAAgB,WAAW,MAAU,EAAM,OAAO;GAC9C,WAAA,MACA,IACE,kBAAC,IAAD;IAAoB;IAAa;GAAQ,CAAA,IAEzC,kBAAC,EAAK,OAAN;IAAY,MAAK;IACb,WAAA,MACA,kBAAC,GAAD;KACE,IAAI;KACJ,OAAO,EAAU,mBAAmB;KACpC,OAAO,EAAM,MAAM;KACnB,UAAU,EAAM;KAChB,aAAY;IACb,CAAA;GAEO,CAAA;EAGF,CAAA;EAChB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAAC,EAAK,OAAN;KAAY,MAAK;KACb,WAAA,MACA,kBAAC,GAAD;MACE,IAAI;MACJ,OAAO,EAAU,SAAS;MAC1B,OAAO,EAAM,MAAM;MACnB,UAAU,EAAM;MAChB,WAAU;MACV,aAAY;KACb,CAAA;IAEO,CAAA;IACZ,kBAAC,EAAK,OAAN;KAAY,MAAK;KACb,WAAA,MACA,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,GAAD;OAAO,SAAS,EAAQ,YAAY;OAClC,UAAA,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA;MAC1B,CAAA,GACP,kBAAC,GAAD;OACE,OAAO,EAAM,MAAM;OACnB,gBAAgB,MACd,EAAM,aAAa,CAAkC;OAHzD,UAAA,CAME,kBAAC,GAAD;QAAe,IAAI,EAAQ,YAAY;QAAG,WAAU;QAClD,UAAA,kBAAC,GAAD,CAAc,CAAA;OACD,CAAA,GACf,kBAAC,GAAD,EAAA,UAAA;QACE,kBAAC,GAAD;SAAY,OAAM;SAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,UAAY,CAAA;QACpB,CAAA;QACZ,kBAAC,GAAD;SAAY,OAAM;SAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,KAAO,CAAA;QACf,CAAA;QACZ,kBAAC,GAAD;SAAY,OAAM;SAChB,UAAA,kBAAC,GAAD,EAAc,IAAI,OAAS,CAAA;QACjB,CAAA;OACC,EAAA,CAAA,CACT;MACL,CAAA,CAAA;;IAEG,CAAA;IACZ,kBAAC,EAAK,OAAN;KAAY,MAAK;KACb,WAAA,MACA,kBAAC,GAAD;MACE,IAAI;MACJ,OAAO,EAAU,gBAAgB;MACjC,OAAO,EAAM,MAAM;MACnB,UAAU,EAAM;MAChB,aAAa,EAAU,YAAY;KACpC,CAAA;IAEO,CAAA;GACT;;CACL,EAAA,CAAA;AAEN;AAEA,SAAS,GAAa,EAAE,SAAM,YAA+C;CAC3E,IAAM,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW,GAE9C,IAAY,EAAM,WAAW,CAAoB;CACvD,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,EAAK,OAAN;EAAY,MAAK;EACb,WAAA,MACA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAAC,GAAD;KAAO,SAAS,EAAQ,kBAAkB;KACxC,UAAA,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA;IAC3B,CAAA;IACP,kBAAC,GAAD;KACE,OAAO,EAAM,MAAM,SAAS;KAC5B,gBAAgB,MAAU,EAAM,aAAa,KAAS,EAAE;KAF1D,UAAA,CAIE,kBAAC,GAAD;MACE,IAAI,EAAQ,kBAAkB;MAC9B,WAAU;MACV,GAAI,EAAgB,oBAAoB,CAAS;MAEjD,UAAA,kBAAC,GAAD,EAAa,aAAa,EAAU,kBAAkB,EAAI,CAAA;KAC7C,CAAA,GACf,kBAAC,GAAD,EAAA,UACG,OAAO,KAAK,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,MACtC,kBAAC,GAAD;MAAsB,OAAO;MAC1B,UAAA;KACS,GAFK,CAEL,CACb,EACY,CAAA,CACT;;IACR,kBAAC,GAAD,EAAY,SAAQ,mBAAoB,CAAA;GACrC;;CAEG,CAAA,GACZ,kBAAC,EAAK,OAAN;EAAY,MAAK;EAAc,MAAK;EAChC,WAAA,MACA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,eAAiB,CAAA,EAC9B,CAAA,GACP,kBAAC,GAAD;MACE,IAAI,EAAQ,iBAAiB;MAC7B,MAAK;MACL,SAAQ;MACR,MAAK;MACL,eACE,EAAM,UAAU;OACd,KAAK;OACL,YAAY;OACZ,eAAe;MACjB,CAAC;MAVL,UAAA,CAaE,kBAAC,GAAD;OAAe,MAAM;OAAW,WAAU;MAAU,CAAA,GACpD,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA,CACzB;KACL,CAAA,CAAA;;IACL,kBAAC,GAAD,EAAY,SAAQ,kBAAmB,CAAA;IACtC,EAAM,MAAM,MAAM,SAAS,KAC1B,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAG,QAAS,CAAA,EACtB,CAAA;MACN,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAG,aAAc,CAAA,EAC3B,CAAA;MACN,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAG,UAAW,CAAA,EACxB,CAAA;MACN,kBAAC,QAAD;OAAM,WAAU;OAAS,eAAY;MAAQ,CAAA;KAC1C;;IAEN,EAAM,MAAM,MAAM,KAAK,GAAK,MAC3B,kBAAC,OAAD;KAEE,WAAU;KAFZ,UAAA;MAIE,kBAAC,GAAD;OACE,IAAI,eAAe,EAAM;OACzB,OAAO,EAAU,OAAO;OACxB,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cAAc,eAAe,EAAM,QAAQ,CAAK;OAEvD,aAAa,EAAU,OAAO;MAC/B,CAAA;MACD,kBAAC,GAAD;OACE,IAAI,eAAe,EAAM;OACzB,OAAO,EAAU,YAAY;OAC7B,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cACH,eAAe,EAAM,eACrB,CACF;OAEF,WAAU;OACV,aAAa,EAAU,OAAO;MAC/B,CAAA;MACD,kBAAC,GAAD;OACE,IAAI,eAAe,EAAM;OACzB,OAAO,EAAU,SAAS;OAC1B,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cACH,eAAe,EAAM,kBACrB,CACF;OAEF,WAAU;OACV,aAAa,EAAU,SAAS;MACjC,CAAA;MACD,kBAAC,IAAD;OACE,OAAO,sBAAsB,IAAQ;OACrC,eAAe,EAAM,YAAY,CAAK;MACvC,CAAA;KACE;IA1CE,GAAA,CA0CF,CACN;GACE;;CAEG,CAAA,CACZ,EAAA,CAAA;AAEN;AAEA,SAAS,GAAa,EAAE,WAAgC;CACtD,IAAM,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW;CAEpD,OACE,kBAAA,GAAA,EAAA,UACE,kBAAC,EAAK,OAAN;EAAY,MAAK;EAAQ,MAAK;EAC1B,WAAA,MACA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,QAAU,CAAA,EACvB,CAAA,GACP,kBAAC,KAAD;MAAG,WAAU;MACX,UAAA,kBAAC,GAAD,EACE,IAAI,sDACL,CAAA;KACA,CAAA,CACA,EAAA,CAAA,GACL,kBAAC,GAAD;MACE,IAAI,EAAQ,UAAU;MACtB,MAAK;MACL,SAAQ;MACR,MAAK;MACL,eACE,EAAM,UAAU;OAAE,MAAM;OAAI,YAAY;OAAI,YAAY;MAAG,CAAC;MANhE,UAAA,CASE,kBAAC,GAAD;OAAe,MAAM;OAAW,WAAU;MAAU,CAAA,GACpD,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA,CACzB;KACL,CAAA,CAAA;;IACL,kBAAC,GAAD,EAAY,SAAQ,WAAY,CAAA;IAC/B,EAAM,MAAM,MAAM,SAAS,KAC1B,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,cAAgB,CAAA,EAC9B,CAAA;MACN,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,aAAe,CAAA,EAC7B,CAAA;MACN,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,cAAgB,CAAA,EAC9B,CAAA;MACN,kBAAC,QAAD;OAAM,WAAU;OAAS,eAAY;MAAQ,CAAA;KAC1C;;IAEN,EAAM,MAAM,MAAM,KAAK,GAAK,MAC3B,kBAAC,OAAD;KAEE,WAAU;KAFZ,UAAA;MAIE,kBAAC,GAAD;OACE,IAAI,QAAQ,EAAM;OAClB,OAAO,EAAU,aAAa;OAC9B,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cAAc,SAAS,EAAM,SAAS,CAAK;OAElD,WAAU;OACV,aACE,MAAU,EAAM,MAAM,MAAM,SAAS,IACjC,aACA;MAEP,CAAA;MACD,kBAAC,GAAD;OACE,IAAI,QAAQ,EAAM;OAClB,OAAO,EAAU,YAAY;OAC7B,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cAAc,SAAS,EAAM,eAAe,CAAK;OAExD,WAAU;OACV,aAAa,EAAU,YAAY;MACpC,CAAA;MACD,kBAAC,GAAD;OACE,IAAI,QAAQ,EAAM;OAClB,OAAO,EAAU,aAAa;OAC9B,OAAO,EAAI;OACX,WAAW,MACT,EAAK,cAAc,SAAS,EAAM,eAAe,CAAK;OAExD,WAAU;OACV,aAAa,EAAU,aAAa;MACrC,CAAA;MACD,kBAAC,IAAD;OACE,OAAO,eAAe,IAAQ;OAC9B,eAAe,EAAM,YAAY,CAAK;OACtC,UAAU,EAAM,MAAM,MAAM,WAAW;MACxC,CAAA;KACE;IA1CE,GAAA,CA0CF,CACN;GACE;;CAEG,CAAA,EACZ,CAAA;AAEN;AAEA,SAAS,GAAc,EAAE,WAAgC;CACvD,IAAM,EAAE,MAAM,MAAc,EAAW;CAEvC,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,EAAK,OAAN;IAAY,MAAK;IACb,WAAA,MACA,kBAAC,GAAD;KACE,IAAI;KACJ,OAAO,EAAU,eAAe;KAChC,OAAO,EAAM,MAAM;KACnB,UAAU,EAAM;KAChB,aAAY;IACb,CAAA;GAEO,CAAA;GACZ,kBAAC,EAAK,OAAN;IAAY,MAAK;IACb,WAAA,MACA,kBAAC,GAAD;KACE,IAAI;KACJ,OAAO,EAAU,mBAAmB;KACpC,OAAO,EAAM,MAAM;KACnB,UAAU,EAAM;KAChB,WAAU;KACV,aAAY;IACb,CAAA;GAEO,CAAA;GACZ,kBAAC,EAAK,OAAN;IAAY,MAAK;IACb,WAAA,MACA,kBAAC,GAAD;KACE,IAAI;KACJ,OAAO,EAAU,YAAY;KAC7B,OAAO,EAAM,MAAM;KACnB,UAAU,EAAM;KAChB,WAAU;KACV,aAAY;IACb,CAAA;GAEO,CAAA;EACT;;AAET;AAEA,SAAS,GAAa,EAAE,SAAM,YAA+C;CAC3E,IAAM,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW,GAE9C,IAAY,EAAM,WAAW,CAAoB;CACvD,OACE,kBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;GACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,gBAAkB,CAAA;EAClC,CAAA,GACJ,kBAAC,KAAD;GAAG,WAAU;GACX,UAAA,kBAAC,GAAD,EACE,IACE,2EAEH,CAAA;EACA,CAAA,CACA,EAAA,CAAA,GACL,kBAAC,EAAK,OAAN;GAAY,MAAK;GAAU,MAAK;GAC5B,WAAA,MACA,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACG,EAAM,MAAM,MAAM,SAAS,KAC1B,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACE,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA,EAC5B,CAAA;OACN,kBAAC,QAAD,EAAA,UACE,kBAAC,GAAD,EAAc,IAAI,SAAW,CAAA,EACzB,CAAA;OACN,kBAAC,QAAD;QAAM,WAAU;QAAS,eAAY;OAAQ,CAAA;MAC1C;;KAEN,EAAM,MAAM,MAAM,KAAK,GAAK,MAC3B,kBAAC,OAAD;MAEE,WAAU;MAFZ,UAAA;OAIE,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA;SACE,kBAAC,GAAD;UACE,SAAS,EAAQ,UAAU,EAAM,WAAW;UAC5C,WAAU;UAEV,UAAA,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA;SAC3B,CAAA;SACP,kBAAC,GAAD;UACE,OAAO,EAAI,OAAO;UAClB,gBAAgB,MACd,EAAK,cAAc,WAAW,EAAM,QAAQ,KAAS,EAAE;UAH3D,UAAA,CAME,kBAAC,GAAD;WACE,IAAI,EAAQ,UAAU,EAAM,WAAW;WACvC,WAAU;WACV,GAAI,EACF,UAAU,EAAM,aAChB,CACF;WAEA,UAAA,kBAAC,GAAD,EAAa,aAAa,EAAU,WAAW,EAAI,CAAA;UACtC,CAAA,GACf,kBAAC,GAAD,EAAA,UACG,OAAO,KAAK,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,MACtC,kBAAC,GAAD;WAAsB,OAAO;WAC1B,UAAA;UACS,GAFK,CAEL,CACb,EACY,CAAA,CACT;;SACR,kBAAC,GAAD,EAAY,SAAS,UAAU,EAAM,YAAc,CAAA;QAChD;;OACL,kBAAC,GAAD;QACE,IAAI,UAAU,EAAM;QACpB,OAAO,EAAU,QAAQ;QACzB,OAAO,EAAI;QACX,WAAW,MACT,EAAK,cAAc,WAAW,EAAM,UAAU,CAAK;QAErD,aAAa,EAAU,QAAQ;OAChC,CAAA;OACD,kBAAC,IAAD;QACE,OAAO,iBAAiB,IAAQ;QAChC,eAAe,EAAM,YAAY,CAAK;OACvC,CAAA;MACE;KAjDE,GAAA,CAiDF,CACN;KACD,kBAAC,GAAD;MACE,MAAK;MACL,SAAQ;MACR,MAAK;MACL,WAAU;MACV,UAAU,OAAO,KAAK,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW;MACvD,eAAe,EAAM,UAAU;OAAE,KAAK;OAAI,OAAO;MAAG,CAAC;MANvD,UAAA,CAQE,kBAAC,GAAD;OAAe,MAAM;OAAW,WAAU;MAAU,CAAA,GACpD,kBAAC,GAAD,EAAc,IAAI,aAAe,CAAA,CAC3B;;IACL;;EAEG,CAAA,CACL;;AAEb;AAEA,SAAS,GAAgB,EAAE,WAAgC;CACzD,IAAM,EAAE,IAAI,GAAS,MAAM,MAAc,EAAW;CACpD,OACE,kBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA;GACE,kBAAC,MAAD;IAAI,WAAU;IACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA;GAC9B,CAAA;GACJ,kBAAC,EAAK,OAAN;IAAY,MAAK;IACb,WAAA,MACA,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,GAAD;MAAO,SAAS,EAAQ,gBAAgB;MACtC,UAAA,kBAAC,GAAD,EAAc,IAAI,iBAAmB,CAAA;KAChC,CAAA,GACP,kBAAC,GAAD;MACE,OAAO,EAAM,MAAM;MACnB,gBAAgB,MACd,EAAM,aAAa,CAA4B;MAHnD,UAAA,CAME,kBAAC,GAAD;OAAe,IAAI,EAAQ,gBAAgB;OAAG,WAAU;OACtD,UAAA,kBAAC,GAAD,CAAc,CAAA;MACD,CAAA,GACf,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAM;OAChB,UAAA,kBAAC,GAAD,EAAc,IAAG,eAAgB,CAAA;MACvB,CAAA,GACZ,kBAAC,GAAD;OAAY,OAAM;OAChB,UAAA,kBAAC,GAAD,EAAc,IAAG,uBAAwB,CAAA;MAC/B,CAAA,CACC,EAAA,CAAA,CACT;KACL,CAAA,CAAA;;GAEG,CAAA;GACZ,kBAAC,EAAK,WAAN;IAAgB,WAAW,MAAU,EAAM,OAAO;IAC9C,WAAA,MACA,MAAS,aACP,kBAAC,EAAK,OAAN;KAAY,MAAK;KACb,WAAA,MACA,kBAAC,GAAD;MACE,IAAI;MACJ,OAAO,EAAU,2BAA2B;MAC5C,OAAO,EAAM,MAAM;MACnB,UAAU,EAAM;MAChB,WAAU;MACV,aAAY;KACb,CAAA;IAEO,CAAA,IACV;GAEQ,CAAA;EACT;;AAEb;AAEA,SAAS,GAAY,EAAE,aAAgD;CACrE,IAAI,IAAU;CACd,IAAI;EACF,IAAM,IAAU,GAAqB,CAAM;EAI3C,AAHA,IAAU,GAAkB,EAC1B,OAAO,EAAQ,MACjB,CAAuB,GACnB,EAAQ,WAAW,aAAa,KAAA,MAClC,KAAW,MAAM,EAAQ,UAAU,SAAS,eAAe,EAAE;CAEjE,QAAQ,CAER;CACA,OACE,kBAAC,WAAD;EAAS,WAAU;EAAqC,aAAU;EAAlE,UAAA,CACE,kBAAC,KAAD;GAAG,WAAU;GACX,UAAA,kBAAC,GAAD,EAAc,IAAI,eAAiB,CAAA;EAClC,CAAA,GACH,kBAAC,KAAD;GAAG,WAAU;GAAyC,UAAA;EAAW,CAAA,CAC1D;;AAEb;AAEA,SAAS,EAAU,EACjB,OACA,UACA,UACA,aACA,gBACA,gBAQC;CACD,IAAM,EAAE,IAAI,MAAY,EAAW,GAE7B,IAAQ,GAAiB,CAAE;CACjC,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,GAAD;IAAO,SAAS,EAAQ,CAAE;IAAI,UAAA;GAAa,CAAA;GAC3C,kBAAC,GAAD;IACE,IAAI,EAAQ,CAAE;IACP;IACP,WAAW,MAAU,EAAS,EAAM,OAAO,KAAK;IACnC;IACF;IACX,cAAa;IACb,GAAI,EAAgB,GAAI,IAAQ;KAAE,SAAS;KAAI,SAAS;IAAM,IAAI,IAAI;GACvE,CAAA;GACD,kBAAC,GAAD,EAAY,SAAS,EAAK,CAAA;EACvB;;AAET;AAEA,SAAS,EAAW,GAA+C;CACjE,OAAO,kBAAC,GAAD;EAAW,GAAI;EAAO,WAAU;CAAW,CAAA;AACpD;AAEA,SAAS,EAAa,EACpB,OACA,UACA,UACA,aACA,gBACA,gBAQC;CACD,IAAM,EAAE,IAAI,MAAY,EAAW,GAE7B,IAAQ,GAAiB,CAAE;CACjC,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,GAAD;IACE,SAAS,EAAQ,CAAE;IACnB,WAAU;IAET,UAAA;GACI,CAAA;GACP,kBAAC,GAAD;IACE,IAAI,EAAQ,CAAE;IACP;IACP,WAAW,MAAU,EAAS,EAAM,OAAO,KAAK;IACnC;IACF;IACX,cAAa;IACb,GAAI,EAAgB,GAAI,IAAQ;KAAE,SAAS;KAAI,SAAS;IAAM,IAAI,IAAI;GACvE,CAAA;GACD,kBAAC,GAAD,EAAY,SAAS,EAAK,CAAA;EACvB;;AAET;AAEA,SAAS,GAAiB,GAAqC;CAC7D,IAAM,IAAQ,EAAM,WAAW,CAAoB;CACnD,OAAO,GAAO,YAAY,IAAU,EAAM,UAAU,KAAA;AACtD;AAEA,SAAS,EAAgB,GAAiB,GAAyB;CACjE,IAAM,IAAU,GAAO,YAAY;CACnC,OAAO;EACL,gBAAgB,KAAW,KAAA;EAC3B,oBAAoB,IAAU,GAAG,EAAQ,UAAU,KAAA;CACrD;AACF;AAEA,SAAS,EAAW,EAAE,cAAgC;CACpD,IAAM,EAAE,IAAI,MAAY,EAAW,GAE7B,IAAU,GAAiB,CAAO;CAExC,OADK,IAEH,kBAAC,KAAD;EAAG,IAAI,EAAQ,GAAG,EAAQ,OAAO;EAAG,WAAU;EAC3C,UAAA;CACA,CAAA,IAJgB;AAMvB;AAEA,SAAS,GAAgB,EACvB,UACA,YACA,eAKC;CACD,OACE,kBAAC,GAAD;EACE,MAAK;EACL,SAAQ;EACR,MAAK;EACL,cAAY;EACH;EACC;EACV,WAAU;EAEV,UAAA,kBAAC,GAAD;GAAe,MAAM;GAAc,WAAU;EAAU,CAAA;CACjD,CAAA;AAEZ;;;AClhCA,IAAM,KAAY;AAElB,SAAgB,KAAsB;CACpC,IAAM,EAAE,MAAM,MAAc,EAAW,GAEjC,EAAE,oBAAiB,EAAiB,GAEpC,CAAC,GAAQ,KAAa,EAAM,SAAS,EAAE,GACvC,IAAQ,EAAe,IAAI,EAAS,GACpC,EAAE,SAAM,cAAW,UAAO,eAAY,GAC1C,EAAa,YAAY,EAAM,MAAM,EAAM,MAAM,CACnD,GACM,IAAgB,EAAiB,GACjC,IAAS,GAAM,QAAQ,CAAC,GACxB,IAAmB,EAAO,KAAK,CAAC,CAAC,YAAY,GAC7C,IAAW,IACb,EAAO,QAAQ,MACb;EACE,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM,WAAW;CACnB,CAAC,CAAC,MAAM,MAAU,GAAO,YAAY,CAAC,CAAC,SAAS,CAAgB,CAAC,CACnE,IACA,GACE,IAAQ,GAAqB;EACjC,SAAS;EACT,OAAO,aAAiB,IAAW,IAAQ,IAAQ,EAAE,QAAQ,IAAI,IAAI;EACrE,OAAO,EAAO;CAChB,CAAC;CAED,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;MACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA;KAC7B,CAAA,GACJ,kBAAC,KAAD;MAAG,WAAU;MACX,UAAA,kBAAC,GAAD,EACE,IACE,wHAEH,CAAA;KACA,CAAA,CACA;IACJ,CAAA,GAAA,KAAiB,MAAU,gBAC1B,kBAAC,IAAD,EAAiB,eAAA,GAAe,CAAA,CAE/B;;GAEJ,KAAQ,CAAC,KACR,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EACE,IACE,iHAEH,CAAA,EACa,CAAA;GAGjB,MAAU,YACT,kBAAC,IAAD,CAAmB,CAAA,IACjB,MAAU,eACZ,kBAAC,GAAD;IACE,OAAO,EAAU,+BAA+B;IAChD,aAAa,EACX,kEACF;GACD,CAAA,IACC,MAAU,UACZ,kBAAC,GAAD;IACE,OAAO,EAAU,8BAA8B;IAC/C,aAAa,EACX,oEACF;IACA,QACE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,MAAK;KAAK,eAAe,KAAK,EAAQ;KAC9D,UAAA,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA;IAC1B,CAAA;GAEX,CAAA,IACC,MAAU,UACZ,kBAAC,GAAD;IACE,OAAO,EAAU,qBAAqB;IACtC,aAAa,EACX,8EACF;IACA,QAAQ,IAAgB,kBAAC,IAAD,EAAiB,eAAA,GAAe,CAAA,IAAI,KAAA;GAC7D,CAAA,IAED,kBAAA,GAAA,EAAA,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,GAAD;MACE,MAAM;MACN,WAAU;KACX,CAAA,GACD,kBAAC,GAAD;MACE,OAAO;MACP,WAAW,MAAU,EAAU,EAAM,OAAO,KAAK;MACjD,WAAU;MACV,aAAa,EAAU,mBAAmB;MAC1C,cAAY,EAAU,4BAA4B;KACnD,CAAA,CACE;;IACL,kBAAC,OAAD;KAAK,WAAU;KACb,UAAA,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UACE,kBAAC,GAAD;MAAU,WAAU;MAApB,UAAA;OACE,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,QAAU,CAAA;OACnB,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,QAAU,CAAA;OACnB,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,cAAgB,CAAA;OACzB,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,gBAAkB,CAAA;OAC3B,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,UAAY,CAAA;OACrB,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,WAAa,CAAA;OACtB,CAAA;OACX,kBAAC,GAAD;QAAW,WAAU;QACnB,UAAA,kBAAC,GAAD,EAAc,IAAI,aAAe,CAAA;OACxB,CAAA;OACX,kBAAC,GAAD,EAAA,UACE,kBAAC,QAAD;QAAM,WAAU;QACd,UAAA,kBAAC,GAAD,EAAc,IAAI,OAAS,CAAA;OACvB,CAAA,EACG,CAAA;MACH;KACC,CAAA,EAAA,CAAA,GACb,kBAAC,IAAD,EAAA,UAAA,CACG,EAAS,KAAK,MACb,kBAAC,IAAD,EAAiC,SAAQ,GAA1B,EAAM,GAAoB,CAC1C,GACA,EAAS,WAAW,KACnB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MACE,SAAS;MACT,WAAU;MAFZ,UAAA;OAIE,kBAAC,GAAD,EAAc,IAAI,iCAAmC,CAAA;OACpD;OAAO;MACC;KACH,CAAA,EAAA,CAAA,CAEH,EAAA,CAAA,CACN,EAAA,CAAA;IACJ,CAAA;IACL,kBAAC,GAAD;KACS;KACP,MAAM,GAAM,MAAM,UAAU;KAC5B,YAAY,GAAM;KAClB,MAAM;KACN,OAAO;MAAC;MAAK;MAAK;KAAG;IACtB,CAAA;GACD,EAAA,CAAA;EAED;;AAET;AAEA,SAAS,GAAS,EAAE,YAA2B;CAC7C,OACE,kBAAC,IAAD;EAAgB,IAAI,qBAAqB,mBAAmB,EAAM,GAAG;EAArE,UAAA;GACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;IACE,WAAU;IACV,IAAI,qBAAqB,mBAAmB,EAAM,GAAG;IAEpD,UAAA,EAAM;GACH,CAAA,GACL,EAAM,QACL,kBAAC,KAAD;IAAG,WAAU;IAAiC,UAAA,EAAM;GAAQ,CAAA,CAErD,EAAA,CAAA;GACX,kBAAC,GAAD,EAAA,UAAY,EAAM,WAAsB,CAAA;GACxC,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAO,SAAQ;IAAa,UAAA,EAAM;GAAmB,CAAA,EAC5C,CAAA;GACX,kBAAC,GAAD;IAAW,WAAU;IAClB,UAAA,GAAkB,EAAM,SAAS;GACzB,CAAA;GACX,kBAAC,GAAD,EAAA,UAAY,EAAM,WAAW,eAAe,IAAe,CAAA;GAC3D,kBAAC,GAAD,EAAA,UACE,kBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CACE,kBAAC,QAAD,EACE,WAAW,yBAAyB,EAAM,eAAe,eAAe,2BACzE,CAAA,GACA,EAAM,eAAe,WAAW,WAC7B;GACG,CAAA,EAAA,CAAA;GACX,kBAAC,GAAD;IAAW,WAAU;IAClB,UAAA,EAAW,EAAM,aAAa;GACtB,CAAA;GACX,kBAAC,GAAD;IAAW,WAAU;IACnB,UAAA,kBAAC,GAAD;KACE,MAAM;KACN,WAAU;IACX,CAAA;GACQ,CAAA;EACG;;AAEpB;AAEA,SAAgB,KAAkB;CAChC,IAAM,EAAE,MAAM,MAAc,EAAW,GAEjC,EAAE,oBAAiB,EAAiB,GAEpC,EAAE,SAAM,OAAO,EAAU,GACzB,IAAW,GACX,IAAW,EAAY,GACvB,IAAa,GAAS,EAAa,WAAW,CAAQ,CAAC,GACvD,IAAgB,EAAiB,GACjC,IAAgB,GACpB,EAAa,YAAY,EAAE,aAAa,6BAA6B,CAAC,CACxE;CAEA,IAAI,EAAW,WAAW,OAAO,kBAAC,IAAD,CAAsB,CAAA;CACvD,IAAI,EAAW,OAAO;EACpB,IAAM,IACJ,EAAW,iBAAiB,KAAY,EAAW,MAAM,WAAW,KAChE,IACJ,EAAW,iBAAiB,KAAY,EAAW,MAAM,WAAW;EACtE,OACE,kBAAC,GAAD;GACE,OACE,IACI,kCACA,IACE,oBACA;GAER,aACE,IACI,2DACA,IACE,8DACA;GAER,QACE,IAAY,KAAA,IACV,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,eACE,IACI,EAAS,mBAAmB,IAC5B,KAAK,EAAW,QAAQ;IAG7B,UAAA,IAAW,qBAAqB;GAC3B,CAAA;EAGb,CAAA;CAEL;CACA,IAAM,IAAQ,EAAW;CACzB,IAAI,CAAC,GAAO,OAAO;CACnB,IAAM,IAAiB,GAAsB,GAAO,CAAa;CAEjE,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,UAAD;IAAQ,WAAU;IAAlB,UAAA;KACE,kBAAC,GAAD;MACE,SAAQ;MACR,MAAK;MACL,eAAe,EAAS,mBAAmB;MAC3C,cAAY,EAAU,kBAAkB;MAExC,UAAA,kBAAC,GAAD;OAAe,MAAM;OAAiB,WAAU;MAAU,CAAA;KACpD,CAAA;KACR,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;QACX,UAAA,EAAM;OACL,CAAA,GACH,CAAC,KACA,kBAAC,GAAD;QAAO,SAAQ;QACb,UAAA,kBAAC,GAAD,EAAc,IAAI,YAAc,CAAA;OAC3B,CAAA,CAEN;MACL,CAAA,GAAA,kBAAC,KAAD;OAAG,WAAU;OAAb,UAAA;QACG,EAAM;QAAW;QAAI,EAAM;QAC3B,EAAM,OAAO,MAAM,EAAM,SAAS;OAClC;MACA,CAAA,CAAA;;KACL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,IAAD;OAAwB;OAAsB;MAAgB,CAAA,GAC9D,kBAAC,IAAD;OACS;OACQ;OACf,UAAU,EAAc,MAAM,QAAQ,CAAC;OACvC,iBAAiB,EAAc;OAC/B,eAAe,EAAQ,EAAc;OACrC,mBACE,EAAc,iBAAiB,KAC/B,EAAc,MAAM,WAAW;MAElC,CAAA,CACE;;IACC;;GAEP,CAAC,KACA,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EACE,IAAI,0DACL,CAAA,EACa,CAAA;GAGlB,kBAAC,WAAD;IAAS,WAAU;IAAnB,UAAA;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;MACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,iBAAmB,CAAA;KACnC,CAAA,GACJ,kBAAC,KAAD;MAAG,WAAU;MAAb,UAAA;OACE,kBAAC,GAAD,EACE,IACE,iGAEH,CAAA;OAAE;OACH,kBAAC,QAAD;QAAM,WAAU;QACd,UAAA,kBAAC,GAAD,EAAc,IAAI,oBAAsB,CAAA;OACpC,CAAA;OACN,kBAAC,GAAD,EAAc,IAAI,oBAAsB,CAAA;MACvC;KACA,CAAA,CAAA,EAAA,CAAA;KACL,kBAAC,MAAD;MAAI,WAAU;MAAd,UAAA;OACE,kBAAC,GAAD;QACE,OAAO,EAAU,YAAY;QAC7B,OAAO,EAAM;OACd,CAAA;OACD,kBAAC,GAAD;QACE,OAAO,EAAU,aAAa;QAC9B,OACE,EAAM,gBAAgB,QAClB,OAAO,EAAM,mBACb;OAEP,CAAA;OACD,kBAAC,GAAD;QAAc,OAAO,EAAU,WAAW;QAAG,OAAO,EAAM;OAAM,CAAA;OAChE,kBAAC,GAAD;QACE,OAAO,EAAU,iBAAiB;QAClC,OAAO,EAAM,oBAAoB,cAAc;OAChD,CAAA;OACA,OAAO,QAAQ,EAAM,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAM,OAChD,kBAAC,GAAD;QAEE,OAAO,cAAc;QACrB,OAAO;OACR,GAHM,CAGN,CACF;MACC;;KACH,KAAkB,KACjB,kBAAC,KAAD;MAAG,WAAU;MAAb,UAAA,CACE,kBAAC,GAAD;OAAe,MAAM;OAAgB,WAAU;MAAU,CAAA,GACxD,CACA;;IAEE;;GAET,kBAAC,IAAD;IAA2B;IAAsB;GAAgB,CAAA;EAC9D;;AAET;AAEA,SAAS,GAAmB,EAC1B,UACA,oBAIC;CACD,IAAM,EAAE,UAAO,kBAAe,sBAAmB,EAAiB,GAE5D,EAAE,MAAM,MAAc,EAAW,GAEjC,IAAU,EAAW,GACrB,IAAc,GAAe,GAC7B,IAAS,GACb,EAAe,2BAA2B,CAAW,CACvD,GACM,IAAO,EAAM,WACb,IAAe,YAAY;EAS1B,UARkB,EAAQ;GAC7B,OAAO;GACP,aACE;GACF,cAAc;GACd,aAAa;GACb,MAAM;EACR,CAAC,GAED,IAAI;GAEF,AADA,MAAM,EAAO,YAAY,CAAK,GAC9B,EAAM,QAAQ,sBAAsB;EACtC,SAAS,GAAO;GACd,EAAc,GAAO,qBAAqB;EAC5C;CACF;CACA,OACE,kBAAC,WAAD;EAAS,WAAU;EAAnB,UAAA,CACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;IACZ,UAAA,kBAAC,GAAD,EAAc,IAAI,eAAiB,CAAA;GACjC,CAAA,GACJ,kBAAC,KAAD;IAAG,WAAU;IACX,UAAA,kBAAC,GAAD,EAAc,IAAI,2BAA6B,CAAA;GAC9C,CAAA,CACA,EAAA,CAAA,GACJ,KAAQ,KACP,kBAAC,GAAD;IACE,SAAQ;IACR,MAAK;IACL,UAAU,EAAO;IACjB,eAAe,KAAK,EAAa;IAJnC,UAAA,CAME,kBAAC,GAAD;KAAe,MAAM;KAAc,WAAU;IAAU,CAAA,GACtD,EAAO,YAAY,cAAc,gBAC5B;GAEP,CAAA,CAAA;EACJ,CAAA,GAAC,EAAM,oBAQH,IASH,kBAAC,MAAD;GAAI,WAAU;GAAd,UAAA;IACE,kBAAC,GAAD;KACE,OAAO,EAAU,OAAO;KACxB,OAAO,GAAkB,CAAI;IAC9B,CAAA;IACD,kBAAC,GAAD;KAAc,OAAO,EAAU,SAAS;KAAG,OAAO,EAAK;IAAc,CAAA;IACrE,kBAAC,GAAD;KACE,OAAO,EAAU,OAAO;KACxB,OAAO,EAAK,MAAM,MAAM,QAAQ,KAAK,GAAG;IACzC,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAU,QAAQ;KACzB,OACE,OAAO,KAAK,EAAK,UAAU,CAAC,CAAC,CAAC,CAAC,SAC3B,OAAO,QAAQ,EAAK,UAAU,CAAC,CAAC,CAAC,CAC9B,KAAK,CAAC,GAAK,OAAY,GAAG,EAAI,IAAI,EAAO,KAAK,IAAI,GAAG,CAAC,CACtD,KAAK,KAAK,IACb;IAEP,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAU,WAAW;KAC5B,OACE,EAAK,WAAW,aAAa,KAAA,IAEzB,SADA,GAAG,EAAK,UAAU,SAAS,eAAe,EAAE;IAGnD,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAU,SAAS;KAC1B,OAAO,EAAW,EAAK,UAAU;IAClC,CAAA;GACC;EAEC,CAAA,IA1CL,kBAAC,KAAD;GAAG,WAAU;GACX,UAAA,kBAAC,GAAD,EACE,IACE,sEAEH,CAAA;EACA,CAAA,IAdH,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EACE,IACE,sEAEH,CAAA,EACa,CAAA,CA4CX;;AAEb;AAEA,SAAS,EAAa,EAAE,UAAO,YAA2C;CACxE,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;GAAiC,UAAA;EAAU,CAAA,GACzD,kBAAC,MAAD;GAAI,WAAU;GACX,UAAA,KAAS;EACR,CAAA,CACD;;AAET;AAEA,SAAS,EAAe,EAAE,eAA2C;CACnE,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,GAAD;GACE,MAAM;GACN,WAAU;EACX,CAAA,GACD,kBAAC,KAAD,EAAI,YAAY,CAAA,CACb;;AAET;AAEA,SAAS,EAAY,EACnB,UACA,gBACA,aAKC;CACD,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;GAAuB,UAAA;EAAU,CAAA,GAC/C,kBAAC,KAAD;GAAG,WAAU;GAAsC,UAAA;EAAe,CAAA,CAC/D,EAAA,CAAA,GACJ,CACE;;AAET;AAEA,SAAS,KAAmB;CAC1B,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,GAC/B,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAsB,WAAU,cAAe,GAAhC,CAAgC,CAChD,CACE;;AAET;AAEA,SAAS,KAAsB;CAC7B,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA;GACjC,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;GACnC,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;GACnC,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;EAChC;;AAET"}