@dainamite/cpq 0.6.0 → 0.7.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 (164) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js +3 -9
  3. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js.map +2 -2
  4. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js +21 -25
  5. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js.map +2 -2
  6. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js +48 -47
  7. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js.map +2 -2
  8. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js +1 -1
  9. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js.map +2 -2
  10. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +2 -2
  11. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +2 -2
  12. package/dist/modules/cpq/backend/cpq/inventory/shared.js +37 -2
  13. package/dist/modules/cpq/backend/cpq/inventory/shared.js.map +2 -2
  14. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +154 -178
  15. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +2 -2
  16. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js +1 -1
  17. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js.map +2 -2
  18. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js +168 -143
  19. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js.map +2 -2
  20. package/dist/modules/cpq/backend/cpq/offerings/page.js +36 -34
  21. package/dist/modules/cpq/backend/cpq/offerings/page.js.map +2 -2
  22. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +69 -66
  23. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +2 -2
  24. package/dist/modules/cpq/backend/cpq/orders/page.js +6 -6
  25. package/dist/modules/cpq/backend/cpq/orders/page.js.map +2 -2
  26. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js +41 -36
  27. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js.map +2 -2
  28. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js +76 -72
  29. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js.map +2 -2
  30. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js +1 -1
  31. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js.map +2 -2
  32. package/dist/modules/cpq/backend/cpq/price-rules/page.js +18 -15
  33. package/dist/modules/cpq/backend/cpq/price-rules/page.js.map +2 -2
  34. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js +23 -21
  35. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js.map +2 -2
  36. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js +22 -50
  37. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js.map +2 -2
  38. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js +74 -52
  39. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js.map +2 -2
  40. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js +20 -17
  41. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js.map +2 -2
  42. package/dist/modules/cpq/backend/cpq/pricing/page.js +1 -1
  43. package/dist/modules/cpq/backend/cpq/pricing/page.js.map +2 -2
  44. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js +115 -123
  45. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js.map +2 -2
  46. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js +6 -3
  47. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js.map +2 -2
  48. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +129 -94
  49. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +2 -2
  50. package/dist/modules/cpq/backend/cpq/quotes/page.js +23 -19
  51. package/dist/modules/cpq/backend/cpq/quotes/page.js.map +2 -2
  52. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js +19 -15
  53. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js.map +2 -2
  54. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js +171 -178
  55. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js.map +2 -2
  56. package/dist/modules/cpq/backend/cpq/specifications/page.js +2 -2
  57. package/dist/modules/cpq/backend/cpq/specifications/page.js.map +2 -2
  58. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js +60 -50
  59. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js.map +2 -2
  60. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js +22 -18
  61. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js.map +2 -2
  62. package/dist/modules/cpq/backend/cpq/wizards/page.js +1 -1
  63. package/dist/modules/cpq/backend/cpq/wizards/page.js.map +2 -2
  64. package/dist/modules/cpq/components/ArcLineDiff.js +2 -2
  65. package/dist/modules/cpq/components/ArcLineDiff.js.map +2 -2
  66. package/dist/modules/cpq/components/ChargeBreakdownTable.js +4 -10
  67. package/dist/modules/cpq/components/ChargeBreakdownTable.js.map +2 -2
  68. package/dist/modules/cpq/components/PriceWaterfall.js +3 -1
  69. package/dist/modules/cpq/components/PriceWaterfall.js.map +2 -2
  70. package/dist/modules/cpq/components/PricingSummaryCard.js +1 -6
  71. package/dist/modules/cpq/components/PricingSummaryCard.js.map +2 -2
  72. package/dist/modules/cpq/components/StatusPath.js +5 -3
  73. package/dist/modules/cpq/components/StatusPath.js.map +2 -2
  74. package/dist/modules/cpq/components/useCpqRowActions.js +10 -22
  75. package/dist/modules/cpq/components/useCpqRowActions.js.map +2 -2
  76. package/dist/modules/cpq/i18n/de.json +1220 -0
  77. package/dist/modules/cpq/i18n/en.json +1220 -0
  78. package/dist/modules/cpq/i18n/es.json +1220 -0
  79. package/dist/modules/cpq/i18n/pl.json +1220 -0
  80. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js +39 -31
  81. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js.map +2 -2
  82. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js +13 -5
  83. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js.map +2 -2
  84. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js +41 -21
  85. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js.map +2 -2
  86. package/dist/modules/cpq/widgets/injection-table.js +2 -2
  87. package/dist/modules/cpq/widgets/injection-table.js.map +2 -2
  88. package/dist/modules/cpq/workflows/WizardRunner.js +10 -8
  89. package/dist/modules/cpq/workflows/WizardRunner.js.map +2 -2
  90. package/dist/modules/cpq/workflows/WizardTrigger.js +15 -9
  91. package/dist/modules/cpq/workflows/WizardTrigger.js.map +2 -2
  92. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js +9 -7
  93. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js.map +2 -2
  94. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js +9 -4
  95. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js.map +2 -2
  96. package/dist/modules/cpq/workflows/steps/ItemListStep.js +16 -19
  97. package/dist/modules/cpq/workflows/steps/ItemListStep.js.map +2 -2
  98. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js +19 -32
  99. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js.map +2 -2
  100. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js +8 -6
  101. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js.map +2 -2
  102. package/dist/modules/cpq/workflows/steps/ReviewStep.js +32 -30
  103. package/dist/modules/cpq/workflows/steps/ReviewStep.js.map +2 -2
  104. package/dist/modules/cpq/workflows/steps/index.js +12 -0
  105. package/dist/modules/cpq/workflows/steps/index.js.map +2 -2
  106. package/package.json +1 -1
  107. package/src/modules/cpq/__tests__/i18n/dictionaries.test.ts +62 -0
  108. package/src/modules/cpq/__tests__/i18n/hardcodedStrings.test.ts +35 -0
  109. package/src/modules/cpq/__tests__/i18n/sourceScan.ts +109 -0
  110. package/src/modules/cpq/backend/cpq/inventory/AssetsTable.tsx +3 -9
  111. package/src/modules/cpq/backend/cpq/inventory/SubscriptionsTable.tsx +22 -26
  112. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.ts +1 -1
  113. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.tsx +43 -46
  114. package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +2 -2
  115. package/src/modules/cpq/backend/cpq/inventory/shared.tsx +37 -1
  116. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.ts +1 -1
  117. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +134 -112
  118. package/src/modules/cpq/backend/cpq/offerings/[id]/page.tsx +169 -130
  119. package/src/modules/cpq/backend/cpq/offerings/page.tsx +34 -24
  120. package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +66 -43
  121. package/src/modules/cpq/backend/cpq/orders/page.tsx +6 -6
  122. package/src/modules/cpq/backend/cpq/price-rules/PriceRuleForm.tsx +48 -34
  123. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.meta.ts +1 -1
  124. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.tsx +76 -70
  125. package/src/modules/cpq/backend/cpq/price-rules/page.tsx +25 -16
  126. package/src/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.tsx +24 -18
  127. package/src/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.tsx +29 -19
  128. package/src/modules/cpq/backend/cpq/pricing/[id]/page.tsx +95 -47
  129. package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.ts +23 -15
  130. package/src/modules/cpq/backend/cpq/pricing/page.tsx +1 -1
  131. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.tsx +111 -88
  132. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.tsx +3 -3
  133. package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +134 -89
  134. package/src/modules/cpq/backend/cpq/quotes/page.tsx +29 -21
  135. package/src/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.tsx +19 -15
  136. package/src/modules/cpq/backend/cpq/specifications/[id]/page.tsx +171 -171
  137. package/src/modules/cpq/backend/cpq/specifications/page.tsx +2 -2
  138. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.tsx +51 -41
  139. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/page.tsx +17 -13
  140. package/src/modules/cpq/backend/cpq/wizards/page.tsx +1 -1
  141. package/src/modules/cpq/components/ArcLineDiff.tsx +2 -2
  142. package/src/modules/cpq/components/ChargeBreakdownTable.tsx +4 -2
  143. package/src/modules/cpq/components/PriceWaterfall.tsx +4 -2
  144. package/src/modules/cpq/components/PricingSummaryCard.tsx +1 -1
  145. package/src/modules/cpq/components/StatusPath.tsx +7 -4
  146. package/src/modules/cpq/components/useCpqRowActions.tsx +17 -25
  147. package/src/modules/cpq/i18n/de.json +1220 -0
  148. package/src/modules/cpq/i18n/en.json +1220 -0
  149. package/src/modules/cpq/i18n/es.json +1220 -0
  150. package/src/modules/cpq/i18n/pl.json +1220 -0
  151. package/src/modules/cpq/widgets/injection/customer-inventory/widget.client.tsx +38 -31
  152. package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.client.tsx +7 -5
  153. package/src/modules/cpq/widgets/injection/quote-configurator/widget.client.tsx +36 -21
  154. package/src/modules/cpq/widgets/injection-table.ts +8 -2
  155. package/src/modules/cpq/workflows/WizardRunner.tsx +8 -5
  156. package/src/modules/cpq/workflows/WizardTrigger.tsx +15 -9
  157. package/src/modules/cpq/workflows/steps/CustomerSelectStep.tsx +11 -7
  158. package/src/modules/cpq/workflows/steps/InventorySelectStep.tsx +9 -5
  159. package/src/modules/cpq/workflows/steps/ItemListStep.tsx +18 -12
  160. package/src/modules/cpq/workflows/steps/OfferingSelectStep.tsx +20 -16
  161. package/src/modules/cpq/workflows/steps/ProductConfigureStep.tsx +8 -6
  162. package/src/modules/cpq/workflows/steps/ReviewStep.tsx +33 -18
  163. package/src/modules/cpq/workflows/steps/index.ts +12 -0
  164. package/src/modules/cpq/workflows/types.ts +4 -0
