Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cd37abbaa | ||
|
|
eec4d71097 | ||
|
|
a2bdf23940 | ||
|
|
d08aaa0068 | ||
|
|
1e1f947060 | ||
|
|
62ae7aaffa | ||
|
|
c234bbe9e1 | ||
|
|
ed38102f17 | ||
|
|
69651ecfb5 | ||
|
|
78d3680ced | ||
|
|
495bfb9683 | ||
|
|
9b60b0fd45 | ||
|
|
c6881e5149 | ||
|
|
5971e3f856 | ||
|
|
647b72e4fa | ||
|
|
b9b74139bf | ||
|
|
653e26dad6 | ||
|
|
0135be8757 | ||
|
|
76598dfa1a | ||
|
|
6a2019629b | ||
|
|
8d18c8e98f | ||
|
|
82e2241bdd | ||
|
|
24a0b143ae | ||
|
|
4b894760a1 | ||
|
|
e300fbc7cb | ||
|
|
038bbfaee1 | ||
|
|
f13bfabde7 | ||
|
|
775042459d | ||
|
|
af54b34f3a |
4
.github/workflows/docker.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v5.3.0
|
uses: docker/metadata-action@v5.4.0
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/${{ github.repository }}
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
|
||||||
@@ -36,6 +36,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
platforms: linux/amd64, linux/arm64/v8
|
platforms: linux/amd64, linux/arm64/v8, linux/arm/v7
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|||||||
21
.github/workflows/release.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform: [amd64, arm64]
|
platform: [amd64, arm64, arm]
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -21,11 +21,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '1.21'
|
go-version: '1.21'
|
||||||
|
|
||||||
- name: Install dependencies for arm64
|
- name: Install dependencies for arm64 and arm
|
||||||
if: matrix.platform == 'arm64'
|
if: matrix.platform == 'arm64' || matrix.platform == 'arm'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt install gcc-aarch64-linux-gnu
|
sudo apt install gcc-aarch64-linux-gnu
|
||||||
|
if [ "${{ matrix.platform }}" == "arm" ]; then
|
||||||
|
sudo apt install gcc-arm-linux-gnueabihf
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Build x-ui
|
- name: Build x-ui
|
||||||
run: |
|
run: |
|
||||||
@@ -34,6 +37,8 @@ jobs:
|
|||||||
export GOARCH=${{ matrix.platform }}
|
export GOARCH=${{ matrix.platform }}
|
||||||
if [ "${{ matrix.platform }}" == "arm64" ]; then
|
if [ "${{ matrix.platform }}" == "arm64" ]; then
|
||||||
export CC=aarch64-linux-gnu-gcc
|
export CC=aarch64-linux-gnu-gcc
|
||||||
|
elif [ "${{ matrix.platform }}" == "arm" ]; then
|
||||||
|
export CC=arm-linux-gnueabihf-gcc
|
||||||
fi
|
fi
|
||||||
go build -o xui-release -v main.go
|
go build -o xui-release -v main.go
|
||||||
|
|
||||||
@@ -50,16 +55,22 @@ jobs:
|
|||||||
wget https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-64.zip
|
wget https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-64.zip
|
||||||
unzip Xray-linux-64.zip
|
unzip Xray-linux-64.zip
|
||||||
rm -f Xray-linux-64.zip
|
rm -f Xray-linux-64.zip
|
||||||
else
|
elif [ "${{ matrix.platform }}" == "arm64" ]; then
|
||||||
wget https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-arm64-v8a.zip
|
wget https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-arm64-v8a.zip
|
||||||
unzip Xray-linux-arm64-v8a.zip
|
unzip Xray-linux-arm64-v8a.zip
|
||||||
rm -f Xray-linux-arm64-v8a.zip
|
rm -f Xray-linux-arm64-v8a.zip
|
||||||
|
else
|
||||||
|
wget https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-arm32-v7a.zip
|
||||||
|
unzip Xray-linux-arm32-v7a.zip
|
||||||
|
rm -f Xray-linux-arm32-v7a.zip
|
||||||
fi
|
fi
|
||||||
rm -f geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat
|
rm -f geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat
|
||||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||||
wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
|
wget -O geoip_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
|
wget -O geosite_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
mv xray xray-linux-${{ matrix.platform }}
|
mv xray xray-linux-${{ matrix.platform }}
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ case $1 in
|
|||||||
ARCH="arm64-v8a"
|
ARCH="arm64-v8a"
|
||||||
FNAME="arm64"
|
FNAME="arm64"
|
||||||
;;
|
;;
|
||||||
|
armv7 | arm | arm32)
|
||||||
|
ARCH="arm32-v7a"
|
||||||
|
FNAME="arm32"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
ARCH="64"
|
ARCH="64"
|
||||||
FNAME="amd64"
|
FNAME="amd64"
|
||||||
@@ -20,10 +24,12 @@ cd build/bin
|
|||||||
|
|
||||||
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-${ARCH}.zip"
|
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.6/Xray-linux-${ARCH}.zip"
|
||||||
unzip "Xray-linux-${ARCH}.zip"
|
unzip "Xray-linux-${ARCH}.zip"
|
||||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat
|
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat
|
||||||
mv xray "xray-linux-${FNAME}"
|
mv xray "xray-linux-${FNAME}"
|
||||||
|
|
||||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||||
wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
|
wget -O geoip_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
|
wget -O geosite_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ENV CGO_ENABLED=1
|
ENV CGO_ENABLED=1
|
||||||
|
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
|
||||||
|
|
||||||
RUN apk --no-cache --update add \
|
RUN apk --no-cache --update add \
|
||||||
build-base \
|
build-base \
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
|
|
||||||
# Install custom version
|
# Install custom version
|
||||||
|
|
||||||
To install your desired version you can add the version to the end of install command. Example for ver `v2.0.0`:
|
To install your desired version you can add the version to the end of install command. Example for ver `v2.0.2`:
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.0.0
|
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.0.2
|
||||||
```
|
```
|
||||||
|
|
||||||
# SSL
|
# SSL
|
||||||
@@ -362,6 +362,8 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
|||||||
- CentOS 8+
|
- CentOS 8+
|
||||||
- Fedora 36+
|
- Fedora 36+
|
||||||
- Arch Linux
|
- Arch Linux
|
||||||
|
- Manjaro
|
||||||
|
- Armbian (for ARM devices)
|
||||||
|
|
||||||
# Pictures
|
# Pictures
|
||||||
|
|
||||||
@@ -371,6 +373,7 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
|||||||

|

|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
## Stargazers over time
|
## Stargazers over time
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.0.0
|
2.0.2
|
||||||
6
go.mod
@@ -10,13 +10,13 @@ require (
|
|||||||
github.com/mymmrac/telego v0.28.0
|
github.com/mymmrac/telego v0.28.0
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.3.0
|
github.com/nicksnyder/go-i18n/v2 v2.3.0
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0
|
github.com/pelletier/go-toml/v2 v2.1.1
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil/v3 v3.23.11
|
github.com/shirou/gopsutil/v3 v3.23.11
|
||||||
github.com/xtls/xray-core v1.8.6
|
github.com/xtls/xray-core v1.8.6
|
||||||
go.uber.org/atomic v1.11.0
|
go.uber.org/atomic v1.11.0
|
||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.14.0
|
||||||
google.golang.org/grpc v1.59.0
|
google.golang.org/grpc v1.60.1
|
||||||
gorm.io/driver/sqlite v1.5.4
|
gorm.io/driver/sqlite v1.5.4
|
||||||
gorm.io/gorm v1.25.5
|
gorm.io/gorm v1.25.5
|
||||||
)
|
)
|
||||||
@@ -83,7 +83,7 @@ require (
|
|||||||
go.uber.org/mock v0.3.0 // indirect
|
go.uber.org/mock v0.3.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
|
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
|
||||||
golang.org/x/arch v0.6.0 // indirect
|
golang.org/x/arch v0.6.0 // indirect
|
||||||
golang.org/x/crypto v0.15.0 // indirect
|
golang.org/x/crypto v0.17.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.14.0 // indirect
|
||||||
golang.org/x/net v0.18.0 // indirect
|
golang.org/x/net v0.18.0 // indirect
|
||||||
|
|||||||
12
go.sum
@@ -191,8 +191,8 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
|
|||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
@@ -319,8 +319,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||||
@@ -412,8 +412,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
|
|||||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
|||||||
19
install.sh
@@ -26,7 +26,8 @@ echo "The OS release is: $release"
|
|||||||
arch3xui() {
|
arch3xui() {
|
||||||
case "$(uname -m)" in
|
case "$(uname -m)" in
|
||||||
x86_64 | x64 | amd64) echo 'amd64' ;;
|
x86_64 | x64 | amd64) echo 'amd64' ;;
|
||||||
armv8 | arm64 | aarch64) echo 'arm64' ;;
|
armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;;
|
||||||
|
armv7* | armv7 | arm | arm32 ) echo 'arm32' ;;
|
||||||
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
|
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -54,7 +55,11 @@ elif [[ "${release}" == "debian" ]]; then
|
|||||||
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
||||||
fi
|
fi
|
||||||
elif [[ "${release}" == "arch" ]]; then
|
elif [[ "${release}" == "arch" ]]; then
|
||||||
echo "OS is ArchLinux"
|
echo "Your OS is ArchLinux"
|
||||||
|
elif [[ "${release}" == "manjaro" ]]; then
|
||||||
|
echo "Your OS is Manjaro"
|
||||||
|
elif [[ "${release}" == "armbian" ]]; then
|
||||||
|
echo "Your OS is Armbian"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo -e "${red}Failed to check the OS version, please contact the author!${plain}" && exit 1
|
echo -e "${red}Failed to check the OS version, please contact the author!${plain}" && exit 1
|
||||||
@@ -63,13 +68,13 @@ fi
|
|||||||
install_base() {
|
install_base() {
|
||||||
case "${release}" in
|
case "${release}" in
|
||||||
centos|fedora)
|
centos|fedora)
|
||||||
yum install -y -q wget curl tar
|
yum -y update && yum install -y -q wget curl tar
|
||||||
;;
|
;;
|
||||||
arch)
|
arch|manjaro)
|
||||||
pacman -Syu --noconfirm wget curl tar
|
pacman -Syu && pacman -Syu --noconfirm wget curl tar
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
apt install -y -q wget curl tar
|
apt-get update && apt-get upgrade -y && apt install -y -q wget curl tar
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -78,7 +83,7 @@ install_base() {
|
|||||||
# This function will be called when user installed x-ui out of security
|
# This function will be called when user installed x-ui out of security
|
||||||
config_after_install() {
|
config_after_install() {
|
||||||
echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}"
|
echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}"
|
||||||
read -p "Do you want to continue with the modification [y/n]? ": config_confirm
|
read -p "Do you want to continue with the modification [y/n]?": config_confirm
|
||||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||||
read -p "Please set up your username:" config_account
|
read -p "Please set up your username:" config_account
|
||||||
echo -e "${yellow}Your username will be:${config_account}${plain}"
|
echo -e "${yellow}Your username will be:${config_account}${plain}"
|
||||||
|
|||||||
BIN
media/1.png
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 150 KiB |
BIN
media/2.png
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 214 KiB |
BIN
media/3.png
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 138 KiB |
BIN
media/4.png
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 52 KiB |
BIN
media/5.png
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 165 KiB |
BIN
media/6.png
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 88 KiB |
BIN
media/7.png
Normal file
|
After Width: | Height: | Size: 261 KiB |
@@ -876,7 +876,7 @@ func (s *SubService) genRemark(inbound *model.Inbound, email string, extra strin
|
|||||||
orders['i'] = inbound.Remark
|
orders['i'] = inbound.Remark
|
||||||
}
|
}
|
||||||
if len(extra) > 0 {
|
if len(extra) > 0 {
|
||||||
orders['e'] = extra
|
orders['o'] = extra
|
||||||
}
|
}
|
||||||
|
|
||||||
var remark []string
|
var remark []string
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ body {
|
|||||||
html {
|
html {
|
||||||
--antd-wave-shadow-color: #008771;
|
--antd-wave-shadow-color: #008771;
|
||||||
line-height: 1.15;
|
line-height: 1.15;
|
||||||
|
text-size-adjust: 100%;
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
-ms-text-size-adjust: 100%;
|
-ms-text-size-adjust: 100%;
|
||||||
-ms-overflow-style: scrollbar;
|
-ms-overflow-style: scrollbar;
|
||||||
@@ -55,7 +56,7 @@ style attribute {
|
|||||||
}
|
}
|
||||||
.ant-table-tbody > tr > td,
|
.ant-table-tbody > tr > td,
|
||||||
.ant-table-thead > tr > th {
|
.ant-table-thead > tr > th {
|
||||||
padding: 12px 16px;
|
padding: 12px 8px;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
.ant-table-thead > tr > th {
|
.ant-table-thead > tr > th {
|
||||||
@@ -93,11 +94,6 @@ style attribute {
|
|||||||
.ant-table-body {
|
.ant-table-body {
|
||||||
overflow-x: auto !important;
|
overflow-x: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|
||||||
margin: -12px -16px -13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-card-hoverable {
|
.ant-card-hoverable {
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -137,6 +133,13 @@ tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.ant-modal-body {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.ant-form-item-label {
|
||||||
|
line-height: 1.5;
|
||||||
|
padding: 8px 0 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-layout-content {
|
.ant-layout-content {
|
||||||
@@ -414,6 +417,10 @@ tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-setting-textarea {
|
.ant-setting-textarea {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
@@ -674,7 +681,7 @@ tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|||||||
.dark .ant-table-row-expand-icon {
|
.dark .ant-table-row-expand-icon {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #fff0;
|
background-color: #fff0;
|
||||||
border-color: #9ea2a8;
|
border-color: rgb(255 255 255 / 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .ant-table-row-expand-icon:hover {
|
.dark .ant-table-row-expand-icon:hover {
|
||||||
@@ -794,16 +801,16 @@ tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|||||||
|
|
||||||
.has-warning .ant-input,
|
.has-warning .ant-input,
|
||||||
.has-warning .ant-input:hover {
|
.has-warning .ant-input:hover {
|
||||||
background-color: #fff6e6;
|
background-color: #ffeee1;
|
||||||
border-color: #ffd98c;
|
border-color: #fec093;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-warning .ant-input::placeholder {
|
.has-warning .ant-input::placeholder {
|
||||||
color: #faad14;
|
color: #f37b24;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-warning .ant-input:not([disabled]):hover {
|
.has-warning .ant-input:not([disabled]):hover {
|
||||||
border-color: #ffd98c;
|
border-color: #fec093;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .has-warning .ant-input,
|
.dark .has-warning .ant-input,
|
||||||
@@ -844,6 +851,17 @@ tr.ant-table-expanded-row td>.ant-table-wrapper {
|
|||||||
.ant-menu,
|
.ant-menu,
|
||||||
.ant-radio-button-wrapper {
|
.ant-radio-button-wrapper {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-calendar-date,
|
||||||
|
.ant-calendar-year-panel-year,
|
||||||
|
.ant-calendar-decade-panel-decade,
|
||||||
|
.ant-calendar-month-panel-month,
|
||||||
|
.ant-checkbox-inner,
|
||||||
|
.ant-checkbox-checked:after,
|
||||||
|
.ant-table-row-expand-icon {
|
||||||
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-calendar-date:hover {
|
.ant-calendar-date:hover {
|
||||||
@@ -902,7 +920,7 @@ li.ant-select-dropdown-menu-item:empty:after {
|
|||||||
.ant-select-dropdown.ant-select-dropdown--multiple
|
.ant-select-dropdown.ant-select-dropdown--multiple
|
||||||
.ant-select-dropdown-menu-item-selected:hover
|
.ant-select-dropdown-menu-item-selected:hover
|
||||||
.ant-select-selected-icon {
|
.ant-select-selected-icon {
|
||||||
color: #3c89e8;
|
color: #008771;
|
||||||
}
|
}
|
||||||
.ant-select-selection:hover,
|
.ant-select-selection:hover,
|
||||||
.ant-input-number-focused,
|
.ant-input-number-focused,
|
||||||
@@ -1044,6 +1062,11 @@ li.ant-select-dropdown-menu-item:empty:after {
|
|||||||
overflow: clip;
|
overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-modal-body,
|
||||||
|
.ant-collapse-content>.ant-collapse-content-box {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-calendar-year-panel-year:hover,
|
.ant-calendar-year-panel-year:hover,
|
||||||
.ant-calendar-decade-panel-decade:hover,
|
.ant-calendar-decade-panel-decade:hover,
|
||||||
.ant-calendar-month-panel-month:hover,
|
.ant-calendar-month-panel-month:hover,
|
||||||
@@ -1076,3 +1099,21 @@ li.ant-select-dropdown-menu-item:empty:after {
|
|||||||
.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
|
.dark .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
|
||||||
background-color: #313f5a;
|
background-color: #313f5a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-select-dropdown,
|
||||||
|
.ant-popover-inner {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.ant-popover-inner-content {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-bg {
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class DBInbound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genInboundLinks() {
|
genInboundLinks(remarkModel) {
|
||||||
const inbound = this.toInbound();
|
const inbound = this.toInbound();
|
||||||
return inbound.genInboundLinks(this.remark,remarkModel);
|
return inbound.genInboundLinks(this.remark,remarkModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ class Outbound extends CommonClass {
|
|||||||
if(data.length !=2) return null;
|
if(data.length !=2) return null;
|
||||||
switch(data[0].toLowerCase()){
|
switch(data[0].toLowerCase()){
|
||||||
case Protocols.VMess:
|
case Protocols.VMess:
|
||||||
return this.fromVmessLink(JSON.parse(atob(data[1])));
|
return this.fromVmessLink(JSON.parse(Base64.decode(data[1])));
|
||||||
case Protocols.VLESS:
|
case Protocols.VLESS:
|
||||||
case Protocols.Trojan:
|
case Protocols.Trojan:
|
||||||
case 'ss':
|
case 'ss':
|
||||||
@@ -493,8 +493,8 @@ class Outbound extends CommonClass {
|
|||||||
if (network === 'tcp') {
|
if (network === 'tcp') {
|
||||||
stream.tcp = new TcpStreamSettings(
|
stream.tcp = new TcpStreamSettings(
|
||||||
json.type,
|
json.type,
|
||||||
json.host ? json.host.split(','): [],
|
json.host ?? '',
|
||||||
json.path ? json.path.split(','): []);
|
json.path ?? '');
|
||||||
} else if (network === 'kcp') {
|
} else if (network === 'kcp') {
|
||||||
stream.kcp = new KcpStreamSettings();
|
stream.kcp = new KcpStreamSettings();
|
||||||
stream.type = json.type;
|
stream.type = json.type;
|
||||||
@@ -505,7 +505,7 @@ class Outbound extends CommonClass {
|
|||||||
stream.network = 'http'
|
stream.network = 'http'
|
||||||
stream.http = new HttpStreamSettings(
|
stream.http = new HttpStreamSettings(
|
||||||
json.path,
|
json.path,
|
||||||
json.host ? json.host.split(',') : []);
|
json.host);
|
||||||
} else if (network === 'quic') {
|
} else if (network === 'quic') {
|
||||||
stream.quic = new QuicStreamSettings(
|
stream.quic = new QuicStreamSettings(
|
||||||
json.host ? json.host : 'none',
|
json.host ? json.host : 'none',
|
||||||
@@ -570,7 +570,7 @@ class Outbound extends CommonClass {
|
|||||||
let sni=url.searchParams.get('sni') ?? '';
|
let sni=url.searchParams.get('sni') ?? '';
|
||||||
let sid=url.searchParams.get('sid') ?? '';
|
let sid=url.searchParams.get('sid') ?? '';
|
||||||
let spx=url.searchParams.get('spx') ?? '';
|
let spx=url.searchParams.get('spx') ?? '';
|
||||||
stream.tls = new RealityStreamSettings(pbk, fp, sni, sid, spx);
|
stream.reality = new RealityStreamSettings(pbk, fp, sni, sid, spx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = link.split('?');
|
let data = link.split('?');
|
||||||
|
|||||||
@@ -474,10 +474,10 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
cipherSuites = '',
|
cipherSuites = '',
|
||||||
rejectUnknownSni = false,
|
rejectUnknownSni = false,
|
||||||
certificates=[new TlsStreamSettings.Cert()],
|
certificates=[new TlsStreamSettings.Cert()],
|
||||||
alpn=[ALPN_OPTION.HTTP1,ALPN_OPTION.H2],
|
alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],
|
||||||
settings=new TlsStreamSettings.Settings()) {
|
settings=new TlsStreamSettings.Settings()) {
|
||||||
super();
|
super();
|
||||||
this.server = serverName;
|
this.sni = serverName;
|
||||||
this.minVersion = minVersion;
|
this.minVersion = minVersion;
|
||||||
this.maxVersion = maxVersion;
|
this.maxVersion = maxVersion;
|
||||||
this.cipherSuites = cipherSuites;
|
this.cipherSuites = cipherSuites;
|
||||||
@@ -519,7 +519,7 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
return {
|
return {
|
||||||
serverName: this.server,
|
serverName: this.sni,
|
||||||
minVersion: this.minVersion,
|
minVersion: this.minVersion,
|
||||||
maxVersion: this.maxVersion,
|
maxVersion: this.maxVersion,
|
||||||
cipherSuites: this.cipherSuites,
|
cipherSuites: this.cipherSuites,
|
||||||
@@ -602,7 +602,7 @@ class XtlsStreamSettings extends XrayCommonClass {
|
|||||||
alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],
|
alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],
|
||||||
settings=new XtlsStreamSettings.Settings()) {
|
settings=new XtlsStreamSettings.Settings()) {
|
||||||
super();
|
super();
|
||||||
this.server = serverName;
|
this.sni = serverName;
|
||||||
this.certs = certificates;
|
this.certs = certificates;
|
||||||
this.alpn = alpn;
|
this.alpn = alpn;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
@@ -636,7 +636,7 @@ class XtlsStreamSettings extends XrayCommonClass {
|
|||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
return {
|
return {
|
||||||
serverName: this.server,
|
serverName: this.sni,
|
||||||
certificates: XtlsStreamSettings.toJsonArray(this.certs),
|
certificates: XtlsStreamSettings.toJsonArray(this.certs),
|
||||||
alpn: this.alpn,
|
alpn: this.alpn,
|
||||||
settings: this.settings,
|
settings: this.settings,
|
||||||
@@ -1080,8 +1080,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get serverName() {
|
get serverName() {
|
||||||
if (this.stream.isTls) return this.stream.tls.server;
|
if (this.stream.isTls) return this.stream.tls.sni;
|
||||||
if (this.stream.isXtls) return this.stream.xtls.server;
|
if (this.stream.isXtls) return this.stream.xtls.sni;
|
||||||
if (this.stream.isReality) return this.stream.reality.serverNames;
|
if (this.stream.isReality) return this.stream.reality.serverNames;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -1233,7 +1233,7 @@ class Inbound extends XrayCommonClass {
|
|||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
||||||
obj.sni = this.stream.tls.server;
|
obj.sni = this.stream.tls.sni;
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.settings.fingerprint)){
|
if (!ObjectUtil.isEmpty(this.stream.tls.settings.fingerprint)){
|
||||||
obj.fp = this.stream.tls.settings.fingerprint;
|
obj.fp = this.stream.tls.settings.fingerprint;
|
||||||
@@ -1311,8 +1311,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.stream.tls.settings.allowInsecure){
|
if(this.stream.tls.settings.allowInsecure){
|
||||||
params.set("allowInsecure", "1");
|
params.set("allowInsecure", "1");
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.server)){
|
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
||||||
params.set("sni", this.stream.tls.server);
|
params.set("sni", this.stream.tls.sni);
|
||||||
}
|
}
|
||||||
if (type == "tcp" && !ObjectUtil.isEmpty(flow)) {
|
if (type == "tcp" && !ObjectUtil.isEmpty(flow)) {
|
||||||
params.set("flow", flow);
|
params.set("flow", flow);
|
||||||
@@ -1326,8 +1326,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.stream.xtls.settings.allowInsecure){
|
if(this.stream.xtls.settings.allowInsecure){
|
||||||
params.set("allowInsecure", "1");
|
params.set("allowInsecure", "1");
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(this.stream.xtls.server)){
|
if (!ObjectUtil.isEmpty(this.stream.xtls.sni)){
|
||||||
params.set("sni", this.stream.xtls.server);
|
params.set("sni", this.stream.xtls.sni);
|
||||||
}
|
}
|
||||||
params.set("flow", flow);
|
params.set("flow", flow);
|
||||||
}
|
}
|
||||||
@@ -1425,8 +1425,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.stream.tls.settings.allowInsecure){
|
if(this.stream.tls.settings.allowInsecure){
|
||||||
params.set("allowInsecure", "1");
|
params.set("allowInsecure", "1");
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.server)){
|
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
||||||
params.set("sni", this.stream.tls.server);
|
params.set("sni", this.stream.tls.sni);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1506,8 +1506,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.stream.tls.settings.allowInsecure){
|
if(this.stream.tls.settings.allowInsecure){
|
||||||
params.set("allowInsecure", "1");
|
params.set("allowInsecure", "1");
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.server)){
|
if (!ObjectUtil.isEmpty(this.stream.tls.sni)){
|
||||||
params.set("sni", this.stream.tls.server);
|
params.set("sni", this.stream.tls.sni);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1533,8 +1533,8 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.stream.xtls.settings.allowInsecure){
|
if(this.stream.xtls.settings.allowInsecure){
|
||||||
params.set("allowInsecure", "1");
|
params.set("allowInsecure", "1");
|
||||||
}
|
}
|
||||||
if (this.stream.xtls.settings.serverName !== ''){
|
if (!ObjectUtil.isEmpty(this.stream.xtls.sni)){
|
||||||
params.set("sni", this.stream.xtls.settings.serverName);
|
params.set("sni", this.stream.xtls.sni);
|
||||||
}
|
}
|
||||||
params.set("flow", flow);
|
params.set("flow", flow);
|
||||||
}
|
}
|
||||||
@@ -1601,7 +1601,7 @@ class Inbound extends XrayCommonClass {
|
|||||||
if(this.clients){
|
if(this.clients){
|
||||||
let links = [];
|
let links = [];
|
||||||
this.clients.forEach((client) => {
|
this.clients.forEach((client) => {
|
||||||
genAllLinks(remark,remarkModel,client).forEach(l => {
|
this.genAllLinks(remark,remarkModel,client).forEach(l => {
|
||||||
links.push(l.link);
|
links.push(l.link);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -1797,8 +1797,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
|
|||||||
Protocols.VLESS,
|
Protocols.VLESS,
|
||||||
json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
|
json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
|
||||||
json.decryption || 'none',
|
json.decryption || 'none',
|
||||||
json.fallbacks.map(fallback => Inbound.VLESSSettings.Fallback.fromJson(fallback)),
|
Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
@@ -1925,8 +1924,7 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
|
|||||||
return new Inbound.TrojanSettings(
|
return new Inbound.TrojanSettings(
|
||||||
Protocols.TROJAN,
|
Protocols.TROJAN,
|
||||||
json.clients.map(client => Inbound.TrojanSettings.Trojan.fromJson(client)),
|
json.clients.map(client => Inbound.TrojanSettings.Trojan.fromJson(client)),
|
||||||
json.fallbacks.map(fallback => Inbound.TrojanSettings.Fallback.fromJson(fallback))
|
Inbound.TrojanSettings.Fallback.fromJson(json.fallbacks),);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson() {
|
toJson() {
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ func (s *AllSetting) CheckValid() error {
|
|||||||
return common.NewError("Sub port is not a valid port:", s.SubPort)
|
return common.NewError("Sub port is not a valid port:", s.SubPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.SubPort == s.WebPort {
|
if (s.SubPort == s.WebPort) && (s.WebListen == s.SubListen) {
|
||||||
return common.NewError("Sub and Web could not use same port:", s.SubPort)
|
return common.NewError("Sub and Web could not use same ip:port, ", s.SubListen, ":", s.SubPort, " & ", s.WebListen, ":", s.WebPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.WebCertFile != "" || s.WebKeyFile != "" {
|
if s.WebCertFile != "" || s.WebKeyFile != "" {
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
</a-tag>
|
</a-tag>
|
||||||
<template v-if="app.subSettings.enable && qrModal.subId">
|
<template v-if="app.subSettings.enable && qrModal.subId">
|
||||||
<a-divider>Subscription</a-divider>
|
<a-divider>Subscription</a-divider>
|
||||||
<canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" style="width: 100%; height: 100%;"></canvas>
|
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-sub',genSubLink(qrModal.client.subId))" id="qrCode-sub" style="width: 100%; height: 100%;"></canvas></div>
|
||||||
</template>
|
</template>
|
||||||
<a-divider>{{ i18n "pages.inbounds.client" }}</a-divider>
|
<a-divider>{{ i18n "pages.inbounds.client" }}</a-divider>
|
||||||
<template v-for="(row, index) in qrModal.qrcodes">
|
<template v-for="(row, index) in qrModal.qrcodes">
|
||||||
<a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
|
<a-tag color="green" style="margin: 10px 0; display: block; text-align: center;">[[ row.remark ]]</a-tag>
|
||||||
<canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas>
|
<div class="qr-bg"><canvas @click="copyToClipboard('qrCode-'+index, row.link)" :id="'qrCode-'+index" style="width: 100%; height: 100%;"></canvas></div>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
genSubLink(subID) {
|
genSubLink(subID) {
|
||||||
return app.subSettings.subURI+subID+'?name='+subID;
|
return app.subSettings.subURI+subID;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
@@ -55,44 +56,12 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes wave {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.wave {
|
|
||||||
opacity: 0.6;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 40%;
|
|
||||||
left: 50%;
|
|
||||||
width: 6000px;
|
|
||||||
height: 6000px;
|
|
||||||
background-color: rgba(0, 135, 113, 0.08);
|
|
||||||
margin-left: -3000px;
|
|
||||||
transform-origin: 50% 48%;
|
|
||||||
border-radius: 46%;
|
|
||||||
animation: wave 72s infinite linear;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.wave2 {
|
|
||||||
animation: wave 88s infinite linear;
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
.wave3 {
|
|
||||||
animation: wave 80s infinite linear;
|
|
||||||
opacity: 0.1;
|
|
||||||
}
|
|
||||||
.under {
|
.under {
|
||||||
background-color: #dbf5ed;
|
background-color: #c7ebe2;
|
||||||
}
|
z-index: 0;
|
||||||
.dark .wave {
|
|
||||||
background: rgb(10 117 87 / 20%);
|
|
||||||
}
|
}
|
||||||
.dark .under {
|
.dark .under {
|
||||||
background-color: #101828;
|
background-color: #0f2d32;
|
||||||
}
|
}
|
||||||
.dark #login {
|
.dark #login {
|
||||||
background-color: #151f31;
|
background-color: #151f31;
|
||||||
@@ -100,12 +69,10 @@
|
|||||||
.dark h1 {
|
.dark h1 {
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
}
|
}
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
.ant-btn-primary-login {
|
.ant-btn-primary-login {
|
||||||
color: #008771;
|
|
||||||
background-color: #eef9f7;
|
|
||||||
border-color: #89d9cc;
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
|
||||||
box-shadow: none;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.ant-btn-primary-login:focus,
|
.ant-btn-primary-login:focus,
|
||||||
@@ -156,10 +123,11 @@
|
|||||||
background-origin: border-box;
|
background-origin: border-box;
|
||||||
background-clip: padding-box, border-box;
|
background-clip: padding-box, border-box;
|
||||||
background-size: 300%;
|
background-size: 300%;
|
||||||
animation: wave-btn-tara 4s ease infinite;
|
transition: all 0.3s cubic-bezier(.645,.045,.355,1);
|
||||||
transition: all 0.5s ease;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
.dark .wave-btn-bg:hover {animation: wave-btn-tara 4s ease infinite;}
|
||||||
.dark .wave-btn-bg-cl {
|
.dark .wave-btn-bg-cl {
|
||||||
background-image: linear-gradient(rgba(13, 14, 33, 0), rgba(13, 14, 33, 0)),
|
background-image: linear-gradient(rgba(13, 14, 33, 0), rgba(13, 14, 33, 0)),
|
||||||
radial-gradient(circle at left top, #006655, #009980, #006655) !important;
|
radial-gradient(circle at left top, #006655, #009980, #006655) !important;
|
||||||
@@ -215,14 +183,84 @@
|
|||||||
background-position-x: 0;
|
background-position-x: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
.waves-header {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #dbf5ed;
|
||||||
|
color: white;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.dark .waves-header {
|
||||||
|
background-color: #101828;
|
||||||
|
}
|
||||||
|
.waves-inner-header {
|
||||||
|
height: 50vh;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.waves {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 15vh;
|
||||||
|
margin-bottom: -5px; /*Fix for safari gap*/
|
||||||
|
min-height: 100px;
|
||||||
|
max-height: 150px;
|
||||||
|
}
|
||||||
|
.parallax > use {
|
||||||
|
animation: move-forever 25s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite;
|
||||||
|
}
|
||||||
|
.dark .parallax > use {
|
||||||
|
fill: rgb(10 117 87 / 20%);
|
||||||
|
}
|
||||||
|
.parallax > use:nth-child(1) {
|
||||||
|
animation-delay: -2s;
|
||||||
|
animation-duration: 7s;
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
.parallax > use:nth-child(2) {
|
||||||
|
animation-delay: -3s;
|
||||||
|
animation-duration: 10s;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.parallax > use:nth-child(3) {
|
||||||
|
animation-delay: -4s;
|
||||||
|
animation-duration: 13s;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
@keyframes move-forever {
|
||||||
|
0% {
|
||||||
|
transform: translate3d(-90px, 0, 0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate3d(85px, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.waves {
|
||||||
|
height: 40px;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
||||||
<transition name="list" appear>
|
<transition name="list" appear>
|
||||||
<a-layout-content class="under" style="min-height: 0;">
|
<a-layout-content class="under" style="min-height: 0;">
|
||||||
<div class='wave'></div>
|
<div class="waves-header">
|
||||||
<div class='wave wave2'></div>
|
<div class="waves-inner-header"></div>
|
||||||
<div class='wave wave3'></div>
|
<svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
|
||||||
|
<defs>
|
||||||
|
<path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||||
|
</defs>
|
||||||
|
<g class="parallax">
|
||||||
|
<use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(0, 135, 113, 0.08)" />
|
||||||
|
<use xlink:href="#gentle-wave" x="48" y="5" fill="rgba(0, 135, 113, 0.08)" />
|
||||||
|
<use xlink:href="#gentle-wave" x="48" y="7" fill="rgba(0, 135, 113, 0.08)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
<a-row type="flex" justify="center" align="middle" style="height: 100%; overflow: auto;">
|
<a-row type="flex" justify="center" align="middle" style="height: 100%; overflow: auto;">
|
||||||
<a-col :xs="22" :sm="20" :md="14" :lg="10" :xl="8" :xxl="6" id="login" style="margin: 3rem 0;">
|
<a-col :xs="22" :sm="20" :md="14" :lg="10" :xl="8" :xxl="6" id="login" style="margin: 3rem 0;">
|
||||||
<a-row type="flex" justify="center">
|
<a-row type="flex" justify="center">
|
||||||
@@ -252,7 +290,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-row justify="center" class="centered">
|
<a-row justify="center" class="centered">
|
||||||
<div class="wave-btn-bg wave-btn-bg-cl">
|
<div class="wave-btn-bg wave-btn-bg-cl" :style="loading ? { width: '54px' } : { display: 'inline-block' }">
|
||||||
<a-button class="ant-btn-primary-login" type="primary" :loading="loading" @click="login" :icon="loading ? 'poweroff' : undefined"
|
<a-button class="ant-btn-primary-login" type="primary" :loading="loading" @click="login" :icon="loading ? 'poweroff' : undefined"
|
||||||
:style="loading ? { width: '50px' } : { display: 'inline-block' }">
|
:style="loading ? { width: '50px' } : { display: 'inline-block' }">
|
||||||
[[ loading ? '' : '{{ i18n "login" }}' ]]
|
[[ loading ? '' : '{{ i18n "login" }}' ]]
|
||||||
|
|||||||
@@ -2,206 +2,123 @@
|
|||||||
<a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title"
|
<a-modal id="client-bulk-modal" v-model="clientsBulkModal.visible" :title="clientsBulkModal.title"
|
||||||
@ok="clientsBulkModal.ok" :confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false"
|
@ok="clientsBulkModal.ok" :confirm-loading="clientsBulkModal.confirmLoading" :closable="true" :mask-closable="false"
|
||||||
:ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
:ok-text="clientsBulkModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.client.method" }}'>
|
||||||
<tr>
|
<a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid"
|
||||||
<td>{{ i18n "pages.client.method" }}</td>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option :value="0">Random</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option :value="1">Random+Prefix</a-select-option>
|
||||||
<a-select v-model="clientsBulkModal.emailMethod" buttonStyle="solid" style="width: 250px"
|
<a-select-option :value="2">Random+Prefix+Num</a-select-option>
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option :value="3">Random+Prefix+Num+Postfix</a-select-option>
|
||||||
<a-select-option :value="0">Random</a-select-option>
|
<a-select-option :value="4">Prefix+Num+Postfix</a-select-option>
|
||||||
<a-select-option :value="1">Random+Prefix</a-select-option>
|
</a-select>
|
||||||
<a-select-option :value="2">Random+Prefix+Num</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option :value="3">Random+Prefix+Num+Postfix</a-select-option>
|
<a-form-item label='{{ i18n "pages.client.first" }}' v-if="clientsBulkModal.emailMethod>1">
|
||||||
<a-select-option :value="4">Prefix+Num+Postfix</a-select-option>
|
<a-input-number v-model="clientsBulkModal.firstNum" :min="1"></a-input-number>
|
||||||
</a-select>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='{{ i18n "pages.client.last" }}' v-if="clientsBulkModal.emailMethod>1">
|
||||||
</td>
|
<a-input-number v-model="clientsBulkModal.lastNum" :min="clientsBulkModal.firstNum"></a-input-number>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr v-if="clientsBulkModal.emailMethod>1">
|
<a-form-item label='{{ i18n "pages.client.prefix" }}' v-if="clientsBulkModal.emailMethod>0">
|
||||||
<td>{{ i18n "pages.client.first" }}</td>
|
<a-input v-model="clientsBulkModal.emailPrefix"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "pages.client.postfix" }}' v-if="clientsBulkModal.emailMethod>2">
|
||||||
<a-input-number v-model="clientsBulkModal.firstNum" :min="1"></a-input-number>
|
<a-input v-model="clientsBulkModal.emailPostfix"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2">
|
||||||
</tr>
|
<a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
|
||||||
<tr v-if="clientsBulkModal.emailMethod>1">
|
</a-form-item>
|
||||||
<td>{{ i18n "pages.client.last" }}</td>
|
<a-form-item label='Flow' v-if="clientsBulkModal.inbound.canEnableTlsFlow()">
|
||||||
<td>
|
<a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-form-item>
|
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||||
<a-input-number v-model="clientsBulkModal.lastNum"
|
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
:min="clientsBulkModal.firstNum"></a-input-number>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='Flow' v-if="clientsBulkModal.inbound.xtls">
|
||||||
</tr>
|
<a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<tr v-if="clientsBulkModal.emailMethod>0">
|
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||||
<td>{{ i18n "pages.client.prefix" }}</td>
|
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
<td>
|
</a-select>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model="clientsBulkModal.emailPrefix" style="width: 250px"></a-input>
|
<a-form-item v-if="app.subSettings.enable">
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
<a-tooltip>
|
||||||
</tr>
|
<template slot="title">
|
||||||
<tr v-if="clientsBulkModal.emailMethod>2">
|
<span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
|
||||||
<td>{{ i18n "pages.client.postfix" }}</td>
|
</template>
|
||||||
<td>
|
Subscription
|
||||||
<a-form-item>
|
<a-icon @click="clientsBulkModal.subId = RandomUtil.randomLowerAndNum(16)" type="sync"></a-icon>
|
||||||
<a-input v-model="clientsBulkModal.emailPostfix" style="width: 250px"></a-input>
|
</a-tooltip>
|
||||||
</a-form-item>
|
</template>
|
||||||
</td>
|
<a-input v-model.trim="clientsBulkModal.subId"></a-input>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr v-if="clientsBulkModal.emailMethod < 2">
|
<a-form-item v-if="app.tgBotEnable">
|
||||||
<td>{{ i18n "pages.client.clientCount" }}</td>
|
<template slot="label">
|
||||||
<td>
|
<a-tooltip>
|
||||||
<a-form-item>
|
<template slot="title">
|
||||||
<a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
|
<span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
|
||||||
</a-form-item>
|
</template>
|
||||||
</td>
|
Telegram ID
|
||||||
</tr>
|
<a-icon type="question-circle"></a-icon>
|
||||||
<tr v-if="clientsBulkModal.inbound.canEnableTlsFlow()">
|
</a-tooltip>
|
||||||
<td>Flow</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="clientsBulkModal.tgId"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-select v-model="clientsBulkModal.flow" style="width: 250px"
|
<a-form-item>
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
<template slot="label">
|
||||||
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
<a-tooltip>
|
||||||
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
<template slot="title">
|
||||||
</a-select>
|
<span>{{ i18n "pages.inbounds.IPLimitDesc" }}</span>
|
||||||
</a-form-item>
|
</template>
|
||||||
</td>
|
<span>{{ i18n "pages.inbounds.IPLimit" }} </span>
|
||||||
</tr>
|
<a-icon type="question-circle"></a-icon>
|
||||||
<tr v-if="app.subSettings.enable">
|
</a-tooltip>
|
||||||
<td>Subscription
|
</template>
|
||||||
<a-tooltip>
|
<a-input-number v-model="clientsBulkModal.limitIp" min="0"></a-input-number>
|
||||||
<template slot="title">
|
</a-form-item>
|
||||||
<span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
|
<a-form-item>
|
||||||
</template>
|
<template slot="label">
|
||||||
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"></a-icon>
|
<a-tooltip>
|
||||||
</a-tooltip>
|
<template slot="title">
|
||||||
</td>
|
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
||||||
<td>
|
</template>
|
||||||
<a-form-item>
|
{{ i18n "pages.inbounds.totalFlow" }} (GB)
|
||||||
<a-input v-model.trim="clientsBulkModal.subId" style="width: 250px"></a-input>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-form-item>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
</tr>
|
<a-input-number v-model="clientsBulkModal.totalGB" :min="0"></a-input-number>
|
||||||
<tr v-if="app.tgBotEnable">
|
</a-form-item>
|
||||||
<td>Telegram ID
|
<a-form-item label='{{ i18n "pages.client.delayedStart" }}'>
|
||||||
<a-tooltip>
|
<a-switch v-model="clientsBulkModal.delayedStart" @click="clientsBulkModal.expiryTime=0"></a-switch>
|
||||||
<template slot="title">
|
</a-form-item>
|
||||||
<span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
|
<a-form-item label='{{ i18n "pages.client.expireDays" }}' v-if="clientsBulkModal.delayedStart">
|
||||||
</template>
|
<a-input-number v-model.number="delayedExpireDays" :min="0"></a-input-number>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
</a-form-item>
|
||||||
</a-tooltip>
|
<a-form-item v-else>
|
||||||
</td>
|
<template slot="label">
|
||||||
<td>
|
<a-tooltip>
|
||||||
<a-form-item>
|
<template slot="title">
|
||||||
<a-input v-model.trim="clientsBulkModal.tgId" style="width: 250px"></a-input>
|
<span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
|
||||||
</a-form-item>
|
</template>
|
||||||
</td>
|
{{ i18n "pages.inbounds.expireDate" }}
|
||||||
</tr>
|
<a-icon type="question-circle"></a-icon>
|
||||||
<tr>
|
</a-tooltip>
|
||||||
<td>
|
</template>
|
||||||
<label>
|
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
||||||
<span>{{ i18n "pages.inbounds.IPLimit" }}</span>
|
:dropdown-class-name="themeSwitcher.currentTheme" v-model="clientsBulkModal.expiryTime"></a-date-picker>
|
||||||
<a-tooltip>
|
</a-form-item>
|
||||||
<template slot="title">
|
<a-form-item v-if="clientsBulkModal.expiryTime != 0">
|
||||||
<span>{{ i18n "pages.inbounds.IPLimitDesc" }}</span>
|
<template slot="label">
|
||||||
</template>
|
<span>{{ i18n "pages.client.renew" }}</span>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-tooltip>
|
||||||
</a-tooltip>
|
<template slot="title">
|
||||||
</label>
|
<span>{{ i18n "pages.client.renewDesc" }}</span>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-icon type="question-circle"></a-icon>
|
||||||
<a-form-item>
|
</a-tooltip>
|
||||||
<a-input-number v-model="clientsBulkModal.limitIp" min="0"></a-input-number>
|
</template>
|
||||||
</a-form-item>
|
<a-input-number v-model.number="clientsBulkModal.reset" :min="0"></a-input-number>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td v-if="clientsBulkModal.inbound.xtls">
|
|
||||||
<label>Flow</label>
|
|
||||||
</td>
|
|
||||||
<td v-if="clientsBulkModal.inbound.xtls">
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="clientsBulkModal.flow" style="width: 200px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="">{{ i18n "none" }}</a-select-option>
|
|
||||||
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.totalFlow" }}</span>(GB)
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="clientsBulkModal.totalGB" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.client.delayedStart" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="clientsBulkModal.delayedStart"
|
|
||||||
@click="clientsBulkModal.expiryTime=0"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="clientsBulkModal.delayedStart">
|
|
||||||
<td>{{ i18n "pages.client.expireDays" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="delayedExpireDays" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-else>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.expireDate" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme" v-model="clientsBulkModal.expiryTime"
|
|
||||||
style="width: 250px;"></a-date-picker>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="clientsBulkModal.expiryTime != 0">
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.client.renew" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.client.renewDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="clientsBulkModal.reset" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -1,223 +1,168 @@
|
|||||||
{{define "form/client"}}
|
{{define "form/client"}}
|
||||||
<a-form layout="inline" v-if="client">
|
<a-form layout="horizontal" v-if="client" :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.inbounds.enable" }}'>
|
||||||
<tr>
|
<a-switch v-model="client.enable"></a-switch>
|
||||||
<td>{{ i18n "pages.inbounds.enable" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item>
|
||||||
<a-form-item>
|
<template slot="label">
|
||||||
<a-switch v-model="client.enable"></a-switch>
|
<a-tooltip>
|
||||||
</a-form-item>
|
<template slot="title">
|
||||||
</td>
|
<span>{{ i18n "pages.inbounds.emailDesc" }}</span>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.email" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.emailDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="sync" @click="client.email = RandomUtil.randomLowerAndNum(9)"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="client.email" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
|
||||||
<td>password
|
|
||||||
<a-icon v-if="inbound.protocol === Protocols.SHADOWSOCKS" @click="client.password = RandomUtil.randomShadowsocksPassword()" type="sync"> </a-icon>
|
|
||||||
<a-icon v-if="inbound.protocol === Protocols.TROJAN" @click="client.password = RandomUtil.randomSeq(10)" type="sync"> </a-icon>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="client.password" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="inbound.protocol === Protocols.VMESS || inbound.protocol === Protocols.VLESS">
|
|
||||||
<td>ID <a-icon @click="client.id = RandomUtil.randomUUID()" type="sync"></a-icon></td>
|
|
||||||
<td>
|
|
||||||
<a-input v-model.trim="client.id" style="width: 300px;"></a-input>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="client.email && app.subSettings.enable">
|
|
||||||
<td>Subscription <a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"></a-icon></td>
|
|
||||||
<td>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="client.subId" style="width: 250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="client.email && app.tgBotEnable">
|
|
||||||
<td>Telegram ID
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="client.tgId" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.IPLimit" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.IPLimitDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="client.limitIp" min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="client.email && client.limitIp > 0 && isEdit">
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.IPLimitlog" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.IPLimitlogDesc" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.IPLimitlogclear" }}</span>
|
|
||||||
</template>
|
|
||||||
<span style="color: #FF4D4F">
|
|
||||||
<a-icon type="delete" @click="clearDBClientIps(client.email)"></a-icon>
|
|
||||||
</span>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form layout="block">
|
|
||||||
<a-textarea id="clientIPs" readonly @click="getDBClientIps(client.email)"
|
|
||||||
placeholder="Click To Get IPs" :auto-size="{ minRows: 5, maxRows: 10 }">
|
|
||||||
</a-textarea>
|
|
||||||
</a-form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="inbound.xtls">
|
|
||||||
<td>Flow</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="client.flow" style="width: 200px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="">{{ i18n "none" }}</a-select-option>
|
|
||||||
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-else-if="inbound.canEnableTlsFlow()">
|
|
||||||
<td>Flow</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="client.flow" style="width: 200px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
|
||||||
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.totalFlow" }}</span> (GB)
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="client._totalGB" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
<template v-if="isEdit && clientStats">
|
|
||||||
<br>
|
|
||||||
<span> {{ i18n "usage" }}:</span>
|
|
||||||
<a-tag :color="clientUsageColor(clientStats, app.trafficDiff)">
|
|
||||||
[[ sizeFormat(clientStats.up) ]] /
|
|
||||||
[[ sizeFormat(clientStats.down) ]]
|
|
||||||
([[ sizeFormat(clientStats.up + clientStats.down) ]])
|
|
||||||
</a-tag>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">{{ i18n "pages.inbounds.resetTraffic" }}</template>
|
|
||||||
<a-icon type="retweet"
|
|
||||||
@click="resetClientTraffic(client.email,clientStats.inboundId,$event.target)"
|
|
||||||
v-if="client.email.length > 0"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</template>
|
</template>
|
||||||
</td>
|
{{ i18n "pages.inbounds.email" }}
|
||||||
</tr>
|
<a-icon type="sync" @click="client.email = RandomUtil.randomLowerAndNum(9)"></a-icon>
|
||||||
<tr>
|
</a-tooltip>
|
||||||
<td>{{ i18n "pages.client.delayedStart" }}</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="client.email"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-switch v-model="delayedStart" @click="client._expiryTime=0"></a-switch>
|
<a-form-item v-if="inbound.protocol === Protocols.TROJAN || inbound.protocol === Protocols.SHADOWSOCKS">
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
<a-tooltip>
|
||||||
</tr>
|
<template slot="title">
|
||||||
<tr v-if="delayedStart">
|
<span>{{ i18n "pages.client.renew" }}</span>
|
||||||
<td>{{ i18n "pages.client.expireDays" }}</td>
|
</template>
|
||||||
<td>
|
{{ i18n "password" }}
|
||||||
<a-form-item>
|
<a-icon v-if="inbound.protocol === Protocols.SHADOWSOCKS"@click="client.password = RandomUtil.randomShadowsocksPassword()" type="sync"></a-icon>
|
||||||
<a-input-number v-model="delayedExpireDays" :min="0"></a-input-number>
|
<a-icon v-if="inbound.protocol === Protocols.TROJAN" @click="client.password = RandomUtil.randomSeq(10)"type="sync"> </a-icon>
|
||||||
</a-form-item>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
</tr>
|
<a-input v-model.trim="client.password"></a-input>
|
||||||
<tr v-else>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item v-if="inbound.protocol === Protocols.VMESS || inbound.protocol === Protocols.VLESS">
|
||||||
<span>{{ i18n "pages.inbounds.expireDate" }}</span>
|
<template slot="label">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
|
<span>{{ i18n "pages.client.renew" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
ID <a-icon @click="client.id = RandomUtil.randomUUID()" type="sync"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="client.id"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
<a-form-item v-if="client.email && app.subSettings.enable">
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"
|
<template slot="label">
|
||||||
style="width: 170px;"></a-date-picker>
|
<a-tooltip>
|
||||||
<a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag>
|
<template slot="title">
|
||||||
</a-form-item>
|
<span>{{ i18n "pages.inbounds.subscriptionDesc" }}</span>
|
||||||
</td>
|
</template>
|
||||||
</tr>
|
Subscription
|
||||||
<tr v-if="client.expiryTime != 0">
|
<a-icon @click="client.subId = RandomUtil.randomLowerAndNum(16)" type="sync"></a-icon>
|
||||||
<td>
|
</a-tooltip>
|
||||||
<span>{{ i18n "pages.client.renew" }}</span>
|
</template>
|
||||||
<a-tooltip>
|
<a-input v-model.trim="client.subId"></a-input>
|
||||||
<template slot="title">
|
</a-form-item>
|
||||||
<span>{{ i18n "pages.client.renewDesc" }}</span>
|
<a-form-item v-if="client.email && app.tgBotEnable">
|
||||||
</template>
|
<template slot="label">
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-tooltip>
|
||||||
</a-tooltip>
|
<template slot="title">
|
||||||
</td>
|
<span>{{ i18n "pages.inbounds.telegramDesc" }}</span>
|
||||||
<td>
|
</template>
|
||||||
<a-form-item>
|
Telegram ID
|
||||||
<a-input-number v-model.number="client.reset" :min="0"></a-input-number>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-form-item>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
</tr>
|
<a-input v-model.trim="client.tgId"></a-input>
|
||||||
</table>
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.IPLimitDesc"}}</span>
|
||||||
|
</template>
|
||||||
|
<span>{{ i18n "pages.inbounds.IPLimit"}} </span>
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input-number v-model="client.limitIp" min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="client.email && client.limitIp > 0 && isEdit">
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.IPLimitlogDesc" }}</span>
|
||||||
|
</template>
|
||||||
|
<span>{{ i18n "pages.inbounds.IPLimitlog" }}</span>
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.IPLimitlogclear" }}</span>
|
||||||
|
</template>
|
||||||
|
<span style="color: #FF4D4F">
|
||||||
|
<a-icon type="delete" @click="clearDBClientIps(client.email)"></a-icon>
|
||||||
|
</span>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-form layout="block">
|
||||||
|
<a-textarea id="clientIPs" readonly @click="getDBClientIps(client.email)" placeholder="Click To Get IPs"
|
||||||
|
:auto-size="{ minRows: 5, maxRows: 10 }">
|
||||||
|
</a-textarea>
|
||||||
|
</a-form>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="inbound.xtls" label='Flow'>
|
||||||
|
<a-select v-model="client.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||||
|
<a-select-option v-for="key in XTLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="inbound.canEnableTlsFlow()" label='Flow'>
|
||||||
|
<a-select v-model="client.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||||
|
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
||||||
|
</template>
|
||||||
|
{{ i18n "pages.inbounds.totalFlow" }}(GB)
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input-number v-model="client._totalGB" :min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="isEdit && clientStats" label='{{ i18n "usage" }}'>
|
||||||
|
<a-tag :color="clientUsageColor(clientStats, app.trafficDiff)">
|
||||||
|
[[ sizeFormat(clientStats.up) ]] /
|
||||||
|
[[ sizeFormat(clientStats.down) ]]
|
||||||
|
([[ sizeFormat(clientStats.up + clientStats.down) ]])
|
||||||
|
</a-tag>
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">{{ i18n "pages.inbounds.resetTraffic" }}</template>
|
||||||
|
<a-icon type="retweet"
|
||||||
|
@click="resetClientTraffic(client.email,clientStats.inboundId,$event.target)"
|
||||||
|
v-if="client.email.length > 0"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label='{{ i18n "pages.client.delayedStart" }}'>
|
||||||
|
<a-switch v-model="delayedStart" @click="client._expiryTime=0"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="delayedStart" label='{{ i18n "pages.client.expireDays" }}'>
|
||||||
|
<a-input-number v-model.number="delayedExpireDays" :min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-else>
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</template>
|
||||||
|
{{ i18n "pages.inbounds.expireDate" }}
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"></a-date-picker>
|
||||||
|
<a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="client.expiryTime != 0">
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">{{ i18n "pages.client.renewDesc" }}</template>
|
||||||
|
{{ i18n "pages.client.renew" }}
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input-number v-model.number="client.reset" :min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,93 +1,64 @@
|
|||||||
{{define "form/inbound"}}
|
{{define "form/inbound"}}
|
||||||
<!-- base -->
|
<!-- base -->
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "enable" }}'>
|
||||||
<tr>
|
<a-switch v-model="dbInbound.enable"></a-switch>
|
||||||
<td>{{ i18n "enable" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='{{ i18n "remark" }}'>
|
||||||
<a-form-item>
|
<a-input v-model.trim="dbInbound.remark"></a-input>
|
||||||
<a-switch v-model="dbInbound.enable"></a-switch>
|
</a-form-item>
|
||||||
</a-form-item>
|
|
||||||
</td>
|
<a-form-item label='{{ i18n "protocol" }}'>
|
||||||
</tr>
|
<a-select v-model="inbound.protocol" :disabled="isEdit" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<tr>
|
<a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>
|
||||||
<td>{{ i18n "remark" }}</td>
|
</a-select>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="dbInbound.remark" style="width: 250px;"></a-input>
|
<a-form-item>
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
<a-tooltip>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "protocol" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.protocol" style="width: 250px;" :disabled="isEdit" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "monitor" }}
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.inbounds.monitorDesc" }}</span>
|
<span>{{ i18n "pages.inbounds.monitorDesc" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
{{ i18n "monitor" }}
|
||||||
</a-tooltip>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</td>
|
</a-tooltip>
|
||||||
<td>
|
</template>
|
||||||
<a-form-item>
|
<a-input v-model.trim="inbound.listen"></a-input>
|
||||||
<a-input v-model.trim="inbound.listen" style="width: 250px;"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.port" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.port"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.totalFlow" }}</span>(GB)
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="dbInbound.totalGB" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>{{ i18n "pages.inbounds.expireDate" }}</span>
|
|
||||||
<a-tooltip>
|
|
||||||
<template slot="title">
|
|
||||||
<span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
|
|
||||||
</template>
|
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
|
||||||
</a-tooltip>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme"
|
|
||||||
v-model="dbInbound._expiryTime" style="width: 250px;"></a-date-picker>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
|
||||||
|
|
||||||
|
<a-form-item label='{{ i18n "pages.inbounds.port" }}'>
|
||||||
|
<a-input-number v-model.number="inbound.port"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item>
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
||||||
|
</template>
|
||||||
|
{{ i18n "pages.inbounds.totalFlow" }}(GB)
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-input-number v-model="dbInbound.totalGB" :min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item>
|
||||||
|
<template slot="label">
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.leaveBlankToNeverExpire" }}</span>
|
||||||
|
</template>
|
||||||
|
{{ i18n "pages.inbounds.expireDate" }}
|
||||||
|
<a-icon type="question-circle"></a-icon>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-date-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
|
v-model="dbInbound._expiryTime"></a-date-picker>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
<!-- vmess settings -->
|
<!-- vmess settings -->
|
||||||
<template v-if="inbound.protocol === Protocols.VMESS">
|
<template v-if="inbound.protocol === Protocols.VMESS">
|
||||||
|
|||||||
@@ -2,535 +2,298 @@
|
|||||||
<!-- base -->
|
<!-- base -->
|
||||||
<a-tabs :active-key="outModal.activeKey" style="padding: 0; background-color: transparent;" @change="(activeKey) => {outModal.toggleJson(activeKey == '2'); }">
|
<a-tabs :active-key="outModal.activeKey" style="padding: 0; background-color: transparent;" @change="(activeKey) => {outModal.toggleJson(activeKey == '2'); }">
|
||||||
<a-tab-pane key="1" tab="Form">
|
<a-tab-pane key="1" tab="Form">
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "protocol" }}'>
|
||||||
<tr>
|
<a-select v-model="outbound.protocol" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>{{ i18n "protocol" }}</td>
|
<a-select-option v-for="x,y in Protocols" :value="x">[[ y ]]</a-select-option>
|
||||||
<td>
|
</a-select>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-select v-model="outbound.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-form-item label='{{ i18n "pages.xray.outbound.tag" }}' has-feedback :validate-status="outModal.duplicateTag? 'warning' : 'success'">
|
||||||
<a-select-option v-for="x,y in Protocols" :value="x">[[ y ]]</a-select-option>
|
<a-input v-model.trim="outbound.tag" @change="outModal.check()" placeholder='{{ i18n "pages.xray.outbound.tagDesc" }}'></a-input>
|
||||||
</a-select>
|
</a-form-item>
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.xray.outbound.tag" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item has-feedback :validate-status="outModal.duplicateTag? 'warning' : 'success'">
|
|
||||||
<a-input v-model.trim="outbound.tag" style="width: 250px" @change="outModal.check()" placeholder='{{ i18n "pages.xray.outbound.tagDesc" }}'></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<!-- freedom settings-->
|
<!-- freedom settings-->
|
||||||
<template v-if="outbound.protocol === Protocols.Freedom">
|
<template v-if="outbound.protocol === Protocols.Freedom">
|
||||||
<tr>
|
<a-form-item label='Strategy'>
|
||||||
<td>Strategy</td>
|
<a-select
|
||||||
<td>
|
v-model="outbound.settings.domainStrategy"
|
||||||
<a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select
|
<a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option>
|
||||||
v-model="outbound.settings.domainStrategy"
|
</a-select>
|
||||||
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option>
|
<a-form-item label='Fragment'>
|
||||||
</a-select>
|
<a-switch
|
||||||
</a-form-item>
|
:checked="Object.keys(outbound.settings.fragment).length >0"
|
||||||
</td>
|
@change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}">
|
||||||
</tr>
|
</a-switch>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>Fragment</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch
|
|
||||||
:checked="Object.keys(outbound.settings.fragment).length >0"
|
|
||||||
@change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}">
|
|
||||||
</a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="Object.keys(outbound.settings.fragment).length >0">
|
<template v-if="Object.keys(outbound.settings.fragment).length >0">
|
||||||
<tr>
|
<a-form-item label='Packets'>
|
||||||
<td>Packets</td>
|
<a-select
|
||||||
<td>
|
v-model="outbound.settings.fragment.packets"
|
||||||
<a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select
|
<a-select-option v-for="s in ['1-3','tlshello']" :value="s">[[ s ]]</a-select-option>
|
||||||
v-model="outbound.settings.fragment.packets"
|
</a-select>
|
||||||
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="s in ['1-3','tlshello']" :value="s">[[ s ]]</a-select-option>
|
<a-form-item label='Length'>
|
||||||
</a-select>
|
<a-input v-model.trim="outbound.settings.fragment.length"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='Interval'>
|
||||||
</tr>
|
<a-input v-model.trim="outbound.settings.fragment.interval"></a-input>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>Length</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.settings.fragment.length" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Interval</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.settings.fragment.interval" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- blackhole settings -->
|
<!-- blackhole settings -->
|
||||||
<template v-if="outbound.protocol === Protocols.Blackhole">
|
<template v-if="outbound.protocol === Protocols.Blackhole">
|
||||||
<tr>
|
<a-form-item label='Response Type'>
|
||||||
<td>Response Type</td>
|
<a-select
|
||||||
<td>
|
v-model="outbound.settings.type"
|
||||||
<a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select
|
<a-select-option v-for="s in ['', 'none','http']" :value="s">[[ s ]]</a-select-option>
|
||||||
v-model="outbound.settings.type"
|
</a-select>
|
||||||
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="s in ['', 'none','http']" :value="s">[[ s ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- dns settings -->
|
<!-- dns settings -->
|
||||||
<template v-if="outbound.protocol === Protocols.DNS">
|
<template v-if="outbound.protocol === Protocols.DNS">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.inbounds.network" }}'>
|
||||||
<td>{{ i18n "pages.inbounds.network" }}</td>
|
<a-select
|
||||||
<td>
|
v-model="outbound.settings.network"
|
||||||
<a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select
|
<a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option>
|
||||||
v-model="outbound.settings.network"
|
</a-select>
|
||||||
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="s in ['udp','tcp']" :value="s">[[ s ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Address + Port -->
|
<!-- Address + Port -->
|
||||||
<template v-if="outbound.hasAddressPort()">
|
<template v-if="outbound.hasAddressPort()">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.inbounds.address" }}'>
|
||||||
<td>{{ i18n "pages.inbounds.address" }}</td>
|
<a-input v-model.trim="outbound.settings.address"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "pages.inbounds.port" }}'>
|
||||||
<a-input v-model.trim="outbound.settings.address" style="width: 250px"></a-input>
|
<a-input-number v-model.number="outbound.settings.port" :min="1" :max="65532"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.port" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.settings.port" :min="1" :max="65532"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Vnext (vless/vmess) settings -->
|
<!-- Vnext (vless/vmess) settings -->
|
||||||
<template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)">
|
<template v-if="[Protocols.VMess, Protocols.VLESS].includes(outbound.protocol)">
|
||||||
<tr>
|
<a-form-item label='ID'>
|
||||||
<td>ID</td>
|
<a-input v-model.trim="outbound.settings.id"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.settings.id" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<!-- vless settings -->
|
<!-- vless settings -->
|
||||||
<template v-if="outbound.canEnableTlsFlow()">
|
<template v-if="outbound.canEnableTlsFlow()">
|
||||||
<tr>
|
<a-form-item label='Flow'>
|
||||||
<td>Flow</td>
|
<a-select v-model="outbound.settings.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
<a-select v-model="outbound.settings.flow" style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-select>
|
||||||
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Servers (trojan/shadowsocks/socks/http) settings -->
|
<!-- Servers (trojan/shadowsocks/socks/http) settings -->
|
||||||
<template v-if="outbound.hasServers()">
|
<template v-if="outbound.hasServers()">
|
||||||
<tr v-if="outbound.hasUsername()">
|
<template v-if="outbound.hasUsername()">
|
||||||
<td>{{ i18n "username" }}</td>
|
<a-form-item label='{{ i18n "username" }}'>
|
||||||
<td>
|
<a-input v-model.trim="outbound.settings.user"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="outbound.settings.user" style="width: 250px"></a-input>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
</a-form-item>
|
<a-input v-model.trim="outbound.settings.password"></a-input>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
</template>
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "password" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.settings.password" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<!-- shadowsocks -->
|
<!-- shadowsocks -->
|
||||||
<template v-if="outbound.protocol === Protocols.Shadowsocks">
|
<template v-if="outbound.protocol === Protocols.Shadowsocks">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "encryption" }}'>
|
||||||
<td>{{ i18n "encryption" }}</td>
|
<a-select v-model="outbound.settings.method" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
|
||||||
<a-form-item>
|
</a-select>
|
||||||
<a-select v-model="outbound.settings.method" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
|
<a-form-item label='UDP over TCP'>
|
||||||
</a-select>
|
<a-switch v-model="outbound.settings.uot"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>UDP over TCP</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="outbound.settings.uot"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- stream settings -->
|
<!-- stream settings -->
|
||||||
<template v-if="outbound.canEnableStream()">
|
<template v-if="outbound.canEnableStream()">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "transmission" }}'>
|
||||||
<td>{{ i18n "transmission" }}</td>
|
<a-select v-model="outbound.stream.network" @change="streamNetworkChange"
|
||||||
<td>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-form-item>
|
<a-select-option value="tcp">TCP</a-select-option>
|
||||||
<a-select v-model="outbound.stream.network" @change="streamNetworkChange"
|
<a-select-option value="kcp">KCP</a-select-option>
|
||||||
style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option value="ws">WS</a-select-option>
|
||||||
<a-select-option value="tcp">TCP</a-select-option>
|
<a-select-option value="http">HTTP2</a-select-option>
|
||||||
<a-select-option value="kcp">KCP</a-select-option>
|
<a-select-option value="quic">QUIC</a-select-option>
|
||||||
<a-select-option value="ws">WebSocket</a-select-option>
|
<a-select-option value="grpc">gRPC</a-select-option>
|
||||||
<a-select-option value="http">HTTP2</a-select-option>
|
</a-select>
|
||||||
<a-select-option value="quic">QUIC</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option value="grpc">gRPC</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="outbound.stream.network === 'tcp'">
|
<template v-if="outbound.stream.network === 'tcp'">
|
||||||
<tr>
|
<a-form-item label='HTTP {{ i18n "camouflage" }}'>
|
||||||
<td>http {{ i18n "camouflage" }}</td>
|
<a-switch
|
||||||
<td>
|
:checked="outbound.stream.tcp.type === 'http'"
|
||||||
<a-form-item>
|
@change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'">
|
||||||
<a-switch
|
</a-switch>
|
||||||
:checked="outbound.stream.tcp.type === 'http'"
|
</a-form-item>
|
||||||
@change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'">
|
|
||||||
</a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="outbound.stream.tcp.type == 'http'">
|
<template v-if="outbound.stream.tcp.type == 'http'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "host" }}'>
|
||||||
<td>{{ i18n "host" }}</td>
|
<a-input v-model.trim="outbound.stream.tcp.host"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.host"></a-input>
|
<a-input v-model.trim="outbound.stream.tcp.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "path" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input style="width: 250px;" v-model.trim="outbound.stream.tcp.path"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- kcp -->
|
<!-- kcp -->
|
||||||
<template v-if="outbound.stream.network === 'kcp'">
|
<template v-if="outbound.stream.network === 'kcp'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "camouflage" }}'>
|
||||||
<td>{{ i18n "camouflage" }}</td>
|
<a-select v-model="outbound.stream.kcp.type" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option value="none">none (not camouflage)</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="srtp">srtp (video call)</a-select-option>
|
||||||
<a-select v-model="outbound.stream.kcp.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option value="utp">utp (BT download)</a-select-option>
|
||||||
<a-select-option value="none">none (not camouflage)</a-select-option>
|
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option>
|
||||||
<a-select-option value="srtp">srtp (video call)</a-select-option>
|
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option>
|
||||||
<a-select-option value="utp">utp (BT download)</a-select-option>
|
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option>
|
||||||
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option>
|
</a-select>
|
||||||
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
</a-select>
|
<a-input v-model="outbound.stream.kcp.seed"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='MTU'>
|
||||||
</tr>
|
<a-input-number v-model.number="outbound.stream.kcp.mtu"></a-input-number>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>{{ i18n "password" }}</td>
|
<a-form-item label='TTI (ms)'>
|
||||||
<td>
|
<a-input-number v-model.number="outbound.stream.kcp.tti"></a-input-number>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model="outbound.stream.kcp.seed" style="width: 250px;"></a-input>
|
<a-form-item label='Uplink Capacity (MB/s)'>
|
||||||
</a-form-item>
|
<a-input-number v-model.number="outbound.stream.kcp.upCap"></a-input-number>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item label='Downlink Capacity (MB/s)'>
|
||||||
<tr>
|
<a-input-number v-model.number="outbound.stream.kcp.downCap"></a-input-number>
|
||||||
<td>mtu</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='Congestion'>
|
||||||
<a-form-item>
|
<a-switch v-model="outbound.stream.kcp.congestion"></a-switch>
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.mtu"></a-input-number>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='Read Buffer Size (MB)'>
|
||||||
</td>
|
<a-input-number v-model.number="outbound.stream.kcp.readBuffer"></a-input-number>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
<a-form-item label='Write Buffer Size (MB)'>
|
||||||
<td>tti (ms)</td>
|
<a-input-number v-model.number="outbound.stream.kcp.writeBuffer"></a-input-number>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.tti"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>uplink capacity (MB/S)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.upCap"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>downlink capacity (MB/S)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.downCap"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>congestion</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="outbound.stream.kcp.congestion"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>read buffer size (MB)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.readBuffer"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>write buffer size (MB)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="outbound.stream.kcp.writeBuffer"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- ws -->
|
<!-- ws -->
|
||||||
<template v-if="outbound.stream.network === 'ws'">
|
<template v-if="outbound.stream.network === 'ws'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "host" }}'>
|
||||||
<td>{{ i18n "host" }}</td>
|
<a-input v-model="outbound.stream.ws.host"></a-input>
|
||||||
<td><a-form-item><a-input style="width: 250px" v-model="outbound.stream.ws.host"></a-input></a-form-item></td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<tr>
|
<a-form-item><a-input v-model.trim="outbound.stream.ws.path"></a-input>
|
||||||
<td>{{ i18n "path" }}</td>
|
</a-form-item>
|
||||||
<td><a-form-item><a-input style="width: 250px;" v-model.trim="outbound.stream.ws.path"></a-input></a-form-item></td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- http -->
|
<!-- http -->
|
||||||
<template v-if="outbound.stream.network === 'http'">
|
<template v-if="outbound.stream.network === 'http'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "host" }}'>
|
||||||
<td>{{ i18n "host" }}</td>
|
<a-input v-model.trim="outbound.stream.http.host"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="outbound.stream.http.host" style="width: 250px;"></a-input>
|
<a-input v-model.trim="outbound.stream.http.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "path" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.stream.http.path" style="width: 250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- quic -->
|
<!-- quic -->
|
||||||
<template v-if="outbound.stream.network === 'quic'">
|
<template v-if="outbound.stream.network === 'quic'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.quic.encryption" }}'>
|
||||||
<td>{{ i18n "pages.inbounds.stream.quic.encryption" }}</td>
|
<a-select v-model="outbound.stream.quic.security" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option value="none">none</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
|
||||||
<a-select v-model="outbound.stream.quic.security" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
|
||||||
<a-select-option value="none">none</a-select-option>
|
</a-select>
|
||||||
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
</a-select>
|
<a-input v-model.trim="outbound.stream.quic.key"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='{{ i18n "camouflage" }}'>
|
||||||
</tr>
|
<a-select v-model="outbound.stream.quic.type" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<tr>
|
<a-select-option value="none">none (No Obfuscation)</a-select-option>
|
||||||
<td>{{ i18n "password" }}</td>
|
<a-select-option value="srtp">SRTP (Video Call)</a-select-option>
|
||||||
<td>
|
<a-select-option value="utp">uTP (Bittorrent)</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="wechat-video">WeChat Video</a-select-option>
|
||||||
<a-input v-model.trim="outbound.stream.quic.key" style="width: 250px;"></a-input>
|
<a-select-option value="dtls">DTLS (DTLS 1.2 packages)</a-select-option>
|
||||||
</a-form-item>
|
<a-select-option value="wireguard">WireGuard (WireGuard Packages)</a-select-option>
|
||||||
</td>
|
</a-select>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "camouflage" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="outbound.stream.quic.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="none">none (not camouflage)</a-select-option>
|
|
||||||
<a-select-option value="srtp">srtp (video call)</a-select-option>
|
|
||||||
<a-select-option value="utp">utp (BT download)</a-select-option>
|
|
||||||
<a-select-option value="wechat-video">wechat-video (WeChat video)</a-select-option>
|
|
||||||
<a-select-option value="dtls">dtls (DTLS 1.2 packages)</a-select-option>
|
|
||||||
<a-select-option value="wireguard">wireguard (wireguard packages)</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- grpc -->
|
<!-- grpc -->
|
||||||
<template v-if="outbound.stream.network === 'grpc'">
|
<template v-if="outbound.stream.network === 'grpc'">
|
||||||
<tr>
|
<a-form-item label='Service Name'>
|
||||||
<td>serviceName</td>
|
<a-input v-model.trim="outbound.stream.grpc.serviceName"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='Multi Mode'>
|
||||||
<a-input v-model.trim="outbound.stream.grpc.serviceName" style="width: 250px;"></a-input>
|
<a-switch v-model="outbound.stream.grpc.multiMode"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>MultiMode</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="outbound.stream.grpc.multiMode"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- tls settings -->
|
<!-- tls settings -->
|
||||||
<template v-if="outbound.canEnableTls()">
|
<template v-if="outbound.canEnableTls()">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "security" }}'>
|
||||||
<td>{{ i18n "security" }}</td>
|
<a-radio-group v-model="outbound.stream.security" button-style="solid">
|
||||||
<td>
|
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
|
||||||
<a-form-item>
|
<a-radio-button value="tls">TLS</a-radio-button>
|
||||||
<a-radio-group v-model="outbound.stream.security" button-style="solid">
|
<a-radio-button v-if="outbound.canEnableReality()" value="reality">Reality</a-radio-button>
|
||||||
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
|
</a-radio-group>
|
||||||
<a-radio-button value="tls">TLS</a-radio-button>
|
</a-form-item>
|
||||||
<a-radio-button v-if="outbound.canEnableReality()" value="reality">Reality</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="outbound.stream.isTls">
|
<template v-if="outbound.stream.isTls">
|
||||||
<tr>
|
<a-form-item label="SNI" placeholder="Server Name Indication">
|
||||||
<td>SNI</td>
|
<a-input v-model.trim="outbound.stream.tls.serverName"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item placeholder="Server Name Indication">
|
<a-form-item label="uTLS">
|
||||||
<a-input v-model.trim="outbound.stream.tls.serverName" style="width: 250px"></a-input>
|
<a-select v-model="outbound.stream.tls.fingerprint"
|
||||||
</a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</td>
|
<a-select-option value=''>None</a-select-option>
|
||||||
</tr>
|
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
||||||
<tr>
|
</a-select>
|
||||||
<td>uTLS</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label="ALPN">
|
||||||
<a-form-item>
|
<a-select
|
||||||
<a-select v-model="outbound.stream.tls.fingerprint"
|
mode="multiple"
|
||||||
style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value=''>None</a-select-option>
|
:dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
v-model="outbound.stream.tls.alpn">
|
||||||
</a-select>
|
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
|
||||||
</a-form-item>
|
</a-select>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item label="Allow Insecure">
|
||||||
<tr>
|
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch>
|
||||||
<td>ALPN</td>
|
</a-form-item>
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select
|
|
||||||
mode="multiple"
|
|
||||||
style="width: 250px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme"
|
|
||||||
v-model="outbound.stream.tls.alpn">
|
|
||||||
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Allow insecure</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- reality settings -->
|
<!-- reality settings -->
|
||||||
<template v-if="outbound.stream.isReality">
|
<template v-if="outbound.stream.isReality">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "domainName" }}'>
|
||||||
<td>{{ i18n "domainName" }}</td>
|
<a-input v-model.trim="outbound.stream.reality.serverName"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label="uTLS">
|
||||||
<a-input v-model.trim="outbound.stream.reality.serverName" style="width: 250px"></a-input>
|
<a-select v-model="outbound.stream.reality.fingerprint"
|
||||||
</a-form-item>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</td>
|
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
||||||
</tr>
|
</a-select>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>uTLS</td>
|
<a-form-item label="Short IDs">
|
||||||
<td>
|
<a-input v-model.trim="outbound.stream.reality.shortId" style="width:250px"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-select v-model="outbound.stream.reality.fingerprint"
|
<a-form-item label="SpiderX">
|
||||||
style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-input v-model.trim="outbound.stream.reality.spiderX" style="width:250px"></a-input>
|
||||||
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
</a-form-item>
|
||||||
</a-select>
|
<a-form-item label="Public Key">
|
||||||
</a-form-item>
|
<a-input v-model.trim="outbound.stream.reality.publicKey"></a-input>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Short Id</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.stream.reality.shortId" style="width:250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>SpiderX</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.stream.reality.spiderX" style="width:250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Public Key</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="outbound.stream.reality.publicKey" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="2" tab="JSON" force-render="true">
|
<a-tab-pane key="2" tab="JSON" force-render="true">
|
||||||
|
|||||||
@@ -1,42 +1,20 @@
|
|||||||
{{define "form/dokodemo"}}
|
{{define "form/dokodemo"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.inbounds.targetAddress"}}'>
|
||||||
<tr>
|
<a-input v-model.trim="inbound.settings.address"></a-input>
|
||||||
<td>{{ i18n "pages.inbounds.targetAddress"}}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='{{ i18n "pages.inbounds.destinationPort"}}'>
|
||||||
<a-form-item>
|
<a-input-number v-model.number="inbound.settings.port"></a-input-number>
|
||||||
<a-input v-model.trim="inbound.settings.address"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='{{ i18n "pages.inbounds.network"}}'>
|
||||||
</td>
|
<a-select v-model="inbound.settings.network" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</tr>
|
<a-select-option value="tcp,udp">TCP,UDP</a-select-option>
|
||||||
<tr>
|
<a-select-option value="tcp">TCP</a-select-option>
|
||||||
<td>{{ i18n "pages.inbounds.destinationPort"}}</td>
|
<a-select-option value="udp">UDP</a-select-option>
|
||||||
<td>
|
</a-select>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input-number v-model.number="inbound.settings.port"></a-input-number>
|
<a-form-item label='Follow Redirect'>
|
||||||
</a-form-item>
|
<a-switch v-model="inbound.settings.followRedirect"></a-switch>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.network"}}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="tcp,udp">tcp+udp</a-select-option>
|
|
||||||
<a-select-option value="tcp">tcp</a-select-option>
|
|
||||||
<a-select-option value="udp">udp</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>FollowRedirect</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.settings.followRedirect"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{{define "form/http"}}
|
{{define "form/http"}}
|
||||||
<a-form layout="inline">
|
<a-form>
|
||||||
<table style="width: 100%; text-align: center; margin-bottom: 10px;">
|
<table style="width: 100%; text-align: center; margin-bottom: 10px;">
|
||||||
<tr>
|
<tr>
|
||||||
<td width="45%">{{ i18n "username" }}</td>
|
<td width="45%">{{ i18n "username" }}</td>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{{define "form/shadowsocks"}}
|
{{define "form/shadowsocks"}}
|
||||||
<a-form layout="inline">
|
<template v-if="inbound.isSSMultiUser">
|
||||||
<template v-if="inbound.isSSMultiUser">
|
|
||||||
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.shadowsockses.slice(0,1)" v-if="!isEdit">
|
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.shadowsockses.slice(0,1)" v-if="!isEdit">
|
||||||
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
||||||
{{template "form/client"}}
|
{{template "form/client"}}
|
||||||
@@ -20,40 +19,29 @@
|
|||||||
</table>
|
</table>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
</template>
|
</template>
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "encryption" }}'>
|
||||||
<td>{{ i18n "encryption" }}</td>
|
<a-select v-model="inbound.settings.method" @change="SSMethodChange" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
|
||||||
<a-form-item>
|
</a-select>
|
||||||
<a-select v-model="inbound.settings.method" style="width: 250px;" @change="SSMethodChange" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="method in SSMethods" :value="method">[[ method ]]</a-select-option>
|
<a-form-item v-if="inbound.isSS2022">
|
||||||
</a-select>
|
<template slot="label">
|
||||||
</a-form-item>
|
<a-tooltip>
|
||||||
</td>
|
<template slot="title">
|
||||||
</tr>
|
<span>{{ i18n "password" }}</span>
|
||||||
<tr v-if="inbound.isSS2022">
|
</template> Password <a-icon @click="inbound.settings.password = RandomUtil.randomShadowsocksPassword()" type="sync"></a-icon>
|
||||||
<td>{{ i18n "password" }}
|
</a-tooltip>
|
||||||
<a-icon @click="inbound.settings.password = RandomUtil.randomShadowsocksPassword()" type="sync"> </a-icon>
|
</template>
|
||||||
</td>
|
<a-input v-model.trim="inbound.settings.password"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "pages.inbounds.network" }}'>
|
||||||
<a-input v-model.trim="inbound.settings.password" style="width: 250px"></a-input>
|
<a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</a-form-item>
|
<a-select-option value="tcp,udp">TCP,UDP</a-select-option>
|
||||||
</td>
|
<a-select-option value="tcp">TCP</a-select-option>
|
||||||
</tr>
|
<a-select-option value="udp">UDP</a-select-option>
|
||||||
<tr>
|
</a-select>
|
||||||
<td>{{ i18n "pages.inbounds.network" }}</td>
|
</a-form-item>
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.settings.network" style="width: 100px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="tcp,udp">tcp+udp</a-select-option>
|
|
||||||
<a-select-option value="tcp">tcp</a-select-option>
|
|
||||||
<a-select-option value="udp">udp</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,52 +1,33 @@
|
|||||||
{{define "form/socks"}}
|
{{define "form/socks"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.inbounds.enable" }} UDP'>
|
||||||
<tr>
|
<a-switch v-model="inbound.settings.udp"></a-switch>
|
||||||
<td style="width: 30%;">{{ i18n "password" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label="IP" v-if="inbound.settings.udp">
|
||||||
<a-form-item>
|
<a-input v-model.trim="inbound.settings.ip"></a-input>
|
||||||
<a-switch :checked="inbound.settings.auth === 'password'"
|
</a-form-item>
|
||||||
@change="checked => inbound.settings.auth = checked ? 'password' : 'noauth'"></a-switch>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
</a-form-item>
|
<a-switch :checked="inbound.settings.auth === 'password'"
|
||||||
</td>
|
@change="checked => inbound.settings.auth = checked ? 'password' : 'noauth'"></a-switch>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr v-if="inbound.settings.auth === 'password'">
|
<template v-if="inbound.settings.auth === 'password'">
|
||||||
<td colspan="2">
|
<table style="width: 100%; text-align: center; margin-bottom: 10px;">
|
||||||
<table style="width: 100%; text-align: center; margin-bottom: 10px;">
|
<tr>
|
||||||
<tr>
|
<td width="45%">{{ i18n "username" }}</td>
|
||||||
<td width="45%">{{ i18n "username" }}</td>
|
<td width="45%">{{ i18n "password" }}</td>
|
||||||
<td width="45%">{{ i18n "password" }}</td>
|
<td><a-button size="small" @click="inbound.settings.addAccount(new Inbound.SocksSettings.SocksAccount())">+</a-button></td>
|
||||||
<td><a-button size="small" @click="inbound.settings.addAccount(new Inbound.SocksSettings.SocksAccount())">+</a-button></td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
<a-input-group compact v-for="(account, index) in inbound.settings.accounts" style="margin-bottom: 10px;">
|
||||||
<a-input-group compact v-for="(account, index) in inbound.settings.accounts" style="margin-bottom: 10px;">
|
<a-input style="width: 50%" v-model.trim="account.user" placeholder='{{ i18n "username" }}'>
|
||||||
<a-input style="width: 50%" v-model.trim="account.user" placeholder='{{ i18n "username" }}'>
|
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||||
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
</a-input>
|
||||||
</a-input>
|
<a-input style="width: 50%" v-model.trim="account.pass" placeholder='{{ i18n "password" }}'>
|
||||||
<a-input style="width: 50%" v-model.trim="account.pass" placeholder='{{ i18n "password" }}'>
|
<template slot="addonAfter">
|
||||||
<template slot="addonAfter">
|
<a-button size="small" @click="inbound.settings.delAccount(index)">-</a-button>
|
||||||
<a-button size="small" @click="inbound.settings.delAccount(index)">-</a-button>
|
</template>
|
||||||
</template>
|
</a-input>
|
||||||
</a-input>
|
</a-input-group>
|
||||||
</a-input-group>
|
</template>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.enable" }} udp</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.settings.udp"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-if="inbound.settings.udp">
|
|
||||||
<td>IP</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.settings.ip"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,30 +1,29 @@
|
|||||||
{{define "form/trojan"}}
|
{{define "form/trojan"}}
|
||||||
<a-form layout="inline" style="padding: 10px 0px;">
|
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.trojans.slice(0,1)" v-if="!isEdit">
|
||||||
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.trojans.slice(0,1)" v-if="!isEdit">
|
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
||||||
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
{{template "form/client"}}
|
||||||
{{template "form/client"}}
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
<a-collapse v-else>
|
||||||
<a-collapse v-else>
|
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount"}} : ' + inbound.settings.trojans.length">
|
||||||
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount"}} : ' + inbound.settings.trojans.length">
|
<table width="100%">
|
||||||
<table width="100%">
|
<tr class="client-table-header">
|
||||||
<tr class="client-table-header">
|
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
<th>Password</th>
|
||||||
<th>Password</th>
|
</tr>
|
||||||
</tr>
|
<tr v-for="(client, index) in inbound.settings.trojans" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||||
<tr v-for="(client, index) in inbound.settings.trojans" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
<td>[[ client.email ]]</td>
|
||||||
<td>[[ client.email ]]</td>
|
<td>[[ client.password ]]</td>
|
||||||
<td>[[ client.password ]]</td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
<template v-if="inbound.isTcp && !inbound.stream.isReality">
|
||||||
</a-form>
|
|
||||||
<template v-if="inbound.isTcp">
|
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
<a-form-item label="Fallbacks">
|
<a-form-item label="Fallbacks">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-button type="primary" size="small" @click="inbound.settings.addFallback()">
|
<a-button type="primary" size="small"
|
||||||
|
@click="inbound.settings.addFallback()">
|
||||||
+
|
+
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -32,54 +31,27 @@
|
|||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<!-- trojan fallbacks -->
|
<!-- trojan fallbacks -->
|
||||||
<a-form v-for="(fallback, index) in inbound.settings.fallbacks" layout="inline">
|
<a-form v-for="(fallback, index) in inbound.settings.fallbacks" :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-divider style="margin:0;">
|
<a-divider style="margin:0;">
|
||||||
fallback[[ index + 1 ]]
|
Fallback [[ index + 1 ]]
|
||||||
<a-icon type="delete" @click="() => inbound.settings.delFallback(index)"
|
<a-icon type="delete" @click="() => inbound.settings.delFallback(index)"
|
||||||
style="color: rgb(255, 77, 79);cursor: pointer;"/>
|
style="color: rgb(255, 77, 79);cursor: pointer;"/>
|
||||||
</a-divider>
|
</a-divider>
|
||||||
<table width="100%">
|
<a-form-item label='Name'>
|
||||||
<tr>
|
<a-input v-model="fallback.name"></a-input>
|
||||||
<td style="width: 20%;">Name</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='ALPN'>
|
||||||
<a-form-item>
|
<a-input v-model="fallback.alpn"></a-input>
|
||||||
<a-input v-model="fallback.name" style="width: 250px"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='Path'>
|
||||||
</td>
|
<a-input v-model="fallback.path"></a-input>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
<a-form-item label='Dest'>
|
||||||
<td>Alpn</td>
|
<a-input v-model="fallback.dest"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='xVer'>
|
||||||
<a-input v-model="fallback.alpn" style="width: 250px"></a-input>
|
<a-input-number v-model="fallback.xver" :min="0" :max="2"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Path</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model="fallback.path" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Dest</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model="fallback.dest" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>xVer</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="fallback.xver" :min="0" :max="2"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-divider style="margin:0;"></a-divider>
|
<a-divider style="margin:0;"></a-divider>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,32 +1,31 @@
|
|||||||
{{define "form/vless"}}
|
{{define "form/vless"}}
|
||||||
<a-form layout="inline" style="padding: 10px 0px;">
|
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.vlesses.slice(0,1)" v-if="!isEdit">
|
||||||
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.vlesses.slice(0,1)" v-if="!isEdit">
|
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
||||||
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
{{template "form/client"}}
|
||||||
{{template "form/client"}}
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
<a-collapse v-else>
|
||||||
<a-collapse v-else>
|
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount"}} : ' + inbound.settings.vlesses.length">
|
||||||
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount"}} : ' + inbound.settings.vlesses.length">
|
<table width="100%">
|
||||||
<table width="100%">
|
<tr class="client-table-header">
|
||||||
<tr class="client-table-header">
|
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
<th>Flow</th>
|
||||||
<th>Flow</th>
|
<th>ID</th>
|
||||||
<th>ID</th>
|
</tr>
|
||||||
</tr>
|
<tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||||
<tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
<td>[[ client.email ]]</td>
|
||||||
<td>[[ client.email ]]</td>
|
<td>[[ client.flow ]]</td>
|
||||||
<td>[[ client.flow ]]</td>
|
<td>[[ client.id ]]</td>
|
||||||
<td>[[ client.id ]]</td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
<template v-if="inbound.isTcp && !inbound.stream.isReality">
|
||||||
</a-form>
|
|
||||||
<template v-if="inbound.isTcp">
|
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
<a-form-item label="Fallbacks">
|
<a-form-item label="Fallbacks">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-button type="primary" size="small" @click="inbound.settings.addFallback()">
|
<a-button type="primary" size="small"
|
||||||
|
@click="inbound.settings.addFallback()">
|
||||||
+
|
+
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -34,55 +33,28 @@
|
|||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<!-- vless fallbacks -->
|
<!-- vless fallbacks -->
|
||||||
<a-form v-for="(fallback, index) in inbound.settings.fallbacks" layout="inline">
|
<a-form v-for="(fallback, index) in inbound.settings.fallbacks" :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-divider style="margin:0;">
|
<a-divider style="margin:0;">
|
||||||
fallback[[ index + 1 ]]
|
Fallback [[ index + 1 ]]
|
||||||
<a-icon type="delete" @click="() => inbound.settings.delFallback(index)"
|
<a-icon type="delete" @click="() => inbound.settings.delFallback(index)"
|
||||||
style="color: rgb(255, 77, 79);cursor: pointer;"/>
|
style="color: rgb(255, 77, 79);cursor: pointer;"/>
|
||||||
</a-divider>
|
</a-divider>
|
||||||
<table width="100%">
|
<a-form-item label='Name'>
|
||||||
<tr>
|
<a-input v-model="fallback.name"></a-input>
|
||||||
<td style="width: 20%;">Name</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='ALPN'>
|
||||||
<a-form-item>
|
<a-input v-model="fallback.alpn"></a-input>
|
||||||
<a-input v-model="fallback.name" style="width: 250px"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='Path'>
|
||||||
</td>
|
<a-input v-model="fallback.path"></a-input>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
<a-form-item label='Dest'>
|
||||||
<td>Alpn</td>
|
<a-input v-model="fallback.dest"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='xVer'>
|
||||||
<a-input v-model="fallback.alpn" style="width: 250px"></a-input>
|
<a-input-number v-model="fallback.xver" :min="0" :max="2"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Path</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model="fallback.path" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Dest</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model="fallback.dest" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>xVer</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="fallback.xver" :min="0" :max="2"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-divider style="margin:0;"></a-divider>
|
<a-divider style="margin:5px 0;"></a-divider>
|
||||||
</template>
|
</template>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
{{define "form/vmess"}}
|
{{define "form/vmess"}}
|
||||||
<a-form layout="inline" style="padding: 10px 0px;">
|
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.vmesses.slice(0,1)" v-if="!isEdit">
|
||||||
<a-collapse activeKey="0" v-for="(client, index) in inbound.settings.vmesses.slice(0,1)" v-if="!isEdit">
|
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
||||||
<a-collapse-panel header='{{ i18n "pages.inbounds.client" }}'>
|
{{template "form/client"}}
|
||||||
{{template "form/client"}}
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
<a-collapse v-else>
|
||||||
<a-collapse v-else>
|
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount"}} : ' + inbound.settings.vmesses.length">
|
||||||
<a-collapse-panel :header="'{{ i18n "pages.client.clientCount" }}: ' + inbound.settings.vmesses.length">
|
<table width="100%">
|
||||||
<table width="100%">
|
<tr class="client-table-header">
|
||||||
<tr class="client-table-header">
|
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
<th>ID</th>
|
||||||
<th>ID</th>
|
</tr>
|
||||||
</tr>
|
<tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||||
<tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
<td>[[ client.email ]]</td>
|
||||||
<td>[[ client.email ]]</td>
|
<td>[[ client.id ]]</td>
|
||||||
<td>[[ client.id ]]</td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
</a-collapse-panel>
|
||||||
</a-collapse-panel>
|
</a-collapse>
|
||||||
</a-collapse>
|
|
||||||
</a-form>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
{{define "form/sniffing"}}
|
{{define "form/sniffing"}}
|
||||||
<a-form layout="inline">
|
<a-divider style="margin:5px 0 0;"></a-divider>
|
||||||
<a-form-item>
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<span slot="label">
|
<a-form-item>
|
||||||
Sniffing
|
<span slot="label">
|
||||||
<a-tooltip>
|
Sniffing
|
||||||
<template slot="title">
|
<a-tooltip>
|
||||||
<span>{{ i18n "pages.inbounds.noRecommendKeepDefault" }}</span>
|
<template slot="title">
|
||||||
</template>
|
<span>{{ i18n "pages.inbounds.noRecommendKeepDefault" }}</span>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
</template>
|
||||||
</a-tooltip>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</span>
|
</a-tooltip>
|
||||||
<a-switch v-model="inbound.sniffing.enabled"></a-switch>
|
</span>
|
||||||
</a-form-item>
|
<a-switch v-model="inbound.sniffing.enabled"></a-switch>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-checkbox-group v-model="inbound.sniffing.destOverride" v-if="inbound.sniffing.enabled">
|
<a-form-item :wrapper-col="{span:24}">
|
||||||
<a-checkbox v-for="key,value in SNIFFING_OPTION" :value="key">[[ value ]]</a-checkbox>
|
<a-checkbox-group v-model="inbound.sniffing.destOverride" v-if="inbound.sniffing.enabled">
|
||||||
</a-checkbox-group>
|
<a-checkbox v-for="key,value in SNIFFING_OPTION" :value="key">[[ value ]]</a-checkbox>
|
||||||
</a-form-item>
|
</a-checkbox-group>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,32 +1,26 @@
|
|||||||
{{define "form/externalProxy"}}
|
{{define "form/externalProxy"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-divider style="margin:0;"></a-divider>
|
<a-divider style="margin:5px 0 0;"></a-divider>
|
||||||
<a-form-item label="External Proxy">
|
<a-form-item label="External Proxy">
|
||||||
<a-switch v-model="externalProxy"></a-switch>
|
<a-switch v-model="externalProxy"></a-switch>
|
||||||
<a-button v-if="externalProxy" type="primary" style="margin-left: 10px" size="small" @click="inbound.stream.externalProxy.push({forceTls: 'same', dest: '', port: 443, remark: ''})">+</a-button>
|
<a-button v-if="externalProxy" type="primary" style="margin-left: 10px" size="small" @click="inbound.stream.externalProxy.push({forceTls: 'same', dest: '', port: 443, remark: ''})">+</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<table width="100%" class="ant-table-tbody" v-if="externalProxy" style="margin-bottom:5px">
|
<a-input-group style="margin: 8px 0;" compact v-for="(row, index) in inbound.stream.externalProxy">
|
||||||
<tr style="line-height: 40px;">
|
<template>
|
||||||
<td width="100%">
|
<a-tooltip title="Force TLS">
|
||||||
<a-input-group style="margin: 0 5px;" compact v-for="(row, index) in inbound.stream.externalProxy">
|
<a-select v-model="row.forceTls" style="width:20%; margin: 0px" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<template>
|
<a-select-option value="same">{{ i18n "pages.inbounds.same" }}</a-select-option>
|
||||||
<a-tooltip title="Force TLS">
|
<a-select-option value="none">{{ i18n "none" }}</a-select-option>
|
||||||
<a-select v-model="row.forceTls" style="width:20%; margin: 0px" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option value="tls">TLS</a-select-option>
|
||||||
<a-select-option value="same">{{ i18n "pages.inbounds.same" }}</a-select-option>
|
</a-select>
|
||||||
<a-select-option value="none">{{ i18n "none" }}</a-select-option>
|
</a-tooltip>
|
||||||
<a-select-option value="tls">TLS</a-select-option>
|
</template>
|
||||||
</a-select>
|
<a-input style="width: 35%" v-model.trim="row.dest" placeholder='{{ i18n "host" }}'></a-input>
|
||||||
</a-tooltip>
|
<a-tooltip title='{{ i18n "pages.inbounds.port" }}'>
|
||||||
</template>
|
<a-input-number style="width: 15%;" v-model.number="row.port" min="1" max="65531"></a-input-number>
|
||||||
<a-input style="width: 35%" v-model.trim="row.dest" placeholder='{{ i18n "host" }}'></a-input>
|
</a-tooltip>
|
||||||
<a-tooltip title='{{ i18n "pages.inbounds.port" }}'>
|
<a-input style="width: 20%" v-model.trim="row.remark" placeholder='{{ i18n "remark" }}'></a-input>
|
||||||
<a-input-number style="width: 15%;" v-model.number="row.port" min="1" max="65531"></a-input-number>
|
<a-button style="width: 10%; margin: 0px" @click="inbound.stream.externalProxy.splice(index, 1)">-</a-button>
|
||||||
</a-tooltip>
|
</a-input-group>
|
||||||
<a-input style="width: 20%" v-model.trim="row.remark" placeholder='{{ i18n "remark" }}'></a-input>
|
|
||||||
<a-button style="width: 10%; margin: 0px" @click="inbound.stream.externalProxy.splice(index, 1)">-</a-button>
|
|
||||||
</a-input-group>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
{{define "form/streamGRPC"}}
|
{{define "form/streamGRPC"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label="Service Name">
|
||||||
<tr>
|
<a-input v-model.trim="inbound.stream.grpc.serviceName"></a-input>
|
||||||
<td>serviceName</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label="Multi Mode">
|
||||||
<a-form-item>
|
<a-switch v-model="inbound.stream.grpc.multiMode"></a-switch>
|
||||||
<a-input v-model.trim="inbound.stream.grpc.serviceName" style="width: 250px;"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>MultiMode</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.stream.grpc.multiMode"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,24 +1,19 @@
|
|||||||
{{define "form/streamHTTP"}}
|
{{define "form/streamHTTP"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<tr>
|
<a-input v-model.trim="inbound.stream.http.path"></a-input>
|
||||||
<td>{{ i18n "path" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item>
|
||||||
<a-form-item>
|
<template slot="label">{{ i18n "host" }}
|
||||||
<a-input v-model.trim="inbound.stream.http.path" style="width: 250px;"></a-input>
|
<a-button size="small" @click="inbound.stream.http.addHost()">+</a-button>
|
||||||
</a-form-item>
|
</template>
|
||||||
</td>
|
<template v-for="(host, index) in inbound.stream.http.host">
|
||||||
</tr>
|
<a-input v-model.trim="inbound.stream.http.host[index]">
|
||||||
<tr>
|
<a-button size="small" slot="addonAfter"
|
||||||
<td>host</td>
|
@click="inbound.stream.http.removeHost(index)"
|
||||||
<td>
|
v-if="inbound.stream.http.host.length>1">-</a-button>
|
||||||
<a-form-item>
|
</a-input>
|
||||||
<a-row v-for="(host, index) in inbound.stream.http.host">
|
</template>
|
||||||
<a-input v-model.trim="inbound.stream.http.host[index]" style="width: 250px;"></a-input>
|
</a-form-item>
|
||||||
</a-row>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,86 +1,38 @@
|
|||||||
{{define "form/streamKCP"}}
|
{{define "form/streamKCP"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "camouflage" }}'>
|
||||||
<tr>
|
<a-select v-model="inbound.stream.kcp.type" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>{{ i18n "camouflage" }}</td>
|
<a-select-option value="none">none (No Obfuscation)</a-select-option>
|
||||||
<td>
|
<a-select-option value="srtp">SRTP (Video Call)</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="utp">uTP (Bittorrent)</a-select-option>
|
||||||
<a-select v-model="inbound.stream.kcp.type" style="width: 250px;"
|
<a-select-option value="wechat-video">WeChat Video</a-select-option>
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option value="dtls">DTLS (DTLS 1.2 packages)</a-select-option>
|
||||||
<a-select-option value="none">None (Not Camouflage)</a-select-option>
|
<a-select-option value="wireguard">WireGuard (WireGuard packages)</a-select-option>
|
||||||
<a-select-option value="srtp">SRTP (Camouflage Video Call)</a-select-option>
|
</a-select>
|
||||||
<a-select-option value="utp">UTP (Camouflage BT Download)</a-select-option>
|
</a-form-item>
|
||||||
<a-select-option value="wechat-video">Wechat-Video (Camouflage WeChat Video)</a-select-option>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
<a-select-option value="dtls">DTLS (Camouflage DTLS 1.2 Packages)</a-select-option>
|
<a-input v-model="inbound.stream.kcp.seed"></a-input>
|
||||||
<a-select-option value="wireguard">Wireguard (Camouflage Wireguard Packages)</a-select-option>
|
</a-form-item>
|
||||||
</a-select>
|
<a-form-item label='MTU'>
|
||||||
</a-form-item>
|
<a-input-number v-model.number="inbound.stream.kcp.mtu"></a-input-number>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item label='TTI (ms)'>
|
||||||
<tr>
|
<a-input-number v-model.number="inbound.stream.kcp.tti"></a-input-number>
|
||||||
<td>{{ i18n "password" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='Uplink (MB/s)'>
|
||||||
<a-form-item>
|
<a-input-number v-model.number="inbound.stream.kcp.upCap"></a-input-number>
|
||||||
<a-input v-model="inbound.stream.kcp.seed" style="width: 250px;"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='Downlink (MB/s)'>
|
||||||
</td>
|
<a-input-number v-model.number="inbound.stream.kcp.downCap"></a-input-number>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
<a-form-item label='Congestion'>
|
||||||
<td>MTU</td>
|
<a-switch v-model="inbound.stream.kcp.congestion"></a-switch>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='Read Buffer (MB)'>
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.mtu"></a-input-number>
|
<a-input-number v-model.number="inbound.stream.kcp.readBuffer"></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='Write Buffer (MB)'>
|
||||||
</tr>
|
<a-input-number v-model.number="inbound.stream.kcp.writeBuffer"></a-input-number>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>TTI (ms)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.tti"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Uplink Capacity (MB/S)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.upCap"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Downlink Capacity (MB/S)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.downCap"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Congestion</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.stream.kcp.congestion"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Read Buffer Size (MB)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.readBuffer"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Write Buffer Size (MB)</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="inbound.stream.kcp.writeBuffer"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,43 +1,24 @@
|
|||||||
{{define "form/streamQUIC"}}
|
{{define "form/streamQUIC"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.inbounds.stream.quic.encryption" }}'>
|
||||||
<tr>
|
<a-select v-model="inbound.stream.quic.security" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>{{ i18n "pages.inbounds.stream.quic.encryption" }}</td>
|
<a-select-option value="none">none</a-select-option>
|
||||||
<td>
|
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
|
||||||
<a-select v-model="inbound.stream.quic.security" style="width: 250px;"
|
</a-select>
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option value="none">none</a-select-option>
|
<a-form-item label='{{ i18n "password" }}'>
|
||||||
<a-select-option value="aes-128-gcm">aes-128-gcm</a-select-option>
|
<a-input v-model.trim="inbound.stream.quic.key"></a-input>
|
||||||
<a-select-option value="chacha20-poly1305">chacha20-poly1305</a-select-option>
|
</a-form-item>
|
||||||
</a-select>
|
<a-form-item label='{{ i18n "camouflage" }}'>
|
||||||
</a-form-item>
|
<a-select v-model="inbound.stream.quic.type" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</td>
|
<a-select-option value="none">none (No Obfuscation)</a-select-option>
|
||||||
</tr>
|
<a-select-option value="srtp">SRTP (Video Call)</a-select-option>
|
||||||
<tr>
|
<a-select-option value="utp">uTP (Bittorrent)</a-select-option>
|
||||||
<td>{{ i18n "password" }}</td>
|
<a-select-option value="wechat-video">WeChat Video</a-select-option>
|
||||||
<td>
|
<a-select-option value="dtls">DTLS (DTLS 1.2 packages)</a-select-option>
|
||||||
<a-form-item>
|
<a-select-option value="wireguard">WireGuard (WireGuard Packages)</a-select-option>
|
||||||
<a-input v-model.trim="inbound.stream.quic.key" style="width: 250px;"></a-input>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "camouflage" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.stream.quic.type" style="width: 280px;"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="none">none (not camouflage)</a-select-option>
|
|
||||||
<a-select-option value="srtp">srtp (camouflage video call)</a-select-option>
|
|
||||||
<a-select-option value="utp">utp (camouflage BT download)</a-select-option>
|
|
||||||
<a-select-option value="wechat-video">wechat-video (camouflage WeChat video)</a-select-option>
|
|
||||||
<a-select-option value="dtls">dtls (camouflage DTLS 1.2 packages)</a-select-option>
|
|
||||||
<a-select-option value="wireguard">wireguard (camouflage wireguard packages)</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
{{define "form/streamSettings"}}
|
{{define "form/streamSettings"}}
|
||||||
<!-- select stream network -->
|
<!-- select stream network -->
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-form-item label='{{ i18n "transmission" }}'>
|
<a-form-item label="{{ i18n "transmission" }}">
|
||||||
<a-select v-model="inbound.stream.network" @change="streamNetworkChange"
|
<a-select v-model="inbound.stream.network" @change="streamNetworkChange"
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme" style="width: 100px;">
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select-option value="tcp">TCP</a-select-option>
|
<a-select-option value="tcp">TCP</a-select-option>
|
||||||
<a-select-option value="kcp">KCP</a-select-option>
|
<a-select-option value="kcp">KCP</a-select-option>
|
||||||
<a-select-option value="ws">WS</a-select-option>
|
<a-select-option value="ws">WS</a-select-option>
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
<template v-if="inbound.stream.network === 'grpc'">
|
<template v-if="inbound.stream.network === 'grpc'">
|
||||||
{{template "form/streamGRPC"}}
|
{{template "form/streamGRPC"}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- sockopt -->
|
<!-- sockopt -->
|
||||||
<template>
|
<template>
|
||||||
{{template "form/streamSockopt"}}
|
{{template "form/streamSockopt"}}
|
||||||
|
|||||||
@@ -1,46 +1,26 @@
|
|||||||
{{define "form/streamSockopt"}}
|
{{define "form/streamSockopt"}}
|
||||||
<a-form layout="inline">
|
<a-divider style="margin:5px 0 0;"></a-divider>
|
||||||
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-form-item label="Transparent Proxy">
|
<a-form-item label="Transparent Proxy">
|
||||||
<a-switch v-model="inbound.stream.sockoptSwitch"></a-switch>
|
<a-switch v-model="inbound.stream.sockoptSwitch"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<table width="100%" class="ant-table-tbody" v-if="inbound.stream.sockoptSwitch">
|
<template v-if="inbound.stream.sockoptSwitch">
|
||||||
<tr>
|
<a-form-item label="Accept Proxy Protocol">
|
||||||
<td>Accept Proxy Protocol</td>
|
<a-switch v-model="inbound.stream.sockopt.acceptProxyProtocol"></a-switch>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label="TCP FastOpen">
|
||||||
<a-switch v-model="inbound.stream.sockopt.acceptProxyProtocol"></a-switch>
|
<a-switch v-model.trim="inbound.stream.sockopt.tcpFastOpen"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label="Route Mark">
|
||||||
</tr>
|
<a-input-number v-model="inbound.stream.sockopt.mark" :min="0"></a-input-number>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>TCP FastOpen</td>
|
<a-form-item label="T-Proxy">
|
||||||
<td>
|
<a-select v-model="inbound.stream.sockopt.tproxy" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-form-item>
|
<a-select-option value="off">OFF</a-select-option>
|
||||||
<a-switch v-model.trim="inbound.stream.sockopt.tcpFastOpen"></a-switch>
|
<a-select-option value="redirect">Redirect</a-select-option>
|
||||||
</a-form-item>
|
<a-select-option value="tproxy">T-Proxy</a-select-option>
|
||||||
</td>
|
</a-select>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
</template>
|
||||||
<td>Route Mark</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="inbound.stream.sockopt.mark" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>T-Proxy</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.stream.sockopt.tproxy" style="width: 250px;"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value="off">OFF</a-select-option>
|
|
||||||
<a-select-option value="redirect">Redirect</a-select-option>
|
|
||||||
<a-select-option value="tproxy">T-Proxy</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,113 +1,76 @@
|
|||||||
{{define "form/streamTCP"}}
|
{{define "form/streamTCP"}}
|
||||||
<!-- tcp type -->
|
<!-- tcp type -->
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-form-item label="Accept Proxy Protocol" v-if="inbound.canEnableTls()">
|
<a-form-item label="Accept Proxy Protocol" v-if="inbound.canEnableTls()">
|
||||||
<a-switch v-model="inbound.stream.tcp.acceptProxyProtocol"></a-switch>
|
<a-switch v-model="inbound.stream.tcp.acceptProxyProtocol"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label='HTTP {{ i18n "camouflage" }}'>
|
<a-form-item label='HTTP {{ i18n "camouflage" }}'>
|
||||||
<a-switch
|
<a-switch
|
||||||
:checked="inbound.stream.tcp.type === 'http'"
|
:checked="inbound.stream.tcp.type === 'http'"
|
||||||
@change="checked => inbound.stream.tcp.type = checked ? 'http' : 'none'">
|
@change="checked => inbound.stream.tcp.type = checked ? 'http' : 'none'">
|
||||||
</a-switch>
|
</a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<!-- tcp request -->
|
<!-- tcp request -->
|
||||||
<a-form v-if="inbound.stream.tcp.type === 'http'" layout="inline">
|
<a-form v-if="inbound.stream.tcp.type === 'http'" :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.requestVersion" }}'>
|
||||||
<tr>
|
<a-input v-model.trim="inbound.stream.tcp.request.version"></a-input>
|
||||||
<td>{{ i18n "pages.inbounds.stream.tcp.requestVersion" }}</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.requestMethod" }}'>
|
||||||
<a-form-item>
|
<a-input v-model.trim="inbound.stream.tcp.request.method"></a-input>
|
||||||
<a-input v-model.trim="inbound.stream.tcp.request.version" style="width: 200px;"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item>
|
||||||
</td>
|
<template slot="label">{{ i18n "pages.inbounds.stream.tcp.requestPath" }}
|
||||||
</tr>
|
<a-button size="small" @click="inbound.stream.tcp.request.addPath('/')">+</a-button>
|
||||||
<tr>
|
</template>
|
||||||
<td>{{ i18n "pages.inbounds.stream.tcp.requestMethod" }}</td>
|
<template v-for="(path, index) in inbound.stream.tcp.request.path">
|
||||||
<td>
|
<a-input v-model.trim="inbound.stream.tcp.request.path[index]">
|
||||||
<a-form-item>
|
<a-button size="small" slot="addonAfter"
|
||||||
<a-input v-model.trim="inbound.stream.tcp.request.method" style="width: 200px;"></a-input>
|
@click="inbound.stream.tcp.request.removePath(index)"
|
||||||
</a-form-item>
|
v-if="inbound.stream.tcp.request.path.length>1">-</a-button>
|
||||||
</td>
|
</a-input>
|
||||||
</tr>
|
</template>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td style="vertical-align: top; padding-top: 10px;">{{ i18n "pages.inbounds.stream.tcp.requestPath" }}
|
<a-form-item label='{{ i18n "pages.inbounds.stream.general.requestHeader" }}'>
|
||||||
<a-button size="small" @click="inbound.stream.tcp.request.addPath('/')">+</a-button>
|
<a-button size="small" @click="inbound.stream.tcp.request.addHeader('', '')">+</a-button>
|
||||||
</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item :wrapper-col="{span:24}">
|
||||||
<a-form-item>
|
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.request.headers">
|
||||||
<a-row v-for="(path, index) in inbound.stream.tcp.request.path">
|
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.tcp.request.path[index]" style="width: 200px;">
|
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||||
<a-button size="small" slot="addonAfter"
|
</a-input>
|
||||||
@click="inbound.stream.tcp.request.removePath(index)"
|
<a-input style="width: 50%" v-model.trim="header.value" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
||||||
v-if="inbound.stream.tcp.request.path.length>1">-</a-button>
|
<a-button slot="addonAfter" size="small" @click="inbound.stream.tcp.request.removeHeader(index)">-</a-button>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-row>
|
</a-input-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" width="100%">
|
|
||||||
<a-form-item>
|
|
||||||
<span>{{ i18n "pages.inbounds.stream.general.requestHeader" }}:</span>
|
|
||||||
<a-button size="small" style="margin-left: 10px" @click="inbound.stream.tcp.request.addHeader('', '')">+</a-button>
|
|
||||||
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.request.headers">
|
|
||||||
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
|
||||||
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
|
||||||
</a-input>
|
|
||||||
<a-input style="width: 50%" v-model.trim="header.value" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
|
||||||
<a-button slot="addonAfter" size="small" @click="inbound.stream.tcp.request.removeHeader(index)">-</a-button>
|
|
||||||
</a-input>
|
|
||||||
</a-input-group>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<!-- tcp response -->
|
<!-- tcp response -->
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.responseVersion" }}'>
|
||||||
<td>{{ i18n "pages.inbounds.stream.tcp.responseVersion" }}</td>
|
<a-input v-model.trim="inbound.stream.tcp.response.version"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.responseStatus" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.tcp.response.version" style="width: 200px;"></a-input>
|
<a-input v-model.trim="inbound.stream.tcp.response.status"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.responseStatusDescription" }}'>
|
||||||
</tr>
|
<a-input v-model.trim="inbound.stream.tcp.response.reason"></a-input>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>{{ i18n "pages.inbounds.stream.tcp.responseStatus" }}</td>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.tcp.responseHeader" }}'>
|
||||||
<td>
|
<a-button size="small"
|
||||||
<a-form-item>
|
@click="inbound.stream.tcp.response.addHeader('Content-Type', 'application/octet-stream')">+</a-button>
|
||||||
<a-input v-model.trim="inbound.stream.tcp.response.status" style="width: 200px;"></a-input>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item :wrapper-col="{span:24}">
|
||||||
</td>
|
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.response.headers">
|
||||||
</tr>
|
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
||||||
<tr>
|
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||||
<td>{{ i18n "pages.inbounds.stream.tcp.responseStatusDescription" }}</td>
|
</a-input>
|
||||||
<td>
|
<a-input style="width: 50%" v-model.trim="header.value"
|
||||||
<a-form-item>
|
placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.tcp.response.reason" style="width: 200px;"></a-input>
|
<template slot="addonAfter">
|
||||||
</a-form-item>
|
<a-button size="small" @click="inbound.stream.tcp.response.removeHeader(index)">-</a-button>
|
||||||
</td>
|
</template>
|
||||||
</tr>
|
</a-input>
|
||||||
<tr>
|
</a-input-group>
|
||||||
<td colspan="2" width="100%">
|
</a-form-item>
|
||||||
<a-form-item>
|
|
||||||
<span>{{ i18n "pages.inbounds.stream.tcp.responseHeader" }}:</span>
|
|
||||||
<a-button size="small" style="margin-left: 10px"
|
|
||||||
@click="inbound.stream.tcp.response.addHeader('Content-Type', 'application/octet-stream')">+</a-button>
|
|
||||||
<a-input-group compact v-for="(header, index) in inbound.stream.tcp.response.headers">
|
|
||||||
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
|
||||||
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
|
||||||
</a-input>
|
|
||||||
<a-input style="width: 50%" v-model.trim="header.value"
|
|
||||||
placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
|
||||||
<template slot="addonAfter">
|
|
||||||
<a-button size="small" @click="inbound.stream.tcp.response.removeHeader(index)">-</a-button>
|
|
||||||
</template>
|
|
||||||
</a-input>
|
|
||||||
</a-input-group>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -1,28 +1,21 @@
|
|||||||
{{define "form/streamWS"}}
|
{{define "form/streamWS"}}
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<a-form-item label="AcceptProxyProtocol">
|
<a-form-item label="Accept Proxy Protocol">
|
||||||
<a-switch v-model="inbound.stream.ws.acceptProxyProtocol"></a-switch>
|
<a-switch v-model="inbound.stream.ws.acceptProxyProtocol"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<br>
|
|
||||||
<a-form-item label='{{ i18n "path" }}'>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="inbound.stream.ws.path"></a-input>
|
<a-input v-model.trim="inbound.stream.ws.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<br>
|
<a-form-item label='{{ i18n "pages.inbounds.stream.general.requestHeader" }}'>
|
||||||
<a-form-item>
|
<a-button size="small" @click="inbound.stream.ws.addHeader()">+</a-button>
|
||||||
<a-row>
|
</a-form-item>
|
||||||
<span>{{ i18n "pages.inbounds.stream.general.requestHeader" }}:</span>
|
<a-form-item :wrapper-col="{span:24}">
|
||||||
<a-button type="primary" size="small" style="margin-left: 10px"
|
<a-input-group compact v-for="(header, index) in inbound.stream.ws.headers">
|
||||||
@click="inbound.stream.ws.addHeader('Host', '')">+</a-button>
|
<a-input style="width: 50%" v-model.trim="header.name" placeholder='{{ i18n "pages.inbounds.stream.general.name"}}'>
|
||||||
</a-row>
|
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||||
<a-input-group v-for="(header, index) in inbound.stream.ws.headers">
|
</a-input>
|
||||||
<a-input style="width: 50%" v-model.trim="header.name"
|
<a-input style="width: 50%" v-model.trim="header.value" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
||||||
addon-before='{{ i18n "pages.inbounds.stream.general.name"}}'></a-input>
|
<a-button slot="addonAfter" size="small" @click="inbound.stream.ws.removeHeader(index)">-</a-button>
|
||||||
<a-input style="width: 50%" v-model.trim="header.value"
|
|
||||||
addon-before='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
|
||||||
<template slot="addonAfter">
|
|
||||||
<a-button type="primary" size="small" style="margin-left: 10px"
|
|
||||||
@click="inbound.stream.ws.removeHeader(index)">-</a-button>
|
|
||||||
</template>
|
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|||||||
@@ -1,395 +1,194 @@
|
|||||||
{{define "form/tlsSettings"}}
|
{{define "form/tlsSettings"}}
|
||||||
<!-- tls enable -->
|
<!-- tls enable -->
|
||||||
|
<a-form v-if="inbound.canEnableTls()" :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||||
|
<a-divider style="margin:3px 0;"></a-divider>
|
||||||
|
<a-form-item label='{{ i18n "security" }}'>
|
||||||
|
<a-radio-group v-model="inbound.stream.security" button-style="solid">
|
||||||
|
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.xtlsDesc" }}</span>
|
||||||
|
</template>
|
||||||
|
<a-radio-button v-if="inbound.canEnableXtls()" value="xtls">XTLS</a-radio-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template slot="title">
|
||||||
|
<span>{{ i18n "pages.inbounds.realityDesc" }}</span>
|
||||||
|
</template>
|
||||||
|
<a-radio-button v-if="inbound.canEnableReality()" value="reality">Reality</a-radio-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-radio-button value="tls">TLS</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<a-form v-if="inbound.canEnableTls()" layout="inline">
|
<!-- tls settings -->
|
||||||
<a-divider style="margin:0;"></a-divider>
|
<template v-if="inbound.stream.isTls">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label="SNI" placeholder="Server Name Indication">
|
||||||
<tr>
|
<a-input v-model.trim="inbound.stream.tls.sni"></a-input>
|
||||||
<td colspan="2">
|
</a-form-item>
|
||||||
<a-form-item label='{{ i18n "security" }}'>
|
<a-form-item label="CipherSuites">
|
||||||
<a-radio-group v-model="inbound.stream.security" button-style="solid">
|
<a-select v-model="inbound.stream.tls.cipherSuites" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
|
<a-select-option value="">auto</a-select-option>
|
||||||
<a-tooltip>
|
<a-select-option v-for="key,value in TLS_CIPHER_OPTION" :value="key">[[ value ]]</a-select-option>
|
||||||
<template slot="title">
|
</a-select>
|
||||||
<span>{{ i18n "pages.inbounds.xtlsDesc" }}</span>
|
</a-form-item>
|
||||||
</template>
|
<a-form-item label="Min/Max Version">
|
||||||
<a-radio-button v-if="inbound.canEnableXtls()" value="xtls">XTLS</a-radio-button>
|
<a-input-group compact>
|
||||||
</a-tooltip>
|
<a-select v-model="inbound.stream.tls.minVersion" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-tooltip>
|
<a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
<template slot="title">
|
</a-select>
|
||||||
<span>{{ i18n "pages.inbounds.realityDesc" }}</span>
|
<a-select v-model="inbound.stream.tls.maxVersion" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</template>
|
<a-select-option v-for="key in TLS_VERSION_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
<a-radio-button v-if="inbound.canEnableReality()" value="reality">Reality</a-radio-button>
|
</a-select>
|
||||||
</a-tooltip>
|
</a-input-group>
|
||||||
<a-radio-button value="tls">TLS</a-radio-button>
|
</a-form-item>
|
||||||
</a-radio-group>
|
<a-form-item label="uTLS">
|
||||||
|
<a-select v-model="inbound.stream.tls.settings.fingerprint"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option value=''>None</a-select-option>
|
||||||
|
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="ALPN">
|
||||||
|
<a-select mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
|
v-model="inbound.stream.tls.alpn">
|
||||||
|
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="Allow Insecure">
|
||||||
|
<a-switch v-model="inbound.stream.tls.settings.allowInsecure"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="Reject Unknown SNI">
|
||||||
|
<a-switch v-model="inbound.stream.tls.rejectUnknownSni"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<template v-for="cert,index in inbound.stream.tls.certs">
|
||||||
|
<a-form-item label='{{ i18n "certificate" }}'>
|
||||||
|
<a-radio-group v-model="cert.useFile" button-style="solid">
|
||||||
|
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button>
|
||||||
|
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-button v-if="index === 0" type="primary" size="small" @click="inbound.stream.tls.addCert()"
|
||||||
|
style="margin-left: 10px">+</a-button>
|
||||||
|
<a-button v-if="inbound.stream.tls.certs.length>1" type="primary" size="small"
|
||||||
|
@click="inbound.stream.tls.removeCert(index)" style="margin-left: 10px">-</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
<template v-if="cert.useFile">
|
||||||
|
<a-form-item label='{{ i18n "pages.inbounds.publicKeyPath" }}'>
|
||||||
|
<a-input v-model.trim="cert.certFile"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='{{ i18n "pages.inbounds.keyPath" }}'>
|
||||||
</tr>
|
<a-input v-model.trim="cert.keyFile"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label=" ">
|
||||||
|
<a-button type="primary" icon="import" @click="setDefaultCertData(index)">{{ i18n
|
||||||
|
"pages.inbounds.setDefaultCert" }}</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<a-form-item label='{{ i18n "pages.inbounds.publicKeyContent" }}'>
|
||||||
|
<a-input type="textarea" :rows="3" v-model="cert.cert"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label='{{ i18n "pages.inbounds.keyContent" }}'>
|
||||||
|
<a-input type="textarea" :rows="3" v-model="cert.key"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
<a-form-item label='ocspStapling'>
|
||||||
|
<a-input-number v-model.number="cert.ocspStapling" :min="0"></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- tls settings -->
|
<!-- xtls settings -->
|
||||||
<template v-if="inbound.stream.isTls">
|
<template v-else-if="inbound.xtls">
|
||||||
<tr>
|
<a-form-item label="SNI" placeholder="Server Name Indication">
|
||||||
<td>SNI</td>
|
<a-input v-model.trim="inbound.stream.xtls.sni"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item placeholder="Server Name Indication">
|
<a-form-item label="ALPN">
|
||||||
<a-input v-model.trim="inbound.stream.tls.sni" style="width: 250px"></a-input>
|
<a-select mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme"
|
||||||
</a-form-item>
|
v-model="inbound.stream.xtls.alpn">
|
||||||
</td>
|
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
|
||||||
</tr>
|
</a-select>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>CipherSuites</td>
|
<a-form-item label="Allow Insecure">
|
||||||
<td>
|
<a-switch v-model="inbound.stream.xtls.settings.allowInsecure"></a-switch>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-select v-model="inbound.stream.tls.cipherSuites" style="width: 250px"
|
<template v-for="cert,index in inbound.stream.xtls.certs">
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
<a-form-item label='{{ i18n "certificate" }}'>
|
||||||
<a-select-option value="">auto</a-select-option>
|
<a-radio-group v-model="cert.useFile" button-style="solid">
|
||||||
<a-select-option v-for="key,value in TLS_CIPHER_OPTION"
|
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath" }}</a-radio-button>
|
||||||
:value="key">[[ value]]</a-select-option>
|
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent" }}</a-radio-button>
|
||||||
</a-select>
|
</a-radio-group>
|
||||||
</a-form-item>
|
<a-button v-if="index === 0" type="primary" size="small" @click="inbound.stream.xtls.addCert()"
|
||||||
</td>
|
style="margin-left: 10px">+</a-button>
|
||||||
</tr>
|
<a-button v-if="inbound.stream.xtls.certs.length>1" type="primary" size="small"
|
||||||
<tr>
|
@click="inbound.stream.xtls.removeCert(index)" style="margin-left: 10px">-</a-button>
|
||||||
<td>Min/Max Version</td>
|
</a-form-item>
|
||||||
<td>
|
<template v-if="cert.useFile">
|
||||||
<a-form-item>
|
<a-form-item label='{{ i18n "pages.inbounds.publicKeyPath" }}'>
|
||||||
<a-input-group compact>
|
<a-input v-model.trim="cert.certFile"></a-input>
|
||||||
<a-select style="width: 125px" v-model="inbound.stream.tls.minVersion"
|
</a-form-item>
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
<a-form-item label='{{ i18n "pages.inbounds.keyPath" }}'>
|
||||||
<a-select-option v-for="key in TLS_VERSION_OPTION"
|
<a-input v-model.trim="cert.keyFile"></a-input>
|
||||||
:value="key">[[ key ]]</a-select-option>
|
</a-form-item>
|
||||||
</a-select>
|
<a-form-item label=" ">
|
||||||
<a-select style="width: 125px" v-model="inbound.stream.tls.maxVersion"
|
<a-button type="primary" icon="import" @click="setDefaultCertXtls(index)">{{ i18n
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
"pages.inbounds.setDefaultCert" }}</a-button>
|
||||||
<a-select-option v-for="key in TLS_VERSION_OPTION"
|
</a-form-item>
|
||||||
:value="key">[[ key ]]</a-select-option>
|
</template>
|
||||||
</a-select>
|
<template v-else>
|
||||||
</a-input-group>
|
<a-form-item label='{{ i18n "pages.inbounds.publicKeyContent" }}'>
|
||||||
</a-form-item>
|
<a-input type="textarea" :rows="3" v-model="cert.cert"></a-input>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item label='{{ i18n "pages.inbounds.keyContent" }}'>
|
||||||
<tr>
|
<a-input type="textarea" :rows="3" v-model="cert.key"></a-input>
|
||||||
<td>uTLS</td>
|
</a-form-item>
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.stream.tls.settings.fingerprint" style="width: 250px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option value=''>None</a-select-option>
|
|
||||||
<a-select-option v-for="key in UTLS_FINGERPRINT"
|
|
||||||
:value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ALPN</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select mode="multiple" style="width: 250px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme"
|
|
||||||
v-model="inbound.stream.tls.alpn">
|
|
||||||
<a-select-option v-for="alpn in ALPN_OPTION"
|
|
||||||
:value="alpn">[[ alpn ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Allow insecure</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.stream.tls.settings.allowInsecure"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Reject Unknown SNI</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.stream.tls.rejectUnknownSni"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-for="cert,index in inbound.stream.tls.certs">
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "certificate" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-radio-group v-model="cert.useFile" button-style="solid">
|
|
||||||
<a-radio-button
|
|
||||||
:value="true">{{ i18n "pages.inbounds.certificatePath"}}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button
|
|
||||||
:value="false">{{ i18n "pages.inbounds.certificateContent"}}
|
|
||||||
</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
<a-button v-if="index === 0" type="primary" size="small"
|
|
||||||
@click="inbound.stream.tls.addCert()" style="margin-left: 10px">+</a-button>
|
|
||||||
<a-button v-if="inbound.stream.tls.certs.length>1" type="primary" size="small"
|
|
||||||
@click="inbound.stream.tls.removeCert(index)" style="margin-left: 10px">-</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="cert.useFile">
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.publicKeyPath" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="cert.certFile" style="width:250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.keyPath" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="cert.keyFile" style="width:250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<a-button type="primary" icon="import" @click="setDefaultCertData(index)">
|
|
||||||
{{ i18n "pages.inbounds.setDefaultCert" }}
|
|
||||||
</a-button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.publicKeyContent" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input type="textarea" :rows="3" style="width:250px;" v-model="cert.cert"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.keyContent" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input type="textarea" :rows="3" style="width:250px;" v-model="cert.key"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
<tr>
|
|
||||||
<td>ocspStapling</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model.number="cert.ocspStapling" :min="0"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
<!-- xtls settings -->
|
<!-- reality settings -->
|
||||||
<template v-else-if="inbound.xtls">
|
<template v-if="inbound.stream.isReality">
|
||||||
<tr>
|
<a-form-item label='Show'>
|
||||||
<td>
|
<a-switch v-model="inbound.stream.reality.show"></a-switch>
|
||||||
<span>SNI</span>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item label='Xver'>
|
||||||
<td>
|
<a-input-number v-model.number="inbound.stream.reality.xver" :min="0"></a-input-number>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="inbound.stream.xtls.server" style="width: 250px"></a-input>
|
<a-form-item label='uTLS'>
|
||||||
</a-form-item>
|
<a-select v-model="inbound.stream.reality.settings.fingerprint"
|
||||||
</td>
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</tr>
|
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
||||||
<tr>
|
</a-select>
|
||||||
<td>
|
</a-form-item>
|
||||||
<span>Alpn</span>
|
<a-form-item label='Dest'>
|
||||||
</td>
|
<a-input v-model.trim="inbound.stream.reality.dest"></a-input>
|
||||||
<td>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item label='Server Names'>
|
||||||
<a-select mode="multiple" style="width: 250px" :dropdown-class-name="themeSwitcher.currentTheme"
|
<a-input v-model.trim="inbound.stream.reality.serverNames"></a-input>
|
||||||
v-model="inbound.stream.xtls.alpn">
|
</a-form-item>
|
||||||
<a-select-option v-for="alpn in ALPN_OPTION" :value="alpn">[[ alpn ]]</a-select-option>
|
<a-form-item>
|
||||||
</a-select>
|
<template slot="label">
|
||||||
</a-form-item>
|
<a-tooltip>
|
||||||
</td>
|
<template slot="title">
|
||||||
</tr>
|
<span>{{ i18n "pages.client.renew" }}</span>
|
||||||
<tr>
|
</template>
|
||||||
<td>
|
Short IDs
|
||||||
<span>Allow insecure</span>
|
<a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortId()" type="sync"> </a-icon>
|
||||||
</td>
|
</a-icon>
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-switch v-model="inbound.stream.xtls.settings.allowInsecure"></a-switch>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-for="cert,index in inbound.stream.xtls.certs">
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "certificate" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-radio-group v-model="cert.useFile" button-style="solid">
|
|
||||||
<a-radio-button :value="true">{{ i18n "pages.inbounds.certificatePath"
|
|
||||||
}}</a-radio-button>
|
|
||||||
<a-radio-button :value="false">{{ i18n "pages.inbounds.certificateContent"
|
|
||||||
}}</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
<a-button v-if="index === 0" type="primary" size="small"
|
|
||||||
@click="inbound.stream.xtls.addCert()" style="margin-left: 10px">+</a-button>
|
|
||||||
<a-button v-if="inbound.stream.xtls.certs.length>1" type="primary" size="small"
|
|
||||||
@click="inbound.stream.xtls.removeCert(index)" style="margin-left: 10px">-</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="cert.useFile">
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.publicKeyPath" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="cert.certFile" style="width:250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.keyPath" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="cert.keyFile" style="width:250px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
|
||||||
<a-button type="primary" icon="import" @click="setDefaultCertData(index)">{{ i18n
|
|
||||||
"pages.inbounds.setDefaultCert" }}</a-button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.publicKeyContent" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input type="textarea" :rows="3" style="width:250px;" v-model="cert.cert"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.inbounds.keyContent" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input type="textarea" :rows="3" style="width:250px;" v-model="cert.key"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
<a-input v-model.trim="inbound.stream.reality.shortIds"></a-input>
|
||||||
|
</a-form-item>
|
||||||
<!-- reality settings -->
|
<a-form-item label='SpiderX'>
|
||||||
<template v-else-if="inbound.reality">
|
<a-input v-model.trim="inbound.stream.reality.settings.spiderX"></a-input>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='Private Key'>
|
||||||
<span>Show</span>
|
<a-input v-model.trim="inbound.stream.reality.privateKey"></a-input>
|
||||||
</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='Public Key'>
|
||||||
<a-form-item>
|
<a-input v-model.trim="inbound.stream.reality.settings.publicKey"></a-input>
|
||||||
<a-switch v-model="inbound.stream.reality.show"></a-switch>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label=" ">
|
||||||
</td>
|
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get new cert</a-button>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
</template>
|
||||||
<td>
|
|
||||||
<span>xVer</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input-number v-model="inbound.stream.reality.xver" :min="0"
|
|
||||||
style="width: 60px"></a-input-number>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>uTLS</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="inbound.stream.reality.settings.fingerprint" style="width: 135px"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option v-for="key in UTLS_FINGERPRINT" :value="key">[[ key ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>Dest</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.dest" style="width: 300px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>Server Names</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.serverNames" style="width: 300px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>ShortIds</span> <a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortId()"
|
|
||||||
type="sync"> </a-icon>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.shortIds" style="width: 150px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>SpiderX</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.settings.spiderX" style="width: 150px;"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>Private Key</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.privateKey" style="width: 300px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span>Public Key</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="inbound.stream.reality.settings.publicKey"
|
|
||||||
style="width: 300px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get New Key</a-button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</table>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
:overlay-class-name="themeSwitcher.currentTheme"
|
:overlay-class-name="themeSwitcher.currentTheme"
|
||||||
ok-text='{{ i18n "reset"}}'
|
ok-text='{{ i18n "reset"}}'
|
||||||
cancel-text='{{ i18n "cancel"}}'>
|
cancel-text='{{ i18n "cancel"}}'>
|
||||||
<a-icon slot="icon" type="question-circle-o" :style="themeSwitcher.isDarkTheme ? 'color: #3c89e8' : 'color: blue'"></a-icon>
|
<a-icon slot="icon" type="question-circle-o" :style="themeSwitcher.isDarkTheme ? 'color: #008771' : 'color: #008771'"></a-icon>
|
||||||
<a-icon style="font-size: 24px; cursor: pointer;" class="normal-icon" type="retweet" v-if="client.email.length > 0"></a-icon>
|
<a-icon style="font-size: 24px; cursor: pointer;" class="normal-icon" type="retweet" v-if="client.email.length > 0"></a-icon>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|||||||
@@ -3,72 +3,89 @@
|
|||||||
v-model="infoModal.visible" title='{{ i18n "pages.inbounds.details"}}'
|
v-model="infoModal.visible" title='{{ i18n "pages.inbounds.details"}}'
|
||||||
:closable="true"
|
:closable="true"
|
||||||
:mask-closable="true"
|
:mask-closable="true"
|
||||||
:class="themeSwitcher.currentTheme"
|
|
||||||
:footer="null"
|
:footer="null"
|
||||||
width="600px"
|
width="600px"
|
||||||
|
:class="themeSwitcher.currentTheme"
|
||||||
>
|
>
|
||||||
<table style="margin-bottom: 10px; width: 100%;">
|
<a-row>
|
||||||
<tr><td>
|
<a-col :xs="24" :md="12">
|
||||||
<table>
|
<table>
|
||||||
<tr><td>{{ i18n "protocol" }}</td><td><a-tag color="purple">[[ dbInbound.protocol ]]</a-tag></td></tr>
|
<tr><td>{{ i18n "protocol" }}</td><td><a-tag color="purple">[[ dbInbound.protocol ]]</a-tag></td></tr>
|
||||||
<tr><td>{{ i18n "pages.inbounds.address" }}</td><td><a-tag>[[ dbInbound.address ]]</a-tag></td></tr>
|
<tr><td>{{ i18n "pages.inbounds.address" }}</td><td>
|
||||||
<tr><td>{{ i18n "pages.inbounds.port" }}</td><td><a-tag>[[ dbInbound.port ]]</a-tag></td></tr>
|
<a-tooltip :title="[[ dbInbound.address ]]">
|
||||||
</table>
|
<a-tag class="info-large-tag">[[ dbInbound.address ]]</a-tag>
|
||||||
</td>
|
</a-tooltip>
|
||||||
<td v-if="dbInbound.isVMess || dbInbound.isVLess || dbInbound.isTrojan || dbInbound.isSS">
|
</td></tr>
|
||||||
<table>
|
<tr><td>{{ i18n "pages.inbounds.port" }}</td><td><a-tag>[[ dbInbound.port ]]</a-tag></td></tr>
|
||||||
<tr>
|
</table>
|
||||||
<td>{{ i18n "transmission" }}</td><td><a-tag color="green">[[ inbound.network ]]</a-tag></td>
|
</a-col>
|
||||||
</tr>
|
<a-col :xs="24" :md="12">
|
||||||
<template v-if="inbound.isTcp || inbound.isWs || inbound.isH2">
|
<template v-if="dbInbound.isVMess || dbInbound.isVLess || dbInbound.isTrojan || dbInbound.isSS">
|
||||||
<tr>
|
<table>
|
||||||
<td>{{ i18n "host" }}</td>
|
<tr>
|
||||||
<td v-if="inbound.host"><a-tag>[[ inbound.host ]]</a-tag></td>
|
<td>{{ i18n "transmission" }}</td><td><a-tag color="green">[[ inbound.network ]]</a-tag></td>
|
||||||
<td v-else><a-tag color="orange">{{ i18n "none" }}</a-tag></td></tr>
|
</tr>
|
||||||
</tr>
|
<template v-if="inbound.isTcp || inbound.isWs || inbound.isH2">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i18n "path" }}</td>
|
<td>{{ i18n "host" }}</td>
|
||||||
<td v-if="inbound.path"><a-tag>[[ inbound.path ]]</a-tag></td>
|
<td v-if="inbound.host">
|
||||||
<td v-else><a-tag color="orange">{{ i18n "none" }}</a-tag></td>
|
<a-tooltip :title="[[ inbound.host ]]">
|
||||||
</tr>
|
<a-tag class="info-large-tag">[[ inbound.host ]]</a-tag>
|
||||||
</template>
|
</a-tooltip>
|
||||||
|
</td>
|
||||||
|
<td v-else><a-tag color="orange">{{ i18n "none" }}</a-tag></td></tr>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ i18n "path" }}</td>
|
||||||
|
<td v-if="inbound.path">
|
||||||
|
<a-tooltip :title="[[ inbound.path ]]">
|
||||||
|
<a-tag class="info-large-tag">[[ inbound.path ]]</a-tag>
|
||||||
|
</a-tooltip>
|
||||||
|
<td v-else><a-tag color="orange">{{ i18n "none" }}</a-tag></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-if="inbound.isQuic">
|
<template v-if="inbound.isQuic">
|
||||||
<tr><td>quic {{ i18n "encryption" }}</td><td><a-tag>[[ inbound.quicSecurity ]]</a-tag></td></tr>
|
<tr><td>quic {{ i18n "encryption" }}</td><td><a-tag>[[ inbound.quicSecurity ]]</a-tag></td></tr>
|
||||||
<tr><td>quic {{ i18n "password" }}</td><td><a-tag>[[ inbound.quicKey ]]</a-tag></td></tr>
|
<tr><td>quic {{ i18n "password" }}</td><td><a-tag>[[ inbound.quicKey ]]</a-tag></td></tr>
|
||||||
<tr><td>quic {{ i18n "camouflage" }}</td><td><a-tag>[[ inbound.quicType ]]</a-tag></td></tr>
|
<tr><td>quic {{ i18n "camouflage" }}</td><td><a-tag>[[ inbound.quicType ]]</a-tag></td></tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="inbound.isKcp">
|
<template v-if="inbound.isKcp">
|
||||||
<tr><td>kcp {{ i18n "encryption" }}</td><td><a-tag>[[ inbound.kcpType ]]</a-tag></td></tr>
|
<tr><td>kcp {{ i18n "encryption" }}</td><td><a-tag>[[ inbound.kcpType ]]</a-tag></td></tr>
|
||||||
<tr><td>kcp {{ i18n "password" }}</td><td><a-tag>[[ inbound.kcpSeed ]]</a-tag></td></tr>
|
<tr><td>kcp {{ i18n "password" }}</td><td><a-tag>[[ inbound.kcpSeed ]]</a-tag></td></tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="inbound.isGrpc">
|
<template v-if="inbound.isGrpc">
|
||||||
<tr><td>grpc serviceName</td><td><a-tag>[[ inbound.serviceName ]]</a-tag></td></tr>
|
<tr><td>grpc serviceName</td><td>
|
||||||
<tr><td>grpc multiMode</td><td><a-tag>[[ inbound.stream.grpc.multiMode ]]</a-tag></td></tr>
|
<a-tooltip :title="[[ inbound.serviceName ]]">
|
||||||
</template>
|
<a-tag class="info-large-tag">[[ inbound.serviceName ]]</a-tag>
|
||||||
</table>
|
</a-tooltip>
|
||||||
</td></tr>
|
<tr><td>grpc multiMode</td><td><a-tag>[[ inbound.stream.grpc.multiMode ]]</a-tag></td></tr>
|
||||||
<tr colspan="2" v-if="dbInbound.hasLink()">
|
</template>
|
||||||
<td>
|
</table>
|
||||||
{{ i18n "security" }}
|
</template>
|
||||||
<a-tag :color="inbound.stream.security == 'none' ? 'red' : 'blue'">[[ inbound.stream.security ]]</a-tag>
|
</a-col>
|
||||||
<br />
|
<template v-if="dbInbound.hasLink()">
|
||||||
<template v-if="inbound.stream.security != 'none'">
|
{{ i18n "security" }}
|
||||||
{{ i18n "domainName" }}
|
<a-tag :color="inbound.stream.security == 'none' ? 'red' : 'green'">[[ inbound.stream.security ]]</a-tag>
|
||||||
<a-tag :color="inbound.serverName ? 'blue' : 'orange'">[[ inbound.serverName ? inbound.serverName : '' ]]</a-tag>
|
<br />
|
||||||
</template>
|
<template v-if="inbound.stream.security != 'none'">
|
||||||
</td>
|
{{ i18n "domainName" }}
|
||||||
</tr>
|
<a-tag :color="inbound.serverName ? 'green' : 'orange'">[[ inbound.serverName ? inbound.serverName : '' ]]</a-tag>
|
||||||
</table>
|
</template>
|
||||||
|
</template>
|
||||||
<table v-if="dbInbound.isSS" style="margin-bottom: 10px; width: 100%;">
|
<table v-if="dbInbound.isSS" style="margin-bottom: 10px; width: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i18n "encryption" }}</td>
|
<td>{{ i18n "encryption" }}</td>
|
||||||
<td><a-tag color="green">[[ inbound.settings.method ]]</a-tag></td>
|
<td><a-tag color="green">[[ inbound.settings.method ]]</a-tag></td>
|
||||||
</tr><tr v-if="inbound.isSS2022">
|
</tr><tr v-if="inbound.isSS2022">
|
||||||
<td>{{ i18n "password" }}</td>
|
<td>{{ i18n "password" }}</td>
|
||||||
<td><a-tag>[[ inbound.settings.password ]]</a-tag></td>
|
<td>
|
||||||
|
<a-tooltip :title="[[ inbound.settings.password ]]">
|
||||||
|
<a-tag class="info-large-tag">[[ inbound.settings.password ]]</a-tag>
|
||||||
|
</a-tooltip>
|
||||||
|
</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td>{{ i18n "pages.inbounds.network" }}</td>
|
<td>{{ i18n "pages.inbounds.network" }}</td>
|
||||||
<td><a-tag color="green">[[ inbound.settings.network ]]</a-tag></td>
|
<td><a-tag color="green">[[ inbound.settings.network ]]</a-tag></td>
|
||||||
@@ -89,9 +106,17 @@
|
|||||||
<td>Flow</td>
|
<td>Flow</td>
|
||||||
<td><a-tag>[[ infoModal.clientSettings.flow ]]</a-tag></td>
|
<td><a-tag>[[ infoModal.clientSettings.flow ]]</a-tag></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr v-if="infoModal.inbound.xtls">
|
||||||
|
<td>Flow</td>
|
||||||
|
<td><a-tag>[[ infoModal.clientSettings.flow ]]</a-tag></td>
|
||||||
|
</tr>
|
||||||
<tr v-if="infoModal.clientSettings.password">
|
<tr v-if="infoModal.clientSettings.password">
|
||||||
<td>Password</td>
|
<td>{{ i18n "password" }}</td>
|
||||||
<td><a-tag>[[ infoModal.clientSettings.password ]]</a-tag></td>
|
<td>
|
||||||
|
<a-tooltip :title="[[ infoModal.clientSettings.password ]]">
|
||||||
|
<a-tag class="info-large-tag">[[ infoModal.clientSettings.password ]]</a-tag>
|
||||||
|
</a-tooltip>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ i18n "status" }}</td>
|
<td>{{ i18n "status" }}</td>
|
||||||
@@ -115,69 +140,69 @@
|
|||||||
<th>{{ i18n "pages.inbounds.totalFlow" }}</th>
|
<th>{{ i18n "pages.inbounds.totalFlow" }}</th>
|
||||||
<th>{{ i18n "pages.inbounds.expireDate" }}</th>
|
<th>{{ i18n "pages.inbounds.expireDate" }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a-tag v-if="infoModal.clientStats && infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)">
|
<a-tag v-if="infoModal.clientStats && infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)">
|
||||||
[[ sizeFormat(infoModal.clientSettings.totalGB - infoModal.clientStats.up - infoModal.clientStats.down) ]]
|
[[ sizeFormat(infoModal.clientSettings.totalGB - infoModal.clientStats.up - infoModal.clientStats.down) ]]
|
||||||
</a-tag>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a-tag v-if="infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)">
|
|
||||||
[[ sizeFormat(infoModal.clientSettings.totalGB) ]]
|
|
||||||
</a-tag>
|
|
||||||
<a-tag v-else color="purple" class="infinite-tag">∞</a-tag>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<template v-if="infoModal.clientSettings.expiryTime > 0">
|
|
||||||
<a-tag :color="usageColor(new Date().getTime(), app.expireDiff, infoModal.clientSettings.expiryTime)">
|
|
||||||
[[ DateUtil.formatMillis(infoModal.clientSettings.expiryTime) ]]
|
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</td>
|
||||||
<a-tag v-else-if="infoModal.clientSettings.expiryTime < 0" color="green">[[ infoModal.clientSettings.expiryTime / -86400000 ]] {{ i18n "pages.client.days" }}</a-tag>
|
<td>
|
||||||
<a-tag v-else color="purple" class="infinite-tag">∞</a-tag>
|
<a-tag v-if="infoModal.clientSettings.totalGB > 0" :color="statsColor(infoModal.clientStats)">
|
||||||
</td>
|
[[ sizeFormat(infoModal.clientSettings.totalGB) ]]
|
||||||
</tr>
|
</a-tag>
|
||||||
</table>
|
<a-tag v-else color="purple" class="infinite-tag">∞</a-tag>
|
||||||
<template v-if="app.subSettings.enable && infoModal.clientSettings.subId">
|
</td>
|
||||||
<a-divider>Subscription link</a-divider>
|
<td>
|
||||||
<a-row>
|
<template v-if="infoModal.clientSettings.expiryTime > 0">
|
||||||
<a-col :span="22"><a :href="[[ infoModal.subLink ]]" target="_blank">[[ infoModal.subLink ]]</a></a-col>
|
<a-tag :color="usageColor(new Date().getTime(), app.expireDiff, infoModal.clientSettings.expiryTime)">
|
||||||
<a-col :span="2">
|
[[ DateUtil.formatMillis(infoModal.clientSettings.expiryTime) ]]
|
||||||
<a-tooltip title='{{ i18n "copy" }}'>
|
</a-tag>
|
||||||
<button class="ant-btn ant-btn-primary" id="copy-sub-link" @click="copyToClipboard('copy-sub-link', infoModal.subLink)">
|
</template>
|
||||||
<a-icon type="snippets"></a-icon>
|
<a-tag v-else-if="infoModal.clientSettings.expiryTime < 0" color="green">[[ infoModal.clientSettings.expiryTime / -86400000 ]] {{ i18n "pages.client.days" }}</a-tag>
|
||||||
</button>
|
<a-tag v-else color="purple" class="infinite-tag">∞</a-tag>
|
||||||
</a-tooltip>
|
</td>
|
||||||
</a-col>
|
</tr>
|
||||||
</a-row>
|
</table>
|
||||||
|
<template v-if="app.subSettings.enable && infoModal.clientSettings.subId">
|
||||||
|
<a-divider>Subscription link</a-divider>
|
||||||
|
<a-row>
|
||||||
|
<a-col :sx="24" :md="22"><a :href="[[ infoModal.subLink ]]" target="_blank">[[ infoModal.subLink ]]</a></a-col>
|
||||||
|
<a-col :sx="24" :md="2" style="text-align: right;">
|
||||||
|
<a-tooltip title='{{ i18n "copy" }}'>
|
||||||
|
<button class="ant-btn ant-btn-primary" id="copy-sub-link" @click="copyToClipboard('copy-sub-link', infoModal.subLink)">
|
||||||
|
<a-icon type="snippets"></a-icon>
|
||||||
|
</button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<template v-if="app.tgBotEnable && infoModal.clientSettings.tgId">
|
||||||
|
<a-divider>Telegram ID</a-divider>
|
||||||
|
<a-row>
|
||||||
|
<a-col :sx="24" :md="22"><a :href="[[ infoModal.tgLink ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></a-col>
|
||||||
|
<a-col :sx="24" :md="2" style="text-align: right;">
|
||||||
|
<a-tooltip title='{{ i18n "copy" }}'>
|
||||||
|
<button class="ant-btn ant-btn-primary" id="copy-tg-link" @click="copyToClipboard('copy-tg-link', '@' + infoModal.clientSettings.tgId)">
|
||||||
|
<a-icon type="snippets"></a-icon>
|
||||||
|
</button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
<template v-if="dbInbound.hasLink()">
|
||||||
|
<a-divider>URL</a-divider>
|
||||||
|
<a-row v-for="(link,index) in infoModal.links">
|
||||||
|
<a-col :sx="24" :md="22"><a-tag color="green">[[ link.remark ]]</a-tag><br />[[ link.link ]]</a-col>
|
||||||
|
<a-col :sx="24" :md="2" style="text-align: right;">
|
||||||
|
<a-tooltip title='{{ i18n "copy" }}'>
|
||||||
|
<button class="ant-btn ant-btn-primary" :id="'copy-url-link-'+index" @click="copyToClipboard('copy-url-link-'+index, link.link)">
|
||||||
|
<a-icon type="snippets"></a-icon>
|
||||||
|
</button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="app.tgBotEnable && infoModal.clientSettings.tgId">
|
|
||||||
<a-divider>Telegram Username</a-divider>
|
|
||||||
<a-row>
|
|
||||||
<a-col :span="22"><a :href="[[ infoModal.tgLink ]]" target="_blank">@[[ infoModal.clientSettings.tgId ]]</a></a-col>
|
|
||||||
<a-col :span="2">
|
|
||||||
<a-tooltip title='{{ i18n "copy" }}'>
|
|
||||||
<button class="ant-btn ant-btn-primary" id="copy-tg-link" @click="copyToClipboard('copy-tg-link', '@' + infoModal.clientSettings.tgId)">
|
|
||||||
<a-icon type="snippets"></a-icon>
|
|
||||||
</button>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</template>
|
|
||||||
<template v-if="dbInbound.hasLink()">
|
|
||||||
<a-divider>URL</a-divider>
|
|
||||||
<a-row v-for="(link,index) in infoModal.links">
|
|
||||||
<a-col :span="22"><a-tag color="green">[[ link.remark ]]</a-tag><br />[[ link.link ]]</a-col>
|
|
||||||
<a-col :span="2" style="text-align: right;">
|
|
||||||
<a-tooltip title='{{ i18n "copy" }}'>
|
|
||||||
<button class="ant-btn ant-btn-primary" :id="'copy-url-link-'+index" @click="copyToClipboard('copy-url-link-'+index, link.link)">
|
|
||||||
<a-icon type="snippets"></a-icon>
|
|
||||||
</button>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-if="dbInbound.isSS && !inbound.isSSMultiUser">
|
<template v-if="dbInbound.isSS && !inbound.isSSMultiUser">
|
||||||
<a-divider>URL</a-divider>
|
<a-divider>URL</a-divider>
|
||||||
@@ -217,7 +242,7 @@
|
|||||||
<td><a-tag color="green">[[ inbound.settings.ip ]]</a-tag></td>
|
<td><a-tag color="green">[[ inbound.settings.ip ]]</a-tag></td>
|
||||||
</tr>
|
</tr>
|
||||||
<template v-if="inbound.settings.auth == 'password'">
|
<template v-if="inbound.settings.auth == 'password'">
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td>{{ i18n "username" }}</td>
|
<td>{{ i18n "username" }}</td>
|
||||||
<td>{{ i18n "password" }}</td>
|
<td>{{ i18n "password" }}</td>
|
||||||
@@ -226,9 +251,9 @@
|
|||||||
<td><a-tag color="green">[[ account.user ]]</a-tag></td>
|
<td><a-tag color="green">[[ account.user ]]</a-tag></td>
|
||||||
<td><a-tag color="green">[[ account.pass ]]</a-tag></td>
|
<td><a-tag color="green">[[ account.pass ]]</a-tag></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
<table v-if="dbInbound.isHTTP" style="margin-bottom: 10px; width: 100%;">
|
<table v-if="dbInbound.isHTTP" style="margin-bottom: 10px; width: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th>{{ i18n "username" }}</th>
|
<th>{{ i18n "username" }}</th>
|
||||||
@@ -246,7 +271,6 @@
|
|||||||
visible: false,
|
visible: false,
|
||||||
inbound: new Inbound(),
|
inbound: new Inbound(),
|
||||||
dbInbound: new DBInbound(),
|
dbInbound: new DBInbound(),
|
||||||
settings: null,
|
|
||||||
clientSettings: null,
|
clientSettings: null,
|
||||||
clientStats: [],
|
clientStats: [],
|
||||||
upStats: 0,
|
upStats: 0,
|
||||||
@@ -279,7 +303,7 @@
|
|||||||
infoModal.visible = false;
|
infoModal.visible = false;
|
||||||
},
|
},
|
||||||
genSubLink(subID) {
|
genSubLink(subID) {
|
||||||
return app.subSettings.subURI+subID+'?name='+subID;
|
return app.subSettings.subURI+subID;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -295,23 +319,23 @@
|
|||||||
return this.infoModal.inbound;
|
return this.infoModal.inbound;
|
||||||
},
|
},
|
||||||
get isActive() {
|
get isActive() {
|
||||||
if (infoModal.clientStats) {
|
if(infoModal.clientStats){
|
||||||
return infoModal.clientStats.enable;
|
return infoModal.clientStats.enable;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
get isEnable() {
|
get isEnable() {
|
||||||
if (infoModal.clientSettings) {
|
if(infoModal.clientSettings){
|
||||||
return infoModal.clientSettings.enable;
|
return infoModal.clientSettings.enable;
|
||||||
}
|
}
|
||||||
return infoModal.dbInbound.isEnable;
|
return infoModal.dbInbound.isEnable;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyToClipboard(elmentId, content) {
|
copyToClipboard(elmentId,content) {
|
||||||
this.infoModal.clipboard = new ClipboardJS('#' + elmentId, {
|
this.infoModal.clipboard = new ClipboardJS('#' + elmentId, {
|
||||||
text: () => content,
|
text: () => content,
|
||||||
});
|
});
|
||||||
this.infoModal.clipboard.on('success', () => {
|
this.infoModal.clipboard.on('success', () => {
|
||||||
app.$message.success('{{ i18n "copied" }}')
|
app.$message.success('{{ i18n "copied" }}')
|
||||||
this.infoModal.clipboard.destroy();
|
this.infoModal.clipboard.destroy();
|
||||||
@@ -321,6 +345,7 @@
|
|||||||
return usageColor(stats.up + stats.down, app.trafficDiff, stats.total);
|
return usageColor(stats.up + stats.down, app.trafficDiff, stats.total);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -98,6 +98,11 @@
|
|||||||
client.flow = "";
|
client.flow = "";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if ((this.inModal.inbound.protocol == Protocols.VLESS || this.inModal.inbound.protocol == Protocols.TROJAN) && !inModal.inbound.xtls) {
|
||||||
|
this.inModal.inbound.settings.vlesses.forEach(client => {
|
||||||
|
client.flow = "";
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SSMethodChange() {
|
SSMethodChange() {
|
||||||
if (this.inModal.inbound.isSSMultiUser) {
|
if (this.inModal.inbound.isSSMultiUser) {
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
0%, 50%, 100% { transform: scale(1); opacity: 1; }
|
0%, 50%, 100% { transform: scale(1); opacity: 1; }
|
||||||
10% { transform: scale(1.5); opacity: .2; }
|
10% { transform: scale(1.5); opacity: .2; }
|
||||||
}
|
}
|
||||||
|
.info-large-tag {
|
||||||
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -157,9 +161,9 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; align-items: center; justify-content: flex-start;">
|
<div :style="isMobile ? '' : 'display: flex; align-items: center; justify-content: flex-start;'">
|
||||||
<a-switch v-model="enableFilter"
|
<a-switch v-model="enableFilter"
|
||||||
style="margin-right: .5rem;"
|
:style="isMobile ? 'margin-bottom: .5rem; display: flex;' : 'margin-right: .5rem;'"
|
||||||
@change="toggleFilter">
|
@change="toggleFilter">
|
||||||
<a-icon slot="checkedChildren" type="search"></a-icon>
|
<a-icon slot="checkedChildren" type="search"></a-icon>
|
||||||
<a-icon slot="unCheckedChildren" type="filter"></a-icon>
|
<a-icon slot="unCheckedChildren" type="filter"></a-icon>
|
||||||
@@ -419,11 +423,11 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="expandedRowRender" slot-scope="record">
|
<template slot="expandedRowRender" slot-scope="record">
|
||||||
<a-table
|
<a-table
|
||||||
:row-key="client => client.id"
|
:row-key="client => client.id"
|
||||||
:columns="isMobile ? innerMobileColumns : innerColumns"
|
:columns="isMobile ? innerMobileColumns : innerColumns"
|
||||||
:data-source="getInboundClients(record)"
|
:data-source="getInboundClients(record)"
|
||||||
:pagination=pagination(getInboundClients(record))
|
:pagination=pagination(getInboundClients(record))
|
||||||
:style="isMobile ? 'margin: -12px -5px -13px;' : 'margin-left: 10px;'">
|
:style="isMobile ? 'margin: -12px 2px -13px;' : 'margin: -12px 22px -13px;'">
|
||||||
{{template "client_table"}}
|
{{template "client_table"}}
|
||||||
</a-table>
|
</a-table>
|
||||||
</template>
|
</template>
|
||||||
@@ -1089,7 +1093,7 @@
|
|||||||
title: '{{ i18n "pages.inbounds.delDepletedClientsTitle"}}',
|
title: '{{ i18n "pages.inbounds.delDepletedClientsTitle"}}',
|
||||||
content: '{{ i18n "pages.inbounds.delDepletedClientsContent"}}',
|
content: '{{ i18n "pages.inbounds.delDepletedClientsContent"}}',
|
||||||
class: themeSwitcher.currentTheme,
|
class: themeSwitcher.currentTheme,
|
||||||
okText: '{{ i18n "reset"}}',
|
okText: '{{ i18n "delete"}}',
|
||||||
cancelText: '{{ i18n "cancel"}}',
|
cancelText: '{{ i18n "cancel"}}',
|
||||||
onOk: () => this.submit('/panel/inbound/delDepletedClients/' + dbInboundId),
|
onOk: () => this.submit('/panel/inbound/delDepletedClients/' + dbInboundId),
|
||||||
})
|
})
|
||||||
@@ -1175,7 +1179,7 @@
|
|||||||
inboundLinks(dbInboundId) {
|
inboundLinks(dbInboundId) {
|
||||||
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
dbInbound = this.dbInbounds.find(row => row.id === dbInboundId);
|
||||||
newDbInbound = this.checkFallback(dbInbound);
|
newDbInbound = this.checkFallback(dbInbound);
|
||||||
txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks, newDbInbound.remark);
|
txtModal.show('{{ i18n "pages.inbounds.export"}}', newDbInbound.genInboundLinks(), newDbInbound.remark);
|
||||||
},
|
},
|
||||||
importInbound() {
|
importInbound() {
|
||||||
promptModal.open({
|
promptModal.open({
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
<p style="max-width: 400px" v-for="line in status.xray.errorMsg.split('\n')">[[ line ]]</p>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
<a-tag color="purple" style="cursor: pointer;" @click="stopXrayService">{{ i18n "pages.index.stopXray" }}</a-tag>
|
<a-tag color="purple" style="cursor: pointer;" @click="stopXrayService">{{ i18n "pages.index.stopXray" }}</a-tag>
|
||||||
<a-tag color="purple" style="cursor: pointer;" @click="restartXrayService">{{ i18n "pages.index.restartXray" }}</a-tag>
|
<a-tag color="purple" style="cursor: pointer;" @click="restartXrayService">{{ i18n "pages.index.restartXray" }}</a-tag>
|
||||||
@@ -125,14 +125,14 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.systemLoadDesc" }}
|
{{ i18n "pages.index.systemLoadDesc" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :sm="24" :md="12">
|
<a-col :sm="24" :md="12">
|
||||||
<a-card hoverable>
|
<a-card hoverable>
|
||||||
{{ i18n "usage"}}:
|
{{ i18n "usage"}}:
|
||||||
Memory [[ sizeFormat(status.appStats.mem) ]] -
|
RAM [[ sizeFormat(status.appStats.mem) ]] -
|
||||||
Threads [[ status.appStats.threads ]]
|
Threads [[ status.appStats.threads ]]
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-card>
|
</a-card>
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
[[ status.publicIP.ipv4 ]]
|
[[ status.publicIP.ipv4 ]]
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
[[ status.publicIP.ipv6 ]]
|
[[ status.publicIP.ipv6 ]]
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.connectionTcpCountDesc" }}
|
{{ i18n "pages.index.connectionTcpCountDesc" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.connectionUdpCountDesc" }}
|
{{ i18n "pages.index.connectionUdpCountDesc" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -190,22 +190,22 @@
|
|||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-icon type="arrow-up"></a-icon>
|
<a-icon type="arrow-up"></a-icon>
|
||||||
[[ sizeFormat(status.netIO.up) ]]/S
|
[[ sizeFormat(status.netIO.up) ]]/s
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.upSpeed" }}
|
{{ i18n "pages.index.upSpeed" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-icon type="arrow-down"></a-icon>
|
<a-icon type="arrow-down"></a-icon>
|
||||||
[[ sizeFormat(status.netIO.down) ]]/S
|
[[ sizeFormat(status.netIO.down) ]]/s
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.downSpeed" }}
|
{{ i18n "pages.index.downSpeed" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.totalSent" }}
|
{{ i18n "pages.index.totalSent" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -231,7 +231,7 @@
|
|||||||
<template slot="title">
|
<template slot="title">
|
||||||
{{ i18n "pages.index.totalReceive" }}
|
{{ i18n "pages.index.totalReceive" }}
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{{template "head" .}}
|
{{template "head" .}}
|
||||||
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/codemirror.css">
|
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/codemirror.css">
|
||||||
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/fold/foldgutter.css">
|
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/fold/foldgutter.css">
|
||||||
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/xq.css">
|
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/xq.css?{{ .cur_ver }}">
|
||||||
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/lint/lint.css">
|
<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/lint/lint.css">
|
||||||
|
|
||||||
<script src="{{ .base_path }}assets/js/model/outbound.js"></script>
|
<script src="{{ .base_path }}assets/js/model/outbound.js"></script>
|
||||||
@@ -29,6 +29,10 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 12px .5rem;
|
padding: 12px .5rem;
|
||||||
}
|
}
|
||||||
|
.ant-table-thead > tr > th,
|
||||||
|
.ant-table-tbody > tr > td {
|
||||||
|
padding: 10px 0px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-tabs-bar {
|
.ant-tabs-bar {
|
||||||
@@ -71,7 +75,7 @@
|
|||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p style="max-width: 400px" v-for="line in restartResult.split('\n')">[[ line ]]</p>
|
<p style="max-width: 400px" v-for="line in restartResult.split('\n')">[[ line ]]</p>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle" theme="filled"></a-icon>
|
<a-icon type="question-circle"></a-icon>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -106,8 +110,8 @@
|
|||||||
<a-row style="padding: 20px">
|
<a-row style="padding: 20px">
|
||||||
<a-col :lg="24" :xl="12">
|
<a-col :lg="24" :xl="12">
|
||||||
<a-list-item-meta
|
<a-list-item-meta
|
||||||
title='{{ i18n "pages.xray.xrayConfigFreedomStrategy" }}'
|
title='{{ i18n "pages.xray.FreedomStrategy" }}'
|
||||||
description='{{ i18n "pages.xray.xrayConfigFreedomStrategyDesc" }}'/>
|
description='{{ i18n "pages.xray.FreedomStrategyDesc" }}'/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="24" :xl="12">
|
<a-col :lg="24" :xl="12">
|
||||||
<template>
|
<template>
|
||||||
@@ -124,8 +128,8 @@
|
|||||||
<a-row style="padding: 20px">
|
<a-row style="padding: 20px">
|
||||||
<a-col :lg="24" :xl="12">
|
<a-col :lg="24" :xl="12">
|
||||||
<a-list-item-meta
|
<a-list-item-meta
|
||||||
title='{{ i18n "pages.xray.xrayConfigRoutingStrategy" }}'
|
title='{{ i18n "pages.xray.RoutingStrategy" }}'
|
||||||
description='{{ i18n "pages.xray.xrayConfigRoutingStrategyDesc" }}'/>
|
description='{{ i18n "pages.xray.RoutingStrategyDesc" }}'/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="24" :xl="12">
|
<a-col :lg="24" :xl="12">
|
||||||
<template>
|
<template>
|
||||||
@@ -149,11 +153,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</a-row>
|
</a-row>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigTorrent"}}' desc='{{ i18n "pages.xray.xrayConfigTorrentDesc"}}' v-model="torrentSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.Torrent"}}' desc='{{ i18n "pages.xray.TorrentDesc"}}' v-model="torrentSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigPrivateIp"}}' desc='{{ i18n "pages.xray.xrayConfigPrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.PrivateIp"}}' desc='{{ i18n "pages.xray.PrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigAds"}}' desc='{{ i18n "pages.xray.xrayConfigAdsDesc"}}' v-model="AdsSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.Ads"}}' desc='{{ i18n "pages.xray.AdsDesc"}}' v-model="AdsSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigFamily"}}' desc='{{ i18n "pages.xray.xrayConfigFamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.Family"}}' desc='{{ i18n "pages.xray.FamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigSpeedtest"}}' desc='{{ i18n "pages.xray.xrayConfigSpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.Speedtest"}}' desc='{{ i18n "pages.xray.SpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
<a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'>
|
<a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'>
|
||||||
<a-row :xs="24" :sm="24" :lg="12">
|
<a-row :xs="24" :sm="24" :lg="12">
|
||||||
@@ -164,12 +168,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</a-row>
|
</a-row>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigIRIp"}}' desc='{{ i18n "pages.xray.xrayConfigIRIpDesc"}}' v-model="IRIpSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.IRIp"}}' desc='{{ i18n "pages.xray.IRIpDesc"}}' v-model="IRIpSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigIRDomain"}}' desc='{{ i18n "pages.xray.xrayConfigIRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.IRDomain"}}' desc='{{ i18n "pages.xray.IRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigChinaIp"}}' desc='{{ i18n "pages.xray.xrayConfigChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.ChinaIp"}}' desc='{{ i18n "pages.xray.ChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigChinaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.ChinaDomain"}}' desc='{{ i18n "pages.xray.ChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigRussiaIp"}}' desc='{{ i18n "pages.xray.xrayConfigRussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.RussiaIp"}}' desc='{{ i18n "pages.xray.RussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigRussiaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigRussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.RussiaDomain"}}' desc='{{ i18n "pages.xray.RussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item>
|
||||||
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.VNIp"}}' desc='{{ i18n "pages.xray.VNIpDesc"}}' v-model="VNIpSettings"></setting-list-item>
|
||||||
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.VNDomain"}}' desc='{{ i18n "pages.xray.VNDomainDesc"}}' v-model="VNDomainSettings"></setting-list-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
<a-collapse-panel header='{{ i18n "pages.xray.directCountryConfigs"}}'>
|
<a-collapse-panel header='{{ i18n "pages.xray.directCountryConfigs"}}'>
|
||||||
<a-row :xs="24" :sm="24" :lg="12">
|
<a-row :xs="24" :sm="24" :lg="12">
|
||||||
@@ -180,12 +186,14 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</a-row>
|
</a-row>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectIRIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectIRIpDesc"}}' v-model="IRIpDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectIRIp"}}' desc='{{ i18n "pages.xray.DirectIRIpDesc"}}' v-model="IRIpDirectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectIRDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectIRDomainDesc"}}' v-model="IRDomainDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectIRDomain"}}' desc='{{ i18n "pages.xray.DirectIRDomainDesc"}}' v-model="IRDomainDirectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectChinaIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectChinaIpDesc"}}' v-model="ChinaIpDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectChinaIp"}}' desc='{{ i18n "pages.xray.DirectChinaIpDesc"}}' v-model="ChinaIpDirectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectChinaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectChinaDomainDesc"}}' v-model="ChinaDomainDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectChinaDomain"}}' desc='{{ i18n "pages.xray.DirectChinaDomainDesc"}}' v-model="ChinaDomainDirectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectRussiaIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectRussiaIpDesc"}}' v-model="RussiaIpDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectRussiaIp"}}' desc='{{ i18n "pages.xray.DirectRussiaIpDesc"}}' v-model="RussiaIpDirectSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectRussiaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectRussiaDomainDesc"}}' v-model="RussiaDomainDirectSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectRussiaDomain"}}' desc='{{ i18n "pages.xray.DirectRussiaDomainDesc"}}' v-model="RussiaDomainDirectSettings"></setting-list-item>
|
||||||
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectVNIp"}}' desc='{{ i18n "pages.xray.DirectVNIpDesc"}}' v-model="VNIpDirectSettings"></setting-list-item>
|
||||||
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.DirectVNDomain"}}' desc='{{ i18n "pages.xray.DirectVNDomainDesc"}}' v-model="VNDomainDirectSettings"></setting-list-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
<a-collapse-panel header='{{ i18n "pages.xray.ipv4Configs"}}'>
|
<a-collapse-panel header='{{ i18n "pages.xray.ipv4Configs"}}'>
|
||||||
<a-row :xs="24" :sm="24" :lg="12">
|
<a-row :xs="24" :sm="24" :lg="12">
|
||||||
@@ -196,8 +204,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</a-row>
|
</a-row>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigGoogleIPv4"}}' desc='{{ i18n "pages.xray.xrayConfigGoogleIPv4Desc"}}' v-model="GoogleIPv4Settings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.GoogleIPv4"}}' desc='{{ i18n "pages.xray.GoogleIPv4Desc"}}' v-model="GoogleIPv4Settings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigNetflixIPv4"}}' desc='{{ i18n "pages.xray.xrayConfigNetflixIPv4Desc"}}' v-model="NetflixIPv4Settings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.NetflixIPv4"}}' desc='{{ i18n "pages.xray.NetflixIPv4Desc"}}' v-model="NetflixIPv4Settings"></setting-list-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
<a-collapse-panel header='{{ i18n "pages.xray.warpConfigs"}}'>
|
<a-collapse-panel header='{{ i18n "pages.xray.warpConfigs"}}'>
|
||||||
<a-row :xs="24" :sm="24" :lg="12">
|
<a-row :xs="24" :sm="24" :lg="12">
|
||||||
@@ -208,10 +216,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</a-row>
|
</a-row>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigGoogleWARP"}}' desc='{{ i18n "pages.xray.xrayConfigGoogleWARPDesc"}}' v-model="GoogleWARPSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.GoogleWARP"}}' desc='{{ i18n "pages.xray.GoogleWARPDesc"}}' v-model="GoogleWARPSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigOpenAIWARP"}}' desc='{{ i18n "pages.xray.xrayConfigOpenAIWARPDesc"}}' v-model="OpenAIWARPSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.OpenAIWARP"}}' desc='{{ i18n "pages.xray.OpenAIWARPDesc"}}' v-model="OpenAIWARPSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigNetflixWARP"}}' desc='{{ i18n "pages.xray.xrayConfigNetflixWARPDesc"}}' v-model="NetflixWARPSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.NetflixWARP"}}' desc='{{ i18n "pages.xray.NetflixWARPDesc"}}' v-model="NetflixWARPSettings"></setting-list-item>
|
||||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigSpotifyWARP"}}' desc='{{ i18n "pages.xray.xrayConfigSpotifyWARPDesc"}}' v-model="SpotifyWARPSettings"></setting-list-item>
|
<setting-list-item type="switch" title='{{ i18n "pages.xray.SpotifyWARP"}}' desc='{{ i18n "pages.xray.SpotifyWARPDesc"}}' v-model="SpotifyWARPSettings"></setting-list-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
@@ -434,7 +442,7 @@
|
|||||||
{ title: 'Port', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]},
|
{ title: 'Port', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]},
|
||||||
{ title: '{{ i18n "pages.xray.rules.inbound"}}', children: [
|
{ title: '{{ i18n "pages.xray.rules.inbound"}}', children: [
|
||||||
{ title: 'Inbound Tag', dataIndex: 'inboundTag', align: 'center', width: 20, ellipsis: true },
|
{ title: 'Inbound Tag', dataIndex: 'inboundTag', align: 'center', width: 20, ellipsis: true },
|
||||||
{ title: 'User email', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]},
|
{ title: 'Client Email', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]},
|
||||||
{ title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 20 },
|
{ title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 20 },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -527,8 +535,9 @@
|
|||||||
ips: {
|
ips: {
|
||||||
local: ["geoip:private"],
|
local: ["geoip:private"],
|
||||||
cn: ["geoip:cn"],
|
cn: ["geoip:cn"],
|
||||||
ir: ["ext:geoip_IR.dat:ir","ext:geoip_IR.dat:arvancloud","ext:geoip_IR.dat:derakcloud","ext:geoip_IR.dat:iranserver"],
|
ir: ["ext:geoip_IR.dat:ir"],
|
||||||
ru: ["geoip:ru"],
|
ru: ["geoip:ru"],
|
||||||
|
vn: ["ext:geoip_VN.dat:vn"],
|
||||||
},
|
},
|
||||||
domains: {
|
domains: {
|
||||||
ads: [
|
ads: [
|
||||||
@@ -552,7 +561,12 @@
|
|||||||
"regexp:.*\\.ir$",
|
"regexp:.*\\.ir$",
|
||||||
"regexp:.*\\.xn--mgba3a4f16a$", // .ایران
|
"regexp:.*\\.xn--mgba3a4f16a$", // .ایران
|
||||||
"ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains.
|
"ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains.
|
||||||
]
|
],
|
||||||
|
vn: [
|
||||||
|
"regexp:.*\\.vn$",
|
||||||
|
"ext:geosite_VN.dat:vn",
|
||||||
|
"ext:geosite_VN.dat:ads"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
familyProtectDNS: {
|
familyProtectDNS: {
|
||||||
"servers": [
|
"servers": [
|
||||||
@@ -837,17 +851,27 @@
|
|||||||
confirm: (reverse, rules) => {
|
confirm: (reverse, rules) => {
|
||||||
reverseModal.loading();
|
reverseModal.loading();
|
||||||
if(reverse.tag.length > 0){
|
if(reverse.tag.length > 0){
|
||||||
oldtag = this.reverseData[index].tag;
|
oldData = this.reverseData[index];
|
||||||
this.deleteReverse(index);
|
|
||||||
newTemplateSettings = this.templateSettings;
|
newTemplateSettings = this.templateSettings;
|
||||||
if(newTemplateSettings.reverse == undefined) newTemplateSettings.reverse = {};
|
oldReverseIndex = newTemplateSettings.reverse[oldData.type+'s'].findIndex(rs => rs.tag == oldData.tag);
|
||||||
if(newTemplateSettings.reverse[reverse.type+'s'] == undefined) newTemplateSettings.reverse[reverse.type+'s'] = [];
|
oldRuleIndex0 = oldRules.length>0 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[0])) : -1;
|
||||||
newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
|
oldRuleIndex1 = oldRules.length==2 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[1])) : -1;
|
||||||
|
if(oldData.type == reverse.type){
|
||||||
|
newTemplateSettings.reverse[oldData.type + 's'][oldReverseIndex] = { tag: reverse.tag, domain: reverse.domain };
|
||||||
|
} else {
|
||||||
|
newTemplateSettings.reverse[oldData.type+'s'].splice(oldReverseIndex,1);
|
||||||
|
// delete empty object
|
||||||
|
if(newTemplateSettings.reverse[oldData.type+'s'].length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
|
||||||
|
// add other type of reverse if it is not exist
|
||||||
|
if(!newTemplateSettings.reverse[reverse.type+'s']) newTemplateSettings.reverse[reverse.type+'s'] = [];
|
||||||
|
newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
|
||||||
|
}
|
||||||
this.templateSettings = newTemplateSettings;
|
this.templateSettings = newTemplateSettings;
|
||||||
|
|
||||||
// Adjust Rules
|
// Adjust Rules
|
||||||
newRules = this.templateSettings.routing.rules.filter(r => r.outboundTag != oldtag && (r.inboundTag && !r.inboundTag.includes(oldtag)));
|
newRules = this.templateSettings.routing.rules;
|
||||||
newRules.push(...rules)
|
oldRuleIndex0 != -1 ? newRules[oldRuleIndex0] = rules[0] : newRules.push(rules[0]);
|
||||||
|
oldRuleIndex1 != -1 ? newRules[oldRuleIndex1] = rules[1] : newRules.push(rules[1]);
|
||||||
this.routingRuleSettings = JSON.stringify(newRules);
|
this.routingRuleSettings = JSON.stringify(newRules);
|
||||||
}
|
}
|
||||||
reverseModal.close();
|
reverseModal.close();
|
||||||
@@ -862,10 +886,17 @@
|
|||||||
realIndex = reverseTypeObj.findIndex(r => r.tag==oldData.tag && r.domain==oldData.domain);
|
realIndex = reverseTypeObj.findIndex(r => r.tag==oldData.tag && r.domain==oldData.domain);
|
||||||
newTemplateSettings.reverse[oldData.type+'s'].splice(realIndex,1);
|
newTemplateSettings.reverse[oldData.type+'s'].splice(realIndex,1);
|
||||||
|
|
||||||
|
// delete empty objects
|
||||||
if(reverseTypeObj.length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
|
if(reverseTypeObj.length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
|
||||||
if(Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings, 'reverse');
|
if(Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings, 'reverse');
|
||||||
|
|
||||||
newRules = newTemplateSettings.routing.rules.filter(r => r.outboundTag != oldData.tag && (r.inboundTag && !r.inboundTag.includes(oldData.tag)));
|
// delete related routing rules
|
||||||
|
newRules = newTemplateSettings.routing.rules;
|
||||||
|
if(oldData.type == "bridge"){
|
||||||
|
newRules = newTemplateSettings.routing.rules.filter(r => !( r.inboundTag && r.inboundTag.length == 1 && r.inboundTag[0] == oldData.tag));
|
||||||
|
} else if(oldData.type == "portal"){
|
||||||
|
newRules = newTemplateSettings.routing.rules.filter(r => r.outboundTag != oldData.tag);
|
||||||
|
}
|
||||||
newTemplateSettings.routing.rules = newRules;
|
newTemplateSettings.routing.rules = newRules;
|
||||||
|
|
||||||
this.templateSettings = newTemplateSettings;
|
this.templateSettings = newTemplateSettings;
|
||||||
@@ -1274,6 +1305,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
VNIpSettings: {
|
||||||
|
get: function () {
|
||||||
|
return doAllItemsExist(this.settingsData.ips.vn, this.blockedIPs);
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.blockedIPs = [...this.blockedIPs, ...this.settingsData.ips.vn];
|
||||||
|
} else {
|
||||||
|
this.blockedIPs = this.blockedIPs.filter(data => !this.settingsData.ips.vn.includes(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
VNDomainSettings: {
|
||||||
|
get: function () {
|
||||||
|
return doAllItemsExist(this.settingsData.domains.vn, this.blockedDomains);
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.blockedDomains = [...this.blockedDomains, ...this.settingsData.domains.vn];
|
||||||
|
} else {
|
||||||
|
this.blockedDomains = this.blockedDomains.filter(data => !this.settingsData.domains.vn.includes(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
IRIpDirectSettings: {
|
IRIpDirectSettings: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return doAllItemsExist(this.settingsData.ips.ir, this.directIPs);
|
return doAllItemsExist(this.settingsData.ips.ir, this.directIPs);
|
||||||
@@ -1346,6 +1401,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
VNIpDirectSettings: {
|
||||||
|
get: function () {
|
||||||
|
return doAllItemsExist(this.settingsData.ips.vn, this.directIPs);
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.directIPs = [...this.directIPs, ...this.settingsData.ips.vn];
|
||||||
|
} else {
|
||||||
|
this.directIPs = this.directIPs.filter(data => !this.settingsData.ips.vn.includes(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
VNDomainDirectSettings: {
|
||||||
|
get: function () {
|
||||||
|
return doAllItemsExist(this.settingsData.domains.vn, this.directDomains);
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.directDomains = [...this.directDomains, ...this.settingsData.domains.vn];
|
||||||
|
} else {
|
||||||
|
this.directDomains = this.directDomains.filter(data => !this.settingsData.domains.vn.includes(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
GoogleWARPSettings: {
|
GoogleWARPSettings: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return doAllItemsExist(this.settingsData.domains.google, this.warpDomains);
|
return doAllItemsExist(this.settingsData.domains.google, this.warpDomains);
|
||||||
|
|||||||
@@ -2,77 +2,41 @@
|
|||||||
<a-modal id="reverse-modal" v-model="reverseModal.visible" :title="reverseModal.title" @ok="reverseModal.ok"
|
<a-modal id="reverse-modal" v-model="reverseModal.visible" :title="reverseModal.title" @ok="reverseModal.ok"
|
||||||
:confirm-loading="reverseModal.confirmLoading" :closable="true" :mask-closable="false"
|
:confirm-loading="reverseModal.confirmLoading" :closable="true" :mask-closable="false"
|
||||||
:ok-text="reverseModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
:ok-text="reverseModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='{{ i18n "pages.xray.outbound.type" }}'>
|
||||||
<tr>
|
<a-select v-model="reverseModal.reverse.type" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>{{ i18n "pages.xray.outbound.type" }}</td>
|
<a-select-option v-for="x,y in reverseTypes" :value="y">[[ x ]]</a-select-option>
|
||||||
<td>
|
</a-select>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-select v-model="reverseModal.reverse.type" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-form-item label='{{ i18n "pages.xray.outbound.tag" }}'>
|
||||||
<a-select-option v-for="x,y in reverseTypes" :value="y">[[ x ]]</a-select-option>
|
<a-input v-model.trim="reverseModal.reverse.tag"></a-input>
|
||||||
</a-select>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='{{ i18n "pages.xray.outbound.domain" }}'>
|
||||||
</td>
|
<a-input v-model.trim="reverseModal.reverse.domain"></a-input>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.xray.outbound.tag" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="reverseModal.reverse.tag" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.xray.outbound.domain" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-input v-model.trim="reverseModal.reverse.domain" style="width: 250px"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<template v-if="reverseModal.reverse.type=='bridge'">
|
<template v-if="reverseModal.reverse.type=='bridge'">
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.xray.outbound.intercon" }}'>
|
||||||
<td>{{ i18n "pages.xray.outbound.intercon" }}</td>
|
<a-select v-model="reverseModal.rules[0].outboundTag" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td>
|
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
|
||||||
<a-form-item>
|
</a-select>
|
||||||
<a-select v-model="reverseModal.rules[0].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-form-item>
|
||||||
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
|
<a-form-item label='{{ i18n "pages.xray.rules.outbound" }}'>
|
||||||
</a-select>
|
<a-select v-model="reverseModal.rules[1].outboundTag" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</a-form-item>
|
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
|
||||||
</td>
|
</a-select>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.xray.rules.outbound" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="reverseModal.rules[1].outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option v-for="x in reverseModal.outboundTags" :value="x">[[ x ]]</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<tr>
|
<a-form-item label='{{ i18n "pages.xray.outbound.intercon" }}'>
|
||||||
<td>{{ i18n "pages.xray.outbound.intercon" }}</td>
|
<a-checkbox-group
|
||||||
<td>
|
v-model="reverseModal.rules[0].inboundTag"
|
||||||
<a-form-item>
|
:options="reverseModal.inboundTags"></a-checkbox-group>
|
||||||
<a-checkbox-group
|
</a-form-item>
|
||||||
v-model="reverseModal.rules[0].inboundTag"
|
<a-form-item label='{{ i18n "pages.xray.rules.inbound" }}'>
|
||||||
:options="reverseModal.inboundTags"></a-checkbox-group>
|
<a-checkbox-group
|
||||||
</a-form-item>
|
v-model="reverseModal.rules[1].inboundTag"
|
||||||
</td>
|
:options="reverseModal.inboundTags"></a-checkbox-group>
|
||||||
</tr>
|
</a-form-item>
|
||||||
<tr>
|
|
||||||
<td>{{ i18n "pages.xray.rules.inbound" }}</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-checkbox-group
|
|
||||||
v-model="reverseModal.rules[1].inboundTag"
|
|
||||||
:options="reverseModal.inboundTags"></a-checkbox-group>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|||||||
@@ -2,149 +2,111 @@
|
|||||||
<a-modal id="rule-modal" v-model="ruleModal.visible" :title="ruleModal.title" @ok="ruleModal.ok"
|
<a-modal id="rule-modal" v-model="ruleModal.visible" :title="ruleModal.title" @ok="ruleModal.ok"
|
||||||
:confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false"
|
:confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false"
|
||||||
:ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
:ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
||||||
<a-form layout="inline">
|
<a-form :colon="false" :label-col="{ md: {span:6} }" :wrapper-col="{ md: {span:14} }">
|
||||||
<table width="100%" class="ant-table-tbody">
|
<a-form-item label='Domain Matcher'>
|
||||||
<tr>
|
<a-select v-model="ruleModal.rule.domainMatcher" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<td style="width: 30%;">Domain Matcher</td>
|
|
||||||
<td>
|
|
||||||
<a-form-item>
|
|
||||||
<a-select v-model="ruleModal.rule.domainMatcher" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
|
||||||
<a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
|
<a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</td>
|
<a-form-item>
|
||||||
</tr>
|
<template slot="label">
|
||||||
<tr>
|
|
||||||
<td>Source IPs
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle"></a-icon>
|
Source IPs <a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="ruleModal.rule.source"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="ruleModal.rule.source" style="width: 250px"></a-input>
|
<a-form-item>
|
||||||
</a-form-item>
|
<template slot="label">Source Port
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Source Port
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle"></a-icon>
|
Source Port <a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="ruleModal.rule.sourcePort"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="ruleModal.rule.sourcePort" style="width: 250px"></a-input>
|
<a-form-item label='Network'>
|
||||||
</a-form-item>
|
<a-select v-model="ruleModal.rule.network" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</td>
|
<a-select-option v-for="x in ['','TCP','UDP','TCP,UDP']" :value="x">[[ x ]]</a-select-option>
|
||||||
</tr>
|
</a-select>
|
||||||
<tr>
|
</a-form-item>
|
||||||
<td>Network</td>
|
<a-form-item label='Protocol'>
|
||||||
<td>
|
<a-select v-model="ruleModal.rule.protocol" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-form-item>
|
<a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
|
||||||
<a-select v-model="ruleModal.rule.network" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</a-select>
|
||||||
<a-select-option v-for="x in ['','tcp','tdp','tcp,udp']" :value="x">[[ x ]]</a-select-option>
|
</a-form-item>
|
||||||
</a-select>
|
<a-form-item label='Attributes'>
|
||||||
</a-form-item>
|
<a-button size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])">+</a-button>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item :wrapper-col="{span: 24}">
|
||||||
<tr>
|
<a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs">
|
||||||
<td>Protocol</td>
|
<a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
||||||
<td>
|
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
||||||
<a-form-item>
|
</a-input>
|
||||||
<a-select v-model="ruleModal.rule.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
||||||
<a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
|
<a-button slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)">-</a-button>
|
||||||
</a-select>
|
</a-input>
|
||||||
</a-form-item>
|
</a-input-group>
|
||||||
</td>
|
</a-form-item>
|
||||||
</tr>
|
<a-form-item>
|
||||||
<tr>
|
<template slot="label">
|
||||||
<td colspan="2">
|
|
||||||
<a-form-item>
|
|
||||||
<span>Attributes</span>
|
|
||||||
<a-button size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])">+</a-button>
|
|
||||||
<a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs">
|
|
||||||
<a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
|
|
||||||
<template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
|
|
||||||
</a-input>
|
|
||||||
<a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
|
|
||||||
<a-button slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)">-</a-button>
|
|
||||||
</a-input>
|
|
||||||
</a-input-group>
|
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>IP
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle"></a-icon>
|
IP <a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="ruleModal.rule.ip"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="ruleModal.rule.ip" style="width: 250px"></a-input>
|
<a-form-item>
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Domain
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle"></a-icon>
|
Domain <a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="ruleModal.rule.domain"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="ruleModal.rule.domain" style="width: 250px"></a-input>
|
<a-form-item>
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Port
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-icon type="question-circle"></a-icon>
|
User <a-icon type="question-circle"></a-icon>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</td>
|
</template>
|
||||||
<td>
|
<a-input v-model.trim="ruleModal.rule.user"></a-input>
|
||||||
<a-form-item>
|
</a-form-item>
|
||||||
<a-input v-model.trim="ruleModal.rule.port" style="width: 250px"></a-input>
|
<a-form-item>
|
||||||
</a-form-item>
|
<template slot="label">
|
||||||
</td>
|
<a-tooltip>
|
||||||
</tr>
|
<template slot="title">
|
||||||
<tr>
|
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||||
<td>Inbound Tags</td>
|
</template>
|
||||||
<td>
|
Port <a-icon type="question-circle"></a-icon>
|
||||||
<a-form-item>
|
</a-tooltip>
|
||||||
<a-select v-model="ruleModal.rule.inboundTag" mode="multiple" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
</template>
|
||||||
<a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
|
<a-input v-model.trim="ruleModal.rule.port"></a-input>
|
||||||
</a-select>
|
</a-form-item>
|
||||||
</a-form-item>
|
<a-form-item label='Inbound Tags'>
|
||||||
</td>
|
<a-select v-model="ruleModal.rule.inboundTag" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
</tr>
|
<a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
|
||||||
<tr>
|
</a-select>
|
||||||
<td>Outbound Tag</td>
|
</a-form-item>
|
||||||
<td>
|
<a-form-item label='Outbound Tag'>
|
||||||
<a-form-item>
|
<a-select v-model="ruleModal.rule.outboundTag" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
<a-select v-model="ruleModal.rule.outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
|
<a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
|
||||||
<a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
|
</a-select>
|
||||||
</a-select>
|
</a-form-item>
|
||||||
</a-form-item>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
"edit" = "Edit"
|
"edit" = "Edit"
|
||||||
"delete" = "Delete"
|
"delete" = "Delete"
|
||||||
"reset" = "Reset"
|
"reset" = "Reset"
|
||||||
"copySuccess" = "Copied successfully"
|
"copySuccess" = "Copied Successfully"
|
||||||
"sure" = "Sure"
|
"sure" = "Sure"
|
||||||
"encryption" = "Encryption"
|
"encryption" = "Encryption"
|
||||||
"transmission" = "Transmission"
|
"transmission" = "Transmission"
|
||||||
@@ -40,12 +40,12 @@
|
|||||||
"depletingSoon" = "Depleting"
|
"depletingSoon" = "Depleting"
|
||||||
"offline" = "Offline"
|
"offline" = "Offline"
|
||||||
"online" = "Online"
|
"online" = "Online"
|
||||||
"domainName" = "Domain name"
|
"domainName" = "Domain Name"
|
||||||
"monitor" = "Listening IP"
|
"monitor" = "Listening IP"
|
||||||
"certificate" = "Certificate"
|
"certificate" = "Certificate"
|
||||||
"fail" = "Fail"
|
"fail" = "Fail"
|
||||||
"success" = "Success"
|
"success" = "Success"
|
||||||
"getVersion" = "Get version"
|
"getVersion" = "Get Version"
|
||||||
"install" = "Install"
|
"install" = "Install"
|
||||||
"clients" = "Clients"
|
"clients" = "Clients"
|
||||||
"usage" = "Usage"
|
"usage" = "Usage"
|
||||||
@@ -59,11 +59,11 @@
|
|||||||
"settings" = "Panel Settings"
|
"settings" = "Panel Settings"
|
||||||
"xray" = "Xray Settings"
|
"xray" = "Xray Settings"
|
||||||
"logout" = "Logout"
|
"logout" = "Logout"
|
||||||
"link" = "Other"
|
"link" = "Management"
|
||||||
|
|
||||||
[pages.login]
|
[pages.login]
|
||||||
"title" = "Login"
|
"title" = "Login"
|
||||||
"loginAgain" = "The login time limit has expired. Please log in again."
|
"loginAgain" = "Your session has expired, please log in again"
|
||||||
|
|
||||||
[pages.login.toasts]
|
[pages.login.toasts]
|
||||||
"invalidFormData" = "Input data format is invalid."
|
"invalidFormData" = "Input data format is invalid."
|
||||||
@@ -74,8 +74,8 @@
|
|||||||
|
|
||||||
[pages.index]
|
[pages.index]
|
||||||
"title" = "System Status"
|
"title" = "System Status"
|
||||||
"memory" = "Memory"
|
"memory" = "RAM"
|
||||||
"hard" = "Hard Disk"
|
"hard" = "Disk"
|
||||||
"xrayStatus" = "Status"
|
"xrayStatus" = "Status"
|
||||||
"stopXray" = "Stop"
|
"stopXray" = "Stop"
|
||||||
"restartXray" = "Restart"
|
"restartXray" = "Restart"
|
||||||
@@ -85,21 +85,21 @@
|
|||||||
"operationHours" = "Uptime"
|
"operationHours" = "Uptime"
|
||||||
"systemLoad" = "System Load"
|
"systemLoad" = "System Load"
|
||||||
"systemLoadDesc" = "system load average for the past 1, 5, and 15 minutes"
|
"systemLoadDesc" = "system load average for the past 1, 5, and 15 minutes"
|
||||||
"connectionTcpCountDesc" = "Total TCP connections across all network cards."
|
"connectionTcpCountDesc" = "Total TCP connections across all network cards"
|
||||||
"connectionUdpCountDesc" = "Total UDP connections across all network cards."
|
"connectionUdpCountDesc" = "Total UDP connections across all network cards"
|
||||||
"connectionCount" = "Number of Connections"
|
"connectionCount" = "Number of Connections"
|
||||||
"upSpeed" = "Total upload speed for all network cards."
|
"upSpeed" = "Total upload speed for all network cards"
|
||||||
"downSpeed" = "Total download speed for all network cards."
|
"downSpeed" = "Total download speed for all network cards"
|
||||||
"totalSent" = "Total upload traffic of all network cards since system startup."
|
"totalSent" = "Total upload data across all network cards since OS startup"
|
||||||
"totalReceive" = "Total download data across all network cards since system startup."
|
"totalReceive" = "Total download data across all network cards since OS startup"
|
||||||
"xraySwitchVersionDialog" = "Switch Xray Version"
|
"xraySwitchVersionDialog" = "Switch Xray Version"
|
||||||
"xraySwitchVersionDialogDesc" = "Are you sure you want to switch the Xray version to"
|
"xraySwitchVersionDialogDesc" = "Are you sure you want to switch the Xray version to"
|
||||||
"dontRefresh" = "Installation is in progress, please do not refresh this page."
|
"dontRefresh" = "Installation is in progress, please do not refresh this page"
|
||||||
"logs" = "Logs"
|
"logs" = "Logs"
|
||||||
"config" = "Config"
|
"config" = "Config"
|
||||||
"backup" = "Backup & Restore"
|
"backup" = "Backup & Restore"
|
||||||
"backupTitle" = "Backup & Restore Database"
|
"backupTitle" = "Backup & Restore Database"
|
||||||
"backupDescription" = "Remember to backup before importing a new database."
|
"backupDescription" = "It is recommended to backup before importing a new database."
|
||||||
"exportDatabase" = "Download Database"
|
"exportDatabase" = "Download Database"
|
||||||
"importDatabase" = "Upload Database"
|
"importDatabase" = "Upload Database"
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
"destinationPort" = "Destination Port"
|
"destinationPort" = "Destination Port"
|
||||||
"targetAddress" = "Target Address"
|
"targetAddress" = "Target Address"
|
||||||
"monitorDesc" = "Leave blank by default"
|
"monitorDesc" = "Leave blank by default"
|
||||||
"meansNoLimit" = "Means No Limit"
|
"meansNoLimit" = "Means no limit"
|
||||||
"totalFlow" = "Total Flow"
|
"totalFlow" = "Total Flow"
|
||||||
"leaveBlankToNeverExpire" = "Leave Blank to Never Expire"
|
"leaveBlankToNeverExpire" = "Leave Blank to Never Expire"
|
||||||
"noRecommendKeepDefault" = "No special requirements to maintain default settings"
|
"noRecommendKeepDefault" = "No special requirements to maintain default settings"
|
||||||
@@ -152,16 +152,16 @@
|
|||||||
"cloneInboundContent" = "All settings of this inbound, except for Port, Listening IP, and Clients, will be applied to the clone."
|
"cloneInboundContent" = "All settings of this inbound, except for Port, Listening IP, and Clients, will be applied to the clone."
|
||||||
"cloneInboundOk" = "Clone"
|
"cloneInboundOk" = "Clone"
|
||||||
"resetAllTraffic" = "Reset All Inbounds Traffic"
|
"resetAllTraffic" = "Reset All Inbounds Traffic"
|
||||||
"resetAllTrafficTitle" = "Reset all inbounds traffic"
|
"resetAllTrafficTitle" = "Reset All Inbounds Traffic"
|
||||||
"resetAllTrafficContent" = "Are you sure you want to reset all inbounds traffic?"
|
"resetAllTrafficContent" = "Are you sure you want to reset all inbounds traffic?"
|
||||||
"resetInboundClientTraffics" = "Reset Clients Traffic"
|
"resetInboundClientTraffics" = "Reset Clients Traffic"
|
||||||
"resetInboundClientTrafficTitle" = "Reset all client traffic"
|
"resetInboundClientTrafficTitle" = "Reset Clients Traffic"
|
||||||
"resetInboundClientTrafficContent" = "Are you sure you want to reset all traffic for this inbound's clients?"
|
"resetInboundClientTrafficContent" = "Are you sure you want to reset all traffic for this inbound's clients?"
|
||||||
"resetAllClientTraffics" = "Reset All Clients Traffic"
|
"resetAllClientTraffics" = "Reset All Clients Traffic"
|
||||||
"resetAllClientTrafficTitle" = "Reset all clients traffic"
|
"resetAllClientTrafficTitle" = "Reset all clients traffic"
|
||||||
"resetAllClientTrafficContent" = "Are you sure you want to reset all traffics for all clients?"
|
"resetAllClientTrafficContent" = "Are you sure you want to reset all traffics for all clients?"
|
||||||
"delDepletedClients" = "Delete Depleted Clients"
|
"delDepletedClients" = "Delete Depleted Clients"
|
||||||
"delDepletedClientsTitle" = "Delete depleted clients"
|
"delDepletedClientsTitle" = "Delete Depleted Clients"
|
||||||
"delDepletedClientsContent" = "Are you sure you want to delete all depleted clients?"
|
"delDepletedClientsContent" = "Are you sure you want to delete all depleted clients?"
|
||||||
"email" = "Email"
|
"email" = "Email"
|
||||||
"emailDesc" = "Please provide a unique email address."
|
"emailDesc" = "Please provide a unique email address."
|
||||||
@@ -170,23 +170,23 @@
|
|||||||
"IPLimitlog" = "IP Log"
|
"IPLimitlog" = "IP Log"
|
||||||
"IPLimitlogDesc" = "IPs history log (before enabling inbound after it has been disabled by IP limit, you should clear the log)."
|
"IPLimitlogDesc" = "IPs history log (before enabling inbound after it has been disabled by IP limit, you should clear the log)."
|
||||||
"IPLimitlogclear" = "Clear The Log"
|
"IPLimitlogclear" = "Clear The Log"
|
||||||
"setDefaultCert" = "Set cert from panel"
|
"setDefaultCert" = "Set Cert from Panel"
|
||||||
"xtlsDesc" = "Xray core needs to be 1.7.5"
|
"xtlsDesc" = "Xray core needs to be 1.7.5"
|
||||||
"realityDesc" = "Xray core needs to be 1.8.0 or higher."
|
"realityDesc" = "Xray core needs to be 1.8.0 or higher."
|
||||||
"telegramDesc" = "use Telegram ID without @ or chat IDs ( you can get it here @userinfobot or use '/id' command in bot )"
|
"telegramDesc" = "use Telegram ID without @ or chat IDs ( you can get it here @userinfobot or use '/id' command in bot )"
|
||||||
"subscriptionDesc" = "you can find your sub link on Details, also you can use the same name for several configurations"
|
"subscriptionDesc" = "you can find your sub link on Details, also you can use the same name for several configurations"
|
||||||
"info" = "Info"
|
"info" = "Info"
|
||||||
"same" = "Same"
|
"same" = "Same"
|
||||||
"inboundData" = "Inbound's data"
|
"inboundData" = "Inbound's Data"
|
||||||
"copyToClipboard" = "Copy to clipboard"
|
"copyToClipboard" = "Copy to Clipboard"
|
||||||
"import" = "Import"
|
"import" = "Import"
|
||||||
"importInbound" = "Import an inbound"
|
"importInbound" = "Import an Inbound"
|
||||||
|
|
||||||
[pages.client]
|
[pages.client]
|
||||||
"add" = "Add Client"
|
"add" = "Add Client"
|
||||||
"edit" = "Edit Client"
|
"edit" = "Edit Client"
|
||||||
"submitAdd" = "Add Client"
|
"submitAdd" = "Add Client"
|
||||||
"submitEdit" = "Save changes"
|
"submitEdit" = "Save Changes"
|
||||||
"clientCount" = "Number of Clients"
|
"clientCount" = "Number of Clients"
|
||||||
"bulk" = "Add Bulk"
|
"bulk" = "Add Bulk"
|
||||||
"method" = "Method"
|
"method" = "Method"
|
||||||
@@ -194,28 +194,28 @@
|
|||||||
"last" = "Last"
|
"last" = "Last"
|
||||||
"prefix" = "Prefix"
|
"prefix" = "Prefix"
|
||||||
"postfix" = "Postfix"
|
"postfix" = "Postfix"
|
||||||
"delayedStart" = "Start after first use"
|
"delayedStart" = "Start After First Use"
|
||||||
"expireDays" = "Expire days"
|
"expireDays" = "Expire Days"
|
||||||
"days" = "day(s)"
|
"days" = "Day(s)"
|
||||||
"renew" = "Auto renew"
|
"renew" = "Auto Renew"
|
||||||
"renewDesc" = "Auto renew days after expiration. 0 = disable"
|
"renewDesc" = "Auto renew days after expiration. 0 = disable"
|
||||||
|
|
||||||
[pages.inbounds.toasts]
|
[pages.inbounds.toasts]
|
||||||
"obtain" = "Obtain"
|
"obtain" = "Obtain"
|
||||||
|
|
||||||
[pages.inbounds.stream.general]
|
[pages.inbounds.stream.general]
|
||||||
"requestHeader" = "Request header"
|
"requestHeader" = "Request Header"
|
||||||
"name" = "Name"
|
"name" = "Name"
|
||||||
"value" = "Value"
|
"value" = "Value"
|
||||||
|
|
||||||
[pages.inbounds.stream.tcp]
|
[pages.inbounds.stream.tcp]
|
||||||
"requestVersion" = "Request version"
|
"requestVersion" = "Request Version"
|
||||||
"requestMethod" = "Request method"
|
"requestMethod" = "Request Method"
|
||||||
"requestPath" = "Request path"
|
"requestPath" = "Request Path"
|
||||||
"responseVersion" = "Response version"
|
"responseVersion" = "Response Version"
|
||||||
"responseStatus" = "Response status"
|
"responseStatus" = "Response Status"
|
||||||
"responseStatusDescription" = "Response status description"
|
"responseStatusDescription" = "Response Status Description"
|
||||||
"responseHeader" = "Response header"
|
"responseHeader" = "Response Header"
|
||||||
|
|
||||||
[pages.inbounds.stream.quic]
|
[pages.inbounds.stream.quic]
|
||||||
"encryption" = "Encryption"
|
"encryption" = "Encryption"
|
||||||
@@ -224,8 +224,8 @@
|
|||||||
"title" = "Settings"
|
"title" = "Settings"
|
||||||
"save" = "Save"
|
"save" = "Save"
|
||||||
"infoDesc" = "Every change made here needs to be saved. Please restart the panel to apply changes."
|
"infoDesc" = "Every change made here needs to be saved. Please restart the panel to apply changes."
|
||||||
"restartPanel" = "Restart Panel "
|
"restartPanel" = "Restart Panel"
|
||||||
"restartPanelDesc" = "Are you sure you want to restart the panel? Click OK to restart after 3 seconds. If you cannot access the panel after restarting, please view the panel log information on the server."
|
"restartPanelDesc" = "Are you sure you want to restart the panel? click OK to restart after 3 seconds. If you cannot access the panel after restarting, please view the panel log info on the server."
|
||||||
"actions" = "Actions"
|
"actions" = "Actions"
|
||||||
"resetDefaultConfig" = "Reset to Default Configuration"
|
"resetDefaultConfig" = "Reset to Default Configuration"
|
||||||
"panelSettings" = "Panel Settings"
|
"panelSettings" = "Panel Settings"
|
||||||
@@ -234,68 +234,68 @@
|
|||||||
"panelListeningIP" = "Panel Listening IP"
|
"panelListeningIP" = "Panel Listening IP"
|
||||||
"panelListeningIPDesc" = "Leave blank by default to monitor all IPs."
|
"panelListeningIPDesc" = "Leave blank by default to monitor all IPs."
|
||||||
"panelListeningDomain" = "Panel Listening Domain"
|
"panelListeningDomain" = "Panel Listening Domain"
|
||||||
"panelListeningDomainDesc" = "Leave blank by default to monitor all domains and IPs"
|
"panelListeningDomainDesc" = "Leave blank by default to monitor all domains and IPs."
|
||||||
"panelPort" = "Panel Port"
|
"panelPort" = "Panel Port"
|
||||||
"panelPortDesc" = "The port used to display this panel"
|
"panelPortDesc" = "Port number for serving the panel."
|
||||||
"publicKeyPath" = "Panel Certificate Public Key File Path"
|
"publicKeyPath" = "Panel Certificate Public Key Path"
|
||||||
"publicKeyPathDesc" = "Fill in an absolute path starting with."
|
"publicKeyPathDesc" = "Fill in an absolute path starting with."
|
||||||
"privateKeyPath" = "Panel Certificate Private Key File Path"
|
"privateKeyPath" = "Panel Certificate Private Key Path"
|
||||||
"privateKeyPathDesc" = "Fill in an absolute path starting with."
|
"privateKeyPathDesc" = "Fill in an absolute path starting with."
|
||||||
"panelUrlPath" = "Panel URL Root Path"
|
"panelUrlPath" = "Panel URL Root Path"
|
||||||
"panelUrlPathDesc" = "Must start with '/' and end with."
|
"panelUrlPathDesc" = "Must start with '/' and end with."
|
||||||
"pageSize" = "Pagination size"
|
"pageSize" = "Pagination Size"
|
||||||
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
|
"pageSizeDesc" = "Define page size for inbounds table. Set 0 to disable"
|
||||||
"remarkModel" = "Remark Model and Seperation charachter"
|
"remarkModel" = "Remark Model and Seperation Charachter"
|
||||||
"sampleRemark" = "Sample remark"
|
"sampleRemark" = "Sample Remark"
|
||||||
"oldUsername" = "Current Username"
|
"oldUsername" = "Current Username"
|
||||||
"currentPassword" = "Current Password"
|
"currentPassword" = "Current Password"
|
||||||
"newUsername" = "New Username"
|
"newUsername" = "New Username"
|
||||||
"newPassword" = "New Password"
|
"newPassword" = "New Password"
|
||||||
"telegramBotEnable" = "Enable Telegram bot"
|
"telegramBotEnable" = "Enable Telegram Bot"
|
||||||
"telegramBotEnableDesc" = "Connect to the features of this panel through the Telegram bot"
|
"telegramBotEnableDesc" = "Connect to the features of this panel through the Telegram bot."
|
||||||
"telegramToken" = "Telegram Token"
|
"telegramToken" = "Telegram Token"
|
||||||
"telegramTokenDesc" = "You must get the token from the manager of Telegram bots @botfather"
|
"telegramTokenDesc" = "The token you have got from @BotFather."
|
||||||
"telegramChatId" = "Telegram Admin Chat IDs"
|
"telegramChatId" = "Telegram Admin Chat IDs"
|
||||||
"telegramChatIdDesc" = "Multiple Chat IDs separated by comma. use @userinfobot or use '/id' command in bot to get your Chat IDs."
|
"telegramChatIdDesc" = "Multiple chat IDs separated by comma. use @userinfobot or use '/id' command in bot to get your Chat IDs."
|
||||||
"telegramNotifyTime" = "Telegram bot notification time"
|
"telegramNotifyTime" = "Telegram bot notification time"
|
||||||
"telegramNotifyTimeDesc" = "Use Crontab timing format."
|
"telegramNotifyTimeDesc" = "Use crontab timing format."
|
||||||
"tgNotifyBackup" = "Database Backup"
|
"tgNotifyBackup" = "Database Backup"
|
||||||
"tgNotifyBackupDesc" = "Include database backup file with report notification."
|
"tgNotifyBackupDesc" = "Include database backup file with report notification."
|
||||||
"tgNotifyLogin" = "Login Notification"
|
"tgNotifyLogin" = "Login Notification"
|
||||||
"tgNotifyLoginDesc" = "Displays the username, IP address, and time when someone tries to log into your panel."
|
"tgNotifyLoginDesc" = "Displays the username, IP address, and time when someone tries to log into your panel."
|
||||||
"sessionMaxAge" = "Session maximum age"
|
"sessionMaxAge" = "Session Duration"
|
||||||
"sessionMaxAgeDesc" = "The duration of a login session (unit: minute)"
|
"sessionMaxAgeDesc" = "The duration of a login session. (unit: minute)"
|
||||||
"expireTimeDiff" = "Expiration threshold for notification"
|
"expireTimeDiff" = "Client Expiration Threshold Notification"
|
||||||
"expireTimeDiffDesc" = "Get notified about account expiration before the threshold (unit: day)"
|
"expireTimeDiffDesc" = "Get notified about client expiration before the threshold. (unit: day)"
|
||||||
"trafficDiff" = "Traffic threshold for notification"
|
"trafficDiff" = "Traffic Limit Threshold Notification"
|
||||||
"trafficDiffDesc" = "Get notified about traffic exhaustion before reaching the threshold (unit: GB)"
|
"trafficDiffDesc" = "Get notified about traffic exhaustion before reaching the threshold. (unit: GB)"
|
||||||
"tgNotifyCpu" = "CPU percentage alert threshold"
|
"tgNotifyCpu" = "CPU Load Threshold Notification"
|
||||||
"tgNotifyCpuDesc" = "Receive notification if CPU usage exceeds this threshold (unit: %)"
|
"tgNotifyCpuDesc" = "Get notified if CPU usage exceeds this threshold. (unit: %)"
|
||||||
"timeZone" = "Time zone"
|
"timeZone" = "Time zone"
|
||||||
"timeZoneDesc" = "Scheduled tasks run according to the time in this time zone."
|
"timeZoneDesc" = "Scheduled tasks run according to the time in this time zone."
|
||||||
"subSettings" = "Subscription"
|
"subSettings" = "Subscription"
|
||||||
"subEnable" = "Enable service"
|
"subEnable" = "Enable Service"
|
||||||
"subEnableDesc" = "Subscription feature with separate configuration"
|
"subEnableDesc" = "Subscription feature with separate configuration."
|
||||||
"subListen" = "Listening IP"
|
"subListen" = "Listening IP"
|
||||||
"subListenDesc" = "Leave blank by default to monitor all IPs"
|
"subListenDesc" = "Leave blank by default to monitor all IPs."
|
||||||
"subPort" = "Subscription Port"
|
"subPort" = "Subscription Port"
|
||||||
"subPortDesc" = "Port number for serving the subscription service must be unused in server"
|
"subPortDesc" = "Port number for serving the subscription service. Must be unused in server."
|
||||||
"subCertPath" = "Subscription Certificate Public Key File Path"
|
"subCertPath" = "Subscription Certificate Public Key Path"
|
||||||
"subCertPathDesc" = "Fill in an absolute path starting with '/'"
|
"subCertPathDesc" = "Fill in an absolute path starting with '/'"
|
||||||
"subKeyPath" = "Subscription Certificate Private Key File Path"
|
"subKeyPath" = "Subscription Certificate Private Key Path"
|
||||||
"subKeyPathDesc" = "Fill in an absolute path starting with '/'"
|
"subKeyPathDesc" = "Fill in an absolute path starting with '/'"
|
||||||
"subPath" = "Subscription URL Root Path"
|
"subPath" = "Subscription URL Root Path"
|
||||||
"subPathDesc" = "Must start with '/' and end with '/'"
|
"subPathDesc" = "Must start with '/' and end with '/'"
|
||||||
"subDomain" = "Listening Domain"
|
"subDomain" = "Listening Domain"
|
||||||
"subDomainDesc" = "Leave blank by default to monitor all domains and IPs"
|
"subDomainDesc" = "Leave blank by default to monitor all domains and IPs."
|
||||||
"subUpdates" = "Subscription update intervals"
|
"subUpdates" = "Subscription update intervals"
|
||||||
"subUpdatesDesc" = "Interval hours between updates in client application"
|
"subUpdatesDesc" = "Interval hours between updates in client application."
|
||||||
"subEncrypt" = "Encrypt configs"
|
"subEncrypt" = "Encode Configs"
|
||||||
"subEncryptDesc" = "Encrypt the returned configs in subscription"
|
"subEncryptDesc" = "Encode the returned configs in subscription."
|
||||||
"subShowInfo" = "Show usage info"
|
"subShowInfo" = "Show Usage Info"
|
||||||
"subShowInfoDesc" = "Show remained traffic and date after config name"
|
"subShowInfoDesc" = "Show remained traffic and date after config name."
|
||||||
"subURI" = "Reverse Proxy URI"
|
"subURI" = "Reverse Proxy URI"
|
||||||
"subURIDesc" = "Change base URI of subscription URL for using on behind of proxies"
|
"subURIDesc" = "Change base URI of subscription URL for using on behind of proxies."
|
||||||
|
|
||||||
[pages.xray]
|
[pages.xray]
|
||||||
"title" = "Xray Settings"
|
"title" = "Xray Settings"
|
||||||
@@ -315,71 +315,75 @@
|
|||||||
"ipv4ConfigsDesc" = "These options will route to target domains only via IPv4."
|
"ipv4ConfigsDesc" = "These options will route to target domains only via IPv4."
|
||||||
"warpConfigs" = "WARP Configs"
|
"warpConfigs" = "WARP Configs"
|
||||||
"warpConfigsDesc" = "Caution: Before using these options, install WARP in socks5 proxy mode on your server by following the steps on the panel's GitHub. WARP will route traffic to websites through Cloudflare servers."
|
"warpConfigsDesc" = "Caution: Before using these options, install WARP in socks5 proxy mode on your server by following the steps on the panel's GitHub. WARP will route traffic to websites through Cloudflare servers."
|
||||||
"xrayConfigTemplate" = "Xray Configuration Template"
|
"Template" = "Xray Configuration Template"
|
||||||
"xrayConfigTemplateDesc" = "Generate the final Xray configuration file based on this template."
|
"TemplateDesc" = "Generate the final Xray configuration file based on this template."
|
||||||
"xrayConfigFreedomStrategy" = "Configure Strategy for Freedom Protocol"
|
"FreedomStrategy" = "Configure Strategy for Freedom Protocol"
|
||||||
"xrayConfigFreedomStrategyDesc" = "Set the output strategy of the network in the Freedom Protocol."
|
"FreedomStrategyDesc" = "Set the output strategy of the network in the Freedom Protocol."
|
||||||
"xrayConfigRoutingStrategy" = "Configure Domains Routing Strategy"
|
"RoutingStrategy" = "Configure Domains Routing Strategy"
|
||||||
"xrayConfigRoutingStrategyDesc" = "Set the overall routing strategy for DNS resolving."
|
"RoutingStrategyDesc" = "Set the overall routing strategy for DNS resolving."
|
||||||
"xrayConfigTorrent" = "Ban BitTorrent Usage"
|
"Torrent" = "Ban BitTorrent Protocol"
|
||||||
"xrayConfigTorrentDesc" = "Change the configuration template to avoid using BitTorrent by users."
|
"TorrentDesc" = "Change the configuration template to avoid using BitTorrent protocol."
|
||||||
"xrayConfigPrivateIp" = "Ban Private IP Ranges to Connect"
|
"PrivateIp" = "Ban Private IPs to Connect"
|
||||||
"xrayConfigPrivateIpDesc" = "Change the configuration template to avoid connecting to private IP ranges."
|
"PrivateIpDesc" = "Change the configuration template to avoid connecting to private IP ranges."
|
||||||
"xrayConfigAds" = "Block Ads"
|
"Ads" = "Block Ads"
|
||||||
"xrayConfigAdsDesc" = "Change the configuration template to block ads."
|
"AdsDesc" = "Change the configuration template to block ads."
|
||||||
"xrayConfigFamily" = "Block Malware and Adult Content"
|
"Family" = "Block Malware and Adult Content"
|
||||||
"xrayConfigFamilyDesc" = "DNS resolvers to block malware and adult content for family protection."
|
"FamilyDesc" = "DNS resolvers to block malware and adult content for family protection."
|
||||||
"xrayConfigSpeedtest" = "Block Speedtest Websites"
|
"Speedtest" = "Block Speedtest Websites"
|
||||||
"xrayConfigSpeedtestDesc" = "Change the configuration template to avoid connecting to speedtest websites."
|
"SpeedtestDesc" = "Change the configuration template to avoid connecting to speedtest websites."
|
||||||
"xrayConfigIRIp" = "Disable connection to Iran IP ranges"
|
"IRIp" = "Disable Connection to Iran IPs"
|
||||||
"xrayConfigIRIpDesc" = "Change the configuration template to avoid connecting to Iran IP ranges."
|
"IRIpDesc" = "Change the configuration template to avoid connecting to Iran IP ranges."
|
||||||
"xrayConfigIRDomain" = "Disable connection to Iran domains"
|
"IRDomain" = "Disable Connection to Iran Domains"
|
||||||
"xrayConfigIRDomainDesc" = "Change the configuration template to avoid connecting to Iran domains."
|
"IRDomainDesc" = "Change the configuration template to avoid connecting to Iran domains."
|
||||||
"xrayConfigChinaIp" = "Disable connection to China IP ranges"
|
"ChinaIp" = "Disable Connection to China IPs"
|
||||||
"xrayConfigChinaIpDesc" = "Change the configuration template to avoid connecting to China IP ranges."
|
"ChinaIpDesc" = "Change the configuration template to avoid connecting to China IP ranges."
|
||||||
"xrayConfigChinaDomain" = "Disable connection to China domains"
|
"ChinaDomain" = "Disable Connection to China Domains"
|
||||||
"xrayConfigChinaDomainDesc" = "Change the configuration template to avoid connecting to China domains."
|
"ChinaDomainDesc" = "Change the configuration template to avoid connecting to China domains."
|
||||||
"xrayConfigRussiaIp" = "Disable connection to Russia IP ranges"
|
"RussiaIp" = "Disable Connection to Russia IPs"
|
||||||
"xrayConfigRussiaIpDesc" = "Change the configuration template to avoid connecting to Russia IP ranges."
|
"RussiaIpDesc" = "Change the configuration template to avoid connecting to Russia IP ranges."
|
||||||
"xrayConfigRussiaDomain" = "Disable connection to Russia domains"
|
"RussiaDomain" = "Disable Connection to Russia Domains"
|
||||||
"xrayConfigRussiaDomainDesc" = "Change the configuration template to avoid connecting to Russia domains."
|
"RussiaDomainDesc" = "Change the configuration template to avoid connecting to Russia domains."
|
||||||
"xrayConfigDirectIRIp" = "Direct connection to Iran IP ranges"
|
"VNIp" = "Disable Connection to Vietnam IPs"
|
||||||
"xrayConfigDirectIRIpDesc" = "Change the configuration template for direct connecting to Iran IP ranges."
|
"VNIpDesc" = "Change the configuration template to avoid connecting to Vietnam IP ranges."
|
||||||
"xrayConfigDirectIRDomain" = "Direct connection to Iran domains"
|
"VNDomain" = "Disable Connection to Vietnam Domains"
|
||||||
"xrayConfigDirectIRDomainDesc" = "Change the configuration template for direct connecting to Iran domains."
|
"VNDomainDesc" = "Change the configuration template to avoid connecting to Vietnam domains."
|
||||||
"xrayConfigDirectChinaIp" = "Direct connection to China IP ranges"
|
"DirectIRIp" = "Direct Connection to Iran IPs"
|
||||||
"xrayConfigDirectChinaIpDesc" = "Change the configuration template for direct connecting to China IP ranges."
|
"DirectIRIpDesc" = "Change the configuration template for direct connecting to Iran IP ranges."
|
||||||
"xrayConfigDirectChinaDomain" = "Direct connection to China domains"
|
"DirectIRDomain" = "Direct Connection to Iran Domains"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "Change the configuration template for direct connecting to China domains."
|
"DirectIRDomainDesc" = "Change the configuration template for direct connecting to Iran domains."
|
||||||
"xrayConfigDirectRussiaIp" = "Direct connection to Russia IP ranges"
|
"DirectChinaIp" = "Direct Connection to China IPs"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "Change the configuration template for direct connecting to Russia IP ranges."
|
"DirectChinaIpDesc" = "Change the configuration template for direct connecting to China IP ranges."
|
||||||
"xrayConfigDirectRussiaDomain" = "Direct connection to Russia domains"
|
"DirectChinaDomain" = "Direct Connection to China Domains"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "Change the configuration template for direct connecting to Russia domains."
|
"DirectChinaDomainDesc" = "Change the configuration template for direct connecting to China domains."
|
||||||
"xrayConfigGoogleIPv4" = "Use IPv4 for Google"
|
"DirectRussiaIp" = "Direct Connection to Russia IPs"
|
||||||
"xrayConfigGoogleIPv4Desc" = "Add routing for Google to connect with IPv4."
|
"DirectRussiaIpDesc" = "Change the configuration template for direct connecting to Russia IP ranges."
|
||||||
"xrayConfigNetflixIPv4" = "Use IPv4 for Netflix"
|
"DirectRussiaDomain" = "Direct Connection to Russia Domains"
|
||||||
"xrayConfigNetflixIPv4Desc" = "Add routing for Netflix to connect with IPv4."
|
"DirectRussiaDomainDesc" = "Change the configuration template for direct connecting to Russia domains."
|
||||||
"xrayConfigGoogleWARP" = "Route Google through WARP."
|
"DirectVNIp" = "Direct Connection to Vietnam IPs"
|
||||||
"xrayConfigGoogleWARPDesc" = "Add routing for Google via WARP."
|
"DirectVNIpDesc" = "Change the configuration template for direct connecting to Vietnam IP ranges."
|
||||||
"xrayConfigOpenAIWARP" = "Route OpenAI (ChatGPT) through WARP."
|
"DirectVNDomain" = "Direct Connection to Vietnam Domains"
|
||||||
"xrayConfigOpenAIWARPDesc" = "Add routing for OpenAI (ChatGPT) via WARP."
|
"DirectVNDomainDesc" = "Change the configuration template for direct connecting to Vietnam domains."
|
||||||
"xrayConfigNetflixWARP" = "Route Netflix through WARP."
|
"GoogleIPv4" = "Use IPv4 for Google"
|
||||||
"xrayConfigNetflixWARPDesc" = "Add routing for Netflix via WARP."
|
"GoogleIPv4Desc" = "Add routing for Google to connect with IPv4."
|
||||||
"xrayConfigSpotifyWARP" = "Route Spotify through WARP."
|
"NetflixIPv4" = "Use IPv4 for Netflix"
|
||||||
"xrayConfigSpotifyWARPDesc" = "Add routing for Spotify via WARP."
|
"NetflixIPv4Desc" = "Add routing for Netflix to connect with IPv4."
|
||||||
"xrayConfigIRWARP" = "Route Iran domains through WARP."
|
"GoogleWARP" = "Route Google through WARP."
|
||||||
"xrayConfigIRWARPDesc" = "Add routing for Iran domains via WARP."
|
"GoogleWARPDesc" = "Add routing for Google via WARP."
|
||||||
"xrayConfigInbounds" = "Configuration of Inbounds"
|
"OpenAIWARP" = "Route OpenAI (ChatGPT) through WARP."
|
||||||
"xrayConfigInboundsDesc" = "Change the configuration template to accept specific clients."
|
"OpenAIWARPDesc" = "Add routing for OpenAI (ChatGPT) via WARP."
|
||||||
"xrayConfigOutbounds" = "Configuration of Outbounds"
|
"NetflixWARP" = "Route Netflix through WARP."
|
||||||
"xrayConfigOutboundsDesc" = "Change the configuration template to define outgoing ways for this server."
|
"NetflixWARPDesc" = "Add routing for Netflix via WARP."
|
||||||
"xrayConfigRoutings" = "Configuration of routing rules."
|
"SpotifyWARP" = "Route Spotify through WARP."
|
||||||
"xrayConfigRoutingsDesc" = "Change the configuration template to define routing rules for this server."
|
"SpotifyWARPDesc" = "Add routing for Spotify via WARP."
|
||||||
"completeTemplate" = "All"
|
"IRWARP" = "Route Iran domains through WARP."
|
||||||
|
"IRWARPDesc" = "Add routing for Iran domains via WARP."
|
||||||
"Inbounds" = "Inbounds"
|
"Inbounds" = "Inbounds"
|
||||||
|
"InboundsDesc" = "Change the configuration template to accept specific clients."
|
||||||
"Outbounds" = "Outbounds"
|
"Outbounds" = "Outbounds"
|
||||||
"Routings" = "Routing rules"
|
"OutboundsDesc" = "Change the configuration template to define outgoing ways for this server."
|
||||||
|
"Routings" = "Routing Rules"
|
||||||
"RoutingsDesc" = "The priority of each rule is important!"
|
"RoutingsDesc" = "The priority of each rule is important!"
|
||||||
|
"completeTemplate" = "All"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"first" = "First"
|
"first" = "First"
|
||||||
@@ -396,12 +400,12 @@
|
|||||||
"useComma" = "Comma separated items"
|
"useComma" = "Comma separated items"
|
||||||
|
|
||||||
[pages.xray.outbound]
|
[pages.xray.outbound]
|
||||||
"addOutbound" = "Add outbound"
|
"addOutbound" = "Add Outbound"
|
||||||
"addReverse" = "Add reverse"
|
"addReverse" = "Add Reverse"
|
||||||
"editOutbound" = "Edit outbound"
|
"editOutbound" = "Edit Outbound"
|
||||||
"editReverse" = "Edit reverse"
|
"editReverse" = "Edit Reverse"
|
||||||
"tag" = "Tag"
|
"tag" = "Tag"
|
||||||
"tagDesc" = "Unique tag"
|
"tagDesc" = "Unique Tag"
|
||||||
"address" = "Address"
|
"address" = "Address"
|
||||||
"reverse" = "Reverse"
|
"reverse" = "Reverse"
|
||||||
"domain" = "Domain"
|
"domain" = "Domain"
|
||||||
@@ -419,11 +423,11 @@
|
|||||||
"secretTokenDesc" = "Please copy and securely store this token in a safe place. This token is required for login and cannot be recovered from the x-ui command tool."
|
"secretTokenDesc" = "Please copy and securely store this token in a safe place. This token is required for login and cannot be recovered from the x-ui command tool."
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Modify Settings "
|
"modifySettings" = "Modify Settings"
|
||||||
"getSettings" = "Get Settings "
|
"getSettings" = "Get Settings"
|
||||||
"modifyUser" = "Modify User "
|
"modifyUser" = "Modify User"
|
||||||
"originalUserPassIncorrect" = "Incorrect original username or password"
|
"originalUserPassIncorrect" = "Incorrect original username or password"
|
||||||
"userPassMustBeNotEmpty" = "New username and new password cannot be empty"
|
"userPassMustBeNotEmpty" = "New username and password cannot be empty"
|
||||||
|
|
||||||
[tgbot]
|
[tgbot]
|
||||||
"keyboardClosed" = "❌ Custom keyboard closed!"
|
"keyboardClosed" = "❌ Custom keyboard closed!"
|
||||||
@@ -448,14 +452,14 @@
|
|||||||
"help" = "🤖 Welcome to this bot! It's designed to offer you specific data from the server, and it allows you to make modifications as needed.\r\n\r\n"
|
"help" = "🤖 Welcome to this bot! It's designed to offer you specific data from the server, and it allows you to make modifications as needed.\r\n\r\n"
|
||||||
"start" = "👋 Hello <i>{{ .Firstname }}</i>.\r\n"
|
"start" = "👋 Hello <i>{{ .Firstname }}</i>.\r\n"
|
||||||
"welcome" = "🤖 Welcome to <b>{{ .Hostname }}</b> management bot.\r\n"
|
"welcome" = "🤖 Welcome to <b>{{ .Hostname }}</b> management bot.\r\n"
|
||||||
"status" = "✅ Bot is ok!"
|
"status" = "✅ Bot is OK!"
|
||||||
"usage" = "❗ Please provide a text to search!"
|
"usage" = "❗ Please provide a text to search!"
|
||||||
"getID" = "🆔 Your ID: <code>{{ .ID }}</code>"
|
"getID" = "🆔 Your ID: <code>{{ .ID }}</code>"
|
||||||
"helpAdminCommands" = "Search for a client email:\r\n<code>/usage [Email]</code>\r\n \r\nSearch for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>"
|
"helpAdminCommands" = "Search for a client email:\r\n<code>/usage [Email]</code>\r\n \r\nSearch for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>"
|
||||||
"helpClientCommands" = "To search for statistics, just use the following command:\r\n \r\n<code>/usage [UUID|Password]</code>\r\n \r\nUse UUID for vmess/vless and Password for Trojan."
|
"helpClientCommands" = "To search for statistics, just use the following command:\r\n \r\n<code>/usage [UUID|Password]</code>\r\n \r\nUse UUID for vmess/vless and Password for Trojan."
|
||||||
|
|
||||||
[tgbot.messages]
|
[tgbot.messages]
|
||||||
"cpuThreshold" = "🔴 The CPU usage {{ .Percent }}% is more than threshold {{ .Threshold }}%"
|
"cpuThreshold" = "🔴 CPU Load {{ .Percent }}% is more than threshold {{ .Threshold }}%"
|
||||||
"selectUserFailed" = "❌ Error in user selection!"
|
"selectUserFailed" = "❌ Error in user selection!"
|
||||||
"userSaved" = "✅ Telegram User saved."
|
"userSaved" = "✅ Telegram User saved."
|
||||||
"loginSuccess" = "✅ Successfully logged-in to the panel.\r\n"
|
"loginSuccess" = "✅ Successfully logged-in to the panel.\r\n"
|
||||||
@@ -470,9 +474,9 @@
|
|||||||
"ips" = "🔢 IPs: \r\n{{ .IPs }}\r\n"
|
"ips" = "🔢 IPs: \r\n{{ .IPs }}\r\n"
|
||||||
"serverUpTime" = "⏳ Server Uptime: {{ .UpTime }} {{ .Unit }}\r\n"
|
"serverUpTime" = "⏳ Server Uptime: {{ .UpTime }} {{ .Unit }}\r\n"
|
||||||
"serverLoad" = "📈 Server Load: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
|
"serverLoad" = "📈 Server Load: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
|
||||||
"serverMemory" = "📋 Server Memory: {{ .Current }}/{{ .Total }}\r\n"
|
"serverMemory" = "📋 Server RAM: {{ .Current }}/{{ .Total }}\r\n"
|
||||||
"tcpCount" = "🔹 TcpCount: {{ .Count }}\r\n"
|
"tcpCount" = "🔹 TCP: {{ .Count }}\r\n"
|
||||||
"udpCount" = "🔸 UdpCount: {{ .Count }}\r\n"
|
"udpCount" = "🔸 UDP: {{ .Count }}\r\n"
|
||||||
"traffic" = "🚦 Traffic: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
|
"traffic" = "🚦 Traffic: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
|
||||||
"xrayStatus" = "ℹ️ Xray Status: {{ .State }}\r\n"
|
"xrayStatus" = "ℹ️ Xray Status: {{ .State }}\r\n"
|
||||||
"username" = "👤 Username: {{ .Username }}\r\n"
|
"username" = "👤 Username: {{ .Username }}\r\n"
|
||||||
@@ -491,7 +495,7 @@
|
|||||||
"exhaustedMsg" = "🚨 Exhausted {{ .Type }}:\r\n"
|
"exhaustedMsg" = "🚨 Exhausted {{ .Type }}:\r\n"
|
||||||
"exhaustedCount" = "🚨 Exhausted {{ .Type }} count:\r\n"
|
"exhaustedCount" = "🚨 Exhausted {{ .Type }} count:\r\n"
|
||||||
"disabled" = "🛑 Disabled: {{ .Disabled }}\r\n"
|
"disabled" = "🛑 Disabled: {{ .Disabled }}\r\n"
|
||||||
"depleteSoon" = "🔜 Deplete soon: {{ .Deplete }}\r\n \r\n"
|
"depleteSoon" = "🔜 Deplete Soon: {{ .Deplete }}\r\n \r\n"
|
||||||
"backupTime" = "🗄 Backup Time: {{ .Time }}\r\n"
|
"backupTime" = "🗄 Backup Time: {{ .Time }}\r\n"
|
||||||
"refreshedOn" = "\r\n📋🔄 Refreshed On: {{ .Time }}\r\n \r\n"
|
"refreshedOn" = "\r\n📋🔄 Refreshed On: {{ .Time }}\r\n \r\n"
|
||||||
|
|
||||||
|
|||||||
@@ -315,71 +315,75 @@
|
|||||||
"ipv4ConfigsDesc" = "Estas opciones solo enrutarán a los dominios objetivo a través de IPv4."
|
"ipv4ConfigsDesc" = "Estas opciones solo enrutarán a los dominios objetivo a través de IPv4."
|
||||||
"warpConfigs" = "Configuraciones de WARP"
|
"warpConfigs" = "Configuraciones de WARP"
|
||||||
"warpConfigsDesc" = "Precaución: Antes de usar estas opciones, instale WARP en modo de proxy socks5 en su servidor siguiendo los pasos en el GitHub del panel. WARP enrutará el tráfico a los sitios web a través de los servidores de Cloudflare."
|
"warpConfigsDesc" = "Precaución: Antes de usar estas opciones, instale WARP en modo de proxy socks5 en su servidor siguiendo los pasos en el GitHub del panel. WARP enrutará el tráfico a los sitios web a través de los servidores de Cloudflare."
|
||||||
"xrayConfigTemplate" = "Plantilla de Configuración de Xray"
|
"Template" = "Plantilla de Configuración de Xray"
|
||||||
"xrayConfigTemplateDesc" = "Genera el archivo de configuración final de Xray basado en esta plantilla."
|
"TemplateDesc" = "Genera el archivo de configuración final de Xray basado en esta plantilla."
|
||||||
"xrayConfigFreedomStrategy" = "Configurar Estrategia para el Protocolo Freedom"
|
"FreedomStrategy" = "Configurar Estrategia para el Protocolo Freedom"
|
||||||
"xrayConfigFreedomStrategyDesc" = "Establece la estrategia de salida de la red en el Protocolo Freedom."
|
"FreedomStrategyDesc" = "Establece la estrategia de salida de la red en el Protocolo Freedom."
|
||||||
"xrayConfigRoutingStrategy" = "Configurar Estrategia de Enrutamiento de Dominios"
|
"RoutingStrategy" = "Configurar Estrategia de Enrutamiento de Dominios"
|
||||||
"xrayConfigRoutingStrategyDesc" = "Establece la estrategia general de enrutamiento para la resolución de DNS."
|
"RoutingStrategyDesc" = "Establece la estrategia general de enrutamiento para la resolución de DNS."
|
||||||
"xrayConfigTorrent" = "Prohibir Uso de BitTorrent"
|
"Torrent" = "Prohibir Uso de BitTorrent"
|
||||||
"xrayConfigTorrentDesc" = "Cambia la plantilla de configuración para evitar el uso de BitTorrent por parte de los usuarios."
|
"TorrentDesc" = "Cambia la plantilla de configuración para evitar el uso de BitTorrent por parte de los usuarios."
|
||||||
"xrayConfigPrivateIp" = "Prohibir Conexiones a Rangos de IP Privadas"
|
"PrivateIp" = "Prohibir Conexiones a Rangos de IP Privadas"
|
||||||
"xrayConfigPrivateIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP privadas."
|
"PrivateIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP privadas."
|
||||||
"xrayConfigAds" = "Bloquear Anuncios"
|
"Ads" = "Bloquear Anuncios"
|
||||||
"xrayConfigAdsDesc" = "Cambia la plantilla de configuración para bloquear anuncios."
|
"AdsDesc" = "Cambia la plantilla de configuración para bloquear anuncios."
|
||||||
"xrayConfigFamily" = "Bloquear Malware y Contenido para Adultos"
|
"Family" = "Bloquear Malware y Contenido para Adultos"
|
||||||
"xrayConfigFamilyDesc" = "Resolvedores de DNS para bloquear malware y contenido para adultos para protección familiar."
|
"FamilyDesc" = "Resolvedores de DNS para bloquear malware y contenido para adultos para protección familiar."
|
||||||
"xrayConfigSpeedtest" = "Bloquear Sitios Web de Pruebas de Velocidad"
|
"Speedtest" = "Bloquear Sitios Web de Pruebas de Velocidad"
|
||||||
"xrayConfigSpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad."
|
"SpeedtestDesc" = "Cambia la plantilla de configuración para evitar la conexión a sitios web de pruebas de velocidad."
|
||||||
"xrayConfigIRIp" = "Desactivar Conexión a Rangos de IP de Irán"
|
"IRIp" = "Desactivar Conexión a Rangos de IP de Irán"
|
||||||
"xrayConfigIRIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Irán."
|
"IRIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Irán."
|
||||||
"xrayConfigIRDomain" = "Desactivar Conexión a Dominios de Irán"
|
"IRDomain" = "Desactivar Conexión a Dominios de Irán"
|
||||||
"xrayConfigIRDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Irán."
|
"IRDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Irán."
|
||||||
"xrayConfigChinaIp" = "Desactivar Conexión a Rangos de IP de China"
|
"ChinaIp" = "Desactivar Conexión a Rangos de IP de China"
|
||||||
"xrayConfigChinaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de China."
|
"ChinaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de China."
|
||||||
"xrayConfigChinaDomain" = "Desactivar Conexión a Dominios de China"
|
"ChinaDomain" = "Desactivar Conexión a Dominios de China"
|
||||||
"xrayConfigChinaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de China."
|
"ChinaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de China."
|
||||||
"xrayConfigRussiaIp" = "Desactivar Conexión a Rangos de IP de Rusia"
|
"RussiaIp" = "Desactivar Conexión a Rangos de IP de Rusia"
|
||||||
"xrayConfigRussiaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Rusia."
|
"RussiaIpDesc" = "Cambia la plantilla de configuración para evitar la conexión a rangos de IP de Rusia."
|
||||||
"xrayConfigRussiaDomain" = "Desactivar Conexión a Dominios de Rusia"
|
"RussiaDomain" = "Desactivar Conexión a Dominios de Rusia"
|
||||||
"xrayConfigRussiaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Rusia."
|
"RussiaDomainDesc" = "Cambia la plantilla de configuración para evitar la conexión a dominios de Rusia."
|
||||||
"xrayConfigDirectIRIp" = "Conexión Directa a Rangos de IP de Irán"
|
"VNIp" = "Deshabilitar la conexión a las IP de Vietnam"
|
||||||
"xrayConfigDirectIRIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Irán."
|
"VNIpDesc" = "Cambie la plantilla de configuración para evitar conectarse a rangos de IP de Vietnam."
|
||||||
"xrayConfigDirectIRDomain" = "Conexión Directa a Dominios de Irán"
|
"VNDomain" = "Deshabilitar la conexión a dominios de Vietnam"
|
||||||
"xrayConfigDirectIRDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Irán."
|
"VNDomainDesc" = "Cambie la plantilla de configuración para evitar conectarse a dominios de Vietnam."
|
||||||
"xrayConfigDirectChinaIp" = "Conexión Directa a Rangos de IP de China"
|
"DirectIRIp" = "Conexión Directa a Rangos de IP de Irán"
|
||||||
"xrayConfigDirectChinaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de China."
|
"DirectIRIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Irán."
|
||||||
"xrayConfigDirectChinaDomain" = "Conexión Directa a Dominios de China"
|
"DirectIRDomain" = "Conexión Directa a Dominios de Irán"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de China."
|
"DirectIRDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Irán."
|
||||||
"xrayConfigDirectRussiaIp" = "Conexión Directa a Rangos de IP de Rusia"
|
"DirectChinaIp" = "Conexión Directa a Rangos de IP de China"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Rusia."
|
"DirectChinaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de China."
|
||||||
"xrayConfigDirectRussiaDomain" = "Conexión Directa a Dominios de Rusia"
|
"DirectChinaDomain" = "Conexión Directa a Dominios de China"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Rusia."
|
"DirectChinaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de China."
|
||||||
"xrayConfigGoogleIPv4" = "Usar IPv4 para Google"
|
"DirectRussiaIp" = "Conexión Directa a Rangos de IP de Rusia"
|
||||||
"xrayConfigGoogleIPv4Desc" = "Agregar enrutamiento para que Google se conecte con IPv4."
|
"DirectRussiaIpDesc" = "Cambia la plantilla de configuración para conectarse directamente a rangos de IP de Rusia."
|
||||||
"xrayConfigNetflixIPv4" = "Usar IPv4 para Netflix"
|
"DirectRussiaDomain" = "Conexión Directa a Dominios de Rusia"
|
||||||
"xrayConfigNetflixIPv4Desc" = "Agregar enrutamiento para que Netflix se conecte con IPv4."
|
"DirectRussiaDomainDesc" = "Cambia la plantilla de configuración para conectarse directamente a dominios de Rusia."
|
||||||
"xrayConfigGoogleWARP" = "Rutear Google a través de WARP."
|
"DirectVNIp" = "Conexión directa a IP de Vietnam"
|
||||||
"xrayConfigGoogleWARPDesc" = "Agregar enrutamiento para Google a través de WARP."
|
"DirectVNIpDesc" = "Cambie la plantilla de configuración para la conexión directa a rangos de IP de Vietnam."
|
||||||
"xrayConfigOpenAIWARP" = "Rutear OpenAI (ChatGPT) a través de WARP."
|
"DirectVNDomain" = "Conexión directa a dominios de Vietnam"
|
||||||
"xrayConfigOpenAIWARPDesc" = "Agregar enrutamiento para OpenAI (ChatGPT) a través de WARP."
|
"DirectVNDomainDesc" = "Cambie la plantilla de configuración para la conexión directa a dominios de Vietnam."
|
||||||
"xrayConfigNetflixWARP" = "Rutear Netflix a través de WARP."
|
"GoogleIPv4" = "Usar IPv4 para Google"
|
||||||
"xrayConfigNetflixWARPDesc" = "Agregar enrutamiento para Netflix a través de WARP."
|
"GoogleIPv4Desc" = "Agregar enrutamiento para que Google se conecte con IPv4."
|
||||||
"xrayConfigSpotifyWARP" = "Rutear Spotify a través de WARP."
|
"NetflixIPv4" = "Usar IPv4 para Netflix"
|
||||||
"xrayConfigSpotifyWARPDesc" = "Agregar enrutamiento para Spotify a través de WARP."
|
"NetflixIPv4Desc" = "Agregar enrutamiento para que Netflix se conecte con IPv4."
|
||||||
"xrayConfigIRWARP" = "Rutear dominios de Irán a través de WARP."
|
"GoogleWARP" = "Rutear Google a través de WARP."
|
||||||
"xrayConfigIRWARPDesc" = "Agregar enrutamiento para dominios de Irán a través de WARP."
|
"GoogleWARPDesc" = "Agregar enrutamiento para Google a través de WARP."
|
||||||
"xrayConfigInbounds" = "Configuración de Entradas"
|
"OpenAIWARP" = "Rutear OpenAI (ChatGPT) a través de WARP."
|
||||||
"xrayConfigInboundsDesc" = "Cambia la plantilla de configuración para aceptar clientes específicos."
|
"OpenAIWARPDesc" = "Agregar enrutamiento para OpenAI (ChatGPT) a través de WARP."
|
||||||
"xrayConfigOutbounds" = "Configuración de Salidas"
|
"NetflixWARP" = "Rutear Netflix a través de WARP."
|
||||||
"xrayConfigOutboundsDesc" = "Cambia la plantilla de configuración para definir formas de salida para este servidor."
|
"NetflixWARPDesc" = "Agregar enrutamiento para Netflix a través de WARP."
|
||||||
"xrayConfigRoutings" = "Configuración de Reglas de Enrutamiento"
|
"SpotifyWARP" = "Rutear Spotify a través de WARP."
|
||||||
"xrayConfigRoutingsDesc" = "Cambia la plantilla de configuración para definir reglas de enrutamiento para este servidor."
|
"SpotifyWARPDesc" = "Agregar enrutamiento para Spotify a través de WARP."
|
||||||
"completeTemplate" = "Todos"
|
"IRWARP" = "Rutear dominios de Irán a través de WARP."
|
||||||
|
"IRWARPDesc" = "Agregar enrutamiento para dominios de Irán a través de WARP."
|
||||||
"Inbounds" = "Entrante"
|
"Inbounds" = "Entrante"
|
||||||
|
"InboundsDesc" = "Cambia la plantilla de configuración para aceptar clientes específicos."
|
||||||
"Outbounds" = "Salidas"
|
"Outbounds" = "Salidas"
|
||||||
|
"OutboundsDesc" = "Cambia la plantilla de configuración para definir formas de salida para este servidor."
|
||||||
"Routings" = "Reglas de enrutamiento"
|
"Routings" = "Reglas de enrutamiento"
|
||||||
"RoutingsDesc" = "¡La prioridad de cada regla es importante!"
|
"RoutingsDesc" = "¡La prioridad de cada regla es importante!"
|
||||||
|
"completeTemplate" = "Todos"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"first" = "Primero"
|
"first" = "Primero"
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
"settings" = "تنظیمات پنل"
|
"settings" = "تنظیمات پنل"
|
||||||
"xray" = "الگوی ایکسری"
|
"xray" = "الگوی ایکسری"
|
||||||
"logout" = "خروج"
|
"logout" = "خروج"
|
||||||
"link" = "دیگر"
|
"link" = "مدیریت"
|
||||||
|
|
||||||
[pages.login]
|
[pages.login]
|
||||||
"title" = "ورود به سیستم"
|
"title" = "ورود به سیستم"
|
||||||
@@ -315,71 +315,75 @@
|
|||||||
"ipv4ConfigsDesc" = "این گزینه فقط از طریق آیپی ورژن ۴ به دامنه های هدف هدایت می شود"
|
"ipv4ConfigsDesc" = "این گزینه فقط از طریق آیپی ورژن ۴ به دامنه های هدف هدایت می شود"
|
||||||
"warpConfigs" = "تنظیمات برای WARP"
|
"warpConfigs" = "تنظیمات برای WARP"
|
||||||
"warpConfigsDesc" = "هشدار: قبل از استفاده از این گزینه، WARP را در حالت پراکسی socks5 با دنبال کردن مراحل در GitHub پنل روی سرور خود نصب کنید. WARP ترافیک را از طریق سرورهای Cloudflare به وب سایت ها هدایت می کند"
|
"warpConfigsDesc" = "هشدار: قبل از استفاده از این گزینه، WARP را در حالت پراکسی socks5 با دنبال کردن مراحل در GitHub پنل روی سرور خود نصب کنید. WARP ترافیک را از طریق سرورهای Cloudflare به وب سایت ها هدایت می کند"
|
||||||
"xrayConfigTemplate" = "تنظیمات الگو ایکس ری"
|
"Template" = "تنظیمات الگو ایکس ری"
|
||||||
"xrayConfigTemplateDesc" = "فایل پیکربندی ایکس ری نهایی بر اساس این الگو ایجاد میشود. لطفاً این را تغییر ندهید مگر اینکه دقیقاً بدانید که چه کاری انجام می دهید!"
|
"TemplateDesc" = "فایل پیکربندی ایکس ری نهایی بر اساس این الگو ایجاد میشود. لطفاً این را تغییر ندهید مگر اینکه دقیقاً بدانید که چه کاری انجام می دهید!"
|
||||||
"xrayConfigFreedomStrategy" = "روش استفاده از شبکه خروجی مستقیم"
|
"FreedomStrategy" = "روش استفاده از شبکه خروجی مستقیم"
|
||||||
"xrayConfigFreedomStrategyDesc" = "تعیین روش استفاده از خروجی برای پرتکل مستقیم"
|
"FreedomStrategyDesc" = "تعیین روش استفاده از خروجی برای پرتکل مستقیم"
|
||||||
"xrayConfigRoutingStrategy" = "پیکربندی استراتژی حل دامنه در مسیریابی"
|
"RoutingStrategy" = "پیکربندی استراتژی حل دامنه در مسیریابی"
|
||||||
"xrayConfigRoutingStrategyDesc" = "تعیین استراتژی مسیریابی کلی برای پیدا کردن دامنه"
|
"RoutingStrategyDesc" = "تعیین استراتژی مسیریابی کلی برای پیدا کردن دامنه"
|
||||||
"xrayConfigTorrent" = "فیلتر کردن بیت تورنت"
|
"Torrent" = "فیلتر کردن بیت تورنت"
|
||||||
"xrayConfigTorrentDesc" = "الگوی تنظیمات را برای فیلتر کردن پروتکل بیت تورنت برای کاربران تغییر میدهد"
|
"TorrentDesc" = "الگوی تنظیمات را برای فیلتر کردن پروتکل بیت تورنت برای کاربران تغییر میدهد"
|
||||||
"xrayConfigPrivateIp" = "جلوگیری از اتصال آیپی های خصوصی یا محلی"
|
"PrivateIp" = "جلوگیری از اتصال آیپی های خصوصی یا محلی"
|
||||||
"xrayConfigPrivateIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های خصوصی یا محلی و بسته های سرگردان تغییر میدهد"
|
"PrivateIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های خصوصی یا محلی و بسته های سرگردان تغییر میدهد"
|
||||||
"xrayConfigAds" = "مسدود کردن تبلیغات"
|
"Ads" = "مسدود کردن تبلیغات"
|
||||||
"xrayConfigAdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد"
|
"AdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد"
|
||||||
"xrayConfigFamily" = "فعال کردن حالت خانواده"
|
"Family" = "فعال کردن حالت خانواده"
|
||||||
"xrayConfigFamilyDesc" = "برای جلوگیری از ارتباط با وبسایت های ناامن"
|
"FamilyDesc" = "برای جلوگیری از ارتباط با وبسایت های ناامن"
|
||||||
"xrayConfigSpeedtest" = "جلوگیری از اتصال به سایت های تست سرعت"
|
"Speedtest" = "جلوگیری از اتصال به سایت های تست سرعت"
|
||||||
"xrayConfigSpeedtestDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های تست سرعت تغییر میدهد"
|
"SpeedtestDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های تست سرعت تغییر میدهد"
|
||||||
"xrayConfigIRIp" = "جلوگیری از اتصال آیپی های ایران"
|
"IRIp" = "جلوگیری از اتصال آیپی های ایران"
|
||||||
"xrayConfigIRIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های ایران تغییر میدهد"
|
"IRIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های ایران تغییر میدهد"
|
||||||
"xrayConfigIRDomain" = "جلوگیری از اتصال دامنه های ایران"
|
"IRDomain" = "جلوگیری از اتصال دامنه های ایران"
|
||||||
"xrayConfigIRDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های ایران تغییر میدهد"
|
"IRDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های ایران تغییر میدهد"
|
||||||
"xrayConfigChinaIp" = "جلوگیری از اتصال آیپی های چین"
|
"ChinaIp" = "جلوگیری از اتصال آیپی های چین"
|
||||||
"xrayConfigChinaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های چین تغییر میدهد"
|
"ChinaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های چین تغییر میدهد"
|
||||||
"xrayConfigChinaDomain" = "جلوگیری از اتصال دامنه های چین"
|
"ChinaDomain" = "جلوگیری از اتصال دامنه های چین"
|
||||||
"xrayConfigChinaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های چین تغییر میدهد"
|
"ChinaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های چین تغییر میدهد"
|
||||||
"xrayConfigRussiaIp" = "جلوگیری از اتصال آیپی های روسیه"
|
"RussiaIp" = "جلوگیری از اتصال آیپی های روسیه"
|
||||||
"xrayConfigRussiaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های روسیه تغییر میدهد"
|
"RussiaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های روسیه تغییر میدهد"
|
||||||
"xrayConfigRussiaDomain" = "جلوگیری از اتصال دامنه های روسیه"
|
"RussiaDomain" = "جلوگیری از اتصال دامنه های روسیه"
|
||||||
"xrayConfigRussiaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های روسیه تغییر میدهد"
|
"RussiaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های روسیه تغییر میدهد"
|
||||||
"xrayConfigDirectIRIp" = "ارتباط مستقیم به آیپی های ایران"
|
"VNIp" = "جلوگیری از اتصال آیپی های ویتنام"
|
||||||
"xrayConfigDirectIRIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های ایران تغییر میدهد"
|
"VNIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های ویتنام تغییر میدهد"
|
||||||
"xrayConfigDirectIRDomain" = "ارتباط مستقیم به دامنه های ایران"
|
"VNDomain" = "جلوگیری از اتصال دامنه های ویتنام"
|
||||||
"xrayConfigDirectIRDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های ایران تغییر میدهد"
|
"VNDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های ویتنام تغییر میدهد"
|
||||||
"xrayConfigDirectChinaIp" = "ارتباط مستقیم به آیپی های چین"
|
"DirectIRIp" = "ارتباط مستقیم به آیپی های ایران"
|
||||||
"xrayConfigDirectChinaIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های چین تغییر میدهد"
|
"DirectIRIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های ایران تغییر میدهد"
|
||||||
"xrayConfigDirectChinaDomain" = "ارتباط مستقیم به دامنه های چین"
|
"DirectIRDomain" = "ارتباط مستقیم به دامنه های ایران"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های چین تغییر میدهد"
|
"DirectIRDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های ایران تغییر میدهد"
|
||||||
"xrayConfigDirectRussiaIp" = "ارتباط مستقیم به آیپی های روسیه"
|
"DirectChinaIp" = "ارتباط مستقیم به آیپی های چین"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های روسیه تغییر میدهد"
|
"DirectChinaIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های چین تغییر میدهد"
|
||||||
"xrayConfigDirectRussiaDomain" = "ارتباط مستقیم به دامنه های روسیه"
|
"DirectChinaDomain" = "ارتباط مستقیم به دامنه های چین"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های روسیه تغییر میدهد"
|
"DirectChinaDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های چین تغییر میدهد"
|
||||||
"xrayConfigGoogleIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به گوگل"
|
"DirectRussiaIp" = "ارتباط مستقیم به آیپی های روسیه"
|
||||||
"xrayConfigGoogleIPv4Desc" = "مسیردهی جدید برای اتصال به گوگل با آیپی ورژن 4 اضافه میکند"
|
"DirectRussiaIpDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به آیپی های روسیه تغییر میدهد"
|
||||||
"xrayConfigNetflixIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به نتفلیکس"
|
"DirectRussiaDomain" = "ارتباط مستقیم به دامنه های روسیه"
|
||||||
"xrayConfigNetflixIPv4Desc" = "مسیردهی جدید برای اتصال به نتفلیکس با آیپی ورژن 4 اضافه میکند"
|
"DirectRussiaDomainDesc" = "الگوی تنظیمات را برای ارتباط مستقیم به دامنه های روسیه تغییر میدهد"
|
||||||
"xrayConfigGoogleWARP" = "مسیردهی گوگل به WARP"
|
"DirectVNIp" = "اتصال مستقیم به ای پی های ویتنام"
|
||||||
"xrayConfigGoogleWARPDesc" = "مسیردهی جدید برای اتصال به گوگل به WARP اضافه میکند"
|
"DirectVNIpDesc" = "الگوی پیکربندی را برای اتصال مستقیم به محدوده آی پی های ویتنام تغییر میدهد"
|
||||||
"xrayConfigOpenAIWARP" = "مسیردهی OpenAI (ChatGPT) به WARP"
|
"DirectVNDomain" = "اتصال مستقیم به دامنه های ویتنام"
|
||||||
"xrayConfigOpenAIWARPDesc" = "مسیردهی جدید برای اتصال به OpenAI (ChatGPT) به WARP اضافه میکند"
|
"DirectVNDomainDesc" = "الگوی پیکربندی را برای اتصال مستقیم به دامنه های ویتنام تغییر میدهد"
|
||||||
"xrayConfigNetflixWARP" = "مسیردهی نتفلیکس به WARP"
|
"GoogleIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به گوگل"
|
||||||
"xrayConfigNetflixWARPDesc" = "مسیردهی جدید برای اتصال به نتفلیکس به WARP اضافه میکند"
|
"GoogleIPv4Desc" = "مسیردهی جدید برای اتصال به گوگل با آیپی ورژن 4 اضافه میکند"
|
||||||
"xrayConfigSpotifyWARP" = "مسیردهی اسپاتیفای به WARP"
|
"NetflixIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به نتفلیکس"
|
||||||
"xrayConfigSpotifyWARPDesc" = "مسیردهی جدید برای اتصال به اسپاتیفای به WARP اضافه میکند"
|
"NetflixIPv4Desc" = "مسیردهی جدید برای اتصال به نتفلیکس با آیپی ورژن 4 اضافه میکند"
|
||||||
"xrayConfigIRWARP" = "مسیردهی دامنه های ایران به WARP"
|
"GoogleWARP" = "مسیردهی گوگل به WARP"
|
||||||
"xrayConfigIRWARPDesc" = "مسیردهی جدید برای اتصال به دامنه های ایران به WARP اضافه میکند"
|
"GoogleWARPDesc" = "مسیردهی جدید برای اتصال به گوگل به WARP اضافه میکند"
|
||||||
"xrayConfigInbounds" = "تنظیمات ورودی"
|
"OpenAIWARP" = "مسیردهی OpenAI (ChatGPT) به WARP"
|
||||||
"xrayConfigInboundsDesc" = "میتوانید الگوی تنظیمات را برای ورودی های خاص تنظیم نمایید"
|
"OpenAIWARPDesc" = "مسیردهی جدید برای اتصال به OpenAI (ChatGPT) به WARP اضافه میکند"
|
||||||
"xrayConfigOutbounds" = "تنظیمات خروجی"
|
"NetflixWARP" = "مسیردهی نتفلیکس به WARP"
|
||||||
"xrayConfigOutboundsDesc" = "میتوانید الگوی تنظیمات را برای خروجی اینترنت تنظیم نمایید"
|
"NetflixWARPDesc" = "مسیردهی جدید برای اتصال به نتفلیکس به WARP اضافه میکند"
|
||||||
"xrayConfigRoutings" = "تنظیمات قوانین مسیریابی"
|
"SpotifyWARP" = "مسیردهی اسپاتیفای به WARP"
|
||||||
"xrayConfigRoutingsDesc" = "میتوانید الگوی تنظیمات را برای مسیریابی تنظیم نمایید"
|
"SpotifyWARPDesc" = "مسیردهی جدید برای اتصال به اسپاتیفای به WARP اضافه میکند"
|
||||||
"completeTemplate" = "کامل"
|
"IRWARP" = "مسیردهی دامنه های ایران به WARP"
|
||||||
|
"IRWARPDesc" = "مسیردهی جدید برای اتصال به دامنه های ایران به WARP اضافه میکند"
|
||||||
"Inbounds" = "ورودیها"
|
"Inbounds" = "ورودیها"
|
||||||
|
"InboundsDesc" = "میتوانید الگوی تنظیمات را برای ورودی های خاص تنظیم نمایید"
|
||||||
"Outbounds" = "خروجیها"
|
"Outbounds" = "خروجیها"
|
||||||
|
"OutboundsDesc" = "میتوانید الگوی تنظیمات را برای خروجی اینترنت تنظیم نمایید"
|
||||||
"Routings" = "قوانین مسیریابی"
|
"Routings" = "قوانین مسیریابی"
|
||||||
"RoutingsDesc" = "اولویت هر قانون مهم است!"
|
"RoutingsDesc" = "اولویت هر قانون مهم است!"
|
||||||
|
"completeTemplate" = "کامل"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"first" = "اولین"
|
"first" = "اولین"
|
||||||
|
|||||||
@@ -57,9 +57,9 @@
|
|||||||
"dashboard" = "Статус системы"
|
"dashboard" = "Статус системы"
|
||||||
"inbounds" = "Подключения"
|
"inbounds" = "Подключения"
|
||||||
"settings" = "Настройки панели"
|
"settings" = "Настройки панели"
|
||||||
"xray" = "Xray Настройки"
|
"xray" = "Настройки Xray"
|
||||||
"logout" = "Выход"
|
"logout" = "Выход"
|
||||||
"link" = "Прочее"
|
"link" = "менеджмент"
|
||||||
|
|
||||||
[pages.login]
|
[pages.login]
|
||||||
"title" = "Логин"
|
"title" = "Логин"
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
"hard" = "Жесткий диск"
|
"hard" = "Жесткий диск"
|
||||||
"xrayStatus" = "Статус"
|
"xrayStatus" = "Статус"
|
||||||
"stopXray" = "Остановить Xray"
|
"stopXray" = "Остановить Xray"
|
||||||
"restartXray" = "Рестарт Xray"
|
"restartXray" = "Перезапустить Xray"
|
||||||
"xraySwitch" = "Переключить версию"
|
"xraySwitch" = "Переключить версию"
|
||||||
"xraySwitchClick" = "Выберите желаемую версию"
|
"xraySwitchClick" = "Выберите желаемую версию"
|
||||||
"xraySwitchClickDesk" = "Выбирайте внимательно, так как старые версии могут быть несовместимы с текущими конфигурациями"
|
"xraySwitchClickDesk" = "Выбирайте внимательно, так как старые версии могут быть несовместимы с текущими конфигурациями"
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
"expireTimeDiff" = "Порог истечения срока сессии для уведомления"
|
"expireTimeDiff" = "Порог истечения срока сессии для уведомления"
|
||||||
"expireTimeDiffDesc" = "Получение уведомления об истечении срока действия сессии до достижения порогового значения (значение: день)"
|
"expireTimeDiffDesc" = "Получение уведомления об истечении срока действия сессии до достижения порогового значения (значение: день)"
|
||||||
"trafficDiff" = "Порог трафика для уведомления"
|
"trafficDiff" = "Порог трафика для уведомления"
|
||||||
"trafficDiffDesc" = "Получение уведомления об исчерпании трафика до достижения порога (значение: Гб)"
|
"trafficDiffDesc" = "Получение уведомления об исчерпании трафика до достижения порога (значение: ГБ)"
|
||||||
"tgNotifyCpu" = "Порог нагрузки на ЦП для уведомления"
|
"tgNotifyCpu" = "Порог нагрузки на ЦП для уведомления"
|
||||||
"tgNotifyCpuDesc" = "Получение уведомления, если нагрузка на ЦП превышает этот порог (значение: %)"
|
"tgNotifyCpuDesc" = "Получение уведомления, если нагрузка на ЦП превышает этот порог (значение: %)"
|
||||||
"timeZone" = "Часовой пояс"
|
"timeZone" = "Часовой пояс"
|
||||||
@@ -298,9 +298,9 @@
|
|||||||
"subURIDesc" = "Изменить базовый URI URL-адреса подписки для использования за прокси-серверами"
|
"subURIDesc" = "Изменить базовый URI URL-адреса подписки для использования за прокси-серверами"
|
||||||
|
|
||||||
[pages.xray]
|
[pages.xray]
|
||||||
"title" = "Xray Настройки"
|
"title" = "Настройки Xray"
|
||||||
"save" = "Сохранить настройки"
|
"save" = "Сохранить настройки"
|
||||||
"restart" = "Перезапустить рентген"
|
"restart" = "Перезапустить Xray"
|
||||||
"basicTemplate" = "Базовый шаблон"
|
"basicTemplate" = "Базовый шаблон"
|
||||||
"advancedTemplate" = "Расширенный шаблон"
|
"advancedTemplate" = "Расширенный шаблон"
|
||||||
"generalConfigs" = "Основные настройки"
|
"generalConfigs" = "Основные настройки"
|
||||||
@@ -315,71 +315,75 @@
|
|||||||
"ipv4ConfigsDesc" = "Эти параметры позволят пользователям маршрутизироваться к целевым доменам только через IPv4"
|
"ipv4ConfigsDesc" = "Эти параметры позволят пользователям маршрутизироваться к целевым доменам только через IPv4"
|
||||||
"warpConfigs" = "Настройки WARP"
|
"warpConfigs" = "Настройки WARP"
|
||||||
"warpConfigsDesc" = "Внимание: перед использованием этих параметров установите WARP в режиме прокси-сервера socks5 на свой сервер, следуя инструкциям на GitHub панели. WARP будет направлять трафик на веб-сайты через серверы Cloudflare"
|
"warpConfigsDesc" = "Внимание: перед использованием этих параметров установите WARP в режиме прокси-сервера socks5 на свой сервер, следуя инструкциям на GitHub панели. WARP будет направлять трафик на веб-сайты через серверы Cloudflare"
|
||||||
"xrayConfigTemplate" = "Шаблон конфигурации Xray"
|
"Template" = "Шаблон конфигурации Xray"
|
||||||
"xrayConfigTemplateDesc" = "Создание файла конфигурации Xray на основе этого шаблона"
|
"TemplateDesc" = "Создание файла конфигурации Xray на основе этого шаблона"
|
||||||
"xrayConfigFreedomStrategy" = "Настройка стратегии протокола Freedom"
|
"FreedomStrategy" = "Настройка стратегии протокола Freedom"
|
||||||
"xrayConfigFreedomStrategyDesc" = "Установка стратегию вывода сети в протоколе Freedom"
|
"FreedomStrategyDesc" = "Установка стратегию вывода сети в протоколе Freedom"
|
||||||
"xrayConfigRoutingStrategy" = "Настройка стратегии маршрутизации доменов"
|
"RoutingStrategy" = "Настройка стратегии маршрутизации доменов"
|
||||||
"xrayConfigRoutingStrategyDesc" = "Установка общей стратегии маршрутизации разрешения DNS"
|
"RoutingStrategyDesc" = "Установка общей стратегии маршрутизации разрешения DNS"
|
||||||
"xrayConfigTorrent" = "Запрет использования BitTorrent"
|
"Torrent" = "Запрет использования BitTorrent"
|
||||||
"xrayConfigTorrentDesc" = "Изменение шаблона конфигурации для предупреждения использования BitTorrent пользователями"
|
"TorrentDesc" = "Изменение шаблона конфигурации для предупреждения использования BitTorrent пользователями"
|
||||||
"xrayConfigPrivateIp" = "Запрет частных диапазонов IP-адресов для подключения"
|
"PrivateIp" = "Запрет частных диапазонов IP-адресов для подключения"
|
||||||
"xrayConfigPrivateIpDesc" = "Изменение шаблона конфигурации для предупреждения подключения к диапазонам частных IP-адресов"
|
"PrivateIpDesc" = "Изменение шаблона конфигурации для предупреждения подключения к диапазонам частных IP-адресов"
|
||||||
"xrayConfigAds" = "Блокировка рекламы"
|
"Ads" = "Блокировка рекламы"
|
||||||
"xrayConfigAdsDesc" = "Изменение конфигурации для блокировки рекламы"
|
"AdsDesc" = "Изменение конфигурации для блокировки рекламы"
|
||||||
"xrayConfigFamily" = "Блокировать вредоносное ПО и контент для взрослых"
|
"Family" = "Блокировать вредоносное ПО и контент для взрослых"
|
||||||
"xrayConfigFamilyDesc" = "Резольверы DNS для блокировки вредоносных программ и контента для взрослых для защиты семьи"
|
"FamilyDesc" = "Резольверы DNS для блокировки вредоносных программ и контента для взрослых для защиты семьи"
|
||||||
"xrayConfigSpeedtest" = "Блокировать сайты для проверки скорости"
|
"Speedtest" = "Блокировать сайты для проверки скорости"
|
||||||
"xrayConfigSpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости"
|
"SpeedtestDesc" = "Изменение шаблона конфигурации для предупреждения подключения к веб-сайтам для тестирования скорости"
|
||||||
"xrayConfigIRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана"
|
"IRIp" = "Заблокировать подключения к диапазонам IP-адресов Ирана"
|
||||||
"xrayConfigIRIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Ирана"
|
"IRIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Ирана"
|
||||||
"xrayConfigIRDomain" = "Заблокировать подключения к доменам Ирана"
|
"IRDomain" = "Заблокировать подключения к доменам Ирана"
|
||||||
"xrayConfigIRDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Ирана"
|
"IRDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Ирана"
|
||||||
"xrayConfigChinaIp" = "Заблокировать подключения к диапазонам IP-адресов Китая"
|
"ChinaIp" = "Заблокировать подключения к диапазонам IP-адресов Китая"
|
||||||
"xrayConfigChinaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Китая"
|
"ChinaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонам IP-адресов Китая"
|
||||||
"xrayConfigChinaDomain" = "Заблокировать подключения к доменам Китая"
|
"ChinaDomain" = "Заблокировать подключения к доменам Китая"
|
||||||
"xrayConfigChinaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Китая"
|
"ChinaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам Китая"
|
||||||
"xrayConfigRussiaIp" = "Заблокировать подключения к диапазонам IP-адресов России"
|
"RussiaIp" = "Заблокировать подключения к диапазонам IP-адресов России"
|
||||||
"xrayConfigRussiaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонами IP-адресов России"
|
"RussiaIpDesc" = "Изменение конфигурации, чтобы заблокировать подключения к диапазонами IP-адресов России"
|
||||||
"xrayConfigRussiaDomain" = "Заблокировать подключения к доменам России"
|
"RussiaDomain" = "Заблокировать подключения к доменам России"
|
||||||
"xrayConfigRussiaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам России"
|
"RussiaDomainDesc" = "Изменение конфигурации, чтобы заблокировать подключения к доменам России"
|
||||||
"xrayConfigDirectIRIp" = "Прямое подключения к диапазонам IP-адресов Ирана"
|
"VNIp" = "Отключить подключение к IP-адресам Вьетнама"
|
||||||
"xrayConfigDirectIRIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Ирана"
|
"VNIpDesc" = "Измените шаблон конфигурации, чтобы избежать подключения к диапазонам IP-адресов Вьетнама"
|
||||||
"xrayConfigDirectIRDomain" = "Прямое подключение к доменам Ирана"
|
"VNDomain" = "Отключить подключение к доменам Вьетнама"
|
||||||
"xrayConfigDirectIRDomainDesc" = "Изменение шаблон конфигурации для прямого подключения к доменам Ирана"
|
"VNDomainDesc" = "Измените шаблон конфигурации, чтобы избежать подключения к доменам Вьетнама."
|
||||||
"xrayConfigDirectChinaIp" = "Прямое подключение к диапазонам IP-адресов Китая"
|
"DirectIRIp" = "Прямое подключения к диапазонам IP-адресов Ирана"
|
||||||
"xrayConfigDirectChinaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Китая"
|
"DirectIRIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Ирана"
|
||||||
"xrayConfigDirectChinaDomain" = "Прямое подключение к доменам Китая"
|
"DirectIRDomain" = "Прямое подключение к доменам Ирана"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам Китая"
|
"DirectIRDomainDesc" = "Изменение шаблон конфигурации для прямого подключения к доменам Ирана"
|
||||||
"xrayConfigDirectRussiaIp" = "Прямое подключение к диапазонам IP-адресов России"
|
"DirectChinaIp" = "Прямое подключение к диапазонам IP-адресов Китая"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов России"
|
"DirectChinaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов Китая"
|
||||||
"xrayConfigDirectRussiaDomain" = "Прямое подключение к доменам России"
|
"DirectChinaDomain" = "Прямое подключение к доменам Китая"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам России"
|
"DirectChinaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам Китая"
|
||||||
"xrayConfigGoogleIPv4" = "Использовать IPv4 для Google"
|
"DirectRussiaIp" = "Прямое подключение к диапазонам IP-адресов России"
|
||||||
"xrayConfigGoogleIPv4Desc" = "Добавить маршрутизацию для Google для подключения к IPv4"
|
"DirectRussiaIpDesc" = "Изменение шаблона конфигурации для прямого подключения к диапазонам IP-адресов России"
|
||||||
"xrayConfigNetflixIPv4" = "Использовать IPv4 для Netflix"
|
"DirectRussiaDomain" = "Прямое подключение к доменам России"
|
||||||
"xrayConfigNetflixIPv4Desc" = "Добавить маршрутизацию для Netflix для подключения к IPv4"
|
"DirectRussiaDomainDesc" = "Изменение шаблона конфигурации для прямого подключения к доменам России"
|
||||||
"xrayConfigGoogleWARP" = "Маршрутизация Google через WARP"
|
"DirectVNIp" = "Прямое подключение к IP-адресам Вьетнама"
|
||||||
"xrayConfigGoogleWARPDesc" = "Добавить маршрутизацию для Google через WARP"
|
"DirectVNIpDesc" = "Измените шаблон конфигурации для прямого подключения к диапазонам IP-адресов Вьетнама"
|
||||||
"xrayConfigOpenAIWARP" = "Маршрутизация OpenAI (ChatGPT) через WARP"
|
"DirectVNDomain" = "Прямое подключение к доменам Вьетнама"
|
||||||
"xrayConfigOpenAIWARPDesc" = "Добавить маршрутизацию для OpenAI (ChatGPT) через WARP"
|
"DirectVNDomainDesc" = "Измените шаблон конфигурации для прямого подключения к доменам Вьетнама"
|
||||||
"xrayConfigNetflixWARP" = "Маршрутизация Netflix через WARP"
|
"GoogleIPv4" = "Использовать IPv4 для Google"
|
||||||
"xrayConfigNetflixWARPDesc" = "Добавить маршрутизацию для Netflix через WARP"
|
"GoogleIPv4Desc" = "Добавить маршрутизацию для Google для подключения к IPv4"
|
||||||
"xrayConfigSpotifyWARP" = "Маршрутизация Spotify через WARP"
|
"NetflixIPv4" = "Использовать IPv4 для Netflix"
|
||||||
"xrayConfigSpotifyWARPDesc" = "Добавить маршрутизацию для Spotify через WARP"
|
"NetflixIPv4Desc" = "Добавить маршрутизацию для Netflix для подключения к IPv4"
|
||||||
"xrayConfigIRWARP" = "Маршрутизация доменов Ирана через WARP"
|
"GoogleWARP" = "Маршрутизация Google через WARP"
|
||||||
"xrayConfigIRWARPDesc" = "Добавить маршрутизацию для доменов Ирана через WARP"
|
"GoogleWARPDesc" = "Добавить маршрутизацию для Google через WARP"
|
||||||
"xrayConfigInbounds" = "Конфигурация подключений"
|
"OpenAIWARP" = "Маршрутизация OpenAI (ChatGPT) через WARP"
|
||||||
"xrayConfigInboundsDesc" = "Изменение шаблона конфигурации для подключения определенных пользователей"
|
"OpenAIWARPDesc" = "Добавить маршрутизацию для OpenAI (ChatGPT) через WARP"
|
||||||
"xrayConfigOutbounds" = "Конфигурация исходящих"
|
"NetflixWARP" = "Маршрутизация Netflix через WARP"
|
||||||
"xrayConfigOutboundsDesc" = "Изменение шаблона конфигурации, чтобы определить исходящие пути для этого сервера"
|
"NetflixWARPDesc" = "Добавить маршрутизацию для Netflix через WARP"
|
||||||
"xrayConfigRoutings" = "Настройка правил маршрутизации"
|
"SpotifyWARP" = "Маршрутизация Spotify через WARP"
|
||||||
"xrayConfigRoutingsDesc" = "Изменение шаблона конфигурации для определения правил маршрутизации для этого сервера"
|
"SpotifyWARPDesc" = "Добавить маршрутизацию для Spotify через WARP"
|
||||||
"completeTemplate" = "Все"
|
"IRWARP" = "Маршрутизация доменов Ирана через WARP"
|
||||||
|
"IRWARPDesc" = "Добавить маршрутизацию для доменов Ирана через WARP"
|
||||||
"Inbounds" = "Входящие"
|
"Inbounds" = "Входящие"
|
||||||
|
"InboundsDesc" = "Изменение шаблона конфигурации для подключения определенных пользователей"
|
||||||
"Outbounds" = "Исходящие"
|
"Outbounds" = "Исходящие"
|
||||||
|
"OutboundsDesc" = "Изменение шаблона конфигурации, чтобы определить исходящие пути для этого сервера"
|
||||||
"Routings" = "Правила маршрутизации"
|
"Routings" = "Правила маршрутизации"
|
||||||
"RoutingsDesc" = "Важен приоритет каждого правила!"
|
"RoutingsDesc" = "Важен приоритет каждого правила!"
|
||||||
|
"completeTemplate" = "Все"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"first" = "Первый"
|
"first" = "Первый"
|
||||||
@@ -389,7 +393,7 @@
|
|||||||
"source" = "Источник"
|
"source" = "Источник"
|
||||||
"dest" = "Пункт назначения"
|
"dest" = "Пункт назначения"
|
||||||
"inbound" = "Входящий"
|
"inbound" = "Входящий"
|
||||||
"outboun" = "Исходящий"
|
"outbound" = "Исходящий"
|
||||||
"info" = "Информация"
|
"info" = "Информация"
|
||||||
"add" = "Добавить правило"
|
"add" = "Добавить правило"
|
||||||
"edit" = "Редактировать правило"
|
"edit" = "Редактировать правило"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"username" = "Tên người dùng"
|
"username" = "Tên người dùng"
|
||||||
"password" = "Mật khẩu"
|
"password" = "Mật khẩu"
|
||||||
"login" = "Đăng nhập..."
|
"login" = "Đăng nhập"
|
||||||
"confirm" = "Xác nhận"
|
"confirm" = "Xác nhận"
|
||||||
"cancel" = "Hủy bỏ"
|
"cancel" = "Hủy bỏ"
|
||||||
"close" = "Đóng"
|
"close" = "Đóng"
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
"status" = "Trạng thái"
|
"status" = "Trạng thái"
|
||||||
"enabled" = "Đã kích hoạt"
|
"enabled" = "Đã kích hoạt"
|
||||||
"disabled" = "Đã tắt"
|
"disabled" = "Đã tắt"
|
||||||
"depleted" = "Đã cạn kiệt"
|
"depleted" = "Depleted"
|
||||||
"depletingSoon" = "Đang cạn kiệt"
|
"depletingSoon" = "Depleting..."
|
||||||
"offline" = "Ngoại tuyến"
|
"offline" = "Ngoại tuyến"
|
||||||
"online" = "Ngoại tuyến"
|
"online" = "Trực tuyến"
|
||||||
"domainName" = "Tên miền"
|
"domainName" = "Tên miền"
|
||||||
"monitor" = "Listening IP"
|
"monitor" = "Listening IP"
|
||||||
"certificate" = "Chứng chỉ"
|
"certificate" = "Chứng chỉ"
|
||||||
@@ -47,9 +47,9 @@
|
|||||||
"success" = "Thành công"
|
"success" = "Thành công"
|
||||||
"getVersion" = "Lấy phiên bản"
|
"getVersion" = "Lấy phiên bản"
|
||||||
"install" = "Cài đặt"
|
"install" = "Cài đặt"
|
||||||
"clients" = "Khách hàng"
|
"clients" = "Các khách hàng"
|
||||||
"usage" = "Sử dụng"
|
"usage" = "Sử dụng"
|
||||||
"secretToken" = "secretToken"
|
"secretToken" = "Mã bí mật"
|
||||||
"remained" = "Còn lại"
|
"remained" = "Còn lại"
|
||||||
"security" = "Bảo vệ"
|
"security" = "Bảo vệ"
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
"settings" = "Cài đặt bảng điều khiển"
|
"settings" = "Cài đặt bảng điều khiển"
|
||||||
"logout" = "Đăng xuất"
|
"logout" = "Đăng xuất"
|
||||||
"xray" = "Xray Cài đặt"
|
"xray" = "Xray Cài đặt"
|
||||||
"link" = "Khác"
|
"link" = "sự quản lý"
|
||||||
|
|
||||||
[pages.login]
|
[pages.login]
|
||||||
"title" = "Đăng nhập"
|
"title" = "Đăng nhập"
|
||||||
@@ -315,71 +315,75 @@
|
|||||||
"ipv4ConfigsDesc" = "Những tùy chọn này sẽ chỉ định kết nối đến các tên miền mục tiêu qua IPv4."
|
"ipv4ConfigsDesc" = "Những tùy chọn này sẽ chỉ định kết nối đến các tên miền mục tiêu qua IPv4."
|
||||||
"warpConfigs" = "Cấu hình WARP"
|
"warpConfigs" = "Cấu hình WARP"
|
||||||
"warpConfigsDesc" = "Cảnh báo: Trước khi sử dụng những tùy chọn này, hãy cài đặt WARP ở chế độ proxy socks5 trên máy chủ của bạn bằng cách làm theo các bước trên GitHub của bảng điều khiển. WARP sẽ định tuyến lưu lượng đến các trang web qua máy chủ Cloudflare."
|
"warpConfigsDesc" = "Cảnh báo: Trước khi sử dụng những tùy chọn này, hãy cài đặt WARP ở chế độ proxy socks5 trên máy chủ của bạn bằng cách làm theo các bước trên GitHub của bảng điều khiển. WARP sẽ định tuyến lưu lượng đến các trang web qua máy chủ Cloudflare."
|
||||||
"xrayConfigTemplate" = "Mẫu Cấu hình Xray"
|
"Template" = "Mẫu Cấu hình Xray"
|
||||||
"xrayConfigTemplateDesc" = "Tạo tệp cấu hình Xray cuối cùng dựa trên mẫu này."
|
"TemplateDesc" = "Tạo tệp cấu hình Xray cuối cùng dựa trên mẫu này."
|
||||||
"xrayConfigFreedomStrategy" = "Cấu hình Chiến lược cho Giao thức Freedom"
|
"FreedomStrategy" = "Cấu hình Chiến lược cho Giao thức Freedom"
|
||||||
"xrayConfigFreedomStrategyDesc" = "Đặt chiến lược đầu ra của mạng trong Giao thức Freedom."
|
"FreedomStrategyDesc" = "Đặt chiến lược đầu ra của mạng trong Giao thức Freedom."
|
||||||
"xrayConfigRoutingStrategy" = "Cấu hình Chiến lược Định tuyến Tên miền"
|
"RoutingStrategy" = "Cấu hình Chiến lược Định tuyến Tên miền"
|
||||||
"xrayConfigRoutingStrategyDesc" = "Đặt chiến lược định tuyến tổng thể cho việc giải quyết DNS."
|
"RoutingStrategyDesc" = "Đặt chiến lược định tuyến tổng thể cho việc giải quyết DNS."
|
||||||
"xrayConfigTorrent" = "Cấu hình sử dụng BitTorrent"
|
"Torrent" = "Cấu hình sử dụng BitTorrent"
|
||||||
"xrayConfigTorrentDesc" = "Thay đổi mẫu cấu hình để tránh việc người dùng sử dụng BitTorrent."
|
"TorrentDesc" = "Thay đổi mẫu cấu hình để tránh việc người dùng sử dụng BitTorrent."
|
||||||
"xrayConfigPrivateIp" = "Cấm kết nối đến dải IP Riêng tư"
|
"PrivateIp" = "Cấm kết nối đến dải IP Riêng tư"
|
||||||
"xrayConfigPrivateIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP riêng tư."
|
"PrivateIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP riêng tư."
|
||||||
"xrayConfigAds" = "Chặn Quảng cáo"
|
"Ads" = "Chặn Quảng cáo"
|
||||||
"xrayConfigAdsDesc" = "Thay đổi mẫu cấu hình để chặn quảng cáo."
|
"AdsDesc" = "Thay đổi mẫu cấu hình để chặn quảng cáo."
|
||||||
"xrayConfigFamily" = "Chặn Phần mềm độc hại và Nội dung cho Người lớn"
|
"Family" = "Chặn Phần mềm độc hại và Nội dung cho Người lớn"
|
||||||
"xrayConfigFamilyDesc" = "Các trình giải quyết DNS để chặn phần mềm độc hại và nội dung cho bảo vệ gia đình."
|
"FamilyDesc" = "Các trình giải quyết DNS để chặn phần mềm độc hại và nội dung cho bảo vệ gia đình."
|
||||||
"xrayConfigSpeedtest" = "Chặn Trang web Speedtest"
|
"Speedtest" = "Chặn Trang web Speedtest"
|
||||||
"xrayConfigSpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest."
|
"SpeedtestDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các trang web Speedtest."
|
||||||
"xrayConfigIRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran"
|
"IRIp" = "Vô hiệu hóa kết nối đến dải IP của Iran"
|
||||||
"xrayConfigIRIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Iran."
|
"IRIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Iran."
|
||||||
"xrayConfigIRDomain" = "Vô hiệu hóa kết nối đến tên miền của Iran"
|
"IRDomain" = "Vô hiệu hóa kết nối đến tên miền của Iran"
|
||||||
"xrayConfigIRDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Iran."
|
"IRDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Iran."
|
||||||
"xrayConfigChinaIp" = "Vô hiệu hóa kết nối đến dải IP của Trung Quốc"
|
"ChinaIp" = "Vô hiệu hóa kết nối đến dải IP của Trung Quốc"
|
||||||
"xrayConfigChinaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Trung Quốc."
|
"ChinaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Trung Quốc."
|
||||||
"xrayConfigChinaDomain" = "Vô hiệu hóa kết nối đến tên miền của Trung Quốc"
|
"ChinaDomain" = "Vô hiệu hóa kết nối đến tên miền của Trung Quốc"
|
||||||
"xrayConfigChinaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Trung Quốc."
|
"ChinaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Trung Quốc."
|
||||||
"xrayConfigRussiaIp" = "Vô hiệu hóa kết nối đến dải IP của Nga"
|
"RussiaIp" = "Vô hiệu hóa kết nối đến dải IP của Nga"
|
||||||
"xrayConfigRussiaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Nga."
|
"RussiaIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Nga."
|
||||||
"xrayConfigRussiaDomain" = "Vô hiệu hóa kết nối đến tên miền của Nga"
|
"RussiaDomain" = "Vô hiệu hóa kết nối đến tên miền của Nga"
|
||||||
"xrayConfigRussiaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Nga."
|
"RussiaDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Nga."
|
||||||
"xrayConfigDirectIRIp" = "Kết nối trực tiếp đến dải IP của Iran"
|
"VNIp" = "Vô hiệu hóa kết nối đến dải IP của Việt Nam"
|
||||||
"xrayConfigDirectIRIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Iran."
|
"VNIpDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến dải IP của Việt Nam."
|
||||||
"xrayConfigDirectIRDomain" = "Kết nối trực tiếp đến tên miền của Iran"
|
"VNDomain" = "Vô hiệu hóa kết nối đến tên miền của Việt Nam"
|
||||||
"xrayConfigDirectIRDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Iran."
|
"VNDomainDesc" = "Thay đổi mẫu cấu hình để tránh kết nối đến các tên miền của Việt Nam."
|
||||||
"xrayConfigDirectChinaIp" = "Kết nối trực tiếp đến dải IP của Trung Quốc"
|
"DirectIRIp" = "Kết nối trực tiếp đến dải IP của Iran"
|
||||||
"xrayConfigDirectChinaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Trung Quốc."
|
"DirectIRIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Iran."
|
||||||
"xrayConfigDirectChinaDomain" = "Kết nối trực tiếp đến tên miền của Trung Quốc"
|
"DirectIRDomain" = "Kết nối trực tiếp đến tên miền của Iran"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Trung Quốc."
|
"DirectIRDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Iran."
|
||||||
"xrayConfigDirectRussiaIp" = "Kết nối trực tiếp đến dải IP của Nga"
|
"DirectChinaIp" = "Kết nối trực tiếp đến dải IP của Trung Quốc"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Nga."
|
"DirectChinaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Trung Quốc."
|
||||||
"xrayConfigDirectRussiaDomain" = "Kết nối trực tiếp đến tên miền của Nga"
|
"DirectChinaDomain" = "Kết nối trực tiếp đến tên miền của Trung Quốc"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Nga."
|
"DirectChinaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Trung Quốc."
|
||||||
"xrayConfigGoogleIPv4" = "Sử dụng IPv4 cho Google"
|
"DirectRussiaIp" = "Kết nối trực tiếp đến dải IP của Nga"
|
||||||
"xrayConfigGoogleIPv4Desc" = "Thêm định tuyến cho Google để kết nối qua IPv4."
|
"DirectRussiaIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Nga."
|
||||||
"xrayConfigNetflixIPv4" = "Sử dụng IPv4 cho Netflix"
|
"DirectRussiaDomain" = "Kết nối trực tiếp đến tên miền của Nga"
|
||||||
"xrayConfigNetflixIPv4Desc" = "Thêm định tuyến cho Netflix để kết nối qua IPv4."
|
"DirectRussiaDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Nga."
|
||||||
"xrayConfigGoogleWARP" = "Định tuyến Google qua WARP."
|
"DirectVNIp" = "Kết nối trực tiếp đến dải IP của Việt Nam"
|
||||||
"xrayConfigGoogleWARPDesc" = "Thêm định tuyến cho Google qua WARP."
|
"DirectVNIpDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến dải IP của Việt Nam"
|
||||||
"xrayConfigOpenAIWARP" = "Định tuyến OpenAI (ChatGPT) qua WARP."
|
"DirectVNDomain" = "Kết nối trực tiếp đến tên miền của Việt Nam"
|
||||||
"xrayConfigOpenAIWARPDesc" = "Thêm định tuyến cho OpenAI (ChatGPT) qua WARP."
|
"DirectVNDomainDesc" = "Thay đổi mẫu cấu hình cho kết nối trực tiếp đến các tên miền của Việt Nam."
|
||||||
"xrayConfigNetflixWARP" = "Định tuyến Netflix qua WARP."
|
"GoogleIPv4" = "Sử dụng IPv4 cho Google"
|
||||||
"xrayConfigNetflixWARPDesc" = "Thêm định tuyến cho Netflix qua WARP."
|
"GoogleIPv4Desc" = "Thêm định tuyến cho Google để kết nối qua IPv4."
|
||||||
"xrayConfigSpotifyWARP" = "Định tuyến Spotify qua WARP."
|
"NetflixIPv4" = "Sử dụng IPv4 cho Netflix"
|
||||||
"xrayConfigSpotifyWARPDesc" = "Thêm định tuyến cho Spotify qua WARP."
|
"NetflixIPv4Desc" = "Thêm định tuyến cho Netflix để kết nối qua IPv4."
|
||||||
"xrayConfigIRWARP" = "Định tuyến tên miền của Iran qua WARP."
|
"GoogleWARP" = "Định tuyến Google qua WARP."
|
||||||
"xrayConfigIRWARPDesc" = "Thêm định tuyến cho các tên miền của Iran qua WARP."
|
"GoogleWARPDesc" = "Thêm định tuyến cho Google qua WARP."
|
||||||
"xrayConfigInbounds" = "Cấu hình của Inbounds"
|
"OpenAIWARP" = "Định tuyến OpenAI (ChatGPT) qua WARP."
|
||||||
"xrayConfigInboundsDesc" = "Thay đổi mẫu cấu hình để chấp nhận các máy khách cụ thể."
|
"OpenAIWARPDesc" = "Thêm định tuyến cho OpenAI (ChatGPT) qua WARP."
|
||||||
"xrayConfigOutbounds" = "Cấu hình của Outbounds"
|
"NetflixWARP" = "Định tuyến Netflix qua WARP."
|
||||||
"xrayConfigOutboundsDesc" = "Thay đổi mẫu cấu hình để xác định các cách ra đi cho máy chủ này."
|
"NetflixWARPDesc" = "Thêm định tuyến cho Netflix qua WARP."
|
||||||
"xrayConfigRoutings" = "Cấu hình của Luật Định tuyến."
|
"SpotifyWARP" = "Định tuyến Spotify qua WARP."
|
||||||
"xrayConfigRoutingsDesc" = "Thay đổi mẫu cấu hình để xác định luật định tuyến cho máy chủ này."
|
"SpotifyWARPDesc" = "Thêm định tuyến cho Spotify qua WARP."
|
||||||
"completeTemplate" = "All"
|
"IRWARP" = "Định tuyến tên miền của Iran qua WARP."
|
||||||
"Inbounds" = "Vào"
|
"IRWARPDesc" = "Thêm định tuyến cho các tên miền của Iran qua WARP."
|
||||||
"Outbounds" = "Outbounds"
|
"Inbounds" = "Đầu vào"
|
||||||
|
"InboundsDesc" = "Thay đổi mẫu cấu hình để chấp nhận các máy khách cụ thể."
|
||||||
|
"Outbounds" = "Đầu ra"
|
||||||
|
"OutboundsDesc" = "Thay đổi mẫu cấu hình để xác định các cách ra đi cho máy chủ này."
|
||||||
"Routings" = "Quy tắc định tuyến"
|
"Routings" = "Quy tắc định tuyến"
|
||||||
"RoutingsDesc" = "Mức độ ưu tiên của mỗi quy tắc đều quan trọng!"
|
"RoutingsDesc" = "Mức độ ưu tiên của mỗi quy tắc đều quan trọng!"
|
||||||
|
"completeTemplate" = "All"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"first" = "Đầu tiên"
|
"first" = "Đầu tiên"
|
||||||
@@ -389,7 +393,7 @@
|
|||||||
"source" = "Nguồn"
|
"source" = "Nguồn"
|
||||||
"dest" = "Đích"
|
"dest" = "Đích"
|
||||||
"inbound" = "Vào"
|
"inbound" = "Vào"
|
||||||
"outbound" = "Ra ngoài"
|
"outbound" = "Ra"
|
||||||
"info" = "Thông tin"
|
"info" = "Thông tin"
|
||||||
"add" = "Thêm quy tắc"
|
"add" = "Thêm quy tắc"
|
||||||
"edit" = "Chỉnh sửa quy tắc"
|
"edit" = "Chỉnh sửa quy tắc"
|
||||||
@@ -439,8 +443,8 @@
|
|||||||
"days" = "Ngày"
|
"days" = "Ngày"
|
||||||
"hours" = "Giờ"
|
"hours" = "Giờ"
|
||||||
"unknown" = "Không rõ"
|
"unknown" = "Không rõ"
|
||||||
"inbounds" = "Inbounds"
|
"inbounds" = "Vào"
|
||||||
"clients" = "Khách hàng"
|
"clients" = "Các khách hàng"
|
||||||
|
|
||||||
[tgbot.commands]
|
[tgbot.commands]
|
||||||
"unknown" = "❗ Lệnh không rõ"
|
"unknown" = "❗ Lệnh không rõ"
|
||||||
@@ -503,10 +507,10 @@
|
|||||||
"confirmResetTraffic" = "✅ Xác Nhận Đặt Lại Lưu Lượng?"
|
"confirmResetTraffic" = "✅ Xác Nhận Đặt Lại Lưu Lượng?"
|
||||||
"confirmClearIps" = "✅ Xác Nhận Xóa Các IP?"
|
"confirmClearIps" = "✅ Xác Nhận Xóa Các IP?"
|
||||||
"confirmRemoveTGUser" = "✅ Xác Nhận Xóa Người Dùng Telegram?"
|
"confirmRemoveTGUser" = "✅ Xác Nhận Xóa Người Dùng Telegram?"
|
||||||
"dbBackup" = "Tải Backup DB"
|
"dbBackup" = "Tải bản sao lưu cơ sở dữ liệu"
|
||||||
"serverUsage" = "Sử Dụng Máy Chủ"
|
"serverUsage" = "Sử Dụng Máy Chủ"
|
||||||
"getInbounds" = "Lấy Inbounds"
|
"getInbounds" = "Lấy cổng vào"
|
||||||
"depleteSoon" = "Sắp Cạn Kiệt"
|
"depleteSoon" = "Depleted Soon"
|
||||||
"clientUsage" = "Lấy Sử Dụng"
|
"clientUsage" = "Lấy Sử Dụng"
|
||||||
"commands" = "Lệnh"
|
"commands" = "Lệnh"
|
||||||
"refresh" = "🔄 Cập Nhật"
|
"refresh" = "🔄 Cập Nhật"
|
||||||
@@ -516,13 +520,13 @@
|
|||||||
"selectOneTGUser" = "👤 Chọn một người dùng telegram:"
|
"selectOneTGUser" = "👤 Chọn một người dùng telegram:"
|
||||||
"resetTraffic" = "📈 Đặt Lại Lưu Lượng"
|
"resetTraffic" = "📈 Đặt Lại Lưu Lượng"
|
||||||
"resetExpire" = "📅 Đặt Lại Ngày Hết Hạn"
|
"resetExpire" = "📅 Đặt Lại Ngày Hết Hạn"
|
||||||
"ipLog" = "🔢 Log IP"
|
"ipLog" = "🔢 Nhật ký địa chỉ IP"
|
||||||
"ipLimit" = "🔢 Giới Hạn IP"
|
"ipLimit" = "🔢 Giới Hạn địa chỉ IP"
|
||||||
"setTGUser" = "👤 Đặt Người Dùng Telegram"
|
"setTGUser" = "👤 Đặt Người Dùng Telegram"
|
||||||
"toggle" = "🔘 Bật / Tắt"
|
"toggle" = "🔘 Bật / Tắt"
|
||||||
"custom" = "🔢 Phong tục"
|
"custom" = "🔢 Tùy chỉnh"
|
||||||
"confirmNumber" = "✅ Xác nhận : {{ .Num }}"
|
"confirmNumber" = "✅ Xác nhận : {{ .Num }}"
|
||||||
"limitTraffic" = "🚧 Giới hạn giao thông"
|
"limitTraffic" = "🚧 Giới hạn lưu lượng"
|
||||||
|
|
||||||
[tgbot.answers]
|
[tgbot.answers]
|
||||||
"successfulOperation" = "✅ Thành công!"
|
"successfulOperation" = "✅ Thành công!"
|
||||||
@@ -536,8 +540,8 @@
|
|||||||
"setTrafficLimitSuccess" = "✅ {{ .Email }} : Đã lưu thành công giới hạn lưu lượng."
|
"setTrafficLimitSuccess" = "✅ {{ .Email }} : Đã lưu thành công giới hạn lưu lượng."
|
||||||
"expireResetSuccess" = "✅ {{ .Email }} : Đặt Lại Ngày Hết Hạn Thành Công."
|
"expireResetSuccess" = "✅ {{ .Email }} : Đặt Lại Ngày Hết Hạn Thành Công."
|
||||||
"resetIpSuccess" = "✅ {{ .Email }} : Giới Hạn IP {{ .Count }} Đã Được Lưu Thành Công."
|
"resetIpSuccess" = "✅ {{ .Email }} : Giới Hạn IP {{ .Count }} Đã Được Lưu Thành Công."
|
||||||
"clearIpSuccess" = "✅ {{ .Email }} : IPs Đã Được Xóa Thành Công."
|
"clearIpSuccess" = "✅ {{ .Email }} : IP Đã Được Xóa Thành Công."
|
||||||
"getIpLog" = "✅ {{ .Email }} : Lấy Log IP Thành Công."
|
"getIpLog" = "✅ {{ .Email }} : Lấy nhật ký IP Thành Công."
|
||||||
"getUserInfo" = "✅ {{ .Email }} : Lấy Thông Tin Người Dùng Telegram Thành Công."
|
"getUserInfo" = "✅ {{ .Email }} : Lấy Thông Tin Người Dùng Telegram Thành Công."
|
||||||
"removedTGUserSuccess" = "✅ {{ .Email }} : Người Dùng Telegram Đã Được Xóa Thành Công."
|
"removedTGUserSuccess" = "✅ {{ .Email }} : Người Dùng Telegram Đã Được Xóa Thành Công."
|
||||||
"enableSuccess" = "✅ {{ .Email }} : Đã Bật Thành Công."
|
"enableSuccess" = "✅ {{ .Email }} : Đã Bật Thành Công."
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
"settings" = "面板设置"
|
"settings" = "面板设置"
|
||||||
"xray" = "Xray 设置"
|
"xray" = "Xray 设置"
|
||||||
"logout" = "退出登录"
|
"logout" = "退出登录"
|
||||||
"link" = "其他"
|
"link" = "管理"
|
||||||
|
|
||||||
[pages.login]
|
[pages.login]
|
||||||
"title" = "登录"
|
"title" = "登录"
|
||||||
@@ -315,74 +315,78 @@
|
|||||||
"ipv4ConfigsDesc" = "此选项将仅通过 IPv4 路由到目标域"
|
"ipv4ConfigsDesc" = "此选项将仅通过 IPv4 路由到目标域"
|
||||||
"warpConfigs" = "WARP 配置"
|
"warpConfigs" = "WARP 配置"
|
||||||
"warpConfigsDesc" = "注意:在使用这些选项之前,请按照面板 GitHub 上的步骤在您的服务器上以 socks5 代理模式安装 WARP。 WARP 将通过 Cloudflare 服务器将流量路由到网站。"
|
"warpConfigsDesc" = "注意:在使用这些选项之前,请按照面板 GitHub 上的步骤在您的服务器上以 socks5 代理模式安装 WARP。 WARP 将通过 Cloudflare 服务器将流量路由到网站。"
|
||||||
"xrayConfigTemplate" = "Xray 配置模板"
|
"Template" = "Xray 配置模板"
|
||||||
"xrayConfigTemplateDesc" = "以该模型为基础生成最终的Xray配置文件,重新启动面板生成效率"
|
"TemplateDesc" = "以该模型为基础生成最终的Xray配置文件,重新启动面板生成效率"
|
||||||
"xrayConfigFreedomStrategy" = "配置自由协议的策略"
|
"FreedomStrategy" = "配置自由协议的策略"
|
||||||
"xrayConfigFreedomStrategyDesc" = "在自由协议中设置网络输出策略"
|
"FreedomStrategyDesc" = "在自由协议中设置网络输出策略"
|
||||||
"xrayConfigRoutingStrategy" = "配置路由域策略"
|
"RoutingStrategy" = "配置路由域策略"
|
||||||
"xrayConfigRoutingStrategyDesc" = "设置DNS解析的整体路由策略"
|
"RoutingStrategyDesc" = "设置DNS解析的整体路由策略"
|
||||||
"xrayConfigTorrent" = "禁止使用 bittorrent"
|
"Torrent" = "禁止使用 bittorrent"
|
||||||
"xrayConfigTorrentDesc" = "更改配置模板避免用户使用bittorrent"
|
"TorrentDesc" = "更改配置模板避免用户使用bittorrent"
|
||||||
"xrayConfigPrivateIp" = "禁止私人 IP 范围连接"
|
"PrivateIp" = "禁止私人 IP 范围连接"
|
||||||
"xrayConfigPrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围"
|
"PrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围"
|
||||||
"xrayConfigAds" = "屏蔽广告"
|
"Ads" = "屏蔽广告"
|
||||||
"xrayConfigAdsDesc" = "修改配置模板屏蔽广告"
|
"AdsDesc" = "修改配置模板屏蔽广告"
|
||||||
"xrayConfigFamily" = "启用家庭友好配置"
|
"Family" = "启用家庭友好配置"
|
||||||
"xrayConfigFamilyDesc" = "避免为家人连接到不安全的网站"
|
"FamilyDesc" = "避免为家人连接到不安全的网站"
|
||||||
"xrayConfigSpeedtest" = "阻止测速网站"
|
"Speedtest" = "阻止测速网站"
|
||||||
"xrayConfigSpeedtestDesc" = "更改配置模板以避免连接到速度测试网站。 重新启动面板以应用更改。"
|
"SpeedtestDesc" = "更改配置模板以避免连接到速度测试网站。 重新启动面板以应用更改。"
|
||||||
"xrayConfigIRIp" = "禁止伊朗 IP 范围连接"
|
"IRIp" = "禁止伊朗 IP 范围连接"
|
||||||
"xrayConfigIRIpDesc" = "修改配置模板避免连接伊朗IP段"
|
"IRIpDesc" = "修改配置模板避免连接伊朗IP段"
|
||||||
"xrayConfigIRDomain" = "禁止伊朗域连接"
|
"IRDomain" = "禁止伊朗域连接"
|
||||||
"xrayConfigIRDomainDesc" = "更改配置模板避免连接伊朗域名"
|
"IRDomainDesc" = "更改配置模板避免连接伊朗域名"
|
||||||
"xrayConfigChinaIp" = "禁止中国 IP 范围连接"
|
"ChinaIp" = "禁止中国 IP 范围连接"
|
||||||
"xrayConfigChinaIpDesc" = "修改配置模板避免连接中国IP段"
|
"ChinaIpDesc" = "修改配置模板避免连接中国IP段"
|
||||||
"xrayConfigChinaDomain" = "禁止中国域名连接"
|
"ChinaDomain" = "禁止中国域名连接"
|
||||||
"xrayConfigChinaDomainDesc" = "更改配置模板避免连接中国域"
|
"ChinaDomainDesc" = "更改配置模板避免连接中国域"
|
||||||
"xrayConfigRussiaIp" = "禁止俄罗斯 IP 范围连接"
|
"RussiaIp" = "禁止俄罗斯 IP 范围连接"
|
||||||
"xrayConfigRussiaIpDesc" = "修改配置模板避免连接俄罗斯IP范围"
|
"RussiaIpDesc" = "修改配置模板避免连接俄罗斯IP范围"
|
||||||
"xrayConfigRussiaDomain" = "禁止俄罗斯域连接"
|
"RussiaDomain" = "禁止俄罗斯域连接"
|
||||||
"xrayConfigRussiaDomainDesc" = "更改配置模板避免连接俄罗斯域"
|
"RussiaDomainDesc" = "更改配置模板避免连接俄罗斯域"
|
||||||
"xrayConfigDirectIRIp" = "直接连接到伊朗 IP 范围"
|
"VNIp" = "禁用与越南 IP 的连接"
|
||||||
"xrayConfigDirectIRIpDesc" = "更改直接连接到伊朗 IP 范围的配置模板"
|
"VNIpDesc" = "更改配置模板以避免连接到越南 IP 范围"
|
||||||
"xrayConfigDirectIRDomain" = "直接连接到伊朗域"
|
"VNDomain" = "禁用与越南域的连接"
|
||||||
"xrayConfigDirectIRDomainDesc" = "更改直接连接到伊朗域的配置模板"
|
"VNDomainDesc" = "更改配置模板以避免连接到越南域"
|
||||||
"xrayConfigDirectChinaIp" = "直连中国IP范围"
|
"DirectIRIp" = "直接连接到伊朗 IP 范围"
|
||||||
"xrayConfigDirectChinaIpDesc" = "更改直连中国 IP 范围的配置模板"
|
"DirectIRIpDesc" = "更改直接连接到伊朗 IP 范围的配置模板"
|
||||||
"xrayConfigDirectChinaDomain" = "直连中国域名"
|
"DirectIRDomain" = "直接连接到伊朗域"
|
||||||
"xrayConfigDirectChinaDomainDesc" = "修改中国域名直连配置模板"
|
"DirectIRDomainDesc" = "更改直接连接到伊朗域的配置模板"
|
||||||
"xrayConfigDirectRussiaIp" = "直接连接到俄罗斯 IP 范围"
|
"DirectChinaIp" = "直连中国IP范围"
|
||||||
"xrayConfigDirectRussiaIpDesc" = "更改直接连接到俄罗斯 IP 范围的配置模板"
|
"DirectChinaIpDesc" = "更改直连中国 IP 范围的配置模板"
|
||||||
"xrayConfigDirectRussiaDomain" = "直接连接到俄罗斯域"
|
"DirectChinaDomain" = "直连中国域名"
|
||||||
"xrayConfigDirectRussiaDomainDesc" = "更改直接连接到俄罗斯域的配置模板"
|
"DirectChinaDomainDesc" = "修改中国域名直连配置模板"
|
||||||
"xrayConfigGoogleIPv4" = "为谷歌使用 IPv4"
|
"DirectRussiaIp" = "直接连接到俄罗斯 IP 范围"
|
||||||
"xrayConfigGoogleIPv4Desc" = "添加谷歌连接IPv4的路由"
|
"DirectRussiaIpDesc" = "更改直接连接到俄罗斯 IP 范围的配置模板"
|
||||||
"xrayConfigNetflixIPv4" = "为 Netflix 使用 IPv4"
|
"DirectRussiaDomain" = "直接连接到俄罗斯域"
|
||||||
"xrayConfigNetflixIPv4Desc" = "添加Netflix连接IPv4的路由"
|
"DirectRussiaDomainDesc" = "更改直接连接到俄罗斯域的配置模板"
|
||||||
"xrayConfigGoogleWARP" = "将谷歌路由到 WARP"
|
"DirectVNIp" = "直接连接越南IP"
|
||||||
"xrayConfigGoogleWARPDesc" = "为谷歌添加路由到WARP"
|
"DirectVNIpDesc" = "更改直接连接到越南 IP 范围的配置模板"
|
||||||
"xrayConfigOpenAIWARP" = "将 OpenAI (ChatGPT) 路由到 WARP"
|
"DirectVNDomain" = "直接连接至越南域名"
|
||||||
"xrayConfigOpenAIWARPDesc" = "将OpenAI(ChatGPT)路由添加到WARP"
|
"DirectVNDomainDesc" = "更改直连越南域的配置模板。"
|
||||||
"xrayConfigNetflixWARP" = "将 Netflix 路由到 WARP"
|
"GoogleIPv4" = "为谷歌使用 IPv4"
|
||||||
"xrayConfigNetflixWARPDesc" = "为Netflix添加路由到WARP"
|
"GoogleIPv4Desc" = "添加谷歌连接IPv4的路由"
|
||||||
"xrayConfigSpotifyWARP" = "将 Spotify 路由到 WARP"
|
"NetflixIPv4" = "为 Netflix 使用 IPv4"
|
||||||
"xrayConfigSpotifyWARPDesc" = "为Spotify添加路由到WARP"
|
"NetflixIPv4Desc" = "添加Netflix连接IPv4的路由"
|
||||||
"xrayConfigIRWARP" = "将伊朗域名路由到 WARP"
|
"GoogleWARP" = "将谷歌路由到 WARP"
|
||||||
"xrayConfigIRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效"
|
"GoogleWARPDesc" = "为谷歌添加路由到WARP"
|
||||||
"xrayConfigInbounds" = "入站配置"
|
"OpenAIWARP" = "将 OpenAI (ChatGPT) 路由到 WARP"
|
||||||
"xrayConfigInboundsDesc" = "更改配置模板接受特殊客户端"
|
"OpenAIWARPDesc" = "将OpenAI(ChatGPT)路由添加到WARP"
|
||||||
"xrayConfigOutbounds" = "出站配置"
|
"NetflixWARP" = "将 Netflix 路由到 WARP"
|
||||||
"xrayConfigOutboundsDesc" = "更改配置模板定义此服务器的传出方式"
|
"NetflixWARPDesc" = "为Netflix添加路由到WARP"
|
||||||
"xrayConfigRoutings" = "路由规则配置"
|
"SpotifyWARP" = "将 Spotify 路由到 WARP"
|
||||||
"xrayConfigRoutingsDesc" = "更改配置模板为该服务器定义路由规则"
|
"SpotifyWARPDesc" = "为Spotify添加路由到WARP"
|
||||||
"completeTemplate" = "全部"
|
"IRWARP" = "将伊朗域名路由到 WARP"
|
||||||
|
"IRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效"
|
||||||
"Inbounds" = "界内"
|
"Inbounds" = "界内"
|
||||||
|
"InboundsDesc" = "更改配置模板接受特殊客户端"
|
||||||
"Outbounds" = "出站"
|
"Outbounds" = "出站"
|
||||||
|
"OutboundsDesc" = "更改配置模板定义此服务器的传出方式"
|
||||||
"Routings" = "路由规则"
|
"Routings" = "路由规则"
|
||||||
"RoutingsDesc" = "每条规则的优先级都很重要"
|
"RoutingsDesc" = "每条规则的优先级都很重要"
|
||||||
|
"completeTemplate" = "全部"
|
||||||
|
|
||||||
[pages.xray.rules]
|
[pages.xray.rules]
|
||||||
"firsto" = "第一个"
|
"first" = "第一个"
|
||||||
"last" = "最后"
|
"last" = "最后"
|
||||||
"up" = "向上"
|
"up" = "向上"
|
||||||
"down" = "向下"
|
"down" = "向下"
|
||||||
@@ -403,7 +407,7 @@
|
|||||||
"tag" = "标签"
|
"tag" = "标签"
|
||||||
"tagDesc" = "独特的标签"
|
"tagDesc" = "独特的标签"
|
||||||
"address" = "地址"
|
"address" = "地址"
|
||||||
"rreverse" = "反转"
|
"reverse" = "反转"
|
||||||
"domain" = "域名"
|
"domain" = "域名"
|
||||||
"type" = "类型"
|
"type" = "类型"
|
||||||
"bridge" = "桥"
|
"bridge" = "桥"
|
||||||
|
|||||||
12
x-ui.sh
@@ -55,7 +55,11 @@ elif [[ "${release}" == "debian" ]]; then
|
|||||||
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
||||||
fi
|
fi
|
||||||
elif [[ "${release}" == "arch" ]]; then
|
elif [[ "${release}" == "arch" ]]; then
|
||||||
echo "OS is ArchLinux"
|
echo "Your OS is ArchLinux"
|
||||||
|
elif [[ "${release}" == "manjaro" ]]; then
|
||||||
|
echo "Your OS is Manjaro"
|
||||||
|
elif [[ "${release}" == "armbian" ]]; then
|
||||||
|
echo "Your OS is Armbian"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -519,11 +523,13 @@ update_geo() {
|
|||||||
|
|
||||||
systemctl stop x-ui
|
systemctl stop x-ui
|
||||||
cd ${binFolder}
|
cd ${binFolder}
|
||||||
rm -f geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat
|
rm -f geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat
|
||||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||||
wget -O geoip_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
wget -O geoip_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
wget -O geosite_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
wget -O geosite_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
|
wget -O geoip_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
|
wget -O geosite_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
systemctl start x-ui
|
systemctl start x-ui
|
||||||
echo -e "${green}Geosite.dat + Geoip.dat + geoip_IR.dat + geosite_IR.dat have been updated successfully in bin folder '${binfolder}'!${plain}"
|
echo -e "${green}Geosite.dat + Geoip.dat + geoip_IR.dat + geosite_IR.dat have been updated successfully in bin folder '${binfolder}'!${plain}"
|
||||||
before_show_menu
|
before_show_menu
|
||||||
@@ -579,7 +585,7 @@ ssl_cert_issue() {
|
|||||||
fi
|
fi
|
||||||
# install socat second
|
# install socat second
|
||||||
case "${release}" in
|
case "${release}" in
|
||||||
ubuntu|debian)
|
ubuntu|debian|armbian)
|
||||||
apt update && apt install socat -y ;;
|
apt update && apt install socat -y ;;
|
||||||
centos)
|
centos)
|
||||||
yum -y update && yum -y install socat ;;
|
yum -y update && yum -y install socat ;;
|
||||||
|
|||||||