@umituz/react-native-localization 1.5.6 ā 1.5.7
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 +2 -1
- package/scripts/prepublish.js +80 -0
- package/src/infrastructure/config/i18n.ts +3 -0
- package/src/infrastructure/locales/en-US/auth.json +2 -2
- package/src/infrastructure/locales/en-US/branding.json +1 -1
- package/src/infrastructure/locales/en-US/general.json +1 -5
- package/src/infrastructure/locales/en-US/index.ts +3 -1
- package/src/infrastructure/locales/en-US/navigation.json +4 -1
- package/src/infrastructure/locales/en-US/flashcards.json +0 -310
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-localization",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.7",
|
|
4
4
|
"description": "Universal localization system for React Native apps with i18n support",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"lint": "tsc --noEmit",
|
|
10
10
|
"locales:generate": "node scripts/createLocaleLoaders.js",
|
|
11
11
|
"locales:generate:lang": "node scripts/createLocaleLoaders.js",
|
|
12
|
+
"prepublishOnly": "node scripts/prepublish.js",
|
|
12
13
|
"version:patch": "npm version patch -m 'chore: release v%s'",
|
|
13
14
|
"version:minor": "npm version minor -m 'chore: release v%s'",
|
|
14
15
|
"version:major": "npm version major -m 'chore: release v%s'",
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Pre-Publish Script
|
|
6
|
+
*
|
|
7
|
+
* This script runs automatically before npm publish to ensure:
|
|
8
|
+
* 1. en-US translation files are ready
|
|
9
|
+
* 2. en-US index.ts loader is generated
|
|
10
|
+
* 3. All required files are in place
|
|
11
|
+
*
|
|
12
|
+
* Runs automatically via "prepublishOnly" npm script
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
|
|
19
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
20
|
+
const EN_US_DIR = path.join(PACKAGE_ROOT, 'src/infrastructure/locales/en-US');
|
|
21
|
+
const EN_US_INDEX = path.join(EN_US_DIR, 'index.ts');
|
|
22
|
+
|
|
23
|
+
console.log('š Pre-publish checks...\n');
|
|
24
|
+
|
|
25
|
+
// Check if en-US directory exists
|
|
26
|
+
if (!fs.existsSync(EN_US_DIR)) {
|
|
27
|
+
console.error('ā en-US directory not found!');
|
|
28
|
+
console.error(` Expected: ${EN_US_DIR}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check if en-US has JSON files
|
|
33
|
+
const jsonFiles = fs.readdirSync(EN_US_DIR)
|
|
34
|
+
.filter(file => file.endsWith('.json'))
|
|
35
|
+
.sort();
|
|
36
|
+
|
|
37
|
+
if (jsonFiles.length === 0) {
|
|
38
|
+
console.error('ā No JSON translation files found in en-US directory!');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log(`ā
Found ${jsonFiles.length} translation files in en-US:`);
|
|
43
|
+
jsonFiles.forEach(file => console.log(` - ${file}`));
|
|
44
|
+
|
|
45
|
+
// Generate index.ts if it doesn't exist or is outdated
|
|
46
|
+
const needsIndexUpdate = !fs.existsSync(EN_US_INDEX) ||
|
|
47
|
+
jsonFiles.some(file => {
|
|
48
|
+
const filePath = path.join(EN_US_DIR, file);
|
|
49
|
+
const indexStat = fs.statSync(EN_US_INDEX);
|
|
50
|
+
const fileStat = fs.statSync(filePath);
|
|
51
|
+
return fileStat.mtime > indexStat.mtime;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (needsIndexUpdate) {
|
|
55
|
+
console.log('\nš Generating en-US index.ts loader...');
|
|
56
|
+
try {
|
|
57
|
+
// Run createLocaleLoaders script for en-US
|
|
58
|
+
const createLoaderScript = path.join(PACKAGE_ROOT, 'scripts/createLocaleLoaders.js');
|
|
59
|
+
execSync(`node "${createLoaderScript}" en-US`, {
|
|
60
|
+
stdio: 'inherit',
|
|
61
|
+
cwd: PACKAGE_ROOT,
|
|
62
|
+
});
|
|
63
|
+
console.log('ā
en-US index.ts generated successfully');
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('ā Failed to generate en-US index.ts:', error.message);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
console.log('\nā
en-US index.ts is up to date');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Verify index.ts exists
|
|
73
|
+
if (!fs.existsSync(EN_US_INDEX)) {
|
|
74
|
+
console.error('ā en-US/index.ts not found after generation!');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.log('\nā
Pre-publish checks passed!');
|
|
79
|
+
console.log(' Package is ready to publish.\n');
|
|
80
|
+
|
|
@@ -204,6 +204,9 @@ if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
|
204
204
|
languages: Object.keys(resources),
|
|
205
205
|
enUSKeys: resources['en-US']?.translation ? Object.keys(resources['en-US'].translation) : [],
|
|
206
206
|
hasGoals: !!resources['en-US']?.translation?.goals,
|
|
207
|
+
navigationKeys: resources['en-US']?.translation?.navigation ? Object.keys(resources['en-US'].translation.navigation) : [],
|
|
208
|
+
hasMilestones: !!resources['en-US']?.translation?.navigation?.milestones,
|
|
209
|
+
hasStatistics: !!resources['en-US']?.translation?.navigation?.statistics,
|
|
207
210
|
});
|
|
208
211
|
}
|
|
209
212
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"title": "Welcome",
|
|
3
3
|
"subtitle": "Sign in to your account or continue as guest",
|
|
4
4
|
"welcomeBack": "Welcome Back",
|
|
5
|
-
"loginSubtitle": "Sign in to sync your
|
|
5
|
+
"loginSubtitle": "Sign in to sync your data across devices",
|
|
6
6
|
"email": "Email",
|
|
7
7
|
"emailPlaceholder": "Enter your email",
|
|
8
8
|
"password": "Password",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"guestMode": "Guest Mode",
|
|
33
33
|
"guestModeDescription": "Your data is stored locally on this device",
|
|
34
34
|
"syncData": "Sync Local Data",
|
|
35
|
-
"syncDataDescription": "Upload your local
|
|
35
|
+
"syncDataDescription": "Upload your local data to the cloud",
|
|
36
36
|
"syncSuccess": "Data synced successfully",
|
|
37
37
|
"syncFailed": "Failed to sync data"
|
|
38
38
|
}
|
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
* 2. File is auto-discovered and loaded
|
|
18
18
|
* 3. Access via t('my_domain.key')
|
|
19
19
|
*
|
|
20
|
-
* This file is automatically generated by setup-languages.js
|
|
20
|
+
* This file is automatically generated by setup-languages.js or createLocaleLoaders.js
|
|
21
21
|
* but can be manually edited if needed.
|
|
22
|
+
*
|
|
23
|
+
* Generated: 2025-11-13T00:33:06.438Z
|
|
22
24
|
*/
|
|
23
25
|
|
|
24
26
|
// Metro bundler require.context - auto-discover all .json files
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"home": {
|
|
3
|
-
"welcome": "Welcome to Flashcard Maker",
|
|
4
|
-
"subtitle": "Master any subject with interactive flashcards",
|
|
5
|
-
"quickStudy": "Quick Study",
|
|
6
|
-
"quickStudyDesc": "Start studying your recent decks",
|
|
7
|
-
"createDeck": "Create Deck",
|
|
8
|
-
"createDeckDesc": "Build a new flashcard deck",
|
|
9
|
-
"recentActivity": "Recent Activity",
|
|
10
|
-
"noDecksYet": "You haven't created any decks yet",
|
|
11
|
-
"browseDecks": "Browse Decks",
|
|
12
|
-
"statistics": "Statistics",
|
|
13
|
-
"totalDecks": "Total Decks",
|
|
14
|
-
"totalCards": "Total Cards",
|
|
15
|
-
"studySessions": "Study Sessions"
|
|
16
|
-
},
|
|
17
|
-
"decks": {
|
|
18
|
-
"noDecks": "No Decks Found",
|
|
19
|
-
"noDecksDesc": "Create your first flashcard deck to get started",
|
|
20
|
-
"createFirstDeck": "Create First Deck",
|
|
21
|
-
"createDeck": "Create Deck",
|
|
22
|
-
"editDeck": "Edit Deck",
|
|
23
|
-
"recentlyStudied": "Recently Studied",
|
|
24
|
-
"allDecks": "All Decks",
|
|
25
|
-
"easy": "Easy",
|
|
26
|
-
"medium": "Medium",
|
|
27
|
-
"hard": "Hard"
|
|
28
|
-
},
|
|
29
|
-
"study": {
|
|
30
|
-
"noCards": "No Cards Available",
|
|
31
|
-
"noCardsDesc": "Add some cards to a deck to start studying",
|
|
32
|
-
"browseDecks": "Browse Decks",
|
|
33
|
-
"question": "Question",
|
|
34
|
-
"answer": "Answer",
|
|
35
|
-
"showQuestion": "Show Question",
|
|
36
|
-
"showAnswer": "Show Answer",
|
|
37
|
-
"correct": "Correct",
|
|
38
|
-
"incorrect": "Incorrect",
|
|
39
|
-
"skip": "Skip",
|
|
40
|
-
"skipped": "Skipped",
|
|
41
|
-
"studyComplete": "Study Complete",
|
|
42
|
-
"wellDone": "Well done!",
|
|
43
|
-
"sessionComplete": "Session Complete"
|
|
44
|
-
},
|
|
45
|
-
"create": {
|
|
46
|
-
"createDeck": "Create Deck",
|
|
47
|
-
"addCards": "Add Cards",
|
|
48
|
-
"deckInfo": "Deck Information",
|
|
49
|
-
"cardInfo": "Card Information",
|
|
50
|
-
"deckTitle": "Deck Title",
|
|
51
|
-
"deckTitlePlaceholder": "Enter deck title",
|
|
52
|
-
"deckDescription": "Description",
|
|
53
|
-
"deckDescriptionPlaceholder": "Enter deck description",
|
|
54
|
-
"category": "Category",
|
|
55
|
-
"selectCategory": "Select category",
|
|
56
|
-
"cardFront": "Front Side",
|
|
57
|
-
"cardFrontPlaceholder": "Enter question or term",
|
|
58
|
-
"cardBack": "Back Side",
|
|
59
|
-
"cardBackPlaceholder": "Enter answer or definition",
|
|
60
|
-
"difficulty": "Difficulty",
|
|
61
|
-
"addCard": "Add Card",
|
|
62
|
-
"addedCards": "Added Cards",
|
|
63
|
-
"saveDeck": "Save Deck"
|
|
64
|
-
},
|
|
65
|
-
"cards": {
|
|
66
|
-
"noCards": "No Cards Found",
|
|
67
|
-
"noCardsDesc": "Create your first flashcard to get started",
|
|
68
|
-
"createFirstCard": "Create First Card",
|
|
69
|
-
"createCard": "Create Card",
|
|
70
|
-
"editCard": "Edit Card",
|
|
71
|
-
"selectDeck": "Select Deck",
|
|
72
|
-
"selectDeckPlaceholder": "Choose a deck for this card"
|
|
73
|
-
},
|
|
74
|
-
"common": {
|
|
75
|
-
"clearFilter": "Clear Filter"
|
|
76
|
-
},
|
|
77
|
-
"studyModes": {
|
|
78
|
-
"classic": "Classic",
|
|
79
|
-
"matching": "Matching Game",
|
|
80
|
-
"quiz": "Multiple Choice",
|
|
81
|
-
"writing": "Writing Mode",
|
|
82
|
-
"timed": "Timed Challenge",
|
|
83
|
-
"selectMode": "Select Study Mode"
|
|
84
|
-
},
|
|
85
|
-
"session": {
|
|
86
|
-
"complete": "Session Complete",
|
|
87
|
-
"accuracy": "Accuracy",
|
|
88
|
-
"speed": "Speed",
|
|
89
|
-
"score": "Score",
|
|
90
|
-
"cardsPerMinute": "cards/min",
|
|
91
|
-
"grade": "Grade",
|
|
92
|
-
"feedback": {
|
|
93
|
-
"excellent": "Excellent work! You have mastered this deck!",
|
|
94
|
-
"great": "Great job! Keep up the good work!",
|
|
95
|
-
"good": "Good progress! Practice more to improve.",
|
|
96
|
-
"keep_practicing": "Keep practicing! You're getting there.",
|
|
97
|
-
"keep_studying": "Keep studying! Review these cards again."
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
"rating": {
|
|
101
|
-
"fail": "Again",
|
|
102
|
-
"hard": "Hard",
|
|
103
|
-
"good": "Good",
|
|
104
|
-
"easy": "Easy",
|
|
105
|
-
"perfect": "Perfect"
|
|
106
|
-
},
|
|
107
|
-
"srs": {
|
|
108
|
-
"dueToday": "Due Today",
|
|
109
|
-
"dueCards": "Due Cards",
|
|
110
|
-
"nextReview": "Next Review",
|
|
111
|
-
"interval": "Interval",
|
|
112
|
-
"repetitions": "Repetitions",
|
|
113
|
-
"easeFactor": "Ease Factor",
|
|
114
|
-
"reviewHistory": "Review History",
|
|
115
|
-
"retention": "Retention Rate",
|
|
116
|
-
"again": "Again",
|
|
117
|
-
"hard": "Hard",
|
|
118
|
-
"good": "Good",
|
|
119
|
-
"easy": "Easy"
|
|
120
|
-
},
|
|
121
|
-
"media": {
|
|
122
|
-
"addImage": "Add Image",
|
|
123
|
-
"addAudio": "Add Audio",
|
|
124
|
-
"takePhoto": "Take Photo",
|
|
125
|
-
"chooseFromLibrary": "Choose from Library",
|
|
126
|
-
"record": "Record",
|
|
127
|
-
"play": "Play",
|
|
128
|
-
"stop": "Stop",
|
|
129
|
-
"delete": "Delete Media",
|
|
130
|
-
"tts": {
|
|
131
|
-
"speak": "Speak Text",
|
|
132
|
-
"stopSpeaking": "Stop Speaking",
|
|
133
|
-
"language": "Language",
|
|
134
|
-
"rate": "Speed",
|
|
135
|
-
"pitch": "Pitch"
|
|
136
|
-
},
|
|
137
|
-
"errors": {
|
|
138
|
-
"permissionDenied": "Permission denied",
|
|
139
|
-
"cameraNotAvailable": "Camera not available",
|
|
140
|
-
"audioNotAvailable": "Audio recording not available",
|
|
141
|
-
"ttsNotAvailable": "Text-to-speech not available"
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
"import": {
|
|
145
|
-
"title": "Import Deck",
|
|
146
|
-
"chooseFormat": "Choose Format",
|
|
147
|
-
"csv": "CSV (Excel)",
|
|
148
|
-
"json": "JSON",
|
|
149
|
-
"quizlet": "Quizlet",
|
|
150
|
-
"selectFile": "Select File",
|
|
151
|
-
"importing": "Importing...",
|
|
152
|
-
"success": "Successfully imported {{count}} cards",
|
|
153
|
-
"errors": "{{count}} errors occurred",
|
|
154
|
-
"viewErrors": "View Errors"
|
|
155
|
-
},
|
|
156
|
-
"export": {
|
|
157
|
-
"title": "Export Deck",
|
|
158
|
-
"chooseFormat": "Choose Format",
|
|
159
|
-
"csv": "CSV (Excel)",
|
|
160
|
-
"json": "JSON (Complete)",
|
|
161
|
-
"quizlet": "Quizlet",
|
|
162
|
-
"includeStats": "Include Statistics",
|
|
163
|
-
"includeMedia": "Include Media",
|
|
164
|
-
"exporting": "Exporting...",
|
|
165
|
-
"success": "Deck exported successfully"
|
|
166
|
-
},
|
|
167
|
-
"statistics": {
|
|
168
|
-
"title": "Statistics",
|
|
169
|
-
"overview": "Overview",
|
|
170
|
-
"totalCards": "Total Cards",
|
|
171
|
-
"cardsStudied": "Cards Studied",
|
|
172
|
-
"totalReviews": "Total Reviews",
|
|
173
|
-
"correctReviews": "Correct Reviews",
|
|
174
|
-
"accuracy": "Accuracy",
|
|
175
|
-
"averageTimePerCard": "Avg Time per Card",
|
|
176
|
-
"totalStudyTime": "Total Study Time",
|
|
177
|
-
"studySessions": "Study Sessions",
|
|
178
|
-
"streak": {
|
|
179
|
-
"current": "Current Streak",
|
|
180
|
-
"longest": "Longest Streak",
|
|
181
|
-
"days": "days"
|
|
182
|
-
},
|
|
183
|
-
"charts": {
|
|
184
|
-
"daily": "Daily",
|
|
185
|
-
"weekly": "Weekly",
|
|
186
|
-
"monthly": "Monthly",
|
|
187
|
-
"performance": "Performance",
|
|
188
|
-
"activity": "Activity"
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
"sharing": {
|
|
192
|
-
"title": "Share Deck",
|
|
193
|
-
"generateCode": "Generate Share Code",
|
|
194
|
-
"shareCode": "Share Code",
|
|
195
|
-
"qrCode": "QR Code",
|
|
196
|
-
"copyCode": "Copy Code",
|
|
197
|
-
"codeCopied": "Code copied to clipboard",
|
|
198
|
-
"shareAsFile": "Share as File",
|
|
199
|
-
"shareAsLink": "Share as Link",
|
|
200
|
-
"importCode": "Import Code",
|
|
201
|
-
"enterCode": "Enter 6-digit code",
|
|
202
|
-
"invalidCode": "Invalid share code",
|
|
203
|
-
"importing": "Importing deck...",
|
|
204
|
-
"importSuccess": "Deck imported successfully",
|
|
205
|
-
"downloadCount": "Downloads",
|
|
206
|
-
"makePublic": "Make Public",
|
|
207
|
-
"makePrivate": "Make Private"
|
|
208
|
-
},
|
|
209
|
-
"gamification": {
|
|
210
|
-
"profile": {
|
|
211
|
-
"level": "Level",
|
|
212
|
-
"xp": "XP",
|
|
213
|
-
"rank": "Rank",
|
|
214
|
-
"progress": "Progress to next level",
|
|
215
|
-
"totalXP": "Total XP Earned"
|
|
216
|
-
},
|
|
217
|
-
"ranks": {
|
|
218
|
-
"novice": "Novice",
|
|
219
|
-
"apprentice": "Apprentice",
|
|
220
|
-
"scholar": "Scholar",
|
|
221
|
-
"expert": "Expert",
|
|
222
|
-
"master": "Master",
|
|
223
|
-
"grandmaster": "Grandmaster",
|
|
224
|
-
"legend": "Legend"
|
|
225
|
-
},
|
|
226
|
-
"achievements": {
|
|
227
|
-
"title": "Achievements",
|
|
228
|
-
"unlocked": "Unlocked",
|
|
229
|
-
"locked": "Locked",
|
|
230
|
-
"progress": "Progress",
|
|
231
|
-
"reward": "Reward",
|
|
232
|
-
"unlockedAt": "Unlocked on",
|
|
233
|
-
"categories": {
|
|
234
|
-
"study": "Study",
|
|
235
|
-
"cards": "Cards",
|
|
236
|
-
"decks": "Decks",
|
|
237
|
-
"streak": "Streak",
|
|
238
|
-
"special": "Special"
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
"challenges": {
|
|
242
|
-
"title": "Daily Challenges",
|
|
243
|
-
"today": "Today's Challenges",
|
|
244
|
-
"completed": "Completed",
|
|
245
|
-
"inProgress": "In Progress",
|
|
246
|
-
"reward": "Reward",
|
|
247
|
-
"goal": "Goal",
|
|
248
|
-
"progress": "Progress"
|
|
249
|
-
},
|
|
250
|
-
"xpRewards": {
|
|
251
|
-
"cardReviewed": "+{{amount}} XP - Card Reviewed",
|
|
252
|
-
"cardCorrect": "+{{amount}} XP - Correct Answer",
|
|
253
|
-
"cardPerfect": "+{{amount}} XP - Perfect!",
|
|
254
|
-
"deckCreated": "+{{amount}} XP - Deck Created",
|
|
255
|
-
"studySession": "+{{amount}} XP - Study Session",
|
|
256
|
-
"dailyGoal": "+{{amount}} XP - Daily Goal Met",
|
|
257
|
-
"streakDay": "+{{amount}} XP - Streak Day",
|
|
258
|
-
"achievementUnlocked": "+{{amount}} XP - Achievement Unlocked"
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
"matching": {
|
|
262
|
-
"title": "Matching Game",
|
|
263
|
-
"instructions": "Match the cards by tapping pairs",
|
|
264
|
-
"matches": "Matches",
|
|
265
|
-
"attempts": "Attempts",
|
|
266
|
-
"timeElapsed": "Time",
|
|
267
|
-
"perfect": "Perfect Match!",
|
|
268
|
-
"tryAgain": "Try Again"
|
|
269
|
-
},
|
|
270
|
-
"quiz": {
|
|
271
|
-
"title": "Multiple Choice Quiz",
|
|
272
|
-
"question": "Question",
|
|
273
|
-
"chooseAnswer": "Choose the correct answer",
|
|
274
|
-
"correct": "Correct!",
|
|
275
|
-
"incorrect": "Incorrect",
|
|
276
|
-
"showAnswer": "Show Answer",
|
|
277
|
-
"nextQuestion": "Next Question"
|
|
278
|
-
},
|
|
279
|
-
"writing": {
|
|
280
|
-
"title": "Writing Mode",
|
|
281
|
-
"instructions": "Type the answer",
|
|
282
|
-
"yourAnswer": "Your Answer",
|
|
283
|
-
"correctAnswer": "Correct Answer",
|
|
284
|
-
"similarity": "Similarity",
|
|
285
|
-
"strictMode": "Strict Mode",
|
|
286
|
-
"fuzzyMatching": "Fuzzy Matching",
|
|
287
|
-
"check": "Check Answer"
|
|
288
|
-
},
|
|
289
|
-
"media": {
|
|
290
|
-
"image": "Image",
|
|
291
|
-
"chooseImage": "Choose Image",
|
|
292
|
-
"takePhoto": "Take Photo",
|
|
293
|
-
"permissionDenied": "Permission denied to access photos",
|
|
294
|
-
"cameraPermissionDenied": "Permission denied to access camera",
|
|
295
|
-
"imageFailed": "Failed to load image",
|
|
296
|
-
"cameraFailed": "Failed to open camera",
|
|
297
|
-
"audio": "Audio",
|
|
298
|
-
"record": "Record Audio",
|
|
299
|
-
"recording": "Recording...",
|
|
300
|
-
"stopRecording": "Stop Recording",
|
|
301
|
-
"play": "Play",
|
|
302
|
-
"stop": "Stop",
|
|
303
|
-
"speak": "Speak",
|
|
304
|
-
"audioPermissionDenied": "Permission denied to record audio",
|
|
305
|
-
"recordingFailed": "Failed to record audio",
|
|
306
|
-
"playbackFailed": "Failed to play audio",
|
|
307
|
-
"ttsFailed": "Text-to-speech failed",
|
|
308
|
-
"noText": "No text to speak"
|
|
309
|
-
}
|
|
310
|
-
}
|