mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-16 21:31:10 -05:00
✨ feat(config): Add translations for server configuration in multiple languages
This commit is contained in:
parent
39d746f0a1
commit
f9a7ece9bf
@ -8,16 +8,42 @@ export const protocols = [
|
|||||||
'hysteria2',
|
'hysteria2',
|
||||||
'tuic',
|
'tuic',
|
||||||
'anytls',
|
'anytls',
|
||||||
|
'socks',
|
||||||
|
'naive',
|
||||||
|
'http',
|
||||||
|
'meru',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
// 字段配置类型
|
||||||
|
export type FieldConfig = {
|
||||||
|
name: string;
|
||||||
|
type: 'input' | 'select' | 'switch' | 'number' | 'textarea';
|
||||||
|
label: string;
|
||||||
|
placeholder?: string | ((t: (key: string) => string, protocol: any) => string);
|
||||||
|
options?: readonly string[];
|
||||||
|
defaultValue?: any;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
|
suffix?: string;
|
||||||
|
condition?: (protocol: any, values: any) => boolean;
|
||||||
|
group?: 'basic' | 'transport' | 'security' | 'reality' | 'plugin';
|
||||||
|
gridSpan?: 1 | 2;
|
||||||
|
};
|
||||||
|
|
||||||
// Global label map for display; fallback to raw value if missing
|
// Global label map for display; fallback to raw value if missing
|
||||||
export const LABELS = {
|
export const LABELS = {
|
||||||
// transport
|
// transport
|
||||||
'tcp': 'TCP',
|
'tcp': 'TCP',
|
||||||
|
'udp': 'UDP',
|
||||||
'websocket': 'WebSocket',
|
'websocket': 'WebSocket',
|
||||||
'http2': 'HTTP/2',
|
|
||||||
'httpupgrade': 'HTTP Upgrade',
|
|
||||||
'grpc': 'gRPC',
|
'grpc': 'gRPC',
|
||||||
|
'mkcp': 'mKCP',
|
||||||
|
'httpupgrade': 'HTTP Upgrade',
|
||||||
|
'xhttp': 'XHTTP',
|
||||||
|
// vless flow
|
||||||
|
'xtls-rprx-direct': 'XTLS-RPRX-Direct',
|
||||||
|
'xtls-rprx-splice': 'XTLS-RPRX-Splice',
|
||||||
'xtls-rprx-vision': 'XTLS-RPRX-Vision',
|
'xtls-rprx-vision': 'XTLS-RPRX-Vision',
|
||||||
// security
|
// security
|
||||||
'none': 'NONE',
|
'none': 'NONE',
|
||||||
@ -32,6 +58,14 @@ export const LABELS = {
|
|||||||
'edge': 'edge',
|
'edge': 'edge',
|
||||||
'360': '360',
|
'360': '360',
|
||||||
'qq': 'QQ',
|
'qq': 'QQ',
|
||||||
|
// multiplex
|
||||||
|
'off': 'Off',
|
||||||
|
'low': 'Low',
|
||||||
|
'middle': 'Middle',
|
||||||
|
'high': 'High',
|
||||||
|
// ss plugins
|
||||||
|
'obfs': 'Simple Obfs',
|
||||||
|
'v2ray-plugin': 'V2Ray Plugin',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Flat arrays for enum-like sets
|
// Flat arrays for enum-like sets
|
||||||
@ -45,10 +79,13 @@ export const SS_CIPHERS = [
|
|||||||
'2022-blake3-chacha20-poly1305',
|
'2022-blake3-chacha20-poly1305',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
export const SS_PLUGINS = ['none', 'obfs', 'v2ray-plugin'] as const;
|
||||||
|
|
||||||
export const TRANSPORTS = {
|
export const TRANSPORTS = {
|
||||||
vmess: ['tcp', 'websocket', 'grpc', 'httpupgrade'] as const,
|
vmess: ['tcp', 'websocket', 'grpc'] as const,
|
||||||
vless: ['tcp', 'websocket', 'grpc', 'httpupgrade', 'http2'] as const,
|
vless: ['tcp', 'websocket', 'grpc', 'mkcp', 'httpupgrade', 'xhttp'] as const,
|
||||||
trojan: ['tcp', 'websocket', 'grpc'] as const,
|
trojan: ['tcp', 'websocket', 'grpc'] as const,
|
||||||
|
meru: ['tcp', 'udp'] as const,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const SECURITY = {
|
export const SECURITY = {
|
||||||
@ -56,13 +93,15 @@ export const SECURITY = {
|
|||||||
vless: ['none', 'tls', 'reality'] as const,
|
vless: ['none', 'tls', 'reality'] as const,
|
||||||
trojan: ['tls'] as const,
|
trojan: ['tls'] as const,
|
||||||
hysteria2: ['tls'] as const,
|
hysteria2: ['tls'] as const,
|
||||||
|
naive: ['none', 'tls'] as const,
|
||||||
|
http: ['none', 'tls'] as const,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const FLOWS = {
|
export const FLOWS = {
|
||||||
vless: ['none', 'xtls-rprx-vision'] as const,
|
vless: ['none', 'xtls-rprx-direct', 'xtls-rprx-splice', 'xtls-rprx-vision'] as const,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const TUIC_UDP_RELAY_MODES = ['native', 'quic', 'none'] as const;
|
export const TUIC_UDP_RELAY_MODES = ['native', 'quic'] as const;
|
||||||
export const TUIC_CONGESTION = ['bbr', 'cubic', 'new_reno'] as const;
|
export const TUIC_CONGESTION = ['bbr', 'cubic', 'new_reno'] as const;
|
||||||
export const FINGERPRINTS = [
|
export const FINGERPRINTS = [
|
||||||
'chrome',
|
'chrome',
|
||||||
@ -75,6 +114,8 @@ export const FINGERPRINTS = [
|
|||||||
'qq',
|
'qq',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
export const multiplexLevels = ['off', 'low', 'middle', 'high'] as const;
|
||||||
|
|
||||||
export function getLabel(value: string): string {
|
export function getLabel(value: string): string {
|
||||||
return (LABELS as Record<string, string>)[value] ?? value;
|
return (LABELS as Record<string, string>)[value] ?? value;
|
||||||
}
|
}
|
||||||
@ -89,6 +130,8 @@ const ss = z.object({
|
|||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
cipher: z.enum(SS_CIPHERS as any).nullish(),
|
cipher: z.enum(SS_CIPHERS as any).nullish(),
|
||||||
server_key: nullableString,
|
server_key: nullableString,
|
||||||
|
plugin: z.enum(SS_PLUGINS as any).nullish(),
|
||||||
|
plugin_opts: nullableString,
|
||||||
});
|
});
|
||||||
|
|
||||||
const vmess = z.object({
|
const vmess = z.object({
|
||||||
@ -162,13 +205,43 @@ const tuic = z.object({
|
|||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const socks = z.object({
|
||||||
|
type: z.literal('socks'),
|
||||||
|
port: nullablePort,
|
||||||
|
});
|
||||||
|
|
||||||
|
const naive = z.object({
|
||||||
|
type: z.literal('naive'),
|
||||||
|
port: nullablePort,
|
||||||
|
security: z.enum(SECURITY.naive as any).nullish(),
|
||||||
|
sni: nullableString,
|
||||||
|
allow_insecure: nullableBool,
|
||||||
|
fingerprint: nullableString,
|
||||||
|
});
|
||||||
|
|
||||||
|
const http = z.object({
|
||||||
|
type: z.literal('http'),
|
||||||
|
port: nullablePort,
|
||||||
|
security: z.enum(SECURITY.http as any).nullish(),
|
||||||
|
sni: nullableString,
|
||||||
|
allow_insecure: nullableBool,
|
||||||
|
fingerprint: nullableString,
|
||||||
|
});
|
||||||
|
|
||||||
|
const meru = z.object({
|
||||||
|
type: z.literal('meru'),
|
||||||
|
port: nullablePort,
|
||||||
|
multiplex: z.enum(multiplexLevels).nullish(),
|
||||||
|
transport: z.enum(TRANSPORTS.meru as any).nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
const anytls = z.object({
|
const anytls = z.object({
|
||||||
type: z.literal('anytls'),
|
type: z.literal('anytls'),
|
||||||
host: nullableString,
|
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
|
padding_scheme: nullableString,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const protocolApiScheme = z.discriminatedUnion('type', [
|
export const protocolApiScheme = z.discriminatedUnion('type', [
|
||||||
@ -179,6 +252,10 @@ export const protocolApiScheme = z.discriminatedUnion('type', [
|
|||||||
hysteria2,
|
hysteria2,
|
||||||
tuic,
|
tuic,
|
||||||
anytls,
|
anytls,
|
||||||
|
socks,
|
||||||
|
naive,
|
||||||
|
http,
|
||||||
|
meru,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const formSchema = z.object({
|
export const formSchema = z.object({
|
||||||
@ -202,6 +279,8 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
port: null,
|
port: null,
|
||||||
cipher: 'chacha20-ietf-poly1305',
|
cipher: 'chacha20-ietf-poly1305',
|
||||||
server_key: null,
|
server_key: null,
|
||||||
|
plugin: 'none',
|
||||||
|
plugin_opts: null,
|
||||||
} as any;
|
} as any;
|
||||||
case 'vmess':
|
case 'vmess':
|
||||||
return { type: 'vmess', port: null, transport: 'tcp', security: 'none' } as any;
|
return { type: 'vmess', port: null, transport: 'tcp', security: 'none' } as any;
|
||||||
@ -227,9 +306,587 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
udp_relay_mode: 'native',
|
udp_relay_mode: 'native',
|
||||||
congestion_controller: 'bbr',
|
congestion_controller: 'bbr',
|
||||||
} as any;
|
} as any;
|
||||||
|
case 'socks':
|
||||||
|
return {
|
||||||
|
type: 'socks',
|
||||||
|
port: null,
|
||||||
|
} as any;
|
||||||
|
case 'naive':
|
||||||
|
return {
|
||||||
|
type: 'naive',
|
||||||
|
port: null,
|
||||||
|
security: 'none',
|
||||||
|
} as any;
|
||||||
|
case 'http':
|
||||||
|
return {
|
||||||
|
type: 'http',
|
||||||
|
port: null,
|
||||||
|
security: 'none',
|
||||||
|
} as any;
|
||||||
|
case 'meru':
|
||||||
|
return {
|
||||||
|
type: 'meru',
|
||||||
|
port: null,
|
||||||
|
multiplex: 'off',
|
||||||
|
transport: 'tcp',
|
||||||
|
} as any;
|
||||||
case 'anytls':
|
case 'anytls':
|
||||||
return { type: 'anytls', port: null } as any;
|
return { type: 'anytls', port: null, padding_scheme: null } as any;
|
||||||
default:
|
default:
|
||||||
return {} as any;
|
return {} as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 协议字段配置
|
||||||
|
export const PROTOCOL_FIELDS: Record<string, FieldConfig[]> = {
|
||||||
|
shadowsocks: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cipher',
|
||||||
|
type: 'select',
|
||||||
|
label: 'encryption_method',
|
||||||
|
options: SS_CIPHERS,
|
||||||
|
defaultValue: 'chacha20-ietf-poly1305',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'server_key',
|
||||||
|
type: 'input',
|
||||||
|
label: 'server_key',
|
||||||
|
group: 'basic',
|
||||||
|
condition: (p) =>
|
||||||
|
[
|
||||||
|
'2022-blake3-aes-128-gcm',
|
||||||
|
'2022-blake3-aes-256-gcm',
|
||||||
|
'2022-blake3-chacha20-poly1305',
|
||||||
|
].includes(p.cipher),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'plugin',
|
||||||
|
type: 'select',
|
||||||
|
label: 'plugin',
|
||||||
|
options: SS_PLUGINS,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'plugin',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'plugin_opts',
|
||||||
|
type: 'textarea',
|
||||||
|
label: 'plugin_opts',
|
||||||
|
placeholder: (t: (key: string) => string, p: any) => {
|
||||||
|
switch (p.plugin) {
|
||||||
|
case 'obfs':
|
||||||
|
return 'obfs=http;obfs-host=www.bing.com;path=/';
|
||||||
|
case 'v2ray-plugin':
|
||||||
|
return 'WebSocket: mode=websocket;host=mydomain.me;path=/;tls=true\n\nQUIC: mode=quic;host=mydomain.me';
|
||||||
|
default:
|
||||||
|
return 'key=value;key2=value2';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
group: 'plugin',
|
||||||
|
condition: (p) => p.plugin !== 'none',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
vmess: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transport',
|
||||||
|
type: 'select',
|
||||||
|
label: 'transport',
|
||||||
|
options: TRANSPORTS.vmess,
|
||||||
|
defaultValue: 'tcp',
|
||||||
|
group: 'transport',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'security',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security',
|
||||||
|
options: SECURITY.vmess,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'host',
|
||||||
|
type: 'input',
|
||||||
|
label: 'host',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'xhttp', 'httpupgrade'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'path',
|
||||||
|
type: 'input',
|
||||||
|
label: 'path',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'xhttp', 'httpupgrade'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'service_name',
|
||||||
|
type: 'input',
|
||||||
|
label: 'service_name',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => p.transport === 'grpc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sni',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_sni',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allow_insecure',
|
||||||
|
type: 'switch',
|
||||||
|
label: 'security_allow_insecure',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
vless: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'flow',
|
||||||
|
type: 'select',
|
||||||
|
label: 'flow',
|
||||||
|
options: FLOWS.vless,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transport',
|
||||||
|
type: 'select',
|
||||||
|
label: 'transport',
|
||||||
|
options: TRANSPORTS.vless,
|
||||||
|
defaultValue: 'tcp',
|
||||||
|
group: 'transport',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'security',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security',
|
||||||
|
options: SECURITY.vless,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'host',
|
||||||
|
type: 'input',
|
||||||
|
label: 'host',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'mkcp', 'httpupgrade', 'xhttp'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'path',
|
||||||
|
type: 'input',
|
||||||
|
label: 'path',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'mkcp', 'httpupgrade', 'xhttp'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'service_name',
|
||||||
|
type: 'input',
|
||||||
|
label: 'service_name',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => p.transport === 'grpc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sni',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_sni',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allow_insecure',
|
||||||
|
type: 'switch',
|
||||||
|
label: 'security_allow_insecure',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reality_server_addr',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_server_address',
|
||||||
|
placeholder: (t) => t('security_server_address_placeholder'),
|
||||||
|
group: 'reality',
|
||||||
|
condition: (p) => p.security === 'reality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reality_server_port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'security_server_port',
|
||||||
|
min: 1,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'reality',
|
||||||
|
condition: (p) => p.security === 'reality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reality_private_key',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_private_key',
|
||||||
|
placeholder: (t) => t('security_private_key_placeholder'),
|
||||||
|
group: 'reality',
|
||||||
|
condition: (p) => p.security === 'reality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reality_public_key',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_public_key',
|
||||||
|
placeholder: (t) => t('security_public_key_placeholder'),
|
||||||
|
group: 'reality',
|
||||||
|
condition: (p) => p.security === 'reality',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reality_short_id',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_short_id',
|
||||||
|
group: 'reality',
|
||||||
|
condition: (p) => p.security === 'reality',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trojan: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transport',
|
||||||
|
type: 'select',
|
||||||
|
label: 'transport',
|
||||||
|
options: TRANSPORTS.trojan,
|
||||||
|
defaultValue: 'tcp',
|
||||||
|
group: 'transport',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'security',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security',
|
||||||
|
options: SECURITY.trojan,
|
||||||
|
defaultValue: 'tls',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'host',
|
||||||
|
type: 'input',
|
||||||
|
label: 'host',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'xhttp', 'httpupgrade'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'path',
|
||||||
|
type: 'input',
|
||||||
|
label: 'path',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => ['websocket', 'xhttp', 'httpupgrade'].includes(p.transport),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'service_name',
|
||||||
|
type: 'input',
|
||||||
|
label: 'service_name',
|
||||||
|
group: 'transport',
|
||||||
|
condition: (p) => p.transport === 'grpc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sni',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_sni',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allow_insecure',
|
||||||
|
type: 'switch',
|
||||||
|
label: 'security_allow_insecure',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
hysteria2: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'obfs_password',
|
||||||
|
type: 'input',
|
||||||
|
label: 'obfs_password',
|
||||||
|
placeholder: (t) => t('obfs_password_placeholder'),
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'hop_ports',
|
||||||
|
type: 'input',
|
||||||
|
label: 'hop_ports',
|
||||||
|
placeholder: (t) => t('hop_ports_placeholder'),
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'hop_interval',
|
||||||
|
type: 'number',
|
||||||
|
label: 'hop_interval',
|
||||||
|
min: 0,
|
||||||
|
suffix: 'S',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{ name: 'sni', type: 'input', label: 'security_sni', group: 'security' },
|
||||||
|
{ name: 'allow_insecure', type: 'switch', label: 'security_allow_insecure', group: 'security' },
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tuic: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'udp_relay_mode',
|
||||||
|
type: 'select',
|
||||||
|
label: 'udp_relay_mode',
|
||||||
|
options: TUIC_UDP_RELAY_MODES,
|
||||||
|
defaultValue: 'native',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'congestion_controller',
|
||||||
|
type: 'select',
|
||||||
|
label: 'congestion_controller',
|
||||||
|
options: TUIC_CONGESTION,
|
||||||
|
defaultValue: 'bbr',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{ name: 'disable_sni', type: 'switch', label: 'disable_sni', group: 'basic' },
|
||||||
|
{ name: 'reduce_rtt', type: 'switch', label: 'reduce_rtt', group: 'basic' },
|
||||||
|
{ name: 'sni', type: 'input', label: 'security_sni', group: 'security' },
|
||||||
|
{ name: 'allow_insecure', type: 'switch', label: 'security_allow_insecure', group: 'security' },
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
socks: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
naive: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'security',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security',
|
||||||
|
options: SECURITY.naive,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sni',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_sni',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allow_insecure',
|
||||||
|
type: 'switch',
|
||||||
|
label: 'security_allow_insecure',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
http: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'security',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security',
|
||||||
|
options: SECURITY.http,
|
||||||
|
defaultValue: 'none',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sni',
|
||||||
|
type: 'input',
|
||||||
|
label: 'security_sni',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'allow_insecure',
|
||||||
|
type: 'switch',
|
||||||
|
label: 'security_allow_insecure',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
condition: (p) => p.security !== 'none',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
meru: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'multiplex',
|
||||||
|
type: 'select',
|
||||||
|
label: 'multiplex',
|
||||||
|
options: multiplexLevels,
|
||||||
|
defaultValue: 'off',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transport',
|
||||||
|
type: 'select',
|
||||||
|
label: 'transport',
|
||||||
|
options: TRANSPORTS.meru,
|
||||||
|
defaultValue: 'tcp',
|
||||||
|
group: 'transport',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
anytls: [
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
type: 'number',
|
||||||
|
label: 'port',
|
||||||
|
min: 0,
|
||||||
|
max: 65535,
|
||||||
|
placeholder: '1-65535',
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'padding_scheme',
|
||||||
|
type: 'textarea',
|
||||||
|
label: 'padding_scheme',
|
||||||
|
placeholder: (t: (key: string) => string) => t('padding_scheme_placeholder'),
|
||||||
|
group: 'basic',
|
||||||
|
},
|
||||||
|
{ name: 'sni', type: 'input', label: 'security_sni', group: 'security' },
|
||||||
|
{ name: 'allow_insecure', type: 'switch', label: 'security_allow_insecure', group: 'security' },
|
||||||
|
{
|
||||||
|
name: 'fingerprint',
|
||||||
|
type: 'select',
|
||||||
|
label: 'security_fingerprint',
|
||||||
|
options: FINGERPRINTS,
|
||||||
|
defaultValue: 'chrome',
|
||||||
|
group: 'security',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionContent,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionTrigger,
|
||||||
|
} from '@workspace/ui/components/accordion';
|
||||||
import { Button } from '@workspace/ui/components/button';
|
import { Button } from '@workspace/ui/components/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
|
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -28,7 +33,6 @@ import {
|
|||||||
SheetTrigger,
|
SheetTrigger,
|
||||||
} from '@workspace/ui/components/sheet';
|
} from '@workspace/ui/components/sheet';
|
||||||
import { Switch } from '@workspace/ui/components/switch';
|
import { Switch } from '@workspace/ui/components/switch';
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
|
|
||||||
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
||||||
import { Icon } from '@workspace/ui/custom-components/icon';
|
import { Icon } from '@workspace/ui/custom-components/icon';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
@ -36,25 +40,246 @@ import { useEffect, useState } from 'react';
|
|||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import {
|
import {
|
||||||
FINGERPRINTS,
|
FieldConfig,
|
||||||
FLOWS,
|
|
||||||
formSchema,
|
formSchema,
|
||||||
getLabel,
|
getLabel,
|
||||||
getProtocolDefaultConfig,
|
getProtocolDefaultConfig,
|
||||||
LABELS,
|
PROTOCOL_FIELDS,
|
||||||
protocols as PROTOCOLS,
|
protocols as PROTOCOLS,
|
||||||
SECURITY,
|
|
||||||
ServerFormValues,
|
ServerFormValues,
|
||||||
SS_CIPHERS,
|
|
||||||
TRANSPORTS,
|
|
||||||
TUIC_CONGESTION,
|
|
||||||
TUIC_UDP_RELAY_MODES,
|
|
||||||
} from './form-schema';
|
} from './form-schema';
|
||||||
|
|
||||||
function titleCase(s: string) {
|
function titleCase(s: string) {
|
||||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DynamicField({
|
||||||
|
field,
|
||||||
|
control,
|
||||||
|
protocolIndex,
|
||||||
|
protocolData,
|
||||||
|
t,
|
||||||
|
}: {
|
||||||
|
field: FieldConfig;
|
||||||
|
control: any;
|
||||||
|
protocolIndex: number;
|
||||||
|
protocolData: any;
|
||||||
|
t: (key: string) => string;
|
||||||
|
}) {
|
||||||
|
const fieldName = `protocols.${protocolIndex}.${field.name}` as const;
|
||||||
|
|
||||||
|
// 检查字段是否应该显示
|
||||||
|
if (field.condition && !field.condition(protocolData, {})) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const commonProps = {
|
||||||
|
control,
|
||||||
|
name: fieldName,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (field.type) {
|
||||||
|
case 'input':
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
{...commonProps}
|
||||||
|
render={({ field: fieldProps }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t(field.label)}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
{...fieldProps}
|
||||||
|
placeholder={
|
||||||
|
field.placeholder
|
||||||
|
? typeof field.placeholder === 'function'
|
||||||
|
? field.placeholder(t, protocolData)
|
||||||
|
: field.placeholder
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onValueChange={(v) => fieldProps.onChange(v)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'number':
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
{...commonProps}
|
||||||
|
render={({ field: fieldProps }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t(field.label)}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
{...fieldProps}
|
||||||
|
type='number'
|
||||||
|
min={field.min}
|
||||||
|
max={field.max}
|
||||||
|
step={field.step || 1}
|
||||||
|
suffix={field.suffix}
|
||||||
|
placeholder={field.placeholder as string}
|
||||||
|
onValueChange={(v) => fieldProps.onChange(v)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'select':
|
||||||
|
// 如果选项只有一个,直接隐藏该字段
|
||||||
|
if (!field.options || field.options.length <= 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
{...commonProps}
|
||||||
|
render={({ field: fieldProps }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t(field.label)}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Select
|
||||||
|
value={fieldProps.value ?? field.defaultValue}
|
||||||
|
onValueChange={(v) => fieldProps.onChange(v)}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder={t('please_select')} />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{field.options?.map((option) => (
|
||||||
|
<SelectItem key={option} value={option}>
|
||||||
|
{getLabel(option)}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'switch':
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
{...commonProps}
|
||||||
|
render={({ field: fieldProps }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t(field.label)}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<div className='pt-2'>
|
||||||
|
<Switch
|
||||||
|
checked={!!fieldProps.value}
|
||||||
|
onCheckedChange={(checked) => fieldProps.onChange(checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'textarea':
|
||||||
|
return (
|
||||||
|
<FormField
|
||||||
|
{...commonProps}
|
||||||
|
render={({ field: fieldProps }) => (
|
||||||
|
<FormItem className='col-span-2'>
|
||||||
|
<FormLabel>{t(field.label)}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<textarea
|
||||||
|
{...fieldProps}
|
||||||
|
className='border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50'
|
||||||
|
placeholder={
|
||||||
|
field.placeholder
|
||||||
|
? typeof field.placeholder === 'function'
|
||||||
|
? field.placeholder(t, protocolData)
|
||||||
|
: t(field.placeholder)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onChange={(e) => fieldProps.onChange(e.target.value)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderFieldsByGroup(
|
||||||
|
fields: FieldConfig[],
|
||||||
|
group: string,
|
||||||
|
control: any,
|
||||||
|
protocolIndex: number,
|
||||||
|
protocolData: any,
|
||||||
|
t: (key: string) => string,
|
||||||
|
) {
|
||||||
|
const groupFields = fields.filter((field) => field.group === group);
|
||||||
|
if (groupFields.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
|
{groupFields.map((field) => (
|
||||||
|
<DynamicField
|
||||||
|
key={field.name}
|
||||||
|
field={field}
|
||||||
|
control={control}
|
||||||
|
protocolIndex={protocolIndex}
|
||||||
|
protocolData={protocolData}
|
||||||
|
t={t}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderGroupCard(
|
||||||
|
title: string,
|
||||||
|
fields: FieldConfig[],
|
||||||
|
group: string,
|
||||||
|
control: any,
|
||||||
|
protocolIndex: number,
|
||||||
|
protocolData: any,
|
||||||
|
t: (key: string) => string,
|
||||||
|
) {
|
||||||
|
const groupFields = fields.filter((field) => field.group === group);
|
||||||
|
if (groupFields.length === 0) return null;
|
||||||
|
|
||||||
|
// 检查是否有字段需要显示
|
||||||
|
const visibleFields = groupFields.filter(
|
||||||
|
(field) => !field.condition || field.condition(protocolData, {}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (visibleFields.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='relative'>
|
||||||
|
<fieldset className='border-border rounded-lg border'>
|
||||||
|
<legend className='text-foreground bg-background ml-3 px-1 py-1 text-sm font-medium'>
|
||||||
|
{t(title)}
|
||||||
|
</legend>
|
||||||
|
<div className='p-4 pt-2'>
|
||||||
|
{renderFieldsByGroup(fields, group, control, protocolIndex, protocolData, t)}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function ServerForm(props: {
|
export default function ServerForm(props: {
|
||||||
trigger: string;
|
trigger: string;
|
||||||
title: string;
|
title: string;
|
||||||
@ -65,7 +290,6 @@ export default function ServerForm(props: {
|
|||||||
const { trigger, title, loading, initialValues, onSubmit } = props;
|
const { trigger, title, loading, initialValues, onSubmit } = props;
|
||||||
const t = useTranslations('servers');
|
const t = useTranslations('servers');
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [activeType, setActiveType] = useState<(typeof PROTOCOLS)[number]>('shadowsocks');
|
|
||||||
const [protocolsEnabled, setProtocolsEnabled] = useState<string[]>([]);
|
const [protocolsEnabled, setProtocolsEnabled] = useState<string[]>([]);
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
@ -252,33 +476,41 @@ export default function ServerForm(props: {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='pt-2'>
|
<div className='my-3'>
|
||||||
<Tabs value={activeType} onValueChange={(v) => setActiveType(v as any)}>
|
<h3 className='text-foreground text-sm font-semibold'>
|
||||||
<TabsList className='h-auto w-full flex-wrap'>
|
{t('protocol_configurations')}
|
||||||
{PROTOCOLS.map((type) => (
|
</h3>
|
||||||
<TabsTrigger key={type} value={type}>
|
<p className='text-muted-foreground mt-1 text-xs'>
|
||||||
{titleCase(type)}
|
{t('protocol_configurations_desc')}
|
||||||
</TabsTrigger>
|
</p>
|
||||||
))}
|
</div>
|
||||||
</TabsList>
|
<Accordion type='single' className='w-full space-y-3'>
|
||||||
{PROTOCOLS.map((type) => {
|
{PROTOCOLS.map((type) => {
|
||||||
const i = Math.max(
|
const i = Math.max(
|
||||||
0,
|
0,
|
||||||
PROTOCOLS.findIndex((t) => t === type),
|
PROTOCOLS.findIndex((t) => t === type),
|
||||||
);
|
);
|
||||||
const current = Array.isArray(protocolsValues) ? protocolsValues[i] || {} : {};
|
const current = Array.isArray(protocolsValues) ? protocolsValues[i] || {} : {};
|
||||||
const transport = ((current as any)?.transport as string | undefined) ?? 'tcp';
|
|
||||||
const security = (current as any)?.security as string | undefined;
|
|
||||||
const cipher = (current as any)?.cipher as string | undefined;
|
|
||||||
const isEnabled = protocolsEnabled.includes(type);
|
const isEnabled = protocolsEnabled.includes(type);
|
||||||
|
const fields = PROTOCOL_FIELDS[type] || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabsContent key={type} value={type} className='space-y-4 pt-3'>
|
<AccordionItem key={type} value={type} className='mb-2 rounded-lg border'>
|
||||||
<div className='flex items-center justify-between'>
|
<AccordionTrigger className='px-4 py-3 hover:no-underline'>
|
||||||
<span className='text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'>
|
<div className='flex w-full items-center justify-between'>
|
||||||
{t('enabled')}
|
<div className='flex flex-col items-start'>
|
||||||
|
<span className='font-medium'>{titleCase(type)}</span>
|
||||||
|
<span className='text-muted-foreground text-xs'>
|
||||||
|
{isEnabled ? t('enabled') : t('disabled')}
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center gap-3'>
|
||||||
|
{isEnabled && (
|
||||||
|
<div className='flex h-2 w-2 rounded-full bg-green-500'></div>
|
||||||
|
)}
|
||||||
<Switch
|
<Switch
|
||||||
|
className='mr-2'
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
checked={isEnabled}
|
checked={isEnabled}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
@ -289,614 +521,39 @@ export default function ServerForm(props: {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</AccordionTrigger>
|
||||||
{isEnabled && (
|
{isEnabled && (
|
||||||
<div className='space-y-4'>
|
<AccordionContent className='px-4 pb-4 pt-0'>
|
||||||
<div className='grid grid-cols-2 gap-2'>
|
<div className='-mx-4 space-y-4 rounded-b-lg border-t px-4 pt-4'>
|
||||||
<FormField
|
{renderGroupCard('basic', fields, 'basic', control, i, current, t)}
|
||||||
control={control}
|
{renderGroupCard('plugin', fields, 'plugin', control, i, current, t)}
|
||||||
name={`protocols.${i}.port` as const}
|
{renderGroupCard(
|
||||||
render={({ field }) => (
|
'transport',
|
||||||
<FormItem>
|
fields,
|
||||||
<FormLabel>{t('port')}</FormLabel>
|
'transport',
|
||||||
<FormControl>
|
control,
|
||||||
<EnhancedInput
|
i,
|
||||||
{...field}
|
current,
|
||||||
type='number'
|
t,
|
||||||
step={1}
|
|
||||||
min={0}
|
|
||||||
max={65535}
|
|
||||||
placeholder='1-65535'
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
)}
|
||||||
/>
|
{renderGroupCard(
|
||||||
|
'security',
|
||||||
{type === 'shadowsocks' && (
|
fields,
|
||||||
<>
|
'security',
|
||||||
<FormField
|
control,
|
||||||
control={control}
|
i,
|
||||||
name={`protocols.${i}.cipher` as const}
|
current,
|
||||||
render={({ field }) => (
|
t,
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('encryption_method')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'chacha20-ietf-poly1305'}
|
|
||||||
onValueChange={(value) => field.onChange(value)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue
|
|
||||||
placeholder={t('select_encryption_method')}
|
|
||||||
/>
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(SS_CIPHERS as readonly string[]).map((c) => (
|
|
||||||
<SelectItem key={c} value={c}>
|
|
||||||
{getLabel(c)}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
)}
|
||||||
/>
|
{renderGroupCard('reality', fields, 'reality', control, i, current, t)}
|
||||||
{[
|
|
||||||
'2022-blake3-aes-128-gcm',
|
|
||||||
'2022-blake3-aes-256-gcm',
|
|
||||||
'2022-blake3-chacha20-poly1305',
|
|
||||||
].includes((cipher || '').toString()) && (
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.server_key` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('server_key')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{type === 'vless' && (
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.flow` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('flow')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'none'}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(FLOWS.vless as readonly string[]).map((opt) => (
|
|
||||||
<SelectItem key={opt} value={opt}>
|
|
||||||
{getLabel(opt)}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{type === 'hysteria2' && (
|
|
||||||
<>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.obfs_password` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('obfs_password')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
placeholder={t('obfs_password_placeholder')}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.hop_ports` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('hop_ports')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
placeholder={t('hop_ports_placeholder')}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.hop_interval` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('hop_interval')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
type='number'
|
|
||||||
min={0}
|
|
||||||
suffix='S'
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{type === 'tuic' && (
|
|
||||||
<>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.udp_relay_mode` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('udp_relay_mode')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'native'}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(TUIC_UDP_RELAY_MODES as readonly string[]).map(
|
|
||||||
(opt) => (
|
|
||||||
<SelectItem key={opt} value={opt}>
|
|
||||||
{getLabel(opt)}
|
|
||||||
</SelectItem>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.congestion_controller` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('congestion_controller')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'bbr'}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(TUIC_CONGESTION as readonly string[]).map((opt) => (
|
|
||||||
<SelectItem key={opt} value={opt}>
|
|
||||||
{getLabel(opt)}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.disable_sni` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('disable_sni')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<div className='pt-2'>
|
|
||||||
<Switch
|
|
||||||
checked={!!field.value}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
field.onChange(checked)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</FormControl>
|
</AccordionContent>
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
)}
|
||||||
/>
|
</AccordionItem>
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reduce_rtt` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('reduce_rtt')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<div className='pt-2'>
|
|
||||||
<Switch
|
|
||||||
checked={!!field.value}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
field.onChange(checked)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{['vmess', 'vless', 'trojan'].includes(type) && (
|
|
||||||
<Card>
|
|
||||||
<CardHeader className='flex flex-row items-center justify-between p-3'>
|
|
||||||
<CardTitle>{t('transport_title')}</CardTitle>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.transport` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className='!mt-0 min-w-32'>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'tcp'}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(
|
|
||||||
TRANSPORTS[
|
|
||||||
type as 'vmess' | 'vless' | 'trojan'
|
|
||||||
] as readonly string[]
|
|
||||||
).map((opt) => (
|
|
||||||
<SelectItem key={opt} value={opt}>
|
|
||||||
{getLabel(opt)}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</CardHeader>
|
|
||||||
{transport !== 'tcp' && (
|
|
||||||
<CardContent className='flex gap-4 p-3'>
|
|
||||||
{['websocket', 'http2', 'httpupgrade'].includes(
|
|
||||||
transport as string,
|
|
||||||
) && (
|
|
||||||
<>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={`protocols.${i}.host` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>HOST</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
form.setValue(field.name, value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.path` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('path')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{transport === 'grpc' && (
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.service_name` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('service_name')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{['vmess', 'vless', 'trojan', 'anytls', 'tuic', 'hysteria2'].includes(
|
|
||||||
type,
|
|
||||||
) && (
|
|
||||||
<Card>
|
|
||||||
<CardHeader className='flex flex-row items-center justify-between p-3'>
|
|
||||||
<CardTitle>{t('security_title')}</CardTitle>
|
|
||||||
{['vmess', 'vless', 'trojan'].includes(type) && (
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.security` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className='!mt-0 min-w-32'>
|
|
||||||
<Select
|
|
||||||
value={
|
|
||||||
field.value ??
|
|
||||||
(type === 'vless'
|
|
||||||
? 'none'
|
|
||||||
: type === 'trojan'
|
|
||||||
? 'tls'
|
|
||||||
: 'none')
|
|
||||||
}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(
|
|
||||||
SECURITY[
|
|
||||||
type as 'vless' | 'vmess' | 'trojan'
|
|
||||||
] as readonly string[]
|
|
||||||
).map((opt) => (
|
|
||||||
<SelectItem key={opt} value={opt}>
|
|
||||||
{LABELS[opt as keyof typeof LABELS] ?? opt}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</CardHeader>
|
|
||||||
|
|
||||||
{(['anytls', 'tuic', 'hysteria2'].includes(type) ||
|
|
||||||
(['vmess', 'vless', 'trojan'].includes(type) &&
|
|
||||||
security !== 'none')) && (
|
|
||||||
<CardContent className='grid grid-cols-2 gap-4 p-3'>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.sni` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_sni')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{type === 'vless' && security === 'reality' && (
|
|
||||||
<>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reality_server_addr` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_server_address')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
placeholder={t(
|
|
||||||
'security_server_address_placeholder',
|
|
||||||
)}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reality_server_port` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_server_port')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
type='number'
|
|
||||||
min={1}
|
|
||||||
max={65535}
|
|
||||||
placeholder='1-65535'
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reality_private_key` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_private_key')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
placeholder={t(
|
|
||||||
'security_private_key_placeholder',
|
|
||||||
)}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reality_public_key` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_public_key')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
placeholder={t('security_public_key_placeholder')}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.reality_short_id` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_short_id')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.fingerprint` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_fingerprint')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
value={field.value ?? 'chrome'}
|
|
||||||
onValueChange={(v) => field.onChange(v)}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('please_select')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{(FINGERPRINTS as readonly string[]).map((fp) => (
|
|
||||||
<SelectItem key={fp} value={fp}>
|
|
||||||
{getLabel(fp)}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={control}
|
|
||||||
name={`protocols.${i}.allow_insecure` as const}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('security_allow_insecure')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<div className='pt-2'>
|
|
||||||
<Switch
|
|
||||||
checked={!!field.value}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
field.onChange(checked)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</CardContent>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</TabsContent>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Tabs>
|
</Accordion>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresa",
|
"address": "Adresa",
|
||||||
"address_placeholder": "Adresa serveru",
|
"address_placeholder": "Adresa serveru",
|
||||||
|
"basic": "Základní konfigurace",
|
||||||
"cancel": "Zrušit",
|
"cancel": "Zrušit",
|
||||||
"city": "Město",
|
"city": "Město",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Smazat",
|
"delete": "Smazat",
|
||||||
"deleted": "Úspěšně smazáno",
|
"deleted": "Úspěšně smazáno",
|
||||||
"disable_sni": "Zakázat SNI",
|
"disable_sni": "Zakázat SNI",
|
||||||
|
"disabled": "Deaktivováno",
|
||||||
"disk": "Disk",
|
"disk": "Disk",
|
||||||
"drawerCreateTitle": "Vytvořit server",
|
"drawerCreateTitle": "Vytvořit server",
|
||||||
"drawerEditTitle": "Upravit server",
|
"drawerEditTitle": "Upravit server",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Online uživatelé",
|
"onlineUsers": "Online uživatelé",
|
||||||
|
"padding_scheme": "Schéma vycpání",
|
||||||
|
"padding_scheme_placeholder": "Jedno pravidlo vycpání na řádek, formát: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servery",
|
"pageTitle": "Servery",
|
||||||
"path": "Cesta",
|
"path": "Cesta",
|
||||||
"please_select": "Prosím vyberte",
|
"please_select": "Prosím vyberte",
|
||||||
|
"plugin": "Konfigurace pluginu",
|
||||||
|
"plugin_opts": "Možnosti pluginu",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Konfigurace protokolu",
|
||||||
|
"protocol_configurations_desc": "Povolit a nakonfigurovat požadované typy protokolů",
|
||||||
|
"protocol_disabled_hint": "Tento protokol je deaktivován, aktivujte přepínač pro konfiguraci",
|
||||||
"protocols": "Protokoly",
|
"protocols": "Protokoly",
|
||||||
|
"reality": "Konfigurace reality",
|
||||||
"reduce_rtt": "Snížit RTT",
|
"reduce_rtt": "Snížit RTT",
|
||||||
|
"security": "Konfigurace zabezpečení",
|
||||||
"security_allow_insecure": "Povolit nezabezpečené",
|
"security_allow_insecure": "Povolit nezabezpečené",
|
||||||
"security_fingerprint": "Otisk prstu",
|
"security_fingerprint": "Otisk prstu",
|
||||||
"security_private_key": "Soukromý klíč reality",
|
"security_private_key": "Soukromý klíč reality",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Krátké ID reality",
|
"security_short_id": "Krátké ID reality",
|
||||||
"security_short_id_placeholder": "Hexadecimální řetězec (max. 16 znaků)",
|
"security_short_id_placeholder": "Hexadecimální řetězec (max. 16 znaků)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Bezpečnost",
|
|
||||||
"select_encryption_method": "Vyberte metodu šifrování",
|
"select_encryption_method": "Vyberte metodu šifrování",
|
||||||
"server_key": "Klíč serveru",
|
"server_key": "Klíč serveru",
|
||||||
"service_name": "Název služby",
|
"service_name": "Název služby",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Předplatné",
|
"subscription": "Předplatné",
|
||||||
"traffic": "Provoz",
|
"traffic": "Provoz",
|
||||||
"traffic_ratio": "Multiplikátor",
|
"traffic_ratio": "Multiplikátor",
|
||||||
"transport_title": "Transport",
|
"transport": "Metoda přenosu",
|
||||||
"udp_relay_mode": "Režim UDP relé",
|
"udp_relay_mode": "Režim UDP relé",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Neomezeno",
|
"unlimited": "Neomezeno",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"address_placeholder": "Serveradresse",
|
"address_placeholder": "Serveradresse",
|
||||||
|
"basic": "Grundkonfiguration",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
"city": "Stadt",
|
"city": "Stadt",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"deleted": "Erfolgreich gelöscht",
|
"deleted": "Erfolgreich gelöscht",
|
||||||
"disable_sni": "SNI deaktivieren",
|
"disable_sni": "SNI deaktivieren",
|
||||||
|
"disabled": "Deaktiviert",
|
||||||
"disk": "Festplatte",
|
"disk": "Festplatte",
|
||||||
"drawerCreateTitle": "Server erstellen",
|
"drawerCreateTitle": "Server erstellen",
|
||||||
"drawerEditTitle": "Server bearbeiten",
|
"drawerEditTitle": "Server bearbeiten",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Online-Benutzer",
|
"onlineUsers": "Online-Benutzer",
|
||||||
|
"padding_scheme": "Polsterungsschema",
|
||||||
|
"padding_scheme_placeholder": "Eine Polsterungsregel pro Zeile, Format: stop=8, 0=30-30",
|
||||||
"pageTitle": "Server",
|
"pageTitle": "Server",
|
||||||
"path": "Pfad",
|
"path": "Pfad",
|
||||||
"please_select": "Bitte auswählen",
|
"please_select": "Bitte auswählen",
|
||||||
|
"plugin": "Plugin-Konfiguration",
|
||||||
|
"plugin_opts": "Plugin-Optionen",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Protokollkonfigurationen",
|
||||||
|
"protocol_configurations_desc": "Aktivieren und konfigurieren Sie die erforderlichen Protokolltypen",
|
||||||
|
"protocol_disabled_hint": "Dieses Protokoll ist deaktiviert, aktivieren Sie den Schalter, um es zu konfigurieren",
|
||||||
"protocols": "Protokolle",
|
"protocols": "Protokolle",
|
||||||
|
"reality": "Realitätskonfiguration",
|
||||||
"reduce_rtt": "RTT reduzieren",
|
"reduce_rtt": "RTT reduzieren",
|
||||||
|
"security": "Sicherheitskonfiguration",
|
||||||
"security_allow_insecure": "Unsichere Verbindungen zulassen",
|
"security_allow_insecure": "Unsichere Verbindungen zulassen",
|
||||||
"security_fingerprint": "Fingerprint",
|
"security_fingerprint": "Fingerprint",
|
||||||
"security_private_key": "Echter privater Schlüssel",
|
"security_private_key": "Echter privater Schlüssel",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Echte kurze ID",
|
"security_short_id": "Echte kurze ID",
|
||||||
"security_short_id_placeholder": "Hex-String (bis zu 16 Zeichen)",
|
"security_short_id_placeholder": "Hex-String (bis zu 16 Zeichen)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Sicherheit",
|
|
||||||
"select_encryption_method": "Verschlüsselungsmethode auswählen",
|
"select_encryption_method": "Verschlüsselungsmethode auswählen",
|
||||||
"server_key": "Server-Schlüssel",
|
"server_key": "Server-Schlüssel",
|
||||||
"service_name": "Dienstname",
|
"service_name": "Dienstname",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Abonnement",
|
"subscription": "Abonnement",
|
||||||
"traffic": "Verkehr",
|
"traffic": "Verkehr",
|
||||||
"traffic_ratio": "Multiplikator",
|
"traffic_ratio": "Multiplikator",
|
||||||
"transport_title": "Transport",
|
"transport": "Transportmethode",
|
||||||
"udp_relay_mode": "UDP-Relay-Modus",
|
"udp_relay_mode": "UDP-Relay-Modus",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Unbegrenzt",
|
"unlimited": "Unbegrenzt",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"address_placeholder": "Server address",
|
"address_placeholder": "Server address",
|
||||||
|
"basic": "Basic Configuration",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"city": "City",
|
"city": "City",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"deleted": "Deleted successfully",
|
"deleted": "Deleted successfully",
|
||||||
"disable_sni": "Disable SNI",
|
"disable_sni": "Disable SNI",
|
||||||
|
"disabled": "Disabled",
|
||||||
"disk": "Disk",
|
"disk": "Disk",
|
||||||
"drawerCreateTitle": "Create Server",
|
"drawerCreateTitle": "Create Server",
|
||||||
"drawerEditTitle": "Edit Server",
|
"drawerEditTitle": "Edit Server",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Online users",
|
"onlineUsers": "Online users",
|
||||||
|
"padding_scheme": "Padding Scheme",
|
||||||
|
"padding_scheme_placeholder": "One padding rule per line, format: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servers",
|
"pageTitle": "Servers",
|
||||||
"path": "Path",
|
"path": "Path",
|
||||||
"please_select": "Please select",
|
"please_select": "Please select",
|
||||||
|
"plugin": "Plugin Configuration",
|
||||||
|
"plugin_opts": "Plugin Options",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Protocol Configurations",
|
||||||
|
"protocol_configurations_desc": "Enable and configure the required protocol types",
|
||||||
|
"protocol_disabled_hint": "This protocol is disabled, enable the switch to configure",
|
||||||
"protocols": "Protocols",
|
"protocols": "Protocols",
|
||||||
|
"reality": "Reality Configuration",
|
||||||
"reduce_rtt": "Reduce RTT",
|
"reduce_rtt": "Reduce RTT",
|
||||||
|
"security": "Security Configuration",
|
||||||
"security_allow_insecure": "Allow insecure",
|
"security_allow_insecure": "Allow insecure",
|
||||||
"security_fingerprint": "Fingerprint",
|
"security_fingerprint": "Fingerprint",
|
||||||
"security_private_key": "Reality private key",
|
"security_private_key": "Reality private key",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Reality short ID",
|
"security_short_id": "Reality short ID",
|
||||||
"security_short_id_placeholder": "Hex string (up to 16 chars)",
|
"security_short_id_placeholder": "Hex string (up to 16 chars)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Security",
|
|
||||||
"select_encryption_method": "Select encryption method",
|
"select_encryption_method": "Select encryption method",
|
||||||
"server_key": "Server key",
|
"server_key": "Server key",
|
||||||
"service_name": "Service name",
|
"service_name": "Service name",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Subscription",
|
"subscription": "Subscription",
|
||||||
"traffic": "Traffic",
|
"traffic": "Traffic",
|
||||||
"traffic_ratio": "Ratio",
|
"traffic_ratio": "Ratio",
|
||||||
"transport_title": "Transport",
|
"transport": "Transport Method",
|
||||||
"udp_relay_mode": "UDP relay mode",
|
"udp_relay_mode": "UDP relay mode",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Unlimited",
|
"unlimited": "Unlimited",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Dirección",
|
"address": "Dirección",
|
||||||
"address_placeholder": "Dirección del servidor",
|
"address_placeholder": "Dirección del servidor",
|
||||||
|
"basic": "Configuración Básica",
|
||||||
"cancel": "Cancelar",
|
"cancel": "Cancelar",
|
||||||
"city": "Ciudad",
|
"city": "Ciudad",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Eliminar",
|
"delete": "Eliminar",
|
||||||
"deleted": "Eliminado con éxito",
|
"deleted": "Eliminado con éxito",
|
||||||
"disable_sni": "Deshabilitar SNI",
|
"disable_sni": "Deshabilitar SNI",
|
||||||
|
"disabled": "Deshabilitado",
|
||||||
"disk": "Disco",
|
"disk": "Disco",
|
||||||
"drawerCreateTitle": "Crear Servidor",
|
"drawerCreateTitle": "Crear Servidor",
|
||||||
"drawerEditTitle": "Editar Servidor",
|
"drawerEditTitle": "Editar Servidor",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Desconectado",
|
"offline": "Desconectado",
|
||||||
"online": "Conectado",
|
"online": "Conectado",
|
||||||
"onlineUsers": "Usuarios en línea",
|
"onlineUsers": "Usuarios en línea",
|
||||||
|
"padding_scheme": "Esquema de Relleno",
|
||||||
|
"padding_scheme_placeholder": "Una regla de relleno por línea, formato: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servidores",
|
"pageTitle": "Servidores",
|
||||||
"path": "Ruta",
|
"path": "Ruta",
|
||||||
"please_select": "Por favor seleccione",
|
"please_select": "Por favor seleccione",
|
||||||
|
"plugin": "Configuración del Plugin",
|
||||||
|
"plugin_opts": "Opciones del Plugin",
|
||||||
"port": "Puerto",
|
"port": "Puerto",
|
||||||
|
"protocol_configurations": "Configuraciones de Protocolo",
|
||||||
|
"protocol_configurations_desc": "Habilitar y configurar los tipos de protocolo requeridos",
|
||||||
|
"protocol_disabled_hint": "Este protocolo está deshabilitado, habilita el interruptor para configurar",
|
||||||
"protocols": "Protocolos",
|
"protocols": "Protocolos",
|
||||||
|
"reality": "Configuración de Realidad",
|
||||||
"reduce_rtt": "Reducir RTT",
|
"reduce_rtt": "Reducir RTT",
|
||||||
|
"security": "Configuración de Seguridad",
|
||||||
"security_allow_insecure": "Permitir inseguro",
|
"security_allow_insecure": "Permitir inseguro",
|
||||||
"security_fingerprint": "Huella digital",
|
"security_fingerprint": "Huella digital",
|
||||||
"security_private_key": "Clave privada de realidad",
|
"security_private_key": "Clave privada de realidad",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID corta de realidad",
|
"security_short_id": "ID corta de realidad",
|
||||||
"security_short_id_placeholder": "Cadena hexadecimal (hasta 16 caracteres)",
|
"security_short_id_placeholder": "Cadena hexadecimal (hasta 16 caracteres)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Seguridad",
|
|
||||||
"select_encryption_method": "Seleccionar método de cifrado",
|
"select_encryption_method": "Seleccionar método de cifrado",
|
||||||
"server_key": "Clave del servidor",
|
"server_key": "Clave del servidor",
|
||||||
"service_name": "Nombre del servicio",
|
"service_name": "Nombre del servicio",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Suscripción",
|
"subscription": "Suscripción",
|
||||||
"traffic": "Tráfico",
|
"traffic": "Tráfico",
|
||||||
"traffic_ratio": "Multiplicador",
|
"traffic_ratio": "Multiplicador",
|
||||||
"transport_title": "Transporte",
|
"transport": "Método de Transporte",
|
||||||
"udp_relay_mode": "Modo de retransmisión UDP",
|
"udp_relay_mode": "Modo de retransmisión UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Ilimitado",
|
"unlimited": "Ilimitado",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Dirección",
|
"address": "Dirección",
|
||||||
"address_placeholder": "Dirección del servidor",
|
"address_placeholder": "Dirección del servidor",
|
||||||
|
"basic": "Configuración Básica",
|
||||||
"cancel": "Cancelar",
|
"cancel": "Cancelar",
|
||||||
"city": "Ciudad",
|
"city": "Ciudad",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Eliminar",
|
"delete": "Eliminar",
|
||||||
"deleted": "Eliminado con éxito",
|
"deleted": "Eliminado con éxito",
|
||||||
"disable_sni": "Deshabilitar SNI",
|
"disable_sni": "Deshabilitar SNI",
|
||||||
|
"disabled": "Deshabilitado",
|
||||||
"disk": "Disco",
|
"disk": "Disco",
|
||||||
"drawerCreateTitle": "Crear Servidor",
|
"drawerCreateTitle": "Crear Servidor",
|
||||||
"drawerEditTitle": "Editar Servidor",
|
"drawerEditTitle": "Editar Servidor",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Desconectado",
|
"offline": "Desconectado",
|
||||||
"online": "Conectado",
|
"online": "Conectado",
|
||||||
"onlineUsers": "Usuarios en línea",
|
"onlineUsers": "Usuarios en línea",
|
||||||
|
"padding_scheme": "Esquema de Relleno",
|
||||||
|
"padding_scheme_placeholder": "Una regla de relleno por línea, formato: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servidores",
|
"pageTitle": "Servidores",
|
||||||
"path": "Ruta",
|
"path": "Ruta",
|
||||||
"please_select": "Por favor selecciona",
|
"please_select": "Por favor selecciona",
|
||||||
|
"plugin": "Configuración del Plugin",
|
||||||
|
"plugin_opts": "Opciones del Plugin",
|
||||||
"port": "Puerto",
|
"port": "Puerto",
|
||||||
|
"protocol_configurations": "Configuraciones de Protocolo",
|
||||||
|
"protocol_configurations_desc": "Habilitar y configurar los tipos de protocolo requeridos",
|
||||||
|
"protocol_disabled_hint": "Este protocolo está deshabilitado, habilita el interruptor para configurar",
|
||||||
"protocols": "Protocolos",
|
"protocols": "Protocolos",
|
||||||
|
"reality": "Configuración de Realidad",
|
||||||
"reduce_rtt": "Reducir RTT",
|
"reduce_rtt": "Reducir RTT",
|
||||||
|
"security": "Configuración de Seguridad",
|
||||||
"security_allow_insecure": "Permitir inseguro",
|
"security_allow_insecure": "Permitir inseguro",
|
||||||
"security_fingerprint": "Huella digital",
|
"security_fingerprint": "Huella digital",
|
||||||
"security_private_key": "Clave privada de realidad",
|
"security_private_key": "Clave privada de realidad",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID corto de realidad",
|
"security_short_id": "ID corto de realidad",
|
||||||
"security_short_id_placeholder": "Cadena hexadecimal (hasta 16 caracteres)",
|
"security_short_id_placeholder": "Cadena hexadecimal (hasta 16 caracteres)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Seguridad",
|
|
||||||
"select_encryption_method": "Selecciona el método de encriptación",
|
"select_encryption_method": "Selecciona el método de encriptación",
|
||||||
"server_key": "Clave del servidor",
|
"server_key": "Clave del servidor",
|
||||||
"service_name": "Nombre del servicio",
|
"service_name": "Nombre del servicio",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Suscripción",
|
"subscription": "Suscripción",
|
||||||
"traffic": "Tráfico",
|
"traffic": "Tráfico",
|
||||||
"traffic_ratio": "Multiplicador",
|
"traffic_ratio": "Multiplicador",
|
||||||
"transport_title": "Transporte",
|
"transport": "Método de Transporte",
|
||||||
"udp_relay_mode": "Modo de retransmisión UDP",
|
"udp_relay_mode": "Modo de retransmisión UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Ilimitado",
|
"unlimited": "Ilimitado",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "آدرس",
|
"address": "آدرس",
|
||||||
"address_placeholder": "آدرس سرور",
|
"address_placeholder": "آدرس سرور",
|
||||||
|
"basic": "پیکربندی پایه",
|
||||||
"cancel": "لغو",
|
"cancel": "لغو",
|
||||||
"city": "شهر",
|
"city": "شهر",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "حذف",
|
"delete": "حذف",
|
||||||
"deleted": "با موفقیت حذف شد",
|
"deleted": "با موفقیت حذف شد",
|
||||||
"disable_sni": "غیرفعال کردن SNI",
|
"disable_sni": "غیرفعال کردن SNI",
|
||||||
|
"disabled": "غیرفعال",
|
||||||
"disk": "دیسک",
|
"disk": "دیسک",
|
||||||
"drawerCreateTitle": "ایجاد سرور",
|
"drawerCreateTitle": "ایجاد سرور",
|
||||||
"drawerEditTitle": "ویرایش سرور",
|
"drawerEditTitle": "ویرایش سرور",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "آفلاین",
|
"offline": "آفلاین",
|
||||||
"online": "آنلاین",
|
"online": "آنلاین",
|
||||||
"onlineUsers": "کاربران آنلاین",
|
"onlineUsers": "کاربران آنلاین",
|
||||||
|
"padding_scheme": "طرح پدینگ",
|
||||||
|
"padding_scheme_placeholder": "یک قانون پدینگ در هر خط، فرمت: stop=8, 0=30-30",
|
||||||
"pageTitle": "سرورها",
|
"pageTitle": "سرورها",
|
||||||
"path": "مسیر",
|
"path": "مسیر",
|
||||||
"please_select": "لطفاً انتخاب کنید",
|
"please_select": "لطفاً انتخاب کنید",
|
||||||
|
"plugin": "پیکربندی پلاگین",
|
||||||
|
"plugin_opts": "گزینههای پلاگین",
|
||||||
"port": "پورت",
|
"port": "پورت",
|
||||||
|
"protocol_configurations": "پیکربندیهای پروتکل",
|
||||||
|
"protocol_configurations_desc": "پروتکلهای مورد نیاز را فعال و پیکربندی کنید",
|
||||||
|
"protocol_disabled_hint": "این پروتکل غیرفعال است، سوئیچ را فعال کنید تا پیکربندی شود",
|
||||||
"protocols": "پروتکلها",
|
"protocols": "پروتکلها",
|
||||||
|
"reality": "پیکربندی واقعیت",
|
||||||
"reduce_rtt": "کاهش RTT",
|
"reduce_rtt": "کاهش RTT",
|
||||||
|
"security": "پیکربندی امنیت",
|
||||||
"security_allow_insecure": "اجازه به ناامن",
|
"security_allow_insecure": "اجازه به ناامن",
|
||||||
"security_fingerprint": "اثر انگشت",
|
"security_fingerprint": "اثر انگشت",
|
||||||
"security_private_key": "کلید خصوصی واقعیت",
|
"security_private_key": "کلید خصوصی واقعیت",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "شناسه کوتاه واقعیت",
|
"security_short_id": "شناسه کوتاه واقعیت",
|
||||||
"security_short_id_placeholder": "رشته هگز (حداکثر 16 کاراکتر)",
|
"security_short_id_placeholder": "رشته هگز (حداکثر 16 کاراکتر)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "امنیت",
|
|
||||||
"select_encryption_method": "روش رمزنگاری را انتخاب کنید",
|
"select_encryption_method": "روش رمزنگاری را انتخاب کنید",
|
||||||
"server_key": "کلید سرور",
|
"server_key": "کلید سرور",
|
||||||
"service_name": "نام سرویس",
|
"service_name": "نام سرویس",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "اشتراک",
|
"subscription": "اشتراک",
|
||||||
"traffic": "ترافیک",
|
"traffic": "ترافیک",
|
||||||
"traffic_ratio": "ضریب",
|
"traffic_ratio": "ضریب",
|
||||||
"transport_title": "حمل و نقل",
|
"transport": "روش حمل و نقل",
|
||||||
"udp_relay_mode": "حالت رله UDP",
|
"udp_relay_mode": "حالت رله UDP",
|
||||||
"unitSecondsShort": "ث",
|
"unitSecondsShort": "ث",
|
||||||
"unlimited": "نامحدود",
|
"unlimited": "نامحدود",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Osoite",
|
"address": "Osoite",
|
||||||
"address_placeholder": "Palvelimen osoite",
|
"address_placeholder": "Palvelimen osoite",
|
||||||
|
"basic": "Perusasetukset",
|
||||||
"cancel": "Peruuta",
|
"cancel": "Peruuta",
|
||||||
"city": "Kaupunki",
|
"city": "Kaupunki",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Poista",
|
"delete": "Poista",
|
||||||
"deleted": "Poistettu onnistuneesti",
|
"deleted": "Poistettu onnistuneesti",
|
||||||
"disable_sni": "Poista SNI käytöstä",
|
"disable_sni": "Poista SNI käytöstä",
|
||||||
|
"disabled": "Poissa käytöstä",
|
||||||
"disk": "Levy",
|
"disk": "Levy",
|
||||||
"drawerCreateTitle": "Luo palvelin",
|
"drawerCreateTitle": "Luo palvelin",
|
||||||
"drawerEditTitle": "Muokkaa palvelinta",
|
"drawerEditTitle": "Muokkaa palvelinta",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Verkossa olevat käyttäjät",
|
"onlineUsers": "Verkossa olevat käyttäjät",
|
||||||
|
"padding_scheme": "Täyttökaavio",
|
||||||
|
"padding_scheme_placeholder": "Yksi täyttösääntö per rivi, muoto: stop=8, 0=30-30",
|
||||||
"pageTitle": "Palvelimet",
|
"pageTitle": "Palvelimet",
|
||||||
"path": "Polku",
|
"path": "Polku",
|
||||||
"please_select": "Ole hyvä ja valitse",
|
"please_select": "Ole hyvä ja valitse",
|
||||||
|
"plugin": "Laajennuksen asetukset",
|
||||||
|
"plugin_opts": "Laajennusvaihtoehdot",
|
||||||
"port": "Portti",
|
"port": "Portti",
|
||||||
|
"protocol_configurations": "Protokolla-asetukset",
|
||||||
|
"protocol_configurations_desc": "Ota käyttöön ja määritä tarvittavat protokollatyypit",
|
||||||
|
"protocol_disabled_hint": "Tämä protokolla on pois käytöstä, ota kytkin käyttöön määrittääksesi",
|
||||||
"protocols": "Protokollat",
|
"protocols": "Protokollat",
|
||||||
|
"reality": "Todellisuusasetukset",
|
||||||
"reduce_rtt": "Vähennä RTT",
|
"reduce_rtt": "Vähennä RTT",
|
||||||
|
"security": "Turvallisuusasetukset",
|
||||||
"security_allow_insecure": "Salli epävarma",
|
"security_allow_insecure": "Salli epävarma",
|
||||||
"security_fingerprint": "Sormenjälki",
|
"security_fingerprint": "Sormenjälki",
|
||||||
"security_private_key": "Todellinen yksityinen avain",
|
"security_private_key": "Todellinen yksityinen avain",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Todellinen lyhyt ID",
|
"security_short_id": "Todellinen lyhyt ID",
|
||||||
"security_short_id_placeholder": "Hex-merkkijono (enintään 16 merkkiä)",
|
"security_short_id_placeholder": "Hex-merkkijono (enintään 16 merkkiä)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Turvallisuus",
|
|
||||||
"select_encryption_method": "Valitse salausmenetelmä",
|
"select_encryption_method": "Valitse salausmenetelmä",
|
||||||
"server_key": "Palvelimen avain",
|
"server_key": "Palvelimen avain",
|
||||||
"service_name": "Palvelun nimi",
|
"service_name": "Palvelun nimi",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Tilauksen",
|
"subscription": "Tilauksen",
|
||||||
"traffic": "Liikenne",
|
"traffic": "Liikenne",
|
||||||
"traffic_ratio": "Kerroin",
|
"traffic_ratio": "Kerroin",
|
||||||
"transport_title": "Kuljetus",
|
"transport": "Kuljetustapa",
|
||||||
"udp_relay_mode": "UDP-väylätila",
|
"udp_relay_mode": "UDP-väylätila",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Rajoittamaton",
|
"unlimited": "Rajoittamaton",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"address_placeholder": "Adresse du serveur",
|
"address_placeholder": "Adresse du serveur",
|
||||||
|
"basic": "Configuration de base",
|
||||||
"cancel": "Annuler",
|
"cancel": "Annuler",
|
||||||
"city": "Ville",
|
"city": "Ville",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Supprimer",
|
"delete": "Supprimer",
|
||||||
"deleted": "Supprimé avec succès",
|
"deleted": "Supprimé avec succès",
|
||||||
"disable_sni": "Désactiver SNI",
|
"disable_sni": "Désactiver SNI",
|
||||||
|
"disabled": "Désactivé",
|
||||||
"disk": "Disque",
|
"disk": "Disque",
|
||||||
"drawerCreateTitle": "Créer un serveur",
|
"drawerCreateTitle": "Créer un serveur",
|
||||||
"drawerEditTitle": "Modifier le serveur",
|
"drawerEditTitle": "Modifier le serveur",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Hors ligne",
|
"offline": "Hors ligne",
|
||||||
"online": "En ligne",
|
"online": "En ligne",
|
||||||
"onlineUsers": "Utilisateurs en ligne",
|
"onlineUsers": "Utilisateurs en ligne",
|
||||||
|
"padding_scheme": "Schéma de remplissage",
|
||||||
|
"padding_scheme_placeholder": "Une règle de remplissage par ligne, format : stop=8, 0=30-30",
|
||||||
"pageTitle": "Serveurs",
|
"pageTitle": "Serveurs",
|
||||||
"path": "Chemin",
|
"path": "Chemin",
|
||||||
"please_select": "Veuillez sélectionner",
|
"please_select": "Veuillez sélectionner",
|
||||||
|
"plugin": "Configuration du plugin",
|
||||||
|
"plugin_opts": "Options du plugin",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Configurations de protocole",
|
||||||
|
"protocol_configurations_desc": "Activer et configurer les types de protocole requis",
|
||||||
|
"protocol_disabled_hint": "Ce protocole est désactivé, activez l'interrupteur pour configurer",
|
||||||
"protocols": "Protocoles",
|
"protocols": "Protocoles",
|
||||||
|
"reality": "Configuration de la réalité",
|
||||||
"reduce_rtt": "Réduire le RTT",
|
"reduce_rtt": "Réduire le RTT",
|
||||||
|
"security": "Configuration de la sécurité",
|
||||||
"security_allow_insecure": "Autoriser l'insecure",
|
"security_allow_insecure": "Autoriser l'insecure",
|
||||||
"security_fingerprint": "Empreinte digitale",
|
"security_fingerprint": "Empreinte digitale",
|
||||||
"security_private_key": "Clé privée de réalité",
|
"security_private_key": "Clé privée de réalité",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID court de réalité",
|
"security_short_id": "ID court de réalité",
|
||||||
"security_short_id_placeholder": "Chaîne hexadécimale (jusqu'à 16 caractères)",
|
"security_short_id_placeholder": "Chaîne hexadécimale (jusqu'à 16 caractères)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Sécurité",
|
|
||||||
"select_encryption_method": "Sélectionner la méthode de chiffrement",
|
"select_encryption_method": "Sélectionner la méthode de chiffrement",
|
||||||
"server_key": "Clé du serveur",
|
"server_key": "Clé du serveur",
|
||||||
"service_name": "Nom du service",
|
"service_name": "Nom du service",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Abonnement",
|
"subscription": "Abonnement",
|
||||||
"traffic": "Trafic",
|
"traffic": "Trafic",
|
||||||
"traffic_ratio": "Multiplicateur",
|
"traffic_ratio": "Multiplicateur",
|
||||||
"transport_title": "Transport",
|
"transport": "Méthode de transport",
|
||||||
"udp_relay_mode": "Mode de relais UDP",
|
"udp_relay_mode": "Mode de relais UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Illimité",
|
"unlimited": "Illimité",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "पता",
|
"address": "पता",
|
||||||
"address_placeholder": "सर्वर का पता",
|
"address_placeholder": "सर्वर का पता",
|
||||||
|
"basic": "बुनियादी कॉन्फ़िगरेशन",
|
||||||
"cancel": "रद्द करें",
|
"cancel": "रद्द करें",
|
||||||
"city": "शहर",
|
"city": "शहर",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "हटाएं",
|
"delete": "हटाएं",
|
||||||
"deleted": "सफलता से हटाया गया",
|
"deleted": "सफलता से हटाया गया",
|
||||||
"disable_sni": "SNI अक्षम करें",
|
"disable_sni": "SNI अक्षम करें",
|
||||||
|
"disabled": "अक्षम",
|
||||||
"disk": "डिस्क",
|
"disk": "डिस्क",
|
||||||
"drawerCreateTitle": "सर्वर बनाएं",
|
"drawerCreateTitle": "सर्वर बनाएं",
|
||||||
"drawerEditTitle": "सर्वर संपादित करें",
|
"drawerEditTitle": "सर्वर संपादित करें",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "ऑफलाइन",
|
"offline": "ऑफलाइन",
|
||||||
"online": "ऑनलाइन",
|
"online": "ऑनलाइन",
|
||||||
"onlineUsers": "ऑनलाइन उपयोगकर्ता",
|
"onlineUsers": "ऑनलाइन उपयोगकर्ता",
|
||||||
|
"padding_scheme": "पैडिंग योजना",
|
||||||
|
"padding_scheme_placeholder": "प्रति पंक्ति एक पैडिंग नियम, प्रारूप: रोकें=8, 0=30-30",
|
||||||
"pageTitle": "सर्वर",
|
"pageTitle": "सर्वर",
|
||||||
"path": "पथ",
|
"path": "पथ",
|
||||||
"please_select": "कृपया चुनें",
|
"please_select": "कृपया चुनें",
|
||||||
|
"plugin": "प्लगइन कॉन्फ़िगरेशन",
|
||||||
|
"plugin_opts": "प्लगइन विकल्प",
|
||||||
"port": "पोर्ट",
|
"port": "पोर्ट",
|
||||||
|
"protocol_configurations": "प्रोटोकॉल कॉन्फ़िगरेशन",
|
||||||
|
"protocol_configurations_desc": "आवश्यक प्रोटोकॉल प्रकारों को सक्षम और कॉन्फ़िगर करें",
|
||||||
|
"protocol_disabled_hint": "यह प्रोटोकॉल अक्षम है, कॉन्फ़िगर करने के लिए स्विच सक्षम करें",
|
||||||
"protocols": "प्रोटोकॉल",
|
"protocols": "प्रोटोकॉल",
|
||||||
|
"reality": "वास्तविकता कॉन्फ़िगरेशन",
|
||||||
"reduce_rtt": "RTT कम करें",
|
"reduce_rtt": "RTT कम करें",
|
||||||
|
"security": "सुरक्षा कॉन्फ़िगरेशन",
|
||||||
"security_allow_insecure": "असुरक्षित की अनुमति दें",
|
"security_allow_insecure": "असुरक्षित की अनुमति दें",
|
||||||
"security_fingerprint": "फिंगरप्रिंट",
|
"security_fingerprint": "फिंगरप्रिंट",
|
||||||
"security_private_key": "वास्तविक निजी कुंजी",
|
"security_private_key": "वास्तविक निजी कुंजी",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "वास्तविक शॉर्ट आईडी",
|
"security_short_id": "वास्तविक शॉर्ट आईडी",
|
||||||
"security_short_id_placeholder": "हेक्स स्ट्रिंग (16 अक्षरों तक)",
|
"security_short_id_placeholder": "हेक्स स्ट्रिंग (16 अक्षरों तक)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "सुरक्षा",
|
|
||||||
"select_encryption_method": "एन्क्रिप्शन विधि चुनें",
|
"select_encryption_method": "एन्क्रिप्शन विधि चुनें",
|
||||||
"server_key": "सर्वर कुंजी",
|
"server_key": "सर्वर कुंजी",
|
||||||
"service_name": "सेवा का नाम",
|
"service_name": "सेवा का नाम",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "सदस्यता",
|
"subscription": "सदस्यता",
|
||||||
"traffic": "यातायात",
|
"traffic": "यातायात",
|
||||||
"traffic_ratio": "गुणांक",
|
"traffic_ratio": "गुणांक",
|
||||||
"transport_title": "परिवहन",
|
"transport": "परिवहन विधि",
|
||||||
"udp_relay_mode": "UDP रिले मोड",
|
"udp_relay_mode": "UDP रिले मोड",
|
||||||
"unitSecondsShort": "सेकंड",
|
"unitSecondsShort": "सेकंड",
|
||||||
"unlimited": "असीमित",
|
"unlimited": "असीमित",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Cím",
|
"address": "Cím",
|
||||||
"address_placeholder": "Szerver cím",
|
"address_placeholder": "Szerver cím",
|
||||||
|
"basic": "Alapértelmezett Beállítások",
|
||||||
"cancel": "Mégse",
|
"cancel": "Mégse",
|
||||||
"city": "Város",
|
"city": "Város",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Törlés",
|
"delete": "Törlés",
|
||||||
"deleted": "Sikeresen törölve",
|
"deleted": "Sikeresen törölve",
|
||||||
"disable_sni": "SNI letiltása",
|
"disable_sni": "SNI letiltása",
|
||||||
|
"disabled": "Letiltva",
|
||||||
"disk": "Lemez",
|
"disk": "Lemez",
|
||||||
"drawerCreateTitle": "Szerver létrehozása",
|
"drawerCreateTitle": "Szerver létrehozása",
|
||||||
"drawerEditTitle": "Szerver szerkesztése",
|
"drawerEditTitle": "Szerver szerkesztése",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Online felhasználók",
|
"onlineUsers": "Online felhasználók",
|
||||||
|
"padding_scheme": "Kitöltési Sémák",
|
||||||
|
"padding_scheme_placeholder": "Egy kitöltési szabály soronként, formátum: stop=8, 0=30-30",
|
||||||
"pageTitle": "Szerverek",
|
"pageTitle": "Szerverek",
|
||||||
"path": "Útvonal",
|
"path": "Útvonal",
|
||||||
"please_select": "Kérjük, válasszon",
|
"please_select": "Kérjük, válasszon",
|
||||||
|
"plugin": "Bővítmény Beállítások",
|
||||||
|
"plugin_opts": "Bővítmény Opciók",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Protokoll Beállítások",
|
||||||
|
"protocol_configurations_desc": "Engedélyezze és konfigurálja a szükséges protokolltípusokat",
|
||||||
|
"protocol_disabled_hint": "Ez a protokoll le van tiltva, engedélyezze a kapcsolót a konfiguráláshoz",
|
||||||
"protocols": "Protokollok",
|
"protocols": "Protokollok",
|
||||||
|
"reality": "Valóság Beállítások",
|
||||||
"reduce_rtt": "RTT csökkentése",
|
"reduce_rtt": "RTT csökkentése",
|
||||||
|
"security": "Biztonsági Beállítások",
|
||||||
"security_allow_insecure": "Biztonságos kapcsolat engedélyezése",
|
"security_allow_insecure": "Biztonságos kapcsolat engedélyezése",
|
||||||
"security_fingerprint": "Ujjlenyomat",
|
"security_fingerprint": "Ujjlenyomat",
|
||||||
"security_private_key": "Valóság privát kulcs",
|
"security_private_key": "Valóság privát kulcs",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Valóság rövid ID",
|
"security_short_id": "Valóság rövid ID",
|
||||||
"security_short_id_placeholder": "Hexadecimális karakterlánc (legfeljebb 16 karakter)",
|
"security_short_id_placeholder": "Hexadecimális karakterlánc (legfeljebb 16 karakter)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Biztonság",
|
|
||||||
"select_encryption_method": "Válassza ki a titkosítási módszert",
|
"select_encryption_method": "Válassza ki a titkosítási módszert",
|
||||||
"server_key": "Szerver kulcs",
|
"server_key": "Szerver kulcs",
|
||||||
"service_name": "Szolgáltatás neve",
|
"service_name": "Szolgáltatás neve",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Előfizetés",
|
"subscription": "Előfizetés",
|
||||||
"traffic": "Forgalom",
|
"traffic": "Forgalom",
|
||||||
"traffic_ratio": "Szorzó",
|
"traffic_ratio": "Szorzó",
|
||||||
"transport_title": "Szállítás",
|
"transport": "Szállítási Módszer",
|
||||||
"udp_relay_mode": "UDP átjáró mód",
|
"udp_relay_mode": "UDP átjáró mód",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Korlátlan",
|
"unlimited": "Korlátlan",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "アドレス",
|
"address": "アドレス",
|
||||||
"address_placeholder": "サーバーアドレス",
|
"address_placeholder": "サーバーアドレス",
|
||||||
|
"basic": "基本設定",
|
||||||
"cancel": "キャンセル",
|
"cancel": "キャンセル",
|
||||||
"city": "都市",
|
"city": "都市",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "削除",
|
"delete": "削除",
|
||||||
"deleted": "削除に成功しました",
|
"deleted": "削除に成功しました",
|
||||||
"disable_sni": "SNIを無効にする",
|
"disable_sni": "SNIを無効にする",
|
||||||
|
"disabled": "無効",
|
||||||
"disk": "ディスク",
|
"disk": "ディスク",
|
||||||
"drawerCreateTitle": "サーバーを作成",
|
"drawerCreateTitle": "サーバーを作成",
|
||||||
"drawerEditTitle": "サーバーを編集",
|
"drawerEditTitle": "サーバーを編集",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "オフライン",
|
"offline": "オフライン",
|
||||||
"online": "オンライン",
|
"online": "オンライン",
|
||||||
"onlineUsers": "オンラインユーザー",
|
"onlineUsers": "オンラインユーザー",
|
||||||
|
"padding_scheme": "パディングスキーム",
|
||||||
|
"padding_scheme_placeholder": "1行に1つのパディングルール、形式: stop=8, 0=30-30",
|
||||||
"pageTitle": "サーバー",
|
"pageTitle": "サーバー",
|
||||||
"path": "パス",
|
"path": "パス",
|
||||||
"please_select": "選択してください",
|
"please_select": "選択してください",
|
||||||
|
"plugin": "プラグイン設定",
|
||||||
|
"plugin_opts": "プラグインオプション",
|
||||||
"port": "ポート",
|
"port": "ポート",
|
||||||
|
"protocol_configurations": "プロトコル設定",
|
||||||
|
"protocol_configurations_desc": "必要なプロトコルタイプを有効にして設定します",
|
||||||
|
"protocol_disabled_hint": "このプロトコルは無効です。設定するにはスイッチを有効にしてください",
|
||||||
"protocols": "プロトコル",
|
"protocols": "プロトコル",
|
||||||
|
"reality": "リアリティ設定",
|
||||||
"reduce_rtt": "RTTを減少させる",
|
"reduce_rtt": "RTTを減少させる",
|
||||||
|
"security": "セキュリティ設定",
|
||||||
"security_allow_insecure": "不安全を許可",
|
"security_allow_insecure": "不安全を許可",
|
||||||
"security_fingerprint": "フィンガープリント",
|
"security_fingerprint": "フィンガープリント",
|
||||||
"security_private_key": "リアリティプライベートキー",
|
"security_private_key": "リアリティプライベートキー",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "リアリティショートID",
|
"security_short_id": "リアリティショートID",
|
||||||
"security_short_id_placeholder": "16文字以内の16進数文字列",
|
"security_short_id_placeholder": "16文字以内の16進数文字列",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "セキュリティ",
|
|
||||||
"select_encryption_method": "暗号化方式を選択",
|
"select_encryption_method": "暗号化方式を選択",
|
||||||
"server_key": "サーバーキー",
|
"server_key": "サーバーキー",
|
||||||
"service_name": "サービス名",
|
"service_name": "サービス名",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "サブスクリプション",
|
"subscription": "サブスクリプション",
|
||||||
"traffic": "トラフィック",
|
"traffic": "トラフィック",
|
||||||
"traffic_ratio": "倍率",
|
"traffic_ratio": "倍率",
|
||||||
"transport_title": "トランスポート",
|
"transport": "トランスポート方法",
|
||||||
"udp_relay_mode": "UDPリレーモード",
|
"udp_relay_mode": "UDPリレーモード",
|
||||||
"unitSecondsShort": "秒",
|
"unitSecondsShort": "秒",
|
||||||
"unlimited": "無制限",
|
"unlimited": "無制限",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "주소",
|
"address": "주소",
|
||||||
"address_placeholder": "서버 주소",
|
"address_placeholder": "서버 주소",
|
||||||
|
"basic": "기본 설정",
|
||||||
"cancel": "취소",
|
"cancel": "취소",
|
||||||
"city": "도시",
|
"city": "도시",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "삭제",
|
"delete": "삭제",
|
||||||
"deleted": "성공적으로 삭제됨",
|
"deleted": "성공적으로 삭제됨",
|
||||||
"disable_sni": "SNI 비활성화",
|
"disable_sni": "SNI 비활성화",
|
||||||
|
"disabled": "비활성화됨",
|
||||||
"disk": "디스크",
|
"disk": "디스크",
|
||||||
"drawerCreateTitle": "서버 생성",
|
"drawerCreateTitle": "서버 생성",
|
||||||
"drawerEditTitle": "서버 편집",
|
"drawerEditTitle": "서버 편집",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "오프라인",
|
"offline": "오프라인",
|
||||||
"online": "온라인",
|
"online": "온라인",
|
||||||
"onlineUsers": "온라인 사용자",
|
"onlineUsers": "온라인 사용자",
|
||||||
|
"padding_scheme": "패딩 규칙",
|
||||||
|
"padding_scheme_placeholder": "한 줄에 하나의 패딩 규칙, 형식: stop=8, 0=30-30",
|
||||||
"pageTitle": "서버",
|
"pageTitle": "서버",
|
||||||
"path": "경로",
|
"path": "경로",
|
||||||
"please_select": "선택해 주세요",
|
"please_select": "선택해 주세요",
|
||||||
|
"plugin": "플러그인 설정",
|
||||||
|
"plugin_opts": "플러그인 옵션",
|
||||||
"port": "포트",
|
"port": "포트",
|
||||||
|
"protocol_configurations": "프로토콜 설정",
|
||||||
|
"protocol_configurations_desc": "필요한 프로토콜 유형을 활성화하고 구성합니다",
|
||||||
|
"protocol_disabled_hint": "이 프로토콜은 비활성화되어 있습니다. 구성을 위해 스위치를 활성화하세요",
|
||||||
"protocols": "프로토콜",
|
"protocols": "프로토콜",
|
||||||
|
"reality": "현실 설정",
|
||||||
"reduce_rtt": "RTT 감소",
|
"reduce_rtt": "RTT 감소",
|
||||||
|
"security": "보안 설정",
|
||||||
"security_allow_insecure": "불안전 허용",
|
"security_allow_insecure": "불안전 허용",
|
||||||
"security_fingerprint": "지문",
|
"security_fingerprint": "지문",
|
||||||
"security_private_key": "실제 개인 키",
|
"security_private_key": "실제 개인 키",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "실제 짧은 ID",
|
"security_short_id": "실제 짧은 ID",
|
||||||
"security_short_id_placeholder": "16자 이내의 헥스 문자열",
|
"security_short_id_placeholder": "16자 이내의 헥스 문자열",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "보안",
|
|
||||||
"select_encryption_method": "암호화 방법 선택",
|
"select_encryption_method": "암호화 방법 선택",
|
||||||
"server_key": "서버 키",
|
"server_key": "서버 키",
|
||||||
"service_name": "서비스 이름",
|
"service_name": "서비스 이름",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "구독",
|
"subscription": "구독",
|
||||||
"traffic": "트래픽",
|
"traffic": "트래픽",
|
||||||
"traffic_ratio": "배수",
|
"traffic_ratio": "배수",
|
||||||
"transport_title": "전송",
|
"transport": "전송 방법",
|
||||||
"udp_relay_mode": "UDP 릴레이 모드",
|
"udp_relay_mode": "UDP 릴레이 모드",
|
||||||
"unitSecondsShort": "초",
|
"unitSecondsShort": "초",
|
||||||
"unlimited": "무제한",
|
"unlimited": "무제한",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"address_placeholder": "Serveradresse",
|
"address_placeholder": "Serveradresse",
|
||||||
|
"basic": "Grunnleggende Konfigurasjon",
|
||||||
"cancel": "Avbryt",
|
"cancel": "Avbryt",
|
||||||
"city": "By",
|
"city": "By",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Slett",
|
"delete": "Slett",
|
||||||
"deleted": "Slettet vellykket",
|
"deleted": "Slettet vellykket",
|
||||||
"disable_sni": "Deaktiver SNI",
|
"disable_sni": "Deaktiver SNI",
|
||||||
|
"disabled": "Deaktivert",
|
||||||
"disk": "Disk",
|
"disk": "Disk",
|
||||||
"drawerCreateTitle": "Opprett server",
|
"drawerCreateTitle": "Opprett server",
|
||||||
"drawerEditTitle": "Rediger server",
|
"drawerEditTitle": "Rediger server",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Frakoblet",
|
"offline": "Frakoblet",
|
||||||
"online": "På nett",
|
"online": "På nett",
|
||||||
"onlineUsers": "Brukere på nett",
|
"onlineUsers": "Brukere på nett",
|
||||||
|
"padding_scheme": "Polstring Skjema",
|
||||||
|
"padding_scheme_placeholder": "Én polstringsregel per linje, format: stopp=8, 0=30-30",
|
||||||
"pageTitle": "Servere",
|
"pageTitle": "Servere",
|
||||||
"path": "Sti",
|
"path": "Sti",
|
||||||
"please_select": "Vennligst velg",
|
"please_select": "Vennligst velg",
|
||||||
|
"plugin": "Plugin Konfigurasjon",
|
||||||
|
"plugin_opts": "Plugin Alternativer",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Protokoll Konfigurasjoner",
|
||||||
|
"protocol_configurations_desc": "Aktiver og konfigurer de nødvendige protokolltypene",
|
||||||
|
"protocol_disabled_hint": "Denne protokollen er deaktivert, aktiver bryteren for å konfigurere",
|
||||||
"protocols": "Protokoller",
|
"protocols": "Protokoller",
|
||||||
|
"reality": "Virkelighet Konfigurasjon",
|
||||||
"reduce_rtt": "Reduser RTT",
|
"reduce_rtt": "Reduser RTT",
|
||||||
|
"security": "Sikkerhetskonfigurasjon",
|
||||||
"security_allow_insecure": "Tillat usikker",
|
"security_allow_insecure": "Tillat usikker",
|
||||||
"security_fingerprint": "Fingeravtrykk",
|
"security_fingerprint": "Fingeravtrykk",
|
||||||
"security_private_key": "Privat nøkkel",
|
"security_private_key": "Privat nøkkel",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Kort ID",
|
"security_short_id": "Kort ID",
|
||||||
"security_short_id_placeholder": "Hex-streng (opptil 16 tegn)",
|
"security_short_id_placeholder": "Hex-streng (opptil 16 tegn)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Sikkerhet",
|
|
||||||
"select_encryption_method": "Velg krypteringsmetode",
|
"select_encryption_method": "Velg krypteringsmetode",
|
||||||
"server_key": "Servernøkkel",
|
"server_key": "Servernøkkel",
|
||||||
"service_name": "Tjenestenavn",
|
"service_name": "Tjenestenavn",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Abonnement",
|
"subscription": "Abonnement",
|
||||||
"traffic": "Trafikk",
|
"traffic": "Trafikk",
|
||||||
"traffic_ratio": "Multiplikator",
|
"traffic_ratio": "Multiplikator",
|
||||||
"transport_title": "Transport",
|
"transport": "Transportmetode",
|
||||||
"udp_relay_mode": "UDP relémodus",
|
"udp_relay_mode": "UDP relémodus",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Ubegrenset",
|
"unlimited": "Ubegrenset",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adres",
|
"address": "Adres",
|
||||||
"address_placeholder": "Adres serwera",
|
"address_placeholder": "Adres serwera",
|
||||||
|
"basic": "Podstawowa konfiguracja",
|
||||||
"cancel": "Anuluj",
|
"cancel": "Anuluj",
|
||||||
"city": "Miasto",
|
"city": "Miasto",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Usuń",
|
"delete": "Usuń",
|
||||||
"deleted": "Usunięto pomyślnie",
|
"deleted": "Usunięto pomyślnie",
|
||||||
"disable_sni": "Wyłącz SNI",
|
"disable_sni": "Wyłącz SNI",
|
||||||
|
"disabled": "Wyłączone",
|
||||||
"disk": "Dysk",
|
"disk": "Dysk",
|
||||||
"drawerCreateTitle": "Utwórz serwer",
|
"drawerCreateTitle": "Utwórz serwer",
|
||||||
"drawerEditTitle": "Edytuj serwer",
|
"drawerEditTitle": "Edytuj serwer",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Użytkownicy online",
|
"onlineUsers": "Użytkownicy online",
|
||||||
|
"padding_scheme": "Schemat wypełnienia",
|
||||||
|
"padding_scheme_placeholder": "Jedna reguła wypełnienia na linię, format: stop=8, 0=30-30",
|
||||||
"pageTitle": "Serwery",
|
"pageTitle": "Serwery",
|
||||||
"path": "Ścieżka",
|
"path": "Ścieżka",
|
||||||
"please_select": "Proszę wybrać",
|
"please_select": "Proszę wybrać",
|
||||||
|
"plugin": "Konfiguracja wtyczki",
|
||||||
|
"plugin_opts": "Opcje wtyczki",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Konfiguracje protokołów",
|
||||||
|
"protocol_configurations_desc": "Włącz i skonfiguruj wymagane typy protokołów",
|
||||||
|
"protocol_disabled_hint": "Ten protokół jest wyłączony, włącz przełącznik, aby skonfigurować",
|
||||||
"protocols": "Protokoły",
|
"protocols": "Protokoły",
|
||||||
|
"reality": "Konfiguracja rzeczywistości",
|
||||||
"reduce_rtt": "Zredukuj RTT",
|
"reduce_rtt": "Zredukuj RTT",
|
||||||
|
"security": "Konfiguracja bezpieczeństwa",
|
||||||
"security_allow_insecure": "Zezwól na niebezpieczne",
|
"security_allow_insecure": "Zezwól na niebezpieczne",
|
||||||
"security_fingerprint": "Odcisk palca",
|
"security_fingerprint": "Odcisk palca",
|
||||||
"security_private_key": "Prywatny klucz rzeczywistości",
|
"security_private_key": "Prywatny klucz rzeczywistości",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Krótki ID rzeczywistości",
|
"security_short_id": "Krótki ID rzeczywistości",
|
||||||
"security_short_id_placeholder": "Ciąg szesnastkowy (do 16 znaków)",
|
"security_short_id_placeholder": "Ciąg szesnastkowy (do 16 znaków)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Bezpieczeństwo",
|
|
||||||
"select_encryption_method": "Wybierz metodę szyfrowania",
|
"select_encryption_method": "Wybierz metodę szyfrowania",
|
||||||
"server_key": "Klucz serwera",
|
"server_key": "Klucz serwera",
|
||||||
"service_name": "Nazwa usługi",
|
"service_name": "Nazwa usługi",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Subskrypcja",
|
"subscription": "Subskrypcja",
|
||||||
"traffic": "Ruch",
|
"traffic": "Ruch",
|
||||||
"traffic_ratio": "Mnożnik",
|
"traffic_ratio": "Mnożnik",
|
||||||
"transport_title": "Transport",
|
"transport": "Metoda transportu",
|
||||||
"udp_relay_mode": "Tryb przekazywania UDP",
|
"udp_relay_mode": "Tryb przekazywania UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Nieograniczone",
|
"unlimited": "Nieograniczone",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Endereço",
|
"address": "Endereço",
|
||||||
"address_placeholder": "Endereço do servidor",
|
"address_placeholder": "Endereço do servidor",
|
||||||
|
"basic": "Configuração Básica",
|
||||||
"cancel": "Cancelar",
|
"cancel": "Cancelar",
|
||||||
"city": "Cidade",
|
"city": "Cidade",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Excluir",
|
"delete": "Excluir",
|
||||||
"deleted": "Excluído com sucesso",
|
"deleted": "Excluído com sucesso",
|
||||||
"disable_sni": "Desativar SNI",
|
"disable_sni": "Desativar SNI",
|
||||||
|
"disabled": "Desativado",
|
||||||
"disk": "Disco",
|
"disk": "Disco",
|
||||||
"drawerCreateTitle": "Criar Servidor",
|
"drawerCreateTitle": "Criar Servidor",
|
||||||
"drawerEditTitle": "Editar Servidor",
|
"drawerEditTitle": "Editar Servidor",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Usuários online",
|
"onlineUsers": "Usuários online",
|
||||||
|
"padding_scheme": "Esquema de Preenchimento",
|
||||||
|
"padding_scheme_placeholder": "Uma regra de preenchimento por linha, formato: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servidores",
|
"pageTitle": "Servidores",
|
||||||
"path": "Caminho",
|
"path": "Caminho",
|
||||||
"please_select": "Por favor, selecione",
|
"please_select": "Por favor, selecione",
|
||||||
|
"plugin": "Configuração do Plugin",
|
||||||
|
"plugin_opts": "Opções do Plugin",
|
||||||
"port": "Porta",
|
"port": "Porta",
|
||||||
|
"protocol_configurations": "Configurações de Protocolo",
|
||||||
|
"protocol_configurations_desc": "Ative e configure os tipos de protocolo necessários",
|
||||||
|
"protocol_disabled_hint": "Este protocolo está desativado, ative o interruptor para configurar",
|
||||||
"protocols": "Protocolos",
|
"protocols": "Protocolos",
|
||||||
|
"reality": "Configuração de Realidade",
|
||||||
"reduce_rtt": "Reduzir RTT",
|
"reduce_rtt": "Reduzir RTT",
|
||||||
|
"security": "Configuração de Segurança",
|
||||||
"security_allow_insecure": "Permitir inseguro",
|
"security_allow_insecure": "Permitir inseguro",
|
||||||
"security_fingerprint": "Impressão digital",
|
"security_fingerprint": "Impressão digital",
|
||||||
"security_private_key": "Chave privada da realidade",
|
"security_private_key": "Chave privada da realidade",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID curto da realidade",
|
"security_short_id": "ID curto da realidade",
|
||||||
"security_short_id_placeholder": "String hexadecimal (até 16 caracteres)",
|
"security_short_id_placeholder": "String hexadecimal (até 16 caracteres)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Segurança",
|
|
||||||
"select_encryption_method": "Selecionar método de criptografia",
|
"select_encryption_method": "Selecionar método de criptografia",
|
||||||
"server_key": "Chave do servidor",
|
"server_key": "Chave do servidor",
|
||||||
"service_name": "Nome do serviço",
|
"service_name": "Nome do serviço",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Assinatura",
|
"subscription": "Assinatura",
|
||||||
"traffic": "Tráfego",
|
"traffic": "Tráfego",
|
||||||
"traffic_ratio": "Multiplicador",
|
"traffic_ratio": "Multiplicador",
|
||||||
"transport_title": "Transporte",
|
"transport": "Método de Transporte",
|
||||||
"udp_relay_mode": "Modo de retransmissão UDP",
|
"udp_relay_mode": "Modo de retransmissão UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Ilimitado",
|
"unlimited": "Ilimitado",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adresă",
|
"address": "Adresă",
|
||||||
"address_placeholder": "Adresă server",
|
"address_placeholder": "Adresă server",
|
||||||
|
"basic": "Configurare de bază",
|
||||||
"cancel": "Anulează",
|
"cancel": "Anulează",
|
||||||
"city": "Oraș",
|
"city": "Oraș",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Șterge",
|
"delete": "Șterge",
|
||||||
"deleted": "Șters cu succes",
|
"deleted": "Șters cu succes",
|
||||||
"disable_sni": "Dezactivează SNI",
|
"disable_sni": "Dezactivează SNI",
|
||||||
|
"disabled": "Dezactivat",
|
||||||
"disk": "Disc",
|
"disk": "Disc",
|
||||||
"drawerCreateTitle": "Creează Server",
|
"drawerCreateTitle": "Creează Server",
|
||||||
"drawerEditTitle": "Editează Server",
|
"drawerEditTitle": "Editează Server",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"onlineUsers": "Utilizatori online",
|
"onlineUsers": "Utilizatori online",
|
||||||
|
"padding_scheme": "Schema de umplere",
|
||||||
|
"padding_scheme_placeholder": "O regulă de umplere pe linie, format: stop=8, 0=30-30",
|
||||||
"pageTitle": "Servere",
|
"pageTitle": "Servere",
|
||||||
"path": "Cale",
|
"path": "Cale",
|
||||||
"please_select": "Te rog selectează",
|
"please_select": "Te rog selectează",
|
||||||
|
"plugin": "Configurare plugin",
|
||||||
|
"plugin_opts": "Opțiuni plugin",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Configurări protocol",
|
||||||
|
"protocol_configurations_desc": "Activează și configurează tipurile de protocol necesare",
|
||||||
|
"protocol_disabled_hint": "Acest protocol este dezactivat, activează comutatorul pentru a configura",
|
||||||
"protocols": "Protocoale",
|
"protocols": "Protocoale",
|
||||||
|
"reality": "Configurare realitate",
|
||||||
"reduce_rtt": "Reducere RTT",
|
"reduce_rtt": "Reducere RTT",
|
||||||
|
"security": "Configurare securitate",
|
||||||
"security_allow_insecure": "Permite nesecurizat",
|
"security_allow_insecure": "Permite nesecurizat",
|
||||||
"security_fingerprint": "Amprentă",
|
"security_fingerprint": "Amprentă",
|
||||||
"security_private_key": "Cheie privată reală",
|
"security_private_key": "Cheie privată reală",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID scurt real",
|
"security_short_id": "ID scurt real",
|
||||||
"security_short_id_placeholder": "Șir hexazecimal (până la 16 caractere)",
|
"security_short_id_placeholder": "Șir hexazecimal (până la 16 caractere)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Securitate",
|
|
||||||
"select_encryption_method": "Selectează metoda de criptare",
|
"select_encryption_method": "Selectează metoda de criptare",
|
||||||
"server_key": "Cheie server",
|
"server_key": "Cheie server",
|
||||||
"service_name": "Nume serviciu",
|
"service_name": "Nume serviciu",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Abonament",
|
"subscription": "Abonament",
|
||||||
"traffic": "Trafic",
|
"traffic": "Trafic",
|
||||||
"traffic_ratio": "Multiplicator",
|
"traffic_ratio": "Multiplicator",
|
||||||
"transport_title": "Transport",
|
"transport": "Metodă de transport",
|
||||||
"udp_relay_mode": "Mod relay UDP",
|
"udp_relay_mode": "Mod relay UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Nelimitat",
|
"unlimited": "Nelimitat",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Адрес",
|
"address": "Адрес",
|
||||||
"address_placeholder": "Адрес сервера",
|
"address_placeholder": "Адрес сервера",
|
||||||
|
"basic": "Базовая конфигурация",
|
||||||
"cancel": "Отмена",
|
"cancel": "Отмена",
|
||||||
"city": "Город",
|
"city": "Город",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Удалить",
|
"delete": "Удалить",
|
||||||
"deleted": "Успешно удалено",
|
"deleted": "Успешно удалено",
|
||||||
"disable_sni": "Отключить SNI",
|
"disable_sni": "Отключить SNI",
|
||||||
|
"disabled": "Отключено",
|
||||||
"disk": "Диск",
|
"disk": "Диск",
|
||||||
"drawerCreateTitle": "Создать сервер",
|
"drawerCreateTitle": "Создать сервер",
|
||||||
"drawerEditTitle": "Редактировать сервер",
|
"drawerEditTitle": "Редактировать сервер",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Офлайн",
|
"offline": "Офлайн",
|
||||||
"online": "Онлайн",
|
"online": "Онлайн",
|
||||||
"onlineUsers": "Онлайн пользователи",
|
"onlineUsers": "Онлайн пользователи",
|
||||||
|
"padding_scheme": "Схема выравнивания",
|
||||||
|
"padding_scheme_placeholder": "Одно правило выравнивания на строку, формат: stop=8, 0=30-30",
|
||||||
"pageTitle": "Серверы",
|
"pageTitle": "Серверы",
|
||||||
"path": "Путь",
|
"path": "Путь",
|
||||||
"please_select": "Пожалуйста, выберите",
|
"please_select": "Пожалуйста, выберите",
|
||||||
|
"plugin": "Конфигурация плагина",
|
||||||
|
"plugin_opts": "Опции плагина",
|
||||||
"port": "Порт",
|
"port": "Порт",
|
||||||
|
"protocol_configurations": "Конфигурации протоколов",
|
||||||
|
"protocol_configurations_desc": "Включите и настройте необходимые типы протоколов",
|
||||||
|
"protocol_disabled_hint": "Этот протокол отключен, включите переключатель для настройки",
|
||||||
"protocols": "Протоколы",
|
"protocols": "Протоколы",
|
||||||
|
"reality": "Конфигурация реальности",
|
||||||
"reduce_rtt": "Сократить RTT",
|
"reduce_rtt": "Сократить RTT",
|
||||||
|
"security": "Конфигурация безопасности",
|
||||||
"security_allow_insecure": "Разрешить небезопасное",
|
"security_allow_insecure": "Разрешить небезопасное",
|
||||||
"security_fingerprint": "Отпечаток",
|
"security_fingerprint": "Отпечаток",
|
||||||
"security_private_key": "Закрытый ключ реальности",
|
"security_private_key": "Закрытый ключ реальности",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Короткий ID реальности",
|
"security_short_id": "Короткий ID реальности",
|
||||||
"security_short_id_placeholder": "Шестнадцатеричная строка (до 16 символов)",
|
"security_short_id_placeholder": "Шестнадцатеричная строка (до 16 символов)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Безопасность",
|
|
||||||
"select_encryption_method": "Выберите метод шифрования",
|
"select_encryption_method": "Выберите метод шифрования",
|
||||||
"server_key": "Ключ сервера",
|
"server_key": "Ключ сервера",
|
||||||
"service_name": "Имя службы",
|
"service_name": "Имя службы",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Подписка",
|
"subscription": "Подписка",
|
||||||
"traffic": "Трафик",
|
"traffic": "Трафик",
|
||||||
"traffic_ratio": "Множитель",
|
"traffic_ratio": "Множитель",
|
||||||
"transport_title": "Транспорт",
|
"transport": "Метод передачи",
|
||||||
"udp_relay_mode": "Режим UDP ретрансляции",
|
"udp_relay_mode": "Режим UDP ретрансляции",
|
||||||
"unitSecondsShort": "С",
|
"unitSecondsShort": "С",
|
||||||
"unlimited": "Неограниченно",
|
"unlimited": "Неограниченно",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "ที่อยู่",
|
"address": "ที่อยู่",
|
||||||
"address_placeholder": "ที่อยู่เซิร์ฟเวอร์",
|
"address_placeholder": "ที่อยู่เซิร์ฟเวอร์",
|
||||||
|
"basic": "การตั้งค่าพื้นฐาน",
|
||||||
"cancel": "ยกเลิก",
|
"cancel": "ยกเลิก",
|
||||||
"city": "เมือง",
|
"city": "เมือง",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "ลบ",
|
"delete": "ลบ",
|
||||||
"deleted": "ลบสำเร็จ",
|
"deleted": "ลบสำเร็จ",
|
||||||
"disable_sni": "ปิดการใช้งาน SNI",
|
"disable_sni": "ปิดการใช้งาน SNI",
|
||||||
|
"disabled": "ปิดใช้งาน",
|
||||||
"disk": "ดิสก์",
|
"disk": "ดิสก์",
|
||||||
"drawerCreateTitle": "สร้างเซิร์ฟเวอร์",
|
"drawerCreateTitle": "สร้างเซิร์ฟเวอร์",
|
||||||
"drawerEditTitle": "แก้ไขเซิร์ฟเวอร์",
|
"drawerEditTitle": "แก้ไขเซิร์ฟเวอร์",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "ออฟไลน์",
|
"offline": "ออฟไลน์",
|
||||||
"online": "ออนไลน์",
|
"online": "ออนไลน์",
|
||||||
"onlineUsers": "ผู้ใช้งานออนไลน์",
|
"onlineUsers": "ผู้ใช้งานออนไลน์",
|
||||||
|
"padding_scheme": "รูปแบบการเติม",
|
||||||
|
"padding_scheme_placeholder": "กฎการเติมหนึ่งกฎต่อหนึ่งบรรทัด รูปแบบ: stop=8, 0=30-30",
|
||||||
"pageTitle": "เซิร์ฟเวอร์",
|
"pageTitle": "เซิร์ฟเวอร์",
|
||||||
"path": "เส้นทาง",
|
"path": "เส้นทาง",
|
||||||
"please_select": "กรุณาเลือก",
|
"please_select": "กรุณาเลือก",
|
||||||
|
"plugin": "การตั้งค่าปลั๊กอิน",
|
||||||
|
"plugin_opts": "ตัวเลือกปลั๊กอิน",
|
||||||
"port": "พอร์ต",
|
"port": "พอร์ต",
|
||||||
|
"protocol_configurations": "การตั้งค่าโปรโตคอล",
|
||||||
|
"protocol_configurations_desc": "เปิดใช้งานและกำหนดค่าประเภทโปรโตคอลที่ต้องการ",
|
||||||
|
"protocol_disabled_hint": "โปรโตคอลนี้ถูกปิดใช้งาน เปิดสวิตช์เพื่อกำหนดค่า",
|
||||||
"protocols": "โปรโตคอล",
|
"protocols": "โปรโตคอล",
|
||||||
|
"reality": "การตั้งค่าความเป็นจริง",
|
||||||
"reduce_rtt": "ลด RTT",
|
"reduce_rtt": "ลด RTT",
|
||||||
|
"security": "การตั้งค่าความปลอดภัย",
|
||||||
"security_allow_insecure": "อนุญาตให้ไม่ปลอดภัย",
|
"security_allow_insecure": "อนุญาตให้ไม่ปลอดภัย",
|
||||||
"security_fingerprint": "ลายนิ้วมือ",
|
"security_fingerprint": "ลายนิ้วมือ",
|
||||||
"security_private_key": "คีย์ส่วนตัวจริง",
|
"security_private_key": "คีย์ส่วนตัวจริง",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "รหัสสั้นจริง",
|
"security_short_id": "รหัสสั้นจริง",
|
||||||
"security_short_id_placeholder": "สตริงฮีซ (สูงสุด 16 ตัวอักษร)",
|
"security_short_id_placeholder": "สตริงฮีซ (สูงสุด 16 ตัวอักษร)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "ความปลอดภัย",
|
|
||||||
"select_encryption_method": "เลือกวิธีการเข้ารหัส",
|
"select_encryption_method": "เลือกวิธีการเข้ารหัส",
|
||||||
"server_key": "คีย์เซิร์ฟเวอร์",
|
"server_key": "คีย์เซิร์ฟเวอร์",
|
||||||
"service_name": "ชื่อบริการ",
|
"service_name": "ชื่อบริการ",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "การสมัครสมาชิก",
|
"subscription": "การสมัครสมาชิก",
|
||||||
"traffic": "การจราจร",
|
"traffic": "การจราจร",
|
||||||
"traffic_ratio": "ตัวคูณ",
|
"traffic_ratio": "ตัวคูณ",
|
||||||
"transport_title": "การขนส่ง",
|
"transport": "วิธีการขนส่ง",
|
||||||
"udp_relay_mode": "โหมดการส่งต่อ UDP",
|
"udp_relay_mode": "โหมดการส่งต่อ UDP",
|
||||||
"unitSecondsShort": "ว",
|
"unitSecondsShort": "ว",
|
||||||
"unlimited": "ไม่จำกัด",
|
"unlimited": "ไม่จำกัด",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Adres",
|
"address": "Adres",
|
||||||
"address_placeholder": "Sunucu adresi",
|
"address_placeholder": "Sunucu adresi",
|
||||||
|
"basic": "Temel Yapılandırma",
|
||||||
"cancel": "İptal",
|
"cancel": "İptal",
|
||||||
"city": "Şehir",
|
"city": "Şehir",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Sil",
|
"delete": "Sil",
|
||||||
"deleted": "Başarıyla silindi",
|
"deleted": "Başarıyla silindi",
|
||||||
"disable_sni": "SNI'yi devre dışı bırak",
|
"disable_sni": "SNI'yi devre dışı bırak",
|
||||||
|
"disabled": "Devre Dışı",
|
||||||
"disk": "Disk",
|
"disk": "Disk",
|
||||||
"drawerCreateTitle": "Sunucu Oluştur",
|
"drawerCreateTitle": "Sunucu Oluştur",
|
||||||
"drawerEditTitle": "Sunucuyu Düzenle",
|
"drawerEditTitle": "Sunucuyu Düzenle",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Çevrimdışı",
|
"offline": "Çevrimdışı",
|
||||||
"online": "Çevrimiçi",
|
"online": "Çevrimiçi",
|
||||||
"onlineUsers": "Çevrimiçi kullanıcılar",
|
"onlineUsers": "Çevrimiçi kullanıcılar",
|
||||||
|
"padding_scheme": "Dolgu Şeması",
|
||||||
|
"padding_scheme_placeholder": "Her satırda bir dolgu kuralı, format: stop=8, 0=30-30",
|
||||||
"pageTitle": "Sunucular",
|
"pageTitle": "Sunucular",
|
||||||
"path": "Yol",
|
"path": "Yol",
|
||||||
"please_select": "Lütfen seçin",
|
"please_select": "Lütfen seçin",
|
||||||
|
"plugin": "Eklenti Yapılandırması",
|
||||||
|
"plugin_opts": "Eklenti Seçenekleri",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
|
"protocol_configurations": "Protokol Yapılandırmaları",
|
||||||
|
"protocol_configurations_desc": "Gerekli protokol türlerini etkinleştir ve yapılandır",
|
||||||
|
"protocol_disabled_hint": "Bu protokol devre dışı, yapılandırmak için anahtarı etkinleştir",
|
||||||
"protocols": "Protokoller",
|
"protocols": "Protokoller",
|
||||||
|
"reality": "Gerçeklik Yapılandırması",
|
||||||
"reduce_rtt": "RTT'yi azalt",
|
"reduce_rtt": "RTT'yi azalt",
|
||||||
|
"security": "Güvenlik Yapılandırması",
|
||||||
"security_allow_insecure": "Güvensiz bağlantılara izin ver",
|
"security_allow_insecure": "Güvensiz bağlantılara izin ver",
|
||||||
"security_fingerprint": "Parmak izi",
|
"security_fingerprint": "Parmak izi",
|
||||||
"security_private_key": "Gerçek özel anahtar",
|
"security_private_key": "Gerçek özel anahtar",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Gerçek kısa ID",
|
"security_short_id": "Gerçek kısa ID",
|
||||||
"security_short_id_placeholder": "Hex dizesi (en fazla 16 karakter)",
|
"security_short_id_placeholder": "Hex dizesi (en fazla 16 karakter)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Güvenlik",
|
|
||||||
"select_encryption_method": "Şifreleme yöntemini seçin",
|
"select_encryption_method": "Şifreleme yöntemini seçin",
|
||||||
"server_key": "Sunucu anahtarı",
|
"server_key": "Sunucu anahtarı",
|
||||||
"service_name": "Hizmet adı",
|
"service_name": "Hizmet adı",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Abonelik",
|
"subscription": "Abonelik",
|
||||||
"traffic": "Trafik",
|
"traffic": "Trafik",
|
||||||
"traffic_ratio": "Çarpan",
|
"traffic_ratio": "Çarpan",
|
||||||
"transport_title": "Taşıma",
|
"transport": "Taşıma Yöntemi",
|
||||||
"udp_relay_mode": "UDP iletim modu",
|
"udp_relay_mode": "UDP iletim modu",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Sınırsız",
|
"unlimited": "Sınırsız",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Адреса",
|
"address": "Адреса",
|
||||||
"address_placeholder": "Адреса сервера",
|
"address_placeholder": "Адреса сервера",
|
||||||
|
"basic": "Базова конфігурація",
|
||||||
"cancel": "Скасувати",
|
"cancel": "Скасувати",
|
||||||
"city": "Місто",
|
"city": "Місто",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Видалити",
|
"delete": "Видалити",
|
||||||
"deleted": "Успішно видалено",
|
"deleted": "Успішно видалено",
|
||||||
"disable_sni": "Вимкнути SNI",
|
"disable_sni": "Вимкнути SNI",
|
||||||
|
"disabled": "Вимкнено",
|
||||||
"disk": "Диск",
|
"disk": "Диск",
|
||||||
"drawerCreateTitle": "Створити сервер",
|
"drawerCreateTitle": "Створити сервер",
|
||||||
"drawerEditTitle": "Редагувати сервер",
|
"drawerEditTitle": "Редагувати сервер",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Офлайн",
|
"offline": "Офлайн",
|
||||||
"online": "Онлайн",
|
"online": "Онлайн",
|
||||||
"onlineUsers": "Онлайн користувачі",
|
"onlineUsers": "Онлайн користувачі",
|
||||||
|
"padding_scheme": "Схема заповнення",
|
||||||
|
"padding_scheme_placeholder": "Одне правило заповнення на рядок, формат: stop=8, 0=30-30",
|
||||||
"pageTitle": "Сервери",
|
"pageTitle": "Сервери",
|
||||||
"path": "Шлях",
|
"path": "Шлях",
|
||||||
"please_select": "Будь ласка, виберіть",
|
"please_select": "Будь ласка, виберіть",
|
||||||
|
"plugin": "Конфігурація плагіна",
|
||||||
|
"plugin_opts": "Опції плагіна",
|
||||||
"port": "Порт",
|
"port": "Порт",
|
||||||
|
"protocol_configurations": "Конфігурації протоколів",
|
||||||
|
"protocol_configurations_desc": "Увімкніть та налаштуйте необхідні типи протоколів",
|
||||||
|
"protocol_disabled_hint": "Цей протокол вимкнено, увімкніть перемикач для налаштування",
|
||||||
"protocols": "Протоколи",
|
"protocols": "Протоколи",
|
||||||
|
"reality": "Конфігурація реальності",
|
||||||
"reduce_rtt": "Зменшити RTT",
|
"reduce_rtt": "Зменшити RTT",
|
||||||
|
"security": "Конфігурація безпеки",
|
||||||
"security_allow_insecure": "Дозволити небезпечне",
|
"security_allow_insecure": "Дозволити небезпечне",
|
||||||
"security_fingerprint": "Відбиток",
|
"security_fingerprint": "Відбиток",
|
||||||
"security_private_key": "Приватний ключ реальності",
|
"security_private_key": "Приватний ключ реальності",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Короткий ID реальності",
|
"security_short_id": "Короткий ID реальності",
|
||||||
"security_short_id_placeholder": "Шістнадцятковий рядок (до 16 символів)",
|
"security_short_id_placeholder": "Шістнадцятковий рядок (до 16 символів)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Безпека",
|
|
||||||
"select_encryption_method": "Виберіть метод шифрування",
|
"select_encryption_method": "Виберіть метод шифрування",
|
||||||
"server_key": "Ключ сервера",
|
"server_key": "Ключ сервера",
|
||||||
"service_name": "Назва служби",
|
"service_name": "Назва служби",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Підписка",
|
"subscription": "Підписка",
|
||||||
"traffic": "Трафік",
|
"traffic": "Трафік",
|
||||||
"traffic_ratio": "Множник",
|
"traffic_ratio": "Множник",
|
||||||
"transport_title": "Транспорт",
|
"transport": "Метод транспорту",
|
||||||
"udp_relay_mode": "Режим UDP ретрансляції",
|
"udp_relay_mode": "Режим UDP ретрансляції",
|
||||||
"unitSecondsShort": "С",
|
"unitSecondsShort": "С",
|
||||||
"unlimited": "Без обмежень",
|
"unlimited": "Без обмежень",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "Địa chỉ",
|
"address": "Địa chỉ",
|
||||||
"address_placeholder": "Địa chỉ máy chủ",
|
"address_placeholder": "Địa chỉ máy chủ",
|
||||||
|
"basic": "Cấu Hình Cơ Bản",
|
||||||
"cancel": "Hủy",
|
"cancel": "Hủy",
|
||||||
"city": "Thành phố",
|
"city": "Thành phố",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "Xóa",
|
"delete": "Xóa",
|
||||||
"deleted": "Xóa thành công",
|
"deleted": "Xóa thành công",
|
||||||
"disable_sni": "Vô hiệu hóa SNI",
|
"disable_sni": "Vô hiệu hóa SNI",
|
||||||
|
"disabled": "Đã Vô Hiệu Hóa",
|
||||||
"disk": "Ổ đĩa",
|
"disk": "Ổ đĩa",
|
||||||
"drawerCreateTitle": "Tạo Máy chủ",
|
"drawerCreateTitle": "Tạo Máy chủ",
|
||||||
"drawerEditTitle": "Chỉnh sửa Máy chủ",
|
"drawerEditTitle": "Chỉnh sửa Máy chủ",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "Ngoại tuyến",
|
"offline": "Ngoại tuyến",
|
||||||
"online": "Trực tuyến",
|
"online": "Trực tuyến",
|
||||||
"onlineUsers": "Người dùng trực tuyến",
|
"onlineUsers": "Người dùng trực tuyến",
|
||||||
|
"padding_scheme": "Sơ Đồ Đệm",
|
||||||
|
"padding_scheme_placeholder": "Một quy tắc đệm mỗi dòng, định dạng: stop=8, 0=30-30",
|
||||||
"pageTitle": "Máy chủ",
|
"pageTitle": "Máy chủ",
|
||||||
"path": "Đường dẫn",
|
"path": "Đường dẫn",
|
||||||
"please_select": "Vui lòng chọn",
|
"please_select": "Vui lòng chọn",
|
||||||
|
"plugin": "Cấu Hình Plugin",
|
||||||
|
"plugin_opts": "Tùy Chọn Plugin",
|
||||||
"port": "Cổng",
|
"port": "Cổng",
|
||||||
|
"protocol_configurations": "Cấu Hình Giao Thức",
|
||||||
|
"protocol_configurations_desc": "Kích hoạt và cấu hình các loại giao thức cần thiết",
|
||||||
|
"protocol_disabled_hint": "Giao thức này đã bị vô hiệu hóa, hãy bật công tắc để cấu hình",
|
||||||
"protocols": "Giao thức",
|
"protocols": "Giao thức",
|
||||||
|
"reality": "Cấu Hình Thực Tế",
|
||||||
"reduce_rtt": "Giảm RTT",
|
"reduce_rtt": "Giảm RTT",
|
||||||
|
"security": "Cấu Hình Bảo Mật",
|
||||||
"security_allow_insecure": "Cho phép không an toàn",
|
"security_allow_insecure": "Cho phép không an toàn",
|
||||||
"security_fingerprint": "Dấu vân tay",
|
"security_fingerprint": "Dấu vân tay",
|
||||||
"security_private_key": "Khóa riêng thực tế",
|
"security_private_key": "Khóa riêng thực tế",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "ID ngắn thực tế",
|
"security_short_id": "ID ngắn thực tế",
|
||||||
"security_short_id_placeholder": "Chuỗi hex (tối đa 16 ký tự)",
|
"security_short_id_placeholder": "Chuỗi hex (tối đa 16 ký tự)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "Bảo mật",
|
|
||||||
"select_encryption_method": "Chọn phương pháp mã hóa",
|
"select_encryption_method": "Chọn phương pháp mã hóa",
|
||||||
"server_key": "Khóa máy chủ",
|
"server_key": "Khóa máy chủ",
|
||||||
"service_name": "Tên dịch vụ",
|
"service_name": "Tên dịch vụ",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "Đăng ký",
|
"subscription": "Đăng ký",
|
||||||
"traffic": "Lưu lượng",
|
"traffic": "Lưu lượng",
|
||||||
"traffic_ratio": "Hệ số",
|
"traffic_ratio": "Hệ số",
|
||||||
"transport_title": "Vận chuyển",
|
"transport": "Phương Thức Vận Chuyển",
|
||||||
"udp_relay_mode": "Chế độ chuyển tiếp UDP",
|
"udp_relay_mode": "Chế độ chuyển tiếp UDP",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "Không giới hạn",
|
"unlimited": "Không giới hạn",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "地址",
|
"address": "地址",
|
||||||
"address_placeholder": "服务器地址",
|
"address_placeholder": "服务器地址",
|
||||||
|
"basic": "基础配置",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"city": "城市",
|
"city": "城市",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"deleted": "删除成功",
|
"deleted": "删除成功",
|
||||||
"disable_sni": "禁用 SNI",
|
"disable_sni": "禁用 SNI",
|
||||||
|
"disabled": "禁用",
|
||||||
"disk": "磁盘",
|
"disk": "磁盘",
|
||||||
"drawerCreateTitle": "新建服务器",
|
"drawerCreateTitle": "新建服务器",
|
||||||
"drawerEditTitle": "编辑服务器",
|
"drawerEditTitle": "编辑服务器",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "离线",
|
"offline": "离线",
|
||||||
"online": "在线",
|
"online": "在线",
|
||||||
"onlineUsers": "在线人数",
|
"onlineUsers": "在线人数",
|
||||||
|
"padding_scheme": "填充方案",
|
||||||
|
"padding_scheme_placeholder": "每行一个填充规则,格式如: stop=8, 0=30-30",
|
||||||
"pageTitle": "服务器",
|
"pageTitle": "服务器",
|
||||||
"path": "路径",
|
"path": "路径",
|
||||||
"please_select": "请选择",
|
"please_select": "请选择",
|
||||||
|
"plugin": "插件配置",
|
||||||
|
"plugin_opts": "插件选项",
|
||||||
"port": "端口",
|
"port": "端口",
|
||||||
|
"protocol_configurations": "协议配置",
|
||||||
|
"protocol_configurations_desc": "启用并配置所需的协议类型",
|
||||||
|
"protocol_disabled_hint": "此协议已禁用,启用开关以进行配置",
|
||||||
"protocols": "协议",
|
"protocols": "协议",
|
||||||
|
"reality": "Reality 配置",
|
||||||
"reduce_rtt": "降低 RTT",
|
"reduce_rtt": "降低 RTT",
|
||||||
|
"security": "安全配置",
|
||||||
"security_allow_insecure": "允许不安全",
|
"security_allow_insecure": "允许不安全",
|
||||||
"security_fingerprint": "指纹",
|
"security_fingerprint": "指纹",
|
||||||
"security_private_key": "Reality 私钥",
|
"security_private_key": "Reality 私钥",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "Reality Short ID",
|
"security_short_id": "Reality Short ID",
|
||||||
"security_short_id_placeholder": "16 位内十六进制",
|
"security_short_id_placeholder": "16 位内十六进制",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "安全",
|
|
||||||
"select_encryption_method": "选择加密方式",
|
"select_encryption_method": "选择加密方式",
|
||||||
"server_key": "服务器密钥",
|
"server_key": "服务器密钥",
|
||||||
"service_name": "服务名",
|
"service_name": "服务名",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "订阅",
|
"subscription": "订阅",
|
||||||
"traffic": "流量",
|
"traffic": "流量",
|
||||||
"traffic_ratio": "倍率",
|
"traffic_ratio": "倍率",
|
||||||
"transport_title": "传输方式",
|
"transport": "传输方式",
|
||||||
"udp_relay_mode": "UDP 转发模式",
|
"udp_relay_mode": "UDP 转发模式",
|
||||||
"unitSecondsShort": "S",
|
"unitSecondsShort": "S",
|
||||||
"unlimited": "不限",
|
"unlimited": "不限",
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"address": "地址",
|
"address": "地址",
|
||||||
"address_placeholder": "伺服器地址",
|
"address_placeholder": "伺服器地址",
|
||||||
|
"basic": "基本配置",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"city": "城市",
|
"city": "城市",
|
||||||
"config": {
|
"config": {
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"deleted": "刪除成功",
|
"deleted": "刪除成功",
|
||||||
"disable_sni": "禁用 SNI",
|
"disable_sni": "禁用 SNI",
|
||||||
|
"disabled": "已禁用",
|
||||||
"disk": "磁碟",
|
"disk": "磁碟",
|
||||||
"drawerCreateTitle": "創建伺服器",
|
"drawerCreateTitle": "創建伺服器",
|
||||||
"drawerEditTitle": "編輯伺服器",
|
"drawerEditTitle": "編輯伺服器",
|
||||||
@ -68,12 +70,21 @@
|
|||||||
"offline": "離線",
|
"offline": "離線",
|
||||||
"online": "在線",
|
"online": "在線",
|
||||||
"onlineUsers": "在線用戶",
|
"onlineUsers": "在線用戶",
|
||||||
|
"padding_scheme": "填充方案",
|
||||||
|
"padding_scheme_placeholder": "每行一條填充規則,格式:stop=8, 0=30-30",
|
||||||
"pageTitle": "伺服器",
|
"pageTitle": "伺服器",
|
||||||
"path": "路徑",
|
"path": "路徑",
|
||||||
"please_select": "請選擇",
|
"please_select": "請選擇",
|
||||||
|
"plugin": "插件配置",
|
||||||
|
"plugin_opts": "插件選項",
|
||||||
"port": "端口",
|
"port": "端口",
|
||||||
|
"protocol_configurations": "協議配置",
|
||||||
|
"protocol_configurations_desc": "啟用並配置所需的協議類型",
|
||||||
|
"protocol_disabled_hint": "此協議已禁用,請啟用開關以進行配置",
|
||||||
"protocols": "協議",
|
"protocols": "協議",
|
||||||
|
"reality": "現實配置",
|
||||||
"reduce_rtt": "減少 RTT",
|
"reduce_rtt": "減少 RTT",
|
||||||
|
"security": "安全配置",
|
||||||
"security_allow_insecure": "允許不安全",
|
"security_allow_insecure": "允許不安全",
|
||||||
"security_fingerprint": "指紋",
|
"security_fingerprint": "指紋",
|
||||||
"security_private_key": "實際私鑰",
|
"security_private_key": "實際私鑰",
|
||||||
@ -86,7 +97,6 @@
|
|||||||
"security_short_id": "實際短 ID",
|
"security_short_id": "實際短 ID",
|
||||||
"security_short_id_placeholder": "十六進制字符串(最多 16 個字符)",
|
"security_short_id_placeholder": "十六進制字符串(最多 16 個字符)",
|
||||||
"security_sni": "SNI",
|
"security_sni": "SNI",
|
||||||
"security_title": "安全性",
|
|
||||||
"select_encryption_method": "選擇加密方法",
|
"select_encryption_method": "選擇加密方法",
|
||||||
"server_key": "伺服器密鑰",
|
"server_key": "伺服器密鑰",
|
||||||
"service_name": "服務名稱",
|
"service_name": "服務名稱",
|
||||||
@ -95,7 +105,7 @@
|
|||||||
"subscription": "訂閱",
|
"subscription": "訂閱",
|
||||||
"traffic": "流量",
|
"traffic": "流量",
|
||||||
"traffic_ratio": "乘數",
|
"traffic_ratio": "乘數",
|
||||||
"transport_title": "傳輸",
|
"transport": "傳輸方式",
|
||||||
"udp_relay_mode": "UDP 中繼模式",
|
"udp_relay_mode": "UDP 中繼模式",
|
||||||
"unitSecondsShort": "秒",
|
"unitSecondsShort": "秒",
|
||||||
"unlimited": "無限制",
|
"unlimited": "無限制",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user