@modern-js/main-doc 2.66.0 → 2.66.1-alpha.1
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/docs/en/apis/app/hooks/src/app.mdx +20 -34
- package/docs/en/apis/app/hooks/src/modern.runtime.mdx +9 -0
- package/docs/en/apis/app/runtime/app/define-config.mdx +6 -0
- package/docs/en/apis/app/runtime/web-server/hook.mdx +5 -0
- package/docs/en/apis/app/runtime/web-server/middleware.mdx +2 -23
- package/docs/en/components/enable-micro-frontend.mdx +20 -3
- package/docs/en/components/micro-runtime-config.mdx +12 -13
- package/docs/en/components/reduck-notify.mdx +27 -0
- package/docs/en/components/runtime-cli-config.mdx +0 -0
- package/docs/en/configure/app/runtime/0-intro.mdx +66 -90
- package/docs/en/configure/app/usage.mdx +93 -69
- package/docs/en/guides/advanced-features/web-server.mdx +38 -102
- package/docs/en/guides/basic-features/render/_meta.json +1 -1
- package/docs/en/guides/basic-features/render/before-render.mdx +115 -0
- package/docs/en/guides/basic-features/routes.mdx +0 -95
- package/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
- package/docs/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
- package/docs/en/guides/topic-detail/model/auto-actions.mdx +0 -4
- package/docs/en/guides/topic-detail/model/computed-state.mdx +0 -5
- package/docs/en/guides/topic-detail/model/define-model.mdx +0 -4
- package/docs/en/guides/topic-detail/model/faq.mdx +0 -5
- package/docs/en/guides/topic-detail/model/manage-effects.mdx +0 -5
- package/docs/en/guides/topic-detail/model/model-communicate.mdx +0 -5
- package/docs/en/guides/topic-detail/model/performance.mdx +0 -4
- package/docs/en/guides/topic-detail/model/quick-start.mdx +5 -7
- package/docs/en/guides/topic-detail/model/redux-integration.mdx +0 -4
- package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
- package/docs/en/guides/topic-detail/model/use-model.mdx +0 -5
- package/docs/en/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
- package/docs/zh/apis/app/hooks/src/app.mdx +18 -26
- package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +9 -0
- package/docs/zh/apis/app/runtime/app/define-config.mdx +5 -0
- package/docs/zh/apis/app/runtime/web-server/hook.mdx +4 -0
- package/docs/zh/apis/app/runtime/web-server/middleware.mdx +2 -23
- package/docs/zh/components/enable-micro-frontend.mdx +19 -12
- package/docs/zh/components/micro-runtime-config.mdx +3 -3
- package/docs/zh/components/reduck-notify.mdx +27 -0
- package/docs/zh/components/runtime-cli-config.mdx +0 -0
- package/docs/zh/configure/app/runtime/0-intro.mdx +71 -86
- package/docs/zh/configure/app/usage.mdx +44 -21
- package/docs/zh/guides/advanced-features/web-server.mdx +35 -97
- package/docs/zh/guides/basic-features/render/_meta.json +1 -1
- package/docs/zh/guides/basic-features/render/before-render.mdx +115 -0
- package/docs/zh/guides/basic-features/routes.mdx +0 -95
- package/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
- package/docs/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
- package/docs/zh/guides/topic-detail/model/auto-actions.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/computed-state.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/define-model.mdx +1 -4
- package/docs/zh/guides/topic-detail/model/faq.mdx +0 -5
- package/docs/zh/guides/topic-detail/model/manage-effects.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/model-communicate.mdx +1 -4
- package/docs/zh/guides/topic-detail/model/performance.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/quick-start.mdx +7 -8
- package/docs/zh/guides/topic-detail/model/redux-integration.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/use-model.mdx +0 -5
- package/docs/zh/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
- package/package.json +1 -1
- package/docs/en/configure/app/server/enable-framework-ext.mdx +0 -49
- package/docs/zh/configure/app/server/enable-framework-ext.mdx +0 -49
@@ -480,101 +480,6 @@ The `prefetch` attribute has three optional values:
|
|
480
480
|
|
481
481
|
:::
|
482
482
|
|
483
|
-
|
484
|
-
## Runtime Configuration
|
485
|
-
|
486
|
-
{/* Todo Move to runtime configuration chapter */}
|
487
|
-
|
488
|
-
In the root `<Layout>` component (`routes/layout.ts`), you can dynamically define runtime configuration:
|
489
|
-
|
490
|
-
```tsx title="src/routes/layout.tsx"
|
491
|
-
// Define runtime configuration
|
492
|
-
import type { AppConfig } from '@modern-js/runtime';
|
493
|
-
|
494
|
-
export const config = (): AppConfig => {
|
495
|
-
return {
|
496
|
-
router: {
|
497
|
-
createRoutes() {
|
498
|
-
return [
|
499
|
-
{
|
500
|
-
path: 'modern',
|
501
|
-
element: <div>modern</div>,
|
502
|
-
},
|
503
|
-
];
|
504
|
-
},
|
505
|
-
},
|
506
|
-
};
|
507
|
-
};
|
508
|
-
```
|
509
|
-
|
510
|
-
## Pre-render Hooks
|
511
|
-
|
512
|
-
{/* Todo Move to runtime configuration chapter */}
|
513
|
-
|
514
|
-
In some scenarios, you need to perform certain actions before the application renders. You can define the `init` hook in `routes/layout.tsx`, which will be executed both on the client and server. A basic example is shown below:
|
515
|
-
|
516
|
-
```ts title="src/routes/layout.tsx"
|
517
|
-
import type { RuntimeContext } from '@modern-js/runtime';
|
518
|
-
|
519
|
-
export const init = (context: RuntimeContext) => {
|
520
|
-
// do something
|
521
|
-
};
|
522
|
-
```
|
523
|
-
|
524
|
-
With the `init` hook, you can mount some global data that can be accessed elsewhere in the application via the `runtimeContext` variable:
|
525
|
-
|
526
|
-
:::note
|
527
|
-
This feature is very useful when applications require pre-rendered data, custom data injection, or framework migration (e.g., Next.js).
|
528
|
-
:::
|
529
|
-
|
530
|
-
```ts title="src/routes/layout.tsx"
|
531
|
-
import { RuntimeContext } from '@modern-js/runtime';
|
532
|
-
|
533
|
-
type InitialData = {
|
534
|
-
message: string;
|
535
|
-
}
|
536
|
-
|
537
|
-
export const init = (context: RuntimeContext): InitialData => {
|
538
|
-
return {
|
539
|
-
message: 'Hello World',
|
540
|
-
};
|
541
|
-
};
|
542
|
-
```
|
543
|
-
|
544
|
-
```tsx title="src/routes/page.tsx"
|
545
|
-
import { useRuntimeContext } from '@modern-js/runtime;
|
546
|
-
|
547
|
-
export default () => {
|
548
|
-
const context = useRuntimeContext();
|
549
|
-
const { message } = context.initialData as InitialData;
|
550
|
-
|
551
|
-
return <div>{message}</div>;
|
552
|
-
};
|
553
|
-
```
|
554
|
-
|
555
|
-
With SSR, the browser can obtain the data returned by `init` during SSR. Developers can decide whether to re-fetch the data on the browser side to override the SSR data. For example:
|
556
|
-
|
557
|
-
```tsx title="src/routes/layout.tsx"
|
558
|
-
import type { RuntimeContext } from '@modern-js/runtime;
|
559
|
-
|
560
|
-
export const init = (runtimeContext: RuntimeContext) => {
|
561
|
-
if (process.env.MODERN_TARGET === 'node') {
|
562
|
-
return {
|
563
|
-
message: 'Hello World By Server',
|
564
|
-
};
|
565
|
-
} else {
|
566
|
-
const { context } = runtimeContext;
|
567
|
-
const data = context.getInitData();
|
568
|
-
// If the expected data is not obtained
|
569
|
-
if (!data.message) {
|
570
|
-
return {
|
571
|
-
message: 'Hello World By Client',
|
572
|
-
};
|
573
|
-
}
|
574
|
-
}
|
575
|
-
};
|
576
|
-
```
|
577
|
-
|
578
483
|
<Motivation />
|
579
484
|
|
580
485
|
## FAQ
|
@@ -14,9 +14,9 @@ Through this chapter you can learn:
|
|
14
14
|
|
15
15
|
The routing modes of the current project are divided into the following three types:
|
16
16
|
|
17
|
-
-
|
18
|
-
- Self-
|
19
|
-
- Other (
|
17
|
+
- [Conventional Routing](/guides/concept/entries.html#conventional-routing)
|
18
|
+
- [Self-controlled Routing](/guides/concept/entries.html#self-controlled-routing)
|
19
|
+
- Other (independent installation of `react-router-dom` in the project)
|
20
20
|
|
21
21
|
First, clarify the routing mode of the main application [create a file-based routing main App](#file-based-routing-main-app) or [create a self-controlled main App](#self-controlled-main-app)
|
22
22
|
|
@@ -198,7 +198,6 @@ export default defineConfig({
|
|
198
198
|
},
|
199
199
|
runtime: {
|
200
200
|
router: true,
|
201
|
-
state: true,
|
202
201
|
},
|
203
202
|
deploy: {
|
204
203
|
microFrontend: true,
|
@@ -245,7 +244,6 @@ export default defineConfig({
|
|
245
244
|
},
|
246
245
|
runtime: {
|
247
246
|
router: true,
|
248
|
-
state: true,
|
249
247
|
},
|
250
248
|
deploy: {
|
251
249
|
microFrontend: true,
|
@@ -35,8 +35,10 @@ import MicroRuntimeConfig from '@site-docs-en/components/micro-runtime-config';
|
|
35
35
|
|
36
36
|
This function allows you to pull a list of remote child applications and register them with the runtime framework:
|
37
37
|
|
38
|
-
```ts title="
|
39
|
-
|
38
|
+
```ts title="src/modern.runtime.ts"
|
39
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
40
|
+
|
41
|
+
export default defineRuntimeConfig({
|
40
42
|
masterApp: {
|
41
43
|
manifest: {
|
42
44
|
getAppList: async () => {
|
@@ -1,7 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 6
|
3
|
-
title: Automatically Actions
|
4
|
-
---
|
5
1
|
# Automatically Generated Actions
|
6
2
|
|
7
3
|
In the [Quick Start](/guides/topic-detail/model/quick-start), we implemented the simplest counter model, which still required 10 lines of code. In fact, Modern.js supports automatically generating commonly used actions based on the declared `state` type, which reduces the amount of boilerplate code. The currently supported types are:
|
@@ -1,8 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 4
|
3
|
-
title: Derived State
|
4
|
-
---
|
5
|
-
|
6
1
|
# Derived State
|
7
2
|
|
8
3
|
In some scenarios, components need to perform further calculations on the State in Model before they can be used in the components. This logic can be directly written in the component or implemented through derived states in Model. Derived states are defined under the `computed` field in the Model. Depending on the dependencies of the Model and the return type, there are three ways to define derived states.
|
@@ -1,8 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 5
|
3
|
-
title: Management Effect
|
4
|
-
---
|
5
|
-
|
6
1
|
# Management Effect
|
7
2
|
|
8
3
|
The actions in the model must be pure functions and cannot have any side effects during execution. However, in real-world scenarios, we often encounter many side effects, such as: requesting data from an HTTP API to obtain state data, or modifying `localStorage` or sending events while updating the state. In Reduck, side effects are managed through the model's `effects` function.
|
@@ -1,7 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 8
|
3
|
-
title: Performance Optimization
|
4
|
-
---
|
5
1
|
# Performance Optimization
|
6
2
|
|
7
3
|
Reduck has already done a lot of performance optimization work internally, so performance issues generally do not need to be considered. However, when performance is more sensitive, or when encountering performance issues, you can consider more targeted performance optimization from the following three aspects.
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
|
-
sidebar_position: 1
|
3
|
-
title: Quick Start
|
4
|
-
---
|
1
|
+
# Quick Start
|
5
2
|
|
6
3
|
:::caution
|
7
4
|
New projects are no longer recommended to use Reduck. You can use state management tools from the community, such as [Jotai](https://jotai.org/), [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction), [valtio](https://valtio.dev/docs/introduction/getting-started), etc.
|
8
5
|
:::
|
9
6
|
|
10
|
-
|
7
|
+
import ReduckNotify from '@site-docs-en/components/reduck-notify';
|
8
|
+
|
9
|
+
<ReduckNotify />
|
11
10
|
|
12
11
|
import ReduckMigration from "@site-docs-en/components/reduck-migration"
|
13
12
|
|
@@ -22,8 +21,7 @@ In the MVC pattern, Reduck plays the role of M(Model), React UI Component corres
|
|
22
21
|
The state management solution of Modern.js is implemented through built-in Reduck. Using Reduck in Modern.js not only eliminates the manual integration process, but also allows all Reduck APIs to be imported and used directly from the Modern.js Runtime package, providing a better consistency experience.
|
23
22
|
|
24
23
|
:::info
|
25
|
-
|
26
|
-
2. Reduck can also be used separately as a state management library [outside of Modern.js](/guides/topic-detail/model/use-out-of-modernjs).
|
24
|
+
Reduck can also be used separately as a state management library [outside of Modern.js](/guides/topic-detail/model/use-out-of-modernjs).
|
27
25
|
|
28
26
|
:::
|
29
27
|
|
@@ -1,7 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 11
|
3
|
-
title: Ecosystem Integration
|
4
|
-
---
|
5
1
|
# Redux Ecosystem Integration
|
6
2
|
|
7
3
|
Reduck is based on Redux, so you can use libraries from the [Redux ecosystem](https://redux.js.org/introduction/ecosystem) to enhance its functionality. APIs like [`Provider`](/apis/app/runtime/model/Provider), [`createApp`](/apis/app/runtime/model/create-app), and [`createStore`](/apis/app/runtime/model/create-store) allow you to configure the use of [middlewares](https://redux.js.org/understanding/thinking-in-redux/glossary#middleware) and [store enhancers](https://redux.js.org/understanding/thinking-in-redux/glossary#store-enhancer); and using [`createStore`](/apis/app/runtime/model/create-store), you can take complete control over the process of creating the store.
|
@@ -1,7 +1,3 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 10
|
3
|
-
title: TS Best Practices
|
4
|
-
---
|
5
1
|
# TS Best Practices
|
6
2
|
|
7
3
|
Reduck provides excellent support for TypeScript, and in most cases, you can get API type prompts directly without any extra work. In this section, we will provide additional information on other usage scenarios.
|
@@ -2,6 +2,7 @@
|
|
2
2
|
title: App.[tj]sx
|
3
3
|
sidebar_position: 1
|
4
4
|
---
|
5
|
+
|
5
6
|
# App.[tj]sx
|
6
7
|
|
7
8
|
应用使用[自控路由](/guides/concept/entries.html#自控式路由)时的入口标识符。
|
@@ -9,35 +10,26 @@ sidebar_position: 1
|
|
9
10
|
`App.[tj]sx` 并不是实际的应用入口,Modern.js 会自动生成真正的构建打包的入口文件, 内容大致如下:
|
10
11
|
|
11
12
|
```js
|
12
|
-
|
13
|
-
import
|
14
|
-
import { createApp, bootstrap } from '@modern-js/runtime';
|
15
|
-
// App.[jt]sx
|
13
|
+
// runtime-global-context
|
14
|
+
import { setGlobalContext } from '@modern-js/runtime/context';
|
16
15
|
import App from '@_modern_js_src/App';
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
})(App)
|
31
|
-
if (IS_BROWSER) {
|
32
|
-
bootstrap(AppWrapper, MOUNT_ID, null, ReactDOM);
|
33
|
-
}
|
34
|
-
return AppWrapper
|
35
|
-
}
|
36
|
-
|
37
|
-
AppWrapper = render();
|
38
|
-
export default AppWrapper;
|
16
|
+
|
17
|
+
setGlobalContext({
|
18
|
+
App,
|
19
|
+
});
|
20
|
+
|
21
|
+
// index.tsx
|
22
|
+
import './runtime-global-context';
|
23
|
+
import { createRoot } from '@modern-js/runtime/react';
|
24
|
+
import { render } from '@modern-js/runtime/browser';
|
25
|
+
|
26
|
+
const ModernRoot = createRoot();
|
27
|
+
|
28
|
+
render(<ModernRoot />, 'root');
|
39
29
|
```
|
40
30
|
|
31
|
+
`createRoot` 执行时,会去获取注册的 Globa App,生成真实的 React 组件。
|
32
|
+
|
41
33
|
:::note
|
42
34
|
在多入口的场景下,每个入口都可以拥有独立的 `App.[jt]sx`,详见[入口](/guides/concept/entries)。
|
43
35
|
|
@@ -6,6 +6,10 @@ title: Hook
|
|
6
6
|
|
7
7
|
用于拓展 Modern.js 内置的 Web Server,所有的页面请求都会经过 Hook。
|
8
8
|
|
9
|
+
:::warning
|
10
|
+
推荐使用 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware) 来处理页面请求。
|
11
|
+
:::
|
12
|
+
|
9
13
|
:::note
|
10
14
|
更多内容可以查看[自定义 Web Server](/guides/advanced-features/web-server)。
|
11
15
|
:::
|
@@ -6,11 +6,9 @@ title: Middleware
|
|
6
6
|
|
7
7
|
用于拓展 Modern.js 内置的 Web Server,与 [Hook](/apis/app/runtime/web-server/hook) 不同的是,Middleware 可以直接操作 Node 原生的请求、响应对象,并且可以使用框架拓展。
|
8
8
|
|
9
|
-
:::
|
10
|
-
|
11
|
-
在下一个大版本,Modern.js 将会使用新 Middleware 来替代该写法。
|
9
|
+
:::warning
|
12
10
|
|
13
|
-
|
11
|
+
Middleware 将会在下一个大版本中废弃,推荐使用 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware) 处理页面请求。
|
14
12
|
|
15
13
|
:::
|
16
14
|
|
@@ -119,22 +117,3 @@ export const Middleware = () => async (ctx, next) => {
|
|
119
117
|
ctx.response.locals.rpc = createRpcInstance();
|
120
118
|
};
|
121
119
|
```
|
122
|
-
|
123
|
-
### 框架拓展
|
124
|
-
|
125
|
-
Middleware 还可以和 BFF 一样,使用运行时框架拓展。Modern.js 约定,当使用框架运行时拓展时,类型信息从 `@modern-js/runtime/{namespace}` 下导出,Middleware 可以使用框架语法,例如框架中间件写法,以下是伪代码:
|
126
|
-
|
127
|
-
```ts
|
128
|
-
import { SomeType } from '@modern-js/runtime/{namespace}';
|
129
|
-
|
130
|
-
export const middleware: SomeType = (ctx, next) => {
|
131
|
-
console.log(ctx.url);
|
132
|
-
next();
|
133
|
-
};
|
134
|
-
```
|
135
|
-
|
136
|
-
默认情况下,在安装框架拓展插件后,Web Server 的框架拓展能力是关闭的。如果希望使用框架拓展,可以通过 [`server.enableFrameworkExt`](/configure/app/server/enable-framework-ext.html) 开启。
|
137
|
-
|
138
|
-
:::info
|
139
|
-
框架拓展导出的类型名不一定为 Middleware,命名由框架拓展插件。
|
140
|
-
:::
|
@@ -1,23 +1,30 @@
|
|
1
|
-
```
|
1
|
+
```ts title="modern.config.ts"
|
2
2
|
import { appTools, defineConfig } from '@modern-js/app-tools';
|
3
3
|
import { garfishPlugin } from '@modern-js/plugin-garfish';
|
4
4
|
|
5
5
|
export default defineConfig({
|
6
6
|
runtime: {
|
7
7
|
router: true,
|
8
|
-
masterApp: {
|
9
|
-
apps: [{
|
10
|
-
name: 'Table',
|
11
|
-
entry: 'http://localhost:8081',
|
12
|
-
// activeWhen: '/table'
|
13
|
-
}, {
|
14
|
-
name: 'Dashboard',
|
15
|
-
entry: 'http://localhost:8082'
|
16
|
-
// activeWhen: '/dashboard'
|
17
|
-
}]
|
18
|
-
},
|
19
8
|
},
|
20
9
|
plugins: [appTools(), garfishPlugin()],
|
21
10
|
});
|
22
11
|
|
23
12
|
```
|
13
|
+
|
14
|
+
```ts title="src/modern.runtime.ts"
|
15
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
16
|
+
|
17
|
+
export default defineRuntimeConfig({
|
18
|
+
masterApp: {
|
19
|
+
apps: [{
|
20
|
+
name: 'Table',
|
21
|
+
entry: 'http://localhost:8081',
|
22
|
+
// activeWhen: '/table'
|
23
|
+
}, {
|
24
|
+
name: 'Dashboard',
|
25
|
+
entry: 'http://localhost:8082'
|
26
|
+
// activeWhen: '/dashboard'
|
27
|
+
}]
|
28
|
+
},
|
29
|
+
});
|
30
|
+
```
|
@@ -1,7 +1,7 @@
|
|
1
|
-
```
|
2
|
-
import {
|
1
|
+
```ts title="src/modern.runtime.ts"
|
2
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
3
3
|
|
4
|
-
|
4
|
+
export default defineRuntimeConfig({
|
5
5
|
masterApp: {
|
6
6
|
apps: [{
|
7
7
|
name: 'Table',
|
@@ -0,0 +1,27 @@
|
|
1
|
+
:::warning
|
2
|
+
从 `MAJOR_VERSION.67.0` 起,Modern.js 不再默认提供 Reduck 状态管理能力。如果需要使用 Reduck,您需要安装并注册 state 插件。
|
3
|
+
|
4
|
+
**安装步骤**
|
5
|
+
|
6
|
+
1. 安装 `@modern-js/plugin-state` 依赖:
|
7
|
+
|
8
|
+
```bash
|
9
|
+
pnpm add @modern-js/plugin-state
|
10
|
+
```
|
11
|
+
|
12
|
+
2. 注册 state 插件:
|
13
|
+
|
14
|
+
```ts title="modern.config.ts"
|
15
|
+
import { defineConfig } from '@modern-js/app-tools';
|
16
|
+
import { statePlugin } from '@modern-js/plugin-state';
|
17
|
+
|
18
|
+
export default defineConfig({
|
19
|
+
...,
|
20
|
+
plugins: [
|
21
|
+
...,
|
22
|
+
statePlugin(),
|
23
|
+
],
|
24
|
+
});
|
25
|
+
```
|
26
|
+
|
27
|
+
:::
|
File without changes
|