fastbrowser_cli 1.0.16 → 1.0.18
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.
|
@@ -3,9 +3,9 @@ import Fs from 'node:fs';
|
|
|
3
3
|
import Os from 'node:os';
|
|
4
4
|
import Path from 'node:path';
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const STATE_DIRNAME = Path.join(Os.homedir(), '.fastbrowser_cli');
|
|
7
|
+
const PID_FILENAME = Path.join(STATE_DIRNAME, 'server.json');
|
|
8
|
+
const LOG_FILENAME = Path.join(STATE_DIRNAME, 'server.log');
|
|
9
9
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
10
|
///////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
//
|
|
@@ -58,8 +58,8 @@ export class ServerManager {
|
|
|
58
58
|
spawnArgs = ['tsx', ...spawnArgs];
|
|
59
59
|
}
|
|
60
60
|
const packageRoot = Path.resolve(import.meta.dirname, '..', '..', '..');
|
|
61
|
-
Fs.mkdirSync(
|
|
62
|
-
const logFd = Fs.openSync(
|
|
61
|
+
Fs.mkdirSync(STATE_DIRNAME, { recursive: true });
|
|
62
|
+
const logFd = Fs.openSync(LOG_FILENAME, 'a');
|
|
63
63
|
const child = spawn(spawnCommand, spawnArgs, {
|
|
64
64
|
detached: true,
|
|
65
65
|
stdio: ['ignore', logFd, logFd],
|
|
@@ -77,7 +77,7 @@ export class ServerManager {
|
|
|
77
77
|
port,
|
|
78
78
|
startedAt: new Date().toISOString(),
|
|
79
79
|
};
|
|
80
|
-
Fs.writeFileSync(
|
|
80
|
+
Fs.writeFileSync(PID_FILENAME, JSON.stringify(pidFile, null, 2));
|
|
81
81
|
const deadline = Date.now() + 10000;
|
|
82
82
|
while (Date.now() < deadline) {
|
|
83
83
|
const state = await ServerManager.status(serverUrl);
|
|
@@ -93,17 +93,17 @@ export class ServerManager {
|
|
|
93
93
|
throw new Error(`fastbrowser server did not become healthy within 10s. Log tail:\n${tail}`);
|
|
94
94
|
}
|
|
95
95
|
static async stop(serverUrl) {
|
|
96
|
-
if (Fs.existsSync(
|
|
96
|
+
if (Fs.existsSync(PID_FILENAME) === false) {
|
|
97
97
|
console.error('no server pid file; nothing to stop');
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
100
|
let pidFile;
|
|
101
101
|
try {
|
|
102
|
-
const raw = Fs.readFileSync(
|
|
102
|
+
const raw = Fs.readFileSync(PID_FILENAME, 'utf8');
|
|
103
103
|
pidFile = JSON.parse(raw);
|
|
104
104
|
}
|
|
105
105
|
catch (err) {
|
|
106
|
-
throw new Error(`Failed to read pid file ${
|
|
106
|
+
throw new Error(`Failed to read pid file ${PID_FILENAME}: ${err.message}`);
|
|
107
107
|
}
|
|
108
108
|
const pid = pidFile.pid;
|
|
109
109
|
try {
|
|
@@ -130,7 +130,7 @@ export class ServerManager {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
try {
|
|
133
|
-
Fs.unlinkSync(
|
|
133
|
+
Fs.unlinkSync(PID_FILENAME);
|
|
134
134
|
}
|
|
135
135
|
catch {
|
|
136
136
|
// best effort
|
|
@@ -181,7 +181,7 @@ export class ServerManager {
|
|
|
181
181
|
}
|
|
182
182
|
static readLogTail(maxLines) {
|
|
183
183
|
try {
|
|
184
|
-
const content = Fs.readFileSync(
|
|
184
|
+
const content = Fs.readFileSync(LOG_FILENAME, 'utf8');
|
|
185
185
|
const lines = content.split('\n');
|
|
186
186
|
return lines.slice(Math.max(0, lines.length - maxLines)).join('\n');
|
|
187
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../../../src/fastbrowser_cli/libs/server-manager.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAc3C,MAAM,
|
|
1
|
+
{"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../../../src/fastbrowser_cli/libs/server-manager.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAc3C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAClE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAE5D,+EAA+E;AAC/E,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAE/E,MAAM,OAAO,aAAa;IACzB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAiB;QACpC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,SAAS,EAAE;gBAC9C,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;aAChC,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC5C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAsB,CAAC;YAC1D,OAAO,OAAO,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,SAAiB;QAC3C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAEhC,IAAI,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,8DAA8D,CAAC,CAAC;QACnH,CAAC;QACD,MAAM,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAiB;QACnC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAC;YACpE,OAAO;QACR,CAAC;QAED,IAAI,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,qBAAqB,CAAC,CAAC;QACvE,CAAC;QAED,WAAW;QACX,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,EAAE,sBAAsB,CAAC,CAAC;QAC3G,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;QACpC,IAAI,SAAS,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QACnD,0CAA0C;QAC1C,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAE,CAAC;YAC5C,YAAY,GAAG,oBAAoB,CAAC;YACpC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpD,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAExE,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAE7C,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,SAAS,EAAE;YAC5C,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC;YAC/B,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAEd,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvB,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAAY;YACxB,GAAG;YACH,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QACF,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAM,CAAC;QACrC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,mCAAmC,GAAG,UAAU,IAAI,GAAG,CAAC,CAAC;gBACvE,OAAO;YACR,CAAC;YACD,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,oEAAoE,IAAI,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAiB;QAClC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,KAAK,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACrD,OAAO;QACR,CAAC;QAED,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAClD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACxB,IAAI,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACtB,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAK,CAAC;QACpC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC9B,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK;gBAAE,MAAM;YAChD,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACzC,IAAI,CAAC;gBACJ,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACR,cAAc;YACf,CAAC;QACF,CAAC;QAED,IAAI,CAAC;YACJ,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACR,cAAc;QACf,CAAC;QAED,sFAAsF;QACtF,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,eAAe,SAAS,4BAA4B,CAAC,CAAC;YAC3F,OAAO;QACR,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC7C,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,SAAiB;QAC1C,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC7B,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,CAAC;QAC7F,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAEO,MAAM,CAAC,SAAS,CAAC,SAAiB;QACzC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;YAClC,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC9C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK;oBAAE,OAAO,IAAI,CAAC;YAC/C,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,eAAe;QAChB,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,MAAM,CAAC,OAAO,CAAC,GAAW;QACjC,IAAI,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;YAClC,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,QAAgB;QAC1C,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,mBAAmB,CAAC;QAC5B,CAAC;IACF,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,EAAU;QAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;CACD"}
|
package/package.json
CHANGED
|
@@ -16,9 +16,9 @@ type PidFile = {
|
|
|
16
16
|
startedAt: string;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
19
|
+
const STATE_DIRNAME = Path.join(Os.homedir(), '.fastbrowser_cli');
|
|
20
|
+
const PID_FILENAME = Path.join(STATE_DIRNAME, 'server.json');
|
|
21
|
+
const LOG_FILENAME = Path.join(STATE_DIRNAME, 'server.log');
|
|
22
22
|
|
|
23
23
|
///////////////////////////////////////////////////////////////////////////////
|
|
24
24
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -76,8 +76,8 @@ export class ServerManager {
|
|
|
76
76
|
}
|
|
77
77
|
const packageRoot = Path.resolve(import.meta.dirname, '..', '..', '..');
|
|
78
78
|
|
|
79
|
-
Fs.mkdirSync(
|
|
80
|
-
const logFd = Fs.openSync(
|
|
79
|
+
Fs.mkdirSync(STATE_DIRNAME, { recursive: true });
|
|
80
|
+
const logFd = Fs.openSync(LOG_FILENAME, 'a');
|
|
81
81
|
|
|
82
82
|
const child = spawn(spawnCommand, spawnArgs, {
|
|
83
83
|
detached: true,
|
|
@@ -98,7 +98,7 @@ export class ServerManager {
|
|
|
98
98
|
port,
|
|
99
99
|
startedAt: new Date().toISOString(),
|
|
100
100
|
};
|
|
101
|
-
Fs.writeFileSync(
|
|
101
|
+
Fs.writeFileSync(PID_FILENAME, JSON.stringify(pidFile, null, 2));
|
|
102
102
|
|
|
103
103
|
const deadline = Date.now() + 10_000;
|
|
104
104
|
while (Date.now() < deadline) {
|
|
@@ -117,17 +117,17 @@ export class ServerManager {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
static async stop(serverUrl: string): Promise<void> {
|
|
120
|
-
if (Fs.existsSync(
|
|
120
|
+
if (Fs.existsSync(PID_FILENAME) === false) {
|
|
121
121
|
console.error('no server pid file; nothing to stop');
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
let pidFile: PidFile;
|
|
126
126
|
try {
|
|
127
|
-
const raw = Fs.readFileSync(
|
|
127
|
+
const raw = Fs.readFileSync(PID_FILENAME, 'utf8');
|
|
128
128
|
pidFile = JSON.parse(raw) as PidFile;
|
|
129
129
|
} catch (err) {
|
|
130
|
-
throw new Error(`Failed to read pid file ${
|
|
130
|
+
throw new Error(`Failed to read pid file ${PID_FILENAME}: ${(err as Error).message}`);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
const pid = pidFile.pid;
|
|
@@ -155,7 +155,7 @@ export class ServerManager {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
try {
|
|
158
|
-
Fs.unlinkSync(
|
|
158
|
+
Fs.unlinkSync(PID_FILENAME);
|
|
159
159
|
} catch {
|
|
160
160
|
// best effort
|
|
161
161
|
}
|
|
@@ -205,7 +205,7 @@ export class ServerManager {
|
|
|
205
205
|
|
|
206
206
|
private static readLogTail(maxLines: number): string {
|
|
207
207
|
try {
|
|
208
|
-
const content = Fs.readFileSync(
|
|
208
|
+
const content = Fs.readFileSync(LOG_FILENAME, 'utf8');
|
|
209
209
|
const lines = content.split('\n');
|
|
210
210
|
return lines.slice(Math.max(0, lines.length - maxLines)).join('\n');
|
|
211
211
|
} catch {
|