@endora-commerce/mod-price-lists 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.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/admin/components/ApplicationRuleBuilder.d.ts +24 -0
- package/dist/admin/components/ApplicationRuleBuilder.d.ts.map +1 -0
- package/dist/admin/components/ApplicationRuleBuilder.js +249 -0
- package/dist/admin/components/ApplicationRuleBuilder.js.map +1 -0
- package/dist/admin/components/BracketGrid.d.ts +29 -0
- package/dist/admin/components/BracketGrid.d.ts.map +1 -0
- package/dist/admin/components/BracketGrid.js +252 -0
- package/dist/admin/components/BracketGrid.js.map +1 -0
- package/dist/admin/components/DisplayModeOverrideRow.d.ts +46 -0
- package/dist/admin/components/DisplayModeOverrideRow.d.ts.map +1 -0
- package/dist/admin/components/DisplayModeOverrideRow.js +109 -0
- package/dist/admin/components/DisplayModeOverrideRow.js.map +1 -0
- package/dist/admin/components/LinkedPriceListsPanel.d.ts +55 -0
- package/dist/admin/components/LinkedPriceListsPanel.d.ts.map +1 -0
- package/dist/admin/components/LinkedPriceListsPanel.js +131 -0
- package/dist/admin/components/LinkedPriceListsPanel.js.map +1 -0
- package/dist/admin/index.d.ts +34 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +119 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/DisplayModeOverridesPage.d.ts +25 -0
- package/dist/admin/pages/DisplayModeOverridesPage.d.ts.map +1 -0
- package/dist/admin/pages/DisplayModeOverridesPage.js +266 -0
- package/dist/admin/pages/DisplayModeOverridesPage.js.map +1 -0
- package/dist/admin/pages/PriceListDetailPage.d.ts +23 -0
- package/dist/admin/pages/PriceListDetailPage.d.ts.map +1 -0
- package/dist/admin/pages/PriceListDetailPage.js +421 -0
- package/dist/admin/pages/PriceListDetailPage.js.map +1 -0
- package/dist/admin/pages/PriceListsPage.d.ts +17 -0
- package/dist/admin/pages/PriceListsPage.d.ts.map +1 -0
- package/dist/admin/pages/PriceListsPage.js +198 -0
- package/dist/admin/pages/PriceListsPage.js.map +1 -0
- package/dist/admin/zones/CategoryDisplayMode.d.ts +27 -0
- package/dist/admin/zones/CategoryDisplayMode.d.ts.map +1 -0
- package/dist/admin/zones/CategoryDisplayMode.js +11 -0
- package/dist/admin/zones/CategoryDisplayMode.js.map +1 -0
- package/dist/admin/zones/OrganizationDisplayMode.d.ts +36 -0
- package/dist/admin/zones/OrganizationDisplayMode.d.ts.map +1 -0
- package/dist/admin/zones/OrganizationDisplayMode.js +12 -0
- package/dist/admin/zones/OrganizationDisplayMode.js.map +1 -0
- package/dist/admin/zones/ProductLinkedPriceLists.d.ts +16 -0
- package/dist/admin/zones/ProductLinkedPriceLists.d.ts.map +1 -0
- package/dist/admin/zones/ProductLinkedPriceLists.js +7 -0
- package/dist/admin/zones/ProductLinkedPriceLists.js.map +1 -0
- package/dist/backend/entities/price-display-mode-override.entity.d.ts +23 -0
- package/dist/backend/entities/price-display-mode-override.entity.d.ts.map +1 -0
- package/dist/backend/entities/price-display-mode-override.entity.js +58 -0
- package/dist/backend/entities/price-display-mode-override.entity.js.map +1 -0
- package/dist/backend/entities/price-list-price-bracket.entity.d.ts +26 -0
- package/dist/backend/entities/price-list-price-bracket.entity.d.ts.map +1 -0
- package/dist/backend/entities/price-list-price-bracket.entity.js +73 -0
- package/dist/backend/entities/price-list-price-bracket.entity.js.map +1 -0
- package/dist/backend/entities/price-list-product.entity.d.ts +15 -0
- package/dist/backend/entities/price-list-product.entity.d.ts.map +1 -0
- package/dist/backend/entities/price-list-product.entity.js +43 -0
- package/dist/backend/entities/price-list-product.entity.js.map +1 -0
- package/dist/backend/entities/price-list.entity.d.ts +34 -0
- package/dist/backend/entities/price-list.entity.d.ts.map +1 -0
- package/dist/backend/entities/price-list.entity.js +115 -0
- package/dist/backend/entities/price-list.entity.js.map +1 -0
- package/dist/backend/index.d.ts +125 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +179 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/plugin.d.ts +68 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +88 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/routes.d.ts +40 -0
- package/dist/backend/routes.d.ts.map +1 -0
- package/dist/backend/routes.js +447 -0
- package/dist/backend/routes.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +47 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +131 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/services/application-rule-evaluator.d.ts +25 -0
- package/dist/backend/services/application-rule-evaluator.d.ts.map +1 -0
- package/dist/backend/services/application-rule-evaluator.js +2 -0
- package/dist/backend/services/application-rule-evaluator.js.map +1 -0
- package/dist/backend/services/audit-references.d.ts +11 -0
- package/dist/backend/services/audit-references.d.ts.map +1 -0
- package/dist/backend/services/audit-references.js +23 -0
- package/dist/backend/services/audit-references.js.map +1 -0
- package/dist/backend/services/default-price-list-migration.d.ts +70 -0
- package/dist/backend/services/default-price-list-migration.d.ts.map +1 -0
- package/dist/backend/services/default-price-list-migration.js +177 -0
- package/dist/backend/services/default-price-list-migration.js.map +1 -0
- package/dist/backend/services/display-mode-resolver.d.ts +78 -0
- package/dist/backend/services/display-mode-resolver.d.ts.map +1 -0
- package/dist/backend/services/display-mode-resolver.js +71 -0
- package/dist/backend/services/display-mode-resolver.js.map +1 -0
- package/dist/backend/services/listing-price-chain.d.ts +26 -0
- package/dist/backend/services/listing-price-chain.d.ts.map +1 -0
- package/dist/backend/services/listing-price-chain.js +55 -0
- package/dist/backend/services/listing-price-chain.js.map +1 -0
- package/dist/backend/services/price-bracket-resolver.d.ts +24 -0
- package/dist/backend/services/price-bracket-resolver.d.ts.map +1 -0
- package/dist/backend/services/price-bracket-resolver.js +16 -0
- package/dist/backend/services/price-bracket-resolver.js.map +1 -0
- package/dist/backend/services/price-list-candidate-vector.d.ts +116 -0
- package/dist/backend/services/price-list-candidate-vector.d.ts.map +1 -0
- package/dist/backend/services/price-list-candidate-vector.js +133 -0
- package/dist/backend/services/price-list-candidate-vector.js.map +1 -0
- package/dist/backend/services/price-list-currency-reference.d.ts +12 -0
- package/dist/backend/services/price-list-currency-reference.d.ts.map +1 -0
- package/dist/backend/services/price-list-currency-reference.js +24 -0
- package/dist/backend/services/price-list-currency-reference.js.map +1 -0
- package/dist/backend/services/price-list-read-port.d.ts +29 -0
- package/dist/backend/services/price-list-read-port.d.ts.map +1 -0
- package/dist/backend/services/price-list-read-port.js +64 -0
- package/dist/backend/services/price-list-read-port.js.map +1 -0
- package/dist/backend/services/price-list-resolver.d.ts +26 -0
- package/dist/backend/services/price-list-resolver.d.ts.map +1 -0
- package/dist/backend/services/price-list-resolver.js +37 -0
- package/dist/backend/services/price-list-resolver.js.map +1 -0
- package/dist/backend/services/price-list-service.d.ts +431 -0
- package/dist/backend/services/price-list-service.d.ts.map +1 -0
- package/dist/backend/services/price-list-service.js +1238 -0
- package/dist/backend/services/price-list-service.js.map +1 -0
- package/dist/backend/services/price-list-status-worker.d.ts +28 -0
- package/dist/backend/services/price-list-status-worker.d.ts.map +1 -0
- package/dist/backend/services/price-list-status-worker.js +38 -0
- package/dist/backend/services/price-list-status-worker.js.map +1 -0
- package/dist/backend/services/pricing-cache.d.ts +53 -0
- package/dist/backend/services/pricing-cache.d.ts.map +1 -0
- package/dist/backend/services/pricing-cache.js +88 -0
- package/dist/backend/services/pricing-cache.js.map +1 -0
- package/dist/backend/services/pricing-service.d.ts +304 -0
- package/dist/backend/services/pricing-service.d.ts.map +1 -0
- package/dist/backend/services/pricing-service.interface.d.ts +151 -0
- package/dist/backend/services/pricing-service.interface.d.ts.map +1 -0
- package/dist/backend/services/pricing-service.interface.js +10 -0
- package/dist/backend/services/pricing-service.interface.js.map +1 -0
- package/dist/backend/services/pricing-service.js +803 -0
- package/dist/backend/services/pricing-service.js.map +1 -0
- package/dist/backend/services/unit-price-ordering.d.ts +121 -0
- package/dist/backend/services/unit-price-ordering.d.ts.map +1 -0
- package/dist/backend/services/unit-price-ordering.js +164 -0
- package/dist/backend/services/unit-price-ordering.js.map +1 -0
- package/dist/manifest.d.ts +218 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +228 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260426T075235_price_lists_pricing_init.d.ts +24 -0
- package/dist/migrations/20260426T075235_price_lists_pricing_init.d.ts.map +1 -0
- package/dist/migrations/20260426T075235_price_lists_pricing_init.js +89 -0
- package/dist/migrations/20260426T075235_price_lists_pricing_init.js.map +1 -0
- package/dist/migrations/20260504T125655_price_lists_engine.d.ts +6 -0
- package/dist/migrations/20260504T125655_price_lists_engine.d.ts.map +1 -0
- package/dist/migrations/20260504T125655_price_lists_engine.js +319 -0
- package/dist/migrations/20260504T125655_price_lists_engine.js.map +1 -0
- package/dist/migrations/20260817T055457_price_lists_single_system_price_list.d.ts +15 -0
- package/dist/migrations/20260817T055457_price_lists_single_system_price_list.d.ts.map +1 -0
- package/dist/migrations/20260817T055457_price_lists_single_system_price_list.js +58 -0
- package/dist/migrations/20260817T055457_price_lists_single_system_price_list.js.map +1 -0
- package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.d.ts +40 -0
- package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.d.ts.map +1 -0
- package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.js +46 -0
- package/dist/migrations/20260821T135907_price_lists_unit_price_amount_index.js.map +1 -0
- package/dist/migrations/index.d.ts +30 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +35 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/price_lists.md +278 -0
- package/i18n/en.json +14 -0
- package/i18n/pl.json +14 -0
- package/package.json +99 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RuleEvaluation } from './application-rule-evaluator.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pure priority chain resolver (feature 011 / FR-026, FR-027).
|
|
4
|
+
*
|
|
5
|
+
* Picks one matching list per the deterministic order:
|
|
6
|
+
* 1. List whose rule explicitly names the customer's Organization
|
|
7
|
+
* 2. else explicit Customer Group
|
|
8
|
+
* 3. else explicit Category
|
|
9
|
+
* 4. else explicit Sales Channel
|
|
10
|
+
* 5. else any other matching list
|
|
11
|
+
*
|
|
12
|
+
* Tie-break at every step: most recent `modifiedAt` first, then
|
|
13
|
+
* lexicographically smallest `name`. Tie-break is total — the same input
|
|
14
|
+
* yields the same picked list every run.
|
|
15
|
+
*/
|
|
16
|
+
export interface PriceListCandidate<TList = unknown> {
|
|
17
|
+
list: TList;
|
|
18
|
+
evaluation: RuleEvaluation;
|
|
19
|
+
modifiedAt: Date;
|
|
20
|
+
name: string;
|
|
21
|
+
/** Marker for the seeded `Default` row — the resolver's terminal fallback. */
|
|
22
|
+
isSystem: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function pickPriorityChain<TList>(candidates: readonly PriceListCandidate<TList>[]): PriceListCandidate<TList> | null;
|
|
25
|
+
export declare function tieBreak<TList>(candidates: readonly PriceListCandidate<TList>[]): PriceListCandidate<TList>;
|
|
26
|
+
//# sourceMappingURL=price-list-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-list-resolver.d.ts","sourceRoot":"","sources":["../../../src/backend/services/price-list-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK,GAAG,OAAO;IACjD,IAAI,EAAE,KAAK,CAAC;IACZ,UAAU,EAAE,cAAc,CAAC;IAC3B,UAAU,EAAE,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CACnB;AASD,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,UAAU,EAAE,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAC/C,kBAAkB,CAAC,KAAK,CAAC,GAAG,IAAI,CAqBlC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAC5B,UAAU,EAAE,SAAS,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAC/C,kBAAkB,CAAC,KAAK,CAAC,CAQ3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const PRIORITY_ORDER = [
|
|
2
|
+
'organization',
|
|
3
|
+
'customerGroup',
|
|
4
|
+
'category',
|
|
5
|
+
'salesChannel',
|
|
6
|
+
];
|
|
7
|
+
export function pickPriorityChain(candidates) {
|
|
8
|
+
if (candidates.length === 0)
|
|
9
|
+
return null;
|
|
10
|
+
for (const level of PRIORITY_ORDER) {
|
|
11
|
+
const atLevel = candidates.filter((c) => c.evaluation.explicitOn.has(level));
|
|
12
|
+
if (atLevel.length === 0)
|
|
13
|
+
continue;
|
|
14
|
+
if (level === 'organization') {
|
|
15
|
+
// Feature 056 — within the organization level, a list naming a NEARER org
|
|
16
|
+
// (smaller nearness rank) outranks one naming a farther ancestor (R5). A
|
|
17
|
+
// flat direct-org match is rank 0, so flat behavior is unchanged.
|
|
18
|
+
const nearest = Math.min(...atLevel.map((c) => c.evaluation.organizationRank ?? Number.POSITIVE_INFINITY));
|
|
19
|
+
const nearestOnly = atLevel.filter((c) => (c.evaluation.organizationRank ?? Number.POSITIVE_INFINITY) === nearest);
|
|
20
|
+
return tieBreak(nearestOnly);
|
|
21
|
+
}
|
|
22
|
+
return tieBreak(atLevel);
|
|
23
|
+
}
|
|
24
|
+
// Step 5 — any other matching list. Default lives here.
|
|
25
|
+
return tieBreak(candidates);
|
|
26
|
+
}
|
|
27
|
+
export function tieBreak(candidates) {
|
|
28
|
+
// Most recent modifiedAt first, then lexicographic name.
|
|
29
|
+
const sorted = [...candidates].sort((a, b) => {
|
|
30
|
+
const dt = b.modifiedAt.getTime() - a.modifiedAt.getTime();
|
|
31
|
+
if (dt !== 0)
|
|
32
|
+
return dt;
|
|
33
|
+
return a.name.localeCompare(b.name);
|
|
34
|
+
});
|
|
35
|
+
return sorted[0];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=price-list-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-list-resolver.js","sourceRoot":"","sources":["../../../src/backend/services/price-list-resolver.ts"],"names":[],"mappings":"AA0BA,MAAM,cAAc,GAAiC;IACnD,cAAc;IACd,eAAe;IACf,UAAU;IACV,cAAc;CACf,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,UAAgD;IAEhD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACnC,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;YAC7B,0EAA0E;YAC1E,yEAAyE;YACzE,kEAAkE;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,IAAI,MAAM,CAAC,iBAAiB,CAAC,CACjF,CAAC;YACF,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,IAAI,MAAM,CAAC,iBAAiB,CAAC,KAAK,OAAO,CAC/E,CAAC;YACF,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,wDAAwD;IACxD,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,UAAgD;IAEhD,yDAAyD;IACzD,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC3D,IAAI,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,CAAC,CAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
2
|
+
import { type ApplicationRule } from '@endora-commerce/contracts';
|
|
3
|
+
import type { CatalogCategoryReadPort, CatalogProductReadPort, CustomerGroupReadPort, OrganizationDetailsPort } from '@endora-commerce/contracts';
|
|
4
|
+
import { PriceList } from '../entities/price-list.entity.js';
|
|
5
|
+
import { PriceDisplayModeOverride } from '../entities/price-display-mode-override.entity.js';
|
|
6
|
+
import type { AuditPort } from '@endora-commerce/platform/kernel';
|
|
7
|
+
import type { CommandBus } from '@endora-commerce/platform/commands';
|
|
8
|
+
import type { PriceListsAuditContext } from '../plugin.js';
|
|
9
|
+
export type DisplayMode = 'gross_only' | 'net_only' | 'both' | 'none';
|
|
10
|
+
export type DisplayModeOverrideScope = 'organization' | 'category' | 'product';
|
|
11
|
+
export type PriceListStatus = 'draft' | 'active' | 'scheduled' | 'expired';
|
|
12
|
+
export type PriceListType = 'base' | 'sale';
|
|
13
|
+
export interface CreatePriceListInput {
|
|
14
|
+
name: string;
|
|
15
|
+
type: PriceListType;
|
|
16
|
+
startsAt?: Date | null;
|
|
17
|
+
endsAt?: Date | null;
|
|
18
|
+
applicationRule?: ApplicationRule;
|
|
19
|
+
}
|
|
20
|
+
export interface PatchPriceListInput {
|
|
21
|
+
name?: string;
|
|
22
|
+
type?: PriceListType;
|
|
23
|
+
startsAt?: Date | null;
|
|
24
|
+
endsAt?: Date | null;
|
|
25
|
+
applicationRule?: ApplicationRule;
|
|
26
|
+
}
|
|
27
|
+
export interface BracketInput {
|
|
28
|
+
minQuantity: number;
|
|
29
|
+
maxQuantity: number | null;
|
|
30
|
+
/** Decimal amount as string (the storage shape on `price_list_price_brackets`). */
|
|
31
|
+
amount: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ReplaceProductsResult {
|
|
34
|
+
added: number;
|
|
35
|
+
removed: number;
|
|
36
|
+
unchanged: number;
|
|
37
|
+
}
|
|
38
|
+
export interface CopyCurrencyResult {
|
|
39
|
+
added: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The neighbours this service has to **ask** rather than query (feature 075
|
|
43
|
+
* Phase C).
|
|
44
|
+
*
|
|
45
|
+
* A price-list rule and a display-mode override both point at rows two other
|
|
46
|
+
* modules own — an organisation, a category, a product — and this service used
|
|
47
|
+
* to validate them with `em.count(Organization, …)` and friends, which is
|
|
48
|
+
* another module's table on this module's connection. It answers rows whatever
|
|
49
|
+
* state that module is in, so an operator with `catalog` switched off could
|
|
50
|
+
* still pin a price list to a category the platform will not serve.
|
|
51
|
+
*
|
|
52
|
+
* Grouped into one object because it is one decision: a composition either
|
|
53
|
+
* knows how to reach its neighbours or it does not, and there is no coherent
|
|
54
|
+
* state where it can resolve categories but not organisations.
|
|
55
|
+
*/
|
|
56
|
+
export interface PriceListTargetReads {
|
|
57
|
+
organizationDetails: OrganizationDetailsPort;
|
|
58
|
+
catalogCategoryRead: CatalogCategoryReadPort;
|
|
59
|
+
catalogProductRead: CatalogProductReadPort;
|
|
60
|
+
/**
|
|
61
|
+
* Feature 076 (D-79) — customer groups moved to `customer_accounts`, so the
|
|
62
|
+
* rule-target validation reads them the same way it already read
|
|
63
|
+
* organisations and categories.
|
|
64
|
+
*/
|
|
65
|
+
customerGroupRead: CustomerGroupReadPort;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* PriceListService — admin CRUD over PriceList + the two child collections
|
|
69
|
+
* (items + assignments). Keeping all three operations on the same service
|
|
70
|
+
* keeps the "edit a price list and its rules" admin flow on one transaction
|
|
71
|
+
* boundary when we need it later.
|
|
72
|
+
*/
|
|
73
|
+
export declare class PriceListService {
|
|
74
|
+
#private;
|
|
75
|
+
private readonly emFactory;
|
|
76
|
+
/**
|
|
77
|
+
* Optional pricing cache. Every write path on this service calls
|
|
78
|
+
* `invalidateAll()` so the next read repopulates from the DB.
|
|
79
|
+
* Coarse but correct — fan-out makes per-tuple invalidation
|
|
80
|
+
* unprofitable until profiling shows otherwise.
|
|
81
|
+
*/
|
|
82
|
+
private readonly pricingCache?;
|
|
83
|
+
/** Feature 024 — optional audit log writer. When omitted, no audit
|
|
84
|
+
* rows are emitted (tests that don't care about audit pass nothing). */
|
|
85
|
+
private readonly auditLog?;
|
|
86
|
+
/**
|
|
87
|
+
* Feature 054 — when injected, `patch` runs through the Command Bus so the
|
|
88
|
+
* update is audited co-transactionally (Principle XIII). Optional: bus-less
|
|
89
|
+
* construction keeps the legacy audit path, byte-identical.
|
|
90
|
+
*/
|
|
91
|
+
private readonly commandBus?;
|
|
92
|
+
/**
|
|
93
|
+
* Feature 075 Phase C — the ports behind every rule-target and
|
|
94
|
+
* override-target existence check. Optional in the signature because a
|
|
95
|
+
* price list with no organisation, category or product target never reaches
|
|
96
|
+
* them; **never optional in effect**, because the paths that need them
|
|
97
|
+
* refuse rather than skip when they are absent (see {@link targets}).
|
|
98
|
+
*/
|
|
99
|
+
private readonly targetReads?;
|
|
100
|
+
constructor(emFactory: () => EntityManager,
|
|
101
|
+
/**
|
|
102
|
+
* Optional pricing cache. Every write path on this service calls
|
|
103
|
+
* `invalidateAll()` so the next read repopulates from the DB.
|
|
104
|
+
* Coarse but correct — fan-out makes per-tuple invalidation
|
|
105
|
+
* unprofitable until profiling shows otherwise.
|
|
106
|
+
*/
|
|
107
|
+
pricingCache?: {
|
|
108
|
+
invalidateAll: () => void;
|
|
109
|
+
} | undefined,
|
|
110
|
+
/** Feature 024 — optional audit log writer. When omitted, no audit
|
|
111
|
+
* rows are emitted (tests that don't care about audit pass nothing). */
|
|
112
|
+
auditLog?: AuditPort | undefined,
|
|
113
|
+
/**
|
|
114
|
+
* Feature 054 — when injected, `patch` runs through the Command Bus so the
|
|
115
|
+
* update is audited co-transactionally (Principle XIII). Optional: bus-less
|
|
116
|
+
* construction keeps the legacy audit path, byte-identical.
|
|
117
|
+
*/
|
|
118
|
+
commandBus?: CommandBus | undefined,
|
|
119
|
+
/**
|
|
120
|
+
* Feature 075 Phase C — the ports behind every rule-target and
|
|
121
|
+
* override-target existence check. Optional in the signature because a
|
|
122
|
+
* price list with no organisation, category or product target never reaches
|
|
123
|
+
* them; **never optional in effect**, because the paths that need them
|
|
124
|
+
* refuse rather than skip when they are absent (see {@link targets}).
|
|
125
|
+
*/
|
|
126
|
+
targetReads?: PriceListTargetReads | undefined);
|
|
127
|
+
/**
|
|
128
|
+
* The neighbour ports, or a refusal. Skipping the validation when nothing was
|
|
129
|
+
* wired would turn "this composition cannot reach `catalog`" into "every
|
|
130
|
+
* category id is valid", which is the fail-open shape feature 075 exists to
|
|
131
|
+
* remove.
|
|
132
|
+
*/
|
|
133
|
+
private targets;
|
|
134
|
+
private invalidatePricingCache;
|
|
135
|
+
private audit;
|
|
136
|
+
listEngine(filter?: {
|
|
137
|
+
status?: PriceListStatus[];
|
|
138
|
+
type?: PriceListType[];
|
|
139
|
+
search?: string;
|
|
140
|
+
}): Promise<PriceList[]>;
|
|
141
|
+
getById(id: string, em?: EntityManager): Promise<PriceList>;
|
|
142
|
+
remove(id: string): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Default-list rule-attachment guard (FR-006). Rejects any attempt to attach
|
|
145
|
+
* a non-empty Application Rule to the seeded `Default` row.
|
|
146
|
+
*/
|
|
147
|
+
assertCanSetApplicationRule(id: string, rule: {
|
|
148
|
+
kind: string;
|
|
149
|
+
}): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* Default-list status-change guard (FR-005 / FR-006 / spec.md §State Machines).
|
|
152
|
+
* The system Default row stays `active` for the platform's lifetime. The
|
|
153
|
+
* service rejects any attempt to move it to `draft`, `scheduled`, or `expired`.
|
|
154
|
+
*/
|
|
155
|
+
assertCanTransitionStatus(id: string, nextStatus: 'draft' | 'active' | 'scheduled' | 'expired'): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Create a new price list. Status defaults to `draft`. Default-list
|
|
158
|
+
* protections are out of scope here — system rows are seeded by migration
|
|
159
|
+
* 031, never created via this method.
|
|
160
|
+
*/
|
|
161
|
+
create(input: CreatePriceListInput, auditCtx?: PriceListsAuditContext): Promise<PriceList>;
|
|
162
|
+
/**
|
|
163
|
+
* Partial update. Bumps `modifiedAt` on every material change.
|
|
164
|
+
* Refuses non-empty rule attachment on the seeded `Default` row (FR-006).
|
|
165
|
+
*/
|
|
166
|
+
patch(id: string, input: PatchPriceListInput, auditCtx?: PriceListsAuditContext): Promise<PriceList>;
|
|
167
|
+
/**
|
|
168
|
+
* Manual transition: draft → active (or scheduled / expired if dates
|
|
169
|
+
* dictate). FR-009 row 1.
|
|
170
|
+
*/
|
|
171
|
+
activate(id: string, auditCtx?: PriceListsAuditContext): Promise<PriceList>;
|
|
172
|
+
/**
|
|
173
|
+
* Manual transition: any state → draft. Freezes the list immediately.
|
|
174
|
+
*/
|
|
175
|
+
draftify(id: string, auditCtx?: PriceListsAuditContext): Promise<PriceList>;
|
|
176
|
+
/**
|
|
177
|
+
* Duplicate a price list. Copies the rule, the assigned products, and
|
|
178
|
+
* every bracket row. Resets status to `draft`, clears dates, and derives
|
|
179
|
+
* a unique name (suffix ` (copy)`, ` (copy 2)`, …) — FR-013.
|
|
180
|
+
*/
|
|
181
|
+
duplicate(id: string, auditCtx?: PriceListsAuditContext): Promise<PriceList>;
|
|
182
|
+
/**
|
|
183
|
+
* Normalise + validate an Application Rule (US4 / FR-020..FR-024).
|
|
184
|
+
*
|
|
185
|
+
* Steps in order:
|
|
186
|
+
* 1. Recursively walk the AST.
|
|
187
|
+
* 2. For criteria: dedupe values, uppercase currency codes, validate
|
|
188
|
+
* target IDs against their respective tables. Empty `values` arrays
|
|
189
|
+
* collapse to `{ kind: 'all' }`.
|
|
190
|
+
* 3. For groups: recursively normalise each child, then drop children
|
|
191
|
+
* that collapsed to `{ kind: 'all' }`. If the group becomes empty
|
|
192
|
+
* it collapses to `{ kind: 'all' }` as well; if it's left with a
|
|
193
|
+
* single child, that child takes its place.
|
|
194
|
+
* 4. Reject malformed currencies, depth > 5, and unknown target IDs
|
|
195
|
+
* with `400 VALIDATION_FAILED`.
|
|
196
|
+
*
|
|
197
|
+
* Returns the normalised rule. Does NOT enforce FR-023 (non-Default
|
|
198
|
+
* rules must be non-empty); that gate fires at activation time.
|
|
199
|
+
*/
|
|
200
|
+
normaliseAndValidateRule(rule: ApplicationRule): Promise<ApplicationRule>;
|
|
201
|
+
private normaliseRuleNode;
|
|
202
|
+
/**
|
|
203
|
+
* Validate that every value in an ID-based criterion is a real row in the
|
|
204
|
+
* appropriate table. Throws `400 VALIDATION_FAILED` for any unknown ID.
|
|
205
|
+
*/
|
|
206
|
+
private assertTargetsExist;
|
|
207
|
+
/**
|
|
208
|
+
* Date sanity per FR-010: `endsAt` must be greater than `startsAt`; at
|
|
209
|
+
* creation time `endsAt` must be in the future.
|
|
210
|
+
*/
|
|
211
|
+
private assertDateSanity;
|
|
212
|
+
/**
|
|
213
|
+
* For a given product, return every price list the product is assigned
|
|
214
|
+
* to with a per-currency bracket summary and a deep-link path. Powers
|
|
215
|
+
* the admin Catalog product editor's Pricing tab (FR-044/045/046).
|
|
216
|
+
*/
|
|
217
|
+
summarizeBracketsForProduct(productId: string): Promise<Array<{
|
|
218
|
+
list: {
|
|
219
|
+
id: string;
|
|
220
|
+
name: string;
|
|
221
|
+
type: 'base' | 'sale';
|
|
222
|
+
status: 'draft' | 'active' | 'scheduled' | 'expired';
|
|
223
|
+
modifiedAt: Date;
|
|
224
|
+
};
|
|
225
|
+
summary: Array<{
|
|
226
|
+
currencyCode: string;
|
|
227
|
+
summary: string;
|
|
228
|
+
}>;
|
|
229
|
+
deepLinkPath: string;
|
|
230
|
+
}>>;
|
|
231
|
+
/**
|
|
232
|
+
* Build a human-readable summary string for one currency's bracket
|
|
233
|
+
* series, e.g.:
|
|
234
|
+
* - "80,0000 across 1 bracket"
|
|
235
|
+
* - "80,0000 – 100,0000 across 3 brackets"
|
|
236
|
+
* The numeric formatting deliberately keeps the storage scale (4
|
|
237
|
+
* fractional digits); the admin UI may re-format per locale.
|
|
238
|
+
*/
|
|
239
|
+
private summariseBrackets;
|
|
240
|
+
private formatAmount;
|
|
241
|
+
/**
|
|
242
|
+
* Upsert a per-Org / per-Category / per-Product display-mode override
|
|
243
|
+
* (FR-038). The mode value `'inherit'` deletes the override row.
|
|
244
|
+
* Validates the target ID against the appropriate table — orphans are
|
|
245
|
+
* refused with 400 (the polymorphic FK is enforced here, not at the DB
|
|
246
|
+
* level, since the target table varies — see data-model.md §1.4).
|
|
247
|
+
*/
|
|
248
|
+
upsertDisplayModeOverride(scope: DisplayModeOverrideScope, targetId: string, mode: DisplayMode | 'inherit'): Promise<PriceDisplayModeOverride | null>;
|
|
249
|
+
listDisplayModeOverrides(scope?: DisplayModeOverrideScope): Promise<PriceDisplayModeOverride[]>;
|
|
250
|
+
getDisplayModeOverride(scope: DisplayModeOverrideScope, targetId: string): Promise<PriceDisplayModeOverride | null>;
|
|
251
|
+
/**
|
|
252
|
+
* Update a `pricing.*` settings-group display-mode key. Settings are
|
|
253
|
+
* per-sales-channel under the foundation settings module — when no
|
|
254
|
+
* channel is supplied, this method writes the value across every
|
|
255
|
+
* sales channel (treating it as a tenant-wide override). For
|
|
256
|
+
* channel-specific overrides, callers may pass a single channel.
|
|
257
|
+
*
|
|
258
|
+
* `key` is the bare suffix (e.g. `default_display_mode` or
|
|
259
|
+
* `unauthenticated_display_mode`) — the full code is derived as
|
|
260
|
+
* `pricing.<key>`.
|
|
261
|
+
*/
|
|
262
|
+
setSettingsDisplayMode(key: 'default_display_mode' | 'unauthenticated_display_mode', mode: DisplayMode, salesChannelId?: string): Promise<void>;
|
|
263
|
+
/**
|
|
264
|
+
* Read the value of a `pricing.*` display-mode setting for a sales
|
|
265
|
+
* channel. Resolves along the settings tier chain
|
|
266
|
+
* per-channel override → global value → manifest `defaultValue`
|
|
267
|
+
* (mirroring `SettingsService.get`). The global tier lives on
|
|
268
|
+
* `settings.global_value` and is what the admin "All channels" editor
|
|
269
|
+
* writes; without it a globally-set mode (e.g. `both`) was ignored and
|
|
270
|
+
* the resolver silently fell back to the manifest default `gross_only`.
|
|
271
|
+
*/
|
|
272
|
+
readSettingsDisplayMode(key: 'default_display_mode' | 'unauthenticated_display_mode', salesChannelId: string): Promise<DisplayMode>;
|
|
273
|
+
/**
|
|
274
|
+
* Resolve the effective display mode for a (product, organization?,
|
|
275
|
+
* salesChannel) tuple along the FR-039 chain
|
|
276
|
+
* Product → Category → Organization → Settings.
|
|
277
|
+
*
|
|
278
|
+
* Walks the product's category memberships to find the most specific
|
|
279
|
+
* category override (deepest in the tree, with `(sort_order ASC, id ASC)`
|
|
280
|
+
* as the deterministic tie-break). Reads override rows from
|
|
281
|
+
* `price_display_mode_overrides`; falls back to the per-channel
|
|
282
|
+
* settings value (`default_display_mode` for signed-in customers,
|
|
283
|
+
* `unauthenticated_display_mode` for guests).
|
|
284
|
+
*/
|
|
285
|
+
resolveDisplayMode(input: {
|
|
286
|
+
productId: string;
|
|
287
|
+
organizationId: string | null;
|
|
288
|
+
salesChannelId: string;
|
|
289
|
+
customerKind: 'guest' | 'signed_in';
|
|
290
|
+
}): Promise<DisplayMode>;
|
|
291
|
+
/**
|
|
292
|
+
* The chain's answer with **no product in hand** — feature 086 / FR-016.
|
|
293
|
+
*
|
|
294
|
+
* A price ordering and a price range are refused where the page may not show
|
|
295
|
+
* prices at all, and `pricing.unauthenticated_display_mode = none` is the
|
|
296
|
+
* supported "hide prices until login" configuration. Deciding that needs the
|
|
297
|
+
* mode a *page* resolves to, which is the Organization → Settings tail of the
|
|
298
|
+
* FR-039 chain with the product and category steps deliberately absent.
|
|
299
|
+
*
|
|
300
|
+
* **The absence is the ruling, not a shortcut** (spec 086, clarification 2).
|
|
301
|
+
* A single product overridden to `none` keeps its position in a price
|
|
302
|
+
* ordering: a per-product override reads as "ask us for a quote" rather than
|
|
303
|
+
* "this price is secret", and withdrawing the whole control because one
|
|
304
|
+
* product opts out would make the sort appear and disappear as a buyer walks
|
|
305
|
+
* the catalogue. Moving those products to the tail instead is a change to
|
|
306
|
+
* this method's two omitted steps and to nothing else.
|
|
307
|
+
*
|
|
308
|
+
* The decision itself still goes through `decideDisplayMode`, so a page and a
|
|
309
|
+
* card cannot rank the organisation tier differently.
|
|
310
|
+
*/
|
|
311
|
+
resolvePageDisplayMode(input: {
|
|
312
|
+
organizationId: string | null;
|
|
313
|
+
salesChannelId: string;
|
|
314
|
+
customerKind: 'guest' | 'signed_in';
|
|
315
|
+
}): Promise<DisplayMode>;
|
|
316
|
+
/**
|
|
317
|
+
* The same chain for a **set** of products (issue #132 follow-up).
|
|
318
|
+
*
|
|
319
|
+
* A catalogue listing asked this question once per product, which cost four
|
|
320
|
+
* to six queries per card on the page's hottest read. Every step is a set
|
|
321
|
+
* lookup — the product-scope overrides, the category memberships, the
|
|
322
|
+
* category-scope overrides, the one organization row and the one settings
|
|
323
|
+
* pair — so the whole page costs what a single product used to.
|
|
324
|
+
*
|
|
325
|
+
* The *decision* is not duplicated: both this method and `resolveDisplayMode`
|
|
326
|
+
* hand their four inputs to `decideDisplayMode`, so a batched page cannot
|
|
327
|
+
* rank an override differently from a product page. Only the loading differs.
|
|
328
|
+
*
|
|
329
|
+
* `categoryIdsByProduct` is an optional prefetch for a caller that has
|
|
330
|
+
* already read the memberships — `PricingService.resolveListingPrices` needs
|
|
331
|
+
* them for the application rules and would otherwise read the same table
|
|
332
|
+
* twice per page.
|
|
333
|
+
*/
|
|
334
|
+
resolveDisplayModes(input: {
|
|
335
|
+
productIds: readonly string[];
|
|
336
|
+
organizationId: string | null;
|
|
337
|
+
salesChannelId: string;
|
|
338
|
+
customerKind: 'guest' | 'signed_in';
|
|
339
|
+
categoryIdsByProduct?: ReadonlyMap<string, ReadonlySet<string>>;
|
|
340
|
+
}): Promise<Map<string, DisplayMode>>;
|
|
341
|
+
/**
|
|
342
|
+
* `(product, category)` memberships for a set of products, read through
|
|
343
|
+
* `catalog`'s port (feature 075 / D-87).
|
|
344
|
+
*
|
|
345
|
+
* One call for the whole set, not one per product: the port takes the array
|
|
346
|
+
* for exactly this reason, and a page turning into a round trip per card is
|
|
347
|
+
* the regression this shape exists to prevent.
|
|
348
|
+
*
|
|
349
|
+
* **Structural, deliberately** — no `activeOnly`. The single-product path
|
|
350
|
+
* ranks the same memberships, and `evaluateApplicationRule`'s `category`
|
|
351
|
+
* criterion tests the raw membership, so narrowing to live categories here
|
|
352
|
+
* would make the display-mode chain and the rule that prices the product
|
|
353
|
+
* disagree about which categories a product is in.
|
|
354
|
+
*
|
|
355
|
+
* Every product asked about gets an entry, so an uncategorised product is an
|
|
356
|
+
* empty set rather than a missing key.
|
|
357
|
+
*/
|
|
358
|
+
private loadCategoryMemberships;
|
|
359
|
+
/**
|
|
360
|
+
* Turn category-scope override rows into the chain's ranking inputs.
|
|
361
|
+
*
|
|
362
|
+
* `ancestorsOf` answers the category **and** its ancestors, nearest-first, so
|
|
363
|
+
* one port call replaces the `findOne` plus the parent-pointer loop that
|
|
364
|
+
* walked `catalog`'s table a level at a time. Depth is the chain length minus
|
|
365
|
+
* the category itself; an unknown id answers an empty chain and is dropped,
|
|
366
|
+
* which is what the old `continue` did.
|
|
367
|
+
*/
|
|
368
|
+
private rankCategoryOverrides;
|
|
369
|
+
/**
|
|
370
|
+
* Validate that a polymorphic override target exists in the appropriate
|
|
371
|
+
* table. Throws 400 VALIDATION_FAILED on orphan target IDs (FR-038).
|
|
372
|
+
*/
|
|
373
|
+
private assertOverrideTargetExists;
|
|
374
|
+
/**
|
|
375
|
+
* List the assigned products for a price list, with their per-currency
|
|
376
|
+
* brackets in `minQuantity` ascending order. Powers the admin Products
|
|
377
|
+
* tab and the linked-price-lists panel from US8.
|
|
378
|
+
*/
|
|
379
|
+
listProducts(priceListId: string): Promise<Array<{
|
|
380
|
+
productId: string;
|
|
381
|
+
bracketsByCurrency: Record<string, BracketInput[]>;
|
|
382
|
+
}>>;
|
|
383
|
+
/**
|
|
384
|
+
* Idempotent append: assigns a single product to a price list. No-op when
|
|
385
|
+
* the assignment already exists. The list's `modifiedAt` is bumped only
|
|
386
|
+
* when the assignment is actually new.
|
|
387
|
+
*/
|
|
388
|
+
addProduct(priceListId: string, productId: string): Promise<void>;
|
|
389
|
+
/**
|
|
390
|
+
* Removes a product's assignment + its bracket rows (cascade via FK).
|
|
391
|
+
* No-op when the assignment does not exist.
|
|
392
|
+
*/
|
|
393
|
+
removeProduct(priceListId: string, productId: string): Promise<void>;
|
|
394
|
+
/**
|
|
395
|
+
* Bulk delta replacement of the product roster. Adds new pairs, removes
|
|
396
|
+
* pairs absent from the request. Returns the {added, removed, unchanged}
|
|
397
|
+
* counts. Cascade deletes brackets for removed pairs.
|
|
398
|
+
*/
|
|
399
|
+
replaceProducts(priceListId: string, productIds: readonly string[], auditCtx?: PriceListsAuditContext): Promise<ReplaceProductsResult>;
|
|
400
|
+
/**
|
|
401
|
+
* Bulk replacement of bracket rows for one (list, product) pair across
|
|
402
|
+
* every currency in the request. Currencies absent from the input are
|
|
403
|
+
* cleared. Brackets are validated for:
|
|
404
|
+
* - assignment existence (404 when product is not in the list);
|
|
405
|
+
* - per-row sanity: minQuantity ≥ 1, maxQuantity ≥ minQuantity (when
|
|
406
|
+
* present), amount ≥ 0;
|
|
407
|
+
* - per-currency overlap freedom (FR-015).
|
|
408
|
+
*
|
|
409
|
+
* The whole save runs in one EM flush so a partial save is impossible.
|
|
410
|
+
*/
|
|
411
|
+
replaceBrackets(priceListId: string, productId: string, bracketsByCurrency: Record<string, readonly BracketInput[]>, auditCtx?: PriceListsAuditContext): Promise<Record<string, BracketInput[]>>;
|
|
412
|
+
/**
|
|
413
|
+
* Convenience: copy one currency's brackets into other currencies for the
|
|
414
|
+
* same (list, product) pair. The target currencies' existing brackets (if
|
|
415
|
+
* any) are NOT cleared — this method appends. Conflicts on
|
|
416
|
+
* `(currency, minQuantity)` are refused via the PK constraint (caller
|
|
417
|
+
* should normally use this on currencies with no brackets yet, e.g. via
|
|
418
|
+
* the admin "Copy currency" affordance).
|
|
419
|
+
*/
|
|
420
|
+
copyCurrencyBrackets(priceListId: string, productId: string, fromCurrency: string, toCurrencies: readonly string[]): Promise<CopyCurrencyResult>;
|
|
421
|
+
/**
|
|
422
|
+
* Per-row bracket sanity (FR-014, FR-015).
|
|
423
|
+
*/
|
|
424
|
+
private assertBracketSanity;
|
|
425
|
+
/**
|
|
426
|
+
* Overlap-freedom within a currency series (FR-015). Assumes the input is
|
|
427
|
+
* sorted ascending by `minQuantity`.
|
|
428
|
+
*/
|
|
429
|
+
private assertNoOverlap;
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=price-list-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price-list-service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/price-list-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAC;AAU7F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAC3E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C;;;;OAIG;IACH,iBAAiB,EAAE,qBAAqB,CAAC;CAC1C;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;;IAEzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B;6EACyE;IACzE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAxBZ,SAAS,EAAE,MAAM,aAAa;IAC/C;;;;;OAKG;IACc,YAAY,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,IAAI,CAAA;KAAE,YAAA;IAC7D;6EACyE;IACxD,QAAQ,CAAC,EAAE,SAAS,YAAA;IACrC;;;;OAIG;IACc,UAAU,CAAC,EAAE,UAAU,YAAA;IACxC;;;;;;OAMG;IACc,WAAW,CAAC,EAAE,oBAAoB,YAAA;IAGrD;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,sBAAsB;YAIhB,KAAK;IAqEb,UAAU,CAAC,MAAM,GAAE;QACvB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;KACZ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAYvB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IAO3D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBvC;;;OAGG;IACG,2BAA2B,CAC/B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GACrB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;OAIG;IACG,yBAAyB,CAC7B,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GACvD,OAAO,CAAC,IAAI,CAAC;IAahB;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IA2ChG;;;OAGG;IACG,KAAK,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,CAAC,EAAE,sBAAsB,GAChC,OAAO,CAAC,SAAS,CAAC;IA+GrB;;;OAGG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IAoCjF;;OAEG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IAiBjF;;;;OAIG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IA+ElF;;;;;;;;;;;;;;;;;OAiBG;IACG,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;YAIjE,iBAAiB;IAmD/B;;;OAGG;YACW,kBAAkB;IA6BhC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;;OAIG;IACG,2BAA2B,CAC/B,SAAS,EAAE,MAAM,GAChB,OAAO,CACR,KAAK,CAAC;QACJ,IAAI,EAAE;YACJ,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;YACtB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;YACrD,UAAU,EAAE,IAAI,CAAC;SAClB,CAAC;QACF,OAAO,EAAE,KAAK,CAAC;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC1D,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CACH;IA8CD;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,YAAY;IAMpB;;;;;;OAMG;IACG,yBAAyB,CAC7B,KAAK,EAAE,wBAAwB,EAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,GAAG,SAAS,GAC5B,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IA2BrC,wBAAwB,CAC5B,KAAK,CAAC,EAAE,wBAAwB,GAC/B,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAShC,sBAAsB,CAC1B,KAAK,EAAE,wBAAwB,EAC/B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAI3C;;;;;;;;;;OAUG;IACG,sBAAsB,CAC1B,GAAG,EAAE,sBAAsB,GAAG,8BAA8B,EAC5D,IAAI,EAAE,WAAW,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC;IAyBhB;;;;;;;;OAQG;IACG,uBAAuB,CAC3B,GAAG,EAAE,sBAAsB,GAAG,8BAA8B,EAC5D,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,WAAW,CAAC;IAgBvB;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,KAAK,EAAE;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,OAAO,GAAG,WAAW,CAAC;KACrC,GAAG,OAAO,CAAC,WAAW,CAAC;IAoDxB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,sBAAsB,CAAC,KAAK,EAAE;QAClC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,OAAO,GAAG,WAAW,CAAC;KACrC,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxB;;;;;;;;;;;;;;;;;OAiBG;IACG,mBAAmB,CAAC,KAAK,EAAE;QAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;QAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,OAAO,GAAG,WAAW,CAAC;QACpC,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;KACjE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAyErC;;;;;;;;;;;;;;;;OAgBG;YACW,uBAAuB;IAcrC;;;;;;;;OAQG;YACW,qBAAqB;IAkBnC;;;OAGG;YACW,0BAA0B;IA2BxC;;;;OAIG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAC9C,KAAK,CAAC;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;KACpD,CAAC,CACH;IA4BD;;;;OAIG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvE;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E;;;;OAIG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,QAAQ,CAAC,EAAE,sBAAsB,GAChC,OAAO,CAAC,qBAAqB,CAAC;IAmCjC;;;;;;;;;;OAUG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,EAC3D,QAAQ,CAAC,EAAE,sBAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IA0E1C;;;;;;;OAOG;IACG,oBAAoB,CACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IA6D9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA6B3B;;;OAGG;IACH,OAAO,CAAC,eAAe;CAexB"}
|