mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 21:42:24 +00:00
Compare commits
3 commits
227e841ce4
...
b2fc653f74
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b2fc653f74 | ||
![]() |
d30cdbf49a | ||
![]() |
036df9f7b3 |
20 changed files with 140 additions and 73 deletions
|
@ -107,11 +107,16 @@ func (s *Server) initRouter() (*gin.Engine, error) {
|
|||
SubJsonRules = ""
|
||||
}
|
||||
|
||||
SubTitle, err := s.settingService.GetSubTitle()
|
||||
if err != nil {
|
||||
SubTitle = ""
|
||||
}
|
||||
|
||||
g := engine.Group("/")
|
||||
|
||||
s.sub = NewSUBController(
|
||||
g, LinksPath, JsonPath, Encrypt, ShowInfo, RemarkModel, SubUpdates,
|
||||
SubJsonFragment, SubJsonNoises, SubJsonMux, SubJsonRules)
|
||||
SubJsonFragment, SubJsonNoises, SubJsonMux, SubJsonRules, SubTitle)
|
||||
|
||||
return engine, nil
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
)
|
||||
|
||||
type SUBController struct {
|
||||
subTitle string
|
||||
subPath string
|
||||
subJsonPath string
|
||||
subEncrypt bool
|
||||
|
@ -30,9 +31,11 @@ func NewSUBController(
|
|||
jsonNoise string,
|
||||
jsonMux string,
|
||||
jsonRules string,
|
||||
subTitle string,
|
||||
) *SUBController {
|
||||
sub := NewSubService(showInfo, rModel)
|
||||
a := &SUBController{
|
||||
subTitle: subTitle,
|
||||
subPath: subPath,
|
||||
subJsonPath: jsonPath,
|
||||
subEncrypt: encrypt,
|
||||
|
@ -82,7 +85,7 @@ func (a *SUBController) subs(c *gin.Context) {
|
|||
// Add headers
|
||||
c.Writer.Header().Set("Subscription-Userinfo", header)
|
||||
c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval)
|
||||
c.Writer.Header().Set("Profile-Title", subId)
|
||||
c.Writer.Header().Set("Profile-Title", a.subTitle)
|
||||
|
||||
if a.subEncrypt {
|
||||
c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
|
||||
|
@ -116,7 +119,7 @@ func (a *SUBController) subJsons(c *gin.Context) {
|
|||
// Add headers
|
||||
c.Writer.Header().Set("Subscription-Userinfo", header)
|
||||
c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval)
|
||||
c.Writer.Header().Set("Profile-Title", subId)
|
||||
c.Writer.Header().Set("Profile-Title", a.subTitle)
|
||||
|
||||
c.String(200, jsonSub)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class AllSetting {
|
|||
this.xrayTemplateConfig = "";
|
||||
this.secretEnable = false;
|
||||
this.subEnable = false;
|
||||
this.subTitle = "";
|
||||
this.subListen = "";
|
||||
this.subPort = 2096;
|
||||
this.subPath = "/sub/";
|
||||
|
|
|
@ -40,6 +40,7 @@ type AllSetting struct {
|
|||
TimeLocation string `json:"timeLocation" form:"timeLocation"`
|
||||
SecretEnable bool `json:"secretEnable" form:"secretEnable"`
|
||||
SubEnable bool `json:"subEnable" form:"subEnable"`
|
||||
SubTitle string `json:"subTitle" form:"subTitle"`
|
||||
SubListen string `json:"subListen" form:"subListen"`
|
||||
SubPort int `json:"subPort" form:"subPort"`
|
||||
SubPath string `json:"subPath" form:"subPath"`
|
||||
|
|
|
@ -662,6 +662,7 @@
|
|||
refreshInterval: Number(localStorage.getItem("refreshInterval")) || 5000,
|
||||
subSettings: {
|
||||
enable : false,
|
||||
subTitle : '',
|
||||
subURI : '',
|
||||
subJsonURI : '',
|
||||
},
|
||||
|
@ -711,6 +712,7 @@
|
|||
this.tgBotEnable = tgBotEnable;
|
||||
this.subSettings = {
|
||||
enable : subEnable,
|
||||
subTitle : subTitle,
|
||||
subURI: subURI,
|
||||
subJsonURI: subJsonURI
|
||||
};
|
||||
|
|
|
@ -25,13 +25,16 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
.dark .ant-backup-list-item svg,
|
||||
.dark .ant-card-actions>li>span>.anticon, .ant-card-actions>li>span a:not(.ant-btn),
|
||||
.dark .ant-card-actions>li>*,
|
||||
.dark .ant-badge-status-text,
|
||||
.dark .ant-statistic-title,
|
||||
.dark .ant-statistic-content,
|
||||
.dark .ant-card-extra {
|
||||
color: var(--dark-color-text-primary) !important;
|
||||
}
|
||||
.dark .ant-card-actions>li>*:hover {
|
||||
color: var(--color-primary-100) !important;
|
||||
}
|
||||
.dark .ant-backup-list,
|
||||
.dark .ant-xray-version-list,
|
||||
.dark .ant-card-actions,
|
||||
|
@ -41,6 +44,12 @@
|
|||
.ant-card-actions {
|
||||
background: transparent !important;
|
||||
}
|
||||
.ant-statistic-content-prefix {
|
||||
font-size: 20px;
|
||||
}
|
||||
.ant-statistic-content-value {
|
||||
font-size: 18px;
|
||||
}
|
||||
.ip-hidden {
|
||||
filter: blur(10px);
|
||||
}
|
||||
|
@ -120,6 +129,58 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<a-row>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.xrayStatus" }}' hoverable>
|
||||
<template #extra>
|
||||
<template v-if="status.xray.state != State.Error">
|
||||
<a-badge :text="status.xray.state" :color="status.xray.color" style="text-transform: capitalize;"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-popover :overlay-class-name="themeSwitcher.currentTheme">
|
||||
<span slot="title" style="font-size: 12pt">An error occurred while running Xray
|
||||
<a-tag color="purple" style="cursor: pointer; float: right;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
</span>
|
||||
<template slot="content">
|
||||
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
||||
</template>
|
||||
<a-badge :text="status.xray.state" :color="status.xray.color" style="text-transform: capitalize;"/>
|
||||
</a-popover>
|
||||
</template>
|
||||
</template>
|
||||
<template #actions>
|
||||
<a-space direction="horizontal" @click="stopXrayService" style="justify-content: center;">
|
||||
<a-icon type="poweroff"></a-icon>
|
||||
<span>{{ i18n "pages.index.stopXray" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="restartXrayService" style="justify-content: center;">
|
||||
<a-icon type="reload"></a-icon>
|
||||
<span>{{ i18n "pages.index.restartXray" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openSelectV2rayVersion" style="justify-content: center;">
|
||||
<a-icon type="tool"></a-icon>
|
||||
<span>v[[ status.xray.version ]]</span>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "menu.link" }}' hoverable>
|
||||
<template #actions>
|
||||
<a-space direction="horizontal" @click="openLogs()" style="justify-content: center;">
|
||||
<a-icon type="bars"></a-icon>
|
||||
<span>{{ i18n "pages.index.logs" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openConfig" style="justify-content: center;">
|
||||
<a-icon type="control"></a-icon>
|
||||
<span>{{ i18n "pages.index.config" }}</span>
|
||||
</a-space>
|
||||
<a-space direction="horizontal" @click="openBackup" style="justify-content: center;">
|
||||
<a-icon type="cloud-server"></a-icon>
|
||||
<span>{{ i18n "pages.index.backup" }}</span>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='3X-UI' hoverable>
|
||||
<a rel="noopener" href="https://github.com/MHSanaei/3x-ui/releases" target="_blank"><a-tag color="green">v{{ .cur_ver }}</a-tag></a>
|
||||
|
@ -132,54 +193,6 @@
|
|||
<a-tag color="green">OS: [[ TimeFormatter.formatSecond(status.uptime) ]]</a-tag>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.xrayStatus" }}' hoverable>
|
||||
<template #extra>
|
||||
<a-badge :text="status.xray.state" :color="status.xray.color" style="text-transform: capitalize;"/>
|
||||
<a-popover v-if="status.xray.state === State.Error" :overlay-class-name="themeSwitcher.currentTheme">
|
||||
<span slot="title" style="font-size: 12pt">An error occurred while running Xray
|
||||
<a-tag color="purple" style="cursor: pointer; float: right;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
|
||||
</span>
|
||||
<template slot="content">
|
||||
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
||||
</template>
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-popover>
|
||||
</template>
|
||||
<template #actions class="ant-card-actions">
|
||||
<a-tooltip>
|
||||
<template #title>{{ i18n "pages.index.stopXray" }}</template>
|
||||
<a-icon type="poweroff" @click="stopXrayService"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>{{ i18n "pages.index.restartXray" }}</template>
|
||||
<a-icon type="reload" @click="restartXrayService"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>v[[ status.xray.version ]]</template>
|
||||
<a-icon type="tool" @click="openSelectV2rayVersion"/>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "menu.link" }}' hoverable>
|
||||
<template #actions class="ant-card-actions">
|
||||
<a-tooltip>
|
||||
<template #title>{{ i18n "pages.index.logs" }}</template>
|
||||
<a-icon type="bars" @click="openLogs()"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>{{ i18n "pages.index.config" }}</template>
|
||||
<a-icon type="control" @click="openConfig"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>{{ i18n "pages.index.backup" }}</template>
|
||||
<a-icon type="cloud-server" @click="openBackup"/>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.systemLoad" }}' hoverable>
|
||||
<a-tag color="green">
|
||||
|
@ -209,14 +222,14 @@
|
|||
</a-tooltip>
|
||||
</template>
|
||||
<a-row :class="showIp ? 'ip-visible' : 'ip-hidden'">
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="IPv4" :value="status.publicIP.ipv4">
|
||||
<template #prefix>
|
||||
<a-icon type="global" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="IPv6" :value="status.publicIP.ipv6">
|
||||
<template #prefix>
|
||||
<a-icon type="global" />
|
||||
|
@ -229,14 +242,14 @@
|
|||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.connectionCount" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="TCP" :value="status.tcpCount">
|
||||
<template #prefix>
|
||||
<a-icon type="swap" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title="UDP" :value="status.udpCount">
|
||||
<template #prefix>
|
||||
<a-icon type="swap" />
|
||||
|
@ -249,7 +262,7 @@
|
|||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.overallSpeed" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.upload" }}' :value="SizeFormatter.sizeFormat(status.netIO.up)">
|
||||
<template #prefix>
|
||||
<a-icon type="arrow-up" />
|
||||
|
@ -259,7 +272,7 @@
|
|||
</template>
|
||||
</a-statistic>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.download" }}' :value="SizeFormatter.sizeFormat(status.netIO.down)">
|
||||
<template #prefix>
|
||||
<a-icon type="arrow-down" />
|
||||
|
@ -275,14 +288,14 @@
|
|||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='{{ i18n "pages.index.totalData" }}' hoverable>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.sent" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.sent)">
|
||||
<template #prefix>
|
||||
<a-icon type="cloud-upload" />
|
||||
</template>
|
||||
</a-statistic>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-col :lg="12" :sm="24" :style="{ marginTop: isMobile ? '10px' : 0 }">
|
||||
<a-statistic title='{{ i18n "pages.index.received" }}' :value="SizeFormatter.sizeFormat(status.netTraffic.recv)">
|
||||
<template #prefix>
|
||||
<a-icon type="cloud-download" />
|
||||
|
@ -567,6 +580,7 @@
|
|||
loadingTip: '{{ i18n "loading"}}',
|
||||
showAlert: false,
|
||||
showIp: false,
|
||||
isMobile: window.innerWidth <= 768
|
||||
},
|
||||
methods: {
|
||||
loading(spinning, tip = '{{ i18n "loading"}}') {
|
||||
|
|
|
@ -409,6 +409,13 @@
|
|||
<a-switch v-model="allSetting.subEnable"></a-switch>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
<a-setting-list-item paddings="small">
|
||||
<template #title>{{ i18n "pages.settings.subTitle"}}</template>
|
||||
<template #description>{{ i18n "pages.settings.subTitleDesc"}}</template>
|
||||
<template #control>
|
||||
<a-input type="text" v-model="allSetting.subTitle"></a-input>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
<a-setting-list-item paddings="small">
|
||||
<template #title>{{ i18n "pages.settings.subListen"}}</template>
|
||||
<template #description>{{ i18n "pages.settings.subListenDesc"}}</template>
|
||||
|
|
|
@ -50,6 +50,7 @@ var defaultValueMap = map[string]string{
|
|||
"tgLang": "en-US",
|
||||
"secretEnable": "false",
|
||||
"subEnable": "false",
|
||||
"subTitle": "",
|
||||
"subListen": "",
|
||||
"subPort": "2096",
|
||||
"subPath": "/sub/",
|
||||
|
@ -418,6 +419,10 @@ func (s *SettingService) GetSubEnable() (bool, error) {
|
|||
return s.getBool("subEnable")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetSubTitle() (string, error) {
|
||||
return s.getString("subTitle")
|
||||
}
|
||||
|
||||
func (s *SettingService) GetSubListen() (string, error) {
|
||||
return s.getString("subListen")
|
||||
}
|
||||
|
@ -562,6 +567,7 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
|
|||
"defaultKey": func() (any, error) { return s.GetKeyFile() },
|
||||
"tgBotEnable": func() (any, error) { return s.GetTgbotEnabled() },
|
||||
"subEnable": func() (any, error) { return s.GetSubEnable() },
|
||||
"subTitle": func() (any, error) { return s.GetSubTitle() },
|
||||
"subURI": func() (any, error) { return s.GetSubURI() },
|
||||
"subJsonURI": func() (any, error) { return s.GetSubJsonURI() },
|
||||
"remarkModel": func() (any, error) { return s.GetRemarkModel() },
|
||||
|
@ -581,6 +587,7 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
|
|||
|
||||
if result["subEnable"].(bool) && (result["subURI"].(string) == "" || result["subJsonURI"].(string) == "") {
|
||||
subURI := ""
|
||||
subTitle, _ := s.GetSubTitle()
|
||||
subPort, _ := s.GetSubPort()
|
||||
subPath, _ := s.GetSubPath()
|
||||
subJsonPath, _ := s.GetSubJsonPath()
|
||||
|
@ -607,6 +614,9 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
|
|||
if result["subURI"].(string) == "" {
|
||||
result["subURI"] = subURI + subPath
|
||||
}
|
||||
if result["subTitle"].(string) == "" {
|
||||
result["subTitle"] = subTitle
|
||||
}
|
||||
if result["subJsonURI"].(string) == "" {
|
||||
result["subJsonURI"] = subURI + subJsonPath
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
"dontRefresh" = "Installation is in progress, please do not refresh this page"
|
||||
"logs" = "Logs"
|
||||
"config" = "Config"
|
||||
"backup" = "Backup & Restore"
|
||||
"backup" = "Backup"
|
||||
"backupTitle" = "Database Backup & Restore"
|
||||
"exportDatabase" = "Back Up"
|
||||
"exportDatabaseDesc" = "Click to download a .db file containing a backup of your current database to your device."
|
||||
|
@ -294,6 +294,8 @@
|
|||
"subSettings" = "Subscription"
|
||||
"subEnable" = "Enable Subscription Service"
|
||||
"subEnableDesc" = "Enables the subscription service."
|
||||
"subTitle" = "Subscription Title"
|
||||
"subTitleDesc" = "Title shown in VPN client"
|
||||
"subListen" = "Listen IP"
|
||||
"subListenDesc" = "The IP address for the subscription service. (leave blank to listen on all IPs)"
|
||||
"subPort" = "Listen Port"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "La instalación está en progreso, por favor no actualices esta página."
|
||||
"logs" = "Registros"
|
||||
"config" = "Configuración"
|
||||
"backup" = "Copia de Seguridad y Restauración"
|
||||
"backup" = "Сopia de Seguridad"
|
||||
"backupTitle" = "Copia de Seguridad y Restauración de la Base de Datos"
|
||||
"exportDatabase" = "Copia de seguridad"
|
||||
"exportDatabaseDesc" = "Haz clic para descargar un archivo .db que contiene una copia de seguridad de tu base de datos actual en tu dispositivo."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Suscripción"
|
||||
"subEnable" = "Habilitar Servicio"
|
||||
"subEnableDesc" = "Función de suscripción con configuración separada."
|
||||
"subTitle" = "Título de la Suscripción"
|
||||
"subTitleDesc" = "Título mostrado en el cliente de VPN"
|
||||
"subListen" = "Listening IP"
|
||||
"subListenDesc" = "Dejar en blanco por defecto para monitorear todas las IPs."
|
||||
"subPort" = "Puerto de Suscripción"
|
||||
|
|
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "سابسکریپشن"
|
||||
"subEnable" = "فعالسازی سرویس سابسکریپشن"
|
||||
"subEnableDesc" = "سرویس سابسکریپشن را فعالمیکند"
|
||||
"subTitle" = "عنوان اشتراک"
|
||||
"subTitleDesc" = "عنوان نمایش داده شده در کلاینت VPN"
|
||||
"subListen" = "آدرس آیپی"
|
||||
"subListenDesc" = "آدرس آیپی برای سرویس سابسکریپشن. برای گوش دادن بهتمام آیپیها خالیبگذارید"
|
||||
"subPort" = "پورت"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Instalasi sedang berlangsung, harap jangan menyegarkan halaman ini"
|
||||
"logs" = "Log"
|
||||
"config" = "Konfigurasi"
|
||||
"backup" = "Cadangan & Pulihkan"
|
||||
"backup" = "Cadangan"
|
||||
"backupTitle" = "Cadangan & Pulihkan Database"
|
||||
"exportDatabase" = "Cadangkan"
|
||||
"exportDatabaseDesc" = "Klik untuk mengunduh file .db yang berisi cadangan dari database Anda saat ini ke perangkat Anda."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Langganan"
|
||||
"subEnable" = "Aktifkan Layanan Langganan"
|
||||
"subEnableDesc" = "Mengaktifkan layanan langganan."
|
||||
"subTitle" = "Judul Langganan"
|
||||
"subTitleDesc" = "Judul yang ditampilkan di klien VPN"
|
||||
"subListen" = "IP Pendengar"
|
||||
"subListenDesc" = "Alamat IP untuk layanan langganan. (biarkan kosong untuk mendengarkan semua IP)"
|
||||
"subPort" = "Port Pendengar"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "インストール中、このページをリロードしないでください"
|
||||
"logs" = "ログ"
|
||||
"config" = "設定"
|
||||
"backup" = "バックアップと復元"
|
||||
"backup" = "バックアップ"
|
||||
"backupTitle" = "データベースのバックアップと復元"
|
||||
"exportDatabase" = "バックアップ"
|
||||
"exportDatabaseDesc" = "クリックして、現在のデータベースのバックアップを含む .db ファイルをデバイスにダウンロードします。"
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "サブスクリプション設定"
|
||||
"subEnable" = "サブスクリプションサービスを有効にする"
|
||||
"subEnableDesc" = "サブスクリプションサービス機能を有効にする"
|
||||
"subTitle" = "サブスクリプションタイトル"
|
||||
"subTitleDesc" = "VPNクライアントに表示されるタイトル"
|
||||
"subListen" = "監視IP"
|
||||
"subListenDesc" = "サブスクリプションサービスが監視するIPアドレス(空白にするとすべてのIPを監視)"
|
||||
"subPort" = "監視ポート"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Instalação em andamento, por favor não atualize a página"
|
||||
"logs" = "Logs"
|
||||
"config" = "Configuração"
|
||||
"backup" = "Backup e Restauração"
|
||||
"backup" = "Backup"
|
||||
"backupTitle" = "Backup e Restauração do Banco de Dados"
|
||||
"exportDatabase" = "Backup"
|
||||
"exportDatabaseDesc" = "Clique para baixar um arquivo .db contendo um backup do seu banco de dados atual para o seu dispositivo."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Assinatura"
|
||||
"subEnable" = "Ativar Serviço de Assinatura"
|
||||
"subEnableDesc" = "Ativa o serviço de assinatura."
|
||||
"subTitle" = "Título da Assinatura"
|
||||
"subTitleDesc" = "Título exibido no cliente VPN"
|
||||
"subListen" = "IP de Escuta"
|
||||
"subListenDesc" = "O endereço IP para o serviço de assinatura. (deixe em branco para escutar em todos os IPs)"
|
||||
"subPort" = "Porta de Escuta"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Установка в процессе. Не обновляйте страницу"
|
||||
"logs" = "Логи"
|
||||
"config" = "Конфигурация"
|
||||
"backup" = "Резервное копирование и восстановление"
|
||||
"backup" = "Резервная копия"
|
||||
"backupTitle" = "База данных резервных копий"
|
||||
"exportDatabase" = "Экспорт базы данных"
|
||||
"exportDatabaseDesc" = "Нажмите, чтобы скачать файл .db, содержащий резервную копию вашей текущей базы данных на ваше устройство."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Подписка"
|
||||
"subEnable" = "Включить службу"
|
||||
"subEnableDesc" = "Функция подписки с отдельной конфигурацией"
|
||||
"subTitle" = "Заголовок подписки"
|
||||
"subTitleDesc" = "Название подписки, которое видит клиент в VPN клиенте"
|
||||
"subListen" = "Прослушивание IP"
|
||||
"subListenDesc" = "Оставьте пустым по умолчанию, чтобы отслеживать все IP-адреса"
|
||||
"subPort" = "Порт подписки"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Kurulum devam ediyor, lütfen bu sayfayı yenilemeyin"
|
||||
"logs" = "Günlükler"
|
||||
"config" = "Yapılandırma"
|
||||
"backup" = "Yedekle & Geri Yükle"
|
||||
"backup" = "Yedek"
|
||||
"backupTitle" = "Veritabanı Yedekleme & Geri Yükleme"
|
||||
"exportDatabase" = "Yedekle"
|
||||
"exportDatabaseDesc" = "Mevcut veritabanınızın yedeğini içeren bir .db dosyasını cihazınıza indirmek için tıklayın."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Abonelik"
|
||||
"subEnable" = "Abonelik Hizmetini Etkinleştir"
|
||||
"subEnableDesc" = "Abonelik hizmetini etkinleştirir."
|
||||
"subTitle" = "Abonelik Başlığı"
|
||||
"subTitleDesc" = "VPN istemcisinde gösterilen başlık"
|
||||
"subListen" = "Dinleme IP"
|
||||
"subListenDesc" = "Abonelik hizmeti için IP adresi. (tüm IP'leri dinlemek için boş bırakın)"
|
||||
"subPort" = "Dinleme Portu"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Інсталяція триває, будь ласка, не оновлюйте цю сторінку"
|
||||
"logs" = "Журнали"
|
||||
"config" = "Конфігурація"
|
||||
"backup" = "Резервне копіювання та відновлення"
|
||||
"backup" = "Резервна копія"
|
||||
"backupTitle" = "Резервне копіювання та відновлення бази даних"
|
||||
"exportDatabase" = "Резервна копія"
|
||||
"exportDatabaseDesc" = "Натисніть, щоб завантажити файл .db, що містить резервну копію вашої поточної бази даних на ваш пристрій."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Підписка"
|
||||
"subEnable" = "Увімкнути службу підписки"
|
||||
"subEnableDesc" = "Вмикає службу підписки."
|
||||
"subTitle" = "Назва Підписки"
|
||||
"subTitleDesc" = "Назва, яка відображається у VPN-клієнті"
|
||||
"subListen" = "Слухати IP"
|
||||
"subListenDesc" = "IP-адреса для служби підписки. (залиште порожнім, щоб слухати всі IP-адреси)"
|
||||
"subPort" = "Слухати порт"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "Đang tiến hành cài đặt, vui lòng không làm mới trang này."
|
||||
"logs" = "Nhật ký"
|
||||
"config" = "Cấu hình"
|
||||
"backup" = "Sao lưu & Khôi phục"
|
||||
"backup" = "Sao lưu"
|
||||
"backupTitle" = "Sao lưu & Khôi phục Cơ sở dữ liệu"
|
||||
"exportDatabase" = "Sao lưu"
|
||||
"exportDatabaseDesc" = "Nhấp để tải xuống tệp .db chứa bản sao lưu cơ sở dữ liệu hiện tại của bạn vào thiết bị."
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "Gói đăng ký"
|
||||
"subEnable" = "Bật dịch vụ"
|
||||
"subEnableDesc" = "Tính năng gói đăng ký với cấu hình riêng"
|
||||
"subTitle" = "Tiêu đề Đăng ký"
|
||||
"subTitleDesc" = "Tiêu đề hiển thị trong ứng dụng VPN"
|
||||
"subListen" = "Listening IP"
|
||||
"subListenDesc" = "Mặc định để trống để nghe tất cả các IP"
|
||||
"subPort" = "Cổng gói đăng ký"
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"dontRefresh" = "安装中,请勿刷新此页面"
|
||||
"logs" = "日志"
|
||||
"config" = "配置"
|
||||
"backup" = "备份和恢复"
|
||||
"backup" = "备份"
|
||||
"backupTitle" = "备份和恢复数据库"
|
||||
"exportDatabase" = "备份"
|
||||
"exportDatabaseDesc" = "点击下载包含当前数据库备份的 .db 文件到您的设备。"
|
||||
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "订阅设置"
|
||||
"subEnable" = "启用订阅服务"
|
||||
"subEnableDesc" = "启用订阅服务功能"
|
||||
"subTitle" = "订阅标题"
|
||||
"subTitleDesc" = "在VPN客户端中显示的标题"
|
||||
"subListen" = "监听 IP"
|
||||
"subListenDesc" = "订阅服务监听的 IP 地址(留空表示监听所有 IP)"
|
||||
"subPort" = "监听端口"
|
||||
|
|
|
@ -296,6 +296,8 @@
|
|||
"subSettings" = "訂閱設定"
|
||||
"subEnable" = "啟用訂閱服務"
|
||||
"subEnableDesc" = "啟用訂閱服務功能"
|
||||
"subTitle" = "訂閱標題"
|
||||
"subTitleDesc" = "在VPN客戶端中顯示的標題"
|
||||
"subListen" = "監聽 IP"
|
||||
"subListenDesc" = "訂閱服務監聽的 IP 地址(留空表示監聽所有 IP)"
|
||||
"subPort" = "監聽埠"
|
||||
|
|
Loading…
Reference in a new issue