Mayo commited on
Commit
43cad16
·
unverified ·
1 Parent(s): 92e816e

refactor: i18n

Browse files
bun.lock CHANGED
@@ -32,6 +32,8 @@
32
  "class-variance-authority": "^0.7.1",
33
  "clsx": "^2.1.1",
34
  "i18next": "^25.8.0",
 
 
35
  "lucide-react": "^0.563.0",
36
  "next": "^16.1.4",
37
  "radix-ui": "^1.4.3",
@@ -472,6 +474,10 @@
472
 
473
  "i18next": ["i18next@25.8.0", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-urrg4HMFFMQZ2bbKRK7IZ8/CTE7D8H4JRlAwqA2ZwDRFfdd0K/4cdbNNLgfn9mo+I/h9wJu61qJzH7jCFAhUZQ=="],
474
 
 
 
 
 
475
  "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
476
 
477
  "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
 
32
  "class-variance-authority": "^0.7.1",
33
  "clsx": "^2.1.1",
34
  "i18next": "^25.8.0",
35
+ "i18next-browser-languagedetector": "^8.2.0",
36
+ "i18next-localstorage-backend": "^4.3.1",
37
  "lucide-react": "^0.563.0",
38
  "next": "^16.1.4",
39
  "radix-ui": "^1.4.3",
 
474
 
475
  "i18next": ["i18next@25.8.0", "", { "dependencies": { "@babel/runtime": "^7.28.4" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-urrg4HMFFMQZ2bbKRK7IZ8/CTE7D8H4JRlAwqA2ZwDRFfdd0K/4cdbNNLgfn9mo+I/h9wJu61qJzH7jCFAhUZQ=="],
476
 
477
+ "i18next-browser-languagedetector": ["i18next-browser-languagedetector@8.2.0", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g=="],
478
+
479
+ "i18next-localstorage-backend": ["i18next-localstorage-backend@4.3.1", "", { "dependencies": { "@babel/runtime": "^7.28.4" } }, "sha512-ry8WNBanUs55rsRZs9+xaZWRxCoTEMMOf+2vNSfzzJqDPbHaf0eMFMrtYp/2ocxU6Xrxfwz17Fdz0rSs3Kw39Q=="],
480
+
481
  "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
482
 
483
  "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
package.json CHANGED
@@ -12,7 +12,8 @@
12
  "dev": "bun run setup tauri dev",
13
  "build": "bun run setup tauri build",
14
  "cargo": "bun run setup cargo",
15
- "prepare": "husky"
 
16
  },
17
  "workspaces": [
18
  "ui/"
 
12
  "dev": "bun run setup tauri dev",
13
  "build": "bun run setup tauri build",
14
  "cargo": "bun run setup cargo",
15
+ "prepare": "husky",
16
+ "format": "prettier --write ui/ --ignore-path ui/.gitignore"
17
  },
18
  "workspaces": [
19
  "ui/"
ui/app/layout.tsx CHANGED
@@ -2,7 +2,6 @@ import type { Metadata } from 'next'
2
  import { Noto_Sans_JP } from 'next/font/google'
3
  import './globals.css'
4
  import Providers from '@/app/providers'
5
- import { defaultLocale } from '@/lib/i18n'
6
 
7
  const notoSansJP = Noto_Sans_JP({
8
  subsets: ['latin'],
@@ -18,7 +17,7 @@ function RootLayout({
18
  children: React.ReactNode
19
  }>) {
20
  return (
21
- <html lang={defaultLocale}>
22
  <body
23
  className={`${notoSansJP.className} antialiased`}
24
  suppressHydrationWarning
 
2
  import { Noto_Sans_JP } from 'next/font/google'
3
  import './globals.css'
4
  import Providers from '@/app/providers'
 
5
 
6
  const notoSansJP = Noto_Sans_JP({
7
  subsets: ['latin'],
 
17
  children: React.ReactNode
18
  }>) {
19
  return (
20
+ <html lang='en-US'>
21
  <body
22
  className={`${notoSansJP.className} antialiased`}
23
  suppressHydrationWarning
ui/app/page.tsx CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import { MenuBar } from '@/components/MenuBar'
2
  import { Panels } from '@/components/Panels'
3
  import { Workspace, StatusBar } from '@/components/Canvas'
 
1
+ 'use client'
2
+
3
  import { MenuBar } from '@/components/MenuBar'
4
  import { Panels } from '@/components/Panels'
5
  import { Workspace, StatusBar } from '@/components/Canvas'
ui/app/providers.tsx CHANGED
@@ -1,18 +1,14 @@
1
  'use client'
2
 
3
- import { useEffect, type ReactNode } from 'react'
4
  import { I18nextProvider } from 'react-i18next'
5
  import { TooltipProvider } from '@/components/ui/tooltip'
6
  import { invoke, listen } from '@/lib/backend'
7
- import i18n, {
8
- getPreferredLocale,
9
- locales,
10
- persistLocale,
11
- type LocaleCode,
12
- } from '@/lib/i18n'
13
  import { useAppStore } from '@/lib/store'
14
 
15
  export function Providers({ children }: { children: ReactNode }) {
 
16
  const setTotalPages = useAppStore((state) => state.setTotalPages)
17
 
18
  useEffect(() => {
@@ -38,17 +34,10 @@ export function Providers({ children }: { children: ReactNode }) {
38
  }, [setTotalPages])
39
 
40
  useEffect(() => {
41
- const preferred = getPreferredLocale()
42
- if (preferred && preferred !== i18n.language) {
43
- void i18n.changeLanguage(preferred)
44
- }
45
 
46
  const handleLanguageChange = (lng: string) => {
47
- const nextLocale: LocaleCode = locales.includes(lng as LocaleCode)
48
- ? (lng as LocaleCode)
49
- : locales[0]
50
- document.documentElement.lang = nextLocale
51
- persistLocale(nextLocale)
52
  }
53
 
54
  handleLanguageChange(i18n.language)
@@ -58,6 +47,8 @@ export function Providers({ children }: { children: ReactNode }) {
58
  }
59
  }, [])
60
 
 
 
61
  return (
62
  <I18nextProvider i18n={i18n}>
63
  <TooltipProvider delayDuration={300}>{children}</TooltipProvider>
 
1
  'use client'
2
 
3
+ import { useEffect, useState, type ReactNode } from 'react'
4
  import { I18nextProvider } from 'react-i18next'
5
  import { TooltipProvider } from '@/components/ui/tooltip'
6
  import { invoke, listen } from '@/lib/backend'
7
+ import i18n from '@/lib/i18n'
 
 
 
 
 
8
  import { useAppStore } from '@/lib/store'
9
 
10
  export function Providers({ children }: { children: ReactNode }) {
11
+ const [mounted, setMounted] = useState(false)
12
  const setTotalPages = useAppStore((state) => state.setTotalPages)
13
 
14
  useEffect(() => {
 
34
  }, [setTotalPages])
35
 
36
  useEffect(() => {
37
+ setMounted(true)
 
 
 
38
 
39
  const handleLanguageChange = (lng: string) => {
40
+ document.documentElement.lang = lng
 
 
 
 
41
  }
42
 
43
  handleLanguageChange(i18n.language)
 
47
  }
48
  }, [])
49
 
50
+ if (!mounted) return null
51
+
52
  return (
53
  <I18nextProvider i18n={i18n}>
54
  <TooltipProvider delayDuration={300}>{children}</TooltipProvider>
ui/components/MenuBar.tsx CHANGED
@@ -1,10 +1,9 @@
1
  'use client'
2
 
3
- import { useEffect, useState } from 'react'
4
  import { invoke } from '@/lib/backend'
5
  import { useTranslation } from 'react-i18next'
6
  import { useAppStore } from '@/lib/store'
7
- import { locales } from '@/lib/i18n'
8
  import { fitCanvasToViewport, resetCanvasScale } from '@/components/Canvas'
9
  import {
10
  Menubar,
@@ -24,6 +23,10 @@ type MenuItem = {
24
 
25
  export function MenuBar() {
26
  const { t, i18n } = useTranslation()
 
 
 
 
27
  const [appVersion, setAppVersion] = useState<string>()
28
  const {
29
  openDocuments,
@@ -144,7 +147,7 @@ export function MenuBar() {
144
  }
145
  }}
146
  >
147
- {locales.map((code: string) => (
148
  <MenubarRadioItem
149
  key={code}
150
  value={code}
 
1
  'use client'
2
 
3
+ import { useEffect, useState, useMemo } from 'react'
4
  import { invoke } from '@/lib/backend'
5
  import { useTranslation } from 'react-i18next'
6
  import { useAppStore } from '@/lib/store'
 
7
  import { fitCanvasToViewport, resetCanvasScale } from '@/components/Canvas'
8
  import {
9
  Menubar,
 
23
 
24
  export function MenuBar() {
25
  const { t, i18n } = useTranslation()
26
+ const locales = useMemo(
27
+ () => Object.keys(i18n.options.resources || {}),
28
+ [i18n.options.resources],
29
+ )
30
  const [appVersion, setAppVersion] = useState<string>()
31
  const {
32
  openDocuments,
 
147
  }
148
  }}
149
  >
150
+ {locales.map((code) => (
151
  <MenubarRadioItem
152
  key={code}
153
  value={code}
ui/lib/i18n.ts CHANGED
@@ -2,16 +2,13 @@
2
 
3
  import i18n, { type Resource } from 'i18next'
4
  import { initReactI18next } from 'react-i18next'
5
- import enUS from '../public/locales/en-US/translation.json'
6
- import zhCN from '../public/locales/zh-CN/translation.json'
7
- import zhTW from '../public/locales/zh-TW/translation.json'
8
- import jaJP from '../public/locales/ja-JP/translation.json'
9
 
10
- export const locales = ['en-US', 'zh-CN', 'zh-TW', 'ja-JP'] as const
11
- export type LocaleCode = (typeof locales)[number]
12
- export const defaultLocale: LocaleCode = 'en-US'
13
-
14
- const STORAGE_KEY = 'koharu-language'
15
 
16
  const resources = {
17
  'en-US': { translation: enUS },
@@ -20,47 +17,21 @@ const resources = {
20
  'ja-JP': { translation: jaJP },
21
  } satisfies Resource
22
 
23
- const detectLocale = (): LocaleCode => defaultLocale
24
-
25
- if (!i18n.isInitialized) {
26
- void i18n.use(initReactI18next).init({
 
27
  resources,
28
- lng: detectLocale(),
29
- fallbackLng: defaultLocale,
30
- supportedLngs: locales,
31
- interpolation: { escapeValue: false },
32
- returnEmptyString: false,
33
- react: { useSuspense: false },
34
- defaultNS: 'translation',
35
- })
36
- }
37
 
38
- export const getPreferredLocale = (): LocaleCode | undefined => {
39
- if (typeof window === 'undefined') return undefined
 
 
40
 
41
- try {
42
- const stored = localStorage.getItem(STORAGE_KEY) as LocaleCode | null
43
- if (stored && locales.includes(stored)) return stored
44
- } catch (_) {}
45
-
46
- const browser = (navigator.language || '').toLowerCase()
47
- if (browser.startsWith('zh')) {
48
- return browser.includes('tw') ||
49
- browser.includes('hk') ||
50
- browser.includes('mo')
51
- ? 'zh-TW'
52
- : 'zh-CN'
53
- }
54
- if (browser.startsWith('ja')) return 'ja-JP'
55
- const exact = locales.find((locale) => locale.toLowerCase() === browser)
56
- return exact
57
- }
58
-
59
- export const persistLocale = (locale: LocaleCode) => {
60
- if (!locales.includes(locale)) return
61
- try {
62
- localStorage.setItem(STORAGE_KEY, locale)
63
- } catch (_) {}
64
- }
65
 
66
  export default i18n
 
2
 
3
  import i18n, { type Resource } from 'i18next'
4
  import { initReactI18next } from 'react-i18next'
5
+ import LanguageDetector from 'i18next-browser-languagedetector'
6
+ import LocalStorageBackend from 'i18next-localstorage-backend'
 
 
7
 
8
+ import enUS from '@/public/locales/en-US/translation.json'
9
+ import zhCN from '@/public/locales/zh-CN/translation.json'
10
+ import zhTW from '@/public/locales/zh-TW/translation.json'
11
+ import jaJP from '@/public/locales/ja-JP/translation.json'
 
12
 
13
  const resources = {
14
  'en-US': { translation: enUS },
 
17
  'ja-JP': { translation: jaJP },
18
  } satisfies Resource
19
 
20
+ i18n
21
+ .use(LocalStorageBackend)
22
+ .use(LanguageDetector)
23
+ .use(initReactI18next)
24
+ .init({
25
  resources,
 
 
 
 
 
 
 
 
 
26
 
27
+ fallbackLng: 'en-US',
28
+ interpolation: {
29
+ escapeValue: false, // not needed for react as it escapes by default
30
+ },
31
 
32
+ react: {
33
+ useSuspense: false,
34
+ },
35
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  export default i18n
ui/package.json CHANGED
@@ -5,8 +5,7 @@
5
  "scripts": {
6
  "dev": "next dev",
7
  "build": "next build",
8
- "start": "next start",
9
- "lint": "eslint"
10
  },
11
  "dependencies": {
12
  "@radix-ui/react-accordion": "^1.2.12",
@@ -25,6 +24,8 @@
25
  "class-variance-authority": "^0.7.1",
26
  "clsx": "^2.1.1",
27
  "i18next": "^25.8.0",
 
 
28
  "lucide-react": "^0.563.0",
29
  "next": "^16.1.4",
30
  "radix-ui": "^1.4.3",
 
5
  "scripts": {
6
  "dev": "next dev",
7
  "build": "next build",
8
+ "start": "next start"
 
9
  },
10
  "dependencies": {
11
  "@radix-ui/react-accordion": "^1.2.12",
 
24
  "class-variance-authority": "^0.7.1",
25
  "clsx": "^2.1.1",
26
  "i18next": "^25.8.0",
27
+ "i18next-browser-languagedetector": "^8.2.0",
28
+ "i18next-localstorage-backend": "^4.3.1",
29
  "lucide-react": "^0.563.0",
30
  "next": "^16.1.4",
31
  "radix-ui": "^1.4.3",
ui/postcss.config.mjs CHANGED
@@ -1,7 +1,7 @@
1
  const config = {
2
  plugins: {
3
- "@tailwindcss/postcss": {},
4
  },
5
- };
6
 
7
- export default config;
 
1
  const config = {
2
  plugins: {
3
+ '@tailwindcss/postcss': {},
4
  },
5
+ }
6
 
7
+ export default config
ui/public/locales/en-US/translation.json CHANGED
@@ -1,147 +1,147 @@
1
- {
2
- "common": {
3
- "initializing": "Initializing..."
4
- },
5
- "menu": {
6
- "file": "File",
7
- "openFile": "Open File...",
8
- "save": "Save...",
9
- "export": "Export...",
10
- "view": "View",
11
- "fitWindow": "Fit Window",
12
- "originalSize": "Original Size",
13
- "process": "Process",
14
- "processCurrent": "Process current image",
15
- "redoInpaintRender": "Redo inpaint and render",
16
- "processAll": "Process all images",
17
- "help": "Help",
18
- "discord": "Discord",
19
- "github": "GitHub",
20
- "version": "Version: {{version}}",
21
- "versionUnknown": "Version: Unknown",
22
- "language": "Language",
23
- "languages": {
24
- "en-US": "English",
25
- "zh-CN": "简体中文",
26
- "zh-TW": "繁體中文",
27
- "ja-JP": "日本語"
28
- }
29
- },
30
- "operations": {
31
- "title": "Working",
32
- "inProgress": "Please wait while we finish up.",
33
- "loadKhr": "Loading project",
34
- "saveKhr": "Saving project",
35
- "loadModel": "Loading LLM model",
36
- "processCurrent": "Processing current image",
37
- "processAll": "Processing all images",
38
- "imageProgress": "Image {{current}} / {{total}}",
39
- "stepProgress": "Step {{current}} / {{total}}: {{step}}",
40
- "cancel": "Stop",
41
- "cancelling": "Stopping..."
42
- },
43
- "navigator": {
44
- "title": "Navigator",
45
- "pages_one": "{{count}} page",
46
- "pages_other": "{{count}} pages",
47
- "empty": "No documents",
48
- "prompt": "Select or import a page to begin"
49
- },
50
- "panels": {
51
- "processing": "Processing",
52
- "mask": "Mask",
53
- "llm": "LLM",
54
- "render": "Render"
55
- },
56
- "processing": {
57
- "detect": "Detect",
58
- "detectTooltip": "Run text detection on current page",
59
- "ocr": "OCR",
60
- "ocrTooltip": "Recognize text for detected regions",
61
- "render": "Render"
62
- },
63
- "mask": {
64
- "showSegmentationMask": "Show segmentation mask",
65
- "showInpainted": "Show inpainted image",
66
- "showBrushLayer": "Show brush layer",
67
- "showRendered": "Show rendered text",
68
- "showTextBlocks": "Show text blocks",
69
- "inpaint": "Inpaint",
70
- "inpaintTooltip": "Apply inpainting"
71
- },
72
- "llm": {
73
- "title": "LLM",
74
- "ready": "Ready",
75
- "idle": "Idle",
76
- "selectPlaceholder": "Select model",
77
- "modelLabel": "Model",
78
- "openaiCompatible": "OpenAI Compatible",
79
- "openaiEndpointLabel": "OpenAI compatible endpoint",
80
- "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
- "openaiApiKeyLabel": "API key",
82
- "openaiApiKeyPlaceholder": "sk-...",
83
- "openaiModelLabel": "Model name",
84
- "openaiModelPlaceholder": "gpt-4o-mini",
85
- "openaiPromptLabel": "Prompt",
86
- "openaiPromptPlaceholder": "Translate the following text to Chinese, retain formatting, do not add extra explanations:\n",
87
- "languageLabel": "Target language",
88
- "languagePlaceholder": "Select language",
89
- "load": "Load",
90
- "unload": "Unload",
91
- "loadTooltip": "Load selected model",
92
- "unloadTooltip": "Unload model",
93
- "generate": "Generate",
94
- "generating": "Generating...",
95
- "generateTooltip": "Generate translations for detected text blocks",
96
- "render": "Render text",
97
- "renderTooltip": "Render translations onto the page",
98
- "loadingModel": "Loading LLM model",
99
- "statusReady": "LLM Ready",
100
- "statusIdle": "LLM Not Loaded"
101
- },
102
- "render": {
103
- "effectLabel": "Text effect",
104
- "effectNormal": "Normal",
105
- "effectAntique": "Antique book",
106
- "effectMetal": "Metal",
107
- "effectManga": "Manga tone",
108
- "effectMotionBlur": "Motion blur",
109
- "fontLabel": "Font",
110
- "fontPlaceholder": "Select font",
111
- "fontColorLabel": "Font color",
112
- "fontScopeGlobal": "Global",
113
- "fontScopeBlock": "Per block",
114
- "fontScopeBlockIndex": "Block {{index}}"
115
- },
116
- "textBlocks": {
117
- "emptyPrompt": "Open an image to see text blocks.",
118
- "title": "Text Blocks ({{count}})",
119
- "none": "No text blocks yet. Run detection to populate the list.",
120
- "emptySummary": "<empty>",
121
- "ocrLabel": "OCR text",
122
- "translationLabel": "Translation",
123
- "addOcrPlaceholder": "Add OCR text",
124
- "addTranslationPlaceholder": "Add translation"
125
- },
126
- "workspace": {
127
- "importPrompt": "Import a page to begin editing.",
128
- "deleteBlock": "Delete block"
129
- },
130
- "statusBar": {
131
- "zoom": "Zoom",
132
- "canvas": "Canvas"
133
- },
134
- "toolbar": {
135
- "brush": "Brush",
136
- "eraser": "Eraser",
137
- "brushSize": "Brush size",
138
- "brushColor": "Brush color"
139
- },
140
- "toolRail": {
141
- "select": "Select",
142
- "block": "Block",
143
- "brush": "Brush",
144
- "repairBrush": "Repair brush",
145
- "eraser": "Eraser"
146
- }
147
- }
 
1
+ {
2
+ "common": {
3
+ "initializing": "Initializing..."
4
+ },
5
+ "menu": {
6
+ "file": "File",
7
+ "openFile": "Open File...",
8
+ "save": "Save...",
9
+ "export": "Export...",
10
+ "view": "View",
11
+ "fitWindow": "Fit Window",
12
+ "originalSize": "Original Size",
13
+ "process": "Process",
14
+ "processCurrent": "Process current image",
15
+ "redoInpaintRender": "Redo inpaint and render",
16
+ "processAll": "Process all images",
17
+ "help": "Help",
18
+ "discord": "Discord",
19
+ "github": "GitHub",
20
+ "version": "Version: {{version}}",
21
+ "versionUnknown": "Version: Unknown",
22
+ "language": "Language",
23
+ "languages": {
24
+ "en-US": "English",
25
+ "zh-CN": "简体中文",
26
+ "zh-TW": "繁體中文",
27
+ "ja-JP": "日本語"
28
+ }
29
+ },
30
+ "operations": {
31
+ "title": "Working",
32
+ "inProgress": "Please wait while we finish up.",
33
+ "loadKhr": "Loading project",
34
+ "saveKhr": "Saving project",
35
+ "loadModel": "Loading LLM model",
36
+ "processCurrent": "Processing current image",
37
+ "processAll": "Processing all images",
38
+ "imageProgress": "Image {{current}} / {{total}}",
39
+ "stepProgress": "Step {{current}} / {{total}}: {{step}}",
40
+ "cancel": "Stop",
41
+ "cancelling": "Stopping..."
42
+ },
43
+ "navigator": {
44
+ "title": "Navigator",
45
+ "pages_one": "{{count}} page",
46
+ "pages_other": "{{count}} pages",
47
+ "empty": "No documents",
48
+ "prompt": "Select or import a page to begin"
49
+ },
50
+ "panels": {
51
+ "processing": "Processing",
52
+ "mask": "Mask",
53
+ "llm": "LLM",
54
+ "render": "Render"
55
+ },
56
+ "processing": {
57
+ "detect": "Detect",
58
+ "detectTooltip": "Run text detection on current page",
59
+ "ocr": "OCR",
60
+ "ocrTooltip": "Recognize text for detected regions",
61
+ "render": "Render"
62
+ },
63
+ "mask": {
64
+ "showSegmentationMask": "Show segmentation mask",
65
+ "showInpainted": "Show inpainted image",
66
+ "showBrushLayer": "Show brush layer",
67
+ "showRendered": "Show rendered text",
68
+ "showTextBlocks": "Show text blocks",
69
+ "inpaint": "Inpaint",
70
+ "inpaintTooltip": "Apply inpainting"
71
+ },
72
+ "llm": {
73
+ "title": "LLM",
74
+ "ready": "Ready",
75
+ "idle": "Idle",
76
+ "selectPlaceholder": "Select model",
77
+ "modelLabel": "Model",
78
+ "openaiCompatible": "OpenAI Compatible",
79
+ "openaiEndpointLabel": "OpenAI compatible endpoint",
80
+ "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
+ "openaiApiKeyLabel": "API key",
82
+ "openaiApiKeyPlaceholder": "sk-...",
83
+ "openaiModelLabel": "Model name",
84
+ "openaiModelPlaceholder": "gpt-4o-mini",
85
+ "openaiPromptLabel": "Prompt",
86
+ "openaiPromptPlaceholder": "Translate the following text to Chinese, retain formatting, do not add extra explanations:\n",
87
+ "languageLabel": "Target language",
88
+ "languagePlaceholder": "Select language",
89
+ "load": "Load",
90
+ "unload": "Unload",
91
+ "loadTooltip": "Load selected model",
92
+ "unloadTooltip": "Unload model",
93
+ "generate": "Generate",
94
+ "generating": "Generating...",
95
+ "generateTooltip": "Generate translations for detected text blocks",
96
+ "render": "Render text",
97
+ "renderTooltip": "Render translations onto the page",
98
+ "loadingModel": "Loading LLM model",
99
+ "statusReady": "LLM Ready",
100
+ "statusIdle": "LLM Not Loaded"
101
+ },
102
+ "render": {
103
+ "effectLabel": "Text effect",
104
+ "effectNormal": "Normal",
105
+ "effectAntique": "Antique book",
106
+ "effectMetal": "Metal",
107
+ "effectManga": "Manga tone",
108
+ "effectMotionBlur": "Motion blur",
109
+ "fontLabel": "Font",
110
+ "fontPlaceholder": "Select font",
111
+ "fontColorLabel": "Font color",
112
+ "fontScopeGlobal": "Global",
113
+ "fontScopeBlock": "Per block",
114
+ "fontScopeBlockIndex": "Block {{index}}"
115
+ },
116
+ "textBlocks": {
117
+ "emptyPrompt": "Open an image to see text blocks.",
118
+ "title": "Text Blocks ({{count}})",
119
+ "none": "No text blocks yet. Run detection to populate the list.",
120
+ "emptySummary": "<empty>",
121
+ "ocrLabel": "OCR text",
122
+ "translationLabel": "Translation",
123
+ "addOcrPlaceholder": "Add OCR text",
124
+ "addTranslationPlaceholder": "Add translation"
125
+ },
126
+ "workspace": {
127
+ "importPrompt": "Import a page to begin editing.",
128
+ "deleteBlock": "Delete block"
129
+ },
130
+ "statusBar": {
131
+ "zoom": "Zoom",
132
+ "canvas": "Canvas"
133
+ },
134
+ "toolbar": {
135
+ "brush": "Brush",
136
+ "eraser": "Eraser",
137
+ "brushSize": "Brush size",
138
+ "brushColor": "Brush color"
139
+ },
140
+ "toolRail": {
141
+ "select": "Select",
142
+ "block": "Block",
143
+ "brush": "Brush",
144
+ "repairBrush": "Repair brush",
145
+ "eraser": "Eraser"
146
+ }
147
+ }
ui/public/locales/ja-JP/translation.json CHANGED
@@ -1,147 +1,147 @@
1
- {
2
- "common": {
3
- "initializing": "初期化中..."
4
- },
5
- "menu": {
6
- "file": "ファイル",
7
- "openFile": "ファイルを開く...",
8
- "save": "保存...",
9
- "export": "エクスポート...",
10
- "view": "表示",
11
- "fitWindow": "ウィンドウに合わせる",
12
- "originalSize": "原寸",
13
- "process": "処理",
14
- "processCurrent": "現在の画像を処理",
15
- "redoInpaintRender": "再インペイントしてレンダー",
16
- "processAll": "すべての画像を処理",
17
- "help": "ヘルプ",
18
- "discord": "Discord",
19
- "github": "GitHub",
20
- "version": "バージョン: {{version}}",
21
- "versionUnknown": "バージョン: 不明",
22
- "language": "言語",
23
- "languages": {
24
- "en-US": "English",
25
- "zh-CN": "简体中文",
26
- "zh-TW": "繁體中文",
27
- "ja-JP": "日本語"
28
- }
29
- },
30
- "operations": {
31
- "title": "処理中",
32
- "inProgress": "処理が完了するまでお待ちください。",
33
- "loadKhr": "プロジェクトを読み込み中",
34
- "saveKhr": "プロジェクトを保存中",
35
- "loadModel": "LLM モデルを読み込み中",
36
- "processCurrent": "現在の画像を処理中",
37
- "processAll": "すべての画像を一括処理中",
38
- "imageProgress": "画像 {{current}} / {{total}}",
39
- "stepProgress": "ステップ {{current}} / {{total}}:{{step}}",
40
- "cancel": "停止",
41
- "cancelling": "停止中..."
42
- },
43
- "navigator": {
44
- "title": "ナビゲーター",
45
- "pages_one": "{{count}} ページ",
46
- "pages_other": "{{count}} ページ",
47
- "empty": "ドキュメントがありません",
48
- "prompt": "ページを選択または読み込んで開始してください"
49
- },
50
- "panels": {
51
- "processing": "処理",
52
- "mask": "マスク",
53
- "llm": "LLM",
54
- "render": "レンダー"
55
- },
56
- "processing": {
57
- "detect": "検出",
58
- "detectTooltip": "現在のページでテキスト検出を実行",
59
- "ocr": "OCR",
60
- "ocrTooltip": "検出された領域のテキストを認識",
61
- "render": "レンダー"
62
- },
63
- "mask": {
64
- "showSegmentationMask": "セグメンテーションマスクを表示",
65
- "showInpainted": "インペイント画像を表示",
66
- "showBrushLayer": "ブラシレイヤーを表示",
67
- "showRendered": "レンダー済みテキストを表示",
68
- "showTextBlocks": "テキスト枠を表示",
69
- "inpaint": "インペイント",
70
- "inpaintTooltip": "インペイントを適用"
71
- },
72
- "llm": {
73
- "title": "LLM",
74
- "ready": "準備完了",
75
- "idle": "待機中",
76
- "selectPlaceholder": "モデルを選択",
77
- "modelLabel": "モデル",
78
- "openaiCompatible": "OpenAI 互換サービス",
79
- "openaiEndpointLabel": "OpenAI 端点",
80
- "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
- "openaiApiKeyLabel": "API キー",
82
- "openaiApiKeyPlaceholder": "sk-...",
83
- "openaiModelLabel": "モデル名",
84
- "openaiModelPlaceholder": "gpt-4o-mini",
85
- "openaiPromptLabel": "プロンプト",
86
- "openaiPromptPlaceholder": "以下のテキストを日本語に翻訳し、フォーマットを保持し、追加の説明を加えないでください:\n",
87
- "languageLabel": "翻訳先の言語",
88
- "languagePlaceholder": "言語を選択",
89
- "load": "読み込み",
90
- "unload": "解放",
91
- "loadTooltip": "選択したモデルを読み込む",
92
- "unloadTooltip": "モデルを解放する",
93
- "generate": "生成",
94
- "generating": "生成中...",
95
- "generateTooltip": "検出されたテキストブロックを翻訳する",
96
- "render": "テキストをレンダー",
97
- "renderTooltip": "翻訳をページにレンダー",
98
- "loadingModel": "LLM モデルを読み込み中",
99
- "statusReady": "LLM 準備完了",
100
- "statusIdle": "LLM 未読み込み"
101
- },
102
- "render": {
103
- "effectLabel": "文字効果",
104
- "effectNormal": "標準",
105
- "effectAntique": "古書風",
106
- "effectMetal": "メタル",
107
- "effectManga": "漫画トーン",
108
- "effectMotionBlur": "モーションブラー",
109
- "fontLabel": "フォント",
110
- "fontPlaceholder": "フォントを選択",
111
- "fontColorLabel": "フォントカラー",
112
- "fontScopeGlobal": "Global",
113
- "fontScopeBlock": "Per block",
114
- "fontScopeBlockIndex": "Block {{index}}"
115
- },
116
- "textBlocks": {
117
- "emptyPrompt": "画像を開くとテキストブロックが表示されます。",
118
- "title": "テキストブロック({{count}})",
119
- "none": "まだテキストブロックがありません。検出を実行してください。",
120
- "emptySummary": "<空>",
121
- "ocrLabel": "OCR テキスト",
122
- "translationLabel": "翻訳",
123
- "addOcrPlaceholder": "OCR テキストを追加",
124
- "addTranslationPlaceholder": "翻訳を追加"
125
- },
126
- "workspace": {
127
- "importPrompt": "ページを読み込んで編集を開始してください。",
128
- "deleteBlock": "ブロックを削除"
129
- },
130
- "statusBar": {
131
- "zoom": "ズーム",
132
- "canvas": "キャンバス"
133
- },
134
- "toolbar": {
135
- "brush": "ブラシ",
136
- "eraser": "消しゴム",
137
- "brushSize": "ブラシサイズ",
138
- "brushColor": "ブラシカラー"
139
- },
140
- "toolRail": {
141
- "select": "選択",
142
- "block": "ブロック",
143
- "brush": "ブラシ",
144
- "repairBrush": "リペアブラシ",
145
- "eraser": "消しゴム"
146
- }
147
- }
 
1
+ {
2
+ "common": {
3
+ "initializing": "初期化中..."
4
+ },
5
+ "menu": {
6
+ "file": "ファイル",
7
+ "openFile": "ファイルを開く...",
8
+ "save": "保存...",
9
+ "export": "エクスポート...",
10
+ "view": "表示",
11
+ "fitWindow": "ウィンドウに合わせる",
12
+ "originalSize": "原寸",
13
+ "process": "処理",
14
+ "processCurrent": "現在の画像を処理",
15
+ "redoInpaintRender": "再インペイントしてレンダー",
16
+ "processAll": "すべての画像を処理",
17
+ "help": "ヘルプ",
18
+ "discord": "Discord",
19
+ "github": "GitHub",
20
+ "version": "バージョン: {{version}}",
21
+ "versionUnknown": "バージョン: 不明",
22
+ "language": "言語",
23
+ "languages": {
24
+ "en-US": "English",
25
+ "zh-CN": "简体中文",
26
+ "zh-TW": "繁體中文",
27
+ "ja-JP": "日本語"
28
+ }
29
+ },
30
+ "operations": {
31
+ "title": "処理中",
32
+ "inProgress": "処理が完了するまでお待ちください。",
33
+ "loadKhr": "プロジェクトを読み込み中",
34
+ "saveKhr": "プロジェクトを保存中",
35
+ "loadModel": "LLM モデルを読み込み中",
36
+ "processCurrent": "現在の画像を処理中",
37
+ "processAll": "すべての画像を一括処理中",
38
+ "imageProgress": "画像 {{current}} / {{total}}",
39
+ "stepProgress": "ステップ {{current}} / {{total}}:{{step}}",
40
+ "cancel": "停止",
41
+ "cancelling": "停止中..."
42
+ },
43
+ "navigator": {
44
+ "title": "ナビゲーター",
45
+ "pages_one": "{{count}} ページ",
46
+ "pages_other": "{{count}} ページ",
47
+ "empty": "ドキュメントがありません",
48
+ "prompt": "ページを選択または読み込んで開始してください"
49
+ },
50
+ "panels": {
51
+ "processing": "処理",
52
+ "mask": "マスク",
53
+ "llm": "LLM",
54
+ "render": "レンダー"
55
+ },
56
+ "processing": {
57
+ "detect": "検出",
58
+ "detectTooltip": "現在のページでテキスト検出を実行",
59
+ "ocr": "OCR",
60
+ "ocrTooltip": "検出された領域のテキストを認識",
61
+ "render": "レンダー"
62
+ },
63
+ "mask": {
64
+ "showSegmentationMask": "セグメンテーションマスクを表示",
65
+ "showInpainted": "インペイント画像を表示",
66
+ "showBrushLayer": "ブラシレイヤーを表示",
67
+ "showRendered": "レンダー済みテキストを表示",
68
+ "showTextBlocks": "テキスト枠を表示",
69
+ "inpaint": "インペイント",
70
+ "inpaintTooltip": "インペイントを適用"
71
+ },
72
+ "llm": {
73
+ "title": "LLM",
74
+ "ready": "準備完了",
75
+ "idle": "待機中",
76
+ "selectPlaceholder": "モデルを選択",
77
+ "modelLabel": "モデル",
78
+ "openaiCompatible": "OpenAI 互換サービス",
79
+ "openaiEndpointLabel": "OpenAI 端点",
80
+ "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
+ "openaiApiKeyLabel": "API キー",
82
+ "openaiApiKeyPlaceholder": "sk-...",
83
+ "openaiModelLabel": "モデル名",
84
+ "openaiModelPlaceholder": "gpt-4o-mini",
85
+ "openaiPromptLabel": "プロンプト",
86
+ "openaiPromptPlaceholder": "以下のテキストを日本語に翻訳し、フォーマットを保持し、追加の説明を加えないでください:\n",
87
+ "languageLabel": "翻訳先の言語",
88
+ "languagePlaceholder": "言語を選択",
89
+ "load": "読み込み",
90
+ "unload": "解放",
91
+ "loadTooltip": "選択したモデルを読み込む",
92
+ "unloadTooltip": "モデルを解放する",
93
+ "generate": "生成",
94
+ "generating": "生成中...",
95
+ "generateTooltip": "検出されたテキストブロックを翻訳する",
96
+ "render": "テキストをレンダー",
97
+ "renderTooltip": "翻訳をページにレンダー",
98
+ "loadingModel": "LLM モデルを読み込み中",
99
+ "statusReady": "LLM 準備完了",
100
+ "statusIdle": "LLM 未読み込み"
101
+ },
102
+ "render": {
103
+ "effectLabel": "文字効果",
104
+ "effectNormal": "標準",
105
+ "effectAntique": "古書風",
106
+ "effectMetal": "メタル",
107
+ "effectManga": "漫画トーン",
108
+ "effectMotionBlur": "モーションブラー",
109
+ "fontLabel": "フォント",
110
+ "fontPlaceholder": "フォントを選択",
111
+ "fontColorLabel": "フォントカラー",
112
+ "fontScopeGlobal": "Global",
113
+ "fontScopeBlock": "Per block",
114
+ "fontScopeBlockIndex": "Block {{index}}"
115
+ },
116
+ "textBlocks": {
117
+ "emptyPrompt": "画像を開くとテキストブロックが表示されます。",
118
+ "title": "テキストブロック({{count}})",
119
+ "none": "まだテキストブロックがありません。検出を実行してください。",
120
+ "emptySummary": "<空>",
121
+ "ocrLabel": "OCR テキスト",
122
+ "translationLabel": "翻訳",
123
+ "addOcrPlaceholder": "OCR テキストを追加",
124
+ "addTranslationPlaceholder": "翻訳を追加"
125
+ },
126
+ "workspace": {
127
+ "importPrompt": "ページを読み込んで編集を開始してください。",
128
+ "deleteBlock": "ブロックを削除"
129
+ },
130
+ "statusBar": {
131
+ "zoom": "ズーム",
132
+ "canvas": "キャンバス"
133
+ },
134
+ "toolbar": {
135
+ "brush": "ブラシ",
136
+ "eraser": "消しゴム",
137
+ "brushSize": "ブラシサイズ",
138
+ "brushColor": "ブラシカラー"
139
+ },
140
+ "toolRail": {
141
+ "select": "選択",
142
+ "block": "ブロック",
143
+ "brush": "ブラシ",
144
+ "repairBrush": "リペアブラシ",
145
+ "eraser": "消しゴム"
146
+ }
147
+ }
ui/public/locales/zh-CN/translation.json CHANGED
@@ -1,147 +1,147 @@
1
- {
2
- "common": {
3
- "initializing": "初始化中..."
4
- },
5
- "menu": {
6
- "file": "文件",
7
- "openFile": "打开文件...",
8
- "save": "保存...",
9
- "export": "导出...",
10
- "view": "视图",
11
- "fitWindow": "适应窗口",
12
- "originalSize": "原始大小",
13
- "process": "处理",
14
- "processCurrent": "处理当前图片",
15
- "redoInpaintRender": "重新修补并渲染",
16
- "processAll": "处理所有图片",
17
- "help": "帮助",
18
- "discord": "Discord",
19
- "github": "GitHub",
20
- "version": "版本:{{version}}",
21
- "versionUnknown": "版本:未知",
22
- "language": "语言",
23
- "languages": {
24
- "en-US": "English",
25
- "zh-CN": "简体中文",
26
- "zh-TW": "繁體中文",
27
- "ja-JP": "日本語"
28
- }
29
- },
30
- "operations": {
31
- "title": "处理中",
32
- "inProgress": "请稍候,正在处理。",
33
- "loadKhr": "正在加载项目",
34
- "saveKhr": "正在保存项目",
35
- "loadModel": "正在加载 LLM 模型",
36
- "processCurrent": "正在处理当前图片",
37
- "processAll": "正在批量处理所有图片",
38
- "imageProgress": "图片 {{current}} / {{total}}",
39
- "stepProgress": "步骤 {{current}} / {{total}}:{{step}}",
40
- "cancel": "停止",
41
- "cancelling": "正在停止..."
42
- },
43
- "navigator": {
44
- "title": "导航",
45
- "pages_one": "{{count}} 页",
46
- "pages_other": "{{count}} 页",
47
- "empty": "没有文档",
48
- "prompt": "选择或导入页面开始"
49
- },
50
- "panels": {
51
- "processing": "处理",
52
- "mask": "遮罩",
53
- "llm": "LLM",
54
- "render": "渲染"
55
- },
56
- "processing": {
57
- "detect": "检测",
58
- "detectTooltip": "对当前页面运行文本检测",
59
- "ocr": "识别",
60
- "ocrTooltip": "识别已检测区域中的文本",
61
- "render": "渲染"
62
- },
63
- "mask": {
64
- "showSegmentationMask": "显示分割遮罩",
65
- "showInpainted": "显示修补图像",
66
- "showBrushLayer": "显示笔刷图层",
67
- "showRendered": "显示渲染文本",
68
- "showTextBlocks": "显示文本框",
69
- "inpaint": "修补",
70
- "inpaintTooltip": "执行图像修补"
71
- },
72
- "llm": {
73
- "title": "LLM",
74
- "ready": "就绪",
75
- "idle": "空闲",
76
- "selectPlaceholder": "选择模型",
77
- "modelLabel": "模型",
78
- "openaiCompatible": "OpenAI 兼容服务",
79
- "openaiEndpointLabel": "OpenAI 端点",
80
- "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
- "openaiApiKeyLabel": "API 密钥",
82
- "openaiApiKeyPlaceholder": "sk-...",
83
- "openaiModelLabel": "模型名称",
84
- "openaiModelPlaceholder": "gpt-4o-mini",
85
- "openaiPromptLabel": "提示词",
86
- "openaiPromptPlaceholder": "将下列文本翻译为中文,保留格式,不要添加额外说明:\n",
87
- "languageLabel": "目标语言",
88
- "languagePlaceholder": "选择语言",
89
- "load": "加载",
90
- "unload": "卸载",
91
- "loadTooltip": "加载所选模型",
92
- "unloadTooltip": "卸载当前模型",
93
- "generate": "生成",
94
- "generating": "生成中...",
95
- "generateTooltip": "为检测到的文本块生成翻译",
96
- "render": "渲染文本",
97
- "renderTooltip": "将翻译渲染到页面",
98
- "loadingModel": "正在加载 LLM 模型",
99
- "statusReady": "LLM 已就绪",
100
- "statusIdle": "LLM 未加载"
101
- },
102
- "render": {
103
- "effectLabel": "文字效果",
104
- "effectNormal": "正常",
105
- "effectAntique": "古书质感",
106
- "effectMetal": "金属",
107
- "effectManga": "漫画网点",
108
- "effectMotionBlur": "动态模糊",
109
- "fontLabel": "字体",
110
- "fontPlaceholder": "选择字体",
111
- "fontColorLabel": "字体颜色",
112
- "fontScopeGlobal": "Global",
113
- "fontScopeBlock": "Per block",
114
- "fontScopeBlockIndex": "Block {{index}}"
115
- },
116
- "textBlocks": {
117
- "emptyPrompt": "打开图像以查看文本块。",
118
- "title": "文本块({{count}})",
119
- "none": "尚无文本块。运行检测以填充列表。",
120
- "emptySummary": "<空>",
121
- "ocrLabel": "OCR 文本",
122
- "translationLabel": "翻译",
123
- "addOcrPlaceholder": "添加 OCR 文本",
124
- "addTranslationPlaceholder": "添加翻译"
125
- },
126
- "workspace": {
127
- "importPrompt": "导入页面以开始编辑。",
128
- "deleteBlock": "删除块"
129
- },
130
- "statusBar": {
131
- "zoom": "缩放",
132
- "canvas": "画布"
133
- },
134
- "toolbar": {
135
- "brush": "画笔",
136
- "eraser": "橡皮擦",
137
- "brushSize": "笔刷大小",
138
- "brushColor": "笔刷颜色"
139
- },
140
- "toolRail": {
141
- "select": "选择",
142
- "block": "框选",
143
- "brush": "画笔",
144
- "repairBrush": "修复笔",
145
- "eraser": "橡皮擦"
146
- }
147
- }
 
1
+ {
2
+ "common": {
3
+ "initializing": "初始化中..."
4
+ },
5
+ "menu": {
6
+ "file": "文件",
7
+ "openFile": "打开文件...",
8
+ "save": "保存...",
9
+ "export": "导出...",
10
+ "view": "视图",
11
+ "fitWindow": "适应窗口",
12
+ "originalSize": "原始大小",
13
+ "process": "处理",
14
+ "processCurrent": "处理当前图片",
15
+ "redoInpaintRender": "重新修补并渲染",
16
+ "processAll": "处理所有图片",
17
+ "help": "帮助",
18
+ "discord": "Discord",
19
+ "github": "GitHub",
20
+ "version": "版本:{{version}}",
21
+ "versionUnknown": "版本:未知",
22
+ "language": "语言",
23
+ "languages": {
24
+ "en-US": "English",
25
+ "zh-CN": "简体中文",
26
+ "zh-TW": "繁體中文",
27
+ "ja-JP": "日本語"
28
+ }
29
+ },
30
+ "operations": {
31
+ "title": "处理中",
32
+ "inProgress": "请稍候,正在处理。",
33
+ "loadKhr": "正在加载项目",
34
+ "saveKhr": "正在保存项目",
35
+ "loadModel": "正在加载 LLM 模型",
36
+ "processCurrent": "正在处理当前图片",
37
+ "processAll": "正在批量处理所有图片",
38
+ "imageProgress": "图片 {{current}} / {{total}}",
39
+ "stepProgress": "步骤 {{current}} / {{total}}:{{step}}",
40
+ "cancel": "停止",
41
+ "cancelling": "正在停止..."
42
+ },
43
+ "navigator": {
44
+ "title": "导航",
45
+ "pages_one": "{{count}} 页",
46
+ "pages_other": "{{count}} 页",
47
+ "empty": "没有文档",
48
+ "prompt": "选择或导入页面开始"
49
+ },
50
+ "panels": {
51
+ "processing": "处理",
52
+ "mask": "遮罩",
53
+ "llm": "LLM",
54
+ "render": "渲染"
55
+ },
56
+ "processing": {
57
+ "detect": "检测",
58
+ "detectTooltip": "对当前页面运行文本检测",
59
+ "ocr": "识别",
60
+ "ocrTooltip": "识别已检测区域中的文本",
61
+ "render": "渲染"
62
+ },
63
+ "mask": {
64
+ "showSegmentationMask": "显示分割遮罩",
65
+ "showInpainted": "显示修补图像",
66
+ "showBrushLayer": "显示笔刷图层",
67
+ "showRendered": "显示渲染文本",
68
+ "showTextBlocks": "显示文本框",
69
+ "inpaint": "修补",
70
+ "inpaintTooltip": "执行图像修补"
71
+ },
72
+ "llm": {
73
+ "title": "LLM",
74
+ "ready": "就绪",
75
+ "idle": "空闲",
76
+ "selectPlaceholder": "选择模型",
77
+ "modelLabel": "模型",
78
+ "openaiCompatible": "OpenAI 兼容服务",
79
+ "openaiEndpointLabel": "OpenAI 端点",
80
+ "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
+ "openaiApiKeyLabel": "API 密钥",
82
+ "openaiApiKeyPlaceholder": "sk-...",
83
+ "openaiModelLabel": "模型名称",
84
+ "openaiModelPlaceholder": "gpt-4o-mini",
85
+ "openaiPromptLabel": "提示词",
86
+ "openaiPromptPlaceholder": "将下列文本翻译为中文,保留格式,不要添加额外说明:\n",
87
+ "languageLabel": "目标语言",
88
+ "languagePlaceholder": "选择语言",
89
+ "load": "加载",
90
+ "unload": "卸载",
91
+ "loadTooltip": "加载所选模型",
92
+ "unloadTooltip": "卸载当前模型",
93
+ "generate": "生成",
94
+ "generating": "生成中...",
95
+ "generateTooltip": "为检测到的文本块生成翻译",
96
+ "render": "渲染文本",
97
+ "renderTooltip": "将翻译渲染到页面",
98
+ "loadingModel": "正在加载 LLM 模型",
99
+ "statusReady": "LLM 已就绪",
100
+ "statusIdle": "LLM 未加载"
101
+ },
102
+ "render": {
103
+ "effectLabel": "文字效果",
104
+ "effectNormal": "正常",
105
+ "effectAntique": "古书质感",
106
+ "effectMetal": "金属",
107
+ "effectManga": "漫画网点",
108
+ "effectMotionBlur": "动态模糊",
109
+ "fontLabel": "字体",
110
+ "fontPlaceholder": "选择字体",
111
+ "fontColorLabel": "字体颜色",
112
+ "fontScopeGlobal": "Global",
113
+ "fontScopeBlock": "Per block",
114
+ "fontScopeBlockIndex": "Block {{index}}"
115
+ },
116
+ "textBlocks": {
117
+ "emptyPrompt": "打开图像以查看文本块。",
118
+ "title": "文本块({{count}})",
119
+ "none": "尚无文本块。运行检测以填充列表。",
120
+ "emptySummary": "<空>",
121
+ "ocrLabel": "OCR 文本",
122
+ "translationLabel": "翻译",
123
+ "addOcrPlaceholder": "添加 OCR 文本",
124
+ "addTranslationPlaceholder": "添加翻译"
125
+ },
126
+ "workspace": {
127
+ "importPrompt": "导入页面以开始编辑。",
128
+ "deleteBlock": "删除块"
129
+ },
130
+ "statusBar": {
131
+ "zoom": "缩放",
132
+ "canvas": "画布"
133
+ },
134
+ "toolbar": {
135
+ "brush": "画笔",
136
+ "eraser": "橡皮擦",
137
+ "brushSize": "笔刷大小",
138
+ "brushColor": "笔刷颜色"
139
+ },
140
+ "toolRail": {
141
+ "select": "选择",
142
+ "block": "框选",
143
+ "brush": "画笔",
144
+ "repairBrush": "修复笔",
145
+ "eraser": "橡皮擦"
146
+ }
147
+ }
ui/public/locales/zh-TW/translation.json CHANGED
@@ -1,147 +1,147 @@
1
- {
2
- "common": {
3
- "initializing": "初始化中..."
4
- },
5
- "menu": {
6
- "file": "檔案",
7
- "openFile": "開啟檔案...",
8
- "save": "儲存...",
9
- "export": "匯出...",
10
- "view": "檢視",
11
- "fitWindow": "符合視窗",
12
- "originalSize": "原始大小",
13
- "process": "處",
14
- "processCurrent": "處理目前圖片",
15
- "redoInpaintRender": "重新修補並渲染",
16
- "processAll": "處理所有圖片",
17
- "help": "說明",
18
- "discord": "Discord",
19
- "github": "GitHub",
20
- "version": "版本:{{version}}",
21
- "versionUnknown": "版本:未知",
22
- "language": "語言",
23
- "languages": {
24
- "en-US": "English",
25
- "zh-CN": "简体中文",
26
- "zh-TW": "繁體中文",
27
- "ja-JP": "日本語"
28
- }
29
- },
30
- "operations": {
31
- "title": "處理中",
32
- "inProgress": "請稍候,正在處理。",
33
- "loadKhr": "正在載入專案",
34
- "saveKhr": "正在儲存專案",
35
- "loadModel": "正在載入 LLM 模型",
36
- "processCurrent": "正在處理目前圖片",
37
- "processAll": "正在批次處理所有圖片",
38
- "imageProgress": "圖片 {{current}} / {{total}}",
39
- "stepProgress": "步驟 {{current}} / {{total}}:{{step}}",
40
- "cancel": "停止",
41
- "cancelling": "停止中..."
42
- },
43
- "navigator": {
44
- "title": "導覽",
45
- "pages_one": "{{count}} 頁",
46
- "pages_other": "{{count}} 頁",
47
- "empty": "沒有文件",
48
- "prompt": "選擇或匯入頁面以開始"
49
- },
50
- "panels": {
51
- "processing": "處理",
52
- "mask": "遮罩",
53
- "llm": "LLM",
54
- "render": "渲染"
55
- },
56
- "processing": {
57
- "detect": "偵測",
58
- "detectTooltip": "在目前頁面執行文字偵測",
59
- "ocr": "辨識",
60
- "ocrTooltip": "辨識已偵測區域中的文字",
61
- "render": "渲染"
62
- },
63
- "mask": {
64
- "showSegmentationMask": "顯示分割遮罩",
65
- "showInpainted": "顯示修補影像",
66
- "showBrushLayer": "顯示筆刷圖層",
67
- "showRendered": "顯示渲染文字",
68
- "showTextBlocks": "顯示文字框",
69
- "inpaint": "修補",
70
- "inpaintTooltip": "套用影像修補"
71
- },
72
- "llm": {
73
- "title": "LLM",
74
- "ready": "就緒",
75
- "idle": "閒置",
76
- "selectPlaceholder": "選擇模型",
77
- "modelLabel": "模型",
78
- "openaiCompatible": "OpenAI 兼容服務",
79
- "openaiEndpointLabel": "OpenAI 端點",
80
- "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
- "openaiApiKeyLabel": "API 密鑰",
82
- "openaiApiKeyPlaceholder": "sk-...",
83
- "openaiModelLabel": "模型名稱",
84
- "openaiModelPlaceholder": "gpt-4o-mini",
85
- "openaiPromptLabel": "提示詞",
86
- "openaiPromptPlaceholder": "將下列文本翻譯為繁體中文,保留格式,不要添加額外說明:\n",
87
- "languageLabel": "目標語言",
88
- "languagePlaceholder": "選擇語言",
89
- "load": "載入",
90
- "unload": "卸載",
91
- "loadTooltip": "載入所選模型",
92
- "unloadTooltip": "卸載目前模型",
93
- "generate": "產生",
94
- "generating": "產生中...",
95
- "generateTooltip": "為偵測到的文字區塊產生翻譯",
96
- "render": "渲染文字",
97
- "renderTooltip": "將翻譯渲染到頁面",
98
- "loadingModel": "正在載入 LLM 模型",
99
- "statusReady": "LLM 已就緒",
100
- "statusIdle": "LLM 未載入"
101
- },
102
- "render": {
103
- "effectLabel": "文字效果",
104
- "effectNormal": "一般",
105
- "effectAntique": "古書質感",
106
- "effectMetal": "金屬",
107
- "effectManga": "漫畫網點",
108
- "effectMotionBlur": "動態模糊",
109
- "fontLabel": "字體",
110
- "fontPlaceholder": "選擇字體",
111
- "fontColorLabel": "字體顏色",
112
- "fontScopeGlobal": "Global",
113
- "fontScopeBlock": "Per block",
114
- "fontScopeBlockIndex": "Block {{index}}"
115
- },
116
- "textBlocks": {
117
- "emptyPrompt": "開啟影像以查看文字區塊。",
118
- "title": "文字區塊({{count}})",
119
- "none": "尚無文字區塊。請執行偵測以產生列表。",
120
- "emptySummary": "<空>",
121
- "ocrLabel": "OCR 文字",
122
- "translationLabel": "翻譯",
123
- "addOcrPlaceholder": "新增 OCR 文字",
124
- "addTranslationPlaceholder": "新增翻譯"
125
- },
126
- "workspace": {
127
- "importPrompt": "匯入頁面以開始編輯。",
128
- "deleteBlock": "刪除區塊"
129
- },
130
- "statusBar": {
131
- "zoom": "縮放",
132
- "canvas": "畫布"
133
- },
134
- "toolbar": {
135
- "brush": "筆刷",
136
- "eraser": "橡皮擦",
137
- "brushSize": "筆刷大小",
138
- "brushColor": "筆刷顏色"
139
- },
140
- "toolRail": {
141
- "select": "選擇",
142
- "block": "框選",
143
- "brush": "筆刷",
144
- "repairBrush": "修復筆",
145
- "eraser": "橡皮擦"
146
- }
147
- }
 
1
+ {
2
+ "common": {
3
+ "initializing": "初始化中..."
4
+ },
5
+ "menu": {
6
+ "file": "檔案",
7
+ "openFile": "開啟檔案...",
8
+ "save": "儲存...",
9
+ "export": "匯出...",
10
+ "view": "檢視",
11
+ "fitWindow": "符合視窗",
12
+ "originalSize": "原始大小",
13
+ "process": "處���",
14
+ "processCurrent": "處理目前圖片",
15
+ "redoInpaintRender": "重新修補並渲染",
16
+ "processAll": "處理所有圖片",
17
+ "help": "說明",
18
+ "discord": "Discord",
19
+ "github": "GitHub",
20
+ "version": "版本:{{version}}",
21
+ "versionUnknown": "版本:未知",
22
+ "language": "語言",
23
+ "languages": {
24
+ "en-US": "English",
25
+ "zh-CN": "简体中文",
26
+ "zh-TW": "繁體中文",
27
+ "ja-JP": "日本語"
28
+ }
29
+ },
30
+ "operations": {
31
+ "title": "處理中",
32
+ "inProgress": "請稍候,正在處理。",
33
+ "loadKhr": "正在載入專案",
34
+ "saveKhr": "正在儲存專案",
35
+ "loadModel": "正在載入 LLM 模型",
36
+ "processCurrent": "正在處理目前圖片",
37
+ "processAll": "正在批次處理所有圖片",
38
+ "imageProgress": "圖片 {{current}} / {{total}}",
39
+ "stepProgress": "步驟 {{current}} / {{total}}:{{step}}",
40
+ "cancel": "停止",
41
+ "cancelling": "停止中..."
42
+ },
43
+ "navigator": {
44
+ "title": "導覽",
45
+ "pages_one": "{{count}} 頁",
46
+ "pages_other": "{{count}} 頁",
47
+ "empty": "沒有文件",
48
+ "prompt": "選擇或匯入頁面以開始"
49
+ },
50
+ "panels": {
51
+ "processing": "處理",
52
+ "mask": "遮罩",
53
+ "llm": "LLM",
54
+ "render": "渲染"
55
+ },
56
+ "processing": {
57
+ "detect": "偵測",
58
+ "detectTooltip": "在目前頁面執行文字偵測",
59
+ "ocr": "辨識",
60
+ "ocrTooltip": "辨識已偵測區域中的文字",
61
+ "render": "渲染"
62
+ },
63
+ "mask": {
64
+ "showSegmentationMask": "顯示分割遮罩",
65
+ "showInpainted": "顯示修補影像",
66
+ "showBrushLayer": "顯示筆刷圖層",
67
+ "showRendered": "顯示渲染文字",
68
+ "showTextBlocks": "顯示文字框",
69
+ "inpaint": "修補",
70
+ "inpaintTooltip": "套用影像修補"
71
+ },
72
+ "llm": {
73
+ "title": "LLM",
74
+ "ready": "就緒",
75
+ "idle": "閒置",
76
+ "selectPlaceholder": "選擇模型",
77
+ "modelLabel": "模型",
78
+ "openaiCompatible": "OpenAI 兼容服務",
79
+ "openaiEndpointLabel": "OpenAI 端點",
80
+ "openaiEndpointPlaceholder": "https://api.openai.com/v1",
81
+ "openaiApiKeyLabel": "API 密鑰",
82
+ "openaiApiKeyPlaceholder": "sk-...",
83
+ "openaiModelLabel": "模型名稱",
84
+ "openaiModelPlaceholder": "gpt-4o-mini",
85
+ "openaiPromptLabel": "提示詞",
86
+ "openaiPromptPlaceholder": "將下列文本翻譯為繁體中文,保留格式,不要添加額外說明:\n",
87
+ "languageLabel": "目標語言",
88
+ "languagePlaceholder": "選擇語言",
89
+ "load": "載入",
90
+ "unload": "卸載",
91
+ "loadTooltip": "載入所選模型",
92
+ "unloadTooltip": "卸載目前模型",
93
+ "generate": "產生",
94
+ "generating": "產生中...",
95
+ "generateTooltip": "為偵測到的文字區塊產生翻譯",
96
+ "render": "渲染文字",
97
+ "renderTooltip": "將翻譯渲染到頁面",
98
+ "loadingModel": "正在載入 LLM 模型",
99
+ "statusReady": "LLM 已就緒",
100
+ "statusIdle": "LLM 未載入"
101
+ },
102
+ "render": {
103
+ "effectLabel": "文字效果",
104
+ "effectNormal": "一般",
105
+ "effectAntique": "古書質感",
106
+ "effectMetal": "金屬",
107
+ "effectManga": "漫畫網點",
108
+ "effectMotionBlur": "動態模糊",
109
+ "fontLabel": "字體",
110
+ "fontPlaceholder": "選擇字體",
111
+ "fontColorLabel": "字體顏色",
112
+ "fontScopeGlobal": "Global",
113
+ "fontScopeBlock": "Per block",
114
+ "fontScopeBlockIndex": "Block {{index}}"
115
+ },
116
+ "textBlocks": {
117
+ "emptyPrompt": "開啟影像以查看文字區塊。",
118
+ "title": "文字區塊({{count}})",
119
+ "none": "尚無文字區塊。請執行偵測以產生列表。",
120
+ "emptySummary": "<空>",
121
+ "ocrLabel": "OCR 文字",
122
+ "translationLabel": "翻譯",
123
+ "addOcrPlaceholder": "新增 OCR 文字",
124
+ "addTranslationPlaceholder": "新增翻譯"
125
+ },
126
+ "workspace": {
127
+ "importPrompt": "匯入頁面以開始編輯。",
128
+ "deleteBlock": "刪除區塊"
129
+ },
130
+ "statusBar": {
131
+ "zoom": "縮放",
132
+ "canvas": "畫布"
133
+ },
134
+ "toolbar": {
135
+ "brush": "筆刷",
136
+ "eraser": "橡皮擦",
137
+ "brushSize": "筆刷大小",
138
+ "brushColor": "筆刷顏色"
139
+ },
140
+ "toolRail": {
141
+ "select": "選擇",
142
+ "block": "框選",
143
+ "brush": "筆刷",
144
+ "repairBrush": "修復筆",
145
+ "eraser": "橡皮擦"
146
+ }
147
+ }