@endora-commerce/mod-taxes 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/admin/index.d.ts +25 -0
  4. package/dist/admin/index.d.ts.map +1 -0
  5. package/dist/admin/index.js +34 -0
  6. package/dist/admin/index.js.map +1 -0
  7. package/dist/admin/pages/TaxesPage.d.ts +4 -0
  8. package/dist/admin/pages/TaxesPage.d.ts.map +1 -0
  9. package/dist/admin/pages/TaxesPage.js +135 -0
  10. package/dist/admin/pages/TaxesPage.js.map +1 -0
  11. package/dist/backend/demo/reset.d.ts +13 -0
  12. package/dist/backend/demo/reset.d.ts.map +1 -0
  13. package/dist/backend/demo/reset.js +11 -0
  14. package/dist/backend/demo/reset.js.map +1 -0
  15. package/dist/backend/demo/rows.d.ts +33 -0
  16. package/dist/backend/demo/rows.d.ts.map +1 -0
  17. package/dist/backend/demo/rows.js +27 -0
  18. package/dist/backend/demo/rows.js.map +1 -0
  19. package/dist/backend/demo/seed.d.ts +16 -0
  20. package/dist/backend/demo/seed.d.ts.map +1 -0
  21. package/dist/backend/demo/seed.js +31 -0
  22. package/dist/backend/demo/seed.js.map +1 -0
  23. package/dist/backend/entities/tax.entity.d.ts +21 -0
  24. package/dist/backend/entities/tax.entity.d.ts.map +1 -0
  25. package/dist/backend/entities/tax.entity.js +83 -0
  26. package/dist/backend/entities/tax.entity.js.map +1 -0
  27. package/dist/backend/index.d.ts +76 -0
  28. package/dist/backend/index.d.ts.map +1 -0
  29. package/dist/backend/index.js +86 -0
  30. package/dist/backend/index.js.map +1 -0
  31. package/dist/backend/routes.d.ts +9 -0
  32. package/dist/backend/routes.d.ts.map +1 -0
  33. package/dist/backend/routes.js +63 -0
  34. package/dist/backend/routes.js.map +1 -0
  35. package/dist/backend/services/tax-country-reference.d.ts +12 -0
  36. package/dist/backend/services/tax-country-reference.d.ts.map +1 -0
  37. package/dist/backend/services/tax-country-reference.js +24 -0
  38. package/dist/backend/services/tax-country-reference.js.map +1 -0
  39. package/dist/backend/services/tax-service.d.ts +51 -0
  40. package/dist/backend/services/tax-service.d.ts.map +1 -0
  41. package/dist/backend/services/tax-service.js +169 -0
  42. package/dist/backend/services/tax-service.js.map +1 -0
  43. package/dist/manifest.d.ts +169 -0
  44. package/dist/manifest.d.ts.map +1 -0
  45. package/dist/manifest.js +113 -0
  46. package/dist/manifest.js.map +1 -0
  47. package/dist/migrations/20260426T081516_taxes_promotions_init.d.ts +14 -0
  48. package/dist/migrations/20260426T081516_taxes_promotions_init.d.ts.map +1 -0
  49. package/dist/migrations/20260426T081516_taxes_promotions_init.js +63 -0
  50. package/dist/migrations/20260426T081516_taxes_promotions_init.js.map +1 -0
  51. package/dist/migrations/20260912T094654_taxes_sales_channel_taxes.d.ts +27 -0
  52. package/dist/migrations/20260912T094654_taxes_sales_channel_taxes.d.ts.map +1 -0
  53. package/dist/migrations/20260912T094654_taxes_sales_channel_taxes.js +44 -0
  54. package/dist/migrations/20260912T094654_taxes_sales_channel_taxes.js.map +1 -0
  55. package/dist/migrations/index.d.ts +28 -0
  56. package/dist/migrations/index.d.ts.map +1 -0
  57. package/dist/migrations/index.js +31 -0
  58. package/dist/migrations/index.js.map +1 -0
  59. package/docs/taxes.md +75 -0
  60. package/i18n/en.json +3 -0
  61. package/i18n/pl.json +3 -0
  62. package/package.json +92 -0
  63. package/tailwind.css +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ <!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
