@scayle/storefront-core 8.8.0 → 8.10.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/CHANGELOG.md +85 -0
- package/dist/helpers/advancedAttributeHelpers.d.ts +27 -0
- package/dist/helpers/arrayHelpers.d.ts +7 -0
- package/dist/helpers/attributeHelpers.d.ts +32 -0
- package/dist/helpers/basketHelpers.d.ts +7 -0
- package/dist/helpers/categoryHelper.d.ts +38 -0
- package/dist/helpers/filterHelper.d.ts +96 -10
- package/dist/helpers/formHelpers.d.ts +57 -24
- package/dist/helpers/imageHelpers.d.ts +18 -0
- package/dist/helpers/localization.d.ts +6 -4
- package/dist/helpers/objectHelpers.d.ts +7 -0
- package/dist/helpers/orderHelpers.d.ts +31 -16
- package/dist/helpers/productDisruptorHelper.d.ts +43 -0
- package/dist/helpers/productHelpers.d.ts +169 -0
- package/dist/helpers/sanitizationHelpers.d.ts +61 -0
- package/dist/helpers/sortingHelper.d.ts +16 -0
- package/dist/helpers/stringHelpers.d.ts +14 -0
- package/dist/index.d.ts +3 -1
- package/dist/rpc/methods/basket/basket.d.ts +95 -10
- package/dist/rpc/methods/basket/basket.mjs +4 -5
- package/dist/rpc/methods/brands.d.ts +26 -0
- package/dist/rpc/methods/campaign.d.ts +8 -4
- package/dist/rpc/methods/categories.d.ts +65 -5
- package/dist/rpc/methods/categories.mjs +2 -1
- package/dist/rpc/methods/cbd.d.ts +10 -0
- package/dist/rpc/methods/checkout/checkout.d.ts +42 -3
- package/dist/rpc/methods/checkout/checkout.mjs +2 -3
- package/dist/rpc/methods/checkout/order.d.ts +12 -0
- package/dist/rpc/methods/checkout/shopUser.d.ts +20 -0
- package/dist/rpc/methods/checkout/shopUserAddresses.d.ts +7 -0
- package/dist/rpc/methods/navigationTrees.d.ts +27 -0
- package/dist/rpc/methods/oauth/idp.d.ts +24 -0
- package/dist/rpc/methods/products.d.ts +160 -36
- package/dist/rpc/methods/products.mjs +8 -11
- package/dist/rpc/methods/promotion.d.ts +46 -4
- package/dist/rpc/methods/search.d.ts +17 -12
- package/dist/rpc/methods/search.mjs +4 -2
- package/dist/rpc/methods/session.d.ts +71 -0
- package/dist/rpc/methods/session.mjs +13 -13
- package/dist/rpc/methods/shopConfiguration.d.ts +12 -1
- package/dist/rpc/methods/shopConfiguration.mjs +2 -1
- package/dist/rpc/methods/user.d.ts +34 -4
- package/dist/rpc/methods/variants.d.ts +30 -2
- package/dist/rpc/methods/variants.mjs +1 -2
- package/dist/rpc/methods/wishlist.d.ts +42 -7
- package/dist/rpc/methods/wishlist.mjs +3 -4
- package/dist/test/factories/user.d.ts +10 -0
- package/dist/types/api/auth.d.ts +67 -0
- package/dist/types/api/context.d.ts +82 -1
- package/dist/types/api/rpc.d.ts +19 -0
- package/dist/types/breadcrumb.d.ts +9 -0
- package/dist/types/promises.d.ts +10 -0
- package/dist/types/sapi/basket.d.ts +26 -1
- package/dist/types/sapi/filter.d.ts +37 -0
- package/dist/types/sapi/navigation.d.ts +16 -4
- package/dist/types/sapi/order.d.ts +137 -242
- package/dist/types/sapi/product.d.ts +85 -0
- package/dist/types/sapi/productFilter.d.ts +14 -0
- package/dist/types/sapi/router.d.ts +3 -0
- package/dist/types/sapi/search.d.ts +19 -0
- package/dist/types/sapi/sorting.d.ts +7 -0
- package/dist/types/sapi/wishlist.d.ts +6 -0
- package/dist/types/user.d.ts +102 -0
- package/dist/utils/campaign.d.ts +25 -10
- package/package.json +4 -4
|
@@ -5,6 +5,10 @@ import type { CachedType } from '../../cache/cached';
|
|
|
5
5
|
import type { AuthenticationType, ShopUser } from '../user';
|
|
6
6
|
import type { BasketWithOptions, CategoryWith, ProductCategoryWith, ProductWith, SearchV2With, SearchWith, VariantWith, WishlistWithOptions } from '../';
|
|
7
7
|
import type { IDPConfig, OAuthTokens } from './auth';
|
|
8
|
+
import type { RpcMethodCall } from '../..';
|
|
9
|
+
/**
|
|
10
|
+
* Parameters that can be included in the request context.
|
|
11
|
+
*/
|
|
8
12
|
export type WithParams = Partial<{
|
|
9
13
|
basket: BasketWithOptions;
|
|
10
14
|
wishlist: WishlistWithOptions;
|
|
@@ -15,11 +19,32 @@ export type WithParams = Partial<{
|
|
|
15
19
|
searchV2: SearchV2With;
|
|
16
20
|
variant: VariantWith;
|
|
17
21
|
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Represents runtime configuration options.
|
|
24
|
+
*/
|
|
18
25
|
export interface RuntimeConfiguration {
|
|
19
26
|
[key: string]: any;
|
|
20
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Additional context information for RPC calls.
|
|
30
|
+
* AThis interface can be augmented to extend the `RpcContext` type and
|
|
31
|
+
* allows to adding custom properties to the RPC context.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // Augment AdditionalRpcContext type
|
|
36
|
+
* declare module '@scayle/storefront-core' {
|
|
37
|
+
* interface AdditionalRpcContext {
|
|
38
|
+
* myNewProp: string
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
21
43
|
export interface AdditionalRpcContext {
|
|
22
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Context interface with session information.
|
|
47
|
+
*/
|
|
23
48
|
export interface ContextWithSession {
|
|
24
49
|
wishlistKey: string;
|
|
25
50
|
basketKey: string;
|
|
@@ -32,6 +57,9 @@ export interface ContextWithSession {
|
|
|
32
57
|
updateUser: (user: ShopUser) => void;
|
|
33
58
|
updateTokens: (tokens: OAuthTokens) => void;
|
|
34
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Context interface without session information.
|
|
62
|
+
*/
|
|
35
63
|
export interface ContextWithoutSession {
|
|
36
64
|
wishlistKey: undefined;
|
|
37
65
|
basketKey: undefined;
|
|
@@ -44,21 +72,39 @@ export interface ContextWithoutSession {
|
|
|
44
72
|
updateUser: undefined;
|
|
45
73
|
updateTokens: undefined;
|
|
46
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Information provided after a successful login.
|
|
77
|
+
*/
|
|
47
78
|
interface LoginInformation {
|
|
48
79
|
shopId: number;
|
|
49
80
|
user: ShopUser;
|
|
50
81
|
authenticationType?: AuthenticationType;
|
|
51
82
|
accessToken: string;
|
|
52
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Information provided after a successful logout.
|
|
86
|
+
*/
|
|
53
87
|
interface LogoutInformation {
|
|
54
88
|
shopId: number;
|
|
55
89
|
user: ShopUser;
|
|
56
90
|
authenticationType?: AuthenticationType;
|
|
57
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Hooks for storefront events.
|
|
94
|
+
*/
|
|
58
95
|
export interface StorefrontHooks {
|
|
96
|
+
/**
|
|
97
|
+
* Hook called after a successful login.
|
|
98
|
+
*/
|
|
59
99
|
'storefront:afterLogin': (loginInfo: LoginInformation, context: RpcContext) => Promise<void> | void;
|
|
100
|
+
/**
|
|
101
|
+
* Hook called after a successful logout.
|
|
102
|
+
*/
|
|
60
103
|
'storefront:afterLogout': (logoutInfo: LogoutInformation, context: RpcContext) => Promise<void> | void;
|
|
61
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* The main RPC context interface, combining various properties.
|
|
107
|
+
*/
|
|
62
108
|
export type RpcContext = {
|
|
63
109
|
locale: string;
|
|
64
110
|
checkout: {
|
|
@@ -78,7 +124,25 @@ export type RpcContext = {
|
|
|
78
124
|
domain?: string;
|
|
79
125
|
withParams?: WithParams;
|
|
80
126
|
/**
|
|
81
|
-
* @deprecated
|
|
127
|
+
* @deprecated The `getCampaignKey` RPC method should be used instead to retrieve the default campaign key.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
*
|
|
131
|
+
* ```typescript
|
|
132
|
+
* // Before
|
|
133
|
+
* async function rpcMethod(context) {
|
|
134
|
+
* const campaignKey = { context }
|
|
135
|
+
* // ...
|
|
136
|
+
* }
|
|
137
|
+
* // After
|
|
138
|
+
* async function rpcMethod(context) {
|
|
139
|
+
* const campaignKey = await context.callRpc?.('getCampaignKey')
|
|
140
|
+
* // ...
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* To override the default campaign key, override the getCampaignKey RPC with your own implementation
|
|
145
|
+
* @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/rpc-methods#overriding-core-rpc-methods
|
|
82
146
|
*/
|
|
83
147
|
campaignKey?: string;
|
|
84
148
|
destroySessionsForUserId: (userId: number, sessionsToKeep?: string[]) => Promise<void>;
|
|
@@ -102,8 +166,25 @@ export type RpcContext = {
|
|
|
102
166
|
callHook?: Hookable<StorefrontHooks>['callHook'];
|
|
103
167
|
callHookParallel?: Hookable<StorefrontHooks>['callHookParallel'];
|
|
104
168
|
callHookWith?: Hookable<StorefrontHooks>['callHookWith'];
|
|
169
|
+
callRpc?: RpcMethodCall;
|
|
105
170
|
} & AdditionalRpcContext & (ContextWithoutSession | ContextWithSession);
|
|
171
|
+
/**
|
|
172
|
+
* RPC context type with guaranteed session information.
|
|
173
|
+
*/
|
|
106
174
|
export type RpcContextWithSession = RpcContext & ContextWithSession;
|
|
175
|
+
/**
|
|
176
|
+
* Assertion function to narrow the type of `RpcContext` to `RpcContextWithSession`.
|
|
177
|
+
*
|
|
178
|
+
* @param context - The RPC context object.
|
|
179
|
+
*
|
|
180
|
+
* @throws {Error} If `context.sessionId` is not defined.
|
|
181
|
+
*/
|
|
107
182
|
export declare function assertSession(context: RpcContext): asserts context is RpcContextWithSession;
|
|
183
|
+
/**
|
|
184
|
+
* Type guard function to check if the provided `RpcContext` has session information.
|
|
185
|
+
* @param context The RPC context object.
|
|
186
|
+
*
|
|
187
|
+
* @returns True if `context.sessionId` is defined, false otherwise.
|
|
188
|
+
*/
|
|
108
189
|
export declare function hasSession(context: RpcContext): context is RpcContextWithSession;
|
|
109
190
|
export {};
|
package/dist/types/api/rpc.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import type { RpcContext } from './context';
|
|
2
|
+
/**
|
|
3
|
+
* Type for an RPC handler that accepts parameters.
|
|
4
|
+
*
|
|
5
|
+
* @template Params The type of the parameters object.
|
|
6
|
+
* @template ResponseType The type of the response.
|
|
7
|
+
*/
|
|
2
8
|
export type ParamRpcHandler<Params extends Record<string, any>, ResponseType> = (params: Params, context: RpcContext) => Promise<(ResponseType extends undefined ? void : ResponseType) | Response> | ResponseType | Response;
|
|
9
|
+
/**
|
|
10
|
+
* Type for an RPC handler that does not accept parameters.
|
|
11
|
+
*
|
|
12
|
+
* @template ResponseType The type of the response.
|
|
13
|
+
*/
|
|
3
14
|
export type NoParamRpcHandler<ResponseType> = (context: RpcContext) => Promise<ResponseType | Response> | ResponseType | Response;
|
|
15
|
+
/**
|
|
16
|
+
* Generic RPC handler type. Handles both cases with and without parameters.
|
|
17
|
+
*
|
|
18
|
+
* @template A The response type if no parameters are used, or the parameters type if parameters are used.
|
|
19
|
+
* @template B The response type if parameters are used.
|
|
20
|
+
* If `void`, no parameters are expected.
|
|
21
|
+
* This allows for defining RPC handlers that either accept parameters or not.
|
|
22
|
+
*/
|
|
4
23
|
export type RpcHandler<A, B = void> = B extends void ? NoParamRpcHandler<A> : ParamRpcHandler<A, B>;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an item in a breadcrumb navigation.
|
|
3
|
+
*/
|
|
1
4
|
export interface BreadcrumbItem {
|
|
5
|
+
/**
|
|
6
|
+
* The displayed text for the breadcrumb item.
|
|
7
|
+
*/
|
|
2
8
|
value: string;
|
|
9
|
+
/**
|
|
10
|
+
* The navigation target (URL or route) for the breadcrumb item.
|
|
11
|
+
*/
|
|
3
12
|
to: string;
|
|
4
13
|
}
|
package/dist/types/promises.d.ts
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the type resolved by a promise or promise-like value.
|
|
3
|
+
*
|
|
4
|
+
* @template T The input type, which can be a promise-like value.
|
|
5
|
+
*/
|
|
1
6
|
export type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
|
|
7
|
+
/**
|
|
8
|
+
* Extracts the return type of a promise-returning function, after the promise resolves.
|
|
9
|
+
*
|
|
10
|
+
* @template T The promise-returning function type.
|
|
11
|
+
*/
|
|
2
12
|
export type PromiseReturnType<T extends (...args: any) => Promise<any>> = Awaited<ReturnType<T>>;
|
|
@@ -1,23 +1,48 @@
|
|
|
1
1
|
import type { BasketItemDisplayData, BasketItemDisplayDataKey, BasketResponse, BasketResponseData, BasketWith, BasketItemDisplayDataItem, CreateBasketItemParameters, ItemGroup } from '@scayle/storefront-api';
|
|
2
|
+
/**
|
|
3
|
+
* Represents custom data for a basket item. Corresponds to the `customData` property
|
|
4
|
+
* of `CreateBasketItemParameters`.
|
|
5
|
+
*/
|
|
2
6
|
export type BasketCustomData = Pick<CreateBasketItemParameters, 'customData'>;
|
|
7
|
+
/**
|
|
8
|
+
* Represents display data for a basket item. Uses a partial record to allow flexibility in
|
|
9
|
+
* which display data keys are present.
|
|
10
|
+
*/
|
|
3
11
|
export type BasketDisplayData = Partial<Record<BasketItemDisplayDataKey, BasketItemDisplayDataItem>>;
|
|
4
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Parameters for adding or updating an item in the basket.
|
|
14
|
+
*/
|
|
5
15
|
export interface AddOrUpdateItemType {
|
|
6
16
|
variantId: number;
|
|
7
17
|
quantity: number;
|
|
18
|
+
/** Display data for the item. */
|
|
8
19
|
displayData?: BasketItemDisplayData;
|
|
20
|
+
/** Custom data for the item. */
|
|
9
21
|
customData?: {
|
|
10
22
|
[key: string | number]: any;
|
|
11
23
|
};
|
|
24
|
+
/** Item group for the item. */
|
|
12
25
|
itemGroup?: ItemGroup;
|
|
26
|
+
/** If the product is not in the "catalog" anymore, keep it in the basket */
|
|
13
27
|
includeItemsWithoutProductData?: boolean;
|
|
14
28
|
promotionId?: string | null;
|
|
15
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Options for fetching a basket, extending the base `BasketWith` type.
|
|
32
|
+
*/
|
|
16
33
|
export interface BasketWithOptions extends BasketWith {
|
|
34
|
+
/** Key for filtering the price promotions */
|
|
17
35
|
pricePromotionKey?: string;
|
|
36
|
+
/** if the product is not in the "catalog" anymore, keep it in the basket */
|
|
18
37
|
includeItemsWithoutProductData?: boolean;
|
|
19
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Parameters for the `useBasket` composable.
|
|
41
|
+
*/
|
|
20
42
|
export interface UseBasketParams {
|
|
43
|
+
/** Key for caching. */
|
|
21
44
|
key?: string;
|
|
45
|
+
/** Data to include with the basket. */
|
|
22
46
|
with: BasketWithOptions;
|
|
23
47
|
}
|
|
48
|
+
export type { BasketItemDisplayData, BasketItemDisplayDataItem, BasketResponseData, BasketWith, BasketResponse, ItemGroup, };
|
|
@@ -2,31 +2,53 @@ import type { AttributeWithBooleanValueFilter, AttributeWithValuesFilter, Filter
|
|
|
2
2
|
import type { Query } from './router';
|
|
3
3
|
export type { AttributesFilterItemWithValues } from '@scayle/storefront-api';
|
|
4
4
|
export type { AttributeWithBooleanValueFilter, AttributeWithValuesFilter, AttributeKey, } from '@scayle/storefront-api';
|
|
5
|
+
/**
|
|
6
|
+
* Parameters for filtering products.
|
|
7
|
+
*/
|
|
5
8
|
export interface FilterParams {
|
|
6
9
|
page?: number;
|
|
7
10
|
perPage?: number;
|
|
11
|
+
/** The where clause for filtering. */
|
|
8
12
|
where?: {
|
|
13
|
+
/** The search term. */
|
|
9
14
|
term?: ProductSearchQuery['term'];
|
|
15
|
+
/** The minimum price. */
|
|
10
16
|
minPrice?: ProductSearchQuery['minPrice'];
|
|
17
|
+
/** The maximum price. */
|
|
11
18
|
maxPrice?: ProductSearchQuery['maxPrice'];
|
|
19
|
+
/** The attributes filter. */
|
|
12
20
|
attributes?: ProductSearchQuery['attributes'];
|
|
21
|
+
/** Attributes to whitelist */
|
|
13
22
|
whitelistAttributes?: ProductSearchQuery['attributes'];
|
|
14
23
|
};
|
|
24
|
+
/** The sort configuration. */
|
|
15
25
|
sort?: ProductSortConfig;
|
|
26
|
+
/** The OR filters operator. */
|
|
16
27
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
17
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Parameters for fetching filters.
|
|
31
|
+
*/
|
|
18
32
|
export type FetchFiltersParams = {
|
|
19
33
|
includedFilters?: Array<string>;
|
|
34
|
+
/** where clause for prefiltering the filters */
|
|
20
35
|
where?: {
|
|
36
|
+
/** The search term. */
|
|
21
37
|
term?: ProductSearchQuery['term'];
|
|
38
|
+
/** The minimum price. */
|
|
22
39
|
minPrice?: ProductSearchQuery['minPrice'];
|
|
40
|
+
/** The maximum price. */
|
|
23
41
|
maxPrice?: ProductSearchQuery['maxPrice'];
|
|
42
|
+
/** The attributes filter. */
|
|
24
43
|
attributes?: ProductSearchQuery['attributes'];
|
|
44
|
+
/** wether to disable fuzziness on term */
|
|
25
45
|
disableFuzziness?: ProductSearchQuery['disableFuzziness'];
|
|
46
|
+
/** Attributes to whitelist */
|
|
26
47
|
whitelistAttributes?: ProductSearchQuery['attributes'];
|
|
27
48
|
};
|
|
28
49
|
includeSoldOut?: boolean;
|
|
29
50
|
includeSellableForFree?: boolean;
|
|
51
|
+
/** or operator for filters */
|
|
30
52
|
orFiltersOperator?: ProductsSearchEndpointParameters['orFiltersOperator'];
|
|
31
53
|
} & ({
|
|
32
54
|
category?: string;
|
|
@@ -35,18 +57,33 @@ export type FetchFiltersParams = {
|
|
|
35
57
|
categoryId: number;
|
|
36
58
|
category?: undefined;
|
|
37
59
|
});
|
|
60
|
+
/**
|
|
61
|
+
* The response from fetching filters.
|
|
62
|
+
*/
|
|
38
63
|
export interface FetchFiltersResponse {
|
|
39
64
|
filters: FiltersEndpointResponseData;
|
|
40
65
|
unfilteredCount: number;
|
|
41
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Represents a filter query.
|
|
69
|
+
*/
|
|
42
70
|
export interface FilterQuery {
|
|
43
71
|
page?: Query;
|
|
44
72
|
sort?: Query;
|
|
45
73
|
term?: Query;
|
|
46
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Filter setup type.
|
|
77
|
+
*/
|
|
47
78
|
export type FilterSetup = Record<string, unknown>;
|
|
79
|
+
/**
|
|
80
|
+
* Parameters for sanitizing attributes.
|
|
81
|
+
*/
|
|
48
82
|
export interface SanitizeAttributesParams {
|
|
83
|
+
/** The attributes to sanitize. */
|
|
49
84
|
attributes: (AttributeWithValuesFilter | AttributeWithBooleanValueFilter)[];
|
|
85
|
+
/** The filter keys. */
|
|
50
86
|
filterKeys: string[];
|
|
87
|
+
/** included filter names */
|
|
51
88
|
includedFilters?: string[];
|
|
52
89
|
}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import type { GetNavigationParameters, NavigationItems } from '@scayle/storefront-api';
|
|
2
2
|
export type { NavigationItems, NavigationTree, NavigationItemExternal, NavigationItemPage, NavigationItemCategory, } from '@scayle/storefront-api';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a navigation tree item.
|
|
5
|
+
*/
|
|
3
6
|
export type NavigationTreeItem = NavigationItems[0];
|
|
7
|
+
/**
|
|
8
|
+
* Parameters for fetching navigation trees.
|
|
9
|
+
*/
|
|
4
10
|
export interface FetchNavigationTreesParams {
|
|
5
11
|
params?: GetNavigationParameters;
|
|
6
12
|
}
|
|
7
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Parameters for fetching a navigation tree by ID.
|
|
15
|
+
*/
|
|
16
|
+
export interface FetchNavigationTreeByIdParams extends FetchNavigationTreesParams {
|
|
8
17
|
treeId: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parameters for fetching a navigation tree by name.
|
|
21
|
+
*/
|
|
22
|
+
export interface FetchNavigationTreeByNameParams extends FetchNavigationTreesParams {
|
|
11
23
|
treeName: string;
|
|
12
|
-
}
|
|
24
|
+
}
|