@@ -25,6 +25,7 @@ import {
25
25
  } from "../../../components/statusMaps.js";
26
26
  const PAGE_SIZE = 50;
27
27
  function ChargePopover({ charge }) {
28
+ const t = useT();
28
29
  const [open, setOpen] = React.useState(false);
29
30
  const variant = chargeTypeMap[charge.chargeType] ?? "neutral";
30
31
  return /* @__PURE__ */ jsxs(
@@ -40,17 +41,14 @@ function ChargePopover({ charge }) {
40
41
  /* @__PURE__ */ jsx("div", { className: "text-muted-foreground font-mono", children: charge.code }),
41
42
  charge.description && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: charge.description }),
42
43
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pt-1 border-t", children: [
43
- /* @__PURE__ */ jsxs("span", { children: [
44
- "Pricing: ",
45
- charge.pricingMethod
46
- ] }),
44
+ /* @__PURE__ */ jsx("span", { children: t("cpq.offerings.list.chargePopover.pricing", "Pricing: {method}", { method: charge.pricingMethod }) }),
47
45
  charge.fixedPrice != null && /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
48
46
  charge.currencyCode ?? "USD",
49
47
  " ",
50
48
  charge.fixedPrice
51
49
  ] })
52
50
  ] }),
53
- !charge.isActive && /* @__PURE__ */ jsx(Tag, { variant: "warning", dot: true, children: "Inactive" }),
51
+ !charge.isActive && /* @__PURE__ */ jsx(Tag, { variant: "warning", dot: true, children: t("cpq.common.inactive", "Inactive") }),
54
52
  /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-2 h-2 bg-popover border-b border-r rotate-45 -mt-1" })
55
53
  ] })
56
54
  ]
@@ -163,7 +161,7 @@ function OfferingsListPage() {
163
161
  });
164
162
  if (!res.ok) {
165
163
  const body = await res.json().catch(() => ({}));
166
- setError(body.error ?? `Failed to save charge for ${offering.name}`);
164
+ setError(body.error ?? t("cpq.offerings.bulk.error.saveChargeFor", "Failed to save charge for {name}", { name: offering.name }));
167
165
  setSaving(false);
168
166
  return;
169
167
  }
@@ -173,7 +171,7 @@ function OfferingsListPage() {
173
171
  setBulkChargeTargets([]);
174
172
  data.reload();
175
173
  } catch {
176
- setError("Failed to save charges");
174
+ setError(t("cpq.offerings.bulk.error.saveCharges", "Failed to save charges"));
177
175
  } finally {
178
176
  setSaving(false);
179
177
  }
@@ -197,7 +195,7 @@ function OfferingsListPage() {
197
195
  header: t("cpq.offerings.name", "Name"),
198
196
  cell: ({ row }) => /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
199
197
  row.original.name,
200
- row.original.offeringType === "bundle" && /* @__PURE__ */ jsx(Tag, { variant: "brand", className: "ml-2 px-2 text-[10px]", children: "bundle" })
198
+ row.original.offeringType === "bundle" && /* @__PURE__ */ jsx(Tag, { variant: "brand", className: "ml-2 px-2 text-[10px]", children: t("cpq.offerings.list.tag.bundle", "bundle") })
201
199
  ] })
202
200
  },
203
201
  {
@@ -251,39 +249,47 @@ function OfferingsListPage() {
251
249
  bulkChargeTargets.length > 1 ? t("cpq.offerings.bulk.offeringsPlural", "offerings") : t("cpq.offerings.bulk.offeringsSingular", "offering")
252
250
  ] }),
253
251
  /* @__PURE__ */ jsxs(Alert, { children: [
254
- "Bulk creation supports ",
255
- /* @__PURE__ */ jsx("strong", { children: "flat pricing only" }),
256
- ". For ",
257
- /* @__PURE__ */ jsx("em", { children: "per unit" }),
258
- " or ",
259
- /* @__PURE__ */ jsx("em", { children: "tiered" }),
260
- " pricing, open each offering individually \u2014 those methods need a pricing table and a numeric attribute that lives on the offering's spec, which usually differs between offerings."
252
+ t("cpq.offerings.bulk.notice.supports", "Bulk creation supports"),
253
+ " ",
254
+ /* @__PURE__ */ jsx("strong", { children: t("cpq.offerings.bulk.notice.flatOnly", "flat pricing only") }),
255
+ t("cpq.offerings.bulk.notice.for", ". For"),
256
+ " ",
257
+ /* @__PURE__ */ jsx("em", { children: t("cpq.offerings.bulk.notice.perUnit", "per unit") }),
258
+ " ",
259
+ t("cpq.offerings.bulk.notice.or", "or"),
260
+ " ",
261
+ /* @__PURE__ */ jsx("em", { children: t("cpq.offerings.bulk.notice.tiered", "tiered") }),
262
+ " ",
263
+ t(
264
+ "cpq.offerings.bulk.notice.rest",
265
+ "pricing, open each offering individually \u2014 those methods need a pricing table and a numeric attribute that lives on the offering's spec, which usually differs between offerings."
266
+ )
261
267
  ] }),
262
268
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-3", children: [
263
269
  /* @__PURE__ */ jsxs("div", { children: [
264
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: "Code" }),
270
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: t("cpq.offerings.bulk.fields.code", "Code") }),
265
271
  /* @__PURE__ */ jsx(
266
272
  Input,
267
273
  {
268
274
  value: chargeForm.code,
269
275
  onChange: (e) => setChargeForm({ ...chargeForm, code: e.target.value }),
270
- placeholder: "e.g. mrc-monthly"
276
+ placeholder: t("cpq.offerings.bulk.fields.codePlaceholder", "e.g. mrc-monthly")
271
277
  }
272
278
  )
273
279
  ] }),
274
280
  /* @__PURE__ */ jsxs("div", { children: [
275
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: "Name" }),
281
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: t("cpq.offerings.bulk.fields.name", "Name") }),
276
282
  /* @__PURE__ */ jsx(
277
283
  Input,
278
284
  {
279
285
  value: chargeForm.name,
280
286
  onChange: (e) => setChargeForm({ ...chargeForm, name: e.target.value }),
281
- placeholder: "e.g. Monthly Recurring"
287
+ placeholder: t("cpq.offerings.bulk.fields.namePlaceholder", "e.g. Monthly Recurring")
282
288
  }
283
289
  )
284
290
  ] }),
285
291
  /* @__PURE__ */ jsxs("div", { children: [
286
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: "Type" }),
292
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: t("cpq.offerings.bulk.fields.type", "Type") }),
287
293
  /* @__PURE__ */ jsxs(
288
294
  Select,
289
295
  {
@@ -292,9 +298,9 @@ function OfferingsListPage() {
292
298
  children: [
293
299
  /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
294
300
  /* @__PURE__ */ jsxs(SelectContent, { children: [
295
- /* @__PURE__ */ jsx(SelectItem, { value: "nrc", children: "NRC (Non-Recurring)" }),
296
- /* @__PURE__ */ jsx(SelectItem, { value: "mrc", children: "MRC (Monthly Recurring)" }),
297
- /* @__PURE__ */ jsx(SelectItem, { value: "usage", children: "Usage" })
301
+ /* @__PURE__ */ jsx(SelectItem, { value: "nrc", children: t("cpq.offerings.chargeType.nrc", "NRC (Non-Recurring)") }),
302
+ /* @__PURE__ */ jsx(SelectItem, { value: "mrc", children: t("cpq.offerings.chargeType.mrc", "MRC (Monthly Recurring)") }),
303
+ /* @__PURE__ */ jsx(SelectItem, { value: "usage", children: t("cpq.offerings.chargeType.usage", "Usage") })
298
304
  ] })
299
305
  ]
300
306
  }
@@ -302,19 +308,19 @@ function OfferingsListPage() {
302
308
  ] })
