5 Commits 17e6b5a460 ... 87ebcc7a6f

Auteur SHA1 Bericht Datum
  PathGao 87ebcc7a6f feat(ui): tag settings that sit at their shipped default value (#6128) 9 uur geleden
  PathGao 55f0281692 chore(lint): forbid the Number-or-clamp idiom in direct-write settings pages (#6129) 9 uur geleden
  PathGao bcd71c9296 chore(build): stop shipping production sourcemaps inside the binary (#6131) 9 uur geleden
  PathGao 33f72f8f4a fix(api): authenticate GET /panel/api/openapi.json + pin the route registry to the router (#6133) 9 uur geleden
  PathGao ea35884390 chore(i18n): delete 230 dead translation keys and guard against new ones (#6132) 9 uur geleden
40 gewijzigde bestanden met toevoegingen van 725 en 3026 verwijderingen
  1. 33 0
      frontend/eslint.config.js
  2. 60 0
      frontend/public/openapi.json
  3. 22 0
      frontend/src/api/queries/useFactoryDefaults.ts
  4. 1 0
      frontend/src/api/queryKeys.ts
  5. 37 0
      frontend/src/components/ui/DefaultSettingTag.tsx
  6. 8 1
      frontend/src/components/ui/SettingListItem.tsx
  7. 1 0
      frontend/src/components/ui/index.ts
  8. 2 2
      frontend/src/models/setting.ts
  9. 10 0
      frontend/src/pages/api-docs/endpoints.ts
  10. 2 2
      frontend/src/pages/settings/EmailTab.tsx
  11. 10 10
      frontend/src/pages/settings/GeneralTab.tsx
  12. 3 3
      frontend/src/pages/settings/SubscriptionGeneralTab.tsx
  13. 3 1
      frontend/src/pages/settings/TelegramTab.tsx
  14. 4 3
      frontend/src/pages/xray/basics/BasicsTab.tsx
  15. 4 0
      frontend/src/schemas/setting.ts
  16. 64 0
      frontend/src/test/default-setting-tag.test.tsx
  17. 53 0
      frontend/src/test/factory-defaults-contract.test.ts
  18. 91 0
      frontend/src/test/i18n-dead-keys.test.ts
  19. 12 2
      frontend/src/test/test-utils.tsx
  20. 7 1
      frontend/vite.config.js
  21. 2 0
      internal/web/controller/api.go
  22. 0 166
      internal/web/controller/api_docs_test.go
  23. 5 0
      internal/web/controller/setting.go
  24. 139 0
      internal/web/routes_contract_test.go
  25. 30 0
      internal/web/service/setting.go
  26. 83 0
      internal/web/service/setting_factory_defaults_test.go
  27. 3 218
      internal/web/translation/ar-EG.json
  28. 3 218
      internal/web/translation/en-US.json
  29. 3 218
      internal/web/translation/es-ES.json
  30. 3 218
      internal/web/translation/fa-IR.json
  31. 3 218
      internal/web/translation/id-ID.json
  32. 3 218
      internal/web/translation/ja-JP.json
  33. 3 218
      internal/web/translation/pt-BR.json
  34. 3 218
      internal/web/translation/ru-RU.json
  35. 3 218
      internal/web/translation/tr-TR.json
  36. 3 218
      internal/web/translation/uk-UA.json
  37. 3 218
      internal/web/translation/vi-VN.json
  38. 3 218
      internal/web/translation/zh-CN.json
  39. 3 218
      internal/web/translation/zh-TW.json
  40. 0 1
      internal/web/web.go

+ 33 - 0
frontend/eslint.config.js

@@ -53,4 +53,37 @@ export default [
       'jsx-a11y/no-autofocus': 'off',
     },
   },
+  {
+    // The settings and xray pages write numeric InputNumber changes straight
+    // into state, so a null-collapsing handler (`Number(v) || N`, or the
+    // ternary `typeof v === 'number' ? v : N`) turns a cleared field into a
+    // stored N — the cleared-port bug, #6121. Handlers here go through
+    // onNumber() (src/utils/onNumber.ts) instead. Known limit: a handler
+    // extracted into a variable and passed as onChange={handler} is not
+    // matched; the inline shapes below are the ones that drift in practice.
+    files: ['src/pages/settings/**/*.tsx', 'src/pages/xray/**/*.tsx'],
+    rules: {
+      'no-restricted-syntax': ['error', {
+        selector: 'JSXElement[openingElement.name.name="InputNumber"] JSXAttribute[name.name="onChange"] LogicalExpression[operator="||"] > CallExpression[callee.name="Number"]',
+        message: 'A cleared InputNumber must not write a synthetic value; wrap the handler with onNumber() from @/utils/onNumber (see #6127).',
+      }, {
+        selector: 'JSXElement[openingElement.name.name="InputNumber"] JSXAttribute[name.name="onChange"] ConditionalExpression[test.left.operator="typeof"][alternate.type="Literal"]',
+        message: 'A cleared InputNumber must not write a synthetic value; wrap the handler with onNumber() from @/utils/onNumber (see #6127).',
+      }, {
+        selector: 'JSXElement[openingElement.name.name="InputNumber"] JSXAttribute[name.name="onChange"] LogicalExpression[operator="??"][right.type="Literal"]',
+        message: 'A cleared InputNumber must not write a synthetic value; wrap the handler with onNumber() from @/utils/onNumber (see #6127).',
+      }],
+    },
+  },
+  {
+    // The xray form modals (OutboundFormModal, BalancerFormModal,
+    // DnsServerModal, WarpModal, …) stage values behind Zod validation like
+    // the clients/inbounds modals do, and some of their fields carry a
+    // deliberate clear-means-zero semantic — the direct-write rule above
+    // does not apply to them.
+    files: ['src/pages/xray/**/*Modal.tsx'],
+    rules: {
+      'no-restricted-syntax': 'off',
+    },
+  },
 ];

+ 60 - 0
frontend/public/openapi.json

@@ -3980,6 +3980,36 @@
         }
       }
     },
+    "/panel/api/openapi.json": {
+      "get": {
+        "tags": [
+          "Server"
+        ],
+        "summary": "Serve this API description as an OpenAPI 3 document — the same file that powers the API Docs page. Requires a session or Bearer token like the rest of /panel/api. Useful for generating clients or importing into API tooling.",
+        "operationId": "get_panel_api_openapi_json",
+        "responses": {
+          "200": {
+            "description": "Successful response",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "properties": {
+                    "success": {
+                      "type": "boolean"
+                    },
+                    "msg": {
+                      "type": "string"
+                    },
+                    "obj": {}
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/panel/api/server/status": {
       "get": {
         "tags": [
@@ -9739,6 +9769,36 @@
         }
       }
     },
+    "/panel/api/setting/factoryDefaults": {
+      "post": {
+        "tags": [
+          "Settings"
+        ],
+        "summary": "Return the shipped (factory) default value per browser-safe setting key, so clients can tell a stored value apart from the default it would fall back to. Per-install material (secret, panelGuid, mTLS keys) and credential fields are never included.",
+        "operationId": "post_panel_api_setting_factoryDefaults",
+        "responses": {
+          "200": {
+            "description": "Successful response",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "properties": {
+                    "success": {
+                      "type": "boolean"
+                    },
+                    "msg": {
+                      "type": "string"
+                    },
+                    "obj": {}
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/panel/api/setting/update": {
       "post": {
         "tags": [

+ 22 - 0
frontend/src/api/queries/useFactoryDefaults.ts

@@ -0,0 +1,22 @@
+import { useQuery } from '@tanstack/react-query';
+
+import { HttpUtil } from '@/utils';
+import { parseMsg } from '@/utils/zodValidate';
+import { FactoryDefaultsSchema, type FactoryDefaults } from '@/schemas/setting';
+import { keys } from '@/api/queryKeys';
+
+async function fetchFactoryDefaults(): Promise<FactoryDefaults> {
+  const msg = await HttpUtil.post('/panel/api/setting/factoryDefaults', undefined, { silent: true });
+  if (!msg?.success) throw new Error(msg?.msg || 'Failed to fetch factory defaults');
+  const validated = parseMsg(msg, FactoryDefaultsSchema, 'setting/factoryDefaults');
+  const parsed = FactoryDefaultsSchema.safeParse(validated.obj);
+  return parsed.success ? parsed.data : {};
+}
+
+export function useFactoryDefaults() {
+  return useQuery({
+    queryKey: keys.settings.factoryDefaults(),
+    queryFn: fetchFactoryDefaults,
+    staleTime: Infinity,
+  });
+}

+ 1 - 0
frontend/src/api/queryKeys.ts

@@ -17,6 +17,7 @@ export const keys = {
     root: () => ['settings'] as const,
     all: () => ['settings', 'all'] as const,
     defaults: () => ['settings', 'defaults'] as const,
+    factoryDefaults: () => ['settings', 'factoryDefaults'] as const,
   },
   inbounds: {
     root: () => ['inbounds'] as const,

+ 37 - 0
frontend/src/components/ui/DefaultSettingTag.tsx

@@ -0,0 +1,37 @@
+import { Tag } from 'antd';
+import { useTranslation } from 'react-i18next';
+
+import { useFactoryDefaults } from '@/api/queries/useFactoryDefaults';
+
+/**
+ * Value semantics on purpose: the tag answers "does this equal the shipped
+ * default?", not "has the user ever saved this key?" — a stored 2096 and a
+ * fallback 2096 behave identically, so they read identically.
+ */
+export function matchesFactoryDefault(current: unknown, factoryDefault: string | undefined): boolean {
+  if (factoryDefault === undefined) return false;
+  if (typeof current === 'number') {
+    const parsed = Number(factoryDefault);
+    return factoryDefault.trim() !== '' && !Number.isNaN(parsed) && parsed === current;
+  }
+  if (typeof current === 'boolean') {
+    if (factoryDefault !== 'true' && factoryDefault !== 'false') return false;
+    return (factoryDefault === 'true') === current;
+  }
+  if (typeof current === 'string') return factoryDefault === current;
+  return false;
+}
+
+interface DefaultSettingTagProps {
+  settingKey: string;
+  value: unknown;
+}
+
+export default function DefaultSettingTag({ settingKey, value }: DefaultSettingTagProps) {
+  const { t } = useTranslation();
+  const defaults = useFactoryDefaults();
+
+  if (!matchesFactoryDefault(value, defaults.data?.[settingKey])) return null;
+
+  return <Tag style={{ marginLeft: 8 }}>{t('pages.settings.defaultTag')}</Tag>;
+}

+ 8 - 1
frontend/src/components/ui/SettingListItem.tsx

@@ -5,6 +5,7 @@ import './SettingListItem.css';
 interface SettingListItemProps {
   paddings?: 'small' | 'default';
   title?: ReactNode;
+  badge?: ReactNode;
   description?: ReactNode;
   children?: ReactNode;
   control?: ReactNode;
@@ -13,6 +14,7 @@ interface SettingListItemProps {
 export default function SettingListItem({
   paddings = 'default',
   title,
+  badge,
   description,
   children,
   control,
@@ -28,7 +30,12 @@ export default function SettingListItem({
       <Row gutter={[8, 16]} style={{ width: '100%' }}>
         <Col xs={24} lg={12}>
           <div className="setting-list-meta">
-            {title && <div className="setting-list-title" id={titleId}>{title}</div>}
+            {title && (
+              <div className="setting-list-title">
+                <span id={titleId}>{title}</span>
+                {badge}
+              </div>
+            )}
             {description && <div className="setting-list-description">{description}</div>}
           </div>
         </Col>

+ 1 - 0
frontend/src/components/ui/index.ts

@@ -1,3 +1,4 @@
 export { default as InputAddon } from './InputAddon';
 export { default as InfinityIcon } from './InfinityIcon';
 export { default as SettingListItem } from './SettingListItem';
+export { default as DefaultSettingTag } from './DefaultSettingTag';

+ 2 - 2
frontend/src/models/setting.ts

@@ -91,7 +91,7 @@ export class AllSetting {
   ldapDefaultTotalGB = 0;
   ldapDefaultExpiryDays = 0;
   ldapDefaultLimitIP = 0;
-  tgEnabledEvents = '';
+  tgEnabledEvents = 'login.attempt,cpu.high';
   smtpEnable = false;
   smtpHost = '';
   smtpPort = 587;
@@ -101,7 +101,7 @@ export class AllSetting {
   smtpFromName = '';
   smtpTo = '';
   smtpEncryptionType = 'starttls';
-  smtpEnabledEvents = '';
+  smtpEnabledEvents = 'login.attempt,cpu.high';
   smtpCpu = 80;
   smtpMemory = 80;
   outboundDownThreshold = 3;

+ 10 - 0
frontend/src/pages/api-docs/endpoints.ts

@@ -254,6 +254,11 @@ export const sections: readonly Section[] = [
     description:
       'System status, log retrieval, certificate generators, Xray binary management, and backup/restore. All under /panel/api/server.',
     endpoints: [
+      {
+        method: 'GET',
+        path: '/panel/api/openapi.json',
+        summary: 'Serve this API description as an OpenAPI 3 document — the same file that powers the API Docs page. Requires a session or Bearer token like the rest of /panel/api. Useful for generating clients or importing into API tooling.',
+      },
       {
         method: 'GET',
         path: '/panel/api/server/status',
@@ -1164,6 +1169,11 @@ export const sections: readonly Section[] = [
         path: '/panel/api/setting/defaultSettings',
         summary: 'Return the computed default settings based on the request host. Useful to preview what a fresh install would use.',
       },
+      {
+        method: 'POST',
+        path: '/panel/api/setting/factoryDefaults',
+        summary: 'Return the shipped (factory) default value per browser-safe setting key, so clients can tell a stored value apart from the default it would fall back to. Per-install material (secret, panelGuid, mTLS keys) and credential fields are never included.',
+      },
       {
         method: 'POST',
         path: '/panel/api/setting/update',

+ 2 - 2
frontend/src/pages/settings/EmailTab.tsx

@@ -5,7 +5,7 @@ import { MailOutlined, SendOutlined, SettingOutlined } from '@ant-design/icons';
 import { HttpUtil } from '@/utils';
 import { onNumber } from '@/utils/onNumber';
 import type { AllSetting } from '@/models/setting';
-import { SettingListItem } from '@/components/ui';
+import { DefaultSettingTag, SettingListItem } from '@/components/ui';
 import { EmailNotifications } from '@/components/ui/notifications/EmailNotifications';
 import { useMediaQuery } from '@/hooks/useMediaQuery';
 import { catTabLabel } from './catTabLabel';
@@ -63,7 +63,7 @@ export default function EmailTab({ allSetting, updateSetting }: EmailTabProps) {
                 onChange={(e) => updateSetting({ smtpHost: e.target.value })} />
             </SettingListItem>
 
-            <SettingListItem paddings="small" title={t('pages.settings.smtpPort')} description={t('pages.settings.smtpPortDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.smtpPort')} badge={<DefaultSettingTag settingKey="smtpPort" value={allSetting.smtpPort} />} description={t('pages.settings.smtpPortDesc')}>
               <InputNumber value={allSetting.smtpPort} min={1} max={65535} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ smtpPort: v }))} />
             </SettingListItem>

+ 10 - 10
frontend/src/pages/settings/GeneralTab.tsx

@@ -18,7 +18,7 @@ import {
 import type { AllSetting } from '@/models/setting';
 import { HttpUtil, LanguageManager } from '@/utils';
 import { onNumber } from '@/utils/onNumber';
-import { SettingListItem } from '@/components/ui';
+import { DefaultSettingTag, SettingListItem } from '@/components/ui';
 import { useMediaQuery } from '@/hooks/useMediaQuery';
 import { catTabLabel } from './catTabLabel';
 import { sanitizePath } from './uriPath';
@@ -169,7 +169,7 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
               <Input value={allSetting.webDomain} onChange={(e) => updateSetting({ webDomain: e.target.value })} />
             </SettingListItem>
 
-            <SettingListItem paddings="small" title={t('pages.settings.panelPort')} description={t('pages.settings.panelPortDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.panelPort')} badge={<DefaultSettingTag settingKey="webPort" value={allSetting.webPort} />} description={t('pages.settings.panelPortDesc')}>
               <InputNumber value={allSetting.webPort} min={1} max={65535} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ webPort: v }))} />
             </SettingListItem>
@@ -178,7 +178,7 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
               <Input value={allSetting.webBasePath} onChange={(e) => updateSetting({ webBasePath: sanitizePath(e.target.value) })} />
             </SettingListItem>
 
-            <SettingListItem paddings="small" title={t('pages.settings.sessionMaxAge')} description={t('pages.settings.sessionMaxAgeDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.sessionMaxAge')} badge={<DefaultSettingTag settingKey="sessionMaxAge" value={allSetting.sessionMaxAge} />} description={t('pages.settings.sessionMaxAgeDesc')}>
               <InputNumber value={allSetting.sessionMaxAge} min={60} max={525600} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ sessionMaxAge: v }))} />
             </SettingListItem>
@@ -207,7 +207,7 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
               />
             </SettingListItem>
 
-            <SettingListItem paddings="small" title={t('pages.settings.pageSize')} description={t('pages.settings.pageSizeDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.pageSize')} badge={<DefaultSettingTag settingKey="pageSize" value={allSetting.pageSize} />} description={t('pages.settings.pageSizeDesc')}>
               <InputNumber value={allSetting.pageSize} min={0} max={1000} step={5} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ pageSize: v }))} />
             </SettingListItem>
@@ -233,11 +233,11 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
         label: catTabLabel(<BellOutlined />, t('pages.settings.notifications'), isMobile),
         children: (
           <>
-            <SettingListItem paddings="small" title={t('pages.settings.expireTimeDiff')} description={t('pages.settings.expireTimeDiffDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.expireTimeDiff')} badge={<DefaultSettingTag settingKey="expireDiff" value={allSetting.expireDiff} />} description={t('pages.settings.expireTimeDiffDesc')}>
               <InputNumber value={allSetting.expireDiff} min={0} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ expireDiff: v }))} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.trafficDiff')} description={t('pages.settings.trafficDiffDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.trafficDiff')} badge={<DefaultSettingTag settingKey="trafficDiff" value={allSetting.trafficDiff} />} description={t('pages.settings.trafficDiffDesc')}>
               <InputNumber value={allSetting.trafficDiff} min={0} max={100} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ trafficDiff: v }))} />
             </SettingListItem>
@@ -307,7 +307,7 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
             <SettingListItem paddings="small" title={t('pages.settings.ldap.host')}>
               <Input value={allSetting.ldapHost} onChange={(e) => updateSetting({ ldapHost: e.target.value })} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.ldap.port')}>
+            <SettingListItem paddings="small" title={t('pages.settings.ldap.port')} badge={<DefaultSettingTag settingKey="ldapPort" value={allSetting.ldapPort} />}>
               <InputNumber value={allSetting.ldapPort} min={1} max={65535} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ ldapPort: v }))} />
             </SettingListItem>
@@ -386,15 +386,15 @@ export default function GeneralTab({ allSetting, updateSetting }: GeneralTabProp
             <SettingListItem paddings="small" title={t('pages.settings.ldap.autoDelete')}>
               <Switch checked={allSetting.ldapAutoDelete} onChange={(v) => updateSetting({ ldapAutoDelete: v })} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultTotalGb')}>
+            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultTotalGb')} badge={<DefaultSettingTag settingKey="ldapDefaultTotalGB" value={allSetting.ldapDefaultTotalGB} />}>
               <InputNumber value={allSetting.ldapDefaultTotalGB} min={0} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ ldapDefaultTotalGB: v }))} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultExpiryDays')}>
+            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultExpiryDays')} badge={<DefaultSettingTag settingKey="ldapDefaultExpiryDays" value={allSetting.ldapDefaultExpiryDays} />}>
               <InputNumber value={allSetting.ldapDefaultExpiryDays} min={0} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ ldapDefaultExpiryDays: v }))} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultIpLimit')}>
+            <SettingListItem paddings="small" title={t('pages.settings.ldap.defaultIpLimit')} badge={<DefaultSettingTag settingKey="ldapDefaultLimitIP" value={allSetting.ldapDefaultLimitIP} />}>
               <InputNumber value={allSetting.ldapDefaultLimitIP} min={0} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ ldapDefaultLimitIP: v }))} />
             </SettingListItem>

+ 3 - 3
frontend/src/pages/settings/SubscriptionGeneralTab.tsx

@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
 import { useNavigate } from 'react-router';
 import type { AllSetting } from '@/models/setting';
 import { onNumber } from '@/utils/onNumber';
-import { SettingListItem } from '@/components/ui';
+import { DefaultSettingTag, SettingListItem } from '@/components/ui';
 import { RemarkTemplateField } from '@/components/form';
 import { useMediaQuery } from '@/hooks/useMediaQuery';
 import { catTabLabel } from './catTabLabel';
@@ -56,7 +56,7 @@ export default function SubscriptionGeneralTab({ allSetting, updateSetting }: Su
             <SettingListItem paddings="small" title={t('pages.settings.subDomain')} description={t('pages.settings.subDomainDesc')}>
               <Input value={allSetting.subDomain} onChange={(e) => updateSetting({ subDomain: e.target.value })} />
             </SettingListItem>
-            <SettingListItem paddings="small" title={t('pages.settings.subPort')} description={t('pages.settings.subPortDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.subPort')} badge={<DefaultSettingTag settingKey="subPort" value={allSetting.subPort} />} description={t('pages.settings.subPortDesc')}>
               <InputNumber value={allSetting.subPort} min={1} max={65535} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ subPort: v }))} />
             </SettingListItem>
@@ -105,7 +105,7 @@ export default function SubscriptionGeneralTab({ allSetting, updateSetting }: Su
               />
             </SettingListItem>
 
-            <SettingListItem paddings="small" title={t('pages.settings.subUpdates')} description={t('pages.settings.subUpdatesDesc')}>
+            <SettingListItem paddings="small" title={t('pages.settings.subUpdates')} badge={<DefaultSettingTag settingKey="subUpdates" value={allSetting.subUpdates} />} description={t('pages.settings.subUpdatesDesc')}>
               <InputNumber value={allSetting.subUpdates} min={0} max={525600} style={{ width: '100%' }}
                 onChange={onNumber((v) => updateSetting({ subUpdates: v }))} />
             </SettingListItem>

+ 3 - 1
frontend/src/pages/settings/TelegramTab.tsx

@@ -4,6 +4,7 @@ import { Alert, Button, Input, InputNumber, Select, Space, Switch, Tabs } from '
 import { BellOutlined, SendOutlined, SettingOutlined } from '@ant-design/icons';
 import { LanguageManager } from '@/utils';
 import { HttpUtil } from '@/utils';
+import { onNumber } from '@/utils/onNumber';
 import type { AllSetting } from '@/models/setting';
 import { SettingListItem } from '@/components/ui';
 import { TelegramNotifications } from '@/components/ui/notifications/TelegramNotifications';
@@ -122,9 +123,10 @@ function NotifyTimeField({ value, onChange }: { value: string; onChange: (v: str
         <Space.Compact style={{ width: '100%' }}>
           <InputNumber
             min={1}
+            precision={0}
             style={{ width: '50%' }}
             value={state.num}
-            onChange={(v) => update({ num: Math.max(1, Number(v) || 1) })}
+            onChange={onNumber((v) => update({ num: Math.max(1, v) }))}
             aria-label={t('pages.settings.notifyTime.interval')}
           />
           <Select<Unit>

+ 4 - 3
frontend/src/pages/xray/basics/BasicsTab.tsx

@@ -1,4 +1,5 @@
 import { useCallback } from 'react';
+import { onNumber } from '@/utils/onNumber';
 import { useTranslation } from 'react-i18next';
 import { Alert, Button, Input, InputNumber, Modal, Select, Space, Switch, Tabs } from 'antd';
 import {
@@ -216,10 +217,10 @@ export default function BasicsTab({
                     style={{ width: '100%' }}
                     value={directHappyEyeballs.tryDelayMs}
                     placeholder="150"
-                    onChange={(v) => setDirectHappyEyeballs({
+                    onChange={onNumber((v) => setDirectHappyEyeballs({
                       ...directHappyEyeballs,
-                      tryDelayMs: typeof v === 'number' ? v : 0,
-                    })}
+                      tryDelayMs: v,
+                    }))}
                   />
                 }
               />

+ 4 - 0
frontend/src/schemas/setting.ts

@@ -103,3 +103,7 @@ export const AllSettingSchema = z.object({
 }).loose();
 
 export type AllSettingInput = z.infer<typeof AllSettingSchema>;
+
+export const FactoryDefaultsSchema = z.record(z.string(), z.string());
+
+export type FactoryDefaults = z.infer<typeof FactoryDefaultsSchema>;

+ 64 - 0
frontend/src/test/default-setting-tag.test.tsx

@@ -0,0 +1,64 @@
+import { screen } from '@testing-library/react';
+import { describe, expect, it } from 'vitest';
+
+import { keys } from '@/api/queryKeys';
+import DefaultSettingTag, { matchesFactoryDefault } from '@/components/ui/DefaultSettingTag';
+import { makeTestQueryClient, renderWithProviders } from './test-utils';
+
+function clientWithDefaults(defaults: Record<string, string>) {
+  const queryClient = makeTestQueryClient();
+  queryClient.setQueryData(keys.settings.factoryDefaults(), defaults);
+  return queryClient;
+}
+
+describe('matchesFactoryDefault', () => {
+  it('compares by value with type-aware coercion', () => {
+    expect(matchesFactoryDefault(2096, '2096')).toBe(true);
+    expect(matchesFactoryDefault(8443, '2096')).toBe(false);
+    expect(matchesFactoryDefault(true, 'true')).toBe(true);
+    expect(matchesFactoryDefault(false, 'true')).toBe(false);
+    expect(matchesFactoryDefault('/sub/', '/sub/')).toBe(true);
+    expect(matchesFactoryDefault('/other/', '/sub/')).toBe(false);
+  });
+
+  it('never matches when the key has no shipped default', () => {
+    expect(matchesFactoryDefault(2096, undefined)).toBe(false);
+  });
+
+  it('rejects blank or unparsable defaults instead of coercing them', () => {
+    expect(matchesFactoryDefault(0, '')).toBe(false);
+    expect(matchesFactoryDefault(0, '  ')).toBe(false);
+    expect(matchesFactoryDefault(0, 'none')).toBe(false);
+    expect(matchesFactoryDefault(false, '')).toBe(false);
+    expect(matchesFactoryDefault(false, 'no')).toBe(false);
+  });
+});
+
+describe('DefaultSettingTag', () => {
+  it('shows the tag when the current value equals the shipped default, however it got there', () => {
+    renderWithProviders(
+      <DefaultSettingTag settingKey="subPort" value={2096} />,
+      { queryClient: clientWithDefaults({ subPort: '2096' }) },
+    );
+
+    expect(screen.getByText('Default')).toBeDefined();
+  });
+
+  it('renders nothing when the value differs from the default', () => {
+    renderWithProviders(
+      <DefaultSettingTag settingKey="subPort" value={8443} />,
+      { queryClient: clientWithDefaults({ subPort: '2096' }) },
+    );
+
+    expect(screen.queryByText('Default')).toBeNull();
+  });
+
+  it('renders nothing while defaults are unknown', () => {
+    renderWithProviders(
+      <DefaultSettingTag settingKey="subPort" value={2096} />,
+      { queryClient: makeTestQueryClient() },
+    );
+
+    expect(screen.queryByText('Default')).toBeNull();
+  });
+});

+ 53 - 0
frontend/src/test/factory-defaults-contract.test.ts

@@ -0,0 +1,53 @@
+import { readFileSync } from 'node:fs';
+import { resolve } from 'node:path';
+
+import { describe, expect, it } from 'vitest';
+
+import { matchesFactoryDefault } from '@/components/ui/DefaultSettingTag';
+import { AllSetting } from '@/models/setting';
+
+/*
+ * Contract test between the three homes of a setting's default value: the Go
+ * defaultValueMap (authoritative, served by /setting/factoryDefaults), the
+ * frontend AllSetting class defaults (what the form shows when the API omits
+ * a value), and the tag's own comparison. If someone bumps a default on one
+ * side only, the Default tag would start calling a different value "Default"
+ * than the one the form displays — this test fails instead.
+ */
+
+function goDefaultLiterals(): Record<string, string> {
+  const source = readFileSync(
+    resolve(process.cwd(), '..', 'internal', 'web', 'service', 'setting.go'),
+    'utf8',
+  );
+  const start = source.indexOf('var defaultValueMap = map[string]string{');
+  const end = source.indexOf('\n}', start);
+  const block = source.slice(start, end);
+  const literals: Record<string, string> = {};
+  for (const match of block.matchAll(/"([A-Za-z0-9]+)":\s+"((?:[^"\\]|\\.)*)"\s*,/g)) {
+    literals[match[1]] = JSON.parse(`"${match[2]}"`);
+  }
+  return literals;
+}
+
+describe('factory defaults contract', () => {
+  const goDefaults = goDefaultLiterals();
+  const frontend = new AllSetting() as unknown as Record<string, unknown>;
+  const sharedKeys = Object.keys(goDefaults).filter((key) => {
+    const value = frontend[key];
+    return typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string';
+  });
+
+  it('parses a plausible slice of the Go map', () => {
+    expect(goDefaults.webPort).toBe('2053');
+    expect(goDefaults.subPort).toBe('2096');
+    expect(sharedKeys.length).toBeGreaterThan(20);
+  });
+
+  it.each(sharedKeys)('frontend default for %s matches the shipped default', (key) => {
+    expect(
+      matchesFactoryDefault(frontend[key], goDefaults[key]),
+      `AllSetting.${key} = ${JSON.stringify(frontend[key])} vs defaultValueMap ${JSON.stringify(goDefaults[key])}`,
+    ).toBe(true);
+  });
+});

+ 91 - 0
frontend/src/test/i18n-dead-keys.test.ts

@@ -0,0 +1,91 @@
+import { readFileSync, readdirSync, statSync } from 'node:fs';
+import { fileURLToPath } from 'node:url';
+import { join, resolve } from 'node:path';
+
+import { describe, expect, it } from 'vitest';
+
+/*
+ * Guards the 13-locale translation set two ways: every key in en-US must be
+ * referenced somewhere in the frontend or Go sources (dead keys accumulate
+ * silently — this test deleted over two hundred of them when it was
+ * introduced), and every locale must carry exactly the en-US key set
+ * (missing keys fall back to en-US at runtime, so nothing else fails the
+ * build when a translation is forgotten).
+ *
+ * References are matched as whole dotted tokens, not substrings, so a dead
+ * key cannot hide behind a longer live sibling. Dynamically built keys are
+ * covered by harvesting the string-literal prefixes that appear next to
+ * concatenation or template-literal interpolation; the prefix needs at
+ * least one dot but need not end on one, so a literal that stops mid-leaf
+ * right before the interpolation still keeps its subtree alive. This file
+ * excludes itself from the scan so the prose above cannot whitelist
+ * anything.
+ */
+
+const repoRoot = resolve(process.cwd(), '..');
+const translationDir = join(repoRoot, 'internal', 'web', 'translation');
+const selfPath = fileURLToPath(import.meta.url);
+
+function flattenKeys(obj: Record<string, unknown>, prefix = ''): string[] {
+  const keys: string[] = [];
+  for (const [k, v] of Object.entries(obj)) {
+    const key = `${prefix}${k}`;
+    if (v !== null && typeof v === 'object') {
+      keys.push(...flattenKeys(v as Record<string, unknown>, `${key}.`));
+    } else {
+      keys.push(key);
+    }
+  }
+  return keys;
+}
+
+function collectSources(dir: string, exts: string[], out: string[]): void {
+  for (const entry of readdirSync(dir)) {
+    if (['node_modules', 'dist', 'generated', '.git', '.local', 'storybook-static'].includes(entry)) continue;
+    const full = join(dir, entry);
+    if (statSync(full).isDirectory()) {
+      collectSources(full, exts, out);
+    } else if (exts.some((ext) => entry.endsWith(ext)) && resolve(full) !== selfPath) {
+      out.push(readFileSync(full, 'utf8'));
+    }
+  }
+}
+
+describe('i18n keys', () => {
+  const enUS = JSON.parse(readFileSync(join(translationDir, 'en-US.json'), 'utf8'));
+  const enKeys = flattenKeys(enUS);
+
+  const sources: string[] = [];
+  collectSources(join(repoRoot, 'frontend', 'src'), ['.ts', '.tsx'], sources);
+  collectSources(join(repoRoot, 'internal'), ['.go'], sources);
+  const blob = sources.join('\n');
+
+  const tokens = new Set(blob.match(/[A-Za-z][A-Za-z0-9_.]*/g) ?? []);
+
+  const prefixes: string[] = [];
+  for (const match of blob.matchAll(/['"`]([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+\.?)['"`]\s*\+/g)) {
+    prefixes.push(match[1]);
+  }
+  for (const match of blob.matchAll(/[`']([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+\.?)\$\{/g)) {
+    prefixes.push(match[1]);
+  }
+
+  it('every en-US key is referenced by the frontend or Go sources', () => {
+    const dead = enKeys.filter(
+      (key) => !tokens.has(key) && !prefixes.some((p) => key.startsWith(p)),
+    );
+    expect(dead, `dead i18n keys (delete from all 13 locales):\n  ${dead.join('\n  ')}`).toEqual([]);
+  });
+
+  it('every locale carries exactly the en-US key set', () => {
+    const enSet = new Set(enKeys);
+    for (const file of readdirSync(translationDir)) {
+      if (!file.endsWith('.json') || file === 'en-US.json') continue;
+      const keys = new Set(flattenKeys(JSON.parse(readFileSync(join(translationDir, file), 'utf8'))));
+      const missing = enKeys.filter((k) => !keys.has(k));
+      const orphans = [...keys].filter((k) => !enSet.has(k));
+      expect(missing, `${file} is missing keys:\n  ${missing.join('\n  ')}`).toEqual([]);
+      expect(orphans, `${file} has keys absent from en-US:\n  ${orphans.join('\n  ')}`).toEqual([]);
+    }
+  });
+});

+ 12 - 2
frontend/src/test/test-utils.tsx

@@ -1,10 +1,20 @@
 import type { ReactElement } from 'react';
 import { render, fireEvent } from '@testing-library/react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
 
 import { ThemeProvider } from '@/hooks/useTheme';
 
-export function renderWithProviders(ui: ReactElement) {
-  return render(<ThemeProvider>{ui}</ThemeProvider>);
+export function makeTestQueryClient() {
+  return new QueryClient({ defaultOptions: { queries: { retry: false } } });
+}
+
+export function renderWithProviders(ui: ReactElement, options?: { queryClient?: QueryClient }) {
+  const queryClient = options?.queryClient ?? makeTestQueryClient();
+  return render(
+    <QueryClientProvider client={queryClient}>
+      <ThemeProvider>{ui}</ThemeProvider>
+    </QueryClientProvider>,
+  );
 }
 
 export function fieldLabels(): string[] {

+ 7 - 1
frontend/vite.config.js

@@ -171,7 +171,13 @@ export default defineConfig({
   build: {
     outDir,
     emptyOutDir: true,
-    sourcemap: true,
+    // Everything in outDir is embedded into the Go binary via embed.FS, so
+    // production sourcemaps (~18MB across 112 files, 72% of dist) ship inside
+    // every release build. Nothing consumes them there; `npm run dev` serves
+    // its own maps regardless of this setting. To debug a minified bundle
+    // (including the XUI_DEBUG serve-from-disk path), build once with
+    // XUI_SOURCEMAP=true — no tracked-file edit to accidentally commit.
+    sourcemap: process.env.XUI_SOURCEMAP === 'true',
     target: 'es2020',
     chunkSizeWarningLimit: 1500,
     rollupOptions: {

+ 2 - 0
internal/web/controller/api.go

@@ -78,6 +78,8 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
 	api.Use(middleware.ConfigEnvelopeMiddleware())
 	api.Use(middleware.CSRFMiddleware())
 
+	api.GET("/openapi.json", ServeOpenAPISpec)
+
 	// Inbounds API
 	inbounds := api.Group("/inbounds")
 	a.inboundController = NewInboundController(inbounds)

+ 0 - 166
internal/web/controller/api_docs_test.go

@@ -1,166 +0,0 @@
-package controller
-
-import (
-	"os"
-	"path/filepath"
-	"regexp"
-	"strings"
-	"testing"
-)
-
-type routeDef struct {
-	Method string
-	Path   string
-}
-
-// routePattern matches route registrations like g.GET("/path", handler) or api.GET("/path", handler)
-var routePattern = regexp.MustCompile(`\b(g|api)\.(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\("([^"]+)"`)
-
-// docRoutePattern matches { method: 'X', path: 'Y' ... } entries in endpoints.ts.
-var docRoutePattern = regexp.MustCompile(`method:\s*'([A-Z]+)'\s*,\s*path:\s*'([^']+)'`)
-
-// buildDocSet parses frontend/src/pages/api-docs/endpoints.ts and returns the
-// set of documented "METHOD PATH" keys. WS pseudo-routes and subscription
-// placeholders (paths starting with /{...}) are skipped because they aren't
-// registered on the main Gin engine.
-func buildDocSet(t *testing.T) map[string]bool {
-	t.Helper()
-	controllerDir, err := filepath.Abs(".")
-	if err != nil {
-		t.Fatalf("failed to get current dir: %v", err)
-	}
-	endpointsPath := filepath.Join(controllerDir, "..", "..", "..", "frontend", "src", "pages", "api-docs", "endpoints.ts")
-	data, err := os.ReadFile(endpointsPath)
-	if err != nil {
-		t.Fatalf("failed to read endpoints.ts at %s: %v", endpointsPath, err)
-	}
-	docSet := make(map[string]bool)
-	for _, m := range docRoutePattern.FindAllStringSubmatch(string(data), -1) {
-		method, path := m[1], m[2]
-		if method == "WS" {
-			continue
-		}
-		if !strings.HasPrefix(path, "/") || strings.HasPrefix(path, "/{") {
-			continue
-		}
-		docSet[method+" "+path] = true
-	}
-	if len(docSet) == 0 {
-		t.Fatalf("no documented routes parsed from %s — regex or file format may have changed", endpointsPath)
-	}
-	return docSet
-}
-
-func TestAPIRoutesDocumented(t *testing.T) {
-	docSet := buildDocSet(t)
-
-	controllerDir, err := filepath.Abs(".")
-	if err != nil {
-		t.Fatalf("failed to get current dir: %v", err)
-	}
-
-	var allRoutes []routeDef
-
-	entries, err := os.ReadDir(controllerDir)
-	if err != nil {
-		t.Fatalf("failed to read controller dir: %v", err)
-	}
-
-	for _, entry := range entries {
-		if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || strings.HasSuffix(entry.Name(), "_test.go") {
-			continue
-		}
-		data, err := os.ReadFile(filepath.Join(controllerDir, entry.Name()))
-		if err != nil {
-			t.Fatalf("failed to read %s: %v", entry.Name(), err)
-		}
-		src := string(data)
-
-		// Determine the base path for this file based on its initRouter patterns
-		basePath := ""
-		switch entry.Name() {
-		case "index.go":
-			basePath = ""
-		case "spa.go":
-			basePath = "/panel"
-		case "api.go":
-			basePath = "/panel/api"
-		case "inbound.go":
-			basePath = "/panel/api/inbounds"
-		case "client.go":
-			basePath = "/panel/api/clients"
-		case "group.go":
-			basePath = "/panel/api/clients"
-		case "server.go":
-			basePath = "/panel/api/server"
-		case "node.go":
-			basePath = "/panel/api/nodes"
-		case "host.go":
-			basePath = "/panel/api/hosts"
-		case "setting.go":
-			basePath = "/panel/api/setting"
-		case "xray_setting.go":
-			basePath = "/panel/api/xray"
-		case "websocket.go":
-			basePath = ""
-		}
-
-		// Find all route registrations
-		matches := routePattern.FindAllStringSubmatch(src, -1)
-		for _, m := range matches {
-			method := m[2]
-			path := strings.TrimSpace(m[3])
-			if basePath == "" {
-				allRoutes = append(allRoutes, routeDef{Method: method, Path: path})
-			} else {
-				fullPath := basePath + path
-				allRoutes = append(allRoutes, routeDef{Method: method, Path: fullPath})
-			}
-		}
-	}
-
-	// The WebSocket route /ws is registered in web/web.go (not a controller file)
-	allRoutes = append(allRoutes, routeDef{Method: "GET", Path: "/ws"})
-
-	missingFromDocs := 0
-	foundInDoc := 0
-	sourceSet := make(map[string]bool)
-
-	for _, r := range allRoutes {
-		key := r.Method + " " + r.Path
-		// Skip SPA page routes (these are UI pages, not API endpoints)
-		spaPages := map[string]bool{
-			"/": true, "/panel/": true, "/panel/inbounds": true,
-			"/panel/clients": true, "/panel/groups": true,
-			"/panel/nodes": true, "/panel/settings": true,
-			"/panel/xray": true, "/panel/outbound": true,
-			"/panel/routing": true, "/panel/api-docs": true,
-		}
-		if spaPages[r.Path] {
-			continue
-		}
-		// Skip /panel/csrf-token (documented under auth as /csrf-token)
-		if r.Path == "/panel/csrf-token" {
-			continue
-		}
-		// Skip Chrome DevTools route
-		if strings.Contains(r.Path, ".well-known") {
-			continue
-		}
-
-		sourceSet[key] = true
-		if docSet[key] {
-			foundInDoc++
-		} else {
-			missingFromDocs++
-			t.Errorf("Route not documented in endpoints.ts: %s %s", r.Method, r.Path)
-		}
-	}
-
-	t.Logf("Routes found in source: %d, documented: %d, matching: %d, missing: %d",
-		len(sourceSet), len(docSet), foundInDoc, missingFromDocs)
-
-	if missingFromDocs > 0 {
-		t.Errorf("Found %d undocumented route(s). Update endpoints.ts to match.", missingFromDocs)
-	}
-}

+ 5 - 0
internal/web/controller/setting.go

@@ -65,6 +65,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) {
 
 	g.POST("/all", a.getAllSetting)
 	g.POST("/defaultSettings", a.getDefaultSettings)
+	g.POST("/factoryDefaults", a.getFactoryDefaults)
 	g.POST("/update", a.updateSetting)
 	g.POST("/validateRegex", a.validateRegex)
 	g.POST("/updateUser", a.updateUser)
@@ -112,6 +113,10 @@ func (a *SettingController) getDefaultSettings(c *gin.Context) {
 	jsonObj(c, result, nil)
 }
 
+func (a *SettingController) getFactoryDefaults(c *gin.Context) {
+	jsonObj(c, a.settingService.GetFactoryDefaults(), nil)
+}
+
 // updateSetting updates all settings with the provided data.
 func (a *SettingController) updateSetting(c *gin.Context) {
 	form, ok := middleware.BindAndValidate[updateSettingForm](c)

+ 139 - 0
internal/web/routes_contract_test.go

@@ -0,0 +1,139 @@
+package web
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/robfig/cron/v3"
+
+	"github.com/mhsanaei/3x-ui/v3/internal/database"
+	"github.com/mhsanaei/3x-ui/v3/internal/web/global"
+)
+
+/*
+frontend/src/pages/api-docs/endpoints.ts is a hand-maintained registry: an
+API route omitted there silently vanishes from the generated OpenAPI docs,
+and an entry for a removed route documents an endpoint that 404s. This test
+constructs the real router and diffs it against the registry both ways.
+
+Scope: everything under /panel/api/ plus the session-auth surface the
+registry also documents (/login, /logout, /csrf-token, /getTwoFactorEnable,
+/ws). SPA page routes are UI, not API, and stay out; registry paths that
+start with "/{" describe the standalone subscription server, which this
+engine does not serve.
+*/
+
+var contractExtraRoutes = map[string]bool{
+	"POST /login":              true,
+	"POST /logout":             true,
+	"GET /csrf-token":          true,
+	"POST /getTwoFactorEnable": true,
+	"GET /ws":                  true,
+}
+
+func inContractScope(method, path string) bool {
+	return strings.HasPrefix(path, "/panel/api/") || contractExtraRoutes[method+" "+path]
+}
+
+func registeredContractRoutes(t *testing.T) map[string]bool {
+	t.Helper()
+	if err := database.InitDB(filepath.Join(t.TempDir(), "x-ui.db")); err != nil {
+		t.Fatalf("init db: %v", err)
+	}
+	t.Cleanup(func() { _ = database.CloseDB() })
+
+	previous := global.GetWebServer()
+	s := NewServer()
+	s.cron = cron.New(cron.WithLocation(time.Local), cron.WithSeconds())
+	global.SetWebServer(s)
+	t.Cleanup(func() {
+		s.cancel()
+		global.SetWebServer(previous)
+	})
+
+	engine, err := s.initRouter()
+	if err != nil {
+		t.Fatalf("init router: %v", err)
+	}
+	routes := make(map[string]bool)
+	for _, r := range engine.Routes() {
+		routes[r.Method+" "+r.Path] = true
+	}
+	if len(routes) == 0 {
+		t.Fatal("no routes registered; router construction is broken")
+	}
+	return routes
+}
+
+func documentedContractRoutes(t *testing.T) map[string]bool {
+	t.Helper()
+	source, err := os.ReadFile(filepath.Join("..", "..", "frontend", "src", "pages", "api-docs", "endpoints.ts"))
+	if err != nil {
+		t.Fatalf("read endpoints.ts: %v", err)
+	}
+	text := string(source)
+	methodRe := regexp.MustCompile(`method:\s*'(GET|POST|PUT|DELETE|PATCH|WS)'`)
+	pathRe := regexp.MustCompile(`path:\s*'([^']+)'`)
+	methods := methodRe.FindAllStringSubmatchIndex(text, -1)
+	if declared := strings.Count(text, "method: '"); len(methods) != declared {
+		t.Fatalf("parsed %d method fields but endpoints.ts declares %d — the parser regex no longer matches the file shape", len(methods), declared)
+	}
+	docs := make(map[string]bool)
+	for i, m := range methods {
+		segmentEnd := len(text)
+		if i+1 < len(methods) {
+			segmentEnd = methods[i+1][0]
+		}
+		pathMatch := pathRe.FindStringSubmatch(text[m[1]:segmentEnd])
+		if pathMatch == nil {
+			t.Fatalf("entry %d in endpoints.ts has a method but no path before the next entry — the parser cannot pair it", i)
+		}
+		method := text[m[2]:m[3]]
+		if strings.HasPrefix(pathMatch[1], "/{") || !strings.HasPrefix(pathMatch[1], "/") {
+			continue
+		}
+		docs[method+" "+pathMatch[1]] = true
+	}
+	if len(docs) == 0 {
+		t.Fatal("no entries parsed from endpoints.ts; the parser regex is broken")
+	}
+	return docs
+}
+
+func TestRouteRegistryContract(t *testing.T) {
+	registered := registeredContractRoutes(t)
+	documented := documentedContractRoutes(t)
+
+	t.Run("every API route is documented", func(t *testing.T) {
+		var missing []string
+		for route := range registered {
+			fields := strings.Fields(route)
+			if inContractScope(fields[0], fields[1]) && !documented[route] {
+				missing = append(missing, route)
+			}
+		}
+		sort.Strings(missing)
+		for _, route := range missing {
+			t.Error(fmt.Errorf("route %s is registered but absent from endpoints.ts — add an entry or it vanishes from the API docs", route))
+		}
+	})
+
+	t.Run("every documented route is registered", func(t *testing.T) {
+		var stale []string
+		for route := range documented {
+			if !registered[route] {
+				stale = append(stale, route)
+			}
+		}
+		sort.Strings(stale)
+		for _, route := range stale {
+			t.Error(fmt.Errorf("endpoints.ts documents %s but the server does not register it — remove or fix the entry", route))
+		}
+	})
+}

+ 30 - 0
internal/web/service/setting.go

@@ -1445,3 +1445,33 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
 
 	return result, nil
 }
+
+var factoryDefaultSecretKeys = map[string]bool{
+	"tgBotToken":     true,
+	"twoFactorToken": true,
+	"ldapPassword":   true,
+	"smtpPassword":   true,
+}
+
+/*
+GetFactoryDefaults returns the shipped default value per setting, keyed by
+the AllSetting json field name. Unlike GetDefaultSettings (which reports
+current effective values), this is defaultValueMap projected through the
+AllSetting field set: only keys that exist as an AllSetting json tag are
+returned, minus the credential fields in factoryDefaultSecretKeys. Keys
+with no AllSetting field (secret, panelGuid, the node mTLS material,
+xrayTemplateConfig) are excluded structurally rather than by deny-list.
+*/
+func (s *SettingService) GetFactoryDefaults() map[string]string {
+	result := make(map[string]string)
+	for _, field := range reflect_util.GetFields(reflect.TypeFor[entity.AllSetting]()) {
+		key := field.Tag.Get("json")
+		if key == "" || factoryDefaultSecretKeys[key] {
+			continue
+		}
+		if value, ok := defaultValueMap[key]; ok {
+			result[key] = value
+		}
+	}
+	return result
+}

+ 83 - 0
internal/web/service/setting_factory_defaults_test.go

@@ -0,0 +1,83 @@
+package service
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/mhsanaei/3x-ui/v3/internal/util/reflect_util"
+	"github.com/mhsanaei/3x-ui/v3/internal/web/entity"
+)
+
+func allSettingJSONTags(t *testing.T) map[string]bool {
+	t.Helper()
+	tags := make(map[string]bool)
+	for _, field := range reflect_util.GetFields(reflect.TypeFor[entity.AllSetting]()) {
+		if tag := field.Tag.Get("json"); tag != "" {
+			tags[tag] = true
+		}
+	}
+	return tags
+}
+
+func TestGetFactoryDefaultsExposesBrowserSafeKeys(t *testing.T) {
+	defaults := (&SettingService{}).GetFactoryDefaults()
+
+	tests := []struct {
+		key  string
+		want string
+	}{
+		{key: "webPort", want: "2053"},
+		{key: "subPort", want: "2096"},
+	}
+	for _, tc := range tests {
+		t.Run(tc.key, func(t *testing.T) {
+			got, ok := defaults[tc.key]
+			if !ok {
+				t.Fatalf("expected key %q in factory defaults", tc.key)
+			}
+			if got != tc.want {
+				t.Errorf("factory default for %q = %q, want %q", tc.key, got, tc.want)
+			}
+		})
+	}
+}
+
+func TestGetFactoryDefaultsOmitsSensitiveMaterial(t *testing.T) {
+	defaults := (&SettingService{}).GetFactoryDefaults()
+
+	for _, key := range []string{
+		"secret",
+		"panelGuid",
+		"nodeMtlsCaCertPem",
+		"nodeMtlsCaKeyPem",
+		"nodeMtlsClientCertPem",
+		"nodeMtlsClientKeyPem",
+		"xrayTemplateConfig",
+		"tgBotToken",
+		"twoFactorToken",
+		"ldapPassword",
+		"smtpPassword",
+	} {
+		t.Run(key, func(t *testing.T) {
+			if _, ok := defaults[key]; ok {
+				t.Errorf("factory defaults must not expose %q", key)
+			}
+		})
+	}
+}
+
+func TestGetFactoryDefaultsInvariant(t *testing.T) {
+	defaults := (&SettingService{}).GetFactoryDefaults()
+	tags := allSettingJSONTags(t)
+
+	for key := range defaults {
+		t.Run(key, func(t *testing.T) {
+			if !tags[key] {
+				t.Errorf("key %q is not an entity.AllSetting json tag", key)
+			}
+			if factoryDefaultSecretKeys[key] {
+				t.Errorf("key %q is in the credential deny-list and must not be returned", key)
+			}
+		})
+	}
+}

+ 3 - 218
internal/web/translation/ar-EG.json

@@ -48,7 +48,6 @@
   "copySuccess": "اتنسخ بنجاح",
   "sure": "متأكد؟",
   "encryption": "تشفير",
-  "useIPv4ForHost": "استخدم IPv4 للمضيف",
   "transmission": "نقل",
   "host": "المضيف",
   "path": "المسار",
@@ -74,18 +73,9 @@
   "twoFactorCode": "الكود",
   "remained": "المتبقي",
   "security": "أمان",
-  "secAlertTitle": "تنبيه أمني",
-  "secAlertSsl": "الاتصال ده مش آمن. ابعد عن إدخال معلومات حساسة لغاية ما تشغل TLS لحماية البيانات.",
-  "secAlertConf": "بعض الإعدادات معرضة لهجمات. ينصح بتعزيز بروتوكولات الأمان عشان تمنع الاختراقات المحتملة.",
-  "secAlertSSL": "البانل مش مؤمن. حمّل شهادة TLS لحماية البيانات.",
-  "secAlertPanelPort": "بورت البانل الافتراضي معرض للخطر. ياريت تغير لبورت عشوائي أو محدد.",
-  "secAlertPanelURI": "مسار URI الافتراضي للبانل مش آمن. ياريت تضبط مسار URI معقد.",
-  "secAlertSubURI": "مسار URI الافتراضي للاشتراك مش آمن. ياريت تضبط مسار URI معقد.",
-  "secAlertSubJsonURI": "مسار URI الافتراضي لاشتراك JSON مش آمن. ياريت تضبط مسار URI معقد.",
   "emptyDnsDesc": "مفيش سيرفر DNS مضاف.",
   "emptyFakeDnsDesc": "مفيش سيرفر Fake DNS مضاف.",
   "emptyBalancersDesc": "مفيش موازن تحميل مضاف.",
-  "emptyReverseDesc": "مفيش بروكسي عكسي مضاف.",
   "somethingWentWrong": "حدث خطأ ما",
   "subscription": {
     "title": "معلومات الاشتراك",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "الثيم",
-    "dark": "داكن",
-    "ultraDark": "داكن جدًا",
     "dashboard": "نظرة عامة",
     "inbounds": "الواردات",
     "clients": "العملاء",
@@ -118,7 +106,6 @@
     "routing": "التوجيه",
     "outbounds": "الصادرات",
     "apiDocs": "توثيق API",
-    "logout": "تسجيل خروج",
     "link": "إدارة",
     "donate": "تبرع",
     "hosts": "المضيفات",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "نظرة عامة",
       "cpu": "المعالج",
       "logicalProcessors": "المعالجات المنطقية",
       "frequency": "التردد",
@@ -152,7 +138,6 @@
       "restartXray": "إعادة تشغيل",
       "xraySwitch": "النسخة",
       "xrayUpdates": "تحديثات Xray",
-      "xraySwitchClick": "اختار النسخة اللي عايز تتحول لها.",
       "xraySwitchClickDesk": "اختار بحذر، النسخ القديمة ممكن ما تتوافقش مع الإعدادات الحالية.",
       "updatePanel": "تحديث البانل",
       "panelUpdateDesc": "ده هيحدث 3X-UI لآخر إصدار وهيعيد تشغيل خدمة البانل.",
@@ -164,12 +149,10 @@
       "currentCommit": "الكومِت الحالي",
       "latestCommit": "أحدث كومِت",
       "updateChannelChanged": "تم تغيير قناة التحديث",
-      "upToDate": "محدث",
       "xrayStatusUnknown": "مش معروف",
       "xrayStatusRunning": "شغالة",
       "xrayStatusStop": "متوقفة",
       "xrayStatusError": "خطأ",
-      "xrayErrorPopoverTitle": "حصل خطأ أثناء تشغيل Xray",
       "operationHours": "مدة التشغيل",
       "systemHistoryTitle": "تاريخ النظام",
       "historyTitleCpu": "استخدام المعالج",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "غير متصل",
       "xrayObservatoryLastSeen": "آخر مشاهدة",
       "xrayObservatoryLastTry": "آخر محاولة",
-      "trendLast2Min": "آخر دقيقتين",
-      "systemLoad": "تحميل النظام",
-      "systemLoadDesc": "متوسط تحميل النظام في الدقائق 1, 5, و15",
       "connectionCount": "إحصائيات الاتصال",
       "ipAddresses": "عناوين IP",
       "toggleIpVisibility": "بدل إظهار IP",
@@ -223,13 +203,11 @@
       "totalData": "إجمالي البيانات",
       "sent": "مرسل",
       "received": "مستقبل",
-      "documentation": "التوثيق",
       "xraySwitchVersionDialog": "هل تريد حقًا تغيير إصدار Xray؟",
       "xraySwitchVersionDialogDesc": "سيؤدي هذا إلى تغيير إصدار Xray إلى #version#.",
       "xraySwitchVersionPopover": "تم تحديث Xray بنجاح",
       "panelUpdateDialog": "هل فعلاً عايز تحدث البانل؟",
       "panelUpdateDialogDesc": "ده هيحدث 3X-UI للإصدار #version# وهيعيد تشغيل البانل.",
-      "panelUpdateCheckPopover": "فشل التحقق من تحديث البانل",
       "panelUpdateStartedPopover": "بدأ تحديث البانل",
       "panelUpdateFailedTitle": "فشل تحديث البانل",
       "panelUpdateFailedDesc": "لم يكتمل التحديث بنجاح. تحقق من سجلات الخادم، أو نفّذ الأمر «x-ui update» من سطر الأوامر.",
@@ -258,7 +236,6 @@
       "accessLogs": "سجلات الوصول",
       "autoUpdate": "تحديث تلقائي",
       "config": "الإعدادات",
-      "backup": "نسخ احتياطي",
       "backupTitle": "نسخ احتياطي واستعادة",
       "exportDatabase": "اخزن نسخة",
       "exportDatabaseDesc": "اضغط عشان تحمل ملف .db يحتوي على نسخة احتياطية لقاعدة البيانات الحالية على جهازك. نفس الملف ممكن كمان يترجع على لوحة شغالة بـ PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "انقر لتنزيل قاعدة بيانات SQLite بامتداد .db مبنية من بيانات PostgreSQL الخاصة بك، جاهزة لتشغيل هذه اللوحة على SQLite."
     },
     "inbounds": {
-      "title": "الواردات",
       "totalDownUp": "إجمالي المرسل/المستقبل",
       "totalUsage": "إجمالي الاستخدام",
       "inboundCount": "عدد الإدخالات",
@@ -288,21 +264,11 @@
       "localPanel": "بانل محلي",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "عند وصول اتصال إلى هذا الـ inbound لا يطابق أي عميل، يتم توجيهه إلى مكان آخر. اختر inbound فرعيًا أدناه لملء حقول التوجيه (SNI / ALPN / Path / xver) تلقائيًا من نقله، أو اترك القائمة فارغة واضبط Dest مباشرةً (مثل 8080 أو 127.0.0.1:8080) للتوجيه إلى خادم خارجي مثل Nginx. يجب أن يستمع كل inbound فرعي على 127.0.0.1 مع security=none.",
         "empty": "لا توجد fallbacks بعد",
         "add": "إضافة fallback",
         "pickInbound": "اختر inbound",
         "matchAny": "أي",
         "destPlaceholder": "تلقائي (listen:port للفرع)",
-        "rederive": "إعادة الملء من الفرع",
-        "rederived": "تم إعادة الملء من الفرع",
-        "editAdvanced": "تحرير حقول التوجيه",
-        "hideAdvanced": "إخفاء المتقدم",
-        "quickAddAll": "إضافة سريعة لكل الـ inbounds المؤهلة",
-        "quickAdded": "تمت إضافة {n} fallback",
-        "quickAddedNone": "لا توجد inbounds جديدة مؤهلة للإضافة",
-        "routesWhen": "يوجَّه عندما",
-        "defaultCatchAll": "افتراضي — يلتقط أي شيء آخر",
         "needsTls": "تصبح الـ Fallbacks متاحة بعد اختيار TLS أو Reality في تبويب الأمان (فقط VLESS/Trojan عبر RAW)."
       },
       "protocol": "بروتوكول",
@@ -310,8 +276,6 @@
       "portMap": "تعيين المنفذ",
       "traffic": "حركة المرور",
       "speed": "السرعة",
-      "details": "تفاصيل",
-      "transportConfig": "النقل",
       "expireDate": "المدة",
       "createdAt": "تاريخ الإنشاء",
       "updatedAt": "تاريخ التحديث",
@@ -319,8 +283,6 @@
       "addInbound": "أضف إدخال",
       "generalActions": "إجراءات عامة",
       "modifyInbound": "تعديل الإدخال",
-      "deleteInbound": "حذف الإدخال",
-      "deleteInboundContent": "متأكد إنك عايز تحذف الإدخال؟",
       "deleteConfirmTitle": "حذف الإدخال \"{remark}\"؟",
       "deleteConfirmContent": "سيؤدي هذا إلى إزالة الإدخال وجميع عملائه. لا يمكن التراجع.",
       "resetConfirmTitle": "إعادة تعيين ترافيك \"{remark}\"؟",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "جميع-الواردات",
       "exportAllSubsFileName": "جميع-الواردات-Subs",
       "inboundJsonTitle": "JSON الوارد",
-      "deleteClient": "حذف العميل",
-      "deleteClientContent": "متأكد إنك عايز تحذف العميل؟",
       "resetTrafficContent": "متأكد إنك عايز تعيد ضبط الترافيك؟",
       "copyLink": "انسخ الرابط",
       "address": "العنوان",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= غير محدود. (الوحدة: GB)",
       "totalFlow": "إجمالي التدفق",
       "leaveBlankToNeverExpire": "سيبها فاضية عشان ماتنتهيش",
-      "noRecommendKeepDefault": "ننصح باستخدام الافتراضي",
       "certificatePath": "مسار الملف",
       "certificateContent": "محتوى الملف",
       "publicKey": "المفتاح العام",
       "privatekey": "المفتاح الخاص",
-      "clickOnQRcode": "اضغط على كود QR للنسخ",
       "client": "عميل",
       "export": "تصدير كل الروابط",
       "clone": "استنساخ",
-      "cloneInbound": "استنساخ الإدخال",
-      "cloneInboundContent": "كل إعدادات الإدخال ده، غير البورت، IP الاستماع، والعملاء، هتتطبق على الاستنساخ.",
-      "cloneInboundOk": "استنساخ",
       "resetAllTraffic": "إعادة ضبط ترافيك كل الإدخالات",
       "resetAllTrafficTitle": "إعادة ضبط ترافيك كل الإدخالات",
       "resetAllTrafficContent": "متأكد إنك عايز تعيد ضبط الترافيك لكل الإدخالات؟",
-      "resetInboundClientTraffics": "إعادة ضبط ترافيك العملاء",
-      "resetInboundClientTrafficTitle": "إعادة ضبط ترافيك العملاء",
-      "resetInboundClientTrafficContent": "متأكد إنك عايز تعيد ضبط ترافيك عملاء الإدخال ده؟",
-      "resetAllClientTraffics": "إعادة ضبط ترافيك كل العملاء",
-      "resetAllClientTrafficTitle": "إعادة ضبط ترافيك كل العملاء",
-      "resetAllClientTrafficContent": "متأكد إنك عايز تعيد ضبط ترافيك كل العملاء؟",
-      "delDepletedClients": "حذف العملاء اللي خلصت",
-      "delDepletedClientsTitle": "حذف العملاء اللي خلصت",
-      "delDepletedClientsContent": "متأكد إنك عايز تحذف كل العملاء اللي خلصت؟",
       "email": "البريد",
-      "emailDesc": "ادخل إيميل فريد.",
       "IPLimit": "تحديد IP",
-      "IPLimitDesc": "بيعطل الإدخال لو العدد زاد عن القيمة المحددة. (0 = تعطيل)",
       "IPLimitlog": "سجل IP",
-      "IPLimitlogDesc": "سجل تاريخ الـ IPs. (عشان تفعل الإدخال بعد التعطيل، امسح السجل)",
       "IPLimitlogclear": "امسح السجل",
       "setDefaultCert": "استخدم شهادة البانل",
       "setDefaultCertEmpty": "لا توجد شهادة معدّة للوحة. عينّ واحدة من الإعدادات أولاً.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "غلاف كتلة sniffing في Xray:",
         "stream": "Stream",
-        "streamHelp": "غلاف كتلة stream في Xray:",
-        "jsonErrorPrefix": "JSON متقدم"
+        "streamHelp": "غلاف كتلة stream في Xray:"
       },
-      "telegramDesc": "ادخل ID شات Telegram. (استخدم '/id' في البوت) أو ({'@'}userinfobot)",
-      "subscriptionDesc": "عشان تلاقي رابط الاشتراك، ادخل على 'التفاصيل'. وكمان ممكن تستخدم نفس الاسم لعدة عملاء.",
       "subSortIndex": "ترتيب الاشتراك",
-      "same": "نفسه",
       "inboundInfo": "معلومات الإدخال",
       "exportInbound": "تصدير الإدخال",
       "import": "استيراد",
       "importInbound": "استيراد إدخال",
       "periodicTrafficResetTitle": "إعادة تعيين حركة المرور",
-      "periodicTrafficResetDesc": "إعادة تعيين عداد حركة المرور تلقائيًا في فترات محددة",
       "periodicTrafficResetDay": "يوم إعادة التعيين الشهري",
-      "lastReset": "آخر إعادة تعيين",
       "periodicTrafficReset": {
         "never": "أبداً",
         "daily": "يومياً",
@@ -464,7 +401,6 @@
         "obtain": "تم الحصول عليه",
         "updateSuccess": "تم التحديث بنجاح",
         "logCleanSuccess": "تم مسح السجل",
-        "inboundsUpdateSuccess": "تم تحديث الواردات بنجاح",
         "inboundUpdateSuccess": "تم تحديث الوارد بنجاح",
         "inboundCreateSuccess": "تم إنشاء الوارد بنجاح",
         "bulkDeleted": "تم حذف {count} إدخال",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "تم حذف عميل وارد",
         "inboundClientUpdateSuccess": "تم تحديث عميل وارد",
         "savedNodeOfflineWillSync": "تم الحفظ محليًا. إحدى العُقد الداعمة غير متصلة أو معطّلة — ستتم مزامنة التغيير بمجرد إعادة الاتصال.",
-        "delDepletedClientsSuccess": "تم حذف جميع العملاء المستنفذين",
         "resetAllClientTrafficSuccess": "تم إعادة تعيين كل حركة المرور من العميل",
         "resetAllTrafficSuccess": "تم إعادة تعيين كل حركة المرور",
         "resetInboundClientTrafficSuccess": "تم إعادة تعيين حركة المرور",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "تكوين Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "طلب",
-          "response": "رد",
-          "name": "اسم",
-          "value": "قيمة"
-        },
-        "tcp": {
-          "version": "نسخة",
-          "method": "طريقة",
-          "path": "المسار",
-          "status": "الحالة",
-          "statusDescription": "وصف الحالة",
-          "requestHeader": "رأس الطلب",
-          "responseHeader": "رأس الرد"
-        }
-      },
       "sniffingDestOverride": "تجاوز الوجهة"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "إضافة اشتراك خارجي",
       "noExternalLinks": "لا توجد روابط خارجية بعد.",
       "noExternalSubscriptions": "لا توجد اشتراكات خارجية بعد.",
-      "add": "إضافة عميل",
-      "edit": "تعديل العميل",
-      "submitAdd": "إضافة عميل",
       "submitEdit": "حفظ التغييرات",
       "clientCount": "عدد العملاء",
       "bulk": "إضافة مجمعة",
-      "copyFromInbound": "نسخ العملاء من الاتصال الوارد",
-      "copyToInbound": "نسخ العملاء إلى",
-      "copySelected": "نسخ المحدد",
-      "copySource": "المصدر",
-      "copyEmailPreview": "معاينة البريد الناتج",
-      "copySelectSourceFirst": "يرجى تحديد اتصال وارد مصدر أولاً.",
-      "copyResult": "نتيجة النسخ",
-      "copyResultSuccess": "تم النسخ بنجاح",
-      "copyResultNone": "لا شيء للنسخ: لم يتم تحديد عملاء أو أن المصدر فارغ",
-      "copyResultErrors": "أخطاء النسخ",
-      "copyFlowLabel": "Flow للعملاء الجدد (VLESS)",
-      "copyFlowHint": "يُطبَّق على جميع العملاء المنسوخين. اتركه فارغًا للتخطي.",
       "selectAll": "تحديد الكل",
       "clearAll": "مسح الكل",
       "method": "الطريقة",
@@ -775,7 +678,6 @@
       "postfix": "لاحقة",
       "delayedStart": "البدء بعد أول استخدام",
       "expireDays": "المدة (أيام)",
-      "days": "يوم",
       "renew": "تجديد تلقائي",
       "renewDesc": "تجديد تلقائي بعد انتهاء الصلاحية. (0 = تعطيل) (الوحدة: يوم)",
       "renewDays": "تجديد تلقائي (أيام)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "الأقرب انتهاءً",
       "has": "يملك",
       "hasNot": "لا يملك",
-      "title": "العملاء",
       "actions": "الإجراءات",
       "totalGB": "حد البيانات (جيجابايت)",
       "totalGBDesc": "حصة البيانات لهذا العميل. 0 = غير محدود.",
@@ -826,8 +727,6 @@
       "addClient": "إضافة عميل",
       "qrCode": "رمز QR",
       "clientInfo": "معلومات العميل",
-      "delete": "حذف",
-      "reset": "إعادة ضبط حركة المرور",
       "editClient": "تعديل العميل",
       "client": "العميل",
       "enabled": "مفعّل",
@@ -841,13 +740,11 @@
       "noLinks": "لا توجد روابط للمشاركة — قم بإرفاق هذا العميل بأحد الاتصالات الواردة الداعمة للبروتوكول أولاً.",
       "link": "الرابط",
       "resetNotPossible": "قم بإرفاق هذا العميل بأحد الاتصالات الواردة أولاً.",
-      "general": "عام",
       "resetAllTraffics": "إعادة ضبط حركة مرور كل العملاء",
       "resetAllTrafficsTitle": "إعادة ضبط حركة مرور كل العملاء؟",
       "resetAllTrafficsContent": "يُعاد ضبط عدّاد الإرسال/الاستقبال لكل عميل إلى الصفر. لا تتأثر الحصص ومواعيد الانتهاء. لا يمكن التراجع.",
       "deleteConfirmTitle": "حذف العميل {email}؟",
       "deleteConfirmContent": "سيؤدي هذا إلى إزالة العميل من جميع الاتصالات الواردة المرتبطة وحذف سجل حركة مروره. لا يمكن التراجع.",
-      "deleteSelected": "حذف ({count})",
       "adjustSelected": "تعديل ({count})",
       "subLinksSelected": "روابط الاشتراك ({count})",
       "addToGroupTitle": "إضافة {count} عميل إلى مجموعة",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "تعطيل {count} عميل؟",
       "bulkDisableConfirmContent": "يُعطّل كل عميل محدد على جميع الإدخالات المرفقة. يفقدون الوصول فورًا لكن تُحفَظ سجلاتهم وحركة بياناتهم.",
       "selectedCount": "{count} محدد",
-      "attachSelected": "إرفاق ({count})",
       "attachToInboundsTitle": "إرفاق {count} عميل بالواردات",
       "attachToInboundsDesc": "يربط {count} عميل المحدد (نفس UUID/كلمة المرور والمرور المشترك) بالواردات المختارة. يحتفظون بارتباطاتهم الحالية.",
       "attachToInboundsTargets": "الواردات الهدف",
       "attachToInboundsNoTargets": "لا توجد واردات متعددة المستخدمين للارتباط.",
-      "detachSelected": "فصل ({count})",
       "detach": "فصل",
       "detachFromInboundsTitle": "فصل {count} عميل من الواردات",
       "detachFromInboundsDesc": "يزيل {count} عميل المحدد من الواردات المختارة. الأزواج التي لم يكن العميل مرتبطاً بها يتم تخطيها بصمت. تُحفظ سجلات العملاء (استخدم Delete للإزالة الكاملة).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag اختياري",
       "telegramId": "معرّف مستخدم تلغرام",
       "telegramIdPlaceholder": "معرّف مستخدم تلغرام رقمي (0 = لا شيء)",
-      "created": "تاريخ الإنشاء",
-      "updated": "تاريخ التحديث",
       "ipLimit": "حد IP",
       "toasts": {
         "deleted": "تم حذف العميل",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "المجموعات",
       "name": "الاسم",
       "clientCount": "العملاء",
       "totalGroups": "إجمالي المجموعات",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "تمت إزالة {count} عميل من {name}."
     },
     "nodes": {
-      "title": "النودز",
       "addNode": "إضافة نود",
       "editNode": "تحرير العقدة",
       "totalNodes": "إجمالي النودز",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "التوكن من صفحة إعدادات البانل البعيد",
       "apiTokenHint": "البانل البعيد بيعرض توكن API بتاعه في المصادقة → توكن API.",
       "apiTokenKeepHint": "اتركه فارغًا للإبقاء على التوكن الحالي",
-      "regenerate": "تجديد التوكن",
-      "regenerateConfirm": "تجديد التوكن هيلغي التوكن الحالي. أي بانل مركزي بيستخدمه هيفقد الصلاحية لحد ما تحدّث التوكن. تكمّل؟",
       "allowPrivateAddress": "السماح بالعنوان الخاص",
       "allowPrivateAddressHint": "التفعيل فقط للعقد على شبكة خاصة أو VPN.",
       "outboundTag": "اتصال صادر",
@@ -1046,7 +935,6 @@
       "updatePanel": "تحديث اللوحة",
       "updateSelected": "تحديث المحدد ({count})",
       "updateAvailable": "تحديث متاح",
-      "upToDate": "محدّث",
       "updateConfirmTitle": "تحديث {count} عقدة إلى أحدث إصدار؟",
       "updateConfirmContent": "كل عقدة محددة ستنزّل أحدث إصدار وتعيد التشغيل عليه. يتم تحديث العقد المفعّلة والمتصلة فقط.",
       "updateDevChannel": "التحديث إلى قناة التطوير (أحدث كومِت)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "تعذّر جلب الشهادة"
     },
     "settings": {
+      "defaultTag": "افتراضي",
       "title": "إعدادات البانل",
       "save": "حفظ",
       "infoDesc": "كل تغيير هتعمله هنا لازم يتخزن. ياريت تعيد تشغيل البانل عشان التعديلات تتفعل.",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "تراجع عن المسح"
     },
     "xray": {
-      "title": "إعدادات Xray",
       "save": "احفظ",
-      "restart": "إعادة تشغيل Xray",
       "restartSuccess": "تم إعادة تشغيل Xray بنجاح",
-      "restartOutputTitle": "مخرجات إعادة تشغيل Xray",
-      "restartConfirmTitle": "إعادة تشغيل xray؟",
-      "restartConfirmContent": "يعيد تحميل خدمة xray بالتكوين المحفوظ.",
       "stopSuccess": "تم إيقاف Xray بنجاح",
       "restartError": "حدث خطأ أثناء إعادة تشغيل Xray.",
       "stopError": "حدث خطأ أثناء إيقاف Xray.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "الخيارات دي هتحدد التعديلات العامة.",
       "logConfigs": "السجل",
       "logConfigsDesc": "السجلات ممكن تأثر على كفاءة السيرفر. ننصح بتفعيلها بحكمة لما تكون محتاجها.",
-      "blockConfigsDesc": "الخيارات دي هتحجب الترافيك بناءً على بروتوكولات ومواقع محددة.",
       "basicRouting": "توجيه أساسي",
       "blockConnectionsConfigsDesc": "الخيارات دي هتحجب الترافيك بناءً على الدولة المطلوبة.",
       "directConnectionsConfigsDesc": "الاتصال المباشر بيضمن إن الترافيك المعين مايمرش من سيرفر تاني.",
@@ -1473,10 +1356,6 @@
       "directdomains": "اتصالات مباشرة للدومينات",
       "ipv4Routing": "توجيه IPv4",
       "ipv4RoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر IPv4.",
-      "warpRouting": "توجيه WARP",
-      "warpRoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر WARP.",
-      "nordRouting": "توجيه NordVPN",
-      "nordRoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر NordVPN.",
       "Template": "قالب إعدادات Xray المتقدم",
       "TemplateDesc": "ملف إعدادات Xray النهائي هيتولد بناءً على القالب ده.",
       "FreedomStrategy": "استراتيجية بروتوكول الحرية",
@@ -1490,10 +1369,7 @@
       "outboundTestUrlDesc": "الرابط المستخدم عند اختبار اتصال المخرج",
       "Torrent": "حظر بروتوكول التورنت",
       "Inbounds": "الواردات",
-      "InboundsDesc": "قبول العملاء المعينين.",
       "Outbounds": "الصادرات",
-      "OutboundSubscriptions": "اشتراكات الصادرات",
-      "OutboundSubscriptionsDesc": "استورد الصادرات من روابط اشتراك بعيدة (vmess/vless/trojan/ss/...). الوسوم بتفضل ثابتة عشان تستخدمها في موازنات التحميل وقواعد التوجيه. التحديثات بتتم تلقائياً.",
       "importRules": "استيراد القواعد",
       "exportRules": "تصدير القواعد",
       "importOutbounds": "استيراد الصادرات",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "الصادر المطابق",
       "routeTesterViaBalancer": "عبر موازن التحميل",
       "routeTesterDefaultOutbound": "ما في قاعدة توجيه اتطابقت — الترافيك رايح للصادر الافتراضي (الأول).",
-      "OutboundsDesc": "حدد مسار الترافيك الصادر.",
       "Routings": "قواعد التوجيه",
-      "RoutingsDesc": "أولوية كل قاعدة مهمة جداً!",
       "completeTemplate": "الكل",
       "logLevel": "مستوى السجلات",
       "logLevelDesc": "مستوى السجل الخاص بالأخطاء، اللي بيوضح المعلومات المطلوبة للتسجيل.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "إخفاء عنوان الـ IP؛ لو مفعل، هيستبدل تلقائياً عنوان IP اللي بيظهر في السجل.",
       "statistics": "إحصائيات",
       "statsInboundUplink": "إحصائيات رفع الإدخال",
-      "statsInboundUplinkDesc": "تفعيل جمع الإحصائيات لترافيك الرفع لكل بروكسي من الإدخالات.",
       "statsInboundDownlink": "إحصائيات تنزيل الإدخال",
-      "statsInboundDownlinkDesc": "تفعيل جمع الإحصائيات لترافيك التنزيل لكل بروكسي من الإدخالات.",
       "statsOutboundUplink": "إحصائيات رفع المخرجات",
-      "statsOutboundUplinkDesc": "تفعيل جمع الإحصائيات لترافيك الرفع لكل بروكسي من المخرجات.",
       "statsOutboundDownlink": "إحصائيات تنزيل المخرجات",
-      "statsOutboundDownlinkDesc": "تفعيل جمع الإحصائيات لترافيك التنزيل لكل بروكسي من المخرجات.",
       "connectionLimits": "حدود الاتصال",
       "connectionLimitsDesc": "سياسات على مستوى الاتصال لمستوى المستخدم 0. اترك الحقل فارغًا لاستخدام القيمة الافتراضية لـ Xray.",
       "connIdle": "مهلة الخمول",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "تلقائي",
       "seconds": "ثانية",
       "rules": {
-        "first": "أول",
-        "last": "آخر",
-        "up": "فوق",
-        "down": "تحت",
         "source": "المصدر",
         "dest": "الوجهة",
         "inbound": "إدخال",
-        "outbound": "مخرج",
         "balancer": "موازن",
-        "info": "معلومات",
-        "add": "أضف قاعدة",
-        "edit": "عدل القاعدة",
         "useComma": "عناصر مفصولة بفواصل"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "القاعدة {n}",
         "action": "الإجراء",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "القواعد النهائية",
         "overrideXrayPrivateIp": "تجاوز حظر IP الخاص الافتراضي في Xray",
         "blockDelay": "تأخير الحظر (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "فاصل keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "الواجهة",
-        "ipv6Only": "IPv6 فقط",
-        "acceptProxyProtocol": "قبول proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (ثانية)"
       },
       "outbound": {
-        "addOutbound": "أضف مخرج",
-        "addReverse": "أضف عكسي",
-        "editOutbound": "عدل المخرج",
-        "editReverse": "عدل العكسي",
-        "reverseTag": "وسم العكسي",
-        "reverseTagDesc": "وسم الخروج لبروكسي VLESS العكسي البسيط. اتركه فارغاً لتعطيله.",
-        "reverseTagPlaceholder": "وسم الخروج (اتركه فارغاً للتعطيل)",
         "tag": "الوسم",
-        "tagDesc": "تاج فريد",
-        "address": "العنوان",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "عكسي",
-        "domain": "النطاق",
-        "type": "النوع",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "الرابط",
-        "intercon": "تواصل",
-        "settings": "إعدادات",
-        "accountInfo": "معلومات الحساب",
         "outboundStatus": "حالة المخرج",
         "sendThrough": "أرسل من خلال",
         "targetStrategy": "استراتيجية الوجهة",
-        "test": "اختبار",
-        "testResult": "نتيجة الاختبار",
-        "testing": "جاري اختبار الاتصال...",
-        "testSuccess": "الاختبار ناجح",
-        "testFailed": "فشل الاختبار",
-        "testError": "فشل اختبار المخرج",
         "modeRealDelay": "التأخير الفعلي",
         "testModeTooltip": "TCP: فحص dial سريع. HTTP: طلب كامل عبر xray. التأخير الفعلي: الوقت الكامل شاملاً إنشاء الاتصال.",
         "testAll": "اختبار الكل",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "اتصال البروكسي",
         "breakdownTls": "TLS عبر الصادر",
         "breakdownTtfb": "أول بايت",
-        "nordvpn": "NordVPN",
-        "accessToken": "رمز الوصول",
         "country": "الدولة",
         "server": "الخادم",
         "city": "المدينة",
         "allCities": "كل المدن",
-        "privateKey": "المفتاح الخاص",
-        "load": "الحمل",
         "moveToTop": "نقل إلى الأعلى"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "الاشتراكات النشطة",
         "empty": "مفيش اشتراكات لسه. أضف واحد من فوق.",
         "colRemark": "ملاحظة",
-        "colPrefix": "بادئة",
-        "colInterval": "الفاصل",
         "colLastFetch": "آخر جلب",
         "colEnabled": "مفعّل",
         "auto": "تلقائي",
         "never": "أبداً",
-        "yes": "نعم",
-        "no": "لا",
         "refreshNow": "حدّث الآن",
-        "lastError": "آخر خطأ",
         "deleteConfirm": "تحذف الاشتراك ده؟",
         "restartHint": "بعد الإضافة أو التحديث، أعد تشغيل Xray (أو استنى إعادة التحميل التلقائي اللي جاية) عشان تفعّل الصادرات.",
         "fromSubsTitle": "من اشتراكات الصادرات (للقراءة فقط)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "إعدادات الموازن",
       "tabObservatory": "المرصد",
       "observatory": {
-        "title": "المرصد",
-        "burstTitle": "مرصد Burst",
         "autoManaged": "تتم إدارة المراصد تلقائيًا من الموازنات لديك. اضبط طريقة الفحص بالأسفل؛ تتبع الوجهات الصادرة المراقَبة محدِّدات الموازن.",
         "emptyHint": "لا يوجد مرصد اتصال نشط. تتم إضافة واحد تلقائيًا عند إنشاء موازن Least Ping أو Least Load — أو موازن Random / Round-robin مع fallback — حتى تتمكن الموازنات المعتمدة على المرصد من فحص صحة الوجهات الصادرة قبل اختيار الهدف.",
         "mixedLegacy": "يحتوي هذا الإعداد على Observatory و Burst Observatory معًا. يستخدم Xray مرصدًا عالميًا واحدًا، لذلك هذه الحالة القديمة المختلطة غير مدعومة؛ حفظ الموازنات سيحوّلها إلى مرصد واحد.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "الموازن {tag} — أُزيل (لا توجد أهداف متبقية)"
       },
       "balancer": {
-        "addBalancer": "أضف موازن تحميل",
-        "editBalancer": "عدل موازن التحميل",
         "balancerStrategy": "استراتيجية الموازن",
-        "balancerSelectors": "المحددات",
         "tag": "الوسم",
-        "tagDesc": "تاج فريد",
         "tagDuplicate": "الوسم مستخدم بالفعل من قبل موازن آخر",
         "tagPlaceholder": "وسم موازن فريد",
         "selector": "المحدد",
@@ -1789,7 +1609,6 @@
         "tolerance": "التحمل",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "ماينفعش تستخدم balancerTag و outboundTag مع بعض. لو اتستخدموا مع بعض، outboundTag هو اللي هيشتغل.",
         "costMatch": "نمط الوسم",
         "costValue": "الوزن",
         "costRegexp": "مطابقة تعبير نمطي",
@@ -1804,14 +1623,10 @@
         "publicKey": "المفتاح العام",
         "allowedIPs": "عناوين IP المسموح بها",
         "endpoint": "النهاية",
-        "psk": "المفتاح المشترك",
         "domainStrategy": "استراتيجية الدومين"
       },
       "tun": {
-        "nameDesc": "اسم واجهة TUN. القيمة الافتراضية هي 'xray0'",
-        "mtuDesc": "وحدة النقل الأقصى. الحد الأقصى لحجم حزم البيانات. القيمة الافتراضية هي 1500",
-        "userLevel": "مستوى المستخدم",
-        "userLevelDesc": "ستستخدم جميع الاتصالات المُرسلة عبر هذا الإدخال مستوى المستخدم هذا. القيمة الافتراضية هي 0"
+        "userLevel": "مستوى المستخدم"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "أضف Fake DNS",
-        "edit": "عدل Fake DNS",
         "ipPool": "نطاق IP Pool",
         "poolSize": "حجم المجموعة"
       },
@@ -2032,7 +1846,6 @@
     "add": "إضافة",
     "month": "شهر",
     "months": "أشهر",
-    "day": "يوم",
     "days": "أيام",
     "hours": "ساعات",
     "minutes": "دقائق",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ حفظت بيانات مستخدم Telegram.",
       "loginSuccess": "✅ تسجيل الدخول للبانل تم بنجاح.\r\n",
       "loginFailed": "❗️فشل محاولة تسجيل الدخول للبانل.\r\n",
-      "2faFailed": "فشل 2FA",
       "report": "🕰 التقارير المجدولة: {{ .RunTime }}\r\n",
       "datetime": "⏰ التاريخ والوقت: {{ .DateTime }}\r\n",
       "hostname": "💻 المضيف: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 التنزيل: ↓{{ .Download }}\r\n",
       "total": "📊 الإجمالي: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 مستخدم Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 نفذ {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 عدد النفاذ لـ {{ .Type }}:\r\n",
       "onlinesCount": "🌐 العملاء الأونلاين: {{ .Count }}\r\n",
       "disabled": "🛑 معطل: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 اتحدّث في: {{ .Time }}\r\n\r\n",
       "yes": "✅ أيوه",
       "no": "❌ لا",
-      "received_id": "🔑📥 الـ ID اتحدث.",
-      "received_password": "🔑📥 الباسورد اتحدث.",
       "received_email": "📧📥 الإيميل اتحدث.",
       "received_comment": "💬📥 التعليق اتحدث.",
-      "id_prompt": "🔑 الـ ID الافتراضي: {{ .ClientId }}\n\nادخل الـ ID بتاعك.",
-      "pass_prompt": "🔑 الباسورد الافتراضي: {{ .ClientPassword }}\n\nادخل الباسورد بتاعك.",
       "email_prompt": "📧 الإيميل الافتراضي: {{ .ClientEmail }}\n\nادخل الإيميل بتاعك.",
       "comment_prompt": "💬 التعليق الافتراضي: {{ .ClientComment }}\n\nادخل تعليقك.",
-      "inbound_client_data_id": "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 المعرف: {{ .ClientId }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!",
-      "inbound_client_data_pass": "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 كلمة المرور: {{ .ClientPass }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!",
       "cancel": "❌ العملية اتلغت! \n\nممكن تبدأ من /start في أي وقت. 🔄",
       "error_add_client": "⚠️ خطأ:\n\n {{ .error }}",
       "using_default_value": "تمام، هشيل على القيمة الافتراضية. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "الخطأ: {{ .Error }}",
       "eventNodeDown": "العقدة {{ .Name }} غير متصلة",
       "eventNodeUp": "العقدة {{ .Name }} متصلة",
-      "eventCPUHigh": "ارتفاع استخدام المعالج",
-      "eventCPUHighDetail": "المعالج: {{ .Detail }}",
       "eventLoginFallback": "فشل تسجيل الدخول من {{ .Source }}",
       "memoryThreshold": "استخدام الذاكرة {{ .Percent }}% يتجاوز الحد {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "إرسال كمعطّل ☑️",
       "submitEnable": "إرسال كمفعّل ✅",
       "use_default": "🏷️ استخدام الإعدادات الافتراضية",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 كلمة السر",
       "change_email": "⚙️📧 البريد",
       "change_comment": "⚙️💬 تعليق",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "إعادة ضبط جميع الترافيك",
       "SortedTrafficUsageReport": "تقرير استخدام الترافيك المرتب"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "الصادر {{ .Tag }} غير متصل",
-    "subjectOutboundUp": "الصادر {{ .Tag }} متصل",
-    "subjectXrayCrash": "تعطّل Xray",
-    "subjectCPUHigh": "ارتفاع استخدام المعالج",
-    "subjectLoginSuccess": "نجح تسجيل الدخول",
-    "subjectLoginFailed": "فشل تسجيل الدخول",
-    "titleOutboundDown": "الصادر غير متصل",
-    "titleOutboundUp": "الصادر متصل",
-    "titleXrayCrash": "تعطّل Xray",
-    "titleCPUHigh": "ارتفاع استخدام المعالج",
-    "titleLoginSuccess": "نجح تسجيل الدخول",
-    "titleLoginFailed": "فشل تسجيل الدخول",
     "labelStatus": "الحالة",
     "labelOutbound": "الصادر",
     "labelNode": "العقدة",
     "labelError": "الخطأ",
     "labelDelay": "التأخير",
-    "labelDetail": "التفاصيل",
     "labelUsername": "اسم المستخدم",
     "labelIP": "IP",
     "labelReason": "السبب",
     "labelSource": "المصدر",
-    "labelTime": "الوقت",
     "statusCrashed": "متعطّل",
-    "statusRunning": "يعمل",
     "statusHigh": "مرتفع",
     "statusSuccess": "نجاح",
     "statusFailed": "فشل",

+ 3 - 218
internal/web/translation/en-US.json

@@ -48,7 +48,6 @@
   "copySuccess": "Copied successfully",
   "sure": "Sure",
   "encryption": "Encryption",
-  "useIPv4ForHost": "Use IPv4 for host",
   "transmission": "Transmission",
   "host": "Host",
   "path": "Path",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Code",
   "remained": "Remaining",
   "security": "Security",
-  "secAlertTitle": "Security Alert",
-  "secAlertSsl": "This connection is not secure. Please avoid entering sensitive information until TLS is activated for data protection.",
-  "secAlertConf": "Certain settings are vulnerable to attacks. It is recommended to reinforce security protocols to prevent potential breaches.",
-  "secAlertSSL": "Panel lacks secure connection. Please install TLS certificate for data protection.",
-  "secAlertPanelPort": "Panel default port is vulnerable. Please configure a random or specific port.",
-  "secAlertPanelURI": "Panel default URI path is insecure. Please configure a complex URI path.",
-  "secAlertSubURI": "Subscription default URI path is insecure. Please configure a complex URI path.",
-  "secAlertSubJsonURI": "Subscription JSON default URI path is insecure. Please configure a complex URI path.",
   "emptyDnsDesc": "No added DNS servers.",
   "emptyFakeDnsDesc": "No added Fake DNS servers.",
   "emptyBalancersDesc": "No added balancers.",
-  "emptyReverseDesc": "No added reverse proxies.",
   "somethingWentWrong": "Something went wrong",
   "subscription": {
     "title": "Subscription info",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Theme",
-    "dark": "Dark",
-    "ultraDark": "Ultra Dark",
     "dashboard": "Overview",
     "inbounds": "Inbounds",
     "clients": "Clients",
@@ -119,7 +107,6 @@
     "routing": "Routing",
     "outbounds": "Outbounds",
     "apiDocs": "API Docs",
-    "logout": "Log Out",
     "link": "Manage",
     "donate": "Donate",
     "docs": "Documentation",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Overview",
       "cpu": "CPU",
       "logicalProcessors": "Logical Processors",
       "frequency": "Frequency",
@@ -152,7 +138,6 @@
       "restartXray": "Restart",
       "xraySwitch": "Version",
       "xrayUpdates": "Xray Updates",
-      "xraySwitchClick": "Choose the version you want to switch to.",
       "xraySwitchClickDesk": "Choose carefully, as older versions may not be compatible with current configurations.",
       "updatePanel": "Update Panel",
       "panelUpdateDesc": "This will update 3X-UI itself to the latest release and restart the panel service.",
@@ -164,12 +149,10 @@
       "currentCommit": "Current commit",
       "latestCommit": "Latest commit",
       "updateChannelChanged": "Update channel changed",
-      "upToDate": "Up to date",
       "xrayStatusUnknown": "Unknown",
       "xrayStatusRunning": "Running",
       "xrayStatusStop": "Stopped",
       "xrayStatusError": "Error",
-      "xrayErrorPopoverTitle": "An error occurred while running Xray",
       "operationHours": "Uptime",
       "systemHistoryTitle": "System History",
       "historyTitleCpu": "CPU Usage",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Down",
       "xrayObservatoryLastSeen": "Last seen",
       "xrayObservatoryLastTry": "Last try",
-      "trendLast2Min": "Last 2 minutes",
-      "systemLoad": "System Load",
-      "systemLoadDesc": "System load average for the past 1, 5, and 15 minutes",
       "connectionCount": "Connection Stats",
       "ipAddresses": "IP Addresses",
       "toggleIpVisibility": "Toggle visibility of the IP",
@@ -223,13 +203,11 @@
       "totalData": "Total Data",
       "sent": "Sent",
       "received": "Received",
-      "documentation": "Documentation",
       "xraySwitchVersionDialog": "Do you really want to change the Xray version?",
       "xraySwitchVersionDialogDesc": "This will change the Xray version to #version#.",
       "xraySwitchVersionPopover": "Xray updated successfully",
       "panelUpdateDialog": "Do you really want to update the panel?",
       "panelUpdateDialogDesc": "This will update 3X-UI to #version# and restart the panel service.",
-      "panelUpdateCheckPopover": "Panel update check failed",
       "panelUpdateStartedPopover": "Panel update started",
       "panelUpdateFailedTitle": "Panel update failed",
       "panelUpdateFailedDesc": "The update did not finish successfully. Check the server logs, or run 'x-ui update' from the command line.",
@@ -258,7 +236,6 @@
       "accessLogs": "Access Logs",
       "autoUpdate": "Auto Update",
       "config": "Config",
-      "backup": "Backup",
       "backupTitle": "Backup & Restore",
       "exportDatabase": "Back Up",
       "exportDatabaseDesc": "Click to download a .db file containing a backup of your current database to your device. The same file can also be restored into a panel running on PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Click to download a .db SQLite database built from your PostgreSQL data, ready to run this panel on SQLite."
     },
     "inbounds": {
-      "title": "Inbounds",
       "totalDownUp": "Total Sent/Received",
       "totalUsage": "Total Usage",
       "inboundCount": "Total Inbounds",
@@ -288,21 +264,11 @@
       "localPanel": "Local panel",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "When a connection on this inbound does not match any client, route it elsewhere. Pick a child inbound below to auto-fill the routing fields (SNI / ALPN / path / xver) from its transport, or leave the picker empty and set Dest directly (e.g. 8080 or 127.0.0.1:8080) to route to an external server such as Nginx. Each child inbound should listen on 127.0.0.1 with security=none.",
         "empty": "No fallbacks yet",
         "add": "Add fallback",
         "pickInbound": "Pick an inbound",
         "matchAny": "any",
         "destPlaceholder": "auto (child listen:port)",
-        "rederive": "Re-fill from child",
-        "rederived": "Re-filled from child",
-        "editAdvanced": "Edit routing fields",
-        "hideAdvanced": "Hide advanced",
-        "quickAddAll": "Quick add all eligible",
-        "quickAdded": "Added {n} fallback(s)",
-        "quickAddedNone": "No new eligible inbounds to add",
-        "routesWhen": "Routes when",
-        "defaultCatchAll": "Default — catches anything else",
         "needsTls": "Fallbacks become available once Security is set to TLS or Reality on the Security tab (VLESS/Trojan over RAW only)."
       },
       "protocol": "Protocol",
@@ -310,8 +276,6 @@
       "portMap": "Port Mapping",
       "traffic": "Traffic",
       "speed": "Speed",
-      "details": "Details",
-      "transportConfig": "Transport",
       "expireDate": "Duration",
       "createdAt": "Created",
       "updatedAt": "Updated",
@@ -319,8 +283,6 @@
       "addInbound": "Add Inbound",
       "generalActions": "General Actions",
       "modifyInbound": "Modify Inbound",
-      "deleteInbound": "Delete Inbound",
-      "deleteInboundContent": "Are you sure you want to delete this inbound?",
       "deleteConfirmTitle": "Delete inbound \"{remark}\"?",
       "deleteConfirmContent": "This removes the inbound and all its clients. This cannot be undone.",
       "resetConfirmTitle": "Reset traffic for \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "All-Inbounds",
       "exportAllSubsFileName": "All-Inbounds-Subs",
       "inboundJsonTitle": "Inbound JSON",
-      "deleteClient": "Delete Client",
-      "deleteClientContent": "Are you sure you want to delete this client?",
       "resetTrafficContent": "Are you sure you want to reset traffic?",
       "copyLink": "Copy URL",
       "address": "Address",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Unlimited. (unit: GB)",
       "totalFlow": "Total Flow",
       "leaveBlankToNeverExpire": "Leave blank to never expire",
-      "noRecommendKeepDefault": "It is recommended to keep the default",
       "certificatePath": "File Path",
       "certificateContent": "File Content",
       "publicKey": "Public Key",
       "privatekey": "Private Key",
-      "clickOnQRcode": "Click on QR Code to Copy",
       "client": "Client",
       "export": "Export All URLs",
       "clone": "Clone",
-      "cloneInbound": "Clone",
-      "cloneInboundContent": "All settings of this inbound, except Port, Listening IP, and Clients, will be applied to the clone.",
-      "cloneInboundOk": "Clone",
       "resetAllTraffic": "Reset Traffic for All Inbounds",
       "resetAllTrafficTitle": "Reset Traffic for All Inbounds",
       "resetAllTrafficContent": "Are you sure you want to reset the traffic of all inbounds?",
-      "resetInboundClientTraffics": "Reset Clients' Traffic",
-      "resetInboundClientTrafficTitle": "Reset Clients' Traffic",
-      "resetInboundClientTrafficContent": "Are you sure you want to reset the traffic of this inbound's clients?",
-      "resetAllClientTraffics": "Reset All Clients' Traffic",
-      "resetAllClientTrafficTitle": "Reset All Clients' Traffic",
-      "resetAllClientTrafficContent": "Are you sure you want to reset the traffic of all clients?",
-      "delDepletedClients": "Delete Depleted Clients",
-      "delDepletedClientsTitle": "Delete Depleted Clients",
-      "delDepletedClientsContent": "Are you sure you want to delete all the depleted clients?",
       "email": "Email",
-      "emailDesc": "Please provide a unique email address.",
       "IPLimit": "IP Limit",
-      "IPLimitDesc": "Disables inbound if the count exceeds the set value. (0 = disable)",
       "IPLimitlog": "IP Log",
-      "IPLimitlogDesc": "The IP history log. (to re-enable the inbound after disabling, clear the log)",
       "IPLimitlogclear": "Clear the Log",
       "setDefaultCert": "Set Cert from Panel",
       "setDefaultCertEmpty": "No certificate is configured for the panel. Set one under Settings first.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Xray sniffing block wrapper:",
         "stream": "Stream",
-        "streamHelp": "Xray stream block wrapper:",
-        "jsonErrorPrefix": "Advanced JSON"
+        "streamHelp": "Xray stream block wrapper:"
       },
-      "telegramDesc": "Please provide Telegram Chat ID. (use '/id' command in the bot) or ({'@'}userinfobot)",
-      "subscriptionDesc": "To find your subscription URL, navigate to the 'Details'. Additionally, you can use the same name for several clients.",
       "subSortIndex": "Sub order",
-      "same": "Same",
       "inboundInfo": "Inbound Information",
       "exportInbound": "Export Inbound",
       "import": "Import",
       "importInbound": "Import an Inbound",
       "periodicTrafficResetTitle": "Traffic Reset",
-      "periodicTrafficResetDesc": "Automatically reset traffic counter at specified intervals",
       "periodicTrafficResetDay": "Monthly reset day",
-      "lastReset": "Last Reset",
       "periodicTrafficReset": {
         "never": "Never",
         "daily": "Daily",
@@ -464,7 +401,6 @@
         "obtain": "Obtain",
         "updateSuccess": "The update was successful.",
         "logCleanSuccess": "The log has been cleared.",
-        "inboundsUpdateSuccess": "Inbounds have been successfully updated.",
         "inboundUpdateSuccess": "Inbound has been successfully updated.",
         "inboundCreateSuccess": "Inbound has been successfully created.",
         "bulkDeleted": "{count} inbounds deleted",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Inbound client has been deleted.",
         "inboundClientUpdateSuccess": "Inbound client has been updated.",
         "savedNodeOfflineWillSync": "Saved locally. A backing node is offline or disabled — the change will sync once it reconnects.",
-        "delDepletedClientsSuccess": "All depleted clients have been deleted.",
         "resetAllClientTrafficSuccess": "Traffic for all clients has been reset.",
         "resetAllTrafficSuccess": "All traffic has been reset.",
         "resetInboundClientTrafficSuccess": "Traffic has been reset.",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Peer {n} config"
       },
-      "stream": {
-        "general": {
-          "request": "Request",
-          "response": "Response",
-          "name": "Name",
-          "value": "Value"
-        },
-        "tcp": {
-          "version": "Version",
-          "method": "Method",
-          "path": "Path",
-          "status": "Status",
-          "statusDescription": "Status Desc",
-          "requestHeader": "Request Header",
-          "responseHeader": "Response Header"
-        }
-      },
       "sniffingDestOverride": "Destination override"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Add External Subscription",
       "noExternalLinks": "No external links yet.",
       "noExternalSubscriptions": "No external subscriptions yet.",
-      "add": "Add Client",
-      "edit": "Edit Client",
-      "submitAdd": "Add Client",
       "submitEdit": "Save Changes",
       "clientCount": "Number of Clients",
       "bulk": "Add Bulk",
-      "copyFromInbound": "Copy Clients from Inbound",
-      "copyToInbound": "Copy clients to",
-      "copySelected": "Copy Selected",
-      "copySource": "Source",
-      "copyEmailPreview": "Resulting email preview",
-      "copySelectSourceFirst": "Please select a source inbound first.",
-      "copyResult": "Copy result",
-      "copyResultSuccess": "Copied successfully",
-      "copyResultNone": "Nothing to copy: no clients selected or source is empty",
-      "copyResultErrors": "Copy errors",
-      "copyFlowLabel": "Flow for new clients (VLESS)",
-      "copyFlowHint": "Applied to all copied clients. Leave empty to skip.",
       "selectAll": "Select all",
       "clearAll": "Clear all",
       "method": "Method",
@@ -775,7 +678,6 @@
       "postfix": "Postfix",
       "delayedStart": "Start After First Use",
       "expireDays": "Duration (days)",
-      "days": "Day(s)",
       "renew": "Auto Renew",
       "renewDesc": "Auto-renewal after expiration. (0 = disable)(unit: day)",
       "renewDays": "Auto Renew (days)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Expiring soonest",
       "has": "Has",
       "hasNot": "Doesn't have",
-      "title": "Clients",
       "actions": "Actions",
       "totalGB": "Traffic Limit (GB)",
       "totalGBDesc": "Data quota for this client. 0 = unlimited.",
@@ -826,8 +727,6 @@
       "addClient": "Add Client",
       "qrCode": "QR Code",
       "clientInfo": "Client Information",
-      "delete": "Delete",
-      "reset": "Reset Traffic",
       "editClient": "Edit Client",
       "client": "Client",
       "enabled": "Enabled",
@@ -841,13 +740,11 @@
       "noLinks": "No shareable links — attach this client to a protocol-capable inbound first.",
       "link": "Link",
       "resetNotPossible": "Attach this client to an inbound first.",
-      "general": "General",
       "resetAllTraffics": "Reset all client traffic",
       "resetAllTrafficsTitle": "Reset all client traffic?",
       "resetAllTrafficsContent": "Every client's up/down counter drops to zero. Quotas and expiry are not affected. This cannot be undone.",
       "deleteConfirmTitle": "Delete client {email}?",
       "deleteConfirmContent": "This removes the client from every attached inbound and drops its traffic record. This cannot be undone.",
-      "deleteSelected": "Delete ({count})",
       "adjustSelected": "Adjust ({count})",
       "subLinksSelected": "Sub links ({count})",
       "addToGroupTitle": "Add {count} client(s) to a group",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Disable {count} clients?",
       "bulkDisableConfirmContent": "Disables each selected client on every attached inbound. They lose access immediately but their records and traffic are kept.",
       "selectedCount": "{count} selected",
-      "attachSelected": "Attach ({count})",
       "attachToInboundsTitle": "Attach {count} client(s) to inbound(s)",
       "attachToInboundsDesc": "Attaches the selected {count} client(s) (same UUID/password and shared traffic) to the chosen inbound(s). They keep their existing attachments too.",
       "attachToInboundsTargets": "Target inbounds",
       "attachToInboundsNoTargets": "No multi-user inbounds available to attach to.",
-      "detachSelected": "Detach ({count})",
       "detach": "Detach",
       "detachFromInboundsTitle": "Detach {count} client(s) from inbound(s)",
       "detachFromInboundsDesc": "Removes the selected {count} client(s) from the chosen inbound(s). Pairs where the client wasn't attached are silently skipped. Client records are kept (use Delete to remove fully).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Optional reverse tag",
       "telegramId": "Telegram user ID",
       "telegramIdPlaceholder": "Numeric Telegram user ID (0 = none)",
-      "created": "Created",
-      "updated": "Updated",
       "ipLimit": "IP limit",
       "toasts": {
         "deleted": "Client deleted",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Groups",
       "name": "Name",
       "clientCount": "Clients",
       "totalGroups": "Total groups",
@@ -1111,7 +1003,6 @@
       }
     },
     "nodes": {
-      "title": "Nodes",
       "addNode": "Add Node",
       "editNode": "Edit Node",
       "totalNodes": "Total Nodes",
@@ -1130,8 +1021,6 @@
       "apiTokenPlaceholder": "Token from the remote panel's Settings page",
       "apiTokenHint": "The remote panel exposes its API token under Authentication → API Token.",
       "apiTokenKeepHint": "Leave blank to keep the current token",
-      "regenerate": "Regenerate Token",
-      "regenerateConfirm": "Regenerating invalidates the current token. Any central panel using it will lose access until updated. Continue?",
       "allowPrivateAddress": "Allow private address",
       "allowPrivateAddressHint": "Enable only for nodes on a private network or VPN.",
       "outboundTag": "Connection outbound",
@@ -1163,7 +1052,6 @@
       "updatePanel": "Update Panel",
       "updateSelected": "Update Selected ({count})",
       "updateAvailable": "Update available",
-      "upToDate": "Up to date",
       "updateConfirmTitle": "Update {count} node(s) to the latest version?",
       "updateConfirmContent": "Each selected node downloads the latest release and restarts onto it. Only enabled, online nodes are updated.",
       "updateDevChannel": "Update to Dev channel (latest commit)",
@@ -1227,6 +1115,7 @@
       "pinFetchFailed": "Could not fetch the certificate"
     },
     "settings": {
+      "defaultTag": "Default",
       "title": "Panel Settings",
       "save": "Save",
       "infoDesc": "Every change made here needs to be saved. Please restart the panel to apply changes.",
@@ -1564,13 +1453,8 @@
       "secretClearUndo": "Undo clear"
     },
     "xray": {
-      "title": "Xray Configs",
       "save": "Save",
-      "restart": "Restart Xray",
       "restartSuccess": "Xray has been successfully relaunched.",
-      "restartOutputTitle": "Xray restart output",
-      "restartConfirmTitle": "Restart xray?",
-      "restartConfirmContent": "Reloads the xray service with the saved configuration.",
       "stopSuccess": "Xray has been successfully stopped.",
       "restartError": "There was an error when rebooting the Xray.",
       "stopError": "There was an error when stopping the Xray.",
@@ -1580,7 +1464,6 @@
       "generalConfigsDesc": "These options will determine general adjustments.",
       "logConfigs": "Log",
       "logConfigsDesc": "Logs may affect your server's efficiency. It is recommended to enable them wisely only when needed.",
-      "blockConfigsDesc": "These options will block traffic based on specific requested protocols and websites.",
       "basicRouting": "Basic Routing",
       "blockConnectionsConfigsDesc": "These options will block traffic based on the specific requested country.",
       "directConnectionsConfigsDesc": "A direct connection ensures that specific traffic is not routed through another server.",
@@ -1590,10 +1473,6 @@
       "directdomains": "Direct Domains",
       "ipv4Routing": "IPv4 Routing",
       "ipv4RoutingDesc": "These options will route traffic based on a specific destination via IPv4.",
-      "warpRouting": "WARP Routing",
-      "warpRoutingDesc": "These options will route traffic based on a specific destination via WARP.",
-      "nordRouting": "NordVPN Routing",
-      "nordRoutingDesc": "These options will route traffic based on a specific destination via NordVPN.",
       "Template": "Advanced Xray Configuration Template",
       "TemplateDesc": "The final Xray config file will be generated based on this template.",
       "FreedomStrategy": "Freedom Protocol Strategy",
@@ -1607,10 +1486,7 @@
       "outboundTestUrlDesc": "URL used when testing outbound connectivity.",
       "Torrent": "Block BitTorrent Protocol",
       "Inbounds": "Inbounds",
-      "InboundsDesc": "Accepting the specific clients.",
       "Outbounds": "Outbounds",
-      "OutboundSubscriptions": "Outbound Subscriptions",
-      "OutboundSubscriptionsDesc": "Import outbounds from remote subscription URLs (vmess/vless/trojan/ss/...). Tags are kept stable for use in balancers and routing rules. Updates are automatic.",
       "Balancers": "Balancers",
       "balancerTagRequired": "Tag is required",
       "balancerSelectorRequired": "Pick at least one outbound",
@@ -1629,9 +1505,7 @@
       "routeTesterMatchedOutbound": "Matched outbound",
       "routeTesterViaBalancer": "via balancer",
       "routeTesterDefaultOutbound": "No routing rule matched — traffic goes to the default (first) outbound.",
-      "OutboundsDesc": "Set the outgoing traffic pathway.",
       "Routings": "Routing Rules",
-      "RoutingsDesc": "The priority of each rule is important!",
       "importRules": "Import Rules",
       "exportRules": "Export Rules",
       "importOutbounds": "Import Outbounds",
@@ -1650,13 +1524,9 @@
       "maskAddressDesc": "IP address mask, when enabled, will automatically replace the IP address that appears in the log.",
       "statistics": "Statistics",
       "statsInboundUplink": "Inbound Upload Statistics",
-      "statsInboundUplinkDesc": "Enables the statistics collection for upstream traffic of all inbound proxies.",
       "statsInboundDownlink": "Inbound Download Statistics",
-      "statsInboundDownlinkDesc": "Enables the statistics collection for downstream traffic of all inbound proxies.",
       "statsOutboundUplink": "Outbound Upload Statistics",
-      "statsOutboundUplinkDesc": "Enables the statistics collection for upstream traffic of all outbound proxies.",
       "statsOutboundDownlink": "Outbound Download Statistics",
-      "statsOutboundDownlinkDesc": "Enables the statistics collection for downstream traffic of all outbound proxies.",
       "metricsListen": "Metrics Endpoint",
       "metricsListenDesc": "Expose Xray's Prometheus-style metrics on this address:port (e.g. 127.0.0.1:11111). Leave empty to disable. Bind to localhost and reverse-proxy it — it is unauthenticated.",
       "metricsTag": "Metrics Tag",
@@ -1669,18 +1539,10 @@
       "bufferSizePlaceholder": "auto",
       "seconds": "seconds",
       "rules": {
-        "first": "First",
-        "last": "Last",
-        "up": "Up",
-        "down": "Down",
         "source": "Source",
         "dest": "Destination",
         "inbound": "Inbound",
-        "outbound": "Outbound",
         "balancer": "Balancer",
-        "info": "Info",
-        "add": "Add Rule",
-        "edit": "Edit Rule",
         "useComma": "Comma-separated list"
       },
       "routing": {
@@ -1721,7 +1583,6 @@
         "ruleN": "Rule {n}",
         "action": "Action",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Final Rules",
         "overrideXrayPrivateIp": "Override Xray's default private-IP block",
         "blockDelay": "Block delay (ms)",
@@ -1747,43 +1608,17 @@
         "keepAliveInterval": "Keep alive interval",
         "markFwmark": "Mark (fwmark)",
         "interface": "Interface",
-        "ipv6Only": "IPv6 only",
-        "acceptProxyProtocol": "Accept proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "Add Outbound",
-        "addReverse": "Add Reverse",
-        "editOutbound": "Edit Outbound",
-        "editReverse": "Edit Reverse",
-        "reverseTag": "Reverse Tag",
-        "reverseTagDesc": "VLESS simple reverse proxy tag. Leave empty to disable.",
-        "reverseTagPlaceholder": "reverse tag (leave empty to disable)",
         "tag": "Tag",
-        "tagDesc": "Unique Tag",
-        "address": "Address",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Reverse",
-        "domain": "Domain",
-        "type": "Type",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Link",
-        "intercon": "Interconnection",
-        "settings": "Settings",
-        "accountInfo": "Account Information",
         "outboundStatus": "Outbound Status",
         "sendThrough": "Send Through",
         "targetStrategy": "Target Strategy",
-        "test": "Test",
-        "testResult": "Test Result",
-        "testing": "Testing connection...",
-        "testSuccess": "Test successful",
-        "testFailed": "Test failed",
-        "testError": "Failed to test outbound",
         "modeRealDelay": "Real delay",
         "testModeTooltip": "TCP: fast dial-only probe. HTTP: full request through xray. Real delay: total time including connection setup.",
         "testAll": "Test all",
@@ -1791,14 +1626,10 @@
         "breakdownConnect": "Proxy connect",
         "breakdownTls": "TLS via outbound",
         "breakdownTtfb": "First byte",
-        "nordvpn": "NordVPN",
-        "accessToken": "Access Token",
         "country": "Country",
         "server": "Server",
         "city": "City",
         "allCities": "All Cities",
-        "privateKey": "Private Key",
-        "load": "Load",
         "moveToTop": "Move to top"
       },
       "outboundSub": {
@@ -1828,16 +1659,11 @@
         "active": "Active subscriptions",
         "empty": "No subscriptions yet. Add one above.",
         "colRemark": "Remark",
-        "colPrefix": "Prefix",
-        "colInterval": "Interval",
         "colLastFetch": "Last fetch",
         "colEnabled": "Enabled",
         "auto": "auto",
         "never": "never",
-        "yes": "Yes",
-        "no": "No",
         "refreshNow": "Refresh now",
-        "lastError": "Last error",
         "deleteConfirm": "Delete this subscription?",
         "restartHint": "After adding or refreshing, restart Xray (or wait for the next auto-reload) to make the outbounds active.",
         "fromSubsTitle": "From outbound subscriptions (read-only)",
@@ -1854,8 +1680,6 @@
       "tabBalancerSettings": "Balancer Settings",
       "tabObservatory": "Observatory",
       "observatory": {
-        "title": "Observatory",
-        "burstTitle": "Burst Observatory",
         "autoManaged": "Observers are managed automatically from your balancers. Tune how they probe below — the watched outbounds follow your balancer selectors.",
         "emptyHint": "No connection observer is active. One is added automatically when you create a Least Ping or Least Load balancer — or a Random / Round-robin balancer with a fallback — so observer-backed balancers can check outbound health before choosing a target.",
         "mixedLegacy": "This config contains both Observatory and Burst Observatory. Xray uses one global observer, so this mixed legacy state is not supported; saving balancers will normalize it to one observer.",
@@ -1889,12 +1713,8 @@
         "balancerRemoved": "Balancer {tag} — removed (no targets left)"
       },
       "balancer": {
-        "addBalancer": "Add Balancer",
-        "editBalancer": "Edit Balancer",
         "balancerStrategy": "Strategy",
-        "balancerSelectors": "Selectors",
         "tag": "Tag",
-        "tagDesc": "Unique Tag",
         "tagDuplicate": "Tag already used by another balancer",
         "tagPlaceholder": "unique balancer tag",
         "selector": "Selector",
@@ -1911,7 +1731,6 @@
         "tolerance": "Tolerance",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "It is not possible to use balancerTag and outboundTag at the same time. If used at the same time, only outboundTag will work.",
         "costMatch": "Tag pattern",
         "costValue": "Weight",
         "costRegexp": "Regular expression match"
@@ -1921,14 +1740,10 @@
         "publicKey": "Public Key",
         "allowedIPs": "Allowed IPs",
         "endpoint": "Endpoint",
-        "psk": "PreShared Key",
         "domainStrategy": "Domain Strategy"
       },
       "tun": {
-        "nameDesc": "The name of the TUN interface. Default is 'xray0'",
-        "mtuDesc": "Maximum Transmission Unit. The maximum size of data packets. Default is 1500",
-        "userLevel": "User Level",
-        "userLevelDesc": "All connections made through this inbound will use this user level. Default is 0"
+        "userLevel": "User Level"
       },
       "nord": {
         "accessToken": "Access token",
@@ -2013,7 +1828,6 @@
       },
       "fakedns": {
         "add": "Add Fake DNS",
-        "edit": "Edit Fake DNS",
         "ipPool": "IP Pool Subnet",
         "poolSize": "Pool Size"
       },
@@ -2032,7 +1846,6 @@
     "add": "Add",
     "month": "Month",
     "months": "Months",
-    "day": "Day",
     "days": "Days",
     "hours": "Hours",
     "minutes": "Minutes",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Telegram User saved.",
       "loginSuccess": "✅ Logged in to the panel successfully.\r\n",
       "loginFailed": "❗️Login attempt to the panel failed.\r\n",
-      "2faFailed": "2FA Failed",
       "report": "🕰 Scheduled Reports: {{ .RunTime }}\r\n",
       "datetime": "⏰ Date&Time: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Download: ↓{{ .Download }}\r\n",
       "total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Telegram User: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Exhausted {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Exhausted {{ .Type }} count:\r\n",
       "onlinesCount": "🌐 Online Clients: {{ .Count }}\r\n",
       "disabled": "🛑 Disabled: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Refreshed On: {{ .Time }}\r\n\r\n",
       "yes": "✅ Yes",
       "no": "❌ No",
-      "received_id": "🔑📥 ID updated.",
-      "received_password": "🔑📥 Password updated.",
       "received_email": "📧📥 Email updated.",
       "received_comment": "💬📥 Comment updated.",
-      "id_prompt": "🔑 Default ID: {{ .ClientId }}\n\nEnter your ID.",
-      "pass_prompt": "🔑 Default Password: {{ .ClientPassword }}\n\nEnter your password.",
       "email_prompt": "📧 Default Email: {{ .ClientEmail }}\n\nEnter your email.",
       "comment_prompt": "💬 Default Comment: {{ .ClientComment }}\n\nEnter your comment.",
-      "inbound_client_data_id": "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!",
-      "inbound_client_data_pass": "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 Password: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!",
       "cancel": "❌ Process Canceled! \n\nYou can /start again anytime. 🔄",
       "error_add_client": "⚠️ Error:\n\n {{ .error }}",
       "using_default_value": "Okay, I'll stick with the default value. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Error: {{ .Error }}",
       "eventNodeDown": "Node {{ .Name }} is DOWN",
       "eventNodeUp": "Node {{ .Name }} is UP",
-      "eventCPUHigh": "CPU high",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Login failed from {{ .Source }}",
       "memoryThreshold": "Memory Load {{ .Percent }}% exceeds the threshold of {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Submit As Disable ☑️",
       "submitEnable": "Submit As Enable ✅",
       "use_default": "🏷️ Use default",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Password",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Comment",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Reset All Traffic",
       "SortedTrafficUsageReport": "Sorted Traffic Usage Report"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "Outbound {{ .Tag }} is DOWN",
-    "subjectOutboundUp": "Outbound {{ .Tag }} is UP",
-    "subjectXrayCrash": "Xray CRASHED",
-    "subjectCPUHigh": "CPU high",
-    "subjectLoginSuccess": "Login successful",
-    "subjectLoginFailed": "Login failed",
-    "titleOutboundDown": "Outbound DOWN",
-    "titleOutboundUp": "Outbound UP",
-    "titleXrayCrash": "Xray CRASHED",
-    "titleCPUHigh": "CPU high",
-    "titleLoginSuccess": "Login successful",
-    "titleLoginFailed": "Login failed",
     "labelStatus": "Status",
     "labelOutbound": "Outbound",
     "labelNode": "Node",
     "labelError": "Error",
     "labelDelay": "Delay",
-    "labelDetail": "Detail",
     "labelUsername": "Username",
     "labelIP": "IP",
     "labelReason": "Reason",
     "labelSource": "Source",
-    "labelTime": "Time",
     "statusCrashed": "CRASHED",
-    "statusRunning": "Running",
     "statusHigh": "HIGH",
     "statusSuccess": "SUCCESS",
     "statusFailed": "FAILED",

+ 3 - 218
internal/web/translation/es-ES.json

@@ -48,7 +48,6 @@
   "copySuccess": "Copiado exitosamente",
   "sure": "Seguro",
   "encryption": "Encriptación",
-  "useIPv4ForHost": "Usar IPv4 para el host",
   "transmission": "Transmisión",
   "host": "Host",
   "path": "Ruta",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Código",
   "remained": "Restante",
   "security": "Seguridad",
-  "secAlertTitle": "Alerta de Seguridad",
-  "secAlertSsl": "Esta conexión no es segura. Por favor, evite ingresar información sensible hasta que se active TLS para la protección de datos.",
-  "secAlertConf": "Ciertas configuraciones son vulnerables a ataques. Se recomienda reforzar los protocolos de seguridad para prevenir posibles violaciones.",
-  "secAlertSSL": "El panel carece de una conexión segura. Por favor, instale un certificado TLS para la protección de datos.",
-  "secAlertPanelPort": "El puerto predeterminado del panel es vulnerable. Por favor, configure un puerto aleatorio o específico.",
-  "secAlertPanelURI": "La ruta URI predeterminada del panel no es segura. Por favor, configure una ruta URI compleja.",
-  "secAlertSubURI": "La ruta URI predeterminada de la suscripción no es segura. Por favor, configure una ruta URI compleja.",
-  "secAlertSubJsonURI": "La ruta URI JSON predeterminada de la suscripción no es segura. Por favor, configure una ruta URI compleja.",
   "emptyDnsDesc": "No hay servidores DNS añadidos.",
   "emptyFakeDnsDesc": "No hay servidores Fake DNS añadidos.",
   "emptyBalancersDesc": "No hay balanceadores añadidos.",
-  "emptyReverseDesc": "No hay proxies inversos añadidos.",
   "somethingWentWrong": "Algo salió mal",
   "subscription": {
     "title": "Información de suscripción",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Tema",
-    "dark": "Oscuro",
-    "ultraDark": "Ultra Oscuro",
     "dashboard": "Estado del Sistema",
     "inbounds": "Entradas",
     "clients": "Clientes",
@@ -118,7 +106,6 @@
     "routing": "Enrutamiento",
     "outbounds": "Salidas",
     "apiDocs": "Documentación de la API",
-    "logout": "Cerrar Sesión",
     "link": "Gestionar",
     "donate": "Donar",
     "hosts": "Hosts",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Estado del Sistema",
       "cpu": "CPU",
       "logicalProcessors": "Procesadores lógicos",
       "frequency": "Frecuencia",
@@ -152,7 +138,6 @@
       "restartXray": "Reiniciar",
       "xraySwitch": "Versión",
       "xrayUpdates": "Actualizaciones de Xray",
-      "xraySwitchClick": "Elige la versión a la que deseas cambiar.",
       "xraySwitchClickDesk": "Elige sabiamente, ya que las versiones anteriores pueden no ser compatibles con las configuraciones actuales.",
       "updatePanel": "Actualizar panel",
       "panelUpdateDesc": "Esto actualizará 3X-UI a la última versión y reiniciará el servicio del panel.",
@@ -164,12 +149,10 @@
       "currentCommit": "Commit actual",
       "latestCommit": "Último commit",
       "updateChannelChanged": "Canal de actualización cambiado",
-      "upToDate": "Actualizado",
       "xrayStatusUnknown": "Desconocido",
       "xrayStatusRunning": "En ejecución",
       "xrayStatusStop": "Detenido",
       "xrayStatusError": "Error",
-      "xrayErrorPopoverTitle": "Se produjo un error al ejecutar Xray",
       "operationHours": "Tiempo de Funcionamiento",
       "systemHistoryTitle": "Historial del Sistema",
       "historyTitleCpu": "Uso de CPU",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Caído",
       "xrayObservatoryLastSeen": "Visto por última vez",
       "xrayObservatoryLastTry": "Último intento",
-      "trendLast2Min": "Últimos 2 minutos",
-      "systemLoad": "Carga del Sistema",
-      "systemLoadDesc": "promedio de carga del sistema en los últimos 1, 5 y 15 minutos",
       "connectionCount": "Número de Conexiones",
       "ipAddresses": "Direcciones IP",
       "toggleIpVisibility": "Alternar visibilidad de la IP",
@@ -223,13 +203,11 @@
       "totalData": "Datos totales",
       "sent": "Enviado",
       "received": "Recibido",
-      "documentation": "Documentación",
       "xraySwitchVersionDialog": "¿Realmente deseas cambiar la versión de Xray?",
       "xraySwitchVersionDialogDesc": "Esto cambiará la versión de Xray a #version#.",
       "xraySwitchVersionPopover": "Xray se actualizó correctamente",
       "panelUpdateDialog": "¿Deseas actualizar el panel?",
       "panelUpdateDialogDesc": "Esto actualizará 3X-UI a la versión #version# y reiniciará el servicio del panel.",
-      "panelUpdateCheckPopover": "Fallo al comprobar actualización del panel",
       "panelUpdateStartedPopover": "Actualización del panel iniciada",
       "panelUpdateFailedTitle": "Error al actualizar el panel",
       "panelUpdateFailedDesc": "La actualización no se completó correctamente. Revisa los registros del servidor o ejecuta 'x-ui update' desde la línea de comandos.",
@@ -258,7 +236,6 @@
       "accessLogs": "Registros de acceso",
       "autoUpdate": "Actualización automática",
       "config": "Configuración",
-      "backup": "Copia de seguridad",
       "backupTitle": "Copia & Restauración",
       "exportDatabase": "Copia de seguridad",
       "exportDatabaseDesc": "Haz clic para descargar un archivo .db que contiene una copia de seguridad de tu base de datos actual en tu dispositivo. El mismo archivo también puede restaurarse en un panel que funcione con PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Haz clic para descargar una base de datos SQLite .db creada a partir de tus datos de PostgreSQL, lista para ejecutar este panel en SQLite."
     },
     "inbounds": {
-      "title": "Entradas",
       "totalDownUp": "Subidas/Descargas Totales",
       "totalUsage": "Uso Total",
       "inboundCount": "Número de Entradas",
@@ -288,21 +264,11 @@
       "localPanel": "Panel local",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "Cuando una conexión en este inbound no coincide con ningún cliente, redirígela a otro lugar. Elige un inbound hijo abajo para rellenar automáticamente los campos de enrutamiento (SNI / ALPN / Path / xver) desde su transporte, o deja el selector vacío y define Dest directamente (p. ej. 8080 o 127.0.0.1:8080) para redirigir a un servidor externo como Nginx. Cada inbound hijo debe escuchar en 127.0.0.1 con security=none.",
         "empty": "Aún no hay fallbacks",
         "add": "Añadir fallback",
         "pickInbound": "Selecciona un inbound",
         "matchAny": "cualquiera",
         "destPlaceholder": "automático (listen:puerto del hijo)",
-        "rederive": "Rellenar desde el hijo",
-        "rederived": "Rellenado desde el hijo",
-        "editAdvanced": "Editar campos de enrutamiento",
-        "hideAdvanced": "Ocultar avanzado",
-        "quickAddAll": "Añadir todos los elegibles",
-        "quickAdded": "Se añadieron {n} fallback(s)",
-        "quickAddedNone": "No hay nuevos inbounds elegibles",
-        "routesWhen": "Enruta cuando",
-        "defaultCatchAll": "Por defecto — captura cualquier otra cosa",
         "needsTls": "Los fallbacks estarán disponibles al seleccionar TLS o Reality en la pestaña de Seguridad (solo VLESS/Trojan sobre RAW)."
       },
       "protocol": "Protocolo",
@@ -310,8 +276,6 @@
       "portMap": "Asignación de puertos",
       "traffic": "Tráfico",
       "speed": "Velocidad",
-      "details": "Detalles",
-      "transportConfig": "Transporte",
       "expireDate": "Fecha de Expiración",
       "createdAt": "Creado",
       "updatedAt": "Actualizado",
@@ -319,8 +283,6 @@
       "addInbound": "Agregar Entrada",
       "generalActions": "Acciones Generales",
       "modifyInbound": "Modificar Entrada",
-      "deleteInbound": "Eliminar Entrada",
-      "deleteInboundContent": "¿Confirmar eliminación de entrada?",
       "deleteConfirmTitle": "¿Eliminar el inbound \"{remark}\"?",
       "deleteConfirmContent": "Esto elimina el inbound y todos sus clientes. No se puede deshacer.",
       "resetConfirmTitle": "¿Restablecer el tráfico de \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Todas-las-entradas",
       "exportAllSubsFileName": "Todas-las-entradas-Subs",
       "inboundJsonTitle": "JSON de entrada",
-      "deleteClient": "Eliminar cliente",
-      "deleteClientContent": "¿Está seguro de que desea eliminar el cliente?",
       "resetTrafficContent": "¿Confirmar restablecimiento de tráfico?",
       "copyLink": "Copiar Enlace",
       "address": "Dirección",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Ilimitado. (unidad: GB)",
       "totalFlow": "Flujo Total",
       "leaveBlankToNeverExpire": "Dejar en Blanco para Nunca Expirar",
-      "noRecommendKeepDefault": "No hay requisitos especiales para mantener la configuración predeterminada",
       "certificatePath": "Ruta Cert",
       "certificateContent": "Datos Cert",
       "publicKey": "Clave Pública",
       "privatekey": "Clave Privada",
-      "clickOnQRcode": "Haz clic en el Código QR para Copiar",
       "client": "Cliente",
       "export": "Exportar Enlaces",
       "clone": "Clonar",
-      "cloneInbound": "Clonar Entradas",
-      "cloneInboundContent": "Se aplicarán todas las configuraciones de esta entrada, excepto el Puerto, la IP de Escucha y los Clientes, al clon.",
-      "cloneInboundOk": "Clonar",
       "resetAllTraffic": "Restablecer Tráfico de Todas las Entradas",
       "resetAllTrafficTitle": "Restablecer tráfico de todas las entradas",
       "resetAllTrafficContent": "¿Estás seguro de que deseas restablecer el tráfico de todas las entradas?",
-      "resetInboundClientTraffics": "Restablecer Tráfico de Clientes",
-      "resetInboundClientTrafficTitle": "Restablecer todo el tráfico de clientes",
-      "resetInboundClientTrafficContent": "¿Estás seguro de que deseas restablecer todo el tráfico para los clientes de esta entrada?",
-      "resetAllClientTraffics": "Restablecer Tráfico de Todos los Clientes",
-      "resetAllClientTrafficTitle": "Restablecer todo el tráfico de clientes",
-      "resetAllClientTrafficContent": "¿Estás seguro de que deseas restablecer todo el tráfico para todos los clientes?",
-      "delDepletedClients": "Eliminar Clientes Agotados",
-      "delDepletedClientsTitle": "Eliminar clientes agotados",
-      "delDepletedClientsContent": "¿Estás seguro de que deseas eliminar todos los clientes agotados?",
       "email": "Email",
-      "emailDesc": "Por favor proporciona una dirección de correo electrónico única.",
       "IPLimit": "Límite de IP",
-      "IPLimitDesc": "Desactiva la entrada si la cantidad supera el valor ingresado (ingresa 0 para desactivar el límite de IP).",
       "IPLimitlog": "Registro de IP",
-      "IPLimitlogDesc": "Registro de historial de IPs (antes de habilitar la entrada después de que haya sido desactivada por el límite de IP, debes borrar el registro).",
       "IPLimitlogclear": "Limpiar el Registro",
       "setDefaultCert": "Establecer certificado desde el panel",
       "setDefaultCertEmpty": "No hay certificado configurado para el panel. Configura uno en Ajustes primero.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Envoltorio del bloque sniffing de Xray:",
         "stream": "Stream",
-        "streamHelp": "Envoltorio del bloque stream de Xray:",
-        "jsonErrorPrefix": "JSON avanzado"
+        "streamHelp": "Envoltorio del bloque stream de Xray:"
       },
-      "telegramDesc": "Por favor, proporciona el ID de Chat de Telegram. (usa el comando '/id' en el bot) o ({'@'}userinfobot)",
-      "subscriptionDesc": "Puedes encontrar tu enlace de suscripción en Detalles, también puedes usar el mismo nombre para varias configuraciones.",
       "subSortIndex": "Orden sub",
-      "same": "misma",
       "inboundInfo": "Información de entrada",
       "exportInbound": "Exportación entrante",
       "import": "Importar",
       "importInbound": "Importar un entrante",
       "periodicTrafficResetTitle": "Reset de Tráfico",
-      "periodicTrafficResetDesc": "Reiniciar automáticamente el contador de tráfico en intervalos especificados",
       "periodicTrafficResetDay": "Día de reinicio mensual",
-      "lastReset": "Último reinicio",
       "periodicTrafficReset": {
         "never": "Nunca",
         "daily": "Diariamente",
@@ -464,7 +401,6 @@
         "obtain": "Recibir",
         "updateSuccess": "La actualización fue exitosa",
         "logCleanSuccess": "El registro ha sido limpiado",
-        "inboundsUpdateSuccess": "Entradas actualizadas correctamente",
         "inboundUpdateSuccess": "Entrada actualizada correctamente",
         "inboundCreateSuccess": "Entrada creada correctamente",
         "bulkDeleted": "{count} inbounds eliminados",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Cliente de entrada eliminado",
         "inboundClientUpdateSuccess": "Cliente de entrada actualizado",
         "savedNodeOfflineWillSync": "Guardado localmente. Un nodo de respaldo está desconectado o deshabilitado: el cambio se sincronizará cuando vuelva a conectarse.",
-        "delDepletedClientsSuccess": "Todos los clientes con tráfico agotado fueron eliminados",
         "resetAllClientTrafficSuccess": "Todo el tráfico del cliente ha sido reiniciado",
         "resetAllTrafficSuccess": "Todo el tráfico ha sido reiniciado",
         "resetInboundClientTrafficSuccess": "El tráfico ha sido reiniciado",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Config Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Pedido",
-          "response": "Respuesta",
-          "name": "Nombre",
-          "value": "Valor"
-        },
-        "tcp": {
-          "version": "Versión",
-          "method": "Método",
-          "path": "Ruta",
-          "status": "Estado",
-          "statusDescription": "Descripción de la Situación",
-          "requestHeader": "Encabezado de solicitud",
-          "responseHeader": "Encabezado de respuesta"
-        }
-      },
       "sniffingDestOverride": "Anulación de destino"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Añadir suscripción externa",
       "noExternalLinks": "Aún no hay enlaces externos.",
       "noExternalSubscriptions": "Aún no hay suscripciones externas.",
-      "add": "Añadir cliente",
-      "edit": "Editar cliente",
-      "submitAdd": "Añadir cliente",
       "submitEdit": "Guardar cambios",
       "clientCount": "Número de clientes",
       "bulk": "Añadir en lote",
-      "copyFromInbound": "Copiar clientes desde inbound",
-      "copyToInbound": "Copiar clientes a",
-      "copySelected": "Copiar selección",
-      "copySource": "Origen",
-      "copyEmailPreview": "Vista previa del correo resultante",
-      "copySelectSourceFirst": "Selecciona primero un inbound de origen.",
-      "copyResult": "Resultado de la copia",
-      "copyResultSuccess": "Copiado correctamente",
-      "copyResultNone": "Nada que copiar: no hay clientes seleccionados o el origen está vacío",
-      "copyResultErrors": "Errores de copia",
-      "copyFlowLabel": "Flow para clientes nuevos (VLESS)",
-      "copyFlowHint": "Se aplica a todos los clientes copiados. Déjalo vacío para omitir.",
       "selectAll": "Seleccionar todo",
       "clearAll": "Limpiar todo",
       "method": "Método",
@@ -775,7 +678,6 @@
       "postfix": "Sufijo",
       "delayedStart": "Iniciar tras el primer uso",
       "expireDays": "Duración (días)",
-      "days": "Día(s)",
       "renew": "Renovación automática",
       "renewDesc": "Renovación automática tras la expiración. (0 = desactivado) (unidad: día)",
       "renewDays": "Renovación automática (días)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Caducidad más próxima",
       "has": "Tiene",
       "hasNot": "No tiene",
-      "title": "Clientes",
       "actions": "Acciones",
       "totalGB": "Límite de tráfico (GB)",
       "totalGBDesc": "Cuota de datos para este cliente. 0 = ilimitado.",
@@ -826,8 +727,6 @@
       "addClient": "Añadir cliente",
       "qrCode": "Código QR",
       "clientInfo": "Información del cliente",
-      "delete": "Eliminar",
-      "reset": "Restablecer tráfico",
       "editClient": "Editar cliente",
       "client": "Cliente",
       "enabled": "Habilitado",
@@ -841,13 +740,11 @@
       "noLinks": "No hay enlaces compartibles — asocia primero este cliente a un inbound con protocolo válido.",
       "link": "Enlace",
       "resetNotPossible": "Asocia primero este cliente a un inbound.",
-      "general": "General",
       "resetAllTraffics": "Restablecer tráfico de todos los clientes",
       "resetAllTrafficsTitle": "¿Restablecer tráfico de todos los clientes?",
       "resetAllTrafficsContent": "El contador de subida/bajada de cada cliente vuelve a cero. Las cuotas y la expiración no se modifican. Esta acción no se puede deshacer.",
       "deleteConfirmTitle": "¿Eliminar al cliente {email}?",
       "deleteConfirmContent": "Esto elimina al cliente de cada inbound asociado y descarta su registro de tráfico. No se puede deshacer.",
-      "deleteSelected": "Eliminar ({count})",
       "adjustSelected": "Ajustar ({count})",
       "subLinksSelected": "Enlaces sub ({count})",
       "addToGroupTitle": "Añadir {count} cliente(s) a un grupo",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "¿Deshabilitar {count} clientes?",
       "bulkDisableConfirmContent": "Deshabilita cada cliente seleccionado en todos los inbounds asociados. Pierden el acceso de inmediato, pero se conservan sus registros y su tráfico.",
       "selectedCount": "{count} seleccionado(s)",
-      "attachSelected": "Asociar ({count})",
       "attachToInboundsTitle": "Asociar {count} cliente(s) a entrada(s)",
       "attachToInboundsDesc": "Asocia los {count} cliente(s) seleccionados (mismo UUID/contraseña y tráfico compartido) a las entradas elegidas. Mantienen sus asociaciones existentes.",
       "attachToInboundsTargets": "Entradas objetivo",
       "attachToInboundsNoTargets": "No hay entradas multiusuario disponibles para asociar.",
-      "detachSelected": "Desasociar ({count})",
       "detach": "Desasociar",
       "detachFromInboundsTitle": "Desasociar {count} cliente(s) de entrada(s)",
       "detachFromInboundsDesc": "Quita los {count} cliente(s) seleccionados de las entradas elegidas. Las parejas donde el cliente no estaba asociado se omiten silenciosamente. Los registros de los clientes se conservan (usa Delete para eliminar por completo).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag opcional",
       "telegramId": "ID de usuario de Telegram",
       "telegramIdPlaceholder": "ID numérico de usuario de Telegram (0 = ninguno)",
-      "created": "Creado",
-      "updated": "Actualizado",
       "ipLimit": "Límite de IP",
       "toasts": {
         "deleted": "Cliente eliminado",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Grupos",
       "name": "Nombre",
       "clientCount": "Clientes",
       "totalGroups": "Total de grupos",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "Quitados {count} cliente(s) de {name}."
     },
     "nodes": {
-      "title": "Nodos",
       "addNode": "Agregar nodo",
       "editNode": "Editar nodo",
       "totalNodes": "Total de nodos",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Token desde la página de Configuración del panel remoto",
       "apiTokenHint": "El panel remoto expone su token de API en Configuraciones de Seguridad → Token de API.",
       "apiTokenKeepHint": "Déjalo en blanco para mantener el token actual",
-      "regenerate": "Regenerar token",
-      "regenerateConfirm": "Regenerar invalida el token actual. Cualquier panel central que lo use perderá el acceso hasta que se actualice. ¿Continuar?",
       "allowPrivateAddress": "Permitir dirección privada",
       "allowPrivateAddressHint": "Habilitar solo para nodos en una red privada o VPN.",
       "outboundTag": "Outbound de conexión",
@@ -1046,7 +935,6 @@
       "updatePanel": "Actualizar panel",
       "updateSelected": "Actualizar seleccionados ({count})",
       "updateAvailable": "Actualización disponible",
-      "upToDate": "Actualizado",
       "updateConfirmTitle": "¿Actualizar {count} nodo(s) a la última versión?",
       "updateConfirmContent": "Cada nodo seleccionado descarga la última versión y se reinicia con ella. Solo se actualizan los nodos habilitados y en línea.",
       "updateDevChannel": "Actualizar al canal de desarrollo (último commit)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "No se pudo obtener el certificado"
     },
     "settings": {
+      "defaultTag": "Predeterminado",
       "title": "Configuraciones",
       "save": "Guardar",
       "infoDesc": "Cada cambio realizado aquí debe ser guardado. Por favor, reinicie el panel para aplicar los cambios.",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "Deshacer borrado"
     },
     "xray": {
-      "title": "Xray Configuración",
       "save": "Guardar configuración",
-      "restart": "Reiniciar Xray",
       "restartSuccess": "Xray se ha reiniciado correctamente",
-      "restartOutputTitle": "Salida del reinicio de Xray",
-      "restartConfirmTitle": "¿Reiniciar xray?",
-      "restartConfirmContent": "Recarga el servicio xray con la configuración guardada.",
       "stopSuccess": "Xray se ha detenido correctamente",
       "restartError": "Ocurrió un error al reiniciar Xray.",
       "stopError": "Ocurrió un error al detener Xray.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "Estas opciones proporcionarán ajustes generales.",
       "logConfigs": "Registro",
       "logConfigsDesc": "Los registros pueden afectar la eficiencia de su servidor. Se recomienda habilitarlos sabiamente solo en caso de sus necesidades.",
-      "blockConfigsDesc": "Estas opciones evitarán que los usuarios se conecten a protocolos y sitios web específicos.",
       "basicRouting": "Enrutamiento Básico",
       "blockConnectionsConfigsDesc": "Estas opciones bloquearán el tráfico según el país solicitado específico.",
       "directConnectionsConfigsDesc": "Una conexión directa asegura que el tráfico específico no sea enrutado a través de otro servidor.",
@@ -1473,10 +1356,6 @@
       "directdomains": "Dominios Directos",
       "ipv4Routing": "Enrutamiento IPv4",
       "ipv4RoutingDesc": "Estas opciones solo enrutarán a los dominios objetivo a través de IPv4.",
-      "warpRouting": "Enrutamiento WARP",
-      "warpRoutingDesc": "Precaución: Antes de usar estas opciones, instale WARP en modo de proxy socks5 en su servidor siguiendo los pasos en el GitHub del panel. WARP enrutará el tráfico a los sitios web a través de los servidores de Cloudflare.",
-      "nordRouting": "Enrutamiento NordVPN",
-      "nordRoutingDesc": "Estas opciones enrutarán el tráfico basado en un destino específico a través de NordVPN.",
       "Template": "Plantilla de Configuración de Xray",
       "TemplateDesc": "Genera el archivo de configuración final de Xray basado en esta plantilla.",
       "FreedomStrategy": "Configurar Estrategia para el Protocolo Freedom",
@@ -1490,10 +1369,7 @@
       "outboundTestUrlDesc": "URL usada al probar la conectividad del outbound",
       "Torrent": "Prohibir Uso de BitTorrent",
       "Inbounds": "Entradas",
-      "InboundsDesc": "Cambia la plantilla de configuración para aceptar clientes específicos.",
       "Outbounds": "Salidas",
-      "OutboundSubscriptions": "Suscripciones de salida",
-      "OutboundSubscriptionsDesc": "Importa salidas desde URLs de suscripción remotas (vmess/vless/trojan/ss/...). Las etiquetas se mantienen estables para usarlas en balanceadores y reglas de enrutamiento. Las actualizaciones son automáticas.",
       "Balancers": "Equilibradores",
       "balancerTagRequired": "La etiqueta es obligatoria",
       "balancerSelectorRequired": "Elige al menos una salida",
@@ -1512,9 +1388,7 @@
       "routeTesterMatchedOutbound": "Salida coincidente",
       "routeTesterViaBalancer": "vía balanceador",
       "routeTesterDefaultOutbound": "Ninguna regla de enrutamiento coincidió — el tráfico va a la salida predeterminada (primera).",
-      "OutboundsDesc": "Cambia la plantilla de configuración para definir formas de salida para este servidor.",
       "Routings": "Reglas de enrutamiento",
-      "RoutingsDesc": "¡La prioridad de cada regla es importante!",
       "completeTemplate": "Todo",
       "logLevel": "Nivel de registro",
       "logLevelDesc": "El nivel de registro para registros de errores, que indica la información que debe registrarse.",
@@ -1528,13 +1402,9 @@
       "maskAddressDesc": "Máscara de dirección IP, cuando se habilita, reemplazará automáticamente la dirección IP que aparece en el registro.",
       "statistics": "Estadísticas",
       "statsInboundUplink": "Estadísticas de Subida de Entrada",
-      "statsInboundUplinkDesc": "Habilita la recopilación de estadísticas para el tráfico ascendente de todos los proxies de entrada.",
       "statsInboundDownlink": "Estadísticas de Bajada de Entrada",
-      "statsInboundDownlinkDesc": "Habilita la recopilación de estadísticas para el tráfico descendente de todos los proxies de entrada.",
       "statsOutboundUplink": "Estadísticas de Subida de Salida",
-      "statsOutboundUplinkDesc": "Habilita la recopilación de estadísticas para el tráfico ascendente de todos los proxies de salida.",
       "statsOutboundDownlink": "Estadísticas de Bajada de Salida",
-      "statsOutboundDownlinkDesc": "Habilita la recopilación de estadísticas para el tráfico descendente de todos los proxies de salida.",
       "connectionLimits": "Límites de conexión",
       "connectionLimitsDesc": "Políticas a nivel de conexión para el nivel de usuario 0. Deja un campo vacío para usar el valor predeterminado de Xray.",
       "connIdle": "Tiempo de inactividad",
@@ -1552,18 +1422,10 @@
       "metricsListenDesc": "Expone las métricas estilo Prometheus de Xray en esta dirección:puerto (por ejemplo, 127.0.0.1:11111). Déjalo vacío para deshabilitarlo. Vincúlalo a localhost y ponlo tras un proxy inverso — no está autenticado.",
       "metricsTag": "Etiqueta de métricas",
       "rules": {
-        "first": "Primero",
-        "last": "Último",
-        "up": "Arriba",
-        "down": "Abajo",
         "source": "Fuente",
         "dest": "Destino",
         "inbound": "Entrante",
-        "outbound": "Saliente",
         "balancer": "Equilibrador",
-        "info": "Info",
-        "add": "Agregar Regla",
-        "edit": "Editar Regla",
         "useComma": "Elementos separados por comas"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Regla {n}",
         "action": "Acción",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Reglas finales",
         "overrideXrayPrivateIp": "Sobrescribir el bloqueo de IP privada por defecto de Xray",
         "blockDelay": "Retraso de bloqueo (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Intervalo keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Interfaz",
-        "ipv6Only": "Solo IPv6",
-        "acceptProxyProtocol": "Aceptar proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "Agregar salida",
-        "addReverse": "Agregar reverso",
-        "editOutbound": "Editar salida",
-        "editReverse": "Editar reverso",
-        "reverseTag": "Etiqueta Reverso",
-        "reverseTagDesc": "Etiqueta de salida del proxy inverso simple VLESS. Dejar vacío para deshabilitar. Cuando se establece, las conexiones de este cliente pueden usarse como túnel de proxy inverso.",
-        "reverseTagPlaceholder": "etiqueta de salida (vacío para deshabilitar)",
         "tag": "Etiqueta",
-        "tagDesc": "etiqueta única",
-        "address": "Dirección",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Reverso",
-        "domain": "Dominio",
-        "type": "Tipo",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Enlace",
-        "intercon": "Interconexión",
-        "settings": "Configuración",
-        "accountInfo": "Información de la Cuenta",
         "outboundStatus": "Estado de Salida",
         "sendThrough": "Enviar a través de",
         "targetStrategy": "Estrategia de destino",
-        "test": "Probar",
-        "testResult": "Resultado de la prueba",
-        "testing": "Probando conexión...",
-        "testSuccess": "Prueba exitosa",
-        "testFailed": "Prueba fallida",
-        "testError": "Error al probar la salida",
         "modeRealDelay": "Retardo real",
         "testModeTooltip": "TCP: sonda rápida solo de dial. HTTP: petición completa a través de xray. Retardo real: tiempo total incluyendo el establecimiento de la conexión.",
         "testAll": "Probar todo",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Conexión al proxy",
         "breakdownTls": "TLS vía salida",
         "breakdownTtfb": "Primer byte",
-        "nordvpn": "NordVPN",
-        "accessToken": "Token de acceso",
         "country": "País",
         "server": "Servidor",
         "city": "Ciudad",
         "allCities": "Todas las ciudades",
-        "privateKey": "Clave privada",
-        "load": "Carga",
         "moveToTop": "Mover al principio"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Suscripciones activas",
         "empty": "Aún no hay suscripciones. Añade una arriba.",
         "colRemark": "Notas",
-        "colPrefix": "Prefijo",
-        "colInterval": "Intervalo",
         "colLastFetch": "Última descarga",
         "colEnabled": "Habilitado",
         "auto": "auto",
         "never": "nunca",
-        "yes": "Sí",
-        "no": "No",
         "refreshNow": "Actualizar ahora",
-        "lastError": "Último error",
         "deleteConfirm": "¿Eliminar esta suscripción?",
         "restartHint": "Después de añadir o actualizar, reinicia Xray (o espera a la próxima recarga automática) para activar las salidas.",
         "fromSubsTitle": "Desde suscripciones de salida (solo lectura)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Ajustes del balanceador",
       "tabObservatory": "Observatorio",
       "observatory": {
-        "title": "Observatorio",
-        "burstTitle": "Observatorio Burst",
         "autoManaged": "Los observadores se gestionan automáticamente a partir de tus balanceadores. Ajusta abajo cómo sondean; las salidas vigiladas siguen los selectores del balanceador.",
         "emptyHint": "No hay ningún observador de conexión activo. Se añade uno automáticamente al crear un balanceador Least Ping o Least Load —o un balanceador Random / Round-robin con fallback— para que los balanceadores que usan observador puedan comprobar la salud de las salidas antes de elegir un destino.",
         "mixedLegacy": "Esta configuración contiene Observatory y Burst Observatory a la vez. Xray usa un único observador global, por lo que este estado mixto heredado no está soportado; al guardar balanceadores se normalizará a un solo observador.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Balanceador {tag} — eliminado (sin destinos restantes)"
       },
       "balancer": {
-        "addBalancer": "Agregar equilibrador",
-        "editBalancer": "Editar balanceador",
         "balancerStrategy": "Estrategia",
-        "balancerSelectors": "Selectores",
         "tag": "Etiqueta",
-        "tagDesc": "etiqueta única",
         "tagDuplicate": "Etiqueta ya usada por otro balanceador",
         "tagPlaceholder": "etiqueta única de balanceador",
         "selector": "Selector",
@@ -1789,7 +1609,6 @@
         "tolerance": "Tolerancia",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "No es posible utilizar balancerTag y outboundTag al mismo tiempo. Si se utilizan al mismo tiempo, sólo funcionará outboundTag.",
         "costMatch": "Patrón de etiqueta",
         "costValue": "Peso",
         "costRegexp": "Coincidencia por expresión regular",
@@ -1804,14 +1623,10 @@
         "publicKey": "Llave pública",
         "allowedIPs": "IP permitidas",
         "endpoint": "Punto final",
-        "psk": "Clave precompartida",
         "domainStrategy": "Estrategia de dominio"
       },
       "tun": {
-        "nameDesc": "El nombre de la interfaz TUN. El valor predeterminado es 'xray0'",
-        "mtuDesc": "Unidad Máxima de Transmisión. El tamaño máximo de los paquetes de datos. El valor predeterminado es 1500",
-        "userLevel": "Nivel de Usuario",
-        "userLevelDesc": "Todas las conexiones realizadas a través de este entrada utilizarán este nivel de usuario. El valor predeterminado es 0"
+        "userLevel": "Nivel de Usuario"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Agregar DNS Falso",
-        "edit": "Editar DNS Falso",
         "ipPool": "Subred del grupo de IP",
         "poolSize": "Tamaño del grupo"
       },
@@ -2032,7 +1846,6 @@
     "add": "Añadir",
     "month": "Mes",
     "months": "Meses",
-    "day": "Día",
     "days": "Días",
     "hours": "Horas",
     "minutes": "Minutos",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Usuario de Telegram guardado.",
       "loginSuccess": "✅ Has iniciado sesión en el panel con éxito.\r\n",
       "loginFailed": "❗️ Falló el inicio de sesión en el panel.\r\n",
-      "2faFailed": "Error de 2FA",
       "report": "🕰 Informes programados: {{ .RunTime }}\r\n",
       "datetime": "⏰ Fecha y Hora: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Descarga: ↓{{ .Download }}\r\n",
       "total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Usuario de Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Agotado {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Cantidad de Agotados {{ .Type }}:\r\n",
       "onlinesCount": "🌐 Clientes en línea: {{ .Count }}\r\n",
       "disabled": "🛑 Desactivado: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Actualizado en: {{ .Time }}\r\n\r\n",
       "yes": "✅ Sí",
       "no": "❌ No",
-      "received_id": "🔑📥 ID actualizado.",
-      "received_password": "🔑📥 Contraseña actualizada.",
       "received_email": "📧📥 Correo electrónico actualizado.",
       "received_comment": "💬📥 Comentario actualizado.",
-      "id_prompt": "🔑 ID predeterminado: {{ .ClientId }}\n\nIntroduce tu ID.",
-      "pass_prompt": "🔑 Contraseña predeterminada: {{ .ClientPassword }}\n\nIntroduce tu contraseña.",
       "email_prompt": "📧 Correo electrónico predeterminado: {{ .ClientEmail }}\n\nIntroduce tu correo electrónico.",
       "comment_prompt": "💬 Comentario predeterminado: {{ .ClientComment }}\n\nIntroduce tu comentario.",
-      "inbound_client_data_id": "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Correo: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de expiración: {{ .ClientExp }}\n🌐 Límite de IP: {{ .IpLimit }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!",
-      "inbound_client_data_pass": "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Contraseña: {{ .ClientPass }}\n📧 Correo: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de expiración: {{ .ClientExp }}\n🌐 Límite de IP: {{ .IpLimit }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!",
       "cancel": "❌ ¡Proceso cancelado! \n\nPuedes /start de nuevo en cualquier momento. 🔄",
       "error_add_client": "⚠️ Error:\n\n {{ .error }}",
       "using_default_value": "Está bien, me quedaré con el valor predeterminado. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Error: {{ .Error }}",
       "eventNodeDown": "El nodo {{ .Name }} está CAÍDO",
       "eventNodeUp": "El nodo {{ .Name }} está ACTIVO",
-      "eventCPUHigh": "CPU alta",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Inicio de sesión fallido desde {{ .Source }}",
       "memoryThreshold": "Uso de memoria {{ .Percent }}% supera el umbral de {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Enviar como deshabilitado ☑️",
       "submitEnable": "Enviar como habilitado ✅",
       "use_default": "🏷️ Usar por defecto",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Contraseña",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Comentario",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Reiniciar todo el tráfico",
       "SortedTrafficUsageReport": "Informe de uso de tráfico ordenado"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "El saliente {{ .Tag }} está CAÍDO",
-    "subjectOutboundUp": "El saliente {{ .Tag }} está ACTIVO",
-    "subjectXrayCrash": "Xray se ha BLOQUEADO",
-    "subjectCPUHigh": "CPU alta",
-    "subjectLoginSuccess": "Inicio de sesión correcto",
-    "subjectLoginFailed": "Inicio de sesión fallido",
-    "titleOutboundDown": "Saliente CAÍDO",
-    "titleOutboundUp": "Saliente ACTIVO",
-    "titleXrayCrash": "Xray se ha BLOQUEADO",
-    "titleCPUHigh": "CPU alta",
-    "titleLoginSuccess": "Inicio de sesión correcto",
-    "titleLoginFailed": "Inicio de sesión fallido",
     "labelStatus": "Estado",
     "labelOutbound": "Saliente",
     "labelNode": "Nodo",
     "labelError": "Error",
     "labelDelay": "Retardo",
-    "labelDetail": "Detalle",
     "labelUsername": "Usuario",
     "labelIP": "IP",
     "labelReason": "Motivo",
     "labelSource": "Origen",
-    "labelTime": "Hora",
     "statusCrashed": "BLOQUEADO",
-    "statusRunning": "En ejecución",
     "statusHigh": "ALTA",
     "statusSuccess": "CORRECTO",
     "statusFailed": "FALLIDO",

+ 3 - 218
internal/web/translation/fa-IR.json

@@ -48,7 +48,6 @@
   "copySuccess": "باموفقیت کپی‌شد",
   "sure": "مطمئن",
   "encryption": "رمزگذاری",
-  "useIPv4ForHost": "از IPv4 برای میزبان استفاده کنید",
   "transmission": "راه‌اتصال",
   "host": "میزبان",
   "path": "مسیر",
@@ -74,18 +73,9 @@
   "twoFactorCode": "کد",
   "remained": "باقی‌مانده",
   "security": "امنیت",
-  "secAlertTitle": "هشدار‌امنیتی",
-  "secAlertSsl": "این‌اتصال‌امن نیست. لطفا‌ تازمانی‌که تی‌ال‌اس برای محافظت از‌ داده‌ها فعال نشده‌است، از وارد کردن اطلاعات حساس خودداری کنید",
-  "secAlertConf": "تنظیمات خاصی در برابر حملات آسیب پذیر هستند. توصیه می‌شود پروتکل‌های امنیتی را برای جلوگیری از نفوذ احتمالی تقویت کنید",
-  "secAlertSSL": "پنل فاقد ارتباط امن است. لطفاً یک گواهینامه تی‌ال‌اس برای محافظت از داده‌ها نصب کنید",
-  "secAlertPanelPort": "استفاده از پورت پیش‌فرض پنل ناامن است. لطفاً یک پورت تصادفی یا خاص تنظیم کنید",
-  "secAlertPanelURI": "مسیر پیش‌فرض لینک پنل ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
-  "secAlertSubURI": "مسیر پیش‌فرض لینک سابسکریپشن ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
-  "secAlertSubJsonURI": "مسیر پیش‌فرض لینک سابسکریپشن جیسون ناامن است. لطفاً یک مسیر پیچیده تنظیم کنید",
   "emptyDnsDesc": "هیچ سرور DNS اضافه نشده است.",
   "emptyFakeDnsDesc": "هیچ سرور Fake DNS اضافه نشده است.",
   "emptyBalancersDesc": "هیچ بالانسر اضافه نشده است.",
-  "emptyReverseDesc": "هیچ پروکسی معکوس اضافه نشده است.",
   "somethingWentWrong": "مشکلی پیش آمد",
   "subscription": {
     "title": "اطلاعات سابسکریپشن",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "تم",
-    "dark": "تیره",
-    "ultraDark": "فوق تیره",
     "dashboard": "نمای کلی",
     "inbounds": "ورودی‌ها",
     "clients": "کلاینت‌ها",
@@ -118,7 +106,6 @@
     "routing": "مسیریابی",
     "outbounds": "خروجی‌ها",
     "apiDocs": "مستندات API",
-    "logout": "خروج",
     "link": "مدیریت",
     "donate": "حمایت مالی",
     "hosts": "میزبان‌ها",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "نمای کلی",
       "cpu": "پردازنده",
       "logicalProcessors": "پردازنده‌های منطقی",
       "frequency": "فرکانس",
@@ -152,7 +138,6 @@
       "restartXray": "راه‌اندازی مجدد",
       "xraySwitch": "‌نسخه",
       "xrayUpdates": "به‌روزرسانی‌های Xray",
-      "xraySwitchClick": "نسخه مورد نظر را انتخاب کنید",
       "xraySwitchClickDesk": "لطفا بادقت انتخاب کنید. درصورت انتخاب نسخه قدیمی‌تر، امکان ناهماهنگی با پیکربندی فعلی وجود دارد",
       "updatePanel": "به‌روزرسانی پنل",
       "panelUpdateDesc": "این عملیات 3X-UI را به آخرین نسخه به‌روزرسانی می‌کند و سرویس پنل را مجدداً راه‌اندازی می‌کند.",
@@ -164,12 +149,10 @@
       "currentCommit": "کامیت فعلی",
       "latestCommit": "آخرین کامیت",
       "updateChannelChanged": "کانال به‌روزرسانی تغییر کرد",
-      "upToDate": "به‌روز",
       "xrayStatusUnknown": "ناشناخته",
       "xrayStatusRunning": "در حال اجرا",
       "xrayStatusStop": "متوقف",
       "xrayStatusError": "خطا",
-      "xrayErrorPopoverTitle": "خطا در هنگام اجرای Xray رخ داد",
       "operationHours": "مدت‌کارکرد",
       "systemHistoryTitle": "تاریخچه سیستم",
       "historyTitleCpu": "مصرف پردازنده",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "غیرفعال",
       "xrayObservatoryLastSeen": "آخرین مشاهده",
       "xrayObservatoryLastTry": "آخرین تلاش",
-      "trendLast2Min": "۲ دقیقه اخیر",
-      "systemLoad": "بارسیستم",
-      "systemLoadDesc": "میانگین بار سیستم برای 1، 5 و 15 دقیقه گذشته",
       "connectionCount": "تعداد کانکشن ها",
       "ipAddresses": "آدرس‌های IP",
       "toggleIpVisibility": "تغییر وضعیت نمایش IP",
@@ -223,13 +203,11 @@
       "totalData": "داده‌های کل",
       "sent": "ارسال شده",
       "received": "دریافت شده",
-      "documentation": "مستندات",
       "xraySwitchVersionDialog": "آیا واقعاً می‌خواهید نسخه Xray را تغییر دهید؟",
       "xraySwitchVersionDialogDesc": "این کار نسخه Xray را به #version# تغییر می‌دهد.",
       "xraySwitchVersionPopover": "Xray با موفقیت به‌روز شد",
       "panelUpdateDialog": "آیا مطمئن هستید که می‌خواهید پنل را به‌روزرسانی کنید؟",
       "panelUpdateDialogDesc": "این 3X-UI را به نسخه #version# به‌روزرسانی کرده و سرویس پنل را مجدداً راه‌اندازی می‌کند.",
-      "panelUpdateCheckPopover": "خطا در بررسی به‌روزرسانی پنل",
       "panelUpdateStartedPopover": "به‌روزرسانی پنل آغاز شد",
       "panelUpdateFailedTitle": "به‌روزرسانی پنل ناموفق بود",
       "panelUpdateFailedDesc": "به‌روزرسانی با موفقیت به پایان نرسید. گزارش‌های سرور را بررسی کنید یا دستور «x-ui update» را از خط فرمان اجرا کنید.",
@@ -258,7 +236,6 @@
       "accessLogs": "لاگ‌های دسترسی",
       "autoUpdate": "به‌روزرسانی خودکار",
       "config": "پیکربندی",
-      "backup": "پشتیبان‌گیری",
       "backupTitle": "پشتیبان‌گیری و بازیابی",
       "exportDatabase": "پشتیبان‌گیری",
       "exportDatabaseDesc": "برای دانلود یک فایل .db حاوی پشتیبان از پایگاه داده فعلی خود به دستگاهتان کلیک کنید. همین فایل در پنلی که روی PostgreSQL اجرا می‌شود نیز قابل بازیابی است.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "برای دانلود یک پایگاه‌دادهٔ SQLite با پسوند ‎.db که از داده‌های PostgreSQL شما ساخته می‌شود کلیک کنید؛ آمادهٔ اجرای این پنل روی SQLite."
     },
     "inbounds": {
-      "title": "ورودی‌ها",
       "totalDownUp": "دریافت/ارسال کل",
       "totalUsage": "‌‌‌مصرف کل",
       "inboundCount": "کل ورودی‌ها",
@@ -288,21 +264,11 @@
       "localPanel": "پنل لوکال",
       "fallbacks": {
         "title": "Fallbackها",
-        "help": "وقتی اتصالی روی این اینباند با هیچ کلاینتی تطبیق پیدا نمی‌کند، به جای دیگری ارجاع داده می‌شود. یک اینباند فرزند از پایین انتخاب کنید تا فیلدهای مسیریابی (SNI / ALPN / Path / xver) خودکار از روی transport آن پر شود، یا انتخاب‌گر را خالی بگذارید و مقدار Dest را مستقیم تنظیم کنید (مثلاً 8080 یا 127.0.0.1:8080) تا به یک سرور بیرونی مانند Nginx ارجاع شود. هر اینباند فرزند باید روی 127.0.0.1 با security=none گوش بدهد.",
         "empty": "هنوز فال‌بکی اضافه نشده",
         "add": "افزودن فال‌بک",
         "pickInbound": "یک اینباند انتخاب کنید",
         "matchAny": "همه",
         "destPlaceholder": "خودکار (listen:port فرزند)",
-        "rederive": "پر کردن مجدد از فرزند",
-        "rederived": "از فرزند پر شد",
-        "editAdvanced": "ویرایش فیلدهای مسیریابی",
-        "hideAdvanced": "بستن پیشرفته",
-        "quickAddAll": "افزودن سریع همه‌ی موارد واجد شرایط",
-        "quickAdded": "{n} فال‌بک افزوده شد",
-        "quickAddedNone": "اینباند جدیدی برای افزودن وجود ندارد",
-        "routesWhen": "هدایت می‌شود وقتی",
-        "defaultCatchAll": "پیش‌فرض — همه‌ی موارد دیگر را می‌گیرد",
         "needsTls": "فال‌بک‌ها پس از انتخاب TLS یا Reality در برگه‌ی امنیت در دسترس می‌شوند (فقط VLESS/Trojan روی RAW)."
       },
       "protocol": "پروتکل",
@@ -310,8 +276,6 @@
       "portMap": "نگاشت پورت",
       "traffic": "ترافیک",
       "speed": "سرعت",
-      "details": "توضیحات",
-      "transportConfig": "انتقال",
       "expireDate": "مدت زمان",
       "createdAt": "ایجاد",
       "updatedAt": "به‌روزرسانی",
@@ -319,8 +283,6 @@
       "addInbound": "افزودن ورودی",
       "generalActions": "عملیات کلی",
       "modifyInbound": "ویرایش ورودی",
-      "deleteInbound": "حذف ورودی",
-      "deleteInboundContent": "آیا مطمئن به حذف ورودی هستید؟",
       "deleteConfirmTitle": "اینباند «{remark}» حذف شود؟",
       "deleteConfirmContent": "این اینباند و تمام کلاینت‌های آن حذف می‌شود. این عمل غیرقابل بازگشت است.",
       "resetConfirmTitle": "ترافیک اینباند «{remark}» صفر شود؟",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "همه-ورودی‌ها",
       "exportAllSubsFileName": "همه-ورودی‌ها-Subs",
       "inboundJsonTitle": "JSON ورودی",
-      "deleteClient": "حذف کاربر",
-      "deleteClientContent": "آیا مطمئن به حذف کاربر هستید؟",
       "resetTrafficContent": "آیا مطمئن به ریست ترافیک هستید؟",
       "copyLink": "کپی لینک",
       "address": "آدرس",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= نامحدود. (واحد: GB)",
       "totalFlow": "ترافیک کل",
       "leaveBlankToNeverExpire": "برای منقضی‌نشدن خالی‌بگذارید",
-      "noRecommendKeepDefault": "توصیه‌می‌شود به‌طور پیش‌فرض حفظ‌شود",
       "certificatePath": "مسیر فایل",
       "certificateContent": "محتوای فایل",
       "publicKey": "کلید عمومی",
       "privatekey": "کلید خصوصی",
-      "clickOnQRcode": "برای کپی بر روی کدتصویری کلیک کنید",
       "client": "کاربر",
       "export": "استخراج لینک‌ها",
       "clone": "شبیه‌سازی",
-      "cloneInbound": "شبیه‌سازی ورودی",
-      "cloneInboundContent": "همه موارد این ورودی بجز پورت، آی‌پی و کاربر‌ها شبیه‌سازی خواهند شد",
-      "cloneInboundOk": "ساختن شبیه ساز",
       "resetAllTraffic": "ریست ترافیک کل ورودی‌ها",
       "resetAllTrafficTitle": "ریست ترافیک کل ورودی‌ها",
       "resetAllTrafficContent": "آیا مطمئن به ریست ترافیک تمام ورودی‌ها هستید؟",
-      "resetInboundClientTraffics": "ریست ترافیک کاربران",
-      "resetInboundClientTrafficTitle": "ریست ترافیک کاربران",
-      "resetInboundClientTrafficContent": "آیا مطمئن به ریست ترافیک تمام کاربران این‌ ورودی هستید؟",
-      "resetAllClientTraffics": "ریست ترافیک کل کاربران",
-      "resetAllClientTrafficTitle": "ریست ترافیک کل کاربران",
-      "resetAllClientTrafficContent": "آیا مطمئن به ریست ترافیک تمام کاربران هستید؟",
-      "delDepletedClients": "حذف کاربران منقضی",
-      "delDepletedClientsTitle": "حذف کاربران منقضی",
-      "delDepletedClientsContent": "آیا مطمئن به حذف تمام کاربران منقضی‌شده ‌هستید؟",
       "email": "ایمیل",
-      "emailDesc": "باید یک ایمیل یکتا باشد",
       "IPLimit": "محدودیت آی‌پی",
-      "IPLimitDesc": "(اگر تعداد از مقدار تنظیم شده بیشتر شود، ورودی را غیرفعال می کند. (0 = غیرفعال",
       "IPLimitlog": "گزارش‌ها",
-      "IPLimitlogDesc": "گزارش تاریخچه آی‌پی. برای فعال کردن ورودی پس از غیرفعال شدن، گزارش را پاک کنید",
       "IPLimitlogclear": "پاک کردن گزارش‌ها",
       "setDefaultCert": "استفاده از گواهی پنل",
       "setDefaultCertEmpty": "هیچ گواهی‌ای برای پنل پیکربندی نشده. ابتدا از تنظیمات یکی تعیین کنید.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "ساختار بلوک sniffing در Xray:",
         "stream": "Stream",
-        "streamHelp": "ساختار بلوک stream در Xray:",
-        "jsonErrorPrefix": "JSON پیشرفته"
+        "streamHelp": "ساختار بلوک stream در Xray:"
       },
-      "telegramDesc": "لطفا شناسه گفتگوی تلگرام را وارد کنید. (از دستور '/id' در ربات استفاده کنید) یا ({'@'}userinfobot)",
-      "subscriptionDesc": "شما می‌توانید لینک سابسکربپشن خودرا در 'جزئیات' پیدا کنید، همچنین می‌توانید از همین نام برای چندین کاربر استفاده‌کنید",
       "subSortIndex": "ترتیب اشتراک",
-      "same": "همسان",
       "inboundInfo": "اطلاعات ورودی",
       "exportInbound": "استخراج ورودی",
       "import": "افزودن",
       "importInbound": "افزودن یک ورودی",
       "periodicTrafficResetTitle": "بازنشانی ترافیک",
-      "periodicTrafficResetDesc": "بازنشانی خودکار شمارنده ترافیک در فواصل زمانی مشخص",
       "periodicTrafficResetDay": "روز بازنشانی ماهانه",
-      "lastReset": "آخرین بازنشانی",
       "periodicTrafficReset": {
         "never": "هرگز",
         "daily": "روزانه",
@@ -464,7 +401,6 @@
         "obtain": "فراهم‌سازی",
         "updateSuccess": "بروزرسانی با موفقیت انجام شد",
         "logCleanSuccess": "لاگ پاکسازی شد",
-        "inboundsUpdateSuccess": "ورودی‌ها با موفقیت به‌روزرسانی شدند",
         "inboundUpdateSuccess": "ورودی با موفقیت به‌روزرسانی شد",
         "inboundCreateSuccess": "ورودی با موفقیت ایجاد شد",
         "bulkDeleted": "{count} اینباند حذف شد",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "کلاینت ورودی حذف شد",
         "inboundClientUpdateSuccess": "کلاینت ورودی به‌روزرسانی شد",
         "savedNodeOfflineWillSync": "به‌صورت محلی ذخیره شد. یک نود پشتیبان آفلاین یا غیرفعال است — تغییر پس از اتصال مجدد همگام‌سازی می‌شود.",
-        "delDepletedClientsSuccess": "تمام کلاینت‌های مصرف شده حذف شدند",
         "resetAllClientTrafficSuccess": "تمام ترافیک کلاینت بازنشانی شد",
         "resetAllTrafficSuccess": "تمام ترافیک‌ها بازنشانی شدند",
         "resetInboundClientTrafficSuccess": "ترافیک بازنشانی شد",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "پیکربندی Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "درخواست",
-          "response": "پاسخ",
-          "name": "نام",
-          "value": "مقدار"
-        },
-        "tcp": {
-          "version": "نسخه",
-          "method": "متد",
-          "path": "مسیر",
-          "status": "وضعیت",
-          "statusDescription": "توضیحات وضعیت",
-          "requestHeader": "سربرگ درخواست",
-          "responseHeader": "سربرگ پاسخ"
-        }
-      },
       "sniffingDestOverride": "بازنویسی مقصد"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "افزودن سابسکریپشن خارجی",
       "noExternalLinks": "هنوز لینک خارجی‌ای اضافه نشده.",
       "noExternalSubscriptions": "هنوز سابسکریپشن خارجی‌ای اضافه نشده.",
-      "add": "افزودن کلاینت",
-      "edit": "ویرایش کلاینت",
-      "submitAdd": "افزودن کلاینت",
       "submitEdit": "ذخیره تغییرات",
       "clientCount": "تعداد کلاینت‌ها",
       "bulk": "افزودن گروهی",
-      "copyFromInbound": "کپی کلاینت‌ها از اینباند",
-      "copyToInbound": "کپی کلاینت‌ها به",
-      "copySelected": "کپی انتخاب‌شده‌ها",
-      "copySource": "منبع",
-      "copyEmailPreview": "پیش‌نمایش ایمیل خروجی",
-      "copySelectSourceFirst": "ابتدا یک اینباند مبدأ انتخاب کنید.",
-      "copyResult": "نتیجه کپی",
-      "copyResultSuccess": "با موفقیت کپی شد",
-      "copyResultNone": "چیزی برای کپی نیست: کلاینتی انتخاب نشده یا منبع خالی است",
-      "copyResultErrors": "خطاهای کپی",
-      "copyFlowLabel": "Flow برای کلاینت‌های جدید (VLESS)",
-      "copyFlowHint": "روی همه کلاینت‌های کپی‌شده اعمال می‌شود. خالی بگذارید تا رد شود.",
       "selectAll": "انتخاب همه",
       "clearAll": "پاک کردن همه",
       "method": "روش",
@@ -775,7 +678,6 @@
       "postfix": "پسوند",
       "delayedStart": "شروع پس از اولین استفاده",
       "expireDays": "مدت اعتبار (روز)",
-      "days": "روز",
       "renew": "تمدید خودکار",
       "renewDesc": "تمدید خودکار پس از انقضا. (۰ = غیرفعال) (واحد: روز)",
       "renewDays": "تمدید خودکار (روز)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "نزدیک‌ترین انقضا",
       "has": "دارد",
       "hasNot": "ندارد",
-      "title": "کلاینت‌ها",
       "actions": "عملیات",
       "totalGB": "سقف حجم (گیگابایت)",
       "totalGBDesc": "سهمیه‌ی حجم مصرفی کلاینت. ۰ = نامحدود",
@@ -826,8 +727,6 @@
       "addClient": "افزودن کلاینت",
       "qrCode": "کد QR",
       "clientInfo": "اطلاعات کلاینت",
-      "delete": "حذف",
-      "reset": "بازنشانی ترافیک",
       "editClient": "ویرایش کلاینت",
       "client": "کلاینت",
       "enabled": "فعال",
@@ -841,13 +740,11 @@
       "noLinks": "لینکی برای اشتراک‌گذاری نیست — ابتدا این کلاینت را به یک اینباند با پروتکل سازگار متصل کنید.",
       "link": "لینک",
       "resetNotPossible": "ابتدا این کلاینت را به یک اینباند متصل کنید.",
-      "general": "عمومی",
       "resetAllTraffics": "بازنشانی ترافیک همه کلاینت‌ها",
       "resetAllTrafficsTitle": "بازنشانی ترافیک همه کلاینت‌ها؟",
       "resetAllTrafficsContent": "شمارنده ارسال/دریافت همه کلاینت‌ها به صفر می‌رسد. سهمیه و تاریخ انقضا تغییری نمی‌کند. این عمل غیرقابل بازگشت است.",
       "deleteConfirmTitle": "حذف کلاینت {email}؟",
       "deleteConfirmContent": "این کلاینت از تمام اینباندهای متصل حذف و سابقه ترافیک آن پاک می‌شود. این عمل غیرقابل بازگشت است.",
-      "deleteSelected": "حذف ({count})",
       "adjustSelected": "تنظیم ({count})",
       "subLinksSelected": "لینک‌های اشتراک ({count})",
       "addToGroupTitle": "افزودن {count} کاربر به یک گروه",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "{count} کلاینت غیرفعال شوند؟",
       "bulkDisableConfirmContent": "هر کلاینت انتخاب‌شده روی تمام اینباندهای متصل غیرفعال می‌شود. دسترسی آن‌ها بلافاصله قطع می‌شود اما رکورد و ترافیکشان حفظ می‌گردد.",
       "selectedCount": "{count} انتخاب‌شده",
-      "attachSelected": "الصاق ({count})",
       "attachToInboundsTitle": "الصاق {count} کاربر به ورودی‌(ها)",
       "attachToInboundsDesc": "{count} کاربر انتخاب‌شده (همان UUID/رمز و ترافیک مشترک) را به ورودی‌های انتخابی الصاق می‌کند. الصاق‌های قبلی حفظ می‌شوند.",
       "attachToInboundsTargets": "ورودی‌های مقصد",
       "attachToInboundsNoTargets": "هیچ ورودی چندکاربره‌ای برای الصاق در دسترس نیست.",
-      "detachSelected": "جداسازی ({count})",
       "detach": "جداسازی",
       "detachFromInboundsTitle": "جداسازی {count} کاربر از ورودی‌(ها)",
       "detachFromInboundsDesc": "{count} کاربر انتخاب‌شده را از ورودی‌های انتخابی حذف می‌کند. در مواردی که کاربر الصاق نبوده، نادیده گرفته می‌شود. رکورد کاربر حفظ می‌شود (برای حذف کامل از Delete استفاده کنید).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag اختیاری",
       "telegramId": "شناسه کاربر تلگرام",
       "telegramIdPlaceholder": "شناسه عددی کاربر تلگرام (۰ = هیچ)",
-      "created": "ساخته‌شده",
-      "updated": "به‌روزشده",
       "ipLimit": "محدودیت IP",
       "toasts": {
         "deleted": "کلاینت حذف شد",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "گروه‌ها",
       "name": "نام",
       "clientCount": "کاربران",
       "totalGroups": "تعداد گروه‌ها",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "{count} کاربر از {name} حذف شد."
     },
     "nodes": {
-      "title": "نودها",
       "addNode": "افزودن نود",
       "editNode": "ویرایش نود",
       "totalNodes": "کل نودها",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "توکن از صفحه تنظیمات پنل ریموت",
       "apiTokenHint": "پنل ریموت توکن API خودش را در بخش احرازهویت → توکن API نمایش می‌دهد.",
       "apiTokenKeepHint": "برای حفظ توکن فعلی خالی بگذارید",
-      "regenerate": "تولید مجدد توکن",
-      "regenerateConfirm": "تولید مجدد، توکن فعلی را باطل می‌کند. هر پنل مرکزی‌ای که از این توکن استفاده می‌کند تا زمان به‌روزرسانی، دسترسی‌اش قطع می‌شود. ادامه می‌دهید؟",
       "allowPrivateAddress": "اجازه آدرس خصوصی",
       "allowPrivateAddressHint": "فقط برای نودهای روی شبکه خصوصی یا VPN فعال شود.",
       "outboundTag": "خروجی اتصال",
@@ -1046,7 +935,6 @@
       "updatePanel": "به‌روزرسانی پنل",
       "updateSelected": "به‌روزرسانی انتخاب‌شده‌ها ({count})",
       "updateAvailable": "به‌روزرسانی موجود",
-      "upToDate": "به‌روز",
       "updateConfirmTitle": "{count} نود به آخرین نسخه به‌روزرسانی شوند؟",
       "updateConfirmContent": "هر نود انتخاب‌شده آخرین نسخه را دانلود و روی آن ری‌استارت می‌شود. فقط نودهای فعال و آنلاین به‌روزرسانی می‌شوند.",
       "updateDevChannel": "به‌روزرسانی به کانال دِو (آخرین کامیت)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "دریافت گواهی ممکن نشد"
     },
     "settings": {
+      "defaultTag": "پیش‌فرض",
       "title": "تنظیمات پنل",
       "save": "ذخیره",
       "infoDesc": "برای اعمال تغییرات در این بخش باید پس از ذخیره کردن، پنل را ریستارت کنید",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "لغو پاک کردن"
     },
     "xray": {
-      "title": "پیکربندی ایکس‌ری",
       "save": "ذخیره",
-      "restart": "راه‌اندازی مجدد Xray",
       "restartSuccess": "Xray با موفقیت راه‌اندازی مجدد شد",
-      "restartOutputTitle": "خروجی راه‌اندازی مجدد Xray",
-      "restartConfirmTitle": "راه‌اندازی مجدد xray؟",
-      "restartConfirmContent": "سرویس xray با پیکربندی ذخیره‌شده دوباره بارگذاری می‌شود.",
       "stopSuccess": "Xray با موفقیت متوقف شد",
       "restartError": "خطا در راه‌اندازی مجدد Xray.",
       "stopError": "خطا در توقف Xray.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "این گزینه‌ها استراتژی کلی ترافیک را تعیین می‌کنند",
       "logConfigs": "لاگ",
       "logConfigsDesc": "گزارش‌ها ممکن است بر کارایی سرور شما تأثیر بگذارد. توصیه می شود فقط در صورت نیاز آن را عاقلانه فعال کنید",
-      "blockConfigsDesc": "این گزینه‌ها ترافیک را بر اساس پروتکل‌های درخواستی خاص، و وب سایت‌ها مسدود می‌کند",
       "basicRouting": "مسیریابی پایه",
       "blockConnectionsConfigsDesc": "این گزینه‌ها ترافیک را بر اساس کشور درخواست‌شده خاص مسدود می‌کنند.",
       "directConnectionsConfigsDesc": "یک اتصال مستقیم تضمین می‌کند که ترافیک خاص از طریق سرور دیگری مسیریابی نشود.",
@@ -1473,10 +1356,6 @@
       "directdomains": "دامنه‌های مستقیم",
       "ipv4Routing": "IPv4 مسیریابی",
       "ipv4RoutingDesc": "این گزینه‌ها ترافیک را از طریق آی‌پی نسخه4 سرور، به مقصد هدایت می‌کند",
-      "warpRouting": "WARP مسیریابی",
-      "warpRoutingDesc": "این گزینه‌ها ترافیک‌ را از طریق وارپ کلادفلر به مقصد هدایت می‌کند",
-      "nordRouting": "مسیریابی NordVPN",
-      "nordRoutingDesc": "این گزینه‌ها ترافیک را بر اساس مقصد خاص از طریق NordVPN مسیریابی می‌کنند.",
       "Template": "‌پیکربندی پیشرفته الگو ایکس‌ری",
       "TemplateDesc": "فایل پیکربندی نهایی ایکس‌ری بر اساس این الگو ایجاد می‌شود",
       "FreedomStrategy": "Freedom استراتژی پروتکل",
@@ -1490,10 +1369,7 @@
       "outboundTestUrlDesc": "آدرسی که برای تست اتصال خروجی استفاده می‌شود.",
       "Torrent": "مسدودسازی پروتکل بیت‌تورنت",
       "Inbounds": "ورودی‌ها",
-      "InboundsDesc": "پذیرش کلاینت خاص",
       "Outbounds": "خروجی‌ها",
-      "OutboundSubscriptions": "سابسکریپشن‌های خروجی",
-      "OutboundSubscriptionsDesc": "خروجی‌ها را از آدرس‌های سابسکریپشن راه‌دور (vmess/vless/trojan/ss/...) وارد کنید. تگ‌ها ثابت می‌مانند تا در بالانسرها و قوانین مسیریابی قابل استفاده باشند. به‌روزرسانی‌ها به‌صورت خودکار انجام می‌شوند.",
       "Balancers": "بالانسرها",
       "balancerTagRequired": "تگ الزامی است",
       "balancerSelectorRequired": "حداقل یک خروجی انتخاب کنید",
@@ -1512,9 +1388,7 @@
       "routeTesterMatchedOutbound": "خروجی منطبق",
       "routeTesterViaBalancer": "از طریق بالانسر",
       "routeTesterDefaultOutbound": "هیچ قانونی منطبق نشد — ترافیک به خروجی پیش‌فرض (اولین خروجی) می‌رود.",
-      "OutboundsDesc": "مسیر ترافیک خروجی را تنظیم کنید",
       "Routings": "قوانین مسیریابی",
-      "RoutingsDesc": "اولویت هر قانون مهم است",
       "importRules": "ورود قوانین",
       "exportRules": "خروج قوانین",
       "importOutbounds": "ورود خروجی‌ها",
@@ -1533,13 +1407,9 @@
       "maskAddressDesc": "پوشش آدرس IP، هنگامی که فعال می‌شود، به طور خودکار آدرس IP که در لاگ ظاهر می‌شود را جایگزین می‌کند.",
       "statistics": "آمار",
       "statsInboundUplink": "آمار آپلود ورودی",
-      "statsInboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
       "statsInboundDownlink": "آمار دانلود ورودی",
-      "statsInboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های ورودی را فعال می‌کند.",
       "statsOutboundUplink": "آمار آپلود خروجی",
-      "statsOutboundUplinkDesc": "جمع‌آوری آمار برای ترافیک بالارو (آپلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
       "statsOutboundDownlink": "آمار دانلود خروجی",
-      "statsOutboundDownlinkDesc": "جمع‌آوری آمار برای ترافیک پایین‌رو (دانلود) تمام پروکسی‌های خروجی را فعال می‌کند.",
       "metricsListen": "نقطه پایانی متریک",
       "metricsListenDesc": "متریک‌های Xray (سبک Prometheus) را روی این آدرس:پورت در دسترس قرار می‌دهد (مثلاً 127.0.0.1:11111). برای غیرفعال‌کردن خالی بگذارید. روی localhost ببندید و با ریورس‌پروکسی ارائه دهید — احراز هویت ندارد.",
       "metricsTag": "تگ متریک",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "خودکار",
       "seconds": "ثانیه",
       "rules": {
-        "first": "اولین",
-        "last": "آخرین",
-        "up": "بالا",
-        "down": "پایین",
         "source": "مبدا",
         "dest": "مقصد",
         "inbound": "ورودی",
-        "outbound": "خروجی",
         "balancer": "بالانسر",
-        "info": "اطلاعات",
-        "add": "افزودن قانون",
-        "edit": "ویرایش قانون",
         "useComma": "موارد جدا شده با کاما"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "قانون {n}",
         "action": "عمل",
         "redirect": "بازهدایت",
-        "fragment": "Fragment",
         "finalRules": "قوانین نهایی",
         "overrideXrayPrivateIp": "override بلاک پیش‌فرض IP خصوصی Xray",
         "blockDelay": "تأخیر بلاک (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "بازه Keep alive",
         "markFwmark": "علامت (fwmark)",
         "interface": "رابط",
-        "ipv6Only": "فقط IPv6",
-        "acceptProxyProtocol": "پذیرش Proxy Protocol",
         "proxyProtocol": "Proxy Protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "افزودن خروجی",
-        "addReverse": "افزودن معکوس",
-        "editOutbound": "ویرایش خروجی",
-        "editReverse": "ویرایش معکوس",
-        "reverseTag": "تگ معکوس",
-        "reverseTagDesc": "تگ خروجی پروکسی معکوس ساده VLESS. برای غیرفعال کردن خالی بگذارید. در صورت تنظیم، اتصالات این کلاینت می‌توانند به عنوان تونل پروکسی معکوس استفاده شوند.",
-        "reverseTagPlaceholder": "تگ خروجی (خالی = غیرفعال)",
         "tag": "تگ",
-        "tagDesc": "برچسب یگانه",
-        "address": "آدرس",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "معکوس",
-        "domain": "دامنه",
-        "type": "نوع",
-        "bridge": "پل",
-        "portal": "پورتال",
-        "link": "لینک",
-        "intercon": "اتصال میانی",
-        "settings": "تنظیمات",
-        "accountInfo": "اطلاعات حساب",
         "outboundStatus": "وضعیت خروجی",
         "sendThrough": "ارسال با",
         "targetStrategy": "استراتژی مقصد",
-        "test": "تست",
-        "testResult": "نتیجه تست",
-        "testing": "در حال تست اتصال...",
-        "testSuccess": "تست موفقیت‌آمیز",
-        "testFailed": "تست ناموفق",
-        "testError": "خطا در تست خروجی",
         "modeRealDelay": "تأخیر واقعی",
         "testModeTooltip": "TCP: فقط dial سریع. HTTP: درخواست کامل از طریق xray. تأخیر واقعی: کل زمان همراه با برقراری اتصال.",
         "testAll": "تست همه",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "اتصال پروکسی",
         "breakdownTls": "TLS از طریق خروجی",
         "breakdownTtfb": "اولین بایت",
-        "nordvpn": "NordVPN",
-        "accessToken": "توکن دسترسی",
         "country": "کشور",
         "server": "سرور",
         "city": "شهر",
         "allCities": "همه شهرها",
-        "privateKey": "کلید خصوصی",
-        "load": "فشار سرور",
         "moveToTop": "انتقال به بالا"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "سابسکریپشن‌های فعال",
         "empty": "هنوز سابسکریپشنی وجود ندارد. از بالا یکی اضافه کنید.",
         "colRemark": "نام",
-        "colPrefix": "پیشوند",
-        "colInterval": "بازه",
         "colLastFetch": "آخرین دریافت",
         "colEnabled": "فعال",
         "auto": "خودکار",
         "never": "هرگز",
-        "yes": "بله",
-        "no": "خیر",
         "refreshNow": "تازه‌سازی اکنون",
-        "lastError": "آخرین خطا",
         "deleteConfirm": "این سابسکریپشن حذف شود؟",
         "restartHint": "پس از افزودن یا تازه‌سازی، برای فعال‌شدن خروجی‌ها Xray را راه‌اندازی مجدد کنید (یا منتظر بارگذاری مجدد خودکار بعدی بمانید).",
         "fromSubsTitle": "از سابسکریپشن‌های خروجی (فقط‌خواندنی)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "تنظیمات بالانسر",
       "tabObservatory": "رصدخانه",
       "observatory": {
-        "title": "رصدخانه",
-        "burstTitle": "رصدخانه Burst",
         "autoManaged": "رصدگرها به‌صورت خودکار از روی بالانسرهای شما مدیریت می‌شوند. در ادامه می‌توانید نحوهٔ پروب‌زدن را تنظیم کنید؛ خروجی‌های تحت نظر از سلکتورهای بالانسر پیروی می‌کنند.",
         "emptyHint": "هیچ رصدگر اتصالی فعال نیست. وقتی یک بالانسر Least Ping یا Least Load بسازید — یا یک بالانسر Random / Round-robin همراه با fallback — به‌صورت خودکار یکی اضافه می‌شود تا بالانسرهای متکی به رصدگر بتوانند پیش از انتخاب مقصد، سلامت خروجی‌ها را بررسی کنند.",
         "mixedLegacy": "این پیکربندی هم Observatory و هم Burst Observatory دارد. Xray فقط از یک رصدگر سراسری استفاده می‌کند، بنابراین این حالت قدیمیِ ترکیبی پشتیبانی نمی‌شود؛ ذخیرهٔ بالانسرها آن را به یک رصدگر عادی‌سازی می‌کند.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "بالانسر {tag} — حذف شد (هدفی باقی نماند)"
       },
       "balancer": {
-        "addBalancer": "افزودن بالانسر",
-        "editBalancer": "ویرایش بالانسر",
         "balancerStrategy": "استراتژی",
-        "balancerSelectors": "انتخاب‌گرها",
         "tag": "تگ",
-        "tagDesc": "برچسب یگانه",
         "tagDuplicate": "این تگ توسط بالانسر دیگری استفاده شده است",
         "tagPlaceholder": "تگ منحصربه‌فرد بالانسر",
         "selector": "انتخابگر",
@@ -1789,7 +1609,6 @@
         "tolerance": "تحمل",
         "baselines": "خطوط پایه",
         "costs": "هزینه‌ها",
-        "balancerDesc": "امکان استفاده همزمان balancerTag و outboundTag باهم وجود ندارد. درصورت استفاده همزمان فقط outboundTag عمل خواهد کرد.",
         "costMatch": "الگوی برچسب",
         "costValue": "وزن",
         "costRegexp": "تطبیق با عبارت باقاعده",
@@ -1804,14 +1623,10 @@
         "publicKey": "کلید عمومی",
         "allowedIPs": "آی‌پی‌های مجاز",
         "endpoint": "نقطه پایانی",
-        "psk": "کلید مشترک",
         "domainStrategy": "استراتژی حل دامنه"
       },
       "tun": {
-        "nameDesc": "نام رابط TUN. مقدار پیش‌فرض 'xray0' است",
-        "mtuDesc": "واحد انتقال حداکثر. بیشترین اندازه بسته‌های داده. مقدار پیش‌فرض 1500 است",
-        "userLevel": "سطح کاربر",
-        "userLevelDesc": "تمام اتصالات انجام‌شده از طریق این ورودی از این سطح کاربری استفاده خواهند کرد. مقدار پیش‌فرض 0 است"
+        "userLevel": "سطح کاربر"
       },
       "nord": {
         "accessToken": "توکن دسترسی",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "افزودن دی‌ان‌اس جعلی",
-        "edit": "ویرایش دی‌ان‌اس جعلی",
         "ipPool": "زیرشبکه استخر آی‌پی",
         "poolSize": "اندازه استخر"
       },
@@ -2032,7 +1846,6 @@
     "add": "افزودن",
     "month": "ماه",
     "months": "ماه",
-    "day": "روز",
     "days": "روز",
     "hours": "ساعت",
     "minutes": "دقیقه",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ کاربر تلگرام ذخیره شد.",
       "loginSuccess": "✅ با موفقیت به پنل وارد شدید.\r\n",
       "loginFailed": "❗️ ورود به پنل ناموفق‌بود \r\n",
-      "2faFailed": "خطای 2FA",
       "report": "🕰 گزارشات‌زمان‌بندی‌شده: {{ .RunTime }}\r\n",
       "datetime": "⏰ تاریخ‌وزمان: {{ .DateTime }}\r\n",
       "hostname": "💻 میزبان: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 دانلود: ↓{{ .Download }}\r\n",
       "total": "📊 کل: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 کاربر تلگرام: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 {{ .Type }} به‌اتمام‌رسیده‌است:\r\n",
       "exhaustedCount": "🚨 تعداد {{ .Type }} به‌اتمام‌رسیده‌است:\r\n",
       "onlinesCount": "🌐 کاربران‌آنلاین: {{ .Count }}\r\n",
       "disabled": "🛑 غیرفعال: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 تازه‌سازی شده در: {{ .Time }}\r\n\r\n",
       "yes": "✅ بله",
       "no": "❌ خیر",
-      "received_id": "🔑📥 شناسه به‌روزرسانی شد.",
-      "received_password": "🔑📥 رمز عبور به‌روزرسانی شد.",
       "received_email": "📧📥 ایمیل به‌روزرسانی شد.",
       "received_comment": "💬📥 نظر به‌روزرسانی شد.",
-      "id_prompt": "🔑 شناسه پیش‌فرض: {{ .ClientId }}\n\nشناسه خود را وارد کنید.",
-      "pass_prompt": "🔑 رمز عبور پیش‌فرض: {{ .ClientPassword }}\n\nرمز عبور خود را وارد کنید.",
       "email_prompt": "📧 ایمیل پیش‌فرض: {{ .ClientEmail }}\n\nایمیل خود را وارد کنید.",
       "comment_prompt": "💬 نظر پیش‌فرض: {{ .ClientComment }}\n\nنظر خود را وارد کنید.",
-      "inbound_client_data_id": "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 شناسه: {{ .ClientId }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون می‌تونی مشتری را به ورودی اضافه کنی!",
-      "inbound_client_data_pass": "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 رمز عبور: {{ .ClientPass }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون می‌تونی مشتری را به ورودی اضافه کنی!",
       "cancel": "❌ فرآیند لغو شد! \n\nمی‌توانید هر زمان که خواستید /start را دوباره اجرا کنید. 🔄",
       "error_add_client": "⚠️ خطا:\n\n {{ .error }}",
       "using_default_value": "باشه، از مقدار پیش‌فرض استفاده می‌کنم. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "خطا: {{ .Error }}",
       "eventNodeDown": "نود {{ .Name }} قطع است",
       "eventNodeUp": "نود {{ .Name }} وصل است",
-      "eventCPUHigh": "بالا بودن CPU",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "ورود ناموفق از {{ .Source }}",
       "memoryThreshold": "مصرف حافظه {{ .Percent }}% از حد آستانه {{ .Threshold }}% فراتر رفته است"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "ارسال به عنوان غیرفعال ☑️",
       "submitEnable": "ارسال به عنوان فعال ✅",
       "use_default": "🏷️ استفاده از پیش‌فرض",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 گذرواژه",
       "change_email": "⚙️📧 ایمیل",
       "change_comment": "⚙️💬 نظر",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "بازنشانی همه ترافیک‌ها",
       "SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتب‌شده"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "خروجی {{ .Tag }} قطع است",
-    "subjectOutboundUp": "خروجی {{ .Tag }} وصل است",
-    "subjectXrayCrash": "Xray کرش کرد",
-    "subjectCPUHigh": "بالا بودن CPU",
-    "subjectLoginSuccess": "ورود موفق",
-    "subjectLoginFailed": "ورود ناموفق",
-    "titleOutboundDown": "خروجی قطع شد",
-    "titleOutboundUp": "خروجی وصل شد",
-    "titleXrayCrash": "Xray کرش کرد",
-    "titleCPUHigh": "بالا بودن CPU",
-    "titleLoginSuccess": "ورود موفق",
-    "titleLoginFailed": "ورود ناموفق",
     "labelStatus": "وضعیت",
     "labelOutbound": "خروجی",
     "labelNode": "نود",
     "labelError": "خطا",
     "labelDelay": "تأخیر",
-    "labelDetail": "جزئیات",
     "labelUsername": "نام‌کاربری",
     "labelIP": "IP",
     "labelReason": "دلیل",
     "labelSource": "مبدأ",
-    "labelTime": "زمان",
     "statusCrashed": "کرش کرد",
-    "statusRunning": "در حال اجرا",
     "statusHigh": "بالا",
     "statusSuccess": "موفق",
     "statusFailed": "ناموفق",

+ 3 - 218
internal/web/translation/id-ID.json

@@ -48,7 +48,6 @@
   "copySuccess": "Berhasil Disalin",
   "sure": "Yakin",
   "encryption": "Enkripsi",
-  "useIPv4ForHost": "Gunakan IPv4 untuk host",
   "transmission": "Transmisi",
   "host": "Host",
   "path": "Path",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Kode",
   "remained": "Tersisa",
   "security": "Keamanan",
-  "secAlertTitle": "Peringatan keamanan",
-  "secAlertSsl": "Koneksi ini tidak aman. Harap hindari memasukkan informasi sensitif sampai TLS diaktifkan untuk perlindungan data.",
-  "secAlertConf": "Beberapa pengaturan rentan terhadap serangan. Disarankan untuk memperkuat protokol keamanan guna mencegah pelanggaran potensial.",
-  "secAlertSSL": "Panel kekurangan koneksi yang aman. Harap instal sertifikat TLS untuk perlindungan data.",
-  "secAlertPanelPort": "Port default panel rentan. Harap konfigurasi port acak atau tertentu.",
-  "secAlertPanelURI": "Jalur URI default panel tidak aman. Harap konfigurasi jalur URI kompleks.",
-  "secAlertSubURI": "Jalur URI default langganan tidak aman. Harap konfigurasi jalur URI kompleks.",
-  "secAlertSubJsonURI": "Jalur URI default JSON langganan tidak aman. Harap konfigurasikan jalur URI kompleks.",
   "emptyDnsDesc": "Tidak ada server DNS yang ditambahkan.",
   "emptyFakeDnsDesc": "Tidak ada server Fake DNS yang ditambahkan.",
   "emptyBalancersDesc": "Tidak ada penyeimbang yang ditambahkan.",
-  "emptyReverseDesc": "Tidak ada proxy terbalik yang ditambahkan.",
   "somethingWentWrong": "Terjadi kesalahan",
   "subscription": {
     "title": "Info langganan",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Tema",
-    "dark": "Gelap",
-    "ultraDark": "Sangat Gelap",
     "dashboard": "Ikhtisar",
     "inbounds": "Inbound",
     "clients": "Klien",
@@ -118,7 +106,6 @@
     "routing": "Pengalihan",
     "outbounds": "Outbound",
     "apiDocs": "Dokumentasi API",
-    "logout": "Keluar",
     "link": "Kelola",
     "donate": "Donasi",
     "hosts": "Host",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Ikhtisar",
       "cpu": "CPU",
       "logicalProcessors": "Prosesor logis",
       "frequency": "Frekuensi",
@@ -152,7 +138,6 @@
       "restartXray": "Mulai ulang",
       "xraySwitch": "Versi",
       "xrayUpdates": "Pembaruan Xray",
-      "xraySwitchClick": "Pilih versi yang ingin Anda pindah.",
       "xraySwitchClickDesk": "Pilih dengan hati-hati, karena versi yang lebih lama mungkin tidak kompatibel dengan konfigurasi saat ini.",
       "updatePanel": "Perbarui Panel",
       "panelUpdateDesc": "Ini akan memperbarui 3X-UI ke rilis terbaru dan me-restart layanan panel.",
@@ -164,12 +149,10 @@
       "currentCommit": "Commit saat ini",
       "latestCommit": "Commit terbaru",
       "updateChannelChanged": "Kanal pembaruan diubah",
-      "upToDate": "Terbaru",
       "xrayStatusUnknown": "Tidak diketahui",
       "xrayStatusRunning": "Berjalan",
       "xrayStatusStop": "Berhenti",
       "xrayStatusError": "Error",
-      "xrayErrorPopoverTitle": "Terjadi kesalahan saat menjalankan Xray",
       "operationHours": "Waktu Aktif",
       "systemHistoryTitle": "Riwayat Sistem",
       "historyTitleCpu": "Penggunaan CPU",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Mati",
       "xrayObservatoryLastSeen": "Terakhir terlihat",
       "xrayObservatoryLastTry": "Percobaan terakhir",
-      "trendLast2Min": "2 menit terakhir",
-      "systemLoad": "Beban Sistem",
-      "systemLoadDesc": "Rata-rata beban sistem selama 1, 5, dan 15 menit terakhir",
       "connectionCount": "Statistik Koneksi",
       "ipAddresses": "Alamat IP",
       "toggleIpVisibility": "Alihkan visibilitas IP",
@@ -223,13 +203,11 @@
       "totalData": "Total data",
       "sent": "Dikirim",
       "received": "Diterima",
-      "documentation": "Dokumentasi",
       "xraySwitchVersionDialog": "Apakah Anda yakin ingin mengubah versi Xray?",
       "xraySwitchVersionDialogDesc": "Ini akan mengubah versi Xray ke #version#.",
       "xraySwitchVersionPopover": "Xray berhasil diperbarui",
       "panelUpdateDialog": "Apakah Anda benar-benar ingin memperbarui panel?",
       "panelUpdateDialogDesc": "Ini akan memperbarui 3X-UI ke #version# dan me-restart layanan panel.",
-      "panelUpdateCheckPopover": "Pemeriksaan pembaruan panel gagal",
       "panelUpdateStartedPopover": "Pembaruan panel dimulai",
       "panelUpdateFailedTitle": "Pembaruan panel gagal",
       "panelUpdateFailedDesc": "Pembaruan tidak selesai dengan sukses. Periksa log server, atau jalankan 'x-ui update' dari baris perintah.",
@@ -258,7 +236,6 @@
       "accessLogs": "Log Akses",
       "autoUpdate": "Pembaruan Otomatis",
       "config": "Konfigurasi",
-      "backup": "Cadangan",
       "backupTitle": "Cadangan & Pulihkan",
       "exportDatabase": "Cadangkan",
       "exportDatabaseDesc": "Klik untuk mengunduh file .db yang berisi cadangan dari database Anda saat ini ke perangkat Anda. Berkas yang sama juga dapat dipulihkan ke panel yang berjalan di PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Klik untuk mengunduh basis data SQLite .db yang dibuat dari data PostgreSQL Anda, siap menjalankan panel ini di SQLite."
     },
     "inbounds": {
-      "title": "Inbound",
       "totalDownUp": "Total Terkirim/Diterima",
       "totalUsage": "Penggunaan Total",
       "inboundCount": "Total Masuk",
@@ -288,21 +264,11 @@
       "localPanel": "Panel lokal",
       "fallbacks": {
         "title": "Fallback",
-        "help": "Saat koneksi pada inbound ini tidak cocok dengan client mana pun, arahkan ke tempat lain. Pilih inbound child di bawah untuk mengisi otomatis field routing (SNI / ALPN / Path / xver) dari transport-nya, atau biarkan pemilih kosong dan atur Dest langsung (mis. 8080 atau 127.0.0.1:8080) untuk mengarahkan ke server eksternal seperti Nginx. Setiap inbound child harus listen di 127.0.0.1 dengan security=none.",
         "empty": "Belum ada fallback",
         "add": "Tambah fallback",
         "pickInbound": "Pilih inbound",
         "matchAny": "apa pun",
         "destPlaceholder": "otomatis (listen:port child)",
-        "rederive": "Isi ulang dari child",
-        "rederived": "Diisi ulang dari child",
-        "editAdvanced": "Edit field routing",
-        "hideAdvanced": "Sembunyikan lanjutan",
-        "quickAddAll": "Tambah cepat semua yang memenuhi syarat",
-        "quickAdded": "Menambahkan {n} fallback",
-        "quickAddedNone": "Tidak ada inbound baru yang memenuhi syarat",
-        "routesWhen": "Diarahkan ketika",
-        "defaultCatchAll": "Default — menangkap apa pun lainnya",
         "needsTls": "Fallback tersedia setelah memilih TLS atau Reality di tab Keamanan (hanya VLESS/Trojan melalui RAW)."
       },
       "protocol": "Protokol",
@@ -310,8 +276,6 @@
       "portMap": "Pemetaan port",
       "traffic": "Trafik",
       "speed": "Kecepatan",
-      "details": "Rincian",
-      "transportConfig": "Transport",
       "expireDate": "Durasi",
       "createdAt": "Dibuat",
       "updatedAt": "Diperbarui",
@@ -319,8 +283,6 @@
       "addInbound": "Tambahkan Masuk",
       "generalActions": "Tindakan Umum",
       "modifyInbound": "Ubah Masuk",
-      "deleteInbound": "Hapus Masuk",
-      "deleteInboundContent": "Apakah Anda yakin ingin menghapus masuk?",
       "deleteConfirmTitle": "Hapus inbound \"{remark}\"?",
       "deleteConfirmContent": "Tindakan ini menghapus inbound beserta semua kliennya. Tidak dapat dibatalkan.",
       "resetConfirmTitle": "Reset trafik \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Semua-Inbound",
       "exportAllSubsFileName": "Semua-Inbound-Subs",
       "inboundJsonTitle": "JSON inbound",
-      "deleteClient": "Hapus Klien",
-      "deleteClientContent": "Apakah Anda yakin ingin menghapus klien?",
       "resetTrafficContent": "Apakah Anda yakin ingin mereset traffic?",
       "copyLink": "Salin URL",
       "address": "Alamat",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Tanpa batas. (satuan: GB)",
       "totalFlow": "Total Aliran",
       "leaveBlankToNeverExpire": "Biarkan kosong untuk tidak pernah kedaluwarsa",
-      "noRecommendKeepDefault": "Disarankan untuk tetap menggunakan pengaturan default",
       "certificatePath": "Path Berkas",
       "certificateContent": "Konten Berkas",
       "publicKey": "Kunci Publik",
       "privatekey": "Kunci Pribadi",
-      "clickOnQRcode": "Klik pada Kode QR untuk Menyalin",
       "client": "Klien",
       "export": "Ekspor Semua URL",
       "clone": "Duplikat",
-      "cloneInbound": "Duplikat",
-      "cloneInboundContent": "Semua pengaturan masuk ini, kecuali Port, Listening IP, dan Klien, akan diterapkan pada duplikat.",
-      "cloneInboundOk": "Duplikat",
       "resetAllTraffic": "Reset Semua Traffic Masuk",
       "resetAllTrafficTitle": "Reset Semua Traffic Masuk",
       "resetAllTrafficContent": "Apakah Anda yakin ingin mereset traffic semua masuk?",
-      "resetInboundClientTraffics": "Reset Traffic Klien Masuk",
-      "resetInboundClientTrafficTitle": "Reset Traffic Klien Masuk",
-      "resetInboundClientTrafficContent": "Apakah Anda yakin ingin mereset traffic klien masuk ini?",
-      "resetAllClientTraffics": "Reset Traffic Semua Klien",
-      "resetAllClientTrafficTitle": "Reset Traffic Semua Klien",
-      "resetAllClientTrafficContent": "Apakah Anda yakin ingin mereset traffic semua klien?",
-      "delDepletedClients": "Hapus Klien Habis",
-      "delDepletedClientsTitle": "Hapus Klien Habis",
-      "delDepletedClientsContent": "Apakah Anda yakin ingin menghapus semua klien yang habis?",
       "email": "Email",
-      "emailDesc": "Harap berikan alamat email yang unik.",
       "IPLimit": "Batas IP",
-      "IPLimitDesc": "Menonaktifkan masuk jika jumlah melebihi nilai yang ditetapkan. (0 = nonaktif)",
       "IPLimitlog": "Log IP",
-      "IPLimitlogDesc": "Log histori IP. (untuk mengaktifkan masuk setelah menonaktifkan, hapus log)",
       "IPLimitlogclear": "Hapus Log",
       "setDefaultCert": "Atur Sertifikat dari Panel",
       "setDefaultCertEmpty": "Tidak ada sertifikat yang dikonfigurasi untuk panel. Atur dulu di Pengaturan.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Pembungkus blok sniffing Xray:",
         "stream": "Stream",
-        "streamHelp": "Pembungkus blok stream Xray:",
-        "jsonErrorPrefix": "JSON lanjutan"
+        "streamHelp": "Pembungkus blok stream Xray:"
       },
-      "telegramDesc": "Harap berikan ID Obrolan Telegram. (gunakan perintah '/id' di bot) atau ({'@'}userinfobot)",
-      "subscriptionDesc": "Untuk menemukan URL langganan Anda, buka 'Rincian'. Selain itu, Anda dapat menggunakan nama yang sama untuk beberapa klien.",
       "subSortIndex": "Urutan sub",
-      "same": "Sama",
       "inboundInfo": "Informasi Inbound",
       "exportInbound": "Ekspor Masuk",
       "import": "Impor",
       "importInbound": "Impor Masuk",
       "periodicTrafficResetTitle": "Reset Trafik Berkala",
-      "periodicTrafficResetDesc": "Reset otomatis penghitung trafik pada interval tertentu",
       "periodicTrafficResetDay": "Hari reset bulanan",
-      "lastReset": "Reset Terakhir",
       "periodicTrafficReset": {
         "never": "Tidak Pernah",
         "daily": "Harian",
@@ -464,7 +401,6 @@
         "obtain": "Dapatkan",
         "updateSuccess": "Pembaruan berhasil",
         "logCleanSuccess": "Log telah dibersihkan",
-        "inboundsUpdateSuccess": "Inbound berhasil diperbarui",
         "inboundUpdateSuccess": "Inbound berhasil diperbarui",
         "inboundCreateSuccess": "Inbound berhasil dibuat",
         "bulkDeleted": "{count} inbound dihapus",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Klien inbound telah dihapus",
         "inboundClientUpdateSuccess": "Klien inbound telah diperbarui",
         "savedNodeOfflineWillSync": "Disimpan secara lokal. Node pendukung sedang offline atau dinonaktifkan — perubahan akan disinkronkan setelah terhubung kembali.",
-        "delDepletedClientsSuccess": "Semua klien yang habis telah dihapus",
         "resetAllClientTrafficSuccess": "Semua lalu lintas klien telah direset",
         "resetAllTrafficSuccess": "Semua lalu lintas telah direset",
         "resetInboundClientTrafficSuccess": "Lalu lintas telah direset",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Konfig Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Permintaan",
-          "response": "Respons",
-          "name": "Nama",
-          "value": "Nilai"
-        },
-        "tcp": {
-          "version": "Versi",
-          "method": "Metode",
-          "path": "Path",
-          "status": "Status",
-          "statusDescription": "Deskripsi Status",
-          "requestHeader": "Header Permintaan",
-          "responseHeader": "Header Respons"
-        }
-      },
       "sniffingDestOverride": "Penggantian tujuan"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Tambah Langganan Eksternal",
       "noExternalLinks": "Belum ada tautan eksternal.",
       "noExternalSubscriptions": "Belum ada langganan eksternal.",
-      "add": "Tambah klien",
-      "edit": "Ubah klien",
-      "submitAdd": "Tambah klien",
       "submitEdit": "Simpan perubahan",
       "clientCount": "Jumlah klien",
       "bulk": "Tambah massal",
-      "copyFromInbound": "Salin klien dari inbound",
-      "copyToInbound": "Salin klien ke",
-      "copySelected": "Salin terpilih",
-      "copySource": "Sumber",
-      "copyEmailPreview": "Pratinjau email hasil",
-      "copySelectSourceFirst": "Pilih inbound sumber terlebih dahulu.",
-      "copyResult": "Hasil salinan",
-      "copyResultSuccess": "Berhasil disalin",
-      "copyResultNone": "Tidak ada yang disalin: tidak ada klien terpilih atau sumber kosong",
-      "copyResultErrors": "Kesalahan salin",
-      "copyFlowLabel": "Flow untuk klien baru (VLESS)",
-      "copyFlowHint": "Diterapkan ke semua klien yang disalin. Kosongkan untuk dilewati.",
       "selectAll": "Pilih semua",
       "clearAll": "Hapus semua",
       "method": "Metode",
@@ -775,7 +678,6 @@
       "postfix": "Akhiran",
       "delayedStart": "Mulai setelah penggunaan pertama",
       "expireDays": "Durasi (hari)",
-      "days": "Hari",
       "renew": "Perpanjangan otomatis",
       "renewDesc": "Perpanjangan otomatis setelah kedaluwarsa. (0 = nonaktif) (satuan: hari)",
       "renewDays": "Perpanjangan otomatis (hari)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Segera kedaluwarsa",
       "has": "Memiliki",
       "hasNot": "Tidak memiliki",
-      "title": "Klien",
       "actions": "Aksi",
       "totalGB": "Batas Trafik (GB)",
       "totalGBDesc": "Kuota data untuk klien ini. 0 = tidak terbatas.",
@@ -826,8 +727,6 @@
       "addClient": "Tambah klien",
       "qrCode": "Kode QR",
       "clientInfo": "Informasi Klien",
-      "delete": "Hapus",
-      "reset": "Reset lalu lintas",
       "editClient": "Ubah klien",
       "client": "Klien",
       "enabled": "Aktif",
@@ -841,13 +740,11 @@
       "noLinks": "Tidak ada tautan yang bisa dibagikan — lampirkan klien ini ke inbound yang mendukung protokol terlebih dahulu.",
       "link": "Tautan",
       "resetNotPossible": "Lampirkan klien ini ke inbound terlebih dahulu.",
-      "general": "Umum",
       "resetAllTraffics": "Reset lalu lintas semua klien",
       "resetAllTrafficsTitle": "Reset lalu lintas semua klien?",
       "resetAllTrafficsContent": "Penghitung kirim/terima setiap klien turun ke nol. Kuota dan kedaluwarsa tidak terpengaruh. Tidak dapat dibatalkan.",
       "deleteConfirmTitle": "Hapus klien {email}?",
       "deleteConfirmContent": "Tindakan ini menghapus klien dari setiap inbound terlampir dan menghapus catatan lalu lintasnya. Tidak dapat dibatalkan.",
-      "deleteSelected": "Hapus ({count})",
       "adjustSelected": "Sesuaikan ({count})",
       "subLinksSelected": "Tautan sub ({count})",
       "addToGroupTitle": "Tambahkan {count} klien ke grup",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Nonaktifkan {count} klien?",
       "bulkDisableConfirmContent": "Menonaktifkan setiap klien yang dipilih di semua inbound yang terlampir. Mereka langsung kehilangan akses, tetapi catatan dan trafiknya tetap disimpan.",
       "selectedCount": "{count} dipilih",
-      "attachSelected": "Lampirkan ({count})",
       "attachToInboundsTitle": "Lampirkan {count} klien ke inbound",
       "attachToInboundsDesc": "Melampirkan {count} klien terpilih (UUID/kata sandi sama dan trafik bersama) ke inbound terpilih. Lampiran yang ada tetap dipertahankan.",
       "attachToInboundsTargets": "Inbound tujuan",
       "attachToInboundsNoTargets": "Tidak ada inbound multi-pengguna untuk dilampirkan.",
-      "detachSelected": "Lepas ({count})",
       "detach": "Lepas",
       "detachFromInboundsTitle": "Lepas {count} klien dari inbound",
       "detachFromInboundsDesc": "Menghapus {count} klien terpilih dari inbound terpilih. Pasangan di mana klien tidak terlampir akan dilewati secara diam-diam. Catatan klien dipertahankan (gunakan Delete untuk menghapus sepenuhnya).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag opsional",
       "telegramId": "ID pengguna Telegram",
       "telegramIdPlaceholder": "ID numerik pengguna Telegram (0 = tidak ada)",
-      "created": "Dibuat",
-      "updated": "Diperbarui",
       "ipLimit": "Batas IP",
       "toasts": {
         "deleted": "Klien dihapus",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Grup",
       "name": "Nama",
       "clientCount": "Klien",
       "totalGroups": "Total grup",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "{count} klien dihapus dari {name}."
     },
     "nodes": {
-      "title": "Node",
       "addNode": "Tambah Node",
       "editNode": "Edit node",
       "totalNodes": "Total Node",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Token dari halaman Pengaturan panel jarak jauh",
       "apiTokenHint": "Panel jarak jauh menampilkan token API-nya di Otentikasi → Token API.",
       "apiTokenKeepHint": "Biarkan kosong untuk mempertahankan token saat ini",
-      "regenerate": "Buat Ulang Token",
-      "regenerateConfirm": "Membuat ulang akan membatalkan token saat ini. Setiap panel pusat yang menggunakannya akan kehilangan akses sampai diperbarui. Lanjutkan?",
       "allowPrivateAddress": "Izinkan alamat pribadi",
       "allowPrivateAddressHint": "Aktifkan hanya untuk node di jaringan pribadi atau VPN.",
       "outboundTag": "Outbound koneksi",
@@ -1046,7 +935,6 @@
       "updatePanel": "Perbarui Panel",
       "updateSelected": "Perbarui Terpilih ({count})",
       "updateAvailable": "Pembaruan tersedia",
-      "upToDate": "Terbaru",
       "updateConfirmTitle": "Perbarui {count} node ke versi terbaru?",
       "updateConfirmContent": "Setiap node terpilih mengunduh rilis terbaru dan memulai ulang. Hanya node aktif dan online yang diperbarui.",
       "updateDevChannel": "Perbarui ke kanal dev (commit terbaru)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Tidak dapat mengambil sertifikat"
     },
     "settings": {
+      "defaultTag": "Bawaan",
       "title": "Pengaturan Panel",
       "save": "Simpan",
       "infoDesc": "Setiap perubahan yang dibuat di sini perlu disimpan. Harap restart panel untuk menerapkan perubahan.",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "Batalkan hapus"
     },
     "xray": {
-      "title": "Konfigurasi Xray",
       "save": "Simpan",
-      "restart": "Mulai ulang Xray",
       "restartSuccess": "Xray berhasil diluncurkan ulang",
-      "restartOutputTitle": "Output mulai ulang Xray",
-      "restartConfirmTitle": "Mulai ulang xray?",
-      "restartConfirmContent": "Memuat ulang layanan xray dengan konfigurasi tersimpan.",
       "stopSuccess": "Xray telah berhasil dihentikan",
       "restartError": "Terjadi kesalahan saat memulai ulang Xray.",
       "stopError": "Terjadi kesalahan saat menghentikan Xray.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "Opsi ini akan menentukan penyesuaian strategi umum.",
       "logConfigs": "Log",
       "logConfigsDesc": "Log dapat mempengaruhi efisiensi server Anda. Disarankan untuk mengaktifkannya dengan bijak hanya jika diperlukan",
-      "blockConfigsDesc": "Opsi ini akan memblokir lalu lintas berdasarkan protokol dan situs web yang diminta.",
       "basicRouting": "Perutean Dasar",
       "blockConnectionsConfigsDesc": "Opsi ini akan memblokir lalu lintas berdasarkan negara yang diminta.",
       "directConnectionsConfigsDesc": "Koneksi langsung memastikan bahwa lalu lintas tertentu tidak dialihkan melalui server lain.",
@@ -1473,10 +1356,6 @@
       "directdomains": "Domain Langsung",
       "ipv4Routing": "Perutean IPv4",
       "ipv4RoutingDesc": "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui IPv4.",
-      "warpRouting": "Perutean WARP",
-      "warpRoutingDesc": "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui WARP.",
-      "nordRouting": "Routing NordVPN",
-      "nordRoutingDesc": "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui NordVPN.",
       "Template": "Template Konfigurasi Xray Lanjutan",
       "TemplateDesc": "File konfigurasi Xray akhir akan dibuat berdasarkan template ini.",
       "FreedomStrategy": "Strategi Protokol Freedom",
@@ -1490,7 +1369,6 @@
       "outboundTestUrlDesc": "URL yang digunakan saat menguji konektivitas outbound",
       "Torrent": "Blokir Protokol BitTorrent",
       "Inbounds": "Inbound",
-      "InboundsDesc": "Menerima klien tertentu.",
       "Outbounds": "Outbound",
       "importRules": "Impor aturan",
       "exportRules": "Ekspor aturan",
@@ -1500,8 +1378,6 @@
       "metricsListen": "Endpoint metrik",
       "metricsListenDesc": "Tampilkan metrik gaya Prometheus dari Xray pada alamat:port ini (mis. 127.0.0.1:11111). Biarkan kosong untuk menonaktifkan. Ikat ke localhost dan reverse-proxy — endpoint ini tanpa autentikasi.",
       "metricsTag": "Tag metrik",
-      "OutboundSubscriptions": "Langganan Outbound",
-      "OutboundSubscriptionsDesc": "Impor outbound dari URL langganan jarak jauh (vmess/vless/trojan/ss/...). Tag dijaga tetap stabil untuk digunakan pada penyeimbang dan aturan routing. Pembaruan berjalan otomatis.",
       "Balancers": "Penyeimbang",
       "balancerTagRequired": "Tag wajib diisi",
       "balancerSelectorRequired": "Pilih setidaknya satu outbound",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "Outbound yang cocok",
       "routeTesterViaBalancer": "melalui penyeimbang",
       "routeTesterDefaultOutbound": "Tidak ada aturan routing yang cocok — lalu lintas menuju outbound default (pertama).",
-      "OutboundsDesc": "Atur jalur lalu lintas keluar.",
       "Routings": "Aturan Pengalihan",
-      "RoutingsDesc": "Prioritas setiap aturan penting!",
       "completeTemplate": "Semua",
       "logLevel": "Tingkat Log",
       "logLevelDesc": "Tingkat log untuk log kesalahan, menunjukkan informasi yang perlu dicatat.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "Masker alamat IP, ketika diaktifkan, akan secara otomatis mengganti alamat IP yang muncul di log.",
       "statistics": "Statistik",
       "statsInboundUplink": "Statistik Unggah Masuk",
-      "statsInboundUplinkDesc": "Mengaktifkan pengumpulan statistik untuk lalu lintas unggah dari semua proxy masuk.",
       "statsInboundDownlink": "Statistik Unduh Masuk",
-      "statsInboundDownlinkDesc": "Mengaktifkan pengumpulan statistik untuk lalu lintas unduh dari semua proxy masuk.",
       "statsOutboundUplink": "Statistik Unggah Keluar",
-      "statsOutboundUplinkDesc": "Mengaktifkan pengumpulan statistik untuk lalu lintas unggah dari semua proxy keluar.",
       "statsOutboundDownlink": "Statistik Unduh Keluar",
-      "statsOutboundDownlinkDesc": "Mengaktifkan pengumpulan statistik untuk lalu lintas unduh dari semua proxy keluar.",
       "connectionLimits": "Batas Koneksi",
       "connectionLimitsDesc": "Kebijakan tingkat koneksi untuk level pengguna 0. Biarkan kolom kosong untuk menggunakan nilai bawaan Xray.",
       "connIdle": "Batas Waktu Idle",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "otomatis",
       "seconds": "detik",
       "rules": {
-        "first": "Pertama",
-        "last": "Terakhir",
-        "up": "Naik",
-        "down": "Turun",
         "source": "Sumber",
         "dest": "Tujuan",
         "inbound": "Masuk",
-        "outbound": "Keluar",
         "balancer": "Pengimbang",
-        "info": "Info",
-        "add": "Tambahkan Aturan",
-        "edit": "Edit Aturan",
         "useComma": "Item yang dipisahkan koma"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Aturan {n}",
         "action": "Aksi",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Aturan akhir",
         "overrideXrayPrivateIp": "Timpa blok IP privat default Xray",
         "blockDelay": "Penundaan blokir (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Interval keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Interface",
-        "ipv6Only": "Hanya IPv6",
-        "acceptProxyProtocol": "Terima proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (d)"
       },
       "outbound": {
-        "addOutbound": "Tambahkan Keluar",
-        "addReverse": "Tambahkan Revers",
-        "editOutbound": "Edit Keluar",
-        "editReverse": "Edit Revers",
-        "reverseTag": "Tag Revers",
-        "reverseTagDesc": "Tag outbound proxy revers sederhana VLESS. Kosongkan untuk menonaktifkan.",
-        "reverseTagPlaceholder": "tag outbound (kosong untuk menonaktifkan)",
         "tag": "Tag",
-        "tagDesc": "Tag Unik",
-        "address": "Alamat",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Revers",
-        "domain": "Domain",
-        "type": "Tipe",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Tautan",
-        "intercon": "Interkoneksi",
-        "settings": "Pengaturan",
-        "accountInfo": "Informasi Akun",
         "outboundStatus": "Status Keluar",
         "sendThrough": "Kirim Melalui",
         "targetStrategy": "Strategi Target",
-        "test": "Tes",
-        "testResult": "Hasil Tes",
-        "testing": "Menguji koneksi...",
-        "testSuccess": "Tes berhasil",
-        "testFailed": "Tes gagal",
-        "testError": "Gagal menguji outbound",
         "modeRealDelay": "Delay nyata",
         "testModeTooltip": "TCP: probe dial-only cepat. HTTP: permintaan penuh via xray. Delay nyata: total waktu termasuk pembentukan koneksi.",
         "testAll": "Tes semua",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Koneksi proxy",
         "breakdownTls": "TLS melalui outbound",
         "breakdownTtfb": "Byte pertama",
-        "nordvpn": "NordVPN",
-        "accessToken": "Token Akses",
         "country": "Negara",
         "server": "Server",
         "city": "Kota",
         "allCities": "Semua Kota",
-        "privateKey": "Kunci Privat",
-        "load": "Beban",
         "moveToTop": "Pindahkan ke atas"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Langganan aktif",
         "empty": "Belum ada langganan. Tambahkan satu di atas.",
         "colRemark": "Catatan",
-        "colPrefix": "Awalan",
-        "colInterval": "Interval",
         "colLastFetch": "Pengambilan terakhir",
         "colEnabled": "Aktif",
         "auto": "otomatis",
         "never": "tidak pernah",
-        "yes": "Ya",
-        "no": "Tidak",
         "refreshNow": "Segarkan sekarang",
-        "lastError": "Kesalahan terakhir",
         "deleteConfirm": "Hapus langganan ini?",
         "restartHint": "Setelah menambahkan atau menyegarkan, mulai ulang Xray (atau tunggu muat ulang otomatis berikutnya) agar outbound menjadi aktif.",
         "fromSubsTitle": "Dari langganan outbound (hanya-baca)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Pengaturan Balancer",
       "tabObservatory": "Observatory",
       "observatory": {
-        "title": "Observatory",
-        "burstTitle": "Burst Observatory",
         "autoManaged": "Observer dikelola otomatis dari balancer Anda. Atur cara mereka melakukan probe di bawah; outbound yang dipantau mengikuti selector balancer.",
         "emptyHint": "Tidak ada observer koneksi yang aktif. Satu akan ditambahkan otomatis saat Anda membuat balancer Least Ping atau Least Load — atau balancer Random / Round-robin dengan fallback — sehingga balancer yang memakai observer dapat memeriksa kesehatan outbound sebelum memilih target.",
         "mixedLegacy": "Konfigurasi ini berisi Observatory dan Burst Observatory sekaligus. Xray memakai satu observer global, jadi status campuran lama ini tidak didukung; menyimpan balancer akan menormalkannya menjadi satu observer.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Balancer {tag} — dihapus (tidak ada target tersisa)"
       },
       "balancer": {
-        "addBalancer": "Tambahkan Penyeimbang",
-        "editBalancer": "Sunting Penyeimbang",
         "balancerStrategy": "Strategi",
-        "balancerSelectors": "Penyeleksi",
         "tag": "Tag",
-        "tagDesc": "Label Unik",
         "tagDuplicate": "Tag sudah digunakan oleh balancer lain",
         "tagPlaceholder": "tag balancer unik",
         "selector": "Selector",
@@ -1789,7 +1609,6 @@
         "tolerance": "Toleransi",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "BalancerTag dan outboundTag tidak dapat digunakan secara bersamaan. Jika digunakan secara bersamaan, hanya outboundTag yang akan berfungsi.",
         "costMatch": "Pola tag",
         "costValue": "Bobot",
         "costRegexp": "Pencocokan ekspresi reguler",
@@ -1804,14 +1623,10 @@
         "publicKey": "Kunci Publik",
         "allowedIPs": "IP yang Diizinkan",
         "endpoint": "Titik Akhir",
-        "psk": "Kunci Pra-Bagi",
         "domainStrategy": "Strategi Domain"
       },
       "tun": {
-        "nameDesc": "Nama antarmuka TUN. Standar adalah 'xray0'",
-        "mtuDesc": "Unit Transmisi Maksimum. Ukuran maksimum paket data. Standar adalah 1500",
-        "userLevel": "Level Pengguna",
-        "userLevelDesc": "Semua koneksi yang dibuat melalui inbound ini akan menggunakan level pengguna ini. Standar adalah 0"
+        "userLevel": "Level Pengguna"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Tambahkan DNS Palsu",
-        "edit": "Edit DNS Palsu",
         "ipPool": "Subnet Kumpulan IP",
         "poolSize": "Ukuran Kolam"
       },
@@ -2032,7 +1846,6 @@
     "add": "Tambah",
     "month": "Bulan",
     "months": "Bulan",
-    "day": "Hari",
     "days": "Hari",
     "hours": "Jam",
     "minutes": "Menit",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Pengguna Telegram tersimpan.",
       "loginSuccess": "✅ Berhasil masuk ke panel.\r\n",
       "loginFailed": "❗️ Gagal masuk ke panel.\r\n",
-      "2faFailed": "2FA Gagal",
       "report": "🕰 Laporan Terjadwal: {{ .RunTime }}\r\n",
       "datetime": "⏰ Tanggal & Waktu: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Unduh: ↓{{ .Download }}\r\n",
       "total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Pengguna Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Habis {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Jumlah Habis {{ .Type }}:\r\n",
       "onlinesCount": "🌐 Klien Online: {{ .Count }}\r\n",
       "disabled": "🛑 Dinonaktifkan: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Diperbarui Pada: {{ .Time }}\r\n\r\n",
       "yes": "✅ Ya",
       "no": "❌ Tidak",
-      "received_id": "🔑📥 ID diperbarui.",
-      "received_password": "🔑📥 Kata sandi diperbarui.",
       "received_email": "📧📥 Email diperbarui.",
       "received_comment": "💬📥 Komentar diperbarui.",
-      "id_prompt": "🔑 ID Default: {{ .ClientId }}\n\nMasukkan ID Anda.",
-      "pass_prompt": "🔑 Kata Sandi Default: {{ .ClientPassword }}\n\nMasukkan kata sandi Anda.",
       "email_prompt": "📧 Email Default: {{ .ClientEmail }}\n\nMasukkan email Anda.",
       "comment_prompt": "💬 Komentar Default: {{ .ClientComment }}\n\nMasukkan komentar Anda.",
-      "inbound_client_data_id": "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n🌐 Batas IP: {{ .IpLimit }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang kamu bisa menambahkan klien ke inbound!",
-      "inbound_client_data_pass": "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 Kata sandi: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n🌐 Batas IP: {{ .IpLimit }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang kamu bisa menambahkan klien ke inbound!",
       "cancel": "❌ Proses Dibatalkan! \n\nAnda dapat /start lagi kapan saja. 🔄",
       "error_add_client": "⚠️ Error:\n\n {{ .error }}",
       "using_default_value": "Oke, saya akan tetap menggunakan nilai default. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Kesalahan: {{ .Error }}",
       "eventNodeDown": "Node {{ .Name }} MATI",
       "eventNodeUp": "Node {{ .Name }} AKTIF",
-      "eventCPUHigh": "CPU tinggi",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Gagal masuk dari {{ .Source }}",
       "memoryThreshold": "Penggunaan memori {{ .Percent }}% melebihi ambang batas {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Kirim Sebagai Nonaktif ☑️",
       "submitEnable": "Kirim Sebagai Aktif ✅",
       "use_default": "🏷️ Gunakan Default",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Kata Sandi",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Komentar",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Reset Semua Lalu Lintas",
       "SortedTrafficUsageReport": "Laporan Penggunaan Lalu Lintas yang Terurut"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "Outbound {{ .Tag }} MATI",
-    "subjectOutboundUp": "Outbound {{ .Tag }} AKTIF",
-    "subjectXrayCrash": "Xray CRASH",
-    "subjectCPUHigh": "CPU tinggi",
-    "subjectLoginSuccess": "Berhasil masuk",
-    "subjectLoginFailed": "Gagal masuk",
-    "titleOutboundDown": "Outbound MATI",
-    "titleOutboundUp": "Outbound AKTIF",
-    "titleXrayCrash": "Xray CRASH",
-    "titleCPUHigh": "CPU tinggi",
-    "titleLoginSuccess": "Berhasil masuk",
-    "titleLoginFailed": "Gagal masuk",
     "labelStatus": "Status",
     "labelOutbound": "Outbound",
     "labelNode": "Node",
     "labelError": "Kesalahan",
     "labelDelay": "Penundaan",
-    "labelDetail": "Detail",
     "labelUsername": "Nama Pengguna",
     "labelIP": "IP",
     "labelReason": "Alasan",
     "labelSource": "Sumber",
-    "labelTime": "Waktu",
     "statusCrashed": "CRASH",
-    "statusRunning": "Berjalan",
     "statusHigh": "TINGGI",
     "statusSuccess": "BERHASIL",
     "statusFailed": "GAGAL",

+ 3 - 218
internal/web/translation/ja-JP.json

@@ -48,7 +48,6 @@
   "copySuccess": "コピー成功",
   "sure": "確定",
   "encryption": "暗号化",
-  "useIPv4ForHost": "ホストにIPv4を使用",
   "transmission": "伝送",
   "host": "ホスト",
   "path": "パス",
@@ -74,18 +73,9 @@
   "twoFactorCode": "コード",
   "remained": "残り",
   "security": "セキュリティ",
-  "secAlertTitle": "セキュリティアラート",
-  "secAlertSsl": "この接続は安全ではありません。TLSを有効にしてデータ保護を行うまで、機密情報を入力しないでください。",
-  "secAlertConf": "一部の設定は脆弱です。潜在的な脆弱性を防ぐために、セキュリティプロトコルを強化することをお勧めします。",
-  "secAlertSSL": "セキュアな接続がありません。データ保護のためにTLS証明書をインストールしてください。",
-  "secAlertPanelPort": "デフォルトのポートにはセキュリティリスクがあります。ランダムなポートまたは特定のポートを設定してください。",
-  "secAlertPanelURI": "デフォルトのURIパスは安全ではありません。複雑なURIパスを設定してください。",
-  "secAlertSubURI": "サブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。",
-  "secAlertSubJsonURI": "JSONサブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。",
   "emptyDnsDesc": "追加されたDNSサーバーはありません。",
   "emptyFakeDnsDesc": "追加されたFake DNSサーバーはありません。",
   "emptyBalancersDesc": "追加されたバランサーはありません。",
-  "emptyReverseDesc": "追加されたリバースプロキシはありません。",
   "somethingWentWrong": "エラーが発生しました",
   "subscription": {
     "title": "サブスクリプション情報",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "テーマ",
-    "dark": "ダーク",
-    "ultraDark": "ウルトラダーク",
     "dashboard": "ダッシュボード",
     "inbounds": "インバウンド",
     "clients": "クライアント",
@@ -118,7 +106,6 @@
     "routing": "ルーティング",
     "outbounds": "アウトバウンド",
     "apiDocs": "API ドキュメント",
-    "logout": "ログアウト",
     "link": "リンク管理",
     "donate": "寄付",
     "hosts": "ホスト",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "システムステータス",
       "cpu": "CPU",
       "logicalProcessors": "論理プロセッサ",
       "frequency": "周波数",
@@ -152,7 +138,6 @@
       "restartXray": "再起動",
       "xraySwitch": "バージョン",
       "xrayUpdates": "Xrayの更新",
-      "xraySwitchClick": "切り替えるバージョンを選択してください",
       "xraySwitchClickDesk": "慎重に選択してください。古いバージョンは現在の設定と互換性がない可能性があります。",
       "updatePanel": "パネルを更新",
       "panelUpdateDesc": "これにより3X-UIが最新リリースに更新され、パネルサービスが再起動されます。",
@@ -164,12 +149,10 @@
       "currentCommit": "現在のコミット",
       "latestCommit": "最新のコミット",
       "updateChannelChanged": "更新チャンネルを変更しました",
-      "upToDate": "最新",
       "xrayStatusUnknown": "不明",
       "xrayStatusRunning": "実行中",
       "xrayStatusStop": "停止",
       "xrayStatusError": "エラー",
-      "xrayErrorPopoverTitle": "Xrayの実行中にエラーが発生しました",
       "operationHours": "システム稼働時間",
       "systemHistoryTitle": "システム履歴",
       "historyTitleCpu": "CPU 使用率",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "停止",
       "xrayObservatoryLastSeen": "最終確認",
       "xrayObservatoryLastTry": "最終試行",
-      "trendLast2Min": "直近2分",
-      "systemLoad": "システム負荷",
-      "systemLoadDesc": "過去1、5、15分間のシステム平均負荷",
       "connectionCount": "接続数",
       "ipAddresses": "IPアドレス",
       "toggleIpVisibility": "IPの表示を切り替える",
@@ -223,13 +203,11 @@
       "totalData": "総データ量",
       "sent": "送信",
       "received": "受信",
-      "documentation": "ドキュメント",
       "xraySwitchVersionDialog": "Xrayのバージョンを本当に変更しますか?",
       "xraySwitchVersionDialogDesc": "Xrayのバージョンが#version#に変更されます。",
       "xraySwitchVersionPopover": "Xrayの更新が成功しました",
       "panelUpdateDialog": "本当にパネルを更新しますか?",
       "panelUpdateDialogDesc": "これにより3X-UIが#version#に更新され、パネルサービスが再起動されます。",
-      "panelUpdateCheckPopover": "パネルの更新確認に失敗しました",
       "panelUpdateStartedPopover": "パネルの更新を開始しました",
       "panelUpdateFailedTitle": "パネルの更新に失敗しました",
       "panelUpdateFailedDesc": "更新が正常に完了しませんでした。サーバーのログを確認するか、コマンドラインで「x-ui update」を実行してください。",
@@ -258,7 +236,6 @@
       "accessLogs": "アクセスログ",
       "autoUpdate": "自動更新",
       "config": "設定",
-      "backup": "バックアップ",
       "backupTitle": "バックアップと復元",
       "exportDatabase": "バックアップ",
       "exportDatabaseDesc": "クリックして、現在のデータベースのバックアップを含む .db ファイルをデバイスにダウンロードします。同じファイルは PostgreSQL で動作するパネルにも復元できます。",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "PostgreSQL のデータから作成した .db SQLite データベースをダウンロードします。このパネルを SQLite で実行する準備が整います。"
     },
     "inbounds": {
-      "title": "インバウンド",
       "totalDownUp": "総アップロード / ダウンロード",
       "totalUsage": "総使用量",
       "inboundCount": "インバウンド数",
@@ -288,21 +264,11 @@
       "localPanel": "ローカルパネル",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "このインバウンドへの接続がどのクライアントにも一致しない場合、別の宛先へルーティングします。下から子インバウンドを選ぶとルーティング項目(SNI / ALPN / Path / xver)がそのトランスポートから自動的に埋められます。あるいは選択を空のままにして Dest を直接指定すると(例: 8080 または 127.0.0.1:8080)、Nginx などの外部サーバーへルーティングできます。各子インバウンドは 127.0.0.1 で security=none をリッスンする必要があります。",
         "empty": "フォールバックはまだありません",
         "add": "フォールバックを追加",
         "pickInbound": "インバウンドを選択",
         "matchAny": "任意",
         "destPlaceholder": "自動(子の listen:port)",
-        "rederive": "子から再取得",
-        "rederived": "子から再取得しました",
-        "editAdvanced": "ルーティング項目を編集",
-        "hideAdvanced": "詳細を隠す",
-        "quickAddAll": "対象のインバウンドをすべて一括追加",
-        "quickAdded": "{n} 件のフォールバックを追加しました",
-        "quickAddedNone": "追加可能な新規インバウンドはありません",
-        "routesWhen": "次の条件でルーティング",
-        "defaultCatchAll": "デフォルト — その他すべてを捕捉",
         "needsTls": "フォールバックは、セキュリティタブで TLS または Reality を選択すると設定できます(RAW 上の VLESS/Trojan のみ)。"
       },
       "protocol": "プロトコル",
@@ -310,8 +276,6 @@
       "portMap": "ポートマッピング",
       "traffic": "トラフィック",
       "speed": "速度",
-      "details": "詳細情報",
-      "transportConfig": "トランスポート",
       "expireDate": "有効期限",
       "createdAt": "作成",
       "updatedAt": "更新",
@@ -319,8 +283,6 @@
       "addInbound": "インバウンド追加",
       "generalActions": "一般操作",
       "modifyInbound": "インバウンド修正",
-      "deleteInbound": "インバウンド削除",
-      "deleteInboundContent": "インバウンドを削除してもよろしいですか?",
       "deleteConfirmTitle": "インバウンド「{remark}」を削除しますか?",
       "deleteConfirmContent": "インバウンドと関連付けされたすべてのクライアントを削除します。元に戻せません。",
       "resetConfirmTitle": "「{remark}」のトラフィックをリセットしますか?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "全インバウンド",
       "exportAllSubsFileName": "全インバウンド-Subs",
       "inboundJsonTitle": "インバウンド JSON",
-      "deleteClient": "クライアント削除",
-      "deleteClientContent": "クライアントを削除してもよろしいですか?",
       "resetTrafficContent": "トラフィックをリセットしてもよろしいですか?",
       "copyLink": "リンクをコピー",
       "address": "アドレス",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= 無制限。(単位: GB)",
       "totalFlow": "総トラフィック",
       "leaveBlankToNeverExpire": "空白にすると期限なし",
-      "noRecommendKeepDefault": "デフォルト値を保持することをお勧めします",
       "certificatePath": "ファイルパス",
       "certificateContent": "ファイル内容",
       "publicKey": "公開鍵",
       "privatekey": "秘密鍵",
-      "clickOnQRcode": "QRコードをクリックしてコピー",
       "client": "クライアント",
       "export": "リンクエクスポート",
       "clone": "複製",
-      "cloneInbound": "複製",
-      "cloneInboundContent": "このインバウンドルールは、ポート(Port)、リスニングIP(Listening IP)、クライアント(Clients)を除くすべての設定がクローンされます",
-      "cloneInboundOk": "クローン作成",
       "resetAllTraffic": "すべてのインバウンドトラフィックをリセット",
       "resetAllTrafficTitle": "すべてのインバウンドトラフィックをリセット",
       "resetAllTrafficContent": "すべてのインバウンドトラフィックをリセットしてもよろしいですか?",
-      "resetInboundClientTraffics": "クライアントトラフィックをリセット",
-      "resetInboundClientTrafficTitle": "すべてのクライアントトラフィックをリセット",
-      "resetInboundClientTrafficContent": "このインバウンドクライアントのすべてのトラフィックをリセットしてもよろしいですか?",
-      "resetAllClientTraffics": "すべてのクライアントトラフィックをリセット",
-      "resetAllClientTrafficTitle": "すべてのクライアントトラフィックをリセット",
-      "resetAllClientTrafficContent": "すべてのクライアントのトラフィックをリセットしてもよろしいですか?",
-      "delDepletedClients": "トラフィックが尽きたクライアントを削除",
-      "delDepletedClientsTitle": "トラフィックが尽きたクライアントを削除",
-      "delDepletedClientsContent": "トラフィックが尽きたすべてのクライアントを削除してもよろしいですか?",
       "email": "メール",
-      "emailDesc": "メールアドレスは一意でなければなりません",
       "IPLimit": "IP制限",
-      "IPLimitDesc": "設定値を超えるとインバウンドトラフィックが無効になります。(0 = 無効)",
       "IPLimitlog": "IPログ",
-      "IPLimitlogDesc": "IP履歴ログ(無効なインバウンドトラフィックを有効にするには、ログをクリアしてください)",
       "IPLimitlogclear": "ログをクリア",
       "setDefaultCert": "パネル設定から証明書を設定",
       "setDefaultCertEmpty": "パネル用の証明書が設定されていません。先に設定から指定してください。",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Xray sniffing ブロックのラッパー:",
         "stream": "Stream",
-        "streamHelp": "Xray stream ブロックのラッパー:",
-        "jsonErrorPrefix": "高度な JSON"
+        "streamHelp": "Xray stream ブロックのラッパー:"
       },
-      "telegramDesc": "TelegramチャットIDを提供してください。(ボットで'/id'コマンドを使用)または({'@'}userinfobot)",
-      "subscriptionDesc": "サブスクリプションURLを見つけるには、“詳細情報”に移動してください。また、複数のクライアントに同じ名前を使用することができます。",
       "subSortIndex": "サブ並び順",
-      "same": "同じ",
       "inboundInfo": "インバウンド情報",
       "exportInbound": "インバウンドルールをエクスポート",
       "import": "インポート",
       "importInbound": "インバウンドルールをインポート",
       "periodicTrafficResetTitle": "トラフィックリセット",
-      "periodicTrafficResetDesc": "指定された間隔でトラフィックカウンタを自動的にリセット",
       "periodicTrafficResetDay": "毎月のリセット日",
-      "lastReset": "最後のリセット",
       "periodicTrafficReset": {
         "never": "なし",
         "daily": "毎日",
@@ -464,7 +401,6 @@
         "obtain": "取得",
         "updateSuccess": "更新が成功しました",
         "logCleanSuccess": "ログがクリアされました",
-        "inboundsUpdateSuccess": "インバウンドが正常に更新されました",
         "inboundUpdateSuccess": "インバウンドが正常に更新されました",
         "inboundCreateSuccess": "インバウンドが正常に作成されました",
         "bulkDeleted": "{count} 件のインバウンドを削除しました",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "インバウンドクライアントが削除されました",
         "inboundClientUpdateSuccess": "インバウンドクライアントが更新されました",
         "savedNodeOfflineWillSync": "ローカルに保存しました。バックエンドのノードがオフラインまたは無効になっています — 再接続後に変更が同期されます。",
-        "delDepletedClientsSuccess": "すべての枯渇したクライアントが削除されました",
         "resetAllClientTrafficSuccess": "クライアントのすべてのトラフィックがリセットされました",
         "resetAllTrafficSuccess": "すべてのトラフィックがリセットされました",
         "resetInboundClientTrafficSuccess": "トラフィックがリセットされました",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Peer {n} 設定"
       },
-      "stream": {
-        "general": {
-          "request": "リクエスト",
-          "response": "レスポンス",
-          "name": "名前",
-          "value": "値"
-        },
-        "tcp": {
-          "version": "バージョン",
-          "method": "方法",
-          "path": "パス",
-          "status": "ステータス",
-          "statusDescription": "ステータス説明",
-          "requestHeader": "リクエストヘッダー",
-          "responseHeader": "レスポンスヘッダー"
-        }
-      },
       "sniffingDestOverride": "宛先のオーバーライド"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "外部サブスクリプションを追加",
       "noExternalLinks": "外部リンクはまだありません。",
       "noExternalSubscriptions": "外部サブスクリプションはまだありません。",
-      "add": "クライアントを追加",
-      "edit": "クライアントを編集",
-      "submitAdd": "クライアントを追加",
       "submitEdit": "変更を保存",
       "clientCount": "クライアント数",
       "bulk": "一括追加",
-      "copyFromInbound": "インバウンドからクライアントをコピー",
-      "copyToInbound": "コピー先",
-      "copySelected": "選択をコピー",
-      "copySource": "コピー元",
-      "copyEmailPreview": "生成されるメールのプレビュー",
-      "copySelectSourceFirst": "まずコピー元のインバウンドを選択してください。",
-      "copyResult": "コピー結果",
-      "copyResultSuccess": "コピーに成功しました",
-      "copyResultNone": "コピーする対象がありません。クライアントが選択されていないか、コピー元が空です",
-      "copyResultErrors": "コピーエラー",
-      "copyFlowLabel": "新規クライアントの Flow (VLESS)",
-      "copyFlowHint": "コピーされる全クライアントに適用されます。空欄でスキップします。",
       "selectAll": "すべて選択",
       "clearAll": "すべてクリア",
       "method": "メソッド",
@@ -775,7 +678,6 @@
       "postfix": "サフィックス",
       "delayedStart": "初回使用から開始",
       "expireDays": "期間 (日)",
-      "days": "日",
       "renew": "自動更新",
       "renewDesc": "有効期限切れ後に自動更新します。(0 = 無効) (単位: 日)",
       "renewDays": "自動更新 (日)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "もうすぐ期限切れ",
       "has": "あり",
       "hasNot": "なし",
-      "title": "クライアント",
       "actions": "操作",
       "totalGB": "トラフィック上限 (GB)",
       "totalGBDesc": "このクライアントのデータ割当量。0 = 無制限。",
@@ -826,8 +727,6 @@
       "addClient": "クライアントを追加",
       "qrCode": "QR コード",
       "clientInfo": "クライアント情報",
-      "delete": "削除",
-      "reset": "トラフィックをリセット",
       "editClient": "クライアントを編集",
       "client": "クライアント",
       "enabled": "有効",
@@ -841,13 +740,11 @@
       "noLinks": "共有可能なリンクがありません — まずこのクライアントを対応するプロトコルのインバウンドに関連付けてください。",
       "link": "リンク",
       "resetNotPossible": "まずこのクライアントをインバウンドに関連付けてください。",
-      "general": "一般",
       "resetAllTraffics": "すべてのクライアントのトラフィックをリセット",
       "resetAllTrafficsTitle": "すべてのクライアントのトラフィックをリセットしますか?",
       "resetAllTrafficsContent": "すべてのクライアントの送受信カウンターがゼロにリセットされます。クォータと有効期限には影響しません。元に戻せません。",
       "deleteConfirmTitle": "クライアント {email} を削除しますか?",
       "deleteConfirmContent": "クライアントを関連付けされたすべてのインバウンドから削除し、トラフィック記録も破棄します。元に戻せません。",
-      "deleteSelected": "削除 ({count})",
       "adjustSelected": "調整 ({count})",
       "subLinksSelected": "サブリンク ({count})",
       "addToGroupTitle": "{count} クライアントをグループに追加",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "{count} 件のクライアントを無効化しますか?",
       "bulkDisableConfirmContent": "選択した各クライアントを、接続されているすべてのインバウンドで無効化します。アクセスはすぐに失われますが、記録とトラフィックは保持されます。",
       "selectedCount": "{count} 選択中",
-      "attachSelected": "アタッチ ({count})",
       "attachToInboundsTitle": "{count} クライアントをインバウンドにアタッチ",
       "attachToInboundsDesc": "選択した {count} クライアント(同じ UUID/パスワードと共有トラフィック)を選択したインバウンドにアタッチします。既存のアタッチは維持されます。",
       "attachToInboundsTargets": "ターゲットインバウンド",
       "attachToInboundsNoTargets": "アタッチ可能なマルチユーザーインバウンドがありません。",
-      "detachSelected": "デタッチ ({count})",
       "detach": "デタッチ",
       "detachFromInboundsTitle": "{count} クライアントをインバウンドからデタッチ",
       "detachFromInboundsDesc": "選択した {count} クライアントを選択したインバウンドから外します。アタッチされていなかったペアは黙ってスキップされます。クライアントレコードは保持されます (完全に削除するには Delete を使用)。",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "任意の Reverse tag",
       "telegramId": "Telegram ユーザー ID",
       "telegramIdPlaceholder": "数値の Telegram ユーザー ID (0 = なし)",
-      "created": "作成日",
-      "updated": "更新日",
       "ipLimit": "IP 制限",
       "toasts": {
         "deleted": "クライアントを削除しました",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "グループ",
       "name": "名前",
       "clientCount": "クライアント",
       "totalGroups": "グループ合計",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "{count} クライアントを {name} から外しました。"
     },
     "nodes": {
-      "title": "ノード",
       "addNode": "ノードを追加",
       "editNode": "ノード編集",
       "totalNodes": "ノード総数",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "リモートパネルの設定ページから取得したトークン",
       "apiTokenHint": "リモートパネルでは、セキュリティ設定 → APIトークン でAPIトークンを確認できます。",
       "apiTokenKeepHint": "現在のトークンを保持するには空欄のままにします",
-      "regenerate": "トークンを再生成",
-      "regenerateConfirm": "再生成すると現在のトークンは無効になります。これを使用しているすべての中央パネルは更新されるまでアクセスできなくなります。続行しますか?",
       "allowPrivateAddress": "プライベートアドレスを許可",
       "allowPrivateAddressHint": "プライベートネットワークまたはVPN上のノードにのみ有効にします。",
       "outboundTag": "接続アウトバウンド",
@@ -1046,7 +935,6 @@
       "updatePanel": "パネルを更新",
       "updateSelected": "選択を更新 ({count})",
       "updateAvailable": "更新あり",
-      "upToDate": "最新",
       "updateConfirmTitle": "{count} 個のノードを最新バージョンに更新しますか?",
       "updateConfirmContent": "選択した各ノードは最新リリースをダウンロードして再起動します。有効かつオンラインのノードのみが更新されます。",
       "updateDevChannel": "開発チャンネルに更新(最新コミット)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "証明書を取得できませんでした"
     },
     "settings": {
+      "defaultTag": "デフォルト",
       "title": "パネル設定",
       "save": "保存",
       "infoDesc": "ここでのすべての変更は、保存してパネルを再起動する必要があります",
@@ -1447,7 +1336,6 @@
       "secretClearUndo": "クリアを取り消す"
     },
     "xray": {
-      "title": "Xray 設定",
       "importRules": "ルールをインポート",
       "exportRules": "ルールをエクスポート",
       "importOutbounds": "アウトバウンドをインポート",
@@ -1457,11 +1345,7 @@
       "metricsListenDesc": "この アドレス:ポート で Xray の Prometheus 形式メトリクスを公開します(例: 127.0.0.1:11111)。空欄にすると無効になります。認証されないため、localhost にバインドしてリバースプロキシ経由で公開してください。",
       "metricsTag": "メトリクスタグ",
       "save": "保存",
-      "restart": "Xray を再起動",
       "restartSuccess": "Xrayの再起動に成功しました",
-      "restartOutputTitle": "Xray 再起動の出力",
-      "restartConfirmTitle": "xray を再起動?",
-      "restartConfirmContent": "保存された構成で xray サービスを再ロードします。",
       "stopSuccess": "Xrayが正常に停止しました",
       "restartError": "Xrayの再起動中にエラーが発生しました。",
       "stopError": "Xrayの停止中にエラーが発生しました。",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "これらのオプションは一般設定を決定します",
       "logConfigs": "ログ",
       "logConfigsDesc": "ログはサーバーのパフォーマンスに影響を与える可能性があるため、必要な場合にのみ有効にすることをお勧めします",
-      "blockConfigsDesc": "これらのオプションは、特定のプロトコルやウェブサイトへのユーザー接続をブロックします",
       "basicRouting": "基本ルーティング",
       "blockConnectionsConfigsDesc": "これらのオプションにより、特定のリクエスト元の国に基づいてトラフィックをブロックします。",
       "directConnectionsConfigsDesc": "直接接続により、特定のトラフィックが他のサーバーを経由しないようにします。",
@@ -1481,10 +1364,6 @@
       "directdomains": "直接ドメイン",
       "ipv4Routing": "IPv4 ルーティング",
       "ipv4RoutingDesc": "このオプションはIPv4のみを介してターゲットドメインへルーティングします",
-      "warpRouting": "WARP ルーティング",
-      "warpRoutingDesc": "注意:これらのオプションを使用する前に、パネルのGitHubの手順に従って、サーバーにsocks5プロキシモードでWARPをインストールしてください。WARPはCloudflareサーバー経由でトラフィックをウェブサイトにルーティングします。",
-      "nordRouting": "NordVPN ルーティング",
-      "nordRoutingDesc": "これらのオプションはNordVPN経由で特定の宛先にトラフィックをルーティングします。",
       "Template": "高度なXray設定テンプレート",
       "TemplateDesc": "最終的なXray設定ファイルはこのテンプレートに基づいて生成されます",
       "FreedomStrategy": "Freedom プロトコル戦略",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "アウトバウンド接続テストに使用する URL。既定値",
       "Torrent": "BitTorrent プロトコルをブロック",
       "Inbounds": "インバウンド",
-      "InboundsDesc": "特定のクライアントからのトラフィックを受け入れる",
       "Outbounds": "アウトバウンド",
-      "OutboundSubscriptions": "アウトバウンドサブスクリプション",
-      "OutboundSubscriptionsDesc": "リモートのサブスクリプションURL(vmess/vless/trojan/ss/...)からアウトバウンドをインポートします。タグはバランサーやルーティングルールで使えるように安定して保持されます。更新は自動的に行われます。",
       "Balancers": "負荷分散",
       "balancerTagRequired": "タグは必須です",
       "balancerSelectorRequired": "アウトバウンドを少なくとも1つ選んでください",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "マッチしたアウトバウンド",
       "routeTesterViaBalancer": "バランサー経由",
       "routeTesterDefaultOutbound": "ルーティングルールに一致しませんでした — トラフィックはデフォルト(最初の)アウトバウンドに送られます。",
-      "OutboundsDesc": "アウトバウンドトラフィックの送信方法を設定する",
       "Routings": "ルーティングルール",
-      "RoutingsDesc": "各ルールの優先順位が重要です",
       "completeTemplate": "すべて",
       "logLevel": "ログレベル",
       "logLevelDesc": "エラーログのレベルを指定し、記録する情報を示します",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "IPアドレスをマスクし、有効にするとログに表示されるIPアドレスを自動的に置き換えます",
       "statistics": "統計",
       "statsInboundUplink": "インバウンドアップロード統計",
-      "statsInboundUplinkDesc": "すべてのインバウンドプロキシのアップストリームトラフィックの統計収集を有効にします。",
       "statsInboundDownlink": "インバウンドダウンロード統計",
-      "statsInboundDownlinkDesc": "すべてのインバウンドプロキシのダウンストリームトラフィックの統計収集を有効にします。",
       "statsOutboundUplink": "アウトバウンドアップロード統計",
-      "statsOutboundUplinkDesc": "すべてのアウトバウンドプロキシのアップストリームトラフィックの統計収集を有効にします。",
       "statsOutboundDownlink": "アウトバウンドダウンロード統計",
-      "statsOutboundDownlinkDesc": "すべてのアウトバウンドプロキシのダウンストリームトラフィックの統計収集を有効にします。",
       "connectionLimits": "接続制限",
       "connectionLimitsDesc": "ユーザーレベル0の接続レベルのポリシーです。フィールドを空のままにすると Xray のデフォルト値が使用されます。",
       "connIdle": "アイドルタイムアウト",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "自動",
       "seconds": "秒",
       "rules": {
-        "first": "最初",
-        "last": "最後",
-        "up": "上へ",
-        "down": "下へ",
         "source": "ソース",
         "dest": "宛先アドレス",
         "inbound": "インバウンド",
-        "outbound": "アウトバウンド",
         "balancer": "負荷分散",
-        "info": "情報",
-        "add": "ルール追加",
-        "edit": "ルール編集",
         "useComma": "カンマ区切りの項目"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "ルール {n}",
         "action": "アクション",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "最終ルール",
         "overrideXrayPrivateIp": "Xray のデフォルトプライベート IP ブロックを上書き",
         "blockDelay": "ブロック遅延 (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "keep alive 間隔",
         "markFwmark": "Mark (fwmark)",
         "interface": "インターフェース",
-        "ipv6Only": "IPv6 のみ",
-        "acceptProxyProtocol": "proxy protocol を受け入れる",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (秒)"
       },
       "outbound": {
-        "addOutbound": "アウトバウンド追加",
-        "addReverse": "リバース追加",
-        "editOutbound": "アウトバウンド編集",
-        "editReverse": "リバース編集",
-        "reverseTag": "リバースタグ",
-        "reverseTagDesc": "VLESSシンプルリバースプロキシのアウトバウンドタグ。無効にするには空欄にしてください。",
-        "reverseTagPlaceholder": "アウトバウンドタグ(空欄で無効)",
         "tag": "タグ",
-        "tagDesc": "一意のタグ",
-        "address": "アドレス",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "リバース",
-        "domain": "ドメイン",
-        "type": "タイプ",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "リンク",
-        "intercon": "インターコネクション",
-        "settings": "設定",
-        "accountInfo": "アカウント情報",
         "outboundStatus": "アウトバウンドステータス",
         "sendThrough": "送信経路",
         "targetStrategy": "ターゲット解決戦略",
-        "test": "テスト",
-        "testResult": "テスト結果",
-        "testing": "接続をテスト中...",
-        "testSuccess": "テスト成功",
-        "testFailed": "テスト失敗",
-        "testError": "アウトバウンドのテストに失敗しました",
         "modeRealDelay": "実際の遅延",
         "testModeTooltip": "TCP: 高速 dial-only プローブ。HTTP: xray を経由した完全リクエスト。実際の遅延: 接続確立を含む合計時間。",
         "testAll": "すべてテスト",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "プロキシ接続",
         "breakdownTls": "アウトバウンド経由のTLS",
         "breakdownTtfb": "最初のバイト",
-        "nordvpn": "NordVPN",
-        "accessToken": "アクセストークン",
         "country": "国",
         "server": "サーバー",
         "city": "都市",
         "allCities": "すべての都市",
-        "privateKey": "秘密鍵",
-        "load": "負荷",
         "moveToTop": "先頭に移動"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "有効なサブスクリプション",
         "empty": "サブスクリプションはまだありません。上から追加してください。",
         "colRemark": "備考",
-        "colPrefix": "プレフィックス",
-        "colInterval": "間隔",
         "colLastFetch": "最終取得",
         "colEnabled": "有効",
         "auto": "自動",
         "never": "なし",
-        "yes": "はい",
-        "no": "いいえ",
         "refreshNow": "今すぐ更新",
-        "lastError": "最後のエラー",
         "deleteConfirm": "このサブスクリプションを削除しますか?",
         "restartHint": "追加または更新した後、アウトバウンドを有効にするにはXrayを再起動してください(または次の自動リロードをお待ちください)。",
         "fromSubsTitle": "アウトバウンドサブスクリプションから(読み取り専用)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "バランサー設定",
       "tabObservatory": "オブザーバトリ",
       "observatory": {
-        "title": "オブザーバトリ",
-        "burstTitle": "バースト オブザーバトリ",
         "autoManaged": "オブザーバはバランサーから自動的に管理されます。プローブの方法は下で調整できます。監視対象のアウトバウンドはバランサーのセレクターに従います。",
         "emptyHint": "有効な接続オブザーバはありません。Least Ping または Least Load のバランサー、あるいは fallback 付きの Random / Round-robin バランサーを作成すると自動的に追加され、オブザーバを使うバランサーがターゲットを選ぶ前にアウトバウンドの健全性を確認できるようになります。",
         "mixedLegacy": "この設定には Observatory と Burst Observatory の両方が含まれています。Xray は単一のグローバルオブザーバを使用するため、この古い混在状態はサポートされません。バランサーを保存すると 1 つのオブザーバに正規化されます。",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "バランサー {tag} — 削除(対象が残っていません)"
       },
       "balancer": {
-        "addBalancer": "負荷分散追加",
-        "editBalancer": "負荷分散編集",
         "balancerStrategy": "戦略",
-        "balancerSelectors": "セレクター",
         "tag": "タグ",
-        "tagDesc": "一意のタグ",
         "tagDuplicate": "このタグは他のバランサーで使用されています",
         "tagPlaceholder": "一意のバランサータグ",
         "selector": "セレクター",
@@ -1789,7 +1609,6 @@
         "tolerance": "許容範囲",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "balancerTagとoutboundTagは同時に使用できません。同時に使用された場合、outboundTagのみが有効になります。",
         "costMatch": "タグパターン",
         "costValue": "重み",
         "costRegexp": "正規表現で一致",
@@ -1804,14 +1623,10 @@
         "publicKey": "公開鍵",
         "allowedIPs": "許可されたIP",
         "endpoint": "エンドポイント",
-        "psk": "共有キー",
         "domainStrategy": "ドメイン戦略"
       },
       "tun": {
-        "nameDesc": "TUN インターフェースの名前。デフォルトは 'xray0' です",
-        "mtuDesc": "最大伝送単位。データパケットの最大サイズ。デフォルトは 1500 です",
-        "userLevel": "ユーザーレベル",
-        "userLevelDesc": "このインバウンドを通じて確立されたすべての接続は、このユーザーレベルを使用します。デフォルトは 0 です"
+        "userLevel": "ユーザーレベル"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "フェイクDNS追加",
-        "edit": "フェイクDNS編集",
         "ipPool": "IPプールサブネット",
         "poolSize": "プールサイズ"
       },
@@ -2032,7 +1846,6 @@
     "add": "追加",
     "month": "月",
     "months": "ヶ月",
-    "day": "日",
     "days": "日間",
     "hours": "時間",
     "minutes": "分",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Telegramユーザーが保存されました。",
       "loginSuccess": "✅ パネルに正常にログインしました。\r\n",
       "loginFailed": "❗️ パネルのログインに失敗しました。\r\n",
-      "2faFailed": "2FAエラー",
       "report": "🕰 定期報告:{{ .RunTime }}\r\n",
       "datetime": "⏰ 日時:{{ .DateTime }}\r\n",
       "hostname": "💻 ホスト: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 ダウンロード: ↓{{ .Download }}\r\n",
       "total": "📊 合計: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Telegramユーザー:{{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 消耗済みの {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 消耗済みの {{ .Type }} 数量:\r\n",
       "onlinesCount": "🌐 オンラインクライアント:{{ .Count }}\r\n",
       "disabled": "🛑 無効化:{{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 更新時間:{{ .Time }}\r\n\r\n",
       "yes": "✅ はい",
       "no": "❌ いいえ",
-      "received_id": "🔑📥 IDが更新されました。",
-      "received_password": "🔑📥 パスワードが更新されました。",
       "received_email": "📧📥 メールが更新されました。",
       "received_comment": "💬📥 コメントが更新されました。",
-      "id_prompt": "🔑 デフォルトID: {{ .ClientId }}\n\nIDを入力してください。",
-      "pass_prompt": "🔑 デフォルトパスワード: {{ .ClientPassword }}\n\nパスワードを入力してください。",
       "email_prompt": "📧 デフォルトメール: {{ .ClientEmail }}\n\nメールを入力してください。",
       "comment_prompt": "💬 デフォルトコメント: {{ .ClientComment }}\n\nコメントを入力してください。",
-      "inbound_client_data_id": "🔄 インバウンド: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 有効期限: {{ .ClientExp }}\n🌐 IP制限: {{ .IpLimit }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐこのクライアントをインバウンドに追加できます!",
-      "inbound_client_data_pass": "🔄 インバウンド: {{ .InboundRemark }}\n\n🔑 パスワード: {{ .ClientPass }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 有効期限: {{ .ClientExp }}\n🌐 IP制限: {{ .IpLimit }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐこのクライアントをインバウンドに追加できます!",
       "cancel": "❌ プロセスがキャンセルされました!\n\nいつでも /start で再開できます。 🔄",
       "error_add_client": "⚠️ エラー:\n\n {{ .error }}",
       "using_default_value": "わかりました、デフォルト値を使用します。 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "エラー: {{ .Error }}",
       "eventNodeDown": "ノード {{ .Name }} がダウンしています",
       "eventNodeUp": "ノード {{ .Name }} が復旧しました",
-      "eventCPUHigh": "CPU高負荷",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "{{ .Source }} からのログインに失敗しました",
       "memoryThreshold": "メモリ使用率 {{ .Percent }}% がしきい値 {{ .Threshold }}% を超えました"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "無効として送信 ☑️",
       "submitEnable": "有効として送信 ✅",
       "use_default": "🏷️ デフォルトを使用",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 パスワード",
       "change_email": "⚙️📧 メール",
       "change_comment": "⚙️💬 コメント",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "すべてのトラフィックをリセット",
       "SortedTrafficUsageReport": "ソートされたトラフィック使用レポート"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "アウトバウンド {{ .Tag }} がダウンしています",
-    "subjectOutboundUp": "アウトバウンド {{ .Tag }} が復旧しました",
-    "subjectXrayCrash": "Xrayがクラッシュしました",
-    "subjectCPUHigh": "CPU高負荷",
-    "subjectLoginSuccess": "ログイン成功",
-    "subjectLoginFailed": "ログイン失敗",
-    "titleOutboundDown": "アウトバウンド ダウン",
-    "titleOutboundUp": "アウトバウンド 復旧",
-    "titleXrayCrash": "Xrayがクラッシュしました",
-    "titleCPUHigh": "CPU高負荷",
-    "titleLoginSuccess": "ログイン成功",
-    "titleLoginFailed": "ログイン失敗",
     "labelStatus": "ステータス",
     "labelOutbound": "アウトバウンド",
     "labelNode": "ノード",
     "labelError": "エラー",
     "labelDelay": "遅延",
-    "labelDetail": "詳細",
     "labelUsername": "ユーザー名",
     "labelIP": "IP",
     "labelReason": "理由",
     "labelSource": "送信元",
-    "labelTime": "時刻",
     "statusCrashed": "クラッシュ",
-    "statusRunning": "実行中",
     "statusHigh": "高負荷",
     "statusSuccess": "成功",
     "statusFailed": "失敗",

+ 3 - 218
internal/web/translation/pt-BR.json

@@ -48,7 +48,6 @@
   "copySuccess": "Copiado com Sucesso",
   "sure": "Certo",
   "encryption": "Criptografia",
-  "useIPv4ForHost": "Usar IPv4 para o host",
   "transmission": "Transmissão",
   "host": "Host",
   "path": "Caminho",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Código",
   "remained": "Restante",
   "security": "Segurança",
-  "secAlertTitle": "Alerta de Segurança",
-  "secAlertSsl": "Esta conexão não é segura. Evite inserir informações confidenciais até que o TLS seja ativado para proteção de dados.",
-  "secAlertConf": "Algumas configurações estão vulneráveis a ataques. Recomenda-se reforçar os protocolos de segurança para evitar possíveis violações.",
-  "secAlertSSL": "O painel não possui uma conexão segura. Instale o certificado TLS para proteção de dados.",
-  "secAlertPanelPort": "A porta padrão do painel é vulnerável. Configure uma porta aleatória ou específica.",
-  "secAlertPanelURI": "O caminho URI padrão do painel não é seguro. Configure um caminho URI complexo.",
-  "secAlertSubURI": "O caminho URI padrão de inscrição não é seguro. Configure um caminho URI complexo.",
-  "secAlertSubJsonURI": "O caminho URI JSON de inscrição padrão não é seguro. Configure um caminho URI complexo.",
   "emptyDnsDesc": "Nenhum servidor DNS adicionado.",
   "emptyFakeDnsDesc": "Nenhum servidor Fake DNS adicionado.",
   "emptyBalancersDesc": "Nenhum balanceador adicionado.",
-  "emptyReverseDesc": "Nenhum proxy reverso adicionado.",
   "somethingWentWrong": "Algo deu errado",
   "subscription": {
     "title": "Informações da assinatura",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Tema",
-    "dark": "Escuro",
-    "ultraDark": "Ultra Escuro",
     "dashboard": "Visão Geral",
     "inbounds": "Entradas",
     "clients": "Clientes",
@@ -118,7 +106,6 @@
     "routing": "Roteamento",
     "outbounds": "Saídas",
     "apiDocs": "Documentação da API",
-    "logout": "Sair",
     "link": "Gerenciar",
     "donate": "Doar",
     "hosts": "Hosts",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Visão Geral",
       "cpu": "CPU",
       "logicalProcessors": "Processadores lógicos",
       "frequency": "Frequência",
@@ -152,7 +138,6 @@
       "restartXray": "Reiniciar",
       "xraySwitch": "Versão",
       "xrayUpdates": "Atualizações do Xray",
-      "xraySwitchClick": "Escolha a versão para a qual deseja alternar.",
       "xraySwitchClickDesk": "Escolha com cuidado, pois versões mais antigas podem não ser compatíveis com as configurações atuais.",
       "updatePanel": "Atualizar painel",
       "panelUpdateDesc": "Isso atualizará o 3X-UI para a versão mais recente e reiniciará o serviço do painel.",
@@ -164,12 +149,10 @@
       "currentCommit": "Commit atual",
       "latestCommit": "Último commit",
       "updateChannelChanged": "Canal de atualização alterado",
-      "upToDate": "Atualizado",
       "xrayStatusUnknown": "Desconhecido",
       "xrayStatusRunning": "Em execução",
       "xrayStatusStop": "Parado",
       "xrayStatusError": "Erro",
-      "xrayErrorPopoverTitle": "Ocorreu um erro ao executar o Xray",
       "operationHours": "Tempo de Atividade",
       "systemHistoryTitle": "Histórico do Sistema",
       "historyTitleCpu": "Uso da CPU",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Inativo",
       "xrayObservatoryLastSeen": "Visto pela última vez",
       "xrayObservatoryLastTry": "Última tentativa",
-      "trendLast2Min": "Últimos 2 minutos",
-      "systemLoad": "Carga do Sistema",
-      "systemLoadDesc": "Média de carga do sistema nos últimos 1, 5 e 15 minutos",
       "connectionCount": "Estatísticas de Conexão",
       "ipAddresses": "Endereços IP",
       "toggleIpVisibility": "Alternar visibilidade do IP",
@@ -223,13 +203,11 @@
       "totalData": "Dados totais",
       "sent": "Enviado",
       "received": "Recebido",
-      "documentation": "Documentação",
       "xraySwitchVersionDialog": "Você realmente deseja alterar a versão do Xray?",
       "xraySwitchVersionDialogDesc": "Isso mudará a versão do Xray para #version#.",
       "xraySwitchVersionPopover": "Xray atualizado com sucesso",
       "panelUpdateDialog": "Deseja realmente atualizar o painel?",
       "panelUpdateDialogDesc": "Isso atualizará o 3X-UI para #version# e reiniciará o serviço do painel.",
-      "panelUpdateCheckPopover": "Falha na verificação de atualização do painel",
       "panelUpdateStartedPopover": "Atualização do painel iniciada",
       "panelUpdateFailedTitle": "Falha ao atualizar o painel",
       "panelUpdateFailedDesc": "A atualização não foi concluída com sucesso. Verifique os logs do servidor ou execute 'x-ui update' na linha de comando.",
@@ -258,7 +236,6 @@
       "accessLogs": "Logs de acesso",
       "autoUpdate": "Atualização automática",
       "config": "Configuração",
-      "backup": "Backup",
       "backupTitle": "Backup & Restauração",
       "exportDatabase": "Backup",
       "exportDatabaseDesc": "Clique para baixar um arquivo .db contendo um backup do seu banco de dados atual para o seu dispositivo. O mesmo arquivo também pode ser restaurado em um painel executando PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Clique para baixar um banco de dados SQLite .db criado a partir dos seus dados do PostgreSQL, pronto para executar este painel no SQLite."
     },
     "inbounds": {
-      "title": "Entradas",
       "totalDownUp": "Total Enviado/Recebido",
       "totalUsage": "Uso Total",
       "inboundCount": "Total de Inbounds",
@@ -288,21 +264,11 @@
       "localPanel": "Painel local",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "Quando uma conexão neste inbound não corresponde a nenhum cliente, redirecione-a para outro lugar. Escolha um inbound filho abaixo para preencher automaticamente os campos de roteamento (SNI / ALPN / Path / xver) a partir do transporte dele, ou deixe o seletor vazio e defina Dest diretamente (ex.: 8080 ou 127.0.0.1:8080) para rotear para um servidor externo como o Nginx. Cada inbound filho deve escutar em 127.0.0.1 com security=none.",
         "empty": "Ainda sem fallbacks",
         "add": "Adicionar fallback",
         "pickInbound": "Escolha um inbound",
         "matchAny": "qualquer",
         "destPlaceholder": "automático (listen:porta do filho)",
-        "rederive": "Preencher a partir do filho",
-        "rederived": "Preenchido a partir do filho",
-        "editAdvanced": "Editar campos de roteamento",
-        "hideAdvanced": "Ocultar avançado",
-        "quickAddAll": "Adicionar todos os elegíveis",
-        "quickAdded": "{n} fallback(s) adicionado(s)",
-        "quickAddedNone": "Nenhum inbound novo elegível para adicionar",
-        "routesWhen": "Roteia quando",
-        "defaultCatchAll": "Padrão — captura qualquer outra coisa",
         "needsTls": "Os fallbacks ficam disponíveis após selecionar TLS ou Reality na aba Segurança (apenas VLESS/Trojan sobre RAW)."
       },
       "protocol": "Protocolo",
@@ -310,8 +276,6 @@
       "portMap": "Mapeamento de portas",
       "traffic": "Tráfego",
       "speed": "Velocidade",
-      "details": "Detalhes",
-      "transportConfig": "Transporte",
       "expireDate": "Duração",
       "createdAt": "Criado",
       "updatedAt": "Atualizado",
@@ -319,8 +283,6 @@
       "addInbound": "Adicionar Inbound",
       "generalActions": "Ações Gerais",
       "modifyInbound": "Modificar Inbound",
-      "deleteInbound": "Excluir Inbound",
-      "deleteInboundContent": "Tem certeza de que deseja excluir o inbound?",
       "deleteConfirmTitle": "Excluir o inbound \"{remark}\"?",
       "deleteConfirmContent": "Isto remove o inbound e todos os seus clientes. Não é possível desfazer.",
       "resetConfirmTitle": "Redefinir o tráfego de \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Todas-as-entradas",
       "exportAllSubsFileName": "Todas-as-entradas-Subs",
       "inboundJsonTitle": "JSON da entrada",
-      "deleteClient": "Excluir Cliente",
-      "deleteClientContent": "Tem certeza de que deseja excluir o cliente?",
       "resetTrafficContent": "Tem certeza de que deseja redefinir o tráfego?",
       "copyLink": "Copiar URL",
       "address": "Endereço",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Ilimitado. (unidade: GB)",
       "totalFlow": "Fluxo Total",
       "leaveBlankToNeverExpire": "Deixe em branco para nunca expirar",
-      "noRecommendKeepDefault": "Recomenda-se manter o padrão",
       "certificatePath": "Caminho",
       "certificateContent": "Conteúdo",
       "publicKey": "Chave Pública",
       "privatekey": "Chave Privada",
-      "clickOnQRcode": "Clique no Código QR para Copiar",
       "client": "Cliente",
       "export": "Exportar Todos os URLs",
       "clone": "Clonar",
-      "cloneInbound": "Clonar",
-      "cloneInboundContent": "Todas as configurações deste inbound, exceto Porta, IP de Escuta e Clientes, serão aplicadas ao clone.",
-      "cloneInboundOk": "Clonar",
       "resetAllTraffic": "Redefinir Tráfego de Todos os Inbounds",
       "resetAllTrafficTitle": "Redefinir Tráfego de Todos os Inbounds",
       "resetAllTrafficContent": "Tem certeza de que deseja redefinir o tráfego de todos os inbounds?",
-      "resetInboundClientTraffics": "Redefinir Tráfego dos Clientes",
-      "resetInboundClientTrafficTitle": "Redefinir Tráfego dos Clientes",
-      "resetInboundClientTrafficContent": "Tem certeza de que deseja redefinir o tráfego dos clientes deste inbound?",
-      "resetAllClientTraffics": "Redefinir Tráfego de Todos os Clientes",
-      "resetAllClientTrafficTitle": "Redefinir Tráfego de Todos os Clientes",
-      "resetAllClientTrafficContent": "Tem certeza de que deseja redefinir o tráfego de todos os clientes?",
-      "delDepletedClients": "Excluir Clientes Esgotados",
-      "delDepletedClientsTitle": "Excluir Clientes Esgotados",
-      "delDepletedClientsContent": "Tem certeza de que deseja excluir todos os clientes esgotados?",
       "email": "Email",
-      "emailDesc": "Por favor, forneça um endereço de e-mail único.",
       "IPLimit": "Limite de IP",
-      "IPLimitDesc": "Desativa o inbound se o número ultrapassar o valor definido. (0 = desativar)",
       "IPLimitlog": "Log de IP",
-      "IPLimitlogDesc": "O histórico de IPs. (para ativar o inbound após a desativação, limpe o log)",
       "IPLimitlogclear": "Limpar o Log",
       "setDefaultCert": "Definir Certificado pelo Painel",
       "setDefaultCertEmpty": "Nenhum certificado configurado para o painel. Configure um em Configurações primeiro.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Wrapper do bloco sniffing do Xray:",
         "stream": "Stream",
-        "streamHelp": "Wrapper do bloco stream do Xray:",
-        "jsonErrorPrefix": "JSON avançado"
+        "streamHelp": "Wrapper do bloco stream do Xray:"
       },
-      "telegramDesc": "Por favor, forneça o ID do Chat do Telegram. (use o comando '/id' no bot) ou ({'@'}userinfobot)",
-      "subscriptionDesc": "Para encontrar seu URL de assinatura, navegue até 'Detalhes'. Além disso, você pode usar o mesmo nome para vários clientes.",
       "subSortIndex": "Ordem sub",
-      "same": "Igual",
       "inboundInfo": "Informações do Inbound",
       "exportInbound": "Exportar Inbound",
       "import": "Importar",
       "importInbound": "Importar um Inbound",
       "periodicTrafficResetTitle": "Reset de Tráfego",
-      "periodicTrafficResetDesc": "Reinicia automaticamente o contador de tráfego em intervalos especificados",
       "periodicTrafficResetDay": "Dia da redefinição mensal",
-      "lastReset": "Último Reset",
       "periodicTrafficReset": {
         "never": "Nunca",
         "daily": "Diariamente",
@@ -464,7 +401,6 @@
         "obtain": "Obter",
         "updateSuccess": "A atualização foi bem-sucedida",
         "logCleanSuccess": "O log foi limpo",
-        "inboundsUpdateSuccess": "Entradas atualizadas com sucesso",
         "inboundUpdateSuccess": "Entrada atualizada com sucesso",
         "inboundCreateSuccess": "Entrada criada com sucesso",
         "bulkDeleted": "{count} inbounds excluídos",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Cliente de entrada excluído",
         "inboundClientUpdateSuccess": "Cliente de entrada atualizado",
         "savedNodeOfflineWillSync": "Salvo localmente. Um nó de apoio está offline ou desativado — a alteração será sincronizada assim que reconectar.",
-        "delDepletedClientsSuccess": "Todos os clientes esgotados foram excluídos",
         "resetAllClientTrafficSuccess": "Todo o tráfego do cliente foi reiniciado",
         "resetAllTrafficSuccess": "Todo o tráfego foi reiniciado",
         "resetInboundClientTrafficSuccess": "O tráfego foi reiniciado",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Config Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Requisição",
-          "response": "Resposta",
-          "name": "Nome",
-          "value": "Valor"
-        },
-        "tcp": {
-          "version": "Versão",
-          "method": "Método",
-          "path": "Caminho",
-          "status": "Status",
-          "statusDescription": "Descrição do Status",
-          "requestHeader": "Cabeçalho da Requisição",
-          "responseHeader": "Cabeçalho da Resposta"
-        }
-      },
       "sniffingDestOverride": "Substituição de destino"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Adicionar assinatura externa",
       "noExternalLinks": "Ainda não há links externos.",
       "noExternalSubscriptions": "Ainda não há assinaturas externas.",
-      "add": "Adicionar cliente",
-      "edit": "Editar cliente",
-      "submitAdd": "Adicionar cliente",
       "submitEdit": "Salvar alterações",
       "clientCount": "Número de clientes",
       "bulk": "Adicionar em lote",
-      "copyFromInbound": "Copiar clientes do inbound",
-      "copyToInbound": "Copiar clientes para",
-      "copySelected": "Copiar selecionados",
-      "copySource": "Origem",
-      "copyEmailPreview": "Prévia do e-mail resultante",
-      "copySelectSourceFirst": "Selecione primeiro um inbound de origem.",
-      "copyResult": "Resultado da cópia",
-      "copyResultSuccess": "Copiado com sucesso",
-      "copyResultNone": "Nada a copiar: nenhum cliente selecionado ou a origem está vazia",
-      "copyResultErrors": "Erros de cópia",
-      "copyFlowLabel": "Flow para os novos clientes (VLESS)",
-      "copyFlowHint": "Aplicado a todos os clientes copiados. Deixe em branco para ignorar.",
       "selectAll": "Selecionar tudo",
       "clearAll": "Limpar tudo",
       "method": "Método",
@@ -775,7 +678,6 @@
       "postfix": "Sufixo",
       "delayedStart": "Iniciar após o primeiro uso",
       "expireDays": "Duração (dias)",
-      "days": "Dia(s)",
       "renew": "Renovação automática",
       "renewDesc": "Renovação automática após a expiração. (0 = desativar) (unidade: dia)",
       "renewDays": "Renovação automática (dias)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Expira em breve",
       "has": "Tem",
       "hasNot": "Não tem",
-      "title": "Clientes",
       "actions": "Ações",
       "totalGB": "Limite de tráfego (GB)",
       "totalGBDesc": "Cota de dados para este cliente. 0 = ilimitado.",
@@ -826,8 +727,6 @@
       "addClient": "Adicionar cliente",
       "qrCode": "Código QR",
       "clientInfo": "Informações do cliente",
-      "delete": "Excluir",
-      "reset": "Redefinir tráfego",
       "editClient": "Editar cliente",
       "client": "Cliente",
       "enabled": "Habilitado",
@@ -841,13 +740,11 @@
       "noLinks": "Sem links compartilháveis — associe primeiro este cliente a um inbound compatível com o protocolo.",
       "link": "Link",
       "resetNotPossible": "Associe primeiro este cliente a um inbound.",
-      "general": "Geral",
       "resetAllTraffics": "Redefinir o tráfego de todos os clientes",
       "resetAllTrafficsTitle": "Redefinir o tráfego de todos os clientes?",
       "resetAllTrafficsContent": "Os contadores de envio/recebimento de cada cliente vão a zero. Cota e expiração não são afetadas. Não é possível desfazer.",
       "deleteConfirmTitle": "Excluir o cliente {email}?",
       "deleteConfirmContent": "Isto remove o cliente de cada inbound associado e descarta o registro de tráfego. Não é possível desfazer.",
-      "deleteSelected": "Excluir ({count})",
       "adjustSelected": "Ajustar ({count})",
       "subLinksSelected": "Links sub ({count})",
       "addToGroupTitle": "Adicionar {count} cliente(s) a um grupo",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Desativar {count} clientes?",
       "bulkDisableConfirmContent": "Desativa cada cliente selecionado em todos os inbounds associados. Eles perdem o acesso imediatamente, mas seus registros e tráfego são mantidos.",
       "selectedCount": "{count} selecionado(s)",
-      "attachSelected": "Associar ({count})",
       "attachToInboundsTitle": "Associar {count} cliente(s) a entrada(s)",
       "attachToInboundsDesc": "Associa os {count} cliente(s) selecionados (mesmo UUID/senha e tráfego compartilhado) às entradas escolhidas. Mantêm suas associações existentes.",
       "attachToInboundsTargets": "Entradas de destino",
       "attachToInboundsNoTargets": "Não há entradas multiusuário disponíveis para associação.",
-      "detachSelected": "Desassociar ({count})",
       "detach": "Desassociar",
       "detachFromInboundsTitle": "Desassociar {count} cliente(s) de entrada(s)",
       "detachFromInboundsDesc": "Remove os {count} cliente(s) selecionados das entradas escolhidas. Pares onde o cliente não estava associado são ignorados silenciosamente. Os registros dos clientes são mantidos (use Delete para remover completamente).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag opcional",
       "telegramId": "ID de usuário do Telegram",
       "telegramIdPlaceholder": "ID numérico de usuário do Telegram (0 = nenhum)",
-      "created": "Criado",
-      "updated": "Atualizado",
       "ipLimit": "Limite de IP",
       "toasts": {
         "deleted": "Cliente excluído",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Grupos",
       "name": "Nome",
       "clientCount": "Clientes",
       "totalGroups": "Total de grupos",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "Removidos {count} cliente(s) de {name}."
     },
     "nodes": {
-      "title": "Nós",
       "addNode": "Adicionar nó",
       "editNode": "Editar nó",
       "totalNodes": "Total de nós",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Token da página de Configurações do painel remoto",
       "apiTokenHint": "O painel remoto exibe o token da API em Autenticação → Token da API.",
       "apiTokenKeepHint": "Deixe em branco para manter o token atual",
-      "regenerate": "Regenerar token",
-      "regenerateConfirm": "Regenerar invalida o token atual. Qualquer painel central que o utilize perderá acesso até ser atualizado. Continuar?",
       "allowPrivateAddress": "Permitir endereço privado",
       "allowPrivateAddressHint": "Ativar apenas para nós em uma rede privada ou VPN.",
       "outboundTag": "Outbound de conexão",
@@ -1046,7 +935,6 @@
       "updatePanel": "Atualizar painel",
       "updateSelected": "Atualizar selecionados ({count})",
       "updateAvailable": "Atualização disponível",
-      "upToDate": "Atualizado",
       "updateConfirmTitle": "Atualizar {count} nó(s) para a versão mais recente?",
       "updateConfirmContent": "Cada nó selecionado baixa a versão mais recente e reinicia nela. Apenas nós ativos e online são atualizados.",
       "updateDevChannel": "Atualizar para o canal de desenvolvimento (último commit)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Não foi possível obter o certificado"
     },
     "settings": {
+      "defaultTag": "Padrão",
       "title": "Configurações do Painel",
       "save": "Salvar",
       "infoDesc": "Toda alteração feita aqui precisa ser salva. Reinicie o painel para aplicar as alterações.",
@@ -1447,7 +1336,6 @@
       "secretClearUndo": "Desfazer limpeza"
     },
     "xray": {
-      "title": "Configurações Xray",
       "importRules": "Importar regras",
       "exportRules": "Exportar regras",
       "importOutbounds": "Importar saídas",
@@ -1457,11 +1345,7 @@
       "metricsListenDesc": "Expõe as métricas no estilo Prometheus do Xray neste endereço:porta (por exemplo, 127.0.0.1:11111). Deixe vazio para desativar. Vincule ao localhost e use um proxy reverso — ele não é autenticado.",
       "metricsTag": "Tag de métricas",
       "save": "Salvar",
-      "restart": "Reiniciar Xray",
       "restartSuccess": "Xray foi reiniciado com sucesso",
-      "restartOutputTitle": "Saída do reinício do Xray",
-      "restartConfirmTitle": "Reiniciar xray?",
-      "restartConfirmContent": "Recarrega o serviço xray com a configuração salva.",
       "stopSuccess": "Xray foi interrompido com sucesso",
       "restartError": "Ocorreu um erro ao reiniciar o Xray.",
       "stopError": "Ocorreu um erro ao parar o Xray.",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "Essas opções determinam ajustes gerais.",
       "logConfigs": "Log",
       "logConfigsDesc": "Os logs podem afetar a eficiência do servidor. É recomendável habilitá-los com sabedoria apenas se necessário.",
-      "blockConfigsDesc": "Essas opções bloqueiam tráfego com base em protocolos e sites específicos solicitados.",
       "basicRouting": "Roteamento Básico",
       "blockConnectionsConfigsDesc": "Essas opções bloquearão o tráfego com base no país solicitado.",
       "directConnectionsConfigsDesc": "Uma conexão direta garante que o tráfego específico não seja roteado por outro servidor.",
@@ -1481,10 +1364,6 @@
       "directdomains": "Domínios Diretos",
       "ipv4Routing": "Roteamento IPv4",
       "ipv4RoutingDesc": "Essas opções roteam o tráfego para um destino específico via IPv4.",
-      "warpRouting": "Roteamento WARP",
-      "warpRoutingDesc": "Essas opções roteam o tráfego para um destino específico via WARP.",
-      "nordRouting": "Roteamento NordVPN",
-      "nordRoutingDesc": "Essas opções roteiam o tráfego para um destino específico via NordVPN.",
       "Template": "Modelo de Configuração Avançada do Xray",
       "TemplateDesc": "O arquivo final de configuração do Xray será gerado com base neste modelo.",
       "FreedomStrategy": "Estratégia do Protocolo Freedom",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "URL usada ao testar conectividade do outbound",
       "Torrent": "Bloquear Protocolo BitTorrent",
       "Inbounds": "Entradas",
-      "InboundsDesc": "Aceitar clientes específicos.",
       "Outbounds": "Saídas",
-      "OutboundSubscriptions": "Assinaturas de Saída",
-      "OutboundSubscriptionsDesc": "Importe saídas a partir de URLs de assinatura remotas (vmess/vless/trojan/ss/...). As tags são mantidas estáveis para uso em balanceadores e regras de roteamento. As atualizações são automáticas.",
       "Balancers": "Balanceadores",
       "balancerTagRequired": "A tag é obrigatória",
       "balancerSelectorRequired": "Selecione pelo menos uma saída",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "Saída correspondente",
       "routeTesterViaBalancer": "via balanceador",
       "routeTesterDefaultOutbound": "Nenhuma regra de roteamento correspondeu — o tráfego vai para a saída padrão (primeira).",
-      "OutboundsDesc": "Definir o caminho de saída do tráfego.",
       "Routings": "Regras de Roteamento",
-      "RoutingsDesc": "A prioridade de cada regra é importante!",
       "completeTemplate": "Tudo",
       "logLevel": "Nível de Log",
       "logLevelDesc": "O nível de log para erros, indicando a informação que precisa ser registrada.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "Máscara de endereço IP, quando ativado, substitui automaticamente o endereço IP que aparece no log.",
       "statistics": "Estatísticas",
       "statsInboundUplink": "Estatísticas de Upload de Entrada",
-      "statsInboundUplinkDesc": "Habilita a coleta de estatísticas para o tráfego de upload de todos os proxies de entrada.",
       "statsInboundDownlink": "Estatísticas de Download de Entrada",
-      "statsInboundDownlinkDesc": "Habilita a coleta de estatísticas para o tráfego de download de todos os proxies de entrada.",
       "statsOutboundUplink": "Estatísticas de Upload de Saída",
-      "statsOutboundUplinkDesc": "Habilita a coleta de estatísticas para o tráfego de upload de todos os proxies de saída.",
       "statsOutboundDownlink": "Estatísticas de Download de Saída",
-      "statsOutboundDownlinkDesc": "Habilita a coleta de estatísticas para o tráfego de download de todos os proxies de saída.",
       "connectionLimits": "Limites de conexão",
       "connectionLimitsDesc": "Políticas em nível de conexão para o nível de usuário 0. Deixe um campo vazio para usar o padrão do Xray.",
       "connIdle": "Tempo limite de inatividade",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "automático",
       "seconds": "segundos",
       "rules": {
-        "first": "Primeiro",
-        "last": "Último",
-        "up": "Cima",
-        "down": "Baixo",
         "source": "Fonte",
         "dest": "Destino",
         "inbound": "Entrada",
-        "outbound": "Saída",
         "balancer": "Balanceador",
-        "info": "Info",
-        "add": "Adicionar Regra",
-        "edit": "Editar Regra",
         "useComma": "Itens separados por vírgula"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Regra {n}",
         "action": "Ação",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Regras finais",
         "overrideXrayPrivateIp": "Sobrescrever o bloqueio de IP privado padrão do Xray",
         "blockDelay": "Atraso do bloqueio (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Intervalo keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Interface",
-        "ipv6Only": "Apenas IPv6",
-        "acceptProxyProtocol": "Aceitar proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "Adicionar Saída",
-        "addReverse": "Adicionar Reverso",
-        "editOutbound": "Editar Saída",
-        "editReverse": "Editar Reverso",
-        "reverseTag": "Tag de Reverso",
-        "reverseTagDesc": "Tag de saída do proxy reverso simples VLESS. Deixe vazio para desabilitar.",
-        "reverseTagPlaceholder": "tag de saída (vazio para desabilitar)",
         "tag": "Tag",
-        "tagDesc": "Tag Única",
-        "address": "Endereço",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Reverso",
-        "domain": "Domínio",
-        "type": "Tipo",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Link",
-        "intercon": "Interconexão",
-        "settings": "Configurações",
-        "accountInfo": "Informações da Conta",
         "outboundStatus": "Status de Saída",
         "sendThrough": "Enviar Através de",
         "targetStrategy": "Estratégia de destino",
-        "test": "Testar",
-        "testResult": "Resultado do teste",
-        "testing": "Testando conexão...",
-        "testSuccess": "Teste bem-sucedido",
-        "testFailed": "Teste falhou",
-        "testError": "Falha ao testar saída",
         "modeRealDelay": "Latência real",
         "testModeTooltip": "TCP: sondagem rápida apenas de dial. HTTP: requisição completa pelo xray. Latência real: tempo total incluindo o estabelecimento da conexão.",
         "testAll": "Testar todos",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Conexão do proxy",
         "breakdownTls": "TLS via saída",
         "breakdownTtfb": "Primeiro byte",
-        "nordvpn": "NordVPN",
-        "accessToken": "Token de Acesso",
         "country": "País",
         "server": "Servidor",
         "city": "Cidade",
         "allCities": "Todas as Cidades",
-        "privateKey": "Chave Privada",
-        "load": "Carga",
         "moveToTop": "Mover para o topo"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Assinaturas ativas",
         "empty": "Nenhuma assinatura ainda. Adicione uma acima.",
         "colRemark": "Observação",
-        "colPrefix": "Prefixo",
-        "colInterval": "Intervalo",
         "colLastFetch": "Última busca",
         "colEnabled": "Ativado",
         "auto": "auto",
         "never": "nunca",
-        "yes": "Sim",
-        "no": "Não",
         "refreshNow": "Atualizar agora",
-        "lastError": "Último erro",
         "deleteConfirm": "Excluir esta assinatura?",
         "restartHint": "Após adicionar ou atualizar, reinicie o Xray (ou aguarde o próximo recarregamento automático) para ativar as saídas.",
         "fromSubsTitle": "De assinaturas de saída (somente leitura)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Configurações do balanceador",
       "tabObservatory": "Observatório",
       "observatory": {
-        "title": "Observatório",
-        "burstTitle": "Observatório Burst",
         "autoManaged": "Os observadores são gerenciados automaticamente a partir dos seus balanceadores. Ajuste abaixo como eles sondam; as saídas monitoradas seguem os seletores do balanceador.",
         "emptyHint": "Nenhum observador de conexão ativo. Um é adicionado automaticamente ao criar um balanceador Least Ping ou Least Load — ou um balanceador Random / Round-robin com fallback — para que balanceadores com observador possam verificar a saúde das saídas antes de escolher um destino.",
         "mixedLegacy": "Esta configuração contém Observatory e Burst Observatory ao mesmo tempo. O Xray usa um único observador global, então esse estado misto legado não é suportado; ao salvar os balanceadores ele será normalizado para um único observador.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Balanceador {tag} — removido (sem destinos restantes)"
       },
       "balancer": {
-        "addBalancer": "Adicionar Balanceador",
-        "editBalancer": "Editar Balanceador",
         "balancerStrategy": "Estratégia",
-        "balancerSelectors": "Seletores",
         "tag": "Tag",
-        "tagDesc": "Tag Única",
         "tagDuplicate": "Tag já usada por outro balanceador",
         "tagPlaceholder": "tag única do balanceador",
         "selector": "Seletor",
@@ -1789,7 +1609,6 @@
         "tolerance": "Tolerância",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "Não é possível usar balancerTag e outboundTag ao mesmo tempo. Se usados simultaneamente, apenas outboundTag funcionará.",
         "costMatch": "Padrão de tag",
         "costValue": "Peso",
         "costRegexp": "Correspondência por expressão regular",
@@ -1804,14 +1623,10 @@
         "publicKey": "Chave Pública",
         "allowedIPs": "IPs Permitidos",
         "endpoint": "Ponto Final",
-        "psk": "Chave Pré-Compartilhada",
         "domainStrategy": "Estratégia de Domínio"
       },
       "tun": {
-        "nameDesc": "O nome da interface TUN. O padrão é 'xray0'",
-        "mtuDesc": "Unidade Máxima de Transmissão. O tamanho máximo dos pacotes de dados. O padrão é 1500",
-        "userLevel": "Nível do Usuário",
-        "userLevelDesc": "Todas as conexões feitas através deste inbound usarão este nível de usuário. O padrão é 0"
+        "userLevel": "Nível do Usuário"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Adicionar Fake DNS",
-        "edit": "Editar Fake DNS",
         "ipPool": "Sub-rede do Pool de IP",
         "poolSize": "Tamanho do Pool"
       },
@@ -2032,7 +1846,6 @@
     "add": "Adicionar",
     "month": "Mês",
     "months": "Meses",
-    "day": "Dia",
     "days": "Dias",
     "hours": "Horas",
     "minutes": "Minutos",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Usuário do Telegram salvo.",
       "loginSuccess": "✅ Conectado ao painel com sucesso.\r\n",
       "loginFailed": "❗️Tentativa de login no painel falhou.\r\n",
-      "2faFailed": "Falha no 2FA",
       "report": "🕰 Relatórios agendados: {{ .RunTime }}\r\n",
       "datetime": "⏰ Data&Hora: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Download: ↓{{ .Download }}\r\n",
       "total": "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Usuário do Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 {{ .Type }} esgotado:\r\n",
       "exhaustedCount": "🚨 Contagem de {{ .Type }} esgotado:\r\n",
       "onlinesCount": "🌐 Clientes online: {{ .Count }}\r\n",
       "disabled": "🛑 Desativado: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Atualizado em: {{ .Time }}\r\n\r\n",
       "yes": "✅ Sim",
       "no": "❌ Não",
-      "received_id": "🔑📥 ID atualizado.",
-      "received_password": "🔑📥 Senha atualizada.",
       "received_email": "📧📥 E-mail atualizado.",
       "received_comment": "💬📥 Comentário atualizado.",
-      "id_prompt": "🔑 ID Padrão: {{ .ClientId }}\n\nDigite seu ID.",
-      "pass_prompt": "🔑 Senha Padrão: {{ .ClientPassword }}\n\nDigite sua senha.",
       "email_prompt": "📧 E-mail Padrão: {{ .ClientEmail }}\n\nDigite seu e-mail.",
       "comment_prompt": "💬 Comentário Padrão: {{ .ClientComment }}\n\nDigite seu comentário.",
-      "inbound_client_data_id": "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n🌐 Limite de IP: {{ .IpLimit }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!",
-      "inbound_client_data_pass": "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Senha: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n🌐 Limite de IP: {{ .IpLimit }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!",
       "cancel": "❌ Processo Cancelado! \n\nVocê pode iniciar novamente a qualquer momento com /start. 🔄",
       "error_add_client": "⚠️ Erro:\n\n {{ .error }}",
       "using_default_value": "Tudo bem, vou manter o valor padrão. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Erro: {{ .Error }}",
       "eventNodeDown": "O nó {{ .Name }} está INATIVO",
       "eventNodeUp": "O nó {{ .Name }} está ATIVO",
-      "eventCPUHigh": "CPU alta",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Falha de login a partir de {{ .Source }}",
       "memoryThreshold": "Uso de memória {{ .Percent }}% excede o limite de {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Enviar como Desativado ☑️",
       "submitEnable": "Enviar como Ativado ✅",
       "use_default": "🏷️ Usar padrão",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Senha",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Comentário",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Redefinir Todo o Tráfego",
       "SortedTrafficUsageReport": "Relatório de Uso de Tráfego Ordenado"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "O outbound {{ .Tag }} está INATIVO",
-    "subjectOutboundUp": "O outbound {{ .Tag }} está ATIVO",
-    "subjectXrayCrash": "O Xray FALHOU",
-    "subjectCPUHigh": "CPU alta",
-    "subjectLoginSuccess": "Login bem-sucedido",
-    "subjectLoginFailed": "Falha de login",
-    "titleOutboundDown": "Outbound INATIVO",
-    "titleOutboundUp": "Outbound ATIVO",
-    "titleXrayCrash": "O Xray FALHOU",
-    "titleCPUHigh": "CPU alta",
-    "titleLoginSuccess": "Login bem-sucedido",
-    "titleLoginFailed": "Falha de login",
     "labelStatus": "Status",
     "labelOutbound": "Outbound",
     "labelNode": "Nó",
     "labelError": "Erro",
     "labelDelay": "Latência",
-    "labelDetail": "Detalhe",
     "labelUsername": "Nome de usuário",
     "labelIP": "IP",
     "labelReason": "Motivo",
     "labelSource": "Origem",
-    "labelTime": "Horário",
     "statusCrashed": "FALHOU",
-    "statusRunning": "Em execução",
     "statusHigh": "ALTA",
     "statusSuccess": "SUCESSO",
     "statusFailed": "FALHOU",

+ 3 - 218
internal/web/translation/ru-RU.json

@@ -48,7 +48,6 @@
   "copySuccess": "Скопировано",
   "sure": "Да",
   "encryption": "Шифрование",
-  "useIPv4ForHost": "Использовать IPv4 для подключения к хосту",
   "transmission": "Транспорт",
   "host": "Хост",
   "path": "Путь",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Код 2FA",
   "remained": "Остаток",
   "security": "Безопасность",
-  "secAlertTitle": "Предупреждение системы безопасности",
-  "secAlertSsl": "Соединение не защищено. Не вводите конфиденциальные данные до установки SSL-сертификата.",
-  "secAlertConf": "Некоторые настройки уязвимы. Рекомендуется усилить защиту для предотвращения атак.",
-  "secAlertSSL": "Подключение к панели не защищено. Установите SSL-сертификат для защиты данных.",
-  "secAlertPanelPort": "Порт панели по умолчанию небезопасен. Установите нестандартный или случайный порт.",
-  "secAlertPanelURI": "Адрес панели по умолчанию небезопасен. Настройте уникальный и сложный URI.",
-  "secAlertSubURI": "URI подписки по умолчанию небезопасен. Настройте уникальный и сложный адрес.",
-  "secAlertSubJsonURI": "URI JSON-подписки по умолчанию небезопасен. Настройте уникальный и сложный адрес.",
   "emptyDnsDesc": "Нет добавленных DNS-серверов.",
   "emptyFakeDnsDesc": "Нет добавленных Fake DNS-серверов.",
   "emptyBalancersDesc": "Нет добавленных балансировщиков.",
-  "emptyReverseDesc": "Нет добавленных реверс-прокси.",
   "somethingWentWrong": "Что-то пошло не так",
   "subscription": {
     "title": "Информация о подписке",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Тема",
-    "dark": "Темная",
-    "ultraDark": "Очень темная",
     "dashboard": "Дашборд",
     "inbounds": "Входящие",
     "clients": "Клиенты",
@@ -118,7 +106,6 @@
     "routing": "Маршрутизация",
     "outbounds": "Исходящие",
     "apiDocs": "Документация API",
-    "logout": "Выход",
     "link": "Управление",
     "donate": "Поддержать",
     "hosts": "Хосты",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Дашборд",
       "cpu": "ЦП",
       "logicalProcessors": "Логические процессоры",
       "frequency": "Частота",
@@ -152,7 +138,6 @@
       "restartXray": "Перезапуск",
       "xraySwitch": "Выбор версии",
       "xrayUpdates": "Обновления Xray",
-      "xraySwitchClick": "Выберите нужную версию",
       "xraySwitchClickDesk": "Важно: старые версии могут не поддерживать текущие настройки",
       "updatePanel": "Обновить панель",
       "panelUpdateDesc": "Это обновит 3X-UI до последнего релиза и перезапустит сервис панели.",
@@ -164,12 +149,10 @@
       "currentCommit": "Текущий коммит",
       "latestCommit": "Последний коммит",
       "updateChannelChanged": "Канал обновления изменён",
-      "upToDate": "Обновлено",
       "xrayStatusUnknown": "Неизвестно",
       "xrayStatusRunning": "Запущен",
       "xrayStatusStop": "Остановлен",
       "xrayStatusError": "Ошибка",
-      "xrayErrorPopoverTitle": "Ошибка при запуске Xray",
       "operationHours": "Время работы системы",
       "systemHistoryTitle": "История системы",
       "historyTitleCpu": "Загрузка ЦП",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Недоступен",
       "xrayObservatoryLastSeen": "Последняя активность",
       "xrayObservatoryLastTry": "Последняя попытка",
-      "trendLast2Min": "Последние 2 минуты",
-      "systemLoad": "Нагрузка на систему",
-      "systemLoadDesc": "Средняя загрузка системы за последние 1, 5 и 15 минут",
       "connectionCount": "Количество соединений",
       "ipAddresses": "IP-адреса сервера",
       "toggleIpVisibility": "Скрыть или показать IP-адреса сервера",
@@ -223,13 +203,11 @@
       "totalData": "Общий объем трафика",
       "sent": "Отправлено",
       "received": "Получено",
-      "documentation": "Документация",
       "xraySwitchVersionDialog": "Переключить версию Xray",
       "xraySwitchVersionDialogDesc": "Вы точно хотите сменить версию Xray?",
       "xraySwitchVersionPopover": "Xray успешно обновлён",
       "panelUpdateDialog": "Вы действительно хотите обновить панель?",
       "panelUpdateDialogDesc": "Это обновит 3X-UI до версии #version# и перезапустит сервис панели.",
-      "panelUpdateCheckPopover": "Проверка обновления панели не удалась",
       "panelUpdateStartedPopover": "Обновление панели началось",
       "panelUpdateFailedTitle": "Не удалось обновить панель",
       "panelUpdateFailedDesc": "Обновление не завершилось успешно. Проверьте журналы сервера или выполните 'x-ui update' в командной строке.",
@@ -258,7 +236,6 @@
       "accessLogs": "Логи доступа",
       "autoUpdate": "Автообновление",
       "config": "Конфигурация",
-      "backup": "Резервная копия",
       "backupTitle": "Бэкап и восстановление",
       "exportDatabase": "Экспорт базы данных",
       "exportDatabaseDesc": "Нажмите, чтобы скачать файл .db, содержащий резервную копию вашей текущей базы данных на ваше устройство. Этот же файл можно восстановить на панели, работающей на PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Нажмите, чтобы скачать базу данных SQLite (.db), собранную из ваших данных PostgreSQL и готовую для запуска панели на SQLite."
     },
     "inbounds": {
-      "title": "Входящие",
       "totalDownUp": "Отправлено/получено",
       "totalUsage": "Всего трафика",
       "inboundCount": "Всего подключений",
@@ -288,21 +264,11 @@
       "localPanel": "Локальная панель",
       "fallbacks": {
         "title": "Fallback'и",
-        "help": "Когда соединение на этом инбаунде не совпадает ни с одним клиентом, оно перенаправляется в другое место. Выберите дочерний инбаунд ниже, чтобы поля маршрутизации (SNI / ALPN / Path / xver) заполнились автоматически из его транспорта, либо оставьте выбор пустым и задайте Dest напрямую (например, 8080 или 127.0.0.1:8080), чтобы перенаправить на внешний сервер, такой как Nginx. Каждый дочерний инбаунд должен слушать на 127.0.0.1 с security=none.",
         "empty": "Фолбэков пока нет",
         "add": "Добавить фолбэк",
         "pickInbound": "Выберите инбаунд",
         "matchAny": "любой",
         "destPlaceholder": "авто (listen:порт дочернего)",
-        "rederive": "Заполнить из дочернего",
-        "rederived": "Заполнено из дочернего",
-        "editAdvanced": "Изменить поля маршрутизации",
-        "hideAdvanced": "Скрыть расширенные",
-        "quickAddAll": "Быстро добавить все подходящие",
-        "quickAdded": "Добавлено {n} фолбэк(ов)",
-        "quickAddedNone": "Нет новых подходящих инбаундов",
-        "routesWhen": "Маршрутизирует, когда",
-        "defaultCatchAll": "По умолчанию — ловит всё остальное",
         "needsTls": "Fallbacks станут доступны после выбора TLS или Reality на вкладке «Безопасность» (только VLESS/Trojan поверх RAW)."
       },
       "protocol": "Протокол",
@@ -310,8 +276,6 @@
       "portMap": "Сопоставление портов",
       "traffic": "Трафик",
       "speed": "Скорость",
-      "details": "Подробнее",
-      "transportConfig": "Транспорт",
       "expireDate": "Дата окончания",
       "createdAt": "Создано",
       "updatedAt": "Обновлено",
@@ -319,8 +283,6 @@
       "addInbound": "Создать подключение",
       "generalActions": "Общие действия",
       "modifyInbound": "Изменить подключение",
-      "deleteInbound": "Удалить подключение",
-      "deleteInboundContent": "Вы уверены, что хотите удалить подключение?",
       "deleteConfirmTitle": "Удалить подключение \"{remark}\"?",
       "deleteConfirmContent": "Подключение и все его клиенты будут удалены. Это действие нельзя отменить.",
       "resetConfirmTitle": "Сбросить трафик \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Все-входящие",
       "exportAllSubsFileName": "Все-входящие-Subs",
       "inboundJsonTitle": "JSON входящего",
-      "deleteClient": "Удалить клиента",
-      "deleteClientContent": "Вы уверены, что хотите удалить клиента?",
       "resetTrafficContent": "Вы уверены, что хотите сбросить трафик?",
       "copyLink": "Копировать ссылку",
       "address": "Адрес",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Безлимит. (единица: ГБ)",
       "totalFlow": "Общий расход",
       "leaveBlankToNeverExpire": "Оставьте пустым, чтобы было бесконечным",
-      "noRecommendKeepDefault": "Рекомендуется оставить настройки по умолчанию",
       "certificatePath": "Путь к сертификату",
       "certificateContent": "Содержимое сертификата",
       "publicKey": "Публичный ключ",
       "privatekey": "Приватный ключ",
-      "clickOnQRcode": "Нажмите на QR-код, чтобы скопировать",
       "client": "Клиент",
       "export": "Экспорт ссылок",
       "clone": "Клонировать",
-      "cloneInbound": "Клонировать",
-      "cloneInboundContent": "Будут клонированы все настройки подключений, кроме списка клиентов, порта и IP-адреса прослушивания",
-      "cloneInboundOk": "Клонировано",
       "resetAllTraffic": "Сброс трафика всех подключений",
       "resetAllTrafficTitle": "Сброс трафика всех подключений",
       "resetAllTrafficContent": "Вы уверены, что хотите сбросить трафик всех подключений?",
-      "resetInboundClientTraffics": "Сброс трафика клиента",
-      "resetInboundClientTrafficTitle": "Сброс трафика клиентов",
-      "resetInboundClientTrafficContent": "Вы уверены, что хотите сбросить трафик для этих клиентов?",
-      "resetAllClientTraffics": "Сброс трафика всех клиентов",
-      "resetAllClientTrafficTitle": "Сброс трафика всех клиентов",
-      "resetAllClientTrafficContent": "Вы уверены, что хотите сбросить трафик всех клиентов?",
-      "delDepletedClients": "Удалить отключенных клиентов",
-      "delDepletedClientsTitle": "Удаление отключенных клиентов",
-      "delDepletedClientsContent": "Вы уверены, что хотите удалить всех отключенных клиентов?",
       "email": "Email",
-      "emailDesc": "Пожалуйста, укажите уникальный Email",
       "IPLimit": "Лимит по количеству IP",
-      "IPLimitDesc": "Ограничение числа одновременных подключений с разных IP (0 – отключить)",
       "IPLimitlog": "Лог IP-адресов",
-      "IPLimitlogDesc": "Лог IP-адресов (перед включением лога IP-адресов, вы должны очистить лог)",
       "IPLimitlogclear": "Очистить лог",
       "setDefaultCert": "Установить сертификат панели",
       "setDefaultCertEmpty": "Для панели не настроен сертификат. Сначала установите его в Настройках.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Обёртка блока sniffing Xray:",
         "stream": "Stream",
-        "streamHelp": "Обёртка блока stream Xray:",
-        "jsonErrorPrefix": "Расширенный JSON"
+        "streamHelp": "Обёртка блока stream Xray:"
       },
-      "telegramDesc": "Пожалуйста, укажите Chat ID Telegram. (используйте команду '/id' в боте) или ({'@'}userinfobot)",
-      "subscriptionDesc": "Вы можете найти свою ссылку подписки в разделе 'Подробнее'",
       "subSortIndex": "Порядок",
-      "same": "Тот же",
       "inboundInfo": "Информация о подключении",
       "exportInbound": "Экспорт подключений",
       "import": "Импортировать",
       "importInbound": "Импорт подключений",
       "periodicTrafficResetTitle": "Сброс трафика",
-      "periodicTrafficResetDesc": "Автоматический сброс счетчика трафика через указанные интервалы",
       "periodicTrafficResetDay": "День ежемесячного сброса",
-      "lastReset": "Последний сброс",
       "periodicTrafficReset": {
         "never": "Никогда",
         "daily": "Ежедневно",
@@ -464,7 +401,6 @@
         "obtain": "Получить",
         "updateSuccess": "Обновление прошло успешно",
         "logCleanSuccess": "Лог был очищен",
-        "inboundsUpdateSuccess": "Подключения успешно обновлены",
         "inboundUpdateSuccess": "Подключение успешно обновлено",
         "inboundCreateSuccess": "Подключение успешно создано",
         "bulkDeleted": "Удалено подключений: {count}",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Клиент подключения удалён",
         "inboundClientUpdateSuccess": "Клиент подключения обновлён",
         "savedNodeOfflineWillSync": "Сохранено локально. Опорный узел отключён или недоступен — изменение синхронизируется после повторного подключения.",
-        "delDepletedClientsSuccess": "Все исчерпанные клиенты удалены",
         "resetAllClientTrafficSuccess": "Весь трафик клиента сброшен",
         "resetAllTrafficSuccess": "Весь трафик сброшен",
         "resetInboundClientTrafficSuccess": "Трафик сброшен",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Конфиг Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Запрос",
-          "response": "Ответ",
-          "name": "Имя",
-          "value": "Значение"
-        },
-        "tcp": {
-          "version": "Версия",
-          "method": "Метод",
-          "path": "Путь",
-          "status": "Статус",
-          "statusDescription": "Описание статуса",
-          "requestHeader": "Заголовок запроса",
-          "responseHeader": "Заголовок ответа"
-        }
-      },
       "sniffingDestOverride": "Переопределение назначения"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Добавить внешнюю подписку",
       "noExternalLinks": "Пока нет внешних ссылок.",
       "noExternalSubscriptions": "Пока нет внешних подписок.",
-      "add": "Добавить клиента",
-      "edit": "Изменить клиента",
-      "submitAdd": "Добавить клиента",
       "submitEdit": "Сохранить изменения",
       "clientCount": "Количество клиентов",
       "bulk": "Массовое добавление",
-      "copyFromInbound": "Скопировать клиентов из входящего",
-      "copyToInbound": "Скопировать клиентов в",
-      "copySelected": "Скопировать выбранное",
-      "copySource": "Источник",
-      "copyEmailPreview": "Предпросмотр результирующего email",
-      "copySelectSourceFirst": "Сначала выберите исходный входящий.",
-      "copyResult": "Результат копирования",
-      "copyResultSuccess": "Скопировано успешно",
-      "copyResultNone": "Нечего копировать: клиенты не выбраны или источник пуст",
-      "copyResultErrors": "Ошибки копирования",
-      "copyFlowLabel": "Flow для новых клиентов (VLESS)",
-      "copyFlowHint": "Применяется ко всем скопированным клиентам. Оставьте пустым, чтобы пропустить.",
       "selectAll": "Выбрать всё",
       "clearAll": "Очистить всё",
       "method": "Метод",
@@ -775,7 +678,6 @@
       "postfix": "Постфикс",
       "delayedStart": "Старт после первого использования",
       "expireDays": "Длительность (дней)",
-      "days": "Дни",
       "renew": "Автопродление",
       "renewDesc": "Автоматическое продление после окончания. (0 = отключено) (единица: день)",
       "renewDays": "Автопродление (дней)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Скорее истекают",
       "has": "Есть",
       "hasNot": "Нет",
-      "title": "Клиенты",
       "actions": "Действия",
       "totalGB": "Лимит трафика (ГБ)",
       "totalGBDesc": "Квота трафика для этого клиента. 0 = без ограничений.",
@@ -826,8 +727,6 @@
       "addClient": "Добавить клиента",
       "qrCode": "QR-код",
       "clientInfo": "Информация о клиенте",
-      "delete": "Удалить",
-      "reset": "Сбросить трафик",
       "editClient": "Изменить клиента",
       "client": "Клиент",
       "enabled": "Включён",
@@ -841,13 +740,11 @@
       "noLinks": "Нет ссылок для общего доступа — сначала привяжите клиента к входящему с поддерживаемым протоколом.",
       "link": "Ссылка",
       "resetNotPossible": "Сначала привяжите этого клиента к входящему.",
-      "general": "Общие",
       "resetAllTraffics": "Сбросить трафик всех клиентов",
       "resetAllTrafficsTitle": "Сбросить трафик всех клиентов?",
       "resetAllTrafficsContent": "Счётчики отправки/приёма всех клиентов сбрасываются в ноль. Квоты и срок действия не затрагиваются. Это действие нельзя отменить.",
       "deleteConfirmTitle": "Удалить клиента {email}?",
       "deleteConfirmContent": "Клиент будет удалён из всех привязанных входящих, а его запись трафика будет уничтожена. Это действие нельзя отменить.",
-      "deleteSelected": "Удалить ({count})",
       "adjustSelected": "Изменить ({count})",
       "subLinksSelected": "Sub-ссылки ({count})",
       "addToGroupTitle": "Добавить {count} клиент(ов) в группу",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Отключить {count} клиентов?",
       "bulkDisableConfirmContent": "Отключает каждого выбранного клиента на всех привязанных подключениях. Они сразу теряют доступ, но их записи и трафик сохраняются.",
       "selectedCount": "{count} выбрано",
-      "attachSelected": "Привязать ({count})",
       "attachToInboundsTitle": "Привязать {count} клиент(ов) к входящим",
       "attachToInboundsDesc": "Привязывает выбранных {count} клиент(ов) (тот же UUID/пароль и общий трафик) к выбранным входящим. Существующие привязки сохраняются.",
       "attachToInboundsTargets": "Целевые входящие",
       "attachToInboundsNoTargets": "Нет доступных многопользовательских входящих для привязки.",
-      "detachSelected": "Отвязать ({count})",
       "detach": "Отвязать",
       "detachFromInboundsTitle": "Отвязать {count} клиент(ов) от входящих",
       "detachFromInboundsDesc": "Удаляет выбранных {count} клиент(ов) из выбранных входящих. Пары, где клиент не был привязан, тихо пропускаются. Записи клиентов сохраняются (используйте Delete для полного удаления).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Необязательный Reverse tag",
       "telegramId": "ID пользователя Telegram",
       "telegramIdPlaceholder": "Числовой ID пользователя Telegram (0 = нет)",
-      "created": "Создан",
-      "updated": "Обновлён",
       "ipLimit": "Лимит IP",
       "toasts": {
         "deleted": "Клиент удалён",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Группы",
       "name": "Имя",
       "clientCount": "Клиенты",
       "totalGroups": "Всего групп",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "Удалено {count} клиент(ов) из {name}."
     },
     "nodes": {
-      "title": "Узлы",
       "addNode": "Добавить узел",
       "editNode": "Изменить узел",
       "totalNodes": "Всего узлов",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Токен со страницы Настроек удалённой панели",
       "apiTokenHint": "Удалённая панель показывает свой токен API в разделе Учетная запись → Токен API.",
       "apiTokenKeepHint": "Оставьте пустым, чтобы сохранить текущий токен",
-      "regenerate": "Сгенерировать токен заново",
-      "regenerateConfirm": "Повторная генерация аннулирует текущий токен. Любая центральная панель, использующая его, потеряет доступ до обновления. Продолжить?",
       "allowPrivateAddress": "Разрешить частный адрес",
       "allowPrivateAddressHint": "Включить только для узлов в частной сети или VPN.",
       "outboundTag": "Исходящее подключение",
@@ -1046,7 +935,6 @@
       "updatePanel": "Обновить панель",
       "updateSelected": "Обновить выбранные ({count})",
       "updateAvailable": "Доступно обновление",
-      "upToDate": "Актуально",
       "updateConfirmTitle": "Обновить {count} узлов до последней версии?",
       "updateConfirmContent": "Каждый выбранный узел загрузит последний релиз и перезапустится. Обновляются только включённые узлы в сети.",
       "updateDevChannel": "Обновить до канала разработки (последний коммит)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Не удалось получить сертификат"
     },
     "settings": {
+      "defaultTag": "По умолчанию",
       "title": "Настройки",
       "save": "Сохранить",
       "infoDesc": "Сохраните изменения и перезапустите панель для их применения.",
@@ -1455,13 +1344,8 @@
       "metricsListen": "Эндпоинт метрик",
       "metricsListenDesc": "Публикует метрики Xray в стиле Prometheus по этому адресу:порту (например, 127.0.0.1:11111). Оставьте пустым, чтобы отключить. Привяжите к localhost и проксируйте через reverse-proxy — он без аутентификации.",
       "metricsTag": "Тег метрик",
-      "title": "Настройки Xray",
       "save": "Сохранить",
-      "restart": "Перезапуск Xray",
       "restartSuccess": "Xray успешно перезапущен",
-      "restartOutputTitle": "Вывод перезапуска Xray",
-      "restartConfirmTitle": "Перезапустить xray?",
-      "restartConfirmContent": "Перезагружает сервис xray с сохранённой конфигурацией.",
       "stopSuccess": "Xray успешно остановлен",
       "restartError": "Произошла ошибка при перезапуске Xray.",
       "stopError": "Произошла ошибка при остановке Xray.",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "Эти параметры описывают общие настройки",
       "logConfigs": "Лог",
       "logConfigsDesc": "Логи могут замедлять работу сервера. Включайте только нужные вам виды логов при необходимости!",
-      "blockConfigsDesc": "Настройте, чтобы клиенты не имели доступа к определенным протоколам",
       "basicRouting": "Базовые соединения",
       "blockConnectionsConfigsDesc": "Эти параметры будут блокировать трафик в зависимости от страны назначения.",
       "directConnectionsConfigsDesc": "Прямое соединение означает, что определенный трафик не будет перенаправлен через другой сервер.",
@@ -1481,10 +1364,6 @@
       "directdomains": "Прямые домены",
       "ipv4Routing": "Правила IPv4",
       "ipv4RoutingDesc": "Эти параметры позволят клиентам маршрутизироваться к целевым доменам только через IPv4",
-      "warpRouting": "Правила WARP",
-      "warpRoutingDesc": " Эти опции будут направлять трафик в зависимости от конкретного пункта назначения через WARP.",
-      "nordRouting": "Маршрутизация NordVPN",
-      "nordRoutingDesc": "Эти опции будут направлять трафик в зависимости от конкретного пункта назначения через NordVPN.",
       "Template": "Шаблон конфигурации Xray",
       "TemplateDesc": "На основе шаблона создаётся конфигурационный файл Xray.",
       "FreedomStrategy": "Настройка стратегии протокола Freedom",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "URL для проверки подключения исходящего",
       "Torrent": "Заблокировать BitTorrent",
       "Inbounds": "Входящие",
-      "InboundsDesc": "Изменение шаблона конфигурации для подключения определенных клиентов",
       "Outbounds": "Исходящие",
-      "OutboundSubscriptions": "Подписки исходящих",
-      "OutboundSubscriptionsDesc": "Импорт исходящих из удалённых URL подписок (vmess/vless/trojan/ss/...). Теги остаются неизменными для использования в балансировщиках и правилах маршрутизации. Обновление выполняется автоматически.",
       "Balancers": "Балансировщик",
       "balancerTagRequired": "Тег обязателен",
       "balancerSelectorRequired": "Выберите хотя бы одно исходящее",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "Совпавший исходящий",
       "routeTesterViaBalancer": "через балансировщик",
       "routeTesterDefaultOutbound": "Ни одно правило маршрутизации не совпало — трафик направляется в исходящий по умолчанию (первый).",
-      "OutboundsDesc": "Изменение шаблона конфигурации, чтобы определить исходящие подключения для этого сервера",
       "Routings": "Маршрутизация",
-      "RoutingsDesc": "Важен приоритет каждого правила!",
       "completeTemplate": "Все",
       "logLevel": "Уровень логов",
       "logLevelDesc": "Уровень журнала для журналов ошибок, указывающий информацию, которую необходимо записать.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "При активации реальный IP-адрес заменяется на маскировочный в логах.",
       "statistics": "Статистика",
       "statsInboundUplink": "Статистика входящего аплинка",
-      "statsInboundUplinkDesc": "Включает сбор статистики для исходящего трафика всех входящих прокси.",
       "statsInboundDownlink": "Статистика входящего даунлинка",
-      "statsInboundDownlinkDesc": "Включает сбор статистики для входящего трафика всех входящих прокси.",
       "statsOutboundUplink": "Статистика исходящего аплинка",
-      "statsOutboundUplinkDesc": "Включает сбор статистики для исходящего трафика всех исходящих прокси.",
       "statsOutboundDownlink": "Статистика исходящего даунлинка",
-      "statsOutboundDownlinkDesc": "Включает сбор статистики для входящего трафика всех исходящих прокси.",
       "connectionLimits": "Ограничения соединения",
       "connectionLimitsDesc": "Политики уровня соединения для пользователей уровня 0. Оставьте поле пустым, чтобы использовать значение Xray по умолчанию.",
       "connIdle": "Тайм-аут простоя",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "авто",
       "seconds": "секунд",
       "rules": {
-        "first": "Первый",
-        "last": "Последний",
-        "up": "Поднять вверх",
-        "down": "Опустить вниз",
         "source": "Источник",
         "dest": "Пункт назначения",
         "inbound": "Входящее подключение",
-        "outbound": "Исходящее подключение",
         "balancer": "Балансировщик",
-        "info": "Инфо",
-        "add": "Создать правило",
-        "edit": "Редактировать правило",
         "useComma": "Элементы, разделённые запятыми"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Правило {n}",
         "action": "Действие",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Финальные правила",
         "overrideXrayPrivateIp": "Переопределить дефолтный блок частных IP в Xray",
         "blockDelay": "Задержка блока (мс)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Интервал keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Интерфейс",
-        "ipv6Only": "Только IPv6",
-        "acceptProxyProtocol": "Принимать proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (мс)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (с)"
       },
       "outbound": {
-        "addOutbound": "Создать исходящее подключение",
-        "addReverse": "Создать реверс-прокси",
-        "editOutbound": "Изменить исходящее подключение",
-        "editReverse": "Редактировать реверс-прокси",
-        "reverseTag": "Тег реверс-прокси",
-        "reverseTagDesc": "Тег исходящего подключения для простого реверс-прокси VLESS. Оставьте пустым для отключения.",
-        "reverseTagPlaceholder": "тег исходящего (пусто = отключено)",
         "tag": "Тег",
-        "tagDesc": "Уникальный тег",
-        "address": "Адрес",
         "egress": "Выход",
         "egressHint": "Запустите HTTP-тест, чтобы показать выходной IP и страну.",
-        "reverse": "Реверс-прокси",
-        "domain": "Домен",
-        "type": "Тип",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Ссылка",
-        "intercon": "Соединение",
-        "settings": "Настройки",
-        "accountInfo": "Информация об учетной записи",
         "outboundStatus": "Статус исходящего подключения",
         "sendThrough": "Отправить через",
         "targetStrategy": "Стратегия назначения",
-        "test": "Тест",
-        "testResult": "Результат теста",
-        "testing": "Тестирование соединения...",
-        "testSuccess": "Тест успешен",
-        "testFailed": "Тест не пройден",
-        "testError": "Не удалось протестировать исходящее подключение",
         "modeRealDelay": "Реальная задержка",
         "testModeTooltip": "TCP: быстрый dial-only probe. HTTP: полный запрос через xray. Реальная задержка: полное время с установлением соединения.",
         "testAll": "Тестировать все",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Подключение к прокси",
         "breakdownTls": "TLS через исходящий",
         "breakdownTtfb": "Первый байт",
-        "nordvpn": "NordVPN",
-        "accessToken": "Токен доступа",
         "country": "Страна",
         "server": "Сервер",
         "city": "Город",
         "allCities": "Все города",
-        "privateKey": "Приватный ключ",
-        "load": "Нагрузка",
         "moveToTop": "Переместить наверх"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Активные подписки",
         "empty": "Подписок пока нет. Добавьте одну выше.",
         "colRemark": "Примечание",
-        "colPrefix": "Префикс",
-        "colInterval": "Интервал",
         "colLastFetch": "Последнее обновление",
         "colEnabled": "Включено",
         "auto": "авто",
         "never": "никогда",
-        "yes": "Да",
-        "no": "Нет",
         "refreshNow": "Обновить сейчас",
-        "lastError": "Последняя ошибка",
         "deleteConfirm": "Удалить эту подписку?",
         "restartHint": "После добавления или обновления перезапустите Xray (или дождитесь следующей автоперезагрузки), чтобы исходящие стали активными.",
         "fromSubsTitle": "Из подписок исходящих (только для чтения)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Настройки балансировщика",
       "tabObservatory": "Обсерватория",
       "observatory": {
-        "title": "Обсерватория",
-        "burstTitle": "Burst-обсерватория",
         "autoManaged": "Наблюдатели управляются автоматически на основе ваших балансировщиков. Ниже можно настроить, как они опрашивают; отслеживаемые исходящие следуют за селекторами балансировщика.",
         "emptyHint": "Нет активного наблюдателя соединений. Он добавляется автоматически при создании балансировщика Least Ping или Least Load — либо Random / Round-robin с fallback — чтобы балансировщики с наблюдателем могли проверять состояние исходящих перед выбором цели.",
         "mixedLegacy": "В этой конфигурации одновременно есть Observatory и Burst Observatory. Xray использует один глобальный наблюдатель, поэтому такое устаревшее смешанное состояние не поддерживается; сохранение балансировщиков нормализует его до одного наблюдателя.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Балансировщик {tag} — удалён (не осталось целей)"
       },
       "balancer": {
-        "addBalancer": "Создать балансировщик",
-        "editBalancer": "Редактировать балансировщик",
         "balancerStrategy": "Стратегия",
-        "balancerSelectors": "Селекторы",
         "tag": "Тег",
-        "tagDesc": "Уникальный тег",
         "tagDuplicate": "Тег уже используется другим балансировщиком",
         "tagPlaceholder": "уникальный тег балансировщика",
         "selector": "Селектор",
@@ -1789,7 +1609,6 @@
         "tolerance": "Допуск",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "Невозможно одновременно использовать balancerTag и outboundTag. При одновременном использовании будет работать только outboundTag.",
         "costMatch": "Шаблон тега",
         "costValue": "Вес",
         "costRegexp": "Совпадение по регулярному выражению",
@@ -1804,14 +1623,10 @@
         "publicKey": "Публичный ключ",
         "allowedIPs": "Разрешенные IP-адреса",
         "endpoint": "Конечная точка",
-        "psk": "Общий ключ",
         "domainStrategy": "Стратегия домена"
       },
       "tun": {
-        "nameDesc": "Имя интерфейса TUN. Значение по умолчанию - 'xray0'",
-        "mtuDesc": "Максимальная единица передачи. Максимальный размер пакетов данных. Значение по умолчанию - 1500",
-        "userLevel": "Уровень пользователя",
-        "userLevelDesc": "Все соединения, установленные через этот входящий поток, будут использовать этот уровень пользователя. Значение по умолчанию - 0"
+        "userLevel": "Уровень пользователя"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Создать Fake DNS",
-        "edit": "Редактировать Fake DNS",
         "ipPool": "Подсеть пула IP",
         "poolSize": "Размер пула"
       },
@@ -2032,7 +1846,6 @@
     "add": "Добавить",
     "month": "Месяц",
     "months": "Месяцев",
-    "day": "День",
     "days": "Дней",
     "hours": "Часов",
     "minutes": "Минуты",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Пользователь Telegram сохранен.",
       "loginSuccess": "✅ Успешный вход в панель.\r\n",
       "loginFailed": "❗️ Ошибка входа в панель.\r\n",
-      "2faFailed": "Ошибка 2FA",
       "report": "🕰 Запланированные отчеты: {{ .RunTime }}\r\n",
       "datetime": "⏰ Дата и время: {{ .DateTime }}\r\n",
       "hostname": "💻 Хост: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Загрузка: ↓{{ .Download }}\r\n",
       "total": "📊 Всего: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Telegram User ID: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Исчерпаны {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Количество исчерпанных {{ .Type }}:\r\n",
       "onlinesCount": "🌐 Клиентов онлайн: {{ .Count }}\r\n",
       "disabled": "🛑 Отключено: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Обновлено: {{ .Time }}\r\n\r\n",
       "yes": "✅ Да",
       "no": "❌ Нет",
-      "received_id": "🔑📥 ID обновлён.",
-      "received_password": "🔑📥 Пароль обновлён.",
       "received_email": "📧📥 Email обновлен.",
       "received_comment": "💬📥 Комментарий обновлён.",
-      "id_prompt": "🔑 Стандартный ID: {{ .ClientId }}\n\nВведите ваш ID.",
-      "pass_prompt": "🔑 Стандартный пароль: {{ .ClientPassword }}\n\nВведите ваш пароль.",
       "email_prompt": "📧 Стандартный email: {{ .ClientEmail }}\n\nВведите ваш email.",
       "comment_prompt": "💬 Стандартный комментарий: {{ .ClientComment }}\n\nВведите ваш комментарий.",
-      "inbound_client_data_id": "🔄 Входящие подключения: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Срок действия: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента в входящее подключение!",
-      "inbound_client_data_pass": "🔄 Входящие подключения: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Срок действия: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента в входящее подключение!",
       "cancel": "❌ Процесс отменён! \n\nВы можете снова начать с /start в любое время. 🔄",
       "error_add_client": "⚠️ Ошибка:\n\n {{ .error }}",
       "using_default_value": "Используется значение по умолчанию👌",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Ошибка: {{ .Error }}",
       "eventNodeDown": "Узел {{ .Name }} НЕДОСТУПЕН",
       "eventNodeUp": "Узел {{ .Name }} В СЕТИ",
-      "eventCPUHigh": "Высокая загрузка CPU",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Неудачный вход с {{ .Source }}",
       "memoryThreshold": "🔴 Использование памяти {{ .Percent }}% превышает пороговое значение {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Добавить отключенным ☑️",
       "submitEnable": "Добавить включенным ✅",
       "use_default": "🏷️ Использовать по умолчанию",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Пароль",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Комментарий",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Сбросить весь трафик",
       "SortedTrafficUsageReport": "Отсортированный отчет об использовании трафика"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "Исходящее подключение {{ .Tag }} НЕДОСТУПНО",
-    "subjectOutboundUp": "Исходящее подключение {{ .Tag }} РАБОТАЕТ",
-    "subjectXrayCrash": "Сбой Xray",
-    "subjectCPUHigh": "Высокая загрузка CPU",
-    "subjectLoginSuccess": "Успешный вход",
-    "subjectLoginFailed": "Неудачный вход",
-    "titleOutboundDown": "Исходящее подключение НЕДОСТУПНО",
-    "titleOutboundUp": "Исходящее подключение РАБОТАЕТ",
-    "titleXrayCrash": "Сбой Xray",
-    "titleCPUHigh": "Высокая загрузка CPU",
-    "titleLoginSuccess": "Успешный вход",
-    "titleLoginFailed": "Неудачный вход",
     "labelStatus": "Статус",
     "labelOutbound": "Исходящее подключение",
     "labelNode": "Узел",
     "labelError": "Ошибка",
     "labelDelay": "Задержка",
-    "labelDetail": "Подробности",
     "labelUsername": "Имя пользователя",
     "labelIP": "IP",
     "labelReason": "Причина",
     "labelSource": "Источник",
-    "labelTime": "Время",
     "statusCrashed": "СБОЙ",
-    "statusRunning": "Работает",
     "statusHigh": "ВЫСОКАЯ",
     "statusSuccess": "УСПЕШНО",
     "statusFailed": "НЕУДАЧНО",

+ 3 - 218
internal/web/translation/tr-TR.json

@@ -48,7 +48,6 @@
   "copySuccess": "Başarıyla kopyalandı",
   "sure": "Emin misiniz?",
   "encryption": "Şifreleme",
-  "useIPv4ForHost": "Ana bilgisayar için IPv4 kullan",
   "transmission": "İletim",
   "host": "Host",
   "path": "Yol",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Kod",
   "remained": "Kalan",
   "security": "Güvenlik",
-  "secAlertTitle": "Güvenlik Uyarısı",
-  "secAlertSsl": "Bu bağlantı güvenli değil. Verilerin korunması için TLS etkinleştirilene kadar hassas bilgi girmekten kaçının.",
-  "secAlertConf": "Bazı ayarlar saldırıya açıktır. Olası ihlalleri önlemek için güvenlik protokollerini güçlendirmeniz önerilir.",
-  "secAlertSSL": "Panelde güvenli bağlantı yok. Verilerin korunması için TLS sertifikası yükleyin.",
-  "secAlertPanelPort": "Panelin varsayılan portu savunmasız. Rastgele veya belirli bir port yapılandırın.",
-  "secAlertPanelURI": "Panelin varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın.",
-  "secAlertSubURI": "Aboneliğin varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın.",
-  "secAlertSubJsonURI": "Abonelik JSON dosyasının varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın.",
   "emptyDnsDesc": "Eklenmiş DNS sunucusu yok.",
   "emptyFakeDnsDesc": "Eklenmiş Fake DNS sunucusu yok.",
   "emptyBalancersDesc": "Eklenmiş dengeleyici yok.",
-  "emptyReverseDesc": "Eklenmiş ters proxy yok.",
   "somethingWentWrong": "Bir hata oluştu",
   "subscription": {
     "title": "Abonelik Bilgisi",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Tema",
-    "dark": "Koyu",
-    "ultraDark": "Ultra Koyu",
     "dashboard": "Genel Bakış",
     "inbounds": "Gelen Bağlantılar",
     "clients": "Kullanıcılar",
@@ -118,7 +106,6 @@
     "routing": "Yönlendirme",
     "outbounds": "Giden Bağlantılar",
     "apiDocs": "API Belgeleri",
-    "logout": "Çıkış Yap",
     "link": "Yönet",
     "donate": "Bağış Yap",
     "hosts": "Host'lar",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Genel Bakış",
       "cpu": "CPU",
       "logicalProcessors": "Mantıksal İşlemciler",
       "frequency": "Frekans",
@@ -152,7 +138,6 @@
       "restartXray": "Yeniden Başlat",
       "xraySwitch": "Sürüm",
       "xrayUpdates": "Xray Güncellemeleri",
-      "xraySwitchClick": "Geçiş yapmak istediğiniz sürümü seçin.",
       "xraySwitchClickDesk": "Dikkatli seçin, eski sürümler mevcut yapılandırmalarla uyumlu olmayabilir.",
       "updatePanel": "Paneli Güncelle",
       "panelUpdateDesc": "Bu işlem 3X-UI'yi en son sürüme güncelleyecek ve panel servisini yeniden başlatacaktır.",
@@ -164,12 +149,10 @@
       "currentCommit": "Geçerli commit",
       "latestCommit": "Son commit",
       "updateChannelChanged": "Güncelleme kanalı değiştirildi",
-      "upToDate": "Güncel",
       "xrayStatusUnknown": "Bilinmiyor",
       "xrayStatusRunning": "Çalışıyor",
       "xrayStatusStop": "Durduruldu",
       "xrayStatusError": "Hata",
-      "xrayErrorPopoverTitle": "Xray çalıştırılırken bir hata oluştu",
       "operationHours": "Çalışma Süresi",
       "systemHistoryTitle": "Sistem Geçmişi",
       "historyTitleCpu": "CPU Kullanımı",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Kapalı",
       "xrayObservatoryLastSeen": "Son görülme",
       "xrayObservatoryLastTry": "Son deneme",
-      "trendLast2Min": "Son 2 dakika",
-      "systemLoad": "Sistem Yükü",
-      "systemLoadDesc": "Son 1, 5 ve 15 dakikanın sistem yükü ortalaması",
       "connectionCount": "Bağlantı İstatistikleri",
       "ipAddresses": "IP Adresleri",
       "toggleIpVisibility": "IP görünürlüğünü değiştir",
@@ -223,13 +203,11 @@
       "totalData": "Toplam Veri",
       "sent": "Gönderilen",
       "received": "Alınan",
-      "documentation": "Dokümantasyon",
       "xraySwitchVersionDialog": "Xray sürümünü gerçekten değiştirmek istiyor musunuz?",
       "xraySwitchVersionDialogDesc": "Bu işlem Xray sürümünü #version# olarak değiştirecektir.",
       "xraySwitchVersionPopover": "Xray başarıyla güncellendi",
       "panelUpdateDialog": "Gerçekten paneli güncellemek istiyor musunuz?",
       "panelUpdateDialogDesc": "Bu işlem 3X-UI'yi #version# sürümüne güncelleyecek ve panel servisini yeniden başlatacaktır.",
-      "panelUpdateCheckPopover": "Panel güncelleme kontrolü başarısız oldu",
       "panelUpdateStartedPopover": "Panel güncellemesi başlatıldı",
       "panelUpdateFailedTitle": "Panel güncellemesi başarısız oldu",
       "panelUpdateFailedDesc": "Güncelleme başarıyla tamamlanamadı. Sunucu günlüklerini kontrol edin veya komut satırından 'x-ui update' çalıştırın.",
@@ -258,7 +236,6 @@
       "accessLogs": "Erişim Günlükleri",
       "autoUpdate": "Otomatik Güncelleme",
       "config": "Yapılandırma",
-      "backup": "Yedek",
       "backupTitle": "Yedekleme ve Geri Yükleme",
       "exportDatabase": "Yedekle",
       "exportDatabaseDesc": "Mevcut veritabanınızın yedeğini içeren bir .db dosyasını cihazınıza indirmek için tıklayın. Aynı dosya PostgreSQL üzerinde çalışan bir panele de geri yüklenebilir.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "PostgreSQL verilerinizden oluşturulan ve bu paneli SQLite üzerinde çalıştırmaya hazır bir .db SQLite veritabanı indirmek için tıklayın."
     },
     "inbounds": {
-      "title": "Gelen Bağlantılar",
       "totalDownUp": "Toplam Gönderilen/Alınan",
       "totalUsage": "Toplam Kullanım",
       "inboundCount": "Toplam Gelen Bağlantı",
@@ -288,21 +264,11 @@
       "localPanel": "Yerel Panel",
       "fallbacks": {
         "title": "Fallback'ler",
-        "help": "Bu gelen bağlantı üzerindeki bir istek hiçbir istemci ile eşleşmediğinde, başka bir yere yönlendirilir. Aşağıdan bir alt (child) gelen bağlantı seçerek yönlendirme alanlarını (SNI / ALPN / Path / xver) aktarım (transport) ayarlarından otomatik doldurun ya da seçimi boş bırakıp Hedef (Dest) değerini doğrudan girin (örn. 8080 veya 127.0.0.1:8080); böylece Nginx gibi harici bir sunucuya yönlendirebilirsiniz. Her alt gelen bağlantı 127.0.0.1 üzerinde security=none (güvenlik=yok) ile dinlemelidir.",
         "empty": "Henüz fallback yok",
         "add": "Fallback Ekle",
         "pickInbound": "Bir Gelen Bağlantı Seç",
         "matchAny": "herhangi",
         "destPlaceholder": "otomatik (child listen:port)",
-        "rederive": "Child'dan Yeniden Doldur",
-        "rederived": "Child'dan yeniden dolduruldu",
-        "editAdvanced": "Yönlendirme Alanlarını Düzenle",
-        "hideAdvanced": "Gelişmişi Gizle",
-        "quickAddAll": "Uygun Olan Tümünü Hızlı Ekle",
-        "quickAdded": "{n} fallback eklendi",
-        "quickAddedNone": "Eklenecek yeni uygun gelen bağlantı yok",
-        "routesWhen": "Şu Durumda Yönlendirir",
-        "defaultCatchAll": "Varsayılan — başka her şeyi yakalar",
         "needsTls": "Geri düşüşler (fallback), Güvenlik sekmesinde TLS veya Reality seçildiğinde kullanılabilir olur (yalnızca RAW üzerinde VLESS/Trojan)."
       },
       "protocol": "Protokol",
@@ -310,8 +276,6 @@
       "portMap": "Port Eşlemesi",
       "traffic": "Trafik",
       "speed": "Hız",
-      "details": "Detaylar",
-      "transportConfig": "Aktarım",
       "expireDate": "Süre",
       "createdAt": "Oluşturuldu",
       "updatedAt": "Güncellendi",
@@ -319,8 +283,6 @@
       "addInbound": "Gelen Bağlantı Ekle",
       "generalActions": "Genel İşlemler",
       "modifyInbound": "Gelen Bağlantını Düzenle",
-      "deleteInbound": "Gelen Bağlantını Sil",
-      "deleteInboundContent": "Bu gelen bağlantıyı silmek istediğinizden emin misiniz?",
       "deleteConfirmTitle": "\"{remark}\" gelen bağlantı silinsin mi?",
       "deleteConfirmContent": "Bu işlem gelen bağlantıyı ve tüm kullanıcılarını siler. Geri alınamaz.",
       "resetConfirmTitle": "\"{remark}\" trafiği sıfırlansın mı?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Tüm-BağlantıNoktaları",
       "exportAllSubsFileName": "Tüm-BağlantıNoktaları-Subs",
       "inboundJsonTitle": "Gelen Bağlantı JSON",
-      "deleteClient": "Kullanıcıyı Sil",
-      "deleteClientContent": "Kullanıcıyı silmek istediğinizden emin misiniz?",
       "resetTrafficContent": "Trafiği sıfırlamak istediğinizden emin misiniz?",
       "copyLink": "URL'yi Kopyala",
       "address": "Adres",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Sınırsız. (birim: GB)",
       "totalFlow": "Toplam Akış",
       "leaveBlankToNeverExpire": "Süresiz olması için boş bırakın",
-      "noRecommendKeepDefault": "Varsayılan ayarda bırakılması önerilir",
       "certificatePath": "Dosya Yolu",
       "certificateContent": "Dosya İçeriği",
       "publicKey": "Genel Anahtar",
       "privatekey": "Özel Anahtar",
-      "clickOnQRcode": "Kopyalamak İçin QR Koda Tıklayın",
       "client": "Kullanıcı",
       "export": "Tüm URL'leri Dışa Aktar",
       "clone": "Klonla",
-      "cloneInbound": "Klonla",
-      "cloneInboundContent": "Bu gelen bağlantıyın tüm ayarları, Port, Dinleme IP ve Kullanıcılar hariç, klona uygulanacaktır.",
-      "cloneInboundOk": "Klonla",
       "resetAllTraffic": "Tüm Gelen Trafiği Sıfırla",
       "resetAllTrafficTitle": "Tüm Gelen Trafiği Sıfırla",
       "resetAllTrafficContent": "Tüm gelen bağlantılarnın trafiğini sıfırlamak istediğinizden emin misiniz?",
-      "resetInboundClientTraffics": "Kullanıcıların Trafiğini Sıfırla",
-      "resetInboundClientTrafficTitle": "Kullanıcı Trafiklerini Sıfırla",
-      "resetInboundClientTrafficContent": "Bu gelen bağlantıya ait kullanıcıların trafiğini sıfırlamak istediğinizden emin misiniz?",
-      "resetAllClientTraffics": "Tüm Kullanıcıların Trafiğini Sıfırla",
-      "resetAllClientTrafficTitle": "Tüm Kullanıcı Trafiklerini Sıfırla",
-      "resetAllClientTrafficContent": "Tüm kullanıcıların trafiğini sıfırlamak istediğinizden emin misiniz?",
-      "delDepletedClients": "Kotası Dolan Kullanıcıları Sil",
-      "delDepletedClientsTitle": "Kotası Dolan Kullanıcıları Sil",
-      "delDepletedClientsContent": "Kotası dolan veya süresi biten tüm kullanıcıları silmek istediğinizden emin misiniz?",
       "email": "E-posta",
-      "emailDesc": "Lütfen benzersiz bir e-posta adresi sağlayın.",
       "IPLimit": "IP Limiti",
-      "IPLimitDesc": "Sayının aşılması durumunda gelen bağlantı devre dışı bırakılır. (0 = devre dışı)",
       "IPLimitlog": "IP Günlüğü",
-      "IPLimitlogDesc": "IP geçmiş günlüğü. (devre dışı bırakıldıktan sonra yeniden etkinleştirmek için günlüğü temizleyin)",
       "IPLimitlogclear": "Günlüğü Temizle",
       "setDefaultCert": "Panelden Sertifikayı Ayarla",
       "setDefaultCertEmpty": "Panel için sertifika yapılandırılmamış. Önce Ayarlar'dan ayarlayın.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Xray sniffing bloğunun sarmalayıcısı:",
         "stream": "Stream",
-        "streamHelp": "Xray stream bloğunun sarmalayıcısı:",
-        "jsonErrorPrefix": "Gelişmiş JSON"
+        "streamHelp": "Xray stream bloğunun sarmalayıcısı:"
       },
-      "telegramDesc": "Lütfen Telegram Sohbet Kimliği (Chat ID) sağlayın. ({'@'}userinfobot'tan öğrenebilir veya botta '/id' komutunu kullanabilirsiniz.)",
-      "subscriptionDesc": "Abonelik URL'nizi bulmak için 'Detaylar'a gidin. Aynı adı birden fazla kullanıcı için kullanabilirsiniz.",
       "subSortIndex": "Sıralama",
-      "same": "Aynı",
       "inboundInfo": "Gelen Bağlantı Bilgileri",
       "exportInbound": "Gelen Bağlantını Dışa Aktar",
       "import": "İçe Aktar",
       "importInbound": "Gelen Bağlantı İçe Aktar",
       "periodicTrafficResetTitle": "Trafik Sıfırlama",
-      "periodicTrafficResetDesc": "Belirtilen aralıklarla trafik sayacını otomatik olarak sıfırla",
       "periodicTrafficResetDay": "Aylık sıfırlama günü",
-      "lastReset": "Son Sıfırlama",
       "periodicTrafficReset": {
         "never": "Asla",
         "daily": "Günlük",
@@ -464,7 +401,6 @@
         "obtain": "Al",
         "updateSuccess": "Güncelleme başarılı oldu.",
         "logCleanSuccess": "Günlük temizlendi.",
-        "inboundsUpdateSuccess": "Gelen bağlantılar başarıyla güncellendi.",
         "inboundUpdateSuccess": "Gelen bağlantı başarıyla güncellendi.",
         "inboundCreateSuccess": "Gelen bağlantı başarıyla oluşturuldu.",
         "bulkDeleted": "{count} gelen bağlantı silindi",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Gelen bağlantı kullanıcısı silindi.",
         "inboundClientUpdateSuccess": "Gelen bağlantı kullanıcısı güncellendi.",
         "savedNodeOfflineWillSync": "Yerel olarak kaydedildi. Destekleyen bir düğüm çevrimdışı veya devre dışı — değişiklik yeniden bağlandığında senkronize edilecek.",
-        "delDepletedClientsSuccess": "Tüm tükenmiş kullanıcılar silindi.",
         "resetAllClientTrafficSuccess": "Tüm kullanıcıların trafiği sıfırlandı.",
         "resetAllTrafficSuccess": "Tüm trafik sıfırlandı.",
         "resetInboundClientTrafficSuccess": "Trafik sıfırlandı.",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Peer {n} Yapılandırması"
       },
-      "stream": {
-        "general": {
-          "request": "İstek",
-          "response": "Yanıt",
-          "name": "Ad",
-          "value": "Değer"
-        },
-        "tcp": {
-          "version": "Sürüm",
-          "method": "Yöntem",
-          "path": "Yol",
-          "status": "Durum",
-          "statusDescription": "Durum Açıklaması",
-          "requestHeader": "İstek Başlığı",
-          "responseHeader": "Yanıt Başlığı"
-        }
-      },
       "sniffingDestOverride": "Hedef geçersiz kılma"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Harici Abonelik Ekle",
       "noExternalLinks": "Henüz harici bağlantı yok.",
       "noExternalSubscriptions": "Henüz harici abonelik yok.",
-      "add": "Kullanıcı Ekle",
-      "edit": "Kullanıcıyı Düzenle",
-      "submitAdd": "Kullanıcı Ekle",
       "submitEdit": "Değişiklikleri Kaydet",
       "clientCount": "Kullanıcı Sayısı",
       "bulk": "Toplu Ekle",
-      "copyFromInbound": "Gelen Bağlantından Kullanıcıları Kopyala",
-      "copyToInbound": "Kullanıcıların Kopyalanacağı Yer",
-      "copySelected": "Seçileni Kopyala",
-      "copySource": "Kaynak",
-      "copyEmailPreview": "Oluşacak E-posta Önizlemesi",
-      "copySelectSourceFirst": "Önce bir kaynak gelen bağlantı seçin.",
-      "copyResult": "Kopya Sonucu",
-      "copyResultSuccess": "Başarıyla kopyalandı",
-      "copyResultNone": "Kopyalanacak bir şey yok: kullanıcı seçilmemiş veya kaynak boş.",
-      "copyResultErrors": "Kopyalama Hataları",
-      "copyFlowLabel": "Yeni Kullanıcılar İçin Flow (VLESS)",
-      "copyFlowHint": "Kopyalanan tüm kullanıcılara uygulanır. Atlamak için boş bırakın.",
       "selectAll": "Tümünü Seç",
       "clearAll": "Tümünü Temizle",
       "method": "Yöntem",
@@ -775,7 +678,6 @@
       "postfix": "Sonek",
       "delayedStart": "İlk Kullanımdan Sonra Başla",
       "expireDays": "Süre (gün)",
-      "days": "Gün(ler)",
       "renew": "Otomatik Yenileme",
       "renewDesc": "Süre dolduktan sonra otomatik yeniler. (0 = devre dışı) (birim: gün)",
       "renewDays": "Otomatik Yenileme (gün)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Yakında Biten",
       "has": "Var",
       "hasNot": "Yok",
-      "title": "Kullanıcılar",
       "actions": "İşlemler",
       "totalGB": "Trafik Limiti (GB)",
       "totalGBDesc": "Bu kullanıcı için veri kotası. 0 = sınırsız.",
@@ -826,8 +727,6 @@
       "addClient": "Kullanıcı Ekle",
       "qrCode": "QR Kodu",
       "clientInfo": "Kullanıcı Bilgileri",
-      "delete": "Sil",
-      "reset": "Trafiği Sıfırla",
       "editClient": "Kullanıcıyı Düzenle",
       "client": "Kullanıcı",
       "enabled": "Etkin",
@@ -841,13 +740,11 @@
       "noLinks": "Paylaşılabilir bağlantı yok — önce bu kullanıcıyı bir protokole sahip olan gelen bağlantıya bağlayın.",
       "link": "Bağlantı",
       "resetNotPossible": "Önce bu kullanıcıyı bir gelen bağlantıya bağlayın.",
-      "general": "Genel",
       "resetAllTraffics": "Tüm Kullanıcıların Trafiğini Sıfırla",
       "resetAllTrafficsTitle": "Tüm Kullanıcıların Trafiği Sıfırlansın Mı?",
       "resetAllTrafficsContent": "Her kullanıcının yükleme/indirme sayaçları sıfırlanır. Kotalar ve son kullanma tarihleri etkilenmez. Geri alınamaz.",
       "deleteConfirmTitle": "{email} Kullanıcısı Silinsin Mi?",
       "deleteConfirmContent": "Bu işlem kullanıcıyı bağlı tüm gelen bağlantılarndan kaldırır ve trafik kaydını siler. Geri alınamaz.",
-      "deleteSelected": "Sil ({count})",
       "adjustSelected": "Ayarla ({count})",
       "subLinksSelected": "Abonelik Bağlantıları ({count})",
       "addToGroupTitle": "{count} Kullanıcıyı Bir Gruba Ekle",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "{count} kullanıcı devre dışı bırakılsın mı?",
       "bulkDisableConfirmContent": "Seçili her kullanıcıyı bağlı olduğu tüm gelen bağlantılarda devre dışı bırakır. Erişimlerini hemen kaybederler ancak kayıtları ve trafikleri korunur.",
       "selectedCount": "{count} Seçildi",
-      "attachSelected": "Bağla ({count})",
       "attachToInboundsTitle": "{count} Kullanıcıyı Gelen Bağlantına Bağla",
       "attachToInboundsDesc": "Seçilen {count} kullanıcıyı (aynı UUID/şifre ve paylaşılan trafikle) seçilen gelen bağlantıya bağlar. Mevcut bağlantıları da korunur.",
       "attachToInboundsTargets": "Hedef Gelen Bağlantılar",
       "attachToInboundsNoTargets": "Bağlanacak çoklu kullanıcılı gelen bağlantı yok.",
-      "detachSelected": "Ayır ({count})",
       "detach": "Ayır",
       "detachFromInboundsTitle": "{count} Kullanıcıyı Gelen Bağlantından Ayır",
       "detachFromInboundsDesc": "Seçilen {count} kullanıcıyı seçilen gelen bağlantıdan kaldırır. Kullanıcının zaten bağlı olmadığı gelen bağlantılar atlanır. Kullanıcı kayıtları korunur (tamamen kaldırmak için Sil'i kullanın).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "İsteğe Bağlı Reverse Tag",
       "telegramId": "Telegram Kullanıcı ID'si",
       "telegramIdPlaceholder": "Sayısal Telegram kullanıcı ID'si (0 = yok)",
-      "created": "Oluşturuldu",
-      "updated": "Güncellendi",
       "ipLimit": "IP Limiti",
       "toasts": {
         "deleted": "Kullanıcı silindi",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Gruplar",
       "name": "İsim",
       "clientCount": "Kullanıcılar",
       "totalGroups": "Toplam grup",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "{name} grubundan {count} kullanıcı çıkarıldı."
     },
     "nodes": {
-      "title": "Düğümler",
       "addNode": "Düğüm Ekle",
       "editNode": "Düğümü Düzenle",
       "totalNodes": "Toplam Düğüm",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Uzak panelin Ayarlar sayfasındaki token",
       "apiTokenHint": "Uzak panel API token'ını Kimlik Doğrulama → API Token altında gösterir.",
       "apiTokenKeepHint": "Mevcut token'ı korumak için boş bırakın",
-      "regenerate": "Token'ı Yeniden Oluştur",
-      "regenerateConfirm": "Yeniden oluşturmak mevcut token'ı geçersiz kılar. Onu kullanan tüm merkezi paneller, güncellenene kadar erişimini kaybeder. Devam edilsin mi?",
       "allowPrivateAddress": "Özel Adrese İzin Ver",
       "allowPrivateAddressHint": "Yalnızca özel ağ veya VPN üzerindeki düğümler için etkinleştirin.",
       "outboundTag": "Bağlantı gideni",
@@ -1046,7 +935,6 @@
       "updatePanel": "Paneli Güncelle",
       "updateSelected": "Seçilenleri Güncelle ({count})",
       "updateAvailable": "Güncelleme mevcut",
-      "upToDate": "Güncel",
       "updateConfirmTitle": "{count} düğüm en son sürüme güncellensin mi?",
       "updateConfirmContent": "Seçilen her düğüm en son sürümü indirir ve yeniden başlatılır. Yalnızca etkin ve çevrimiçi düğümler güncellenir.",
       "updateDevChannel": "Dev kanalına güncelle (son commit)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Sertifika alınamadı"
     },
     "settings": {
+      "defaultTag": "Varsayılan",
       "title": "Panel Ayarları",
       "save": "Kaydet",
       "infoDesc": "Burada yapılan her değişikliğin kaydedilmesi gerekir. Değişikliklerin uygulanması için paneli yeniden başlatın.",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "Temizlemeyi geri al"
     },
     "xray": {
-      "title": "Xray Yapılandırmaları",
       "save": "Kaydet",
-      "restart": "Xray'i Yeniden Başlat",
       "restartSuccess": "Xray başarıyla yeniden başlatıldı.",
-      "restartOutputTitle": "Xray yeniden başlatma çıktısı",
-      "restartConfirmTitle": "Xray'i Yeniden Başlat?",
-      "restartConfirmContent": "Xray hizmeti kaydedilmiş yapılandırma ile yeniden yüklenir.",
       "stopSuccess": "Xray başarıyla durduruldu.",
       "restartError": "Xray yeniden başlatılırken bir hata oluştu.",
       "stopError": "Xray durdurulurken bir hata oluştu.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "Bu seçenekler genel ayarlamaları belirler.",
       "logConfigs": "Günlük",
       "logConfigsDesc": "Günlükler sunucunuzun verimliliğini etkileyebilir. Yalnızca ihtiyaç durumunda akıllıca etkinleştirmeniz önerilir.",
-      "blockConfigsDesc": "Bu seçenekler belirli istek protokolleri ve web siteleri temelinde trafiği engeller.",
       "basicRouting": "Temel Yönlendirme",
       "blockConnectionsConfigsDesc": "Bu seçenekler, istenen belirli ülkelere göre trafiği engelleyecektir.",
       "directConnectionsConfigsDesc": "Doğrudan bağlantı, belirli bir trafiğin başka bir sunucu üzerinden yönlendirilmeden doğrudan hedefe gitmesini sağlar.",
@@ -1473,10 +1356,6 @@
       "directdomains": "Doğrudan Alan Adları",
       "ipv4Routing": "IPv4 Yönlendirme",
       "ipv4RoutingDesc": "Bu seçenekler belirli bir varış yerine IPv4 üzerinden trafiği yönlendirir.",
-      "warpRouting": "WARP Yönlendirme",
-      "warpRoutingDesc": "Bu seçenekler belirli bir varış yerine WARP üzerinden trafiği yönlendirir.",
-      "nordRouting": "NordVPN Yönlendirme",
-      "nordRoutingDesc": "Bu seçenekler belirli bir varış yerine NordVPN üzerinden trafiği yönlendirir.",
       "Template": "Gelişmiş Xray Yapılandırma Şablonu",
       "TemplateDesc": "Nihai Xray yapılandırma dosyası bu şablona göre oluşturulacaktır.",
       "FreedomStrategy": "Freedom Protokol Stratejisi",
@@ -1498,10 +1377,7 @@
       "metricsTag": "Metrik Etiketi",
       "Torrent": "BitTorrent Protokolünü Engelle",
       "Inbounds": "Gelen Bağlantılar",
-      "InboundsDesc": "Belirtilen istemcileri (clients) kabul eder.",
       "Outbounds": "Giden Bağlantılar",
-      "OutboundSubscriptions": "Giden Bağlantı Abonelikleri",
-      "OutboundSubscriptionsDesc": "Uzak abonelik URL'lerinden (vmess/vless/trojan/ss/...) giden bağlantılarnı içe aktarın. Etiketler dengeleyicilerde ve yönlendirme kurallarında kullanılabilmek için sabit tutulur. Güncellemeler otomatiktir.",
       "Balancers": "Dengeleyiciler",
       "balancerTagRequired": "Etiket zorunludur",
       "balancerSelectorRequired": "En az bir giden bağlantı seçin",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "Eşleşen giden",
       "routeTesterViaBalancer": "dengeleyici aracılığıyla",
       "routeTesterDefaultOutbound": "Hiçbir yönlendirme kuralı eşleşmedi — trafik varsayılan (ilk) giden bağlantıya yönlendirilir.",
-      "OutboundsDesc": "Giden trafiğin yolunu ayarlayın.",
       "Routings": "Yönlendirme Kuralları",
-      "RoutingsDesc": "Her kuralın önceliği önemlidir!",
       "completeTemplate": "Tümü",
       "logLevel": "Günlük Seviyesi",
       "logLevelDesc": "Hata günlükleri için kayıt seviyesi; hangi detayda bilginin kaydedileceğini belirler.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "IP adresi maskesi, etkinleştirildiğinde günlükte görünen IP adresini otomatik olarak değiştirecektir.",
       "statistics": "İstatistikler",
       "statsInboundUplink": "Gelen Yükleme İstatistikleri",
-      "statsInboundUplinkDesc": "Tüm gelen proxy'lerin yükleme trafiği için istatistik toplamayı etkinleştirir.",
       "statsInboundDownlink": "Gelen İndirme İstatistikleri",
-      "statsInboundDownlinkDesc": "Tüm gelen proxy'lerin indirme trafiği için istatistik toplamayı etkinleştirir.",
       "statsOutboundUplink": "Giden Yükleme İstatistikleri",
-      "statsOutboundUplinkDesc": "Tüm giden proxy'lerin yükleme trafiği için istatistik toplamayı etkinleştirir.",
       "statsOutboundDownlink": "Giden İndirme İstatistikleri",
-      "statsOutboundDownlinkDesc": "Tüm giden proxy'lerin indirme trafiği için istatistik toplamayı etkinleştirir.",
       "connectionLimits": "Bağlantı Sınırları",
       "connectionLimitsDesc": "Kullanıcı seviyesi 0 için bağlantı düzeyi politikaları. Xray'in varsayılanını kullanmak için alanı boş bırakın.",
       "connIdle": "Boşta Kalma Zaman Aşımı",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "otomatik",
       "seconds": "saniye",
       "rules": {
-        "first": "İlk",
-        "last": "Son",
-        "up": "Yukarı",
-        "down": "Aşağı",
         "source": "Kaynak",
         "dest": "Hedef",
         "inbound": "Gelen Bağlantı",
-        "outbound": "Giden Bağlantı",
         "balancer": "Dengeleyici",
-        "info": "Bilgi",
-        "add": "Kural Ekle",
-        "edit": "Kuralı Düzenle",
         "useComma": "Virgülle ayrılmış öğeler"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Kural {n}",
         "action": "Eylem",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Nihai Kurallar",
         "overrideXrayPrivateIp": "Xray'in varsayılan özel IP bloğunu geçersiz kıl",
         "blockDelay": "Engelleme Gecikmesi (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Keep Alive Aralığı",
         "markFwmark": "Mark (fwmark)",
         "interface": "Arabirim",
-        "ipv6Only": "Yalnızca IPv6",
-        "acceptProxyProtocol": "Proxy Protocol Kabul Et",
         "proxyProtocol": "Proxy Protocol",
         "tcpUserTimeoutMs": "TCP User Timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "Giden Bağlantı Ekle",
-        "addReverse": "Ters Ekle",
-        "editOutbound": "Giden Bağlantını Düzenle",
-        "editReverse": "Tersi Düzenle",
-        "reverseTag": "Ters Etiket",
-        "reverseTagDesc": "VLESS basit ters proxy giden bağlantı etiketi. Devre dışı bırakmak için boş bırakın.",
-        "reverseTagPlaceholder": "çıkış etiketi (boş = devre dışı)",
         "tag": "Etiket",
-        "tagDesc": "Benzersiz Etiket",
-        "address": "Adres",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Ters",
-        "domain": "Alan Adı",
-        "type": "Tür",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Bağlantı",
-        "intercon": "Bağlantı",
-        "settings": "Ayarlar",
-        "accountInfo": "Hesap Bilgileri",
         "outboundStatus": "Giden Bağlantı Durumu",
         "sendThrough": "Üzerinden Gönder",
         "targetStrategy": "Hedef Stratejisi",
-        "test": "Test",
-        "testResult": "Test Sonucu",
-        "testing": "Bağlantı test ediliyor...",
-        "testSuccess": "Test başarılı",
-        "testFailed": "Test başarısız",
-        "testError": "Giden bağlantı test edilemedi",
         "modeRealDelay": "Gerçek gecikme",
         "testModeTooltip": "TCP: hızlı sadece arama (dial-only) testi. HTTP: Xray üzerinden tam istek. Gerçek gecikme: bağlantı kurulumu dahil toplam süre.",
         "testAll": "Tümünü Test Et",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Proxy bağlantısı",
         "breakdownTls": "Giden üzerinden TLS",
         "breakdownTtfb": "İlk bayt",
-        "nordvpn": "NordVPN",
-        "accessToken": "Erişim Jetonu",
         "country": "Ülke",
         "server": "Sunucu",
         "city": "Şehir",
         "allCities": "Tüm Şehirler",
-        "privateKey": "Özel Anahtar",
-        "load": "Yükle",
         "moveToTop": "En üste taşı"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Aktif abonelikler",
         "empty": "Henüz hiç abonelik yok. Yukarıdan bir tane ekleyin.",
         "colRemark": "Açıklama",
-        "colPrefix": "Önek",
-        "colInterval": "Aralık",
         "colLastFetch": "Son getirme",
         "colEnabled": "Etkin",
         "auto": "otomatik",
         "never": "asla",
-        "yes": "Evet",
-        "no": "Hayır",
         "refreshNow": "Şimdi yenile",
-        "lastError": "Son hata",
         "deleteConfirm": "Bu aboneliği silmek istiyor musunuz?",
         "restartHint": "Ekledikten veya yeniledikten sonra giden bağlantılarnı aktif hale getirmek için Xray'i yeniden başlatın (veya bir sonraki otomatik yeniden yüklemeyi bekleyin).",
         "fromSubsTitle": "Giden bağlantı aboneliklerinden (salt okunur)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Dengeleyici Ayarları",
       "tabObservatory": "Gözlemci",
       "observatory": {
-        "title": "Gözlemci",
-        "burstTitle": "Burst Gözlemci",
         "autoManaged": "Gözlemciler dengeleyicilerinize göre otomatik yönetilir. Nasıl sınama yapacaklarını aşağıdan ayarlayın; izlenen çıkışlar dengeleyici seçicilerini izler.",
         "emptyHint": "Etkin bir bağlantı gözlemcisi yok. Least Ping veya Least Load dengeleyici — ya da fallback içeren Random / Round-robin dengeleyici — oluşturduğunuzda otomatik olarak bir tane eklenir; böylece gözlemci kullanan dengeleyiciler hedef seçmeden önce çıkış sağlığını kontrol edebilir.",
         "mixedLegacy": "Bu yapılandırmada hem Observatory hem de Burst Observatory var. Xray tek bir global gözlemci kullanır, bu nedenle bu eski karma durum desteklenmez; dengeleyiciler kaydedildiğinde tek bir gözlemciye normalleştirilir.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Dengeleyici {tag} — kaldırıldı (hedef kalmadı)"
       },
       "balancer": {
-        "addBalancer": "Dengeleyici Ekle",
-        "editBalancer": "Dengeleyiciyi Düzenle",
         "balancerStrategy": "Strateji",
-        "balancerSelectors": "Seçiciler",
         "tag": "Etiket",
-        "tagDesc": "Benzersiz Etiket",
         "tagDuplicate": "Etiket başka bir dengeleyici tarafından kullanılıyor",
         "tagPlaceholder": "benzersiz dengeleyici etiketi",
         "selector": "Seçici",
@@ -1789,7 +1609,6 @@
         "tolerance": "Tolerans",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "Dengeleyici Etiketi (balancerTag) ve Giden Bağlantı Etiketi (outboundTag) aynı anda kullanılamaz. Aynı anda kullanıldığında yalnızca giden bağlantı etiketi geçerli olur.",
         "costMatch": "Etiket deseni",
         "costValue": "Ağırlık",
         "costRegexp": "Düzenli ifade eşleşmesi",
@@ -1804,14 +1623,10 @@
         "publicKey": "Genel Anahtar",
         "allowedIPs": "İzin Verilen IP'ler",
         "endpoint": "Uç Nokta",
-        "psk": "Ön Paylaşılan Anahtar",
         "domainStrategy": "Alan Adı Stratejisi"
       },
       "tun": {
-        "nameDesc": "TUN arabiriminin adı. Varsayılan değer 'xray0'dır.",
-        "mtuDesc": "Maksimum İletim Birimi. Veri paketlerinin maksimum boyutu. Varsayılan değer 1500'dür.",
-        "userLevel": "Kullanıcı Seviyesi",
-        "userLevelDesc": "Bu gelen bağlantı üzerinden yapılan tüm bağlantılar bu kullanıcı seviyesini kullanacaktır. Varsayılan değer 0'dır."
+        "userLevel": "Kullanıcı Seviyesi"
       },
       "nord": {
         "accessToken": "Access Token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Sahte DNS Ekle",
-        "edit": "Sahte DNS'i Düzenle",
         "ipPool": "IP Havuzu Alt Ağı",
         "poolSize": "Havuz Boyutu"
       },
@@ -2032,7 +1846,6 @@
     "add": "Ekle",
     "month": "Ay",
     "months": "Aylar",
-    "day": "Gün",
     "days": "Günler",
     "hours": "Saatler",
     "minutes": "Dakikalar",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Telegram Kullanıcısı kaydedildi.",
       "loginSuccess": "✅ Panele başarıyla giriş yapıldı.\r\n",
       "loginFailed": "❗️Panele giriş denemesi başarısız oldu.\r\n",
-      "2faFailed": "2FA Hatası",
       "report": "🕰 Planlanmış Raporlar: {{ .RunTime }}\r\n",
       "datetime": "⏰ Tarih ve Saat: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 İndirme: ↓{{ .Download }}\r\n",
       "total": "📊 Toplam: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Telegram Kullanıcısı: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Limiti Dolanlar ({{ .Type }}):\r\n",
       "exhaustedCount": "🚨 Limiti Dolan {{ .Type }} sayısı:\r\n",
       "onlinesCount": "🌐 Çevrimiçi Kullanıcılar: {{ .Count }}\r\n",
       "disabled": "🛑 Devre Dışı: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Yenilendi: {{ .Time }}\r\n\r\n",
       "yes": "✅ Evet",
       "no": "❌ Hayır",
-      "received_id": "🔑📥 Kimlik (ID) güncellendi.",
-      "received_password": "🔑📥 Şifre güncellendi.",
       "received_email": "📧📥 E-posta güncellendi.",
       "received_comment": "💬📥 Yorum güncellendi.",
-      "id_prompt": "🔑 Mevcut Kimlik (ID): {{ .ClientId }}\n\nYeni kimliğinizi (ID) girin.",
-      "pass_prompt": "🔑 Varsayılan Şifre: {{ .ClientPassword }}\n\nŞifrenizi girin.",
       "email_prompt": "📧 Varsayılan E-posta: {{ .ClientEmail }}\n\nE-postanızı girin.",
       "comment_prompt": "💬 Varsayılan Yorum: {{ .ClientComment }}\n\nYorumunuzu girin.",
-      "inbound_client_data_id": "🔄 Gelen Bağlantı: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Kota: {{ .ClientTraffic }}\n📅 Bitiş Tarihi: {{ .ClientExp }}\n🌐 IP Sınırı: {{ .IpLimit }}\n💬 Açıklama: {{ .ClientComment }}\n\nArtık bu kullanıcıyı gelen bağlantıya ekleyebilirsiniz!",
-      "inbound_client_data_pass": "🔄 Gelen Bağlantı: {{ .InboundRemark }}\n\n🔑 Şifre: {{ .ClientPass }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Kota: {{ .ClientTraffic }}\n📅 Bitiş Tarihi: {{ .ClientExp }}\n🌐 IP Sınırı: {{ .IpLimit }}\n💬 Açıklama: {{ .ClientComment }}\n\nArtık bu kullanıcıyı gelen bağlantıya ekleyebilirsiniz!",
       "cancel": "❌ İşlem iptal edildi! \n\nİstediğiniz zaman /start ile yeniden başlayabilirsiniz. 🔄",
       "error_add_client": "⚠️ Hata:\n\n {{ .error }}",
       "using_default_value": "Tamam, varsayılan değeri kullanacağım. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Hata: {{ .Error }}",
       "eventNodeDown": "{{ .Name }} düğümü ÇEVRİMDIŞI",
       "eventNodeUp": "{{ .Name }} düğümü ÇEVRİMİÇİ",
-      "eventCPUHigh": "Yüksek CPU",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "{{ .Source }} adresinden oturum açma başarısız",
       "memoryThreshold": "Bellek kullanımı {{ .Percent }}% eşiği {{ .Threshold }}% aşıyor"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Devre Dışı Olarak Gönder ☑️",
       "submitEnable": "Etkin Olarak Gönder ✅",
       "use_default": "🏷️ Varsayılanı Kullan",
-      "change_id": "⚙️🔑 Kimlik",
-      "change_password": "⚙️🔑 Şifre",
       "change_email": "⚙️📧 E-posta",
       "change_comment": "⚙️💬 Yorum",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Tüm Trafikleri Sıfırla",
       "SortedTrafficUsageReport": "Sıralı Trafik Kullanım Raporu"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "{{ .Tag }} giden bağlantısı ÇEVRİMDIŞI",
-    "subjectOutboundUp": "{{ .Tag }} giden bağlantısı ÇEVRİMİÇİ",
-    "subjectXrayCrash": "Xray ÇÖKTÜ",
-    "subjectCPUHigh": "Yüksek CPU",
-    "subjectLoginSuccess": "Oturum açma başarılı",
-    "subjectLoginFailed": "Oturum açma başarısız",
-    "titleOutboundDown": "Giden Bağlantı ÇEVRİMDIŞI",
-    "titleOutboundUp": "Giden Bağlantı ÇEVRİMİÇİ",
-    "titleXrayCrash": "Xray ÇÖKTÜ",
-    "titleCPUHigh": "Yüksek CPU",
-    "titleLoginSuccess": "Oturum açma başarılı",
-    "titleLoginFailed": "Oturum açma başarısız",
     "labelStatus": "Durum",
     "labelOutbound": "Giden Bağlantı",
     "labelNode": "Düğüm",
     "labelError": "Hata",
     "labelDelay": "Gecikme",
-    "labelDetail": "Ayrıntı",
     "labelUsername": "Kullanıcı Adı",
     "labelIP": "IP",
     "labelReason": "Neden",
     "labelSource": "Kaynak",
-    "labelTime": "Zaman",
     "statusCrashed": "ÇÖKTÜ",
-    "statusRunning": "Çalışıyor",
     "statusHigh": "YÜKSEK",
     "statusSuccess": "BAŞARILI",
     "statusFailed": "BAŞARISIZ",

+ 3 - 218
internal/web/translation/uk-UA.json

@@ -48,7 +48,6 @@
   "copySuccess": "Скопійовано успішно",
   "sure": "Звичайно",
   "encryption": "Шифрування",
-  "useIPv4ForHost": "Використовувати IPv4 для хоста",
   "transmission": "Протокол передачи",
   "host": "Хост",
   "path": "Шлях",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Код",
   "remained": "Залишилося",
   "security": "Беспека",
-  "secAlertTitle": "Попередження системи безпеки",
-  "secAlertSsl": "Це з'єднання не є безпечним. Будь ласка, уникайте введення конфіденційної інформації, поки TLS не буде активовано для захисту даних.",
-  "secAlertConf": "Деякі налаштування вразливі до атак. Рекомендується посилити протоколи безпеки, щоб запобігти можливим порушенням.",
-  "secAlertSSL": "Панель не має безпечного з'єднання. Будь ласка, встановіть сертифікат TLS для захисту даних.",
-  "secAlertPanelPort": "Стандартний порт панелі вразливий. Будь ласка, сконфігуруйте випадковий або конкретний порт.",
-  "secAlertPanelURI": "Стандартний URI-шлях панелі небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
-  "secAlertSubURI": "Стандартний URI-шлях підписки небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
-  "secAlertSubJsonURI": "Стандартний URI-шлях JSON підписки небезпечний. Будь ласка, сконфігуруйте складний URI-шлях.",
   "emptyDnsDesc": "Немає доданих DNS-серверів.",
   "emptyFakeDnsDesc": "Немає доданих Fake DNS-серверів.",
   "emptyBalancersDesc": "Немає доданих балансувальників.",
-  "emptyReverseDesc": "Немає доданих зворотних проксі.",
   "somethingWentWrong": "Щось пішло не так",
   "subscription": {
     "title": "Інформація про підписку",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Тема",
-    "dark": "Темна",
-    "ultraDark": "Ультра темна",
     "dashboard": "Огляд",
     "inbounds": "Вхідні",
     "clients": "Клієнти",
@@ -118,7 +106,6 @@
     "routing": "Маршрутизація",
     "outbounds": "Вихідні",
     "apiDocs": "Документація API",
-    "logout": "Вийти",
     "link": "Керувати",
     "donate": "Підтримати",
     "hosts": "Хости",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Огляд",
       "cpu": "ЦП",
       "logicalProcessors": "Логічні процесори",
       "frequency": "Частота",
@@ -152,7 +138,6 @@
       "restartXray": "Перезапуск",
       "xraySwitch": "Версія",
       "xrayUpdates": "Оновлення Xray",
-      "xraySwitchClick": "Виберіть версію, на яку ви хочете перейти.",
       "xraySwitchClickDesk": "Вибирайте уважно, оскільки старіші версії можуть бути несумісними з поточними конфігураціями.",
       "updatePanel": "Оновити панель",
       "panelUpdateDesc": "Це оновить 3X-UI до останнього релізу та перезапустить сервіс панелі.",
@@ -164,12 +149,10 @@
       "currentCommit": "Поточний коміт",
       "latestCommit": "Останній коміт",
       "updateChannelChanged": "Канал оновлення змінено",
-      "upToDate": "Оновлено",
       "xrayStatusUnknown": "Невідомо",
       "xrayStatusRunning": "Запущено",
       "xrayStatusStop": "Зупинено",
       "xrayStatusError": "Помилка",
-      "xrayErrorPopoverTitle": "Під час роботи Xray сталася помилка",
       "operationHours": "Час роботи",
       "systemHistoryTitle": "Історія системи",
       "historyTitleCpu": "Завантаження ЦП",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Недоступний",
       "xrayObservatoryLastSeen": "Остання активність",
       "xrayObservatoryLastTry": "Остання спроба",
-      "trendLast2Min": "Останні 2 хвилини",
-      "systemLoad": "Завантаження системи",
-      "systemLoadDesc": "Середнє завантаження системи за останні 1, 5 і 15 хвилин",
       "connectionCount": "Статистика з'єднання",
       "ipAddresses": "IP-адреси",
       "toggleIpVisibility": "Перемкнути видимість IP",
@@ -223,13 +203,11 @@
       "totalData": "Загальний обсяг даних",
       "sent": "Відправлено",
       "received": "Отримано",
-      "documentation": "Документація",
       "xraySwitchVersionDialog": "Ви дійсно хочете змінити версію Xray?",
       "xraySwitchVersionDialogDesc": "Це змінить версію Xray на #version#.",
       "xraySwitchVersionPopover": "Xray успішно оновлено",
       "panelUpdateDialog": "Ви дійсно хочете оновити панель?",
       "panelUpdateDialogDesc": "Це оновить 3X-UI до #version# та перезапустить сервіс панелі.",
-      "panelUpdateCheckPopover": "Перевірка оновлення панелі не вдалася",
       "panelUpdateStartedPopover": "Розпочато оновлення панелі",
       "panelUpdateFailedTitle": "Не вдалося оновити панель",
       "panelUpdateFailedDesc": "Оновлення не завершилося успішно. Перевірте журнали сервера або виконайте 'x-ui update' у командному рядку.",
@@ -258,7 +236,6 @@
       "accessLogs": "Логи доступу",
       "autoUpdate": "Автооновлення",
       "config": "Конфігурація",
-      "backup": "Резервна копія",
       "backupTitle": "Резервне копіювання та відновлення",
       "exportDatabase": "Резервна копія",
       "exportDatabaseDesc": "Натисніть, щоб завантажити файл .db, що містить резервну копію вашої поточної бази даних на ваш пристрій. Цей самий файл можна відновити на панелі, що працює на PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Натисніть, щоб завантажити базу даних SQLite (.db), створену з ваших даних PostgreSQL і готову для запуску панелі на SQLite."
     },
     "inbounds": {
-      "title": "Вхідні",
       "totalDownUp": "Всього надісланих/отриманих",
       "totalUsage": "Всього використанно",
       "inboundCount": "Загальна кількість вхідних",
@@ -288,21 +264,11 @@
       "localPanel": "Локальна панель",
       "fallbacks": {
         "title": "Fallback'и",
-        "help": "Коли з'єднання на цьому інбаунді не збігається з жодним клієнтом, воно перенаправляється в інше місце. Оберіть дочірній інбаунд нижче, щоб поля маршрутизації (SNI / ALPN / Path / xver) заповнилися автоматично з його транспорту, або залиште вибір порожнім і задайте Dest напряму (наприклад, 8080 або 127.0.0.1:8080), щоб перенаправити на зовнішній сервер, такий як Nginx. Кожен дочірній інбаунд має слухати на 127.0.0.1 з security=none.",
         "empty": "Фолбеків поки немає",
         "add": "Додати фолбек",
         "pickInbound": "Оберіть інбаунд",
         "matchAny": "будь-який",
         "destPlaceholder": "авто (listen:порт дочірнього)",
-        "rederive": "Заповнити з дочірнього",
-        "rederived": "Заповнено з дочірнього",
-        "editAdvanced": "Редагувати поля маршрутизації",
-        "hideAdvanced": "Сховати розширені",
-        "quickAddAll": "Швидко додати всі придатні",
-        "quickAdded": "Додано {n} фолбек(ів)",
-        "quickAddedNone": "Немає нових придатних інбаундів",
-        "routesWhen": "Маршрутизує, коли",
-        "defaultCatchAll": "За замовчуванням — ловить усе інше",
         "needsTls": "Fallbacks стануть доступні після вибору TLS або Reality на вкладці «Безпека» (лише VLESS/Trojan поверх RAW)."
       },
       "protocol": "Протокол",
@@ -310,8 +276,6 @@
       "portMap": "Відображення портів",
       "traffic": "Трафік",
       "speed": "Швидкість",
-      "details": "Деталі",
-      "transportConfig": "Транспорт",
       "expireDate": "Тривалість",
       "createdAt": "Створено",
       "updatedAt": "Оновлено",
@@ -319,8 +283,6 @@
       "addInbound": "Додати вхідний",
       "generalActions": "Загальні дії",
       "modifyInbound": "Змінити вхідний",
-      "deleteInbound": "Видалити вхідні",
-      "deleteInboundContent": "Ви впевнені, що хочете видалити вхідні?",
       "deleteConfirmTitle": "Видалити вхідні \"{remark}\"?",
       "deleteConfirmContent": "Це видалить вхідні та всіх його клієнтів. Цю дію неможливо скасувати.",
       "resetConfirmTitle": "Скинути трафік \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Усі-вхідні",
       "exportAllSubsFileName": "Усі-вхідні-Subs",
       "inboundJsonTitle": "JSON вхідного",
-      "deleteClient": "Видалити клієнта",
-      "deleteClientContent": "Ви впевнені, що хочете видалити клієнт?",
       "resetTrafficContent": "Ви впевнені, що хочете скинути трафік?",
       "copyLink": "Копіювати URL",
       "address": "Адреса",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Без обмежень. (одиниця: ГБ)",
       "totalFlow": "Загальна витрата",
       "leaveBlankToNeverExpire": "Залиште порожнім, щоб ніколи не закінчувався",
-      "noRecommendKeepDefault": "Рекомендується зберегти значення за замовчуванням",
       "certificatePath": "Шлях до файлу",
       "certificateContent": "Вміст файлу",
       "publicKey": "Публічний ключ",
       "privatekey": "Закритий ключ",
-      "clickOnQRcode": "Натисніть QR-код, щоб скопіювати",
       "client": "Клієнт",
       "export": "Експортувати всі URL-адреси",
       "clone": "Клон",
-      "cloneInbound": "Клонувати",
-      "cloneInboundContent": "Усі налаштування цього вхідного потоку, крім порту, IP-адреси прослуховування та клієнтів, будуть застосовані до клону.",
-      "cloneInboundOk": "Клонувати",
       "resetAllTraffic": "Скинути весь вхідний трафік",
       "resetAllTrafficTitle": "Скинути весь вхідний трафік",
       "resetAllTrafficContent": "Ви впевнені, що бажаєте скинути трафік усіх вхідних?",
-      "resetInboundClientTraffics": "Скинути трафік клієнтів",
-      "resetInboundClientTrafficTitle": "Скинути трафік клієнтів",
-      "resetInboundClientTrafficContent": "Ви впевнені, що бажаєте скинути трафік клієнтів цього вхідного потоку?",
-      "resetAllClientTraffics": "Скинути весь трафік клієнтів",
-      "resetAllClientTrafficTitle": "Скинути весь трафік клієнтів",
-      "resetAllClientTrafficContent": "Ви впевнені, що бажаєте скинути трафік усіх клієнтів?",
-      "delDepletedClients": "Видалити вичерпані клієнти",
-      "delDepletedClientsTitle": "Видалити вичерпані клієнти",
-      "delDepletedClientsContent": "Ви впевнені, що хочете видалити всі вичерпані клієнти?",
       "email": "Email",
-      "emailDesc": "Будь ласка, надайте унікальну адресу електронної пошти.",
       "IPLimit": "Обмеження IP",
-      "IPLimitDesc": "Вимикає вхідний, якщо кількість перевищує встановлене значення. (0 = вимкнено)",
       "IPLimitlog": "Журнал IP",
-      "IPLimitlogDesc": "Журнал історії IP-адрес. (щоб увімкнути вхідну після вимкнення, очистіть журнал)",
       "IPLimitlogclear": "Очистити журнал",
       "setDefaultCert": "Установити сертифікат з панелі",
       "setDefaultCertEmpty": "Для панелі не налаштовано сертифікат. Спочатку встановіть його в Налаштуваннях.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Обгортка блоку sniffing Xray:",
         "stream": "Stream",
-        "streamHelp": "Обгортка блоку stream Xray:",
-        "jsonErrorPrefix": "Розширений JSON"
+        "streamHelp": "Обгортка блоку stream Xray:"
       },
-      "telegramDesc": "Будь ласка, вкажіть ID чату Telegram. (використовуйте команду '/id' у боті) або ({'@'}userinfobot)",
-      "subscriptionDesc": "Щоб знайти URL-адресу вашої підписки, перейдіть до «Деталі». Крім того, ви можете використовувати одне ім'я для кількох клієнтів.",
       "subSortIndex": "Порядок",
-      "same": "Те саме",
       "inboundInfo": "Інформація про підключення",
       "exportInbound": "Експортувати вхідні",
       "import": "Імпорт",
       "importInbound": "Імпортувати вхідний",
       "periodicTrafficResetTitle": "Скидання трафіку",
-      "periodicTrafficResetDesc": "Автоматично скидати лічильник трафіку через певні проміжки часу",
       "periodicTrafficResetDay": "День щомісячного скидання",
-      "lastReset": "Останнє скидання",
       "periodicTrafficReset": {
         "never": "Ніколи",
         "daily": "Щодня",
@@ -464,7 +401,6 @@
         "obtain": "Отримати",
         "updateSuccess": "Оновлення пройшло успішно",
         "logCleanSuccess": "Журнал очищено",
-        "inboundsUpdateSuccess": "Вхідні підключення успішно оновлено",
         "inboundUpdateSuccess": "Вхідне підключення успішно оновлено",
         "inboundCreateSuccess": "Вхідне підключення успішно створено",
         "bulkDeleted": "Видалено підключень: {count}",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Клієнта вхідного підключення видалено",
         "inboundClientUpdateSuccess": "Клієнта вхідного підключення оновлено",
         "savedNodeOfflineWillSync": "Збережено локально. Опорний вузол вимкнено або недоступний — зміни синхронізуються після повторного підключення.",
-        "delDepletedClientsSuccess": "Усі вичерпані клієнти видалені",
         "resetAllClientTrafficSuccess": "Весь трафік клієнта скинуто",
         "resetAllTrafficSuccess": "Весь трафік скинуто",
         "resetInboundClientTrafficSuccess": "Трафік скинуто",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Конфіг Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Запит",
-          "response": "Відповідь",
-          "name": "Ім'я",
-          "value": "Значення"
-        },
-        "tcp": {
-          "version": "Версія",
-          "method": "Метод",
-          "path": "Шлях",
-          "status": "Статус",
-          "statusDescription": "Опис стану",
-          "requestHeader": "Заголовок запиту",
-          "responseHeader": "Заголовок відповіді"
-        }
-      },
       "sniffingDestOverride": "Перевизначення призначення"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Додати зовнішню підписку",
       "noExternalLinks": "Зовнішніх посилань ще немає.",
       "noExternalSubscriptions": "Зовнішніх підписок ще немає.",
-      "add": "Додати клієнта",
-      "edit": "Редагувати клієнта",
-      "submitAdd": "Додати клієнта",
       "submitEdit": "Зберегти зміни",
       "clientCount": "Кількість клієнтів",
       "bulk": "Масове додавання",
-      "copyFromInbound": "Скопіювати клієнтів із вхідного",
-      "copyToInbound": "Скопіювати клієнтів у",
-      "copySelected": "Скопіювати вибране",
-      "copySource": "Джерело",
-      "copyEmailPreview": "Перегляд email, що буде створено",
-      "copySelectSourceFirst": "Спочатку виберіть вхідний-джерело.",
-      "copyResult": "Результат копіювання",
-      "copyResultSuccess": "Скопійовано успішно",
-      "copyResultNone": "Нічого копіювати: не вибрано клієнтів або джерело порожнє",
-      "copyResultErrors": "Помилки копіювання",
-      "copyFlowLabel": "Flow для нових клієнтів (VLESS)",
-      "copyFlowHint": "Застосовується до всіх скопійованих клієнтів. Залишіть порожнім, щоб пропустити.",
       "selectAll": "Вибрати все",
       "clearAll": "Очистити все",
       "method": "Метод",
@@ -775,7 +678,6 @@
       "postfix": "Постфікс",
       "delayedStart": "Запуск після першого використання",
       "expireDays": "Тривалість (днів)",
-      "days": "Дні",
       "renew": "Авто-продовження",
       "renewDesc": "Автоматичне продовження після закінчення. (0 = вимкнено) (одиниця: день)",
       "renewDays": "Авто-продовження (днів)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Швидше закінчуються",
       "has": "Має",
       "hasNot": "Не має",
-      "title": "Клієнти",
       "actions": "Дії",
       "totalGB": "Ліміт трафіку (ГБ)",
       "totalGBDesc": "Квота трафіку для цього клієнта. 0 = без обмежень.",
@@ -826,8 +727,6 @@
       "addClient": "Додати клієнта",
       "qrCode": "QR-код",
       "clientInfo": "Інформація про клієнта",
-      "delete": "Видалити",
-      "reset": "Скинути трафік",
       "editClient": "Редагувати клієнта",
       "client": "Клієнт",
       "enabled": "Увімкнено",
@@ -841,13 +740,11 @@
       "noLinks": "Немає посилань для спільного доступу — спочатку прив'яжіть цього клієнта до вхідного з підтримкою протоколу.",
       "link": "Посилання",
       "resetNotPossible": "Спочатку прив'яжіть цього клієнта до вхідного.",
-      "general": "Загальне",
       "resetAllTraffics": "Скинути трафік усіх клієнтів",
       "resetAllTrafficsTitle": "Скинути трафік усіх клієнтів?",
       "resetAllTrafficsContent": "Лічильники відправлення/отримання кожного клієнта обнулюються. Квоти й термін дії не змінюються. Цю дію неможливо скасувати.",
       "deleteConfirmTitle": "Видалити клієнта {email}?",
       "deleteConfirmContent": "Клієнт буде вилучений з усіх прив'язаних вхідних, його запис трафіку буде знищено. Цю дію неможливо скасувати.",
-      "deleteSelected": "Видалити ({count})",
       "adjustSelected": "Змінити ({count})",
       "subLinksSelected": "Sub-посилання ({count})",
       "addToGroupTitle": "Додати {count} клієнт(ів) до групи",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Вимкнути {count} клієнтів?",
       "bulkDisableConfirmContent": "Вимикає кожного вибраного клієнта на всіх прив'язаних підключеннях. Вони одразу втрачають доступ, але їхні записи та трафік зберігаються.",
       "selectedCount": "Обрано {count}",
-      "attachSelected": "Прив'язати ({count})",
       "attachToInboundsTitle": "Прив'язати {count} клієнт(ів) до вхідних",
       "attachToInboundsDesc": "Прив'язує обрані {count} клієнт(ів) (той самий UUID/пароль і спільний трафік) до обраних вхідних. Існуючі прив'язки зберігаються.",
       "attachToInboundsTargets": "Цільові вхідні",
       "attachToInboundsNoTargets": "Немає доступних багатокористувацьких вхідних для прив'язки.",
-      "detachSelected": "Від'єднати ({count})",
       "detach": "Від'єднати",
       "detachFromInboundsTitle": "Від'єднати {count} клієнт(ів) від вхідних",
       "detachFromInboundsDesc": "Видаляє обраних {count} клієнт(ів) з обраних вхідних. Пари, де клієнт не був прив'язаний, тихо пропускаються. Записи клієнтів зберігаються (використовуйте Delete для повного видалення).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Необов'язковий Reverse tag",
       "telegramId": "ID користувача Telegram",
       "telegramIdPlaceholder": "Числовий ID користувача Telegram (0 = немає)",
-      "created": "Створено",
-      "updated": "Оновлено",
       "ipLimit": "Ліміт IP",
       "toasts": {
         "deleted": "Клієнта видалено",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Групи",
       "name": "Назва",
       "clientCount": "Клієнти",
       "totalGroups": "Всього груп",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "Видалено {count} клієнт(ів) з {name}."
     },
     "nodes": {
-      "title": "Вузли",
       "addNode": "Додати вузол",
       "editNode": "Змінити вузол",
       "totalNodes": "Усього вузлів",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Токен зі сторінки Налаштувань віддаленої панелі",
       "apiTokenHint": "Віддалена панель показує свій токен API в Автентифікація → Токен API.",
       "apiTokenKeepHint": "Залиште порожнім, щоб зберегти поточний токен",
-      "regenerate": "Перегенерувати токен",
-      "regenerateConfirm": "Перегенерація скасовує поточний токен. Будь-яка центральна панель, що його використовує, втратить доступ до оновлення. Продовжити?",
       "allowPrivateAddress": "Дозволити приватну адресу",
       "allowPrivateAddressHint": "Увімкнути лише для вузлів у приватній мережі або VPN.",
       "outboundTag": "Вихідне з'єднання",
@@ -1046,7 +935,6 @@
       "updatePanel": "Оновити панель",
       "updateSelected": "Оновити вибрані ({count})",
       "updateAvailable": "Доступне оновлення",
-      "upToDate": "Актуально",
       "updateConfirmTitle": "Оновити {count} вузлів до останньої версії?",
       "updateConfirmContent": "Кожен вибраний вузол завантажить останній реліз і перезапуститься. Оновлюються лише увімкнені вузли в мережі.",
       "updateDevChannel": "Оновити до каналу розробки (останній коміт)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Не вдалося отримати сертифікат"
     },
     "settings": {
+      "defaultTag": "Типово",
       "title": "Параметри панелі",
       "save": "Зберегти",
       "infoDesc": "Кожна внесена тут зміна повинна бути збережена. Перезапустіть панель, щоб застосувати зміни.",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "Скасувати очищення"
     },
     "xray": {
-      "title": "Xray конфігурації",
       "save": "Зберегти",
-      "restart": "Перезапуск Xray",
       "restartSuccess": "Xray успішно перезапущено",
-      "restartOutputTitle": "Вивід перезапуску Xray",
-      "restartConfirmTitle": "Перезапустити xray?",
-      "restartConfirmContent": "Перезавантажує сервіс xray зі збереженою конфігурацією.",
       "stopSuccess": "Xray успішно зупинено",
       "restartError": "Виникла помилка під час перезапуску Xray.",
       "stopError": "Виникла помилка під час зупинки Xray.",
@@ -1463,7 +1347,6 @@
       "generalConfigsDesc": "Ці параметри визначатимуть загальні налаштування.",
       "logConfigs": "Лог",
       "logConfigsDesc": "Журнали можуть вплинути на ефективність вашого сервера. Рекомендується вмикати його з розумом лише у випадку ваших потреб",
-      "blockConfigsDesc": "Ці параметри блокуватимуть трафік на основі конкретних запитуваних протоколів і веб-сайтів.",
       "basicRouting": "Основна Маршрутизація",
       "blockConnectionsConfigsDesc": "Ці параметри блокуватимуть трафік на основі запитаних країн.",
       "directConnectionsConfigsDesc": "Пряме з'єднання гарантує, що певний трафік не буде маршрутизовано через інший сервер.",
@@ -1473,10 +1356,6 @@
       "directdomains": "Прямі домени",
       "ipv4Routing": "Маршрутизація IPv4",
       "ipv4RoutingDesc": "Ці параметри спрямовуватимуть трафік на основі певного призначення через IPv4.",
-      "warpRouting": "WARP Маршрутизація",
-      "warpRoutingDesc": "Ці параметри маршрутизуватимуть трафік на основі певного пункту призначення через WARP.",
-      "nordRouting": "Маршрутизація NordVPN",
-      "nordRoutingDesc": "Ці параметри маршрутизуватимуть трафік на основі певного пункту призначення через NordVPN.",
       "Template": "Шаблон розширеної конфігурації Xray",
       "TemplateDesc": "Остаточний конфігураційний файл Xray буде створено на основі цього шаблону.",
       "FreedomStrategy": "Стратегія протоколу свободи",
@@ -1490,10 +1369,7 @@
       "outboundTestUrlDesc": "URL для перевірки з'єднання outbound",
       "Torrent": "Блокувати протокол BitTorrent",
       "Inbounds": "Вхідні",
-      "InboundsDesc": "Прийняття певних клієнтів.",
       "Outbounds": "Вихідні",
-      "OutboundSubscriptions": "Підписки вихідних",
-      "OutboundSubscriptionsDesc": "Імпортуйте вихідні з віддалених URL підписок (vmess/vless/trojan/ss/...). Теги залишаються стабільними для використання в балансувальниках і правилах маршрутизації. Оновлення відбувається автоматично.",
       "Balancers": "Балансери",
       "balancerTagRequired": "Тег обов'язковий",
       "balancerSelectorRequired": "Виберіть принаймні один вихідний",
@@ -1512,9 +1388,7 @@
       "routeTesterMatchedOutbound": "Відповідний вихідний",
       "routeTesterViaBalancer": "через балансувальник",
       "routeTesterDefaultOutbound": "Жодне правило маршрутизації не збіглося — трафік надходить до вихідного за замовчуванням (першого).",
-      "OutboundsDesc": "Встановити шлях вихідного трафіку.",
       "Routings": "Правила маршрутизації",
-      "RoutingsDesc": "Пріоритет кожного правила важливий!",
       "importRules": "Імпортувати правила",
       "exportRules": "Експортувати правила",
       "importOutbounds": "Імпортувати вихідні",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "Маска IP-адреси, при активації автоматично замінює IP-адресу, яка з'являється у журналі.",
       "statistics": "Статистика",
       "statsInboundUplink": "Статистика вхідного аплінку",
-      "statsInboundUplinkDesc": "Увімкнення збору статистики для вхідного трафіку всіх вхідних проксі.",
       "statsInboundDownlink": "Статистика вхідного даунлінку",
-      "statsInboundDownlinkDesc": "Увімкнення збору статистики для вихідного трафіку всіх вхідних проксі.",
       "statsOutboundUplink": "Статистика вихідного аплінку",
-      "statsOutboundUplinkDesc": "Увімкнення збору статистики для вхідного трафіку всіх вихідних проксі.",
       "statsOutboundDownlink": "Статистика вихідного даунлінку",
-      "statsOutboundDownlinkDesc": "Увімкнення збору статистики для вихідного трафіку всіх вихідних проксі.",
       "connectionLimits": "Обмеження з'єднання",
       "connectionLimitsDesc": "Політики рівня з'єднання для користувачів рівня 0. Залиште поле порожнім, щоб використовувати значення Xray за замовчуванням.",
       "connIdle": "Тайм-аут простою",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "авто",
       "seconds": "секунд",
       "rules": {
-        "first": "Перший",
-        "last": "Останній",
-        "up": "Вгору",
-        "down": "Вниз",
         "source": "Джерело",
         "dest": "Пункт призначення",
         "inbound": "Вхідний",
-        "outbound": "Вихідний",
         "balancer": "Балансувальник",
-        "info": "Інфо",
-        "add": "Додати правило",
-        "edit": "Редагувати правило",
         "useComma": "Елементи, розділені комами"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Правило {n}",
         "action": "Дія",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Фінальні правила",
         "overrideXrayPrivateIp": "Перевизначити дефолтний блок приватних IP у Xray",
         "blockDelay": "Затримка блоку (мс)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Інтервал keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Інтерфейс",
-        "ipv6Only": "Лише IPv6",
-        "acceptProxyProtocol": "Приймати proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (мс)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (с)"
       },
       "outbound": {
-        "addOutbound": "Додати вихідний",
-        "addReverse": "Додати реверс",
-        "editOutbound": "Редагувати вихідні",
-        "editReverse": "Редагувати реверс",
-        "reverseTag": "Тег реверс-проксі",
-        "reverseTagDesc": "Тег вихідного з'єднання для простого реверс-проксі VLESS. Залиште порожнім для вимкнення.",
-        "reverseTagPlaceholder": "тег вихідного (порожнє = вимкнено)",
         "tag": "Тег",
-        "tagDesc": "Унікальний тег",
-        "address": "Адреса",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Зворотний",
-        "domain": "Домен",
-        "type": "Тип",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Посилання",
-        "intercon": "Взаємозв'язок",
-        "settings": "Налаштування",
-        "accountInfo": "Інформація про обліковий запис",
         "outboundStatus": "Статус виходу",
         "sendThrough": "Надіслати через",
         "targetStrategy": "Стратегія призначення",
-        "test": "Тест",
-        "testResult": "Результат тесту",
-        "testing": "Тестування з'єднання...",
-        "testSuccess": "Тест успішний",
-        "testFailed": "Тест не пройдено",
-        "testError": "Не вдалося протестувати вихідне з'єднання",
         "modeRealDelay": "Реальна затримка",
         "testModeTooltip": "TCP: швидкий dial-only probe. HTTP: повний запит через xray. Реальна затримка: повний час із встановленням з'єднання.",
         "testAll": "Тестувати всі",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Підключення до проксі",
         "breakdownTls": "TLS через вихідний",
         "breakdownTtfb": "Перший байт",
-        "nordvpn": "NordVPN",
-        "accessToken": "Токен доступу",
         "country": "Країна",
         "server": "Сервер",
         "city": "Місто",
         "allCities": "Усі міста",
-        "privateKey": "Приватний ключ",
-        "load": "Навантаження",
         "moveToTop": "Перемістити вгору"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Активні підписки",
         "empty": "Підписок поки немає. Додайте одну вище.",
         "colRemark": "Примітка",
-        "colPrefix": "Префікс",
-        "colInterval": "Інтервал",
         "colLastFetch": "Останнє завантаження",
         "colEnabled": "Увімкнено",
         "auto": "авто",
         "never": "ніколи",
-        "yes": "Так",
-        "no": "Ні",
         "refreshNow": "Оновити зараз",
-        "lastError": "Остання помилка",
         "deleteConfirm": "Видалити цю підписку?",
         "restartHint": "Після додавання або оновлення перезапустіть Xray (або зачекайте наступного автоматичного перезавантаження), щоб вихідні стали активними.",
         "fromSubsTitle": "З підписок вихідних (лише для читання)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Налаштування балансувальника",
       "tabObservatory": "Обсерваторія",
       "observatory": {
-        "title": "Обсерваторія",
-        "burstTitle": "Burst-обсерваторія",
         "autoManaged": "Спостерігачі керуються автоматично на основі ваших балансувальників. Нижче можна налаштувати, як вони опитують; відстежувані вихідні слідують за селекторами балансувальника.",
         "emptyHint": "Немає активного спостерігача з’єднань. Його буде додано автоматично під час створення балансувальника Least Ping або Least Load — чи Random / Round-robin із fallback — щоб балансувальники зі спостерігачем могли перевіряти стан вихідних перед вибором цілі.",
         "mixedLegacy": "Ця конфігурація містить і Observatory, і Burst Observatory. Xray використовує одного глобального спостерігача, тому такий застарілий змішаний стан не підтримується; збереження балансувальників нормалізує його до одного спостерігача.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Балансувальник {tag} — видалено (не залишилося цілей)"
       },
       "balancer": {
-        "addBalancer": "Додати балансир",
-        "editBalancer": "Редагувати балансир",
         "balancerStrategy": "Стратегія",
-        "balancerSelectors": "Селектори",
         "tag": "Тег",
-        "tagDesc": "Унікальний тег",
         "tagDuplicate": "Тег уже використовується іншим балансувальником",
         "tagPlaceholder": "унікальний тег балансувальника",
         "selector": "Селектор",
@@ -1789,7 +1609,6 @@
         "tolerance": "Допуск",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "Неможливо використовувати balancerTag і outboundTag одночасно. Якщо використовувати одночасно, працюватиме лише outboundTag.",
         "costMatch": "Шаблон тегу",
         "costValue": "Вага",
         "costRegexp": "Збіг за регулярним виразом",
@@ -1804,14 +1623,10 @@
         "publicKey": "Публічний ключ",
         "allowedIPs": "Дозволені IP-адреси",
         "endpoint": "Кінцева точка",
-        "psk": "Спільний ключ",
         "domainStrategy": "Стратегія домену"
       },
       "tun": {
-        "nameDesc": "Назва інтерфейсу TUN. Значення за замовчуванням - 'xray0'",
-        "mtuDesc": "Максимальна одиниця передачі. Максимальний розмір пакетів даних. Значення за замовчуванням - 1500",
-        "userLevel": "Рівень користувача",
-        "userLevelDesc": "Всі з'єднання, встановлені через цей вхід, використовуватимуть цей рівень користувача. Значення за замовчуванням - 0"
+        "userLevel": "Рівень користувача"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Додати підроблений DNS",
-        "edit": "Редагувати підроблений DNS",
         "ipPool": "Підмережа IP-пулу",
         "poolSize": "Розмір пулу"
       },
@@ -2032,7 +1846,6 @@
     "add": "Додати",
     "month": "Місяць",
     "months": "Місяці",
-    "day": "День",
     "days": "Дні",
     "hours": "Години",
     "minutes": "Хвилини",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Користувача Telegram збережено.",
       "loginSuccess": "✅ Успішно ввійшли в панель\r\n",
       "loginFailed": "❗️ Помилка входу в панель.\r\n",
-      "2faFailed": "Помилка 2FA",
       "report": "🕰 Заплановані звіти: {{ .RunTime }}\r\n",
       "datetime": "⏰ Дата й час: {{ .DateTime }}\r\n",
       "hostname": "💻 Хост: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Завантаження: ↓{{ .Download }}\r\n",
       "total": "📊 Усього: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Користувач Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Вичерпано {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Вичерпано кількість {{ .Type }} count:\r\n",
       "onlinesCount": "🌐 Онлайн-клієнти: {{ .Count }}\r\n",
       "disabled": "🛑 Вимкнено: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Оновлено: {{ .Time }}\r\n\r\n",
       "yes": "✅ Так",
       "no": "❌ Ні",
-      "received_id": "🔑📥 ID оновлено.",
-      "received_password": "🔑📥 Пароль оновлено.",
       "received_email": "📧📥 Електронна пошта оновлена.",
       "received_comment": "💬📥 Коментар оновлено.",
-      "id_prompt": "🔑 Стандартний ID: {{ .ClientId }}\n\nВведіть ваш ID.",
-      "pass_prompt": "🔑 Стандартний пароль: {{ .ClientPassword }}\n\nВведіть ваш пароль.",
       "email_prompt": "📧 Стандартний email: {{ .ClientEmail }}\n\nВведіть ваш email.",
       "comment_prompt": "💬 Стандартний коментар: {{ .ClientComment }}\n\nВведіть ваш коментар.",
-      "inbound_client_data_id": "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!",
-      "inbound_client_data_pass": "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!",
       "cancel": "❌ Процес скасовано! \n\nВи можете знову розпочати, використовуючи /start у будь-який час. 🔄",
       "error_add_client": "⚠️ Помилка:\n\n {{ .error }}",
       "using_default_value": "Гаразд, залишу значення за замовчуванням. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Помилка: {{ .Error }}",
       "eventNodeDown": "Вузол {{ .Name }} НЕДОСТУПНИЙ",
       "eventNodeUp": "Вузол {{ .Name }} ДОСТУПНИЙ",
-      "eventCPUHigh": "Високе навантаження на CPU",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Невдала спроба входу з {{ .Source }}",
       "memoryThreshold": "Використання пам'яті {{ .Percent }}% перевищує порогове значення {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Надіслати як вимкнено ☑️",
       "submitEnable": "Надіслати як увімкнено ✅",
       "use_default": "🏷️ Використати типове",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Пароль",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Коментар",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Скинути весь трафік",
       "SortedTrafficUsageReport": "Відсортований звіт про використання трафіку"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "Вихідне з'єднання {{ .Tag }} НЕДОСТУПНЕ",
-    "subjectOutboundUp": "Вихідне з'єднання {{ .Tag }} ДОСТУПНЕ",
-    "subjectXrayCrash": "Стався збій Xray",
-    "subjectCPUHigh": "Високе навантаження на CPU",
-    "subjectLoginSuccess": "Успішний вхід",
-    "subjectLoginFailed": "Невдалий вхід",
-    "titleOutboundDown": "Вихідне з'єднання НЕДОСТУПНЕ",
-    "titleOutboundUp": "Вихідне з'єднання ДОСТУПНЕ",
-    "titleXrayCrash": "Стався збій Xray",
-    "titleCPUHigh": "Високе навантаження на CPU",
-    "titleLoginSuccess": "Успішний вхід",
-    "titleLoginFailed": "Невдалий вхід",
     "labelStatus": "Статус",
     "labelOutbound": "Вихідне з'єднання",
     "labelNode": "Вузол",
     "labelError": "Помилка",
     "labelDelay": "Затримка",
-    "labelDetail": "Деталі",
     "labelUsername": "Ім'я користувача",
     "labelIP": "IP",
     "labelReason": "Причина",
     "labelSource": "Джерело",
-    "labelTime": "Час",
     "statusCrashed": "ЗБІЙ",
-    "statusRunning": "Працює",
     "statusHigh": "ВИСОКЕ",
     "statusSuccess": "УСПІШНО",
     "statusFailed": "НЕВДАЛО",

+ 3 - 218
internal/web/translation/vi-VN.json

@@ -48,7 +48,6 @@
   "copySuccess": "Đã sao chép thành công",
   "sure": "Chắc chắn",
   "encryption": "Mã hóa",
-  "useIPv4ForHost": "Sử dụng IPv4 cho máy chủ",
   "transmission": "Truyền tải",
   "host": "Host",
   "path": "Đường dẫn",
@@ -74,18 +73,9 @@
   "twoFactorCode": "Mã",
   "remained": "Còn lại",
   "security": "Bảo vệ",
-  "secAlertTitle": "Cảnh báo an ninh-Tiếng Việt by Ohoang7",
-  "secAlertSsl": "Kết nối này không an toàn; Vui lòng không nhập thông tin nhạy cảm cho đến khi TLS được kích hoạt để bảo vệ dữ liệu của Bạn",
-  "secAlertConf": "Một số cài đặt có thể dễ bị tấn công. Đề xuất tăng cường các giao thức bảo mật để ngăn chặn các vi phạm tiềm ẩn.",
-  "secAlertSSL": "Bảng điều khiển thiếu kết nối an toàn. Vui lòng cài đặt chứng chỉ TLS để bảo vệ dữ liệu.",
-  "secAlertPanelPort": "Cổng mặc định của bảng điều khiển có thể dễ bị tấn công. Vui lòng cấu hình một cổng ngẫu nhiên hoặc cụ thể.",
-  "secAlertPanelURI": "Đường dẫn URI mặc định của bảng điều khiển không an toàn. Vui lòng cấu hình một đường dẫn URI phức tạp.",
-  "secAlertSubURI": "Đường dẫn URI mặc định của đăng ký không an toàn. Vui lòng cấu hình một đường dẫn URI phức tạp.",
-  "secAlertSubJsonURI": "Đường dẫn URI JSON mặc định của đăng ký không an toàn. Vui lòng cấu hình một đường dẫn URI phức tạp.",
   "emptyDnsDesc": "Không có máy chủ DNS nào được thêm.",
   "emptyFakeDnsDesc": "Không có máy chủ Fake DNS nào được thêm.",
   "emptyBalancersDesc": "Không có bộ cân bằng tải nào được thêm.",
-  "emptyReverseDesc": "Không có proxy ngược nào được thêm.",
   "somethingWentWrong": "Đã xảy ra lỗi",
   "subscription": {
     "title": "Thông tin đăng ký",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "Chủ đề",
-    "dark": "Tối",
-    "ultraDark": "Siêu tối",
     "dashboard": "Trạng thái hệ thống",
     "inbounds": "Inbound",
     "clients": "Khách hàng",
@@ -118,7 +106,6 @@
     "routing": "Định tuyến",
     "outbounds": "Outbound",
     "apiDocs": "Tài liệu API",
-    "logout": "Đăng xuất",
     "link": "Quản lý",
     "donate": "Quyên góp",
     "hosts": "Hosts",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "Trạng thái hệ thống",
       "cpu": "CPU",
       "logicalProcessors": "Bộ xử lý logic",
       "frequency": "Tần số",
@@ -152,7 +138,6 @@
       "restartXray": "Khởi động lại",
       "xraySwitch": "Phiên bản",
       "xrayUpdates": "Cập nhật Xray",
-      "xraySwitchClick": "Chọn phiên bản mà bạn muốn chuyển đổi sang.",
       "xraySwitchClickDesk": "Hãy lựa chọn thận trọng, vì các phiên bản cũ có thể không tương thích với các cấu hình hiện tại.",
       "updatePanel": "Cập nhật Panel",
       "panelUpdateDesc": "Điều này sẽ cập nhật 3X-UI lên bản phát hành mới nhất và khởi động lại dịch vụ panel.",
@@ -164,12 +149,10 @@
       "currentCommit": "Commit hiện tại",
       "latestCommit": "Commit mới nhất",
       "updateChannelChanged": "Đã đổi kênh cập nhật",
-      "upToDate": "Đã cập nhật",
       "xrayStatusUnknown": "Không xác định",
       "xrayStatusRunning": "Đang chạy",
       "xrayStatusStop": "Dừng",
       "xrayStatusError": "Lỗi",
-      "xrayErrorPopoverTitle": "Đã xảy ra lỗi khi chạy Xray",
       "operationHours": "Thời gian hoạt động",
       "systemHistoryTitle": "Lịch sử hệ thống",
       "historyTitleCpu": "Mức sử dụng CPU",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "Ngừng",
       "xrayObservatoryLastSeen": "Lần cuối thấy",
       "xrayObservatoryLastTry": "Lần thử cuối",
-      "trendLast2Min": "2 phút gần nhất",
-      "systemLoad": "Tải hệ thống",
-      "systemLoadDesc": "trung bình tải hệ thống trong 1, 5 và 15 phút qua",
       "connectionCount": "Số lượng kết nối",
       "ipAddresses": "Địa chỉ IP",
       "toggleIpVisibility": "Chuyển đổi hiển thị IP",
@@ -223,13 +203,11 @@
       "totalData": "Tổng dữ liệu",
       "sent": "Đã gửi",
       "received": "Đã nhận",
-      "documentation": "Tài liệu",
       "xraySwitchVersionDialog": "Bạn có chắc chắn muốn thay đổi phiên bản Xray không?",
       "xraySwitchVersionDialogDesc": "Hành động này sẽ thay đổi phiên bản Xray thành #version#.",
       "xraySwitchVersionPopover": "Xray đã được cập nhật thành công",
       "panelUpdateDialog": "Bạn có chắc muốn cập nhật panel không?",
       "panelUpdateDialogDesc": "Điều này sẽ cập nhật 3X-UI lên #version# và khởi động lại dịch vụ panel.",
-      "panelUpdateCheckPopover": "Kiểm tra cập nhật panel thất bại",
       "panelUpdateStartedPopover": "Bắt đầu cập nhật panel",
       "panelUpdateFailedTitle": "Cập nhật panel thất bại",
       "panelUpdateFailedDesc": "Bản cập nhật không hoàn tất thành công. Hãy kiểm tra nhật ký máy chủ, hoặc chạy 'x-ui update' từ dòng lệnh.",
@@ -258,7 +236,6 @@
       "accessLogs": "Nhật ký truy cập",
       "autoUpdate": "Tự động cập nhật",
       "config": "Cấu hình",
-      "backup": "Sao lưu",
       "backupTitle": "Sao lưu & Khôi phục",
       "exportDatabase": "Sao lưu",
       "exportDatabaseDesc": "Nhấp để tải xuống tệp .db chứa bản sao lưu cơ sở dữ liệu hiện tại của bạn vào thiết bị. Tệp này cũng có thể được khôi phục vào bảng điều khiển chạy PostgreSQL.",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "Nhấp để tải xuống cơ sở dữ liệu SQLite .db được tạo từ dữ liệu PostgreSQL của bạn, sẵn sàng chạy bảng điều khiển này trên SQLite."
     },
     "inbounds": {
-      "title": "Inbound",
       "totalDownUp": "Tổng tải lên/tải xuống",
       "totalUsage": "Tổng sử dụng",
       "inboundCount": "Số lượng điểm vào",
@@ -288,21 +264,11 @@
       "localPanel": "Panel cục bộ",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "Khi một kết nối trên inbound này không khớp với client nào, hãy chuyển hướng nó tới nơi khác. Chọn một inbound con bên dưới để tự động điền các trường định tuyến (SNI / ALPN / Path / xver) từ transport của nó, hoặc để trống ô chọn và đặt Dest trực tiếp (ví dụ 8080 hoặc 127.0.0.1:8080) để chuyển hướng tới một máy chủ bên ngoài như Nginx. Mỗi inbound con nên lắng nghe trên 127.0.0.1 với security=none.",
         "empty": "Chưa có fallback nào",
         "add": "Thêm fallback",
         "pickInbound": "Chọn một inbound",
         "matchAny": "bất kỳ",
         "destPlaceholder": "tự động (listen:port của child)",
-        "rederive": "Điền lại từ child",
-        "rederived": "Đã điền lại từ child",
-        "editAdvanced": "Sửa trường định tuyến",
-        "hideAdvanced": "Ẩn nâng cao",
-        "quickAddAll": "Thêm nhanh tất cả các inbound đủ điều kiện",
-        "quickAdded": "Đã thêm {n} fallback",
-        "quickAddedNone": "Không có inbound mới nào đủ điều kiện",
-        "routesWhen": "Định tuyến khi",
-        "defaultCatchAll": "Mặc định — bắt mọi thứ khác",
         "needsTls": "Fallback khả dụng sau khi chọn TLS hoặc Reality trong thẻ Bảo mật (chỉ VLESS/Trojan trên RAW)."
       },
       "protocol": "Giao thức",
@@ -310,8 +276,6 @@
       "portMap": "Ánh xạ cổng",
       "traffic": "Lưu lượng",
       "speed": "Tốc độ",
-      "details": "Chi tiết",
-      "transportConfig": "Truyền dẫn",
       "expireDate": "Ngày hết hạn",
       "createdAt": "Tạo lúc",
       "updatedAt": "Cập nhật",
@@ -319,8 +283,6 @@
       "addInbound": "Thêm điểm vào",
       "generalActions": "Hành động chung",
       "modifyInbound": "Chỉnh sửa điểm vào (Inbound)",
-      "deleteInbound": "Xóa điểm vào (Inbound)",
-      "deleteInboundContent": "Xác nhận xóa điểm vào? (Inbound)",
       "deleteConfirmTitle": "Xóa inbound \"{remark}\"?",
       "deleteConfirmContent": "Hành động này xóa inbound và toàn bộ khách hàng của nó. Không thể hoàn tác.",
       "resetConfirmTitle": "Đặt lại lưu lượng của \"{remark}\"?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "Tat-ca-Inbound",
       "exportAllSubsFileName": "Tat-ca-Inbound-Subs",
       "inboundJsonTitle": "JSON inbound",
-      "deleteClient": "Xóa người dùng",
-      "deleteClientContent": "Bạn có chắc chắn muốn xóa người dùng không?",
       "resetTrafficContent": "Xác nhận đặt lại lưu lượng?",
       "copyLink": "Sao chép liên kết",
       "address": "Địa chỉ",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= Không giới hạn. (đơn vị: GB)",
       "totalFlow": "Tổng lưu lượng",
       "leaveBlankToNeverExpire": "Để trống để không bao giờ hết hạn",
-      "noRecommendKeepDefault": "Không yêu cầu đặc biệt để giữ nguyên cài đặt mặc định",
       "certificatePath": "Đường dẫn tập",
       "certificateContent": "Nội dung tập",
       "publicKey": "Khóa công khai",
       "privatekey": "Khóa cá nhân",
-      "clickOnQRcode": "Nhấn vào Mã QR để sao chép",
       "client": "Người dùng",
       "export": "Xuất liên kết",
       "clone": "Sao chép",
-      "cloneInbound": "Sao chép điểm vào (Inbound)",
-      "cloneInboundContent": "Tất cả cài đặt của điểm vào này, trừ Cổng, IP nghe và máy khách, sẽ được áp dụng cho bản sao.",
-      "cloneInboundOk": "Sao chép",
       "resetAllTraffic": "Đặt lại lưu lượng cho tất cả điểm vào",
       "resetAllTrafficTitle": "Đặt lại lưu lượng cho tất cả điểm vào",
       "resetAllTrafficContent": "Bạn có chắc chắn muốn đặt lại lưu lượng cho tất cả điểm vào không?",
-      "resetInboundClientTraffics": "Đặt lại lưu lượng toàn bộ người dùng của điểm vào",
-      "resetInboundClientTrafficTitle": "Đặt lại lưu lượng cho toàn bộ người dùng của điểm vào",
-      "resetInboundClientTrafficContent": "Bạn có chắc chắn muốn đặt lại tất cả lưu lượng cho các người dùng của điểm vào này không?",
-      "resetAllClientTraffics": "Đặt lại lưu lượng cho toàn bộ người dùng",
-      "resetAllClientTrafficTitle": "Đặt lại lưu lượng cho toàn bộ người dùng",
-      "resetAllClientTrafficContent": "Bạn có chắc chắn muốn đặt lại tất cả lưu lượng cho toàn bộ người dùng không?",
-      "delDepletedClients": "Xóa các người dùng đã cạn kiệt",
-      "delDepletedClientsTitle": "Xóa các người dùng đã cạn kiệt",
-      "delDepletedClientsContent": "Bạn có chắc chắn muốn xóa toàn bộ người dùng đã cạn kiệt không?",
       "email": "Email",
-      "emailDesc": "Vui lòng cung cấp một địa chỉ email duy nhất.",
       "IPLimit": "Giới hạn IP",
-      "IPLimitDesc": "Vô hiệu hóa điểm vào nếu số lượng vượt quá giá trị đã nhập (nhập 0 để vô hiệu hóa giới hạn IP).",
       "IPLimitlog": "Lịch sử IP",
-      "IPLimitlogDesc": "Lịch sử đăng nhập IP (trước khi kích hoạt điểm vào sau khi bị vô hiệu hóa bởi giới hạn IP, bạn nên xóa lịch sử).",
       "IPLimitlogclear": "Xóa Lịch sử",
       "setDefaultCert": "Đặt chứng chỉ từ bảng điều khiển",
       "setDefaultCertEmpty": "Không có chứng chỉ nào được cấu hình cho bảng điều khiển. Hãy đặt một chứng chỉ trong Cài đặt trước.",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Bao đóng khối sniffing của Xray:",
         "stream": "Stream",
-        "streamHelp": "Bao đóng khối stream của Xray:",
-        "jsonErrorPrefix": "JSON nâng cao"
+        "streamHelp": "Bao đóng khối stream của Xray:"
       },
-      "telegramDesc": "Vui lòng cung cấp ID Trò chuyện Telegram. (sử dụng lệnh '/id' trong bot) hoặc ({'@'}userinfobot)",
-      "subscriptionDesc": "Bạn có thể tìm liên kết gói đăng ký của mình trong Chi tiết, cũng như bạn có thể sử dụng cùng tên cho nhiều cấu hình khác nhau",
       "subSortIndex": "Thứ tự sub",
-      "same": "Giống nhau",
       "inboundInfo": "Thông tin Inbound",
       "exportInbound": "Xuất nhập khẩu",
       "import": "Nhập",
       "importInbound": "Nhập inbound",
       "periodicTrafficResetTitle": "Đặt lại lưu lượng",
-      "periodicTrafficResetDesc": "Tự động đặt lại bộ đếm lưu lượng theo khoảng thời gian xác định",
       "periodicTrafficResetDay": "Ngày đặt lại hàng tháng",
-      "lastReset": "Đặt lại lần cuối",
       "periodicTrafficReset": {
         "never": "Không bao giờ",
         "daily": "Hàng ngày",
@@ -464,7 +401,6 @@
         "obtain": "Nhận",
         "updateSuccess": "Cập nhật thành công",
         "logCleanSuccess": "Đã xóa nhật ký",
-        "inboundsUpdateSuccess": "Đã cập nhật thành công các kết nối inbound",
         "inboundUpdateSuccess": "Đã cập nhật thành công kết nối inbound",
         "inboundCreateSuccess": "Đã tạo thành công kết nối inbound",
         "bulkDeleted": "Đã xóa {count} inbound",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "Đã xóa client inbound",
         "inboundClientUpdateSuccess": "Đã cập nhật client inbound",
         "savedNodeOfflineWillSync": "Đã lưu cục bộ. Một nút hỗ trợ đang ngoại tuyến hoặc bị tắt — thay đổi sẽ được đồng bộ khi kết nối lại.",
-        "delDepletedClientsSuccess": "Đã xóa tất cả client hết hạn",
         "resetAllClientTrafficSuccess": "Đã đặt lại toàn bộ lưu lượng client",
         "resetAllTrafficSuccess": "Đã đặt lại toàn bộ lưu lượng",
         "resetInboundClientTrafficSuccess": "Đã đặt lại lưu lượng",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Cấu hình Peer {n}"
       },
-      "stream": {
-        "general": {
-          "request": "Lời yêu cầu",
-          "response": "Phản ứng",
-          "name": "Tên",
-          "value": "Giá trị"
-        },
-        "tcp": {
-          "version": "Phiên bản",
-          "method": "Phương pháp",
-          "path": "Đường dẫn",
-          "status": "Trạng thái",
-          "statusDescription": "Tình trạng Mô tả",
-          "requestHeader": "Header yêu cầu",
-          "responseHeader": "Header phản hồi"
-        }
-      },
       "sniffingDestOverride": "Ghi đè đích"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "Thêm đăng ký ngoài",
       "noExternalLinks": "Chưa có liên kết ngoài.",
       "noExternalSubscriptions": "Chưa có đăng ký ngoài.",
-      "add": "Thêm khách hàng",
-      "edit": "Chỉnh sửa khách hàng",
-      "submitAdd": "Thêm khách hàng",
       "submitEdit": "Lưu thay đổi",
       "clientCount": "Số lượng khách hàng",
       "bulk": "Thêm hàng loạt",
-      "copyFromInbound": "Sao chép khách hàng từ inbound",
-      "copyToInbound": "Sao chép khách hàng đến",
-      "copySelected": "Sao chép đã chọn",
-      "copySource": "Nguồn",
-      "copyEmailPreview": "Xem trước email kết quả",
-      "copySelectSourceFirst": "Hãy chọn inbound nguồn trước.",
-      "copyResult": "Kết quả sao chép",
-      "copyResultSuccess": "Đã sao chép thành công",
-      "copyResultNone": "Không có gì để sao chép: chưa chọn khách hàng hoặc nguồn rỗng",
-      "copyResultErrors": "Lỗi sao chép",
-      "copyFlowLabel": "Flow cho khách hàng mới (VLESS)",
-      "copyFlowHint": "Áp dụng cho tất cả khách hàng được sao chép. Để trống để bỏ qua.",
       "selectAll": "Chọn tất cả",
       "clearAll": "Xóa tất cả",
       "method": "Phương thức",
@@ -775,7 +678,6 @@
       "postfix": "Hậu tố",
       "delayedStart": "Bắt đầu sau lần dùng đầu",
       "expireDays": "Thời hạn (ngày)",
-      "days": "Ngày",
       "renew": "Tự động gia hạn",
       "renewDesc": "Tự động gia hạn sau khi hết hạn. (0 = tắt) (đơn vị: ngày)",
       "renewDays": "Tự động gia hạn (ngày)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "Sắp hết hạn",
       "has": "Có",
       "hasNot": "Không có",
-      "title": "Khách hàng",
       "actions": "Hành động",
       "totalGB": "Giới hạn lưu lượng (GB)",
       "totalGBDesc": "Hạn mức dữ liệu cho khách hàng này. 0 = không giới hạn.",
@@ -826,8 +727,6 @@
       "addClient": "Thêm khách hàng",
       "qrCode": "Mã QR",
       "clientInfo": "Thông tin khách hàng",
-      "delete": "Xóa",
-      "reset": "Đặt lại lưu lượng",
       "editClient": "Chỉnh sửa khách hàng",
       "client": "Khách hàng",
       "enabled": "Đã bật",
@@ -841,13 +740,11 @@
       "noLinks": "Không có liên kết chia sẻ — hãy gắn khách hàng này vào một inbound có giao thức tương thích trước.",
       "link": "Liên kết",
       "resetNotPossible": "Hãy gắn khách hàng này vào một inbound trước.",
-      "general": "Chung",
       "resetAllTraffics": "Đặt lại lưu lượng của tất cả khách hàng",
       "resetAllTrafficsTitle": "Đặt lại lưu lượng của tất cả khách hàng?",
       "resetAllTrafficsContent": "Bộ đếm gửi/nhận của mỗi khách hàng về 0. Hạn mức và thời hạn không bị ảnh hưởng. Không thể hoàn tác.",
       "deleteConfirmTitle": "Xóa khách hàng {email}?",
       "deleteConfirmContent": "Hành động này gỡ khách hàng khỏi mọi inbound đã gắn và xóa bản ghi lưu lượng. Không thể hoàn tác.",
-      "deleteSelected": "Xóa ({count})",
       "adjustSelected": "Điều chỉnh ({count})",
       "subLinksSelected": "Liên kết sub ({count})",
       "addToGroupTitle": "Thêm {count} client vào một nhóm",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "Tắt {count} khách hàng?",
       "bulkDisableConfirmContent": "Tắt từng khách hàng đã chọn trên mọi inbound được gắn. Họ mất quyền truy cập ngay lập tức nhưng hồ sơ và lưu lượng của họ vẫn được giữ lại.",
       "selectedCount": "Đã chọn {count}",
-      "attachSelected": "Gắn ({count})",
       "attachToInboundsTitle": "Gắn {count} client vào inbound",
       "attachToInboundsDesc": "Gắn {count} client đã chọn (cùng UUID/mật khẩu và lưu lượng chung) vào các inbound đã chọn. Các gắn kết hiện tại được giữ nguyên.",
       "attachToInboundsTargets": "Inbound đích",
       "attachToInboundsNoTargets": "Không có inbound đa người dùng nào để gắn.",
-      "detachSelected": "Tách ({count})",
       "detach": "Tách",
       "detachFromInboundsTitle": "Tách {count} client khỏi inbound",
       "detachFromInboundsDesc": "Xóa {count} client đã chọn khỏi các inbound đã chọn. Các cặp client chưa gắn sẽ được bỏ qua. Hồ sơ client được giữ lại (dùng Delete để xóa hoàn toàn).",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "Reverse tag tùy chọn",
       "telegramId": "ID người dùng Telegram",
       "telegramIdPlaceholder": "ID người dùng Telegram dạng số (0 = không có)",
-      "created": "Tạo",
-      "updated": "Cập nhật",
       "ipLimit": "Giới hạn IP",
       "toasts": {
         "deleted": "Đã xóa khách hàng",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "Nhóm",
       "name": "Tên",
       "clientCount": "Client",
       "totalGroups": "Tổng số nhóm",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "Đã xóa {count} client khỏi {name}."
     },
     "nodes": {
-      "title": "Nút",
       "addNode": "Thêm nút",
       "editNode": "Sửa node",
       "totalNodes": "Tổng số nút",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "Token từ trang Cài đặt của panel từ xa",
       "apiTokenHint": "Panel từ xa hiển thị token API tại Bảo mật → Token API.",
       "apiTokenKeepHint": "Để trống để giữ token hiện tại",
-      "regenerate": "Tạo lại token",
-      "regenerateConfirm": "Tạo lại sẽ vô hiệu hóa token hiện tại. Mọi panel trung tâm dùng nó sẽ mất quyền truy cập cho đến khi được cập nhật. Tiếp tục?",
       "allowPrivateAddress": "Cho phép địa chỉ riêng",
       "allowPrivateAddressHint": "Chỉ bật cho các nút trên mạng riêng hoặc VPN.",
       "outboundTag": "Outbound kết nối",
@@ -1046,7 +935,6 @@
       "updatePanel": "Cập nhật bảng điều khiển",
       "updateSelected": "Cập nhật đã chọn ({count})",
       "updateAvailable": "Có bản cập nhật",
-      "upToDate": "Mới nhất",
       "updateConfirmTitle": "Cập nhật {count} node lên phiên bản mới nhất?",
       "updateConfirmContent": "Mỗi node đã chọn sẽ tải bản phát hành mới nhất và khởi động lại. Chỉ các node đang bật và trực tuyến được cập nhật.",
       "updateDevChannel": "Cập nhật lên kênh phát triển (commit mới nhất)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "Không thể lấy chứng chỉ"
     },
     "settings": {
+      "defaultTag": "Mặc định",
       "title": "Cài đặt",
       "save": "Lưu",
       "infoDesc": "Mọi thay đổi được thực hiện ở đây cần phải được lưu. Vui lòng khởi động lại bảng điều khiển để áp dụng các thay đổi.",
@@ -1447,7 +1336,6 @@
       "secretClearUndo": "Hoàn tác xóa"
     },
     "xray": {
-      "title": "Cài đặt Xray",
       "importRules": "Nhập quy tắc",
       "exportRules": "Xuất quy tắc",
       "importOutbounds": "Nhập outbound",
@@ -1457,11 +1345,7 @@
       "metricsListenDesc": "Hiển thị các chỉ số kiểu Prometheus của Xray tại địa chỉ:cổng này (ví dụ 127.0.0.1:11111). Để trống để tắt. Hãy gắn vào localhost và reverse-proxy nó — vì nó không có xác thực.",
       "metricsTag": "Metrics Tag",
       "save": "Lưu cài đặt",
-      "restart": "Khởi động lại Xray",
       "restartSuccess": "Đã khởi động lại Xray thành công",
-      "restartOutputTitle": "Đầu ra khởi động lại Xray",
-      "restartConfirmTitle": "Khởi động lại xray?",
-      "restartConfirmContent": "Tải lại dịch vụ xray với cấu hình đã lưu.",
       "stopSuccess": "Xray đã được dừng thành công",
       "restartError": "Đã xảy ra lỗi khi khởi động lại Xray.",
       "stopError": "Đã xảy ra lỗi khi dừng Xray.",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "Những tùy chọn này sẽ cung cấp điều chỉnh tổng quát.",
       "logConfigs": "Nhật ký",
       "logConfigsDesc": "Nhật ký có thể ảnh hưởng đến hiệu suất máy chủ của bạn. Bạn chỉ nên kích hoạt nó một cách khôn ngoan trong trường hợp bạn cần",
-      "blockConfigsDesc": "Những tùy chọn này sẽ ngăn người dùng kết nối đến các giao thức và trang web cụ thể.",
       "basicRouting": "Định tuyến Cơ bản",
       "blockConnectionsConfigsDesc": "Các tùy chọn này sẽ chặn lưu lượng truy cập dựa trên quốc gia được yêu cầu cụ thể.",
       "directConnectionsConfigsDesc": "Kết nối trực tiếp đảm bảo rằng lưu lượng truy cập cụ thể không được định tuyến qua máy chủ khác.",
@@ -1481,10 +1364,6 @@
       "directdomains": "Tên Miền Trực Tiếp",
       "ipv4Routing": "Định tuyến IPv4",
       "ipv4RoutingDesc": "Những tùy chọn này sẽ chỉ định kết nối đến các tên miền mục tiêu qua IPv4.",
-      "warpRouting": "Định tuyến WARP",
-      "warpRoutingDesc": "Cảnh báo: Trước khi sử dụng những tùy chọn này, hãy cài đặt WARP ở chế độ proxy socks5 trên máy chủ của bạn bằng cách làm theo các bước trên GitHub của bảng điều khiển. WARP sẽ định tuyến lưu lượng đến các trang web qua máy chủ Cloudflare.",
-      "nordRouting": "Định tuyến NordVPN",
-      "nordRoutingDesc": "Các tùy chọn này sẽ định tuyến lưu lượng dựa trên đích cụ thể qua NordVPN.",
       "Template": "Mẫu Cấu hình Xray",
       "TemplateDesc": "Tạo tệp cấu hình Xray cuối cùng dựa trên mẫu này.",
       "FreedomStrategy": "Cấu hình Chiến lược cho Giao thức Freedom",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "URL dùng khi kiểm tra kết nối outbound",
       "Torrent": "Cấu hình sử dụng BitTorrent",
       "Inbounds": "Inbound",
-      "InboundsDesc": "Thay đổi mẫu cấu hình để chấp nhận các máy khách cụ thể.",
       "Outbounds": "Outbound",
-      "OutboundSubscriptions": "Đăng ký Outbound",
-      "OutboundSubscriptionsDesc": "Nhập các outbound từ URL đăng ký từ xa (vmess/vless/trojan/ss/...). Tag được giữ ổn định để dùng trong bộ cân bằng tải và quy tắc định tuyến. Cập nhật diễn ra tự động.",
       "Balancers": "Cân bằng",
       "balancerTagRequired": "Tag là bắt buộc",
       "balancerSelectorRequired": "Chọn ít nhất một outbound",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "Outbound phù hợp",
       "routeTesterViaBalancer": "qua bộ cân bằng tải",
       "routeTesterDefaultOutbound": "Không có quy tắc định tuyến nào khớp — lưu lượng đến outbound mặc định (đầu tiên).",
-      "OutboundsDesc": "Thay đổi mẫu cấu hình để xác định các cách ra đi cho máy chủ này.",
       "Routings": "Quy tắc định tuyến",
-      "RoutingsDesc": "Mức độ ưu tiên của mỗi quy tắc đều quan trọng!",
       "completeTemplate": "Tất cả",
       "logLevel": "Mức đăng nhập",
       "logLevelDesc": "Cấp độ nhật ký cho nhật ký lỗi, cho biết thông tin cần được ghi lại.",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "Mặt nạ địa chỉ IP, khi được bật, sẽ tự động thay thế địa chỉ IP xuất hiện trong nhật ký.",
       "statistics": "Thống kê",
       "statsInboundUplink": "Thống kê tải lên đầu vào",
-      "statsInboundUplinkDesc": "Kích hoạt thu thập thống kê cho lưu lượng tải lên của tất cả các proxy đầu vào.",
       "statsInboundDownlink": "Thống kê tải xuống đầu vào",
-      "statsInboundDownlinkDesc": "Kích hoạt thu thập thống kê cho lưu lượng tải xuống của tất cả các proxy đầu vào.",
       "statsOutboundUplink": "Thống kê tải lên đầu ra",
-      "statsOutboundUplinkDesc": "Kích hoạt thu thập thống kê cho lưu lượng tải lên của tất cả các proxy đầu ra.",
       "statsOutboundDownlink": "Thống kê tải xuống đầu ra",
-      "statsOutboundDownlinkDesc": "Kích hoạt thu thập thống kê cho lưu lượng tải xuống của tất cả các proxy đầu ra.",
       "connectionLimits": "Giới hạn kết nối",
       "connectionLimitsDesc": "Chính sách cấp kết nối cho người dùng cấp 0. Để trống một trường để sử dụng giá trị mặc định của Xray.",
       "connIdle": "Thời gian chờ nhàn rỗi",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "tự động",
       "seconds": "giây",
       "rules": {
-        "first": "Đầu tiên",
-        "last": "Cuối cùng",
-        "up": "Lên",
-        "down": "Xuống",
         "source": "Nguồn",
         "dest": "Đích",
         "inbound": "Vào",
-        "outbound": "Ra",
         "balancer": "Cân bằng",
-        "info": "Thông tin",
-        "add": "Thêm quy tắc",
-        "edit": "Chỉnh sửa quy tắc",
         "useComma": "Các mục được phân tách bằng dấu phẩy"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "Quy tắc {n}",
         "action": "Hành động",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "Quy tắc cuối",
         "overrideXrayPrivateIp": "Ghi đè chặn IP riêng mặc định của Xray",
         "blockDelay": "Trễ chặn (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "Khoảng keep alive",
         "markFwmark": "Mark (fwmark)",
         "interface": "Giao diện",
-        "ipv6Only": "Chỉ IPv6",
-        "acceptProxyProtocol": "Chấp nhận proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "Thêm thư đi",
-        "addReverse": "Thêm đảo ngược",
-        "editOutbound": "Chỉnh sửa gửi đi",
-        "editReverse": "Chỉnh sửa ngược lại",
-        "reverseTag": "Thẻ Ngược",
-        "reverseTagDesc": "Thẻ outbound của proxy ngược đơn giản VLESS. Để trống để vô hiệu hóa.",
-        "reverseTagPlaceholder": "thẻ outbound (để trống để vô hiệu hóa)",
         "tag": "Tag",
-        "tagDesc": "thẻ duy nhất",
-        "address": "Địa chỉ",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "Đảo ngược",
-        "domain": "Tên miền",
-        "type": "Loại",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "Liên kết",
-        "intercon": "Kết nối",
-        "settings": "cài đặt",
-        "accountInfo": "Thông tin tài khoản",
         "outboundStatus": "Trạng thái đầu ra",
         "sendThrough": "Gửi qua",
         "targetStrategy": "Chiến lược đích",
-        "test": "Kiểm tra",
-        "testResult": "Kết quả kiểm tra",
-        "testing": "Đang kiểm tra kết nối...",
-        "testSuccess": "Kiểm tra thành công",
-        "testFailed": "Kiểm tra thất bại",
-        "testError": "Không thể kiểm tra đầu ra",
         "modeRealDelay": "Độ trễ thực",
         "testModeTooltip": "TCP: probe dial nhanh. HTTP: yêu cầu đầy đủ qua xray. Độ trễ thực: tổng thời gian gồm cả thiết lập kết nối.",
         "testAll": "Kiểm tra tất cả",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "Kết nối proxy",
         "breakdownTls": "TLS qua outbound",
         "breakdownTtfb": "Byte đầu tiên",
-        "nordvpn": "NordVPN",
-        "accessToken": "Mã truy cập",
         "country": "Quốc gia",
         "server": "Máy chủ",
         "city": "Thành phố",
         "allCities": "Tất cả thành phố",
-        "privateKey": "Khóa riêng",
-        "load": "Tải",
         "moveToTop": "Chuyển lên đầu"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "Đăng ký đang hoạt động",
         "empty": "Chưa có đăng ký nào. Hãy thêm một mục ở trên.",
         "colRemark": "Ghi chú",
-        "colPrefix": "Tiền tố",
-        "colInterval": "Khoảng",
         "colLastFetch": "Lần tải gần nhất",
         "colEnabled": "Đã kích hoạt",
         "auto": "tự động",
         "never": "không bao giờ",
-        "yes": "Có",
-        "no": "Không",
         "refreshNow": "Cập nhật ngay",
-        "lastError": "Lỗi gần nhất",
         "deleteConfirm": "Xóa đăng ký này?",
         "restartHint": "Sau khi thêm hoặc cập nhật, hãy khởi động lại Xray (hoặc chờ lần tự động tải lại tiếp theo) để kích hoạt các outbound.",
         "fromSubsTitle": "Từ đăng ký outbound (chỉ đọc)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "Cài đặt Balancer",
       "tabObservatory": "Observatory",
       "observatory": {
-        "title": "Observatory",
-        "burstTitle": "Burst Observatory",
         "autoManaged": "Observer được quản lý tự động từ các balancer của bạn. Điều chỉnh cách chúng dò ở bên dưới; các outbound được theo dõi sẽ tuân theo selector của balancer.",
         "emptyHint": "Không có observer kết nối nào đang hoạt động. Một observer sẽ được thêm tự động khi bạn tạo balancer Least Ping hoặc Least Load — hoặc balancer Random / Round-robin có fallback — để các balancer dùng observer có thể kiểm tra sức khỏe outbound trước khi chọn mục tiêu.",
         "mixedLegacy": "Cấu hình này có cả Observatory và Burst Observatory. Xray chỉ dùng một observer toàn cục, nên trạng thái hỗn hợp cũ này không được hỗ trợ; khi lưu balancer, nó sẽ được chuẩn hóa về một observer.",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "Balancer {tag} — đã xóa (không còn mục tiêu)"
       },
       "balancer": {
-        "addBalancer": "Thêm cân bằng",
-        "editBalancer": "Chỉnh sửa cân bằng",
         "balancerStrategy": "Chiến lược",
-        "balancerSelectors": "Bộ chọn",
         "tag": "Tag",
-        "tagDesc": "thẻ duy nhất",
         "tagDuplicate": "Tag đã được dùng bởi balancer khác",
         "tagPlaceholder": "tag balancer duy nhất",
         "selector": "Selector",
@@ -1789,7 +1609,6 @@
         "tolerance": "Dung sai",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "Không thể sử dụng balancerTag và outboundTag cùng một lúc. Nếu sử dụng cùng lúc thì chỉ outboundTag mới hoạt động.",
         "costMatch": "Mẫu thẻ",
         "costValue": "Trọng số",
         "costRegexp": "Khớp biểu thức chính quy",
@@ -1804,14 +1623,10 @@
         "publicKey": "Khóa công khai",
         "allowedIPs": "IP được phép",
         "endpoint": "Điểm cuối",
-        "psk": "Khóa chia sẻ",
         "domainStrategy": "Chiến lược tên miền"
       },
       "tun": {
-        "nameDesc": "Tên của giao diện TUN. Giá trị mặc định là 'xray0'",
-        "mtuDesc": "Đơn vị Truyền Tối đa. Kích thước tối đa của các gói dữ liệu. Giá trị mặc định là 1500",
-        "userLevel": "Mức Người Dùng",
-        "userLevelDesc": "Tất cả các kết nối được thực hiện thông qua inbound này sẽ sử dụng mức người dùng này. Giá trị mặc định là 0"
+        "userLevel": "Mức Người Dùng"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "Thêm DNS giả",
-        "edit": "Chỉnh sửa DNS giả",
         "ipPool": "Mạng con nhóm IP",
         "poolSize": "Kích thước bể bơi"
       },
@@ -2032,7 +1846,6 @@
     "add": "Thêm",
     "month": "Tháng",
     "months": "Tháng",
-    "day": "Ngày",
     "days": "Ngày",
     "hours": "Giờ",
     "minutes": "Phút",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ Người dùng Telegram đã được lưu.",
       "loginSuccess": "✅ Đăng nhập thành công vào bảng điều khiển.\r\n",
       "loginFailed": "❗️ Đăng nhập vào bảng điều khiển thất bại.\r\n",
-      "2faFailed": "Lỗi 2FA",
       "report": "🕰 Báo cáo định kỳ: {{ .RunTime }}\r\n",
       "datetime": "⏰ Ngày-Giờ: {{ .DateTime }}\r\n",
       "hostname": "💻 Host: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 Tải xuống: ↓{{ .Download }}\r\n",
       "total": "📊 Tổng: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 Người dùng Telegram: {{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 Sự cạn kiệt {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 Số lần cạn kiệt {{ .Type }}:\r\n",
       "onlinesCount": "🌐 Khách hàng trực tuyến: {{ .Count }}\r\n",
       "disabled": "🛑 Vô hiệu hóa: {{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 Đã cập nhật lần cuối vào: {{ .Time }}\r\n\r\n",
       "yes": "✅ Có",
       "no": "❌ Không",
-      "received_id": "🔑📥 ID đã được cập nhật.",
-      "received_password": "🔑📥 Mật khẩu đã được cập nhật.",
       "received_email": "📧📥 Email đã được cập nhật.",
       "received_comment": "💬📥 Bình luận đã được cập nhật.",
-      "id_prompt": "🔑 ID mặc định: {{ .ClientId }}\n\nVui lòng nhập ID của bạn.",
-      "pass_prompt": "🔑 Mật khẩu mặc định: {{ .ClientPassword }}\n\nVui lòng nhập mật khẩu của bạn.",
       "email_prompt": "📧 Email mặc định: {{ .ClientEmail }}\n\nVui lòng nhập email của bạn.",
       "comment_prompt": "💬 Bình luận mặc định: {{ .ClientComment }}\n\nVui lòng nhập bình luận của bạn.",
-      "inbound_client_data_id": "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!",
-      "inbound_client_data_pass": "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 Mật khẩu: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!",
       "cancel": "❌ Quá trình đã bị hủy! \n\nBạn có thể bắt đầu lại bất cứ lúc nào bằng cách nhập /start. 🔄",
       "error_add_client": "⚠️ Lỗi:\n\n {{ .error }}",
       "using_default_value": "Được rồi, tôi sẽ sử dụng giá trị mặc định. 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "Lỗi: {{ .Error }}",
       "eventNodeDown": "Node {{ .Name }} đã NGỪNG HOẠT ĐỘNG",
       "eventNodeUp": "Node {{ .Name }} đã HOẠT ĐỘNG",
-      "eventCPUHigh": "CPU cao",
-      "eventCPUHighDetail": "CPU: {{ .Detail }}",
       "eventLoginFallback": "Đăng nhập thất bại từ {{ .Source }}",
       "memoryThreshold": "Sử dụng bộ nhớ {{ .Percent }}% vượt quá ngưỡng {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "Gửi Dưới Dạng Vô Hiệu ☑️",
       "submitEnable": "Gửi Dưới Dạng Kích Hoạt ✅",
       "use_default": "🏷️ Sử Dụng Mặc Định",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 Mật Khẩu",
       "change_email": "⚙️📧 Email",
       "change_comment": "⚙️💬 Bình Luận",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "Đặt lại tất cả lưu lượng",
       "SortedTrafficUsageReport": "Báo cáo sử dụng lưu lượng đã sắp xếp"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "Outbound {{ .Tag }} đã NGỪNG HOẠT ĐỘNG",
-    "subjectOutboundUp": "Outbound {{ .Tag }} đã HOẠT ĐỘNG",
-    "subjectXrayCrash": "Xray GẶP SỰ CỐ",
-    "subjectCPUHigh": "CPU cao",
-    "subjectLoginSuccess": "Đăng nhập thành công",
-    "subjectLoginFailed": "Đăng nhập thất bại",
-    "titleOutboundDown": "Outbound NGỪNG HOẠT ĐỘNG",
-    "titleOutboundUp": "Outbound HOẠT ĐỘNG",
-    "titleXrayCrash": "Xray GẶP SỰ CỐ",
-    "titleCPUHigh": "CPU cao",
-    "titleLoginSuccess": "Đăng nhập thành công",
-    "titleLoginFailed": "Đăng nhập thất bại",
     "labelStatus": "Trạng thái",
     "labelOutbound": "Outbound",
     "labelNode": "Node",
     "labelError": "Lỗi",
     "labelDelay": "Độ trễ",
-    "labelDetail": "Chi tiết",
     "labelUsername": "Tên đăng nhập",
     "labelIP": "IP",
     "labelReason": "Lý do",
     "labelSource": "Nguồn",
-    "labelTime": "Thời gian",
     "statusCrashed": "GẶP SỰ CỐ",
-    "statusRunning": "Đang chạy",
     "statusHigh": "CAO",
     "statusSuccess": "THÀNH CÔNG",
     "statusFailed": "THẤT BẠI",

+ 3 - 218
internal/web/translation/zh-CN.json

@@ -48,7 +48,6 @@
   "copySuccess": "复制成功",
   "sure": "确定",
   "encryption": "加密",
-  "useIPv4ForHost": "使用 IPv4 连接主机",
   "transmission": "传输",
   "host": "主机",
   "path": "路径",
@@ -74,18 +73,9 @@
   "twoFactorCode": "代码",
   "remained": "剩余",
   "security": "安全",
-  "secAlertTitle": "安全警报",
-  "secAlertSsl": "此连接不安全。在激活 TLS 进行数据保护之前,请勿输入敏感信息。",
-  "secAlertConf": "某些设置易受攻击。建议加强安全协议以防止潜在漏洞。",
-  "secAlertSSL": "面板缺少安全连接。请安装 TLS 证书以保护数据安全。",
-  "secAlertPanelPort": "面板默认端口存在安全风险。请配置随机端口或特定端口。",
-  "secAlertPanelURI": "面板默认 URI 路径不安全。请配置复杂的 URI 路径。",
-  "secAlertSubURI": "订阅默认 URI 路径不安全。请配置复杂的 URI 路径。",
-  "secAlertSubJsonURI": "订阅 JSON 默认 URI 路径不安全。请配置复杂的 URI 路径。",
   "emptyDnsDesc": "未添加 DNS 服务器。",
   "emptyFakeDnsDesc": "未添加 Fake DNS 服务器。",
   "emptyBalancersDesc": "未添加负载均衡器。",
-  "emptyReverseDesc": "未添加反向代理。",
   "somethingWentWrong": "出了点问题",
   "subscription": {
     "title": "订阅信息",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "主题",
-    "dark": "暗色",
-    "ultraDark": "超暗色",
     "dashboard": "系统状态",
     "inbounds": "入站",
     "clients": "客户端",
@@ -118,7 +106,6 @@
     "routing": "路由",
     "outbounds": "出站",
     "apiDocs": "API 文档",
-    "logout": "退出登录",
     "link": "管理",
     "donate": "捐赠",
     "hosts": "主机",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "系统状态",
       "cpu": "CPU",
       "logicalProcessors": "逻辑处理器",
       "frequency": "频率",
@@ -152,7 +138,6 @@
       "restartXray": "重启",
       "xraySwitch": "版本",
       "xrayUpdates": "Xray 更新",
-      "xraySwitchClick": "选择你要切换到的版本",
       "xraySwitchClickDesk": "请谨慎选择,因为较旧版本可能与当前配置不兼容",
       "updatePanel": "更新面板",
       "panelUpdateDesc": "这将把 3X-UI 更新到最新版本并重启面板服务。",
@@ -164,12 +149,10 @@
       "currentCommit": "当前提交",
       "latestCommit": "最新提交",
       "updateChannelChanged": "更新通道已切换",
-      "upToDate": "已是最新",
       "xrayStatusUnknown": "未知",
       "xrayStatusRunning": "运行中",
       "xrayStatusStop": "停止",
       "xrayStatusError": "错误",
-      "xrayErrorPopoverTitle": "运行 Xray 时发生错误",
       "operationHours": "系统正常运行时间",
       "systemHistoryTitle": "系统历史",
       "historyTitleCpu": "CPU 使用率",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "离线",
       "xrayObservatoryLastSeen": "最后在线",
       "xrayObservatoryLastTry": "最后尝试",
-      "trendLast2Min": "最近 2 分钟",
-      "systemLoad": "系统负载",
-      "systemLoadDesc": "过去 1、5 和 15 分钟的系统平均负载",
       "connectionCount": "连接数",
       "ipAddresses": "IP 地址",
       "toggleIpVisibility": "切换 IP 可见性",
@@ -223,13 +203,11 @@
       "totalData": "总数据",
       "sent": "已发送",
       "received": "已接收",
-      "documentation": "文档",
       "xraySwitchVersionDialog": "您确定要更改 Xray 版本吗?",
       "xraySwitchVersionDialogDesc": "这将把 Xray 版本更改为 #version#。",
       "xraySwitchVersionPopover": "Xray 更新成功",
       "panelUpdateDialog": "您确定要更新面板吗?",
       "panelUpdateDialogDesc": "这将把 3X-UI 更新到 #version# 并重启面板服务。",
-      "panelUpdateCheckPopover": "面板更新检查失败",
       "panelUpdateStartedPopover": "已开始更新面板",
       "panelUpdateFailedTitle": "面板更新失败",
       "panelUpdateFailedDesc": "更新未成功完成。请检查服务器日志,或在命令行运行「x-ui update」。",
@@ -258,7 +236,6 @@
       "accessLogs": "访问日志",
       "autoUpdate": "自动更新",
       "config": "配置",
-      "backup": "备份",
       "backupTitle": "备份和恢复",
       "exportDatabase": "备份",
       "exportDatabaseDesc": "点击下载包含当前数据库备份的 .db 文件到您的设备。同一文件也可以恢复到运行 PostgreSQL 的面板中。",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "点击下载由 PostgreSQL 数据构建的 .db SQLite 数据库,可用于在 SQLite 上运行本面板。"
     },
     "inbounds": {
-      "title": "入站",
       "totalDownUp": "总上传 / 下载",
       "totalUsage": "总用量",
       "inboundCount": "入站数量",
@@ -288,21 +264,11 @@
       "localPanel": "本地面板",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "当此入站的连接未匹配任何客户端时,将其路由到其他位置。在下方选择一个子入站,可从其传输方式自动填充路由字段(SNI / ALPN / Path / xver);或将选择框留空并直接设置 Dest(例如 8080 或 127.0.0.1:8080),以路由到 Nginx 等外部服务器。每个子入站应监听 127.0.0.1,security=none。",
         "empty": "暂无回落",
         "add": "添加回落",
         "pickInbound": "选择一个入站",
         "matchAny": "任意",
         "destPlaceholder": "自动(子入站 listen:port)",
-        "rederive": "从子入站重新填充",
-        "rederived": "已从子入站重新填充",
-        "editAdvanced": "编辑路由字段",
-        "hideAdvanced": "隐藏高级",
-        "quickAddAll": "一键添加所有可用入站",
-        "quickAdded": "已添加 {n} 条回落",
-        "quickAddedNone": "没有可添加的新入站",
-        "routesWhen": "当满足条件时路由",
-        "defaultCatchAll": "默认 — 兜底匹配其他所有",
         "needsTls": "在“安全”标签页选择 TLS 或 Reality 后即可配置回落(仅限 RAW 上的 VLESS/Trojan)。"
       },
       "protocol": "协议",
@@ -310,8 +276,6 @@
       "portMap": "端口映射",
       "traffic": "流量",
       "speed": "速度",
-      "details": "详细信息",
-      "transportConfig": "传输",
       "expireDate": "到期时间",
       "createdAt": "创建时间",
       "updatedAt": "更新时间",
@@ -319,8 +283,6 @@
       "addInbound": "添加入站",
       "generalActions": "通用操作",
       "modifyInbound": "修改入站",
-      "deleteInbound": "删除入站",
-      "deleteInboundContent": "确定要删除入站吗?",
       "deleteConfirmTitle": "删除入站 \"{remark}\"?",
       "deleteConfirmContent": "将删除此入站及其所有客户端。该操作不可撤销。",
       "resetConfirmTitle": "重置 \"{remark}\" 的流量?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "所有入站",
       "exportAllSubsFileName": "所有入站-Subs",
       "inboundJsonTitle": "入站 JSON",
-      "deleteClient": "删除客户端",
-      "deleteClientContent": "确定要删除客户端吗?",
       "resetTrafficContent": "确定要重置流量吗?",
       "copyLink": "复制链接",
       "address": "地址",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= 无限制。(单位: GB)",
       "totalFlow": "总流量",
       "leaveBlankToNeverExpire": "留空表示永不过期",
-      "noRecommendKeepDefault": "建议保留默认值",
       "certificatePath": "文件路径",
       "certificateContent": "文件内容",
       "publicKey": "公钥",
       "privatekey": "私钥",
-      "clickOnQRcode": "点击二维码复制",
       "client": "客户",
       "export": "导出链接",
       "clone": "克隆",
-      "cloneInbound": "克隆",
-      "cloneInboundContent": "此入站规则除端口(Port)、监听 IP(Listening IP)和客户端(Clients)以外的所有配置都将应用于克隆",
-      "cloneInboundOk": "创建克隆",
       "resetAllTraffic": "重置所有入站流量",
       "resetAllTrafficTitle": "重置所有入站流量",
       "resetAllTrafficContent": "确定要重置所有入站流量吗?",
-      "resetInboundClientTraffics": "重置客户端流量",
-      "resetInboundClientTrafficTitle": "重置所有客户端流量",
-      "resetInboundClientTrafficContent": "确定要重置此入站客户端的所有流量吗?",
-      "resetAllClientTraffics": "重置所有客户端流量",
-      "resetAllClientTrafficTitle": "重置所有客户端流量",
-      "resetAllClientTrafficContent": "确定要重置所有客户端的所有流量吗?",
-      "delDepletedClients": "删除流量耗尽的客户端",
-      "delDepletedClientsTitle": "删除流量耗尽的客户端",
-      "delDepletedClientsContent": "确定要删除所有流量耗尽的客户端吗?",
       "email": "邮箱",
-      "emailDesc": "电子邮件必须完全唯一",
       "IPLimit": "IP 限制",
-      "IPLimitDesc": "如果数量超过设置值,则禁用入站流量。(0 = 禁用)",
       "IPLimitlog": "IP 日志",
-      "IPLimitlogDesc": "IP 历史日志(要启用被禁用的入站流量,请清除日志)",
       "IPLimitlogclear": "清除日志",
       "setDefaultCert": "从面板设置证书",
       "setDefaultCertEmpty": "面板尚未配置证书。请先在“设置”中设置。",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Xray sniffing 块包装:",
         "stream": "Stream",
-        "streamHelp": "Xray stream 块包装:",
-        "jsonErrorPrefix": "高级 JSON"
+        "streamHelp": "Xray stream 块包装:"
       },
-      "telegramDesc": "请提供 Telegram 聊天 ID。(在机器人中使用'/id'命令)或({'@'}userinfobot",
-      "subscriptionDesc": "要找到你的订阅 URL,请导航到“详细信息”。此外,你可以为多个客户端使用相同的名称。",
       "subSortIndex": "订阅排序",
-      "same": "相同",
       "inboundInfo": "入站信息",
       "exportInbound": "导出入站规则",
       "import": "导入",
       "importInbound": "导入入站规则",
       "periodicTrafficResetTitle": "流量重置",
-      "periodicTrafficResetDesc": "按指定间隔自动重置流量计数器",
       "periodicTrafficResetDay": "每月重置日",
-      "lastReset": "上次重置",
       "periodicTrafficReset": {
         "never": "从不",
         "daily": "每日",
@@ -464,7 +401,6 @@
         "obtain": "获取",
         "updateSuccess": "更新成功",
         "logCleanSuccess": "日志已清除",
-        "inboundsUpdateSuccess": "入站连接已成功更新",
         "inboundUpdateSuccess": "入站连接已成功更新",
         "inboundCreateSuccess": "入站连接已成功创建",
         "bulkDeleted": "已删除 {count} 个入站",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "入站客户端已删除",
         "inboundClientUpdateSuccess": "入站客户端已更新",
         "savedNodeOfflineWillSync": "已在本地保存。某个支撑节点离线或已禁用——重新连接后将同步此更改。",
-        "delDepletedClientsSuccess": "所有耗尽客户端已删除",
         "resetAllClientTrafficSuccess": "客户端所有流量已重置",
         "resetAllTrafficSuccess": "所有流量已重置",
         "resetInboundClientTrafficSuccess": "流量已重置",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Peer {n} 配置"
       },
-      "stream": {
-        "general": {
-          "request": "请求",
-          "response": "响应",
-          "name": "名称",
-          "value": "值"
-        },
-        "tcp": {
-          "version": "版本",
-          "method": "方法",
-          "path": "路径",
-          "status": "状态",
-          "statusDescription": "状态说明",
-          "requestHeader": "请求头",
-          "responseHeader": "响应头"
-        }
-      },
       "sniffingDestOverride": "目标覆盖"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "添加外部订阅",
       "noExternalLinks": "暂无外部链接。",
       "noExternalSubscriptions": "暂无外部订阅。",
-      "add": "添加客户端",
-      "edit": "编辑客户端",
-      "submitAdd": "添加客户端",
       "submitEdit": "保存更改",
       "clientCount": "客户端数量",
       "bulk": "批量添加",
-      "copyFromInbound": "从入站复制客户端",
-      "copyToInbound": "复制客户端到",
-      "copySelected": "复制所选",
-      "copySource": "来源",
-      "copyEmailPreview": "生成的邮箱预览",
-      "copySelectSourceFirst": "请先选择一个来源入站。",
-      "copyResult": "复制结果",
-      "copyResultSuccess": "复制成功",
-      "copyResultNone": "没有内容可复制:未选中客户端或来源为空",
-      "copyResultErrors": "复制错误",
-      "copyFlowLabel": "新客户端的 Flow (VLESS)",
-      "copyFlowHint": "应用于所有被复制的客户端。留空则跳过。",
       "selectAll": "全选",
       "clearAll": "全部清除",
       "method": "方式",
@@ -775,7 +678,6 @@
       "postfix": "后缀",
       "delayedStart": "首次使用后开始",
       "expireDays": "时长 (天)",
-      "days": "天",
       "renew": "自动续期",
       "renewDesc": "到期后自动续期。(0 = 禁用) (单位: 天)",
       "renewDays": "自动续期 (天)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "即将过期",
       "has": "拥有",
       "hasNot": "不拥有",
-      "title": "客户端",
       "actions": "操作",
       "totalGB": "流量上限 (GB)",
       "totalGBDesc": "该客户端的流量配额。0 = 不限制。",
@@ -826,8 +727,6 @@
       "addClient": "添加客户端",
       "qrCode": "二维码",
       "clientInfo": "客户端信息",
-      "delete": "删除",
-      "reset": "重置流量",
       "editClient": "编辑客户端",
       "client": "客户端",
       "enabled": "已启用",
@@ -841,13 +740,11 @@
       "noLinks": "没有可共享的链接 — 请先将此客户端关联到支持协议的入站。",
       "link": "链接",
       "resetNotPossible": "请先将此客户端关联到入站。",
-      "general": "常规",
       "resetAllTraffics": "重置所有客户端流量",
       "resetAllTrafficsTitle": "重置所有客户端流量?",
       "resetAllTrafficsContent": "所有客户端的上下行计数器将归零。配额与过期时间不受影响。该操作不可撤销。",
       "deleteConfirmTitle": "删除客户端 {email}?",
       "deleteConfirmContent": "将从所有关联入站中移除该客户端并删除其流量记录。该操作不可撤销。",
-      "deleteSelected": "删除 ({count})",
       "adjustSelected": "调整 ({count})",
       "subLinksSelected": "订阅链接 ({count})",
       "addToGroupTitle": "将 {count} 个客户端添加到分组",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "禁用 {count} 个客户端?",
       "bulkDisableConfirmContent": "在每个已附加的入站上禁用所选的客户端。他们将立即失去访问权限,但其记录和流量将被保留。",
       "selectedCount": "已选 {count} 项",
-      "attachSelected": "附加 ({count})",
       "attachToInboundsTitle": "将 {count} 个客户端附加到入站",
       "attachToInboundsDesc": "将选中的 {count} 个客户端(相同 UUID/密码和共享流量)附加到选定的入站。它们保留现有的附加关系。",
       "attachToInboundsTargets": "目标入站",
       "attachToInboundsNoTargets": "没有可用于附加的多用户入站。",
-      "detachSelected": "分离 ({count})",
       "detach": "分离",
       "detachFromInboundsTitle": "从入站分离 {count} 个客户端",
       "detachFromInboundsDesc": "从选定的入站中移除选中的 {count} 个客户端。客户端未附加的配对将被静默跳过。客户端记录保留(使用 Delete 完全移除)。",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "可选 Reverse tag",
       "telegramId": "Telegram 用户 ID",
       "telegramIdPlaceholder": "数字形式的 Telegram 用户 ID (0 = 无)",
-      "created": "创建时间",
-      "updated": "更新时间",
       "ipLimit": "IP 限制",
       "toasts": {
         "deleted": "客户端已删除",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "分组",
       "name": "名称",
       "clientCount": "客户端",
       "totalGroups": "分组总数",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "已从 {name} 移除 {count} 个客户端。"
     },
     "nodes": {
-      "title": "节点",
       "addNode": "添加节点",
       "editNode": "编辑节点",
       "totalNodes": "节点总数",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "远程面板设置页中的令牌",
       "apiTokenHint": "远程面板在 安全设定 → API 令牌 中显示其 API 令牌。",
       "apiTokenKeepHint": "留空以保留当前令牌",
-      "regenerate": "重新生成令牌",
-      "regenerateConfirm": "重新生成会使当前令牌失效。任何使用该令牌的中央面板都会失去访问权限,直至更新。是否继续?",
       "allowPrivateAddress": "允许私有地址",
       "allowPrivateAddressHint": "仅对私有网络或 VPN 上的节点启用。",
       "outboundTag": "连接出站",
@@ -1046,7 +935,6 @@
       "updatePanel": "更新面板",
       "updateSelected": "更新所选 ({count})",
       "updateAvailable": "有可用更新",
-      "upToDate": "已是最新",
       "updateConfirmTitle": "将 {count} 个节点更新到最新版本?",
       "updateConfirmContent": "每个所选节点会下载最新版本并重启。仅更新已启用且在线的节点。",
       "updateDevChannel": "更新到开发通道(最新提交)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "无法获取证书"
     },
     "settings": {
+      "defaultTag": "默认",
       "title": "面板设置",
       "save": "保存",
       "infoDesc": "此处的所有更改都需要保存并重启面板才能生效",
@@ -1455,13 +1344,8 @@
       "metricsListen": "指标端点",
       "metricsListenDesc": "在此 address:port 上暴露 Xray 的 Prometheus 风格指标(例如 127.0.0.1:11111)。留空则禁用。请绑定到本地回环并通过反向代理转发——它没有身份验证。",
       "metricsTag": "指标标签",
-      "title": "Xray 配置",
       "save": "保存",
-      "restart": "重启 Xray",
       "restartSuccess": "Xray 已成功重新启动",
-      "restartOutputTitle": "Xray 重启输出",
-      "restartConfirmTitle": "重启 xray?",
-      "restartConfirmContent": "使用已保存的配置重新加载 xray 服务。",
       "stopSuccess": "Xray 已成功停止",
       "restartError": "重启 Xray 时发生错误。",
       "stopError": "停止 Xray 时发生错误。",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "这些选项将决定常规配置",
       "logConfigs": "日志",
       "logConfigsDesc": "日志可能会影响服务器的性能,建议仅在需要时启用",
-      "blockConfigsDesc": "这些选项将阻止用户连接到特定协议和网站",
       "basicRouting": "基本路由",
       "blockConnectionsConfigsDesc": "这些选项将根据特定的请求国家阻止流量。",
       "directConnectionsConfigsDesc": "直接连接确保特定的流量不会通过其他服务器路由。",
@@ -1481,10 +1364,6 @@
       "directdomains": "直接域名",
       "ipv4Routing": "IPv4 路由",
       "ipv4RoutingDesc": "此选项将仅通过 IPv4 路由到目标域",
-      "warpRouting": "WARP 路由",
-      "warpRoutingDesc": "注意:在使用这些选项之前,请按照面板 GitHub 上的步骤在你的服务器上以 socks5 代理模式安装 WARP。WARP 将通过 Cloudflare 服务器将流量路由到网站。",
-      "nordRouting": "NordVPN 路由",
-      "nordRoutingDesc": "这些选项将根据特定目的地通过 NordVPN 路由流量。",
       "Template": "高级 Xray 配置模板",
       "TemplateDesc": "最终的 Xray 配置文件将基于此模板生成",
       "FreedomStrategy": "Freedom 协议策略",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "测试出站连接时使用的 URL",
       "Torrent": "屏蔽 BitTorrent 协议",
       "Inbounds": "入站",
-      "InboundsDesc": "接受来自特定客户端的流量",
       "Outbounds": "出站",
-      "OutboundSubscriptions": "出站订阅",
-      "OutboundSubscriptionsDesc": "从远程订阅 URL(vmess/vless/trojan/ss/…)导入出站。标签保持稳定,可用于负载均衡器和路由规则。更新会自动进行。",
       "Balancers": "负载均衡",
       "balancerTagRequired": "标签为必填项",
       "balancerSelectorRequired": "至少选择一个出站",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "匹配出站",
       "routeTesterViaBalancer": "经由负载均衡器",
       "routeTesterDefaultOutbound": "无路由规则匹配 — 流量将发往默认(第一个)出站。",
-      "OutboundsDesc": "设置出站流量传出方式",
       "Routings": "路由规则",
-      "RoutingsDesc": "每条规则的优先级都很重要",
       "completeTemplate": "全部",
       "logLevel": "日志级别",
       "logLevelDesc": "错误日志的日志级别,用于指示需要记录的信息",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "IP 地址掩码,启用时会自动替换日志中出现的 IP 地址。",
       "statistics": "统计",
       "statsInboundUplink": "入站上传统计",
-      "statsInboundUplinkDesc": "启用所有入站代理的上行流量统计收集。",
       "statsInboundDownlink": "入站下载统计",
-      "statsInboundDownlinkDesc": "启用所有入站代理的下行流量统计收集。",
       "statsOutboundUplink": "出站上传统计",
-      "statsOutboundUplinkDesc": "启用所有出站代理的上行流量统计收集。",
       "statsOutboundDownlink": "出站下载统计",
-      "statsOutboundDownlinkDesc": "启用所有出站代理的下行流量统计收集。",
       "connectionLimits": "连接限制",
       "connectionLimitsDesc": "用户等级 0 的连接级策略。留空则使用 Xray 的默认值。",
       "connIdle": "空闲超时",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "自动",
       "seconds": "秒",
       "rules": {
-        "first": "置顶",
-        "last": "置底",
-        "up": "向上",
-        "down": "向下",
         "source": "来源",
         "dest": "目的地址",
         "inbound": "入站",
-        "outbound": "出站",
         "balancer": "负载均衡",
-        "info": "信息",
-        "add": "添加规则",
-        "edit": "编辑规则",
         "useComma": "逗号分隔的项目"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "规则 {n}",
         "action": "操作",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "最终规则",
         "overrideXrayPrivateIp": "覆盖 Xray 默认的私有 IP 阻止",
         "blockDelay": "阻塞延迟 (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "keep alive 间隔",
         "markFwmark": "Mark (fwmark)",
         "interface": "接口",
-        "ipv6Only": "仅 IPv6",
-        "acceptProxyProtocol": "接受 proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "添加出站",
-        "addReverse": "添加反向",
-        "editOutbound": "编辑出站",
-        "editReverse": "编辑反向",
-        "reverseTag": "反向标签",
-        "reverseTagDesc": "VLESS 简易反向代理出站标签。留空则禁用。设置后,此客户端的连接可用作反向代理隧道。",
-        "reverseTagPlaceholder": "出站标签(留空则禁用)",
         "tag": "标签",
-        "tagDesc": "唯一标签",
-        "address": "地址",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "反向",
-        "domain": "域名",
-        "type": "类型",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "链接",
-        "intercon": "互连",
-        "settings": "设置",
-        "accountInfo": "帐户信息",
         "outboundStatus": "出站状态",
         "sendThrough": "发送通过",
         "targetStrategy": "目标解析策略",
-        "test": "测试",
-        "testResult": "测试结果",
-        "testing": "正在测试连接...",
-        "testSuccess": "测试成功",
-        "testFailed": "测试失败",
-        "testError": "测试出站失败",
         "modeRealDelay": "真实延迟",
         "testModeTooltip": "TCP: 快速 dial-only 探测。HTTP: 通过 xray 的完整请求。真实延迟: 含建立连接的总耗时。",
         "testAll": "全部测试",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "代理连接",
         "breakdownTls": "经由出站的 TLS",
         "breakdownTtfb": "首字节",
-        "nordvpn": "NordVPN",
-        "accessToken": "访问令牌",
         "country": "国家",
         "server": "服务器",
         "city": "城市",
         "allCities": "所有城市",
-        "privateKey": "私钥",
-        "load": "负载",
         "moveToTop": "移到顶部"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "已启用的订阅",
         "empty": "暂无订阅。请在上方添加。",
         "colRemark": "备注",
-        "colPrefix": "前缀",
-        "colInterval": "间隔",
         "colLastFetch": "上次拉取",
         "colEnabled": "启用",
         "auto": "自动",
         "never": "从未",
-        "yes": "是",
-        "no": "否",
         "refreshNow": "立即刷新",
-        "lastError": "上次错误",
         "deleteConfirm": "删除此订阅?",
         "restartHint": "添加或刷新后,请重启 Xray(或等待下一次自动重载)以使出站生效。",
         "fromSubsTitle": "来自出站订阅(只读)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "负载均衡设置",
       "tabObservatory": "观测器",
       "observatory": {
-        "title": "观测器",
-        "burstTitle": "突发观测器",
         "autoManaged": "观测器会根据你的负载均衡器自动管理。可在下方调整探测方式;被观测的出站会跟随负载均衡器的选择器。",
         "emptyHint": "当前没有活动的连接观测器。当你创建 Least Ping 或 Least Load 负载均衡器,或带有 fallback 的 Random / Round-robin 负载均衡器时,会自动添加一个,以便依赖观测器的负载均衡器在选择目标前检查出站健康状态。",
         "mixedLegacy": "此配置同时包含 Observatory 和 Burst Observatory。Xray 只使用一个全局观测器,因此不支持这种旧式混合状态;保存负载均衡器时会将其规范化为单个观测器。",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "负载均衡器 {tag} — 已移除(没有剩余目标)"
       },
       "balancer": {
-        "addBalancer": "添加负载均衡",
-        "editBalancer": "编辑负载均衡",
         "balancerStrategy": "策略",
-        "balancerSelectors": "选择器",
         "tag": "标签",
-        "tagDesc": "唯一标签",
         "tagDuplicate": "该标签已被其他均衡器使用",
         "tagPlaceholder": "唯一均衡器标签",
         "selector": "选择器",
@@ -1789,7 +1609,6 @@
         "tolerance": "容差",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "无法同时使用 balancerTag 和 outboundTag。如果同时使用,则只有 outboundTag 会生效。",
         "costMatch": "标签匹配模式",
         "costValue": "权重",
         "costRegexp": "正则表达式匹配",
@@ -1804,14 +1623,10 @@
         "publicKey": "公钥",
         "allowedIPs": "允许的 IP",
         "endpoint": "端点",
-        "psk": "共享密钥",
         "domainStrategy": "域策略"
       },
       "tun": {
-        "nameDesc": "TUN 接口的名称。默认值为 'xray0'",
-        "mtuDesc": "最大传输单元。数据包的最大大小。默认值为 1500",
-        "userLevel": "用户级别",
-        "userLevelDesc": "通过此入站的所有连接都将使用此用户级别。默认值为 0"
+        "userLevel": "用户级别"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "添加假 DNS",
-        "edit": "编辑假 DNS",
         "ipPool": "IP 池子网",
         "poolSize": "池大小"
       },
@@ -2032,7 +1846,6 @@
     "add": "添加",
     "month": "月",
     "months": "月",
-    "day": "天",
     "days": "天",
     "hours": "小时",
     "minutes": "分钟",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ 电报用户已保存。",
       "loginSuccess": "✅ 成功登录到面板。\r\n",
       "loginFailed": "❗️ 面板登录失败。\r\n",
-      "2faFailed": "2FA 失败",
       "report": "🕰 定时报告:{{ .RunTime }}\r\n",
       "datetime": "⏰ 日期时间:{{ .DateTime }}\r\n",
       "hostname": "💻 主机: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 下载: ↓{{ .Download }}\r\n",
       "total": "📊 总计: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 电报用户:{{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 耗尽的 {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 耗尽的 {{ .Type }} 数量:\r\n",
       "onlinesCount": "🌐 在线客户:{{ .Count }}\r\n",
       "disabled": "🛑 禁用:{{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 刷新时间:{{ .Time }}\r\n\r\n",
       "yes": "✅ 是的",
       "no": "❌ 否",
-      "received_id": "🔑📥 ID 已更新。",
-      "received_password": "🔑📥 密码已更新。",
       "received_email": "📧📥 邮箱已更新。",
       "received_comment": "💬📥 评论已更新。",
-      "id_prompt": "🔑 默认 ID: {{ .ClientId }}\n\n请输入您的 ID。",
-      "pass_prompt": "🔑 默认密码: {{ .ClientPassword }}\n\n请输入您的密码。",
       "email_prompt": "📧 默认邮箱: {{ .ClientEmail }}\n\n请输入您的邮箱。",
       "comment_prompt": "💬 默认评论: {{ .ClientComment }}\n\n请输入您的评论。",
-      "inbound_client_data_id": "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!",
-      "inbound_client_data_pass": "🔄 入站: {{ .InboundRemark }}\n\n🔑 密码: {{ .ClientPass }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!",
       "cancel": "❌ 进程已取消!\n\n您可以随时使用 /start 重新开始。 🔄",
       "error_add_client": "⚠️ 错误:\n\n {{ .error }}",
       "using_default_value": "好的,我会使用默认值。 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "错误:{{ .Error }}",
       "eventNodeDown": "节点 {{ .Name }} 已离线",
       "eventNodeUp": "节点 {{ .Name }} 已上线",
-      "eventCPUHigh": "CPU 占用过高",
-      "eventCPUHighDetail": "CPU:{{ .Detail }}",
       "eventLoginFallback": "来自 {{ .Source }} 的登录失败",
       "memoryThreshold": "内存使用率 {{ .Percent }}% 超过阈值 {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "提交为禁用 ☑️",
       "submitEnable": "提交为启用 ✅",
       "use_default": "🏷️ 使用默认",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 密码",
       "change_email": "⚙️📧 邮箱",
       "change_comment": "⚙️💬 评论",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "重置所有流量",
       "SortedTrafficUsageReport": "排序的流量使用报告"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "出站 {{ .Tag }} 已断开",
-    "subjectOutboundUp": "出站 {{ .Tag }} 已恢复",
-    "subjectXrayCrash": "Xray 已崩溃",
-    "subjectCPUHigh": "CPU 占用过高",
-    "subjectLoginSuccess": "登录成功",
-    "subjectLoginFailed": "登录失败",
-    "titleOutboundDown": "出站断开",
-    "titleOutboundUp": "出站恢复",
-    "titleXrayCrash": "Xray 已崩溃",
-    "titleCPUHigh": "CPU 占用过高",
-    "titleLoginSuccess": "登录成功",
-    "titleLoginFailed": "登录失败",
     "labelStatus": "状态",
     "labelOutbound": "出站",
     "labelNode": "节点",
     "labelError": "错误",
     "labelDelay": "延迟",
-    "labelDetail": "详情",
     "labelUsername": "用户名",
     "labelIP": "IP",
     "labelReason": "原因",
     "labelSource": "来源",
-    "labelTime": "时间",
     "statusCrashed": "已崩溃",
-    "statusRunning": "运行中",
     "statusHigh": "过高",
     "statusSuccess": "成功",
     "statusFailed": "失败",

+ 3 - 218
internal/web/translation/zh-TW.json

@@ -48,7 +48,6 @@
   "copySuccess": "複製成功",
   "sure": "確定",
   "encryption": "加密",
-  "useIPv4ForHost": "使用 IPv4 連接主機",
   "transmission": "傳輸",
   "host": "主機",
   "path": "路徑",
@@ -74,18 +73,9 @@
   "twoFactorCode": "代碼",
   "remained": "剩餘",
   "security": "安全",
-  "secAlertTitle": "安全警報",
-  "secAlertSsl": "此連線不安全。在啟用 TLS 進行資料保護之前,請勿輸入敏感資訊。",
-  "secAlertConf": "某些設定易受攻擊。建議加強安全協議以防止潛在漏洞。",
-  "secAlertSSL": "面板缺少安全連線。請安裝 TLS 證書以保護資料安全。",
-  "secAlertPanelPort": "面板預設埠存在安全風險。請配置隨機埠或特定埠。",
-  "secAlertPanelURI": "面板預設 URI 路徑不安全。請配置複雜的 URI 路徑。",
-  "secAlertSubURI": "訂閱預設 URI 路徑不安全。請配置複雜的 URI 路徑。",
-  "secAlertSubJsonURI": "訂閱 JSON 預設 URI 路徑不安全。請配置複雜的 URI 路徑。",
   "emptyDnsDesc": "未添加 DNS 伺服器。",
   "emptyFakeDnsDesc": "未添加 Fake DNS 伺服器。",
   "emptyBalancersDesc": "未添加負載平衡器。",
-  "emptyReverseDesc": "未添加反向代理。",
   "somethingWentWrong": "發生錯誤",
   "subscription": {
     "title": "訂閱資訊",
@@ -106,8 +96,6 @@
   },
   "menu": {
     "theme": "主題",
-    "dark": "深色",
-    "ultraDark": "超深色",
     "dashboard": "系統狀態",
     "inbounds": "入站",
     "clients": "客戶端",
@@ -118,7 +106,6 @@
     "routing": "路由",
     "outbounds": "出站",
     "apiDocs": "API 文件",
-    "logout": "退出登入",
     "link": "管理",
     "donate": "捐贈",
     "hosts": "Hosts",
@@ -139,7 +126,6 @@
       }
     },
     "index": {
-      "title": "系統狀態",
       "cpu": "CPU",
       "logicalProcessors": "邏輯處理器",
       "frequency": "頻率",
@@ -152,7 +138,6 @@
       "restartXray": "重新啟動",
       "xraySwitch": "版本",
       "xrayUpdates": "Xray 更新",
-      "xraySwitchClick": "選擇你要切換到的版本",
       "xraySwitchClickDesk": "請謹慎選擇,因為較舊版本可能與當前配置不相容",
       "updatePanel": "更新面板",
       "panelUpdateDesc": "這將把 3X-UI 更新到最新版本並重新啟動面板服務。",
@@ -164,12 +149,10 @@
       "currentCommit": "目前提交",
       "latestCommit": "最新提交",
       "updateChannelChanged": "更新通道已切換",
-      "upToDate": "已是最新",
       "xrayStatusUnknown": "未知",
       "xrayStatusRunning": "運行中",
       "xrayStatusStop": "停止",
       "xrayStatusError": "錯誤",
-      "xrayErrorPopoverTitle": "執行 Xray 時發生錯誤",
       "operationHours": "系統正常執行時間",
       "systemHistoryTitle": "系統歷史",
       "historyTitleCpu": "CPU 使用率",
@@ -211,9 +194,6 @@
       "xrayObservatoryDead": "離線",
       "xrayObservatoryLastSeen": "最後在線",
       "xrayObservatoryLastTry": "最後嘗試",
-      "trendLast2Min": "最近 2 分鐘",
-      "systemLoad": "系統負載",
-      "systemLoadDesc": "過去 1、5 和 15 分鐘的系統平均負載",
       "connectionCount": "連線數",
       "ipAddresses": "IP 地址",
       "toggleIpVisibility": "切換 IP 可見性",
@@ -223,13 +203,11 @@
       "totalData": "總數據",
       "sent": "已發送",
       "received": "已接收",
-      "documentation": "文件",
       "xraySwitchVersionDialog": "您確定要變更 Xray 版本嗎?",
       "xraySwitchVersionDialogDesc": "這將會把 Xray 版本變更為 #version#。",
       "xraySwitchVersionPopover": "Xray 更新成功",
       "panelUpdateDialog": "您確定要更新面板嗎?",
       "panelUpdateDialogDesc": "這將把 3X-UI 更新到 #version# 並重新啟動面板服務。",
-      "panelUpdateCheckPopover": "面板更新檢查失敗",
       "panelUpdateStartedPopover": "面板更新已開始",
       "panelUpdateFailedTitle": "面板更新失敗",
       "panelUpdateFailedDesc": "更新未成功完成。請檢查伺服器日誌,或在命令列執行「x-ui update」。",
@@ -258,7 +236,6 @@
       "accessLogs": "存取記錄",
       "autoUpdate": "自動更新",
       "config": "配置",
-      "backup": "備份",
       "backupTitle": "備份和恢復",
       "exportDatabase": "備份",
       "exportDatabaseDesc": "點擊下載包含當前資料庫備份的 .db 文件到您的設備。同一檔案也可以還原到執行 PostgreSQL 的面板中。",
@@ -276,7 +253,6 @@
       "migrationDownloadPgDesc": "點擊下載由 PostgreSQL 資料建立的 .db SQLite 資料庫,可用於在 SQLite 上執行本面板。"
     },
     "inbounds": {
-      "title": "入站",
       "totalDownUp": "總上傳 / 下載",
       "totalUsage": "總用量",
       "inboundCount": "入站數量",
@@ -288,21 +264,11 @@
       "localPanel": "本機面板",
       "fallbacks": {
         "title": "Fallbacks",
-        "help": "當此入站的連線未匹配任何用戶時,將其路由到其他位置。在下方選擇一個子入站,可從其傳輸方式自動填入路由欄位(SNI / ALPN / Path / xver);或將選擇框留空並直接設定 Dest(例如 8080 或 127.0.0.1:8080),以路由到 Nginx 等外部伺服器。每個子入站應監聽 127.0.0.1,security=none。",
         "empty": "尚未新增回落",
         "add": "新增回落",
         "pickInbound": "選擇一個入站",
         "matchAny": "任何",
         "destPlaceholder": "自動(子入站 listen:port)",
-        "rederive": "從子入站重新填入",
-        "rederived": "已從子入站重新填入",
-        "editAdvanced": "編輯路由欄位",
-        "hideAdvanced": "隱藏進階",
-        "quickAddAll": "一鍵新增所有符合的入站",
-        "quickAdded": "已新增 {n} 個回落",
-        "quickAddedNone": "沒有可新增的新入站",
-        "routesWhen": "當條件成立時路由",
-        "defaultCatchAll": "預設 — 兜底匹配其餘",
         "needsTls": "在「安全」分頁選擇 TLS 或 Reality 後即可設定回落(僅限 RAW 上的 VLESS/Trojan)。"
       },
       "protocol": "協議",
@@ -310,8 +276,6 @@
       "portMap": "連接埠對應",
       "traffic": "流量",
       "speed": "速度",
-      "details": "詳細資訊",
-      "transportConfig": "傳輸",
       "expireDate": "到期時間",
       "createdAt": "建立時間",
       "updatedAt": "更新時間",
@@ -319,8 +283,6 @@
       "addInbound": "新增入站",
       "generalActions": "通用操作",
       "modifyInbound": "修改入站",
-      "deleteInbound": "刪除入站",
-      "deleteInboundContent": "確定要刪除入站嗎?",
       "deleteConfirmTitle": "刪除入站「{remark}」?",
       "deleteConfirmContent": "將刪除此入站及其所有客戶端。此操作無法復原。",
       "resetConfirmTitle": "重置「{remark}」的流量?",
@@ -364,8 +326,6 @@
       "exportAllLinksFileName": "所有入站",
       "exportAllSubsFileName": "所有入站-Subs",
       "inboundJsonTitle": "入站 JSON",
-      "deleteClient": "刪除客戶端",
-      "deleteClientContent": "確定要刪除客戶端嗎?",
       "resetTrafficContent": "確定要重置流量嗎?",
       "copyLink": "複製連結",
       "address": "地址",
@@ -376,36 +336,19 @@
       "meansNoLimit": "= 無限制。(單位: GB)",
       "totalFlow": "總流量",
       "leaveBlankToNeverExpire": "留空表示永不過期",
-      "noRecommendKeepDefault": "建議保留預設值",
       "certificatePath": "檔案路徑",
       "certificateContent": "檔案內容",
       "publicKey": "公鑰",
       "privatekey": "私鑰",
-      "clickOnQRcode": "點選二維碼複製",
       "client": "客戶",
       "export": "匯出連結",
       "clone": "複製",
-      "cloneInbound": "複製",
-      "cloneInboundContent": "此入站規則除埠(Port)、監聽 IP(Listening IP)和客戶端(Clients)以外的所有配置都將應用於克隆",
-      "cloneInboundOk": "建立克隆",
       "resetAllTraffic": "重置所有入站流量",
       "resetAllTrafficTitle": "重置所有入站流量",
       "resetAllTrafficContent": "確定要重置所有入站流量嗎?",
-      "resetInboundClientTraffics": "重置客戶端流量",
-      "resetInboundClientTrafficTitle": "重置所有客戶端流量",
-      "resetInboundClientTrafficContent": "確定要重置此入站客戶端的所有流量嗎?",
-      "resetAllClientTraffics": "重置所有客戶端流量",
-      "resetAllClientTrafficTitle": "重置所有客戶端流量",
-      "resetAllClientTrafficContent": "確定要重置所有客戶端的所有流量嗎?",
-      "delDepletedClients": "刪除流量耗盡的客戶端",
-      "delDepletedClientsTitle": "刪除流量耗盡的客戶端",
-      "delDepletedClientsContent": "確定要刪除所有流量耗盡的客戶端嗎?",
       "email": "電子郵件",
-      "emailDesc": "電子郵件必須完全唯一",
       "IPLimit": "IP 限制",
-      "IPLimitDesc": "如果數量超過設定值,則禁用入站流量。(0 = 禁用)",
       "IPLimitlog": "IP 日誌",
-      "IPLimitlogDesc": "IP 歷史日誌(要啟用被禁用的入站流量,請清除日誌)",
       "IPLimitlogclear": "清除日誌",
       "setDefaultCert": "從面板設定證書",
       "setDefaultCertEmpty": "面板尚未設定憑證。請先在「設定」中設定。",
@@ -438,21 +381,15 @@
         "sniffing": "Sniffing",
         "sniffingHelp": "Xray sniffing 區塊包裝:",
         "stream": "Stream",
-        "streamHelp": "Xray stream 區塊包裝:",
-        "jsonErrorPrefix": "進階 JSON"
+        "streamHelp": "Xray stream 區塊包裝:"
       },
-      "telegramDesc": "請提供 Telegram 聊天 ID。(在機器人中使用'/id'命令)或({'@'}userinfobot",
-      "subscriptionDesc": "要找到你的訂閱 URL,請導航到“詳細資訊”。此外,你可以為多個客戶端使用相同的名稱。",
       "subSortIndex": "訂閱排序",
-      "same": "相同",
       "inboundInfo": "入站資訊",
       "exportInbound": "匯出入站規則",
       "import": "匯入",
       "importInbound": "匯入入站規則",
       "periodicTrafficResetTitle": "流量重置",
-      "periodicTrafficResetDesc": "按指定間隔自動重置流量計數器",
       "periodicTrafficResetDay": "每月重置日",
-      "lastReset": "上次重置",
       "periodicTrafficReset": {
         "never": "從不",
         "daily": "每日",
@@ -464,7 +401,6 @@
         "obtain": "獲取",
         "updateSuccess": "更新成功",
         "logCleanSuccess": "日誌已清除",
-        "inboundsUpdateSuccess": "入站連接已成功更新",
         "inboundUpdateSuccess": "入站連接已成功更新",
         "inboundCreateSuccess": "入站連接已成功建立",
         "bulkDeleted": "已刪除 {count} 個入站",
@@ -474,7 +410,6 @@
         "inboundClientDeleteSuccess": "入站客戶端已刪除",
         "inboundClientUpdateSuccess": "入站客戶端已更新",
         "savedNodeOfflineWillSync": "已在本機儲存。某個支撐節點離線或已停用——重新連線後將同步此變更。",
-        "delDepletedClientsSuccess": "所有耗盡客戶端已刪除",
         "resetAllClientTrafficSuccess": "客戶端所有流量已重置",
         "resetAllTrafficSuccess": "所有流量已重置",
         "resetInboundClientTrafficSuccess": "流量已重置",
@@ -717,23 +652,6 @@
         "peerNumber": "Peer {n}",
         "peerNumberConfig": "Peer {n} 設定"
       },
-      "stream": {
-        "general": {
-          "request": "請求",
-          "response": "響應",
-          "name": "名稱",
-          "value": "值"
-        },
-        "tcp": {
-          "version": "版本",
-          "method": "方法",
-          "path": "路徑",
-          "status": "狀態",
-          "statusDescription": "狀態說明",
-          "requestHeader": "請求頭",
-          "responseHeader": "響應頭"
-        }
-      },
       "sniffingDestOverride": "目標覆寫"
     },
     "clients": {
@@ -747,24 +665,9 @@
       "addExternalSubscription": "新增外部訂閱",
       "noExternalLinks": "尚無外部連結。",
       "noExternalSubscriptions": "尚無外部訂閱。",
-      "add": "新增客戶端",
-      "edit": "編輯客戶端",
-      "submitAdd": "新增客戶端",
       "submitEdit": "儲存變更",
       "clientCount": "客戶端數量",
       "bulk": "批次新增",
-      "copyFromInbound": "從入站複製客戶端",
-      "copyToInbound": "複製客戶端至",
-      "copySelected": "複製所選",
-      "copySource": "來源",
-      "copyEmailPreview": "產生的信箱預覽",
-      "copySelectSourceFirst": "請先選擇一個來源入站。",
-      "copyResult": "複製結果",
-      "copyResultSuccess": "複製成功",
-      "copyResultNone": "沒有內容可複製:未選取客戶端或來源為空",
-      "copyResultErrors": "複製錯誤",
-      "copyFlowLabel": "新客戶端的 Flow (VLESS)",
-      "copyFlowHint": "套用至所有被複製的客戶端。留空則略過。",
       "selectAll": "全選",
       "clearAll": "全部清除",
       "method": "方法",
@@ -775,7 +678,6 @@
       "postfix": "後綴",
       "delayedStart": "首次使用後開始",
       "expireDays": "時長 (天)",
-      "days": "天",
       "renew": "自動續期",
       "renewDesc": "到期後自動續期。(0 = 停用) (單位: 天)",
       "renewDays": "自動續期 (天)",
@@ -798,7 +700,6 @@
       "sortExpiringSoonest": "即將到期",
       "has": "擁有",
       "hasNot": "不擁有",
-      "title": "客戶端",
       "actions": "操作",
       "totalGB": "流量上限 (GB)",
       "totalGBDesc": "該客戶端的流量配額。0 = 不限制。",
@@ -826,8 +727,6 @@
       "addClient": "新增客戶端",
       "qrCode": "QR 碼",
       "clientInfo": "客戶端資訊",
-      "delete": "刪除",
-      "reset": "重設流量",
       "editClient": "編輯客戶端",
       "client": "客戶端",
       "enabled": "已啟用",
@@ -841,13 +740,11 @@
       "noLinks": "沒有可共享的連結 — 請先將此客戶端關聯至支援協定的入站。",
       "link": "連結",
       "resetNotPossible": "請先將此客戶端關聯至入站。",
-      "general": "一般",
       "resetAllTraffics": "重設所有客戶端流量",
       "resetAllTrafficsTitle": "重設所有客戶端流量?",
       "resetAllTrafficsContent": "所有客戶端的上下行計數器將歸零。配額與到期時間不受影響。此操作無法復原。",
       "deleteConfirmTitle": "刪除客戶端 {email}?",
       "deleteConfirmContent": "將從所有關聯入站中移除該客戶端並刪除其流量紀錄。此操作無法復原。",
-      "deleteSelected": "刪除 ({count})",
       "adjustSelected": "調整 ({count})",
       "subLinksSelected": "訂閱連結 ({count})",
       "addToGroupTitle": "將 {count} 個客戶端加入群組",
@@ -869,12 +766,10 @@
       "bulkDisableConfirmTitle": "停用 {count} 個客戶端?",
       "bulkDisableConfirmContent": "在每個已附加的入站上停用所選的客戶端。他們將立即失去存取權限,但其記錄與流量將被保留。",
       "selectedCount": "已選 {count} 項",
-      "attachSelected": "附加 ({count})",
       "attachToInboundsTitle": "將 {count} 個客戶端附加到入站",
       "attachToInboundsDesc": "將選取的 {count} 個客戶端(相同 UUID/密碼與共享流量)附加到選定入站。它們保留現有附加關係。",
       "attachToInboundsTargets": "目標入站",
       "attachToInboundsNoTargets": "沒有可供附加的多用戶入站。",
-      "detachSelected": "分離 ({count})",
       "detach": "分離",
       "detachFromInboundsTitle": "從入站分離 {count} 個客戶端",
       "detachFromInboundsDesc": "從選定入站中移除選取的 {count} 個客戶端。客戶端未附加的配對會被靜默略過。客戶端記錄保留(用 Delete 完全移除)。",
@@ -928,8 +823,6 @@
       "reverseTagPlaceholder": "選用 Reverse tag",
       "telegramId": "Telegram 使用者 ID",
       "telegramIdPlaceholder": "數字形式的 Telegram 使用者 ID (0 = 無)",
-      "created": "建立時間",
-      "updated": "更新時間",
       "ipLimit": "IP 限制",
       "toasts": {
         "deleted": "客戶端已刪除",
@@ -952,7 +845,6 @@
       }
     },
     "groups": {
-      "title": "群組",
       "name": "名稱",
       "clientCount": "客戶端",
       "totalGroups": "群組總數",
@@ -994,7 +886,6 @@
       "removeFromGroupResult": "已從 {name} 移除 {count} 個客戶端。"
     },
     "nodes": {
-      "title": "節點",
       "addNode": "新增節點",
       "editNode": "編輯節點",
       "totalNodes": "節點總數",
@@ -1013,8 +904,6 @@
       "apiTokenPlaceholder": "遠端面板設定頁中的權杖",
       "apiTokenHint": "遠端面板在 安全設定 → API 權杖 中顯示其 API 權杖。",
       "apiTokenKeepHint": "留空以保留目前的權杖",
-      "regenerate": "重新產生權杖",
-      "regenerateConfirm": "重新產生會使目前的權杖失效。任何使用該權杖的中央面板將失去存取權,直到更新為止。是否繼續?",
       "allowPrivateAddress": "允許私有地址",
       "allowPrivateAddressHint": "僅對私有網路或 VPN 上的節點啟用。",
       "outboundTag": "連線出站",
@@ -1046,7 +935,6 @@
       "updatePanel": "更新面板",
       "updateSelected": "更新所選 ({count})",
       "updateAvailable": "有可用更新",
-      "upToDate": "已是最新",
       "updateConfirmTitle": "將 {count} 個節點更新到最新版本?",
       "updateConfirmContent": "每個所選節點會下載最新版本並重新啟動。僅更新已啟用且在線的節點。",
       "updateDevChannel": "更新到開發通道(最新提交)",
@@ -1110,6 +998,7 @@
       "pinFetchFailed": "無法取得憑證"
     },
     "settings": {
+      "defaultTag": "預設",
       "title": "面板設定",
       "save": "儲存",
       "infoDesc": "此處的所有更改都需要儲存並重啟面板才能生效",
@@ -1447,13 +1336,8 @@
       "secretClearUndo": "復原清除"
     },
     "xray": {
-      "title": "Xray 配置",
       "save": "儲存",
-      "restart": "重新啟動 Xray",
       "restartSuccess": "Xray 已成功重新啟動",
-      "restartOutputTitle": "Xray 重新啟動輸出",
-      "restartConfirmTitle": "重新啟動 xray?",
-      "restartConfirmContent": "使用已儲存的設定重新載入 xray 服務。",
       "stopSuccess": "Xray 已成功停止",
       "restartError": "重新啟動 Xray 時發生錯誤。",
       "stopError": "停止 Xray 時發生錯誤。",
@@ -1471,7 +1355,6 @@
       "generalConfigsDesc": "這些選項將決定常規配置",
       "logConfigs": "記錄",
       "logConfigsDesc": "日誌可能會影響伺服器的效能,建議僅在需要時啟用",
-      "blockConfigsDesc": "這些選項將阻止使用者連線到特定協議和網站",
       "basicRouting": "基本路由",
       "blockConnectionsConfigsDesc": "這些選項將根據特定的請求國家阻止流量。",
       "directConnectionsConfigsDesc": "直接連線確保特定的流量不會通過其他伺服器路由。",
@@ -1481,10 +1364,6 @@
       "directdomains": "直接域名",
       "ipv4Routing": "IPv4 路由",
       "ipv4RoutingDesc": "此選項將僅通過 IPv4 路由到目標域",
-      "warpRouting": "WARP 路由",
-      "warpRoutingDesc": "注意:在使用這些選項之前,請按照面板 GitHub 上的步驟在你的伺服器上以 socks5 代理模式安裝 WARP。WARP 將通過 Cloudflare 伺服器將流量路由到網站。",
-      "nordRouting": "NordVPN 路由",
-      "nordRoutingDesc": "這些選項將根據特定目的地通過 NordVPN 路由流量。",
       "Template": "高階 Xray 配置模板",
       "TemplateDesc": "最終的 Xray 配置檔案將基於此模板生成",
       "FreedomStrategy": "Freedom 協議策略",
@@ -1498,10 +1377,7 @@
       "outboundTestUrlDesc": "測試出站連線時使用的 URL",
       "Torrent": "遮蔽 BitTorrent 協議",
       "Inbounds": "入站",
-      "InboundsDesc": "接受來自特定客戶端的流量",
       "Outbounds": "出站",
-      "OutboundSubscriptions": "出站訂閱",
-      "OutboundSubscriptionsDesc": "從遠端訂閱 URL(vmess/vless/trojan/ss/...)匯入出站。標籤會保持穩定,以便在負載均衡與路由規則中使用。系統會自動更新。",
       "Balancers": "負載均衡",
       "balancerTagRequired": "標籤為必填",
       "balancerSelectorRequired": "至少選擇一個出站",
@@ -1520,9 +1396,7 @@
       "routeTesterMatchedOutbound": "匹配出站",
       "routeTesterViaBalancer": "經由負載均衡器",
       "routeTesterDefaultOutbound": "無路由規則匹配 — 流量將導向預設(第一個)出站。",
-      "OutboundsDesc": "設定出站流量傳出方式",
       "Routings": "路由規則",
-      "RoutingsDesc": "每條規則的優先順序都很重要",
       "completeTemplate": "全部",
       "logLevel": "日誌級別",
       "logLevelDesc": "錯誤日誌的日誌級別,用於指示需要記錄的資訊",
@@ -1536,13 +1410,9 @@
       "maskAddressDesc": "IP 地址掩碼,啟用時會自動替換日誌中出現的 IP 地址。",
       "statistics": "統計",
       "statsInboundUplink": "入站上傳統計",
-      "statsInboundUplinkDesc": "啟用所有入站代理的上行流量統計收集。",
       "statsInboundDownlink": "入站下載統計",
-      "statsInboundDownlinkDesc": "啟用所有入站代理的下行流量統計收集。",
       "statsOutboundUplink": "出站上傳統計",
-      "statsOutboundUplinkDesc": "啟用所有出站代理的上行流量統計收集。",
       "statsOutboundDownlink": "出站下載統計",
-      "statsOutboundDownlinkDesc": "啟用所有出站代理的下行流量統計收集。",
       "connectionLimits": "連線限制",
       "connectionLimitsDesc": "使用者等級 0 的連線層級原則。留空則使用 Xray 的預設值。",
       "connIdle": "閒置逾時",
@@ -1552,18 +1422,10 @@
       "bufferSizePlaceholder": "自動",
       "seconds": "秒",
       "rules": {
-        "first": "置頂",
-        "last": "置底",
-        "up": "向上",
-        "down": "向下",
         "source": "來源",
         "dest": "目的地址",
         "inbound": "入站",
-        "outbound": "出站",
         "balancer": "負載均衡",
-        "info": "資訊",
-        "add": "新增規則",
-        "edit": "編輯規則",
         "useComma": "逗號分隔的項目"
       },
       "routing": {
@@ -1604,7 +1466,6 @@
         "ruleN": "規則 {n}",
         "action": "動作",
         "redirect": "Redirect",
-        "fragment": "Fragment",
         "finalRules": "最終規則",
         "overrideXrayPrivateIp": "覆寫 Xray 預設的私有 IP 封鎖",
         "blockDelay": "阻斷延遲 (ms)",
@@ -1630,43 +1491,17 @@
         "keepAliveInterval": "keep alive 間隔",
         "markFwmark": "Mark (fwmark)",
         "interface": "介面",
-        "ipv6Only": "僅 IPv6",
-        "acceptProxyProtocol": "接受 proxy protocol",
         "proxyProtocol": "Proxy protocol",
         "tcpUserTimeoutMs": "TCP user timeout (ms)",
         "tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
       },
       "outbound": {
-        "addOutbound": "新增出站",
-        "addReverse": "新增反向",
-        "editOutbound": "編輯出站",
-        "editReverse": "編輯反向",
-        "reverseTag": "反向標籤",
-        "reverseTagDesc": "VLESS 簡易反向代理出站標籤。留空則停用。設定後,此客戶端的連線可作為反向代理隧道。",
-        "reverseTagPlaceholder": "出站標籤(留空則停用)",
         "tag": "標籤",
-        "tagDesc": "唯一標籤",
-        "address": "地址",
         "egress": "Egress",
         "egressHint": "Run an HTTP test to show egress IP and country.",
-        "reverse": "反向",
-        "domain": "網域",
-        "type": "類型",
-        "bridge": "Bridge",
-        "portal": "Portal",
-        "link": "連結",
-        "intercon": "互連",
-        "settings": "設定",
-        "accountInfo": "帳戶資訊",
         "outboundStatus": "出站狀態",
         "sendThrough": "傳送通過",
         "targetStrategy": "目標解析策略",
-        "test": "測試",
-        "testResult": "測試結果",
-        "testing": "正在測試連接...",
-        "testSuccess": "測試成功",
-        "testFailed": "測試失敗",
-        "testError": "測試出站失敗",
         "modeRealDelay": "真實延遲",
         "testModeTooltip": "TCP: 快速 dial-only 探測。HTTP: 透過 xray 的完整請求。真實延遲: 含建立連線的總耗時。",
         "testAll": "全部測試",
@@ -1674,14 +1509,10 @@
         "breakdownConnect": "代理連線",
         "breakdownTls": "經由出站的 TLS",
         "breakdownTtfb": "首位元組",
-        "nordvpn": "NordVPN",
-        "accessToken": "訪問令牌",
         "country": "國家",
         "server": "伺服器",
         "city": "城市",
         "allCities": "所有城市",
-        "privateKey": "私密金鑰",
-        "load": "負載",
         "moveToTop": "移到頂部"
       },
       "outboundSub": {
@@ -1711,16 +1542,11 @@
         "active": "啟用中的訂閱",
         "empty": "尚無訂閱。請從上方新增。",
         "colRemark": "備註",
-        "colPrefix": "前綴",
-        "colInterval": "間隔",
         "colLastFetch": "上次抓取",
         "colEnabled": "啟用",
         "auto": "自動",
         "never": "從不",
-        "yes": "是",
-        "no": "否",
         "refreshNow": "立即重新整理",
-        "lastError": "上次錯誤",
         "deleteConfirm": "確定要刪除此訂閱嗎?",
         "restartHint": "新增或重新整理後,請重新啟動 Xray(或等待下次自動重新載入),讓出站生效。",
         "fromSubsTitle": "來自出站訂閱(唯讀)",
@@ -1737,8 +1563,6 @@
       "tabBalancerSettings": "負載平衡設定",
       "tabObservatory": "觀測器",
       "observatory": {
-        "title": "觀測器",
-        "burstTitle": "突發觀測器",
         "autoManaged": "觀測器會根據你的負載平衡器自動管理。可在下方調整探測方式;被觀測的出站會跟隨負載平衡器的選擇器。",
         "emptyHint": "目前沒有作用中的連線觀測器。當你建立 Least Ping 或 Least Load 負載平衡器,或帶有 fallback 的 Random / Round-robin 負載平衡器時,會自動新增一個,讓依賴觀測器的負載平衡器能在選擇目標前檢查出站健康狀態。",
         "mixedLegacy": "此設定同時包含 Observatory 與 Burst Observatory。Xray 只使用一個全域觀測器,因此不支援這種舊式混合狀態;儲存負載平衡器時會將其正規化為單一觀測器。",
@@ -1772,12 +1596,8 @@
         "balancerRemoved": "負載平衡器 {tag} — 已移除(沒有剩餘目標)"
       },
       "balancer": {
-        "addBalancer": "新增負載均衡",
-        "editBalancer": "編輯負載均衡",
         "balancerStrategy": "策略",
-        "balancerSelectors": "選擇器",
         "tag": "標籤",
-        "tagDesc": "唯一標籤",
         "tagDuplicate": "該標籤已被其他均衡器使用",
         "tagPlaceholder": "唯一均衡器標籤",
         "selector": "選擇器",
@@ -1789,7 +1609,6 @@
         "tolerance": "容差",
         "baselines": "Baselines",
         "costs": "Costs",
-        "balancerDesc": "無法同時使用 balancerTag 和 outboundTag。如果同時使用,則只有 outboundTag 會生效。",
         "costMatch": "標籤比對模式",
         "costValue": "權重",
         "costRegexp": "正規表示式比對",
@@ -1804,14 +1623,10 @@
         "publicKey": "公鑰",
         "allowedIPs": "允許的 IP",
         "endpoint": "端點",
-        "psk": "共享金鑰",
         "domainStrategy": "域策略"
       },
       "tun": {
-        "nameDesc": "TUN 介面的名稱。預設值為 'xray0'",
-        "mtuDesc": "最大傳輸單元。資料包的最大大小。預設值為 1500",
-        "userLevel": "用戶級別",
-        "userLevelDesc": "通過此入站的所有連接都將使用此用戶級別。預設值為 0"
+        "userLevel": "用戶級別"
       },
       "nord": {
         "accessToken": "Access token",
@@ -1896,7 +1711,6 @@
       },
       "fakedns": {
         "add": "新增假 DNS",
-        "edit": "編輯假 DNS",
         "ipPool": "IP 池子網",
         "poolSize": "池大小"
       },
@@ -2032,7 +1846,6 @@
     "add": "添加",
     "month": "月",
     "months": "月",
-    "day": "天",
     "days": "天",
     "hours": "小時",
     "minutes": "分鐘",
@@ -2071,7 +1884,6 @@
       "userSaved": "✅ 電報使用者已儲存。",
       "loginSuccess": "✅ 成功登入到面板。\r\n",
       "loginFailed": "❗️ 面板登入失敗。\r\n",
-      "2faFailed": "2FA 失敗",
       "report": "🕰 定時報告:{{ .RunTime }}\r\n",
       "datetime": "⏰ 日期時間:{{ .DateTime }}\r\n",
       "hostname": "💻 主機: {{ .Hostname }}\r\n",
@@ -2104,7 +1916,6 @@
       "download": "🔽 下載: ↓{{ .Download }}\r\n",
       "total": "📊 總計: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
       "TGUser": "👤 電報使用者:{{ .TelegramID }}\r\n",
-      "exhaustedMsg": "🚨 耗盡的 {{ .Type }}:\r\n",
       "exhaustedCount": "🚨 耗盡的 {{ .Type }} 數量:\r\n",
       "onlinesCount": "🌐 線上客戶:{{ .Count }}\r\n",
       "disabled": "🛑 禁用:{{ .Disabled }}\r\n",
@@ -2113,16 +1924,10 @@
       "refreshedOn": "\r\n📋🔄 重新整理時間:{{ .Time }}\r\n\r\n",
       "yes": "✅ 是的",
       "no": "❌ 否",
-      "received_id": "🔑📥 ID 已更新。",
-      "received_password": "🔑📥 密碼已更新。",
       "received_email": "📧📥 電子郵件已更新。",
       "received_comment": "💬📥 評論已更新。",
-      "id_prompt": "🔑 預設 ID: {{ .ClientId }}\n\n請輸入您的 ID。",
-      "pass_prompt": "🔑 預設密碼: {{ .ClientPassword }}\n\n請輸入您的密碼。",
       "email_prompt": "📧 預設電子郵件: {{ .ClientEmail }}\n\n請輸入您的電子郵件。",
       "comment_prompt": "💬 預設評論: {{ .ClientComment }}\n\n請輸入您的評論。",
-      "inbound_client_data_id": "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!",
-      "inbound_client_data_pass": "🔄 入站: {{ .InboundRemark }}\n\n🔑 密碼: {{ .ClientPass }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!",
       "cancel": "❌ 程序已取消!\n\n您可以隨時使用 /start 重新開始。 🔄",
       "error_add_client": "⚠️ 錯誤:\n\n {{ .error }}",
       "using_default_value": "好的,我會使用預設值。 😊",
@@ -2139,8 +1944,6 @@
       "eventXrayCrashError": "錯誤:{{ .Error }}",
       "eventNodeDown": "節點 {{ .Name }} 已離線",
       "eventNodeUp": "節點 {{ .Name }} 已上線",
-      "eventCPUHigh": "CPU 偏高",
-      "eventCPUHighDetail": "CPU:{{ .Detail }}",
       "eventLoginFallback": "來自 {{ .Source }} 的登入失敗",
       "memoryThreshold": "記憶體使用率 {{ .Percent }}% 超過閾值 {{ .Threshold }}%"
     },
@@ -2181,11 +1984,8 @@
       "submitDisable": "以停用方式送出 ☑️",
       "submitEnable": "以啟用方式送出 ✅",
       "use_default": "🏷️ 使用預設值",
-      "change_id": "⚙️🔑 ID",
-      "change_password": "⚙️🔑 密碼",
       "change_email": "⚙️📧 電子郵件",
       "change_comment": "⚙️💬 評論",
-      "change_flow": "⚙️🚦 Flow",
       "ResetAllTraffics": "重設所有流量",
       "SortedTrafficUsageReport": "排序過的流量使用報告"
     },
@@ -2214,31 +2014,16 @@
     }
   },
   "email": {
-    "subjectOutboundDown": "出站 {{ .Tag }} 已中斷",
-    "subjectOutboundUp": "出站 {{ .Tag }} 已恢復",
-    "subjectXrayCrash": "Xray 已當機",
-    "subjectCPUHigh": "CPU 偏高",
-    "subjectLoginSuccess": "登入成功",
-    "subjectLoginFailed": "登入失敗",
-    "titleOutboundDown": "出站中斷",
-    "titleOutboundUp": "出站恢復",
-    "titleXrayCrash": "Xray 已當機",
-    "titleCPUHigh": "CPU 偏高",
-    "titleLoginSuccess": "登入成功",
-    "titleLoginFailed": "登入失敗",
     "labelStatus": "狀態",
     "labelOutbound": "出站",
     "labelNode": "節點",
     "labelError": "錯誤",
     "labelDelay": "延遲",
-    "labelDetail": "詳細資訊",
     "labelUsername": "使用者名稱",
     "labelIP": "IP",
     "labelReason": "原因",
     "labelSource": "來源",
-    "labelTime": "時間",
     "statusCrashed": "已當機",
-    "statusRunning": "執行中",
     "statusHigh": "偏高",
     "statusSuccess": "成功",
     "statusFailed": "失敗",

+ 0 - 1
internal/web/web.go

@@ -247,7 +247,6 @@ func (s *Server) initRouter() (*gin.Engine, error) {
 
 	s.index = controller.NewIndexController(g)
 	s.panel = controller.NewXUIController(g)
-	g.GET("/panel/api/openapi.json", controller.ServeOpenAPISpec)
 	s.api = controller.NewAPIController(g)
 
 	// Initialize WebSocket hub