@open-mercato/core 0.4.9-develop-b2b88cde69 → 0.4.9-develop-d1d38e26fb

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/catalog/backend/catalog/products/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport dynamic from \"next/dynamic\";\nimport { useRouter } from \"next/navigation\";\nimport { Page, PageBody } from \"@open-mercato/ui/backend/Page\";\nimport {\n CrudForm,\n type CrudFormGroup,\n type CrudFormGroupComponentProps,\n} from \"@open-mercato/ui/backend/CrudForm\";\nimport {\n updateCrud,\n createCrud,\n deleteCrud,\n} from \"@open-mercato/ui/backend/utils/crud\";\nimport { createCrudFormError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport { collectCustomFieldValues } from \"@open-mercato/ui/backend/utils/customFieldValues\";\nimport { flash } from \"@open-mercato/ui/backend/FlashMessages\";\nimport { Button } from \"@open-mercato/ui/primitives/button\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport { TagsInput } from \"@open-mercato/ui/backend/inputs/TagsInput\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport { DataLoader } from \"@open-mercato/ui/primitives/DataLoader\";\nimport { cn } from \"@open-mercato/shared/lib/utils\";\nimport { Spinner } from \"@open-mercato/ui/primitives/spinner\";\nimport {\n apiCall,\n readApiResultOrThrow,\n} from \"@open-mercato/ui/backend/utils/apiCall\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { useConfirmDialog } from \"@open-mercato/ui/backend/confirm-dialog\";\nimport { E } from \"#generated/entities.ids.generated\";\nimport {\n ProductMediaManager,\n type ProductMediaItem,\n} from \"@open-mercato/core/modules/catalog/components/products/ProductMediaManager\";\nimport {\n fetchOptionSchemaTemplate,\n type OptionSchemaRecord,\n type OptionSchemaTemplateSummary,\n} from \"../optionSchemaClient\";\nimport {\n type ProductFormValues,\n type TaxRateSummary,\n type ProductOptionInput,\n type PriceKindSummary,\n type PriceKindApiPayload,\n type ProductUnitConversionDraft,\n type ProductUnitPriceReferenceUnit,\n type ProductUnitRoundingMode,\n productFormSchema,\n BASE_INITIAL_VALUES,\n createLocalId,\n slugify,\n formatTaxRateLabel,\n buildOptionSchemaDefinition,\n convertSchemaToProductOptions,\n normalizePriceKindSummary,\n buildOptionValuesKey,\n buildVariantCombinations,\n normalizeProductDimensions,\n normalizeProductWeight,\n sanitizeProductDimensions,\n sanitizeProductWeight,\n updateDimensionValue,\n updateWeightValue,\n} from \"@open-mercato/core/modules/catalog/components/products/productForm\";\nimport type { CatalogProductOptionSchema } from \"@open-mercato/core/modules/catalog/data/types\";\nimport { MetadataEditor } from \"@open-mercato/core/modules/catalog/components/products/MetadataEditor\";\nimport {\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from \"@open-mercato/core/modules/attachments/lib/imageUrls\";\nimport {\n ProductCategorizeSection,\n type ProductCategorizePickerOption,\n} from \"@open-mercato/core/modules/catalog/components/products/ProductCategorizeSection\";\nimport { ProductUomSection } from \"@open-mercato/core/modules/catalog/components/products/ProductUomSection\";\nimport { canonicalizeUnitCode } from \"@open-mercato/core/modules/catalog/lib/unitCodes\";\nimport {\n UNIT_PRICE_REFERENCE_UNITS,\n toTrimmedOrNull,\n parseNumericInput,\n toPositiveNumberOrNull,\n toIntegerInRangeOrDefault,\n normalizeProductConversionInputs,\n type ProductUnitConversionInput,\n} from \"@open-mercato/core/modules/catalog/components/products/productFormUtils\";\nimport {\n AlignLeft,\n BookMarked,\n ExternalLink,\n FileText,\n Layers,\n Plus,\n Save,\n Trash2,\n} from \"lucide-react\";\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"@open-mercato/ui/primitives/dialog\";\nimport { SendObjectMessageDialog } from \"@open-mercato/ui/backend/messages/SendObjectMessageDialog.tsx\";\n\nconst MarkdownEditor = dynamic(() => import(\"@uiw/react-md-editor\"), {\n ssr: false,\n loading: () => (\n <div className=\"flex h-48 items-center justify-center text-sm text-muted-foreground\">\n <Spinner />\n </div>\n ),\n}) as unknown as React.ComponentType<{\n value?: string;\n height?: number;\n onChange?: (value?: string) => void;\n previewOptions?: { remarkPlugins?: unknown[] };\n}>;\n\ntype ProductResponse = {\n items?: Array<Record<string, unknown>>;\n};\n\ntype VariantListResponse = {\n items?: VariantSummaryApi[];\n};\n\ntype VariantSummaryApi = {\n id?: string;\n name?: string | null;\n sku?: string | null;\n is_default?: boolean;\n isDefault?: boolean;\n metadata?: Record<string, unknown> | null;\n};\n\ntype AttachmentListResponse = {\n items?: {\n id: string;\n url: string;\n fileName: string;\n fileSize: number;\n thumbnailUrl?: string | null;\n }[];\n};\n\ntype OptionSchemaTemplateListResponse = {\n items?: OptionSchemaTemplateSummary[];\n};\n\ntype VariantSummary = {\n id: string;\n name: string;\n sku: string;\n isDefault: boolean;\n prices: VariantPriceSummary[];\n optionValues: Record<string, string> | null;\n};\n\ntype VariantPriceListResponse = {\n items?: VariantPriceSummaryApi[];\n};\n\ntype VariantPriceSummaryApi = {\n id?: string;\n variant_id?: string | null;\n variantId?: string | null;\n price_kind_id?: string | null;\n priceKindId?: string | null;\n currency_code?: string | null;\n currencyCode?: string | null;\n unit_price_net?: string | null;\n unitPriceNet?: string | null;\n unit_price_gross?: string | null;\n unitPriceGross?: string | null;\n};\n\ntype VariantPriceSummary = {\n id: string;\n variantId: string;\n priceKindId: string | null;\n currencyCode: string | null;\n amount: string | null;\n displayMode: \"including-tax\" | \"excluding-tax\";\n};\n\ntype OfferSnapshot = {\n id: string | null;\n channelId: string;\n title: string | null;\n description: string | null;\n defaultMediaId: string | null;\n defaultMediaUrl: string | null;\n metadata: Record<string, unknown> | null;\n isActive: boolean;\n channelName: string | null;\n channelCode: string | null;\n};\n\nfunction mapVariantPriceSummary(\n item: VariantPriceSummaryApi | undefined,\n): VariantPriceSummary | null {\n if (!item) return null;\n const getString = (value: unknown): string | null => {\n if (typeof value === \"string\" && value.trim().length) return value.trim();\n if (typeof value === \"number\" || typeof value === \"bigint\")\n return String(value);\n return null;\n };\n const variantId = getString(item.variant_id ?? item.variantId);\n const id = getString(item.id);\n if (!variantId || !id) return null;\n const priceKindId = getString(item.price_kind_id ?? item.priceKindId);\n const currencyCode = getString(item.currency_code ?? item.currencyCode);\n const unitGross = getString(item.unit_price_gross ?? item.unitPriceGross);\n const unitNet = getString(item.unit_price_net ?? item.unitPriceNet);\n const amount = unitGross ?? unitNet ?? null;\n return {\n id,\n variantId,\n priceKindId,\n currencyCode,\n amount,\n displayMode: unitGross ? \"including-tax\" : \"excluding-tax\",\n };\n}\n\nfunction normalizeVariantOptionValues(\n input: unknown,\n): Record<string, string> | null {\n if (!input || typeof input !== \"object\") return null;\n const result: Record<string, string> = {};\n Object.entries(input as Record<string, unknown>).forEach(([key, value]) => {\n if (\n typeof key === \"string\" &&\n typeof value === \"string\" &&\n key.trim().length\n ) {\n result[key] = value;\n }\n });\n return Object.keys(result).length ? result : null;\n}\n\nfunction readProductConversionRows(\n items: Array<Record<string, unknown>> | undefined,\n): ProductUnitConversionDraft[] {\n const rows = Array.isArray(items) ? items : [];\n return rows\n .map((item) => {\n const id = toTrimmedOrNull(item.id);\n const unitCode = canonicalizeUnitCode(item.unit_code ?? item.unitCode);\n const factor = toPositiveNumberOrNull(\n item.to_base_factor ?? item.toBaseFactor,\n );\n if (!unitCode || factor === null) return null;\n const sortOrderRaw = toIntegerInRangeOrDefault(\n item.sort_order ?? item.sortOrder,\n 0,\n 100000,\n 0,\n );\n const isActive =\n typeof item.is_active === \"boolean\"\n ? item.is_active\n : typeof item.isActive === \"boolean\"\n ? item.isActive\n : true;\n return {\n id: id ?? null,\n unitCode,\n toBaseFactor: String(factor),\n sortOrder: String(sortOrderRaw),\n isActive,\n } satisfies ProductUnitConversionDraft;\n })\n .filter((entry): entry is ProductUnitConversionDraft => Boolean(entry));\n}\n\nexport default function EditCatalogProductPage({\n params,\n}: {\n params?: { id?: string };\n}) {\n const productId = params?.id ? String(params.id) : null;\n const t = useT();\n const router = useRouter();\n const [taxRates, setTaxRates] = React.useState<TaxRateSummary[]>([]);\n const [variants, setVariants] = React.useState<VariantSummary[]>([]);\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([]);\n const [initialValues, setInitialValues] =\n React.useState<Partial<ProductFormValues> | null>(null);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n const offerSnapshotsRef = React.useRef<OfferSnapshot[]>([]);\n const initialConversionsRef = React.useRef<ProductUnitConversionDraft[]>([]);\n const [categorizeOptions, setCategorizeOptions] = React.useState<{\n categories: ProductCategorizePickerOption[];\n channels: ProductCategorizePickerOption[];\n tags: ProductCategorizePickerOption[];\n }>({ categories: [], channels: [], tags: [] });\n\n const loadVariants = React.useCallback(async (id: string) => {\n try {\n const [variantsRes, pricesRes] = await Promise.all([\n apiCall<VariantListResponse>(\n `/api/catalog/variants?productId=${encodeURIComponent(id)}&page=1&pageSize=100`,\n ),\n apiCall<VariantPriceListResponse>(\n `/api/catalog/prices?productId=${encodeURIComponent(id)}&page=1&pageSize=100`,\n ),\n ]);\n if (!variantsRes.ok) {\n setVariants([]);\n return;\n }\n const priceMap: Record<string, VariantPriceSummary[]> = {};\n if (pricesRes.ok) {\n const priceItems = Array.isArray(pricesRes.result?.items)\n ? pricesRes.result?.items\n : [];\n for (const item of priceItems) {\n const summary = mapVariantPriceSummary(item);\n if (!summary) continue;\n if (!priceMap[summary.variantId]) {\n priceMap[summary.variantId] = [];\n }\n priceMap[summary.variantId].push(summary);\n }\n Object.keys(priceMap).forEach((key) => {\n priceMap[key].sort((left, right) => {\n const leftKey =\n (left.priceKindId ?? \"\") + (left.currencyCode ?? \"\");\n const rightKey =\n (right.priceKindId ?? \"\") + (right.currencyCode ?? \"\");\n return leftKey.localeCompare(rightKey);\n });\n });\n }\n const items = Array.isArray(variantsRes.result?.items)\n ? variantsRes.result?.items\n : [];\n setVariants(\n items\n .map((variant) => {\n const variantId =\n typeof variant.id === \"string\" ? variant.id : null;\n if (!variantId) return null;\n const variantRecord = variant as Record<string, unknown>;\n const optionValues =\n normalizeVariantOptionValues(variantRecord?.[\"option_values\"]) ??\n normalizeVariantOptionValues(variantRecord?.optionValues);\n return {\n id: variantId,\n name:\n typeof variant.name === \"string\" && variant.name.trim().length\n ? variant.name\n : (variant.sku ?? variantId),\n sku: typeof variant.sku === \"string\" ? variant.sku : \"\",\n isDefault: Boolean(variant.is_default ?? variant.isDefault),\n prices: priceMap[variantId] ?? [],\n optionValues,\n };\n })\n .filter((entry): entry is VariantSummary => Boolean(entry)),\n );\n } catch (err) {\n console.error(\"catalog.variants.fetch failed\", err);\n setVariants([]);\n }\n }, []);\n\n const refreshVariants = React.useCallback(async () => {\n if (!productId) return;\n await loadVariants(productId);\n }, [loadVariants, productId]);\n\n const fetchAttachments = React.useCallback(\n async (id: string): Promise<ProductMediaItem[]> => {\n try {\n const res = await apiCall<AttachmentListResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(id)}`,\n );\n if (!res.ok) return [];\n return (res.result?.items ?? []).map((item) => ({\n id: item.id,\n url: item.url,\n fileName: item.fileName,\n fileSize: item.fileSize,\n thumbnailUrl: item.thumbnailUrl ?? undefined,\n }));\n } catch (err) {\n console.error(\"attachments.fetch failed\", err);\n return [];\n }\n },\n [],\n );\n\n React.useEffect(() => {\n const loadTaxRates = async () => {\n try {\n const payload = await readApiResultOrThrow<{\n items?: Array<Record<string, unknown>>;\n }>(\"/api/sales/tax-rates?pageSize=100\", undefined, {\n errorMessage: t(\n \"catalog.products.create.taxRates.error\",\n \"Failed to load tax rates.\",\n ),\n fallback: { items: [] },\n });\n const items = Array.isArray(payload.items) ? payload.items : [];\n setTaxRates(\n items.map((item) => {\n const rawRate =\n typeof item.rate === \"number\"\n ? item.rate\n : Number(item.rate ?? Number.NaN);\n return {\n id: String(item.id),\n name:\n typeof item.name === \"string\" && item.name.trim().length\n ? item.name\n : t(\n \"catalog.products.create.taxRates.unnamed\",\n \"Untitled tax rate\",\n ),\n code:\n typeof item.code === \"string\" && item.code.trim().length\n ? item.code\n : null,\n rate: Number.isFinite(rawRate) ? rawRate : null,\n isDefault: Boolean(\n typeof item.isDefault === \"boolean\"\n ? item.isDefault\n : typeof item.is_default === \"boolean\"\n ? item.is_default\n : false,\n ),\n };\n }),\n );\n } catch (err) {\n console.error(\"sales.tax-rates.fetch failed\", err);\n setTaxRates([]);\n }\n };\n loadTaxRates().catch(() => {});\n }, [t]);\n\n React.useEffect(() => {\n if (!productId) {\n setLoading(false);\n setError(\n t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n ),\n );\n return;\n }\n let cancelled = false;\n async function loadProduct() {\n setLoading(true);\n setError(null);\n try {\n const productRes = await apiCall<ProductResponse>(\n `/api/catalog/products?id=${encodeURIComponent(productId!)}&page=1&pageSize=1&withDeleted=false`,\n );\n if (!productRes.ok) throw new Error(\"load_failed\");\n const record = Array.isArray(productRes.result?.items)\n ? productRes.result?.items?.[0]\n : undefined;\n if (!record)\n throw new Error(\n t(\"catalog.products.edit.errors.notFound\", \"Product not found.\"),\n );\n const rawMetadata = isRecord(record.metadata)\n ? (record.metadata as Record<string, unknown>)\n : null;\n const dimensions = normalizeProductDimensions(\n record.dimensions ?? rawMetadata?.dimensions ?? null,\n );\n const rawWeightMeta = isRecord(rawMetadata?.weight)\n ? (rawMetadata.weight as Record<string, unknown>)\n : null;\n const weight = normalizeProductWeight({\n value:\n record.weight_value ??\n record.weightValue ??\n rawWeightMeta?.value,\n unit:\n record.weight_unit ??\n record.weightUnit ??\n rawWeightMeta?.unit,\n });\n const metadata = normalizeMetadata(rawMetadata);\n const optionSchemaId =\n typeof record.option_schema_id === \"string\"\n ? record.option_schema_id\n : typeof record.optionSchemaId === \"string\"\n ? record.optionSchemaId\n : null;\n const taxRateId =\n typeof record.tax_rate_id === \"string\"\n ? record.tax_rate_id\n : typeof record.taxRateId === \"string\"\n ? record.taxRateId\n : null;\n const optionSchemaTemplate = optionSchemaId\n ? await fetchOptionSchemaTemplate(optionSchemaId)\n : null;\n const normalizedSchema = normalizeOptionSchemaRecord(\n optionSchemaTemplate?.schema,\n );\n let optionInputs = normalizedSchema\n ? convertSchemaToProductOptions(normalizedSchema)\n : [];\n if (!optionInputs.length) {\n optionInputs = readOptionSchema(metadata);\n }\n const [attachments, conversionsRes] = await Promise.all([\n fetchAttachments(productId!),\n apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/product-unit-conversions?productId=${encodeURIComponent(productId!)}&page=1&pageSize=100`,\n undefined,\n { fallback: { items: [] } },\n ),\n ]);\n const conversionRows = conversionsRes.ok\n ? readProductConversionRows(conversionsRes.result?.items)\n : [];\n initialConversionsRef.current = conversionRows;\n const { customValues } = extractCustomFields(record);\n const offers = readOfferSnapshots(record);\n offerSnapshotsRef.current = offers;\n const channelIds = extractChannelIds(offers);\n const channelOptionEntries = buildChannelOptions(offers);\n const { ids: categoryIds, options: categoryOptions } =\n readCategorySelections(record);\n const { values: tagValues, options: tagOptions } =\n readTagSelections(record);\n const defaultMediaId =\n typeof record.default_media_id === \"string\"\n ? record.default_media_id\n : typeof record.defaultMediaId === \"string\"\n ? record.defaultMediaId\n : null;\n const defaultMediaUrl =\n typeof record.default_media_url === \"string\"\n ? record.default_media_url\n : typeof record.defaultMediaUrl === \"string\"\n ? record.defaultMediaUrl\n : \"\";\n const {\n defaultUnit,\n defaultSalesUnit,\n defaultSalesUnitQuantity,\n roundingScale,\n roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit,\n unitPriceBaseQuantity,\n } = extractUomFields(record);\n const initial: ProductFormValues = {\n title: typeof record.title === \"string\" ? record.title : \"\",\n subtitle: typeof record.subtitle === \"string\" ? record.subtitle : \"\",\n handle: typeof record.handle === \"string\" ? record.handle : \"\",\n description:\n typeof record.description === \"string\" ? record.description : \"\",\n useMarkdown: Boolean(metadata.__useMarkdown),\n taxRateId,\n mediaDraftId: productId!,\n mediaItems: attachments,\n defaultMediaId,\n defaultMediaUrl,\n hasVariants: Boolean(record.is_configurable ?? record.isConfigurable),\n options: optionInputs,\n optionSchemaId,\n variants: [],\n metadata,\n dimensions: sanitizeProductDimensions(dimensions),\n weight: sanitizeProductWeight(weight),\n defaultUnit: defaultUnit ?? null,\n defaultSalesUnit: defaultSalesUnit ?? defaultUnit ?? null,\n defaultSalesUnitQuantity: String(defaultSalesUnitQuantity ?? 1),\n uomRoundingScale: String(roundingScale),\n uomRoundingMode: roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit:\n unitPriceReferenceUnit &&\n UNIT_PRICE_REFERENCE_UNITS.has(\n unitPriceReferenceUnit as ProductUnitPriceReferenceUnit,\n )\n ? (unitPriceReferenceUnit as ProductUnitPriceReferenceUnit)\n : null,\n unitPriceBaseQuantity:\n unitPriceBaseQuantity === null ? \"\" : String(unitPriceBaseQuantity),\n unitConversions: conversionRows,\n customFieldsetCode:\n typeof record.custom_fieldset_code === \"string\"\n ? record.custom_fieldset_code\n : typeof record.customFieldsetCode === \"string\"\n ? record.customFieldsetCode\n : null,\n categoryIds,\n channelIds,\n tags: tagValues,\n };\n if (!cancelled) {\n setInitialValues({ ...initial, ...customValues });\n setCategorizeOptions({\n categories: categoryOptions,\n channels: channelOptionEntries,\n tags: tagOptions,\n });\n }\n await loadVariants(productId!);\n } catch (err) {\n console.error(\"catalog.products.edit.load failed\", err);\n if (!cancelled) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t(\n \"catalog.products.edit.errors.load\",\n \"Failed to load product details.\",\n );\n setError(message);\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n loadProduct();\n return () => {\n cancelled = true;\n };\n }, [fetchAttachments, loadVariants, productId, t]);\n\n React.useEffect(() => {\n let cancelled = false;\n async function loadPriceKinds() {\n try {\n const payload = await readApiResultOrThrow<{\n items?: PriceKindApiPayload[];\n }>(\"/api/catalog/price-kinds?pageSize=100\", undefined, {\n fallback: { items: [] },\n });\n const items = Array.isArray(payload.items) ? payload.items : [];\n const summaries = items\n .map((item) => normalizePriceKindSummary(item))\n .filter((entry): entry is PriceKindSummary => !!entry);\n if (!cancelled) {\n setPriceKinds(summaries);\n }\n } catch (err) {\n console.error(\"catalog.price-kinds.fetch failed\", err);\n if (!cancelled) {\n setPriceKinds([]);\n }\n }\n }\n loadPriceKinds().catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n\n const handleVariantDeleted = React.useCallback((variantId: string) => {\n setVariants((prev) => prev.filter((variant) => variant.id !== variantId));\n }, []);\n\n const groups = React.useMemo<CrudFormGroup[]>(\n () => [\n {\n id: \"details\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductDetailsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n productId={productId ?? \"\"}\n />\n ),\n },\n {\n id: \"dimensions\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductDimensionsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"metadata\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductMetadataSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"options\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductOptionsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"product-uom\",\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <ProductUomSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"variants\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductVariantsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n productId={productId ?? \"\"}\n variants={variants}\n priceKinds={priceKinds}\n onVariantDeleted={handleVariantDeleted}\n onVariantsReload={refreshVariants}\n />\n ),\n },\n {\n id: \"meta\",\n column: 2,\n title: t(\"catalog.products.create.meta.title\", \"Product meta\"),\n description: t(\n \"catalog.products.create.meta.description\",\n \"Manage subtitle and handle for storefronts.\",\n ),\n component: ({ values, setValue, errors }) => (\n <ProductMetaSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n taxRates={taxRates}\n />\n ),\n },\n {\n id: \"categorize\",\n column: 2,\n title: t(\"catalog.products.create.organize.title\", \"Categorize\"),\n description: t(\n \"catalog.products.create.organize.description\",\n \"Assign categories, sales channels, and tags.\",\n ),\n component: ({ values, setValue, errors }) => (\n <ProductCategorizeSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n initialCategoryOptions={categorizeOptions.categories}\n initialChannelOptions={categorizeOptions.channels}\n initialTagOptions={categorizeOptions.tags}\n />\n ),\n },\n {\n id: \"custom-fields\",\n column: 2,\n title: t(\"catalog.products.edit.custom.title\", \"Custom attributes\"),\n kind: \"customFields\",\n },\n ],\n [\n categorizeOptions,\n handleVariantDeleted,\n priceKinds,\n productId,\n refreshVariants,\n t,\n taxRates,\n variants,\n ],\n );\n\n const handleSubmit = React.useCallback(\n async (formValues: ProductFormValues) => {\n const translateValidationMessage = (message: string | null | undefined) => {\n if (typeof message !== \"string\") return \"\";\n const trimmed = message.trim();\n if (!trimmed) return \"\";\n return t(trimmed, trimmed);\n };\n if (!productId) {\n throw createCrudFormError(\n t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n ),\n );\n }\n const parsed = productFormSchema.safeParse(formValues);\n if (!parsed.success) {\n const issues = parsed.error.issues;\n const fieldErrors: Record<string, string> = {};\n issues.forEach((issue) => {\n const path = issue.path.join(\".\") || \"form\";\n if (!fieldErrors[path]) {\n fieldErrors[path] = translateValidationMessage(issue.message);\n }\n });\n const message =\n translateValidationMessage(issues[0]?.message) ||\n t(\n \"catalog.products.edit.errors.validation\",\n \"Fix highlighted fields.\",\n );\n throw createCrudFormError(message, fieldErrors);\n }\n const values: ProductFormValues = {\n ...BASE_INITIAL_VALUES,\n ...parsed.data,\n title: parsed.data.title ?? \"\",\n subtitle: parsed.data.subtitle ?? \"\",\n handle: parsed.data.handle ?? \"\",\n description: parsed.data.description ?? \"\",\n useMarkdown: parsed.data.useMarkdown ?? false,\n taxRateId: parsed.data.taxRateId ?? null,\n mediaDraftId: parsed.data.mediaDraftId ?? productId!,\n mediaItems: Array.isArray(parsed.data.mediaItems)\n ? parsed.data.mediaItems\n : [],\n defaultMediaId: parsed.data.defaultMediaId ?? null,\n defaultMediaUrl: parsed.data.defaultMediaUrl ?? \"\",\n hasVariants: parsed.data.hasVariants ?? false,\n options: Array.isArray(parsed.data.options) ? parsed.data.options : [],\n variants: Array.isArray(parsed.data.variants)\n ? parsed.data.variants\n : [],\n metadata: parsed.data.metadata ?? {},\n dimensions: parsed.data.dimensions ?? null,\n weight: parsed.data.weight ?? null,\n defaultUnit: parsed.data.defaultUnit ?? null,\n defaultSalesUnit: parsed.data.defaultSalesUnit ?? null,\n defaultSalesUnitQuantity:\n parsed.data.defaultSalesUnitQuantity?.toString() ?? \"1\",\n uomRoundingScale: parsed.data.uomRoundingScale?.toString() ?? \"4\",\n uomRoundingMode: parsed.data.uomRoundingMode ?? \"half_up\",\n unitPriceEnabled: Boolean(parsed.data.unitPriceEnabled),\n unitPriceReferenceUnit: parsed.data.unitPriceReferenceUnit ?? null,\n unitPriceBaseQuantity:\n parsed.data.unitPriceBaseQuantity?.toString() ?? \"\",\n unitConversions: Array.isArray(parsed.data.unitConversions)\n ? parsed.data.unitConversions.map((entry) => ({\n id: toTrimmedOrNull(entry.id) ?? null,\n unitCode: toTrimmedOrNull(entry.unitCode) ?? \"\",\n toBaseFactor:\n toPositiveNumberOrNull(entry.toBaseFactor) === null\n ? \"\"\n : String(toPositiveNumberOrNull(entry.toBaseFactor)),\n sortOrder:\n typeof entry.sortOrder === \"number\" &&\n Number.isFinite(entry.sortOrder)\n ? String(entry.sortOrder)\n : \"\",\n isActive: entry.isActive !== false,\n }))\n : [],\n customFieldsetCode: parsed.data.customFieldsetCode ?? null,\n categoryIds: parsed.data.categoryIds ?? [],\n channelIds: parsed.data.channelIds ?? [],\n tags: parsed.data.tags ?? [],\n optionSchemaId: parsed.data.optionSchemaId ?? null,\n };\n const title = values.title?.trim();\n if (!title) {\n const message = t(\n \"catalog.products.create.errors.title\",\n \"Provide a product title.\",\n );\n throw createCrudFormError(message, { title: message });\n }\n const handle = values.handle?.trim() || undefined;\n const description = values.description?.trim() || undefined;\n const metadata = buildMetadataPayload(values);\n const dimensions = sanitizeProductDimensions(values.dimensions ?? null);\n const weight = sanitizeProductWeight(values.weight ?? null);\n const resolveTaxRateValue = (taxRateId?: string | null) => {\n if (!taxRateId) return null;\n const match = taxRates.find((rate) => rate.id === taxRateId);\n return typeof match?.rate === \"number\" && Number.isFinite(match.rate)\n ? match.rate\n : null;\n };\n const productTaxRateValue = resolveTaxRateValue(values.taxRateId ?? null);\n const defaultMediaId =\n typeof values.defaultMediaId === \"string\" &&\n values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : null;\n const defaultMediaEntry = defaultMediaId\n ? values.mediaItems.find((item) => item.id === defaultMediaId)\n : null;\n const defaultMediaUrl = defaultMediaEntry\n ? buildAttachmentImageUrl(defaultMediaEntry.id, {\n slug: slugifyAttachmentFileName(defaultMediaEntry.fileName),\n })\n : null;\n const defaultUnit = canonicalizeUnitCode(values.defaultUnit);\n const defaultSalesUnit = canonicalizeUnitCode(values.defaultSalesUnit);\n const defaultSalesUnitQuantity =\n toPositiveNumberOrNull(values.defaultSalesUnitQuantity) ?? 1;\n const uomRoundingScale = toIntegerInRangeOrDefault(\n values.uomRoundingScale,\n 0,\n 6,\n 4,\n );\n const uomRoundingMode: ProductUnitRoundingMode =\n values.uomRoundingMode === \"down\" || values.uomRoundingMode === \"up\"\n ? values.uomRoundingMode\n : \"half_up\";\n const unitPriceEnabled = Boolean(values.unitPriceEnabled);\n const unitPriceReferenceUnit = canonicalizeUnitCode(\n values.unitPriceReferenceUnit,\n );\n const unitPriceBaseQuantity = toPositiveNumberOrNull(\n values.unitPriceBaseQuantity,\n );\n if (defaultSalesUnit && !defaultUnit) {\n const message = t(\n \"catalog.products.uom.errors.baseRequired\",\n \"Base unit is required when default sales unit is set.\",\n );\n throw createCrudFormError(message, { defaultSalesUnit: message });\n }\n const conversionInputs = normalizeProductConversionInputs(\n values.unitConversions,\n t(\n \"catalog.products.uom.errors.duplicateConversion\",\n \"Duplicate conversion unit is not allowed.\",\n ),\n );\n if (conversionInputs.length && !defaultUnit) {\n const message = t(\n \"catalog.products.uom.errors.baseRequiredForConversions\",\n \"Base unit is required when conversions are configured.\",\n );\n throw createCrudFormError(message, { defaultUnit: message });\n }\n const defaultUnitKey = defaultUnit?.toLowerCase() ?? null;\n const defaultSalesUnitKey = defaultSalesUnit?.toLowerCase() ?? null;\n if (\n defaultUnitKey &&\n defaultSalesUnitKey &&\n defaultSalesUnitKey !== defaultUnitKey\n ) {\n const hasDefaultSalesConversion = conversionInputs.some(\n (entry) =>\n entry.isActive &&\n entry.unitCode.toLowerCase() === defaultSalesUnitKey,\n );\n if (!hasDefaultSalesConversion) {\n const message = t(\n \"catalog.products.uom.errors.defaultSalesConversionRequired\",\n \"Active conversion for default sales unit is required when it differs from base unit.\",\n );\n throw createCrudFormError(message, {\n defaultSalesUnit: message,\n unitConversions: message,\n });\n }\n }\n if (unitPriceEnabled) {\n if (\n !unitPriceReferenceUnit ||\n !UNIT_PRICE_REFERENCE_UNITS.has(\n unitPriceReferenceUnit as ProductUnitPriceReferenceUnit,\n )\n ) {\n const message = t(\n \"catalog.products.unitPrice.errors.referenceUnit\",\n \"Reference unit is required when unit price display is enabled.\",\n );\n throw createCrudFormError(message, {\n unitPriceReferenceUnit: message,\n });\n }\n if (unitPriceBaseQuantity === null) {\n const message = t(\n \"catalog.products.unitPrice.errors.baseQuantity\",\n \"Base quantity is required when unit price display is enabled.\",\n );\n throw createCrudFormError(message, {\n unitPriceBaseQuantity: message,\n });\n }\n }\n const payload: Record<string, unknown> = {\n id: productId,\n title,\n subtitle: values.subtitle?.trim() || undefined,\n description,\n handle,\n taxRateId: values.taxRateId ?? null,\n taxRate: productTaxRateValue ?? null,\n isConfigurable: Boolean(values.hasVariants),\n metadata,\n dimensions,\n weightValue: weight?.value ?? null,\n weightUnit: weight?.unit ?? null,\n defaultMediaId: defaultMediaId ?? undefined,\n defaultMediaUrl: defaultMediaUrl ?? undefined,\n defaultUnit: defaultUnit ?? null,\n defaultSalesUnit: defaultSalesUnit ?? defaultUnit ?? null,\n defaultSalesUnitQuantity,\n uomRoundingScale,\n uomRoundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit: unitPriceEnabled\n ? unitPriceReferenceUnit\n : undefined,\n unitPriceBaseQuantity: unitPriceEnabled\n ? unitPriceBaseQuantity\n : undefined,\n customFieldsetCode: values.customFieldsetCode?.trim().length\n ? values.customFieldsetCode\n : undefined,\n };\n const categoryIds = normalizeIdList(values.categoryIds);\n const channelIds = normalizeIdList(values.channelIds);\n const tags = normalizeTagValues(values.tags);\n payload.categoryIds = categoryIds;\n payload.tags = tags;\n const optionSchemaDefinition = buildOptionSchemaDefinition(\n values.options,\n title,\n );\n if (optionSchemaDefinition) {\n payload.optionSchema = optionSchemaDefinition;\n } else if (values.optionSchemaId) {\n payload.optionSchemaId = null;\n }\n const customFields = collectCustomFieldValues(values);\n if (Object.keys(customFields).length) {\n payload.customFields = customFields;\n }\n const previousSnapshots = offerSnapshotsRef.current;\n const offersPayload = buildOfferPayloads({\n channelIds,\n offerSnapshots: previousSnapshots,\n fallback: {\n title,\n description: description ?? undefined,\n defaultMediaId,\n defaultMediaUrl: defaultMediaUrl ?? undefined,\n },\n });\n payload.offers = offersPayload;\n const removedOffers = previousSnapshots.filter(\n (offer) =>\n typeof offer.id === \"string\" && !channelIds.includes(offer.channelId),\n );\n if (removedOffers.length) {\n try {\n for (const offer of removedOffers) {\n if (!offer.id) continue;\n await deleteCrud(\"catalog/offers\", offer.id, {\n errorMessage: t(\n \"catalog.products.edit.offers.deleteError\",\n \"Failed to remove sales channel offer.\",\n ),\n });\n }\n } catch (err) {\n console.error(\"catalog.products.edit.offers.delete\", err);\n throw createCrudFormError(\n t(\n \"catalog.products.edit.offers.deleteError\",\n \"Failed to remove sales channel offer.\",\n ),\n );\n }\n }\n await updateCrud(\"catalog/products\", payload);\n const previousConversionIds = new Set(\n initialConversionsRef.current\n .map((entry) => toTrimmedOrNull(entry.id))\n .filter((id): id is string => Boolean(id)),\n );\n const nextConversionIds = new Set(\n conversionInputs\n .map((entry) =>\n entry.id && entry.id.trim().length ? entry.id : null,\n )\n .filter((id): id is string => Boolean(id)),\n );\n const removedConversionIds = Array.from(previousConversionIds).filter(\n (id) => !nextConversionIds.has(id),\n );\n for (const conversionId of removedConversionIds) {\n await deleteCrud(\"catalog/product-unit-conversions\", conversionId, {\n errorMessage: t(\n \"catalog.products.uom.errors.sync\",\n \"Failed to synchronize product conversions.\",\n ),\n });\n }\n const persistedConversions: ProductUnitConversionDraft[] = [];\n for (const conversion of conversionInputs) {\n if (conversion.id) {\n await updateCrud(\"catalog/product-unit-conversions\", {\n id: conversion.id,\n unitCode: conversion.unitCode,\n toBaseFactor: conversion.toBaseFactor,\n sortOrder: conversion.sortOrder,\n isActive: conversion.isActive,\n });\n persistedConversions.push({\n id: conversion.id,\n unitCode: conversion.unitCode,\n toBaseFactor: String(conversion.toBaseFactor),\n sortOrder: String(conversion.sortOrder),\n isActive: conversion.isActive,\n });\n continue;\n }\n const created = await createCrud<{ id?: string }>(\n \"catalog/product-unit-conversions\",\n {\n productId,\n unitCode: conversion.unitCode,\n toBaseFactor: conversion.toBaseFactor,\n sortOrder: conversion.sortOrder,\n isActive: conversion.isActive,\n },\n );\n const createdId =\n created.result &&\n typeof created.result === \"object\" &&\n typeof (created.result as { id?: unknown }).id === \"string\"\n ? (created.result as { id: string }).id\n : null;\n persistedConversions.push({\n id: createdId,\n unitCode: conversion.unitCode,\n toBaseFactor: String(conversion.toBaseFactor),\n sortOrder: String(conversion.sortOrder),\n isActive: conversion.isActive,\n });\n }\n initialConversionsRef.current = persistedConversions;\n offerSnapshotsRef.current = mergeOfferSnapshots(\n previousSnapshots,\n offersPayload,\n );\n flash(t(\"catalog.products.edit.success\", \"Product updated.\"), \"success\");\n router.push(\"/backend/catalog/products\");\n },\n [productId, t, taxRates, router],\n );\n\n if (!productId) {\n return (\n <Page>\n <PageBody>\n <div className=\"rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n )}\n </div>\n </PageBody>\n </Page>\n );\n }\n\n return (\n <Page>\n <PageBody>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<ProductFormValues>\n title={t(\"catalog.products.edit.title\", \"Edit product\")}\n backHref=\"/backend/catalog/products\"\n versionHistory={{\n resourceKind: \"catalog.product\",\n resourceId: productId ? String(productId) : \"\",\n }}\n extraActions={productId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: \"catalog\",\n entityType: \"product\",\n entityId: productId,\n previewData: {\n title: initialValues?.title ?? productId,\n }\n }}\n viewHref={`/backend/catalog/products/${productId}/edit`}\n />\n ) : undefined}\n fields={[]}\n groups={groups}\n injectionSpotId=\"crud-form:catalog.product\"\n entityId={E.catalog.catalog_product}\n customFieldsetBindings={{\n [E.catalog.catalog_product]: { valueKey: \"customFieldsetCode\" },\n }}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t(\"catalog.products.edit.loading\", \"Loading product\")}\n submitLabel={t(\"catalog.products.edit.save\", \"Save changes\")}\n cancelHref=\"/backend/catalog/products\"\n onSubmit={handleSubmit}\n />\n </PageBody>\n </Page>\n );\n}\n\ntype ProductFormGroupProps = CrudFormGroupComponentProps & {\n values: ProductFormValues;\n};\n\ntype ProductDetailsSectionProps = ProductFormGroupProps & { productId: string };\n\ntype ProductMetaSectionProps = ProductFormGroupProps & {\n taxRates: TaxRateSummary[];\n};\n\ntype ProductVariantsSectionProps = Omit<\n CrudFormGroupComponentProps,\n \"values\"\n> & {\n values: ProductFormValues;\n productId: string;\n variants: VariantSummary[];\n priceKinds: PriceKindSummary[];\n onVariantDeleted: (variantId: string) => void;\n onVariantsReload?: () => Promise<void> | void;\n};\n\ntype ProductDimensionsSectionProps = ProductFormGroupProps;\n\nfunction ProductDetailsSection({\n values,\n setValue,\n errors,\n productId,\n}: ProductDetailsSectionProps) {\n const t = useT();\n const mediaItems = React.useMemo(\n () => (Array.isArray(values.mediaItems) ? values.mediaItems : []),\n [values.mediaItems],\n );\n\n const handleMediaItemsChange = React.useCallback(\n (nextItems: ProductMediaItem[]) => {\n setValue(\"mediaItems\", nextItems);\n const hasCurrent = nextItems.some(\n (item) => item.id === values.defaultMediaId,\n );\n if (!hasCurrent) {\n const fallbackId = nextItems[0]?.id ?? null;\n setValue(\"defaultMediaId\", fallbackId);\n if (fallbackId && nextItems[0]) {\n setValue(\n \"defaultMediaUrl\",\n buildAttachmentImageUrl(fallbackId, {\n slug: slugifyAttachmentFileName(nextItems[0].fileName),\n }),\n );\n } else {\n setValue(\"defaultMediaUrl\", \"\");\n }\n }\n },\n [setValue, values.defaultMediaId],\n );\n\n const handleDefaultMediaChange = React.useCallback(\n (attachmentId: string | null) => {\n setValue(\"defaultMediaId\", attachmentId);\n if (!attachmentId) {\n setValue(\"defaultMediaUrl\", \"\");\n return;\n }\n const target = mediaItems.find((item) => item.id === attachmentId);\n if (target) {\n setValue(\n \"defaultMediaUrl\",\n buildAttachmentImageUrl(target.id, {\n slug: slugifyAttachmentFileName(target.fileName),\n }),\n );\n }\n },\n [mediaItems, setValue],\n );\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <Label className=\"flex items-center gap-1\">\n {t(\"catalog.products.form.title\", \"Title\")}\n <span className=\"text-red-600\">*</span>\n </Label>\n <Input\n value={values.title}\n onChange={(event) => setValue(\"title\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.title\",\n \"e.g., Summer sneaker\",\n )}\n />\n {errors.title ? (\n <p className=\"text-xs text-red-600\">{errors.title}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Label>{t(\"catalog.products.form.description\", \"Description\")}</Label>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setValue(\"useMarkdown\", !values.useMarkdown)}\n className=\"gap-2 text-xs\"\n >\n {values.useMarkdown ? (\n <AlignLeft className=\"h-4 w-4\" />\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n {values.useMarkdown\n ? t(\"catalog.products.create.actions.usePlain\", \"Use plain text\")\n : t(\n \"catalog.products.create.actions.useMarkdown\",\n \"Use markdown\",\n )}\n </Button>\n </div>\n {values.useMarkdown ? (\n <div\n data-color-mode=\"light\"\n className=\"overflow-hidden rounded-md border\"\n >\n <MarkdownEditor\n value={values.description}\n height={260}\n onChange={(val) => setValue(\"description\", val ?? \"\")}\n previewOptions={{ remarkPlugins: [] }}\n />\n </div>\n ) : (\n <Textarea\n className=\"min-h-[180px]\"\n value={values.description}\n onChange={(event) => setValue(\"description\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.description\",\n \"Describe the product...\",\n )}\n />\n )}\n </div>\n\n <ProductMediaManager\n entityId={E.catalog.catalog_product}\n draftRecordId={values.mediaDraftId || productId}\n items={mediaItems}\n defaultMediaId={values.defaultMediaId ?? null}\n onItemsChange={handleMediaItemsChange}\n onDefaultChange={handleDefaultMediaChange}\n />\n </div>\n );\n}\n\nfunction ProductDimensionsSection({\n values,\n setValue,\n}: ProductDimensionsSectionProps) {\n const t = useT();\n const dimensionValues = normalizeProductDimensions(values.dimensions);\n const weightValues = normalizeProductWeight(values.weight);\n\n return (\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.edit.dimensions\", \"Dimensions & weight\")}\n </h3>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.width\", \"Width\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.width ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"width\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.height\", \"Height\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.height ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"height\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.depth\", \"Depth\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.depth ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"depth\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.unit\", \"Size unit\")}\n </Label>\n <Input\n value={dimensionValues?.unit ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"unit\",\n event.target.value,\n ),\n )\n }\n placeholder=\"cm\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.weight.value\", \"Weight\")}\n </Label>\n <Input\n type=\"number\"\n value={weightValues?.value ?? \"\"}\n onChange={(event) =>\n setValue(\n \"weight\",\n updateWeightValue(\n values.weight ?? null,\n \"value\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.weight.unit\", \"Weight unit\")}\n </Label>\n <Input\n value={weightValues?.unit ?? \"\"}\n onChange={(event) =>\n setValue(\n \"weight\",\n updateWeightValue(\n values.weight ?? null,\n \"unit\",\n event.target.value,\n ),\n )\n }\n placeholder=\"kg\"\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction ProductMetadataSection({ values, setValue }: ProductFormGroupProps) {\n const metadata = normalizeMetadata(values.metadata);\n const handleMetadataChange = React.useCallback(\n (next: Record<string, unknown>) => {\n setValue(\"metadata\", next);\n },\n [setValue],\n );\n\n return (\n <MetadataEditor value={metadata} onChange={handleMetadataChange} embedded />\n );\n}\n\nfunction ProductOptionsSection({ values, setValue }: ProductFormGroupProps) {\n const t = useT();\n const [schemaDialogOpen, setSchemaDialogOpen] = React.useState(false);\n const [schemaTemplates, setSchemaTemplates] = React.useState<\n OptionSchemaTemplateSummary[]\n >([]);\n const [schemaLoading, setSchemaLoading] = React.useState(false);\n const [saveSchemaOpen, setSaveSchemaOpen] = React.useState(false);\n const [schemaToEdit, setSchemaToEdit] =\n React.useState<OptionSchemaTemplateSummary | null>(null);\n\n const loadSchemas = React.useCallback(async () => {\n setSchemaLoading(true);\n try {\n const res = await apiCall<OptionSchemaTemplateListResponse>(\n \"/api/catalog/option-schemas?page=1&pageSize=100\",\n );\n if (res.ok) {\n setSchemaTemplates(\n Array.isArray(res.result?.items) ? (res.result?.items ?? []) : [],\n );\n } else {\n setSchemaTemplates([]);\n }\n } catch (err) {\n console.error(\"catalog.option-schemas.list failed\", err);\n setSchemaTemplates([]);\n } finally {\n setSchemaLoading(false);\n }\n }, []);\n\n const handleDeleteSchema = React.useCallback(\n async (id: string) => {\n try {\n await deleteCrud(\"catalog/option-schemas\", id, {\n errorMessage: t(\n \"catalog.products.edit.schemas.deleteError\",\n \"Failed to delete schema.\",\n ),\n });\n flash(\n t(\"catalog.products.edit.schemas.deleted\", \"Schema deleted.\"),\n \"success\",\n );\n void loadSchemas();\n } catch (err) {\n console.error(\"catalog.option-schemas.delete failed\", err);\n }\n },\n [loadSchemas, t],\n );\n\n const handleSaveSchema = React.useCallback(\n async (name: string) => {\n if (!name.trim().length) {\n const message = t(\n \"catalog.products.edit.schemas.nameRequired\",\n \"Provide a schema name.\",\n );\n throw createCrudFormError(message, { name: message });\n }\n const schemaPayload = buildSchemaFromOptions(\n Array.isArray(values.options) ? values.options : [],\n name,\n );\n if (!schemaPayload.options?.length) {\n throw createCrudFormError(\n t(\n \"catalog.products.edit.schemas.empty\",\n \"Add at least one option before saving.\",\n ),\n {},\n );\n }\n const payload: Record<string, unknown> = {\n name: name.trim(),\n code: slugify(name.trim()),\n schema: schemaPayload,\n isActive: true,\n };\n if (schemaToEdit?.id) payload.id = schemaToEdit.id;\n if (schemaToEdit?.id) await updateCrud(\"catalog/option-schemas\", payload);\n else await createCrud(\"catalog/option-schemas\", payload);\n flash(\n t(\"catalog.products.edit.schemas.saved\", \"Schema saved.\"),\n \"success\",\n );\n setSaveSchemaOpen(false);\n setSchemaToEdit(null);\n void loadSchemas();\n },\n [schemaToEdit, t, values.options, loadSchemas],\n );\n\n const handleOptionTitleChange = React.useCallback(\n (optionId: string, nextTitle: string) => {\n const next = (Array.isArray(values.options) ? values.options : []).map(\n (option) =>\n option.id === optionId ? { ...option, title: nextTitle } : option,\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n const setOptionValues = React.useCallback(\n (optionId: string, labels: string[]) => {\n const normalized = labels\n .map((label) => label.trim())\n .filter((label) => label.length);\n const unique = Array.from(new Set(normalized));\n const next = (Array.isArray(values.options) ? values.options : []).map(\n (option) => {\n if (option.id !== optionId) return option;\n const existingByLabel = new Map(\n option.values.map((value) => [value.label, value]),\n );\n const nextValues = unique.map(\n (label) =>\n existingByLabel.get(label) ?? { id: createLocalId(), label },\n );\n return {\n ...option,\n values: nextValues,\n };\n },\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n const addOption = React.useCallback(() => {\n const next = [\n ...(Array.isArray(values.options) ? values.options : []),\n { id: createLocalId(), title: \"\", values: [] },\n ];\n setValue(\"options\", next);\n }, [setValue, values.options]);\n\n const removeOption = React.useCallback(\n (optionId: string) => {\n const next = (Array.isArray(values.options) ? values.options : []).filter(\n (option) => option.id !== optionId,\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n return (\n <>\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">\n {t(\n \"catalog.products.create.optionsBuilder.title\",\n \"Product options\",\n )}\n </h3>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setSchemaDialogOpen(true);\n void loadSchemas();\n }}\n title={t(\n \"catalog.products.edit.schemas.manage\",\n \"Open schema library\",\n )}\n >\n <BookMarked className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setSchemaToEdit(null);\n setSaveSchemaOpen(true);\n }}\n title={t(\"catalog.products.edit.schemas.save\", \"Save as schema\")}\n >\n <Save className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={addOption}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {t(\"catalog.products.create.optionsBuilder.add\", \"Add option\")}\n </Button>\n </div>\n </div>\n {(Array.isArray(values.options) ? values.options : []).map((option) => (\n <div key={option.id} className=\"rounded-md bg-muted/40 p-4\">\n <div className=\"flex items-center gap-2\">\n <Input\n value={option.title}\n onChange={(event) =>\n handleOptionTitleChange(option.id, event.target.value)\n }\n placeholder={t(\n \"catalog.products.create.optionsBuilder.placeholder\",\n \"e.g., Color\",\n )}\n className=\"flex-1\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n onClick={() => removeOption(option.id)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n <div className=\"mt-3 space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.create.optionsBuilder.values\", \"Values\")}\n </Label>\n <TagsInput\n value={option.values.map((value) => value.label)}\n onChange={(labels) => setOptionValues(option.id, labels)}\n placeholder={t(\n \"catalog.products.create.optionsBuilder.valuePlaceholder\",\n \"Type a value and press Enter\",\n )}\n />\n </div>\n </div>\n ))}\n {!values.options?.length ? (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n \"catalog.products.create.optionsBuilder.empty\",\n \"No options yet. Add your first option to generate variants.\",\n )}\n </p>\n ) : null}\n </div>\n\n <OptionSchemaDialog\n open={schemaDialogOpen}\n onOpenChange={(next) => {\n setSchemaDialogOpen(next);\n if (next) void loadSchemas();\n }}\n isLoading={schemaLoading}\n templates={schemaTemplates}\n onSelect={(template) => {\n setSchemaDialogOpen(false);\n if (!template) return;\n const options = extractOptionsFromTemplate(template);\n setValue(\"options\", options);\n }}\n onDelete={handleDeleteSchema}\n onEdit={(template) => {\n setSchemaToEdit(template);\n setSaveSchemaOpen(true);\n }}\n />\n\n <SaveSchemaDialog\n open={saveSchemaOpen}\n onOpenChange={(next) => {\n setSaveSchemaOpen(next);\n if (!next) setSchemaToEdit(null);\n }}\n defaultName={schemaToEdit?.name ?? \"\"}\n onSubmit={handleSaveSchema}\n />\n </>\n );\n}\n\nfunction ProductVariantsSection({\n values,\n productId,\n variants,\n priceKinds,\n onVariantDeleted,\n onVariantsReload,\n}: ProductVariantsSectionProps) {\n const t = useT();\n const { confirm, ConfirmDialogElement } = useConfirmDialog();\n const [deletingId, setDeletingId] = React.useState<string | null>(null);\n const [generating, setGenerating] = React.useState(false);\n const [checkingVariantFeature, setCheckingVariantFeature] =\n React.useState(true);\n const [canManageVariants, setCanManageVariants] = React.useState(false);\n const optionDefinitions = React.useMemo(\n () => (Array.isArray(values.options) ? values.options : []),\n [values.options],\n );\n const combos = React.useMemo(\n () => buildVariantCombinations(optionDefinitions),\n [optionDefinitions],\n );\n const existingKeys = React.useMemo(() => {\n const set = new Set<string>();\n variants.forEach((variant) => {\n const key = buildOptionValuesKey(variant.optionValues ?? undefined);\n if (key) set.add(key);\n });\n return set;\n }, [variants]);\n const missingCombos = React.useMemo(\n () =>\n combos.filter((combo) => {\n const key = buildOptionValuesKey(combo);\n if (!key) return false;\n return !existingKeys.has(key);\n }),\n [combos, existingKeys],\n );\n const priceKindLookup = React.useMemo(() => {\n const map = new Map<string, PriceKindSummary>();\n for (const kind of priceKinds) {\n map.set(kind.id, kind);\n }\n return map;\n }, [priceKinds]);\n React.useEffect(() => {\n let cancelled = false;\n async function checkVariantFeature() {\n try {\n const payload = await readApiResultOrThrow<{\n ok?: boolean;\n granted?: unknown;\n }>(\n \"/api/auth/feature-check\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ features: [\"catalog.variants.manage\"] }),\n },\n { allowNullResult: true },\n );\n if (cancelled) return;\n const sourceGranted = Array.isArray(payload?.granted)\n ? payload?.granted\n : [];\n const granted = (sourceGranted as unknown[]).filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.length > 0,\n );\n const hasFeature =\n payload?.ok === true || granted.includes(\"catalog.variants.manage\");\n setCanManageVariants(hasFeature);\n } catch {\n if (!cancelled) setCanManageVariants(false);\n } finally {\n if (!cancelled) setCheckingVariantFeature(false);\n }\n }\n checkVariantFeature().catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n const allowVariantActions = canManageVariants && !checkingVariantFeature;\n const formatPriceLabel = React.useCallback(\n (price: VariantPriceSummary): string => {\n const kind = price.priceKindId\n ? priceKindLookup.get(price.priceKindId)\n : null;\n if (kind?.title) return kind.title;\n if (kind?.code) return kind.code.toUpperCase();\n return t(\"catalog.products.edit.variantList.priceFallback\", \"Price\");\n },\n [priceKindLookup, t],\n );\n const formatPriceAmount = React.useCallback(\n (price: VariantPriceSummary): string => {\n const amount =\n typeof price.amount === \"string\" && price.amount.trim().length\n ? price.amount.trim()\n : \"\";\n if (!amount) return \"\u2014\";\n if (!price.currencyCode) return amount;\n return `${price.currencyCode.toUpperCase()} ${amount}`;\n },\n [],\n );\n const handleDeleteVariant = React.useCallback(\n async (variant: VariantSummary) => {\n if (!allowVariantActions) return;\n const label = variant.name || variant.sku || variant.id;\n const confirmMessage = t(\n \"catalog.products.edit.variantList.deleteConfirm\",\n 'Delete variant \"{{name}}\"?',\n ).replace(\"{{name}}\", label);\n const confirmed = await confirm({\n title: confirmMessage,\n variant: \"destructive\",\n });\n if (!confirmed) return;\n setDeletingId(variant.id);\n try {\n await deleteCrud(\"catalog/variants\", variant.id, {\n errorMessage: t(\n \"catalog.variants.form.deleteError\",\n \"Failed to delete variant.\",\n ),\n });\n flash(\n t(\"catalog.variants.form.deleted\", \"Variant deleted.\"),\n \"success\",\n );\n onVariantDeleted(variant.id);\n } catch (err) {\n console.error(\"catalog.products.edit.variants.delete\", err);\n flash(\n t(\"catalog.variants.form.deleteError\", \"Failed to delete variant.\"),\n \"error\",\n );\n } finally {\n setDeletingId(null);\n }\n },\n [allowVariantActions, confirm, onVariantDeleted, t],\n );\n const handleGenerateVariants = React.useCallback(async () => {\n if (!productId || !allowVariantActions) return;\n if (!missingCombos.length) {\n flash(\n t(\n \"catalog.products.edit.variantList.generateEmpty\",\n \"All option combinations already exist.\",\n ),\n \"info\",\n );\n return;\n }\n setGenerating(true);\n try {\n for (const combo of missingCombos) {\n const title =\n Object.values(combo)\n .map((value) => value?.trim())\n .filter((value) => value && value.length)\n .join(\" / \") ||\n t(\"catalog.products.edit.variantList.defaultTitle\", \"Variant\");\n await createCrud(\"catalog/variants\", {\n productId,\n name: title,\n optionValues: combo,\n isDefault: false,\n isActive: true,\n });\n }\n flash(\n t(\n \"catalog.products.edit.variantList.generateSuccess\",\n \"Missing variants generated.\",\n ),\n \"success\",\n );\n if (onVariantsReload) await onVariantsReload();\n } catch (err) {\n console.error(\"catalog.products.edit.variantList.generate\", err);\n flash(\n t(\n \"catalog.products.edit.variantList.generateError\",\n \"Failed to generate variants.\",\n ),\n \"error\",\n );\n } finally {\n setGenerating(false);\n }\n }, [allowVariantActions, missingCombos, onVariantsReload, productId, t]);\n\n const showGenerateButton =\n optionDefinitions.length > 0 && allowVariantActions;\n\n return (\n <>\n <div className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <h3 id=\"variants\" className=\"text-sm font-semibold\">\n {t(\"catalog.products.edit.variants\", \"Variants\")}\n </h3>\n <div className=\"flex flex-wrap items-center gap-2\">\n {showGenerateButton ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={generating}\n onClick={() => {\n void handleGenerateVariants();\n }}\n >\n {generating\n ? t(\n \"catalog.products.edit.variantList.generating\",\n \"Generating\u2026\",\n )\n : t(\n \"catalog.products.edit.variantList.generate\",\n \"Generate variants\",\n )}\n </Button>\n ) : null}\n {allowVariantActions ? (\n <Button asChild size=\"sm\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/create`}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {t(\"catalog.products.edit.variants.add\", \"Add variant\")}\n </Link>\n </Button>\n ) : null}\n </div>\n </div>\n {variants.length ? (\n <div className=\"overflow-x-auto rounded-md border\">\n <table className=\"w-full table-auto text-sm\">\n <thead className=\"bg-muted/40 text-left text-xs uppercase text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 font-normal\">\n {t(\"catalog.products.form.variants\", \"Variant\")}\n </th>\n <th className=\"px-3 py-2 font-normal\">SKU</th>\n <th className=\"px-3 py-2 font-normal\">\n {t(\n \"catalog.products.edit.variantList.pricesHeading\",\n \"Prices\",\n )}\n </th>\n <th className=\"px-3 py-2 font-normal\">\n {t(\"catalog.products.edit.variants.default\", \"Default\")}\n </th>\n <th className=\"px-3 py-2 font-normal text-right\">\n {t(\"catalog.products.edit.variantList.actions\", \"Actions\")}\n </th>\n </tr>\n </thead>\n <tbody>\n {variants.map((variant) => (\n <tr key={variant.id} className=\"border-t hover:bg-muted/40\">\n <td className=\"px-3 py-2\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/${variant.id}`}\n className=\"text-sm font-medium hover:underline\"\n >\n {variant.name || variant.id}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {variant.sku || \"\u2014\"}\n </td>\n <td className=\"px-3 py-2\">\n {variant.prices.length ? (\n <ul className=\"space-y-1\">\n {variant.prices.map((price) => (\n <li\n key={price.id}\n className=\"text-xs text-muted-foreground\"\n >\n <span className=\"font-medium text-foreground\">\n {formatPriceLabel(price)}\n </span>{\" \"}\n <span>{formatPriceAmount(price)}</span>\n </li>\n ))}\n </ul>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.edit.variantList.pricesEmpty\",\n \"No prices yet.\",\n )}\n </span>\n )}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {variant.isDefault ? t(\"common.yes\", \"Yes\") : \"\u2014\"}\n </td>\n <td className=\"px-3 py-2\">\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button asChild size=\"sm\" variant=\"outline\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/${variant.id}`}\n >\n {t(\"catalog.products.list.actions.edit\", \"Edit\")}\n </Link>\n </Button>\n {allowVariantActions ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"text-destructive hover:text-destructive\"\n disabled={deletingId === variant.id}\n onClick={() => {\n void handleDeleteVariant(variant);\n }}\n >\n {deletingId === variant.id\n ? t(\n \"catalog.products.edit.variantList.deleting\",\n \"Deleting\u2026\",\n )\n : t(\n \"catalog.products.list.actions.delete\",\n \"Delete\",\n )}\n </Button>\n ) : null}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.edit.variants.empty\",\n \"No variants defined yet.\",\n )}\n </p>\n )}\n </div>\n {ConfirmDialogElement}\n </>\n );\n}\n\nfunction ProductMetaSection({\n values,\n setValue,\n errors,\n taxRates,\n}: ProductMetaSectionProps) {\n const t = useT();\n const handleValue = typeof values.handle === \"string\" ? values.handle : \"\";\n const titleSource = typeof values.title === \"string\" ? values.title : \"\";\n const autoHandleEnabledRef = React.useRef(handleValue.trim().length === 0);\n\n React.useEffect(() => {\n if (!autoHandleEnabledRef.current) return;\n const normalizedTitle = titleSource.trim();\n if (!normalizedTitle) {\n if (handleValue) {\n setValue(\"handle\", \"\");\n }\n return;\n }\n const nextHandle = slugify(normalizedTitle);\n if (nextHandle !== handleValue) {\n setValue(\"handle\", nextHandle);\n }\n }, [titleSource, handleValue, setValue]);\n\n const handleHandleInputChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const nextValue = event.target.value;\n autoHandleEnabledRef.current = nextValue.trim().length === 0;\n setValue(\"handle\", nextValue);\n },\n [setValue],\n );\n\n const handleGenerateHandle = React.useCallback(() => {\n const slug = slugify(titleSource);\n autoHandleEnabledRef.current = true;\n setValue(\"handle\", slug);\n }, [titleSource, setValue]);\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>{t(\"catalog.products.form.subtitle\", \"Subtitle\")}</Label>\n <Input\n value={typeof values.subtitle === \"string\" ? values.subtitle : \"\"}\n onChange={(event) => setValue(\"subtitle\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.subtitle\",\n \"Optional subtitle\",\n )}\n />\n {errors.subtitle ? (\n <p className=\"text-xs text-red-600\">{errors.subtitle}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label>\n {t(\"catalog.products.create.meta.handleLabel\", \"Handle\")}\n </Label>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleGenerateHandle}\n >\n {t(\"catalog.products.create.actions.generateHandle\", \"Generate\")}\n </Button>\n </div>\n <Input\n value={handleValue}\n onChange={handleHandleInputChange}\n placeholder={t(\n \"catalog.products.create.placeholders.handle\",\n \"e.g., summer-sneaker\",\n )}\n className=\"font-mono lowercase\"\n />\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.create.handleHelp\",\n \"Handle is used for URLs and must be unique.\",\n )}\n </p>\n {errors.handle ? (\n <p className=\"text-xs text-red-600\">{errors.handle}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label>\n {t(\"catalog.products.create.taxRates.label\", \"Tax class\")}\n </Label>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (typeof window !== \"undefined\") {\n window.open(\n \"/backend/config/sales?section=tax-rates\",\n \"_blank\",\n \"noopener,noreferrer\",\n );\n }\n }}\n title={t(\n \"catalog.products.create.taxRates.manage\",\n \"Manage tax classes\",\n )}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Layers className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.create.taxRates.manage\",\n \"Manage tax classes\",\n )}\n </span>\n </Button>\n </div>\n <select\n className=\"w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n value={values.taxRateId ?? \"\"}\n onChange={(event) =>\n setValue(\"taxRateId\", event.target.value || null)\n }\n disabled={!taxRates.length}\n >\n <option value=\"\">\n {taxRates.length\n ? t(\n \"catalog.products.create.taxRates.noneSelected\",\n \"No tax class selected\",\n )\n : t(\n \"catalog.products.create.taxRates.emptyOption\",\n \"No tax classes available\",\n )}\n </option>\n {taxRates.map((rate) => (\n <option key={rate.id} value={rate.id}>\n {formatTaxRateLabel(rate)}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-muted-foreground\">\n {taxRates.length\n ? t(\n \"catalog.products.create.taxRates.help\",\n \"Applied to prices unless overridden per variant.\",\n )\n : t(\n \"catalog.products.create.taxRates.empty\",\n \"Define tax classes under Sales \u2192 Configuration.\",\n )}\n </p>\n </div>\n </div>\n );\n}\n\nfunction normalizeMetadata(value: unknown): Record<string, any> {\n if (!value || typeof value !== \"object\") return {};\n const entries = Object.entries(value as Record<string, unknown>).filter(\n ([key]) =>\n !key.startsWith(\"cf\") && key !== \"dimensions\" && key !== \"weight\",\n );\n return Object.fromEntries(entries);\n}\n\nfunction readOptionSchema(metadata: Record<string, any>): ProductOptionInput[] {\n const raw = Array.isArray(metadata.optionSchema)\n ? metadata.optionSchema\n : Array.isArray(metadata.option_schema)\n ? metadata.option_schema\n : [];\n return raw\n .map((option) => {\n if (!option || typeof option !== \"object\") return null;\n const values = Array.isArray(option.values)\n ? option.values\n .map((value: any) =>\n value && typeof value === \"object\"\n ? {\n id: String(value.id ?? createLocalId()),\n label: typeof value.label === \"string\" ? value.label : \"\",\n }\n : null,\n )\n .filter(\n (\n entry: { id?: string; label?: string } | null,\n ): entry is { id: string; label: string } => !!entry,\n )\n : [];\n return {\n id: String(option.id ?? createLocalId()),\n title: typeof option.title === \"string\" ? option.title : \"\",\n values,\n };\n })\n .filter((entry): entry is ProductOptionInput => !!entry);\n}\n\nfunction extractCustomFields(record: Record<string, unknown>): {\n customValues: Record<string, unknown>;\n} {\n const customValues: Record<string, unknown> = {};\n Object.entries(record).forEach(([key, value]) => {\n if (key.startsWith(\"cf_\")) customValues[key] = value;\n else if (key.startsWith(\"cf:\")) customValues[`cf_${key.slice(3)}`] = value;\n });\n return { customValues };\n}\n\nfunction normalizeIdList(value: unknown): string[] {\n const ids = Array.isArray(value)\n ? value\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter((entry) => entry.length)\n : [];\n return Array.from(new Set(ids));\n}\n\nfunction normalizeTagValues(value: unknown): string[] {\n const tags = Array.isArray(value)\n ? value\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter((entry) => entry.length)\n : [];\n return Array.from(new Set(tags));\n}\n\nfunction formatCategoryLabel(\n name: string | null,\n fallback: string,\n parentName: string | null,\n): string {\n const base = name ?? fallback;\n return parentName ? `${base} / ${parentName}` : base;\n}\n\nfunction readCategorySelections(record: Record<string, unknown>): {\n ids: string[];\n options: ProductCategorizePickerOption[];\n} {\n const rawCategories = Array.isArray(\n (record as Record<string, unknown>).categories,\n )\n ? ((record as Record<string, unknown>).categories as Array<\n Record<string, unknown>\n >)\n : [];\n const options = rawCategories\n .map((entry) => {\n const value =\n getString(entry.id) ??\n getString(entry.categoryId) ??\n getString(entry.category_id);\n if (!value) return null;\n const name = getString(entry.name);\n const parentName = getString(entry.parentName);\n const label = formatCategoryLabel(name, value, parentName);\n const description =\n parentName && !label.toLowerCase().includes(parentName.toLowerCase())\n ? parentName\n : null;\n return { value, label, description };\n })\n .filter(\n (\n option: {\n value: string;\n label: string;\n description: string | null;\n } | null,\n ): option is {\n value: string;\n label: string;\n description: string | null;\n } => !!option,\n );\n const fallbackIds = normalizeIdList(\n (record as Record<string, unknown>).categoryIds,\n );\n const combinedIds = Array.from(\n new Set([...options.map((option) => option.value), ...fallbackIds]),\n );\n return { ids: combinedIds, options };\n}\n\nfunction readTagSelections(record: Record<string, unknown>): {\n values: string[];\n options: ProductCategorizePickerOption[];\n} {\n const values = normalizeTagValues((record as Record<string, unknown>).tags);\n const options = values.map((label) => ({ value: label, label }));\n return { values, options };\n}\n\nfunction readOfferSnapshots(record: Record<string, unknown>): OfferSnapshot[] {\n const rawOffers = Array.isArray((record as Record<string, unknown>).offers)\n ? ((record as Record<string, unknown>).offers as Array<\n Record<string, unknown>\n >)\n : [];\n const snapshots: OfferSnapshot[] = [];\n for (const offer of rawOffers) {\n if (!offer || typeof offer !== \"object\") continue;\n const channelId =\n getString(offer.channelId) ?? getString(offer.channel_id) ?? null;\n if (!channelId) continue;\n snapshots.push({\n id: getString(offer.id),\n channelId,\n title: getString(offer.title) ?? null,\n description: getString(offer.description) ?? null,\n defaultMediaId:\n getString(offer.defaultMediaId) ?? getString(offer.default_media_id),\n defaultMediaUrl:\n getString(offer.defaultMediaUrl) ?? getString(offer.default_media_url),\n metadata: isRecord(offer.metadata)\n ? (offer.metadata as Record<string, unknown>)\n : null,\n isActive: offer.isActive !== false,\n channelName:\n getString(offer.channelName) ?? getString(offer.channel_name),\n channelCode:\n getString(offer.channelCode) ?? getString(offer.channel_code),\n });\n }\n return snapshots;\n}\n\nfunction extractChannelIds(offers: OfferSnapshot[]): string[] {\n return Array.from(new Set(offers.map((offer) => offer.channelId)));\n}\n\nfunction buildChannelOptions(\n offers: OfferSnapshot[],\n): ProductCategorizePickerOption[] {\n const seen = new Set<string>();\n const options: ProductCategorizePickerOption[] = [];\n for (const offer of offers) {\n if (seen.has(offer.channelId)) continue;\n seen.add(offer.channelId);\n const label = offer.channelName || offer.channelCode || offer.channelId;\n const description =\n offer.channelCode && offer.channelCode !== label\n ? offer.channelCode\n : null;\n options.push({\n value: offer.channelId,\n label,\n description,\n });\n }\n return options;\n}\n\ntype OfferPayload = {\n id?: string;\n channelId: string;\n title: string;\n description?: string;\n defaultMediaId?: string | null;\n defaultMediaUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n isActive?: boolean;\n};\n\nfunction buildOfferPayloads(params: {\n channelIds: string[];\n offerSnapshots: OfferSnapshot[];\n fallback: {\n title: string;\n description?: string;\n defaultMediaId?: string | null;\n defaultMediaUrl?: string | null;\n };\n}): OfferPayload[] {\n const { channelIds, offerSnapshots, fallback } = params;\n const byChannel = new Map(\n offerSnapshots.map((offer) => [offer.channelId, offer]),\n );\n const payloads: OfferPayload[] = [];\n const fallbackTitle = fallback.title.trim();\n for (const channelId of channelIds) {\n const existing = byChannel.get(channelId);\n const title = ensureString(existing?.title) ?? fallbackTitle;\n const description =\n ensureString(existing?.description) ?? ensureString(fallback.description);\n payloads.push({\n id: existing?.id ?? undefined,\n channelId,\n title,\n description,\n defaultMediaId:\n existing?.defaultMediaId ?? fallback.defaultMediaId ?? null,\n defaultMediaUrl:\n existing?.defaultMediaUrl ?? fallback.defaultMediaUrl ?? null,\n metadata: existing?.metadata ?? undefined,\n isActive: existing?.isActive ?? true,\n });\n }\n return payloads;\n}\n\nfunction mergeOfferSnapshots(\n current: OfferSnapshot[],\n payloads: OfferPayload[],\n): OfferSnapshot[] {\n const currentByChannel = new Map(\n current.map((snapshot) => [snapshot.channelId, snapshot]),\n );\n return payloads.map((entry) => {\n const previous = currentByChannel.get(entry.channelId);\n return {\n id: entry.id ?? previous?.id ?? null,\n channelId: entry.channelId,\n title: entry.title ?? previous?.title ?? null,\n description: entry.description ?? previous?.description ?? null,\n defaultMediaId: entry.defaultMediaId ?? previous?.defaultMediaId ?? null,\n defaultMediaUrl:\n entry.defaultMediaUrl ?? previous?.defaultMediaUrl ?? null,\n metadata: entry.metadata ?? previous?.metadata ?? null,\n isActive: entry.isActive ?? previous?.isActive ?? true,\n channelName: previous?.channelName ?? null,\n channelCode: previous?.channelCode ?? null,\n };\n });\n}\n\nfunction getString(value: unknown): string | null {\n if (typeof value === \"string\" && value.trim().length) return value.trim();\n return null;\n}\n\nfunction ensureString(value: unknown): string | undefined {\n const normalized = getString(value);\n return normalized ?? undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction extractUomFields(record: Record<string, unknown>) {\n const unitPriceObject = isRecord(record.unit_price)\n ? (record.unit_price as Record<string, unknown>)\n : null;\n const defaultUnit = canonicalizeUnitCode(\n record.default_unit ?? record.defaultUnit,\n );\n const defaultSalesUnit = canonicalizeUnitCode(\n record.default_sales_unit ?? record.defaultSalesUnit,\n );\n const defaultSalesUnitQuantity = toPositiveNumberOrNull(\n record.default_sales_unit_quantity ?? record.defaultSalesUnitQuantity,\n );\n const roundingScale = toIntegerInRangeOrDefault(\n record.uom_rounding_scale ?? record.uomRoundingScale,\n 0,\n 6,\n 4,\n );\n const roundingModeRaw = toTrimmedOrNull(\n record.uom_rounding_mode ?? record.uomRoundingMode,\n );\n const roundingMode: ProductUnitRoundingMode =\n roundingModeRaw === \"down\" || roundingModeRaw === \"up\"\n ? roundingModeRaw\n : \"half_up\";\n const unitPriceEnabled = Boolean(\n unitPriceObject?.enabled ??\n record.unit_price_enabled ??\n record.unitPriceEnabled,\n );\n const unitPriceReferenceUnit = canonicalizeUnitCode(\n unitPriceObject?.reference_unit ??\n unitPriceObject?.referenceUnit ??\n record.unit_price_reference_unit ??\n record.unitPriceReferenceUnit,\n );\n const unitPriceBaseQuantity = toPositiveNumberOrNull(\n unitPriceObject?.base_quantity ??\n unitPriceObject?.baseQuantity ??\n record.unit_price_base_quantity ??\n record.unitPriceBaseQuantity,\n );\n return {\n defaultUnit,\n defaultSalesUnit,\n defaultSalesUnitQuantity,\n roundingScale,\n roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit,\n unitPriceBaseQuantity,\n };\n}\n\nfunction buildMetadataPayload(\n values: ProductFormValues,\n): Record<string, unknown> {\n const metadata = normalizeMetadata(values.metadata);\n metadata.__useMarkdown = values.useMarkdown ?? false;\n delete metadata.optionSchema;\n delete metadata.option_schema;\n delete metadata.dimensions;\n delete metadata.weight;\n return metadata;\n}\n\nfunction normalizeOptionSchemaRecord(\n schema: OptionSchemaRecord | null | undefined,\n): CatalogProductOptionSchema | null {\n if (!schema || !Array.isArray(schema.options)) return null;\n return {\n version: typeof schema.version === \"number\" ? schema.version : undefined,\n name: schema.name ?? null,\n description: schema.description ?? null,\n options: schema.options.map((option) => {\n const code = option.code?.trim() || createLocalId();\n const label = option.label?.trim() || code;\n const inputType =\n option.inputType === \"text\" ||\n option.inputType === \"textarea\" ||\n option.inputType === \"number\"\n ? option.inputType\n : \"select\";\n const choices = Array.isArray(option.choices)\n ? option.choices.map((choice) => {\n const choiceCode = choice.code?.trim() || createLocalId();\n const choiceLabel = choice.label?.trim() || choiceCode;\n return { code: choiceCode, label: choiceLabel };\n })\n : [];\n return {\n code,\n label,\n description: option.description ?? undefined,\n inputType,\n choices,\n };\n }),\n };\n}\n\nfunction buildSchemaFromOptions(\n options: ProductOptionInput[],\n name: string,\n): OptionSchemaRecord {\n return {\n version: 1,\n name,\n options: options.map((option) => ({\n code: slugify(option.title || createLocalId()),\n label: option.title,\n inputType: \"select\",\n choices: option.values.map((value) => ({\n code: slugify(value.label || value.id),\n label: value.label,\n })),\n })),\n };\n}\n\nfunction extractOptionsFromTemplate(\n template: OptionSchemaTemplateSummary,\n): ProductOptionInput[] {\n const schema = normalizeOptionSchemaRecord(template?.schema);\n if (!schema) return [];\n return convertSchemaToProductOptions(schema);\n}\n\nfunction OptionSchemaDialog({\n open,\n onOpenChange,\n templates,\n isLoading,\n onSelect,\n onDelete,\n onEdit,\n}: OptionSchemaDialogProps) {\n const t = useT();\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-xl\">\n <DialogHeader>\n <DialogTitle>\n {t(\"catalog.products.edit.schemas.dialogTitle\", \"Option schemas\")}\n </DialogTitle>\n </DialogHeader>\n {isLoading ? (\n <div className=\"py-6\">\n <DataLoader\n isLoading\n loadingMessage={t(\n \"catalog.products.edit.schemas.loading\",\n \"Loading\u2026\",\n )}\n spinnerSize=\"md\"\n >\n <></>\n </DataLoader>\n </div>\n ) : templates.length ? (\n <div className=\"divide-y rounded-md border\">\n {templates.map((template) => {\n const id = typeof template.id === \"string\" ? template.id : null;\n return (\n <div\n key={id ?? template.name ?? createLocalId()}\n className=\"flex items-center justify-between px-4 py-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">\n {template.name ?? template.id ?? \"Schema\"}\n </p>\n {template.description ? (\n <p className=\"text-xs text-muted-foreground\">\n {template.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => onSelect(template)}\n >\n {t(\"catalog.products.edit.schemas.apply\", \"Apply\")}\n </Button>\n {id ? (\n <>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n onClick={() => onEdit(template)}\n >\n <Save className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.edit.schemas.edit\",\n \"Edit schema\",\n )}\n </span>\n </Button>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n onClick={() => void onDelete(id)}\n >\n <Trash2 className=\"h-4 w-4 text-destructive\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.edit.schemas.delete\",\n \"Delete schema\",\n )}\n </span>\n </Button>\n </>\n ) : null}\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"py-4 text-sm text-muted-foreground\">\n {t(\"catalog.products.edit.schemas.empty\", \"No saved schemas yet.\")}\n </p>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n\ntype OptionSchemaDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n templates: OptionSchemaTemplateSummary[];\n isLoading: boolean;\n onSelect: (template: OptionSchemaTemplateSummary | null) => void;\n onDelete: (id: string) => Promise<void> | void;\n onEdit: (template: OptionSchemaTemplateSummary) => void;\n};\n\ntype SaveSchemaDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n defaultName?: string;\n onSubmit: (name: string) => Promise<void>;\n};\n\nfunction SaveSchemaDialog({\n open,\n onOpenChange,\n defaultName = \"\",\n onSubmit,\n}: SaveSchemaDialogProps) {\n const t = useT();\n const [name, setName] = React.useState(defaultName);\n const [saving, setSaving] = React.useState(false);\n\n React.useEffect(() => {\n if (open) setName(defaultName);\n }, [defaultName, open]);\n\n const handleSubmit = React.useCallback(async () => {\n setSaving(true);\n try {\n await onSubmit(name);\n onOpenChange(false);\n } catch (err) {\n console.error(\"schema.save.failed\", err);\n } finally {\n setSaving(false);\n }\n }, [name, onOpenChange, onSubmit]);\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"catalog.products.edit.schemas.saveTitle\", \"Save option schema\")}\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-2\">\n <Label htmlFor=\"schemaName\">\n {t(\"catalog.products.edit.schemas.nameLabel\", \"Schema name\")}\n </Label>\n <Input\n id=\"schemaName\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n placeholder={t(\n \"catalog.products.edit.schemas.namePlaceholder\",\n \"e.g., Color + Size set\",\n )}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n >\n {t(\"common.cancel\", \"Cancel\")}\n </Button>\n <Button type=\"button\" onClick={handleSubmit} disabled={saving}>\n {saving ? t(\"common.saving\", \"Saving\u2026\") : t(\"common.save\", \"Save\")}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport dynamic from \"next/dynamic\";\nimport { useRouter } from \"next/navigation\";\nimport { Page, PageBody } from \"@open-mercato/ui/backend/Page\";\nimport {\n CrudForm,\n type CrudFormGroup,\n type CrudFormGroupComponentProps,\n} from \"@open-mercato/ui/backend/CrudForm\";\nimport {\n updateCrud,\n createCrud,\n deleteCrud,\n} from \"@open-mercato/ui/backend/utils/crud\";\nimport { createCrudFormError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport { collectCustomFieldValues } from \"@open-mercato/ui/backend/utils/customFieldValues\";\nimport { flash } from \"@open-mercato/ui/backend/FlashMessages\";\nimport { Button } from \"@open-mercato/ui/primitives/button\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport { TagsInput } from \"@open-mercato/ui/backend/inputs/TagsInput\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport { DataLoader } from \"@open-mercato/ui/primitives/DataLoader\";\nimport { cn } from \"@open-mercato/shared/lib/utils\";\nimport { Spinner } from \"@open-mercato/ui/primitives/spinner\";\nimport {\n apiCall,\n readApiResultOrThrow,\n} from \"@open-mercato/ui/backend/utils/apiCall\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { useConfirmDialog } from \"@open-mercato/ui/backend/confirm-dialog\";\nimport { E } from \"#generated/entities.ids.generated\";\nimport {\n ProductMediaManager,\n type ProductMediaItem,\n} from \"@open-mercato/core/modules/catalog/components/products/ProductMediaManager\";\nimport {\n fetchOptionSchemaTemplate,\n type OptionSchemaRecord,\n type OptionSchemaTemplateSummary,\n} from \"../optionSchemaClient\";\nimport {\n type ProductFormValues,\n type TaxRateSummary,\n type ProductOptionInput,\n type PriceKindSummary,\n type PriceKindApiPayload,\n type ProductUnitConversionDraft,\n type ProductUnitPriceReferenceUnit,\n type ProductUnitRoundingMode,\n productFormSchema,\n BASE_INITIAL_VALUES,\n createLocalId,\n slugify,\n formatTaxRateLabel,\n buildOptionSchemaDefinition,\n convertSchemaToProductOptions,\n normalizePriceKindSummary,\n buildOptionValuesKey,\n buildVariantCombinations,\n normalizeProductDimensions,\n normalizeProductWeight,\n sanitizeProductDimensions,\n sanitizeProductWeight,\n updateDimensionValue,\n updateWeightValue,\n isConfigurableProductType,\n} from \"@open-mercato/core/modules/catalog/components/products/productForm\";\nimport {\n CATALOG_PRODUCT_TYPES,\n type CatalogProductOptionSchema,\n type CatalogProductType,\n} from \"@open-mercato/core/modules/catalog/data/types\";\nimport { MetadataEditor } from \"@open-mercato/core/modules/catalog/components/products/MetadataEditor\";\nimport {\n buildAttachmentImageUrl,\n slugifyAttachmentFileName,\n} from \"@open-mercato/core/modules/attachments/lib/imageUrls\";\nimport {\n ProductCategorizeSection,\n type ProductCategorizePickerOption,\n} from \"@open-mercato/core/modules/catalog/components/products/ProductCategorizeSection\";\nimport { ProductUomSection } from \"@open-mercato/core/modules/catalog/components/products/ProductUomSection\";\nimport { canonicalizeUnitCode } from \"@open-mercato/core/modules/catalog/lib/unitCodes\";\nimport {\n UNIT_PRICE_REFERENCE_UNITS,\n toTrimmedOrNull,\n parseNumericInput,\n toPositiveNumberOrNull,\n toIntegerInRangeOrDefault,\n normalizeProductConversionInputs,\n type ProductUnitConversionInput,\n} from \"@open-mercato/core/modules/catalog/components/products/productFormUtils\";\nimport {\n AlignLeft,\n BookMarked,\n ExternalLink,\n FileText,\n Layers,\n Plus,\n Save,\n Trash2,\n} from \"lucide-react\";\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"@open-mercato/ui/primitives/dialog\";\nimport { SendObjectMessageDialog } from \"@open-mercato/ui/backend/messages/SendObjectMessageDialog.tsx\";\n\nconst MarkdownEditor = dynamic(() => import(\"@uiw/react-md-editor\"), {\n ssr: false,\n loading: () => (\n <div className=\"flex h-48 items-center justify-center text-sm text-muted-foreground\">\n <Spinner />\n </div>\n ),\n}) as unknown as React.ComponentType<{\n value?: string;\n height?: number;\n onChange?: (value?: string) => void;\n previewOptions?: { remarkPlugins?: unknown[] };\n}>;\n\ntype ProductResponse = {\n items?: Array<Record<string, unknown>>;\n};\n\ntype VariantListResponse = {\n items?: VariantSummaryApi[];\n};\n\ntype VariantSummaryApi = {\n id?: string;\n name?: string | null;\n sku?: string | null;\n is_default?: boolean;\n isDefault?: boolean;\n metadata?: Record<string, unknown> | null;\n};\n\ntype AttachmentListResponse = {\n items?: {\n id: string;\n url: string;\n fileName: string;\n fileSize: number;\n thumbnailUrl?: string | null;\n }[];\n};\n\ntype OptionSchemaTemplateListResponse = {\n items?: OptionSchemaTemplateSummary[];\n};\n\ntype VariantSummary = {\n id: string;\n name: string;\n sku: string;\n isDefault: boolean;\n prices: VariantPriceSummary[];\n optionValues: Record<string, string> | null;\n};\n\ntype VariantPriceListResponse = {\n items?: VariantPriceSummaryApi[];\n};\n\ntype VariantPriceSummaryApi = {\n id?: string;\n variant_id?: string | null;\n variantId?: string | null;\n price_kind_id?: string | null;\n priceKindId?: string | null;\n currency_code?: string | null;\n currencyCode?: string | null;\n unit_price_net?: string | null;\n unitPriceNet?: string | null;\n unit_price_gross?: string | null;\n unitPriceGross?: string | null;\n};\n\ntype VariantPriceSummary = {\n id: string;\n variantId: string;\n priceKindId: string | null;\n currencyCode: string | null;\n amount: string | null;\n displayMode: \"including-tax\" | \"excluding-tax\";\n};\n\ntype OfferSnapshot = {\n id: string | null;\n channelId: string;\n title: string | null;\n description: string | null;\n defaultMediaId: string | null;\n defaultMediaUrl: string | null;\n metadata: Record<string, unknown> | null;\n isActive: boolean;\n channelName: string | null;\n channelCode: string | null;\n};\n\nfunction mapVariantPriceSummary(\n item: VariantPriceSummaryApi | undefined,\n): VariantPriceSummary | null {\n if (!item) return null;\n const getString = (value: unknown): string | null => {\n if (typeof value === \"string\" && value.trim().length) return value.trim();\n if (typeof value === \"number\" || typeof value === \"bigint\")\n return String(value);\n return null;\n };\n const variantId = getString(item.variant_id ?? item.variantId);\n const id = getString(item.id);\n if (!variantId || !id) return null;\n const priceKindId = getString(item.price_kind_id ?? item.priceKindId);\n const currencyCode = getString(item.currency_code ?? item.currencyCode);\n const unitGross = getString(item.unit_price_gross ?? item.unitPriceGross);\n const unitNet = getString(item.unit_price_net ?? item.unitPriceNet);\n const amount = unitGross ?? unitNet ?? null;\n return {\n id,\n variantId,\n priceKindId,\n currencyCode,\n amount,\n displayMode: unitGross ? \"including-tax\" : \"excluding-tax\",\n };\n}\n\nfunction normalizeVariantOptionValues(\n input: unknown,\n): Record<string, string> | null {\n if (!input || typeof input !== \"object\") return null;\n const result: Record<string, string> = {};\n Object.entries(input as Record<string, unknown>).forEach(([key, value]) => {\n if (\n typeof key === \"string\" &&\n typeof value === \"string\" &&\n key.trim().length\n ) {\n result[key] = value;\n }\n });\n return Object.keys(result).length ? result : null;\n}\n\nfunction readProductConversionRows(\n items: Array<Record<string, unknown>> | undefined,\n): ProductUnitConversionDraft[] {\n const rows = Array.isArray(items) ? items : [];\n return rows\n .map((item) => {\n const id = toTrimmedOrNull(item.id);\n const unitCode = canonicalizeUnitCode(item.unit_code ?? item.unitCode);\n const factor = toPositiveNumberOrNull(\n item.to_base_factor ?? item.toBaseFactor,\n );\n if (!unitCode || factor === null) return null;\n const sortOrderRaw = toIntegerInRangeOrDefault(\n item.sort_order ?? item.sortOrder,\n 0,\n 100000,\n 0,\n );\n const isActive =\n typeof item.is_active === \"boolean\"\n ? item.is_active\n : typeof item.isActive === \"boolean\"\n ? item.isActive\n : true;\n return {\n id: id ?? null,\n unitCode,\n toBaseFactor: String(factor),\n sortOrder: String(sortOrderRaw),\n isActive,\n } satisfies ProductUnitConversionDraft;\n })\n .filter((entry): entry is ProductUnitConversionDraft => Boolean(entry));\n}\n\nexport default function EditCatalogProductPage({\n params,\n}: {\n params?: { id?: string };\n}) {\n const productId = params?.id ? String(params.id) : null;\n const t = useT();\n const router = useRouter();\n const [taxRates, setTaxRates] = React.useState<TaxRateSummary[]>([]);\n const [variants, setVariants] = React.useState<VariantSummary[]>([]);\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([]);\n const [initialValues, setInitialValues] =\n React.useState<Partial<ProductFormValues> | null>(null);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n const offerSnapshotsRef = React.useRef<OfferSnapshot[]>([]);\n const initialConversionsRef = React.useRef<ProductUnitConversionDraft[]>([]);\n const [categorizeOptions, setCategorizeOptions] = React.useState<{\n categories: ProductCategorizePickerOption[];\n channels: ProductCategorizePickerOption[];\n tags: ProductCategorizePickerOption[];\n }>({ categories: [], channels: [], tags: [] });\n\n const loadVariants = React.useCallback(async (id: string) => {\n try {\n const [variantsRes, pricesRes] = await Promise.all([\n apiCall<VariantListResponse>(\n `/api/catalog/variants?productId=${encodeURIComponent(id)}&page=1&pageSize=100`,\n ),\n apiCall<VariantPriceListResponse>(\n `/api/catalog/prices?productId=${encodeURIComponent(id)}&page=1&pageSize=100`,\n ),\n ]);\n if (!variantsRes.ok) {\n setVariants([]);\n return;\n }\n const priceMap: Record<string, VariantPriceSummary[]> = {};\n if (pricesRes.ok) {\n const priceItems = Array.isArray(pricesRes.result?.items)\n ? pricesRes.result?.items\n : [];\n for (const item of priceItems) {\n const summary = mapVariantPriceSummary(item);\n if (!summary) continue;\n if (!priceMap[summary.variantId]) {\n priceMap[summary.variantId] = [];\n }\n priceMap[summary.variantId].push(summary);\n }\n Object.keys(priceMap).forEach((key) => {\n priceMap[key].sort((left, right) => {\n const leftKey =\n (left.priceKindId ?? \"\") + (left.currencyCode ?? \"\");\n const rightKey =\n (right.priceKindId ?? \"\") + (right.currencyCode ?? \"\");\n return leftKey.localeCompare(rightKey);\n });\n });\n }\n const items = Array.isArray(variantsRes.result?.items)\n ? variantsRes.result?.items\n : [];\n setVariants(\n items\n .map((variant) => {\n const variantId =\n typeof variant.id === \"string\" ? variant.id : null;\n if (!variantId) return null;\n const variantRecord = variant as Record<string, unknown>;\n const optionValues =\n normalizeVariantOptionValues(variantRecord?.[\"option_values\"]) ??\n normalizeVariantOptionValues(variantRecord?.optionValues);\n return {\n id: variantId,\n name:\n typeof variant.name === \"string\" && variant.name.trim().length\n ? variant.name\n : (variant.sku ?? variantId),\n sku: typeof variant.sku === \"string\" ? variant.sku : \"\",\n isDefault: Boolean(variant.is_default ?? variant.isDefault),\n prices: priceMap[variantId] ?? [],\n optionValues,\n };\n })\n .filter((entry): entry is VariantSummary => Boolean(entry)),\n );\n } catch (err) {\n console.error(\"catalog.variants.fetch failed\", err);\n setVariants([]);\n }\n }, []);\n\n const refreshVariants = React.useCallback(async () => {\n if (!productId) return;\n await loadVariants(productId);\n }, [loadVariants, productId]);\n\n const fetchAttachments = React.useCallback(\n async (id: string): Promise<ProductMediaItem[]> => {\n try {\n const res = await apiCall<AttachmentListResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(id)}`,\n );\n if (!res.ok) return [];\n return (res.result?.items ?? []).map((item) => ({\n id: item.id,\n url: item.url,\n fileName: item.fileName,\n fileSize: item.fileSize,\n thumbnailUrl: item.thumbnailUrl ?? undefined,\n }));\n } catch (err) {\n console.error(\"attachments.fetch failed\", err);\n return [];\n }\n },\n [],\n );\n\n React.useEffect(() => {\n const loadTaxRates = async () => {\n try {\n const payload = await readApiResultOrThrow<{\n items?: Array<Record<string, unknown>>;\n }>(\"/api/sales/tax-rates?pageSize=100\", undefined, {\n errorMessage: t(\n \"catalog.products.create.taxRates.error\",\n \"Failed to load tax rates.\",\n ),\n fallback: { items: [] },\n });\n const items = Array.isArray(payload.items) ? payload.items : [];\n setTaxRates(\n items.map((item) => {\n const rawRate =\n typeof item.rate === \"number\"\n ? item.rate\n : Number(item.rate ?? Number.NaN);\n return {\n id: String(item.id),\n name:\n typeof item.name === \"string\" && item.name.trim().length\n ? item.name\n : t(\n \"catalog.products.create.taxRates.unnamed\",\n \"Untitled tax rate\",\n ),\n code:\n typeof item.code === \"string\" && item.code.trim().length\n ? item.code\n : null,\n rate: Number.isFinite(rawRate) ? rawRate : null,\n isDefault: Boolean(\n typeof item.isDefault === \"boolean\"\n ? item.isDefault\n : typeof item.is_default === \"boolean\"\n ? item.is_default\n : false,\n ),\n };\n }),\n );\n } catch (err) {\n console.error(\"sales.tax-rates.fetch failed\", err);\n setTaxRates([]);\n }\n };\n loadTaxRates().catch(() => {});\n }, [t]);\n\n React.useEffect(() => {\n if (!productId) {\n setLoading(false);\n setError(\n t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n ),\n );\n return;\n }\n let cancelled = false;\n async function loadProduct() {\n setLoading(true);\n setError(null);\n try {\n const productRes = await apiCall<ProductResponse>(\n `/api/catalog/products?id=${encodeURIComponent(productId!)}&page=1&pageSize=1&withDeleted=false`,\n );\n if (!productRes.ok) throw new Error(\"load_failed\");\n const record = Array.isArray(productRes.result?.items)\n ? productRes.result?.items?.[0]\n : undefined;\n if (!record)\n throw new Error(\n t(\"catalog.products.edit.errors.notFound\", \"Product not found.\"),\n );\n const rawMetadata = isRecord(record.metadata)\n ? (record.metadata as Record<string, unknown>)\n : null;\n const dimensions = normalizeProductDimensions(\n record.dimensions ?? rawMetadata?.dimensions ?? null,\n );\n const rawWeightMeta = isRecord(rawMetadata?.weight)\n ? (rawMetadata.weight as Record<string, unknown>)\n : null;\n const weight = normalizeProductWeight({\n value:\n record.weight_value ??\n record.weightValue ??\n rawWeightMeta?.value,\n unit:\n record.weight_unit ??\n record.weightUnit ??\n rawWeightMeta?.unit,\n });\n const metadata = normalizeMetadata(rawMetadata);\n const optionSchemaId =\n typeof record.option_schema_id === \"string\"\n ? record.option_schema_id\n : typeof record.optionSchemaId === \"string\"\n ? record.optionSchemaId\n : null;\n const taxRateId =\n typeof record.tax_rate_id === \"string\"\n ? record.tax_rate_id\n : typeof record.taxRateId === \"string\"\n ? record.taxRateId\n : null;\n const optionSchemaTemplate = optionSchemaId\n ? await fetchOptionSchemaTemplate(optionSchemaId)\n : null;\n const normalizedSchema = normalizeOptionSchemaRecord(\n optionSchemaTemplate?.schema,\n );\n let optionInputs = normalizedSchema\n ? convertSchemaToProductOptions(normalizedSchema)\n : [];\n if (!optionInputs.length) {\n optionInputs = readOptionSchema(metadata);\n }\n const [attachments, conversionsRes] = await Promise.all([\n fetchAttachments(productId!),\n apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/product-unit-conversions?productId=${encodeURIComponent(productId!)}&page=1&pageSize=100`,\n undefined,\n { fallback: { items: [] } },\n ),\n ]);\n const conversionRows = conversionsRes.ok\n ? readProductConversionRows(conversionsRes.result?.items)\n : [];\n initialConversionsRef.current = conversionRows;\n const { customValues } = extractCustomFields(record);\n const offers = readOfferSnapshots(record);\n offerSnapshotsRef.current = offers;\n const channelIds = extractChannelIds(offers);\n const channelOptionEntries = buildChannelOptions(offers);\n const { ids: categoryIds, options: categoryOptions } =\n readCategorySelections(record);\n const { values: tagValues, options: tagOptions } =\n readTagSelections(record);\n const defaultMediaId =\n typeof record.default_media_id === \"string\"\n ? record.default_media_id\n : typeof record.defaultMediaId === \"string\"\n ? record.defaultMediaId\n : null;\n const defaultMediaUrl =\n typeof record.default_media_url === \"string\"\n ? record.default_media_url\n : typeof record.defaultMediaUrl === \"string\"\n ? record.defaultMediaUrl\n : \"\";\n const {\n defaultUnit,\n defaultSalesUnit,\n defaultSalesUnitQuantity,\n roundingScale,\n roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit,\n unitPriceBaseQuantity,\n } = extractUomFields(record);\n const initial: ProductFormValues = {\n title: typeof record.title === \"string\" ? record.title : \"\",\n subtitle: typeof record.subtitle === \"string\" ? record.subtitle : \"\",\n handle: typeof record.handle === \"string\" ? record.handle : \"\",\n sku: typeof record.sku === \"string\" ? record.sku : \"\",\n productType: (\n typeof record.product_type === \"string\"\n ? record.product_type\n : typeof record.productType === \"string\"\n ? record.productType\n : \"simple\"\n ) as CatalogProductType,\n description:\n typeof record.description === \"string\" ? record.description : \"\",\n useMarkdown: Boolean(metadata.__useMarkdown),\n taxRateId,\n mediaDraftId: productId!,\n mediaItems: attachments,\n defaultMediaId,\n defaultMediaUrl,\n hasVariants: Boolean(record.is_configurable ?? record.isConfigurable),\n options: optionInputs,\n optionSchemaId,\n variants: [],\n metadata,\n dimensions: sanitizeProductDimensions(dimensions),\n weight: sanitizeProductWeight(weight),\n defaultUnit: defaultUnit ?? null,\n defaultSalesUnit: defaultSalesUnit ?? defaultUnit ?? null,\n defaultSalesUnitQuantity: String(defaultSalesUnitQuantity ?? 1),\n uomRoundingScale: String(roundingScale),\n uomRoundingMode: roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit:\n unitPriceReferenceUnit &&\n UNIT_PRICE_REFERENCE_UNITS.has(\n unitPriceReferenceUnit as ProductUnitPriceReferenceUnit,\n )\n ? (unitPriceReferenceUnit as ProductUnitPriceReferenceUnit)\n : null,\n unitPriceBaseQuantity:\n unitPriceBaseQuantity === null ? \"\" : String(unitPriceBaseQuantity),\n unitConversions: conversionRows,\n customFieldsetCode:\n typeof record.custom_fieldset_code === \"string\"\n ? record.custom_fieldset_code\n : typeof record.customFieldsetCode === \"string\"\n ? record.customFieldsetCode\n : null,\n categoryIds,\n channelIds,\n tags: tagValues,\n };\n if (!cancelled) {\n setInitialValues({ ...initial, ...customValues });\n setCategorizeOptions({\n categories: categoryOptions,\n channels: channelOptionEntries,\n tags: tagOptions,\n });\n }\n await loadVariants(productId!);\n } catch (err) {\n console.error(\"catalog.products.edit.load failed\", err);\n if (!cancelled) {\n const message =\n err instanceof Error && err.message\n ? err.message\n : t(\n \"catalog.products.edit.errors.load\",\n \"Failed to load product details.\",\n );\n setError(message);\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n loadProduct();\n return () => {\n cancelled = true;\n };\n }, [fetchAttachments, loadVariants, productId, t]);\n\n React.useEffect(() => {\n let cancelled = false;\n async function loadPriceKinds() {\n try {\n const payload = await readApiResultOrThrow<{\n items?: PriceKindApiPayload[];\n }>(\"/api/catalog/price-kinds?pageSize=100\", undefined, {\n fallback: { items: [] },\n });\n const items = Array.isArray(payload.items) ? payload.items : [];\n const summaries = items\n .map((item) => normalizePriceKindSummary(item))\n .filter((entry): entry is PriceKindSummary => !!entry);\n if (!cancelled) {\n setPriceKinds(summaries);\n }\n } catch (err) {\n console.error(\"catalog.price-kinds.fetch failed\", err);\n if (!cancelled) {\n setPriceKinds([]);\n }\n }\n }\n loadPriceKinds().catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n\n const handleVariantDeleted = React.useCallback((variantId: string) => {\n setVariants((prev) => prev.filter((variant) => variant.id !== variantId));\n }, []);\n\n const groups = React.useMemo<CrudFormGroup[]>(\n () => [\n {\n id: \"details\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductDetailsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n productId={productId ?? \"\"}\n />\n ),\n },\n {\n id: \"dimensions\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductDimensionsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"metadata\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductMetadataSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"options\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductOptionsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"product-uom\",\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <ProductUomSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n />\n ),\n },\n {\n id: \"variants\",\n column: 1,\n component: ({ values, setValue, errors }) => (\n <ProductVariantsSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n productId={productId ?? \"\"}\n variants={variants}\n priceKinds={priceKinds}\n onVariantDeleted={handleVariantDeleted}\n onVariantsReload={refreshVariants}\n />\n ),\n },\n {\n id: \"meta\",\n column: 2,\n title: t(\"catalog.products.create.meta.title\", \"Product meta\"),\n description: t(\n \"catalog.products.create.meta.description\",\n \"Manage subtitle and handle for storefronts.\",\n ),\n component: ({ values, setValue, errors }) => (\n <ProductMetaSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n taxRates={taxRates}\n />\n ),\n },\n {\n id: \"categorize\",\n column: 2,\n title: t(\"catalog.products.create.organize.title\", \"Categorize\"),\n description: t(\n \"catalog.products.create.organize.description\",\n \"Assign categories, sales channels, and tags.\",\n ),\n component: ({ values, setValue, errors }) => (\n <ProductCategorizeSection\n values={values as ProductFormValues}\n setValue={setValue}\n errors={errors}\n initialCategoryOptions={categorizeOptions.categories}\n initialChannelOptions={categorizeOptions.channels}\n initialTagOptions={categorizeOptions.tags}\n />\n ),\n },\n {\n id: \"custom-fields\",\n column: 2,\n title: t(\"catalog.products.edit.custom.title\", \"Custom attributes\"),\n kind: \"customFields\",\n },\n ],\n [\n categorizeOptions,\n handleVariantDeleted,\n priceKinds,\n productId,\n refreshVariants,\n t,\n taxRates,\n variants,\n ],\n );\n\n const handleSubmit = React.useCallback(\n async (formValues: ProductFormValues) => {\n const translateValidationMessage = (message: string | null | undefined) => {\n if (typeof message !== \"string\") return \"\";\n const trimmed = message.trim();\n if (!trimmed) return \"\";\n return t(trimmed, trimmed);\n };\n if (!productId) {\n throw createCrudFormError(\n t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n ),\n );\n }\n const parsed = productFormSchema.safeParse(formValues);\n if (!parsed.success) {\n const issues = parsed.error.issues;\n const fieldErrors: Record<string, string> = {};\n issues.forEach((issue) => {\n const path = issue.path.join(\".\") || \"form\";\n if (!fieldErrors[path]) {\n fieldErrors[path] = translateValidationMessage(issue.message);\n }\n });\n const message =\n translateValidationMessage(issues[0]?.message) ||\n t(\n \"catalog.products.edit.errors.validation\",\n \"Fix highlighted fields.\",\n );\n throw createCrudFormError(message, fieldErrors);\n }\n const values: ProductFormValues = {\n ...BASE_INITIAL_VALUES,\n ...parsed.data,\n title: parsed.data.title ?? \"\",\n subtitle: parsed.data.subtitle ?? \"\",\n handle: parsed.data.handle ?? \"\",\n description: parsed.data.description ?? \"\",\n useMarkdown: parsed.data.useMarkdown ?? false,\n taxRateId: parsed.data.taxRateId ?? null,\n mediaDraftId: parsed.data.mediaDraftId ?? productId!,\n mediaItems: Array.isArray(parsed.data.mediaItems)\n ? parsed.data.mediaItems\n : [],\n defaultMediaId: parsed.data.defaultMediaId ?? null,\n defaultMediaUrl: parsed.data.defaultMediaUrl ?? \"\",\n productType: (parsed.data.productType ?? \"simple\") as CatalogProductType,\n hasVariants: parsed.data.hasVariants ?? false,\n options: Array.isArray(parsed.data.options) ? parsed.data.options : [],\n variants: Array.isArray(parsed.data.variants)\n ? parsed.data.variants\n : [],\n metadata: parsed.data.metadata ?? {},\n dimensions: parsed.data.dimensions ?? null,\n weight: parsed.data.weight ?? null,\n defaultUnit: parsed.data.defaultUnit ?? null,\n defaultSalesUnit: parsed.data.defaultSalesUnit ?? null,\n defaultSalesUnitQuantity:\n parsed.data.defaultSalesUnitQuantity?.toString() ?? \"1\",\n uomRoundingScale: parsed.data.uomRoundingScale?.toString() ?? \"4\",\n uomRoundingMode: parsed.data.uomRoundingMode ?? \"half_up\",\n unitPriceEnabled: Boolean(parsed.data.unitPriceEnabled),\n unitPriceReferenceUnit: parsed.data.unitPriceReferenceUnit ?? null,\n unitPriceBaseQuantity:\n parsed.data.unitPriceBaseQuantity?.toString() ?? \"\",\n unitConversions: Array.isArray(parsed.data.unitConversions)\n ? parsed.data.unitConversions.map((entry) => ({\n id: toTrimmedOrNull(entry.id) ?? null,\n unitCode: toTrimmedOrNull(entry.unitCode) ?? \"\",\n toBaseFactor:\n toPositiveNumberOrNull(entry.toBaseFactor) === null\n ? \"\"\n : String(toPositiveNumberOrNull(entry.toBaseFactor)),\n sortOrder:\n typeof entry.sortOrder === \"number\" &&\n Number.isFinite(entry.sortOrder)\n ? String(entry.sortOrder)\n : \"\",\n isActive: entry.isActive !== false,\n }))\n : [],\n customFieldsetCode: parsed.data.customFieldsetCode ?? null,\n categoryIds: parsed.data.categoryIds ?? [],\n channelIds: parsed.data.channelIds ?? [],\n tags: parsed.data.tags ?? [],\n optionSchemaId: parsed.data.optionSchemaId ?? null,\n };\n const title = values.title?.trim();\n if (!title) {\n const message = t(\n \"catalog.products.create.errors.title\",\n \"Provide a product title.\",\n );\n throw createCrudFormError(message, { title: message });\n }\n const handle = values.handle?.trim() || undefined;\n const description = values.description?.trim() || undefined;\n const metadata = buildMetadataPayload(values);\n const dimensions = sanitizeProductDimensions(values.dimensions ?? null);\n const weight = sanitizeProductWeight(values.weight ?? null);\n const resolveTaxRateValue = (taxRateId?: string | null) => {\n if (!taxRateId) return null;\n const match = taxRates.find((rate) => rate.id === taxRateId);\n return typeof match?.rate === \"number\" && Number.isFinite(match.rate)\n ? match.rate\n : null;\n };\n const productTaxRateValue = resolveTaxRateValue(values.taxRateId ?? null);\n const defaultMediaId =\n typeof values.defaultMediaId === \"string\" &&\n values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : null;\n const defaultMediaEntry = defaultMediaId\n ? values.mediaItems.find((item) => item.id === defaultMediaId)\n : null;\n const defaultMediaUrl = defaultMediaEntry\n ? buildAttachmentImageUrl(defaultMediaEntry.id, {\n slug: slugifyAttachmentFileName(defaultMediaEntry.fileName),\n })\n : null;\n const defaultUnit = canonicalizeUnitCode(values.defaultUnit);\n const defaultSalesUnit = canonicalizeUnitCode(values.defaultSalesUnit);\n const defaultSalesUnitQuantity =\n toPositiveNumberOrNull(values.defaultSalesUnitQuantity) ?? 1;\n const uomRoundingScale = toIntegerInRangeOrDefault(\n values.uomRoundingScale,\n 0,\n 6,\n 4,\n );\n const uomRoundingMode: ProductUnitRoundingMode =\n values.uomRoundingMode === \"down\" || values.uomRoundingMode === \"up\"\n ? values.uomRoundingMode\n : \"half_up\";\n const unitPriceEnabled = Boolean(values.unitPriceEnabled);\n const unitPriceReferenceUnit = canonicalizeUnitCode(\n values.unitPriceReferenceUnit,\n );\n const unitPriceBaseQuantity = toPositiveNumberOrNull(\n values.unitPriceBaseQuantity,\n );\n if (defaultSalesUnit && !defaultUnit) {\n const message = t(\n \"catalog.products.uom.errors.baseRequired\",\n \"Base unit is required when default sales unit is set.\",\n );\n throw createCrudFormError(message, { defaultSalesUnit: message });\n }\n const conversionInputs = normalizeProductConversionInputs(\n values.unitConversions,\n t(\n \"catalog.products.uom.errors.duplicateConversion\",\n \"Duplicate conversion unit is not allowed.\",\n ),\n );\n if (conversionInputs.length && !defaultUnit) {\n const message = t(\n \"catalog.products.uom.errors.baseRequiredForConversions\",\n \"Base unit is required when conversions are configured.\",\n );\n throw createCrudFormError(message, { defaultUnit: message });\n }\n const defaultUnitKey = defaultUnit?.toLowerCase() ?? null;\n const defaultSalesUnitKey = defaultSalesUnit?.toLowerCase() ?? null;\n if (\n defaultUnitKey &&\n defaultSalesUnitKey &&\n defaultSalesUnitKey !== defaultUnitKey\n ) {\n const hasDefaultSalesConversion = conversionInputs.some(\n (entry) =>\n entry.isActive &&\n entry.unitCode.toLowerCase() === defaultSalesUnitKey,\n );\n if (!hasDefaultSalesConversion) {\n const message = t(\n \"catalog.products.uom.errors.defaultSalesConversionRequired\",\n \"Active conversion for default sales unit is required when it differs from base unit.\",\n );\n throw createCrudFormError(message, {\n defaultSalesUnit: message,\n unitConversions: message,\n });\n }\n }\n if (unitPriceEnabled) {\n if (\n !unitPriceReferenceUnit ||\n !UNIT_PRICE_REFERENCE_UNITS.has(\n unitPriceReferenceUnit as ProductUnitPriceReferenceUnit,\n )\n ) {\n const message = t(\n \"catalog.products.unitPrice.errors.referenceUnit\",\n \"Reference unit is required when unit price display is enabled.\",\n );\n throw createCrudFormError(message, {\n unitPriceReferenceUnit: message,\n });\n }\n if (unitPriceBaseQuantity === null) {\n const message = t(\n \"catalog.products.unitPrice.errors.baseQuantity\",\n \"Base quantity is required when unit price display is enabled.\",\n );\n throw createCrudFormError(message, {\n unitPriceBaseQuantity: message,\n });\n }\n }\n const payload: Record<string, unknown> = {\n id: productId,\n title,\n subtitle: values.subtitle?.trim() || undefined,\n description,\n handle,\n sku: values.sku?.trim() || null,\n productType: values.productType || \"simple\",\n taxRateId: values.taxRateId ?? null,\n taxRate: productTaxRateValue ?? null,\n isConfigurable: isConfigurableProductType(\n values.productType || \"simple\",\n ),\n metadata,\n dimensions,\n weightValue: weight?.value ?? null,\n weightUnit: weight?.unit ?? null,\n defaultMediaId: defaultMediaId ?? undefined,\n defaultMediaUrl: defaultMediaUrl ?? undefined,\n defaultUnit: defaultUnit ?? null,\n defaultSalesUnit: defaultSalesUnit ?? defaultUnit ?? null,\n defaultSalesUnitQuantity,\n uomRoundingScale,\n uomRoundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit: unitPriceEnabled\n ? unitPriceReferenceUnit\n : undefined,\n unitPriceBaseQuantity: unitPriceEnabled\n ? unitPriceBaseQuantity\n : undefined,\n customFieldsetCode: values.customFieldsetCode?.trim().length\n ? values.customFieldsetCode\n : undefined,\n };\n const categoryIds = normalizeIdList(values.categoryIds);\n const channelIds = normalizeIdList(values.channelIds);\n const tags = normalizeTagValues(values.tags);\n payload.categoryIds = categoryIds;\n payload.tags = tags;\n const optionSchemaDefinition = buildOptionSchemaDefinition(\n values.options,\n title,\n );\n if (optionSchemaDefinition) {\n payload.optionSchema = optionSchemaDefinition;\n } else if (values.optionSchemaId) {\n payload.optionSchemaId = null;\n }\n const customFields = collectCustomFieldValues(values);\n if (Object.keys(customFields).length) {\n payload.customFields = customFields;\n }\n const previousSnapshots = offerSnapshotsRef.current;\n const offersPayload = buildOfferPayloads({\n channelIds,\n offerSnapshots: previousSnapshots,\n fallback: {\n title,\n description: description ?? undefined,\n defaultMediaId,\n defaultMediaUrl: defaultMediaUrl ?? undefined,\n },\n });\n payload.offers = offersPayload;\n const removedOffers = previousSnapshots.filter(\n (offer) =>\n typeof offer.id === \"string\" && !channelIds.includes(offer.channelId),\n );\n if (removedOffers.length) {\n try {\n for (const offer of removedOffers) {\n if (!offer.id) continue;\n await deleteCrud(\"catalog/offers\", offer.id, {\n errorMessage: t(\n \"catalog.products.edit.offers.deleteError\",\n \"Failed to remove sales channel offer.\",\n ),\n });\n }\n } catch (err) {\n console.error(\"catalog.products.edit.offers.delete\", err);\n throw createCrudFormError(\n t(\n \"catalog.products.edit.offers.deleteError\",\n \"Failed to remove sales channel offer.\",\n ),\n );\n }\n }\n await updateCrud(\"catalog/products\", payload);\n const previousConversionIds = new Set(\n initialConversionsRef.current\n .map((entry) => toTrimmedOrNull(entry.id))\n .filter((id): id is string => Boolean(id)),\n );\n const nextConversionIds = new Set(\n conversionInputs\n .map((entry) =>\n entry.id && entry.id.trim().length ? entry.id : null,\n )\n .filter((id): id is string => Boolean(id)),\n );\n const removedConversionIds = Array.from(previousConversionIds).filter(\n (id) => !nextConversionIds.has(id),\n );\n for (const conversionId of removedConversionIds) {\n await deleteCrud(\"catalog/product-unit-conversions\", conversionId, {\n errorMessage: t(\n \"catalog.products.uom.errors.sync\",\n \"Failed to synchronize product conversions.\",\n ),\n });\n }\n const persistedConversions: ProductUnitConversionDraft[] = [];\n for (const conversion of conversionInputs) {\n if (conversion.id) {\n await updateCrud(\"catalog/product-unit-conversions\", {\n id: conversion.id,\n unitCode: conversion.unitCode,\n toBaseFactor: conversion.toBaseFactor,\n sortOrder: conversion.sortOrder,\n isActive: conversion.isActive,\n });\n persistedConversions.push({\n id: conversion.id,\n unitCode: conversion.unitCode,\n toBaseFactor: String(conversion.toBaseFactor),\n sortOrder: String(conversion.sortOrder),\n isActive: conversion.isActive,\n });\n continue;\n }\n const created = await createCrud<{ id?: string }>(\n \"catalog/product-unit-conversions\",\n {\n productId,\n unitCode: conversion.unitCode,\n toBaseFactor: conversion.toBaseFactor,\n sortOrder: conversion.sortOrder,\n isActive: conversion.isActive,\n },\n );\n const createdId =\n created.result &&\n typeof created.result === \"object\" &&\n typeof (created.result as { id?: unknown }).id === \"string\"\n ? (created.result as { id: string }).id\n : null;\n persistedConversions.push({\n id: createdId,\n unitCode: conversion.unitCode,\n toBaseFactor: String(conversion.toBaseFactor),\n sortOrder: String(conversion.sortOrder),\n isActive: conversion.isActive,\n });\n }\n initialConversionsRef.current = persistedConversions;\n offerSnapshotsRef.current = mergeOfferSnapshots(\n previousSnapshots,\n offersPayload,\n );\n flash(t(\"catalog.products.edit.success\", \"Product updated.\"), \"success\");\n router.push(\"/backend/catalog/products\");\n },\n [productId, t, taxRates, router],\n );\n\n if (!productId) {\n return (\n <Page>\n <PageBody>\n <div className=\"rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {t(\n \"catalog.products.edit.errors.idMissing\",\n \"Product identifier is missing.\",\n )}\n </div>\n </PageBody>\n </Page>\n );\n }\n\n return (\n <Page>\n <PageBody>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<ProductFormValues>\n title={t(\"catalog.products.edit.title\", \"Edit product\")}\n backHref=\"/backend/catalog/products\"\n versionHistory={{\n resourceKind: \"catalog.product\",\n resourceId: productId ? String(productId) : \"\",\n }}\n extraActions={productId ? (\n <SendObjectMessageDialog\n object={{\n entityModule: \"catalog\",\n entityType: \"product\",\n entityId: productId,\n previewData: {\n title: initialValues?.title ?? productId,\n }\n }}\n viewHref={`/backend/catalog/products/${productId}/edit`}\n />\n ) : undefined}\n fields={[]}\n groups={groups}\n injectionSpotId=\"crud-form:catalog.product\"\n entityId={E.catalog.catalog_product}\n customFieldsetBindings={{\n [E.catalog.catalog_product]: { valueKey: \"customFieldsetCode\" },\n }}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t(\"catalog.products.edit.loading\", \"Loading product\")}\n submitLabel={t(\"catalog.products.edit.save\", \"Save changes\")}\n cancelHref=\"/backend/catalog/products\"\n onSubmit={handleSubmit}\n />\n </PageBody>\n </Page>\n );\n}\n\ntype ProductFormGroupProps = CrudFormGroupComponentProps & {\n values: ProductFormValues;\n};\n\ntype ProductDetailsSectionProps = ProductFormGroupProps & { productId: string };\n\ntype ProductMetaSectionProps = ProductFormGroupProps & {\n taxRates: TaxRateSummary[];\n};\n\ntype ProductVariantsSectionProps = Omit<\n CrudFormGroupComponentProps,\n \"values\"\n> & {\n values: ProductFormValues;\n productId: string;\n variants: VariantSummary[];\n priceKinds: PriceKindSummary[];\n onVariantDeleted: (variantId: string) => void;\n onVariantsReload?: () => Promise<void> | void;\n};\n\ntype ProductDimensionsSectionProps = ProductFormGroupProps;\n\nfunction ProductDetailsSection({\n values,\n setValue,\n errors,\n productId,\n}: ProductDetailsSectionProps) {\n const t = useT();\n const mediaItems = React.useMemo(\n () => (Array.isArray(values.mediaItems) ? values.mediaItems : []),\n [values.mediaItems],\n );\n\n const handleMediaItemsChange = React.useCallback(\n (nextItems: ProductMediaItem[]) => {\n setValue(\"mediaItems\", nextItems);\n const hasCurrent = nextItems.some(\n (item) => item.id === values.defaultMediaId,\n );\n if (!hasCurrent) {\n const fallbackId = nextItems[0]?.id ?? null;\n setValue(\"defaultMediaId\", fallbackId);\n if (fallbackId && nextItems[0]) {\n setValue(\n \"defaultMediaUrl\",\n buildAttachmentImageUrl(fallbackId, {\n slug: slugifyAttachmentFileName(nextItems[0].fileName),\n }),\n );\n } else {\n setValue(\"defaultMediaUrl\", \"\");\n }\n }\n },\n [setValue, values.defaultMediaId],\n );\n\n const handleDefaultMediaChange = React.useCallback(\n (attachmentId: string | null) => {\n setValue(\"defaultMediaId\", attachmentId);\n if (!attachmentId) {\n setValue(\"defaultMediaUrl\", \"\");\n return;\n }\n const target = mediaItems.find((item) => item.id === attachmentId);\n if (target) {\n setValue(\n \"defaultMediaUrl\",\n buildAttachmentImageUrl(target.id, {\n slug: slugifyAttachmentFileName(target.fileName),\n }),\n );\n }\n },\n [mediaItems, setValue],\n );\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <Label className=\"flex items-center gap-1\">\n {t(\"catalog.products.form.title\", \"Title\")}\n <span className=\"text-red-600\">*</span>\n </Label>\n <Input\n value={values.title}\n onChange={(event) => setValue(\"title\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.title\",\n \"e.g., Summer sneaker\",\n )}\n />\n {errors.title ? (\n <p className=\"text-xs text-red-600\">{errors.title}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Label>{t(\"catalog.products.form.description\", \"Description\")}</Label>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setValue(\"useMarkdown\", !values.useMarkdown)}\n className=\"gap-2 text-xs\"\n >\n {values.useMarkdown ? (\n <AlignLeft className=\"h-4 w-4\" />\n ) : (\n <FileText className=\"h-4 w-4\" />\n )}\n {values.useMarkdown\n ? t(\"catalog.products.create.actions.usePlain\", \"Use plain text\")\n : t(\n \"catalog.products.create.actions.useMarkdown\",\n \"Use markdown\",\n )}\n </Button>\n </div>\n {values.useMarkdown ? (\n <div\n data-color-mode=\"light\"\n className=\"overflow-hidden rounded-md border\"\n >\n <MarkdownEditor\n value={values.description}\n height={260}\n onChange={(val) => setValue(\"description\", val ?? \"\")}\n previewOptions={{ remarkPlugins: [] }}\n />\n </div>\n ) : (\n <Textarea\n className=\"min-h-[180px]\"\n value={values.description}\n onChange={(event) => setValue(\"description\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.description\",\n \"Describe the product...\",\n )}\n />\n )}\n </div>\n\n <ProductMediaManager\n entityId={E.catalog.catalog_product}\n draftRecordId={values.mediaDraftId || productId}\n items={mediaItems}\n defaultMediaId={values.defaultMediaId ?? null}\n onItemsChange={handleMediaItemsChange}\n onDefaultChange={handleDefaultMediaChange}\n />\n </div>\n );\n}\n\nfunction ProductDimensionsSection({\n values,\n setValue,\n}: ProductDimensionsSectionProps) {\n const t = useT();\n const dimensionValues = normalizeProductDimensions(values.dimensions);\n const weightValues = normalizeProductWeight(values.weight);\n\n return (\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.edit.dimensions\", \"Dimensions & weight\")}\n </h3>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.width\", \"Width\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.width ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"width\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.height\", \"Height\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.height ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"height\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.depth\", \"Depth\")}\n </Label>\n <Input\n type=\"number\"\n value={dimensionValues?.depth ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"depth\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.dimensions.unit\", \"Size unit\")}\n </Label>\n <Input\n value={dimensionValues?.unit ?? \"\"}\n onChange={(event) =>\n setValue(\n \"dimensions\",\n updateDimensionValue(\n values.dimensions ?? null,\n \"unit\",\n event.target.value,\n ),\n )\n }\n placeholder=\"cm\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.weight.value\", \"Weight\")}\n </Label>\n <Input\n type=\"number\"\n value={weightValues?.value ?? \"\"}\n onChange={(event) =>\n setValue(\n \"weight\",\n updateWeightValue(\n values.weight ?? null,\n \"value\",\n event.target.value,\n ),\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.edit.weight.unit\", \"Weight unit\")}\n </Label>\n <Input\n value={weightValues?.unit ?? \"\"}\n onChange={(event) =>\n setValue(\n \"weight\",\n updateWeightValue(\n values.weight ?? null,\n \"unit\",\n event.target.value,\n ),\n )\n }\n placeholder=\"kg\"\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction ProductMetadataSection({ values, setValue }: ProductFormGroupProps) {\n const metadata = normalizeMetadata(values.metadata);\n const handleMetadataChange = React.useCallback(\n (next: Record<string, unknown>) => {\n setValue(\"metadata\", next);\n },\n [setValue],\n );\n\n return (\n <MetadataEditor value={metadata} onChange={handleMetadataChange} embedded />\n );\n}\n\nfunction ProductOptionsSection({ values, setValue }: ProductFormGroupProps) {\n const t = useT();\n const [schemaDialogOpen, setSchemaDialogOpen] = React.useState(false);\n const [schemaTemplates, setSchemaTemplates] = React.useState<\n OptionSchemaTemplateSummary[]\n >([]);\n const [schemaLoading, setSchemaLoading] = React.useState(false);\n const [saveSchemaOpen, setSaveSchemaOpen] = React.useState(false);\n const [schemaToEdit, setSchemaToEdit] =\n React.useState<OptionSchemaTemplateSummary | null>(null);\n\n const loadSchemas = React.useCallback(async () => {\n setSchemaLoading(true);\n try {\n const res = await apiCall<OptionSchemaTemplateListResponse>(\n \"/api/catalog/option-schemas?page=1&pageSize=100\",\n );\n if (res.ok) {\n setSchemaTemplates(\n Array.isArray(res.result?.items) ? (res.result?.items ?? []) : [],\n );\n } else {\n setSchemaTemplates([]);\n }\n } catch (err) {\n console.error(\"catalog.option-schemas.list failed\", err);\n setSchemaTemplates([]);\n } finally {\n setSchemaLoading(false);\n }\n }, []);\n\n const handleDeleteSchema = React.useCallback(\n async (id: string) => {\n try {\n await deleteCrud(\"catalog/option-schemas\", id, {\n errorMessage: t(\n \"catalog.products.edit.schemas.deleteError\",\n \"Failed to delete schema.\",\n ),\n });\n flash(\n t(\"catalog.products.edit.schemas.deleted\", \"Schema deleted.\"),\n \"success\",\n );\n void loadSchemas();\n } catch (err) {\n console.error(\"catalog.option-schemas.delete failed\", err);\n }\n },\n [loadSchemas, t],\n );\n\n const handleSaveSchema = React.useCallback(\n async (name: string) => {\n if (!name.trim().length) {\n const message = t(\n \"catalog.products.edit.schemas.nameRequired\",\n \"Provide a schema name.\",\n );\n throw createCrudFormError(message, { name: message });\n }\n const schemaPayload = buildSchemaFromOptions(\n Array.isArray(values.options) ? values.options : [],\n name,\n );\n if (!schemaPayload.options?.length) {\n throw createCrudFormError(\n t(\n \"catalog.products.edit.schemas.empty\",\n \"Add at least one option before saving.\",\n ),\n {},\n );\n }\n const payload: Record<string, unknown> = {\n name: name.trim(),\n code: slugify(name.trim()),\n schema: schemaPayload,\n isActive: true,\n };\n if (schemaToEdit?.id) payload.id = schemaToEdit.id;\n if (schemaToEdit?.id) await updateCrud(\"catalog/option-schemas\", payload);\n else await createCrud(\"catalog/option-schemas\", payload);\n flash(\n t(\"catalog.products.edit.schemas.saved\", \"Schema saved.\"),\n \"success\",\n );\n setSaveSchemaOpen(false);\n setSchemaToEdit(null);\n void loadSchemas();\n },\n [schemaToEdit, t, values.options, loadSchemas],\n );\n\n const handleOptionTitleChange = React.useCallback(\n (optionId: string, nextTitle: string) => {\n const next = (Array.isArray(values.options) ? values.options : []).map(\n (option) =>\n option.id === optionId ? { ...option, title: nextTitle } : option,\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n const setOptionValues = React.useCallback(\n (optionId: string, labels: string[]) => {\n const normalized = labels\n .map((label) => label.trim())\n .filter((label) => label.length);\n const unique = Array.from(new Set(normalized));\n const next = (Array.isArray(values.options) ? values.options : []).map(\n (option) => {\n if (option.id !== optionId) return option;\n const existingByLabel = new Map(\n option.values.map((value) => [value.label, value]),\n );\n const nextValues = unique.map(\n (label) =>\n existingByLabel.get(label) ?? { id: createLocalId(), label },\n );\n return {\n ...option,\n values: nextValues,\n };\n },\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n const addOption = React.useCallback(() => {\n const next = [\n ...(Array.isArray(values.options) ? values.options : []),\n { id: createLocalId(), title: \"\", values: [] },\n ];\n setValue(\"options\", next);\n }, [setValue, values.options]);\n\n const removeOption = React.useCallback(\n (optionId: string) => {\n const next = (Array.isArray(values.options) ? values.options : []).filter(\n (option) => option.id !== optionId,\n );\n setValue(\"options\", next);\n },\n [setValue, values.options],\n );\n\n return (\n <>\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">\n {t(\n \"catalog.products.create.optionsBuilder.title\",\n \"Product options\",\n )}\n </h3>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setSchemaDialogOpen(true);\n void loadSchemas();\n }}\n title={t(\n \"catalog.products.edit.schemas.manage\",\n \"Open schema library\",\n )}\n >\n <BookMarked className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n setSchemaToEdit(null);\n setSaveSchemaOpen(true);\n }}\n title={t(\"catalog.products.edit.schemas.save\", \"Save as schema\")}\n >\n <Save className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={addOption}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {t(\"catalog.products.create.optionsBuilder.add\", \"Add option\")}\n </Button>\n </div>\n </div>\n {(Array.isArray(values.options) ? values.options : []).map((option) => (\n <div key={option.id} className=\"rounded-md bg-muted/40 p-4\">\n <div className=\"flex items-center gap-2\">\n <Input\n value={option.title}\n onChange={(event) =>\n handleOptionTitleChange(option.id, event.target.value)\n }\n placeholder={t(\n \"catalog.products.create.optionsBuilder.placeholder\",\n \"e.g., Color\",\n )}\n className=\"flex-1\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n onClick={() => removeOption(option.id)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n <div className=\"mt-3 space-y-2\">\n <Label className=\"text-xs uppercase text-muted-foreground\">\n {t(\"catalog.products.create.optionsBuilder.values\", \"Values\")}\n </Label>\n <TagsInput\n value={option.values.map((value) => value.label)}\n onChange={(labels) => setOptionValues(option.id, labels)}\n placeholder={t(\n \"catalog.products.create.optionsBuilder.valuePlaceholder\",\n \"Type a value and press Enter\",\n )}\n />\n </div>\n </div>\n ))}\n {!values.options?.length ? (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n \"catalog.products.create.optionsBuilder.empty\",\n \"No options yet. Add your first option to generate variants.\",\n )}\n </p>\n ) : null}\n </div>\n\n <OptionSchemaDialog\n open={schemaDialogOpen}\n onOpenChange={(next) => {\n setSchemaDialogOpen(next);\n if (next) void loadSchemas();\n }}\n isLoading={schemaLoading}\n templates={schemaTemplates}\n onSelect={(template) => {\n setSchemaDialogOpen(false);\n if (!template) return;\n const options = extractOptionsFromTemplate(template);\n setValue(\"options\", options);\n }}\n onDelete={handleDeleteSchema}\n onEdit={(template) => {\n setSchemaToEdit(template);\n setSaveSchemaOpen(true);\n }}\n />\n\n <SaveSchemaDialog\n open={saveSchemaOpen}\n onOpenChange={(next) => {\n setSaveSchemaOpen(next);\n if (!next) setSchemaToEdit(null);\n }}\n defaultName={schemaToEdit?.name ?? \"\"}\n onSubmit={handleSaveSchema}\n />\n </>\n );\n}\n\nfunction ProductVariantsSection({\n values,\n productId,\n variants,\n priceKinds,\n onVariantDeleted,\n onVariantsReload,\n}: ProductVariantsSectionProps) {\n const t = useT();\n const { confirm, ConfirmDialogElement } = useConfirmDialog();\n const [deletingId, setDeletingId] = React.useState<string | null>(null);\n const [generating, setGenerating] = React.useState(false);\n const [checkingVariantFeature, setCheckingVariantFeature] =\n React.useState(true);\n const [canManageVariants, setCanManageVariants] = React.useState(false);\n const optionDefinitions = React.useMemo(\n () => (Array.isArray(values.options) ? values.options : []),\n [values.options],\n );\n const combos = React.useMemo(\n () => buildVariantCombinations(optionDefinitions),\n [optionDefinitions],\n );\n const existingKeys = React.useMemo(() => {\n const set = new Set<string>();\n variants.forEach((variant) => {\n const key = buildOptionValuesKey(variant.optionValues ?? undefined);\n if (key) set.add(key);\n });\n return set;\n }, [variants]);\n const missingCombos = React.useMemo(\n () =>\n combos.filter((combo) => {\n const key = buildOptionValuesKey(combo);\n if (!key) return false;\n return !existingKeys.has(key);\n }),\n [combos, existingKeys],\n );\n const priceKindLookup = React.useMemo(() => {\n const map = new Map<string, PriceKindSummary>();\n for (const kind of priceKinds) {\n map.set(kind.id, kind);\n }\n return map;\n }, [priceKinds]);\n React.useEffect(() => {\n let cancelled = false;\n async function checkVariantFeature() {\n try {\n const payload = await readApiResultOrThrow<{\n ok?: boolean;\n granted?: unknown;\n }>(\n \"/api/auth/feature-check\",\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ features: [\"catalog.variants.manage\"] }),\n },\n { allowNullResult: true },\n );\n if (cancelled) return;\n const sourceGranted = Array.isArray(payload?.granted)\n ? payload?.granted\n : [];\n const granted = (sourceGranted as unknown[]).filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.length > 0,\n );\n const hasFeature =\n payload?.ok === true || granted.includes(\"catalog.variants.manage\");\n setCanManageVariants(hasFeature);\n } catch {\n if (!cancelled) setCanManageVariants(false);\n } finally {\n if (!cancelled) setCheckingVariantFeature(false);\n }\n }\n checkVariantFeature().catch(() => {});\n return () => {\n cancelled = true;\n };\n }, []);\n const allowVariantActions = canManageVariants && !checkingVariantFeature;\n const formatPriceLabel = React.useCallback(\n (price: VariantPriceSummary): string => {\n const kind = price.priceKindId\n ? priceKindLookup.get(price.priceKindId)\n : null;\n if (kind?.title) return kind.title;\n if (kind?.code) return kind.code.toUpperCase();\n return t(\"catalog.products.edit.variantList.priceFallback\", \"Price\");\n },\n [priceKindLookup, t],\n );\n const formatPriceAmount = React.useCallback(\n (price: VariantPriceSummary): string => {\n const amount =\n typeof price.amount === \"string\" && price.amount.trim().length\n ? price.amount.trim()\n : \"\";\n if (!amount) return \"\u2014\";\n if (!price.currencyCode) return amount;\n return `${price.currencyCode.toUpperCase()} ${amount}`;\n },\n [],\n );\n const handleDeleteVariant = React.useCallback(\n async (variant: VariantSummary) => {\n if (!allowVariantActions) return;\n const label = variant.name || variant.sku || variant.id;\n const confirmMessage = t(\n \"catalog.products.edit.variantList.deleteConfirm\",\n 'Delete variant \"{{name}}\"?',\n ).replace(\"{{name}}\", label);\n const confirmed = await confirm({\n title: confirmMessage,\n variant: \"destructive\",\n });\n if (!confirmed) return;\n setDeletingId(variant.id);\n try {\n await deleteCrud(\"catalog/variants\", variant.id, {\n errorMessage: t(\n \"catalog.variants.form.deleteError\",\n \"Failed to delete variant.\",\n ),\n });\n flash(\n t(\"catalog.variants.form.deleted\", \"Variant deleted.\"),\n \"success\",\n );\n onVariantDeleted(variant.id);\n } catch (err) {\n console.error(\"catalog.products.edit.variants.delete\", err);\n flash(\n t(\"catalog.variants.form.deleteError\", \"Failed to delete variant.\"),\n \"error\",\n );\n } finally {\n setDeletingId(null);\n }\n },\n [allowVariantActions, confirm, onVariantDeleted, t],\n );\n const handleGenerateVariants = React.useCallback(async () => {\n if (!productId || !allowVariantActions) return;\n if (!missingCombos.length) {\n flash(\n t(\n \"catalog.products.edit.variantList.generateEmpty\",\n \"All option combinations already exist.\",\n ),\n \"info\",\n );\n return;\n }\n setGenerating(true);\n try {\n for (const combo of missingCombos) {\n const title =\n Object.values(combo)\n .map((value) => value?.trim())\n .filter((value) => value && value.length)\n .join(\" / \") ||\n t(\"catalog.products.edit.variantList.defaultTitle\", \"Variant\");\n await createCrud(\"catalog/variants\", {\n productId,\n name: title,\n optionValues: combo,\n isDefault: false,\n isActive: true,\n });\n }\n flash(\n t(\n \"catalog.products.edit.variantList.generateSuccess\",\n \"Missing variants generated.\",\n ),\n \"success\",\n );\n if (onVariantsReload) await onVariantsReload();\n } catch (err) {\n console.error(\"catalog.products.edit.variantList.generate\", err);\n flash(\n t(\n \"catalog.products.edit.variantList.generateError\",\n \"Failed to generate variants.\",\n ),\n \"error\",\n );\n } finally {\n setGenerating(false);\n }\n }, [allowVariantActions, missingCombos, onVariantsReload, productId, t]);\n\n const showGenerateButton =\n optionDefinitions.length > 0 && allowVariantActions;\n\n return (\n <>\n <div className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <h3 id=\"variants\" className=\"text-sm font-semibold\">\n {t(\"catalog.products.edit.variants\", \"Variants\")}\n </h3>\n <div className=\"flex flex-wrap items-center gap-2\">\n {showGenerateButton ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={generating}\n onClick={() => {\n void handleGenerateVariants();\n }}\n >\n {generating\n ? t(\n \"catalog.products.edit.variantList.generating\",\n \"Generating\u2026\",\n )\n : t(\n \"catalog.products.edit.variantList.generate\",\n \"Generate variants\",\n )}\n </Button>\n ) : null}\n {allowVariantActions ? (\n <Button asChild size=\"sm\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/create`}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {t(\"catalog.products.edit.variants.add\", \"Add variant\")}\n </Link>\n </Button>\n ) : null}\n </div>\n </div>\n {variants.length ? (\n <div className=\"overflow-x-auto rounded-md border\">\n <table className=\"w-full table-auto text-sm\">\n <thead className=\"bg-muted/40 text-left text-xs uppercase text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 font-normal\">\n {t(\"catalog.products.form.variants\", \"Variant\")}\n </th>\n <th className=\"px-3 py-2 font-normal\">SKU</th>\n <th className=\"px-3 py-2 font-normal\">\n {t(\n \"catalog.products.edit.variantList.pricesHeading\",\n \"Prices\",\n )}\n </th>\n <th className=\"px-3 py-2 font-normal\">\n {t(\"catalog.products.edit.variants.default\", \"Default\")}\n </th>\n <th className=\"px-3 py-2 font-normal text-right\">\n {t(\"catalog.products.edit.variantList.actions\", \"Actions\")}\n </th>\n </tr>\n </thead>\n <tbody>\n {variants.map((variant) => (\n <tr key={variant.id} className=\"border-t hover:bg-muted/40\">\n <td className=\"px-3 py-2\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/${variant.id}`}\n className=\"text-sm font-medium hover:underline\"\n >\n {variant.name || variant.id}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {variant.sku || \"\u2014\"}\n </td>\n <td className=\"px-3 py-2\">\n {variant.prices.length ? (\n <ul className=\"space-y-1\">\n {variant.prices.map((price) => (\n <li\n key={price.id}\n className=\"text-xs text-muted-foreground\"\n >\n <span className=\"font-medium text-foreground\">\n {formatPriceLabel(price)}\n </span>{\" \"}\n <span>{formatPriceAmount(price)}</span>\n </li>\n ))}\n </ul>\n ) : (\n <span className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.edit.variantList.pricesEmpty\",\n \"No prices yet.\",\n )}\n </span>\n )}\n </td>\n <td className=\"px-3 py-2 text-muted-foreground\">\n {variant.isDefault ? t(\"common.yes\", \"Yes\") : \"\u2014\"}\n </td>\n <td className=\"px-3 py-2\">\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button asChild size=\"sm\" variant=\"outline\">\n <Link\n href={`/backend/catalog/products/${productId}/variants/${variant.id}`}\n >\n {t(\"catalog.products.list.actions.edit\", \"Edit\")}\n </Link>\n </Button>\n {allowVariantActions ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"text-destructive hover:text-destructive\"\n disabled={deletingId === variant.id}\n onClick={() => {\n void handleDeleteVariant(variant);\n }}\n >\n {deletingId === variant.id\n ? t(\n \"catalog.products.edit.variantList.deleting\",\n \"Deleting\u2026\",\n )\n : t(\n \"catalog.products.list.actions.delete\",\n \"Delete\",\n )}\n </Button>\n ) : null}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.edit.variants.empty\",\n \"No variants defined yet.\",\n )}\n </p>\n )}\n </div>\n {ConfirmDialogElement}\n </>\n );\n}\n\nfunction ProductMetaSection({\n values,\n setValue,\n errors,\n taxRates,\n}: ProductMetaSectionProps) {\n const t = useT();\n const handleValue = typeof values.handle === \"string\" ? values.handle : \"\";\n const titleSource = typeof values.title === \"string\" ? values.title : \"\";\n const autoHandleEnabledRef = React.useRef(handleValue.trim().length === 0);\n\n React.useEffect(() => {\n if (!autoHandleEnabledRef.current) return;\n const normalizedTitle = titleSource.trim();\n if (!normalizedTitle) {\n if (handleValue) {\n setValue(\"handle\", \"\");\n }\n return;\n }\n const nextHandle = slugify(normalizedTitle);\n if (nextHandle !== handleValue) {\n setValue(\"handle\", nextHandle);\n }\n }, [titleSource, handleValue, setValue]);\n\n const handleHandleInputChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const nextValue = event.target.value;\n autoHandleEnabledRef.current = nextValue.trim().length === 0;\n setValue(\"handle\", nextValue);\n },\n [setValue],\n );\n\n const handleGenerateHandle = React.useCallback(() => {\n const slug = slugify(titleSource);\n autoHandleEnabledRef.current = true;\n setValue(\"handle\", slug);\n }, [titleSource, setValue]);\n\n return (\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label>{t(\"catalog.products.form.subtitle\", \"Subtitle\")}</Label>\n <Input\n value={typeof values.subtitle === \"string\" ? values.subtitle : \"\"}\n onChange={(event) => setValue(\"subtitle\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.subtitle\",\n \"Optional subtitle\",\n )}\n />\n {errors.subtitle ? (\n <p className=\"text-xs text-red-600\">{errors.subtitle}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label>\n {t(\"catalog.products.create.meta.handleLabel\", \"Handle\")}\n </Label>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleGenerateHandle}\n >\n {t(\"catalog.products.create.actions.generateHandle\", \"Generate\")}\n </Button>\n </div>\n <Input\n value={handleValue}\n onChange={handleHandleInputChange}\n placeholder={t(\n \"catalog.products.create.placeholders.handle\",\n \"e.g., summer-sneaker\",\n )}\n className=\"font-mono lowercase\"\n />\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.create.handleHelp\",\n \"Handle is used for URLs and must be unique.\",\n )}\n </p>\n {errors.handle ? (\n <p className=\"text-xs text-red-600\">{errors.handle}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <Label>{t(\"catalog.products.form.sku\", \"SKU\")}</Label>\n <Input\n value={values.sku}\n onChange={(event) => setValue(\"sku\", event.target.value)}\n placeholder={t(\n \"catalog.products.create.placeholders.sku\",\n \"e.g., PROD-001\",\n )}\n className=\"font-mono\"\n />\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.create.skuHelp\",\n \"Unique product identifier. Letters, numbers, hyphens, underscores, periods.\",\n )}\n </p>\n {errors.sku ? (\n <p className=\"text-xs text-red-600\">{errors.sku}</p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <Label>\n {t(\"catalog.products.form.productType\", \"Product type\")}\n </Label>\n <select\n className=\"w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n value={values.productType || \"simple\"}\n onChange={(event) => {\n const nextType = event.target.value;\n setValue(\"productType\", nextType);\n const nextIsConfigurable =\n isConfigurableProductType(nextType);\n if (nextIsConfigurable && !values.hasVariants) {\n setValue(\"hasVariants\", true);\n } else if (\n !nextIsConfigurable &&\n values.hasVariants\n ) {\n setValue(\"hasVariants\", false);\n }\n }}\n >\n {CATALOG_PRODUCT_TYPES.map((type) => {\n const isDisabled =\n type === \"bundle\" || type === \"grouped\";\n return (\n <option\n key={type}\n value={type}\n disabled={isDisabled}\n >\n {t(\n `catalog.products.types.${type}`,\n type,\n )}\n {isDisabled\n ? ` (${t(\"common.comingSoon\", \"Coming soon\")})`\n : \"\"}\n </option>\n );\n })}\n </select>\n {errors.productType ? (\n <p className=\"text-xs text-red-600\">\n {errors.productType}\n </p>\n ) : null}\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label>\n {t(\"catalog.products.create.taxRates.label\", \"Tax class\")}\n </Label>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (typeof window !== \"undefined\") {\n window.open(\n \"/backend/config/sales?section=tax-rates\",\n \"_blank\",\n \"noopener,noreferrer\",\n );\n }\n }}\n title={t(\n \"catalog.products.create.taxRates.manage\",\n \"Manage tax classes\",\n )}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <Layers className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.create.taxRates.manage\",\n \"Manage tax classes\",\n )}\n </span>\n </Button>\n </div>\n <select\n className=\"w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n value={values.taxRateId ?? \"\"}\n onChange={(event) =>\n setValue(\"taxRateId\", event.target.value || null)\n }\n disabled={!taxRates.length}\n >\n <option value=\"\">\n {taxRates.length\n ? t(\n \"catalog.products.create.taxRates.noneSelected\",\n \"No tax class selected\",\n )\n : t(\n \"catalog.products.create.taxRates.emptyOption\",\n \"No tax classes available\",\n )}\n </option>\n {taxRates.map((rate) => (\n <option key={rate.id} value={rate.id}>\n {formatTaxRateLabel(rate)}\n </option>\n ))}\n </select>\n <p className=\"text-xs text-muted-foreground\">\n {taxRates.length\n ? t(\n \"catalog.products.create.taxRates.help\",\n \"Applied to prices unless overridden per variant.\",\n )\n : t(\n \"catalog.products.create.taxRates.empty\",\n \"Define tax classes under Sales \u2192 Configuration.\",\n )}\n </p>\n </div>\n </div>\n );\n}\n\nfunction normalizeMetadata(value: unknown): Record<string, any> {\n if (!value || typeof value !== \"object\") return {};\n const entries = Object.entries(value as Record<string, unknown>).filter(\n ([key]) =>\n !key.startsWith(\"cf\") && key !== \"dimensions\" && key !== \"weight\",\n );\n return Object.fromEntries(entries);\n}\n\nfunction readOptionSchema(metadata: Record<string, any>): ProductOptionInput[] {\n const raw = Array.isArray(metadata.optionSchema)\n ? metadata.optionSchema\n : Array.isArray(metadata.option_schema)\n ? metadata.option_schema\n : [];\n return raw\n .map((option) => {\n if (!option || typeof option !== \"object\") return null;\n const values = Array.isArray(option.values)\n ? option.values\n .map((value: any) =>\n value && typeof value === \"object\"\n ? {\n id: String(value.id ?? createLocalId()),\n label: typeof value.label === \"string\" ? value.label : \"\",\n }\n : null,\n )\n .filter(\n (\n entry: { id?: string; label?: string } | null,\n ): entry is { id: string; label: string } => !!entry,\n )\n : [];\n return {\n id: String(option.id ?? createLocalId()),\n title: typeof option.title === \"string\" ? option.title : \"\",\n values,\n };\n })\n .filter((entry): entry is ProductOptionInput => !!entry);\n}\n\nfunction extractCustomFields(record: Record<string, unknown>): {\n customValues: Record<string, unknown>;\n} {\n const customValues: Record<string, unknown> = {};\n Object.entries(record).forEach(([key, value]) => {\n if (key.startsWith(\"cf_\")) customValues[key] = value;\n else if (key.startsWith(\"cf:\")) customValues[`cf_${key.slice(3)}`] = value;\n });\n return { customValues };\n}\n\nfunction normalizeIdList(value: unknown): string[] {\n const ids = Array.isArray(value)\n ? value\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter((entry) => entry.length)\n : [];\n return Array.from(new Set(ids));\n}\n\nfunction normalizeTagValues(value: unknown): string[] {\n const tags = Array.isArray(value)\n ? value\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter((entry) => entry.length)\n : [];\n return Array.from(new Set(tags));\n}\n\nfunction formatCategoryLabel(\n name: string | null,\n fallback: string,\n parentName: string | null,\n): string {\n const base = name ?? fallback;\n return parentName ? `${base} / ${parentName}` : base;\n}\n\nfunction readCategorySelections(record: Record<string, unknown>): {\n ids: string[];\n options: ProductCategorizePickerOption[];\n} {\n const rawCategories = Array.isArray(\n (record as Record<string, unknown>).categories,\n )\n ? ((record as Record<string, unknown>).categories as Array<\n Record<string, unknown>\n >)\n : [];\n const options = rawCategories\n .map((entry) => {\n const value =\n getString(entry.id) ??\n getString(entry.categoryId) ??\n getString(entry.category_id);\n if (!value) return null;\n const name = getString(entry.name);\n const parentName = getString(entry.parentName);\n const label = formatCategoryLabel(name, value, parentName);\n const description =\n parentName && !label.toLowerCase().includes(parentName.toLowerCase())\n ? parentName\n : null;\n return { value, label, description };\n })\n .filter(\n (\n option: {\n value: string;\n label: string;\n description: string | null;\n } | null,\n ): option is {\n value: string;\n label: string;\n description: string | null;\n } => !!option,\n );\n const fallbackIds = normalizeIdList(\n (record as Record<string, unknown>).categoryIds,\n );\n const combinedIds = Array.from(\n new Set([...options.map((option) => option.value), ...fallbackIds]),\n );\n return { ids: combinedIds, options };\n}\n\nfunction readTagSelections(record: Record<string, unknown>): {\n values: string[];\n options: ProductCategorizePickerOption[];\n} {\n const values = normalizeTagValues((record as Record<string, unknown>).tags);\n const options = values.map((label) => ({ value: label, label }));\n return { values, options };\n}\n\nfunction readOfferSnapshots(record: Record<string, unknown>): OfferSnapshot[] {\n const rawOffers = Array.isArray((record as Record<string, unknown>).offers)\n ? ((record as Record<string, unknown>).offers as Array<\n Record<string, unknown>\n >)\n : [];\n const snapshots: OfferSnapshot[] = [];\n for (const offer of rawOffers) {\n if (!offer || typeof offer !== \"object\") continue;\n const channelId =\n getString(offer.channelId) ?? getString(offer.channel_id) ?? null;\n if (!channelId) continue;\n snapshots.push({\n id: getString(offer.id),\n channelId,\n title: getString(offer.title) ?? null,\n description: getString(offer.description) ?? null,\n defaultMediaId:\n getString(offer.defaultMediaId) ?? getString(offer.default_media_id),\n defaultMediaUrl:\n getString(offer.defaultMediaUrl) ?? getString(offer.default_media_url),\n metadata: isRecord(offer.metadata)\n ? (offer.metadata as Record<string, unknown>)\n : null,\n isActive: offer.isActive !== false,\n channelName:\n getString(offer.channelName) ?? getString(offer.channel_name),\n channelCode:\n getString(offer.channelCode) ?? getString(offer.channel_code),\n });\n }\n return snapshots;\n}\n\nfunction extractChannelIds(offers: OfferSnapshot[]): string[] {\n return Array.from(new Set(offers.map((offer) => offer.channelId)));\n}\n\nfunction buildChannelOptions(\n offers: OfferSnapshot[],\n): ProductCategorizePickerOption[] {\n const seen = new Set<string>();\n const options: ProductCategorizePickerOption[] = [];\n for (const offer of offers) {\n if (seen.has(offer.channelId)) continue;\n seen.add(offer.channelId);\n const label = offer.channelName || offer.channelCode || offer.channelId;\n const description =\n offer.channelCode && offer.channelCode !== label\n ? offer.channelCode\n : null;\n options.push({\n value: offer.channelId,\n label,\n description,\n });\n }\n return options;\n}\n\ntype OfferPayload = {\n id?: string;\n channelId: string;\n title: string;\n description?: string;\n defaultMediaId?: string | null;\n defaultMediaUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n isActive?: boolean;\n};\n\nfunction buildOfferPayloads(params: {\n channelIds: string[];\n offerSnapshots: OfferSnapshot[];\n fallback: {\n title: string;\n description?: string;\n defaultMediaId?: string | null;\n defaultMediaUrl?: string | null;\n };\n}): OfferPayload[] {\n const { channelIds, offerSnapshots, fallback } = params;\n const byChannel = new Map(\n offerSnapshots.map((offer) => [offer.channelId, offer]),\n );\n const payloads: OfferPayload[] = [];\n const fallbackTitle = fallback.title.trim();\n for (const channelId of channelIds) {\n const existing = byChannel.get(channelId);\n const title = ensureString(existing?.title) ?? fallbackTitle;\n const description =\n ensureString(existing?.description) ?? ensureString(fallback.description);\n payloads.push({\n id: existing?.id ?? undefined,\n channelId,\n title,\n description,\n defaultMediaId:\n existing?.defaultMediaId ?? fallback.defaultMediaId ?? null,\n defaultMediaUrl:\n existing?.defaultMediaUrl ?? fallback.defaultMediaUrl ?? null,\n metadata: existing?.metadata ?? undefined,\n isActive: existing?.isActive ?? true,\n });\n }\n return payloads;\n}\n\nfunction mergeOfferSnapshots(\n current: OfferSnapshot[],\n payloads: OfferPayload[],\n): OfferSnapshot[] {\n const currentByChannel = new Map(\n current.map((snapshot) => [snapshot.channelId, snapshot]),\n );\n return payloads.map((entry) => {\n const previous = currentByChannel.get(entry.channelId);\n return {\n id: entry.id ?? previous?.id ?? null,\n channelId: entry.channelId,\n title: entry.title ?? previous?.title ?? null,\n description: entry.description ?? previous?.description ?? null,\n defaultMediaId: entry.defaultMediaId ?? previous?.defaultMediaId ?? null,\n defaultMediaUrl:\n entry.defaultMediaUrl ?? previous?.defaultMediaUrl ?? null,\n metadata: entry.metadata ?? previous?.metadata ?? null,\n isActive: entry.isActive ?? previous?.isActive ?? true,\n channelName: previous?.channelName ?? null,\n channelCode: previous?.channelCode ?? null,\n };\n });\n}\n\nfunction getString(value: unknown): string | null {\n if (typeof value === \"string\" && value.trim().length) return value.trim();\n return null;\n}\n\nfunction ensureString(value: unknown): string | undefined {\n const normalized = getString(value);\n return normalized ?? undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction extractUomFields(record: Record<string, unknown>) {\n const unitPriceObject = isRecord(record.unit_price)\n ? (record.unit_price as Record<string, unknown>)\n : null;\n const defaultUnit = canonicalizeUnitCode(\n record.default_unit ?? record.defaultUnit,\n );\n const defaultSalesUnit = canonicalizeUnitCode(\n record.default_sales_unit ?? record.defaultSalesUnit,\n );\n const defaultSalesUnitQuantity = toPositiveNumberOrNull(\n record.default_sales_unit_quantity ?? record.defaultSalesUnitQuantity,\n );\n const roundingScale = toIntegerInRangeOrDefault(\n record.uom_rounding_scale ?? record.uomRoundingScale,\n 0,\n 6,\n 4,\n );\n const roundingModeRaw = toTrimmedOrNull(\n record.uom_rounding_mode ?? record.uomRoundingMode,\n );\n const roundingMode: ProductUnitRoundingMode =\n roundingModeRaw === \"down\" || roundingModeRaw === \"up\"\n ? roundingModeRaw\n : \"half_up\";\n const unitPriceEnabled = Boolean(\n unitPriceObject?.enabled ??\n record.unit_price_enabled ??\n record.unitPriceEnabled,\n );\n const unitPriceReferenceUnit = canonicalizeUnitCode(\n unitPriceObject?.reference_unit ??\n unitPriceObject?.referenceUnit ??\n record.unit_price_reference_unit ??\n record.unitPriceReferenceUnit,\n );\n const unitPriceBaseQuantity = toPositiveNumberOrNull(\n unitPriceObject?.base_quantity ??\n unitPriceObject?.baseQuantity ??\n record.unit_price_base_quantity ??\n record.unitPriceBaseQuantity,\n );\n return {\n defaultUnit,\n defaultSalesUnit,\n defaultSalesUnitQuantity,\n roundingScale,\n roundingMode,\n unitPriceEnabled,\n unitPriceReferenceUnit,\n unitPriceBaseQuantity,\n };\n}\n\nfunction buildMetadataPayload(\n values: ProductFormValues,\n): Record<string, unknown> {\n const metadata = normalizeMetadata(values.metadata);\n metadata.__useMarkdown = values.useMarkdown ?? false;\n delete metadata.optionSchema;\n delete metadata.option_schema;\n delete metadata.dimensions;\n delete metadata.weight;\n return metadata;\n}\n\nfunction normalizeOptionSchemaRecord(\n schema: OptionSchemaRecord | null | undefined,\n): CatalogProductOptionSchema | null {\n if (!schema || !Array.isArray(schema.options)) return null;\n return {\n version: typeof schema.version === \"number\" ? schema.version : undefined,\n name: schema.name ?? null,\n description: schema.description ?? null,\n options: schema.options.map((option) => {\n const code = option.code?.trim() || createLocalId();\n const label = option.label?.trim() || code;\n const inputType =\n option.inputType === \"text\" ||\n option.inputType === \"textarea\" ||\n option.inputType === \"number\"\n ? option.inputType\n : \"select\";\n const choices = Array.isArray(option.choices)\n ? option.choices.map((choice) => {\n const choiceCode = choice.code?.trim() || createLocalId();\n const choiceLabel = choice.label?.trim() || choiceCode;\n return { code: choiceCode, label: choiceLabel };\n })\n : [];\n return {\n code,\n label,\n description: option.description ?? undefined,\n inputType,\n choices,\n };\n }),\n };\n}\n\nfunction buildSchemaFromOptions(\n options: ProductOptionInput[],\n name: string,\n): OptionSchemaRecord {\n return {\n version: 1,\n name,\n options: options.map((option) => ({\n code: slugify(option.title || createLocalId()),\n label: option.title,\n inputType: \"select\",\n choices: option.values.map((value) => ({\n code: slugify(value.label || value.id),\n label: value.label,\n })),\n })),\n };\n}\n\nfunction extractOptionsFromTemplate(\n template: OptionSchemaTemplateSummary,\n): ProductOptionInput[] {\n const schema = normalizeOptionSchemaRecord(template?.schema);\n if (!schema) return [];\n return convertSchemaToProductOptions(schema);\n}\n\nfunction OptionSchemaDialog({\n open,\n onOpenChange,\n templates,\n isLoading,\n onSelect,\n onDelete,\n onEdit,\n}: OptionSchemaDialogProps) {\n const t = useT();\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-xl\">\n <DialogHeader>\n <DialogTitle>\n {t(\"catalog.products.edit.schemas.dialogTitle\", \"Option schemas\")}\n </DialogTitle>\n </DialogHeader>\n {isLoading ? (\n <div className=\"py-6\">\n <DataLoader\n isLoading\n loadingMessage={t(\n \"catalog.products.edit.schemas.loading\",\n \"Loading\u2026\",\n )}\n spinnerSize=\"md\"\n >\n <></>\n </DataLoader>\n </div>\n ) : templates.length ? (\n <div className=\"divide-y rounded-md border\">\n {templates.map((template) => {\n const id = typeof template.id === \"string\" ? template.id : null;\n return (\n <div\n key={id ?? template.name ?? createLocalId()}\n className=\"flex items-center justify-between px-4 py-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">\n {template.name ?? template.id ?? \"Schema\"}\n </p>\n {template.description ? (\n <p className=\"text-xs text-muted-foreground\">\n {template.description}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => onSelect(template)}\n >\n {t(\"catalog.products.edit.schemas.apply\", \"Apply\")}\n </Button>\n {id ? (\n <>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n onClick={() => onEdit(template)}\n >\n <Save className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.edit.schemas.edit\",\n \"Edit schema\",\n )}\n </span>\n </Button>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n onClick={() => void onDelete(id)}\n >\n <Trash2 className=\"h-4 w-4 text-destructive\" />\n <span className=\"sr-only\">\n {t(\n \"catalog.products.edit.schemas.delete\",\n \"Delete schema\",\n )}\n </span>\n </Button>\n </>\n ) : null}\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"py-4 text-sm text-muted-foreground\">\n {t(\"catalog.products.edit.schemas.empty\", \"No saved schemas yet.\")}\n </p>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n\ntype OptionSchemaDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n templates: OptionSchemaTemplateSummary[];\n isLoading: boolean;\n onSelect: (template: OptionSchemaTemplateSummary | null) => void;\n onDelete: (id: string) => Promise<void> | void;\n onEdit: (template: OptionSchemaTemplateSummary) => void;\n};\n\ntype SaveSchemaDialogProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n defaultName?: string;\n onSubmit: (name: string) => Promise<void>;\n};\n\nfunction SaveSchemaDialog({\n open,\n onOpenChange,\n defaultName = \"\",\n onSubmit,\n}: SaveSchemaDialogProps) {\n const t = useT();\n const [name, setName] = React.useState(defaultName);\n const [saving, setSaving] = React.useState(false);\n\n React.useEffect(() => {\n if (open) setName(defaultName);\n }, [defaultName, open]);\n\n const handleSubmit = React.useCallback(async () => {\n setSaving(true);\n try {\n await onSubmit(name);\n onOpenChange(false);\n } catch (err) {\n console.error(\"schema.save.failed\", err);\n } finally {\n setSaving(false);\n }\n }, [name, onOpenChange, onSubmit]);\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>\n {t(\"catalog.products.edit.schemas.saveTitle\", \"Save option schema\")}\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-2\">\n <Label htmlFor=\"schemaName\">\n {t(\"catalog.products.edit.schemas.nameLabel\", \"Schema name\")}\n </Label>\n <Input\n id=\"schemaName\"\n value={name}\n onChange={(event) => setName(event.target.value)}\n placeholder={t(\n \"catalog.products.edit.schemas.namePlaceholder\",\n \"e.g., Color + Size set\",\n )}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n >\n {t(\"common.cancel\", \"Cancel\")}\n </Button>\n <Button type=\"button\" onClick={handleSubmit} disabled={saving}>\n {saving ? t(\"common.saving\", \"Saving\u2026\") : t(\"common.save\", \"Save\")}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],
5
+ "mappings": ";AAuHM,SAykDF,UAzkDE,KA6kCA,YA7kCA;AArHN,YAAY,WAAW;AACvB,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,SAAS,iBAAiB;AAC1B,SAAS,MAAM,gBAAgB;AAC/B;AAAA,EACE;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;AACzC,SAAS,aAAa;AACtB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAE3B,SAAS,eAAe;AACxB;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY;AACrB,SAAS,wBAAwB;AACjC,SAAS,SAAS;AAClB;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAGK;AACP;AAAA,EASE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAGK;AACP,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,+BAA+B;AAExC,MAAM,iBAAiB,QAAQ,MAAM,OAAO,sBAAsB,GAAG;AAAA,EACnE,KAAK;AAAA,EACL,SAAS,MACP,oBAAC,SAAI,WAAU,uEACb,8BAAC,WAAQ,GACX;AAEJ,CAAC;AAuFD,SAAS,uBACP,MAC4B;AAC5B,MAAI,CAAC,KAAM,QAAO;AAClB,QAAMA,aAAY,CAAC,UAAkC;AACnD,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,OAAQ,QAAO,MAAM,KAAK;AACxE,QAAI,OAAO,UAAU,YAAY,OAAO,UAAU;AAChD,aAAO,OAAO,KAAK;AACrB,WAAO;AAAA,EACT;AACA,QAAM,YAAYA,WAAU,KAAK,cAAc,KAAK,SAAS;AAC7D,QAAM,KAAKA,WAAU,KAAK,EAAE;AAC5B,MAAI,CAAC,aAAa,CAAC,GAAI,QAAO;AAC9B,QAAM,cAAcA,WAAU,KAAK,iBAAiB,KAAK,WAAW;AACpE,QAAM,eAAeA,WAAU,KAAK,iBAAiB,KAAK,YAAY;AACtE,QAAM,YAAYA,WAAU,KAAK,oBAAoB,KAAK,cAAc;AACxE,QAAM,UAAUA,WAAU,KAAK,kBAAkB,KAAK,YAAY;AAClE,QAAM,SAAS,aAAa,WAAW;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,YAAY,kBAAkB;AAAA,EAC7C;AACF;AAEA,SAAS,6BACP,OAC+B;AAC/B,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,SAAiC,CAAC;AACxC,SAAO,QAAQ,KAAgC,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,QACE,OAAO,QAAQ,YACf,OAAO,UAAU,YACjB,IAAI,KAAK,EAAE,QACX;AACA,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF,CAAC;AACD,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAC/C;AAEA,SAAS,0BACP,OAC8B;AAC9B,QAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAC7C,SAAO,KACJ,IAAI,CAAC,SAAS;AACb,UAAM,KAAK,gBAAgB,KAAK,EAAE;AAClC,UAAM,WAAW,qBAAqB,KAAK,aAAa,KAAK,QAAQ;AACrE,UAAM,SAAS;AAAA,MACb,KAAK,kBAAkB,KAAK;AAAA,IAC9B;AACA,QAAI,CAAC,YAAY,WAAW,KAAM,QAAO;AACzC,UAAM,eAAe;AAAA,MACnB,KAAK,cAAc,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,WACJ,OAAO,KAAK,cAAc,YACtB,KAAK,YACL,OAAO,KAAK,aAAa,YACvB,KAAK,WACL;AACR,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV;AAAA,MACA,cAAc,OAAO,MAAM;AAAA,MAC3B,WAAW,OAAO,YAAY;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,UAA+C,QAAQ,KAAK,CAAC;AAC1E;AAEe,SAAR,uBAAwC;AAAA,EAC7C;AACF,GAEG;AACD,QAAM,YAAY,QAAQ,KAAK,OAAO,OAAO,EAAE,IAAI;AACnD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAA2B,CAAC,CAAC;AACnE,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAA2B,CAAC,CAAC;AACnE,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAA6B,CAAC,CAAC;AACzE,QAAM,CAAC,eAAe,gBAAgB,IACpC,MAAM,SAA4C,IAAI;AACxD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,IAAI;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAwB,IAAI;AAC5D,QAAM,oBAAoB,MAAM,OAAwB,CAAC,CAAC;AAC1D,QAAM,wBAAwB,MAAM,OAAqC,CAAC,CAAC;AAC3E,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAIrD,EAAE,YAAY,CAAC,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAE7C,QAAM,eAAe,MAAM,YAAY,OAAO,OAAe;AAC3D,QAAI;AACF,YAAM,CAAC,aAAa,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,QACjD;AAAA,UACE,mCAAmC,mBAAmB,EAAE,CAAC;AAAA,QAC3D;AAAA,QACA;AAAA,UACE,iCAAiC,mBAAmB,EAAE,CAAC;AAAA,QACzD;AAAA,MACF,CAAC;AACD,UAAI,CAAC,YAAY,IAAI;AACnB,oBAAY,CAAC,CAAC;AACd;AAAA,MACF;AACA,YAAM,WAAkD,CAAC;AACzD,UAAI,UAAU,IAAI;AAChB,cAAM,aAAa,MAAM,QAAQ,UAAU,QAAQ,KAAK,IACpD,UAAU,QAAQ,QAClB,CAAC;AACL,mBAAW,QAAQ,YAAY;AAC7B,gBAAM,UAAU,uBAAuB,IAAI;AAC3C,cAAI,CAAC,QAAS;AACd,cAAI,CAAC,SAAS,QAAQ,SAAS,GAAG;AAChC,qBAAS,QAAQ,SAAS,IAAI,CAAC;AAAA,UACjC;AACA,mBAAS,QAAQ,SAAS,EAAE,KAAK,OAAO;AAAA,QAC1C;AACA,eAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,QAAQ;AACrC,mBAAS,GAAG,EAAE,KAAK,CAAC,MAAM,UAAU;AAClC,kBAAM,WACH,KAAK,eAAe,OAAO,KAAK,gBAAgB;AACnD,kBAAM,YACH,MAAM,eAAe,OAAO,MAAM,gBAAgB;AACrD,mBAAO,QAAQ,cAAc,QAAQ;AAAA,UACvC,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AACA,YAAM,QAAQ,MAAM,QAAQ,YAAY,QAAQ,KAAK,IACjD,YAAY,QAAQ,QACpB,CAAC;AACL;AAAA,QACE,MACG,IAAI,CAAC,YAAY;AAChB,gBAAM,YACJ,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK;AAChD,cAAI,CAAC,UAAW,QAAO;AACvB,gBAAM,gBAAgB;AACtB,gBAAM,eACJ,6BAA6B,gBAAgB,eAAe,CAAC,KAC7D,6BAA6B,eAAe,YAAY;AAC1D,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,MACE,OAAO,QAAQ,SAAS,YAAY,QAAQ,KAAK,KAAK,EAAE,SACpD,QAAQ,OACP,QAAQ,OAAO;AAAA,YACtB,KAAK,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;AAAA,YACrD,WAAW,QAAQ,QAAQ,cAAc,QAAQ,SAAS;AAAA,YAC1D,QAAQ,SAAS,SAAS,KAAK,CAAC;AAAA,YAChC;AAAA,UACF;AAAA,QACF,CAAC,EACA,OAAO,CAAC,UAAmC,QAAQ,KAAK,CAAC;AAAA,MAC9D;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,iCAAiC,GAAG;AAClD,kBAAY,CAAC,CAAC;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkB,MAAM,YAAY,YAAY;AACpD,QAAI,CAAC,UAAW;AAChB,UAAM,aAAa,SAAS;AAAA,EAC9B,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,OAA4C;AACjD,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,6BAA6B,mBAAmB,EAAE,QAAQ,eAAe,CAAC,aAAa,mBAAmB,EAAE,CAAC;AAAA,QAC/G;AACA,YAAI,CAAC,IAAI,GAAI,QAAO,CAAC;AACrB,gBAAQ,IAAI,QAAQ,SAAS,CAAC,GAAG,IAAI,CAAC,UAAU;AAAA,UAC9C,IAAI,KAAK;AAAA,UACT,KAAK,KAAK;AAAA,UACV,UAAU,KAAK;AAAA,UACf,UAAU,KAAK;AAAA,UACf,cAAc,KAAK,gBAAgB;AAAA,QACrC,EAAE;AAAA,MACJ,SAAS,KAAK;AACZ,gBAAQ,MAAM,4BAA4B,GAAG;AAC7C,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,MAAM;AACpB,UAAM,eAAe,YAAY;AAC/B,UAAI;AACF,cAAM,UAAU,MAAM,qBAEnB,qCAAqC,QAAW;AAAA,UACjD,cAAc;AAAA,YACZ;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU,EAAE,OAAO,CAAC,EAAE;AAAA,QACxB,CAAC;AACD,cAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D;AAAA,UACE,MAAM,IAAI,CAAC,SAAS;AAClB,kBAAM,UACJ,OAAO,KAAK,SAAS,WACjB,KAAK,OACL,OAAO,KAAK,QAAQ,OAAO,GAAG;AACpC,mBAAO;AAAA,cACL,IAAI,OAAO,KAAK,EAAE;AAAA,cAClB,MACE,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,SAC9C,KAAK,OACL;AAAA,gBACE;AAAA,gBACA;AAAA,cACF;AAAA,cACN,MACE,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,SAC9C,KAAK,OACL;AAAA,cACN,MAAM,OAAO,SAAS,OAAO,IAAI,UAAU;AAAA,cAC3C,WAAW;AAAA,gBACT,OAAO,KAAK,cAAc,YACtB,KAAK,YACL,OAAO,KAAK,eAAe,YACzB,KAAK,aACL;AAAA,cACR;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,gCAAgC,GAAG;AACjD,oBAAY,CAAC,CAAC;AAAA,MAChB;AAAA,IACF;AACA,iBAAa,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC/B,GAAG,CAAC,CAAC,CAAC;AAEN,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,WAAW;AACd,iBAAW,KAAK;AAChB;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,YAAY;AAChB,mBAAe,cAAc;AAC3B,iBAAW,IAAI;AACf,eAAS,IAAI;AACb,UAAI;AACF,cAAM,aAAa,MAAM;AAAA,UACvB,4BAA4B,mBAAmB,SAAU,CAAC;AAAA,QAC5D;AACA,YAAI,CAAC,WAAW,GAAI,OAAM,IAAI,MAAM,aAAa;AACjD,cAAM,SAAS,MAAM,QAAQ,WAAW,QAAQ,KAAK,IACjD,WAAW,QAAQ,QAAQ,CAAC,IAC5B;AACJ,YAAI,CAAC;AACH,gBAAM,IAAI;AAAA,YACR,EAAE,yCAAyC,oBAAoB;AAAA,UACjE;AACF,cAAM,cAAc,SAAS,OAAO,QAAQ,IACvC,OAAO,WACR;AACJ,cAAM,aAAa;AAAA,UACjB,OAAO,cAAc,aAAa,cAAc;AAAA,QAClD;AACA,cAAM,gBAAgB,SAAS,aAAa,MAAM,IAC7C,YAAY,SACb;AACJ,cAAM,SAAS,uBAAuB;AAAA,UACpC,OACE,OAAO,gBACP,OAAO,eACP,eAAe;AAAA,UACjB,MACE,OAAO,eACP,OAAO,cACP,eAAe;AAAA,QACnB,CAAC;AACD,cAAM,WAAW,kBAAkB,WAAW;AAC9C,cAAM,iBACJ,OAAO,OAAO,qBAAqB,WAC/B,OAAO,mBACP,OAAO,OAAO,mBAAmB,WAC/B,OAAO,iBACP;AACR,cAAM,YACJ,OAAO,OAAO,gBAAgB,WAC1B,OAAO,cACP,OAAO,OAAO,cAAc,WAC1B,OAAO,YACP;AACR,cAAM,uBAAuB,iBACzB,MAAM,0BAA0B,cAAc,IAC9C;AACJ,cAAM,mBAAmB;AAAA,UACvB,sBAAsB;AAAA,QACxB;AACA,YAAI,eAAe,mBACf,8BAA8B,gBAAgB,IAC9C,CAAC;AACL,YAAI,CAAC,aAAa,QAAQ;AACxB,yBAAe,iBAAiB,QAAQ;AAAA,QAC1C;AACA,cAAM,CAAC,aAAa,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,UACtD,iBAAiB,SAAU;AAAA,UAC3B;AAAA,YACE,mDAAmD,mBAAmB,SAAU,CAAC;AAAA,YACjF;AAAA,YACA,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;AAAA,UAC5B;AAAA,QACF,CAAC;AACD,cAAM,iBAAiB,eAAe,KAClC,0BAA0B,eAAe,QAAQ,KAAK,IACtD,CAAC;AACL,8BAAsB,UAAU;AAChC,cAAM,EAAE,aAAa,IAAI,oBAAoB,MAAM;AACnD,cAAM,SAAS,mBAAmB,MAAM;AACxC,0BAAkB,UAAU;AAC5B,cAAM,aAAa,kBAAkB,MAAM;AAC3C,cAAM,uBAAuB,oBAAoB,MAAM;AACvD,cAAM,EAAE,KAAK,aAAa,SAAS,gBAAgB,IACjD,uBAAuB,MAAM;AAC/B,cAAM,EAAE,QAAQ,WAAW,SAAS,WAAW,IAC7C,kBAAkB,MAAM;AAC1B,cAAM,iBACJ,OAAO,OAAO,qBAAqB,WAC/B,OAAO,mBACP,OAAO,OAAO,mBAAmB,WAC/B,OAAO,iBACP;AACR,cAAM,kBACJ,OAAO,OAAO,sBAAsB,WAChC,OAAO,oBACP,OAAO,OAAO,oBAAoB,WAChC,OAAO,kBACP;AACR,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,IAAI,iBAAiB,MAAM;AAC3B,cAAM,UAA6B;AAAA,UACjC,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,UACzD,UAAU,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW;AAAA,UAClE,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAAA,UAC5D,KAAK,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;AAAA,UACnD,aACE,OAAO,OAAO,iBAAiB,WAC3B,OAAO,eACP,OAAO,OAAO,gBAAgB,WAC5B,OAAO,cACP;AAAA,UAER,aACE,OAAO,OAAO,gBAAgB,WAAW,OAAO,cAAc;AAAA,UAChE,aAAa,QAAQ,SAAS,aAAa;AAAA,UAC3C;AAAA,UACA,cAAc;AAAA,UACd,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA,aAAa,QAAQ,OAAO,mBAAmB,OAAO,cAAc;AAAA,UACpE,SAAS;AAAA,UACT;AAAA,UACA,UAAU,CAAC;AAAA,UACX;AAAA,UACA,YAAY,0BAA0B,UAAU;AAAA,UAChD,QAAQ,sBAAsB,MAAM;AAAA,UACpC,aAAa,eAAe;AAAA,UAC5B,kBAAkB,oBAAoB,eAAe;AAAA,UACrD,0BAA0B,OAAO,4BAA4B,CAAC;AAAA,UAC9D,kBAAkB,OAAO,aAAa;AAAA,UACtC,iBAAiB;AAAA,UACjB;AAAA,UACA,wBACE,0BACA,2BAA2B;AAAA,YACzB;AAAA,UACF,IACK,yBACD;AAAA,UACN,uBACE,0BAA0B,OAAO,KAAK,OAAO,qBAAqB;AAAA,UACpE,iBAAiB;AAAA,UACjB,oBACE,OAAO,OAAO,yBAAyB,WACnC,OAAO,uBACP,OAAO,OAAO,uBAAuB,WACnC,OAAO,qBACP;AAAA,UACR;AAAA,UACA;AAAA,UACA,MAAM;AAAA,QACR;AACA,YAAI,CAAC,WAAW;AACd,2BAAiB,EAAE,GAAG,SAAS,GAAG,aAAa,CAAC;AAChD,+BAAqB;AAAA,YACnB,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AACA,cAAM,aAAa,SAAU;AAAA,MAC/B,SAAS,KAAK;AACZ,gBAAQ,MAAM,qCAAqC,GAAG;AACtD,YAAI,CAAC,WAAW;AACd,gBAAM,UACJ,eAAe,SAAS,IAAI,UACxB,IAAI,UACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF;AACN,mBAAS,OAAO;AAAA,QAClB;AAAA,MACF,UAAE;AACA,YAAI,CAAC,UAAW,YAAW,KAAK;AAAA,MAClC;AAAA,IACF;AACA,gBAAY;AACZ,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,kBAAkB,cAAc,WAAW,CAAC,CAAC;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,iBAAiB;AAC9B,UAAI;AACF,cAAM,UAAU,MAAM,qBAEnB,yCAAyC,QAAW;AAAA,UACrD,UAAU,EAAE,OAAO,CAAC,EAAE;AAAA,QACxB,CAAC;AACD,cAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D,cAAM,YAAY,MACf,IAAI,CAAC,SAAS,0BAA0B,IAAI,CAAC,EAC7C,OAAO,CAAC,UAAqC,CAAC,CAAC,KAAK;AACvD,YAAI,CAAC,WAAW;AACd,wBAAc,SAAS;AAAA,QACzB;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,oCAAoC,GAAG;AACrD,YAAI,CAAC,WAAW;AACd,wBAAc,CAAC,CAAC;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,mBAAe,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAC/B,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAuB,MAAM,YAAY,CAAC,cAAsB;AACpE,gBAAY,CAAC,SAAS,KAAK,OAAO,CAAC,YAAY,QAAQ,OAAO,SAAS,CAAC;AAAA,EAC1E,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS,MAAM;AAAA,IACnB,MAAM;AAAA,MACJ;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW,aAAa;AAAA;AAAA,QAC1B;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW,aAAa;AAAA,YACxB;AAAA,YACA;AAAA,YACA,kBAAkB;AAAA,YAClB,kBAAkB;AAAA;AAAA,QACpB;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO,EAAE,sCAAsC,cAAc;AAAA,QAC7D,aAAa;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,QACA,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO,EAAE,0CAA0C,YAAY;AAAA,QAC/D,aAAa;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,QACA,WAAW,CAAC,EAAE,QAAQ,UAAU,OAAO,MACrC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA,wBAAwB,kBAAkB;AAAA,YAC1C,uBAAuB,kBAAkB;AAAA,YACzC,mBAAmB,kBAAkB;AAAA;AAAA,QACvC;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO,EAAE,sCAAsC,mBAAmB;AAAA,QAClE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO,eAAkC;AACvC,YAAM,6BAA6B,CAAC,YAAuC;AACzE,YAAI,OAAO,YAAY,SAAU,QAAO;AACxC,cAAM,UAAU,QAAQ,KAAK;AAC7B,YAAI,CAAC,QAAS,QAAO;AACrB,eAAO,EAAE,SAAS,OAAO;AAAA,MAC3B;AACA,UAAI,CAAC,WAAW;AACd,cAAM;AAAA,UACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAS,kBAAkB,UAAU,UAAU;AACrD,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,SAAS,OAAO,MAAM;AAC5B,cAAM,cAAsC,CAAC;AAC7C,eAAO,QAAQ,CAAC,UAAU;AACxB,gBAAM,OAAO,MAAM,KAAK,KAAK,GAAG,KAAK;AACrC,cAAI,CAAC,YAAY,IAAI,GAAG;AACtB,wBAAY,IAAI,IAAI,2BAA2B,MAAM,OAAO;AAAA,UAC9D;AAAA,QACF,CAAC;AACD,cAAM,UACJ,2BAA2B,OAAO,CAAC,GAAG,OAAO,KAC7C;AAAA,UACE;AAAA,UACA;AAAA,QACF;AACF,cAAM,oBAAoB,SAAS,WAAW;AAAA,MAChD;AACA,YAAM,SAA4B;AAAA,QAChC,GAAG;AAAA,QACH,GAAG,OAAO;AAAA,QACV,OAAO,OAAO,KAAK,SAAS;AAAA,QAC5B,UAAU,OAAO,KAAK,YAAY;AAAA,QAClC,QAAQ,OAAO,KAAK,UAAU;AAAA,QAC9B,aAAa,OAAO,KAAK,eAAe;AAAA,QACxC,aAAa,OAAO,KAAK,eAAe;AAAA,QACxC,WAAW,OAAO,KAAK,aAAa;AAAA,QACpC,cAAc,OAAO,KAAK,gBAAgB;AAAA,QAC1C,YAAY,MAAM,QAAQ,OAAO,KAAK,UAAU,IAC5C,OAAO,KAAK,aACZ,CAAC;AAAA,QACL,gBAAgB,OAAO,KAAK,kBAAkB;AAAA,QAC9C,iBAAiB,OAAO,KAAK,mBAAmB;AAAA,QAChD,aAAc,OAAO,KAAK,eAAe;AAAA,QACzC,aAAa,OAAO,KAAK,eAAe;AAAA,QACxC,SAAS,MAAM,QAAQ,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,UAAU,CAAC;AAAA,QACrE,UAAU,MAAM,QAAQ,OAAO,KAAK,QAAQ,IACxC,OAAO,KAAK,WACZ,CAAC;AAAA,QACL,UAAU,OAAO,KAAK,YAAY,CAAC;AAAA,QACnC,YAAY,OAAO,KAAK,cAAc;AAAA,QACtC,QAAQ,OAAO,KAAK,UAAU;AAAA,QAC9B,aAAa,OAAO,KAAK,eAAe;AAAA,QACxC,kBAAkB,OAAO,KAAK,oBAAoB;AAAA,QAClD,0BACE,OAAO,KAAK,0BAA0B,SAAS,KAAK;AAAA,QACtD,kBAAkB,OAAO,KAAK,kBAAkB,SAAS,KAAK;AAAA,QAC9D,iBAAiB,OAAO,KAAK,mBAAmB;AAAA,QAChD,kBAAkB,QAAQ,OAAO,KAAK,gBAAgB;AAAA,QACtD,wBAAwB,OAAO,KAAK,0BAA0B;AAAA,QAC9D,uBACE,OAAO,KAAK,uBAAuB,SAAS,KAAK;AAAA,QACnD,iBAAiB,MAAM,QAAQ,OAAO,KAAK,eAAe,IACtD,OAAO,KAAK,gBAAgB,IAAI,CAAC,WAAW;AAAA,UAC1C,IAAI,gBAAgB,MAAM,EAAE,KAAK;AAAA,UACjC,UAAU,gBAAgB,MAAM,QAAQ,KAAK;AAAA,UAC7C,cACE,uBAAuB,MAAM,YAAY,MAAM,OAC3C,KACA,OAAO,uBAAuB,MAAM,YAAY,CAAC;AAAA,UACvD,WACE,OAAO,MAAM,cAAc,YAC3B,OAAO,SAAS,MAAM,SAAS,IAC3B,OAAO,MAAM,SAAS,IACtB;AAAA,UACN,UAAU,MAAM,aAAa;AAAA,QAC/B,EAAE,IACF,CAAC;AAAA,QACL,oBAAoB,OAAO,KAAK,sBAAsB;AAAA,QACtD,aAAa,OAAO,KAAK,eAAe,CAAC;AAAA,QACzC,YAAY,OAAO,KAAK,cAAc,CAAC;AAAA,QACvC,MAAM,OAAO,KAAK,QAAQ,CAAC;AAAA,QAC3B,gBAAgB,OAAO,KAAK,kBAAkB;AAAA,MAChD;AACA,YAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,UAAI,CAAC,OAAO;AACV,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,QACF;AACA,cAAM,oBAAoB,SAAS,EAAE,OAAO,QAAQ,CAAC;AAAA,MACvD;AACA,YAAM,SAAS,OAAO,QAAQ,KAAK,KAAK;AACxC,YAAM,cAAc,OAAO,aAAa,KAAK,KAAK;AAClD,YAAM,WAAW,qBAAqB,MAAM;AAC5C,YAAM,aAAa,0BAA0B,OAAO,cAAc,IAAI;AACtE,YAAM,SAAS,sBAAsB,OAAO,UAAU,IAAI;AAC1D,YAAM,sBAAsB,CAAC,cAA8B;AACzD,YAAI,CAAC,UAAW,QAAO;AACvB,cAAM,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,SAAS;AAC3D,eAAO,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,MAAM,IAAI,IAChE,MAAM,OACN;AAAA,MACN;AACA,YAAM,sBAAsB,oBAAoB,OAAO,aAAa,IAAI;AACxE,YAAM,iBACJ,OAAO,OAAO,mBAAmB,YACjC,OAAO,eAAe,KAAK,EAAE,SACzB,OAAO,iBACP;AACN,YAAM,oBAAoB,iBACtB,OAAO,WAAW,KAAK,CAAC,SAAS,KAAK,OAAO,cAAc,IAC3D;AACJ,YAAM,kBAAkB,oBACpB,wBAAwB,kBAAkB,IAAI;AAAA,QAC5C,MAAM,0BAA0B,kBAAkB,QAAQ;AAAA,MAC5D,CAAC,IACD;AACJ,YAAM,cAAc,qBAAqB,OAAO,WAAW;AAC3D,YAAM,mBAAmB,qBAAqB,OAAO,gBAAgB;AACrE,YAAM,2BACJ,uBAAuB,OAAO,wBAAwB,KAAK;AAC7D,YAAM,mBAAmB;AAAA,QACvB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,kBACJ,OAAO,oBAAoB,UAAU,OAAO,oBAAoB,OAC5D,OAAO,kBACP;AACN,YAAM,mBAAmB,QAAQ,OAAO,gBAAgB;AACxD,YAAM,yBAAyB;AAAA,QAC7B,OAAO;AAAA,MACT;AACA,YAAM,wBAAwB;AAAA,QAC5B,OAAO;AAAA,MACT;AACA,UAAI,oBAAoB,CAAC,aAAa;AACpC,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,QACF;AACA,cAAM,oBAAoB,SAAS,EAAE,kBAAkB,QAAQ,CAAC;AAAA,MAClE;AACA,YAAM,mBAAmB;AAAA,QACvB,OAAO;AAAA,QACP;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,UAAI,iBAAiB,UAAU,CAAC,aAAa;AAC3C,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,QACF;AACA,cAAM,oBAAoB,SAAS,EAAE,aAAa,QAAQ,CAAC;AAAA,MAC7D;AACA,YAAM,iBAAiB,aAAa,YAAY,KAAK;AACrD,YAAM,sBAAsB,kBAAkB,YAAY,KAAK;AAC/D,UACE,kBACA,uBACA,wBAAwB,gBACxB;AACA,cAAM,4BAA4B,iBAAiB;AAAA,UACjD,CAAC,UACC,MAAM,YACN,MAAM,SAAS,YAAY,MAAM;AAAA,QACrC;AACA,YAAI,CAAC,2BAA2B;AAC9B,gBAAM,UAAU;AAAA,YACd;AAAA,YACA;AAAA,UACF;AACA,gBAAM,oBAAoB,SAAS;AAAA,YACjC,kBAAkB;AAAA,YAClB,iBAAiB;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,kBAAkB;AACpB,YACE,CAAC,0BACD,CAAC,2BAA2B;AAAA,UAC1B;AAAA,QACF,GACA;AACA,gBAAM,UAAU;AAAA,YACd;AAAA,YACA;AAAA,UACF;AACA,gBAAM,oBAAoB,SAAS;AAAA,YACjC,wBAAwB;AAAA,UAC1B,CAAC;AAAA,QACH;AACA,YAAI,0BAA0B,MAAM;AAClC,gBAAM,UAAU;AAAA,YACd;AAAA,YACA;AAAA,UACF;AACA,gBAAM,oBAAoB,SAAS;AAAA,YACjC,uBAAuB;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,UAAmC;AAAA,QACvC,IAAI;AAAA,QACJ;AAAA,QACA,UAAU,OAAO,UAAU,KAAK,KAAK;AAAA,QACrC;AAAA,QACA;AAAA,QACA,KAAK,OAAO,KAAK,KAAK,KAAK;AAAA,QAC3B,aAAa,OAAO,eAAe;AAAA,QACnC,WAAW,OAAO,aAAa;AAAA,QAC/B,SAAS,uBAAuB;AAAA,QAChC,gBAAgB;AAAA,UACd,OAAO,eAAe;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa,QAAQ,SAAS;AAAA,QAC9B,YAAY,QAAQ,QAAQ;AAAA,QAC5B,gBAAgB,kBAAkB;AAAA,QAClC,iBAAiB,mBAAmB;AAAA,QACpC,aAAa,eAAe;AAAA,QAC5B,kBAAkB,oBAAoB,eAAe;AAAA,QACrD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,wBAAwB,mBACpB,yBACA;AAAA,QACJ,uBAAuB,mBACnB,wBACA;AAAA,QACJ,oBAAoB,OAAO,oBAAoB,KAAK,EAAE,SAClD,OAAO,qBACP;AAAA,MACN;AACA,YAAM,cAAc,gBAAgB,OAAO,WAAW;AACtD,YAAM,aAAa,gBAAgB,OAAO,UAAU;AACpD,YAAM,OAAO,mBAAmB,OAAO,IAAI;AAC3C,cAAQ,cAAc;AACtB,cAAQ,OAAO;AACf,YAAM,yBAAyB;AAAA,QAC7B,OAAO;AAAA,QACP;AAAA,MACF;AACA,UAAI,wBAAwB;AAC1B,gBAAQ,eAAe;AAAA,MACzB,WAAW,OAAO,gBAAgB;AAChC,gBAAQ,iBAAiB;AAAA,MAC3B;AACA,YAAM,eAAe,yBAAyB,MAAM;AACpD,UAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,gBAAQ,eAAe;AAAA,MACzB;AACA,YAAM,oBAAoB,kBAAkB;AAC5C,YAAM,gBAAgB,mBAAmB;AAAA,QACvC;AAAA,QACA,gBAAgB;AAAA,QAChB,UAAU;AAAA,UACR;AAAA,UACA,aAAa,eAAe;AAAA,UAC5B;AAAA,UACA,iBAAiB,mBAAmB;AAAA,QACtC;AAAA,MACF,CAAC;AACD,cAAQ,SAAS;AACjB,YAAM,gBAAgB,kBAAkB;AAAA,QACtC,CAAC,UACC,OAAO,MAAM,OAAO,YAAY,CAAC,WAAW,SAAS,MAAM,SAAS;AAAA,MACxE;AACA,UAAI,cAAc,QAAQ;AACxB,YAAI;AACF,qBAAW,SAAS,eAAe;AACjC,gBAAI,CAAC,MAAM,GAAI;AACf,kBAAM,WAAW,kBAAkB,MAAM,IAAI;AAAA,cAC3C,cAAc;AAAA,gBACZ;AAAA,gBACA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,SAAS,KAAK;AACZ,kBAAQ,MAAM,uCAAuC,GAAG;AACxD,gBAAM;AAAA,YACJ;AAAA,cACE;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,WAAW,oBAAoB,OAAO;AAC5C,YAAM,wBAAwB,IAAI;AAAA,QAChC,sBAAsB,QACnB,IAAI,CAAC,UAAU,gBAAgB,MAAM,EAAE,CAAC,EACxC,OAAO,CAAC,OAAqB,QAAQ,EAAE,CAAC;AAAA,MAC7C;AACA,YAAM,oBAAoB,IAAI;AAAA,QAC5B,iBACG;AAAA,UAAI,CAAC,UACJ,MAAM,MAAM,MAAM,GAAG,KAAK,EAAE,SAAS,MAAM,KAAK;AAAA,QAClD,EACC,OAAO,CAAC,OAAqB,QAAQ,EAAE,CAAC;AAAA,MAC7C;AACA,YAAM,uBAAuB,MAAM,KAAK,qBAAqB,EAAE;AAAA,QAC7D,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE;AAAA,MACnC;AACA,iBAAW,gBAAgB,sBAAsB;AAC/C,cAAM,WAAW,oCAAoC,cAAc;AAAA,UACjE,cAAc;AAAA,YACZ;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AACA,YAAM,uBAAqD,CAAC;AAC5D,iBAAW,cAAc,kBAAkB;AACzC,YAAI,WAAW,IAAI;AACjB,gBAAM,WAAW,oCAAoC;AAAA,YACnD,IAAI,WAAW;AAAA,YACf,UAAU,WAAW;AAAA,YACrB,cAAc,WAAW;AAAA,YACzB,WAAW,WAAW;AAAA,YACtB,UAAU,WAAW;AAAA,UACvB,CAAC;AACD,+BAAqB,KAAK;AAAA,YACxB,IAAI,WAAW;AAAA,YACf,UAAU,WAAW;AAAA,YACrB,cAAc,OAAO,WAAW,YAAY;AAAA,YAC5C,WAAW,OAAO,WAAW,SAAS;AAAA,YACtC,UAAU,WAAW;AAAA,UACvB,CAAC;AACD;AAAA,QACF;AACA,cAAM,UAAU,MAAM;AAAA,UACpB;AAAA,UACA;AAAA,YACE;AAAA,YACA,UAAU,WAAW;AAAA,YACrB,cAAc,WAAW;AAAA,YACzB,WAAW,WAAW;AAAA,YACtB,UAAU,WAAW;AAAA,UACvB;AAAA,QACF;AACA,cAAM,YACJ,QAAQ,UACR,OAAO,QAAQ,WAAW,YAC1B,OAAQ,QAAQ,OAA4B,OAAO,WAC9C,QAAQ,OAA0B,KACnC;AACN,6BAAqB,KAAK;AAAA,UACxB,IAAI;AAAA,UACJ,UAAU,WAAW;AAAA,UACrB,cAAc,OAAO,WAAW,YAAY;AAAA,UAC5C,WAAW,OAAO,WAAW,SAAS;AAAA,UACtC,UAAU,WAAW;AAAA,QACvB,CAAC;AAAA,MACH;AACA,4BAAsB,UAAU;AAChC,wBAAkB,UAAU;AAAA,QAC1B;AAAA,QACA;AAAA,MACF;AACA,YAAM,EAAE,iCAAiC,kBAAkB,GAAG,SAAS;AACvE,aAAO,KAAK,2BAA2B;AAAA,IACzC;AAAA,IACA,CAAC,WAAW,GAAG,UAAU,MAAM;AAAA,EACjC;AAEA,MAAI,CAAC,WAAW;AACd,WACE,oBAAC,QACC,8BAAC,YACC,8BAAC,SAAI,WAAU,6FACZ;AAAA,MACC;AAAA,MACA;AAAA,IACF,GACF,GACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,QACC,+BAAC,YACE;AAAA,YACC,oBAAC,SAAI,WAAU,kGACZ,iBACH,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,+BAA+B,cAAc;AAAA,QACtD,UAAS;AAAA,QACT,gBAAgB;AAAA,UACd,cAAc;AAAA,UACd,YAAY,YAAY,OAAO,SAAS,IAAI;AAAA,QAC9C;AAAA,QACA,cAAc,YACZ;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ;AAAA,cACN,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,aAAa;AAAA,gBACX,OAAO,eAAe,SAAS;AAAA,cACjC;AAAA,YACF;AAAA,YACA,UAAU,6BAA6B,SAAS;AAAA;AAAA,QAClD,IACE;AAAA,QACJ,QAAQ,CAAC;AAAA,QACT;AAAA,QACA,iBAAgB;AAAA,QAChB,UAAU,EAAE,QAAQ;AAAA,QACpB,wBAAwB;AAAA,UACtB,CAAC,EAAE,QAAQ,eAAe,GAAG,EAAE,UAAU,qBAAqB;AAAA,QAChE;AAAA,QACA,eAAe,iBAAiB;AAAA,QAChC,WAAW;AAAA,QACX,gBAAgB,EAAE,iCAAiC,iBAAiB;AAAA,QACpE,aAAa,EAAE,8BAA8B,cAAc;AAAA,QAC3D,YAAW;AAAA,QACX,UAAU;AAAA;AAAA,IACZ;AAAA,KACF,GACF;AAEJ;AA0BA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,IAAI,KAAK;AACf,QAAM,aAAa,MAAM;AAAA,IACvB,MAAO,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;AAAA,IAC/D,CAAC,OAAO,UAAU;AAAA,EACpB;AAEA,QAAM,yBAAyB,MAAM;AAAA,IACnC,CAAC,cAAkC;AACjC,eAAS,cAAc,SAAS;AAChC,YAAM,aAAa,UAAU;AAAA,QAC3B,CAAC,SAAS,KAAK,OAAO,OAAO;AAAA,MAC/B;AACA,UAAI,CAAC,YAAY;AACf,cAAM,aAAa,UAAU,CAAC,GAAG,MAAM;AACvC,iBAAS,kBAAkB,UAAU;AACrC,YAAI,cAAc,UAAU,CAAC,GAAG;AAC9B;AAAA,YACE;AAAA,YACA,wBAAwB,YAAY;AAAA,cAClC,MAAM,0BAA0B,UAAU,CAAC,EAAE,QAAQ;AAAA,YACvD,CAAC;AAAA,UACH;AAAA,QACF,OAAO;AACL,mBAAS,mBAAmB,EAAE;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU,OAAO,cAAc;AAAA,EAClC;AAEA,QAAM,2BAA2B,MAAM;AAAA,IACrC,CAAC,iBAAgC;AAC/B,eAAS,kBAAkB,YAAY;AACvC,UAAI,CAAC,cAAc;AACjB,iBAAS,mBAAmB,EAAE;AAC9B;AAAA,MACF;AACA,YAAM,SAAS,WAAW,KAAK,CAAC,SAAS,KAAK,OAAO,YAAY;AACjE,UAAI,QAAQ;AACV;AAAA,UACE;AAAA,UACA,wBAAwB,OAAO,IAAI;AAAA,YACjC,MAAM,0BAA0B,OAAO,QAAQ;AAAA,UACjD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,YAAY,QAAQ;AAAA,EACvB;AAEA,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAM,WAAU,2BACd;AAAA,UAAE,+BAA+B,OAAO;AAAA,QACzC,oBAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,SAClC;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,OAAO;AAAA,UACd,UAAU,CAAC,UAAU,SAAS,SAAS,MAAM,OAAO,KAAK;AAAA,UACzD,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,MACC,OAAO,QACN,oBAAC,OAAE,WAAU,wBAAwB,iBAAO,OAAM,IAChD;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,qCACb;AAAA,4BAAC,SAAO,YAAE,qCAAqC,aAAa,GAAE;AAAA,QAC9D;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,SAAS,eAAe,CAAC,OAAO,WAAW;AAAA,YAC1D,WAAU;AAAA,YAET;AAAA,qBAAO,cACN,oBAAC,aAAU,WAAU,WAAU,IAE/B,oBAAC,YAAS,WAAU,WAAU;AAAA,cAE/B,OAAO,cACJ,EAAE,4CAA4C,gBAAgB,IAC9D;AAAA,gBACE;AAAA,gBACA;AAAA,cACF;AAAA;AAAA;AAAA,QACN;AAAA,SACF;AAAA,MACC,OAAO,cACN;AAAA,QAAC;AAAA;AAAA,UACC,mBAAgB;AAAA,UAChB,WAAU;AAAA,UAEV;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,OAAO;AAAA,cACd,QAAQ;AAAA,cACR,UAAU,CAAC,QAAQ,SAAS,eAAe,OAAO,EAAE;AAAA,cACpD,gBAAgB,EAAE,eAAe,CAAC,EAAE;AAAA;AAAA,UACtC;AAAA;AAAA,MACF,IAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,OAAO;AAAA,UACd,UAAU,CAAC,UAAU,SAAS,eAAe,MAAM,OAAO,KAAK;AAAA,UAC/D,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,OAEJ;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,EAAE,QAAQ;AAAA,QACpB,eAAe,OAAO,gBAAgB;AAAA,QACtC,OAAO;AAAA,QACP,gBAAgB,OAAO,kBAAkB;AAAA,QACzC,eAAe;AAAA,QACf,iBAAiB;AAAA;AAAA,IACnB;AAAA,KACF;AAEJ;AAEA,SAAS,yBAAyB;AAAA,EAChC;AAAA,EACA;AACF,GAAkC;AAChC,QAAM,IAAI,KAAK;AACf,QAAM,kBAAkB,2BAA2B,OAAO,UAAU;AACpE,QAAM,eAAe,uBAAuB,OAAO,MAAM;AAEzD,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,QAAG,WAAU,yBACX,YAAE,oCAAoC,qBAAqB,GAC9D;AAAA,IACA,qBAAC,SAAI,WAAU,6BACb;AAAA,2BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,0CAA0C,OAAO,GACtD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO,iBAAiB,SAAS;AAAA,YACjC,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,cAAc;AAAA,gBACrB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,2CAA2C,QAAQ,GACxD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO,iBAAiB,UAAU;AAAA,YAClC,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,cAAc;AAAA,gBACrB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,0CAA0C,OAAO,GACtD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO,iBAAiB,SAAS;AAAA,YACjC,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,cAAc;AAAA,gBACrB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,yCAAyC,WAAW,GACzD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,iBAAiB,QAAQ;AAAA,YAChC,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,cAAc;AAAA,gBACrB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,sCAAsC,QAAQ,GACnD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO,cAAc,SAAS;AAAA,YAC9B,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,UAAU;AAAA,gBACjB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,aACb;AAAA,4BAAC,SAAM,WAAU,2CACd,YAAE,qCAAqC,aAAa,GACvD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,cAAc,QAAQ;AAAA,YAC7B,UAAU,CAAC,UACT;AAAA,cACE;AAAA,cACA;AAAA,gBACE,OAAO,UAAU;AAAA,gBACjB;AAAA,gBACA,MAAM,OAAO;AAAA,cACf;AAAA,YACF;AAAA,YAEF,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,uBAAuB,EAAE,QAAQ,SAAS,GAA0B;AAC3E,QAAM,WAAW,kBAAkB,OAAO,QAAQ;AAClD,QAAM,uBAAuB,MAAM;AAAA,IACjC,CAAC,SAAkC;AACjC,eAAS,YAAY,IAAI;AAAA,IAC3B;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,SACE,oBAAC,kBAAe,OAAO,UAAU,UAAU,sBAAsB,UAAQ,MAAC;AAE9E;AAEA,SAAS,sBAAsB,EAAE,QAAQ,SAAS,GAA0B;AAC1E,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,KAAK;AACpE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAElD,CAAC,CAAC;AACJ,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAS,KAAK;AAChE,QAAM,CAAC,cAAc,eAAe,IAClC,MAAM,SAA6C,IAAI;AAEzD,QAAM,cAAc,MAAM,YAAY,YAAY;AAChD,qBAAiB,IAAI;AACrB,QAAI;AACF,YAAM,MAAM,MAAM;AAAA,QAChB;AAAA,MACF;AACA,UAAI,IAAI,IAAI;AACV;AAAA,UACE,MAAM,QAAQ,IAAI,QAAQ,KAAK,IAAK,IAAI,QAAQ,SAAS,CAAC,IAAK,CAAC;AAAA,QAClE;AAAA,MACF,OAAO;AACL,2BAAmB,CAAC,CAAC;AAAA,MACvB;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,sCAAsC,GAAG;AACvD,yBAAmB,CAAC,CAAC;AAAA,IACvB,UAAE;AACA,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,MAAM;AAAA,IAC/B,OAAO,OAAe;AACpB,UAAI;AACF,cAAM,WAAW,0BAA0B,IAAI;AAAA,UAC7C,cAAc;AAAA,YACZ;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AACD;AAAA,UACE,EAAE,yCAAyC,iBAAiB;AAAA,UAC5D;AAAA,QACF;AACA,aAAK,YAAY;AAAA,MACnB,SAAS,KAAK;AACZ,gBAAQ,MAAM,wCAAwC,GAAG;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,CAAC,aAAa,CAAC;AAAA,EACjB;AAEA,QAAM,mBAAmB,MAAM;AAAA,IAC7B,OAAO,SAAiB;AACtB,UAAI,CAAC,KAAK,KAAK,EAAE,QAAQ;AACvB,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,QACF;AACA,cAAM,oBAAoB,SAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,MACtD;AACA,YAAM,gBAAgB;AAAA,QACpB,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,QAClD;AAAA,MACF;AACA,UAAI,CAAC,cAAc,SAAS,QAAQ;AAClC,cAAM;AAAA,UACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,UACA,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,UAAmC;AAAA,QACvC,MAAM,KAAK,KAAK;AAAA,QAChB,MAAM,QAAQ,KAAK,KAAK,CAAC;AAAA,QACzB,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AACA,UAAI,cAAc,GAAI,SAAQ,KAAK,aAAa;AAChD,UAAI,cAAc,GAAI,OAAM,WAAW,0BAA0B,OAAO;AAAA,UACnE,OAAM,WAAW,0BAA0B,OAAO;AACvD;AAAA,QACE,EAAE,uCAAuC,eAAe;AAAA,QACxD;AAAA,MACF;AACA,wBAAkB,KAAK;AACvB,sBAAgB,IAAI;AACpB,WAAK,YAAY;AAAA,IACnB;AAAA,IACA,CAAC,cAAc,GAAG,OAAO,SAAS,WAAW;AAAA,EAC/C;AAEA,QAAM,0BAA0B,MAAM;AAAA,IACpC,CAAC,UAAkB,cAAsB;AACvC,YAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC,GAAG;AAAA,QACjE,CAAC,WACC,OAAO,OAAO,WAAW,EAAE,GAAG,QAAQ,OAAO,UAAU,IAAI;AAAA,MAC/D;AACA,eAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,IACA,CAAC,UAAU,OAAO,OAAO;AAAA,EAC3B;AAEA,QAAM,kBAAkB,MAAM;AAAA,IAC5B,CAAC,UAAkB,WAAqB;AACtC,YAAM,aAAa,OAChB,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,MAAM;AACjC,YAAM,SAAS,MAAM,KAAK,IAAI,IAAI,UAAU,CAAC;AAC7C,YAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC,GAAG;AAAA,QACjE,CAAC,WAAW;AACV,cAAI,OAAO,OAAO,SAAU,QAAO;AACnC,gBAAM,kBAAkB,IAAI;AAAA,YAC1B,OAAO,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,OAAO,KAAK,CAAC;AAAA,UACnD;AACA,gBAAM,aAAa,OAAO;AAAA,YACxB,CAAC,UACC,gBAAgB,IAAI,KAAK,KAAK,EAAE,IAAI,cAAc,GAAG,MAAM;AAAA,UAC/D;AACA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AACA,eAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,IACA,CAAC,UAAU,OAAO,OAAO;AAAA,EAC3B;AAEA,QAAM,YAAY,MAAM,YAAY,MAAM;AACxC,UAAM,OAAO;AAAA,MACX,GAAI,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACtD,EAAE,IAAI,cAAc,GAAG,OAAO,IAAI,QAAQ,CAAC,EAAE;AAAA,IAC/C;AACA,aAAS,WAAW,IAAI;AAAA,EAC1B,GAAG,CAAC,UAAU,OAAO,OAAO,CAAC;AAE7B,QAAM,eAAe,MAAM;AAAA,IACzB,CAAC,aAAqB;AACpB,YAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC,GAAG;AAAA,QACjE,CAAC,WAAW,OAAO,OAAO;AAAA,MAC5B;AACA,eAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,IACA,CAAC,UAAU,OAAO,OAAO;AAAA,EAC3B;AAEA,SACE,iCACE;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,qDACb;AAAA,4BAAC,QAAG,WAAU,yBACX;AAAA,UACC;AAAA,UACA;AAAA,QACF,GACF;AAAA,QACA,qBAAC,SAAI,WAAU,qCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM;AACb,oCAAoB,IAAI;AACxB,qBAAK,YAAY;AAAA,cACnB;AAAA,cACA,OAAO;AAAA,gBACL;AAAA,gBACA;AAAA,cACF;AAAA,cAEA,8BAAC,cAAW,WAAU,WAAU;AAAA;AAAA,UAClC;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM;AACb,gCAAgB,IAAI;AACpB,kCAAkB,IAAI;AAAA,cACxB;AAAA,cACA,OAAO,EAAE,sCAAsC,gBAAgB;AAAA,cAE/D,8BAAC,QAAK,WAAU,WAAU;AAAA;AAAA,UAC5B;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cAET;AAAA,oCAAC,QAAK,WAAU,gBAAe;AAAA,gBAC9B,EAAE,8CAA8C,YAAY;AAAA;AAAA;AAAA,UAC/D;AAAA,WACF;AAAA,SACF;AAAA,OACE,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC,WAC1D,qBAAC,SAAoB,WAAU,8BAC7B;AAAA,6BAAC,SAAI,WAAU,2BACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,OAAO;AAAA,cACd,UAAU,CAAC,UACT,wBAAwB,OAAO,IAAI,MAAM,OAAO,KAAK;AAAA,cAEvD,aAAa;AAAA,gBACX;AAAA,gBACA;AAAA,cACF;AAAA,cACA,WAAU;AAAA;AAAA,UACZ;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAS,MAAM,aAAa,OAAO,EAAE;AAAA,cAErC,8BAAC,UAAO,WAAU,WAAU;AAAA;AAAA,UAC9B;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,kBACb;AAAA,8BAAC,SAAM,WAAU,2CACd,YAAE,iDAAiD,QAAQ,GAC9D;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,KAAK;AAAA,cAC/C,UAAU,CAAC,WAAW,gBAAgB,OAAO,IAAI,MAAM;AAAA,cACvD,aAAa;AAAA,gBACX;AAAA,gBACA;AAAA,cACF;AAAA;AAAA,UACF;AAAA,WACF;AAAA,WAlCQ,OAAO,EAmCjB,CACD;AAAA,MACA,CAAC,OAAO,SAAS,SAChB,oBAAC,OAAE,WAAU,iCACV;AAAA,QACC;AAAA,QACA;AAAA,MACF,GACF,IACE;AAAA,OACN;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,8BAAoB,IAAI;AACxB,cAAI,KAAM,MAAK,YAAY;AAAA,QAC7B;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU,CAAC,aAAa;AACtB,8BAAoB,KAAK;AACzB,cAAI,CAAC,SAAU;AACf,gBAAM,UAAU,2BAA2B,QAAQ;AACnD,mBAAS,WAAW,OAAO;AAAA,QAC7B;AAAA,QACA,UAAU;AAAA,QACV,QAAQ,CAAC,aAAa;AACpB,0BAAgB,QAAQ;AACxB,4BAAkB,IAAI;AAAA,QACxB;AAAA;AAAA,IACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,4BAAkB,IAAI;AACtB,cAAI,CAAC,KAAM,iBAAgB,IAAI;AAAA,QACjC;AAAA,QACA,aAAa,cAAc,QAAQ;AAAA,QACnC,UAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;AAEA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAwB,IAAI;AACtE,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,CAAC,wBAAwB,yBAAyB,IACtD,MAAM,SAAS,IAAI;AACrB,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAS,KAAK;AACtE,QAAM,oBAAoB,MAAM;AAAA,IAC9B,MAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,IACzD,CAAC,OAAO,OAAO;AAAA,EACjB;AACA,QAAM,SAAS,MAAM;AAAA,IACnB,MAAM,yBAAyB,iBAAiB;AAAA,IAChD,CAAC,iBAAiB;AAAA,EACpB;AACA,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,MAAM,oBAAI,IAAY;AAC5B,aAAS,QAAQ,CAAC,YAAY;AAC5B,YAAM,MAAM,qBAAqB,QAAQ,gBAAgB,MAAS;AAClE,UAAI,IAAK,KAAI,IAAI,GAAG;AAAA,IACtB,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AACb,QAAM,gBAAgB,MAAM;AAAA,IAC1B,MACE,OAAO,OAAO,CAAC,UAAU;AACvB,YAAM,MAAM,qBAAqB,KAAK;AACtC,UAAI,CAAC,IAAK,QAAO;AACjB,aAAO,CAAC,aAAa,IAAI,GAAG;AAAA,IAC9B,CAAC;AAAA,IACH,CAAC,QAAQ,YAAY;AAAA,EACvB;AACA,QAAM,kBAAkB,MAAM,QAAQ,MAAM;AAC1C,UAAM,MAAM,oBAAI,IAA8B;AAC9C,eAAW,QAAQ,YAAY;AAC7B,UAAI,IAAI,KAAK,IAAI,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AACf,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,sBAAsB;AACnC,UAAI;AACF,cAAM,UAAU,MAAM;AAAA,UAIpB;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,CAAC,yBAAyB,EAAE,CAAC;AAAA,UAChE;AAAA,UACA,EAAE,iBAAiB,KAAK;AAAA,QAC1B;AACA,YAAI,UAAW;AACf,cAAM,gBAAgB,MAAM,QAAQ,SAAS,OAAO,IAChD,SAAS,UACT,CAAC;AACL,cAAM,UAAW,cAA4B;AAAA,UAC3C,CAAC,UACC,OAAO,UAAU,YAAY,MAAM,SAAS;AAAA,QAChD;AACA,cAAM,aACJ,SAAS,OAAO,QAAQ,QAAQ,SAAS,yBAAyB;AACpE,6BAAqB,UAAU;AAAA,MACjC,QAAQ;AACN,YAAI,CAAC,UAAW,sBAAqB,KAAK;AAAA,MAC5C,UAAE;AACA,YAAI,CAAC,UAAW,2BAA0B,KAAK;AAAA,MACjD;AAAA,IACF;AACA,wBAAoB,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACpC,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AACL,QAAM,sBAAsB,qBAAqB,CAAC;AAClD,QAAM,mBAAmB,MAAM;AAAA,IAC7B,CAAC,UAAuC;AACtC,YAAM,OAAO,MAAM,cACf,gBAAgB,IAAI,MAAM,WAAW,IACrC;AACJ,UAAI,MAAM,MAAO,QAAO,KAAK;AAC7B,UAAI,MAAM,KAAM,QAAO,KAAK,KAAK,YAAY;AAC7C,aAAO,EAAE,mDAAmD,OAAO;AAAA,IACrE;AAAA,IACA,CAAC,iBAAiB,CAAC;AAAA,EACrB;AACA,QAAM,oBAAoB,MAAM;AAAA,IAC9B,CAAC,UAAuC;AACtC,YAAM,SACJ,OAAO,MAAM,WAAW,YAAY,MAAM,OAAO,KAAK,EAAE,SACpD,MAAM,OAAO,KAAK,IAClB;AACN,UAAI,CAAC,OAAQ,QAAO;AACpB,UAAI,CAAC,MAAM,aAAc,QAAO;AAChC,aAAO,GAAG,MAAM,aAAa,YAAY,CAAC,IAAI,MAAM;AAAA,IACtD;AAAA,IACA,CAAC;AAAA,EACH;AACA,QAAM,sBAAsB,MAAM;AAAA,IAChC,OAAO,YAA4B;AACjC,UAAI,CAAC,oBAAqB;AAC1B,YAAM,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,QAAQ;AACrD,YAAM,iBAAiB;AAAA,QACrB;AAAA,QACA;AAAA,MACF,EAAE,QAAQ,YAAY,KAAK;AAC3B,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AACD,UAAI,CAAC,UAAW;AAChB,oBAAc,QAAQ,EAAE;AACxB,UAAI;AACF,cAAM,WAAW,oBAAoB,QAAQ,IAAI;AAAA,UAC/C,cAAc;AAAA,YACZ;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AACD;AAAA,UACE,EAAE,iCAAiC,kBAAkB;AAAA,UACrD;AAAA,QACF;AACA,yBAAiB,QAAQ,EAAE;AAAA,MAC7B,SAAS,KAAK;AACZ,gBAAQ,MAAM,yCAAyC,GAAG;AAC1D;AAAA,UACE,EAAE,qCAAqC,2BAA2B;AAAA,UAClE;AAAA,QACF;AAAA,MACF,UAAE;AACA,sBAAc,IAAI;AAAA,MACpB;AAAA,IACF;AAAA,IACA,CAAC,qBAAqB,SAAS,kBAAkB,CAAC;AAAA,EACpD;AACA,QAAM,yBAAyB,MAAM,YAAY,YAAY;AAC3D,QAAI,CAAC,aAAa,CAAC,oBAAqB;AACxC,QAAI,CAAC,cAAc,QAAQ;AACzB;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AACA,kBAAc,IAAI;AAClB,QAAI;AACF,iBAAW,SAAS,eAAe;AACjC,cAAM,QACJ,OAAO,OAAO,KAAK,EAChB,IAAI,CAAC,UAAU,OAAO,KAAK,CAAC,EAC5B,OAAO,CAAC,UAAU,SAAS,MAAM,MAAM,EACvC,KAAK,KAAK,KACb,EAAE,kDAAkD,SAAS;AAC/D,cAAM,WAAW,oBAAoB;AAAA,UACnC;AAAA,UACA,MAAM;AAAA,UACN,cAAc;AAAA,UACd,WAAW;AAAA,UACX,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AACA;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF;AACA,UAAI,iBAAkB,OAAM,iBAAiB;AAAA,IAC/C,SAAS,KAAK;AACZ,cAAQ,MAAM,8CAA8C,GAAG;AAC/D;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,qBAAqB,eAAe,kBAAkB,WAAW,CAAC,CAAC;AAEvE,QAAM,qBACJ,kBAAkB,SAAS,KAAK;AAElC,SACE,iCACE;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,qDACb;AAAA,4BAAC,QAAG,IAAG,YAAW,WAAU,yBACzB,YAAE,kCAAkC,UAAU,GACjD;AAAA,QACA,qBAAC,SAAI,WAAU,qCACZ;AAAA,+BACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS,MAAM;AACb,qBAAK,uBAAuB;AAAA,cAC9B;AAAA,cAEC,uBACG;AAAA,gBACE;AAAA,gBACA;AAAA,cACF,IACA;AAAA,gBACE;AAAA,gBACA;AAAA,cACF;AAAA;AAAA,UACN,IACE;AAAA,UACH,sBACC,oBAAC,UAAO,SAAO,MAAC,MAAK,MACnB;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,6BAA6B,SAAS;AAAA,cAE5C;AAAA,oCAAC,QAAK,WAAU,gBAAe;AAAA,gBAC9B,EAAE,sCAAsC,aAAa;AAAA;AAAA;AAAA,UACxD,GACF,IACE;AAAA,WACN;AAAA,SACF;AAAA,MACC,SAAS,SACR,oBAAC,SAAI,WAAU,qCACb,+BAAC,WAAM,WAAU,6BACf;AAAA,4BAAC,WAAM,WAAU,iEACf,+BAAC,QACC;AAAA,8BAAC,QAAG,WAAU,yBACX,YAAE,kCAAkC,SAAS,GAChD;AAAA,UACA,oBAAC,QAAG,WAAU,yBAAwB,iBAAG;AAAA,UACzC,oBAAC,QAAG,WAAU,yBACX;AAAA,YACC;AAAA,YACA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,QAAG,WAAU,yBACX,YAAE,0CAA0C,SAAS,GACxD;AAAA,UACA,oBAAC,QAAG,WAAU,oCACX,YAAE,6CAA6C,SAAS,GAC3D;AAAA,WACF,GACF;AAAA,QACA,oBAAC,WACE,mBAAS,IAAI,CAAC,YACb,qBAAC,QAAoB,WAAU,8BAC7B;AAAA,8BAAC,QAAG,WAAU,aACZ;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,6BAA6B,SAAS,aAAa,QAAQ,EAAE;AAAA,cACnE,WAAU;AAAA,cAET,kBAAQ,QAAQ,QAAQ;AAAA;AAAA,UAC3B,GACF;AAAA,UACA,oBAAC,QAAG,WAAU,mCACX,kBAAQ,OAAO,UAClB;AAAA,UACA,oBAAC,QAAG,WAAU,aACX,kBAAQ,OAAO,SACd,oBAAC,QAAG,WAAU,aACX,kBAAQ,OAAO,IAAI,CAAC,UACnB;AAAA,YAAC;AAAA;AAAA,cAEC,WAAU;AAAA,cAEV;AAAA,oCAAC,UAAK,WAAU,+BACb,2BAAiB,KAAK,GACzB;AAAA,gBAAQ;AAAA,gBACR,oBAAC,UAAM,4BAAkB,KAAK,GAAE;AAAA;AAAA;AAAA,YAN3B,MAAM;AAAA,UAOb,CACD,GACH,IAEA,oBAAC,UAAK,WAAU,iCACb;AAAA,YACC;AAAA,YACA;AAAA,UACF,GACF,GAEJ;AAAA,UACA,oBAAC,QAAG,WAAU,mCACX,kBAAQ,YAAY,EAAE,cAAc,KAAK,IAAI,UAChD;AAAA,UACA,oBAAC,QAAG,WAAU,aACZ,+BAAC,SAAI,WAAU,oCACb;AAAA,gCAAC,UAAO,SAAO,MAAC,MAAK,MAAK,SAAQ,WAChC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM,6BAA6B,SAAS,aAAa,QAAQ,EAAE;AAAA,gBAElE,YAAE,sCAAsC,MAAM;AAAA;AAAA,YACjD,GACF;AAAA,YACC,sBACC;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,UAAU,eAAe,QAAQ;AAAA,gBACjC,SAAS,MAAM;AACb,uBAAK,oBAAoB,OAAO;AAAA,gBAClC;AAAA,gBAEC,yBAAe,QAAQ,KACpB;AAAA,kBACE;AAAA,kBACA;AAAA,gBACF,IACA;AAAA,kBACE;AAAA,kBACA;AAAA,gBACF;AAAA;AAAA,YACN,IACE;AAAA,aACN,GACF;AAAA,aAvEO,QAAQ,EAwEjB,CACD,GACH;AAAA,SACF,GACF,IAEA,oBAAC,OAAE,WAAU,iCACV;AAAA,QACC;AAAA,QACA;AAAA,MACF,GACF;AAAA,OAEJ;AAAA,IACC;AAAA,KACH;AAEJ;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,IAAI,KAAK;AACf,QAAM,cAAc,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AACxE,QAAM,cAAc,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AACtE,QAAM,uBAAuB,MAAM,OAAO,YAAY,KAAK,EAAE,WAAW,CAAC;AAEzE,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,qBAAqB,QAAS;AACnC,UAAM,kBAAkB,YAAY,KAAK;AACzC,QAAI,CAAC,iBAAiB;AACpB,UAAI,aAAa;AACf,iBAAS,UAAU,EAAE;AAAA,MACvB;AACA;AAAA,IACF;AACA,UAAM,aAAa,QAAQ,eAAe;AAC1C,QAAI,eAAe,aAAa;AAC9B,eAAS,UAAU,UAAU;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,aAAa,aAAa,QAAQ,CAAC;AAEvC,QAAM,0BAA0B,MAAM;AAAA,IACpC,CAAC,UAA+C;AAC9C,YAAM,YAAY,MAAM,OAAO;AAC/B,2BAAqB,UAAU,UAAU,KAAK,EAAE,WAAW;AAC3D,eAAS,UAAU,SAAS;AAAA,IAC9B;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,uBAAuB,MAAM,YAAY,MAAM;AACnD,UAAM,OAAO,QAAQ,WAAW;AAChC,yBAAqB,UAAU;AAC/B,aAAS,UAAU,IAAI;AAAA,EACzB,GAAG,CAAC,aAAa,QAAQ,CAAC;AAE1B,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAO,YAAE,kCAAkC,UAAU,GAAE;AAAA,MACxD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW;AAAA,UAC/D,UAAU,CAAC,UAAU,SAAS,YAAY,MAAM,OAAO,KAAK;AAAA,UAC5D,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,MACC,OAAO,WACN,oBAAC,OAAE,WAAU,wBAAwB,iBAAO,UAAS,IACnD;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,2CACb;AAAA,4BAAC,SACE,YAAE,4CAA4C,QAAQ,GACzD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS;AAAA,YAER,YAAE,kDAAkD,UAAU;AAAA;AAAA,QACjE;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU;AAAA,UACV,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA,UACA,WAAU;AAAA;AAAA,MACZ;AAAA,MACA,oBAAC,OAAE,WAAU,iCACV;AAAA,QACC;AAAA,QACA;AAAA,MACF,GACF;AAAA,MACC,OAAO,SACN,oBAAC,OAAE,WAAU,wBAAwB,iBAAO,QAAO,IACjD;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAO,YAAE,6BAA6B,KAAK,GAAE;AAAA,MAC9C;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,OAAO;AAAA,UACd,UAAU,CAAC,UAAU,SAAS,OAAO,MAAM,OAAO,KAAK;AAAA,UACvD,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA,UACA,WAAU;AAAA;AAAA,MACZ;AAAA,MACA,oBAAC,OAAE,WAAU,iCACV;AAAA,QACC;AAAA,QACA;AAAA,MACF,GACF;AAAA,MACC,OAAO,MACN,oBAAC,OAAE,WAAU,wBAAwB,iBAAO,KAAI,IAC9C;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SACE,YAAE,qCAAqC,cAAc,GACxD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,OAAO,eAAe;AAAA,UAC7B,UAAU,CAAC,UAAU;AACnB,kBAAM,WAAW,MAAM,OAAO;AAC9B,qBAAS,eAAe,QAAQ;AAChC,kBAAM,qBACJ,0BAA0B,QAAQ;AACpC,gBAAI,sBAAsB,CAAC,OAAO,aAAa;AAC7C,uBAAS,eAAe,IAAI;AAAA,YAC9B,WACE,CAAC,sBACD,OAAO,aACP;AACA,uBAAS,eAAe,KAAK;AAAA,YAC/B;AAAA,UACF;AAAA,UAEC,gCAAsB,IAAI,CAAC,SAAS;AACnC,kBAAM,aACJ,SAAS,YAAY,SAAS;AAChC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO;AAAA,gBACP,UAAU;AAAA,gBAET;AAAA;AAAA,oBACC,0BAA0B,IAAI;AAAA,oBAC9B;AAAA,kBACF;AAAA,kBACC,aACG,KAAK,EAAE,qBAAqB,aAAa,CAAC,MAC1C;AAAA;AAAA;AAAA,cAVC;AAAA,YAWP;AAAA,UAEJ,CAAC;AAAA;AAAA,MACH;AAAA,MACC,OAAO,cACN,oBAAC,OAAE,WAAU,wBACV,iBAAO,aACV,IACE;AAAA,OACN;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,2CACb;AAAA,4BAAC,SACE,YAAE,0CAA0C,WAAW,GAC1D;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM;AACb,kBAAI,OAAO,WAAW,aAAa;AACjC,uBAAO;AAAA,kBACL;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA,OAAO;AAAA,cACL;AAAA,cACA;AAAA,YACF;AAAA,YACA,WAAU;AAAA,YAEV;AAAA,kCAAC,UAAO,WAAU,WAAU;AAAA,cAC5B,oBAAC,UAAK,WAAU,WACb;AAAA,gBACC;AAAA,gBACA;AAAA,cACF,GACF;AAAA;AAAA;AAAA,QACF;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,OAAO,aAAa;AAAA,UAC3B,UAAU,CAAC,UACT,SAAS,aAAa,MAAM,OAAO,SAAS,IAAI;AAAA,UAElD,UAAU,CAAC,SAAS;AAAA,UAEpB;AAAA,gCAAC,YAAO,OAAM,IACX,mBAAS,SACN;AAAA,cACE;AAAA,cACA;AAAA,YACF,IACA;AAAA,cACE;AAAA,cACA;AAAA,YACF,GACN;AAAA,YACC,SAAS,IAAI,CAAC,SACb,oBAAC,YAAqB,OAAO,KAAK,IAC/B,6BAAmB,IAAI,KADb,KAAK,EAElB,CACD;AAAA;AAAA;AAAA,MACH;AAAA,MACA,oBAAC,OAAE,WAAU,iCACV,mBAAS,SACN;AAAA,QACE;AAAA,QACA;AAAA,MACF,IACA;AAAA,QACE;AAAA,QACA;AAAA,MACF,GACN;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,kBAAkB,OAAqC;AAC9D,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,CAAC;AACjD,QAAM,UAAU,OAAO,QAAQ,KAAgC,EAAE;AAAA,IAC/D,CAAC,CAAC,GAAG,MACH,CAAC,IAAI,WAAW,IAAI,KAAK,QAAQ,gBAAgB,QAAQ;AAAA,EAC7D;AACA,SAAO,OAAO,YAAY,OAAO;AACnC;AAEA,SAAS,iBAAiB,UAAqD;AAC7E,QAAM,MAAM,MAAM,QAAQ,SAAS,YAAY,IAC3C,SAAS,eACT,MAAM,QAAQ,SAAS,aAAa,IAClC,SAAS,gBACT,CAAC;AACP,SAAO,IACJ,IAAI,CAAC,WAAW;AACf,QAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,UAAM,SAAS,MAAM,QAAQ,OAAO,MAAM,IACtC,OAAO,OACJ;AAAA,MAAI,CAAC,UACJ,SAAS,OAAO,UAAU,WACtB;AAAA,QACE,IAAI,OAAO,MAAM,MAAM,cAAc,CAAC;AAAA,QACtC,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAAA,MACzD,IACA;AAAA,IACN,EACC;AAAA,MACC,CACE,UAC2C,CAAC,CAAC;AAAA,IACjD,IACF,CAAC;AACL,WAAO;AAAA,MACL,IAAI,OAAO,OAAO,MAAM,cAAc,CAAC;AAAA,MACvC,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,MACzD;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,UAAuC,CAAC,CAAC,KAAK;AAC3D;AAEA,SAAS,oBAAoB,QAE3B;AACA,QAAM,eAAwC,CAAC;AAC/C,SAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,QAAI,IAAI,WAAW,KAAK,EAAG,cAAa,GAAG,IAAI;AAAA,aACtC,IAAI,WAAW,KAAK,EAAG,cAAa,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,IAAI;AAAA,EACvE,CAAC;AACD,SAAO,EAAE,aAAa;AACxB;AAEA,SAAS,gBAAgB,OAA0B;AACjD,QAAM,MAAM,MAAM,QAAQ,KAAK,IAC3B,MACG,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,EAAG,EAC9D,OAAO,CAAC,UAAU,MAAM,MAAM,IACjC,CAAC;AACL,SAAO,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC;AAChC;AAEA,SAAS,mBAAmB,OAA0B;AACpD,QAAM,OAAO,MAAM,QAAQ,KAAK,IAC5B,MACG,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,EAAG,EAC9D,OAAO,CAAC,UAAU,MAAM,MAAM,IACjC,CAAC;AACL,SAAO,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACjC;AAEA,SAAS,oBACP,MACA,UACA,YACQ;AACR,QAAM,OAAO,QAAQ;AACrB,SAAO,aAAa,GAAG,IAAI,MAAM,UAAU,KAAK;AAClD;AAEA,SAAS,uBAAuB,QAG9B;AACA,QAAM,gBAAgB,MAAM;AAAA,IACzB,OAAmC;AAAA,EACtC,IACM,OAAmC,aAGrC,CAAC;AACL,QAAM,UAAU,cACb,IAAI,CAAC,UAAU;AACd,UAAM,QACJ,UAAU,MAAM,EAAE,KAClB,UAAU,MAAM,UAAU,KAC1B,UAAU,MAAM,WAAW;AAC7B,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,OAAO,UAAU,MAAM,IAAI;AACjC,UAAM,aAAa,UAAU,MAAM,UAAU;AAC7C,UAAM,QAAQ,oBAAoB,MAAM,OAAO,UAAU;AACzD,UAAM,cACJ,cAAc,CAAC,MAAM,YAAY,EAAE,SAAS,WAAW,YAAY,CAAC,IAChE,aACA;AACN,WAAO,EAAE,OAAO,OAAO,YAAY;AAAA,EACrC,CAAC,EACA;AAAA,IACC,CACE,WASG,CAAC,CAAC;AAAA,EACT;AACF,QAAM,cAAc;AAAA,IACjB,OAAmC;AAAA,EACtC;AACA,QAAM,cAAc,MAAM;AAAA,IACxB,oBAAI,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,WAAW,OAAO,KAAK,GAAG,GAAG,WAAW,CAAC;AAAA,EACpE;AACA,SAAO,EAAE,KAAK,aAAa,QAAQ;AACrC;AAEA,SAAS,kBAAkB,QAGzB;AACA,QAAM,SAAS,mBAAoB,OAAmC,IAAI;AAC1E,QAAM,UAAU,OAAO,IAAI,CAAC,WAAW,EAAE,OAAO,OAAO,MAAM,EAAE;AAC/D,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,SAAS,mBAAmB,QAAkD;AAC5E,QAAM,YAAY,MAAM,QAAS,OAAmC,MAAM,IACpE,OAAmC,SAGrC,CAAC;AACL,QAAM,YAA6B,CAAC;AACpC,aAAW,SAAS,WAAW;AAC7B,QAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,UAAM,YACJ,UAAU,MAAM,SAAS,KAAK,UAAU,MAAM,UAAU,KAAK;AAC/D,QAAI,CAAC,UAAW;AAChB,cAAU,KAAK;AAAA,MACb,IAAI,UAAU,MAAM,EAAE;AAAA,MACtB;AAAA,MACA,OAAO,UAAU,MAAM,KAAK,KAAK;AAAA,MACjC,aAAa,UAAU,MAAM,WAAW,KAAK;AAAA,MAC7C,gBACE,UAAU,MAAM,cAAc,KAAK,UAAU,MAAM,gBAAgB;AAAA,MACrE,iBACE,UAAU,MAAM,eAAe,KAAK,UAAU,MAAM,iBAAiB;AAAA,MACvE,UAAU,SAAS,MAAM,QAAQ,IAC5B,MAAM,WACP;AAAA,MACJ,UAAU,MAAM,aAAa;AAAA,MAC7B,aACE,UAAU,MAAM,WAAW,KAAK,UAAU,MAAM,YAAY;AAAA,MAC9D,aACE,UAAU,MAAM,WAAW,KAAK,UAAU,MAAM,YAAY;AAAA,IAChE,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAAmC;AAC5D,SAAO,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC;AACnE;AAEA,SAAS,oBACP,QACiC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,UAA2C,CAAC;AAClD,aAAW,SAAS,QAAQ;AAC1B,QAAI,KAAK,IAAI,MAAM,SAAS,EAAG;AAC/B,SAAK,IAAI,MAAM,SAAS;AACxB,UAAM,QAAQ,MAAM,eAAe,MAAM,eAAe,MAAM;AAC9D,UAAM,cACJ,MAAM,eAAe,MAAM,gBAAgB,QACvC,MAAM,cACN;AACN,YAAQ,KAAK;AAAA,MACX,OAAO,MAAM;AAAA,MACb;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAaA,SAAS,mBAAmB,QAST;AACjB,QAAM,EAAE,YAAY,gBAAgB,SAAS,IAAI;AACjD,QAAM,YAAY,IAAI;AAAA,IACpB,eAAe,IAAI,CAAC,UAAU,CAAC,MAAM,WAAW,KAAK,CAAC;AAAA,EACxD;AACA,QAAM,WAA2B,CAAC;AAClC,QAAM,gBAAgB,SAAS,MAAM,KAAK;AAC1C,aAAW,aAAa,YAAY;AAClC,UAAM,WAAW,UAAU,IAAI,SAAS;AACxC,UAAM,QAAQ,aAAa,UAAU,KAAK,KAAK;AAC/C,UAAM,cACJ,aAAa,UAAU,WAAW,KAAK,aAAa,SAAS,WAAW;AAC1E,aAAS,KAAK;AAAA,MACZ,IAAI,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBACE,UAAU,kBAAkB,SAAS,kBAAkB;AAAA,MACzD,iBACE,UAAU,mBAAmB,SAAS,mBAAmB;AAAA,MAC3D,UAAU,UAAU,YAAY;AAAA,MAChC,UAAU,UAAU,YAAY;AAAA,IAClC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,oBACP,SACA,UACiB;AACjB,QAAM,mBAAmB,IAAI;AAAA,IAC3B,QAAQ,IAAI,CAAC,aAAa,CAAC,SAAS,WAAW,QAAQ,CAAC;AAAA,EAC1D;AACA,SAAO,SAAS,IAAI,CAAC,UAAU;AAC7B,UAAM,WAAW,iBAAiB,IAAI,MAAM,SAAS;AACrD,WAAO;AAAA,MACL,IAAI,MAAM,MAAM,UAAU,MAAM;AAAA,MAChC,WAAW,MAAM;AAAA,MACjB,OAAO,MAAM,SAAS,UAAU,SAAS;AAAA,MACzC,aAAa,MAAM,eAAe,UAAU,eAAe;AAAA,MAC3D,gBAAgB,MAAM,kBAAkB,UAAU,kBAAkB;AAAA,MACpE,iBACE,MAAM,mBAAmB,UAAU,mBAAmB;AAAA,MACxD,UAAU,MAAM,YAAY,UAAU,YAAY;AAAA,MAClD,UAAU,MAAM,YAAY,UAAU,YAAY;AAAA,MAClD,aAAa,UAAU,eAAe;AAAA,MACtC,aAAa,UAAU,eAAe;AAAA,IACxC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UAAU,OAA+B;AAChD,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,OAAQ,QAAO,MAAM,KAAK;AACxE,SAAO;AACT;AAEA,SAAS,aAAa,OAAoC;AACxD,QAAM,aAAa,UAAU,KAAK;AAClC,SAAO,cAAc;AACvB;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACrE;AAEA,SAAS,iBAAiB,QAAiC;AACzD,QAAM,kBAAkB,SAAS,OAAO,UAAU,IAC7C,OAAO,aACR;AACJ,QAAM,cAAc;AAAA,IAClB,OAAO,gBAAgB,OAAO;AAAA,EAChC;AACA,QAAM,mBAAmB;AAAA,IACvB,OAAO,sBAAsB,OAAO;AAAA,EACtC;AACA,QAAM,2BAA2B;AAAA,IAC/B,OAAO,+BAA+B,OAAO;AAAA,EAC/C;AACA,QAAM,gBAAgB;AAAA,IACpB,OAAO,sBAAsB,OAAO;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,kBAAkB;AAAA,IACtB,OAAO,qBAAqB,OAAO;AAAA,EACrC;AACA,QAAM,eACJ,oBAAoB,UAAU,oBAAoB,OAC9C,kBACA;AACN,QAAM,mBAAmB;AAAA,IACvB,iBAAiB,WACjB,OAAO,sBACP,OAAO;AAAA,EACT;AACA,QAAM,yBAAyB;AAAA,IAC7B,iBAAiB,kBACf,iBAAiB,iBACjB,OAAO,6BACP,OAAO;AAAA,EACX;AACA,QAAM,wBAAwB;AAAA,IAC5B,iBAAiB,iBACf,iBAAiB,gBACjB,OAAO,4BACP,OAAO;AAAA,EACX;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBACP,QACyB;AACzB,QAAM,WAAW,kBAAkB,OAAO,QAAQ;AAClD,WAAS,gBAAgB,OAAO,eAAe;AAC/C,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO;AACT;AAEA,SAAS,4BACP,QACmC;AACnC,MAAI,CAAC,UAAU,CAAC,MAAM,QAAQ,OAAO,OAAO,EAAG,QAAO;AACtD,SAAO;AAAA,IACL,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AAAA,IAC/D,MAAM,OAAO,QAAQ;AAAA,IACrB,aAAa,OAAO,eAAe;AAAA,IACnC,SAAS,OAAO,QAAQ,IAAI,CAAC,WAAW;AACtC,YAAM,OAAO,OAAO,MAAM,KAAK,KAAK,cAAc;AAClD,YAAM,QAAQ,OAAO,OAAO,KAAK,KAAK;AACtC,YAAM,YACJ,OAAO,cAAc,UACrB,OAAO,cAAc,cACrB,OAAO,cAAc,WACjB,OAAO,YACP;AACN,YAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,IACxC,OAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,cAAM,aAAa,OAAO,MAAM,KAAK,KAAK,cAAc;AACxD,cAAM,cAAc,OAAO,OAAO,KAAK,KAAK;AAC5C,eAAO,EAAE,MAAM,YAAY,OAAO,YAAY;AAAA,MAChD,CAAC,IACD,CAAC;AACL,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,OAAO,eAAe;AAAA,QACnC;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,uBACP,SACA,MACoB;AACpB,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,SAAS,QAAQ,IAAI,CAAC,YAAY;AAAA,MAChC,MAAM,QAAQ,OAAO,SAAS,cAAc,CAAC;AAAA,MAC7C,OAAO,OAAO;AAAA,MACd,WAAW;AAAA,MACX,SAAS,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,QACrC,MAAM,QAAQ,MAAM,SAAS,MAAM,EAAE;AAAA,QACrC,OAAO,MAAM;AAAA,MACf,EAAE;AAAA,IACJ,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,2BACP,UACsB;AACtB,QAAM,SAAS,4BAA4B,UAAU,MAAM;AAC3D,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,SAAO,8BAA8B,MAAM;AAC7C;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,IAAI,KAAK;AACf,SACE,oBAAC,UAAO,MAAY,cAClB,+BAAC,iBAAc,WAAU,YACvB;AAAA,wBAAC,gBACC,8BAAC,eACE,YAAE,6CAA6C,gBAAgB,GAClE,GACF;AAAA,IACC,YACC,oBAAC,SAAI,WAAU,QACb;AAAA,MAAC;AAAA;AAAA,QACC,WAAS;AAAA,QACT,gBAAgB;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAAA,QACA,aAAY;AAAA,QAEZ,0CAAE;AAAA;AAAA,IACJ,GACF,IACE,UAAU,SACZ,oBAAC,SAAI,WAAU,8BACZ,oBAAU,IAAI,CAAC,aAAa;AAC3B,YAAM,KAAK,OAAO,SAAS,OAAO,WAAW,SAAS,KAAK;AAC3D,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAEV;AAAA,iCAAC,SACC;AAAA,kCAAC,OAAE,WAAU,uBACV,mBAAS,QAAQ,SAAS,MAAM,UACnC;AAAA,cACC,SAAS,cACR,oBAAC,OAAE,WAAU,iCACV,mBAAS,aACZ,IACE;AAAA,eACN;AAAA,YACA,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,SAAS,MAAM,SAAS,QAAQ;AAAA,kBAE/B,YAAE,uCAAuC,OAAO;AAAA;AAAA,cACnD;AAAA,cACC,KACC,iCACE;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,SAAS,MAAM,OAAO,QAAQ;AAAA,oBAE9B;AAAA,0CAAC,QAAK,WAAU,WAAU;AAAA,sBAC1B,oBAAC,UAAK,WAAU,WACb;AAAA,wBACC;AAAA,wBACA;AAAA,sBACF,GACF;AAAA;AAAA;AAAA,gBACF;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,SAAS,MAAM,KAAK,SAAS,EAAE;AAAA,oBAE/B;AAAA,0CAAC,UAAO,WAAU,4BAA2B;AAAA,sBAC7C,oBAAC,UAAK,WAAU,WACb;AAAA,wBACC;AAAA,wBACA;AAAA,sBACF,GACF;AAAA;AAAA;AAAA,gBACF;AAAA,iBACF,IACE;AAAA,eACN;AAAA;AAAA;AAAA,QAtDK,MAAM,SAAS,QAAQ,cAAc;AAAA,MAuD5C;AAAA,IAEJ,CAAC,GACH,IAEA,oBAAC,OAAE,WAAU,sCACV,YAAE,uCAAuC,uBAAuB,GACnE;AAAA,KAEJ,GACF;AAEJ;AAmBA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAA0B;AACxB,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,WAAW;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAEhD,QAAM,UAAU,MAAM;AACpB,QAAI,KAAM,SAAQ,WAAW;AAAA,EAC/B,GAAG,CAAC,aAAa,IAAI,CAAC;AAEtB,QAAM,eAAe,MAAM,YAAY,YAAY;AACjD,cAAU,IAAI;AACd,QAAI;AACF,YAAM,SAAS,IAAI;AACnB,mBAAa,KAAK;AAAA,IACpB,SAAS,KAAK;AACZ,cAAQ,MAAM,sBAAsB,GAAG;AAAA,IACzC,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,MAAM,cAAc,QAAQ,CAAC;AAEjC,SACE,oBAAC,UAAO,MAAY,cAClB,+BAAC,iBACC;AAAA,wBAAC,gBACC,8BAAC,eACE,YAAE,2CAA2C,oBAAoB,GACpE,GACF;AAAA,IACA,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAM,SAAQ,cACZ,YAAE,2CAA2C,aAAa,GAC7D;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,OAAO;AAAA,UACP,UAAU,CAAC,UAAU,QAAQ,MAAM,OAAO,KAAK;AAAA,UAC/C,aAAa;AAAA,YACX;AAAA,YACA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,OACF;AAAA,IACA,qBAAC,gBACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,SAAS,MAAM,aAAa,KAAK;AAAA,UAEhC,YAAE,iBAAiB,QAAQ;AAAA;AAAA,MAC9B;AAAA,MACA,oBAAC,UAAO,MAAK,UAAS,SAAS,cAAc,UAAU,QACpD,mBAAS,EAAE,iBAAiB,cAAS,IAAI,EAAE,eAAe,MAAM,GACnE;AAAA,OACF;AAAA,KACF,GACF;AAEJ;",
6
6
  "names": ["getString"]
7
7
  }