303
309
  ] }),
304
310
  /* @__PURE__ */ jsxs("div", { children: [
305
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: "Description" }),
311
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium mb-1", children: t("cpq.offerings.bulk.fields.description", "Description") }),
306
312
  /* @__PURE__ */ jsx(
307
313
  Input,
308
314
  {
309
315
  value: chargeForm.description,
310
316
  onChange: (e) => setChargeForm({ ...chargeForm, description: e.target.value }),
311
- placeholder: "User-facing charge description"
317
+ placeholder: t("cpq.offerings.bulk.fields.descriptionPlaceholder", "User-facing charge description")
312
318
  }
313
319
  )
314
320
  ] }),
315
321
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
316
322
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
317
- /* @__PURE__ */ jsx("label", { className: "text-xs font-medium", children: "Currency" }),
323
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium", children: t("cpq.offerings.bulk.fields.currency", "Currency") }),
318
324
  /* @__PURE__ */ jsx(
319
325
  Input,
320
326
  {
@@ -327,12 +333,8 @@ function OfferingsListPage() {
327
333
  ] }),
328
334
  /* @__PURE__ */ jsx("div", { className: "rounded border", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
329
335
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/30", children: [
330
- /* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-medium text-xs", children: "Offering" }),
331
- /* @__PURE__ */ jsxs("th", { className: "px-3 py-2 text-left font-medium text-xs", children: [
332
- "Price (",
333
- chargeCurrency,
334
- ")"
335
- ] })
336
+ /* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-medium text-xs", children: t("cpq.offerings.bulk.table.offering", "Offering") }),
337
+ /* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-medium text-xs", children: t("cpq.offerings.bulk.table.price", "Price ({currency})", { currency: chargeCurrency }) })
336
338
  ] }) }),
337
339
  /* @__PURE__ */ jsx("tbody", { children: bulkChargeTargets.map((o) => /* @__PURE__ */ jsxs("tr", { className: "border-b last:border-0", children: [
338
340
  /* @__PURE__ */ jsxs("td", { className: "px-3 py-2 font-medium text-xs", children: [
@@ -363,10 +365,10 @@ function OfferingsListPage() {
363
365
  type: "button",
364
366
  onClick: saveChargesForSelected,
365
367
  disabled: saving || !chargeForm.code || !chargeForm.name,
366
- children: saving ? "Saving..." : `Create Charge for ${bulkChargeTargets.length} Offering${bulkChargeTargets.length > 1 ? "s" : ""}`
368
+ children: saving ? t("cpq.common.saving", "Saving...") : bulkChargeTargets.length > 1 ? t("cpq.offerings.bulk.submitPlural", "Create Charge for {count} Offerings", { count: bulkChargeTargets.length }) : t("cpq.offerings.bulk.submitSingular", "Create Charge for {count} Offering", { count: bulkChargeTargets.length })
367
369
  }
368
370
  ),
369
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => setBulkChargeOpen(false), children: "Cancel" })
371
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => setBulkChargeOpen(false), children: t("cpq.common.cancel", "Cancel") })
370
372
  ] })
371
373
  ] });
