File size: 41,119 Bytes
5ef6e9d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
export type Lang = "zh" | "en";

export const translations = {
  zh: {
    appName: "星光工坊",
    navCreate: "創作",
    navHistory: "歷史記錄",
    navSettings: "API 設定",
    navApiKeys: "API 金鑰",
    navSignIn: "登入",
    navSignOut: "登出",
    navAdmin: "後台",
    canvasTitle: "創作畫布",
    canvasSubtitle: "輸入您的靈感,讓AI為您呈現。",
    promptLabel: "輸入描述",
    promptPlaceholder: "描述您想看到的畫面...",
    modelLabel: "選擇模型",
    modelPlaceholder: "選擇模型",
    styleLabel: "圖片風格",
    stylePlaceholder: "選擇風格",
    ratioLabel: "比例",
    ratioPlaceholder: "選擇比例",
    refImageLabel: "參考圖片(圖生圖)",
    refImageBadge: "可選",
    refImageDrop: "拖曳或點擊上傳參考圖",
    refImageFormats: "JPG / PNG / WebP",
    refImageRemove: "移除",
    btnGenerate: "生成圖片",
    btnImg2Img: "圖生圖",
    btnGenerating: "生成中...",
    emptyTitle: "等待您的靈感",
    emptySubtitle: "選擇模型後輸入描述,點擊生成",
    loadingTitle: "正在施展魔法...",
    loadingSubtitle: "模型生成中,約需 30-60 秒",
    errorFormatTitle: "格式錯誤",
    errorFormatDesc: "請上傳圖片檔案",
    errorGenTitle: "生成失敗",
    errorGenDesc: "請稍後再試或確認 Token 是否有效",
    debugTitle: "API 輸出分析",
    debugFallback: "備用模式",
    debugReal: "真實 API",
    debugEndpoint: "端點",
    debugMethod: "方法",
    debugStatus: "狀態",
    debugDuration: "耗時",
    debugReason: "原因",
    debugSectionInfo: "API 資訊",
    debugSectionRequest: "請求內容",
    debugSectionResponse: "響應內容",
    debugNoResponse: "未收到響應",
    debugMs: "毫秒",
    debugHeaders: "Headers",
    debugBody: "Body",
    settingsTitle: "API 設定",
    settingsStatus: "Token 已設定",
    settingsNoToken: "尚未設定 Token,API 呼叫將失敗",
    settingsAccessLabel: "Access Token(必填)",
    settingsAccessPlaceholder: "貼上 access_token...",
    settingsRefreshLabel: "Refresh Token(選填,用於自動續期)",
    settingsRefreshPlaceholder: "貼上 refresh_token...",
    settingsSave: "儲存 Token",
    settingsSaving: "儲存中...",
    settingsHowTitle: "如何取得 Token?",
    settingsStep1Pre: "前往",
    settingsStep1Post: "並登入帳號",
    settingsStep2: "按下 F12 開啟開發者工具",
    settingsStep3: "選擇「應用程式」→「本機儲存空間」→ geminigen.ai",
    settingsStep4Pre: "複製",
    settingsStep4Mid: "的值(必填)",
    settingsStep5Pre: "同樣複製",
    settingsStep5Mid: "的值(選填,可自動續期)",
    settingsHint: "⚡ 建議同時填入 refresh_token,系統可以在 access_token 過期時自動續期,無需手動更新。",
    settingsSavedTitle: "Token 已儲存",
    settingsSavedDesc: "API Token 設定成功,系統將自動刷新",
    settingsSaveError: "儲存失敗",
    settingsSaveErrorDesc: "請稍後再試",
    settingsRemovedTitle: "Token 已移除",
    resolutionLabel: "輸出解析度",
    resolutionPlaceholder: "選擇解析度",
    resolutionDesc1K: "1K — 標準品質 (1024px)",
    resolutionDesc2K: "2K — 高品質 (2048px)",
    resolutionDesc4K: "4K — 超高清 (4096px)",
    resolutionHint: "此選項僅支援 Nano Banana 系列模型",
    apiKeysTitle: "API 金鑰管理",
    apiKeysSubtitle: "使用 OpenAI 相容格式,透過 API 金鑰存取星光工坊生圖服務",
    apiKeysCreate: "建立新金鑰",
    apiKeysCreateName: "金鑰名稱",
    apiKeysCreateNamePlaceholder: "例:我的應用程式",
    apiKeysCreateBtn: "建立",
    apiKeysCreating: "建立中...",
    apiKeysCopyHint: "請立即複製金鑰,離開後將無法再次查看",
    apiKeysCopied: "已複製",
    apiKeysCopy: "複製",
    apiKeysRevoke: "撤銷",
    apiKeysRevoking: "撤銷中...",
    apiKeysEmpty: "尚無 API 金鑰",
    apiKeysEmptyHint: "點擊「建立新金鑰」開始使用",
    apiKeysLastUsed: "最後使用",
    apiKeysNeverUsed: "尚未使用",
    apiKeysCreatedAt: "建立時間",
    apiKeysDocsTitle: "API 文件",
    apiKeysBaseUrl: "Base URL",
    apiKeysEndpointsTitle: "可用端點",
    apiKeysModelsDesc: "取得可用模型列表",
    apiKeysGenerateDesc: "生成圖片(OpenAI 相容格式)",
    apiKeysExampleTitle: "使用範例",
    apiKeysSignInRequired: "請先登入以管理 API 金鑰",
    apiKeysSignIn: "前往登入",
    authSignIn: "登入",
    authSignUp: "註冊",
    authEmail: "電子郵件",
    authEmailPlaceholder: "your@email.com",
    authPassword: "密碼",
    authPasswordPlaceholder: "輸入密碼",
    authPasswordMinHint: "至少 6 個字元",
    authDisplayName: "暱稱(選填)",
    authDisplayNamePlaceholder: "您的名字",
    authLoading: "處理中...",
    authError: "發生錯誤,請再試一次",
    authNoAccount: "還沒有帳號?",
    authHasAccount: "已有帳號?",
    adminTitle: "後台管理",
    adminSubtitle: "管理使用者、系統設定與 API 配置",
    adminForbiddenTitle: "無存取權限",
    adminForbiddenDesc: "您沒有管理員權限,無法存取此頁面。",
    adminBackHome: "回首頁",
    adminTabUsers: "使用者管理",
    adminTabConfig: "系統設定",
    adminStatUsers: "總使用者",
    adminStatImages: "已生成圖片",
    adminStatApiKeys: "API 金鑰",
    adminYou: "你",
    adminGrantAdmin: "設為管理員",
    adminRevokeAdmin: "撤銷管理員",
    adminDeleteUser: "刪除帳號",
    adminResetPass: "重設密碼",
    adminNewPassPlaceholder: "輸入新密碼(至少6字元)",
    adminResetPassBtn: "確認重設",
    adminUserUpdated: "使用者已更新",
    adminUserDeleted: "使用者已刪除",
    adminPassReset: "密碼已重設",
    adminPassTooShort: "密碼至少需要 6 個字元",
    adminDeleteConfirm: "確定要刪除此使用者?此操作無法復原。",
    adminError: "操作失敗,請再試一次",
    adminNoUsers: "目前沒有使用者",
    adminConfigEmpty: "目前沒有系統設定",
    adminConfigUpdated: "最後更新",
    adminConfigNewValue: "輸入新值",
    adminConfigSaveBtn: "儲存",
    adminConfigSaved: "設定已儲存",
    adminGuideTitle: "如何取得 Refresh Token?",
    adminGuideSubtitle: "從 geminigen.ai 擷取 Token,貼入下方欄位即可啟用服務。",
    adminGuideShow: "查看教學",
    adminGuideHide: "收起教學",
    adminGuideSteps: [
      "開啟 <a href='https://geminigen.ai' target='_blank' class='text-blue-400 underline'>geminigen.ai</a>,先登入您的帳號。",
      "按下 <strong class='text-foreground'>F12</strong> 開啟瀏覽器開發者工具(或右鍵 → 檢查)。",
      "點選上方 <strong class='text-foreground'>Application</strong>(應用程式)分頁。",
      "在左側展開 <strong class='text-foreground'>Local Storage</strong>,點選 <code class='text-yellow-300 bg-black/30 px-1 rounded text-xs'>https://geminigen.ai</code>。",
      "在右側找到 <code class='text-yellow-300 bg-black/30 px-1 rounded text-xs'>authStore</code> 這一行,雙擊展開 JSON 值。",
      "找到 <code class='text-green-300 bg-black/30 px-1 rounded text-xs'>refresh_token</code> 欄位,<strong class='text-foreground'>只複製引號裡面那段長字串</strong>(例如:<code class='text-green-300 bg-black/30 px-1 rounded text-xs'>eyJ...</code> 開頭),不要複製整個 JSON。",
    ],
    adminGuideNote: "※ Token 有效期間約數天到數週,過期後需重新取得。Access Token 由系統每 4 分鐘自動更新,不需手動設定。",
    poolTitle: "🔄 Token 帳戶池",
    poolDesc: "多帳戶輪替生圖,系統自動挑選最近最少使用(LRU)的帳戶,避免單一帳號被限速。",
    poolEmpty: "尚未加入任何帳戶",
    poolEmptyDesc: "點下方「新增帳戶」開始設定",
    poolNeverUsed: "從未使用",
    poolLRUNote: "輪替策略:最近最少使用(LRU)",
    poolAddTitle: "新增帳戶",
    poolBtnConsole: "Console 同步",
    poolBtnConsoleDesc: "Google 帳號適用",
    poolBtnBookmark: "書籤同步",
    poolBtnBookmarkDesc: "一鍵拖曳書籤",
    poolBtnManual: "手動輸入",
    poolBtnManualDesc: "直接貼 Token",
    poolModeConsole: "Console 方式",
    poolModeBookmark: "書籤方式",
    poolAccountLabel: "帳戶名稱(加入 Token 池用)",
    poolAccountPlaceholder: "例:Google 帳號 A",
    poolGenerating: "產生代碼中...",
    poolGenerate: "產生同步代碼",
    poolExpiryPrefix: "代碼有效:約",
    poolExpirySuffix: "分鐘",
    poolRegenerate: "重新產生",
    poolStepsLabel: "操作步驟:",
    poolConsoleStep1: "開啟 geminigen.ai 並用 Google 帳號登入",
    poolConsoleStep2: "按 F12 開啟開發者工具 → 點「Console」分頁",
    poolConsoleStep3: "複製下方代碼,貼到 Console 後按 Enter",
    poolConsoleStep4: "看到「✅ Token 已成功同步到星光工坊!」即完成",
    poolCopyCode: "複製代碼",
    poolCopied: "已複製",
    poolCopyBtn: "複製代碼到剪貼簿",
    poolCopiedBtn: "已複製!",
    poolBookmarkStep1: "把下方按鈕拖曳到瀏覽器書籤列",
    poolBookmarkStep2: "開啟 geminigen.ai 並用 Google 帳號登入",
    poolBookmarkStep3: "點書籤列的「同步到星光工坊」",
    poolBookmarkBtnText: "同步到星光工坊",
    poolBookmarkDragHint: "⬆ 長按並拖曳到書籤列",
    poolManualTitle: "手動輸入 Bearer Token",
    poolManualNamePlaceholder: "帳戶名稱(例:Google 帳號 A)",
    poolManualBearerPlaceholder: "Bearer Token(eyJ...)*必填",
    poolManualRefreshPlaceholder: "Refresh Token(選填)",
    poolManualAddBtn: "加入 Token 池",
    poolCancel: "取消",
    poolUnnamed: "未命名",
    poolHasRefresh: "有 Refresh",
    poolDisable: "停用",
    poolEnable: "啟用",
    poolDelete: "刪除",
    poolAddSuccess: "✅ 帳戶已加入 Token 池",
    poolDeleteSuccess: "帳戶已移除",
    poolGenFailed: "產生失敗",
    poolCopySuccess: "✅ 已複製!前往 geminigen.ai 貼到 Console 執行",
    poolCopyFailed: "複製失敗,請手動選取代碼",
    poolDragToast: "請拖曳此按鈕到書籤列,不要直接點擊",
    renewalTitle: "✅ 自動更新已啟用",
    renewalSetupTitle: "⚡ 設定自動更新(推薦)",
    renewalActiveDesc: "系統將使用儲存的 geminigen.ai 帳號自動重新登入,Token 永不失效。",
    renewalInactiveDesc: "輸入 geminigen.ai 的帳號密碼,Token 過期時系統自動重新登入,無需手動操作。",
    renewalRemove: "移除",
    renewalEmailPlaceholder: "geminigen.ai 帳號(Email)",
    renewalPassPlaceholder: "geminigen.ai 密碼",
    renewalSecureNote: "密碼以 AES-256 加密儲存在你的資料庫,不會洩漏。",
    renewalSaveBtn: "儲存帳號並啟用自動更新",
    renewalSaving: "儲存中...",
    renewalSuccess: "✅ 憑證已儲存!系統將在有可用的驗證碼求解器時自動登入。",
    renewalFailed: "儲存失敗",
    renewalClearedCreds: "已移除自動登入憑證",
    renewalRequireFields: "請輸入帳號和密碼",
    renewalManualTitle: "手動更新 Refresh Token(備用方案)",
    renewalManualDesc: "若不想儲存帳號密碼,可手動從 geminigen.ai 複製 refresh_token 貼入:",
    renewalManualPlaceholder: "eyJ... 開頭的 refresh_token",
    renewalManualBtn: "更新",
    renewalManualSuccess: "✅ Refresh Token 已更新。",
    renewalManualInvalid: "請貼入完整的 refresh_token 值(eyJ... 開頭的長字串)",
    renewalManualFailed: "儲存失敗",
    setupTitle: "初始設定",
    setupSubtitle: "首次使用需要設定 Refresh Token,才能啟動 AI 生圖功能。",
    setupPasteLabel: "貼上 Refresh Token",
    setupPastePlaceholder: "eyJ... 開頭的長字串(只貼 Token 值,不含引號或 JSON)",
    setupPasteHint: "⚠️ 請確認只貼入 token 值本身(eyJ 開頭的長字串),不要貼整個 JSON 或含引號。Token 儲存後系統自動刷新,設定一次可長期使用。",
    setupConfirm: "確認儲存",
    setupSaving: "儲存中...",
    setupSuccess: "Token 已儲存!系統將於數分鐘內自動啟用 AI 生圖功能。",
    setupError: "儲存失敗,請確認貼入的是正確的 Token 值。",
    styles: {
      none: "無風格",
      realistic: "寫實",
      anime: "動漫",
      artistic: "藝術",
      cartoon: "卡通",
      sketch: "素描",
      oil_painting: "油畫",
      watercolor: "水彩",
      digital_art: "數位藝術",
    },
    privateLabel: "私人記錄",
    publicLabel: "公開記錄",
    privateDesc: "僅您本人可見",
    publicDesc: "所有人可見",
    ratios: {
      "1:1": "正方形",
      "16:9": "橫版",
      "9:16": "直版",
      "4:3": "標準",
      "3:4": "直橫",
      "3:2": "相機",
      "2:3": "海報",
    },
    models: {
      grok: { label: "Grok", desc: "xAI 出品,創意強", badge: "快速" },
      meta: { label: "Meta AI", desc: "Meta Llama 生圖模型", badge: "免費" },
      "imagen-pro": { label: "Imagen 3 Pro", desc: "Google 高品質模型", badge: "Pro" },
      "imagen-4": { label: "Imagen 4", desc: "Google 最新一代模型", badge: "新" },
      "imagen-flash": { label: "Imagen Flash", desc: "Google 閃電快速版", badge: "快速" },
      "nano-banana-pro": { label: "Nano Banana Pro", desc: "全新 Banana 模型,免費開放", badge: "免費" },
      "nano-banana-2": { label: "Nano Banana 2", desc: "Banana 第二代升級版本", badge: "免費" },
    },
    historyImages: "圖片",
    historyVideos: "影片",
    historyTabAll: "全部",
    historyTabPublic: "公開",
    historyTabPrivate: "私人",
    historyEmptyImages: "尚未生成任何圖片",
    historyEmptyImagesDesc: "這裡空空如也。前往創作區輸入您的靈感,開始您的藝術之旅吧。",
    historyEmptyVideos: "尚未生成任何影片",
    historyEmptyVideosDesc: "前往影片生成頁面,讓 AI 為您創作精彩影片。",
    historyNoItemsInFilter: "此分類尚無項目",
    historyDeleteImgTitle: "確認刪除圖片?",
    historyDeleteImgDesc: "此操作無法復原,確定要刪除這張圖片嗎?",
    historyDeleteVidTitle: "確認刪除影片?",
    historyDeleteVidDesc: "此操作無法復原,確定要刪除這部影片嗎?",
    historyDeletedImg: "圖片已刪除",
    historyDeletedVid: "影片已刪除",
    historyDeleteFailed: "刪除失敗,請稍後再試",
    historyConfirmDelete: "確認刪除",
    historyDownload: "下載",
    historyLoadingVideos: "載入影片記錄中...",
    navVideo: "影片生成",
    videoTitle: "影片生成",
    videoSubtitle: "描述您想要的畫面,讓 AI 生成 6 秒短片",
    videoModel: "模型",
    videoModelValue: "Grok-3 Video",
    videoDuration: "時長",
    videoDurationValue: "6 秒",
    videoPromptLabel: "輸入描述",
    videoPromptPlaceholder: "描述您想要的影片內容,例如:一隻貓咪在草地上玩耍...",
    videoBtnGenerate: "生成影片",
    videoBtnGenerating: "生成中...",
    videoEmptyTitle: "等待您的靈感",
    videoEmptySubtitle: "輸入描述後點擊生成",
    videoLoadingTitle: "正在生成影片...",
    videoLoadingSubtitle: "Grok-3 影片生成約需 1-3 分鐘",
    videoErrorTitle: "生成失敗",
    videoErrorDesc: "請確認 Token 有效或稍後再試",
    videoHistoryTitle: "影片歷史記錄",
    videoHistoryEmpty: "目前沒有影片記錄",
    videoDelete: "刪除",
    videoDownload: "下載",
    videoDeleteSuccess: "影片已刪除",
    videoDeleteFailed: "刪除失敗",
    videoGenSuccess: "影片生成成功!",
    videoGenFailed: "影片生成失敗",
    videoPrivateLabel: "私人",
    videoPublicLabel: "公開",
    videoRefImageLabel: "參考圖片(圖生影片)",
    videoRefImageBadge: "可選",
    videoRefImageDrop: "拖曳或點擊上傳參考圖",
    videoRefImageFormats: "JPG / PNG / WebP",
    videoRefImageRemove: "移除",
    videoModeText: "文字生影片",
    videoModeImage: "圖生影片",
    videoPhaseSubmitting: "正在提交任務...",
    videoPhaseGettingCaptcha: "正在取得驗證碼...",
    videoPhaseConnecting: "連接生成服務...",
    videoPhaseGenerating: "AI 正在生成影片",
    videoPhaseProcessing: "處理中...",
    videoDone: "影片生成完成!",
    videoGeneratingHint: "影片生成通常需要 1–5 分鐘,請耐心等候。視窗關閉不影響生成。",
    videoConnectionFailed: "連線中斷,請確認 Token 是否有效後重試",
    videoPhaseSubmitLabel: "提交",
    videoPhaseTurnstileLabel: "驗證碼",
    videoPhaseConnectLabel: "連接",
    videoPhaseGenerateLabel: "生成",
    videoModelGrokSub: "xAI · 最快",
    videoModelGrokDesc: "最長 6s · 最高 720p",
    videoModelVeoSub: "Google · 高品質",
    videoModelVeoDesc: "固定 8s · 16:9 / 9:16",
    videoVeoTimingNote: "Veo 3.1 Fast 生成需要約 2–4 分鐘,比 Grok-3 稍長",
    videoVeoNotSupported: "Veo 不支援",
    videoGrokNotSupported: "Grok-3 不支援",
    videoGrokMaxTime: "Grok-3 最長 6 秒",
    videoVeoFixedTime: "Veo 固定 8 秒",
    videoGrokMaxRes: "Grok-3 最高 720p",
    videoAdvanced: "進階設定",
    videoNegativePromptLabel: "負面提示詞",
    videoEnhancePromptLabel: "AI 增強提示詞",
    videoClose: "關閉",
    videoComplete: "影片生成完成",
    videoElapsed: "耗時",
    tokenExpiredTitle: "Refresh Token 已過期,無法生成圖片",
    tokenExpiredDesc: "請重新登入 geminigen.ai 取得新的 refresh_token,然後到",
    tokenExpiredLink: "管理員設定",
    tokenExpiredSuffix: "→ 系統設定 分頁更新 Token。",
    tokenExpiredFallback: "Token 已過期",
    tokenErrorTitle: "圖片生成失敗",
    adminTokenTitle: "更新 geminigen.ai Access Token",
    adminTokenDesc: "Token 過期時(影片生成出現 \"Token has been expired\"),貼上從 geminigen.ai 取得的新 Bearer Token",
    adminTokenHowTo: "取得方式:登入 geminigen.ai → F12 → Network → 任意請求 → Headers → 複製",
    adminTokenUpdate: "更新",
    adminTokenSuccess: "✅ Access Token 已更新!影片生成應恢復正常。",
    adminPlaywrightTitle: "自建 Playwright 求解器(免費 · 優先使用)",
    adminPlaywrightDesc: "部署自建 Turnstile 求解服務到 Vercel 後填入 URL,免費自動求解,優先於 CapSolver 使用。",
    adminPlaywrightStepsLabel: "部署步驟:",
    adminPlaywrightStep1: "將專案 artifacts/turnstile-solver/ 目錄上傳到 GitHub",
    adminPlaywrightStep2: "在 Vercel 建立新項目,匯入該 repo",
    adminPlaywrightStep3: "部署完成後複製 URL(如 https://xxx.vercel.app)",
    adminPlaywrightStep4: "在下方填入 https://xxx.vercel.app/api/solve",
    adminPlaywrightSecretPlaceholder: "SOLVER_SECRET(選填,若 Vercel 環境變數有設定)",
    adminTestConn: "測試連線",
    adminSave: "儲存",
    adminPlaywrightSuccess: "✅ Playwright 求解器 URL 已設定!",
    adminYesCaptchaTitle: "YesCaptcha API Key(有免費額度)",
    adminYesCaptchaDesc: "新帳號有免費額度,支援 Cloudflare Turnstile。費用約 $1 / 1000 次,比 CapSolver 便宜。",
    adminYesCaptchaHowTo: "取得方式:前往 yescaptcha.com 註冊 → 控制台 → API 密鑰",
    adminYesCaptchaSet: "設定",
    adminYesCaptchaSuccess: "✅ YesCaptcha API Key 已設定!",
    adminCapSolverTitle: "CapSolver API Key(付費備援)",
    adminCapSolverDesc: "當 YesCaptcha 失敗時自動切換到 CapSolver。費用約 $2 / 1000 次。",
    adminCapSolverHowTo: "取得方式:前往 capsolver.com 註冊 → Dashboard → API Key",
    adminCapSolverSet: "設定",
    adminCapSolverSuccess: "✅ CapSolver API Key 已設定!影片 Turnstile 驗證將自動解決。",
    adminSaveFailed: "更新失敗",
    adminTestSuccess: "測試成功!Token 開頭",
    adminTestFailed: "測試失敗",
    adminConnectFailed: "連接失敗",
  },
  en: {
    appName: "StarForge",
    navCreate: "Create",
    navHistory: "History",
    navSettings: "Settings",
    navApiKeys: "API Keys",
    navSignIn: "Sign In",
    navSignOut: "Sign Out",
    navAdmin: "Admin",
    canvasTitle: "Creative Canvas",
    canvasSubtitle: "Describe your vision and let AI bring it to life.",
    promptLabel: "Description",
    promptPlaceholder: "Describe the image you want to see...",
    modelLabel: "Select Model",
    modelPlaceholder: "Choose a model",
    styleLabel: "Image Style",
    stylePlaceholder: "Choose style",
    ratioLabel: "Aspect Ratio",
    ratioPlaceholder: "Choose ratio",
    refImageLabel: "Reference Image (img2img)",
    refImageBadge: "Optional",
    refImageDrop: "Drag or click to upload reference image",
    refImageFormats: "JPG / PNG / WebP",
    refImageRemove: "Remove",
    btnGenerate: "Generate Image",
    btnImg2Img: "Image to Image",
    btnGenerating: "Generating...",
    emptyTitle: "Awaiting Your Vision",
    emptySubtitle: "Select a model, enter a description, then click generate",
    loadingTitle: "Casting magic...",
    loadingSubtitle: "Generating with model, approx. 30–60 seconds",
    errorFormatTitle: "Invalid Format",
    errorFormatDesc: "Please upload an image file",
    errorGenTitle: "Generation Failed",
    errorGenDesc: "Please try again or check if your token is valid",
    debugTitle: "API Debug Info",
    debugFallback: "Fallback Mode",
    debugReal: "Real API",
    debugEndpoint: "Endpoint",
    debugMethod: "Method",
    debugStatus: "Status",
    debugDuration: "Duration",
    debugReason: "Reason",
    debugSectionInfo: "API Info",
    debugSectionRequest: "Request",
    debugSectionResponse: "Response",
    debugNoResponse: "No response received",
    debugMs: "ms",
    debugHeaders: "Headers",
    debugBody: "Body",
    settingsTitle: "API Settings",
    settingsStatus: "Token Configured",
    settingsNoToken: "No token set — API calls will fail",
    settingsAccessLabel: "Access Token (required)",
    settingsAccessPlaceholder: "Paste access_token...",
    settingsRefreshLabel: "Refresh Token (optional, enables auto-renewal)",
    settingsRefreshPlaceholder: "Paste refresh_token...",
    settingsSave: "Save Token",
    settingsSaving: "Saving...",
    settingsHowTitle: "How to get your token?",
    settingsStep1Pre: "Go to",
    settingsStep1Post: "and log in",
    settingsStep2: "Press F12 to open DevTools",
    settingsStep3: "Go to Application → Local Storage → geminigen.ai",
    settingsStep4Pre: "Copy the value of",
    settingsStep4Mid: "(required)",
    settingsStep5Pre: "Also copy the value of",
    settingsStep5Mid: "(optional, enables auto-renewal)",
    settingsHint: "⚡ Including the refresh_token lets the system auto-renew your access_token when it expires — no manual updates needed.",
    settingsSavedTitle: "Token Saved",
    settingsSavedDesc: "API token configured. The system will auto-refresh it.",
    settingsSaveError: "Save Failed",
    settingsSaveErrorDesc: "Please try again",
    settingsRemovedTitle: "Token Removed",
    resolutionLabel: "Output Resolution",
    resolutionPlaceholder: "Select resolution",
    resolutionDesc1K: "1K — Standard quality (1024px)",
    resolutionDesc2K: "2K — High quality (2048px)",
    resolutionDesc4K: "4K — Ultra HD (4096px)",
    resolutionHint: "This option is only available for Nano Banana series models",
    apiKeysTitle: "API Key Management",
    apiKeysSubtitle: "Access StarForge image generation via API keys in OpenAI-compatible format",
    apiKeysCreate: "Create New Key",
    apiKeysCreateName: "Key Name",
    apiKeysCreateNamePlaceholder: "e.g. My Application",
    apiKeysCreateBtn: "Create",
    apiKeysCreating: "Creating...",
    apiKeysCopyHint: "Copy your key now — it won't be shown again",
    apiKeysCopied: "Copied",
    apiKeysCopy: "Copy",
    apiKeysRevoke: "Revoke",
    apiKeysRevoking: "Revoking...",
    apiKeysEmpty: "No API keys yet",
    apiKeysEmptyHint: "Click \"Create New Key\" to get started",
    apiKeysLastUsed: "Last used",
    apiKeysNeverUsed: "Never used",
    apiKeysCreatedAt: "Created",
    apiKeysDocsTitle: "API Documentation",
    apiKeysBaseUrl: "Base URL",
    apiKeysEndpointsTitle: "Available Endpoints",
    apiKeysModelsDesc: "List available models",
    apiKeysGenerateDesc: "Generate images (OpenAI-compatible)",
    apiKeysExampleTitle: "Example Usage",
    apiKeysSignInRequired: "Please sign in to manage API keys",
    apiKeysSignIn: "Sign In",
    authSignIn: "Sign In",
    authSignUp: "Sign Up",
    authEmail: "Email",
    authEmailPlaceholder: "your@email.com",
    authPassword: "Password",
    authPasswordPlaceholder: "Enter password",
    authPasswordMinHint: "At least 6 characters",
    authDisplayName: "Display Name (optional)",
    authDisplayNamePlaceholder: "Your name",
    authLoading: "Processing...",
    authError: "Something went wrong, please try again",
    authNoAccount: "Don't have an account?",
    authHasAccount: "Already have an account?",
    adminTitle: "Admin Panel",
    adminSubtitle: "Manage users, system settings and API configuration",
    adminForbiddenTitle: "Access Denied",
    adminForbiddenDesc: "You don't have admin privileges to access this page.",
    adminBackHome: "Back to Home",
    adminTabUsers: "User Management",
    adminTabConfig: "System Config",
    adminStatUsers: "Total Users",
    adminStatImages: "Images Generated",
    adminStatApiKeys: "API Keys",
    adminYou: "You",
    adminGrantAdmin: "Grant Admin",
    adminRevokeAdmin: "Revoke Admin",
    adminDeleteUser: "Delete Account",
    adminResetPass: "Reset Password",
    adminNewPassPlaceholder: "New password (min 6 chars)",
    adminResetPassBtn: "Reset",
    adminUserUpdated: "User updated",
    adminUserDeleted: "User deleted",
    adminPassReset: "Password reset",
    adminPassTooShort: "Password must be at least 6 characters",
    adminDeleteConfirm: "Are you sure you want to delete this user? This cannot be undone.",
    adminError: "Operation failed, please try again",
    adminNoUsers: "No users yet",
    adminConfigEmpty: "No system config found",
    adminConfigUpdated: "Last updated",
    adminConfigNewValue: "Enter new value",
    adminConfigSaveBtn: "Save",
    adminConfigSaved: "Config saved",
    adminGuideTitle: "How to get your Refresh Token",
    adminGuideSubtitle: "Extract the token from geminigen.ai and paste it below to activate the service.",
    adminGuideShow: "View Guide",
    adminGuideHide: "Hide Guide",
    adminGuideSteps: [
      "Open <a href='https://geminigen.ai' target='_blank' class='text-blue-400 underline'>geminigen.ai</a> and log in to your account.",
      "Press <strong class='text-foreground'>F12</strong> to open Chrome DevTools (or right-click → Inspect).",
      "Click the <strong class='text-foreground'>Application</strong> tab at the top.",
      "In the left panel, expand <strong class='text-foreground'>Local Storage</strong> and click <code class='text-yellow-300 bg-black/30 px-1 rounded text-xs'>https://geminigen.ai</code>.",
      "On the right, find the <code class='text-yellow-300 bg-black/30 px-1 rounded text-xs'>authStore</code> row and double-click to expand the JSON value.",
      "Find <code class='text-green-300 bg-black/30 px-1 rounded text-xs'>refresh_token</code> and <strong class='text-foreground'>copy only the string inside the quotes</strong> (it starts with <code class='text-green-300 bg-black/30 px-1 rounded text-xs'>eyJ...</code>). Do NOT copy the entire JSON object.",
    ],
    adminGuideNote: "※ The token typically lasts days to weeks. When it expires, repeat these steps. The Access Token is auto-refreshed every 4 minutes — no manual action needed.",
    poolTitle: "🔄 Token Account Pool",
    poolDesc: "Multi-account rotation for image generation. The system picks the least-recently-used (LRU) account to avoid rate limits.",
    poolEmpty: "No accounts added yet",
    poolEmptyDesc: "Click 'Add Account' below to get started",
    poolNeverUsed: "Never used",
    poolLRUNote: "Rotation: Least Recently Used (LRU)",
    poolAddTitle: "Add Account",
    poolBtnConsole: "Console Sync",
    poolBtnConsoleDesc: "For Google accounts",
    poolBtnBookmark: "Bookmarklet",
    poolBtnBookmarkDesc: "Drag to bookmarks",
    poolBtnManual: "Manual Input",
    poolBtnManualDesc: "Paste token directly",
    poolModeConsole: "Console Method",
    poolModeBookmark: "Bookmarklet Method",
    poolAccountLabel: "Account Name (for Token Pool)",
    poolAccountPlaceholder: "e.g. Google Account A",
    poolGenerating: "Generating code...",
    poolGenerate: "Generate Sync Code",
    poolExpiryPrefix: "Code valid: ~",
    poolExpirySuffix: "min",
    poolRegenerate: "Regenerate",
    poolStepsLabel: "Steps:",
    poolConsoleStep1: "Open geminigen.ai and log in with your Google account",
    poolConsoleStep2: "Press F12 to open DevTools → click the Console tab",
    poolConsoleStep3: "Copy the code below, paste it into the Console, then press Enter",
    poolConsoleStep4: "When you see \"✅ Token synced to StarForge!\" you're done",
    poolCopyCode: "Copy Code",
    poolCopied: "Copied",
    poolCopyBtn: "Copy Code to Clipboard",
    poolCopiedBtn: "Copied!",
    poolBookmarkStep1: "Drag the button below to your browser bookmark bar",
    poolBookmarkStep2: "Open geminigen.ai and log in with your Google account",
    poolBookmarkStep3: "Click the bookmarklet \"Sync to StarForge\"",
    poolBookmarkBtnText: "Sync to StarForge",
    poolBookmarkDragHint: "⬆ Long-press and drag to your bookmark bar",
    poolManualTitle: "Enter Bearer Token Manually",
    poolManualNamePlaceholder: "Account name (e.g. Google Account A)",
    poolManualBearerPlaceholder: "Bearer Token (eyJ...) *required",
    poolManualRefreshPlaceholder: "Refresh Token (optional)",
    poolManualAddBtn: "Add to Token Pool",
    poolCancel: "Cancel",
    poolUnnamed: "Unnamed",
    poolHasRefresh: "Has Refresh",
    poolDisable: "Disable",
    poolEnable: "Enable",
    poolDelete: "Delete",
    poolAddSuccess: "✅ Account added to Token Pool",
    poolDeleteSuccess: "Account removed",
    poolGenFailed: "Failed to generate code",
    poolCopySuccess: "✅ Copied! Go to geminigen.ai, paste in Console and press Enter",
    poolCopyFailed: "Copy failed — please select the code manually",
    poolDragToast: "Please drag this button to your bookmark bar — don't click it",
    renewalTitle: "✅ Auto-Renewal Enabled",
    renewalSetupTitle: "⚡ Set Up Auto-Renewal (Recommended)",
    renewalActiveDesc: "The system will auto re-login using your saved geminigen.ai credentials. Token never expires.",
    renewalInactiveDesc: "Enter your geminigen.ai credentials. When the token expires, the system auto re-logins — no manual action needed.",
    renewalRemove: "Remove",
    renewalEmailPlaceholder: "geminigen.ai account (Email)",
    renewalPassPlaceholder: "geminigen.ai password",
    renewalSecureNote: "Password is stored with AES-256 encryption in your database. Never exposed.",
    renewalSaveBtn: "Save Credentials & Enable Auto-Renewal",
    renewalSaving: "Saving...",
    renewalSuccess: "✅ Credentials saved! System will auto-login when a captcha solver is available.",
    renewalFailed: "Save failed",
    renewalClearedCreds: "Auto-login credentials removed",
    renewalRequireFields: "Please enter email and password",
    renewalManualTitle: "Manual Refresh Token Update (Fallback)",
    renewalManualDesc: "If you prefer not to store credentials, paste your refresh_token manually from geminigen.ai:",
    renewalManualPlaceholder: "refresh_token starting with eyJ...",
    renewalManualBtn: "Update",
    renewalManualSuccess: "✅ Refresh Token updated.",
    renewalManualInvalid: "Please paste a valid refresh_token (starting with eyJ...)",
    renewalManualFailed: "Save failed",
    setupTitle: "Initial Setup",
    setupSubtitle: "A Refresh Token is required to activate AI image generation.",
    setupPasteLabel: "Paste your Refresh Token",
    setupPastePlaceholder: "eyJ... (paste only the token value, no quotes or JSON)",
    setupPasteHint: "⚠️ Paste only the token string itself (starts with eyJ...), not the entire JSON object or surrounding quotes. The token is saved immediately and the system activates within a few minutes.",
    setupConfirm: "Save & Activate",
    setupSaving: "Saving...",
    setupSuccess: "Token saved! The system will activate AI image generation within a few minutes.",
    setupError: "Failed to save. Please check that you pasted the correct token value.",
    styles: {
      none: "No Style",
      realistic: "Realistic",
      anime: "Anime",
      artistic: "Artistic",
      cartoon: "Cartoon",
      sketch: "Sketch",
      oil_painting: "Oil Painting",
      watercolor: "Watercolor",
      digital_art: "Digital Art",
    },
    privateLabel: "Private",
    publicLabel: "Public",
    privateDesc: "Only visible to you",
    publicDesc: "Visible to everyone",
    ratios: {
      "1:1": "Square",
      "16:9": "Landscape",
      "9:16": "Portrait",
      "4:3": "Standard",
      "3:4": "Portrait",
      "3:2": "Camera",
      "2:3": "Poster",
    },
    models: {
      grok: { label: "Grok", desc: "By xAI — fast and highly creative", badge: "Fast" },
      meta: { label: "Meta AI", desc: "Meta Llama image generation model", badge: "Free" },
      "imagen-pro": { label: "Imagen 3 Pro", desc: "Google high-quality image model", badge: "Pro" },
      "imagen-4": { label: "Imagen 4", desc: "Google's latest generation model", badge: "New" },
      "imagen-flash": { label: "Imagen Flash", desc: "Google ultra-fast version", badge: "Fast" },
      "nano-banana-pro": { label: "Nano Banana Pro", desc: "New Banana model — free for all users", badge: "Free" },
      "nano-banana-2": { label: "Nano Banana 2", desc: "Banana 2nd generation — upgraded", badge: "Free" },
    },
    historyImages: "Images",
    historyVideos: "Videos",
    historyTabAll: "All",
    historyTabPublic: "Public",
    historyTabPrivate: "Private",
    historyEmptyImages: "No images generated yet",
    historyEmptyImagesDesc: "Nothing here yet. Go to the creation page, enter your ideas, and start your artistic journey.",
    historyEmptyVideos: "No videos generated yet",
    historyEmptyVideosDesc: "Head to the video generation page and let AI create amazing videos for you.",
    historyNoItemsInFilter: "No items in this category",
    historyDeleteImgTitle: "Delete image?",
    historyDeleteImgDesc: "This cannot be undone. Are you sure you want to delete this image?",
    historyDeleteVidTitle: "Delete video?",
    historyDeleteVidDesc: "This cannot be undone. Are you sure you want to delete this video?",
    historyDeletedImg: "Image deleted",
    historyDeletedVid: "Video deleted",
    historyDeleteFailed: "Delete failed, please try again",
    historyConfirmDelete: "Confirm Delete",
    historyDownload: "Download",
    historyLoadingVideos: "Loading video history...",
    navVideo: "Video",
    videoTitle: "Video Generation",
    videoSubtitle: "Describe your scene and let AI generate a 6-second clip",
    videoModel: "Model",
    videoModelValue: "Grok-3 Video",
    videoDuration: "Duration",
    videoDurationValue: "6 sec",
    videoPromptLabel: "Description",
    videoPromptPlaceholder: "Describe the video you want, e.g.: a cat playing in a meadow...",
    videoBtnGenerate: "Generate Video",
    videoBtnGenerating: "Generating...",
    videoEmptyTitle: "Waiting for your idea",
    videoEmptySubtitle: "Enter a description and click generate",
    videoLoadingTitle: "Generating video...",
    videoLoadingSubtitle: "Grok-3 video generation takes about 1–3 minutes",
    videoErrorTitle: "Generation Failed",
    videoErrorDesc: "Please verify your token is valid or try again later",
    videoHistoryTitle: "Video History",
    videoHistoryEmpty: "No videos yet",
    videoDelete: "Delete",
    videoDownload: "Download",
    videoDeleteSuccess: "Video deleted",
    videoDeleteFailed: "Delete failed",
    videoGenSuccess: "Video generated successfully!",
    videoGenFailed: "Video generation failed",
    videoPrivateLabel: "Private",
    videoPublicLabel: "Public",
    videoRefImageLabel: "Reference Image (Image-to-Video)",
    videoRefImageBadge: "Optional",
    videoRefImageDrop: "Drag & drop or click to upload",
    videoRefImageFormats: "JPG / PNG / WebP",
    videoRefImageRemove: "Remove",
    videoModeText: "Text-to-Video",
    videoModeImage: "Image-to-Video",
    videoPhaseSubmitting: "Submitting task...",
    videoPhaseGettingCaptcha: "Getting captcha...",
    videoPhaseConnecting: "Connecting to service...",
    videoPhaseGenerating: "AI is generating video",
    videoPhaseProcessing: "Processing...",
    videoDone: "Video generation complete!",
    videoGeneratingHint: "Video generation usually takes 1–5 minutes. Closing this window won't stop generation.",
    videoConnectionFailed: "Connection lost. Please verify your token is valid and try again.",
    videoPhaseSubmitLabel: "Submit",
    videoPhaseTurnstileLabel: "Captcha",
    videoPhaseConnectLabel: "Connect",
    videoPhaseGenerateLabel: "Generate",
    videoModelGrokSub: "xAI · Fastest",
    videoModelGrokDesc: "Up to 6s · Up to 720p",
    videoModelVeoSub: "Google · High Quality",
    videoModelVeoDesc: "Fixed 8s · 16:9 / 9:16",
    videoVeoTimingNote: "Veo 3.1 Fast takes about 2–4 minutes — slightly longer than Grok-3",
    videoVeoNotSupported: "Not supported by Veo",
    videoGrokNotSupported: "Not supported by Grok-3",
    videoGrokMaxTime: "Grok-3 max 6 sec",
    videoVeoFixedTime: "Veo fixed 8 sec",
    videoGrokMaxRes: "Grok-3 max 720p",
    videoAdvanced: "Advanced Settings",
    videoNegativePromptLabel: "Negative Prompt",
    videoEnhancePromptLabel: "Enhance Prompt with AI",
    videoClose: "Close",
    videoComplete: "Video generation complete",
    videoElapsed: "Elapsed",
    tokenExpiredTitle: "Refresh Token expired — image generation unavailable",
    tokenExpiredDesc: "Please log in to geminigen.ai again to get a new refresh_token, then go to",
    tokenExpiredLink: "Admin Settings",
    tokenExpiredSuffix: "→ System Config to update the token.",
    tokenExpiredFallback: "Token expired",
    tokenErrorTitle: "Image generation failed",
    adminTokenTitle: "Update geminigen.ai Access Token",
    adminTokenDesc: "When the token expires (video generation shows \"Token has been expired\"), paste a new Bearer Token from geminigen.ai.",
    adminTokenHowTo: "How to get it: Log in to geminigen.ai → F12 → Network → any request → Headers → copy the value after",
    adminTokenUpdate: "Update",
    adminTokenSuccess: "✅ Access Token updated! Video generation should be working again.",
    adminPlaywrightTitle: "Self-hosted Playwright Solver (Free · Priority)",
    adminPlaywrightDesc: "Deploy a Turnstile solver to Vercel and enter the URL below. Free — takes priority over CapSolver.",
    adminPlaywrightStepsLabel: "Deployment steps:",
    adminPlaywrightStep1: "Upload artifacts/turnstile-solver/ to a GitHub repository",
    adminPlaywrightStep2: "Create a new project on Vercel and import the repo",
    adminPlaywrightStep3: "After deployment, copy the URL (e.g. https://xxx.vercel.app)",
    adminPlaywrightStep4: "Enter https://xxx.vercel.app/api/solve below",
    adminPlaywrightSecretPlaceholder: "SOLVER_SECRET (optional, if set as a Vercel env var)",
    adminTestConn: "Test Connection",
    adminSave: "Save",
    adminPlaywrightSuccess: "✅ Playwright solver URL saved!",
    adminYesCaptchaTitle: "YesCaptcha API Key (free credits)",
    adminYesCaptchaDesc: "New accounts get free credits. Supports Cloudflare Turnstile. Price ~$1 / 1,000 solves — cheaper than CapSolver.",
    adminYesCaptchaHowTo: "How to get it: Sign up at yescaptcha.com → Dashboard → API Key",
    adminYesCaptchaSet: "Set",
    adminYesCaptchaSuccess: "✅ YesCaptcha API Key saved!",
    adminCapSolverTitle: "CapSolver API Key (paid fallback)",
    adminCapSolverDesc: "Automatically falls back to CapSolver when YesCaptcha fails. Price ~$2 / 1,000 solves.",
    adminCapSolverHowTo: "How to get it: Sign up at capsolver.com → Dashboard → API Key",
    adminCapSolverSet: "Set",
    adminCapSolverSuccess: "✅ CapSolver API Key saved! Turnstile will now be auto-solved.",
    adminSaveFailed: "Update failed",
    adminTestSuccess: "Test passed! Token prefix",
    adminTestFailed: "Test failed",
    adminConnectFailed: "Connection failed",
  },
} as const;

export type Translations = typeof translations.zh;