x7-code-line 0.3.0 → 0.4.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 +412 -398
- package/bin/x7-code-line.js +8 -8
- package/hooks/git/commit-msg +4 -4
- package/hooks/git/pre-commit +4 -4
- package/package.json +30 -30
- package/src/agent-hooks.js +59 -28
- package/src/cache.js +128 -69
- package/src/cli.js +153 -108
- package/src/diff-lines.js +115 -115
- package/src/git-trailer.js +46 -46
- package/src/index.js +7 -7
- package/src/install.js +268 -267
- package/src/postinstall.js +13 -13
- package/templates/.codex/hooks.json +30 -14
- package/templates/.cursor/hooks.json +17 -14
package/bin/x7-code-line.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { runCli } = require("../src/cli");
|
|
4
|
-
|
|
5
|
-
runCli(process.argv.slice(2)).catch((error) => {
|
|
6
|
-
console.error(`[x7-code-line] ${error.message}`);
|
|
7
|
-
process.exit(1);
|
|
8
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { runCli } = require("../src/cli");
|
|
4
|
+
|
|
5
|
+
runCli(process.argv.slice(2)).catch((error) => {
|
|
6
|
+
console.error(`[x7-code-line] ${error.message}`);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
package/hooks/git/commit-msg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
set -eu
|
|
3
|
-
|
|
4
|
-
npx --no-install x7-code-line git-commit-msg "$1"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
npx --no-install x7-code-line git-commit-msg "$1"
|
package/hooks/git/pre-commit
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
set -eu
|
|
3
|
-
|
|
4
|
-
npx --no-install x7-code-line git-pre-commit "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
npx --no-install x7-code-line git-pre-commit "$@"
|
package/package.json
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "x7-code-line",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Install Cursor, Codex, and git hooks for x7 code line workflows.",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"x7-code-line": "bin/x7-code-line.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"postinstall": "node src/postinstall.js",
|
|
11
|
-
"test": "node test/install.test.js"
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"bin/",
|
|
15
|
-
"hooks/",
|
|
16
|
-
"src/",
|
|
17
|
-
"templates/"
|
|
18
|
-
],
|
|
19
|
-
"keywords": [
|
|
20
|
-
"cursor",
|
|
21
|
-
"codex",
|
|
22
|
-
"hooks",
|
|
23
|
-
"git-hooks"
|
|
24
|
-
],
|
|
25
|
-
"author": "",
|
|
26
|
-
"license": "MIT",
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">=18"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "x7-code-line",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Install Cursor, Codex, and git hooks for x7 code line workflows.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"x7-code-line": "bin/x7-code-line.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node src/postinstall.js",
|
|
11
|
+
"test": "node test/install.test.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin/",
|
|
15
|
+
"hooks/",
|
|
16
|
+
"src/",
|
|
17
|
+
"templates/"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"cursor",
|
|
21
|
+
"codex",
|
|
22
|
+
"hooks",
|
|
23
|
+
"git-hooks"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/agent-hooks.js
CHANGED
|
@@ -1,62 +1,93 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const {
|
|
4
|
-
AI_DIFF_CACHE_FILE,
|
|
5
|
-
NORMAL_DIFF_CACHE_FILE,
|
|
6
|
-
addProjectId,
|
|
7
|
-
getProjectIds,
|
|
8
|
-
readLineIdCache,
|
|
9
|
-
readProjects,
|
|
10
|
-
writeLineIdCache
|
|
11
|
-
} = require("./cache");
|
|
12
|
-
const { getGitDiffLineIds } = require("./diff-lines");
|
|
13
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
AI_DIFF_CACHE_FILE,
|
|
5
|
+
NORMAL_DIFF_CACHE_FILE,
|
|
6
|
+
addProjectId,
|
|
7
|
+
getProjectIds,
|
|
8
|
+
readLineIdCache,
|
|
9
|
+
readProjects,
|
|
10
|
+
writeLineIdCache
|
|
11
|
+
} = require("./cache");
|
|
12
|
+
const { getGitDiffLineIds } = require("./diff-lines");
|
|
13
|
+
|
|
14
14
|
function handlePromptSubmit(baseDir = process.env.INIT_CWD || process.cwd()) {
|
|
15
|
+
log("prompt-submit", `start base=${baseDir}`);
|
|
15
16
|
const projects = readProjects(baseDir);
|
|
16
17
|
const aiCache = readLineIdCache(baseDir, AI_DIFF_CACHE_FILE);
|
|
17
18
|
const normalCache = readLineIdCache(baseDir, NORMAL_DIFF_CACHE_FILE);
|
|
18
19
|
|
|
19
20
|
for (const projectDir of projects) {
|
|
21
|
+
log("prompt-submit", `project ${projectDir}`);
|
|
20
22
|
const aiIds = getProjectIds(aiCache, projectDir);
|
|
21
|
-
|
|
23
|
+
const ids = safelyGetDiffLineIds("prompt-submit", projectDir);
|
|
24
|
+
let addedCount = 0;
|
|
25
|
+
for (const id of ids) {
|
|
22
26
|
if (!aiIds.has(id)) {
|
|
23
|
-
addProjectId(normalCache, projectDir, id)
|
|
27
|
+
if (addProjectId(normalCache, projectDir, id)) {
|
|
28
|
+
addedCount += 1;
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
}
|
|
32
|
+
log("prompt-submit", `project ${projectDir} cached=${addedCount}`);
|
|
26
33
|
}
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
writeCache("prompt-submit", baseDir, NORMAL_DIFF_CACHE_FILE, normalCache);
|
|
36
|
+
log("prompt-submit", "end");
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
function handleStop(baseDir = process.env.INIT_CWD || process.cwd()) {
|
|
40
|
+
log("stop", `start base=${baseDir}`);
|
|
32
41
|
const projects = readProjects(baseDir);
|
|
33
42
|
const aiCache = readLineIdCache(baseDir, AI_DIFF_CACHE_FILE);
|
|
34
43
|
const normalCache = readLineIdCache(baseDir, NORMAL_DIFF_CACHE_FILE);
|
|
35
44
|
|
|
36
45
|
for (const projectDir of projects) {
|
|
46
|
+
log("stop", `project ${projectDir}`);
|
|
37
47
|
const normalIds = getProjectIds(normalCache, projectDir);
|
|
38
|
-
|
|
48
|
+
const ids = safelyGetDiffLineIds("stop", projectDir);
|
|
49
|
+
let addedCount = 0;
|
|
50
|
+
for (const id of ids) {
|
|
39
51
|
if (!normalIds.has(id)) {
|
|
40
|
-
addProjectId(aiCache, projectDir, id)
|
|
52
|
+
if (addProjectId(aiCache, projectDir, id)) {
|
|
53
|
+
addedCount += 1;
|
|
54
|
+
}
|
|
41
55
|
}
|
|
42
56
|
}
|
|
57
|
+
log("stop", `project ${projectDir} cached=${addedCount}`);
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
writeCache("stop", baseDir, AI_DIFF_CACHE_FILE, aiCache);
|
|
61
|
+
log("stop", "end");
|
|
46
62
|
}
|
|
47
63
|
|
|
48
|
-
function safelyGetDiffLineIds(projectDir) {
|
|
64
|
+
function safelyGetDiffLineIds(command, projectDir) {
|
|
65
|
+
log(command, `reading diff ${projectDir}`);
|
|
49
66
|
try {
|
|
50
|
-
|
|
67
|
+
const ids = getGitDiffLineIds(projectDir);
|
|
68
|
+
log(command, `read diff success ${projectDir} count=${ids.length}`);
|
|
69
|
+
return ids;
|
|
51
70
|
} catch (error) {
|
|
52
|
-
|
|
53
|
-
console.error(`[x7-code-line] skip ${projectDir}: ${error.message}`);
|
|
54
|
-
}
|
|
71
|
+
log(command, `read diff failed ${projectDir}: ${error.message}`);
|
|
55
72
|
return [];
|
|
56
73
|
}
|
|
57
74
|
}
|
|
58
75
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
};
|
|
76
|
+
function writeCache(command, baseDir, fileName, cache) {
|
|
77
|
+
try {
|
|
78
|
+
writeLineIdCache(baseDir, fileName, cache);
|
|
79
|
+
log(command, `write cache success ${fileName}`);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
log(command, `write cache failed ${fileName}: ${error.message}`);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function log(command, message) {
|
|
87
|
+
console.error(`[x7-code-line] ${command} ${message}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
handlePromptSubmit,
|
|
92
|
+
handleStop
|
|
93
|
+
};
|
package/src/cache.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const fs = require("node:fs");
|
|
4
|
+
const os = require("node:os");
|
|
4
5
|
const path = require("node:path");
|
|
5
6
|
|
|
6
7
|
const CACHE_DIR_NAME = ".x7-code-line";
|
|
@@ -8,98 +9,150 @@ const PROJECTS_CACHE_FILE = "projects.json";
|
|
|
8
9
|
const AI_DIFF_CACHE_FILE = "ai-diff-line-ids.json";
|
|
9
10
|
const NORMAL_DIFF_CACHE_FILE = "normal-diff-line-ids.json";
|
|
10
11
|
const PENDING_COMMIT_FILE = "pending-commit.json";
|
|
11
|
-
|
|
12
|
+
const BASE_POINTER_FILE = ".x7-code-line-base.json";
|
|
13
|
+
|
|
12
14
|
function getCacheDir(baseDir = process.env.INIT_CWD || process.cwd()) {
|
|
13
15
|
return path.join(path.resolve(baseDir), CACHE_DIR_NAME);
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
19
|
-
ensureJson(path.join(cacheDir, PROJECTS_CACHE_FILE), { projects: [] });
|
|
20
|
-
ensureJson(path.join(cacheDir, AI_DIFF_CACHE_FILE), { projects: {} });
|
|
21
|
-
ensureJson(path.join(cacheDir, NORMAL_DIFF_CACHE_FILE), { projects: {} });
|
|
22
|
-
return cacheDir;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function writeProjects(baseDir, projectDirs) {
|
|
26
|
-
const cacheDir = ensureCacheFiles(baseDir);
|
|
27
|
-
const projects = [...new Set(projectDirs.map((dir) => path.resolve(dir)))];
|
|
28
|
-
writeJson(path.join(cacheDir, PROJECTS_CACHE_FILE), { projects });
|
|
18
|
+
function getInstallFile(baseDir = process.env.INIT_CWD || process.cwd()) {
|
|
19
|
+
return path.join(getCacheDir(baseDir), "install.json");
|
|
29
20
|
}
|
|
30
21
|
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function readLineIdCache(baseDir, fileName) {
|
|
39
|
-
const cacheDir = ensureCacheFiles(baseDir);
|
|
40
|
-
const cache = readJson(path.join(cacheDir, fileName), { projects: {} });
|
|
41
|
-
return cache && typeof cache === "object" && !Array.isArray(cache) ? cache : { projects: {} };
|
|
22
|
+
function getBasePointerPath() {
|
|
23
|
+
if (process.env.X7_CODE_LINE_POINTER_PATH) {
|
|
24
|
+
return path.resolve(process.env.X7_CODE_LINE_POINTER_PATH);
|
|
25
|
+
}
|
|
26
|
+
return path.join(os.homedir(), BASE_POINTER_FILE);
|
|
42
27
|
}
|
|
43
|
-
|
|
44
|
-
function
|
|
45
|
-
const cacheDir =
|
|
46
|
-
|
|
28
|
+
|
|
29
|
+
function ensureCacheFiles(baseDir) {
|
|
30
|
+
const cacheDir = getCacheDir(baseDir);
|
|
31
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
32
|
+
ensureJson(path.join(cacheDir, PROJECTS_CACHE_FILE), { projects: [] });
|
|
33
|
+
ensureJson(path.join(cacheDir, AI_DIFF_CACHE_FILE), { projects: {} });
|
|
34
|
+
ensureJson(path.join(cacheDir, NORMAL_DIFF_CACHE_FILE), { projects: {} });
|
|
35
|
+
return cacheDir;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function writeProjects(baseDir, projectDirs) {
|
|
39
|
+
const cacheDir = ensureCacheFiles(baseDir);
|
|
40
|
+
const projects = [...new Set(projectDirs.map((dir) => path.resolve(dir)))];
|
|
41
|
+
writeJson(path.join(cacheDir, PROJECTS_CACHE_FILE), { projects });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function readProjects(baseDir = process.env.INIT_CWD || process.cwd()) {
|
|
45
|
+
const cacheDir = ensureCacheFiles(baseDir);
|
|
46
|
+
const cache = readJson(path.join(cacheDir, PROJECTS_CACHE_FILE), { projects: [] });
|
|
47
|
+
const projects = Array.isArray(cache.projects) ? cache.projects : [];
|
|
48
|
+
return projects.map((project) => path.resolve(project));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function readLineIdCache(baseDir, fileName) {
|
|
52
|
+
const cacheDir = ensureCacheFiles(baseDir);
|
|
53
|
+
const cache = readJson(path.join(cacheDir, fileName), { projects: {} });
|
|
54
|
+
return cache && typeof cache === "object" && !Array.isArray(cache) ? cache : { projects: {} };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function writeLineIdCache(baseDir, fileName, cache) {
|
|
58
|
+
const cacheDir = ensureCacheFiles(baseDir);
|
|
59
|
+
writeJson(path.join(cacheDir, fileName), cache);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getProjectIds(cache, projectDir) {
|
|
63
|
+
const key = path.resolve(projectDir);
|
|
64
|
+
const ids = cache.projects && Array.isArray(cache.projects[key]) ? cache.projects[key] : [];
|
|
65
|
+
return new Set(ids);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function addProjectId(cache, projectDir, id) {
|
|
69
|
+
const key = path.resolve(projectDir);
|
|
70
|
+
if (!cache.projects || typeof cache.projects !== "object" || Array.isArray(cache.projects)) {
|
|
71
|
+
cache.projects = {};
|
|
72
|
+
}
|
|
73
|
+
if (!Array.isArray(cache.projects[key])) {
|
|
74
|
+
cache.projects[key] = [];
|
|
75
|
+
}
|
|
76
|
+
if (!cache.projects[key].includes(id)) {
|
|
77
|
+
cache.projects[key].push(id);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function clearProjectIds(cache, projectDir) {
|
|
84
|
+
const key = path.resolve(projectDir);
|
|
85
|
+
if (!cache.projects || typeof cache.projects !== "object" || Array.isArray(cache.projects)) {
|
|
86
|
+
cache.projects = {};
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (Object.prototype.hasOwnProperty.call(cache.projects, key)) {
|
|
90
|
+
delete cache.projects[key];
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
47
94
|
}
|
|
48
95
|
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
96
|
+
function writeBasePointer(baseDir) {
|
|
97
|
+
const pointerPath = getBasePointerPath();
|
|
98
|
+
fs.mkdirSync(path.dirname(pointerPath), { recursive: true });
|
|
99
|
+
writeJson(pointerPath, { baseDir: path.resolve(baseDir) });
|
|
53
100
|
}
|
|
54
101
|
|
|
55
|
-
function
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
58
|
-
|
|
102
|
+
function readBasePointer() {
|
|
103
|
+
const pointer = readJson(getBasePointerPath(), {});
|
|
104
|
+
if (!pointer || typeof pointer.baseDir !== "string" || !pointer.baseDir.trim()) {
|
|
105
|
+
return undefined;
|
|
59
106
|
}
|
|
60
|
-
if (!Array.isArray(cache.projects[key])) {
|
|
61
|
-
cache.projects[key] = [];
|
|
62
|
-
}
|
|
63
|
-
if (!cache.projects[key].includes(id)) {
|
|
64
|
-
cache.projects[key].push(id);
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
107
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (!cache.projects || typeof cache.projects !== "object" || Array.isArray(cache.projects)) {
|
|
73
|
-
cache.projects = {};
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
if (Object.prototype.hasOwnProperty.call(cache.projects, key)) {
|
|
77
|
-
delete cache.projects[key];
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
108
|
+
const baseDir = path.resolve(pointer.baseDir);
|
|
109
|
+
return hasInstallFile(baseDir) ? baseDir : undefined;
|
|
81
110
|
}
|
|
82
111
|
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
112
|
+
function findInstalledBase(startDir) {
|
|
113
|
+
let current = path.resolve(startDir);
|
|
114
|
+
|
|
115
|
+
while (true) {
|
|
116
|
+
if (hasInstallFile(current)) {
|
|
117
|
+
return current;
|
|
118
|
+
}
|
|
119
|
+
const parent = path.dirname(current);
|
|
120
|
+
if (parent === current) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
current = parent;
|
|
86
124
|
}
|
|
87
125
|
}
|
|
88
126
|
|
|
89
|
-
function
|
|
127
|
+
function hasInstallFile(baseDir) {
|
|
90
128
|
try {
|
|
91
|
-
return
|
|
129
|
+
return fs.statSync(getInstallFile(baseDir)).isFile();
|
|
92
130
|
} catch {
|
|
93
|
-
return
|
|
131
|
+
return false;
|
|
94
132
|
}
|
|
95
133
|
}
|
|
96
|
-
|
|
97
|
-
function
|
|
98
|
-
fs.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
134
|
+
|
|
135
|
+
function ensureJson(filePath, defaultValue) {
|
|
136
|
+
if (!fs.existsSync(filePath)) {
|
|
137
|
+
writeJson(filePath, defaultValue);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function readJson(filePath, defaultValue) {
|
|
142
|
+
try {
|
|
143
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
144
|
+
} catch {
|
|
145
|
+
return defaultValue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function writeJson(filePath, value) {
|
|
150
|
+
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
102
154
|
AI_DIFF_CACHE_FILE,
|
|
155
|
+
BASE_POINTER_FILE,
|
|
103
156
|
CACHE_DIR_NAME,
|
|
104
157
|
NORMAL_DIFF_CACHE_FILE,
|
|
105
158
|
PENDING_COMMIT_FILE,
|
|
@@ -107,10 +160,16 @@ module.exports = {
|
|
|
107
160
|
addProjectId,
|
|
108
161
|
clearProjectIds,
|
|
109
162
|
ensureCacheFiles,
|
|
163
|
+
findInstalledBase,
|
|
164
|
+
getBasePointerPath,
|
|
110
165
|
getCacheDir,
|
|
166
|
+
getInstallFile,
|
|
111
167
|
getProjectIds,
|
|
168
|
+
hasInstallFile,
|
|
112
169
|
readLineIdCache,
|
|
170
|
+
readBasePointer,
|
|
113
171
|
readProjects,
|
|
172
|
+
writeBasePointer,
|
|
114
173
|
writeLineIdCache,
|
|
115
174
|
writeProjects
|
|
116
175
|
};
|