372
374
  const toolbarContent = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/cpq/backend/cpq/offerings/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { type BulkAction } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Checkbox } from '@open-mercato/ui/primitives/checkbox'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Alert } from '@open-mercato/ui/primitives/alert'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { CpqListView, useCpqListData } from '../../../components/CpqListView'\nimport { NumberInput } from '../../../components/NumberInput'\nimport {\n chargeTypeMap,\n formatStatusLabel,\n lifecycleStatusMap,\n type ChargeType,\n type LifecycleStatus,\n} from '../../../components/statusMaps'\n\ntype Charge = {\n id: string\n code: string\n name: string\n description: string | null\n chargeType: string\n pricingMethod: string\n fixedPrice: string | null\n currencyCode: string | null\n isActive: boolean\n}\n\ntype Offering = {\n id: string\n specId: string\n code: string\n name: string\n description: string | null\n offeringType: string\n designTimeValues: Record<string, unknown>\n lifecycleStatus: string\n isActive: boolean\n createdAt: string\n charges?: Charge[]\n}\n\nconst PAGE_SIZE = 50\n\nfunction ChargePopover({ charge }: { charge: Charge }) {\n const [open, setOpen] = React.useState(false)\n const variant = chargeTypeMap[charge.chargeType as ChargeType] ?? 'neutral'\n return (\n <span\n className=\"relative inline-flex\"\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n >\n <Tag variant={variant} className=\"cursor-default px-2 text-[10px]\">\n {charge.chargeType.toUpperCase()}\n </Tag>\n {open && (\n <div className=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-2 z-50 w-56 rounded-lg border bg-popover p-3 shadow-md text-popover-foreground text-xs space-y-1.5\">\n <div className=\"font-medium text-sm\">{charge.name}</div>\n <div className=\"text-muted-foreground font-mono\">{charge.code}</div>\n {charge.description && <div className=\"text-muted-foreground\">{charge.description}</div>}\n <div className=\"flex items-center justify-between pt-1 border-t\">\n <span>Pricing: {charge.pricingMethod}</span>\n {charge.fixedPrice != null && (\n <span className=\"font-medium\">\n {charge.currencyCode ?? 'USD'} {charge.fixedPrice}\n </span>\n )}\n </div>\n {!charge.isActive && <Tag variant=\"warning\" dot>Inactive</Tag>}\n <div className=\"absolute left-1/2 -translate-x-1/2 top-full w-2 h-2 bg-popover border-b border-r rotate-45 -mt-1\" />\n </div>\n )}\n </span>\n )\n}\n\nfunction buildFilterParams(values: FilterValues, params: URLSearchParams) {\n if (typeof values.lifecycleStatus === 'string' && values.lifecycleStatus) {\n params.set('lifecycleStatus', values.lifecycleStatus)\n }\n if (typeof values.offeringType === 'string' && values.offeringType) {\n params.set('offeringType', values.offeringType)\n }\n if (values.isActive === true) params.set('isActive', 'true')\n if (values.isActive === false) params.set('isActive', 'false')\n}\n\nexport default function OfferingsListPage() {\n const t = useT()\n const router = useRouter()\n\n const data = useCpqListData<Offering>({\n endpoint: '/api/cpq/product-offerings',\n pageSize: PAGE_SIZE,\n buildFilterParams,\n loadErrorMessage: t('cpq.offerings.list.error.load', 'Failed to load offerings'),\n })\n\n // Bulk charge creation is restricted to `flat` pricing \u2014 per_unit/tiered\n // need a pricing table + a numeric quantity attribute that lives on the\n // offering's spec, which differs between selected offerings. We push\n // users to the per-offering detail page for those methods.\n const [bulkChargeOpen, setBulkChargeOpen] = React.useState(false)\n const [bulkChargeTargets, setBulkChargeTargets] = React.useState<Offering[]>([])\n const [chargeForm, setChargeForm] = React.useState({\n code: '',\n name: '',\n description: '',\n chargeType: 'mrc',\n })\n const [chargePrices, setChargePrices] = React.useState<Record<string, string>>({})\n const [chargeCurrency, setChargeCurrency] = React.useState('USD')\n const [saving, setSaving] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n\n const lifecycleOptions = React.useMemo(\n () => [\n { value: 'draft', label: t('cpq.offerings.lifecycle.draft', 'Draft') },\n { value: 'active', label: t('cpq.offerings.lifecycle.active', 'Active') },\n { value: 'deprecated', label: t('cpq.offerings.lifecycle.deprecated', 'Deprecated') },\n ],\n [t],\n )\n\n const offeringTypeOptions = React.useMemo(\n () => [\n { value: 'simple', label: t('cpq.offerings.type.simple', 'Simple') },\n { value: 'bundle', label: t('cpq.offerings.type.bundle', 'Bundle') },\n ],\n [t],\n )\n\n const filters = React.useMemo<FilterDef[]>(\n () => [\n {\n id: 'lifecycleStatus',\n label: t('cpq.offerings.filters.lifecycleStatus', 'Lifecycle Status'),\n type: 'select',\n options: lifecycleOptions,\n },\n {\n id: 'offeringType',\n label: t('cpq.offerings.filters.offeringType', 'Type'),\n type: 'select',\n options: offeringTypeOptions,\n },\n {\n id: 'isActive',\n label: t('cpq.offerings.filters.isActive', 'Active'),\n type: 'checkbox',\n },\n ],\n [lifecycleOptions, offeringTypeOptions, t],\n )\n\n const openBulkChargeForm = React.useCallback(\n (targets: Offering[]) => {\n setBulkChargeTargets(targets)\n setChargeForm({ code: '', name: '', description: '', chargeType: 'mrc' })\n setChargePrices({})\n setChargeCurrency('USD')\n setError(null)\n setBulkChargeOpen(true)\n },\n [],\n )\n\n const saveChargesForSelected = React.useCallback(async () => {\n const targets = bulkChargeTargets\n if (!targets.length || !chargeForm.code || !chargeForm.name) return\n setSaving(true)\n setError(null)\n try {\n for (const offering of targets) {\n const chargeCode = targets.length > 1 ? `${offering.code}--${chargeForm.code}` : chargeForm.code\n const payload: Record<string, unknown> = {\n offeringId: offering.id,\n code: chargeCode,\n name: chargeForm.name,\n description: chargeForm.description || null,\n chargeType: chargeForm.chargeType,\n pricingMethod: 'flat',\n fixedPrice: chargePrices[offering.id] || null,\n currencyCode: chargeCurrency,\n isActive: true,\n sortOrder: 0,\n }\n const res = await fetch('/api/cpq/product-charges', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n })\n if (!res.ok) {\n const body = await res.json().catch(() => ({} as { error?: string }))\n setError(body.error ?? `Failed to save charge for ${offering.name}`)\n setSaving(false)\n return\n }\n }\n flash(t('cpq.offerings.flash.chargesCreated', 'Charges created'), 'success')\n setBulkChargeOpen(false)\n setBulkChargeTargets([])\n data.reload()\n } catch {\n setError('Failed to save charges')\n } finally {\n setSaving(false)\n }\n }, [\n bulkChargeTargets,\n chargeCurrency,\n chargeForm,\n chargePrices,\n data,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<Offering>[]>(\n () => [\n {\n accessorKey: 'code',\n header: t('cpq.offerings.code', 'Code'),\n cell: ({ row }) => <span className=\"font-mono text-xs\">{row.original.code}</span>,\n },\n {\n accessorKey: 'name',\n header: t('cpq.offerings.name', 'Name'),\n cell: ({ row }) => (\n <span className=\"font-medium\">\n {row.original.name}\n {row.original.offeringType === 'bundle' && (\n <Tag variant=\"brand\" className=\"ml-2 px-2 text-[10px]\">\n bundle\n </Tag>\n )}\n </span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('cpq.offerings.isActive', 'Is Active?'),\n cell: ({ row }) => <Checkbox checked={row.original.isActive} disabled />,\n },\n {\n accessorKey: 'lifecycleStatus',\n header: t('cpq.offerings.lifecycleStatus', 'Lifecycle Status'),\n cell: ({ row }) => (\n <Tag variant={lifecycleStatusMap[row.original.lifecycleStatus as LifecycleStatus] ?? 'neutral'} dot>\n {formatStatusLabel(row.original.lifecycleStatus)}\n </Tag>\n ),\n },\n {\n id: 'charges',\n header: t('cpq.offerings.charges', 'Charges'),\n cell: ({ row }) => {\n const charges = row.original.charges ?? []\n if (charges.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n return (\n <div className=\"flex flex-wrap gap-1\" onClick={(e) => e.stopPropagation()}>\n {charges.map((ch) => (\n <ChargePopover key={ch.id} charge={ch} />\n ))}\n </div>\n )\n },\n },\n {\n accessorKey: 'description',\n header: t('cpq.offerings.description', 'Description'),\n cell: ({ row }) => (\n <span className=\"text-muted-foreground\">{row.original.description ?? '\u2014'}</span>\n ),\n meta: { truncate: true, maxWidth: 320 },\n },\n ],\n [t],\n )\n\n // Module-specific bulk actions; \"Delete selected\" is appended automatically\n // by CpqListView when `crud` is provided.\n const bulkActions = React.useMemo<BulkAction<Offering>[]>(\n () => [\n {\n id: 'add-charge',\n label: t('cpq.offerings.bulk.addCharge', 'Add Charge'),\n onExecute: (selectedRows) => {\n if (!selectedRows.length) return { ok: false }\n openBulkChargeForm(selectedRows)\n return { ok: true }\n },\n },\n ],\n [openBulkChargeForm, t],\n )\n\n const bulkChargeForm = bulkChargeOpen && bulkChargeTargets.length > 0 && (\n <div className=\"rounded-lg border bg-card p-5 space-y-4\">\n <h4 className=\"font-medium text-sm\">\n {t('cpq.offerings.bulk.formTitle', 'New Flat-Price Charge for')} {bulkChargeTargets.length}{' '}\n {bulkChargeTargets.length > 1\n ? t('cpq.offerings.bulk.offeringsPlural', 'offerings')\n : t('cpq.offerings.bulk.offeringsSingular', 'offering')}\n </h4>\n\n <Alert>\n Bulk creation supports <strong>flat pricing only</strong>. For <em>per unit</em> or <em>tiered</em> pricing,\n open each offering individually \u2014 those methods need a pricing table and a numeric attribute that lives on\n the offering&apos;s spec, which usually differs between offerings.\n </Alert>\n\n <div className=\"grid grid-cols-3 gap-3\">\n <div>\n <label className=\"block text-xs font-medium mb-1\">Code</label>\n <Input\n value={chargeForm.code}\n onChange={(e) => setChargeForm({ ...chargeForm, code: e.target.value })}\n placeholder=\"e.g. mrc-monthly\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium mb-1\">Name</label>\n <Input\n value={chargeForm.name}\n onChange={(e) => setChargeForm({ ...chargeForm, name: e.target.value })}\n placeholder=\"e.g. Monthly Recurring\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium mb-1\">Type</label>\n <Select\n value={chargeForm.chargeType}\n onValueChange={(value) => setChargeForm({ ...chargeForm, chargeType: value })}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"nrc\">NRC (Non-Recurring)</SelectItem>\n <SelectItem value=\"mrc\">MRC (Monthly Recurring)</SelectItem>\n <SelectItem value=\"usage\">Usage</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium mb-1\">Description</label>\n <Input\n value={chargeForm.description}\n onChange={(e) => setChargeForm({ ...chargeForm, description: e.target.value })}\n placeholder=\"User-facing charge description\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-3\">\n <label className=\"text-xs font-medium\">Currency</label>\n <Input\n value={chargeCurrency}\n onChange={(e) => setChargeCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n className=\"w-20\"\n />\n </div>\n <div className=\"rounded border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/30\">\n <th className=\"px-3 py-2 text-left font-medium text-xs\">Offering</th>\n <th className=\"px-3 py-2 text-left font-medium text-xs\">Price ({chargeCurrency})</th>\n </tr>\n </thead>\n <tbody>\n {bulkChargeTargets.map((o) => (\n <tr key={o.id} className=\"border-b last:border-0\">\n <td className=\"px-3 py-2 font-medium text-xs\">\n {o.name} <span className=\"text-muted-foreground font-mono\">({o.code})</span>\n </td>\n <td className=\"px-3 py-2\">\n <NumberInput\n value={chargePrices[o.id] === undefined || chargePrices[o.id] === '' ? null : Number(chargePrices[o.id])}\n onChange={(n) =>\n setChargePrices({ ...chargePrices, [o.id]: n == null ? '' : String(n) })\n }\n placeholder=\"0.00\"\n className=\"w-32\"\n />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n\n <div className=\"flex gap-2 pt-1\">\n <Button\n type=\"button\"\n onClick={saveChargesForSelected}\n disabled={saving || !chargeForm.code || !chargeForm.name}\n >\n {saving\n ? 'Saving...'\n : `Create Charge for ${bulkChargeTargets.length} Offering${bulkChargeTargets.length > 1 ? 's' : ''}`}\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => setBulkChargeOpen(false)}>\n Cancel\n </Button>\n </div>\n </div>\n )\n\n const toolbarContent = (\n <>\n {error && <Alert variant=\"destructive\">{error}</Alert>}\n {bulkChargeForm}\n </>\n )\n\n return (\n <CpqListView<Offering>\n title={t('cpq.offerings.list.title', 'Product Offerings')}\n tableId=\"cpq.offerings.list\"\n data={data}\n columns={columns}\n filters={filters}\n pageSize={PAGE_SIZE}\n searchPlaceholder={t('cpq.offerings.search.placeholder', 'Search offerings...')}\n actions={\n <Button asChild>\n <a href=\"/backend/cpq/offerings/new\">{t('cpq.offerings.add', 'New Offering')}</a>\n </Button>\n }\n bulkActions={bulkActions}\n crud={{\n endpoint: '/api/cpq/product-offerings',\n entityName: t('cpq.offerings.entityName', 'offering'),\n editHref: (row) => `/backend/cpq/offerings/${row.id}`,\n }}\n onRowClick={(row) => router.push(`/backend/cpq/offerings/${row.id}`)}\n toolbarContent={toolbarContent}\n emptyState={\n <div className=\"rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground\">\n {t(\n 'cpq.offerings.empty',\n 'No product offerings found. Create one to define a sellable variant of a product specification.',\n )}\n </div>\n }\n />\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useRouter } from 'next/navigation'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport { type BulkAction } from '@open-mercato/ui/backend/DataTable'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Checkbox } from '@open-mercato/ui/primitives/checkbox'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Alert } from '@open-mercato/ui/primitives/alert'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { CpqListView, useCpqListData } from '../../../components/CpqListView'\nimport { NumberInput } from '../../../components/NumberInput'\nimport {\n chargeTypeMap,\n formatStatusLabel,\n lifecycleStatusMap,\n type ChargeType,\n type LifecycleStatus,\n} from '../../../components/statusMaps'\n\ntype Charge = {\n id: string\n code: string\n name: string\n description: string | null\n chargeType: string\n pricingMethod: string\n fixedPrice: string | null\n currencyCode: string | null\n isActive: boolean\n}\n\ntype Offering = {\n id: string\n specId: string\n code: string\n name: string\n description: string | null\n offeringType: string\n designTimeValues: Record<string, unknown>\n lifecycleStatus: string\n isActive: boolean\n createdAt: string\n charges?: Charge[]\n}\n\nconst PAGE_SIZE = 50\n\nfunction ChargePopover({ charge }: { charge: Charge }) {\n const t = useT()\n const [open, setOpen] = React.useState(false)\n const variant = chargeTypeMap[charge.chargeType as ChargeType] ?? 'neutral'\n return (\n <span\n className=\"relative inline-flex\"\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n >\n <Tag variant={variant} className=\"cursor-default px-2 text-[10px]\">\n {charge.chargeType.toUpperCase()}\n </Tag>\n {open && (\n <div className=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-2 z-50 w-56 rounded-lg border bg-popover p-3 shadow-md text-popover-foreground text-xs space-y-1.5\">\n <div className=\"font-medium text-sm\">{charge.name}</div>\n <div className=\"text-muted-foreground font-mono\">{charge.code}</div>\n {charge.description && <div className=\"text-muted-foreground\">{charge.description}</div>}\n <div className=\"flex items-center justify-between pt-1 border-t\">\n <span>{t('cpq.offerings.list.chargePopover.pricing', 'Pricing: {method}', { method: charge.pricingMethod })}</span>\n {charge.fixedPrice != null && (\n <span className=\"font-medium\">\n {charge.currencyCode ?? 'USD'} {charge.fixedPrice}\n </span>\n )}\n </div>\n {!charge.isActive && <Tag variant=\"warning\" dot>{t('cpq.common.inactive', 'Inactive')}</Tag>}\n <div className=\"absolute left-1/2 -translate-x-1/2 top-full w-2 h-2 bg-popover border-b border-r rotate-45 -mt-1\" />\n </div>\n )}\n </span>\n )\n}\n\nfunction buildFilterParams(values: FilterValues, params: URLSearchParams) {\n if (typeof values.lifecycleStatus === 'string' && values.lifecycleStatus) {\n params.set('lifecycleStatus', values.lifecycleStatus)\n }\n if (typeof values.offeringType === 'string' && values.offeringType) {\n params.set('offeringType', values.offeringType)\n }\n if (values.isActive === true) params.set('isActive', 'true')\n if (values.isActive === false) params.set('isActive', 'false')\n}\n\nexport default function OfferingsListPage() {\n const t = useT()\n const router = useRouter()\n\n const data = useCpqListData<Offering>({\n endpoint: '/api/cpq/product-offerings',\n pageSize: PAGE_SIZE,\n buildFilterParams,\n loadErrorMessage: t('cpq.offerings.list.error.load', 'Failed to load offerings'),\n })\n\n // Bulk charge creation is restricted to `flat` pricing \u2014 per_unit/tiered\n // need a pricing table + a numeric quantity attribute that lives on the\n // offering's spec, which differs between selected offerings. We push\n // users to the per-offering detail page for those methods.\n const [bulkChargeOpen, setBulkChargeOpen] = React.useState(false)\n const [bulkChargeTargets, setBulkChargeTargets] = React.useState<Offering[]>([])\n const [chargeForm, setChargeForm] = React.useState({\n code: '',\n name: '',\n description: '',\n chargeType: 'mrc',\n })\n const [chargePrices, setChargePrices] = React.useState<Record<string, string>>({})\n const [chargeCurrency, setChargeCurrency] = React.useState('USD')\n const [saving, setSaving] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n\n const lifecycleOptions = React.useMemo(\n () => [\n { value: 'draft', label: t('cpq.offerings.lifecycle.draft', 'Draft') },\n { value: 'active', label: t('cpq.offerings.lifecycle.active', 'Active') },\n { value: 'deprecated', label: t('cpq.offerings.lifecycle.deprecated', 'Deprecated') },\n ],\n [t],\n )\n\n const offeringTypeOptions = React.useMemo(\n () => [\n { value: 'simple', label: t('cpq.offerings.type.simple', 'Simple') },\n { value: 'bundle', label: t('cpq.offerings.type.bundle', 'Bundle') },\n ],\n [t],\n )\n\n const filters = React.useMemo<FilterDef[]>(\n () => [\n {\n id: 'lifecycleStatus',\n label: t('cpq.offerings.filters.lifecycleStatus', 'Lifecycle Status'),\n type: 'select',\n options: lifecycleOptions,\n },\n {\n id: 'offeringType',\n label: t('cpq.offerings.filters.offeringType', 'Type'),\n type: 'select',\n options: offeringTypeOptions,\n },\n {\n id: 'isActive',\n label: t('cpq.offerings.filters.isActive', 'Active'),\n type: 'checkbox',\n },\n ],\n [lifecycleOptions, offeringTypeOptions, t],\n )\n\n const openBulkChargeForm = React.useCallback(\n (targets: Offering[]) => {\n setBulkChargeTargets(targets)\n setChargeForm({ code: '', name: '', description: '', chargeType: 'mrc' })\n setChargePrices({})\n setChargeCurrency('USD')\n setError(null)\n setBulkChargeOpen(true)\n },\n [],\n )\n\n const saveChargesForSelected = React.useCallback(async () => {\n const targets = bulkChargeTargets\n if (!targets.length || !chargeForm.code || !chargeForm.name) return\n setSaving(true)\n setError(null)\n try {\n for (const offering of targets) {\n const chargeCode = targets.length > 1 ? `${offering.code}--${chargeForm.code}` : chargeForm.code\n const payload: Record<string, unknown> = {\n offeringId: offering.id,\n code: chargeCode,\n name: chargeForm.name,\n description: chargeForm.description || null,\n chargeType: chargeForm.chargeType,\n pricingMethod: 'flat',\n fixedPrice: chargePrices[offering.id] || null,\n currencyCode: chargeCurrency,\n isActive: true,\n sortOrder: 0,\n }\n const res = await fetch('/api/cpq/product-charges', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n })\n if (!res.ok) {\n const body = await res.json().catch(() => ({} as { error?: string }))\n setError(body.error ?? t('cpq.offerings.bulk.error.saveChargeFor', 'Failed to save charge for {name}', { name: offering.name }))\n setSaving(false)\n return\n }\n }\n flash(t('cpq.offerings.flash.chargesCreated', 'Charges created'), 'success')\n setBulkChargeOpen(false)\n setBulkChargeTargets([])\n data.reload()\n } catch {\n setError(t('cpq.offerings.bulk.error.saveCharges', 'Failed to save charges'))\n } finally {\n setSaving(false)\n }\n }, [\n bulkChargeTargets,\n chargeCurrency,\n chargeForm,\n chargePrices,\n data,\n t,\n ])\n\n const columns = React.useMemo<ColumnDef<Offering>[]>(\n () => [\n {\n accessorKey: 'code',\n header: t('cpq.offerings.code', 'Code'),\n cell: ({ row }) => <span className=\"font-mono text-xs\">{row.original.code}</span>,\n },\n {\n accessorKey: 'name',\n header: t('cpq.offerings.name', 'Name'),\n cell: ({ row }) => (\n <span className=\"font-medium\">\n {row.original.name}\n {row.original.offeringType === 'bundle' && (\n <Tag variant=\"brand\" className=\"ml-2 px-2 text-[10px]\">\n {t('cpq.offerings.list.tag.bundle', 'bundle')}\n </Tag>\n )}\n </span>\n ),\n },\n {\n accessorKey: 'isActive',\n header: t('cpq.offerings.isActive', 'Is Active?'),\n cell: ({ row }) => <Checkbox checked={row.original.isActive} disabled />,\n },\n {\n accessorKey: 'lifecycleStatus',\n header: t('cpq.offerings.lifecycleStatus', 'Lifecycle Status'),\n cell: ({ row }) => (\n <Tag variant={lifecycleStatusMap[row.original.lifecycleStatus as LifecycleStatus] ?? 'neutral'} dot>\n {formatStatusLabel(row.original.lifecycleStatus)}\n </Tag>\n ),\n },\n {\n id: 'charges',\n header: t('cpq.offerings.charges', 'Charges'),\n cell: ({ row }) => {\n const charges = row.original.charges ?? []\n if (charges.length === 0) return <span className=\"text-xs text-muted-foreground\">\u2014</span>\n return (\n <div className=\"flex flex-wrap gap-1\" onClick={(e) => e.stopPropagation()}>\n {charges.map((ch) => (\n <ChargePopover key={ch.id} charge={ch} />\n ))}\n </div>\n )\n },\n },\n {\n accessorKey: 'description',\n header: t('cpq.offerings.description', 'Description'),\n cell: ({ row }) => (\n <span className=\"text-muted-foreground\">{row.original.description ?? '\u2014'}</span>\n ),\n meta: { truncate: true, maxWidth: 320 },\n },\n ],\n [t],\n )\n\n // Module-specific bulk actions; \"Delete selected\" is appended automatically\n // by CpqListView when `crud` is provided.\n const bulkActions = React.useMemo<BulkAction<Offering>[]>(\n () => [\n {\n id: 'add-charge',\n label: t('cpq.offerings.bulk.addCharge', 'Add Charge'),\n onExecute: (selectedRows) => {\n if (!selectedRows.length) return { ok: false }\n openBulkChargeForm(selectedRows)\n return { ok: true }\n },\n },\n ],\n [openBulkChargeForm, t],\n )\n\n const bulkChargeForm = bulkChargeOpen && bulkChargeTargets.length > 0 && (\n <div className=\"rounded-lg border bg-card p-5 space-y-4\">\n <h4 className=\"font-medium text-sm\">\n {t('cpq.offerings.bulk.formTitle', 'New Flat-Price Charge for')} {bulkChargeTargets.length}{' '}\n {bulkChargeTargets.length > 1\n ? t('cpq.offerings.bulk.offeringsPlural', 'offerings')\n : t('cpq.offerings.bulk.offeringsSingular', 'offering')}\n </h4>\n\n <Alert>\n {t('cpq.offerings.bulk.notice.supports', 'Bulk creation supports')}{' '}\n <strong>{t('cpq.offerings.bulk.notice.flatOnly', 'flat pricing only')}</strong>\n {t('cpq.offerings.bulk.notice.for', '. For')}{' '}\n <em>{t('cpq.offerings.bulk.notice.perUnit', 'per unit')}</em>{' '}\n {t('cpq.offerings.bulk.notice.or', 'or')}{' '}\n <em>{t('cpq.offerings.bulk.notice.tiered', 'tiered')}</em>{' '}\n {t(\n 'cpq.offerings.bulk.notice.rest',\n \"pricing, open each offering individually \u2014 those methods need a pricing table and a numeric attribute that lives on the offering's spec, which usually differs between offerings.\",\n )}\n </Alert>\n\n <div className=\"grid grid-cols-3 gap-3\">\n <div>\n <label className=\"block text-xs font-medium mb-1\">{t('cpq.offerings.bulk.fields.code', 'Code')}</label>\n <Input\n value={chargeForm.code}\n onChange={(e) => setChargeForm({ ...chargeForm, code: e.target.value })}\n placeholder={t('cpq.offerings.bulk.fields.codePlaceholder', 'e.g. mrc-monthly')}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium mb-1\">{t('cpq.offerings.bulk.fields.name', 'Name')}</label>\n <Input\n value={chargeForm.name}\n onChange={(e) => setChargeForm({ ...chargeForm, name: e.target.value })}\n placeholder={t('cpq.offerings.bulk.fields.namePlaceholder', 'e.g. Monthly Recurring')}\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium mb-1\">{t('cpq.offerings.bulk.fields.type', 'Type')}</label>\n <Select\n value={chargeForm.chargeType}\n onValueChange={(value) => setChargeForm({ ...chargeForm, chargeType: value })}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"nrc\">{t('cpq.offerings.chargeType.nrc', 'NRC (Non-Recurring)')}</SelectItem>\n <SelectItem value=\"mrc\">{t('cpq.offerings.chargeType.mrc', 'MRC (Monthly Recurring)')}</SelectItem>\n <SelectItem value=\"usage\">{t('cpq.offerings.chargeType.usage', 'Usage')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium mb-1\">{t('cpq.offerings.bulk.fields.description', 'Description')}</label>\n <Input\n value={chargeForm.description}\n onChange={(e) => setChargeForm({ ...chargeForm, description: e.target.value })}\n placeholder={t('cpq.offerings.bulk.fields.descriptionPlaceholder', 'User-facing charge description')}\n />\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-3\">\n <label className=\"text-xs font-medium\">{t('cpq.offerings.bulk.fields.currency', 'Currency')}</label>\n <Input\n value={chargeCurrency}\n onChange={(e) => setChargeCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n className=\"w-20\"\n />\n </div>\n <div className=\"rounded border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/30\">\n <th className=\"px-3 py-2 text-left font-medium text-xs\">{t('cpq.offerings.bulk.table.offering', 'Offering')}</th>\n <th className=\"px-3 py-2 text-left font-medium text-xs\">{t('cpq.offerings.bulk.table.price', 'Price ({currency})', { currency: chargeCurrency })}</th>\n </tr>\n </thead>\n <tbody>\n {bulkChargeTargets.map((o) => (\n <tr key={o.id} className=\"border-b last:border-0\">\n <td className=\"px-3 py-2 font-medium text-xs\">\n {o.name} <span className=\"text-muted-foreground font-mono\">({o.code})</span>\n </td>\n <td className=\"px-3 py-2\">\n <NumberInput\n value={chargePrices[o.id] === undefined || chargePrices[o.id] === '' ? null : Number(chargePrices[o.id])}\n onChange={(n) =>\n setChargePrices({ ...chargePrices, [o.id]: n == null ? '' : String(n) })\n }\n placeholder=\"0.00\"\n className=\"w-32\"\n />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n\n <div className=\"flex gap-2 pt-1\">\n <Button\n type=\"button\"\n onClick={saveChargesForSelected}\n disabled={saving || !chargeForm.code || !chargeForm.name}\n >\n {saving\n ? t('cpq.common.saving', 'Saving...')\n : bulkChargeTargets.length > 1\n ? t('cpq.offerings.bulk.submitPlural', 'Create Charge for {count} Offerings', { count: bulkChargeTargets.length })\n : t('cpq.offerings.bulk.submitSingular', 'Create Charge for {count} Offering', { count: bulkChargeTargets.length })}\n </Button>\n <Button type=\"button\" variant=\"outline\" onClick={() => setBulkChargeOpen(false)}>\n {t('cpq.common.cancel', 'Cancel')}\n </Button>\n </div>\n </div>\n )\n\n const toolbarContent = (\n <>\n {error && <Alert variant=\"destructive\">{error}</Alert>}\n {bulkChargeForm}\n </>\n )\n\n return (\n <CpqListView<Offering>\n title={t('cpq.offerings.list.title', 'Product Offerings')}\n tableId=\"cpq.offerings.list\"\n data={data}\n columns={columns}\n filters={filters}\n pageSize={PAGE_SIZE}\n searchPlaceholder={t('cpq.offerings.search.placeholder', 'Search offerings...')}\n actions={\n <Button asChild>\n <a href=\"/backend/cpq/offerings/new\">{t('cpq.offerings.add', 'New Offering')}</a>\n </Button>\n }\n bulkActions={bulkActions}\n crud={{\n endpoint: '/api/cpq/product-offerings',\n entityName: t('cpq.offerings.entityName', 'offering'),\n editHref: (row) => `/backend/cpq/offerings/${row.id}`,\n }}\n onRowClick={(row) => router.push(`/backend/cpq/offerings/${row.id}`)}\n toolbarContent={toolbarContent}\n emptyState={\n <div className=\"rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground\">\n {t(\n 'cpq.offerings.empty',\n 'No product offerings found. Create one to define a sellable variant of a product specification.',\n )}\n </div>\n }\n />\n )\n}\n"],
5
+ "mappings": ";AAoEM,SAmXF,UAnXE,KAWQ,YAXR;AAnEN,YAAY,WAAW;AACvB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAG1B,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,WAAW;AACpB,SAAS,aAAa,sBAAsB;AAC5C,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AA4BP,MAAM,YAAY;AAElB,SAAS,cAAc,EAAE,OAAO,GAAuB;AACrD,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,KAAK;AAC5C,QAAM,UAAU,cAAc,OAAO,UAAwB,KAAK;AAClE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,cAAc,MAAM,QAAQ,IAAI;AAAA,MAChC,cAAc,MAAM,QAAQ,KAAK;AAAA,MAEjC;AAAA,4BAAC,OAAI,SAAkB,WAAU,mCAC9B,iBAAO,WAAW,YAAY,GACjC;AAAA,QACC,QACC,qBAAC,SAAI,WAAU,wJACb;AAAA,8BAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAK;AAAA,UAClD,oBAAC,SAAI,WAAU,mCAAmC,iBAAO,MAAK;AAAA,UAC7D,OAAO,eAAe,oBAAC,SAAI,WAAU,yBAAyB,iBAAO,aAAY;AAAA,UAClF,qBAAC,SAAI,WAAU,mDACb;AAAA,gCAAC,UAAM,YAAE,4CAA4C,qBAAqB,EAAE,QAAQ,OAAO,cAAc,CAAC,GAAE;AAAA,YAC3G,OAAO,cAAc,QACpB,qBAAC,UAAK,WAAU,eACb;AAAA,qBAAO,gBAAgB;AAAA,cAAM;AAAA,cAAE,OAAO;AAAA,eACzC;AAAA,aAEJ;AAAA,UACC,CAAC,OAAO,YAAY,oBAAC,OAAI,SAAQ,WAAU,KAAG,MAAE,YAAE,uBAAuB,UAAU,GAAE;AAAA,UACtF,oBAAC,SAAI,WAAU,oGAAmG;AAAA,WACpH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,SAAS,kBAAkB,QAAsB,QAAyB;AACxE,MAAI,OAAO,OAAO,oBAAoB,YAAY,OAAO,iBAAiB;AACxE,WAAO,IAAI,mBAAmB,OAAO,eAAe;AAAA,EACtD;AACA,MAAI,OAAO,OAAO,iBAAiB,YAAY,OAAO,cAAc;AAClE,WAAO,IAAI,gBAAgB,OAAO,YAAY;AAAA,EAChD;AACA,MAAI,OAAO,aAAa,KAAM,QAAO,IAAI,YAAY,MAAM;AAC3D,MAAI,OAAO,aAAa,MAAO,QAAO,IAAI,YAAY,OAAO;AAC/D;AAEe,SAAR,oBAAqC;AAC1C,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AAEzB,QAAM,OAAO,eAAyB;AAAA,IACpC,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA,kBAAkB,EAAE,iCAAiC,0BAA0B;AAAA,EACjF,CAAC;AAMD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAS,KAAK;AAChE,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAqB,CAAC,CAAC;AAC/E,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS;AAAA,IACjD,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,EACd,CAAC;AACD,QAAM,CAAC,cAAc,eAAe,IAAI,MAAM,SAAiC,CAAC,CAAC;AACjF,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAS,KAAK;AAChE,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAE5D,QAAM,mBAAmB,MAAM;AAAA,IAC7B,MAAM;AAAA,MACJ,EAAE,OAAO,SAAS,OAAO,EAAE,iCAAiC,OAAO,EAAE;AAAA,MACrE,EAAE,OAAO,UAAU,OAAO,EAAE,kCAAkC,QAAQ,EAAE;AAAA,MACxE,EAAE,OAAO,cAAc,OAAO,EAAE,sCAAsC,YAAY,EAAE;AAAA,IACtF;AAAA,IACA,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,sBAAsB,MAAM;AAAA,IAChC,MAAM;AAAA,MACJ,EAAE,OAAO,UAAU,OAAO,EAAE,6BAA6B,QAAQ,EAAE;AAAA,MACnE,EAAE,OAAO,UAAU,OAAO,EAAE,6BAA6B,QAAQ,EAAE;AAAA,IACrE;AAAA,IACA,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,EAAE,yCAAyC,kBAAkB;AAAA,QACpE,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,EAAE,sCAAsC,MAAM;AAAA,QACrD,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,EAAE,kCAAkC,QAAQ;AAAA,QACnD,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,qBAAqB,CAAC;AAAA,EAC3C;AAEA,QAAM,qBAAqB,MAAM;AAAA,IAC/B,CAAC,YAAwB;AACvB,2BAAqB,OAAO;AAC5B,oBAAc,EAAE,MAAM,IAAI,MAAM,IAAI,aAAa,IAAI,YAAY,MAAM,CAAC;AACxE,sBAAgB,CAAC,CAAC;AAClB,wBAAkB,KAAK;AACvB,eAAS,IAAI;AACb,wBAAkB,IAAI;AAAA,IACxB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,yBAAyB,MAAM,YAAY,YAAY;AAC3D,UAAM,UAAU;AAChB,QAAI,CAAC,QAAQ,UAAU,CAAC,WAAW,QAAQ,CAAC,WAAW,KAAM;AAC7D,cAAU,IAAI;AACd,aAAS,IAAI;AACb,QAAI;AACF,iBAAW,YAAY,SAAS;AAC9B,cAAM,aAAa,QAAQ,SAAS,IAAI,GAAG,SAAS,IAAI,KAAK,WAAW,IAAI,KAAK,WAAW;AAC5F,cAAM,UAAmC;AAAA,UACvC,YAAY,SAAS;AAAA,UACrB,MAAM;AAAA,UACN,MAAM,WAAW;AAAA,UACjB,aAAa,WAAW,eAAe;AAAA,UACvC,YAAY,WAAW;AAAA,UACvB,eAAe;AAAA,UACf,YAAY,aAAa,SAAS,EAAE,KAAK;AAAA,UACzC,cAAc;AAAA,UACd,UAAU;AAAA,UACV,WAAW;AAAA,QACb;AACA,cAAM,MAAM,MAAM,MAAM,4BAA4B;AAAA,UAClD,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,QAC9B,CAAC;AACD,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAwB;AACpE,mBAAS,KAAK,SAAS,EAAE,0CAA0C,oCAAoC,EAAE,MAAM,SAAS,KAAK,CAAC,CAAC;AAC/H,oBAAU,KAAK;AACf;AAAA,QACF;AAAA,MACF;AACA,YAAM,EAAE,sCAAsC,iBAAiB,GAAG,SAAS;AAC3E,wBAAkB,KAAK;AACvB,2BAAqB,CAAC,CAAC;AACvB,WAAK,OAAO;AAAA,IACd,QAAQ;AACN,eAAS,EAAE,wCAAwC,wBAAwB,CAAC;AAAA,IAC9E,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,sBAAsB,MAAM;AAAA,QACtC,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,UAAK,WAAU,qBAAqB,cAAI,SAAS,MAAK;AAAA,MAC5E;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,sBAAsB,MAAM;AAAA,QACtC,MAAM,CAAC,EAAE,IAAI,MACX,qBAAC,UAAK,WAAU,eACb;AAAA,cAAI,SAAS;AAAA,UACb,IAAI,SAAS,iBAAiB,YAC7B,oBAAC,OAAI,SAAQ,SAAQ,WAAU,yBAC5B,YAAE,iCAAiC,QAAQ,GAC9C;AAAA,WAEJ;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,0BAA0B,YAAY;AAAA,QAChD,MAAM,CAAC,EAAE,IAAI,MAAM,oBAAC,YAAS,SAAS,IAAI,SAAS,UAAU,UAAQ,MAAC;AAAA,MACxE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,iCAAiC,kBAAkB;AAAA,QAC7D,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,OAAI,SAAS,mBAAmB,IAAI,SAAS,eAAkC,KAAK,WAAW,KAAG,MAChG,4BAAkB,IAAI,SAAS,eAAe,GACjD;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ,EAAE,yBAAyB,SAAS;AAAA,QAC5C,MAAM,CAAC,EAAE,IAAI,MAAM;AACjB,gBAAM,UAAU,IAAI,SAAS,WAAW,CAAC;AACzC,cAAI,QAAQ,WAAW,EAAG,QAAO,oBAAC,UAAK,WAAU,iCAAgC,oBAAC;AAClF,iBACE,oBAAC,SAAI,WAAU,wBAAuB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GACrE,kBAAQ,IAAI,CAAC,OACZ,oBAAC,iBAA0B,QAAQ,MAAf,GAAG,EAAgB,CACxC,GACH;AAAA,QAEJ;AAAA,MACF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,6BAA6B,aAAa;AAAA,QACpD,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,UAAK,WAAU,yBAAyB,cAAI,SAAS,eAAe,UAAI;AAAA,QAE3E,MAAM,EAAE,UAAU,MAAM,UAAU,IAAI;AAAA,MACxC;AAAA,IACF;AAAA,IACA,CAAC,CAAC;AAAA,EACJ;AAIA,QAAM,cAAc,MAAM;AAAA,IACxB,MAAM;AAAA,MACJ;AAAA,QACE,IAAI;AAAA,QACJ,OAAO,EAAE,gCAAgC,YAAY;AAAA,QACrD,WAAW,CAAC,iBAAiB;AAC3B,cAAI,CAAC,aAAa,OAAQ,QAAO,EAAE,IAAI,MAAM;AAC7C,6BAAmB,YAAY;AAC/B,iBAAO,EAAE,IAAI,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,CAAC;AAAA,EACxB;AAEA,QAAM,iBAAiB,kBAAkB,kBAAkB,SAAS,KAClE,qBAAC,SAAI,WAAU,2CACb;AAAA,yBAAC,QAAG,WAAU,uBACX;AAAA,QAAE,gCAAgC,2BAA2B;AAAA,MAAE;AAAA,MAAE,kBAAkB;AAAA,MAAQ;AAAA,MAC3F,kBAAkB,SAAS,IACxB,EAAE,sCAAsC,WAAW,IACnD,EAAE,wCAAwC,UAAU;AAAA,OAC1D;AAAA,IAEA,qBAAC,SACE;AAAA,QAAE,sCAAsC,wBAAwB;AAAA,MAAG;AAAA,MACpE,oBAAC,YAAQ,YAAE,sCAAsC,mBAAmB,GAAE;AAAA,MACrE,EAAE,iCAAiC,OAAO;AAAA,MAAG;AAAA,MAC9C,oBAAC,QAAI,YAAE,qCAAqC,UAAU,GAAE;AAAA,MAAM;AAAA,MAC7D,EAAE,gCAAgC,IAAI;AAAA,MAAG;AAAA,MAC1C,oBAAC,QAAI,YAAE,oCAAoC,QAAQ,GAAE;AAAA,MAAM;AAAA,MAC1D;AAAA,QACC;AAAA,QACA;AAAA,MACF;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,0BACb;AAAA,2BAAC,SACC;AAAA,4BAAC,WAAM,WAAU,kCAAkC,YAAE,kCAAkC,MAAM,GAAE;AAAA,QAC/F;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW;AAAA,YAClB,UAAU,CAAC,MAAM,cAAc,EAAE,GAAG,YAAY,MAAM,EAAE,OAAO,MAAM,CAAC;AAAA,YACtE,aAAa,EAAE,6CAA6C,kBAAkB;AAAA;AAAA,QAChF;AAAA,SACF;AAAA,MACA,qBAAC,SACC;AAAA,4BAAC,WAAM,WAAU,kCAAkC,YAAE,kCAAkC,MAAM,GAAE;AAAA,QAC/F;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW;AAAA,YAClB,UAAU,CAAC,MAAM,cAAc,EAAE,GAAG,YAAY,MAAM,EAAE,OAAO,MAAM,CAAC;AAAA,YACtE,aAAa,EAAE,6CAA6C,wBAAwB;AAAA;AAAA,QACtF;AAAA,SACF;AAAA,MACA,qBAAC,SACC;AAAA,4BAAC,WAAM,WAAU,kCAAkC,YAAE,kCAAkC,MAAM,GAAE;AAAA,QAC/F;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW;AAAA,YAClB,eAAe,CAAC,UAAU,cAAc,EAAE,GAAG,YAAY,YAAY,MAAM,CAAC;AAAA,YAE5E;AAAA,kCAAC,iBACC,8BAAC,eAAY,GACf;AAAA,cACA,qBAAC,iBACC;AAAA,oCAAC,cAAW,OAAM,OAAO,YAAE,gCAAgC,qBAAqB,GAAE;AAAA,gBAClF,oBAAC,cAAW,OAAM,OAAO,YAAE,gCAAgC,yBAAyB,GAAE;AAAA,gBACtF,oBAAC,cAAW,OAAM,SAAS,YAAE,kCAAkC,OAAO,GAAE;AAAA,iBAC1E;AAAA;AAAA;AAAA,QACF;AAAA,SACF;AAAA,OACF;AAAA,IAEA,qBAAC,SACC;AAAA,0BAAC,WAAM,WAAU,kCAAkC,YAAE,yCAAyC,aAAa,GAAE;AAAA,MAC7G;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,WAAW;AAAA,UAClB,UAAU,CAAC,MAAM,cAAc,EAAE,GAAG,YAAY,aAAa,EAAE,OAAO,MAAM,CAAC;AAAA,UAC7E,aAAa,EAAE,oDAAoD,gCAAgC;AAAA;AAAA,MACrG;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,WAAM,WAAU,uBAAuB,YAAE,sCAAsC,UAAU,GAAE;AAAA,QAC5F;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,kBAAkB,EAAE,OAAO,MAAM,YAAY,CAAC;AAAA,YAC/D,WAAW;AAAA,YACX,WAAU;AAAA;AAAA,QACZ;AAAA,SACF;AAAA,MACA,oBAAC,SAAI,WAAU,kBACb,+BAAC,WAAM,WAAU,kBACf;AAAA,4BAAC,WACC,+BAAC,QAAG,WAAU,wBACZ;AAAA,8BAAC,QAAG,WAAU,2CAA2C,YAAE,qCAAqC,UAAU,GAAE;AAAA,UAC5G,oBAAC,QAAG,WAAU,2CAA2C,YAAE,kCAAkC,sBAAsB,EAAE,UAAU,eAAe,CAAC,GAAE;AAAA,WACnJ,GACF;AAAA,QACA,oBAAC,WACE,4BAAkB,IAAI,CAAC,MACtB,qBAAC,QAAc,WAAU,0BACvB;AAAA,+BAAC,QAAG,WAAU,iCACX;AAAA,cAAE;AAAA,YAAK;AAAA,YAAC,qBAAC,UAAK,WAAU,mCAAkC;AAAA;AAAA,cAAE,EAAE;AAAA,cAAK;AAAA,eAAC;AAAA,aACvE;AAAA,UACA,oBAAC,QAAG,WAAU,aACZ;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,aAAa,EAAE,EAAE,MAAM,UAAa,aAAa,EAAE,EAAE,MAAM,KAAK,OAAO,OAAO,aAAa,EAAE,EAAE,CAAC;AAAA,cACvG,UAAU,CAAC,MACT,gBAAgB,EAAE,GAAG,cAAc,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,KAAK,OAAO,CAAC,EAAE,CAAC;AAAA,cAEzE,aAAY;AAAA,cACZ,WAAU;AAAA;AAAA,UACZ,GACF;AAAA,aAbO,EAAE,EAcX,CACD,GACH;AAAA,SACF,GACF;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,mBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU,UAAU,CAAC,WAAW,QAAQ,CAAC,WAAW;AAAA,UAEnD,mBACG,EAAE,qBAAqB,WAAW,IAClC,kBAAkB,SAAS,IACzB,EAAE,mCAAmC,uCAAuC,EAAE,OAAO,kBAAkB,OAAO,CAAC,IAC/G,EAAE,qCAAqC,sCAAsC,EAAE,OAAO,kBAAkB,OAAO,CAAC;AAAA;AAAA,MACxH;AAAA,MACA,oBAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,SAAS,MAAM,kBAAkB,KAAK,GAC3E,YAAE,qBAAqB,QAAQ,GAClC;AAAA,OACF;AAAA,KACF;AAGF,QAAM,iBACJ,iCACG;AAAA,aAAS,oBAAC,SAAM,SAAQ,eAAe,iBAAM;AAAA,IAC7C;AAAA,KACH;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,4BAA4B,mBAAmB;AAAA,MACxD,SAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,mBAAmB,EAAE,oCAAoC,qBAAqB;AAAA,MAC9E,SACE,oBAAC,UAAO,SAAO,MACb,8BAAC,OAAE,MAAK,8BAA8B,YAAE,qBAAqB,cAAc,GAAE,GAC/E;AAAA,MAEF;AAAA,MACA,MAAM;AAAA,QACJ,UAAU;AAAA,QACV,YAAY,EAAE,4BAA4B,UAAU;AAAA,QACpD,UAAU,CAAC,QAAQ,0BAA0B,IAAI,EAAE;AAAA,MACrD;AAAA,MACA,YAAY,CAAC,QAAQ,OAAO,KAAK,0BAA0B,IAAI,EAAE,EAAE;AAAA,MACnE;AAAA,MACA,YACE,oBAAC,SAAI,WAAU,2EACZ;AAAA,QACC;AAAA,QACA;AAAA,MACF,GACF;AAAA;AAAA,EAEJ;AAEJ;",
6
6
  "names": []
7
7
  }