oak-domain 5.1.2 → 5.1.4
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/lib/store/IntrinsicCheckers.js +8 -8
- package/lib/types/Sync.d.ts +4 -0
- package/lib/utils/assert.d.ts +1 -0
- package/lib/utils/relationPath.js +1 -1
- package/package.json +1 -1
- package/src/entities/ModiEntity.ts +26 -26
- package/src/entities/OperEntity.ts +27 -27
- package/src/entities/Relation.ts +43 -43
- package/src/entities/UserEntityClaim.ts +29 -29
- package/src/entities/UserEntityGrant.ts +24 -24
- package/src/entities/UserRelation.ts +50 -50
|
@@ -79,7 +79,7 @@ function createUniqueCheckers(schema) {
|
|
|
79
79
|
entity,
|
|
80
80
|
action: 'create',
|
|
81
81
|
type: 'logicalData',
|
|
82
|
-
priority: types_1.CHECKER_MAX_PRIORITY,
|
|
82
|
+
priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
|
|
83
83
|
checker: (operation, context) => {
|
|
84
84
|
const { data } = operation;
|
|
85
85
|
if (data instanceof Array) {
|
|
@@ -95,9 +95,9 @@ function createUniqueCheckers(schema) {
|
|
|
95
95
|
}
|
|
96
96
|
}, {
|
|
97
97
|
entity,
|
|
98
|
-
action: 'update',
|
|
98
|
+
action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性
|
|
99
99
|
type: 'logicalData',
|
|
100
|
-
priority: types_1.CHECKER_MAX_PRIORITY,
|
|
100
|
+
priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
|
|
101
101
|
checker: (operation, context) => {
|
|
102
102
|
const { data, filter: operationFilter } = operation;
|
|
103
103
|
if (data) {
|
|
@@ -227,7 +227,7 @@ function createActionTransformerCheckers(actionDefDict) {
|
|
|
227
227
|
action: 'create',
|
|
228
228
|
type: 'logical',
|
|
229
229
|
entity,
|
|
230
|
-
priority: 10,
|
|
230
|
+
priority: 10, // 优先级要高,先于真正的data检查进行
|
|
231
231
|
checker: (operation) => {
|
|
232
232
|
const { data } = operation;
|
|
233
233
|
if (data instanceof Array) {
|
|
@@ -311,7 +311,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|
|
311
311
|
const checkers = [];
|
|
312
312
|
for (const entity in attrUpdateMatrix) {
|
|
313
313
|
const matrix = attrUpdateMatrix[entity];
|
|
314
|
-
const updateAttrs = Object.keys(matrix);
|
|
314
|
+
const updateAttrs = [types_1.UpdateAtAttribute, types_1.TriggerDataAttribute, types_1.TriggerUuidAttribute].concat(Object.keys(matrix));
|
|
315
315
|
const { actions } = schema[entity];
|
|
316
316
|
const updateActions = actions.filter((a) => !action_1.readOnlyActions.concat(['create', 'remove']).includes(a));
|
|
317
317
|
/**
|
|
@@ -328,7 +328,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|
|
328
328
|
throw new types_1.OakAttrCantUpdateException(entity, extras, '更新了不允许的属性');
|
|
329
329
|
}
|
|
330
330
|
const condition = attrs.map(ele => matrix[ele]);
|
|
331
|
-
const actions = condition.map(ele => ele
|
|
331
|
+
const actions = condition.map(ele => ele?.actions).filter(ele => !!ele);
|
|
332
332
|
const a = actions.length > 0 && (0, lodash_1.intersection)(actions.flat());
|
|
333
333
|
if (a) {
|
|
334
334
|
if (!a.includes(action)) {
|
|
@@ -338,10 +338,10 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
const filters = condition.map(ele => {
|
|
341
|
-
if (typeof ele
|
|
341
|
+
if (typeof ele?.filter === 'function') {
|
|
342
342
|
return ele.filter(action || 'select');
|
|
343
343
|
}
|
|
344
|
-
return ele
|
|
344
|
+
return ele?.filter;
|
|
345
345
|
}).filter(ele => !!ele);
|
|
346
346
|
const f = filters.length > 0 && (0, filter_1.combineFilters)(entity, schema, filters);
|
|
347
347
|
if (f) {
|
package/lib/types/Sync.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export interface PushEntityDef<ED extends EntityDict & BaseEntityDict, T extends
|
|
|
38
38
|
* 同步结果回调,根据接口的幂等原理,同步一定要完全成功再回调
|
|
39
39
|
*/
|
|
40
40
|
onSynchronized?: (result: {
|
|
41
|
+
remoteEntity: keyof ED;
|
|
42
|
+
remoteEntityId: string;
|
|
41
43
|
action: ED[T]['Action'];
|
|
42
44
|
data: ED[T]['Operation']['data'];
|
|
43
45
|
rowIds: string[];
|
|
@@ -64,6 +66,8 @@ export interface SyncRemoteConfig<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|
|
64
66
|
* 同步失败回调
|
|
65
67
|
*/
|
|
66
68
|
onFailed?: (result: {
|
|
69
|
+
remoteEntity: keyof ED;
|
|
70
|
+
remoteEntityId: string;
|
|
67
71
|
data: {
|
|
68
72
|
entity: keyof ED;
|
|
69
73
|
action: ED[keyof ED]['Action'];
|
package/lib/utils/assert.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ function destructRelationPath(schema, entity, path, relationFilter, recursive) {
|
|
|
60
60
|
},
|
|
61
61
|
filter: relationFilter,
|
|
62
62
|
} // as ED['userRelation']['Selection']
|
|
63
|
-
},
|
|
63
|
+
}, // as ED[keyof ED]['Selection']['data'],
|
|
64
64
|
getData: (d) => {
|
|
65
65
|
return d.userRelation$entity;
|
|
66
66
|
},
|
package/package.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { EntityShape } from '../types/Entity';
|
|
3
|
-
import { Schema as Modi } from './Modi';
|
|
4
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
5
|
-
|
|
6
|
-
export interface Schema extends EntityShape {
|
|
7
|
-
modi: Modi,
|
|
8
|
-
entity: String<32>;
|
|
9
|
-
entityId: String<64>;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const entityDesc: EntityDesc<Schema> = {
|
|
13
|
-
locales: {
|
|
14
|
-
zh_CN: {
|
|
15
|
-
name: '更新对象连接',
|
|
16
|
-
attr: {
|
|
17
|
-
modi: '更新',
|
|
18
|
-
entity: '关联对象',
|
|
19
|
-
entityId: '关联对象id',
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
configuration: {
|
|
24
|
-
actionType: 'appendOnly',
|
|
25
|
-
}
|
|
26
|
-
};
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { EntityShape } from '../types/Entity';
|
|
3
|
+
import { Schema as Modi } from './Modi';
|
|
4
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
5
|
+
|
|
6
|
+
export interface Schema extends EntityShape {
|
|
7
|
+
modi: Modi,
|
|
8
|
+
entity: String<32>;
|
|
9
|
+
entityId: String<64>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const entityDesc: EntityDesc<Schema> = {
|
|
13
|
+
locales: {
|
|
14
|
+
zh_CN: {
|
|
15
|
+
name: '更新对象连接',
|
|
16
|
+
attr: {
|
|
17
|
+
modi: '更新',
|
|
18
|
+
entity: '关联对象',
|
|
19
|
+
entityId: '关联对象id',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
configuration: {
|
|
24
|
+
actionType: 'appendOnly',
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { EntityShape, Configuration } from '../types/Entity';
|
|
3
|
-
import { LocaleDef } from '../types/Locale';
|
|
4
|
-
import { Schema as Oper } from './Oper';
|
|
5
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
6
|
-
|
|
7
|
-
export interface Schema extends EntityShape {
|
|
8
|
-
oper: Oper,
|
|
9
|
-
entity: String<32>;
|
|
10
|
-
entityId: String<64>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const entityDesc: EntityDesc<Schema> = {
|
|
14
|
-
locales: {
|
|
15
|
-
zh_CN: {
|
|
16
|
-
name: '操作对象连接',
|
|
17
|
-
attr: {
|
|
18
|
-
oper: '操作',
|
|
19
|
-
entity: '关联对象',
|
|
20
|
-
entityId: '关联对象id',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
configuration: {
|
|
25
|
-
actionType: 'appendOnly',
|
|
26
|
-
}
|
|
27
|
-
};
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { EntityShape, Configuration } from '../types/Entity';
|
|
3
|
+
import { LocaleDef } from '../types/Locale';
|
|
4
|
+
import { Schema as Oper } from './Oper';
|
|
5
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
6
|
+
|
|
7
|
+
export interface Schema extends EntityShape {
|
|
8
|
+
oper: Oper,
|
|
9
|
+
entity: String<32>;
|
|
10
|
+
entityId: String<64>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const entityDesc: EntityDesc<Schema> = {
|
|
14
|
+
locales: {
|
|
15
|
+
zh_CN: {
|
|
16
|
+
name: '操作对象连接',
|
|
17
|
+
attr: {
|
|
18
|
+
oper: '操作',
|
|
19
|
+
entity: '关联对象',
|
|
20
|
+
entityId: '关联对象id',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
configuration: {
|
|
25
|
+
actionType: 'appendOnly',
|
|
26
|
+
}
|
|
27
|
+
};
|
package/src/entities/Relation.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { EntityShape } from '../types/Entity';
|
|
3
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
-
|
|
5
|
-
export interface Schema extends EntityShape {
|
|
6
|
-
entity: String<32>;
|
|
7
|
-
entityId?: String<64>; // 可以为空
|
|
8
|
-
name?: String<32>;
|
|
9
|
-
display?: String<32>;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const entityDesc: EntityDesc<Schema> = {
|
|
13
|
-
locales: {
|
|
14
|
-
zh_CN: {
|
|
15
|
-
name: '用户授权',
|
|
16
|
-
attr: {
|
|
17
|
-
name: '关系',
|
|
18
|
-
entity: '目标对象',
|
|
19
|
-
entityId: '目标对象id',
|
|
20
|
-
display: '显示值',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
indexes: [
|
|
25
|
-
{
|
|
26
|
-
name: 'index_targetEntity_entityId_name',
|
|
27
|
-
attributes: [
|
|
28
|
-
{
|
|
29
|
-
name: 'entity',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'entityId',
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: 'name',
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
config: {
|
|
39
|
-
unique: true,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
]
|
|
43
|
-
};
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { EntityShape } from '../types/Entity';
|
|
3
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
+
|
|
5
|
+
export interface Schema extends EntityShape {
|
|
6
|
+
entity: String<32>;
|
|
7
|
+
entityId?: String<64>; // 可以为空
|
|
8
|
+
name?: String<32>;
|
|
9
|
+
display?: String<32>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const entityDesc: EntityDesc<Schema> = {
|
|
13
|
+
locales: {
|
|
14
|
+
zh_CN: {
|
|
15
|
+
name: '用户授权',
|
|
16
|
+
attr: {
|
|
17
|
+
name: '关系',
|
|
18
|
+
entity: '目标对象',
|
|
19
|
+
entityId: '目标对象id',
|
|
20
|
+
display: '显示值',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
indexes: [
|
|
25
|
+
{
|
|
26
|
+
name: 'index_targetEntity_entityId_name',
|
|
27
|
+
attributes: [
|
|
28
|
+
{
|
|
29
|
+
name: 'entity',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'entityId',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'name',
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
config: {
|
|
39
|
+
unique: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
};
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { EntityShape } from '../types/Entity';
|
|
3
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
-
import { Schema as UserEntityGrant } from './UserEntityGrant';
|
|
5
|
-
import { Schema as User } from './User';
|
|
6
|
-
import { Schema as Relation } from './Relation';
|
|
7
|
-
import { Schema as UserRelation } from './UserRelation';
|
|
8
|
-
|
|
9
|
-
export interface Schema extends EntityShape {
|
|
10
|
-
ueg: UserEntityGrant;
|
|
11
|
-
user: User;
|
|
12
|
-
relation: Relation;
|
|
13
|
-
claimEntityId: String<64>;
|
|
14
|
-
userRelation: UserRelation;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const entityDesc: EntityDesc<Schema, ''> = {
|
|
18
|
-
locales: {
|
|
19
|
-
zh_CN: {
|
|
20
|
-
name: '用户授权领取',
|
|
21
|
-
attr: {
|
|
22
|
-
ueg: '授权',
|
|
23
|
-
user: '用户',
|
|
24
|
-
relation: '关系',
|
|
25
|
-
claimEntityId: '对象Id',
|
|
26
|
-
userRelation: '用户关系',
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { EntityShape } from '../types/Entity';
|
|
3
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
+
import { Schema as UserEntityGrant } from './UserEntityGrant';
|
|
5
|
+
import { Schema as User } from './User';
|
|
6
|
+
import { Schema as Relation } from './Relation';
|
|
7
|
+
import { Schema as UserRelation } from './UserRelation';
|
|
8
|
+
|
|
9
|
+
export interface Schema extends EntityShape {
|
|
10
|
+
ueg: UserEntityGrant;
|
|
11
|
+
user: User;
|
|
12
|
+
relation: Relation;
|
|
13
|
+
claimEntityId: String<64>;
|
|
14
|
+
userRelation: UserRelation;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const entityDesc: EntityDesc<Schema, ''> = {
|
|
18
|
+
locales: {
|
|
19
|
+
zh_CN: {
|
|
20
|
+
name: '用户授权领取',
|
|
21
|
+
attr: {
|
|
22
|
+
ueg: '授权',
|
|
23
|
+
user: '用户',
|
|
24
|
+
relation: '关系',
|
|
25
|
+
claimEntityId: '对象Id',
|
|
26
|
+
userRelation: '用户关系',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
30
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { EntityShape } from '../types/Entity';
|
|
3
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
-
|
|
5
|
-
type RelationIds = string[];
|
|
6
|
-
|
|
7
|
-
export interface Schema extends EntityShape {
|
|
8
|
-
relationEntity: String<32>;
|
|
9
|
-
relationEntityFilter: Object;
|
|
10
|
-
relationIds: RelationIds;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const entityDesc: EntityDesc<Schema, ''> = {
|
|
14
|
-
locales: {
|
|
15
|
-
zh_CN: {
|
|
16
|
-
name: '用户授权',
|
|
17
|
-
attr: {
|
|
18
|
-
relationIds: '关系',
|
|
19
|
-
relationEntity: '关联对象',
|
|
20
|
-
relationEntityFilter: '对象限定条件',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { EntityShape } from '../types/Entity';
|
|
3
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
4
|
+
|
|
5
|
+
type RelationIds = string[];
|
|
6
|
+
|
|
7
|
+
export interface Schema extends EntityShape {
|
|
8
|
+
relationEntity: String<32>;
|
|
9
|
+
relationEntityFilter: Object;
|
|
10
|
+
relationIds: RelationIds;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const entityDesc: EntityDesc<Schema, ''> = {
|
|
14
|
+
locales: {
|
|
15
|
+
zh_CN: {
|
|
16
|
+
name: '用户授权',
|
|
17
|
+
attr: {
|
|
18
|
+
relationIds: '关系',
|
|
19
|
+
relationEntity: '关联对象',
|
|
20
|
+
relationEntityFilter: '对象限定条件',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { String } from '../types/DataType';
|
|
2
|
-
import { LocaleDef } from '../types/Locale';
|
|
3
|
-
import { EntityShape } from '../types/Entity';
|
|
4
|
-
import { Index } from '../types/Storage';
|
|
5
|
-
import { Schema as User } from './User';
|
|
6
|
-
import { Schema as Relation } from './Relation';
|
|
7
|
-
import { EntityDesc } from '../types/EntityDesc';
|
|
8
|
-
|
|
9
|
-
export interface Schema extends EntityShape {
|
|
10
|
-
user: User;
|
|
11
|
-
relation: Relation;
|
|
12
|
-
entity: String<32>;
|
|
13
|
-
entityId: String<64>;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const entityDesc: EntityDesc<Schema> = {
|
|
17
|
-
locales: {
|
|
18
|
-
zh_CN: {
|
|
19
|
-
name: '用户对象关系',
|
|
20
|
-
attr: {
|
|
21
|
-
user: '关系',
|
|
22
|
-
relation: '目标关系',
|
|
23
|
-
entity: '目标对象',
|
|
24
|
-
entityId: '目标对象ID',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
indexes: [
|
|
29
|
-
{
|
|
30
|
-
name: 'index_user_entity_entityId_relation',
|
|
31
|
-
attributes: [
|
|
32
|
-
{
|
|
33
|
-
name: 'user',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
name: 'entity',
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: 'entityId',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: 'relation',
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
config: {
|
|
46
|
-
unique: true,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
]
|
|
50
|
-
};
|
|
1
|
+
import { String } from '../types/DataType';
|
|
2
|
+
import { LocaleDef } from '../types/Locale';
|
|
3
|
+
import { EntityShape } from '../types/Entity';
|
|
4
|
+
import { Index } from '../types/Storage';
|
|
5
|
+
import { Schema as User } from './User';
|
|
6
|
+
import { Schema as Relation } from './Relation';
|
|
7
|
+
import { EntityDesc } from '../types/EntityDesc';
|
|
8
|
+
|
|
9
|
+
export interface Schema extends EntityShape {
|
|
10
|
+
user: User;
|
|
11
|
+
relation: Relation;
|
|
12
|
+
entity: String<32>;
|
|
13
|
+
entityId: String<64>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const entityDesc: EntityDesc<Schema> = {
|
|
17
|
+
locales: {
|
|
18
|
+
zh_CN: {
|
|
19
|
+
name: '用户对象关系',
|
|
20
|
+
attr: {
|
|
21
|
+
user: '关系',
|
|
22
|
+
relation: '目标关系',
|
|
23
|
+
entity: '目标对象',
|
|
24
|
+
entityId: '目标对象ID',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
indexes: [
|
|
29
|
+
{
|
|
30
|
+
name: 'index_user_entity_entityId_relation',
|
|
31
|
+
attributes: [
|
|
32
|
+
{
|
|
33
|
+
name: 'user',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'entity',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'entityId',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'relation',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
config: {
|
|
46
|
+
unique: true,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
]
|
|
50
|
+
};
|