includio-cms 0.26.0 → 0.28.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/API.md +58 -2
- package/CHANGELOG.md +105 -0
- package/DOCS.md +1 -1
- package/ROADMAP.md +8 -0
- package/dist/admin/auth-client.d.ts +42 -42
- package/dist/admin/client/admin/admin-layout.svelte +12 -2
- package/dist/admin/client/admin/admin-layout.svelte.d.ts +2 -1
- package/dist/admin/client/collection/data-table.svelte +0 -39
- package/dist/admin/client/collection/data-table.svelte.d.ts +0 -2
- package/dist/admin/client/shop/coupon-schema.d.ts +1 -1
- package/dist/admin/client/shop/refund-dialog.svelte +37 -1
- package/dist/admin/client/shop/refund-dialog.svelte.d.ts +3 -0
- package/dist/admin/client/shop/shop-order-detail-page.svelte +192 -0
- package/dist/admin/components/fields/field-renderer.svelte +6 -1
- package/dist/admin/components/fields/icon-field.svelte +86 -0
- package/dist/admin/components/fields/icon-field.svelte.d.ts +8 -0
- package/dist/admin/components/fields/icon-picker-dialog.svelte +174 -0
- package/dist/admin/components/fields/icon-picker-dialog.svelte.d.ts +11 -0
- package/dist/admin/components/fields/object-field.svelte +27 -7
- package/dist/admin/components/fields/shop-field.svelte +210 -20
- package/dist/admin/components/layout/layout-tabs.svelte +1 -0
- package/dist/admin/components/variant-form/VariantAttributeRenderer.svelte +109 -0
- package/dist/admin/components/variant-form/VariantAttributeRenderer.svelte.d.ts +9 -0
- package/dist/admin/helpers/build-icon-set-map.d.ts +8 -0
- package/dist/admin/helpers/build-icon-set-map.js +16 -0
- package/dist/admin/helpers/index.d.ts +2 -0
- package/dist/admin/helpers/index.js +2 -0
- package/dist/admin/remote/shop.remote.d.ts +116 -24
- package/dist/admin/remote/shop.remote.js +79 -6
- package/dist/admin/state/icon-sets.svelte.d.ts +9 -0
- package/dist/admin/state/icon-sets.svelte.js +20 -0
- package/dist/cli/scaffold/admin.js +2 -2
- package/dist/components/ui/checkbox/checkbox.svelte +3 -3
- package/dist/core/cms.d.ts +11 -2
- package/dist/core/cms.js +29 -0
- package/dist/core/fields/fieldSchemaToTs.js +7 -0
- package/dist/core/server/generator/fields.d.ts +2 -0
- package/dist/core/server/generator/fields.js +34 -1
- package/dist/core/server/generator/generator.js +2 -1
- package/dist/db-postgres/schema/shop/index.d.ts +1 -0
- package/dist/db-postgres/schema/shop/index.js +1 -0
- package/dist/db-postgres/schema/shop/invoice.d.ts +254 -0
- package/dist/db-postgres/schema/shop/invoice.js +27 -0
- package/dist/db-postgres/schema/shop/order.d.ts +107 -1
- package/dist/db-postgres/schema/shop/order.js +7 -1
- package/dist/db-postgres/schema/shop/payment.d.ts +20 -0
- package/dist/db-postgres/schema/shop/payment.js +4 -1
- package/dist/db-postgres/schema/shop/product.d.ts +20 -0
- package/dist/db-postgres/schema/shop/product.js +3 -1
- package/dist/db-postgres/schema/shop/productVariant.d.ts +12 -2
- package/dist/db-postgres/schema/shop/productVariant.js +22 -0
- package/dist/paraglide/messages/_index.d.ts +36 -3
- package/dist/paraglide/messages/_index.js +71 -3
- package/dist/paraglide/messages/en.d.ts +5 -0
- package/dist/paraglide/messages/en.js +14 -0
- package/dist/paraglide/messages/pl.d.ts +5 -0
- package/dist/paraglide/messages/pl.js +14 -0
- package/dist/shop/adapters/fakturownia/client.d.ts +28 -0
- package/dist/shop/adapters/fakturownia/client.js +67 -0
- package/dist/shop/adapters/fakturownia/index.d.ts +27 -0
- package/dist/shop/adapters/fakturownia/index.js +36 -0
- package/dist/shop/adapters/fakturownia/payload.d.ts +35 -0
- package/dist/shop/adapters/fakturownia/payload.js +45 -0
- package/dist/shop/cart/types.d.ts +1 -0
- package/dist/shop/client/index.d.ts +61 -0
- package/dist/shop/client/index.js +5 -1
- package/dist/shop/expiry.d.ts +35 -0
- package/dist/shop/expiry.js +68 -0
- package/dist/shop/http/balance-handler.d.ts +20 -0
- package/dist/shop/http/balance-handler.js +91 -0
- package/dist/shop/http/cart-handler.js +19 -0
- package/dist/shop/http/checkout-handler.js +30 -1
- package/dist/shop/http/index.d.ts +2 -0
- package/dist/shop/http/index.js +2 -0
- package/dist/shop/http/upcoming-handler.d.ts +16 -0
- package/dist/shop/http/upcoming-handler.js +65 -0
- package/dist/shop/http/webhook-handler.js +46 -9
- package/dist/shop/index.d.ts +7 -1
- package/dist/shop/index.js +10 -1
- package/dist/shop/nip.d.ts +12 -0
- package/dist/shop/nip.js +23 -0
- package/dist/shop/server/balance-payment.d.ts +40 -0
- package/dist/shop/server/balance-payment.js +140 -0
- package/dist/shop/server/cart-hydrate.js +2 -0
- package/dist/shop/server/init.d.ts +14 -0
- package/dist/shop/server/init.js +35 -0
- package/dist/shop/server/invoices.d.ts +64 -0
- package/dist/shop/server/invoices.js +237 -0
- package/dist/shop/server/orders.d.ts +38 -0
- package/dist/shop/server/orders.js +152 -2
- package/dist/shop/server/payment-policy.d.ts +35 -0
- package/dist/shop/server/payment-policy.js +55 -0
- package/dist/shop/server/payments.d.ts +29 -0
- package/dist/shop/server/payments.js +64 -0
- package/dist/shop/server/populate.d.ts +1 -1
- package/dist/shop/server/refund.d.ts +17 -12
- package/dist/shop/server/refund.js +96 -13
- package/dist/shop/server/shop-data.d.ts +4 -1
- package/dist/shop/server/shop-data.js +24 -2
- package/dist/shop/template.d.ts +13 -0
- package/dist/shop/template.js +98 -0
- package/dist/shop/types.d.ts +208 -1
- package/dist/shop/variant-attributes.d.ts +28 -0
- package/dist/shop/variant-attributes.js +69 -0
- package/dist/sveltekit/server/index.d.ts +1 -0
- package/dist/sveltekit/server/index.js +2 -0
- package/dist/types/cms.d.ts +4 -3
- package/dist/types/cms.schema.d.ts +1 -1
- package/dist/types/cms.schema.js +9 -0
- package/dist/types/fields.d.ts +21 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/plugins.d.ts +40 -0
- package/dist/types/plugins.js +4 -1
- package/dist/updates/0.26.1/index.d.ts +2 -0
- package/dist/updates/0.26.1/index.js +19 -0
- package/dist/updates/0.27.0/index.d.ts +2 -0
- package/dist/updates/0.27.0/index.js +50 -0
- package/dist/updates/0.28.0/index.d.ts +2 -0
- package/dist/updates/0.28.0/index.js +38 -0
- package/dist/updates/index.js +7 -1
- package/package.json +1 -1
- package/dist/paraglide/messages/hello_world.d.ts +0 -5
- package/dist/paraglide/messages/hello_world.js +0 -33
- package/dist/paraglide/messages/login_hello.d.ts +0 -16
- package/dist/paraglide/messages/login_hello.js +0 -34
- package/dist/paraglide/messages/login_please_login.d.ts +0 -16
- package/dist/paraglide/messages/login_please_login.js +0 -34
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const update = {
|
|
2
|
+
version: '0.28.0',
|
|
3
|
+
date: '2026-06-01',
|
|
4
|
+
description: 'Fakturowanie — integracja sklepu z Fakturownią: automatyczne wystawianie i wysyłka faktury po opłaceniu zamówienia. Nowy generyczny `InvoicingAdapter` (spójny z payment/carrier) + `fakturowniaAdapter()` jako pierwsza implementacja. Faktura wystawiana fire-and-forget gdy zamówienie jest w pełni opłacone (`!balanceOwed` — zaliczki czekają na dopłatę balansu), wysyłana przez Fakturownię (`send_by_email`). Trigger konfigurowalny per-adapter (`issueWhen`: `b2bAndOnRequest` domyślnie / `always`). Checkout zbiera dane B2B (NIP z twardą walidacją sumy kontrolnej, nazwa firmy, adres do faktury, opt-in „chcę fakturę"). Idempotencja przez `shop_invoices` (unikat per zamówienie); ręczny retry w adminie. Additive only — żadnych breaking zmian.',
|
|
5
|
+
features: [
|
|
6
|
+
'`defineShop({ invoicing })` (`includio-cms/shop`) — nowy opcjonalny slot adaptera fakturowania, analogiczny do `payment` / `carriers`. `InvoicingAdapter { id, issueWhen?, createInvoice(payload, ctx), send?(externalId, ctx) }` + typy payloadu (`InvoicePayload`, `InvoiceBuyer`, `InvoiceLineItem`, `InvoiceCreateResult`, `InvoiceContext`, `InvoiceIssuePolicy`) wyeksportowane jako `@public` z `includio-cms/shop`.',
|
|
7
|
+
'`fakturowniaAdapter({ domain, apiToken, kind?, issueWhen?, sendEmail? })` (`includio-cms/shop`, `@public`) — adapter dla Fakturowni (fakturownia.pl). `createInvoice` mapuje zamówienie na fakturę VAT oznaczoną jako opłacona (`paid_date` = data potwierdzenia płatności), `send` woła `send_by_email` (domyślnie włączone). Numeracja i dane sprzedawcy zarządzane po stronie konta Fakturowni. Sekret `apiToken` przekazywany przez konsumenta z `$env/dynamic/private` (jak `STRIPE_SECRET_KEY`).',
|
|
8
|
+
'Auto-faktura po opłaceniu — `maybeIssueInvoiceForOrder(orderId)` (`$lib/shop/server/invoices.ts`) wołane fire-and-forget z `updateOrderStatus` (przy `paid`) oraz z `markBalancePaid` (po dopłacie balansu). Fail-open: błąd providera nie blokuje webhooka płatności. Guard wystawia fakturę tylko gdy zamówienie w pełni opłacone (`status ∈ {paid, preparing, sent, done}` && `!balanceOwed`) — deposit czeka na dopłatę.',
|
|
9
|
+
'Konfigurowalny trigger `issueWhen`: `b2bAndOnRequest` (domyślny — faktura gdy podano NIP lub zaznaczono „chcę fakturę") albo `always` (każde opłacone zamówienie, np. dla klienta wymagającego faktur również dla osób fizycznych).',
|
|
10
|
+
'`shop_invoices` (nowa tabela) — jedna faktura per zamówienie (`order_id` UNIQUE → idempotencja). Pola `status` (`pending`/`issued`/`sent`/`failed`), `external_id`, `number`, `pdf_url`, `attempts`, `next_retry_at`, `last_error`, `raw`. Kolumny `attempts`/`next_retry_at` zarezerwowane pod przyszły automatyczny retry (obecnie tylko ręczny).',
|
|
11
|
+
'Checkout B2B — `shop_orders` dostaje kolumny `customer_nip`, `customer_company_name`, `billing_address` (jsonb), `invoice_requested` (boolean). `createOrderFromCart` / `checkout-handler` przyjmują i zapisują te pola; `CheckoutInput` (`includio-cms/shop/client`) rozszerzony. Storefront form (pola NIP/firma/checkbox/adres) = warstwa konsumenta.',
|
|
12
|
+
'`isValidNip(nip)` (`includio-cms/shop`, `@public`) — twarda walidacja polskiego NIP (10 cyfr + suma kontrolna, wagi `[6,5,7,2,3,4,5,6,7]`). Checkout odrzuca nieprawidłowy NIP (400) zanim trafi do bazy — Fakturownia odrzuciłaby błędny NIP, a faktura idzie dalej do KSeF, więc walidujemy u źródła.',
|
|
13
|
+
'`getOrderInvoiceAdmin` (query) + `issueInvoiceCmd` (command) — admin remote functions (`includio-cms/admin/remote`). `shop-order-detail-page.svelte` zyskuje sekcję „Faktura": numer, link do PDF, status, przycisk „Wystaw fakturę" / „Wystaw ponownie" (ręczny retry, `force`). Auth-protected (`requireAuth`).'
|
|
14
|
+
],
|
|
15
|
+
fixes: [],
|
|
16
|
+
breakingChanges: [],
|
|
17
|
+
sql: `CREATE TABLE IF NOT EXISTS shop_invoices (
|
|
18
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
19
|
+
order_id uuid NOT NULL UNIQUE REFERENCES shop_orders(id) ON DELETE CASCADE,
|
|
20
|
+
provider text NOT NULL,
|
|
21
|
+
external_id text,
|
|
22
|
+
number text,
|
|
23
|
+
pdf_url text,
|
|
24
|
+
kind text NOT NULL DEFAULT 'vat',
|
|
25
|
+
status text NOT NULL DEFAULT 'pending',
|
|
26
|
+
attempts integer NOT NULL DEFAULT 0,
|
|
27
|
+
next_retry_at timestamptz,
|
|
28
|
+
last_error text,
|
|
29
|
+
raw jsonb,
|
|
30
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
31
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS customer_nip text;
|
|
35
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS customer_company_name text;
|
|
36
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS billing_address jsonb;
|
|
37
|
+
ALTER TABLE shop_orders ADD COLUMN IF NOT EXISTS invoice_requested boolean NOT NULL DEFAULT false;`
|
|
38
|
+
};
|
package/dist/updates/index.js
CHANGED
|
@@ -60,6 +60,9 @@ import { update as update0230 } from './0.23.0/index.js';
|
|
|
60
60
|
import { update as update0240 } from './0.24.0/index.js';
|
|
61
61
|
import { update as update0250 } from './0.25.0/index.js';
|
|
62
62
|
import { update as update0260 } from './0.26.0/index.js';
|
|
63
|
+
import { update as update0261 } from './0.26.1/index.js';
|
|
64
|
+
import { update as update0270 } from './0.27.0/index.js';
|
|
65
|
+
import { update as update0280 } from './0.28.0/index.js';
|
|
63
66
|
export const updates = [
|
|
64
67
|
update0065,
|
|
65
68
|
update0066,
|
|
@@ -122,7 +125,10 @@ export const updates = [
|
|
|
122
125
|
update0230,
|
|
123
126
|
update0240,
|
|
124
127
|
update0250,
|
|
125
|
-
update0260
|
|
128
|
+
update0260,
|
|
129
|
+
update0261,
|
|
130
|
+
update0270,
|
|
131
|
+
update0280
|
|
126
132
|
];
|
|
127
133
|
export const getUpdatesFrom = (fromVersion) => {
|
|
128
134
|
const fromParts = fromVersion.split('.').map(Number);
|
package/package.json
CHANGED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
-
|
|
4
|
-
const en_hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
5
|
-
return `Hello, ${i.name} from en!`
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const pl_hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
9
|
-
return `Hello, ${i.name} from pl!`
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
-
*
|
|
15
|
-
* - Changing this function will be over-written by the next build.
|
|
16
|
-
*
|
|
17
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
-
*
|
|
20
|
-
* @param {{ name: NonNullable<unknown> }} inputs
|
|
21
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
-
* @returns {string}
|
|
23
|
-
*/
|
|
24
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
-
export const hello_world = (inputs, options = {}) => {
|
|
26
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.hello_world(inputs)
|
|
28
|
-
}
|
|
29
|
-
const locale = options.locale ?? getLocale()
|
|
30
|
-
trackMessageCall("hello_world", locale)
|
|
31
|
-
if (locale === "en") return en_hello_world(inputs)
|
|
32
|
-
return pl_hello_world(inputs)
|
|
33
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export { login_hello as login.hello };
|
|
2
|
-
/**
|
|
3
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
4
|
-
*
|
|
5
|
-
* - Changing this function will be over-written by the next build.
|
|
6
|
-
*
|
|
7
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
8
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
9
|
-
*
|
|
10
|
-
* @param {{}} inputs
|
|
11
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
declare function login_hello(inputs?: {}, options?: {
|
|
15
|
-
locale?: "en" | "pl";
|
|
16
|
-
}): string;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
-
|
|
4
|
-
const en_login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
5
|
-
return `Welcome back`
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const pl_login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
-
return `Witaj ponownie`
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
-
*
|
|
15
|
-
* - Changing this function will be over-written by the next build.
|
|
16
|
-
*
|
|
17
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
-
*
|
|
20
|
-
* @param {{}} inputs
|
|
21
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
-
* @returns {string}
|
|
23
|
-
*/
|
|
24
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
-
const login_hello = (inputs = {}, options = {}) => {
|
|
26
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.login_hello(inputs)
|
|
28
|
-
}
|
|
29
|
-
const locale = options.locale ?? getLocale()
|
|
30
|
-
trackMessageCall("login_hello", locale)
|
|
31
|
-
if (locale === "en") return en_login_hello(inputs)
|
|
32
|
-
return pl_login_hello(inputs)
|
|
33
|
-
};
|
|
34
|
-
export { login_hello as "login.hello" }
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export { login_please_login as login.please_login };
|
|
2
|
-
/**
|
|
3
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
4
|
-
*
|
|
5
|
-
* - Changing this function will be over-written by the next build.
|
|
6
|
-
*
|
|
7
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
8
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
9
|
-
*
|
|
10
|
-
* @param {{}} inputs
|
|
11
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
declare function login_please_login(inputs?: {}, options?: {
|
|
15
|
-
locale?: "en" | "pl";
|
|
16
|
-
}): string;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from '../runtime.js';
|
|
3
|
-
|
|
4
|
-
const en_login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
5
|
-
return `Login to your account`
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const pl_login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
-
return `Zaloguj się na swoje konto`
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
14
|
-
*
|
|
15
|
-
* - Changing this function will be over-written by the next build.
|
|
16
|
-
*
|
|
17
|
-
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
18
|
-
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
19
|
-
*
|
|
20
|
-
* @param {{}} inputs
|
|
21
|
-
* @param {{ locale?: "en" | "pl" }} options
|
|
22
|
-
* @returns {string}
|
|
23
|
-
*/
|
|
24
|
-
/* @__NO_SIDE_EFFECTS__ */
|
|
25
|
-
const login_please_login = (inputs = {}, options = {}) => {
|
|
26
|
-
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
27
|
-
return /** @type {any} */ (globalThis).__paraglide_ssr.login_please_login(inputs)
|
|
28
|
-
}
|
|
29
|
-
const locale = options.locale ?? getLocale()
|
|
30
|
-
trackMessageCall("login_please_login", locale)
|
|
31
|
-
if (locale === "en") return en_login_please_login(inputs)
|
|
32
|
-
return pl_login_please_login(inputs)
|
|
33
|
-
};
|
|
34
|
-
export { login_please_login as "login.please_login" }
|