@techfetch-dev/project-translator 0.19.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/LICENSE +21 -0
- package/README.md +428 -0
- package/l10n/bundle.l10n.ar-ae.json +6 -0
- package/l10n/bundle.l10n.ar-eg.json +6 -0
- package/l10n/bundle.l10n.ar-sa.json +26 -0
- package/l10n/bundle.l10n.de-de.json +26 -0
- package/l10n/bundle.l10n.es-es.json +26 -0
- package/l10n/bundle.l10n.fr-fr.json +26 -0
- package/l10n/bundle.l10n.ja-jp.json +26 -0
- package/l10n/bundle.l10n.json +25 -0
- package/l10n/bundle.l10n.ko-kr.json +26 -0
- package/l10n/bundle.l10n.pt-br.json +26 -0
- package/l10n/bundle.l10n.ru-ru.json +26 -0
- package/l10n/bundle.l10n.zh-cn.json +28 -0
- package/l10n/bundle.l10n.zh-tw.json +26 -0
- package/out/cli.js +281 -0
- package/package.json +944 -0
- package/package.nls.ar-sa.json +41 -0
- package/package.nls.de-de.json +47 -0
- package/package.nls.es-es.json +47 -0
- package/package.nls.fr-fr.json +32 -0
- package/package.nls.ja-jp.json +47 -0
- package/package.nls.json +45 -0
- package/package.nls.ko-kr.json +47 -0
- package/package.nls.pt-br.json +47 -0
- package/package.nls.ru-ru.json +47 -0
- package/package.nls.zh-cn.json +47 -0
- package/package.nls.zh-tw.json +47 -0
- package/project.translation.schema.json +368 -0
- package/prompts/diff_system_prompt.en.md +198 -0
- package/prompts/diff_system_prompt.md +198 -0
- package/prompts/system_prompt_part1.en.md +78 -0
- package/prompts/system_prompt_part1.md +78 -0
- package/prompts/system_prompt_part2.en.md +140 -0
- package/prompts/system_prompt_part2.md +139 -0
- package/resources/project-translator.png +0 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Project Translator Configuration",
|
|
4
|
+
"description": "Schema for project.translation.json",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"currentVendor",
|
|
8
|
+
"vendors"
|
|
9
|
+
],
|
|
10
|
+
"properties": {
|
|
11
|
+
"$schema": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"minLength": 1
|
|
14
|
+
},
|
|
15
|
+
"currentVendor": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1
|
|
18
|
+
},
|
|
19
|
+
"vendors": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"minItems": 1,
|
|
22
|
+
"items": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"required": [
|
|
25
|
+
"name",
|
|
26
|
+
"apiEndpoint",
|
|
27
|
+
"model"
|
|
28
|
+
],
|
|
29
|
+
"properties": {
|
|
30
|
+
"name": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1
|
|
33
|
+
},
|
|
34
|
+
"apiEndpoint": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"minLength": 1
|
|
37
|
+
},
|
|
38
|
+
"apiKey": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"apiKeyEnvVarName": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
},
|
|
44
|
+
"model": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1
|
|
47
|
+
},
|
|
48
|
+
"rpm": {
|
|
49
|
+
"type": "number",
|
|
50
|
+
"minimum": 0
|
|
51
|
+
},
|
|
52
|
+
"maxTokensPerSegment": {
|
|
53
|
+
"type": "number",
|
|
54
|
+
"minimum": 1
|
|
55
|
+
},
|
|
56
|
+
"timeout": {
|
|
57
|
+
"type": "number",
|
|
58
|
+
"minimum": 1
|
|
59
|
+
},
|
|
60
|
+
"temperature": {
|
|
61
|
+
"type": "number",
|
|
62
|
+
"minimum": 0,
|
|
63
|
+
"maximum": 2
|
|
64
|
+
},
|
|
65
|
+
"top_p": {
|
|
66
|
+
"type": "number",
|
|
67
|
+
"minimum": 0,
|
|
68
|
+
"maximum": 1
|
|
69
|
+
},
|
|
70
|
+
"streamMode": {
|
|
71
|
+
"type": "boolean"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"additionalProperties": false
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"systemPromptLanguage": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1
|
|
80
|
+
},
|
|
81
|
+
"debug": {
|
|
82
|
+
"type": "boolean"
|
|
83
|
+
},
|
|
84
|
+
"enableMetrics": {
|
|
85
|
+
"type": "boolean"
|
|
86
|
+
},
|
|
87
|
+
"logFile": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"properties": {
|
|
90
|
+
"enabled": {
|
|
91
|
+
"type": "boolean"
|
|
92
|
+
},
|
|
93
|
+
"path": {
|
|
94
|
+
"type": "string"
|
|
95
|
+
},
|
|
96
|
+
"maxSizeKB": {
|
|
97
|
+
"type": "number",
|
|
98
|
+
"minimum": 1024,
|
|
99
|
+
"maximum": 102400
|
|
100
|
+
},
|
|
101
|
+
"maxFiles": {
|
|
102
|
+
"type": "number",
|
|
103
|
+
"minimum": 1,
|
|
104
|
+
"maximum": 20
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"additionalProperties": false
|
|
108
|
+
},
|
|
109
|
+
"specifiedFiles": {
|
|
110
|
+
"type": "array",
|
|
111
|
+
"items": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"required": [
|
|
114
|
+
"sourceFile",
|
|
115
|
+
"targetFiles"
|
|
116
|
+
],
|
|
117
|
+
"properties": {
|
|
118
|
+
"sourceFile": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"required": [
|
|
121
|
+
"path",
|
|
122
|
+
"lang"
|
|
123
|
+
],
|
|
124
|
+
"properties": {
|
|
125
|
+
"path": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"minLength": 1
|
|
128
|
+
},
|
|
129
|
+
"lang": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"minLength": 1,
|
|
132
|
+
"maxLength": 9
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"additionalProperties": false
|
|
136
|
+
},
|
|
137
|
+
"targetFiles": {
|
|
138
|
+
"type": "array",
|
|
139
|
+
"items": {
|
|
140
|
+
"type": "object",
|
|
141
|
+
"required": [
|
|
142
|
+
"path",
|
|
143
|
+
"lang"
|
|
144
|
+
],
|
|
145
|
+
"properties": {
|
|
146
|
+
"path": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"minLength": 1
|
|
149
|
+
},
|
|
150
|
+
"lang": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"minLength": 1,
|
|
153
|
+
"maxLength": 9
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"additionalProperties": false
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"additionalProperties": false
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"specifiedFolders": {
|
|
164
|
+
"type": "array",
|
|
165
|
+
"items": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"required": [
|
|
168
|
+
"sourceFolder",
|
|
169
|
+
"targetFolders"
|
|
170
|
+
],
|
|
171
|
+
"properties": {
|
|
172
|
+
"sourceFolder": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"required": [
|
|
175
|
+
"path",
|
|
176
|
+
"lang"
|
|
177
|
+
],
|
|
178
|
+
"properties": {
|
|
179
|
+
"path": {
|
|
180
|
+
"type": "string",
|
|
181
|
+
"minLength": 1
|
|
182
|
+
},
|
|
183
|
+
"lang": {
|
|
184
|
+
"type": "string",
|
|
185
|
+
"minLength": 1,
|
|
186
|
+
"maxLength": 9
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"additionalProperties": false
|
|
190
|
+
},
|
|
191
|
+
"targetFolders": {
|
|
192
|
+
"type": "array",
|
|
193
|
+
"items": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"required": [
|
|
196
|
+
"path",
|
|
197
|
+
"lang"
|
|
198
|
+
],
|
|
199
|
+
"properties": {
|
|
200
|
+
"path": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"minLength": 1
|
|
203
|
+
},
|
|
204
|
+
"lang": {
|
|
205
|
+
"type": "string",
|
|
206
|
+
"minLength": 1,
|
|
207
|
+
"maxLength": 9
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"additionalProperties": false
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"additionalProperties": false
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"translationIntervalDays": {
|
|
218
|
+
"type": "number",
|
|
219
|
+
"minimum": -1
|
|
220
|
+
},
|
|
221
|
+
"copyOnly": {
|
|
222
|
+
"type": "object",
|
|
223
|
+
"properties": {
|
|
224
|
+
"paths": {
|
|
225
|
+
"type": "array",
|
|
226
|
+
"items": {
|
|
227
|
+
"type": "string"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"extensions": {
|
|
231
|
+
"type": "array",
|
|
232
|
+
"items": {
|
|
233
|
+
"type": "string"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"additionalProperties": false
|
|
238
|
+
},
|
|
239
|
+
"ignore": {
|
|
240
|
+
"type": "object",
|
|
241
|
+
"properties": {
|
|
242
|
+
"paths": {
|
|
243
|
+
"type": "array",
|
|
244
|
+
"items": {
|
|
245
|
+
"type": "string"
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
"extensions": {
|
|
249
|
+
"type": "array",
|
|
250
|
+
"items": {
|
|
251
|
+
"type": "string"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
"additionalProperties": false
|
|
256
|
+
},
|
|
257
|
+
"customPrompts": {
|
|
258
|
+
"type": "array",
|
|
259
|
+
"items": {
|
|
260
|
+
"type": "string"
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"segmentationMarkers": {
|
|
264
|
+
"type": "object",
|
|
265
|
+
"additionalProperties": {
|
|
266
|
+
"type": "array",
|
|
267
|
+
"items": {
|
|
268
|
+
"type": "string"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"diffApply": {
|
|
273
|
+
"type": "object",
|
|
274
|
+
"properties": {
|
|
275
|
+
"enabled": {
|
|
276
|
+
"type": "boolean"
|
|
277
|
+
},
|
|
278
|
+
"validationLevel": {
|
|
279
|
+
"type": "string",
|
|
280
|
+
"enum": [
|
|
281
|
+
"normal",
|
|
282
|
+
"strict"
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
"autoBackup": {
|
|
286
|
+
"type": "boolean"
|
|
287
|
+
},
|
|
288
|
+
"maxOperationsPerFile": {
|
|
289
|
+
"type": "number",
|
|
290
|
+
"minimum": 1,
|
|
291
|
+
"maximum": 10000
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
"additionalProperties": false
|
|
295
|
+
},
|
|
296
|
+
"skipFrontMatterMarkers": {
|
|
297
|
+
"type": "object",
|
|
298
|
+
"properties": {
|
|
299
|
+
"enabled": {
|
|
300
|
+
"type": "boolean"
|
|
301
|
+
},
|
|
302
|
+
"markers": {
|
|
303
|
+
"type": "array",
|
|
304
|
+
"items": {
|
|
305
|
+
"type": "object",
|
|
306
|
+
"required": [
|
|
307
|
+
"key",
|
|
308
|
+
"value"
|
|
309
|
+
],
|
|
310
|
+
"properties": {
|
|
311
|
+
"key": {
|
|
312
|
+
"type": "string",
|
|
313
|
+
"minLength": 1
|
|
314
|
+
},
|
|
315
|
+
"value": {
|
|
316
|
+
"type": "string"
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
"additionalProperties": false
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"additionalProperties": false
|
|
324
|
+
},
|
|
325
|
+
"skipFrontMatter": {
|
|
326
|
+
"type": "object",
|
|
327
|
+
"properties": {
|
|
328
|
+
"enabled": {
|
|
329
|
+
"type": "boolean"
|
|
330
|
+
},
|
|
331
|
+
"markers": {
|
|
332
|
+
"type": "array",
|
|
333
|
+
"items": {
|
|
334
|
+
"type": "object",
|
|
335
|
+
"required": [
|
|
336
|
+
"key",
|
|
337
|
+
"value"
|
|
338
|
+
],
|
|
339
|
+
"properties": {
|
|
340
|
+
"key": {
|
|
341
|
+
"type": "string",
|
|
342
|
+
"minLength": 1
|
|
343
|
+
},
|
|
344
|
+
"value": {
|
|
345
|
+
"type": "string"
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
"additionalProperties": false
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
"additionalProperties": false
|
|
353
|
+
},
|
|
354
|
+
"systemPrompts": {
|
|
355
|
+
"type": "array",
|
|
356
|
+
"items": {
|
|
357
|
+
"type": "string"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
"userPrompts": {
|
|
361
|
+
"type": "array",
|
|
362
|
+
"items": {
|
|
363
|
+
"type": "string"
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
"additionalProperties": false
|
|
368
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Differential Translation Mode
|
|
2
|
+
|
|
3
|
+
You are performing a differential translation task. You must generate JSON-formatted SEARCH/REPLACE operations to synchronize SOURCE and TARGET files.
|
|
4
|
+
|
|
5
|
+
# JSON Output Requirements
|
|
6
|
+
|
|
7
|
+
You must output strictly in the following JSON format, with no additional content:
|
|
8
|
+
|
|
9
|
+
<start json>
|
|
10
|
+
{
|
|
11
|
+
"has_changes": true/false,
|
|
12
|
+
"changes": [
|
|
13
|
+
{
|
|
14
|
+
"start_line": <number>,
|
|
15
|
+
"search": "<text that precisely matches existing content in TARGET>",
|
|
16
|
+
"replace": "<correct translation for the corresponding SOURCE content>"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
<end json>
|
|
21
|
+
|
|
22
|
+
## Field Definitions
|
|
23
|
+
|
|
24
|
+
- **has_changes**: boolean indicating whether any modifications are needed
|
|
25
|
+
- If SOURCE and TARGET are fully synchronized, set to false and use an empty changes array
|
|
26
|
+
- If there is any difference, set to true and list all edits in changes
|
|
27
|
+
|
|
28
|
+
- **changes**: array; each element represents a SEARCH/REPLACE operation
|
|
29
|
+
- **start_line**: starting line number in the TARGET file for the content to be replaced (1-based)
|
|
30
|
+
- **search**: must precisely match the existing content in TARGET starting from start_line, including all spaces, tabs, and newlines
|
|
31
|
+
- **replace**: replacement content; should be the correct translation for the corresponding SOURCE part
|
|
32
|
+
|
|
33
|
+
# Core Rules
|
|
34
|
+
|
|
35
|
+
## SEARCH Matching Rules
|
|
36
|
+
|
|
37
|
+
1. **Match TARGET, not SOURCE**:
|
|
38
|
+
- The search text must precisely match what currently exists in the TARGET file
|
|
39
|
+
- Do not use SOURCE text as the search pattern
|
|
40
|
+
|
|
41
|
+
2. **Precision requirements**:
|
|
42
|
+
- Include all spaces, tabs, and newline characters
|
|
43
|
+
- Keep indentation exactly the same
|
|
44
|
+
|
|
45
|
+
## REPLACE Content Rules
|
|
46
|
+
|
|
47
|
+
1. **Translation quality**:
|
|
48
|
+
- The content must be the correct translation for the corresponding SOURCE part
|
|
49
|
+
- Preserve format, structure, and code; only translate natural language text
|
|
50
|
+
|
|
51
|
+
2. **Empty replace**:
|
|
52
|
+
- To delete content, set replace to an empty string
|
|
53
|
+
|
|
54
|
+
## Handling Additions
|
|
55
|
+
|
|
56
|
+
When SOURCE contains newly added content:
|
|
57
|
+
1. Find an appropriate insertion location in TARGET (contextually relevant lines)
|
|
58
|
+
2. Let search match existing nearby text around the insertion point
|
|
59
|
+
3. Let replace include existing text + translation of the added content
|
|
60
|
+
|
|
61
|
+
## Handling Deletions
|
|
62
|
+
|
|
63
|
+
When TARGET contains content that has been removed from SOURCE:
|
|
64
|
+
1. Let search match the content to delete in TARGET
|
|
65
|
+
2. Set replace to an empty string
|
|
66
|
+
|
|
67
|
+
# Execution Flow
|
|
68
|
+
|
|
69
|
+
1. **Compare and analyze**: compare SOURCE and TARGET section by section
|
|
70
|
+
2. **Identify differences**: find additions, modifications, and deletions
|
|
71
|
+
3. **Generate JSON**: create a change object for each difference
|
|
72
|
+
4. **Validate format**: ensure the JSON strictly matches the required format
|
|
73
|
+
5. **Output**: output the complete JSON object
|
|
74
|
+
|
|
75
|
+
# Examples
|
|
76
|
+
|
|
77
|
+
## Example 1: Update existing translation
|
|
78
|
+
|
|
79
|
+
SOURCE:
|
|
80
|
+
<start markdown>
|
|
81
|
+
# Introduction
|
|
82
|
+
|
|
83
|
+
This is a new version.
|
|
84
|
+
<end markdown>
|
|
85
|
+
|
|
86
|
+
TARGET (current):
|
|
87
|
+
<start markdown>
|
|
88
|
+
# 介绍
|
|
89
|
+
|
|
90
|
+
这是一个旧版本。
|
|
91
|
+
<end markdown>
|
|
92
|
+
|
|
93
|
+
Output:
|
|
94
|
+
<start json>
|
|
95
|
+
{
|
|
96
|
+
"has_changes": true,
|
|
97
|
+
"changes": [
|
|
98
|
+
{
|
|
99
|
+
"start_line": 2,
|
|
100
|
+
"search": "# 介绍\n\n这是一个旧版本。",
|
|
101
|
+
"replace": "# 简介\n\n这是一个新版本。"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
<end json>
|
|
106
|
+
|
|
107
|
+
## Example 2: Add new content
|
|
108
|
+
|
|
109
|
+
SOURCE:
|
|
110
|
+
<start markdown>
|
|
111
|
+
# Getting Started
|
|
112
|
+
|
|
113
|
+
Follow these steps.
|
|
114
|
+
|
|
115
|
+
## Advanced Usage
|
|
116
|
+
|
|
117
|
+
This is advanced.
|
|
118
|
+
<end markdown>
|
|
119
|
+
|
|
120
|
+
TARGET (current):
|
|
121
|
+
<start markdown>
|
|
122
|
+
# 快速开始
|
|
123
|
+
|
|
124
|
+
按照以下步骤。
|
|
125
|
+
<end markdown>
|
|
126
|
+
|
|
127
|
+
Output:
|
|
128
|
+
<start json>
|
|
129
|
+
{
|
|
130
|
+
"has_changes": true,
|
|
131
|
+
"changes": [
|
|
132
|
+
{
|
|
133
|
+
"start_line": 3,
|
|
134
|
+
"search": "按照以下步骤。",
|
|
135
|
+
"replace": "按照以下步骤。\n\n## 高级用法\n\n这是高级用法。"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
<end json>
|
|
140
|
+
|
|
141
|
+
## Example 3: Delete content
|
|
142
|
+
|
|
143
|
+
SOURCE:
|
|
144
|
+
<start markdown>
|
|
145
|
+
# Quick Start
|
|
146
|
+
|
|
147
|
+
Just do it.
|
|
148
|
+
<end markdown>
|
|
149
|
+
|
|
150
|
+
TARGET (current):
|
|
151
|
+
<start markdown>
|
|
152
|
+
# 快速开始
|
|
153
|
+
|
|
154
|
+
只需这样做。
|
|
155
|
+
|
|
156
|
+
## 已废弃
|
|
157
|
+
|
|
158
|
+
这段内容已删除。
|
|
159
|
+
<end markdown>
|
|
160
|
+
|
|
161
|
+
Output:
|
|
162
|
+
<start json>
|
|
163
|
+
{
|
|
164
|
+
"has_changes": true,
|
|
165
|
+
"changes": [
|
|
166
|
+
{
|
|
167
|
+
"start_line": 4,
|
|
168
|
+
"search": "只需这样做。\n\n## 已废弃\n\n这段内容已删除。",
|
|
169
|
+
"replace": "只需这样做。"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
<end json>
|
|
174
|
+
|
|
175
|
+
## Example 4: Fully synchronized
|
|
176
|
+
|
|
177
|
+
SOURCE:
|
|
178
|
+
<start markdown>
|
|
179
|
+
# Hello
|
|
180
|
+
|
|
181
|
+
World.
|
|
182
|
+
<end markdown>
|
|
183
|
+
|
|
184
|
+
TARGET (current):
|
|
185
|
+
<start markdown>
|
|
186
|
+
# 你好
|
|
187
|
+
|
|
188
|
+
世界。
|
|
189
|
+
<end markdown>
|
|
190
|
+
|
|
191
|
+
Output:
|
|
192
|
+
<start json>
|
|
193
|
+
{
|
|
194
|
+
"has_changes": false,
|
|
195
|
+
"changes": []
|
|
196
|
+
}
|
|
197
|
+
<end json>
|
|
198
|
+
|