projxo 1.1.0 → 1.2.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/Readme.md +134 -0
- package/index.js +20 -1
- package/package.json +1 -1
- package/src/commands/list.js +4 -3
- package/src/commands/open.js +119 -0
- package/src/commands/recent.js +156 -0
package/Readme.md
CHANGED
|
@@ -21,6 +21,12 @@ pxo
|
|
|
21
21
|
|
|
22
22
|
# List all your projects
|
|
23
23
|
pxo list
|
|
24
|
+
|
|
25
|
+
# Open a project quickly
|
|
26
|
+
pxo open my-app
|
|
27
|
+
|
|
28
|
+
# List all your recently accessed projects
|
|
29
|
+
pxo recent
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
**That's it!** Pick your framework, name your project, and start coding.
|
|
@@ -46,6 +52,8 @@ You get:
|
|
|
46
52
|
```bash
|
|
47
53
|
pxo # Create & track projects
|
|
48
54
|
pxo list # See all your projects
|
|
55
|
+
pxo open my-app # Open instantly
|
|
56
|
+
pxo recent # See all recent projects
|
|
49
57
|
```
|
|
50
58
|
|
|
51
59
|
**One command. Zero hassle.**
|
|
@@ -71,6 +79,8 @@ npm install -g projxo
|
|
|
71
79
|
|---------|-------|-------------|
|
|
72
80
|
| `pxo` | - | Create a new project with interactive setup |
|
|
73
81
|
| `pxo list` | `pxo ls` | Browse and manage all tracked projects |
|
|
82
|
+
| `pxo recent [limit]` | - | Browse recently accessed projects |
|
|
83
|
+
| `pxo open <project-name>` | - | Quick open project by name |
|
|
74
84
|
| `pxo --version` | `pxo -V` | Show version number |
|
|
75
85
|
| `pxo --help` | `pxo -h` | Display help information |
|
|
76
86
|
|
|
@@ -155,6 +165,75 @@ Select a project and perform actions
|
|
|
155
165
|
Use ↑↓ to navigate • Enter to select
|
|
156
166
|
```
|
|
157
167
|
|
|
168
|
+
### Recent Projects
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pxo recent
|
|
172
|
+
# or with custom limit
|
|
173
|
+
pxo recent 5
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
***Shows your recently accessed projects (default: last 10)***
|
|
177
|
+
|
|
178
|
+
**Features:**
|
|
179
|
+
|
|
180
|
+
- Sorted by last accessed time (most recent first)
|
|
181
|
+
- Quick selection with arrow keys
|
|
182
|
+
- Select to open in your preferred IDE
|
|
183
|
+
|
|
184
|
+
**Example output:**
|
|
185
|
+
|
|
186
|
+
``` bash
|
|
187
|
+
🕐 Recent Projects (5)
|
|
188
|
+
|
|
189
|
+
Select a project to open:
|
|
190
|
+
❯ 1. my-awesome-app React+Vite 2 hours ago
|
|
191
|
+
2. client-dashboard Next.js 1 day ago
|
|
192
|
+
3. mobile-game React Native 3 days ago
|
|
193
|
+
4. api-server Next.js 5 days ago
|
|
194
|
+
5. test-project React+Vite 1 week ago
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Use case:** Perfect for quickly switching between active projects without browsing the full list.
|
|
198
|
+
|
|
199
|
+
### Quick Open Project
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pxo open <project-name>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Instantly open a project by name** - the fastest way to access your work.
|
|
206
|
+
|
|
207
|
+
**Features:**
|
|
208
|
+
|
|
209
|
+
- Direct project opening by name
|
|
210
|
+
- Fuzzy search if exact match not found
|
|
211
|
+
- Opens in your preferred IDE
|
|
212
|
+
- Updates last accessed timestamp
|
|
213
|
+
|
|
214
|
+
**Example output:**
|
|
215
|
+
|
|
216
|
+
``` bash
|
|
217
|
+
# Exact match
|
|
218
|
+
pxo open my-awesome-app
|
|
219
|
+
|
|
220
|
+
# Fuzzy match (finds "my-awesome-app")
|
|
221
|
+
pxo open awesome
|
|
222
|
+
|
|
223
|
+
# Multiple matches - shows selection menu
|
|
224
|
+
pxo open app
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
$ pxo open dashboard
|
|
229
|
+
|
|
230
|
+
Found similar project: client-dashboard
|
|
231
|
+
✓ Opening client-dashboard in VS Code...
|
|
232
|
+
✓ Opened client-dashboard
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Use case:** When you know the project name, this is the fastest way to open it.
|
|
236
|
+
|
|
158
237
|
---
|
|
159
238
|
|
|
160
239
|
### Version & Help
|
|
@@ -209,10 +288,46 @@ $ pxo list
|
|
|
209
288
|
# - View details
|
|
210
289
|
```
|
|
211
290
|
|
|
291
|
+
### Example 3: Quick Access Workflow
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Morning: See what you worked on recently
|
|
295
|
+
$ pxo recent
|
|
296
|
+
# → Select and open your active project
|
|
297
|
+
|
|
298
|
+
# Later: Quick open by name
|
|
299
|
+
$ pxo open client-dashboard
|
|
300
|
+
✓ Opened client-dashboard
|
|
301
|
+
|
|
302
|
+
# End of day: Browse all projects
|
|
303
|
+
$ pxo list
|
|
304
|
+
# → Review and organize
|
|
305
|
+
```
|
|
306
|
+
|
|
212
307
|
---
|
|
213
308
|
|
|
214
309
|
## 💡 Tips & Tricks
|
|
215
310
|
|
|
311
|
+
### Use Recent for Active Work
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Working on multiple projects?
|
|
315
|
+
pxo recent
|
|
316
|
+
|
|
317
|
+
# Shows only what you've touched recently
|
|
318
|
+
# Much faster than scrolling through all projects
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Quick Open for Speed
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
# If you remember the name, use open
|
|
325
|
+
pxo open my-app
|
|
326
|
+
|
|
327
|
+
# Fuzzy search helps with partial names
|
|
328
|
+
pxo open dash # finds "client-dashboard"
|
|
329
|
+
```
|
|
330
|
+
|
|
216
331
|
### Organize Your Projects
|
|
217
332
|
|
|
218
333
|
```bash
|
|
@@ -298,6 +413,18 @@ npm install -g projxo
|
|
|
298
413
|
|
|
299
414
|
Only projects created after installing v1.1.0+ are automatically tracked.
|
|
300
415
|
|
|
416
|
+
### Project Not Found (Open Command)
|
|
417
|
+
|
|
418
|
+
If `pxo open` can't find your project:
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
# Use list to see exact names
|
|
422
|
+
pxo list
|
|
423
|
+
|
|
424
|
+
# Or try partial name (fuzzy search)
|
|
425
|
+
pxo open partial-name
|
|
426
|
+
```
|
|
427
|
+
|
|
301
428
|
---
|
|
302
429
|
|
|
303
430
|
## 🤝 Contributing
|
|
@@ -365,6 +492,13 @@ pxo
|
|
|
365
492
|
pxo list
|
|
366
493
|
pxo ls
|
|
367
494
|
|
|
495
|
+
# Recent projects
|
|
496
|
+
pxo recent
|
|
497
|
+
pxo recent 5
|
|
498
|
+
|
|
499
|
+
# Quick open
|
|
500
|
+
pxo open <project-name>
|
|
501
|
+
|
|
368
502
|
# Version
|
|
369
503
|
pxo --version
|
|
370
504
|
pxo -V
|
package/index.js
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* Entry point for the CLI application
|
|
7
7
|
* Handles command routing and argument parsing
|
|
8
8
|
*
|
|
9
|
-
* @version 1.
|
|
9
|
+
* @version 1.2.0
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const { program } = require('commander');
|
|
13
13
|
const { run: createProject } = require('./src/cli');
|
|
14
14
|
const { listCommand } = require('./src/commands/list');
|
|
15
|
+
const { recentCommand } = require('./src/commands/recent');
|
|
16
|
+
const { openCommand } = require('./src/commands/open');
|
|
15
17
|
const logger = require('./src/utils/logger');
|
|
16
18
|
|
|
17
19
|
// Package info
|
|
@@ -38,6 +40,23 @@ program
|
|
|
38
40
|
listCommand();
|
|
39
41
|
});
|
|
40
42
|
|
|
43
|
+
// Show recent projects
|
|
44
|
+
program
|
|
45
|
+
.command('recent')
|
|
46
|
+
.description('Show recently accessed projects')
|
|
47
|
+
.argument('[limit]', 'number of projects to show', '10')
|
|
48
|
+
.action((limit) => {
|
|
49
|
+
recentCommand(parseInt(limit));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Open project
|
|
53
|
+
program
|
|
54
|
+
.command('open [project-name]')
|
|
55
|
+
.description('Open a project in IDE')
|
|
56
|
+
.action((projectName) => {
|
|
57
|
+
openCommand(projectName);
|
|
58
|
+
});
|
|
59
|
+
|
|
41
60
|
// Handle errors
|
|
42
61
|
program.exitOverride();
|
|
43
62
|
|
package/package.json
CHANGED
package/src/commands/list.js
CHANGED
|
@@ -67,11 +67,12 @@ async function listCommand() {
|
|
|
67
67
|
|
|
68
68
|
// Create choices for inquirer
|
|
69
69
|
const choices = projects.map(project => {
|
|
70
|
-
const typeDisplay = getTypeDisplay(project.type);
|
|
71
|
-
const timeAgo = formatRelativeTime(project.lastAccessed);
|
|
70
|
+
const typeDisplay = getTypeDisplay(project.type).padEnd(16);
|
|
71
|
+
const timeAgo = formatRelativeTime(project.lastAccessed).padEnd(15);
|
|
72
|
+
const nameDisplay = project.name.padEnd(30);
|
|
72
73
|
|
|
73
74
|
return {
|
|
74
|
-
name: `${
|
|
75
|
+
name: `${nameDisplay} ${typeDisplay} ${timeAgo}`,
|
|
75
76
|
value: project.id,
|
|
76
77
|
short: project.name
|
|
77
78
|
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open command - Quick open project by name
|
|
3
|
+
* Usage: pxo open <project-name>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const inquirer = require('inquirer');
|
|
7
|
+
const { getProjectByName, touchProject, searchProjects } = require('../storage/projects');
|
|
8
|
+
const { openInIDE } = require('../handlers/ideOpener');
|
|
9
|
+
const { getIDEChoices } = require('../config/ides');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Execute open command
|
|
14
|
+
* @param {string} projectName - Project name to open
|
|
15
|
+
*/
|
|
16
|
+
async function openCommand(projectName) {
|
|
17
|
+
try {
|
|
18
|
+
if (!projectName) {
|
|
19
|
+
logger.error('Please provide a project name');
|
|
20
|
+
logger.log('\nUsage:', 'dim');
|
|
21
|
+
logger.log(' pxo open <project-name>', 'cyan');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Try to find project
|
|
26
|
+
let project = getProjectByName(projectName);
|
|
27
|
+
|
|
28
|
+
// If not found, try fuzzy search
|
|
29
|
+
if (!project) {
|
|
30
|
+
const matches = searchProjects(projectName);
|
|
31
|
+
|
|
32
|
+
if (matches.length === 0) {
|
|
33
|
+
logger.error(`Project "${projectName}" not found`);
|
|
34
|
+
logger.log('\nList all projects with:', 'dim');
|
|
35
|
+
logger.log(' pxo list', 'cyan');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (matches.length === 1) {
|
|
40
|
+
project = matches[0];
|
|
41
|
+
logger.info(`Found similar project: ${project.name}`);
|
|
42
|
+
} else {
|
|
43
|
+
// Multiple matches, let user choose
|
|
44
|
+
project = await selectFromMatches(matches);
|
|
45
|
+
if (!project) return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Update last accessed time
|
|
50
|
+
touchProject(project.id);
|
|
51
|
+
|
|
52
|
+
// Determine which IDE to use
|
|
53
|
+
let ideKey = project.ide;
|
|
54
|
+
|
|
55
|
+
if (!ideKey || ideKey === 'skip') {
|
|
56
|
+
const { selectedIDE } = await inquirer.prompt([
|
|
57
|
+
{
|
|
58
|
+
type: 'list',
|
|
59
|
+
name: 'selectedIDE',
|
|
60
|
+
message: `Open "${project.name}" in:`,
|
|
61
|
+
choices: getIDEChoices()
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
ideKey = selectedIDE;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Open in IDE
|
|
68
|
+
if (ideKey !== 'skip') {
|
|
69
|
+
const success = await openInIDE(project.path, ideKey);
|
|
70
|
+
if (success) {
|
|
71
|
+
logger.success(`Opened ${project.name}`);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
logger.info(`Project path: ${project.path}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
} catch (error) {
|
|
78
|
+
logger.error(`Failed to open project: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Let user select from multiple matches
|
|
84
|
+
* @param {Array} matches - Array of matching projects
|
|
85
|
+
* @returns {Promise<Object|null>} Selected project or null
|
|
86
|
+
*/
|
|
87
|
+
async function selectFromMatches(matches) {
|
|
88
|
+
logger.info(`Found ${matches.length} matching projects:`);
|
|
89
|
+
logger.newLine();
|
|
90
|
+
|
|
91
|
+
const choices = matches.map(p => ({
|
|
92
|
+
name: `${p.name} (${p.type})`,
|
|
93
|
+
value: p.id,
|
|
94
|
+
short: p.name
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
choices.push(
|
|
98
|
+
new inquirer.Separator(),
|
|
99
|
+
{ name: '← Cancel', value: 'cancel' }
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const { selectedId } = await inquirer.prompt([
|
|
103
|
+
{
|
|
104
|
+
type: 'list',
|
|
105
|
+
name: 'selectedId',
|
|
106
|
+
message: 'Which project did you mean?',
|
|
107
|
+
choices
|
|
108
|
+
}
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
if (selectedId === 'cancel') {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const { getProjectById } = require('../storage/projects');
|
|
116
|
+
return getProjectById(selectedId);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = { openCommand };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recent command - Show recently accessed projects
|
|
3
|
+
* Usage: pxo recent [limit]
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const inquirer = require('inquirer');
|
|
7
|
+
const { getRecentProjects, touchProject } = require('../storage/projects');
|
|
8
|
+
const { openInIDE } = require('../handlers/ideOpener');
|
|
9
|
+
const logger = require('../utils/logger');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Format relative time (same as list.js)
|
|
13
|
+
* @param {string} isoDate - ISO date string
|
|
14
|
+
* @returns {string} Human-readable relative time
|
|
15
|
+
*/
|
|
16
|
+
function formatRelativeTime(isoDate) {
|
|
17
|
+
const date = new Date(isoDate);
|
|
18
|
+
const now = new Date();
|
|
19
|
+
const diffMs = now - date;
|
|
20
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
21
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
22
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
23
|
+
|
|
24
|
+
if (diffMins < 1) return 'just now';
|
|
25
|
+
if (diffMins < 60) return `${diffMins} min${diffMins > 1 ? 's' : ''} ago`;
|
|
26
|
+
if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
|
|
27
|
+
if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
|
|
28
|
+
if (diffDays < 30) return `${Math.floor(diffDays / 7)} week${Math.floor(diffDays / 7) > 1 ? 's' : ''} ago`;
|
|
29
|
+
return `${Math.floor(diffDays / 30)} month${Math.floor(diffDays / 30) > 1 ? 's' : ''} ago`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get project type display name
|
|
34
|
+
* @param {string} type - Project type key
|
|
35
|
+
* @returns {string} Formatted display name
|
|
36
|
+
*/
|
|
37
|
+
function getTypeDisplay(type) {
|
|
38
|
+
const typeMap = {
|
|
39
|
+
'react-vite': 'React+Vite',
|
|
40
|
+
'react-vite-ts': 'React+Vite(TS)',
|
|
41
|
+
'nextjs': 'Next.js',
|
|
42
|
+
'angular': 'Angular',
|
|
43
|
+
'react-native': 'React Native'
|
|
44
|
+
};
|
|
45
|
+
return typeMap[type] || type;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Execute recent command
|
|
50
|
+
* @param {number} limit - Number of recent projects to show
|
|
51
|
+
*/
|
|
52
|
+
async function recentCommand(limit = 10) {
|
|
53
|
+
try {
|
|
54
|
+
const projects = getRecentProjects(limit);
|
|
55
|
+
|
|
56
|
+
if (projects.length === 0) {
|
|
57
|
+
logger.info('No recent projects found');
|
|
58
|
+
logger.log('\nCreate your first project with:', 'dim');
|
|
59
|
+
logger.log(' pxo', 'cyan');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
logger.newLine();
|
|
64
|
+
logger.log(`🕐 Recent Projects (${projects.length})`, 'bright');
|
|
65
|
+
logger.newLine();
|
|
66
|
+
|
|
67
|
+
// Create choices for inquirer
|
|
68
|
+
const choices = projects.map((project, index) => {
|
|
69
|
+
const typeDisplay = getTypeDisplay(project.type).padEnd(16);
|
|
70
|
+
const timeAgo = formatRelativeTime(project.lastAccessed).padEnd(15);
|
|
71
|
+
const indexDisplay = `${index + 1}.`.padEnd(4);
|
|
72
|
+
const nameDisplay = project.name.padEnd(30);
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
name: `${indexDisplay}${nameDisplay} ${typeDisplay} ${timeAgo}`,
|
|
76
|
+
value: project.id,
|
|
77
|
+
short: project.name
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Add separator and back option
|
|
82
|
+
choices.push(
|
|
83
|
+
new inquirer.Separator(),
|
|
84
|
+
{ name: '← Cancel', value: 'cancel' }
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const { selectedId } = await inquirer.prompt([
|
|
88
|
+
{
|
|
89
|
+
type: 'list',
|
|
90
|
+
name: 'selectedId',
|
|
91
|
+
message: 'Select a project to open:',
|
|
92
|
+
choices,
|
|
93
|
+
pageSize: 15
|
|
94
|
+
}
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
if (selectedId === 'cancel') {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Open selected project
|
|
102
|
+
await openSelectedProject(selectedId);
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error.isTtyError) {
|
|
106
|
+
logger.error('This command requires an interactive terminal');
|
|
107
|
+
} else {
|
|
108
|
+
logger.error(`Failed to show recent projects: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Open selected project in IDE
|
|
115
|
+
* @param {string} projectId - Project ID
|
|
116
|
+
*/
|
|
117
|
+
async function openSelectedProject(projectId) {
|
|
118
|
+
const { getProjectById } = require('../storage/projects');
|
|
119
|
+
const { getIDEChoices } = require('../config/ides');
|
|
120
|
+
|
|
121
|
+
const project = getProjectById(projectId);
|
|
122
|
+
|
|
123
|
+
if (!project) {
|
|
124
|
+
logger.error('Project not found');
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Update last accessed time
|
|
129
|
+
touchProject(project.id);
|
|
130
|
+
|
|
131
|
+
// Use project's preferred IDE or prompt
|
|
132
|
+
let ideKey = project.ide;
|
|
133
|
+
|
|
134
|
+
if (!ideKey || ideKey === 'skip') {
|
|
135
|
+
const { selectedIDE } = await inquirer.prompt([
|
|
136
|
+
{
|
|
137
|
+
type: 'list',
|
|
138
|
+
name: 'selectedIDE',
|
|
139
|
+
message: 'Select IDE:',
|
|
140
|
+
choices: getIDEChoices()
|
|
141
|
+
}
|
|
142
|
+
]);
|
|
143
|
+
ideKey = selectedIDE;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (ideKey !== 'skip') {
|
|
147
|
+
const success = await openInIDE(project.path, ideKey);
|
|
148
|
+
if (success) {
|
|
149
|
+
logger.success(`Opened ${project.name}`);
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
logger.info(`Project path: ${project.path}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = { recentCommand };
|