@codingame/monaco-vscode-chat-service-override 20.0.0 → 20.1.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/package.json +36 -36
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.js +16 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingServiceImpl.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/notebook/chatEditingNotebookEditorIntegration.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/simpleBrowserEditorOverlay.js +19 -19
- package/vscode/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/chatParticipant.contribution.js +32 -32
- package/vscode/src/vs/workbench/contrib/chat/browser/chatPasteProviders.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions.contribution.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSetup.js +47 -47
- package/vscode/src/vs/workbench/contrib/chat/browser/chatStatus.js +53 -53
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorHover.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/chatModeActions.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.js +18 -18
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.js +12 -12
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptToolsCodeLensProvider.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptUrlHandler.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/runPromptAction.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/saveToPromptAction.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcomeHandler.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/common/chatProgressTypes/chatToolInvocation.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/chatServiceImpl.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/common/chatSessionStore.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptHeaderDiagnosticsProvider.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptHeaderHovers.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptLinkDiagnosticsProvider.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/headerBase.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/metadata/applyTo.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/metadata/base/enum.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/metadata/base/string.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/metadata/tools.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/promptHeader/promptHeader.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/parsers/topError.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/common/tools/languageModelToolsContribution.js +27 -27
- package/vscode/src/vs/workbench/contrib/chat/common/voiceChatService.js +1 -1
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.js +4 -4
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.js +24 -24
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatCurrentLine.js +8 -8
- package/vscode/src/vs/workbench/contrib/remoteCodingAgents/browser/remoteCodingAgents.contribution.js +7 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.js +16 -16
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.js +12 -12
- package/vscode/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/bufferOutputPolling.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/getTerminalOutputTool.js +3 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalTool.js +4 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/task/createAndRunTaskTool.js +16 -16
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/task/getTaskOutputTool.js +7 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/task/runTaskTool.js +14 -14
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/task.chatAgentTools.contribution.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/terminal.chatAgentTools.contribution.js +1 -1
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.js
CHANGED
|
@@ -32,7 +32,7 @@ class AttachInstructionsAction extends Action2 {
|
|
|
32
32
|
constructor() {
|
|
33
33
|
super({
|
|
34
34
|
id: ATTACH_INSTRUCTIONS_ACTION_ID,
|
|
35
|
-
title: ( localize2(
|
|
35
|
+
title: ( localize2(5242, "Attach Instructions...")),
|
|
36
36
|
f1: false,
|
|
37
37
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
38
38
|
category: CHAT_CATEGORY,
|
|
@@ -66,7 +66,7 @@ class AttachInstructionsAction extends Action2 {
|
|
|
66
66
|
widget.focusInput();
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
const placeholder = ( localize(
|
|
69
|
+
const placeholder = ( localize(5243, 'Select instructions files to attach'));
|
|
70
70
|
const result = await pickers.selectPromptFile({ resource, placeholder, type: PromptsType.instructions });
|
|
71
71
|
if (result !== undefined) {
|
|
72
72
|
widget.attachmentModel.addContext(toPromptFileVariableEntry(result.promptFile, PromptFileVariableKind.Instruction));
|
|
@@ -78,8 +78,8 @@ class ManageInstructionsFilesAction extends Action2 {
|
|
|
78
78
|
constructor() {
|
|
79
79
|
super({
|
|
80
80
|
id: CONFIGURE_INSTRUCTIONS_ACTION_ID,
|
|
81
|
-
title: ( localize2(
|
|
82
|
-
shortTitle: ( localize2(
|
|
81
|
+
title: ( localize2(5244, "Configure Instructions...")),
|
|
82
|
+
shortTitle: ( localize2(5245, "Instructions")),
|
|
83
83
|
icon: Codicon.bookmark,
|
|
84
84
|
f1: true,
|
|
85
85
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
@@ -96,7 +96,7 @@ class ManageInstructionsFilesAction extends Action2 {
|
|
|
96
96
|
const openerService = accessor.get(IOpenerService);
|
|
97
97
|
const instaService = accessor.get(IInstantiationService);
|
|
98
98
|
const pickers = instaService.createInstance(PromptFilePickers);
|
|
99
|
-
const placeholder = ( localize(
|
|
99
|
+
const placeholder = ( localize(5246, 'Select the instructions file to open'));
|
|
100
100
|
const result = await pickers.selectPromptFile({ placeholder, type: PromptsType.instructions, optionEdit: false });
|
|
101
101
|
if (result !== undefined) {
|
|
102
102
|
await openerService.open(result.promptFile);
|
|
@@ -132,7 +132,7 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
132
132
|
this.labelService = labelService;
|
|
133
133
|
this.configurationService = configurationService;
|
|
134
134
|
this.type = 'pickerPick';
|
|
135
|
-
this.label = ( localize(
|
|
135
|
+
this.label = ( localize(5247, 'Instructions...'));
|
|
136
136
|
this.icon = Codicon.bookmark;
|
|
137
137
|
this.commandId = ATTACH_INSTRUCTIONS_ACTION_ID;
|
|
138
138
|
}
|
|
@@ -150,7 +150,7 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
150
150
|
result.push({
|
|
151
151
|
type: 'separator',
|
|
152
152
|
label: storage === 'user'
|
|
153
|
-
? ( localize(
|
|
153
|
+
? ( localize(5248, 'User data folder'))
|
|
154
154
|
: this.labelService.getUriLabel(dirname(uri), { relative: true })
|
|
155
155
|
});
|
|
156
156
|
}
|
|
@@ -164,10 +164,10 @@ let ChatInstructionsPickerPick = class ChatInstructionsPickerPick {
|
|
|
164
164
|
return result;
|
|
165
165
|
});
|
|
166
166
|
return {
|
|
167
|
-
placeholder: ( localize(
|
|
167
|
+
placeholder: ( localize(5249, 'Select instructions files to attach')),
|
|
168
168
|
picks,
|
|
169
169
|
configure: {
|
|
170
|
-
label: ( localize(
|
|
170
|
+
label: ( localize(5250, 'Configure Instructions...')),
|
|
171
171
|
commandId: CONFIGURE_INSTRUCTIONS_ACTION_ID
|
|
172
172
|
}
|
|
173
173
|
};
|
|
@@ -17,7 +17,7 @@ class ConfigModeActionImpl extends Action2 {
|
|
|
17
17
|
const openerService = accessor.get(IOpenerService);
|
|
18
18
|
const instaService = accessor.get(IInstantiationService);
|
|
19
19
|
const pickers = instaService.createInstance(PromptFilePickers);
|
|
20
|
-
const placeholder = ( localize(
|
|
20
|
+
const placeholder = ( localize(5251, 'Select the chat mode file to open'));
|
|
21
21
|
const result = await pickers.selectPromptFile({ placeholder, type: PromptsType.mode, optionEdit: false });
|
|
22
22
|
if (result !== undefined) {
|
|
23
23
|
await openerService.open(result.promptFile);
|
|
@@ -29,7 +29,7 @@ class PickerConfigModeAction extends ConfigModeActionImpl {
|
|
|
29
29
|
constructor() {
|
|
30
30
|
super({
|
|
31
31
|
id: PICKER_CONFIGURE_MODES_ACTION_ID,
|
|
32
|
-
title: ( localize2(
|
|
32
|
+
title: ( localize2(5252, "Configure Modes...")),
|
|
33
33
|
category: CHAT_CATEGORY,
|
|
34
34
|
f1: false,
|
|
35
35
|
menu: {
|
|
@@ -43,8 +43,8 @@ class ManageModeAction extends ConfigModeActionImpl {
|
|
|
43
43
|
constructor() {
|
|
44
44
|
super({
|
|
45
45
|
id: CONFIGURE_MODES_ACTION_ID,
|
|
46
|
-
title: ( localize2(
|
|
47
|
-
shortTitle: ( localize(
|
|
46
|
+
title: ( localize2(5253, "Configure Chat Modes...")),
|
|
47
|
+
shortTitle: ( localize(5254, "Modes")),
|
|
48
48
|
icon: Codicon.bookmark,
|
|
49
49
|
f1: true,
|
|
50
50
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
@@ -83,11 +83,11 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
notificationService.prompt(Severity.Info, ( localize(
|
|
86
|
-
|
|
86
|
+
5255,
|
|
87
87
|
"Do you want to backup and sync your user prompt, instruction and mode files with Setting Sync?'"
|
|
88
88
|
)), [
|
|
89
89
|
{
|
|
90
|
-
label: ( localize(
|
|
90
|
+
label: ( localize(5256, "Enable")),
|
|
91
91
|
run: () => {
|
|
92
92
|
commandService.executeCommand(CONFIGURE_SYNC_COMMAND_ID)
|
|
93
93
|
.catch((error) => {
|
|
@@ -96,7 +96,7 @@ class AbstractNewPromptFileAction extends Action2 {
|
|
|
96
96
|
},
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
|
-
label: ( localize(
|
|
99
|
+
label: ( localize(5257, "Learn More")),
|
|
100
100
|
run: () => {
|
|
101
101
|
openerService.open(( URI.parse('https://aka.ms/vscode-settings-sync-help')));
|
|
102
102
|
},
|
|
@@ -142,24 +142,24 @@ const NEW_INSTRUCTIONS_COMMAND_ID = 'workbench.command.new.instructions';
|
|
|
142
142
|
const NEW_MODE_COMMAND_ID = 'workbench.command.new.mode';
|
|
143
143
|
class NewPromptFileAction extends AbstractNewPromptFileAction {
|
|
144
144
|
constructor() {
|
|
145
|
-
super(NEW_PROMPT_COMMAND_ID, ( localize(
|
|
145
|
+
super(NEW_PROMPT_COMMAND_ID, ( localize(5258, "New Prompt File...")), PromptsType.prompt);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
class NewInstructionsFileAction extends AbstractNewPromptFileAction {
|
|
149
149
|
constructor() {
|
|
150
|
-
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(
|
|
150
|
+
super(NEW_INSTRUCTIONS_COMMAND_ID, ( localize(5259, "New Instructions File...")), PromptsType.instructions);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
class NewModeFileAction extends AbstractNewPromptFileAction {
|
|
154
154
|
constructor() {
|
|
155
|
-
super(NEW_MODE_COMMAND_ID, ( localize(
|
|
155
|
+
super(NEW_MODE_COMMAND_ID, ( localize(5260, "New Mode File...")), PromptsType.mode);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
class NewUntitledPromptFileAction extends Action2 {
|
|
159
159
|
constructor() {
|
|
160
160
|
super({
|
|
161
161
|
id: 'workbench.command.new.untitled.prompt',
|
|
162
|
-
title: ( localize2(
|
|
162
|
+
title: ( localize2(5261, "New Untitled Prompt File")),
|
|
163
163
|
f1: true,
|
|
164
164
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
165
165
|
category: CHAT_CATEGORY,
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.js
CHANGED
|
@@ -25,20 +25,20 @@ async function askForPromptFileName(accessor, type, selectedFolder, existingFile
|
|
|
25
25
|
const fileName = sanitizeInput(value);
|
|
26
26
|
if (!fileName) {
|
|
27
27
|
return {
|
|
28
|
-
content: ( localize(
|
|
28
|
+
content: ( localize(5262, "Please enter a name.")),
|
|
29
29
|
severity: Severity.Warning
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
if (!isValidBasename(fileName)) {
|
|
33
33
|
return {
|
|
34
|
-
content: ( localize(
|
|
34
|
+
content: ( localize(5263, "The name contains invalid characters.")),
|
|
35
35
|
severity: Severity.Error
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
const fileUri = URI.joinPath(selectedFolder, fileName);
|
|
39
39
|
if (await fileService.exists(fileUri)) {
|
|
40
40
|
return {
|
|
41
|
-
content: ( localize(
|
|
41
|
+
content: ( localize(5264, "A file for the given name already exists.")),
|
|
42
42
|
severity: Severity.Error
|
|
43
43
|
};
|
|
44
44
|
}
|
|
@@ -54,11 +54,11 @@ async function askForPromptFileName(accessor, type, selectedFolder, existingFile
|
|
|
54
54
|
function getPlaceholderStringForNew(type) {
|
|
55
55
|
switch (type) {
|
|
56
56
|
case PromptsType.instructions:
|
|
57
|
-
return localize(
|
|
57
|
+
return localize(5265, "Enter the name of the instructions file");
|
|
58
58
|
case PromptsType.prompt:
|
|
59
|
-
return localize(
|
|
59
|
+
return localize(5266, "Enter the name of the prompt file");
|
|
60
60
|
case PromptsType.mode:
|
|
61
|
-
return localize(
|
|
61
|
+
return localize(5267, "Enter the name of the custom chat mode file");
|
|
62
62
|
default:
|
|
63
63
|
throw ( new Error('Unknown prompt type'));
|
|
64
64
|
}
|
|
@@ -66,11 +66,11 @@ function getPlaceholderStringForNew(type) {
|
|
|
66
66
|
function getPlaceholderStringForRename(type) {
|
|
67
67
|
switch (type) {
|
|
68
68
|
case PromptsType.instructions:
|
|
69
|
-
return localize(
|
|
69
|
+
return localize(5268, "Enter a new name of the instructions file");
|
|
70
70
|
case PromptsType.prompt:
|
|
71
|
-
return localize(
|
|
71
|
+
return localize(5269, "Enter a new name of the prompt file");
|
|
72
72
|
case PromptsType.mode:
|
|
73
|
-
return localize(
|
|
73
|
+
return localize(5270, "Enter a new name of the custom chat mode file");
|
|
74
74
|
default:
|
|
75
75
|
throw ( new Error('Unknown prompt type'));
|
|
76
76
|
}
|
|
@@ -26,11 +26,11 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
26
26
|
};
|
|
27
27
|
const foldersList = ( folders.map(folder => {
|
|
28
28
|
const uri = folder.uri;
|
|
29
|
-
const detail = (existingFolder && isEqual(uri, existingFolder)) ? ( localize(
|
|
29
|
+
const detail = (existingFolder && isEqual(uri, existingFolder)) ? ( localize(5271, "Current Location")) : undefined;
|
|
30
30
|
if (folder.storage === 'user') {
|
|
31
31
|
return {
|
|
32
32
|
type: 'item',
|
|
33
|
-
label: ( localize(
|
|
33
|
+
label: ( localize(5272, "User Data Folder")),
|
|
34
34
|
detail,
|
|
35
35
|
tooltip: labelService.getUriLabel(uri),
|
|
36
36
|
folder
|
|
@@ -50,7 +50,7 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
50
50
|
}
|
|
51
51
|
return {
|
|
52
52
|
type: 'item',
|
|
53
|
-
label: ( localize(
|
|
53
|
+
label: ( localize(5273, "Current Workspace")),
|
|
54
54
|
detail,
|
|
55
55
|
tooltip: labelService.getUriLabel(uri),
|
|
56
56
|
folder,
|
|
@@ -65,11 +65,11 @@ async function askForPromptSourceFolder(accessor, type, existingFolder, isMove =
|
|
|
65
65
|
function getPlaceholderStringforNew(type) {
|
|
66
66
|
switch (type) {
|
|
67
67
|
case PromptsType.instructions:
|
|
68
|
-
return localize(
|
|
68
|
+
return localize(5274, "Select a location to create the instructions file in...");
|
|
69
69
|
case PromptsType.prompt:
|
|
70
|
-
return localize(
|
|
70
|
+
return localize(5275, "Select a location to create the prompt file in...");
|
|
71
71
|
case PromptsType.mode:
|
|
72
|
-
return localize(
|
|
72
|
+
return localize(5276, "Select a location to create the mode file in...");
|
|
73
73
|
default:
|
|
74
74
|
throw ( new Error('Unknown prompt type'));
|
|
75
75
|
}
|
|
@@ -78,22 +78,22 @@ function getPlaceholderStringforMove(type, isMove) {
|
|
|
78
78
|
if (isMove) {
|
|
79
79
|
switch (type) {
|
|
80
80
|
case PromptsType.instructions:
|
|
81
|
-
return localize(
|
|
81
|
+
return localize(5277, "Select a location to move the instructions file to...");
|
|
82
82
|
case PromptsType.prompt:
|
|
83
|
-
return localize(
|
|
83
|
+
return localize(5278, "Select a location to move the prompt file to...");
|
|
84
84
|
case PromptsType.mode:
|
|
85
|
-
return localize(
|
|
85
|
+
return localize(5279, "Select a location to move the mode file to...");
|
|
86
86
|
default:
|
|
87
87
|
throw ( new Error('Unknown prompt type'));
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
switch (type) {
|
|
91
91
|
case PromptsType.instructions:
|
|
92
|
-
return localize(
|
|
92
|
+
return localize(5280, "Select a location to copy the instructions file to...");
|
|
93
93
|
case PromptsType.prompt:
|
|
94
|
-
return localize(
|
|
94
|
+
return localize(5281, "Select a location to copy the prompt file to...");
|
|
95
95
|
case PromptsType.mode:
|
|
96
|
-
return localize(
|
|
96
|
+
return localize(5282, "Select a location to copy the mode file to...");
|
|
97
97
|
default:
|
|
98
98
|
throw ( new Error('Unknown prompt type'));
|
|
99
99
|
}
|
|
@@ -119,11 +119,11 @@ async function showNoFoldersDialog(accessor, type) {
|
|
|
119
119
|
function getLearnLabel(type) {
|
|
120
120
|
switch (type) {
|
|
121
121
|
case PromptsType.prompt:
|
|
122
|
-
return localize(
|
|
122
|
+
return localize(5283, 'Learn how to configure reusable prompts');
|
|
123
123
|
case PromptsType.instructions:
|
|
124
|
-
return localize(
|
|
124
|
+
return localize(5284, 'Learn how to configure reusable instructions');
|
|
125
125
|
case PromptsType.mode:
|
|
126
|
-
return localize(
|
|
126
|
+
return localize(5285, 'Learn how to configure custom chat modes');
|
|
127
127
|
default:
|
|
128
128
|
throw ( new Error('Unknown prompt type'));
|
|
129
129
|
}
|
|
@@ -131,11 +131,11 @@ function getLearnLabel(type) {
|
|
|
131
131
|
function getMissingSourceFolderString(type) {
|
|
132
132
|
switch (type) {
|
|
133
133
|
case PromptsType.instructions:
|
|
134
|
-
return localize(
|
|
134
|
+
return localize(5286, 'No instruction source folders found.');
|
|
135
135
|
case PromptsType.prompt:
|
|
136
|
-
return localize(
|
|
136
|
+
return localize(5287, 'No prompt source folders found.');
|
|
137
137
|
case PromptsType.mode:
|
|
138
|
-
return localize(
|
|
138
|
+
return localize(5288, 'No custom chat mode source folders found.');
|
|
139
139
|
default:
|
|
140
140
|
throw ( new Error('Unknown prompt type'));
|
|
141
141
|
}
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.js
CHANGED
|
@@ -25,12 +25,12 @@ import { OS } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform'
|
|
|
25
25
|
import { askForPromptSourceFolder } from './askForPromptSourceFolder.js';
|
|
26
26
|
|
|
27
27
|
const HELP_BUTTON = ( Object.freeze({
|
|
28
|
-
tooltip: ( localize(
|
|
28
|
+
tooltip: ( localize(5289, "Help")),
|
|
29
29
|
iconClass: ThemeIcon.asClassName(Codicon.question),
|
|
30
30
|
}));
|
|
31
31
|
const NEW_PROMPT_FILE_OPTION = ( Object.freeze({
|
|
32
32
|
type: 'item',
|
|
33
|
-
label: `$(plus) ${( localize(
|
|
33
|
+
label: `$(plus) ${( localize(5290, 'New prompt file...'))}`,
|
|
34
34
|
value: ( URI.parse(PROMPT_DOCUMENTATION_URL)),
|
|
35
35
|
pickable: false,
|
|
36
36
|
alwaysShow: true,
|
|
@@ -39,7 +39,7 @@ const NEW_PROMPT_FILE_OPTION = ( Object.freeze({
|
|
|
39
39
|
}));
|
|
40
40
|
const NEW_INSTRUCTIONS_FILE_OPTION = ( Object.freeze({
|
|
41
41
|
type: 'item',
|
|
42
|
-
label: `$(plus) ${( localize(
|
|
42
|
+
label: `$(plus) ${( localize(5291, 'New instruction file...'))}`,
|
|
43
43
|
value: ( URI.parse(INSTRUCTIONS_DOCUMENTATION_URL)),
|
|
44
44
|
pickable: false,
|
|
45
45
|
alwaysShow: true,
|
|
@@ -48,7 +48,7 @@ const NEW_INSTRUCTIONS_FILE_OPTION = ( Object.freeze({
|
|
|
48
48
|
}));
|
|
49
49
|
const UPDATE_INSTRUCTIONS_OPTION = ( Object.freeze({
|
|
50
50
|
type: 'item',
|
|
51
|
-
label: `$(refresh) ${( localize(
|
|
51
|
+
label: `$(refresh) ${( localize(5292, 'Generate instructions...'))}`,
|
|
52
52
|
value: ( URI.parse(INSTRUCTIONS_DOCUMENTATION_URL)),
|
|
53
53
|
pickable: false,
|
|
54
54
|
alwaysShow: true,
|
|
@@ -57,7 +57,7 @@ const UPDATE_INSTRUCTIONS_OPTION = ( Object.freeze({
|
|
|
57
57
|
}));
|
|
58
58
|
const NEW_MODE_FILE_OPTION = ( Object.freeze({
|
|
59
59
|
type: 'item',
|
|
60
|
-
label: `$(plus) ${( localize(
|
|
60
|
+
label: `$(plus) ${( localize(5293, 'Create new custom chat mode file...'))}`,
|
|
61
61
|
value: ( URI.parse(MODE_DOCUMENTATION_URL)),
|
|
62
62
|
pickable: false,
|
|
63
63
|
alwaysShow: true,
|
|
@@ -65,20 +65,20 @@ const NEW_MODE_FILE_OPTION = ( Object.freeze({
|
|
|
65
65
|
commandId: NEW_MODE_COMMAND_ID,
|
|
66
66
|
}));
|
|
67
67
|
const EDIT_BUTTON = ( Object.freeze({
|
|
68
|
-
tooltip: ( localize(
|
|
68
|
+
tooltip: ( localize(5294, "Open in Editor")),
|
|
69
69
|
iconClass: ThemeIcon.asClassName(Codicon.edit),
|
|
70
70
|
}));
|
|
71
71
|
const DELETE_BUTTON = ( Object.freeze({
|
|
72
|
-
tooltip: ( localize(
|
|
72
|
+
tooltip: ( localize(5295, "Delete")),
|
|
73
73
|
iconClass: ThemeIcon.asClassName(Codicon.trash),
|
|
74
74
|
}));
|
|
75
75
|
const RENAME_BUTTON = ( Object.freeze({
|
|
76
|
-
tooltip: ( localize(
|
|
76
|
+
tooltip: ( localize(5296, "Rename")),
|
|
77
77
|
iconClass: ThemeIcon.asClassName(Codicon.replace),
|
|
78
78
|
}));
|
|
79
79
|
const COPY_BUTTON = ( Object.freeze({
|
|
80
80
|
tooltip: ( localize(
|
|
81
|
-
|
|
81
|
+
5297,
|
|
82
82
|
"Copy or Move (press {0})",
|
|
83
83
|
UILabelProvider.modifierLabels[OS].ctrlKey
|
|
84
84
|
)),
|
|
@@ -98,7 +98,7 @@ let PromptFilePickers = class PromptFilePickers {
|
|
|
98
98
|
async selectPromptFile(options) {
|
|
99
99
|
const quickPick = this._quickInputService.createQuickPick();
|
|
100
100
|
quickPick.busy = true;
|
|
101
|
-
quickPick.placeholder = ( localize(
|
|
101
|
+
quickPick.placeholder = ( localize(5298, 'Searching file system...'));
|
|
102
102
|
try {
|
|
103
103
|
const fileOptions = await this._createPromptPickItems(options);
|
|
104
104
|
const activeItem = options.resource && fileOptions.find(f => extUri.isEqual(f.value, options.resource));
|
|
@@ -208,7 +208,7 @@ let PromptFilePickers = class PromptFilePickers {
|
|
|
208
208
|
const { uri, storage } = promptFile;
|
|
209
209
|
const fileWithoutExtension = getCleanPromptName(uri);
|
|
210
210
|
const description = (storage === 'user')
|
|
211
|
-
? ( localize(
|
|
211
|
+
? ( localize(5299, 'User data folder'))
|
|
212
212
|
: this._labelService.getUriLabel(dirname(uri), { relative: true });
|
|
213
213
|
const tooltip = (storage === 'user')
|
|
214
214
|
? description
|
|
@@ -279,7 +279,7 @@ let PromptFilePickers = class PromptFilePickers {
|
|
|
279
279
|
await this.keepQuickPickOpen(quickPick, async () => {
|
|
280
280
|
const filename = getCleanPromptName(value);
|
|
281
281
|
const { confirmed } = await this._dialogService.confirm({
|
|
282
|
-
message: ( localize(
|
|
282
|
+
message: ( localize(5300, "Are you sure you want to delete '{0}'?", filename)),
|
|
283
283
|
});
|
|
284
284
|
if (!confirmed) {
|
|
285
285
|
return;
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptCodingAgentActionOverlay.js
CHANGED
|
@@ -26,11 +26,11 @@ let PromptCodingAgentActionOverlayWidget = class PromptCodingAgentActionOverlayW
|
|
|
26
26
|
this._domNode = $('.prompt-coding-agent-action-overlay');
|
|
27
27
|
this._button = this._register(( new Button(this._domNode, {
|
|
28
28
|
supportIcons: true,
|
|
29
|
-
title: ( localize(
|
|
29
|
+
title: ( localize(5301, "Run prompt file in a remote coding agent"))
|
|
30
30
|
})));
|
|
31
31
|
this._button.element.style.background = 'var(--vscode-button-background)';
|
|
32
32
|
this._button.element.style.color = 'var(--vscode-button-foreground)';
|
|
33
|
-
this._button.label = ( localize(
|
|
33
|
+
this._button.label = ( localize(5302, "{0} Delegate to Copilot coding agent", '$(cloud-upload)'));
|
|
34
34
|
this._register(this._button.onDidClick(async () => {
|
|
35
35
|
await this._execute();
|
|
36
36
|
}));
|
package/vscode/src/vs/workbench/contrib/chat/browser/promptSyntax/promptToolsCodeLensProvider.js
CHANGED
|
@@ -52,7 +52,7 @@ let PromptToolsCodeLensProvider = class PromptToolsCodeLensProvider extends Disp
|
|
|
52
52
|
const codeLens = {
|
|
53
53
|
range: tools.range.collapseToStart(),
|
|
54
54
|
command: {
|
|
55
|
-
title: ( localize(
|
|
55
|
+
title: ( localize(5303, "Configure Tools...")),
|
|
56
56
|
id: this.cmdId,
|
|
57
57
|
arguments: [model, tools]
|
|
58
58
|
}
|
|
@@ -61,7 +61,7 @@ let PromptToolsCodeLensProvider = class PromptToolsCodeLensProvider extends Disp
|
|
|
61
61
|
}
|
|
62
62
|
async updateTools(model, tools) {
|
|
63
63
|
const selectedToolsNow = tools.value ? this.languageModelToolsService.toToolAndToolSetEnablementMap(tools.value) : ( new Map());
|
|
64
|
-
const newSelectedAfter = await this.instantiationService.invokeFunction(showToolsPicker, ( localize(
|
|
64
|
+
const newSelectedAfter = await this.instantiationService.invokeFunction(showToolsPicker, ( localize(5304, "Select tools")), undefined, selectedToolsNow);
|
|
65
65
|
if (!newSelectedAfter) {
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
@@ -69,7 +69,7 @@ let PromptUrlHandler = class PromptUrlHandler extends Disposable {
|
|
|
69
69
|
const result = await this.requestService.request({ type: 'GET', url: urlString }, CancellationToken.None);
|
|
70
70
|
if (result.res.statusCode !== 200) {
|
|
71
71
|
this.logService.error(`[PromptUrlHandler] Failed to fetch URL: ${urlString}`);
|
|
72
|
-
this.notificationService.error(( localize(
|
|
72
|
+
this.notificationService.error(( localize(5305, 'Failed to fetch URL: {0}', urlString)));
|
|
73
73
|
return true;
|
|
74
74
|
}
|
|
75
75
|
const responseData = ( (await streamToBuffer(result.stream)).toString());
|
|
@@ -98,36 +98,36 @@ let PromptUrlHandler = class PromptUrlHandler extends Disposable {
|
|
|
98
98
|
uriLabel = `${uriLabel.substring(0, 35)}...${uriLabel.substring(uriLabel.length - 15)}`;
|
|
99
99
|
}
|
|
100
100
|
const detail = ( new MarkdownString('', { supportHtml: true }));
|
|
101
|
-
detail.appendMarkdown(( localize(
|
|
101
|
+
detail.appendMarkdown(( localize(5306, "This will access {0}.\n\n", `[${uriLabel}](${( url.toString())})`)));
|
|
102
102
|
detail.appendMarkdown(( localize(
|
|
103
|
-
|
|
103
|
+
5307,
|
|
104
104
|
"If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"
|
|
105
105
|
)));
|
|
106
106
|
let message;
|
|
107
107
|
switch (promptType) {
|
|
108
108
|
case PromptsType.prompt:
|
|
109
109
|
message = ( localize(
|
|
110
|
-
|
|
110
|
+
5308,
|
|
111
111
|
"An external application wants to create a prompt file with content from a URL. Do you want to continue by selecting a destination folder and name?"
|
|
112
112
|
));
|
|
113
113
|
break;
|
|
114
114
|
case PromptsType.instructions:
|
|
115
115
|
message = ( localize(
|
|
116
|
-
|
|
116
|
+
5309,
|
|
117
117
|
"An external application wants to create an instructions file with content from a URL. Do you want to continue by selecting a destination folder and name?"
|
|
118
118
|
));
|
|
119
119
|
break;
|
|
120
120
|
default:
|
|
121
121
|
message = ( localize(
|
|
122
|
-
|
|
122
|
+
5310,
|
|
123
123
|
"An external application wants to create a chat mode with content from a URL. Do you want to continue by selecting a destination folder and name?"
|
|
124
124
|
));
|
|
125
125
|
break;
|
|
126
126
|
}
|
|
127
127
|
const { confirmed } = await this.dialogService.confirm({
|
|
128
128
|
type: 'warning',
|
|
129
|
-
primaryButton: ( localize(
|
|
130
|
-
cancelButton: ( localize(
|
|
129
|
+
primaryButton: ( localize(5311, "&&Yes")),
|
|
130
|
+
cancelButton: ( localize(5312, "No")),
|
|
131
131
|
message,
|
|
132
132
|
custom: {
|
|
133
133
|
markdownDetails: [{
|
|
@@ -69,7 +69,7 @@ class RunPromptBaseAction extends Action2 {
|
|
|
69
69
|
return widget;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
const RUN_CURRENT_PROMPT_ACTION_TITLE = ( localize2(
|
|
72
|
+
const RUN_CURRENT_PROMPT_ACTION_TITLE = ( localize2(5313, "Run Prompt in Current Chat"));
|
|
73
73
|
const RUN_CURRENT_PROMPT_ACTION_ICON = Codicon.playCircle;
|
|
74
74
|
class RunCurrentPromptAction extends RunPromptBaseAction {
|
|
75
75
|
constructor() {
|
|
@@ -88,7 +88,7 @@ class RunSelectedPromptAction extends Action2 {
|
|
|
88
88
|
constructor() {
|
|
89
89
|
super({
|
|
90
90
|
id: RUN_SELECTED_PROMPT_ACTION_ID,
|
|
91
|
-
title: ( localize2(
|
|
91
|
+
title: ( localize2(5314, "Run Prompt...")),
|
|
92
92
|
icon: Codicon.bookmark,
|
|
93
93
|
f1: true,
|
|
94
94
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
@@ -106,7 +106,7 @@ class RunSelectedPromptAction extends Action2 {
|
|
|
106
106
|
const instaService = accessor.get(IInstantiationService);
|
|
107
107
|
const pickers = instaService.createInstance(PromptFilePickers);
|
|
108
108
|
const placeholder = ( localize(
|
|
109
|
-
|
|
109
|
+
5315,
|
|
110
110
|
'Select the prompt file to run (hold {0}-key to use in new chat)',
|
|
111
111
|
UILabelProvider.modifierLabels[OS].ctrlKey
|
|
112
112
|
));
|
|
@@ -130,8 +130,8 @@ class ManagePromptFilesAction extends Action2 {
|
|
|
130
130
|
constructor() {
|
|
131
131
|
super({
|
|
132
132
|
id: CONFIGURE_PROMPTS_ACTION_ID,
|
|
133
|
-
title: ( localize2(
|
|
134
|
-
shortTitle: ( localize2(
|
|
133
|
+
title: ( localize2(5316, "Configure Prompt Files...")),
|
|
134
|
+
shortTitle: ( localize2(5317, "Prompt Files")),
|
|
135
135
|
icon: Codicon.bookmark,
|
|
136
136
|
f1: true,
|
|
137
137
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
@@ -148,7 +148,7 @@ class ManagePromptFilesAction extends Action2 {
|
|
|
148
148
|
const openerService = accessor.get(IOpenerService);
|
|
149
149
|
const instaService = accessor.get(IInstantiationService);
|
|
150
150
|
const pickers = instaService.createInstance(PromptFilePickers);
|
|
151
|
-
const placeholder = ( localize(
|
|
151
|
+
const placeholder = ( localize(5318, 'Select the prompt file to open'));
|
|
152
152
|
const result = await pickers.selectPromptFile({ placeholder, type: PromptsType.prompt, optionEdit: false });
|
|
153
153
|
if (result !== undefined) {
|
|
154
154
|
await openerService.open(result.promptFile);
|
|
@@ -164,7 +164,7 @@ function getActivePromptFileUri(accessor) {
|
|
|
164
164
|
return undefined;
|
|
165
165
|
}
|
|
166
166
|
const RUN_CURRENT_PROMPT_IN_NEW_CHAT_ACTION_ID = 'workbench.action.chat.run-in-new-chat.prompt.current';
|
|
167
|
-
const RUN_IN_NEW_CHAT_ACTION_TITLE = ( localize2(
|
|
167
|
+
const RUN_IN_NEW_CHAT_ACTION_TITLE = ( localize2(5319, "Run Prompt In New Chat"));
|
|
168
168
|
const RUN_IN_NEW_CHAT_ACTION_ICON = Codicon.play;
|
|
169
169
|
class RunCurrentPromptInNewChatAction extends RunPromptBaseAction {
|
|
170
170
|
constructor() {
|
|
@@ -22,7 +22,7 @@ class SaveToPromptAction extends Action2 {
|
|
|
22
22
|
constructor() {
|
|
23
23
|
super({
|
|
24
24
|
id: SAVE_TO_PROMPT_ACTION_ID,
|
|
25
|
-
title: ( localize2(
|
|
25
|
+
title: ( localize2(5320, "Save chat session to a prompt file")),
|
|
26
26
|
f1: false,
|
|
27
27
|
precondition: ( ContextKeyExpr.and(PromptsConfig.enabledCtx, ChatContextKeys.enabled)),
|
|
28
28
|
category: CHAT_CATEGORY,
|
|
@@ -44,11 +44,11 @@ const toolSetsSchema = {
|
|
|
44
44
|
allowComments: true,
|
|
45
45
|
allowTrailingCommas: true,
|
|
46
46
|
defaultSnippets: [{
|
|
47
|
-
label: ( localize(
|
|
47
|
+
label: ( localize(5321, "Empty tool set")),
|
|
48
48
|
body: { '${1:toolSetName}': { 'tools': ['${2:someTool}', '${3:anotherTool}'], 'description': '${4:description}', 'icon': '${5:tools}' } }
|
|
49
49
|
}],
|
|
50
50
|
type: 'object',
|
|
51
|
-
description: ( localize(
|
|
51
|
+
description: ( localize(5322, 'User tool sets configuration')),
|
|
52
52
|
additionalProperties: {
|
|
53
53
|
type: 'object',
|
|
54
54
|
required: ['tools'],
|
|
@@ -56,7 +56,7 @@ const toolSetsSchema = {
|
|
|
56
56
|
properties: {
|
|
57
57
|
tools: {
|
|
58
58
|
description: ( localize(
|
|
59
|
-
|
|
59
|
+
5323,
|
|
60
60
|
"A list of tools or tool sets to include in this tool set. Cannot be empty and must reference tools the way they are referenced in prompts."
|
|
61
61
|
)),
|
|
62
62
|
type: 'array',
|
|
@@ -69,7 +69,7 @@ const toolSetsSchema = {
|
|
|
69
69
|
},
|
|
70
70
|
icon: {
|
|
71
71
|
description: ( localize(
|
|
72
|
-
|
|
72
|
+
5324,
|
|
73
73
|
"Icon to use for this tool set in the UI. Uses the `\\$(name)`-syntax, like `\\$(zap)`"
|
|
74
74
|
)),
|
|
75
75
|
type: 'string',
|
|
@@ -77,7 +77,7 @@ const toolSetsSchema = {
|
|
|
77
77
|
markdownEnumDescriptions: Array.from(getAllCodicons(), icon => `$(${icon.id})`),
|
|
78
78
|
},
|
|
79
79
|
description: {
|
|
80
|
-
description: ( localize(
|
|
80
|
+
description: ( localize(5325, "A short description of this tool set.")),
|
|
81
81
|
type: 'string'
|
|
82
82
|
},
|
|
83
83
|
},
|
|
@@ -164,7 +164,7 @@ let UserToolSetsContributions = class UserToolSetsContributions extends Disposab
|
|
|
164
164
|
});
|
|
165
165
|
for (const item of data) {
|
|
166
166
|
toolEnumValues.push(item.name);
|
|
167
|
-
toolEnumDescriptions.push(( localize(
|
|
167
|
+
toolEnumDescriptions.push(( localize(5326, "{1} ({0})\n\n{2}", item.sourceLabel, item.name, item.description)));
|
|
168
168
|
}
|
|
169
169
|
store.clear();
|
|
170
170
|
reg.registerSchema(toolSetSchemaId, toolSetsSchema, store);
|
|
@@ -257,8 +257,8 @@ class ConfigureToolSets extends Action2 {
|
|
|
257
257
|
constructor() {
|
|
258
258
|
super({
|
|
259
259
|
id: ConfigureToolSets.ID,
|
|
260
|
-
title: ( localize2(
|
|
261
|
-
shortTitle: ( localize(
|
|
260
|
+
title: ( localize2(5327, 'Configure Tool Sets...')),
|
|
261
|
+
shortTitle: ( localize(5328, "Tool Sets")),
|
|
262
262
|
category: CHAT_CATEGORY,
|
|
263
263
|
f1: true,
|
|
264
264
|
precondition: ( ContextKeyExpr.and(ChatContextKeys.enabled, ChatContextKeys.Tools.toolsCount.greater(0))),
|
|
@@ -279,7 +279,7 @@ class ConfigureToolSets extends Action2 {
|
|
|
279
279
|
const textFileService = accessor.get(ITextFileService);
|
|
280
280
|
const picks = [];
|
|
281
281
|
picks.push({
|
|
282
|
-
label: ( localize(
|
|
282
|
+
label: ( localize(5329, 'Create new tool sets file...')),
|
|
283
283
|
alwaysShow: true,
|
|
284
284
|
iconClass: ThemeIcon.asClassName(Codicon.plus)
|
|
285
285
|
});
|
|
@@ -296,7 +296,7 @@ class ConfigureToolSets extends Action2 {
|
|
|
296
296
|
}
|
|
297
297
|
const pick = await quickInputService.pick(picks, {
|
|
298
298
|
canPickMany: false,
|
|
299
|
-
placeHolder: ( localize(
|
|
299
|
+
placeHolder: ( localize(5330, 'Select a tool set to configure')),
|
|
300
300
|
});
|
|
301
301
|
if (!pick) {
|
|
302
302
|
return;
|
|
@@ -304,13 +304,13 @@ class ConfigureToolSets extends Action2 {
|
|
|
304
304
|
let resource;
|
|
305
305
|
if (!pick.toolset) {
|
|
306
306
|
const name = await quickInputService.input({
|
|
307
|
-
placeHolder: ( localize(
|
|
307
|
+
placeHolder: ( localize(5331, "Type tool sets file name")),
|
|
308
308
|
validateInput: async (input) => {
|
|
309
309
|
if (!input) {
|
|
310
|
-
return localize(
|
|
310
|
+
return localize(5332, "Invalid file name");
|
|
311
311
|
}
|
|
312
312
|
if (!isValidBasename(input)) {
|
|
313
|
-
return localize(
|
|
313
|
+
return localize(5333, "'{0}' is not a valid file name", input);
|
|
314
314
|
}
|
|
315
315
|
return undefined;
|
|
316
316
|
}
|