@reqall/core 0.0.1 → 0.0.3
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/dist/classify.d.ts +1 -1
- package/dist/classify.d.ts.map +1 -1
- package/dist/classify.js +2 -1
- package/dist/classify.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-client.d.ts +13 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +31 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/types.d.ts +5 -5
- package/package.json +2 -1
- package/src/classify.ts +2 -1
- package/src/index.ts +2 -3
- package/src/types.ts +5 -5
- package/src/context.ts +0 -36
package/dist/classify.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { WorkClassification } from './types.js';
|
|
|
3
3
|
* Classification prompt injected into agent context after a task completes.
|
|
4
4
|
* The agent host uses this to decide whether and how to persist the work.
|
|
5
5
|
*/
|
|
6
|
-
export declare const CLASSIFICATION_PROMPT = "Classify the work just completed into exactly one category:\n\n| Work type | kind | status |\n|------------------------------------|---------|------------|\n| Bug fix | issue | resolved |\n| Architectural change | arch | resolved |\n| New feature request (not yet done) | todo | open |\n| Completed feature request | todo | resolved |\n| New spec or plan | spec | open |\n| Trivial / Q&A / unclassifiable | \u2014 | no action |\n\nIf the work is non-trivial, save it via reqall:upsert_record with the appropriate kind, status, and a short descriptive title.\nIf the work created or modified relationships between records, also call reqall:
|
|
6
|
+
export declare const CLASSIFICATION_PROMPT = "Classify the work just completed into exactly one category:\n\n| Work type | kind | status |\n|------------------------------------|---------|------------|\n| Bug fix | issue | resolved |\n| Architectural change | arch | resolved |\n| New feature request (not yet done) | todo | open |\n| Completed feature request | todo | resolved |\n| New spec or plan | spec | open |\n| Test scenario | test | open |\n| Trivial / Q&A / unclassifiable | \u2014 | no action |\n\nIf the work is non-trivial, save it via reqall:upsert_record with the appropriate kind, status, and a short descriptive title.\nIf the work created or modified relationships between records, also call reqall:upsert_link.";
|
|
7
7
|
/**
|
|
8
8
|
* Parse a classification response from the agent into a structured result.
|
|
9
9
|
* Returns null if the work should be skipped (trivial/Q&A).
|
package/dist/classify.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,81BAa2D,CAAC;AAE9F;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,kBAAkB,GAAG,IAAI,CAgB3B"}
|
package/dist/classify.js
CHANGED
|
@@ -11,10 +11,11 @@ export const CLASSIFICATION_PROMPT = `Classify the work just completed into exac
|
|
|
11
11
|
| New feature request (not yet done) | todo | open |
|
|
12
12
|
| Completed feature request | todo | resolved |
|
|
13
13
|
| New spec or plan | spec | open |
|
|
14
|
+
| Test scenario | test | open |
|
|
14
15
|
| Trivial / Q&A / unclassifiable | — | no action |
|
|
15
16
|
|
|
16
17
|
If the work is non-trivial, save it via reqall:upsert_record with the appropriate kind, status, and a short descriptive title.
|
|
17
|
-
If the work created or modified relationships between records, also call reqall:
|
|
18
|
+
If the work created or modified relationships between records, also call reqall:upsert_link.`;
|
|
18
19
|
/**
|
|
19
20
|
* Parse a classification response from the agent into a structured result.
|
|
20
21
|
* Returns null if the work should be skipped (trivial/Q&A).
|
package/dist/classify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;6FAawD,CAAC;AAE9F;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAwB,EACxB,MAA0B,EAC1B,KAAyB;IAEzB,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;IACtE,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;IAEtF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IAElE,OAAO;QACL,IAAI,EAAE,IAAkC;QACxC,MAAM,EAAE,CAAC,MAAM,IAAI,MAAM,CAAiC;QAC1D,KAAK;KACN,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { loadConfig } from './config.js';
|
|
2
2
|
export { detectProject } from './detect-project.js';
|
|
3
3
|
export { parseClassification as classifyWork, CLASSIFICATION_PROMPT } from './classify.js';
|
|
4
|
-
export {
|
|
5
|
-
export type { ReqallConfig, RecordKind, RecordStatus, EdgeRelationship, EntityType, Project, Record, SearchResult, Edge, WorkClassification, } from './types.js';
|
|
4
|
+
export type { ReqallConfig, RecordKind, RecordStatus, LinkRelationship, EntityType, Project, Record, SearchResult, Link, WorkClassification, } from './types.js';
|
|
6
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,IAAI,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3F,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,IAAI,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3F,YAAY,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { loadConfig } from './config.js';
|
|
2
2
|
export { detectProject } from './detect-project.js';
|
|
3
3
|
export { parseClassification as classifyWork, CLASSIFICATION_PROMPT } from './classify.js';
|
|
4
|
-
export { formatContext } from './context.js';
|
|
5
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,IAAI,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,IAAI,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import type { ReqallConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create an MCP client connected to the Reqall server.
|
|
5
|
+
* Caller must close the client when done.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createMcpClient(config: ReqallConfig): Promise<Client>;
|
|
8
|
+
/**
|
|
9
|
+
* Call an MCP tool and return the text content from the response.
|
|
10
|
+
* Returns null if the call failed or returned an error.
|
|
11
|
+
*/
|
|
12
|
+
export declare function callTool(client: Client, name: string, args?: Record<string, unknown>): Promise<string | null>;
|
|
13
|
+
//# sourceMappingURL=mcp-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;GAGG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAc3E;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create an MCP client connected to the Reqall server.
|
|
5
|
+
* Caller must close the client when done.
|
|
6
|
+
*/
|
|
7
|
+
export async function createMcpClient(config) {
|
|
8
|
+
const client = new Client({ name: 'reqall-plugin', version: '0.0.3' });
|
|
9
|
+
const transport = new StreamableHTTPClientTransport(new URL(`${config.url}/mcp`), {
|
|
10
|
+
requestInit: {
|
|
11
|
+
headers: { Authorization: `Bearer ${config.apiKey}` },
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
await client.connect(transport);
|
|
15
|
+
return client;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Call an MCP tool and return the text content from the response.
|
|
19
|
+
* Returns null if the call failed or returned an error.
|
|
20
|
+
*/
|
|
21
|
+
export async function callTool(client, name, args = {}) {
|
|
22
|
+
const result = await client.callTool({ name, arguments: args });
|
|
23
|
+
if (result.isError)
|
|
24
|
+
return null;
|
|
25
|
+
const textContent = result.content;
|
|
26
|
+
return textContent
|
|
27
|
+
?.filter((c) => c.type === 'text' && c.text)
|
|
28
|
+
.map((c) => c.text)
|
|
29
|
+
.join('\n') ?? null;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAoB;IACxD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAEvE,MAAM,SAAS,GAAG,IAAI,6BAA6B,CACjD,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,EAC5B;QACE,WAAW,EAAE;YACX,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,EAAE;SACtD;KACF,CACF,CAAC;IAEF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAc,EACd,IAAY,EACZ,OAAgC,EAAE;IAElC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAiD,CAAC;IAC7E,OAAO,WAAW;QAChB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;SAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACxB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
export type RecordKind = 'issue' | 'spec' | 'arch' | 'test' | 'todo';
|
|
3
3
|
/** Record statuses */
|
|
4
4
|
export type RecordStatus = 'open' | 'resolved' | 'archived' | 'active' | 'inactive';
|
|
5
|
-
/**
|
|
6
|
-
export type
|
|
7
|
-
/** Entity types for
|
|
5
|
+
/** Link relationship types */
|
|
6
|
+
export type LinkRelationship = 'blocks' | 'implements' | 'tests' | 'parent' | 'related';
|
|
7
|
+
/** Entity types for links */
|
|
8
8
|
export type EntityType = 'records' | 'projects';
|
|
9
9
|
export interface ReqallConfig {
|
|
10
10
|
apiKey: string;
|
|
@@ -30,13 +30,13 @@ export interface Record {
|
|
|
30
30
|
export interface SearchResult extends Record {
|
|
31
31
|
similarity: number;
|
|
32
32
|
}
|
|
33
|
-
export interface
|
|
33
|
+
export interface Link {
|
|
34
34
|
id: number;
|
|
35
35
|
source_id: number;
|
|
36
36
|
source_table: EntityType;
|
|
37
37
|
target_id: number;
|
|
38
38
|
target_table: EntityType;
|
|
39
|
-
relationship:
|
|
39
|
+
relationship: LinkRelationship;
|
|
40
40
|
updated_at: string;
|
|
41
41
|
}
|
|
42
42
|
export interface WorkClassification {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reqall/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Shared plugin logic for Reqall AI agent plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
+
"dependencies": {},
|
|
14
15
|
"license": "MIT",
|
|
15
16
|
"scripts": {
|
|
16
17
|
"build": "tsc",
|
package/src/classify.ts
CHANGED
|
@@ -13,10 +13,11 @@ export const CLASSIFICATION_PROMPT = `Classify the work just completed into exac
|
|
|
13
13
|
| New feature request (not yet done) | todo | open |
|
|
14
14
|
| Completed feature request | todo | resolved |
|
|
15
15
|
| New spec or plan | spec | open |
|
|
16
|
+
| Test scenario | test | open |
|
|
16
17
|
| Trivial / Q&A / unclassifiable | — | no action |
|
|
17
18
|
|
|
18
19
|
If the work is non-trivial, save it via reqall:upsert_record with the appropriate kind, status, and a short descriptive title.
|
|
19
|
-
If the work created or modified relationships between records, also call reqall:
|
|
20
|
+
If the work created or modified relationships between records, also call reqall:upsert_link.`;
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Parse a classification response from the agent into a structured result.
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
export { loadConfig } from './config.js';
|
|
2
2
|
export { detectProject } from './detect-project.js';
|
|
3
3
|
export { parseClassification as classifyWork, CLASSIFICATION_PROMPT } from './classify.js';
|
|
4
|
-
export { formatContext } from './context.js';
|
|
5
4
|
export type {
|
|
6
5
|
ReqallConfig,
|
|
7
6
|
RecordKind,
|
|
8
7
|
RecordStatus,
|
|
9
|
-
|
|
8
|
+
LinkRelationship,
|
|
10
9
|
EntityType,
|
|
11
10
|
Project,
|
|
12
11
|
Record,
|
|
13
12
|
SearchResult,
|
|
14
|
-
|
|
13
|
+
Link,
|
|
15
14
|
WorkClassification,
|
|
16
15
|
} from './types.js';
|
package/src/types.ts
CHANGED
|
@@ -4,10 +4,10 @@ export type RecordKind = 'issue' | 'spec' | 'arch' | 'test' | 'todo';
|
|
|
4
4
|
/** Record statuses */
|
|
5
5
|
export type RecordStatus = 'open' | 'resolved' | 'archived' | 'active' | 'inactive';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
export type
|
|
7
|
+
/** Link relationship types */
|
|
8
|
+
export type LinkRelationship = 'blocks' | 'implements' | 'tests' | 'parent' | 'related';
|
|
9
9
|
|
|
10
|
-
/** Entity types for
|
|
10
|
+
/** Entity types for links */
|
|
11
11
|
export type EntityType = 'records' | 'projects';
|
|
12
12
|
|
|
13
13
|
export interface ReqallConfig {
|
|
@@ -38,13 +38,13 @@ export interface SearchResult extends Record {
|
|
|
38
38
|
similarity: number;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export interface
|
|
41
|
+
export interface Link {
|
|
42
42
|
id: number;
|
|
43
43
|
source_id: number;
|
|
44
44
|
source_table: EntityType;
|
|
45
45
|
target_id: number;
|
|
46
46
|
target_table: EntityType;
|
|
47
|
-
relationship:
|
|
47
|
+
relationship: LinkRelationship;
|
|
48
48
|
updated_at: string;
|
|
49
49
|
}
|
|
50
50
|
|
package/src/context.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Record, SearchResult } from './types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Format recent records and search results into context lines
|
|
5
|
-
* suitable for injection into an agent's prompt.
|
|
6
|
-
*/
|
|
7
|
-
export function formatContext(
|
|
8
|
-
projectName: string,
|
|
9
|
-
recentRecords: Record[],
|
|
10
|
-
searchResults: SearchResult[],
|
|
11
|
-
): string {
|
|
12
|
-
const lines: string[] = [];
|
|
13
|
-
|
|
14
|
-
lines.push(`[reqall] Project: ${projectName}`);
|
|
15
|
-
|
|
16
|
-
if (recentRecords.length > 0) {
|
|
17
|
-
lines.push(`[reqall] Recently updated records:`);
|
|
18
|
-
for (const r of recentRecords) {
|
|
19
|
-
lines.push(`- [${r.kind}] ${r.title} (id=${r.id}, status=${r.status}, updated: ${r.updated_at})`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (searchResults.length > 0) {
|
|
24
|
-
lines.push(`[reqall] Relevant context from memory:`);
|
|
25
|
-
for (const r of searchResults) {
|
|
26
|
-
const proj = r.project_name ? `project: ${r.project_name}, ` : '';
|
|
27
|
-
lines.push(`- [${r.kind}] ${r.title} (${proj}status: ${r.status}, similarity: ${r.similarity.toFixed(2)})`);
|
|
28
|
-
if (r.body) {
|
|
29
|
-
const truncated = r.body.length > 200 ? r.body.slice(0, 200) + '…' : r.body;
|
|
30
|
-
lines.push(` ${truncated}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return lines.join('\n');
|
|
36
|
-
}
|