@truedat/bg 7.4.4 → 7.5.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "7.
|
|
37
|
+
"@truedat/test": "7.5.0",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@truedat/core": "7.
|
|
90
|
-
"@truedat/df": "7.
|
|
91
|
-
"@truedat/lm": "7.
|
|
89
|
+
"@truedat/core": "7.5.0",
|
|
90
|
+
"@truedat/df": "7.5.0",
|
|
91
|
+
"@truedat/lm": "7.5.0",
|
|
92
92
|
"decode-uri-component": "^0.2.2",
|
|
93
93
|
"file-saver": "^2.0.5",
|
|
94
94
|
"moment": "^2.29.4",
|
|
@@ -111,5 +111,5 @@
|
|
|
111
111
|
"react-dom": ">= 16.8.6 < 17",
|
|
112
112
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
113
113
|
},
|
|
114
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "c6088400f5b3724b8b358e9c4893096005fe4e42"
|
|
115
115
|
}
|
|
@@ -4,17 +4,17 @@ describe("selectors: getParsedEvents", () => {
|
|
|
4
4
|
const concept = {
|
|
5
5
|
template: {
|
|
6
6
|
content: [
|
|
7
|
-
{ fields: [{ type: "system", name: "field_1", label: "Label" }] }
|
|
8
|
-
]
|
|
9
|
-
}
|
|
7
|
+
{ fields: [{ type: "system", name: "field_1", label: "Label" }] },
|
|
8
|
+
],
|
|
9
|
+
},
|
|
10
10
|
};
|
|
11
11
|
const r1 = {
|
|
12
12
|
id: 1,
|
|
13
13
|
event: "update_concept_draft",
|
|
14
14
|
resource_id: 2,
|
|
15
15
|
payload: [
|
|
16
|
-
{ msg_key: "changed_field_without_target", msg_params: ["description"] }
|
|
17
|
-
]
|
|
16
|
+
{ msg_key: "changed_field_without_target", msg_params: ["description"] },
|
|
17
|
+
],
|
|
18
18
|
};
|
|
19
19
|
const r2 = {
|
|
20
20
|
id: 2,
|
|
@@ -22,35 +22,35 @@ describe("selectors: getParsedEvents", () => {
|
|
|
22
22
|
resource_id: 3,
|
|
23
23
|
payload: [
|
|
24
24
|
{ msg_key: "changed_field", msg_params: ["changed_field_1", "value_1"] },
|
|
25
|
-
{ msg_key: "changed_field", msg_params: ["changed_field_2", "value_2"] }
|
|
26
|
-
]
|
|
25
|
+
{ msg_key: "changed_field", msg_params: ["changed_field_2", "value_2"] },
|
|
26
|
+
],
|
|
27
27
|
};
|
|
28
28
|
const r3 = {
|
|
29
29
|
id: 3,
|
|
30
30
|
event: "unknown",
|
|
31
31
|
resource_id: 4,
|
|
32
|
-
payload: []
|
|
32
|
+
payload: [],
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
const r4 = {
|
|
36
36
|
id: 4,
|
|
37
37
|
event: "create_concept_draft",
|
|
38
38
|
resource_id: 5,
|
|
39
|
-
payload: [{ msg_key: "created_version", msg_params: [2] }]
|
|
39
|
+
payload: [{ msg_key: "created_version", msg_params: [2] }],
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const r5 = {
|
|
43
43
|
id: 5,
|
|
44
44
|
event: "new_concept_draft",
|
|
45
45
|
resource_id: 6,
|
|
46
|
-
payload: [{ msg_key: "created_version", msg_params: [2] }]
|
|
46
|
+
payload: [{ msg_key: "created_version", msg_params: [2] }],
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
const r6 = {
|
|
50
50
|
id: 6,
|
|
51
51
|
event: "delete_concept_draft",
|
|
52
52
|
resource_id: 7,
|
|
53
|
-
payload: [{ msg_key: "deleted_version", msg_params: [2] }]
|
|
53
|
+
payload: [{ msg_key: "deleted_version", msg_params: [2] }],
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
const r7 = {
|
|
@@ -60,9 +60,9 @@ describe("selectors: getParsedEvents", () => {
|
|
|
60
60
|
payload: [
|
|
61
61
|
{
|
|
62
62
|
msg_key: "concept_field",
|
|
63
|
-
msg_params: ["system", "group", "structure", "field"]
|
|
64
|
-
}
|
|
65
|
-
]
|
|
63
|
+
msg_params: ["system", "group", "structure", "field"],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
const r8 = {
|
|
@@ -72,9 +72,9 @@ describe("selectors: getParsedEvents", () => {
|
|
|
72
72
|
payload: [
|
|
73
73
|
{
|
|
74
74
|
msg_key: "concept_field",
|
|
75
|
-
msg_params: ["system", "group", "structure", "field"]
|
|
76
|
-
}
|
|
77
|
-
]
|
|
75
|
+
msg_params: ["system", "group", "structure", "field"],
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const r9 = {
|
|
@@ -84,9 +84,44 @@ describe("selectors: getParsedEvents", () => {
|
|
|
84
84
|
payload: [
|
|
85
85
|
{
|
|
86
86
|
msg_key: "changed_field_without_target",
|
|
87
|
-
msg_params: ["Label", JSON.stringify({ id: 1, name: "foo" })]
|
|
88
|
-
}
|
|
89
|
-
]
|
|
87
|
+
msg_params: ["Label", JSON.stringify({ id: 1, name: "foo" })],
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const r10 = {
|
|
93
|
+
id: 10,
|
|
94
|
+
event: "update_concept",
|
|
95
|
+
resource_id: 11,
|
|
96
|
+
payload: [
|
|
97
|
+
{
|
|
98
|
+
msg_key: "domain_updated_with_id",
|
|
99
|
+
msg_params: [2],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
const r11 = {
|
|
104
|
+
id: 11,
|
|
105
|
+
event: "update_concept",
|
|
106
|
+
resource_id: 12,
|
|
107
|
+
payload: [
|
|
108
|
+
{
|
|
109
|
+
msg_key: "domain_updated_with_names",
|
|
110
|
+
msg_params: ["foo", "bar"],
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const r12 = {
|
|
116
|
+
id: 12,
|
|
117
|
+
event: "update_concept",
|
|
118
|
+
resource_id: 13,
|
|
119
|
+
payload: [
|
|
120
|
+
{
|
|
121
|
+
msg_key: "shared_to",
|
|
122
|
+
msg_params: ["foo, bar"],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
90
125
|
};
|
|
91
126
|
|
|
92
127
|
const events = [
|
|
@@ -96,8 +131,8 @@ describe("selectors: getParsedEvents", () => {
|
|
|
96
131
|
resource_id: 2,
|
|
97
132
|
payload: {
|
|
98
133
|
description: {},
|
|
99
|
-
content: { removed: {}, changed: {}, added: {} }
|
|
100
|
-
}
|
|
134
|
+
content: { removed: {}, changed: {}, added: {} },
|
|
135
|
+
},
|
|
101
136
|
},
|
|
102
137
|
{
|
|
103
138
|
id: 2,
|
|
@@ -107,39 +142,39 @@ describe("selectors: getParsedEvents", () => {
|
|
|
107
142
|
content: {
|
|
108
143
|
removed: {},
|
|
109
144
|
changed: { changed_field_1: "value_1", changed_field_2: "value_2" },
|
|
110
|
-
added: {}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
145
|
+
added: {},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
113
148
|
},
|
|
114
149
|
{
|
|
115
150
|
id: 3,
|
|
116
151
|
event: "unknown",
|
|
117
152
|
resource_id: 4,
|
|
118
|
-
payload: {}
|
|
153
|
+
payload: {},
|
|
119
154
|
},
|
|
120
155
|
{
|
|
121
156
|
id: 4,
|
|
122
157
|
event: "create_concept_draft",
|
|
123
158
|
resource_id: 5,
|
|
124
159
|
payload: {
|
|
125
|
-
version: 2
|
|
126
|
-
}
|
|
160
|
+
version: 2,
|
|
161
|
+
},
|
|
127
162
|
},
|
|
128
163
|
{
|
|
129
164
|
id: 5,
|
|
130
165
|
event: "new_concept_draft",
|
|
131
166
|
resource_id: 6,
|
|
132
167
|
payload: {
|
|
133
|
-
version: 2
|
|
134
|
-
}
|
|
168
|
+
version: 2,
|
|
169
|
+
},
|
|
135
170
|
},
|
|
136
171
|
{
|
|
137
172
|
id: 6,
|
|
138
173
|
event: "delete_concept_draft",
|
|
139
174
|
resource_id: 7,
|
|
140
175
|
payload: {
|
|
141
|
-
version: 2
|
|
142
|
-
}
|
|
176
|
+
version: 2,
|
|
177
|
+
},
|
|
143
178
|
},
|
|
144
179
|
{
|
|
145
180
|
id: 7,
|
|
@@ -150,9 +185,9 @@ describe("selectors: getParsedEvents", () => {
|
|
|
150
185
|
system: "system",
|
|
151
186
|
group: "group",
|
|
152
187
|
structure: "structure",
|
|
153
|
-
field: "field"
|
|
154
|
-
}
|
|
155
|
-
}
|
|
188
|
+
field: "field",
|
|
189
|
+
},
|
|
190
|
+
},
|
|
156
191
|
},
|
|
157
192
|
{
|
|
158
193
|
id: 8,
|
|
@@ -165,24 +200,73 @@ describe("selectors: getParsedEvents", () => {
|
|
|
165
200
|
system: "system",
|
|
166
201
|
group: "group",
|
|
167
202
|
structure: "structure",
|
|
168
|
-
field: "field"
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
203
|
+
field: "field",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
173
208
|
},
|
|
174
209
|
{
|
|
175
210
|
id: 9,
|
|
176
211
|
event: "update_concept_draft",
|
|
177
212
|
resource_id: 10,
|
|
178
|
-
payload: { content: { changed: { field_1: { id: 1, name: "foo" } } } }
|
|
179
|
-
}
|
|
213
|
+
payload: { content: { changed: { field_1: { id: 1, name: "foo" } } } },
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
id: 10,
|
|
217
|
+
event: "update_concept",
|
|
218
|
+
resource_id: 11,
|
|
219
|
+
payload: {
|
|
220
|
+
domain_id: 2,
|
|
221
|
+
domain_ids: [2],
|
|
222
|
+
subscribable_fields: {},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
{
|
|
227
|
+
id: 11,
|
|
228
|
+
event: "update_concept",
|
|
229
|
+
resource_id: 12,
|
|
230
|
+
payload: {
|
|
231
|
+
domain_id: 417,
|
|
232
|
+
domain_ids: [417],
|
|
233
|
+
domain_new: {
|
|
234
|
+
id: 417,
|
|
235
|
+
name: "bar",
|
|
236
|
+
},
|
|
237
|
+
domain_old: {
|
|
238
|
+
id: 394,
|
|
239
|
+
name: "foo",
|
|
240
|
+
},
|
|
241
|
+
subscribable_fields: {},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
{
|
|
246
|
+
id: 12,
|
|
247
|
+
event: "update_concept",
|
|
248
|
+
resource_id: 13,
|
|
249
|
+
payload: {
|
|
250
|
+
domain_ids: [417],
|
|
251
|
+
shared_to: [
|
|
252
|
+
{
|
|
253
|
+
id: 250,
|
|
254
|
+
name: "foo",
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: 417,
|
|
258
|
+
name: "bar",
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
subscribable_fields: {},
|
|
262
|
+
},
|
|
263
|
+
},
|
|
180
264
|
];
|
|
181
265
|
|
|
182
266
|
it("should return all the events with the new payload", () => {
|
|
183
267
|
const res = getParsedEvents({ events, concept });
|
|
184
|
-
expect(res).toHaveLength(
|
|
185
|
-
expect(res).toEqual([r1, r2, r3, r4, r5, r6, r7, r8, r9]);
|
|
268
|
+
expect(res).toHaveLength(12);
|
|
269
|
+
expect(res).toEqual([r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12]);
|
|
186
270
|
});
|
|
187
271
|
|
|
188
272
|
it("should return empty array when we have no elements", () => {
|
|
@@ -4,21 +4,21 @@ import { getEvents } from "./getEvents";
|
|
|
4
4
|
|
|
5
5
|
const getTemplate = ({ concept }) => _.prop("template")(concept);
|
|
6
6
|
|
|
7
|
-
const toStr = field =>
|
|
7
|
+
const toStr = (field) =>
|
|
8
8
|
_.isObject(field)
|
|
9
9
|
? JSON.stringify(field)
|
|
10
10
|
: _.isBoolean(field)
|
|
11
11
|
? _.toString(field)
|
|
12
12
|
: field;
|
|
13
13
|
|
|
14
|
-
const getDeleteConceptDraftEvent = e => {
|
|
14
|
+
const getDeleteConceptDraftEvent = (e) => {
|
|
15
15
|
const msg_key = "deleted_version";
|
|
16
16
|
const { version } = e.payload;
|
|
17
17
|
const msg_params = [toStr(version)];
|
|
18
18
|
return { ...e, payload: [{ msg_key, msg_params }] };
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const getNewConceptDraftEvent = e => {
|
|
21
|
+
const getNewConceptDraftEvent = (e) => {
|
|
22
22
|
const msg_key = "created_version";
|
|
23
23
|
const { version } = e.payload;
|
|
24
24
|
const msg_params = [toStr(version)];
|
|
@@ -35,7 +35,7 @@ const getConceptFieldChanges = (
|
|
|
35
35
|
_.toPairs,
|
|
36
36
|
_.map(([k, v]) => ({
|
|
37
37
|
msg_key: fromValueType(msg_key, k, v, fieldsWithoutValue),
|
|
38
|
-
msg_params: [getFieldLabel(k, templateFields), toStr(v)]
|
|
38
|
+
msg_params: [getFieldLabel(k, templateFields), toStr(v)],
|
|
39
39
|
}))
|
|
40
40
|
)(fields);
|
|
41
41
|
|
|
@@ -49,11 +49,54 @@ const fromValueType = (msg_key, field, value, fieldsWithoutValue) =>
|
|
|
49
49
|
|
|
50
50
|
const getFieldLabel = (field, fields) =>
|
|
51
51
|
_.flow(
|
|
52
|
-
_.find(f => _.prop("name")(f) == field),
|
|
52
|
+
_.find((f) => _.prop("name")(f) == field),
|
|
53
53
|
_.defaultTo({}),
|
|
54
54
|
_.prop("label")
|
|
55
55
|
)(fields) || field;
|
|
56
56
|
|
|
57
|
+
const getUpdateConceptEvent = (e) => {
|
|
58
|
+
const { payload } = e;
|
|
59
|
+
|
|
60
|
+
if (!payload) return { ...e, payload: [] };
|
|
61
|
+
|
|
62
|
+
const { domain_id } = payload;
|
|
63
|
+
const { domain_old } = payload;
|
|
64
|
+
const { domain_new } = payload;
|
|
65
|
+
const { shared_to } = payload;
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line fp/no-let
|
|
68
|
+
let field_config = [];
|
|
69
|
+
|
|
70
|
+
if (shared_to) {
|
|
71
|
+
const domainNames = _.flow(_.map("name"), _.join(", "))(shared_to);
|
|
72
|
+
// eslint-disable-next-line fp/no-mutation
|
|
73
|
+
field_config = _.concat({
|
|
74
|
+
msg_key: "shared_to",
|
|
75
|
+
msg_params: [domainNames],
|
|
76
|
+
})(field_config);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (domain_new) {
|
|
80
|
+
const { name: domain_new_name } = domain_new;
|
|
81
|
+
const { name: domain_old_name } = domain_old;
|
|
82
|
+
// eslint-disable-next-line fp/no-mutation
|
|
83
|
+
field_config = _.concat({
|
|
84
|
+
msg_key: "domain_updated_with_names",
|
|
85
|
+
msg_params: [domain_old_name, domain_new_name],
|
|
86
|
+
})(field_config);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (domain_id && !domain_new) {
|
|
90
|
+
// eslint-disable-next-line fp/no-mutation
|
|
91
|
+
field_config = _.concat({
|
|
92
|
+
msg_key: "domain_updated_with_id",
|
|
93
|
+
msg_params: [domain_id],
|
|
94
|
+
})(field_config);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { ...e, payload: field_config };
|
|
98
|
+
};
|
|
99
|
+
|
|
57
100
|
const getUpdateConceptDraftEvent = (e, templateFields, fieldsWithoutValue) => {
|
|
58
101
|
const { payload } = e;
|
|
59
102
|
if (!payload) return { ...e, payload: [] };
|
|
@@ -70,14 +113,14 @@ const getUpdateConceptDraftEvent = (e, templateFields, fieldsWithoutValue) => {
|
|
|
70
113
|
// eslint-disable-next-line fp/no-mutation
|
|
71
114
|
field_config = _.concat({
|
|
72
115
|
msg_key: "changed_field_without_target",
|
|
73
|
-
msg_params: ["description"]
|
|
116
|
+
msg_params: ["description"],
|
|
74
117
|
})(field_config);
|
|
75
118
|
|
|
76
119
|
if (name)
|
|
77
120
|
// eslint-disable-next-line fp/no-mutation
|
|
78
121
|
field_config = _.concat({
|
|
79
122
|
msg_key: "changed_field",
|
|
80
|
-
msg_params: ["name", e.payload["name"]]
|
|
123
|
+
msg_params: ["name", e.payload["name"]],
|
|
81
124
|
})(field_config);
|
|
82
125
|
|
|
83
126
|
const { removed, added, changed } = content;
|
|
@@ -104,7 +147,7 @@ const getUpdateConceptDraftEvent = (e, templateFields, fieldsWithoutValue) => {
|
|
|
104
147
|
removed,
|
|
105
148
|
templateFields,
|
|
106
149
|
fieldsWithoutValue
|
|
107
|
-
)
|
|
150
|
+
),
|
|
108
151
|
]),
|
|
109
152
|
_.flatten
|
|
110
153
|
)([]);
|
|
@@ -113,14 +156,14 @@ const getUpdateConceptDraftEvent = (e, templateFields, fieldsWithoutValue) => {
|
|
|
113
156
|
return { ...e, payload: field_config };
|
|
114
157
|
};
|
|
115
158
|
|
|
116
|
-
const getConceptFieldEvent = e => {
|
|
159
|
+
const getConceptFieldEvent = (e) => {
|
|
117
160
|
const msg_key = "concept_field";
|
|
118
161
|
const { system, group, structure, field } = e.payload.field;
|
|
119
162
|
const msg_params = [system, group, structure, field];
|
|
120
163
|
return { ...e, payload: [{ msg_key, msg_params }] };
|
|
121
164
|
};
|
|
122
165
|
|
|
123
|
-
const getRelationFromConceptToFieldEvent = e => {
|
|
166
|
+
const getRelationFromConceptToFieldEvent = (e) => {
|
|
124
167
|
const msg_key = "concept_field";
|
|
125
168
|
const field_attributes = _.prop("payload.context.target.field")(e);
|
|
126
169
|
const { system, group, structure, field } = field_attributes;
|
|
@@ -128,7 +171,7 @@ const getRelationFromConceptToFieldEvent = e => {
|
|
|
128
171
|
return { ...e, payload: [{ msg_key, msg_params }] };
|
|
129
172
|
};
|
|
130
173
|
|
|
131
|
-
const getEmptyPayloadEvent = e => ({ ...e, payload: [] });
|
|
174
|
+
const getEmptyPayloadEvent = (e) => ({ ...e, payload: [] });
|
|
132
175
|
|
|
133
176
|
const getParsedEvents = createSelector(
|
|
134
177
|
[getEvents, getTemplate],
|
|
@@ -140,18 +183,18 @@ const getParsedEvents = createSelector(
|
|
|
140
183
|
)(template);
|
|
141
184
|
|
|
142
185
|
const fieldsWithoutValue = _.flow(
|
|
143
|
-
_.filter(f =>
|
|
186
|
+
_.filter((f) =>
|
|
144
187
|
_.includes(_.prop("type")(f))([
|
|
145
188
|
"enriched_text",
|
|
146
189
|
"url",
|
|
147
190
|
"table",
|
|
148
191
|
"system",
|
|
149
|
-
"image"
|
|
192
|
+
"image",
|
|
150
193
|
])
|
|
151
194
|
),
|
|
152
195
|
_.map(_.prop("name"))
|
|
153
196
|
)(templateFields);
|
|
154
|
-
return _.map(e => {
|
|
197
|
+
return _.map((e) => {
|
|
155
198
|
const { event } = e;
|
|
156
199
|
if (event === "create_concept_draft") {
|
|
157
200
|
return getNewConceptDraftEvent(e);
|
|
@@ -161,6 +204,8 @@ const getParsedEvents = createSelector(
|
|
|
161
204
|
templateFields,
|
|
162
205
|
fieldsWithoutValue
|
|
163
206
|
);
|
|
207
|
+
} else if (event === "update_concept") {
|
|
208
|
+
return getUpdateConceptEvent(e);
|
|
164
209
|
} else if (event === "delete_concept_draft") {
|
|
165
210
|
return getDeleteConceptDraftEvent(e);
|
|
166
211
|
} else if (event === "new_concept_draft") {
|