2
+
3
+ # @endora-commerce/mod-taxes
4
+
5
+ Tax rate configuration and order tax computation.
6
+
7
+ ## What this is
8
+
9
+ An **Endora Commerce module package**. Its module id is `taxes` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
10
+
11
+ A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
12
+
13
+ ## Entry points
14
+
15
+ | Import | Contents |
16
+ | --- | --- |
17
+ | `@endora-commerce/mod-taxes` | the module manifest — its id, version, dependencies, settings and activation |
18
+ | `@endora-commerce/mod-taxes/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
19
+ | `@endora-commerce/mod-taxes/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
20
+ | `@endora-commerce/mod-taxes/migrations` | the module’s own schema migrations, in the order the platform runs them |
21
+ | `@endora-commerce/mod-taxes/tailwind.css` | the Tailwind source declaration for the admin code above |
22
+
23
+ ## Depends on
24
+
25
+ Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
26
+
27
+ **Endora packages**
28
+
29
+ - `@endora-commerce/admin-kit` — *optional*
30
+ - `@endora-commerce/contracts`
31
+ - `@endora-commerce/platform`
32
+
33
+ **Third-party**
34
+
35
+ - `@mikro-orm/core` ^6
36
+ - `@mikro-orm/migrations` ^6
37
+ - `@mikro-orm/postgresql` ^6
38
+ - `fastify` ^5
39
+ - `lucide-react` ^1 — *optional*
40
+ - `react` ^19 — *optional*
41
+
42
+ ## What the tarball carries
43
+
44
+ - `dist/` — the compiled JavaScript and its type declarations
45
+ - `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
46
+ - `docs/` — the package’s own pages in the Endora Commerce documentation site
47
+ - `tailwind.css` — the Tailwind source declaration
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pnpm add @endora-commerce/mod-taxes
53
+ ```
54
+
55
+ ## Licence
56
+
57
+ MIT — the text is in `LICENSE`, beside this file.
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `taxes`' admin surface — one route and one sidebar entry, declared by the
3
+ * module that owns them (feature 091, Phase 4, batch 8;
4
+ * `specs/091-module-owned-admin-surfaces/contracts/admin-contribution.md`).
5
+ *
6
+ * **Its one drain was `dictionaries`' country picker**, which the screen renders
7
+ * to choose the country a tax rule applies to.
8
+ * `backend/scripts/ledgers/cross-module-imports/taxes.ts` recorded it with the
9
+ * retiring condition this batch satisfies — the picker is generic, so it moved
10
+ * into `@endora-commerce/admin-kit` and the shard is deleted rather than
11
+ * edited.
12
+ *
13
+ * **This module declares `activation.nonDeactivatable`**, so its off-state proof
14
+ * is `plan.md`'s Ruling 2 shape: the platform refuses to have an absent state,
15
+ * which is a fact about the module and is asserted as one rather than skipped.
16
+ * The permission axis is real and `useSurfaceVisibility` gates it identically,
17
+ * so the test drives positive control, permission withheld and restored, and
18
+ * reads the lock off the manifest so an unlock fails there.
19
+ *
20
+ * **This entry exports data and nothing else** (R2), like every `./admin`
21
+ * layer; the component is a dynamic-import factory (R6).
22
+ */
23
+ import type { AdminContributions } from '@endora-commerce/admin-kit/contributions';
24
+ export declare const contributions: AdminContributions;
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAKnF,eAAO,MAAM,aAAa,EAAE,kBA8B3B,CAAC"}
@@ -0,0 +1,34 @@
1
+ /** The module's only route: the tax-rule table. */
2
+ const ROUTE_PATH = '/taxes';
3
+ export const contributions = {
4
+ routes: [
5
+ {
6
+ path: ROUTE_PATH,
7
+ component: () => import('./pages/TaxesPage.js'),
8
+ // `requireAdmin('taxes:read')` on `GET /api/v1/admin/taxes`, which the
9
+ // screen calls on mount. The write code gates the mutations the same
10
+ // screen offers, so a read-only operator opens it and is refused field by
11
+ // field — the treatment issue #232 says a landing surface must have.
12
+ requiredPermission: 'taxes:read',
13
+ index: true,
14
+ },
15
+ ],
16
+ nav: [
17
+ {
18
+ to: ROUTE_PATH,
19
+ // Module-relative (R8), out of `packages/modules/taxes/i18n/`. It was
20
+ // `appShell.nav.taxes` in the shared `_i18n` bundle.
21
+ labelKey: 'nav.taxes.label',
22
+ icon: 'Receipt',
23
+ section: 'pricing',
24
+ // Second of three in the hand-written *Pricing* table, after
25
+ // `/price-lists` and before `/delivery-methods`. Both of those are still
26
+ // the host's — `price_lists` is batch 9's — so a registry entry appends
27
+ // after them whatever it declares; the weight is what restores the pair's
28
+ // order against `delivery_methods`' 300 once the section converts.
29
+ weight: 200,
30
+ requiredPermission: 'taxes:read',
31
+ },
32
+ ],
33
+ };
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAwBA,mDAAmD;AACnD,MAAM,UAAU,GAAG,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,MAAM,EAAE;QACN;YACE,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC;YAC/C,uEAAuE;YACvE,qEAAqE;YACrE,0EAA0E;YAC1E,qEAAqE;YACrE,kBAAkB,EAAE,YAAY;YAChC,KAAK,EAAE,IAAI;SACZ;KACF;IACD,GAAG,EAAE;QACH;YACE,EAAE,EAAE,UAAU;YACd,sEAAsE;YACtE,qDAAqD;YACrD,QAAQ,EAAE,iBAAiB;YAC3B,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,SAAS;YAClB,6DAA6D;YAC7D,yEAAyE;YACzE,wEAAwE;YACxE,0EAA0E;YAC1E,mEAAmE;YACnE,MAAM,EAAE,GAAG;YACX,kBAAkB,EAAE,YAAY;SACjC;KACF;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function TaxesPage(): ReactNode;
3
+ export default TaxesPage;
4
+ //# sourceMappingURL=TaxesPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaxesPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/TaxesPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAsBzF,wBAAgB,SAAS,IAAI,SAAS,CAiMrC;AAwHD,eAAe,SAAS,CAAC"}
@@ -0,0 +1,135 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Trash2 } from 'lucide-react';
4
+ import { ApiError, apiClient, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
5
+ import { Alert, AlertDescription, Badge, Button, Card, CardContent, CardHeader, CardTitle, Checkbox, Input, Label, PageHeader, Select, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@endora-commerce/admin-kit/ui';
6
+ import { CountryPicker } from '@endora-commerce/admin-kit/components';
7
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
8
+ const PRODUCT_TYPES = ['simple', 'variant', 'grouped', 'virtual'];
9
+ const VAT_STATUSES = ['vat_payer', 'vat_exempt', 'reverse_charge'];
10
+ export function TaxesPage() {
11
+ const t = useTranslation('core');
12
+ /**
13
+ * The screen's own gate (2026-08-28), on the codes its routes now enforce.
14
+ *
15
+ * `taxes` used to borrow `catalog:write` — on all four routes, the two reads
16
+ * included — so this page had no permission of its own to check and the
17
+ * sidebar entry beside it carried the catalogue's write code. Both moved
18
+ * together; hiding the screen rather than letting it 403 is the treatment the
19
+ * sidebar, the palette and the dashboard already apply to a denied
20
+ * destination, and `AppShell.tsx`'s `PALETTE_ITEMS` comment argues it at
21
+ * length. The module half is asked too, because the admin router carries no
22
+ * guard of its own: a module the platform is not running must contribute no
23
+ * surface at all (Constitution XVII item 5), and a permission gate alone
24
+ * leaves this screen rendering and answering 503.
25
+ *
26
+ * `useSurfaceVisibility` is the predicate the sidebar, the palette and the
27
+ * dashboard already share, so the two axes are one expression rather than two
28
+ * that can drift.
29
+ */
30
+ const isVisible = useSurfaceVisibility();
31
+ const canRead = isVisible({ module: 'taxes', requiredPermission: 'taxes:read' });
32
+ /**
33
+ * The write half, which is new rather than moved: until this change there was
34
+ * no read-only role to have, because reading the table required the code that
35
+ * rewrites it. Now there is, so the upsert form and the per-row delete are
36
+ * hidden from it — hidden and not disabled, for the reason the screen itself
37
+ * is, and hidden rather than left to 403 on submit.
38
+ */
39
+ const canWrite = isVisible({ module: 'taxes', requiredPermission: 'taxes:write' });
40
+ const [rows, setRows] = useState([]);
41
+ const [loading, setLoading] = useState(true);
42
+ const [error, setError] = useState(null);
43
+ const [info, setInfo] = useState(null);
44
+ const refresh = useCallback(async () => {
45
+ // A page that renders nothing has no reason to ask the API a question it
46
+ // will be refused.
47
+ if (!canRead) {
48
+ setLoading(false);
49
+ return;
50
+ }
51
+ setLoading(true);
52
+ setError(null);
53
+ try {
54
+ const res = await apiClient.get('/api/v1/admin/taxes');
55
+ setRows(res.data);
56
+ }
57
+ catch (err) {
58
+ setError(err instanceof ApiError ? err.envelope.error.message : t('taxes.error.load'));
59
+ }
60
+ finally {
61
+ setLoading(false);
62
+ }
63
+ }, [canRead, t]);
64
+ useEffect(() => {
65
+ void refresh();
66
+ }, [refresh]);
67
+ const handleUpsert = useCallback(async (input) => {
68
+ try {
69
+ await apiClient.put(`/api/v1/admin/taxes/${encodeURIComponent(input.code)}`, {
70
+ code: input.code,
71
+ name: input.name,
72
+ rate: input.rate,
73
+ country: input.country,
74
+ productType: input.productType,
75
+ appliesToVatStatuses: input.appliesToVatStatuses,
76
+ isDefault: input.isDefault,
77
+ priority: input.priority,
78
+ });
79
+ setInfo(t('taxes.success.save', { code: input.code }));
80
+ await refresh();
81
+ }
82
+ catch (err) {
83
+ setError(err instanceof ApiError ? err.envelope.error.message : t('taxes.error.save'));
84
+ }
85
+ }, [refresh, t]);
86
+ const handleDelete = useCallback(async (id) => {
87
+ if (!confirm(t('taxes.deleteConfirm')))
88
+ return;
89
+ try {
90
+ await apiClient.delete(`/api/v1/admin/taxes/${id}`);
91
+ await refresh();
92
+ }
93
+ catch (err) {
94
+ setError(err instanceof ApiError ? err.envelope.error.message : t('taxes.error.delete'));
95
+ }
96
+ }, [refresh, t]);
97
+ if (!canRead) {
98
+ return (_jsx(Alert, { children: _jsx(AlertDescription, { children: t('taxes.noPermission') }) }));
99
+ }
100
+ return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: t('taxes.page.title'), description: t('taxes.page.description') }), error ? (_jsx(Alert, { variant: "destructive", className: "mb-4", children: _jsx(AlertDescription, { children: error }) })) : null, info ? (_jsx(Alert, { variant: "success", className: "mb-4", children: _jsx(AlertDescription, { children: info }) })) : null, canWrite ? (_jsxs(Card, { className: "mb-4", children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: t('taxes.upsert.title') }) }), _jsx(CardContent, { children: _jsx(UpsertForm, { onSubmit: handleUpsert }) })] })) : null, _jsx(Card, { children: _jsx(CardContent, { className: "pt-6", children: loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('taxes.loading') })) : rows.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('taxes.empty') })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t('taxes.column.code') }), _jsx(TableHead, { children: t('taxes.column.name') }), _jsx(TableHead, { children: t('taxes.column.rate') }), _jsx(TableHead, { children: t('taxes.column.country') }), _jsx(TableHead, { children: t('taxes.column.productType') }), _jsx(TableHead, { children: t('taxes.column.vatStatuses') }), _jsx(TableHead, { children: t('taxes.column.default') }), _jsx(TableHead, { children: t('taxes.column.priority') }), _jsx(TableHead, {})] }) }), _jsx(TableBody, { children: rows.map((r) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx("code", { className: "font-mono text-xs", children: r.code }) }), _jsx(TableCell, { className: "font-medium", children: r.name }), _jsxs(TableCell, { className: "tabular-nums", children: [(r.rate * 100).toFixed(1), "%"] }), _jsx(TableCell, { children: r.country ?? '—' }), _jsx(TableCell, { children: r.productType ?? '—' }), _jsx(TableCell, { className: "text-xs text-muted-foreground", children: r.appliesToVatStatuses.join(', ') || '—' }), _jsx(TableCell, { children: r.isDefault ? _jsx(Badge, { variant: "default", children: t('taxes.badge.default') }) : null }), _jsx(TableCell, { children: r.priority }), _jsx(TableCell, { children: canWrite ? (_jsxs(Button, { variant: "destructive", size: "sm", type: "button", onClick: () => void handleDelete(r.id), children: [_jsx(Trash2, {}), t('taxes.action.delete')] })) : null })] }, r.id))) })] })) }) })] }));
101
+ }
102
+ function UpsertForm({ onSubmit }) {
103
+ const t = useTranslation('core');
104
+ const [code, setCode] = useState('');
105
+ const [name, setName] = useState('');
106
+ const [rate, setRate] = useState('0.23');
107
+ const [country, setCountry] = useState('');
108
+ const [productType, setProductType] = useState('');
109
+ const [vatStatuses, setVatStatuses] = useState(new Set());
110
+ const [isDefault, setIsDefault] = useState(false);
111
+ const [priority, setPriority] = useState('0');
112
+ return (_jsxs("form", { className: "space-y-4", onSubmit: (e) => {
113
+ e.preventDefault();
114
+ void onSubmit({
115
+ id: '',
116
+ code,
117
+ name,
118
+ rate: Number(rate),
119
+ country: country || null,
120
+ productType: productType || null,
121
+ appliesToVatStatuses: Array.from(vatStatuses),
122
+ isDefault,
123
+ priority: Number(priority),
124
+ });
125
+ }, children: [_jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "tcode", children: t('taxes.field.code') }), _jsx(Input, { id: "tcode", value: code, onChange: (e) => setCode(e.target.value), required: true })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "tname", children: t('taxes.field.name') }), _jsx(Input, { id: "tname", value: name, onChange: (e) => setName(e.target.value), required: true })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "trate", children: t('taxes.field.rate') }), _jsx(Input, { id: "trate", type: "number", step: "0.001", min: "0", value: rate, onChange: (e) => setRate(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "tctry", children: t('taxes.field.country') }), _jsx(CountryPicker, { id: "tctry", value: country, onChange: (e) => setCountry(e.target.value), includeBlank: true, blankLabel: t('taxes.option.any') })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "tptype", children: t('taxes.field.productType') }), _jsxs(Select, { id: "tptype", value: productType, onChange: (e) => setProductType(e.target.value), children: [_jsx("option", { value: "", children: t('taxes.option.any') }), PRODUCT_TYPES.map((pt) => (_jsx("option", { value: pt, children: pt }, pt)))] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "tprio", children: t('taxes.field.priority') }), _jsx(Input, { id: "tprio", type: "number", value: priority, onChange: (e) => setPriority(e.target.value) })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: t('taxes.field.vatStatuses') }), _jsx("div", { className: "flex flex-wrap gap-3", children: VAT_STATUSES.map((v) => (_jsxs("label", { className: "inline-flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: vatStatuses.has(v), onChange: (e) => setVatStatuses((prev) => {
126
+ const next = new Set(prev);
127
+ if (e.target.checked)
128
+ next.add(v);
129
+ else
130
+ next.delete(v);
131
+ return next;
132
+ }) }), v] }, v))) })] }), _jsxs("label", { className: "inline-flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { checked: isDefault, onChange: (e) => setIsDefault(e.target.checked) }), t('taxes.field.isDefault')] }), _jsx("div", { children: _jsx(Button, { type: "submit", children: t('taxes.action.save') }) })] }));
133
+ }
134
+ export default TaxesPage;
135
+ //# sourceMappingURL=TaxesPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaxesPage.js","sourceRoot":"","sources":["../../../src/admin/pages/TaxesPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Withdraw `taxes`' demo data (feature 113, T220 — contract §2.5).
3
+ *
4
+ * By the fixed codes `seed` assigns, never by a predicate over the table: an
5
+ * operator's own rule is indistinguishable from a demo one by every other
6
+ * column, and a `delete from taxes` would take theirs with it. This is the
7
+ * withdrawal that replaces `taxes`' line in the host's 29-table
8
+ * `truncate … cascade`, which could not tell the two apart at all.
9
+ */
10
+ import type { DemoResetResult, ModuleDemoContext } from '@endora-commerce/contracts';
11
+ import type { ModuleContext } from '@endora-commerce/platform/kernel';
12
+ export declare function resetDemo(context: ModuleDemoContext<ModuleContext>): Promise<DemoResetResult>;
13
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../../src/backend/demo/reset.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAStE,wBAAsB,SAAS,CAC7B,OAAO,EAAE,iBAAiB,CAAC,aAAa,CAAC,GACxC,OAAO,CAAC,eAAe,CAAC,CAO1B"}
@@ -0,0 +1,11 @@
1
+ import { Tax } from '../entities/tax.entity.js';
2
+ import { DEMO_TAX_CODES } from './rows.js';
3
+ export async function resetDemo(context) {
4
+ // command-coverage-ignore: the withdrawal half of the demo data above. Same
5
+ // entry point, same `mustBeNonProduction()` guard, same absence of an
6
+ // operator to attribute the write to (contract §2.7).
7
+ const em = context.ctx.cradle().emFactory();
8
+ const removed = await em.nativeDelete(Tax, { code: { $in: [...DEMO_TAX_CODES] } });
9
+ return { removed: [{ entity: 'Tax', count: removed }] };
10
+ }
11
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/backend/demo/reset.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAM3C,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAyC;IAEzC,4EAA4E;IAC5E,sEAAsE;IACtE,sDAAsD;IACtD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAmB,CAAC,SAAS,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;IACnF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The tax rules this module's demo data creates (feature 113, T220).
3
+ *
4
+ * One place holding the data, imported by both bodies: `seed.ts` creates these
5
+ * rows and `reset.ts` withdraws exactly them, by the `code` they are keyed on
6
+ * (contract §2.5 — a predicate over the table would take an operator's own rule
7
+ * with it).
8
+ *
9
+ * The values are the host seed's verbatim, moved rather than rewritten. The
10
+ * frozen copy the parity comparison read them against is deleted with that
11
+ * comparison (T226); what holds them now is
12
+ * `test/integration/demo/demo-shop.test.ts`' recorded delta.
13
+ */
14
+ /** One demo tax rule, in `Tax`'s own field names. */
15
+ export interface DemoTaxRow {
16
+ readonly code: string;
17
+ readonly name: string;
18
+ readonly rate: string;
19
+ readonly country: string;
20
+ readonly isDefault: boolean;
21
+ }
22
+ /**
23
+ * The Polish standard VAT rate.
24
+ *
25
+ * `name` is a plain column on `Tax` rather than a per-language map, so contract
26
+ * §2.6's per-language shape has nowhere to go here; the value is a rule label
27
+ * built out of a country code and a percentage, and it reads the same in both
28
+ * shipped languages.
29
+ */
30
+ export declare const DEMO_TAX_ROWS: readonly DemoTaxRow[];
31
+ /** The codes `reset` withdraws — derived from the rows, never a second list. */
32
+ export declare const DEMO_TAX_CODES: readonly string[];
33
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../../src/backend/demo/rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAE9C,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAyC,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The tax rules this module's demo data creates (feature 113, T220).
3
+ *
4
+ * One place holding the data, imported by both bodies: `seed.ts` creates these
5
+ * rows and `reset.ts` withdraws exactly them, by the `code` they are keyed on
6
+ * (contract §2.5 — a predicate over the table would take an operator's own rule
7
+ * with it).
8
+ *
9
+ * The values are the host seed's verbatim, moved rather than rewritten. The
10
+ * frozen copy the parity comparison read them against is deleted with that
11
+ * comparison (T226); what holds them now is
12
+ * `test/integration/demo/demo-shop.test.ts`' recorded delta.
13
+ */
14
+ /**
15
+ * The Polish standard VAT rate.
16
+ *
17
+ * `name` is a plain column on `Tax` rather than a per-language map, so contract
18
+ * §2.6's per-language shape has nowhere to go here; the value is a rule label
19
+ * built out of a country code and a percentage, and it reads the same in both
20
+ * shipped languages.
21
+ */
22
+ export const DEMO_TAX_ROWS = [
23
+ { code: 'pl_vat_23', name: 'PL VAT 23%', rate: '0.23', country: 'PL', isDefault: true },
24
+ ];
25
+ /** The codes `reset` withdraws — derived from the rows, never a second list. */
26
+ export const DEMO_TAX_CODES = DEMO_TAX_ROWS.map((row) => row.code);
27
+ //# sourceMappingURL=rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.js","sourceRoot":"","sources":["../../../src/backend/demo/rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAA0B;IAClD,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;CACxF,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAsB,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `taxes`' demo data (feature 113, T220 — contract §2).
3
+ *
4
+ * The block that used to sit at the bottom of the host seed's 887-line
5
+ * `main()`, in the module that owns the table. It writes `taxes` and nothing
6
+ * else (§2.1), reads no other module's table and resolves no port (§2.2), so
7
+ * declaring it added no entry to this module's manifest `dependencies` (§2.3).
8
+ *
9
+ * Idempotent by an existence probe on the natural key (§2.4): a second run
10
+ * creates nothing and reports the same count, which is what makes SC-007
11
+ * assertable from the report rather than from a database diff.
12
+ */
13
+ import type { DemoSeedResult, ModuleDemoContext } from '@endora-commerce/contracts';
14
+ import type { ModuleContext } from '@endora-commerce/platform/kernel';
15
+ export declare function seedDemo(context: ModuleDemoContext<ModuleContext>): Promise<DemoSeedResult>;
16
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/backend/demo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAUtE,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,iBAAiB,CAAC,aAAa,CAAC,GACxC,OAAO,CAAC,cAAc,CAAC,CA4BzB"}
@@ -0,0 +1,31 @@
1
+ import { Tax } from '../entities/tax.entity.js';
2
+ import { DEMO_TAX_ROWS } from './rows.js';
3
+ export async function seedDemo(context) {
4
+ // command-coverage-ignore: demo data, reached only by `endora demo seed`,
5
+ // whose entry point calls `mustBeNonProduction()` as its first statement and
6
+ // outside every `try` (contract §2.7, §3.3). The guard is the enforcement:
7
+ // this write has no operator, no tenant and no audit reader, and the command
8
+ // refuses to run against a production database at all.
9
+ const em = context.ctx.cradle().emFactory();
10
+ for (const row of DEMO_TAX_ROWS) {
11
+ const existing = await em.findOne(Tax, { code: row.code });
12
+ // Present already: left exactly as it is. An operator may have edited the
13
+ // demo rule, and overwriting it here would be this body deciding that its
14
+ // own literal outranks their change — which is `reset`'s question, not
15
+ // `seed`'s.
16
+ if (existing)
17
+ continue;
18
+ em.create(Tax, {
19
+ code: row.code,
20
+ name: row.name,
21
+ rate: row.rate,
22
+ country: row.country,
23
+ isDefault: row.isDefault,
24
+ });
25
+ }
26
+ await em.flush();
27
+ // The count is what the demo *holds* after the run, not what this call
28
+ // inserted: seeding twice must report the same counts (`DemoEntityCount`).
29
+ return { created: [{ entity: 'Tax', count: DEMO_TAX_ROWS.length }] };
30
+ }
31
+ //# sourceMappingURL=seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../src/backend/demo/seed.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAO1C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAyC;IAEzC,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,uDAAuD;IACvD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAmB,CAAC,SAAS,EAAE,CAAC;IAE7D,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,0EAA0E;QAC1E,0EAA0E;QAC1E,uEAAuE;QACvE,YAAY;QACZ,IAAI,QAAQ;YAAE,SAAS;QACvB,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE;YACb,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IAEjB,uEAAuE;IACvE,2EAA2E;IAC3E,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AACvE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * Tax — a single rule. Resolution narrows by `country`, `productType`, and
4
+ * `appliesToVatStatuses` (T128 / FR-051). At most one row may carry
5
+ * `isDefault=true`; that row wins when no narrower rule matches.
6
+ */
7
+ export declare class Tax {
8
+ [OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'country' | 'productType' | 'appliesToVatStatuses' | 'isDefault' | 'priority';
9
+ id: string;
10
+ code: string;
11
+ name: string;
12
+ rate: string;
13
+ country?: string | null;
14
+ productType?: 'simple' | 'configurable' | 'grouped' | 'bundle' | 'virtual' | null;
15
+ appliesToVatStatuses: Array<'vat_payer' | 'vat_exempt' | 'reverse_charge'>;
16
+ isDefault: boolean;
17
+ priority: number;
18
+ createdAt: Date;
19
+ updatedAt: Date;
20
+ }
21
+ //# sourceMappingURL=tax.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tax.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/tax.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAgC,MAAM,iBAAiB,CAAC;AAI7F;;;;GAIG;AACH,qBAEa,GAAG;IACd,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,SAAS,GACT,aAAa,GACb,sBAAsB,GACtB,WAAW,GACX,UAAU,CAAC;IAGf,EAAE,EAAE,MAAM,CAAgB;IAI1B,IAAI,EAAG,MAAM,CAAC;IAGd,IAAI,EAAG,MAAM,CAAC;IAGd,IAAI,EAAG,MAAM,CAAC;IAId,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGxB,WAAW,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC;IAGlF,oBAAoB,EAAE,KAAK,CAAC,WAAW,GAAG,YAAY,GAAG,gBAAgB,CAAC,CAAM;IAGhF,SAAS,EAAE,OAAO,CAAS;IAG3B,QAAQ,EAAE,MAAM,CAAK;IAGrB,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,83 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property, Unique } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * Tax — a single rule. Resolution narrows by `country`, `productType`, and
15
+ * `appliesToVatStatuses` (T128 / FR-051). At most one row may carry
16
+ * `isDefault=true`; that row wins when no narrower rule matches.
17
+ */
18
+ let Tax = class Tax {
19
+ [OptionalProps];
20
+ id = randomUUID();
21
+ code;
22
+ name;
23
+ rate;
24
+ country;
25
+ productType;
26
+ appliesToVatStatuses = [];
27
+ isDefault = false;
28
+ priority = 0;
29
+ createdAt = new Date();
30
+ updatedAt = new Date();
31
+ };
32
+ __decorate([
33
+ PrimaryKey({ type: 'uuid' }),
34
+ __metadata("design:type", String)
35
+ ], Tax.prototype, "id", void 0);
36
+ __decorate([
37
+ Property({ type: 'string', length: 64 }),
38
+ Unique(),
39
+ __metadata("design:type", String)
40
+ ], Tax.prototype, "code", void 0);
41
+ __decorate([
42
+ Property({ type: 'string', length: 160 }),
43
+ __metadata("design:type", String)
44
+ ], Tax.prototype, "name", void 0);
45
+ __decorate([
46
+ Property({ type: 'decimal', precision: 6, scale: 4 }),
47
+ __metadata("design:type", String)
48
+ ], Tax.prototype, "rate", void 0);
49
+ __decorate([
50
+ Property({ type: 'string', length: 2, nullable: true }),
51
+ Index(),
52
+ __metadata("design:type", Object)
53
+ ], Tax.prototype, "country", void 0);
54
+ __decorate([
55
+ Property({ type: 'string', length: 16, nullable: true }),
56
+ __metadata("design:type", Object)
57
+ ], Tax.prototype, "productType", void 0);
58
+ __decorate([
59
+ Property({ type: 'json' }),
60
+ __metadata("design:type", Array)
61
+ ], Tax.prototype, "appliesToVatStatuses", void 0);
62
+ __decorate([
63
+ Property({ type: 'boolean' }),
64
+ __metadata("design:type", Boolean)
65
+ ], Tax.prototype, "isDefault", void 0);
66
+ __decorate([
67
+ Property({ type: 'integer' }),
68
+ __metadata("design:type", Number)
69
+ ], Tax.prototype, "priority", void 0);
70
+ __decorate([
71
+ Property({ type: 'datetime', onCreate: () => new Date() }),
72
+ __metadata("design:type", Date)
73
+ ], Tax.prototype, "createdAt", void 0);
74
+ __decorate([
75
+ Property({ type: 'datetime', onUpdate: () => new Date() }),
76
+ __metadata("design:type", Date)
77
+ ], Tax.prototype, "updatedAt", void 0);
78
+ Tax = __decorate([
79
+ GlobalEntity(),
80
+ Entity({ tableName: 'taxes' })
81
+ ], Tax);
82
+ export { Tax };
83
+ //# sourceMappingURL=tax.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tax.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/tax.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;;GAIG;AAGI,IAAM,GAAG,GAAT,MAAM,GAAG;IACd,CAAC,aAAa,CAAC,CAQA;IAGf,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,IAAI,CAAU;IAGd,IAAI,CAAU;IAGd,IAAI,CAAU;IAId,OAAO,CAAiB;IAGxB,WAAW,CAAuE;IAGlF,oBAAoB,GAAyD,EAAE,CAAC;IAGhF,SAAS,GAAY,KAAK,CAAC;IAG3B,QAAQ,GAAW,CAAC,CAAC;IAGrB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAG7B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAjCC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;+BACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxC,MAAM,EAAE;;iCACK;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;iCAC5B;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;iCACxC;AAId;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvD,KAAK,EAAE;;oCACgB;AAGxB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wCACyB;AAGlF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8BACL,KAAK;iDAAqD;AAGhF;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;sCACH;AAG3B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;qCACT;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;sCAAc;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;sCAAc;AA5ClB,GAAG;IAFf,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;GAClB,GAAG,CA6Cf"}