cdui-js 1.0.7 → 1.0.9
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/build/css.ts +32 -23
- package/package.json +1 -1
- package/src/components/Dialog.ts +36 -36
- package/src/components/For.ts +26 -26
- package/src/components/If.ts +14 -14
- package/src/components/KeepAlive.ts +26 -26
- package/src/reactive.ts +44 -25
package/build/css.ts
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
|
|
3
3
|
export interface Rule {
|
|
4
4
|
match: string;
|
|
5
|
-
build(outputs: string[], selector: string, value: string): void;
|
|
5
|
+
build(outputs: string[], selector: string, value: string, before: string[]): void;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export const rules: Rule[] = [
|
|
@@ -35,13 +35,13 @@ export const rules: Rule[] = [
|
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
match: '.border-c',
|
|
38
|
-
build: (outputs: string[], selector: string, value: string) => {
|
|
38
|
+
build: (outputs: string[], selector: string, value: string, before: string[]) => {
|
|
39
39
|
if (selector === '.border-c') {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
before.push(`.border { border-color: ${value} }`);
|
|
41
|
+
before.push(`.border-t { border-top-color: ${value} }`);
|
|
42
|
+
before.push(`.border-r { border-right-color: ${value} }`);
|
|
43
|
+
before.push(`.border-b { border-bottom-color: ${value} }`);
|
|
44
|
+
before.push(`.border-l { border-left-color: ${value} }\n`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
outputs.push(`${selector} { border-color: ${value} }`);
|
|
@@ -143,9 +143,9 @@ export const rules: Rule[] = [
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
match: '.icon-c',
|
|
146
|
-
build: (outputs: string[], selector: string, value: string) => {
|
|
146
|
+
build: (outputs: string[], selector: string, value: string, before: string[]) => {
|
|
147
147
|
if (selector === '.icon-c') {
|
|
148
|
-
|
|
148
|
+
before.push(`body { stroke: ${value}; fill: ${value}; }\n.icon { stroke: inherit; fill: inherit; }`);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
outputs.push(`${selector} { stroke: ${value}; fill: ${value}; }`);
|
|
@@ -153,9 +153,9 @@ export const rules: Rule[] = [
|
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
match: '.icon-s',
|
|
156
|
-
build: (outputs: string[], selector: string, value: string) => {
|
|
156
|
+
build: (outputs: string[], selector: string, value: string, before: string[]) => {
|
|
157
157
|
if (selector === '.icon-s') {
|
|
158
|
-
|
|
158
|
+
before.push(`.icon { width: ${value}; height: ${value}; }\n`);
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
outputs.push(`${selector} .icon { width: ${value}; height: ${value}; }`);
|
|
@@ -188,32 +188,39 @@ const findRule = (name: string) => {
|
|
|
188
188
|
}
|
|
189
189
|
};
|
|
190
190
|
|
|
191
|
-
const parse = (
|
|
191
|
+
const parse = (
|
|
192
|
+
rule: Rule,
|
|
193
|
+
outputs: string[],
|
|
194
|
+
selectorPrefix: string,
|
|
195
|
+
name: string,
|
|
196
|
+
value: string,
|
|
197
|
+
before: string[],
|
|
198
|
+
) => {
|
|
192
199
|
if (name.endsWith('-hover')) {
|
|
193
|
-
rule.build(outputs, selectorPrefix + name + ':hover', value);
|
|
194
|
-
rule.build(outputs, selectorPrefix + '.hover:hover ' + name, value);
|
|
200
|
+
rule.build(outputs, selectorPrefix + name + ':hover', value, before);
|
|
201
|
+
rule.build(outputs, selectorPrefix + '.hover:hover ' + name, value, before);
|
|
195
202
|
return;
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
if (name.endsWith('-active')) {
|
|
199
|
-
rule.build(outputs, selectorPrefix + name + ':active', value);
|
|
200
|
-
rule.build(outputs, selectorPrefix + '.active:active ' + name, value);
|
|
206
|
+
rule.build(outputs, selectorPrefix + name + ':active', value, before);
|
|
207
|
+
rule.build(outputs, selectorPrefix + '.active:active ' + name, value, before);
|
|
201
208
|
return;
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
if (name.endsWith('-focus')) {
|
|
205
|
-
rule.build(outputs, selectorPrefix + name + ':focus', value);
|
|
206
|
-
rule.build(outputs, selectorPrefix + '.focus:focus ' + name, value);
|
|
212
|
+
rule.build(outputs, selectorPrefix + name + ':focus', value, before);
|
|
213
|
+
rule.build(outputs, selectorPrefix + '.focus:focus ' + name, value, before);
|
|
207
214
|
return;
|
|
208
215
|
}
|
|
209
216
|
|
|
210
217
|
if (name.endsWith('-selected')) {
|
|
211
|
-
rule.build(outputs, selectorPrefix + name + '.selected', value);
|
|
212
|
-
rule.build(outputs, selectorPrefix + '.selected ' + name, value);
|
|
218
|
+
rule.build(outputs, selectorPrefix + name + '.selected', value, before);
|
|
219
|
+
rule.build(outputs, selectorPrefix + '.selected ' + name, value, before);
|
|
213
220
|
return;
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
rule.build(outputs, selectorPrefix + name, value);
|
|
223
|
+
rule.build(outputs, selectorPrefix + name, value, before);
|
|
217
224
|
};
|
|
218
225
|
|
|
219
226
|
/**
|
|
@@ -227,6 +234,7 @@ export const buildCSS = (cssRuleFile: string, cssFile?: string) => {
|
|
|
227
234
|
let lines = css.split(/\r?\n\s*/);
|
|
228
235
|
let selectorPrefix = '';
|
|
229
236
|
let outputs = [];
|
|
237
|
+
let before = [];
|
|
230
238
|
|
|
231
239
|
for (let i = 0, l = lines.length; i < l; i++) {
|
|
232
240
|
let line = lines[i].trim();
|
|
@@ -241,7 +249,7 @@ export const buildCSS = (cssRuleFile: string, cssFile?: string) => {
|
|
|
241
249
|
value = line.slice(index + 1);
|
|
242
250
|
|
|
243
251
|
if ((value = value.replace(/}\s*\;*\s*/, '').trim())) {
|
|
244
|
-
rule.build(outputs, selectorPrefix + name, value);
|
|
252
|
+
rule.build(outputs, selectorPrefix + name, value, before);
|
|
245
253
|
}
|
|
246
254
|
|
|
247
255
|
continue;
|
|
@@ -255,7 +263,7 @@ export const buildCSS = (cssRuleFile: string, cssFile?: string) => {
|
|
|
255
263
|
.trim();
|
|
256
264
|
|
|
257
265
|
if (value && value !== '#') {
|
|
258
|
-
parse(rule, outputs, selectorPrefix, name, value);
|
|
266
|
+
parse(rule, outputs, selectorPrefix, name, value, before);
|
|
259
267
|
}
|
|
260
268
|
|
|
261
269
|
continue;
|
|
@@ -283,6 +291,7 @@ export const buildCSS = (cssRuleFile: string, cssFile?: string) => {
|
|
|
283
291
|
}
|
|
284
292
|
}
|
|
285
293
|
|
|
294
|
+
outputs.unshift(...before);
|
|
286
295
|
css = outputs.join('\n');
|
|
287
296
|
|
|
288
297
|
if (cssFile) {
|
package/package.json
CHANGED
package/src/components/Dialog.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { createRoot } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
import { JSX } from '../jsx';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 对话框
|
|
7
|
-
*/
|
|
8
|
-
export type Dialog = HTMLElement & {
|
|
9
|
-
/**
|
|
10
|
-
* 关闭对话框方法
|
|
11
|
-
*/
|
|
12
|
-
close(): void;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 显示对话框
|
|
17
|
-
*
|
|
18
|
-
* @param component 对话框组件
|
|
19
|
-
* @returns 关闭对话框方法
|
|
20
|
-
*/
|
|
21
|
-
export const showDialog = (component: () => JSX.Element): Dialog => {
|
|
22
|
-
return createRoot((dispose) => {
|
|
23
|
-
let body = document.body;
|
|
24
|
-
let dialog = component() as Dialog;
|
|
25
|
-
|
|
26
|
-
dialog.style.cssText = 'position:fixed;z-index:9';
|
|
27
|
-
body.appendChild(dialog);
|
|
28
|
-
|
|
29
|
-
dialog.close = () => {
|
|
30
|
-
body.removeChild(dialog);
|
|
31
|
-
dispose();
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return dialog;
|
|
35
|
-
});
|
|
36
|
-
};
|
|
1
|
+
import { createRoot } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
import { JSX } from '../jsx';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 对话框
|
|
7
|
+
*/
|
|
8
|
+
export type Dialog = HTMLElement & {
|
|
9
|
+
/**
|
|
10
|
+
* 关闭对话框方法
|
|
11
|
+
*/
|
|
12
|
+
close(): void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 显示对话框
|
|
17
|
+
*
|
|
18
|
+
* @param component 对话框组件
|
|
19
|
+
* @returns 关闭对话框方法
|
|
20
|
+
*/
|
|
21
|
+
export const showDialog = (component: () => JSX.Element): Dialog => {
|
|
22
|
+
return createRoot((dispose) => {
|
|
23
|
+
let body = document.body;
|
|
24
|
+
let dialog = component() as Dialog;
|
|
25
|
+
|
|
26
|
+
dialog.style.cssText = 'position:fixed;z-index:9';
|
|
27
|
+
body.appendChild(dialog);
|
|
28
|
+
|
|
29
|
+
dialog.close = () => {
|
|
30
|
+
body.removeChild(dialog);
|
|
31
|
+
dispose();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return dialog;
|
|
35
|
+
});
|
|
36
|
+
};
|
package/src/components/For.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { createMemo, mapArray } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
import { JSX } from '../jsx';
|
|
4
|
-
|
|
5
|
-
export const For = <T, U extends JSX.Element>(props: {
|
|
6
|
-
/**
|
|
7
|
-
* 要循环的数据集合
|
|
8
|
-
*/
|
|
9
|
-
each: readonly T[];
|
|
10
|
-
/**
|
|
11
|
-
* 子节点
|
|
12
|
-
*
|
|
13
|
-
* @param item 数据项
|
|
14
|
-
* @param index 索引
|
|
15
|
-
* @returns JSX.Element
|
|
16
|
-
*/
|
|
17
|
-
children: (item: T, index: () => number) => U;
|
|
18
|
-
}) => {
|
|
19
|
-
return createMemo(
|
|
20
|
-
mapArray(() => props.each, props.children),
|
|
21
|
-
void 0,
|
|
22
|
-
{
|
|
23
|
-
name: 'value',
|
|
24
|
-
}
|
|
25
|
-
) as unknown as JSX.Element;
|
|
26
|
-
};
|
|
1
|
+
import { createMemo, mapArray } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
import { JSX } from '../jsx';
|
|
4
|
+
|
|
5
|
+
export const For = <T, U extends JSX.Element>(props: {
|
|
6
|
+
/**
|
|
7
|
+
* 要循环的数据集合
|
|
8
|
+
*/
|
|
9
|
+
each: readonly T[];
|
|
10
|
+
/**
|
|
11
|
+
* 子节点
|
|
12
|
+
*
|
|
13
|
+
* @param item 数据项
|
|
14
|
+
* @param index 索引
|
|
15
|
+
* @returns JSX.Element
|
|
16
|
+
*/
|
|
17
|
+
children: (item: T, index: () => number) => U;
|
|
18
|
+
}) => {
|
|
19
|
+
return createMemo(
|
|
20
|
+
mapArray(() => props.each, props.children),
|
|
21
|
+
void 0,
|
|
22
|
+
{
|
|
23
|
+
name: 'value',
|
|
24
|
+
}
|
|
25
|
+
) as unknown as JSX.Element;
|
|
26
|
+
};
|
package/src/components/If.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { createMemo } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
import { JSX } from '../jsx';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 条件渲染
|
|
7
|
-
*
|
|
8
|
-
* @param props 属性集合
|
|
9
|
-
*/
|
|
10
|
-
export const If = (props: { when: any; children: JSX.Element | JSX.Element[]; else?: JSX.Element | JSX.Element[] }) => {
|
|
11
|
-
return createMemo(() => {
|
|
12
|
-
return props.when ? props.children : props.else;
|
|
13
|
-
}) as unknown as JSX.Element;
|
|
14
|
-
};
|
|
1
|
+
import { createMemo } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
import { JSX } from '../jsx';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 条件渲染
|
|
7
|
+
*
|
|
8
|
+
* @param props 属性集合
|
|
9
|
+
*/
|
|
10
|
+
export const If = (props: { when: any; children: JSX.Element | JSX.Element[]; else?: JSX.Element | JSX.Element[] }) => {
|
|
11
|
+
return createMemo(() => {
|
|
12
|
+
return props.when ? props.children : props.else;
|
|
13
|
+
}) as unknown as JSX.Element;
|
|
14
|
+
};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { JSX, createMemo, createRoot, onCleanup } from 'solid-js';
|
|
2
|
-
|
|
3
|
-
export const KeepAlive = (props: {
|
|
4
|
-
/**
|
|
5
|
-
* 是否显示
|
|
6
|
-
*/
|
|
7
|
-
show: boolean;
|
|
8
|
-
children: JSX.Element | JSX.Element[];
|
|
9
|
-
}) => {
|
|
10
|
-
let root, ondestory;
|
|
11
|
-
|
|
12
|
-
onCleanup(() => {
|
|
13
|
-
ondestory && ondestory();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
return createMemo(() => {
|
|
17
|
-
return (
|
|
18
|
-
props.show &&
|
|
19
|
-
(root ||
|
|
20
|
-
(root = createRoot((dispose) => {
|
|
21
|
-
ondestory = dispose;
|
|
22
|
-
return props.children;
|
|
23
|
-
})))
|
|
24
|
-
);
|
|
25
|
-
}) as unknown as JSX.Element;
|
|
26
|
-
};
|
|
1
|
+
import { JSX, createMemo, createRoot, onCleanup } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
export const KeepAlive = (props: {
|
|
4
|
+
/**
|
|
5
|
+
* 是否显示
|
|
6
|
+
*/
|
|
7
|
+
show: boolean;
|
|
8
|
+
children: JSX.Element | JSX.Element[];
|
|
9
|
+
}) => {
|
|
10
|
+
let root, ondestory;
|
|
11
|
+
|
|
12
|
+
onCleanup(() => {
|
|
13
|
+
ondestory && ondestory();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return createMemo(() => {
|
|
17
|
+
return (
|
|
18
|
+
props.show &&
|
|
19
|
+
(root ||
|
|
20
|
+
(root = createRoot((dispose) => {
|
|
21
|
+
ondestory = dispose;
|
|
22
|
+
return props.children;
|
|
23
|
+
})))
|
|
24
|
+
);
|
|
25
|
+
}) as unknown as JSX.Element;
|
|
26
|
+
};
|
package/src/reactive.ts
CHANGED
|
@@ -64,10 +64,10 @@ export interface SSRRenderPage {
|
|
|
64
64
|
abort?: boolean;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
const signalOptions: any = { equals: false, internal: true };
|
|
67
68
|
const proxyMap = new WeakMap();
|
|
68
69
|
|
|
69
|
-
const
|
|
70
|
-
let names = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse', 'fill', 'copyWithin'];
|
|
70
|
+
const arrayToKeys = (names: string[]) => {
|
|
71
71
|
let result = Object.create(null);
|
|
72
72
|
|
|
73
73
|
for (let i = 0, l = names.length; i < l; i++) {
|
|
@@ -75,7 +75,19 @@ const arrayMutationMethods = (() => {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
return result;
|
|
78
|
-
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const arrayMutationMethods = arrayToKeys([
|
|
81
|
+
'push',
|
|
82
|
+
'pop',
|
|
83
|
+
'shift',
|
|
84
|
+
'unshift',
|
|
85
|
+
'splice',
|
|
86
|
+
'sort',
|
|
87
|
+
'reverse',
|
|
88
|
+
'fill',
|
|
89
|
+
'copyWithin',
|
|
90
|
+
]);
|
|
79
91
|
|
|
80
92
|
function arrayProxyGetHandler(target: any, property: any, receiver) {
|
|
81
93
|
let index = typeof property === 'string' && +property;
|
|
@@ -105,19 +117,11 @@ function arrayProxyGetHandler(target: any, property: any, receiver) {
|
|
|
105
117
|
let set = handler.fn;
|
|
106
118
|
|
|
107
119
|
return function () {
|
|
108
|
-
let
|
|
109
|
-
let result = value.apply(array, arguments);
|
|
110
|
-
|
|
111
|
-
// 返回的不是对象
|
|
112
|
-
if (result !== array) {
|
|
113
|
-
set(new Proxy(array, handler));
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
let proxy = new Proxy(array, handler);
|
|
120
|
+
let result = value.apply(target, arguments);
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
// 触发更新
|
|
123
|
+
set(receiver);
|
|
124
|
+
return result !== target ? result : receiver;
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
|
|
@@ -133,20 +137,20 @@ function arrayProxySetHandler(target: any, property: any, value, receiver) {
|
|
|
133
137
|
|
|
134
138
|
// 如果是通过索引设置值
|
|
135
139
|
if (property >= 0) {
|
|
136
|
-
target = target.slice(0);
|
|
137
140
|
target[index] = value;
|
|
138
141
|
|
|
139
|
-
|
|
142
|
+
// 触发更新
|
|
143
|
+
this.fn(receiver);
|
|
140
144
|
return true;
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
// 如果设置的是length属性
|
|
144
148
|
if (property === 'length') {
|
|
145
149
|
if (target.length !== value) {
|
|
146
|
-
target = target.slice(0);
|
|
147
150
|
target.length = value;
|
|
148
151
|
|
|
149
|
-
|
|
152
|
+
// 触发更新
|
|
153
|
+
this.fn(receiver);
|
|
150
154
|
return true;
|
|
151
155
|
}
|
|
152
156
|
|
|
@@ -159,7 +163,7 @@ function arrayProxySetHandler(target: any, property: any, value, receiver) {
|
|
|
159
163
|
const createArraySignal = (value: any[]) => {
|
|
160
164
|
let handler = { get: arrayProxyGetHandler, set: arrayProxySetHandler, fn: null };
|
|
161
165
|
let proxy = new Proxy(value, handler);
|
|
162
|
-
let signal = createSignal(proxy);
|
|
166
|
+
let signal = createSignal(proxy, signalOptions);
|
|
163
167
|
|
|
164
168
|
handler.fn = signal[1];
|
|
165
169
|
|
|
@@ -177,7 +181,18 @@ const reactiveObject = (object) => {
|
|
|
177
181
|
const proxy = new Proxy(object, {
|
|
178
182
|
get(target, property, receiver) {
|
|
179
183
|
if (property !== '__raw__') {
|
|
180
|
-
|
|
184
|
+
let value = (signals[property] || initSignal(signals, property, target[property]))[0]();
|
|
185
|
+
|
|
186
|
+
if (typeof value !== 'object' || !value) {
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// 已经是代理对象
|
|
191
|
+
if (value.__raw__) {
|
|
192
|
+
return value;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return proxyMap.get(value) || (isArray(value) ? createArraySignal(value)[0]() : reactiveObject(value));
|
|
181
196
|
}
|
|
182
197
|
|
|
183
198
|
return target;
|
|
@@ -188,7 +203,7 @@ const reactiveObject = (object) => {
|
|
|
188
203
|
value = value.__raw__ || value;
|
|
189
204
|
}
|
|
190
205
|
|
|
191
|
-
(signals[property] || initSignal(signals, property, target[property]))[1](value);
|
|
206
|
+
(signals[property] || initSignal(signals, property, target[property]))[1]((target[property] = value));
|
|
192
207
|
return true;
|
|
193
208
|
},
|
|
194
209
|
|
|
@@ -202,22 +217,26 @@ const reactiveObject = (object) => {
|
|
|
202
217
|
return proxy;
|
|
203
218
|
};
|
|
204
219
|
|
|
220
|
+
const throwReactiveError = () => {
|
|
221
|
+
throw new Error(`Array cannot directly create reactive object,Please use like: reactive({ items: [] })`);
|
|
222
|
+
};
|
|
223
|
+
|
|
205
224
|
/**
|
|
206
225
|
* 创建响应式对象
|
|
207
226
|
*
|
|
208
227
|
* @param object 要封装为响应的对象
|
|
209
228
|
*/
|
|
210
|
-
export const reactive = <T extends { [key: string
|
|
229
|
+
export const reactive = <T extends { [key: string]: any }>(object: T extends any[] ? never : T): T => {
|
|
211
230
|
if (object && typeof object === 'object') {
|
|
212
231
|
// 已经是代理对象
|
|
213
232
|
if (object.__raw__) {
|
|
214
233
|
return object;
|
|
215
234
|
}
|
|
216
235
|
|
|
217
|
-
return proxyMap.get(object) || (isArray(object)
|
|
236
|
+
return proxyMap.get(object) || (!isArray(object) && reactiveObject(object)) || throwReactiveError();
|
|
218
237
|
}
|
|
219
238
|
|
|
220
|
-
|
|
239
|
+
throw new Error(`${object} can not create reactive object`);
|
|
221
240
|
};
|
|
222
241
|
|
|
223
242
|
/**
|