Showing preview only (6,041K chars total). Download the full file or copy to clipboard to get everything.
Repository: gm-cx/3x-ui-cn
Branch: main
Commit: 22fb66e7d05d
Files: 184
Total size: 5.6 MB
Directory structure:
gitextract_e5aa8s52/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── question-.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── docker.yml
│ └── release.yml
├── .gitignore
├── DockerEntrypoint.sh
├── DockerInit.sh
├── Dockerfile
├── LICENSE
├── README.es_ES.md
├── README.md
├── README.zh.md
├── config/
│ ├── config.go
│ ├── name
│ └── version
├── database/
│ ├── db.go
│ └── model/
│ └── model.go
├── docker-compose.yml
├── go.mod
├── go.sum
├── install.sh
├── logger/
│ └── logger.go
├── main.go
├── sub/
│ ├── default.json
│ ├── sub.go
│ ├── subController.go
│ ├── subJsonService.go
│ └── subService.go
├── util/
│ ├── common/
│ │ ├── err.go
│ │ ├── format.go
│ │ └── multi_error.go
│ ├── json_util/
│ │ └── json.go
│ ├── random/
│ │ └── random.go
│ ├── reflect_util/
│ │ └── reflect.go
│ └── sys/
│ ├── psutil.go
│ ├── sys_darwin.go
│ ├── sys_linux.go
│ └── sys_windows.go
├── web/
│ ├── assets/
│ │ ├── ant-design-vue/
│ │ │ └── antd.less
│ │ ├── codemirror/
│ │ │ ├── codemirror.css
│ │ │ ├── codemirror.js
│ │ │ ├── fold/
│ │ │ │ ├── brace-fold.js
│ │ │ │ ├── foldcode.js
│ │ │ │ ├── foldgutter.css
│ │ │ │ └── foldgutter.js
│ │ │ ├── hint/
│ │ │ │ └── javascript-hint.js
│ │ │ ├── javascript.js
│ │ │ ├── jshint.js
│ │ │ ├── jsonlint.js
│ │ │ ├── lint/
│ │ │ │ ├── javascript-lint.js
│ │ │ │ ├── lint.css
│ │ │ │ └── lint.js
│ │ │ └── xq.css
│ │ ├── css/
│ │ │ └── custom.css
│ │ ├── element-ui/
│ │ │ └── theme-chalk/
│ │ │ └── display.css
│ │ ├── js/
│ │ │ ├── axios-init.js
│ │ │ ├── langs.js
│ │ │ ├── model/
│ │ │ │ ├── dbinbound.js
│ │ │ │ ├── outbound.js
│ │ │ │ ├── setting.js
│ │ │ │ └── xray.js
│ │ │ └── util/
│ │ │ ├── common.js
│ │ │ ├── date-util.js
│ │ │ └── utils.js
│ │ └── vue/
│ │ ├── vue.common.dev.js
│ │ ├── vue.common.js
│ │ ├── vue.common.prod.js
│ │ ├── vue.esm.browser.js
│ │ ├── vue.esm.js
│ │ ├── vue.js
│ │ ├── vue.runtime.common.dev.js
│ │ ├── vue.runtime.common.js
│ │ ├── vue.runtime.common.prod.js
│ │ ├── vue.runtime.esm.js
│ │ ├── vue.runtime.js
│ │ └── vue.runtime.mjs
│ ├── controller/
│ │ ├── api.go
│ │ ├── base.go
│ │ ├── inbound.go
│ │ ├── index.go
│ │ ├── server.go
│ │ ├── setting.go
│ │ ├── util.go
│ │ ├── xray_setting.go
│ │ └── xui.go
│ ├── entity/
│ │ └── entity.go
│ ├── global/
│ │ ├── global.go
│ │ └── hashStorage.go
│ ├── html/
│ │ ├── common/
│ │ │ ├── head.html
│ │ │ ├── js.html
│ │ │ ├── prompt_modal.html
│ │ │ ├── qrcode_modal.html
│ │ │ └── text_modal.html
│ │ ├── login.html
│ │ └── xui/
│ │ ├── client_bulk_modal.html
│ │ ├── client_modal.html
│ │ ├── common_sider.html
│ │ ├── component/
│ │ │ ├── password.html
│ │ │ ├── persianDatepicker.html
│ │ │ ├── setting.html
│ │ │ ├── sortableTable.html
│ │ │ └── themeSwitch.html
│ │ ├── dns_modal.html
│ │ ├── fakedns_modal.html
│ │ ├── form/
│ │ │ ├── client.html
│ │ │ ├── inbound.html
│ │ │ ├── outbound.html
│ │ │ ├── protocol/
│ │ │ │ ├── dokodemo.html
│ │ │ │ ├── http.html
│ │ │ │ ├── shadowsocks.html
│ │ │ │ ├── socks.html
│ │ │ │ ├── trojan.html
│ │ │ │ ├── vless.html
│ │ │ │ ├── vmess.html
│ │ │ │ └── wireguard.html
│ │ │ ├── sniffing.html
│ │ │ ├── stream/
│ │ │ │ ├── external_proxy.html
│ │ │ │ ├── stream_grpc.html
│ │ │ │ ├── stream_http.html
│ │ │ │ ├── stream_httpupgrade.html
│ │ │ │ ├── stream_kcp.html
│ │ │ │ ├── stream_quic.html
│ │ │ │ ├── stream_settings.html
│ │ │ │ ├── stream_sockopt.html
│ │ │ │ ├── stream_splithttp.html
│ │ │ │ ├── stream_tcp.html
│ │ │ │ └── stream_ws.html
│ │ │ └── tls_settings.html
│ │ ├── inbound_client_table.html
│ │ ├── inbound_info_modal.html
│ │ ├── inbound_modal.html
│ │ ├── inbounds.html
│ │ ├── index.html
│ │ ├── navigation.html
│ │ ├── settings.html
│ │ ├── warp_modal.html
│ │ ├── xray.html
│ │ ├── xray_balancer_modal.html
│ │ ├── xray_outbound_modal.html
│ │ ├── xray_reverse_modal.html
│ │ └── xray_rule_modal.html
│ ├── job/
│ │ ├── check_client_ip_job.go
│ │ ├── check_cpu_usage.go
│ │ ├── check_hash_storage.go
│ │ ├── check_xray_running_job.go
│ │ ├── clear_logs_job.go
│ │ ├── stats_notify_job.go
│ │ └── xray_traffic_job.go
│ ├── locale/
│ │ └── locale.go
│ ├── middleware/
│ │ ├── domainValidator.go
│ │ └── redirect.go
│ ├── network/
│ │ ├── auto_https_conn.go
│ │ └── auto_https_listener.go
│ ├── service/
│ │ ├── config.json
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ ├── panel.go
│ │ ├── server.go
│ │ ├── setting.go
│ │ ├── tgbot.go
│ │ ├── user.go
│ │ ├── xray.go
│ │ └── xray_setting.go
│ ├── session/
│ │ └── session.go
│ ├── translation/
│ │ ├── translate.en_US.toml
│ │ ├── translate.es_ES.toml
│ │ ├── translate.fa_IR.toml
│ │ ├── translate.id_ID.toml
│ │ ├── translate.ru_RU.toml
│ │ ├── translate.uk_UA.toml
│ │ ├── translate.vi_VN.toml
│ │ └── translate.zh_Hans.toml
│ └── web.go
├── x-ui.service
├── x-ui.sh
└── xray/
├── api.go
├── client_traffic.go
├── config.go
├── inbound.go
├── log_writer.go
├── process.go
└── traffic.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Version (please complete the following information):**
- 3X-UI Version : [e.g. 2.3.5]
- Xray Version : [e.g. 1.8.13]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/ISSUE_TEMPLATE/question-.md
================================================
---
name: 'Question '
about: Describe this issue template's purpose here.
title: ''
labels: question
assignees: ''
---
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/docker.yml
================================================
name: Release 3X-UI for Docker
on:
push:
tags:
- "*"
workflow_dispatch:
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6, linux/386
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
================================================
FILE: .github/workflows/release.yml
================================================
name: Release 3X-UI
on:
push:
tags:
- "*"
workflow_dispatch:
jobs:
build:
strategy:
matrix:
platform:
- amd64
- arm64
- armv7
- armv6
- 386
- armv5
- s390x
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Install dependencies
run: |
sudo apt-get update
if [ "${{ matrix.platform }}" == "arm64" ]; then
sudo apt install gcc-aarch64-linux-gnu
elif [ "${{ matrix.platform }}" == "armv7" ]; then
sudo apt install gcc-arm-linux-gnueabihf
elif [ "${{ matrix.platform }}" == "armv6" ]; then
sudo apt install gcc-arm-linux-gnueabihf
elif [ "${{ matrix.platform }}" == "386" ]; then
sudo apt install gcc-i686-linux-gnu
elif [ "${{ matrix.platform }}" == "armv5" ]; then
sudo apt install gcc-arm-linux-gnueabi
elif [ "${{ matrix.platform }}" == "s390x" ]; then
sudo apt install gcc-s390x-linux-gnu
fi
- name: Build x-ui
run: |
export CGO_ENABLED=1
export GOOS=linux
export GOARCH=${{ matrix.platform }}
if [ "${{ matrix.platform }}" == "arm64" ]; then
export GOARCH=arm64
export CC=aarch64-linux-gnu-gcc
elif [ "${{ matrix.platform }}" == "armv7" ]; then
export GOARCH=arm
export GOARM=7
export CC=arm-linux-gnueabihf-gcc
elif [ "${{ matrix.platform }}" == "armv6" ]; then
export GOARCH=arm
export GOARM=6
export CC=arm-linux-gnueabihf-gcc
elif [ "${{ matrix.platform }}" == "386" ]; then
export GOARCH=386
export CC=i686-linux-gnu-gcc
elif [ "${{ matrix.platform }}" == "armv5" ]; then
export GOARCH=arm
export GOARM=5
export CC=arm-linux-gnueabi-gcc
elif [ "${{ matrix.platform }}" == "s390x" ]; then
export GOARCH=s390x
export CC=s390x-linux-gnu-gcc
fi
go build -o xui-release -v main.go
mkdir x-ui
cp xui-release x-ui/
cp x-ui.service x-ui/
cp x-ui.sh x-ui/
mv x-ui/xui-release x-ui/x-ui
mkdir x-ui/bin
cd x-ui/bin
# Download dependencies
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v1.8.16/"
if [ "${{ matrix.platform }}" == "amd64" ]; then
wget ${Xray_URL}Xray-linux-64.zip
unzip Xray-linux-64.zip
rm -f Xray-linux-64.zip
elif [ "${{ matrix.platform }}" == "arm64" ]; then
wget ${Xray_URL}Xray-linux-arm64-v8a.zip
unzip Xray-linux-arm64-v8a.zip
rm -f Xray-linux-arm64-v8a.zip
elif [ "${{ matrix.platform }}" == "armv7" ]; then
wget ${Xray_URL}Xray-linux-arm32-v7a.zip
unzip Xray-linux-arm32-v7a.zip
rm -f Xray-linux-arm32-v7a.zip
elif [ "${{ matrix.platform }}" == "armv6" ]; then
wget ${Xray_URL}Xray-linux-arm32-v6.zip
unzip Xray-linux-arm32-v6.zip
rm -f Xray-linux-arm32-v6.zip
elif [ "${{ matrix.platform }}" == "386" ]; then
wget ${Xray_URL}Xray-linux-32.zip
unzip Xray-linux-32.zip
rm -f Xray-linux-32.zip
elif [ "${{ matrix.platform }}" == "armv5" ]; then
wget ${Xray_URL}Xray-linux-arm32-v5.zip
unzip Xray-linux-arm32-v5.zip
rm -f Xray-linux-arm32-v5.zip
elif [ "${{ matrix.platform }}" == "s390x" ]; then
wget ${Xray_URL}Xray-linux-s390x.zip
unzip Xray-linux-s390x.zip
rm -f Xray-linux-s390x.zip
fi
rm -f geoip.dat geosite.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 -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 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 }}
cd ../..
- name: Package
run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
- name: Upload files to GH release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref }}
file: x-ui-linux-${{ matrix.platform }}.tar.gz
asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz
prerelease: true
================================================
FILE: .gitignore
================================================
.idea
.vscode
.cache
.sync*
*.tar.gz
*.log
access.log
error.log
tmp
main
backup/
bin/
dist/
release/
/release.sh
/x-ui
================================================
FILE: DockerEntrypoint.sh
================================================
#!/bin/sh
# Start fail2ban
fail2ban-client -x start
# Run x-ui
exec /app/x-ui
================================================
FILE: DockerInit.sh
================================================
#!/bin/sh
case $1 in
amd64)
ARCH="64"
FNAME="amd64"
;;
i386)
ARCH="32"
FNAME="i386"
;;
armv8 | arm64 | aarch64)
ARCH="arm64-v8a"
FNAME="arm64"
;;
armv7 | arm | arm32)
ARCH="arm32-v7a"
FNAME="arm32"
;;
armv6)
ARCH="arm32-v6"
FNAME="armv6"
;;
*)
ARCH="64"
FNAME="amd64"
;;
esac
mkdir -p build/bin
cd build/bin
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.16/Xray-linux-${ARCH}.zip"
unzip "Xray-linux-${ARCH}.zip"
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
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/geosite.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 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
cd ../../
================================================
FILE: Dockerfile
================================================
# ========================================================
# Stage: Builder
# ========================================================
FROM golang:1.22-alpine AS builder
WORKDIR /app
ARG TARGETARCH
RUN apk --no-cache --update add \
build-base \
gcc \
wget \
unzip
COPY . .
ENV CGO_ENABLED=1
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
RUN go build -o build/x-ui main.go
RUN ./DockerInit.sh "$TARGETARCH"
# ========================================================
# Stage: Final Image of 3x-ui
# ========================================================
FROM alpine
ENV TZ=Asia/Shanghai
WORKDIR /app
RUN apk add --no-cache --update \
ca-certificates \
tzdata \
fail2ban \
bash
COPY --from=builder /app/build/ /app/
COPY --from=builder /app/DockerEntrypoint.sh /app/
COPY --from=builder /app/x-ui.sh /usr/bin/x-ui
# Configure fail2ban
RUN rm -f /etc/fail2ban/jail.d/alpine-ssh.conf \
&& cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local \
&& sed -i "s/^\[ssh\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
&& sed -i "s/^\[sshd\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
&& sed -i "s/#allowipv6 = auto/allowipv6 = auto/g" /etc/fail2ban/fail2ban.conf
RUN chmod +x \
/app/DockerEntrypoint.sh \
/app/x-ui \
/usr/bin/x-ui
VOLUME [ "/etc/x-ui" ]
CMD [ "./x-ui" ]
ENTRYPOINT [ "/app/DockerEntrypoint.sh" ]
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.es_ES.md
================================================
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
**Un Panel Web Avanzado • Construido sobre Xray Core**
[](https://github.com/xeefei/3x-ui/releases)
[](#)
[](#)
[](#)
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
> **Descargo de responsabilidad:** Este proyecto es solo para aprendizaje personal y comunicación, por favor no lo uses con fines ilegales, por favor no lo uses en un entorno de producción
**Si este proyecto te es útil, podrías considerar darle una**:star2:
<p align="left"><a href="#"><img width="125" src="https://github.com/xeefei/3x-ui/assets/115543613/7aa895dd-048a-42e7-989b-afd41a74e2e1" alt="Image"></a></p>
- USDT (TRC20): `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
## Instalar y Actualizar
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
```
## Instalar una Versión Personalizada
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.6`:
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.6
```
## Certificado SSL
<details>
<summary>Haz clic para el Certificado SSL</summary>
### Cloudflare
El script de gestión tiene una aplicación de certificado SSL incorporada para Cloudflare. Para usar este script para colocar un certificado, necesitas lo siguiente:
- Correo electrónico registrado en Cloudflare
- Clave Global de API de Cloudflare
- El nombre de dominio se ha resuelto en el servidor actual a través de Cloudflare
**1:** Ejecuta el comando`x-ui`en la terminal, luego elige `Certificado SSL de Cloudflare`.
### Certbot
```
apt-get install certbot -y
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
certbot renew --dry-run
```
***Consejo:*** *Certbot también está integrado en el script de gestión. Puedes ejecutar el comando `x-ui` , luego elegir `Gestión de Certificados SSL`.*
</details>
## Instalación y Actualización Manual
<details>
<summary>Haz clic para más detalles de la instalación manual</summary>
#### Uso
1. Para descargar la última versión del paquete comprimido directamente en tu servidor, ejecuta el siguiente comando:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
*) XUI_ARCH="amd64" ;;
esac
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
```
2. Una vez que se haya descargado el paquete comprimido, ejecuta los siguientes comandos para instalar o actualizar x-ui:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
*) XUI_ARCH="amd64" ;;
esac
cd /root/
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
cp x-ui/x-ui.sh /usr/bin/x-ui
cp -f x-ui/x-ui.service /etc/systemd/system/
mv x-ui/ /usr/local/
systemctl daemon-reload
systemctl enable x-ui
systemctl restart x-ui
```
</details>
## Instalar con Docker
<details>
<summary>Haz clic para más detalles del Docker</summary>
#### Uso
1. Instala Docker:
```sh
bash <(curl -sSL https://get.docker.com)
```
2. Clona el Repositorio del Proyecto:
```sh
git clone https://github.com/xeefei/3x-ui.git
cd 3x-ui
```
3. Inicia el Servicio
```sh
docker compose up -d
```
O tambien
```sh
docker run -itd \
-e XRAY_VMESS_AEAD_FORCED=false \
-v $PWD/db/:/etc/x-ui/ \
-v $PWD/cert/:/root/cert/ \
--network=host \
--restart=unless-stopped \
--name 3x-ui \
ghcr.io/xeefei/3x-ui:latest
```
actualizar a la última versión
```sh
cd 3x-ui
docker compose down
docker compose pull 3x-ui
docker compose up -d
```
eliminar 3x-ui de docker
```sh
docker stop 3x-ui
docker rm 3x-ui
cd --
rm -r 3x-ui
```
</details>
## SO Recomendados
- Ubuntu 20.04+
- Debian 11+
- CentOS 8+
- Fedora 36+
- Arch Linux
- Manjaro
- Armbian
- AlmaLinux 9+
- Rockylinux 9+
- OpenSUSE Tubleweed
## Arquitecturas y Dispositivos Compatibles
<details>
<summary>Haz clic para detalles de arquitecturas y dispositivos compatibles</summary>
Nuestra plataforma ofrece compatibilidad con una amplia gama de arquitecturas y dispositivos, garantizando flexibilidad en diversos entornos informáticos. A continuación se presentan las principales arquitecturas que admitimos:
- **amd64**: Esta arquitectura predominante es la estándar para computadoras personales y servidores, y admite la mayoría de los sistemas operativos modernos sin problemas.
- **x86 / i386**: Ampliamente adoptada en computadoras de escritorio y portátiles, esta arquitectura cuenta con un amplio soporte de numerosos sistemas operativos y aplicaciones, incluidos, entre otros, Windows, macOS y sistemas Linux.
- **armv8 / arm64 / aarch64**: Diseñada para dispositivos móviles y embebidos contemporáneos, como teléfonos inteligentes y tabletas, esta arquitectura está ejemplificada por dispositivos como Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS, entre otros.
- **armv7 / arm / arm32**: Sirve como arquitectura para dispositivos móviles y embebidos más antiguos, y sigue siendo ampliamente utilizada en dispositivos como Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2, entre otros.
- **armv6 / arm / arm32**: Orientada a dispositivos embebidos muy antiguos, esta arquitectura, aunque menos común, todavía se utiliza. Dispositivos como Raspberry Pi 1, Raspberry Pi Zero/Zero W, dependen de esta arquitectura.
- **armv5 / arm / arm32**: Una arquitectura más antigua asociada principalmente con sistemas embebidos tempranos, es menos común hoy en día pero aún puede encontrarse en dispositivos heredados como versiones antiguas de Raspberry Pi y algunos teléfonos inteligentes más antiguos.
</details>
## Idiomas
- Inglés
- Farsi
- Chino
- Ruso
- Vietnamita
- Español
- Indonesio
- Ucraniano
## Características
- Monitoreo del Estado del Sistema
- Búsqueda dentro de todas las reglas de entrada y clientes
- Tema Oscuro/Claro
- Soporta multiusuario y multiprotocolo
- Soporta protocolos, incluyendo VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
- Soporta Protocolos nativos XTLS, incluyendo RPRX-Direct, Visión, REALITY
- Estadísticas de tráfico, límite de tráfico, límite de tiempo de vencimiento
- Plantillas de configuración de Xray personalizables
- Soporta acceso HTTPS al panel (dominio proporcionado por uno mismo + certificado SSL)
- Soporta la solicitud y renovación automática de certificados SSL con un clic
- Para elementos de configuración más avanzados, consulta el panel
- Corrige rutas de API (la configuración del usuario se creará con la API)
- Soporta cambiar las configuraciones por diferentes elementos proporcionados en el panel.
- Soporta exportar/importar base de datos desde el panel
## Configuraciones por Defecto
<details>
<summary>Haz clic para detalles de las configuraciones por defecto</summary>
### Información
- **Puerto:** 2053
- **Usuario y Contraseña:** Se generarán aleatoriamente si omites la modificación.
- **Ruta de la Base de Datos:**
- /etc/x-ui/x-ui.db
- **Ruta de Configuración de Xray:**
- /usr/local/x-ui/bin/config.json
- **Ruta del Panel Web sin Implementar SSL:**
- http://ip:2053/panel
- http://domain:2053/panel
- **Ruta del Panel Web con Implementación de SSL:**
- https://domain:2053/panel
</details>
## Configuración WARP
<details>
<summary>Haz clic para detalles de la configuración WARP</summary>
#### Uso
Si deseas usar enrutamiento a WARP antes de la versión v2.1.0, sigue los pasos a continuación:
**1.** Instala WARP en **Modo de Proxy SOCKS**:
```sh
bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh)
```
**2.** Si ya instalaste warp, puedes desinstalarlo usando el siguiente comando:
```sh
warp u
```
**3.** Activa la configuración que necesites en el panel
Características de Configuración:
- Bloquear Anuncios
- Enrutar Google + Netflix + Spotify + OpenAI (ChatGPT) a WARP
- Corregir error 403 de Google
</details>
## Límite de IP
<details>
<summary>Haz clic para más detalles del límite de IP</summary>
#### Uso
**Nota:** El Límite de IP no funcionará correctamente cuando se use IP Tunnel
- Para versiones hasta `v1.6.1`:
- El límite de IP está integrado en el panel.
- Para versiones `v1.7.0` y posteriores:
- Para que el Límite de IP funcione correctamente, necesitas instalar fail2ban y sus archivos requeridos siguiendo estos pasos:
1. Usa el comando `x-ui` dentro de la terminal.
2. Selecciona `Gestión de Límite de IP`.
3. Elige las opciones apropiadas según tus necesidades.
- asegúrate de tener ./access.log en tu Configuración de Xray después de la v2.1.3 tenemos una opción para ello
```sh
"log": {
"access": "./access.log",
"dnsLog": false,
"loglevel": "warning"
},
```
</details>
## Bot de Telegram
<details>
<summary>Haz clic para más detalles del bot de Telegram</summary>
#### Uso
El panel web admite tráfico diario, inicio de sesión en el panel, copia de seguridad de la base de datos, estado del sistema, información del cliente y otras notificaciones y funciones a través del Bot de Telegram. Para usar el bot, debes establecer los parámetros relacionados con el bot en el panel, que incluyen:
- Token de Telegram
- ID de chat de administrador(es)
- Hora de Notificación (en sintaxis cron)
- Notificación de Fecha de Caducidad
- Notificación de Capacidad de Tráfico
- Copia de seguridad de la base de datos
- Notificación de Carga de CPU
**Sintaxis de referencia:**
- `30 \* \* \* \* \*` - Notifica a los 30s de cada punto
- `0 \*/10 \* \* \* \*` - Notifica en el primer segundo de cada 10 minutos
- `@hourly` - Notificación por hora
- `@daily` - Notificación diaria (00:00 de la mañana)
- `@weekly` - Notificación semanal
- `@every 8h` - Notifica cada 8 horas
### Funcionalidades del Bot de Telegram
- Reporte periódico
- Notificación de inicio de sesión
- Notificación de umbral de CPU
- Umbral de Notificación para Fecha de Caducidad y Tráfico para informar con anticipación
- Soporte para menú de reporte de cliente si el nombre de usuario de Telegram del cliente se agrega a las configuraciones de usuario
- Soporte para reporte de tráfico de Telegram buscado con UUID (VMESS/VLESS) o Contraseña (TROJAN) - anónimamente
- Bot basado en menú
- Buscar cliente por correo electrónico (solo administrador)
- Ver todas las Entradas
- Ver estado del servidor
- Ver clientes agotados
- Recibir copia de seguridad bajo demanda y en informes periódicos
- Bot multilingüe
### Configuración del Bot de Telegram
- Inicia [Botfather](https://t.me/BotFather) en tu cuenta de Telegram:

- Crea un nuevo bot usando el comando /newbot: Te hará 2 preguntas, Un nombre y un nombre de usuario para tu bot. Ten en cuenta que el nombre de usuario debe terminar con la palabra "bot".

- Inicia el bot que acabas de crear. Puedes encontrar el enlace a tu bot aquí.

- Ingresa a tu panel y configura los ajustes del bot de Telegram como se muestra a continuación:

Ingresa el token de tu bot en el campo de entrada número 3.
Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas de Telegram con esta ID serán los administradores del bot. (Puedes ingresar más de uno, solo sepáralos con ,)
- ¿Cómo obtener el ID de chat de Telegram? Usa este [bot](https://t.me/useridinfobot), Inicia el bot y te dará el ID de chat del usuario de Telegram.

</details>
## Rutas de API
<details>
<summary>Haz clic para más detalles de las rutas de API</summary>
#### Uso
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
- `/panel/api/inbounds` base para las siguientes acciones:
| Método | Ruta | Acción |
| :----: | ---------------------------------- | --------------------------------------------------------- |
| `GET` | `"/list"` | Obtener todas los Entradas |
| `GET` | `"/get/:id"` | Obtener Entrada con inbound.id |
| `GET` | `"/getClientTraffics/:email"` | Obtener Tráficos del Cliente con email |
| `GET` | `"/createbackup"` | El bot de Telegram envía copia de seguridad a los admins |
| `POST` | `"/add"` | Agregar Entrada |
| `POST` | `"/del/:id"` | Eliminar Entrada |
| `POST` | `"/update/:id"` | Actualizar Entrada |
| `POST` | `"/clientIps/:email"` | Dirección IP del Cliente |
| `POST` | `"/clearClientIps/:email"` | Borrar Dirección IP del Cliente |
| `POST` | `"/addClient"` | Agregar Cliente a la Entrada |
| `POST` | `"/:id/delClient/:clientId"` | Eliminar Cliente por clientId\* |
| `POST` | `"/updateClient/:clientId"` | Actualizar Cliente por clientId\* |
| `POST` | `"/:id/resetClientTraffic/:email"` | Restablecer Tráfico del Cliente |
| `POST` | `"/resetAllTraffics"` | Restablecer tráfico de todos las Entradas |
| `POST` | `"/resetAllClientTraffics/:id"` | Restablecer tráfico de todos los clientes en una Entrada |
| `POST` | `"/delDepletedClients/:id"` | Eliminar clientes agotados de la entrada (-1: todos) |
| `POST` | `"/onlines"` | Obtener usuarios en línea (lista de correos electrónicos) |
\*- El campo `clientId` debe llenarse por:
- `client.id` para VMESS y VLESS
- `client.password` para TROJAN
- `client.email` para Shadowsocks
- [Documentación de API](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
</details>
## Variables de Entorno
<details>
<summary>Haz clic para más detalles de las variables de entorno</summary>
#### Uso
| Variable | Tipo | Predeterminado |
| -------------- | :--------------------------------------------: | :------------- |
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
| XUI_DEBUG | `boolean` | `false` |
| XUI_BIN_FOLDER | `string` | `"bin"` |
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
Ejemplo:
```sh
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
```
</details>
## Vista previa







## Un agradecimiento especial a
- [alireza0](https://github.com/alireza0/)
## Reconocimientos
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (Licencia: **GPL-3.0**): _Reglas de enrutamiento mejoradas de v2ray/xray y v2ray/xray-clients con dominios iraníes integrados y un enfoque en seguridad y bloqueo de anuncios._
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _Un dominio alojado en Vietnam y una lista de bloqueo con la máxima eficiencia para vietnamitas._
## Estrellas a lo largo del tiempo
[](https://starchart.cc/xeefei/3x-ui)
================================================
FILE: README.md
================================================
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
**------------------一个更好的面板 • 基于Xray Core构建----------------**
[](https://github.com/xeefei/3x-ui/releases)
[](#)
[](#)
[](#)
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
**如果此项目对你有用,请给一个**:star2:
- 赞助地址(USDT/TRC20):`TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
## [【3X-UI】中文交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
## [【3X-UI】详细安装流程步骤:https://xeefei.github.io/xufei/2024/05/3x-ui/](https://xeefei.github.io/xufei/2024/05/3x-ui/)
------------
## ✰〔3X-UI优化版〕跟原版3X-UI的区别?✰
### 大部分功能基于原版3X-UI进行汉化优化,主要的优化内容如下:
#### 1、最大限度地汉化了面板项目,更适合中文宝宝体质,包括:
##### ①优化在VPS中进行〔脚本安装过程〕的汉化提示,增加相应的安装中文提示,让中文用户能明白清楚自己安装到了哪个环节?在细节方面,增加了安装成功之后的〔用户设置信息〕提示,在脚本中加入〔面板登录地址〕显示,
##### ②管理后台进行了相应的〔图标和按钮〕汉化,让中文宝宝能够看得懂,
##### ③安装成功后〔自动更改〕后台管理界面和电报机器人界面默认为〔中文〕,
##### ④在管理后台中〔设置证书处〕,增加了acme方式填入路径的提示;
#### 2、优化了电报机器人响应〔按钮〕的名称和排序;
#### 3、创建了〔3X-UI〕中文交流群,各位中文宝宝可以一起讨论交流;
#### 4、管理后台中增加了〔实用导航〕页面,里面包含实用内容;
#### 5、优化了后台〔二维码〕显示模式,点击打开会更加丝滑美观;
#### 6、在创建reality协议时,更改uTLS指纹默认使用chrome;
#### 7、更新README内容添加备份&恢复操作说明,以及更多其他图文介绍;
#### 8、管理后台中增加〔端口检测〕和〔网络测速〕,点击可以跳转直达;
#### 9、增加了详细的项目〔安装配置教程〕,解决小白用户不懂配置的烦恼。
------------
## ✰如何从其他x-ui版本迁移到〔3X-UI优化版〕?✰
#### 1、若你用的是伊朗老哥的原版3X-UI,是可以直接〔覆盖安装〕的,因为〔3X-UI优化版〕是fork了原版3X-UI的项目,基于原有的功能进行优化的,大功能是没有变化的,主要是进行了脚本的〔汉化处理〕,其他诸如数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
```
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔3X-UI优化版〕。
------------
## 安装之前的准备
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
- PS:若你不想升级系统,则可以跳过此步骤。
- 若你需要更新/升级系统,Debian系统可用如下命令:
```
apt update
apt upgrade -y
apt dist-upgrade -y
apt autoclean
apt autoremove -y
```
- 查看系统当前版本:
```
cat /etc/debian_version
```
- 查看内核版本:
```
uname -r
```
- 列出所有内核:
```
dpkg --list | grep linux-image
```
- 更新完成后执行重新引导:
```
update-grub
```
- 完成以上步骤之后输入reboot重启系统
------------
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
- 以管理员身份使用默认22端口登录到SSH服务器
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
- 找到"Port"选项,并将其更改为您想要的端口号
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
- 保存文件并退出编辑器
- 重启服务器以使更改生效
------------
## 安装 & 升级
- 使用3x-ui脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
- 【全新安装】请执行以下脚本:
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
```
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
```
apt update -y&&apt install -y curl&&apt install -y socat
```
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:


- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】

------------
## 安装指定版本
若要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.9`:
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.9
```
------------
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
- 放行【面板登录端口】
- 放行出入站管理协议端口
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
- 可通过此脚本的第【22】选项去安装防火墙进行管理,如下图:

- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
------------
## 安装证书开启https方式实现域名登录访问管理面板/偷自己
#### PS:如果不需要以上功能或无域名,可以跳过这步,
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,
##### 4、记录好已经安装证书的【路径】,位置在:/root/.acme.sh/(域名)_ecc,后续需要用到,
##### 5、进入后台【面板设置】—–>【常规】中,去分别填入刚才已经记录的证书公钥、私钥路径,
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
------------
## 登录面板进行【常规】设置
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是2053,最好进入面板更改,
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,

##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
##### 4、若申请了证书须填写证书公钥/私钥路径,建议配置电报机器人方便管理,

##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用IP+端口号/路径的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功。
------------
## 创建【入站协议】和添加【客户端】,并测试上网
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,

##### 2、在选择reality协议时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
##### 3、在创建reality协议过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,

##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision-udp443,

##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,

##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
------------
## 备份与恢复/迁移数据库(以Debian系统为例)
#### 一、备份:通过配置好电报管理机器人,并去设置开启【自动备份】,每天凌晨12点会通过VPS管理机器人获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,

#### 二、搭建:在新的VPS中全新安装好3x-ui面板,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,

##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启3x-ui面板即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。

#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/.acme.sh/(域名)_ecc,路径是相同的就不用更改,
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
------------
## 安装完成后如何设置调整成【中文界面】?
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:

- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:

- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:

------------
## 用3x-ui如何实现【自己偷自己】?
- 其实很简单,只要你为面板设置了证书,
- 开启了HTTPS登录,就可以将3x-ui自身作为Web Server,
- 无需Nginx等,这里给一个示例:
- 其中目标网站(Dest)请填写面板监听端口,
- 可选域名(SNI)填写面板登录域名,
- 如果您使用其他web server(如nginx)等,
- 将目标网站改为对应监听端口也可。
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
- 配置方法如下图所示:

------------
## 〔子域名〕被墙针对特征
#### 网络表现:
##### 1、可以Ping通域名和IP地址,
##### 2、子域名无法打开3X-UI管理界面,
##### 3、什么都正常就是不能上网;
#### 问题:
##### 你的子域名被墙针对了:无法上网!
#### 解决方案:
##### 1、更换为新的子域名,
##### 2、解析新的子域名到VPS的IP,
##### 3、重新去安装新证书,
##### 4、重启3X-UI和服务器,
##### 5、重新去获取链接并测试上网。
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及3X-UI面板全部重新安装,之后就正常了!
------------
## 在自己的VPS服务器部署【订阅转换】功能
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
##### 1、进入脚本输入x-ui命令调取面板,选择第【24】选项安装订阅转换模块,如下图:

##### 2、等待安装【订阅转换】成功之后,访问地址:你的IP:18080(端口号)进行转换,

##### 3、因为在转换过程中需要调取后端API,所以请确保端口25500是打开放行的,
##### 4、在得到【转换链接】之后,只要你的VPS服务器25500端口是能ping通的,就能导入Clash/Surge等软件成功下载配置,
##### 5、此功能集成到3x-ui面板中,是为了保证安全,通过调取24选项把【订阅转换】功能部署在自己的VPS中,不会造成链接泄露。
### 【订阅转换】功能在自己的VPS中安装部署成功之后的界面如下图所示:

------------
## 如何保护自己的IP不被墙被封?
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用3x-ui多创建几个【入站】,
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
------------
## SSL 认证
<details>
<summary>点击查看 SSL 认证</summary>
### ACME
要使用 ACME 管理 SSL 证书:
1. 确保您的域名已正确解析到服务器,
2. 输入“x-ui”命令并选择“SSL 证书管理”,
3. 您将看到以下选项:
- **获取证书** ----获取SSL证书
- **吊销证书** ----吊销现有的SSL证书
- **续签证书** ----强制续签SSL证书
### Certbot
安装和使用 Certbot:
```sh
apt-get install certbot -y
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
certbot renew --dry-run
```
### Cloudflare
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
- Cloudflare 邮箱地址
- Cloudflare Global API Key
- 域名已通过 cloudflare 解析到当前服务器
**如何获取 Cloudflare全局API密钥:**
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
3. 点击“查看全局 API 密钥”(如下图所示):

4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):

使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:

</details>
------------
## 手动安装 & 升级
<details>
<summary>点击查看 手动安装 & 升级</summary>
#### 使用
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
s390x) echo 's390x' ;;
*) XUI_ARCH="amd64" ;;
esac
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
```
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
s390x) echo 's390x' ;;
*) XUI_ARCH="amd64" ;;
esac
cd /root/
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
cp x-ui/x-ui.sh /usr/bin/x-ui
cp -f x-ui/x-ui.service /etc/systemd/system/
mv x-ui/ /usr/local/
systemctl daemon-reload
systemctl enable x-ui
systemctl restart x-ui
```
</details>
------------
## 通过Docker安装
<details>
<summary>点击查看 通过Docker安装</summary>
#### 使用
1. **安装Docker**
```sh
bash <(curl -sSL https://get.docker.com)
```
2. **克隆项目仓库**
```sh
git clone https://github.com/xeefei/3x-ui.git
cd 3x-ui
```
3. **启动服务**:
```sh
docker compose up -d
```
**或**
```sh
docker run -itd \
-e XRAY_VMESS_AEAD_FORCED=false \
-v $PWD/db/:/etc/x-ui/ \
-v $PWD/cert/:/root/cert/ \
--network=host \
--restart=unless-stopped \
--name 3x-ui \
ghcr.io/xeefei/3x-ui:latest
```
4. **更新至最新版本**
```sh
cd 3x-ui
docker compose down
docker compose pull 3x-ui
docker compose up -d
```
5. **从Docker中删除3x-ui **
```sh
docker stop 3x-ui
docker rm 3x-ui
cd --
rm -r 3x-ui
```
</details>
------------
## 建议使用的操作系统
- Ubuntu 20.04+
- Debian 11+
- CentOS 8+
- Fedora 36+
- Arch Linux
- Manjaro
- Armbian
- AlmaLinux 9+
- Rocky Linux 9+
- Oracle Linux 8+
- OpenSUSE Tubleweed
------------
## 支持的架构和设备
<details>
<summary>点击查看 支持的架构和设备</summary>
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
</details>
------------
## Languages
- English(英语)
- Farsi(伊朗语)
- Chinese(中文)
- Russian(俄语)
- Vietnamese(越南语)
- Spanish(西班牙语)
- Indonesian (印度尼西亚语)
- Ukrainian(乌克兰语)
------------
## 项目特点
- 系统状态查看与监控
- 可搜索所有入站和客户端信息
- 深色/浅色主题随意切换
- 支持多用户和多协议
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
- 流量统计、流量限制、过期时间限制
- 可自定义的 Xray配置模板
- 支持HTTPS访问面板(自备域名+SSL证书)
- 支持一键式SSL证书申请和自动续签证书
- 更多高级配置项目请参考面板去进行设定
- 修复了 API 路由(用户设置将使用 API 创建)
- 支持通过面板中提供的不同项目更改配置。
- 支持从面板导出/导入数据库
------------
## 默认面板设置
<details>
<summary>点击查看 默认设置</summary>
### 默认信息
- **端口**
- 2053
- **用户名 & 密码 & 访问路径**
- 当您跳过设置时,这些信息会随机生成,
- 您也可以在安装的时候自定义访问路径。
- **数据库路径:**
- /etc/x-ui/x-ui.db
- **Xray 配置路径:**
- /usr/local/x-ui/bin/config.json
- **面板链接(无SSL):**
- http://ip:2053/访问路径/panel
- **面板链接(有SSL):**
- https://你的域名:2053/访问路径/panel
</details>
------------
## [WARP 配置](https://gitlab.com/fscarmen/warp)
<details>
<summary>点击查看 WARP 配置</summary>
#### 使用
**对于版本 `v2.1.0` 及更高版本:**
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
- **Account Type (free, plus, team):** Choose the appropriate account type.
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
- **Uninstall WARP:** Remove the WARP application.
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
```sh
warp u
```
**3.** 在面板中打开您需要的配置
配置:
- Block Ads
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
- Fix Google 403 error
</details>
------------
## IP 限制
<details>
<summary>点击查看 IP 限制</summary>
#### 使用
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
- 对于 `v1.6.1`之前的版本 :
- IP 限制 已被集成在面板中。
- 对于 `v1.7.0` 以及更新的版本:
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
1. 使用面板内置的 `x-ui` 指令
2. 选择 `IP Limit Management`.
3. 根据您的需要选择合适的选项。
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
```sh
"log": {
"access": "./access.log",
"dnsLog": false,
"loglevel": "warning"
},
```
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
</details>
------------
## Telegram 机器人
<details>
<summary>点击查看 Telegram 机器人</summary>
#### 使用
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
- 电报令牌
- 管理员聊天 ID
- 通知时间(cron 语法)
- 到期日期通知
- 流量上限通知
- 数据库备份
- CPU 负载通知
**参考:**
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
- `@hourly` - 每小时通知
- `@daily` - 每天通知 (00:00)
- `@weekly` - 每周通知
- `@every 8h` - 每8小时通知
### Telegram Bot 功能
- 定期报告
- 登录通知
- CPU 阈值通知
- 提前报告的过期时间和流量阈值
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
- 基于菜单的机器人
- 通过电子邮件搜索客户端(仅限管理员)
- 检查所有入库
- 检查服务器状态
- 检查耗尽的用户
- 根据请求和定期报告接收备份
- 多语言机器人
### 注册 Telegram bot
- 与 [Botfather](https://t.me/BotFather) 对话:

- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”

- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。

- 输入您的面板并配置 Telegram 机器人设置,如下所示:

在输入字段编号 3 中输入机器人令牌。
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。

</details>
------------
## API 路由
<details>
<summary>点击查看 API 路由</summary>
#### 使用
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
- `/panel/api/inbounds` 以下操作的基础:
| 方法 | 路径 | 操作 |
| :----: | ---------------------------------- | ------------------------------------------- |
| `GET` | `"/list"` | 获取所有入站 |
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
| `POST` | `"/add"` | 添加入站 |
| `POST` | `"/del/:id"` | 删除入站 |
| `POST` | `"/update/:id"` | 更新入站 |
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
| `POST` | `"/addClient"` | 将客户端添加到入站 |
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
\*- `clientId` 项应该使用下列数据
- `client.id` VMESS and VLESS
- `client.password` TROJAN
- `client.email` Shadowsocks
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
</details>
------------
## 环境变量
<details>
<summary>点击查看 环境变量</summary>
#### Usage
| 变量 | Type | 默认 |
| -------------- | :--------------------------------------------: | :------------ |
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
| XUI_DEBUG | `boolean` | `false` |
| XUI_BIN_FOLDER | `string` | `"bin"` |
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
例子:
```sh
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
```
</details>
------------
## 预览






------------
## 广告赞助
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
- [搬瓦工GIA高端线路,仅推荐购买GIA套餐](https://bandwagonhost.com/aff.php?aff=75015)
- [Dmit高端GIA线路](https://www.dmit.io/aff.php?aff=9326)
- [白丝云【4837线路】实惠量大管饱](https://cloudsilk.io/aff.php?aff=706)
------------
## 特别感谢
- [alireza0](https://github.com/alireza0/)
------------
## 致谢
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
------------
## Star 趋势
[](https://starchart.cc/xeefei/3x-ui)
================================================
FILE: README.zh.md
================================================
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
**一个更好的面板 • 基于Xray Core构建**
[](https://github.com/xeefei/3x-ui/releases)
[](#)
[](#)
[](#)
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
> **Disclaimer:** 此项目仅供个人学习交流,请不要用于非法目的,请不要在生产环境中使用。
**如果此项目对你有用,请给一个**:star2:
<p align="left"><a href="#"><img width="125" src="https://github.com/xeefei/3x-ui/assets/115543613/7aa895dd-048a-42e7-989b-afd41a74e2e1" alt="Image"></a></p>
- USDT (TRC20): `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
## 安装 & 升级
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
```
## 安装指定版本
若需要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.6`:
```
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.6
```
## SSL 认证
<details>
<summary>点击查看 SSL 认证</summary>
### Cloudflare
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
- Cloudflare 邮箱地址
- Cloudflare Global API Key
- 域名已通过 cloudflare 解析到当前服务器
**1:** 在终端中运行`x-ui`, 选择 `Cloudflare SSL Certificate`.
### Certbot
```
apt-get install certbot -y
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
certbot renew --dry-run
```
***Tip:*** *管理脚本具有 Certbot 。使用 `x-ui` 命令, 选择 `SSL Certificate Management`.*
</details>
## 手动安装 & 升级
<details>
<summary>点击查看 手动安装 & 升级</summary>
#### 使用
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
*) XUI_ARCH="amd64" ;;
esac
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
```
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
```sh
ARCH=$(uname -m)
case "${ARCH}" in
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
i*86 | x86) XUI_ARCH="386" ;;
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
armv7* | armv7) XUI_ARCH="armv7" ;;
armv6* | armv6) XUI_ARCH="armv6" ;;
armv5* | armv5) XUI_ARCH="armv5" ;;
*) XUI_ARCH="amd64" ;;
esac
cd /root/
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
cp x-ui/x-ui.sh /usr/bin/x-ui
cp -f x-ui/x-ui.service /etc/systemd/system/
mv x-ui/ /usr/local/
systemctl daemon-reload
systemctl enable x-ui
systemctl restart x-ui
```
</details>
## 通过Docker安装
<details>
<summary>点击查看 通过Docker安装</summary>
#### 使用
1. 安装Docker:
```sh
bash <(curl -sSL https://get.docker.com)
```
2. 克隆仓库:
```sh
git clone https://github.com/xeefei/3x-ui.git
cd 3x-ui
```
3. 运行服务:
```sh
docker compose up -d
```
或
```sh
docker run -itd \
-e XRAY_VMESS_AEAD_FORCED=false \
-v $PWD/db/:/etc/x-ui/ \
-v $PWD/cert/:/root/cert/ \
--network=host \
--restart=unless-stopped \
--name 3x-ui \
ghcr.io/xeefei/3x-ui:latest
```
更新至最新版本
```sh
cd 3x-ui
docker compose down
docker compose pull 3x-ui
docker compose up -d
```
从Docker中删除3x-ui
```sh
docker stop 3x-ui
docker rm 3x-ui
cd --
rm -r 3x-ui
```
</details>
## 建议使用的操作系统
- Ubuntu 20.04+
- Debian 11+
- CentOS 8+
- Fedora 36+
- Arch Linux
- Manjaro
- Armbian
- AlmaLinux 9+
- Rockylinux 9+
- OpenSUSE Tubleweed
## 支持的架构和设备
<details>
<summary>点击查看 支持的架构和设备</summary>
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
</details>
## Languages
- English(英语)
- Farsi(伊朗语)
- Chinese(中文)
- Russian(俄语)
- Vietnamese(越南语)
- Spanish(西班牙语)
- Indonesian (印度尼西亚语)
- Ukrainian(乌克兰语)
## Features
- 系统状态监控
- 在所有入站和客户端中搜索
- 深色/浅色主题
- 支持多用户和多协议
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
- 流量统计、流量限制、过期时间限制
- 可自定义的 Xray配置模板
- 支持HTTPS访问面板(自建域名+SSL证书)
- 支持一键式SSL证书申请和自动续费
- 更多高级配置项目请参考面板
- 修复了 API 路由(用户设置将使用 API 创建)
- 支持通过面板中提供的不同项目更改配置。
- 支持从面板导出/导入数据库
## 默认设置
<details>
<summary>点击查看 默认设置</summary>
### 信息
- **端口:** 2053
- **用户名 & 密码:** 当您跳过设置时,此项会随机生成。
- **数据库路径:**
- /etc/x-ui/x-ui.db
- **Xray 配置路径:**
- /usr/local/x-ui/bin/config.json
- **面板链接(无SSL):**
- http://ip:2053/panel
- http://domain:2053/panel
- **面板链接(有SSL):**
- https://domain:2053/panel
</details>
## WARP 配置
<details>
<summary>点击查看 WARP 配置</summary>
#### 使用
如果要在 v2.1.0 之前使用 WARP 路由,请按照以下步骤操作:
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
```sh
bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh)
```
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
```sh
warp u
```
**3.** 在面板中打开您需要的配置
配置:
- Block Ads
- Route Google + Netflix + Spotify + OpenAI (ChatGPT) to WARP
- Fix Google 403 error
</details>
## IP 限制
<details>
<summary>点击查看 IP 限制</summary>
#### 使用
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
- 适用于最高 `v1.6.1` :
- IP 限制 已被集成在面板中。
- 适用于 `v1.7.0` 以及更新的版本:
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
1. 使用面板内置的 `x-ui` 指令
2. 选择 `IP Limit Management`.
3. 根据您的需要选择合适的选项。
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
```sh
"log": {
"access": "./access.log",
"dnsLog": false,
"loglevel": "warning"
},
```
</details>
## Telegram 机器人
<details>
<summary>点击查看 Telegram 机器人</summary>
#### 使用
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
- 电报令牌
- 管理员聊天 ID
- 通知时间(cron 语法)
- 到期日期通知
- 流量上限通知
- 数据库备份
- CPU 负载通知
**参考:**
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
- `@hourly` - 每小时通知
- `@daily` - 每天通知 (00:00)
- `@weekly` - 每周通知
- `@every 8h` - 每8小时通知
### Telegram Bot 功能
- 定期报告
- 登录通知
- CPU 阈值通知
- 提前报告的过期时间和流量阈值
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
- 基于菜单的机器人
- 通过电子邮件搜索客户端(仅限管理员)
- 检查所有入库
- 检查服务器状态
- 检查耗尽的用户
- 根据请求和定期报告接收备份
- 多语言机器人
### 注册 Telegram bot
- 与 [Botfather](https://t.me/BotFather) 对话:

- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”

- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。

- 输入您的面板并配置 Telegram 机器人设置,如下所示:

在输入字段编号 3 中输入机器人令牌。
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。

</details>
## API 路由
<details>
<summary>点击查看 API 路由</summary>
#### 使用
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
- `/panel/api/inbounds` 以下操作的基础:
| 方法 | 路径 | 操作 |
| :----: | ---------------------------------- | --------------------------------- |
| `GET` | `"/list"` | 获取所有入站 |
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
| `POST` | `"/add"` | 添加入站 |
| `POST` | `"/del/:id"` | 删除入站 |
| `POST` | `"/update/:id"` | 更新入站 |
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
| `POST` | `"/addClient"` | 将客户端添加到入站 |
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
\*- `clientId` 项应该使用下列数据
- `client.id` VMESS and VLESS
- `client.password` TROJAN
- `client.email` Shadowsocks
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
</details>
## 环境变量
<details>
<summary>点击查看 环境变量</summary>
#### Usage
| 变量 | Type | 默认 |
| -------------- | :--------------------------------------------: | :------------ |
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
| XUI_DEBUG | `boolean` | `false` |
| XUI_BIN_FOLDER | `string` | `"bin"` |
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
例子:
```sh
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
```
</details>
## 预览







## 特别感谢
- [alireza0](https://github.com/alireza0/)
## 致谢
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
## Star趋势
[](https://starchart.cc/xeefei/3x-ui)
================================================
FILE: config/config.go
================================================
package config
import (
_ "embed"
"fmt"
"os"
"strings"
)
//go:embed version
var version string
//go:embed name
var name string
type LogLevel string
const (
Debug LogLevel = "debug"
Info LogLevel = "info"
Notice LogLevel = "notice"
Warn LogLevel = "warn"
Error LogLevel = "error"
)
func GetVersion() string {
return strings.TrimSpace(version)
}
func GetName() string {
return strings.TrimSpace(name)
}
func GetLogLevel() LogLevel {
if IsDebug() {
return Debug
}
logLevel := os.Getenv("XUI_LOG_LEVEL")
if logLevel == "" {
return Info
}
return LogLevel(logLevel)
}
func IsDebug() bool {
return os.Getenv("XUI_DEBUG") == "true"
}
func GetBinFolderPath() string {
binFolderPath := os.Getenv("XUI_BIN_FOLDER")
if binFolderPath == "" {
binFolderPath = "bin"
}
return binFolderPath
}
func GetDBFolderPath() string {
dbFolderPath := os.Getenv("XUI_DB_FOLDER")
if dbFolderPath == "" {
dbFolderPath = "/etc/x-ui"
}
return dbFolderPath
}
func GetDBPath() string {
return fmt.Sprintf("%s/%s.db", GetDBFolderPath(), GetName())
}
func GetLogFolder() string {
logFolderPath := os.Getenv("XUI_LOG_FOLDER")
if logFolderPath == "" {
logFolderPath = "/var/log"
}
return logFolderPath
}
================================================
FILE: config/name
================================================
x-ui
================================================
FILE: config/version
================================================
2.3.8
================================================
FILE: database/db.go
================================================
package database
import (
"bytes"
"io"
"io/fs"
"os"
"path"
"x-ui/config"
"x-ui/database/model"
"x-ui/xray"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var db *gorm.DB
var initializers = []func() error{
initUser,
initInbound,
initOutbound,
initSetting,
initInboundClientIps,
initClientTraffic,
}
func initUser() error {
err := db.AutoMigrate(&model.User{})
if err != nil {
return err
}
var count int64
err = db.Model(&model.User{}).Count(&count).Error
if err != nil {
return err
}
if count == 0 {
user := &model.User{
Username: "admin",
Password: "admin",
LoginSecret: "",
}
return db.Create(user).Error
}
return nil
}
func initInbound() error {
return db.AutoMigrate(&model.Inbound{})
}
func initOutbound() error {
return db.AutoMigrate(&model.OutboundTraffics{})
}
func initSetting() error {
return db.AutoMigrate(&model.Setting{})
}
func initInboundClientIps() error {
return db.AutoMigrate(&model.InboundClientIps{})
}
func initClientTraffic() error {
return db.AutoMigrate(&xray.ClientTraffic{})
}
func InitDB(dbPath string) error {
dir := path.Dir(dbPath)
err := os.MkdirAll(dir, fs.ModePerm)
if err != nil {
return err
}
var gormLogger logger.Interface
if config.IsDebug() {
gormLogger = logger.Default
} else {
gormLogger = logger.Discard
}
c := &gorm.Config{
Logger: gormLogger,
}
db, err = gorm.Open(sqlite.Open(dbPath), c)
if err != nil {
return err
}
for _, initialize := range initializers {
if err := initialize(); err != nil {
return err
}
}
return nil
}
func GetDB() *gorm.DB {
return db
}
func IsNotFound(err error) bool {
return err == gorm.ErrRecordNotFound
}
func IsSQLiteDB(file io.ReaderAt) (bool, error) {
signature := []byte("SQLite format 3\x00")
buf := make([]byte, len(signature))
_, err := file.ReadAt(buf, 0)
if err != nil {
return false, err
}
return bytes.Equal(buf, signature), nil
}
func Checkpoint() error {
// Update WAL
err := db.Exec("PRAGMA wal_checkpoint;").Error
if err != nil {
return err
}
return nil
}
================================================
FILE: database/model/model.go
================================================
package model
import (
"fmt"
"x-ui/util/json_util"
"x-ui/xray"
)
type Protocol string
const (
VMess Protocol = "vmess"
VLESS Protocol = "vless"
DOKODEMO Protocol = "dokodemo-door"
HTTP Protocol = "http"
Trojan Protocol = "trojan"
Shadowsocks Protocol = "shadowsocks"
Socks Protocol = "socks"
WireGuard Protocol = "wireguard"
)
type User struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Username string `json:"username"`
Password string `json:"password"`
LoginSecret string `json:"loginSecret"`
}
type Inbound struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
UserId int `json:"-"`
Up int64 `json:"up" form:"up"`
Down int64 `json:"down" form:"down"`
Total int64 `json:"total" form:"total"`
Remark string `json:"remark" form:"remark"`
Enable bool `json:"enable" form:"enable"`
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"`
// config part
Listen string `json:"listen" form:"listen"`
Port int `json:"port" form:"port"`
Protocol Protocol `json:"protocol" form:"protocol"`
Settings string `json:"settings" form:"settings"`
StreamSettings string `json:"streamSettings" form:"streamSettings"`
Tag string `json:"tag" form:"tag" gorm:"unique"`
Sniffing string `json:"sniffing" form:"sniffing"`
}
type OutboundTraffics struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
Tag string `json:"tag" form:"tag" gorm:"unique"`
Up int64 `json:"up" form:"up" gorm:"default:0"`
Down int64 `json:"down" form:"down" gorm:"default:0"`
Total int64 `json:"total" form:"total" gorm:"default:0"`
}
type InboundClientIps struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
ClientEmail string `json:"clientEmail" form:"clientEmail" gorm:"unique"`
Ips string `json:"ips" form:"ips"`
}
func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
listen := i.Listen
if listen != "" {
listen = fmt.Sprintf("\"%v\"", listen)
}
return &xray.InboundConfig{
Listen: json_util.RawMessage(listen),
Port: i.Port,
Protocol: string(i.Protocol),
Settings: json_util.RawMessage(i.Settings),
StreamSettings: json_util.RawMessage(i.StreamSettings),
Tag: i.Tag,
Sniffing: json_util.RawMessage(i.Sniffing),
}
}
type Setting struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
Key string `json:"key" form:"key"`
Value string `json:"value" form:"value"`
}
type Client struct {
ID string `json:"id"`
Password string `json:"password"`
Flow string `json:"flow"`
Email string `json:"email"`
LimitIP int `json:"limitIp"`
TotalGB int64 `json:"totalGB" form:"totalGB"`
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
Enable bool `json:"enable" form:"enable"`
TgID int64 `json:"tgId" form:"tgId"`
SubID string `json:"subId" form:"subId"`
Reset int `json:"reset" form:"reset"`
}
================================================
FILE: docker-compose.yml
================================================
---
version: "3"
services:
3x-ui:
image: ghcr.io/xeefei/3x-ui:latest
container_name: 3x-ui
hostname: yourhostname
volumes:
- $PWD/db/:/etc/x-ui/
- $PWD/cert/:/root/cert/
environment:
XRAY_VMESS_AEAD_FORCED: "false"
tty: true
network_mode: host
restart: unless-stopped
================================================
FILE: go.mod
================================================
module x-ui
go 1.22.4
require (
github.com/gin-contrib/gzip v1.0.1
github.com/gin-contrib/sessions v1.0.1
github.com/gin-gonic/gin v1.10.0
github.com/goccy/go-json v0.10.3
github.com/mymmrac/telego v0.31.0
github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml/v2 v2.2.2
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v4 v4.24.6
github.com/valyala/fasthttp v1.55.0
github.com/xtls/xray-core v1.8.17
go.uber.org/atomic v1.11.0
golang.org/x/text v0.16.0
google.golang.org/grpc v1.65.0
gorm.io/driver/sqlite v1.5.6
gorm.io/gorm v1.25.11
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/bytedance/sonic v1.11.9 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudflare/circl v1.3.9 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/fasthttp/router v1.5.2 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grbit/go-json v0.11.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/quic-go/quic-go v0.45.1 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sagernet/sing v0.4.1 // indirect
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.4.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)
================================================
FILE: go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJSGpevP+8Pk5bANX7fJacO2w04aqLiC5I=
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bytedance/sonic v1.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5zg=
github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fasthttp/router v1.5.2 h1:ckJCCdV7hWkkrMeId3WfEhz+4Gyyf6QPwxi/RHIMZ6I=
github.com/fasthttp/router v1.5.2/go.mod h1:C8EY53ozOwpONyevc/V7Gr8pqnEjwnkFFqPo1alAGs0=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
github.com/gin-contrib/gzip v1.0.1/go.mod h1:njt428fdUNRvjuJf16tZMYZ2Yl+WQB53X5wmhDwXvC4=
github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI=
github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grbit/go-json v0.11.0 h1:bAbyMdYrYl/OjYsSqLH99N2DyQ291mHy726Mx+sYrnc=
github.com/grbit/go-json v0.11.0/go.mod h1:IYpHsdybQ386+6g3VE6AXQ3uTGa5mquBme5/ZWmtzek=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed h1:036IscGBfJsFIgJQzlui7nK1Ncm0tp2ktmPj8xO4N/0=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mymmrac/telego v0.31.0 h1:vsN+JCNkh7Z9vfL/2/AHZ2xBsRk2GCMj3zydjCxkgIc=
github.com/mymmrac/telego v0.31.0/go.mod h1:MuqgVf2xXnIOWZs0prvsp3f4Yss80kCSjVEj4CRl7Ig=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
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/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
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/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA=
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sagernet/sing v0.4.1 h1:zVlpE+7k7AFoC2pv6ReqLf0PIHjihL/jsBl5k05PQFk=
github.com/sagernet/sing v0.4.1/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v4 v4.24.6 h1:9qqCSYF2pgOU+t+NgJtp7Co5+5mHF/HyKBUckySQL64=
github.com/shirou/gopsutil/v4 v4.24.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 h1:tkMT5pTye+1NlKIXETU78NXw0fyjnaNHmJyyLyzw8+U=
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3/go.mod h1:cAAsePK2e15YDAMJNyOpGYEWNe4sIghTY7gpz4cX/Ik=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
github.com/xtls/xray-core v1.8.17 h1:T+A/hkBB33P0sEGXDiuKrQMZUOYxbZ84JlsYfyRiK8w=
github.com/xtls/xray-core v1.8.17/go.mod h1:qEVGJD2suPN7EArG3r5EX6pYGV0QLiSRTlDMn0paJkc=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE=
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
================================================
FILE: install.sh
================================================
#!/bin/bash
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'
cur_dir=$(pwd)
# check root
[[ $EUID -ne 0 ]] && echo -e "${red}致命错误: ${plain} 请使用 root 权限运行此脚本\n" && exit 1
# Check OS and set release variable
if [[ -f /etc/os-release ]]; then
source /etc/os-release
release=$ID
elif [[ -f /usr/lib/os-release ]]; then
source /usr/lib/os-release
release=$ID
else
echo ""
echo -e "${red}检查服务器操作系统失败,请联系作者!${plain}" >&2
exit 1
fi
echo ""
echo -e "${green}---------->>>>>目前服务器的操作系统为: $release${plain}"
arch() {
case "$(uname -m)" in
x86_64 | x64 | amd64 ) echo 'amd64' ;;
i*86 | x86 ) echo '386' ;;
armv8* | armv8 | arm64 | aarch64 ) echo 'arm64' ;;
armv7* | armv7 | arm ) echo 'armv7' ;;
armv6* | armv6 ) echo 'armv6' ;;
armv5* | armv5 ) echo 'armv5' ;;
armv5* | armv5 ) echo 's390x' ;;
*) echo -e "${green}不支持的CPU架构! ${plain}" && rm -f install.sh && exit 1 ;;
esac
}
echo ""
echo -e "${yellow}---------->>>>>当前系统的架构为: $(arch)${plain}"
echo ""
last_version=$(curl -Ls "https://api.github.com/repos/gm-cx/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
# 获取 x-ui 版本
xui_version=$(/usr/local/x-ui/x-ui -v)
# 检查 xui_version 是否为空
if [[ -z "$xui_version" ]]; then
echo ""
echo -e "${red}------>>>当前服务器没有安装任何 x-ui 系列代理面板${plain}"
echo ""
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔3X-UI优化版〕${plain}"
else
# 检查版本号中是否包含冒号
if [[ "$xui_version" == *:* ]]; then
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}其他 x-ui 分支版本${plain}"
echo ""
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔3X-UI优化版〕${plain}"
else
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}〔3X-UI优化版〕v${xui_version}${plain}"
fi
fi
echo ""
echo -e "${yellow}---------------------->>>>>〔3X-UI优化版〕最新版为:${last_version}${plain}"
sleep 4
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
if [[ "${release}" == "arch" ]]; then
echo "您的操作系统是 ArchLinux"
elif [[ "${release}" == "manjaro" ]]; then
echo "您的操作系统是 Manjaro"
elif [[ "${release}" == "armbian" ]]; then
echo "您的操作系统是 Armbian"
elif [[ "${release}" == "alpine" ]]; then
echo "您的操作系统是 Alpine Linux"
elif [[ "${release}" == "opensuse-tumbleweed" ]]; then
echo "您的操作系统是 OpenSUSE Tumbleweed"
elif [[ "${release}" == "centos" ]]; then
if [[ ${os_version} -lt 8 ]]; then
echo -e "${red} 请使用 CentOS 8 或更高版本 ${plain}\n" && exit 1
fi
elif [[ "${release}" == "ubuntu" ]]; then
if [[ ${os_version} -lt 20 ]]; then
echo -e "${red} 请使用 Ubuntu 20 或更高版本!${plain}\n" && exit 1
fi
elif [[ "${release}" == "fedora" ]]; then
if [[ ${os_version} -lt 36 ]]; then
echo -e "${red} 请使用 Fedora 36 或更高版本!${plain}\n" && exit 1
fi
elif [[ "${release}" == "debian" ]]; then
if [[ ${os_version} -lt 11 ]]; then
echo -e "${red} 请使用 Debian 11 或更高版本 ${plain}\n" && exit 1
fi
elif [[ "${release}" == "almalinux" ]]; then
if [[ ${os_version} -lt 9 ]]; then
echo -e "${red} 请使用 AlmaLinux 9 或更高版本 ${plain}\n" && exit 1
fi
elif [[ "${release}" == "rocky" ]]; then
if [[ ${os_version} -lt 9 ]]; then
echo -e "${red} 请使用 RockyLinux 9 或更高版本 ${plain}\n" && exit 1
fi
elif [[ "${release}" == "oracle" ]]; then
if [[ ${os_version} -lt 8 ]]; then
echo -e "${red} 请使用 Oracle Linux 8 或更高版本 ${plain}\n" && exit 1
fi
else
echo -e "${red}此脚本不支持您的操作系统。${plain}\n"
echo "请确保您使用的是以下受支持的操作系统之一:"
echo "- Ubuntu 20.04+"
echo "- Debian 11+"
echo "- CentOS 8+"
echo "- Fedora 36+"
echo "- Arch Linux"
echo "- Manjaro"
echo "- Armbian"
echo "- Alpine Linux"
echo "- AlmaLinux 9+"
echo "- Rocky Linux 9+"
echo "- Oracle Linux 8+"
echo "- OpenSUSE Tumbleweed"
exit 1
fi
install_base() {
case "${release}" in
ubuntu | debian | armbian)
apt-get update && apt-get install -y -q wget curl tar tzdata
;;
centos | almalinux | rocky | oracle)
yum -y update && yum install -y -q wget curl tar tzdata
;;
fedora)
dnf -y update && dnf install -y -q wget curl tar tzdata
;;
arch | manjaro)
pacman -Syu && pacman -Syu --noconfirm wget curl tar tzdata
;;
alpine)
apk update && apk add --no-cache wget curl tar tzdata
;;
opensuse-tumbleweed)
zypper refresh && zypper -q install -y wget curl tar timezone
;;
*)
apt-get update && apt install -y -q wget curl tar tzdata
;;
esac
}
gen_random_string() {
local length="$1"
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w "$length" | head -n 1)
echo "$random_string"
}
# This function will be called when user installed x-ui out of security
config_after_install() {
echo -e "${yellow}安装/更新完成! 为了您的面板安全,建议修改面板设置 ${plain}"
echo ""
read -p "$(echo -e "${green}想继续修改吗?${red}选择“n”以保留旧设置${plain} [y/n]?--->>请输入:")" config_confirm
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
read -p "请设置您的用户名: " config_account
echo -e "${yellow}您的用户名将是: ${config_account}${plain}"
read -p "请设置您的密码: " config_password
echo -e "${yellow}您的密码将是: ${config_password}${plain}"
read -p "请设置面板端口: " config_port
echo -e "${yellow}您的面板端口号为: ${config_port}${plain}"
read -p "请设置面板登录访问路径(访问方式演示:ip:端口号/路径/): " config_webBasePath
echo -e "${yellow}您的面板访问路径为: ${config_webBasePath}${plain}"
echo -e "${yellow}正在初始化,请稍候...${plain}"
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
echo -e "${yellow}用户名和密码设置成功!${plain}"
/usr/local/x-ui/x-ui setting -port ${config_port}
echo -e "${yellow}面板端口号设置成功!${plain}"
/usr/local/x-ui/x-ui setting -webBasePath ${config_webBasePath}
echo -e "${yellow}面板登录访问路径设置成功!${plain}"
echo ""
else
echo ""
sleep 1
echo -e "${red}--------------->>>>Cancel...--------------->>>>>>>取消修改...${plain}"
echo ""
if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
local usernameTemp=$(head -c 6 /dev/urandom | base64)
local passwordTemp=$(head -c 6 /dev/urandom | base64)
local webBasePathTemp=$(gen_random_string 10)
/usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp} -webBasePath ${webBasePathTemp}
echo -e "${yellow}检测到为全新安装,出于安全考虑将生成随机登录信息:${plain}"
echo -e "###############################################"
echo -e "${green}用户名: ${usernameTemp}${plain}"
echo -e "${green}密 码: ${passwordTemp}${plain}"
echo -e "${green}访问路径: ${webBasePathTemp}${plain}"
echo -e "###############################################"
echo -e "${green}如果您忘记了登录信息,可以在安装后通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
else
echo -e "${green}此次操作属于版本升级,保留之前旧设置项,登录方式保持不变${plain}"
echo ""
echo -e "${green}如果您忘记了登录信息,您可以通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
echo ""
echo ""
fi
fi
sleep 1
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ""
/usr/local/x-ui/x-ui migrate
}
echo ""
install_x-ui() {
cd /usr/local/
if [ $# == 0 ]; then
last_version=$(curl -Ls "https://api.github.com/repos/xeefei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ ! -n "$last_version" ]]; then
echo -e "${red}获取 3x-ui 版本失败,可能是 Github API 限制,请稍后再试${plain}"
exit 1
fi
echo ""
echo -e "-----------------------------------------------------"
echo -e "${green}--------->>获取 3x-ui 最新版本:${yellow}${last_version}${plain}${green},开始安装...${plain}"
echo -e "-----------------------------------------------------"
echo ""
sleep 2
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
sleep 3
echo ""
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
echo ""
sleep 2
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/xeefei/3x-ui/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz
if [[ $? -ne 0 ]]; then
echo -e "${red}下载 3x-ui 失败, 请检查服务器是否可以连接至 GitHub? ${plain}"
exit 1
fi
else
last_version=$1
url="https://github.com/xeefei/3x-ui/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz"
echo ""
echo -e "--------------------------------------------"
echo -e "${green}---------------->>>>开始安装 3x-ui $1${plain}"
echo -e "--------------------------------------------"
echo ""
sleep 2
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
sleep 3
echo ""
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
echo ""
sleep 2
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz ${url}
if [[ $? -ne 0 ]]; then
echo -e "${red}下载 3x-ui $1 失败, 请检查此版本是否存在 ${plain}"
exit 1
fi
fi
if [[ -e /usr/local/x-ui/ ]]; then
systemctl stop x-ui
rm /usr/local/x-ui/ -rf
fi
sleep 3
echo -e "${green}------->>>>>>>>>>>检查并保存安装目录${plain}"
echo ""
tar zxvf x-ui-linux-$(arch).tar.gz
rm x-ui-linux-$(arch).tar.gz -f
cd x-ui
chmod +x x-ui
# Check the system's architecture and rename the file accordingly
if [[ $(arch) == "armv5" || $(arch) == "armv6" || $(arch) == "armv7" ]]; then
mv bin/xray-linux-$(arch) bin/xray-linux-arm
chmod +x bin/xray-linux-arm
fi
chmod +x x-ui bin/xray-linux-$(arch)
cp -f x-ui.service /etc/systemd/system/
wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/xeefei/3x-ui/main/x-ui.sh
chmod +x /usr/local/x-ui/x-ui.sh
chmod +x /usr/bin/x-ui
sleep 2
echo -e "${green}------->>>>>>>>>>>保存成功${plain}"
sleep 2
echo ""
config_after_install
systemctl daemon-reload
systemctl enable x-ui
systemctl start x-ui
systemctl stop warp-go >/dev/null 2>&1
wg-quick down wgcf >/dev/null 2>&1
ipv4=$(curl -s4m8 ip.p3terx.com -k | sed -n 1p)
ipv6=$(curl -s6m8 ip.p3terx.com -k | sed -n 1p)
systemctl start warp-go >/dev/null 2>&1
wg-quick up wgcf >/dev/null 2>&1
echo ""
echo -e "------->>>>${green}3x-ui ${last_version}${plain}<<<<安装成功,正在启动..."
sleep 1
echo ""
echo -e " ---------------------"
echo -e " |${green}3X-UI 控制菜单用法 ${plain}|${plain}"
echo -e " | ${yellow}一个更好的面板 ${plain}|${plain}"
echo -e " | ${yellow}基于Xray Core构建 ${plain}|${plain}"
echo -e "--------------------------------------------"
echo -e "x-ui - 进入管理脚本"
echo -e "x-ui start - 启动 3x-ui 面板"
echo -e "x-ui stop - 关闭 3x-ui 面板"
echo -e "x-ui restart - 重启 3x-ui 面板"
echo -e "x-ui status - 查看 3x-ui 状态"
echo -e "x-ui settings - 查看当前设置信息"
echo -e "x-ui enable - 启用 3x-ui 开机启动"
echo -e "x-ui disable - 禁用 3x-ui 开机启动"
echo -e "x-ui log - 查看 3x-ui 运行日志"
echo -e "x-ui banlog - 检查 Fail2ban 禁止日志"
echo -e "x-ui update - 更新 3x-ui 面板"
echo -e "x-ui custom - 自定义 3x-ui 版本"
echo -e "x-ui install - 安装 3x-ui 面板"
echo -e "x-ui uninstall - 卸载 3x-ui 面板"
echo -e "--------------------------------------------"
echo ""
# if [[ -n $ipv4 ]]; then
# echo -e "${yellow}面板 IPv4 访问地址为:${green}http://$ipv4:${config_port}/${config_webBasePath}${plain}"
# fi
# if [[ -n $ipv6 ]]; then
# echo -e "${yellow}面板 IPv6 访问地址为:${green}http://[$ipv6]:${config_port}/${config_webBasePath}${plain}"
# fi
# echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保${red} ${config_port} ${yellow}端口已放行${plain}"
sleep 3
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo ""
echo -e "${yellow}----->>>3X-UI面板和Xray启动成功<<<-----${plain}"
}
install_base
install_x-ui $1
echo ""
echo -e "----------------------------------------------"
sleep 4
info=$(/usr/local/x-ui/x-ui setting -show true)
echo -e "${info}${plain}"
echo ""
echo -e "若您忘记了上述面板信息,后期可通过x-ui命令进入脚本${red}输入数字〔10〕选项获取${plain}"
echo ""
echo -e "----------------------------------------------"
echo ""
sleep 2
echo -e "${green}安装/更新完成,若在使用过程中有任何问题${plain}"
echo -e "${yellow}请先描述清楚所遇问题加〔3X-UI〕中文交流群${plain}"
echo -e "${yellow}在TG群中${red} https://t.me/XUI_CN ${yellow}截图进行反馈${plain}"
echo ""
echo -e "----------------------------------------------"
echo ""
echo -e "${green}〔3X-UI〕优化版项目地址:${yellow}https://github.com/xeefei/3x-ui${plain}"
echo ""
echo -e "${green} 详细安装教程:${yellow}https://xeefei.github.io/xufei/2024/05/3x-ui/${plain}"
echo ""
echo -e "----------------------------------------------"
echo ""
================================================
FILE: logger/logger.go
================================================
package logger
import (
"fmt"
"os"
"time"
"github.com/op/go-logging"
)
var (
logger *logging.Logger
logBuffer []struct {
time string
level logging.Level
log string
}
)
func init() {
InitLogger(logging.INFO)
}
func InitLogger(level logging.Level) {
newLogger := logging.MustGetLogger("x-ui")
var err error
var backend logging.Backend
var format logging.Formatter
ppid := os.Getppid()
backend, err = logging.NewSyslogBackend("")
if err != nil {
println(err)
backend = logging.NewLogBackend(os.Stderr, "", 0)
}
if ppid > 0 && err != nil {
format = logging.MustStringFormatter(`%{time:2006/01/02 15:04:05} %{level} - %{message}`)
} else {
format = logging.MustStringFormatter(`%{level} - %{message}`)
}
backendFormatter := logging.NewBackendFormatter(backend, format)
backendLeveled := logging.AddModuleLevel(backendFormatter)
backendLeveled.SetLevel(level, "x-ui")
newLogger.SetBackend(backendLeveled)
logger = newLogger
}
func Debug(args ...interface{}) {
logger.Debug(args...)
addToBuffer("DEBUG", fmt.Sprint(args...))
}
func Debugf(format string, args ...interface{}) {
logger.Debugf(format, args...)
addToBuffer("DEBUG", fmt.Sprintf(format, args...))
}
func Info(args ...interface{}) {
logger.Info(args...)
addToBuffer("INFO", fmt.Sprint(args...))
}
func Infof(format string, args ...interface{}) {
logger.Infof(format, args...)
addToBuffer("INFO", fmt.Sprintf(format, args...))
}
func Notice(args ...interface{}) {
logger.Notice(args...)
addToBuffer("NOTICE", fmt.Sprint(args...))
}
func Noticef(format string, args ...interface{}) {
logger.Noticef(format, args...)
addToBuffer("NOTICE", fmt.Sprintf(format, args...))
}
func Warning(args ...interface{}) {
logger.Warning(args...)
addToBuffer("WARNING", fmt.Sprint(args...))
}
func Warningf(format string, args ...interface{}) {
logger.Warningf(format, args...)
addToBuffer("WARNING", fmt.Sprintf(format, args...))
}
func Error(args ...interface{}) {
logger.Error(args...)
addToBuffer("ERROR", fmt.Sprint(args...))
}
func Errorf(format string, args ...interface{}) {
logger.Errorf(format, args...)
addToBuffer("ERROR", fmt.Sprintf(format, args...))
}
func addToBuffer(level string, newLog string) {
t := time.Now()
if len(logBuffer) >= 10240 {
logBuffer = logBuffer[1:]
}
logLevel, _ := logging.LogLevel(level)
logBuffer = append(logBuffer, struct {
time string
level logging.Level
log string
}{
time: t.Format("2006/01/02 15:04:05"),
level: logLevel,
log: newLog,
})
}
func GetLogs(c int, level string) []string {
var output []string
logLevel, _ := logging.LogLevel(level)
for i := len(logBuffer) - 1; i >= 0 && len(output) <= c; i-- {
if logBuffer[i].level <= logLevel {
output = append(output, fmt.Sprintf("%s %s - %s", logBuffer[i].time, logBuffer[i].level, logBuffer[i].log))
}
}
return output
}
================================================
FILE: main.go
================================================
package main
import (
"flag"
"fmt"
"log"
"os"
"os/signal"
"os/exec"
"strings"
"syscall"
_ "unsafe"
"x-ui/config"
"x-ui/database"
"x-ui/logger"
"x-ui/sub"
"x-ui/web"
"x-ui/web/global"
"x-ui/web/service"
"github.com/op/go-logging"
)
func runWebServer() {
log.Printf("Starting %v %v", config.GetName(), config.GetVersion())
switch config.GetLogLevel() {
case config.Debug:
logger.InitLogger(logging.DEBUG)
case config.Info:
logger.InitLogger(logging.INFO)
case config.Notice:
logger.InitLogger(logging.NOTICE)
case config.Warn:
logger.InitLogger(logging.WARNING)
case config.Error:
logger.InitLogger(logging.ERROR)
default:
log.Fatalf("Unknown log level: %v", config.GetLogLevel())
}
err := database.InitDB(config.GetDBPath())
if err != nil {
log.Fatalf("Error initializing database(初始化数据库出错): %v", err)
}
var server *web.Server
server = web.NewServer()
global.SetWebServer(server)
err = server.Start()
if err != nil {
log.Fatalf("Error starting web server: %v", err)
return
}
var subServer *sub.Server
subServer = sub.NewServer()
global.SetSubServer(subServer)
err = subServer.Start()
if err != nil {
log.Fatalf("Error starting sub server: %v", err)
return
}
sigCh := make(chan os.Signal, 1)
// Trap shutdown signals
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM)
for {
sig := <-sigCh
switch sig {
case syscall.SIGHUP:
logger.Info("Received SIGHUP signal. Restarting servers...")
err := server.Stop()
if err != nil {
logger.Warning("Error stopping web server:", err)
}
err = subServer.Stop()
if err != nil {
logger.Warning("Error stopping sub server:", err)
}
server = web.NewServer()
global.SetWebServer(server)
err = server.Start()
if err != nil {
log.Fatalf("Error restarting web server: %v", err)
return
}
log.Println("Web server restarted successfully.")
subServer = sub.NewServer()
global.SetSubServer(subServer)
err = subServer.Start()
if err != nil {
log.Fatalf("Error restarting sub server: %v", err)
return
}
log.Println("Sub server restarted successfully.")
default:
server.Stop()
subServer.Stop()
log.Println("Shutting down servers.")
return
}
}
}
func resetSetting() {
err := database.InitDB(config.GetDBPath())
if err != nil {
fmt.Println("Failed to initialize database(初始化数据库失败):", err)
return
}
settingService := service.SettingService{}
err = settingService.ResetSettings()
if err != nil {
fmt.Println("reset setting failed(重置设置失败):", err)
} else {
fmt.Println("reset setting success---->>重置设置成功")
}
}
func showSetting(show bool) {
// 执行 shell 命令获取 IPv4 地址
cmdIPv4 := exec.Command("sh", "-c", "curl -s4m8 ip.p3terx.com -k | sed -n 1p")
outputIPv4, err := cmdIPv4.Output()
if err != nil {
log.Fatal(err)
}
// 执行 shell 命令获取 IPv6 地址
cmdIPv6 := exec.Command("sh", "-c", "curl -s6m8 ip.p3terx.com -k | sed -n 1p")
outputIPv6, err := cmdIPv6.Output()
if err != nil {
log.Fatal(err)
}
// 去除命令输出中的换行符
ipv4 := strings.TrimSpace(string(outputIPv4))
ipv6 := strings.TrimSpace(string(outputIPv6))
// 定义转义字符,定义不同颜色的转义字符
const (
Reset = "\033[0m"
Red = "\033[31m"
Green = "\033[32m"
Yellow = "\033[33m"
)
if show {
settingService := service.SettingService{}
port, err := settingService.GetPort()
if err != nil {
fmt.Println("get current port failed, error info(获取当前端口失败,错误信息):", err)
}
webBasePath, err := settingService.GetBasePath()
if err != nil {
fmt.Println("get webBasePath failed, error info(获取访问路径失败,错误信息):", err)
}
userService := service.UserService{}
userModel, err := userService.GetFirstUser()
if err != nil {
fmt.Println("get current user info failed, error info(获取当前用户信息失败,错误信息):", err)
}
username := userModel.Username
userpasswd := userModel.Password
if username == "" || userpasswd == "" {
fmt.Println("current username or password is empty--->>当前用户名或密码为空")
}
fmt.Println("")
fmt.Println(Yellow + "----->>>以下为面板重要信息,请自行记录保存<<<-----" + Reset)
fmt.Println(Green + "Current panel settings as follows (当前面板设置如下):" + Reset)
fmt.Println("")
fmt.Println(Green + fmt.Sprintf("username(用户名): %s", username) + Reset)
fmt.Println(Green + fmt.Sprintf("password(密 码): %s", userpasswd) + Reset)
fmt.Println(Green + fmt.Sprintf("port(端口号): %d", port) + Reset)
if webBasePath != "" {
fmt.Println(Green + fmt.Sprintf("webBasePath(访问路径): %s", webBasePath) + Reset)
} else {
fmt.Println("webBasePath is not set----->>未设置访问路径")
}
fmt.Println("")
fmt.Println("--------------------------------------------------")
// 根据条件打印带颜色的字符串
if ipv4 != "" {
fmt.Println("")
formattedIPv4 := fmt.Sprintf("%s %s%s:%d%s" + Reset,
Green+"面板 IPv4 访问地址------>>",
Yellow+"http://",
ipv4,
port,
Yellow+webBasePath + Reset)
fmt.Println(formattedIPv4)
fmt.Println("")
}
if ipv6 != "" {
fmt.Println("")
formattedIPv6 := fmt.Sprintf("%s %s[%s%s%s]:%d%s%s",
Green+"面板 IPv6 访问地址------>>", // 绿色的提示信息
Yellow+"http://", // 黄色的 http:// 部分
Yellow, // 黄色的[ 左方括号
ipv6, // IPv6 地址
Yellow, // 黄色的] 右方括号
port, // 端口号
Yellow+webBasePath, // 黄色的 Web 基础路径
Reset) // 重置颜色
fmt.Println(formattedIPv6)
fmt.Println("")
}
fmt.Println(Green + ">>>>>>>>注:若您安装了〔证书〕,请把IP换成您的域名用https方式登录" + Reset)
fmt.Println("")
fmt.Println("--------------------------------------------------")
fmt.Println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑")
fmt.Println(fmt.Sprintf("%s请确保 %s%d%s 端口已打开放行%s",Green, Red, port, Green, Reset))
fmt.Println("请自行确保此端口没有被其他程序占用")
fmt.Println(Green + "若要登录访问面板,请复制上面的地址到浏览器" + Reset)
fmt.Println("")
fmt.Println("--------------------------------------------------")
fmt.Println("")
}
}
func updateTgbotEnableSts(status bool) {
settingService := service.SettingService{}
currentTgSts, err := settingService.GetTgbotEnabled()
if err != nil {
fmt.Println(err)
return
}
logger.Infof("current enabletgbot status[%v],need update to status[%v]", currentTgSts, status)
if currentTgSts != status {
err := settingService.SetTgbotEnabled(status)
if err != nil {
fmt.Println(err)
return
} else {
logger.Infof("SetTgbotEnabled[%v] success", status)
}
}
}
func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) {
err := database.InitDB(config.GetDBPath())
if err != nil {
fmt.Println("Error initializing database(初始化数据库出错):", err)
return
}
settingService := service.SettingService{}
if tgBotToken != "" {
err := settingService.SetTgBotToken(tgBotToken)
if err != nil {
fmt.Printf("Error setting Telegram bot token(设置TG电报机器人令牌出错): %v\n", err)
return
}
logger.Info("Successfully updated Telegram bot token----->>已成功更新TG电报机器人令牌")
}
if tgBotRuntime != "" {
err := settingService.SetTgbotRuntime(tgBotRuntime)
if err != nil {
fmt.Printf("Error setting Telegram bot runtime(设置TG电报机器人通知周期出错): %v\n", err)
return
}
logger.Infof("Successfully updated Telegram bot runtime to(已成功将TG电报机器人通知周期设置为) [%s].", tgBotRuntime)
}
if tgBotChatid != "" {
err := settingService.SetTgBotChatId(tgBotChatid)
if err != nil {
fmt.Printf("Error setting Telegram bot chat ID(设置TG电报机器人管理者聊天ID出错): %v\n", err)
return
}
logger.Info("Successfully updated Telegram bot chat ID----->>已成功更新TG电报机器人管理者聊天ID")
}
}
func updateSetting(port int, username string, password string, webBasePath string) {
err := database.InitDB(config.GetDBPath())
if err != nil {
fmt.Println("Database initialization failed(初始化数据库失败):", err)
return
}
settingService := service.SettingService{}
userService := service.UserService{}
if port > 0 {
err := settingService.SetPort(port)
if err != nil {
fmt.Println("Failed to set port(设置端口失败):", err)
} else {
fmt.Printf("Port set successfully(端口设置成功): %v\n", port)
}
}
if username != "" || password != "" {
err := userService.UpdateFirstUser(username, password)
if err != nil {
fmt.Println("Failed to update username and password(更新用户名和密码失败):", err)
} else {
fmt.Println("Username and password updated successfully------>>用户名和密码更新成功")
}
}
if webBasePath != "" {
err := settingService.SetBasePath(webBasePath)
if err != nil {
fmt.Println("Failed to set base URI path(设置访问路径失败):", err)
} else {
fmt.Println("Base URI path set successfully------>>设置访问路径成功")
}
}
}
func updateCert(publicKey string, privateKey string) {
err := database.InitDB(config.GetDBPath())
if err != nil {
fmt.Println(err)
return
}
if (privateKey != "" && publicKey != "") || (privateKey == "" && publicKey == "") {
settingService := service.SettingService{}
err = settingService.SetCertFile(publicKey)
if err != nil {
fmt.Println("set certificate public key failed(设置证书公钥失败):", err)
} else {
fmt.Println("set certificate public key success--------->>设置证书公钥成功")
}
err = settingService.SetKeyFile(privateKey)
if err != nil {
fmt.Println("set certificate private key failed(设置证书私钥失败):", err)
} else {
fmt.Println("set certificate private key success--------->>设置证书私钥成功")
}
} else {
fmt.Println("both public and private key should be entered.------>>必须同时输入证书公钥和私钥")
}
}
func migrateDb() {
inboundService := service.InboundService{}
err := database.InitDB(config.GetDBPath())
if err != nil {
log.Fatal(err)
}
fmt.Println("Start migrating database...---->>开始迁移数据库...")
inboundService.MigrateDB()
fmt.Println("")
fmt.Println("Migration done!------------>>迁移完成!")
}
func removeSecret() {
userService := service.UserService{}
secretExists, err := userService.CheckSecretExistence()
if err != nil {
fmt.Println("Error checking secret existence:", err)
return
}
if !secretExists {
fmt.Println("No secret exists to remove.")
return
}
err = userService.RemoveUserSecret()
if err != nil {
fmt.Println("Error removing secret:", err)
return
}
settingService := service.SettingService{}
err = settingService.SetSecretStatus(false)
if err != nil {
fmt.Println("Error updating secret status:", err)
return
}
fmt.Println("Secret removed successfully.")
}
func main() {
if len(os.Args) < 2 {
runWebServer()
return
}
var showVersion bool
flag.BoolVar(&showVersion, "v", false, "show version")
runCmd := flag.NewFlagSet("run", flag.ExitOnError)
settingCmd := flag.NewFlagSet("setting", flag.ExitOnError)
var port int
var username string
var password string
var webBasePath string
var webCertFile string
var webKeyFile string
var tgbottoken string
var tgbotchatid string
var enabletgbot bool
var tgbotRuntime string
var reset bool
var show bool
var remove_secret bool
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
settingCmd.BoolVar(&show, "show", false, "Display current settings")
settingCmd.BoolVar(&remove_secret, "remove_secret", false, "Remove secret key")
settingCmd.IntVar(&port, "port", 0, "Set panel port number")
settingCmd.StringVar(&username, "username", "", "Set login username")
settingCmd.StringVar(&password, "password", "", "Set login password")
settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel")
settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel")
settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel")
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot")
settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "Set cron time for Telegram bot notifications")
settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "Set chat ID for Telegram bot notifications")
settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "Enable notifications via Telegram bot")
oldUsage := flag.Usage
flag.Usage = func() {
oldUsage()
fmt.Println()
fmt.Println("Commands:")
fmt.Println(" run run web panel")
fmt.Println(" migrate migrate form other/old x-ui")
fmt.Println(" setting set settings")
}
flag.Parse()
if showVersion {
fmt.Println(config.GetVersion())
return
}
switch os.Args[1] {
case "run":
err := runCmd.Parse(os.Args[2:])
if err != nil {
fmt.Println(err)
return
}
runWebServer()
case "migrate":
migrateDb()
case "setting":
err := settingCmd.Parse(os.Args[2:])
if err != nil {
fmt.Println(err)
return
}
if reset {
resetSetting()
} else {
updateSetting(port, username, password, webBasePath)
}
if show {
showSetting(show)
}
if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
}
if remove_secret {
removeSecret()
}
if enabletgbot {
updateTgbotEnableSts(enabletgbot)
}
case "cert":
err := settingCmd.Parse(os.Args[2:])
if err != nil {
fmt.Println(err)
return
}
if reset {
updateCert("", "")
} else {
updateCert(webCertFile, webKeyFile)
}
default:
fmt.Println("Invalid subcommands----->>无效命令")
fmt.Println()
runCmd.Usage()
fmt.Println()
settingCmd.Usage()
}
}
================================================
FILE: sub/default.json
================================================
{
"remarks": "",
"dns": {
"tag": "dns_out",
"queryStrategy": "UseIP",
"servers": [
{
"address": "8.8.8.8",
"skipFallback": false
}
]
},
"inbounds": [
{
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true,
"userLevel": 8
},
"sniffing": {
"destOverride": [
"http",
"tls",
"fakedns"
],
"enabled": true
},
"tag": "socks"
},
{
"port": 10809,
"protocol": "http",
"settings": {
"userLevel": 8
},
"tag": "http"
}
],
"log": {
"loglevel": "warning"
},
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "http"
}
}
}
],
"policy": {
"levels": {
"8": {
"connIdle": 300,
"downlinkOnly": 1,
"handshake": 4,
"uplinkOnly": 1
}
},
"system": {
"statsOutboundUplink": true,
"statsOutboundDownlink": true
}
},
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
},
"stats": {}
}
================================================
FILE: sub/sub.go
================================================
package sub
import (
"context"
"crypto/tls"
"io"
"net"
"net/http"
"strconv"
"x-ui/config"
"x-ui/logger"
"x-ui/util/common"
"x-ui/web/middleware"
"x-ui/web/network"
"x-ui/web/service"
"github.com/gin-gonic/gin"
)
type Server struct {
httpServer *http.Server
listener net.Listener
sub *SUBController
settingService service.SettingService
ctx context.Context
cancel context.CancelFunc
}
func NewServer() *Server {
ctx, cancel := context.WithCancel(context.Background())
return &Server{
ctx: ctx,
cancel: cancel,
}
}
func (s *Server) initRouter() (*gin.Engine, error) {
if config.IsDebug() {
gin.SetMode(gin.DebugMode)
} else {
gin.DefaultWriter = io.Discard
gin.DefaultErrorWriter = io.Discard
gin.SetMode(gin.ReleaseMode)
}
engine := gin.Default()
subDomain, err := s.settingService.GetSubDomain()
if err != nil {
return nil, err
}
if subDomain != "" {
engine.Use(middleware.DomainValidatorMiddleware(subDomain))
}
LinksPath, err := s.settingService.GetSubPath()
if err != nil {
return nil, err
}
JsonPath, err := s.settingService.GetSubJsonPath()
if err != nil {
return nil, err
}
Encrypt, err := s.settingService.GetSubEncrypt()
if err != nil {
return nil, err
}
ShowInfo, err := s.settingService.GetSubShowInfo()
if err != nil {
return nil, err
}
RemarkModel, err := s.settingService.GetRemarkModel()
if err != nil {
RemarkModel = "-ieo"
}
SubUpdates, err := s.settingService.GetSubUpdates()
if err != nil {
SubUpdates = "10"
}
SubJsonFragment, err := s.settingService.GetSubJsonFragment()
if err != nil {
SubJsonFragment = ""
}
SubJsonMux, err := s.settingService.GetSubJsonMux()
if err != nil {
SubJsonMux = ""
}
SubJsonRules, err := s.settingService.GetSubJsonRules()
if err != nil {
SubJsonRules = ""
}
g := engine.Group("/")
s.sub = NewSUBController(
g, LinksPath, JsonPath, Encrypt, ShowInfo, RemarkModel, SubUpdates,
SubJsonFragment, SubJsonMux, SubJsonRules)
return engine, nil
}
func (s *Server) Start() (err error) {
// This is an anonymous function, no function name
defer func() {
if err != nil {
s.Stop()
}
}()
subEnable, err := s.settingService.GetSubEnable()
if err != nil {
return err
}
if !subEnable {
return nil
}
engine, err := s.initRouter()
if err != nil {
return err
}
certFile, err := s.settingService.GetSubCertFile()
if err != nil {
return err
}
keyFile, err := s.settingService.GetSubKeyFile()
if err != nil {
return err
}
listen, err := s.settingService.GetSubListen()
if err != nil {
return err
}
port, err := s.settingService.GetSubPort()
if err != nil {
return err
}
listenAddr := net.JoinHostPort(listen, strconv.Itoa(port))
listener, err := net.Listen("tcp", listenAddr)
if err != nil {
return err
}
if certFile != "" || keyFile != "" {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err == nil {
c := &tls.Config{
Certificates: []tls.Certificate{cert},
}
listener = network.NewAutoHttpsListener(listener)
listener = tls.NewListener(listener, c)
logger.Info("Sub server running HTTPS on", listener.Addr())
} else {
logger.Error("Error loading certificates:", err)
logger.Info("Sub server running HTTP on", listener.Addr())
}
} else {
logger.Info("Sub server running HTTP on", listener.Addr())
}
s.listener = listener
s.httpServer = &http.Server{
Handler: engine,
}
go func() {
s.httpServer.Serve(listener)
}()
return nil
}
func (s *Server) Stop() error {
s.cancel()
var err1 error
var err2 error
if s.httpServer != nil {
err1 = s.httpServer.Shutdown(s.ctx)
}
if s.listener != nil {
err2 = s.listener.Close()
}
return common.Combine(err1, err2)
}
func (s *Server) GetCtx() context.Context {
return s.ctx
}
================================================
FILE: sub/subController.go
================================================
package sub
import (
"encoding/base64"
"net"
"github.com/gin-gonic/gin"
)
type SUBController struct {
subPath string
subJsonPath string
subEncrypt bool
updateInterval string
subService *SubService
subJsonService *SubJsonService
}
func NewSUBController(
g *gin.RouterGroup,
subPath string,
jsonPath string,
encrypt bool,
showInfo bool,
rModel string,
update string,
jsonFragment string,
jsonMux string,
jsonRules string,
) *SUBController {
sub := NewSubService(showInfo, rModel)
a := &SUBController{
subPath: subPath,
subJsonPath: jsonPath,
subEncrypt: encrypt,
updateInterval: update,
subService: sub,
subJsonService: NewSubJsonService(jsonFragment, jsonMux, jsonRules, sub),
}
a.initRouter(g)
return a
}
func (a *SUBController) initRouter(g *gin.RouterGroup) {
gLink := g.Group(a.subPath)
gJson := g.Group(a.subJsonPath)
gLink.GET(":subid", a.subs)
gJson.GET(":subid", a.subJsons)
}
func (a *SUBController) subs(c *gin.Context) {
subId := c.Param("subid")
host := c.GetHeader("X-Forwarded-Host")
if host == "" {
host = c.GetHeader("X-Real-IP")
}
if host == "" {
var err error
host, _, err = net.SplitHostPort(c.Request.Host)
if err != nil {
host = c.Request.Host
}
}
subs, header, err := a.subService.GetSubs(subId, host)
if err != nil || len(subs) == 0 {
c.String(400, "Error!")
} else {
result := ""
for _, sub := range subs {
result += sub + "\n"
}
// Add headers
c.Writer.Header().Set("Subscription-Userinfo", header)
c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval)
c.Writer.Header().Set("Profile-Title", subId)
if a.subEncrypt {
c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
} else {
c.String(200, result)
}
}
}
func (a *SUBController) subJsons(c *gin.Context) {
subId := c.Param("subid")
host := c.GetHeader("X-Forwarded-Host")
if host == "" {
host = c.GetHeader("X-Real-IP")
}
if host == "" {
var err error
host, _, err = net.SplitHostPort(c.Request.Host)
if err != nil {
host = c.Request.Host
}
}
jsonSub, header, err := a.subJsonService.GetJson(subId, host)
if err != nil || len(jsonSub) == 0 {
c.String(400, "Error!")
} else {
// Add headers
c.Writer.Header().Set("Subscription-Userinfo", header)
c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval)
c.Writer.Header().Set("Profile-Title", subId)
c.String(200, jsonSub)
}
}
================================================
FILE: sub/subJsonService.go
================================================
package sub
import (
_ "embed"
"encoding/json"
"fmt"
"strings"
"x-ui/database/model"
"x-ui/logger"
"x-ui/util/json_util"
"x-ui/util/random"
"x-ui/web/service"
"x-ui/xray"
)
//go:embed default.json
var defaultJson string
type SubJsonService struct {
configJson map[string]interface{}
defaultOutbounds []json_util.RawMessage
fragment string
mux string
inboundService service.InboundService
SubService *SubService
}
func NewSubJsonService(fragment string, mux string, rules string, subService *SubService) *SubJsonService {
var configJson map[string]interface{}
var defaultOutbounds []json_util.RawMessage
json.Unmarshal([]byte(defaultJson), &configJson)
if outboundSlices, ok := configJson["outbounds"].([]interface{}); ok {
for _, defaultOutbound := range outboundSlices {
jsonBytes, _ := json.Marshal(defaultOutbound)
defaultOutbounds = append(defaultOutbounds, jsonBytes)
}
}
if rules != "" {
var newRules []interface{}
routing, _ := configJson["routing"].(map[string]interface{})
defaultRules, _ := routing["rules"].([]interface{})
json.Unmarshal([]byte(rules), &newRules)
defaultRules = append(newRules, defaultRules...)
routing["rules"] = defaultRules
configJson["routing"] = routing
}
if fragment != "" {
defaultOutbounds = append(defaultOutbounds, json_util.RawMessage(fragment))
}
return &SubJsonService{
configJson: configJson,
defaultOutbounds: defaultOutbounds,
fragment: fragment,
mux: mux,
SubService: subService,
}
}
func (s *SubJsonService) GetJson(subId string, host string) (string, string, error) {
inbounds, err := s.SubService.getInboundsBySubId(subId)
if err != nil || len(inbounds) == 0 {
return "", "", err
}
var header string
var traffic xray.ClientTraffic
var clientTraffics []xray.ClientTraffic
var configArray []json_util.RawMessage
// Prepare Inbounds
for _, inbound := range inbounds {
clients, err := s.inboundService.GetClients(inbound)
if err != nil {
logger.Error("SubJsonService - GetClients: Unable to get clients from inbound")
}
if clients == nil {
continue
}
if len(inbound.Listen) > 0 && inbound.Listen[0] == '@' {
listen, port, streamSettings, err := s.SubService.getFallbackMaster(inbound.Listen, inbound.StreamSettings)
if err == nil {
inbound.Listen = listen
inbound.Port = port
inbound.StreamSettings = streamSettings
}
}
for _, client := range clients {
if client.Enable && client.SubID == subId {
clientTraffics = append(clientTraffics, s.SubService.getClientTraffics(inbound.ClientStats, client.Email))
newConfigs := s.getConfig(inbound, client, host)
configArray = append(configArray, newConfigs...)
}
}
}
if len(configArray) == 0 {
return "", "", nil
}
// Prepare statistics
for index, clientTraffic := range clientTraffics {
if index == 0 {
traffic.Up = clientTraffic.Up
traffic.Down = clientTraffic.Down
traffic.Total = clientTraffic.Total
if clientTraffic.ExpiryTime > 0 {
traffic.ExpiryTime = clientTraffic.ExpiryTime
}
} else {
traffic.Up += clientTraffic.Up
traffic.Down += clientTraffic.Down
if traffic.Total == 0 || clientTraffic.Total == 0 {
traffic.Total = 0
} else {
traffic.Total += clientTraffic.Total
}
if clientTraffic.ExpiryTime != traffic.ExpiryTime {
traffic.ExpiryTime = 0
}
}
}
// Combile outbounds
var finalJson []byte
if len(configArray) == 1 {
finalJson, _ = json.MarshalIndent(configArray[0], "", " ")
} else {
finalJson, _ = json.MarshalIndent(configArray, "", " ")
}
header = fmt.Sprintf("upload=%d; download=%d; total=%d; expire=%d", traffic.Up, traffic.Down, traffic.Total, traffic.ExpiryTime/1000)
return string(finalJson), header, nil
}
func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client, host string) []json_util.RawMessage {
var newJsonArray []json_util.RawMessage
stream := s.streamData(inbound.StreamSettings)
externalProxies, ok := stream["externalProxy"].([]interface{})
if !ok || len(externalProxies) == 0 {
externalProxies = []interface{}{
map[string]interface{}{
"forceTls": "same",
"dest": host,
"port": float64(inbound.Port),
"remark": "",
},
}
}
delete(stream, "externalProxy")
for _, ep := range externalProxies {
extPrxy := ep.(map[string]interface{})
inbound.Listen = extPrxy["dest"].(string)
inbound.Port = int(extPrxy["port"].(float64))
newStream := stream
switch extPrxy["forceTls"].(string) {
case "tls":
if newStream["security"] != "tls" {
newStream["security"] = "tls"
newStream["tslSettings"] = map[string]interface{}{}
}
case "none":
if newStream["security"] != "none" {
newStream["security"] = "none"
delete(newStream, "tslSettings")
}
}
streamSettings, _ := json.MarshalIndent(newStream, "", " ")
var newOutbounds []json_util.RawMessage
switch inbound.Protocol {
case "vmess", "vless":
newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client))
case "trojan", "shadowsocks":
newOutbounds = append(newOutbounds, s.genServer(inbound, streamSettings, client))
}
newOutbounds = append(newOutbounds, s.defaultOutbounds...)
newConfigJson := make(map[string]interface{})
for key, value := range s.configJson {
newConfigJson[key] = value
}
newConfigJson["outbounds"] = newOutbounds
newConfigJson["remarks"] = s.SubService.genRemark(inbound, client.Email, extPrxy["remark"].(string))
newConfig, _ := json.MarshalIndent(newConfigJson, "", " ")
newJsonArray = append(newJsonArray, newConfig)
}
return newJsonArray
}
func (s *SubJsonService) streamData(stream string) map[string]interface{} {
var streamSettings map[string]interface{}
json.Unmarshal([]byte(stream), &streamSettings)
security, _ := streamSettings["security"].(string)
if security == "tls" {
streamSettings["tlsSettings"] = s.tlsData(streamSettings["tlsSettings"].(map[string]interface{}))
} else if security == "reality" {
streamSettings["realitySettings"] = s.realityData(streamSettings["realitySettings"].(map[string]interface{}))
}
delete(streamSettings, "sockopt")
if s.fragment != "" {
streamSettings["sockopt"] = json_util.RawMessage(`{"dialerProxy": "fragment", "tcpKeepAliveIdle": 100, "tcpMptcp": true, "tcpNoDelay": true}`)
}
// remove proxy protocol
network, _ := streamSettings["network"].(string)
switch network {
case "tcp":
streamSettings["tcpSettings"] = s.removeAcceptProxy(streamSettings["tcpSettings"])
case "ws":
streamSettings["wsSettings"] = s.removeAcceptProxy(streamSettings["wsSettings"])
case "httpupgrade":
streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"])
}
return streamSettings
}
func (s *SubJsonService) removeAcceptProxy(setting interface{}) map[string]interface{} {
netSettings, ok := setting.(map[string]interface{})
if ok {
delete(netSettings, "acceptProxyProtocol")
}
return netSettings
}
func (s *SubJsonService) tlsData(tData map[string]interface{}) map[string]interface{} {
tlsData := make(map[string]interface{}, 1)
tlsClientSettings, _ := tData["settings"].(map[string]interface{})
tlsData["serverName"] = tData["serverName"]
tlsData["alpn"] = tData["alpn"]
if allowInsecure, ok := tlsClientSettings["allowInsecure"].(bool); ok {
tlsData["allowInsecure"] = allowInsecure
}
if fingerprint, ok := tlsClientSettings["fingerprint"].(string); ok {
tlsData["fingerprint"] = fingerprint
}
return tlsData
}
func (s *SubJsonService) realityData(rData map[string]interface{}) map[string]interface{} {
rltyData := make(map[string]interface{}, 1)
rltyClientSettings, _ := rData["settings"].(map[string]interface{})
rltyData["show"] = false
rltyData["publicKey"] = rltyClientSettings["publicKey"]
rltyData["fingerprint"] = rltyClientSettings["fingerprint"]
// Set random data
rltyData["spiderX"] = "/" + random.Seq(15)
shortIds, ok := rData["shortIds"].([]interface{})
if ok && len(shortIds) > 0 {
rltyData["shortId"] = shortIds[random.Num(len(shortIds))].(string)
} else {
rltyData["shortId"] = ""
}
serverNames, ok := rData["serverNames"].([]interface{})
if ok && len(serverNames) > 0 {
rltyData["serverName"] = serverNames[random.Num(len(serverNames))].(string)
} else {
rltyData["serverName"] = ""
}
return rltyData
}
func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage {
outbound := Outbound{}
usersData := make([]UserVnext, 1)
usersData[0].ID = client.ID
usersData[0].Level = 8
if inbound.Protocol == model.VLESS {
usersData[0].Flow = client.Flow
usersData[0].Encryption = "none"
}
vnextData := make([]VnextSetting, 1)
vnextData[0] = VnextSetting{
Address: inbound.Listen,
Port: inbound.Port,
Users: usersData,
}
outbound.Protocol = string(inbound.Protocol)
outbound.Tag = "proxy"
if s.mux != "" {
outbound.Mux = json_util.RawMessage(s.mux)
}
outbound.StreamSettings = streamSettings
outbound.Settings = OutboundSettings{
Vnext: vnextData,
}
result, _ := json.MarshalIndent(outbound, "", " ")
return result
}
func (s *SubJsonService) genServer(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage {
outbound := Outbound{}
serverData := make([]ServerSetting, 1)
serverData[0] = ServerSetting{
Address: inbound.Listen,
Port: inbound.Port,
Level: 8,
Password: client.Password,
}
if inbound.Protocol == model.Shadowsocks {
var inboundSettings map[string]interface{}
json.Unmarshal([]byte(inbound.Settings), &inboundSettings)
method, _ := inboundSettings["method"].(string)
serverData[0].Method = method
// server password in multi-user 2022 protocols
if strings.HasPrefix(method, "2022") {
if serverPassword, ok := inboundSettings["password"].(string); ok {
serverData[0].Password = fmt.Sprintf("%s:%s", serverPassword, client.Password)
}
}
}
outbound.Protocol = string(inbound.Protocol)
outbound.Tag = "proxy"
if s.mux != "" {
outbound.Mux = json_util.RawMessage(s.mux)
}
outbound.StreamSettings = streamSettings
outbound.Settings = OutboundSettings{
Servers: serverData,
}
result, _ := json.MarshalIndent(outbound, "", " ")
return result
}
type Outbound struct {
Protocol string `json:"protocol"`
Tag string `json:"tag"`
StreamSettings json_util.RawMessage `json:"streamSettings"`
Mux json_util.RawMessage `json:"mux,omitempty"`
ProxySettings map[string]interface{} `json:"proxySettings,omitempty"`
Settings OutboundSettings `json:"settings,omitempty"`
}
type OutboundSettings struct {
Vnext []VnextSetting `json:"vnext,omitempty"`
Servers []ServerSetting `json:"servers,omitempty"`
}
type VnextSetting struct {
Address string `json:"address"`
Port int `json:"port"`
Users []UserVnext `json:"users"`
}
type UserVnext struct {
Encryption string `json:"encryption,omitempty"`
Flow string `json:"flow,omitempty"`
ID string `json:"id"`
Level int `json:"level"`
}
type ServerSetting struct {
Password string `json:"password"`
Level int `json:"level"`
Address string `json:"address"`
Port int `json:"port"`
Flow string `json:"flow,omitempty"`
Method string `json:"method,omitempty"`
}
================================================
FILE: sub/subService.go
================================================
package sub
import (
"encoding/base64"
"fmt"
"net/url"
"strings"
"time"
"x-ui/database"
"x-ui/database/model"
"x-ui/logger"
"x-ui/util/common"
"x-ui/util/random"
"x-ui/web/service"
"x-ui/xray"
"github.com/goccy/go-json"
)
type SubService struct {
address string
showInfo bool
remarkModel string
datepicker string
inboundService service.InboundService
settingService service.SettingService
}
func NewSubService(showInfo bool, remarkModel string) *SubService {
return &SubService{
showInfo: showInfo,
remarkModel: remarkModel,
}
}
func (s *SubService) GetSubs(subId string, host string) ([]string, string, error) {
s.address = host
var result []string
var header string
var traffic xray.ClientTraffic
var clientTraffics []xray.ClientTraffic
inbounds, err := s.getInboundsBySubId(subId)
if err != nil {
return nil, "", err
}
if len(inbounds) == 0 {
return nil, "", common.NewError("No inbounds found with ", subId)
}
s.datepicker, err = s.settingService.GetDatepicker()
if err != nil {
s.datepicker = "gregorian"
}
for _, inbound := range inbounds {
clients, err := s.inboundService.GetClients(inbound)
if err != nil {
logger.Error("SubService - GetClients: Unable to get clients from inbound")
}
if clients == nil {
continue
}
if len(inbound.Listen) > 0 && inbound.Listen[0] == '@' {
listen, port, streamSettings, err := s.getFallbackMaster(inbound.Listen, inbound.StreamSettings)
if err == nil {
inbound.Listen = listen
inbound.Port = port
inbound.StreamSettings = streamSettings
}
}
for _, client := range clients {
if client.Enable && client.SubID == subId {
link := s.getLink(inbound, client.Email)
result = append(result, link)
clientTraffics = append(clientTraffics, s.getClientTraffics(inbound.ClientStats, client.Email))
}
}
}
// Prepare statistics
for index, clientTraffic := range clientTraffics {
if index == 0 {
traffic.Up = clientTraffic.Up
traffic.Down = clientTraffic.Down
traffic.Total = clientTraffic.Total
if clientTraffic.ExpiryTime > 0 {
traffic.ExpiryTime = clientTraffic.ExpiryTime
}
} else {
traffic.Up += clientTraffic.Up
traffic.Down += clientTraffic.Down
if traffic.Total == 0 || clientTraffic.Total == 0 {
traffic.Total = 0
} else {
traffic.Total += clientTraffic.Total
}
if clientTraffic.ExpiryTime != traffic.ExpiryTime {
traffic.ExpiryTime = 0
}
}
}
header = fmt.Sprintf("upload=%d; download=%d; total=%d; expire=%d", traffic.Up, traffic.Down, traffic.Total, traffic.ExpiryTime/1000)
return result, header, nil
}
func (s *SubService) getInb
gitextract_e5aa8s52/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── question-.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── docker.yml
│ └── release.yml
├── .gitignore
├── DockerEntrypoint.sh
├── DockerInit.sh
├── Dockerfile
├── LICENSE
├── README.es_ES.md
├── README.md
├── README.zh.md
├── config/
│ ├── config.go
│ ├── name
│ └── version
├── database/
│ ├── db.go
│ └── model/
│ └── model.go
├── docker-compose.yml
├── go.mod
├── go.sum
├── install.sh
├── logger/
│ └── logger.go
├── main.go
├── sub/
│ ├── default.json
│ ├── sub.go
│ ├── subController.go
│ ├── subJsonService.go
│ └── subService.go
├── util/
│ ├── common/
│ │ ├── err.go
│ │ ├── format.go
│ │ └── multi_error.go
│ ├── json_util/
│ │ └── json.go
│ ├── random/
│ │ └── random.go
│ ├── reflect_util/
│ │ └── reflect.go
│ └── sys/
│ ├── psutil.go
│ ├── sys_darwin.go
│ ├── sys_linux.go
│ └── sys_windows.go
├── web/
│ ├── assets/
│ │ ├── ant-design-vue/
│ │ │ └── antd.less
│ │ ├── codemirror/
│ │ │ ├── codemirror.css
│ │ │ ├── codemirror.js
│ │ │ ├── fold/
│ │ │ │ ├── brace-fold.js
│ │ │ │ ├── foldcode.js
│ │ │ │ ├── foldgutter.css
│ │ │ │ └── foldgutter.js
│ │ │ ├── hint/
│ │ │ │ └── javascript-hint.js
│ │ │ ├── javascript.js
│ │ │ ├── jshint.js
│ │ │ ├── jsonlint.js
│ │ │ ├── lint/
│ │ │ │ ├── javascript-lint.js
│ │ │ │ ├── lint.css
│ │ │ │ └── lint.js
│ │ │ └── xq.css
│ │ ├── css/
│ │ │ └── custom.css
│ │ ├── element-ui/
│ │ │ └── theme-chalk/
│ │ │ └── display.css
│ │ ├── js/
│ │ │ ├── axios-init.js
│ │ │ ├── langs.js
│ │ │ ├── model/
│ │ │ │ ├── dbinbound.js
│ │ │ │ ├── outbound.js
│ │ │ │ ├── setting.js
│ │ │ │ └── xray.js
│ │ │ └── util/
│ │ │ ├── common.js
│ │ │ ├── date-util.js
│ │ │ └── utils.js
│ │ └── vue/
│ │ ├── vue.common.dev.js
│ │ ├── vue.common.js
│ │ ├── vue.common.prod.js
│ │ ├── vue.esm.browser.js
│ │ ├── vue.esm.js
│ │ ├── vue.js
│ │ ├── vue.runtime.common.dev.js
│ │ ├── vue.runtime.common.js
│ │ ├── vue.runtime.common.prod.js
│ │ ├── vue.runtime.esm.js
│ │ ├── vue.runtime.js
│ │ └── vue.runtime.mjs
│ ├── controller/
│ │ ├── api.go
│ │ ├── base.go
│ │ ├── inbound.go
│ │ ├── index.go
│ │ ├── server.go
│ │ ├── setting.go
│ │ ├── util.go
│ │ ├── xray_setting.go
│ │ └── xui.go
│ ├── entity/
│ │ └── entity.go
│ ├── global/
│ │ ├── global.go
│ │ └── hashStorage.go
│ ├── html/
│ │ ├── common/
│ │ │ ├── head.html
│ │ │ ├── js.html
│ │ │ ├── prompt_modal.html
│ │ │ ├── qrcode_modal.html
│ │ │ └── text_modal.html
│ │ ├── login.html
│ │ └── xui/
│ │ ├── client_bulk_modal.html
│ │ ├── client_modal.html
│ │ ├── common_sider.html
│ │ ├── component/
│ │ │ ├── password.html
│ │ │ ├── persianDatepicker.html
│ │ │ ├── setting.html
│ │ │ ├── sortableTable.html
│ │ │ └── themeSwitch.html
│ │ ├── dns_modal.html
│ │ ├── fakedns_modal.html
│ │ ├── form/
│ │ │ ├── client.html
│ │ │ ├── inbound.html
│ │ │ ├── outbound.html
│ │ │ ├── protocol/
│ │ │ │ ├── dokodemo.html
│ │ │ │ ├── http.html
│ │ │ │ ├── shadowsocks.html
│ │ │ │ ├── socks.html
│ │ │ │ ├── trojan.html
│ │ │ │ ├── vless.html
│ │ │ │ ├── vmess.html
│ │ │ │ └── wireguard.html
│ │ │ ├── sniffing.html
│ │ │ ├── stream/
│ │ │ │ ├── external_proxy.html
│ │ │ │ ├── stream_grpc.html
│ │ │ │ ├── stream_http.html
│ │ │ │ ├── stream_httpupgrade.html
│ │ │ │ ├── stream_kcp.html
│ │ │ │ ├── stream_quic.html
│ │ │ │ ├── stream_settings.html
│ │ │ │ ├── stream_sockopt.html
│ │ │ │ ├── stream_splithttp.html
│ │ │ │ ├── stream_tcp.html
│ │ │ │ └── stream_ws.html
│ │ │ └── tls_settings.html
│ │ ├── inbound_client_table.html
│ │ ├── inbound_info_modal.html
│ │ ├── inbound_modal.html
│ │ ├── inbounds.html
│ │ ├── index.html
│ │ ├── navigation.html
│ │ ├── settings.html
│ │ ├── warp_modal.html
│ │ ├── xray.html
│ │ ├── xray_balancer_modal.html
│ │ ├── xray_outbound_modal.html
│ │ ├── xray_reverse_modal.html
│ │ └── xray_rule_modal.html
│ ├── job/
│ │ ├── check_client_ip_job.go
│ │ ├── check_cpu_usage.go
│ │ ├── check_hash_storage.go
│ │ ├── check_xray_running_job.go
│ │ ├── clear_logs_job.go
│ │ ├── stats_notify_job.go
│ │ └── xray_traffic_job.go
│ ├── locale/
│ │ └── locale.go
│ ├── middleware/
│ │ ├── domainValidator.go
│ │ └── redirect.go
│ ├── network/
│ │ ├── auto_https_conn.go
│ │ └── auto_https_listener.go
│ ├── service/
│ │ ├── config.json
│ │ ├── inbound.go
│ │ ├── outbound.go
│ │ ├── panel.go
│ │ ├── server.go
│ │ ├── setting.go
│ │ ├── tgbot.go
│ │ ├── user.go
│ │ ├── xray.go
│ │ └── xray_setting.go
│ ├── session/
│ │ └── session.go
│ ├── translation/
│ │ ├── translate.en_US.toml
│ │ ├── translate.es_ES.toml
│ │ ├── translate.fa_IR.toml
│ │ ├── translate.id_ID.toml
│ │ ├── translate.ru_RU.toml
│ │ ├── translate.uk_UA.toml
│ │ ├── translate.vi_VN.toml
│ │ └── translate.zh_Hans.toml
│ └── web.go
├── x-ui.service
├── x-ui.sh
└── xray/
├── api.go
├── client_traffic.go
├── config.go
├── inbound.go
├── log_writer.go
├── process.go
└── traffic.go
Showing preview only (452K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5835 symbols across 88 files)
FILE: config/config.go
type LogLevel (line 16) | type LogLevel
constant Debug (line 19) | Debug LogLevel = "debug"
constant Info (line 20) | Info LogLevel = "info"
constant Notice (line 21) | Notice LogLevel = "notice"
constant Warn (line 22) | Warn LogLevel = "warn"
constant Error (line 23) | Error LogLevel = "error"
function GetVersion (line 26) | func GetVersion() string {
function GetName (line 30) | func GetName() string {
function GetLogLevel (line 34) | func GetLogLevel() LogLevel {
function IsDebug (line 45) | func IsDebug() bool {
function GetBinFolderPath (line 49) | func GetBinFolderPath() string {
function GetDBFolderPath (line 57) | func GetDBFolderPath() string {
function GetDBPath (line 65) | func GetDBPath() string {
function GetLogFolder (line 69) | func GetLogFolder() string {
FILE: database/db.go
function initUser (line 30) | func initUser() error {
function initInbound (line 51) | func initInbound() error {
function initOutbound (line 55) | func initOutbound() error {
function initSetting (line 59) | func initSetting() error {
function initInboundClientIps (line 63) | func initInboundClientIps() error {
function initClientTraffic (line 67) | func initClientTraffic() error {
function InitDB (line 71) | func InitDB(dbPath string) error {
function GetDB (line 103) | func GetDB() *gorm.DB {
function IsNotFound (line 107) | func IsNotFound(err error) bool {
function IsSQLiteDB (line 111) | func IsSQLiteDB(file io.ReaderAt) (bool, error) {
function Checkpoint (line 121) | func Checkpoint() error {
FILE: database/model/model.go
type Protocol (line 10) | type Protocol
constant VMess (line 13) | VMess Protocol = "vmess"
constant VLESS (line 14) | VLESS Protocol = "vless"
constant DOKODEMO (line 15) | DOKODEMO Protocol = "dokodemo-door"
constant HTTP (line 16) | HTTP Protocol = "http"
constant Trojan (line 17) | Trojan Protocol = "trojan"
constant Shadowsocks (line 18) | Shadowsocks Protocol = "shadowsocks"
constant Socks (line 19) | Socks Protocol = "socks"
constant WireGuard (line 20) | WireGuard Protocol = "wireguard"
type User (line 23) | type User struct
type Inbound (line 30) | type Inbound struct
method GenXrayInboundConfig (line 65) | func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
type OutboundTraffics (line 51) | type OutboundTraffics struct
type InboundClientIps (line 59) | type InboundClientIps struct
type Setting (line 81) | type Setting struct
type Client (line 87) | type Client struct
FILE: logger/logger.go
function init (line 20) | func init() {
function InitLogger (line 24) | func InitLogger(level logging.Level) {
function Debug (line 50) | func Debug(args ...interface{}) {
function Debugf (line 55) | func Debugf(format string, args ...interface{}) {
function Info (line 60) | func Info(args ...interface{}) {
function Infof (line 65) | func Infof(format string, args ...interface{}) {
function Notice (line 70) | func Notice(args ...interface{}) {
function Noticef (line 75) | func Noticef(format string, args ...interface{}) {
function Warning (line 80) | func Warning(args ...interface{}) {
function Warningf (line 85) | func Warningf(format string, args ...interface{}) {
function Error (line 90) | func Error(args ...interface{}) {
function Errorf (line 95) | func Errorf(format string, args ...interface{}) {
function addToBuffer (line 100) | func addToBuffer(level string, newLog string) {
function GetLogs (line 118) | func GetLogs(c int, level string) []string {
FILE: main.go
function runWebServer (line 25) | func runWebServer() {
function resetSetting (line 112) | func resetSetting() {
function showSetting (line 128) | func showSetting(show bool) {
function updateTgbotEnableSts (line 231) | func updateTgbotEnableSts(status bool) {
function updateTgbotSetting (line 250) | func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRunt...
function updateSetting (line 287) | func updateSetting(port int, username string, password string, webBasePa...
function updateCert (line 325) | func updateCert(publicKey string, privateKey string) {
function migrateDb (line 352) | func migrateDb() {
function removeSecret (line 365) | func removeSecret() {
function main (line 395) | func main() {
FILE: sub/sub.go
type Server (line 21) | type Server struct
method initRouter (line 40) | func (s *Server) initRouter() (*gin.Engine, error) {
method Start (line 114) | func (s *Server) Start() (err error) {
method Stop (line 187) | func (s *Server) Stop() error {
method GetCtx (line 201) | func (s *Server) GetCtx() context.Context {
function NewServer (line 32) | func NewServer() *Server {
FILE: sub/subController.go
type SUBController (line 10) | type SUBController struct
method initRouter (line 46) | func (a *SUBController) initRouter(g *gin.RouterGroup) {
method subs (line 55) | func (a *SUBController) subs(c *gin.Context) {
method subJsons (line 90) | func (a *SUBController) subJsons(c *gin.Context) {
function NewSUBController (line 20) | func NewSUBController(
FILE: sub/subJsonService.go
type SubJsonService (line 20) | type SubJsonService struct
method GetJson (line 64) | func (s *SubJsonService) GetJson(subId string, host string) (string, s...
method getConfig (line 141) | func (s *SubJsonService) getConfig(inbound *model.Inbound, client mode...
method streamData (line 202) | func (s *SubJsonService) streamData(stream string) map[string]interfac...
method removeAcceptProxy (line 230) | func (s *SubJsonService) removeAcceptProxy(setting interface{}) map[st...
method tlsData (line 238) | func (s *SubJsonService) tlsData(tData map[string]interface{}) map[str...
method realityData (line 253) | func (s *SubJsonService) realityData(rData map[string]interface{}) map...
method genVnext (line 279) | func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettin...
method genServer (line 311) | func (s *SubJsonService) genServer(inbound *model.Inbound, streamSetti...
function NewSubJsonService (line 30) | func NewSubJsonService(fragment string, mux string, rules string, subSer...
type Outbound (line 350) | type Outbound struct
type OutboundSettings (line 359) | type OutboundSettings struct
type VnextSetting (line 364) | type VnextSetting struct
type UserVnext (line 370) | type UserVnext struct
type ServerSetting (line 377) | type ServerSetting struct
FILE: sub/subService.go
type SubService (line 21) | type SubService struct
method GetSubs (line 37) | func (s *SubService) GetSubs(subId string, host string) ([]string, str...
method getInboundsBySubId (line 107) | func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inboun...
method getClientTraffics (line 124) | func (s *SubService) getClientTraffics(traffics []xray.ClientTraffic, ...
method getFallbackMaster (line 133) | func (s *SubService) getFallbackMaster(dest string, streamSettings str...
method getLink (line 156) | func (s *SubService) getLink(inbound *model.Inbound, email string) str...
method genVmessLink (line 170) | func (s *SubService) genVmessLink(inbound *model.Inbound, email string...
method genVlessLink (line 320) | func (s *SubService) genVlessLink(inbound *model.Inbound, email string...
method genTrojanLink (line 554) | func (s *SubService) genTrojanLink(inbound *model.Inbound, email strin...
method genShadowsocksLink (line 786) | func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email ...
method genRemark (line 961) | func (s *SubService) genRemark(inbound *model.Inbound, email string, e...
function NewSubService (line 30) | func NewSubService(showInfo bool, remarkModel string) *SubService {
function searchKey (line 1047) | func searchKey(data interface{}, key string) (interface{}, bool) {
function searchHost (line 1068) | func searchHost(headers interface{}) string {
FILE: util/common/err.go
function NewErrorf (line 10) | func NewErrorf(format string, a ...interface{}) error {
function NewError (line 15) | func NewError(a ...interface{}) error {
function Recover (line 20) | func Recover(msg string) interface{} {
FILE: util/common/format.go
function FormatTraffic (line 7) | func FormatTraffic(trafficBytes int64) (size string) {
FILE: util/common/multi_error.go
type multiError (line 7) | type multiError
method Error (line 9) | func (e multiError) Error() string {
function Combine (line 19) | func Combine(maybeError ...error) error {
FILE: util/json_util/json.go
type RawMessage (line 7) | type RawMessage
method MarshalJSON (line 10) | func (m RawMessage) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 18) | func (m *RawMessage) UnmarshalJSON(data []byte) error {
FILE: util/random/random.go
function init (line 16) | func init() {
function Seq (line 36) | func Seq(n int) string {
function Num (line 44) | func Num(n int) int {
FILE: util/reflect_util/reflect.go
function GetFields (line 5) | func GetFields(t reflect.Type) []reflect.StructField {
function GetFieldValues (line 14) | func GetFieldValues(v reflect.Value) []reflect.Value {
FILE: util/sys/psutil.go
function HostProc (line 8) | func HostProc(combineWith ...string) string
FILE: util/sys/sys_darwin.go
function GetTCPCount (line 10) | func GetTCPCount() (int, error) {
function GetUDPCount (line 18) | func GetUDPCount() (int, error) {
FILE: util/sys/sys_linux.go
function getLinesNum (line 13) | func getLinesNum(filename string) (int, error) {
function GetTCPCount (line 44) | func GetTCPCount() (int, error) {
function GetUDPCount (line 59) | func GetUDPCount() (int, error) {
FILE: util/sys/sys_windows.go
function GetConnectionCount (line 12) | func GetConnectionCount(proto string) (int, error) {
function GetTCPCount (line 24) | func GetTCPCount() (int, error) {
function GetUDPCount (line 28) | func GetUDPCount() (int, error) {
FILE: web/assets/codemirror/codemirror.js
function classTest (line 51) | function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)...
function removeChildren (line 62) | function removeChildren(e) {
function removeChildrenAndAdd (line 68) | function removeChildrenAndAdd(parent, e) {
function elt (line 72) | function elt(tag, content, className, style) {
function eltP (line 81) | function eltP(tag, content, className, style) {
function contains (line 104) | function contains(parent, child) {
function activeElt (line 115) | function activeElt(doc) {
function addClass (line 130) | function addClass(node, cls) {
function joinClasses (line 134) | function joinClasses(a, b) {
function doc (line 147) | function doc(cm) { return cm.display.wrapper.ownerDocument }
function win (line 149) | function win(cm) { return doc(cm).defaultView }
function bind (line 151) | function bind(f) {
function copyObj (line 156) | function copyObj(obj, target, overwrite) {
function countColumn (line 166) | function countColumn(string, end, tabSize, startIndex, startValue) {
function indexOf (line 205) | function indexOf(array, elt) {
function findColumn (line 223) | function findColumn(string, goal, tabSize) {
function spaceStr (line 238) | function spaceStr(n) {
function lst (line 244) | function lst(arr) { return arr[arr.length-1] }
function map (line 246) | function map(array, f) {
function insertSorted (line 252) | function insertSorted(array, value, score) {
function nothing (line 258) | function nothing() {}
function createObj (line 260) | function createObj(base, props) {
function isWordCharBasic (line 273) | function isWordCharBasic(ch) {
function isWordChar (line 277) | function isWordChar(ch, helper) {
function isEmpty (line 283) | function isEmpty(obj) {
function isExtendingChar (line 294) | function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendi...
function skipExtendingChars (line 297) | function skipExtendingChars(str, pos, dir) {
function findFirst (line 305) | function findFirst(pred, from, to) {
function iterateBidiSections (line 320) | function iterateBidiSections(order, from, to, f) {
function getBidiPartAt (line 334) | function getBidiPartAt(order, ch, sticky) {
function charType (line 380) | function charType(code) {
function BidiSpan (line 393) | function BidiSpan(level, from, to) {
function getOrder (line 526) | function getOrder(line, direction) {
function getHandlers (line 550) | function getHandlers(emitter, type) {
function off (line 554) | function off(emitter, type, f) {
function signal (line 569) | function signal(emitter, type /*, values...*/) {
function signalDOMEvent (line 579) | function signalDOMEvent(cm, e, override) {
function signalCursorActivity (line 586) | function signalCursorActivity(cm) {
function hasHandler (line 594) | function hasHandler(emitter, type) {
function eventMixin (line 600) | function eventMixin(ctor) {
function e_preventDefault (line 608) | function e_preventDefault(e) {
function e_stopPropagation (line 612) | function e_stopPropagation(e) {
function e_defaultPrevented (line 616) | function e_defaultPrevented(e) {
function e_stop (line 619) | function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
function e_target (line 621) | function e_target(e) {return e.target || e.srcElement}
function e_button (line 622) | function e_button(e) {
function zeroWidthElement (line 643) | function zeroWidthElement(measure) {
function hasBadBidiRects (line 658) | function hasBadBidiRects(measure) {
function hasBadZoomedRects (line 707) | function hasBadZoomedRects(measure) {
function defineMode (line 721) | function defineMode(name, mode) {
function defineMIME (line 727) | function defineMIME(mime, spec) {
function resolveMode (line 733) | function resolveMode(spec) {
function getMode (line 752) | function getMode(options, spec) {
function extendMode (line 776) | function extendMode(mode, properties) {
function copyState (line 781) | function copyState(mode, state) {
function innerMode (line 795) | function innerMode(mode, state) {
function startState (line 806) | function startState(mode, a1, a2) {
function getLine (line 896) | function getLine(doc, n) {
function getBetween (line 912) | function getBetween(doc, start, end) {
function getLines (line 924) | function getLines(doc, from, to) {
function updateLineHeight (line 932) | function updateLineHeight(line, height) {
function lineNo (line 939) | function lineNo(line) {
function lineAtHeight (line 953) | function lineAtHeight(chunk, h) {
function isLine (line 973) | function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
function lineNumberFor (line 975) | function lineNumberFor(options, i) {
function Pos (line 980) | function Pos(line, ch, sticky) {
function cmp (line 991) | function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
function equalCursorPos (line 993) | function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b)...
function copyPos (line 995) | function copyPos(x) {return Pos(x.line, x.ch)}
function maxPos (line 996) | function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
function minPos (line 997) | function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
function clipLine (line 1001) | function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.fi...
function clipPos (line 1002) | function clipPos(doc, pos) {
function clipToLen (line 1008) | function clipToLen(pos, linelen) {
function clipPosArray (line 1014) | function clipPosArray(doc, array) {
function highlightLine (line 1071) | function highlightLine(cm, line, context, forceToEnd) {
function getLineStyles (line 1116) | function getLineStyles(cm, line, updateFrontier) {
function getContextBefore (line 1132) | function getContextBefore(cm, n, precise) {
function processLine (line 1152) | function processLine(cm, text, context, startAt) {
function callBlankLine (line 1163) | function callBlankLine(mode, state) {
function readToken (line 1170) | function readToken(mode, stream, state, inner) {
function takeToken (line 1187) | function takeToken(cm, pos, precise, asArray) {
function extractLineClasses (line 1201) | function extractLineClasses(type, output) {
function runMode (line 1216) | function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
function findStartLine (line 1260) | function findStartLine(cm, n, precise) {
function retreatFrontier (line 1277) | function retreatFrontier(doc, n) {
function seeReadOnlySpans (line 1297) | function seeReadOnlySpans() {
function seeCollapsedSpans (line 1301) | function seeCollapsedSpans() {
function MarkedSpan (line 1307) | function MarkedSpan(marker, from, to) {
function getMarkedSpanFor (line 1313) | function getMarkedSpanFor(spans, marker) {
function removeMarkedSpan (line 1322) | function removeMarkedSpan(spans, span) {
function addMarkedSpan (line 1330) | function addMarkedSpan(line, span, op) {
function markedSpansBefore (line 1345) | function markedSpansBefore(old, startCh, isInsert) {
function markedSpansAfter (line 1357) | function markedSpansAfter(old, endCh, isInsert) {
function stretchSpansOverChange (line 1377) | function stretchSpansOverChange(doc, change) {
function clearEmptySpans (line 1439) | function clearEmptySpans(spans) {
function removeReadOnlyRanges (line 1450) | function removeReadOnlyRanges(doc, from, to) {
function detachMarkedSpans (line 1479) | function detachMarkedSpans(line) {
function attachMarkedSpans (line 1486) | function attachMarkedSpans(line, spans) {
function extraLeft (line 1495) | function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
function extraRight (line 1496) | function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
function compareCollapsedMarkers (line 1501) | function compareCollapsedMarkers(a, b) {
function collapsedSpanAtSide (line 1514) | function collapsedSpanAtSide(line, start) {
function collapsedSpanAtStart (line 1524) | function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, t...
function collapsedSpanAtEnd (line 1525) | function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, fal...
function collapsedSpanAround (line 1527) | function collapsedSpanAround(line, ch) {
function conflictingCollapsedRange (line 1540) | function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
function visualLine (line 1560) | function visualLine(line) {
function visualLineEnd (line 1567) | function visualLineEnd(line) {
function visualLineContinued (line 1576) | function visualLineContinued(line) {
function visualLineNo (line 1587) | function visualLineNo(doc, lineN) {
function visualLineEndNo (line 1595) | function visualLineEndNo(doc, lineN) {
function lineIsHidden (line 1607) | function lineIsHidden(doc, line) {
function lineIsHiddenInner (line 1618) | function lineIsHiddenInner(doc, line, span) {
function heightAtLine (line 1635) | function heightAtLine(lineObj) {
function lineLength (line 1657) | function lineLength(line) {
function findMaxLine (line 1676) | function findMaxLine(cm) {
function updateLine (line 1706) | function updateLine(line, text, markedSpans, estimateHeight) {
function cleanUpLine (line 1718) | function cleanUpLine(line) {
function interpretTokenStyle (line 1727) | function interpretTokenStyle(style, options) {
function buildLineContent (line 1739) | function buildLineContent(cm, lineView) {
function defaultSpecialCharPlaceholder (line 1797) | function defaultSpecialCharPlaceholder(ch) {
function buildToken (line 1806) | function buildToken(builder, text, style, startStyle, endStyle, css, att...
function splitSpaces (line 1873) | function splitSpaces(text, trailingBefore) {
function buildTokenBadBidi (line 1888) | function buildTokenBadBidi(inner, order) {
function buildCollapsedSpan (line 1908) | function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
function insertLineContent (line 1926) | function insertLineContent(line, builder, styles) {
function LineView (line 2005) | function LineView(doc, line, lineN) {
function buildViewArray (line 2017) | function buildViewArray(cm, from, to) {
function pushOperation (line 2029) | function pushOperation(op) {
function fireCallbacksForOps (line 2040) | function fireCallbacksForOps(group) {
function finishOperation (line 2056) | function finishOperation(op, endCb) {
function signalLater (line 2076) | function signalLater(emitter, type /*, values...*/) {
function fireOrphanDelayed (line 2096) | function fireOrphanDelayed() {
function updateLineForChanges (line 2105) | function updateLineForChanges(cm, lineView, lineN, dims) {
function ensureLineWrapped (line 2118) | function ensureLineWrapped(lineView) {
function updateLineBackground (line 2129) | function updateLineBackground(cm, lineView) {
function getLineContent (line 2144) | function getLineContent(cm, lineView) {
function updateLineText (line 2157) | function updateLineText(cm, lineView) {
function updateLineClasses (line 2172) | function updateLineClasses(cm, lineView) {
function updateLineGutter (line 2182) | function updateLineGutter(cm, lineView, lineN, dims) {
function updateLineWidgets (line 2221) | function updateLineWidgets(cm, lineView, dims) {
function buildLineElement (line 2232) | function buildLineElement(cm, lineView, lineN, dims) {
function insertLineWidgets (line 2246) | function insertLineWidgets(cm, lineView, dims) {
function insertLineWidgetsFor (line 2252) | function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
function positionLineWidget (line 2268) | function positionLineWidget(widget, node, lineView, dims) {
function widgetHeight (line 2286) | function widgetHeight(widget) {
function eventInWidget (line 2302) | function eventInWidget(display, e) {
function paddingTop (line 2312) | function paddingTop(display) {return display.lineSpace.offsetTop}
function paddingVert (line 2313) | function paddingVert(display) {return display.mover.offsetHeight - displ...
function paddingH (line 2314) | function paddingH(display) {
function scrollGap (line 2323) | function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
function displayWidth (line 2324) | function displayWidth(cm) {
function displayHeight (line 2327) | function displayHeight(cm) {
function ensureLineHeights (line 2335) | function ensureLineHeights(cm, lineView, rect) {
function mapFromLineView (line 2356) | function mapFromLineView(lineView, line, lineN) {
function updateExternalMeasurement (line 2371) | function updateExternalMeasurement(cm, line) {
function measureChar (line 2384) | function measureChar(cm, line, ch, bias) {
function findViewForLine (line 2389) | function findViewForLine(cm, lineN) {
function prepareMeasureForLine (line 2402) | function prepareMeasureForLine(cm, line) {
function measureCharPrepared (line 2424) | function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
function nodeAndOffsetInLineMap (line 2446) | function nodeAndOffsetInLineMap(map, ch, bias) {
function getUsefulRect (line 2484) | function getUsefulRect(rects, bias) {
function measureCharInner (line 2494) | function measureCharInner(cm, prepared, ch, bias) {
function maybeUpdateRectForZooming (line 2547) | function maybeUpdateRectForZooming(measure, rect) {
function clearLineMeasurementCacheFor (line 2557) | function clearLineMeasurementCacheFor(lineView) {
function clearLineMeasurementCache (line 2566) | function clearLineMeasurementCache(cm) {
function clearCaches (line 2573) | function clearCaches(cm) {
function pageScrollX (line 2580) | function pageScrollX(doc) {
function pageScrollY (line 2587) | function pageScrollY(doc) {
function widgetTopHeight (line 2592) | function widgetTopHeight(lineObj) {
function intoCoordSystem (line 2605) | function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
function fromCoordSystem (line 2627) | function fromCoordSystem(cm, coords, context) {
function charCoords (line 2644) | function charCoords(cm, pos, context, lineObj, bias) {
function cursorCoords (line 2665) | function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHei...
function estimateCoords (line 2696) | function estimateCoords(cm, pos) {
function PosWithInfo (line 2711) | function PosWithInfo(line, ch, sticky, outside, xRel) {
function coordsChar (line 2720) | function coordsChar(cm, x, y) {
function wrappedLineExtent (line 2740) | function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
function wrappedLineExtentChar (line 2748) | function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
function boxIsAfter (line 2756) | function boxIsAfter(box, x, y, left) {
function coordsCharInner (line 2760) | function coordsCharInner(cm, lineObj, lineNo, x, y) {
function coordsBidiPart (line 2827) | function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, ...
function coordsBidiPartWrapped (line 2851) | function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, or...
function textHeight (line 2886) | function textHeight(display) {
function charWidth (line 2906) | function charWidth(display) {
function getDimensions (line 2918) | function getDimensions(cm) {
function compensateForHScroll (line 2936) | function compensateForHScroll(display) {
function estimateHeight (line 2943) | function estimateHeight(cm) {
function estimateLineHeights (line 2961) | function estimateLineHeights(cm) {
function posFromMouse (line 2974) | function posFromMouse(cm, e, liberal, forRect) {
function findViewIndex (line 2992) | function findViewIndex(cm, n) {
function regChange (line 3009) | function regChange(cm, from, to, lendiff) {
function regLineChange (line 3074) | function regLineChange(cm, line, type) {
function resetView (line 3088) | function resetView(cm) {
function viewCuttingPoint (line 3094) | function viewCuttingPoint(cm, oldN, newN, dir) {
function adjustView (line 3121) | function adjustView(cm, from, to) {
function countDirtyView (line 3142) | function countDirtyView(cm) {
function updateSelection (line 3151) | function updateSelection(cm) {
function prepareSelection (line 3155) | function prepareSelection(cm, primary) {
function drawSelectionCursor (line 3182) | function drawSelectionCursor(cm, head, output) {
function cmpCoords (line 3206) | function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
function drawSelectionRange (line 3209) | function drawSelectionRange(cm, range, output) {
function restartBlink (line 3302) | function restartBlink(cm) {
function ensureFocus (line 3317) | function ensureFocus(cm) {
function delayBlurEvent (line 3324) | function delayBlurEvent(cm) {
function onFocus (line 3332) | function onFocus(cm, e) {
function onBlur (line 3351) | function onBlur(cm, e) {
function updateHeightsInViewport (line 3365) | function updateHeightsInViewport(cm) {
function updateWidgetHeight (line 3410) | function updateWidgetHeight(line) {
function visibleLines (line 3420) | function visibleLines(display, doc, viewport) {
function maybeScrollWindow (line 3445) | function maybeScrollWindow(cm, rect) {
function scrollPosIntoView (line 3463) | function scrollPosIntoView(cm, pos, end, margin) {
function scrollIntoView (line 3497) | function scrollIntoView(cm, rect) {
function calculateScrollPos (line 3507) | function calculateScrollPos(cm, rect) {
function addToScrollTop (line 3538) | function addToScrollTop(cm, top) {
function ensureCursorVisible (line 3546) | function ensureCursorVisible(cm) {
function scrollToCoords (line 3552) | function scrollToCoords(cm, x, y) {
function scrollToRange (line 3558) | function scrollToRange(cm, range) {
function resolveScrollToPos (line 3567) | function resolveScrollToPos(cm) {
function scrollToCoordsRange (line 3576) | function scrollToCoordsRange(cm, from, to, margin) {
function updateScrollTop (line 3588) | function updateScrollTop(cm, val) {
function setScrollTop (line 3596) | function setScrollTop(cm, val, forceScroll) {
function setScrollLeft (line 3606) | function setScrollLeft(cm, val, isScroller, forceScroll) {
function measureForScrollbars (line 3619) | function measureForScrollbars(cm) {
function maybeDisable (line 3712) | function maybeDisable() {
function updateScrollbars (line 3741) | function updateScrollbars(cm, measure) {
function updateScrollbarsInner (line 3755) | function updateScrollbarsInner(cm, measure) {
function initScrollbars (line 3777) | function initScrollbars(cm) {
function startOperation (line 3807) | function startOperation(cm) {
function endOperation (line 3830) | function endOperation(cm) {
function endOperations (line 3841) | function endOperations(group) {
function endOperation_R1 (line 3855) | function endOperation_R1(op) {
function endOperation_W1 (line 3868) | function endOperation_W1(op) {
function endOperation_R2 (line 3872) | function endOperation_R2(op) {
function endOperation_W2 (line 3893) | function endOperation_W2(op) {
function endOperation_finish (line 3918) | function endOperation_finish(op) {
function runInOp (line 3957) | function runInOp(cm, f) {
function operation (line 3964) | function operation(cm, f) {
function methodOp (line 3974) | function methodOp(f) {
function docMethodOp (line 3982) | function docMethodOp(f) {
function startWorker (line 3994) | function startWorker(cm, time) {
function highlightWorker (line 3999) | function highlightWorker(cm) {
function maybeClipScrollbars (line 4067) | function maybeClipScrollbars(cm) {
function selectionSnapshot (line 4078) | function selectionSnapshot(cm) {
function restoreSelection (line 4095) | function restoreSelection(snapshot) {
function updateDisplayIfNeeded (line 4113) | function updateDisplayIfNeeded(cm, update) {
function postUpdateDisplay (line 4185) | function postUpdateDisplay(cm, update) {
function updateDisplaySimple (line 4217) | function updateDisplaySimple(cm, viewport) {
function patchDisplay (line 4234) | function patchDisplay(cm, updateNumbersFrom, dims) {
function updateGutterSpace (line 4275) | function updateGutterSpace(display) {
function setDocumentHeight (line 4282) | function setDocumentHeight(cm, measure) {
function alignHorizontally (line 4290) | function alignHorizontally(cm) {
function maybeUpdateLineNumberWidth (line 4313) | function maybeUpdateLineNumberWidth(cm) {
function getGutters (line 4331) | function getGutters(gutters, lineNumbers) {
function renderGutters (line 4348) | function renderGutters(display) {
function updateGutters (line 4367) | function updateGutters(cm) {
function Display (line 4377) | function Display(place, doc, input, options) {
function wheelEventDelta (line 4506) | function wheelEventDelta(e) {
function wheelEventPixels (line 4513) | function wheelEventPixels(e) {
function onScrollWheel (line 4520) | function onScrollWheel(cm, e) {
function normalizeSelection (line 4668) | function normalizeSelection(cm, ranges, primIndex) {
function simpleSelection (line 4686) | function simpleSelection(anchor, head) {
function changeEnd (line 4692) | function changeEnd(change) {
function adjustForChange (line 4700) | function adjustForChange(pos, change) {
function computeSelAfterChange (line 4709) | function computeSelAfterChange(doc, change) {
function offsetPos (line 4719) | function offsetPos(pos, old, nw) {
function computeReplacedSel (line 4728) | function computeReplacedSel(doc, changes, hint) {
function loadMode (line 4749) | function loadMode(cm) {
function resetModeState (line 4754) | function resetModeState(cm) {
function isWholeLineUpdate (line 4770) | function isWholeLineUpdate(doc, change) {
function updateDoc (line 4776) | function updateDoc(doc, change, markedSpans, estimateHeight) {
function linkedDocs (line 4828) | function linkedDocs(doc, f, sharedHistOnly) {
function attachDoc (line 4843) | function attachDoc(cm, doc) {
function setDirectionClass (line 4856) | function setDirectionClass(cm) {
function directionChanged (line 4860) | function directionChanged(cm) {
function History (line 4867) | function History(prev) {
function historyChangeFromChange (line 4884) | function historyChangeFromChange(doc, change) {
function clearSelectionEvents (line 4893) | function clearSelectionEvents(array) {
function lastChangeEvent (line 4903) | function lastChangeEvent(hist, force) {
function addChangeToHistory (line 4918) | function addChangeToHistory(doc, change, selAfter, opId) {
function selectionEventCanBeMerged (line 4961) | function selectionEventCanBeMerged(doc, origin, prev, sel) {
function addSelectionToHistory (line 4974) | function addSelectionToHistory(doc, sel, opId, options) {
function pushSelectionToHistory (line 4996) | function pushSelectionToHistory(sel, dest) {
function attachLocalSpans (line 5003) | function attachLocalSpans(doc, change, from, to) {
function removeClearedSpans (line 5014) | function removeClearedSpans(spans) {
function getOldSpans (line 5025) | function getOldSpans(doc, change) {
function mergeOldSpans (line 5038) | function mergeOldSpans(doc, change) {
function copyHistoryArray (line 5062) | function copyHistoryArray(events, newGroup, instantiateSel) {
function extendRange (line 5094) | function extendRange(range, head, other, extend) {
function extendSelection (line 5113) | function extendSelection(doc, head, other, options, extend) {
function extendSelections (line 5120) | function extendSelections(doc, heads, options) {
function replaceOneSelection (line 5130) | function replaceOneSelection(doc, i, range, options) {
function setSimpleSelection (line 5137) | function setSimpleSelection(doc, anchor, head, options) {
function filterSelectionChange (line 5143) | function filterSelectionChange(doc, sel, options) {
function setSelectionReplaceHistory (line 5160) | function setSelectionReplaceHistory(doc, sel, options) {
function setSelection (line 5171) | function setSelection(doc, sel, options) {
function setSelectionNoUndo (line 5176) | function setSelectionNoUndo(doc, sel, options) {
function setSelectionInner (line 5188) | function setSelectionInner(doc, sel) {
function reCheckSelection (line 5203) | function reCheckSelection(doc) {
function skipAtomicInSelection (line 5209) | function skipAtomicInSelection(doc, sel, bias, mayClear) {
function skipAtomicInner (line 5224) | function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
function skipAtomic (line 5264) | function skipAtomic(doc, pos, oldPos, bias, mayClear) {
function movePos (line 5277) | function movePos(doc, pos, dir, line) {
function selectAll (line 5289) | function selectAll(cm) {
function filterChange (line 5296) | function filterChange(doc, change, update) {
function makeChange (line 5323) | function makeChange(doc, change, ignoreReadOnly) {
function makeChangeInner (line 5345) | function makeChangeInner(doc, change) {
function makeChangeFromHistory (line 5363) | function makeChangeFromHistory(doc, type, allowSelectionOnly) {
function shiftDoc (line 5439) | function shiftDoc(doc, distance) {
function makeChangeSingleDoc (line 5455) | function makeChangeSingleDoc(doc, change, selAfter, spans) {
function makeChangeSingleDocInEditor (line 5491) | function makeChangeSingleDocInEditor(cm, change, spans) {
function replaceRange (line 5549) | function replaceRange(doc, code, from, to, origin) {
function rebaseHistSelSingle (line 5560) | function rebaseHistSelSingle(pos, from, to, diff) {
function rebaseHistArray (line 5576) | function rebaseHistArray(array, from, to, diff) {
function rebaseHist (line 5604) | function rebaseHist(hist, change) {
function changeLine (line 5613) | function changeLine(doc, handle, changeType, op) {
function LeafChunk (line 5635) | function LeafChunk(lines) {
function BranchChunk (line 5680) | function BranchChunk(children) {
function adjustScrollWhenAboveVisible (line 5829) | function adjustScrollWhenAboveVisible(cm, line, diff) {
function addLineWidget (line 5834) | function addLineWidget(doc, handle, node, options) {
function markText (line 5990) | function markText(doc, from, to, options, type) {
function markTextShared (line 6085) | function markTextShared(doc, from, to, options, type) {
function findSharedMarkers (line 6100) | function findSharedMarkers(doc) {
function copySharedMarkers (line 6104) | function copySharedMarkers(doc, markers) {
function detachSharedMarkers (line 6116) | function detachSharedMarkers(markers) {
function onDrop (line 6554) | function onDrop(e) {
function onDragStart (line 6625) | function onDragStart(cm, e) {
function onDragOver (line 6648) | function onDragOver(cm, e) {
function clearDragCursor (line 6660) | function clearDragCursor(cm) {
function forEachCodeMirror (line 6671) | function forEachCodeMirror(f) {
function ensureGlobalHandlers (line 6684) | function ensureGlobalHandlers() {
function registerGlobalHandlers (line 6689) | function registerGlobalHandlers() {
function onResize (line 6702) | function onResize(cm) {
function normalizeKeyName (line 6772) | function normalizeKeyName(name) {
function normalizeKeyMap (line 6796) | function normalizeKeyMap(keymap) {
function lookupKey (line 6823) | function lookupKey(key, map, handle, context) {
function isModifierKey (line 6842) | function isModifierKey(value) {
function addModifierNames (line 6847) | function addModifierNames(name, event, noShift) {
function keyName (line 6857) | function keyName(event, noShift) {
function getKeyMap (line 6867) | function getKeyMap(val) {
function deleteNearSelection (line 6873) | function deleteNearSelection(cm, compute) {
function moveCharLogically (line 6896) | function moveCharLogically(line, ch, dir) {
function moveLogically (line 6901) | function moveLogically(line, start, dir) {
function endOfLine (line 6906) | function endOfLine(visually, cm, lineObj, lineNo, dir) {
function moveVisually (line 6934) | function moveVisually(cm, line, start, dir) {
function lineStart (line 7146) | function lineStart(cm, lineN) {
function lineEnd (line 7152) | function lineEnd(cm, lineN) {
function lineStartSmart (line 7158) | function lineStartSmart(cm, pos) {
function doHandleBinding (line 7171) | function doHandleBinding(cm, bound, dropShift) {
function lookupKeyForEditor (line 7191) | function lookupKeyForEditor(cm, name, handle) {
function dispatchKey (line 7205) | function dispatchKey(cm, name, e, handle) {
function dispatchKeyInner (line 7223) | function dispatchKeyInner(cm, name, e, handle) {
function handleKeyBinding (line 7240) | function handleKeyBinding(cm, e) {
function handleCharBinding (line 7259) | function handleCharBinding(cm, e, ch) {
function onKeyDown (line 7264) | function onKeyDown(e) {
function showCrossHair (line 7288) | function showCrossHair(cm) {
function onKeyUp (line 7303) | function onKeyUp(e) {
function onKeyPress (line 7308) | function onKeyPress(e) {
function clickRepeat (line 7336) | function clickRepeat(pos, button) {
function onMouseDown (line 7357) | function onMouseDown(e) {
function handleMappedButton (line 7394) | function handleMappedButton(cm, button, pos, repeat, event) {
function configureMouse (line 7414) | function configureMouse(cm, repeat, event) {
function leftButtonDown (line 7427) | function leftButtonDown(cm, pos, repeat, event) {
function leftButtonStartDrag (line 7445) | function leftButtonStartDrag(cm, event, pos, behavior) {
function rangeForUnit (line 7488) | function rangeForUnit(cm, pos, unit) {
function leftButtonSelect (line 7497) | function leftButtonSelect(cm, event, start, behavior) {
function bidiSimplify (line 7635) | function bidiSimplify(cm, range) {
function gutterEvent (line 7670) | function gutterEvent(cm, e, type, prevent) {
function clickInGutter (line 7699) | function clickInGutter(cm, e) {
function onContextMenu (line 7708) | function onContextMenu(cm, e) {
function contextMenuInGutter (line 7714) | function contextMenuInGutter(cm, e) {
function themeChanged (line 7719) | function themeChanged(cm) {
function defineOptions (line 7730) | function defineOptions(CodeMirror) {
function dragDropChanged (line 7874) | function dragDropChanged(cm, value, old) {
function wrappingChanged (line 7887) | function wrappingChanged(cm) {
function CodeMirror (line 7905) | function CodeMirror(place, options) {
function registerEventHandlers (line 7982) | function registerEventHandlers(cm) {
function indentLine (line 8100) | function indentLine(cm, n, how, aggressive) {
function setLastCopied (line 8164) | function setLastCopied(newLastCopied) {
function applyTextInput (line 8168) | function applyTextInput(cm, inserted, deleted, sel, origin) {
function handlePaste (line 8216) | function handlePaste(e, cm) {
function triggerElectric (line 8226) | function triggerElectric(cm, inserted) {
function copyableRanges (line 8250) | function copyableRanges(cm) {
function disableBrowserMagic (line 8261) | function disableBrowserMagic(field, spellcheck, autocorrect, autocapital...
function hiddenTextarea (line 8267) | function hiddenTextarea() {
function addEditorMethods (line 8289) | function addEditorMethods(CodeMirror) {
function findPosH (line 8729) | function findPosH(doc, pos, dir, unit, visually) {
function findPosV (line 8798) | function findPosV(cm, pos, dir, unit) {
function belongsToInput (line 8837) | function belongsToInput(e) {
function onCopyCut (line 8870) | function onCopyCut(e) {
function poll (line 9040) | function poll() {
function posToDOM (line 9206) | function posToDOM(cm, pos) {
function isInGutter (line 9222) | function isInGutter(node) {
function badPos (line 9228) | function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
function domTextBetween (line 9230) | function domTextBetween(cm, from, to, fromLine, toLine) {
function domToPos (line 9283) | function domToPos(cm, node, offset) {
function locateNodeInLineView (line 9302) | function locateNodeInLineView(lineView, node, offset) {
function prepareCopyCut (line 9400) | function prepareCopyCut(e) {
function p (line 9561) | function p() {
function prepareSelectAllHack (line 9665) | function prepareSelectAllHack() {
function rehide (line 9678) | function rehide() {
function fromTextArea (line 9726) | function fromTextArea(textarea, options) {
function addLegacyProps (line 9783) | function addLegacyProps(CodeMirror) {
FILE: web/assets/codemirror/fold/brace-fold.js
function bracketFolding (line 14) | function bracketFolding(pairs) {
function hasImport (line 77) | function hasImport(line) {
function hasInclude (line 101) | function hasInclude(line) {
FILE: web/assets/codemirror/fold/foldcode.js
function doFold (line 14) | function doFold(cm, pos, options, force) {
function makeWidget (line 63) | function makeWidget(cm, options, range) {
function getOption (line 147) | function getOption(cm, options, name) {
FILE: web/assets/codemirror/fold/foldgutter.js
function State (line 41) | function State(options) {
function parseOptions (line 46) | function parseOptions(opts) {
function isFolded (line 54) | function isFolded(cm, line) {
function marker (line 65) | function marker(spec) {
function updateFoldInfo (line 75) | function updateFoldInfo(cm, from, to) {
function classTest (line 104) | function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)...
function updateInViewport (line 106) | function updateInViewport(cm) {
function onGutterClick (line 115) | function onGutterClick(cm, line, gutter) {
function optionChange (line 125) | function optionChange(cm, option) {
function onChange (line 129) | function onChange(cm) {
function onViewportChange (line 138) | function onViewportChange(cm) {
function onFold (line 162) | function onFold(cm, from) {
FILE: web/assets/codemirror/hint/javascript-hint.js
function forEach (line 14) | function forEach(arr, f) {
function arrayContains (line 18) | function arrayContains(arr, item) {
function scriptHint (line 31) | function scriptHint(editor, keywords, getToken, options) {
function javascriptHint (line 62) | function javascriptHint(editor, options) {
function getCoffeeScriptToken (line 69) | function getCoffeeScriptToken(editor, cur) {
function coffeescriptHint (line 87) | function coffeescriptHint(editor, options) {
function forAllProps (line 102) | function forAllProps(obj, callback) {
function getCompletions (line 111) | function getCompletions(token, context, keywords, options) {
FILE: web/assets/codemirror/javascript.js
function kw (line 26) | function kw(type) {return {type: type, style: "keyword"};}
function readRegexp (line 47) | function readRegexp(stream) {
function ret (line 62) | function ret(tp, style, cont) {
function tokenBase (line 66) | function tokenBase(stream, state) {
function tokenString (line 137) | function tokenString(quote) {
function tokenComment (line 153) | function tokenComment(stream, state) {
function tokenQuasi (line 165) | function tokenQuasi(stream, state) {
function findFatArrow (line 185) | function findFatArrow(stream, state) {
function JSLexical (line 225) | function JSLexical(indented, column, type, align, prev, info) {
function inScope (line 234) | function inScope(state, varname) {
function parseJS (line 244) | function parseJS(state, style, type, content, stream) {
function pass (line 268) | function pass() {
function cont (line 271) | function cont() {
function inList (line 275) | function inList(name, list) {
function register (line 279) | function register(varname) {
function registerVarScoped (line 300) | function registerVarScoped(varname, context) {
function isModifier (line 315) | function isModifier(name) {
function Context (line 321) | function Context(prev, vars, block) { this.prev = prev; this.vars = vars...
function Var (line 322) | function Var(name, next) { this.name = name; this.next = next }
function pushcontext (line 325) | function pushcontext() {
function pushblockcontext (line 329) | function pushblockcontext() {
function popcontext (line 334) | function popcontext() {
function pushlex (line 339) | function pushlex(type, info) {
function poplex (line 350) | function poplex() {
function expect (line 360) | function expect(wanted) {
function statement (line 369) | function statement(type, value) {
function maybeCatchBinding (line 418) | function maybeCatchBinding(type) {
function expression (line 421) | function expression(type, value) {
function expressionNoComma (line 424) | function expressionNoComma(type, value) {
function parenExpr (line 427) | function parenExpr(type) {
function expressionInner (line 431) | function expressionInner(type, value, noComma) {
function maybeexpression (line 451) | function maybeexpression(type) {
function maybeoperatorComma (line 456) | function maybeoperatorComma(type, value) {
function maybeoperatorNoComma (line 460) | function maybeoperatorNoComma(type, value, noComma) {
function quasi (line 483) | function quasi(type, value) {
function continueQuasi (line 488) | function continueQuasi(type) {
function arrowBody (line 495) | function arrowBody(type) {
function arrowBodyNoComma (line 499) | function arrowBodyNoComma(type) {
function maybeTarget (line 503) | function maybeTarget(noComma) {
function target (line 510) | function target(_, value) {
function targetNoComma (line 513) | function targetNoComma(_, value) {
function maybelabel (line 516) | function maybelabel(type) {
function property (line 520) | function property(type) {
function objprop (line 523) | function objprop(type, value) {
function getterSetter (line 553) | function getterSetter(type) {
function afterprop (line 558) | function afterprop(type) {
function commasep (line 562) | function commasep(what, end, sep) {
function contCommasep (line 581) | function contCommasep(what, end, info) {
function block (line 586) | function block(type) {
function maybetype (line 590) | function maybetype(type, value) {
function maybetypeOrIn (line 596) | function maybetypeOrIn(type, value) {
function mayberettype (line 599) | function mayberettype(type) {
function isKW (line 605) | function isKW(_, value) {
function typeexpr (line 611) | function typeexpr(type, value) {
function maybeReturnType (line 628) | function maybeReturnType(type) {
function typeprops (line 631) | function typeprops(type) {
function typeprop (line 636) | function typeprop(type, value) {
function quasiType (line 652) | function quasiType(type, value) {
function continueQuasiType (line 657) | function continueQuasiType(type) {
function typearg (line 664) | function typearg(type, value) {
function afterType (line 670) | function afterType(type, value) {
function maybeTypeArgs (line 677) | function maybeTypeArgs(_, value) {
function typeparam (line 680) | function typeparam() {
function maybeTypeDefault (line 683) | function maybeTypeDefault(_, value) {
function vardef (line 686) | function vardef(_, value) {
function pattern (line 690) | function pattern(type, value) {
function proppattern (line 697) | function proppattern(type, value) {
function eltpattern (line 708) | function eltpattern() {
function maybeAssign (line 711) | function maybeAssign(_type, value) {
function vardefCont (line 714) | function vardefCont(type) {
function maybeelse (line 717) | function maybeelse(type, value) {
function forspec (line 720) | function forspec(type, value) {
function forspec1 (line 724) | function forspec1(type) {
function forspec2 (line 729) | function forspec2(type, value) {
function functiondef (line 735) | function functiondef(type, value) {
function functiondecl (line 741) | function functiondecl(type, value) {
function typename (line 747) | function typename(type, value) {
function funarg (line 755) | function funarg(type, value) {
function classExpression (line 762) | function classExpression(type, value) {
function className (line 767) | function className(type, value) {
function classNameAfter (line 770) | function classNameAfter(type, value) {
function classBody (line 778) | function classBody(type, value) {
function classfield (line 802) | function classfield(type, value) {
function afterExport (line 810) | function afterExport(type, value) {
function exportField (line 816) | function exportField(type, value) {
function afterImport (line 820) | function afterImport(type) {
function importSpec (line 826) | function importSpec(type, value) {
function maybeMoreImports (line 832) | function maybeMoreImports(type) {
function maybeAs (line 835) | function maybeAs(_type, value) {
function maybeFrom (line 838) | function maybeFrom(_type, value) {
function arrayLiteral (line 841) | function arrayLiteral(type) {
function enumdef (line 845) | function enumdef() {
function enummember (line 848) | function enummember() {
function isContinuedStatement (line 852) | function isContinuedStatement(state, textAfter) {
function expressionAllowed (line 858) | function expressionAllowed(stream, state, backUp) {
FILE: web/assets/codemirror/jshint.js
function s (line 6) | function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&re...
function replacer (line 129) | function replacer(key, value) {
function truncate (line 142) | function truncate(s, n) {
function getMessage (line 150) | function getMessage(self) {
function fail (line 167) | function fail(actual, expected, message, operator, stackStartFunction) {
function ok (line 187) | function ok(value, message) {
function _deepEqual (line 218) | function _deepEqual(actual, expected) {
function isArguments (line 263) | function isArguments(object) {
function objEquiv (line 267) | function objEquiv(a, b) {
function expectedException (line 336) | function expectedException(actual, expected) {
function _throws (line 352) | function _throws(shouldThrow, block, expected, message) {
function deprecated (line 516) | function deprecated() {
function inspect (line 563) | function inspect(obj, opts) {
function stylizeWithColor (line 621) | function stylizeWithColor(str, styleType) {
function stylizeNoColor (line 633) | function stylizeNoColor(str, styleType) {
function arrayToHash (line 638) | function arrayToHash(array) {
function formatValue (line 649) | function formatValue(ctx, value, recurseTimes) {
function formatPrimitive (line 762) | function formatPrimitive(ctx, value) {
function formatError (line 781) | function formatError(value) {
function formatArray (line 786) | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
function formatProperty (line 806) | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, arra...
function reduceToSingleString (line 865) | function reduceToSingleString(output, base, braces) {
function isArray (line 888) | function isArray(ar) {
function isBoolean (line 893) | function isBoolean(arg) {
function isNull (line 898) | function isNull(arg) {
function isNullOrUndefined (line 903) | function isNullOrUndefined(arg) {
function isNumber (line 908) | function isNumber(arg) {
function isString (line 913) | function isString(arg) {
function isSymbol (line 918) | function isSymbol(arg) {
function isUndefined (line 923) | function isUndefined(arg) {
function isRegExp (line 928) | function isRegExp(re) {
function isObject (line 933) | function isObject(arg) {
function isDate (line 938) | function isDate(d) {
function isError (line 943) | function isError(e) {
function isFunction (line 949) | function isFunction(arg) {
function isPrimitive (line 954) | function isPrimitive(arg) {
function objectToString (line 966) | function objectToString(o) {
function pad (line 971) | function pad(n) {
function timestamp (line 980) | function timestamp() {
function hasOwnProperty (line 1022) | function hasOwnProperty(obj, prop) {
function log (line 1070) | function log() {}
function info (line 1072) | function info() {
function warn (line 1076) | function warn() {
function error (line 1080) | function error() {
function time (line 1084) | function time(label) {
function timeEnd (line 1088) | function timeEnd(label) {
function trace (line 1098) | function trace() {
function dir (line 1105) | function dir(object) {
function consoleAssert (line 1109) | function consoleAssert(expression) {
function now (line 1120) | function now() {
function EventEmitter (line 1146) | function EventEmitter() {
function g (line 1288) | function g() {
function isFunction (line 1411) | function isFunction(arg) {
function isNumber (line 1415) | function isNumber(arg) {
function isObject (line 1419) | function isObject(arg) {
function isUndefined (line 1423) | function isUndefined(arg) {
function apply (line 1899) | function apply(func, thisArg, args) {
function arrayAggregator (line 1919) | function arrayAggregator(array, setter, iteratee, accumulator) {
function arrayEach (line 1939) | function arrayEach(array, iteratee) {
function arrayEachRight (line 1960) | function arrayEachRight(array, iteratee) {
function arrayEvery (line 1981) | function arrayEvery(array, predicate) {
function arrayFilter (line 2002) | function arrayFilter(array, predicate) {
function arrayIncludes (line 2026) | function arrayIncludes(array, value) {
function arrayIncludesWith (line 2040) | function arrayIncludesWith(array, value, comparator) {
function arrayMap (line 2061) | function arrayMap(array, iteratee) {
function arrayPush (line 2080) | function arrayPush(array, values) {
function arrayReduce (line 2103) | function arrayReduce(array, iteratee, accumulator, initAccum) {
function arrayReduceRight (line 2128) | function arrayReduceRight(array, iteratee, accumulator, initAccum) {
function arraySome (line 2149) | function arraySome(array, predicate) {
function asciiToArray (line 2177) | function asciiToArray(string) {
function asciiWords (line 2188) | function asciiWords(string) {
function baseFindKey (line 2203) | function baseFindKey(collection, predicate, eachFunc) {
function baseFindIndex (line 2225) | function baseFindIndex(array, predicate, fromIndex, fromRight) {
function baseIndexOf (line 2246) | function baseIndexOf(array, value, fromIndex) {
function baseIndexOfWith (line 2262) | function baseIndexOfWith(array, value, fromIndex, comparator) {
function baseIsNaN (line 2281) | function baseIsNaN(value) {
function baseMean (line 2294) | function baseMean(array, iteratee) {
function baseProperty (line 2306) | function baseProperty(key) {
function basePropertyOf (line 2319) | function basePropertyOf(object) {
function baseReduce (line 2338) | function baseReduce(collection, iteratee, accumulator, initAccum, eachFu...
function baseSortBy (line 2357) | function baseSortBy(array, comparer) {
function baseSum (line 2376) | function baseSum(array, iteratee) {
function baseTimes (line 2399) | function baseTimes(n, iteratee) {
function baseToPairs (line 2418) | function baseToPairs(object, props) {
function baseUnary (line 2431) | function baseUnary(func) {
function baseValues (line 2447) | function baseValues(object, props) {
function cacheHas (line 2461) | function cacheHas(cache, key) {
function charsStartIndex (line 2474) | function charsStartIndex(strSymbols, chrSymbols) {
function charsEndIndex (line 2491) | function charsEndIndex(strSymbols, chrSymbols) {
function countHolders (line 2506) | function countHolders(array, placeholder) {
function escapeStringChar (line 2544) | function escapeStringChar(chr) {
function getValue (line 2556) | function getValue(object, key) {
function hasUnicode (line 2567) | function hasUnicode(string) {
function hasUnicodeWord (line 2578) | function hasUnicodeWord(string) {
function iteratorToArray (line 2589) | function iteratorToArray(iterator) {
function mapToArray (line 2606) | function mapToArray(map) {
function overArg (line 2624) | function overArg(func, transform) {
function replaceHolders (line 2639) | function replaceHolders(array, placeholder) {
function setToArray (line 2662) | function setToArray(set) {
function setToPairs (line 2679) | function setToPairs(set) {
function strictIndexOf (line 2699) | function strictIndexOf(array, value, fromIndex) {
function strictLastIndexOf (line 2721) | function strictLastIndexOf(array, value, fromIndex) {
function stringSize (line 2738) | function stringSize(string) {
function stringToArray (line 2751) | function stringToArray(string) {
function unicodeSize (line 2773) | function unicodeSize(string) {
function unicodeToArray (line 2788) | function unicodeToArray(string) {
function unicodeWords (line 2799) | function unicodeWords(string) {
function lodash (line 3076) | function lodash(value) {
function object (line 3097) | function object() {}
function baseLodash (line 3117) | function baseLodash() {
function LodashWrapper (line 3128) | function LodashWrapper(value, chainAll) {
function LazyWrapper (line 3213) | function LazyWrapper(value) {
function lazyClone (line 3231) | function lazyClone() {
function lazyReverse (line 3250) | function lazyReverse() {
function lazyValue (line 3270) | function lazyValue() {
function Hash (line 3332) | function Hash(entries) {
function hashClear (line 3350) | function hashClear() {
function hashDelete (line 3365) | function hashDelete(key) {
function hashGet (line 3380) | function hashGet(key) {
function hashHas (line 3398) | function hashHas(key) {
function hashSet (line 3413) | function hashSet(key, value) {
function ListCache (line 3436) | function ListCache(entries) {
function listCacheClear (line 3454) | function listCacheClear() {
function listCacheDelete (line 3468) | function listCacheDelete(key) {
function listCacheGet (line 3494) | function listCacheGet(key) {
function listCacheHas (line 3510) | function listCacheHas(key) {
function listCacheSet (line 3524) | function listCacheSet(key, value) {
function MapCache (line 3553) | function MapCache(entries) {
function mapCacheClear (line 3571) | function mapCacheClear() {
function mapCacheDelete (line 3589) | function mapCacheDelete(key) {
function mapCacheGet (line 3604) | function mapCacheGet(key) {
function mapCacheHas (line 3617) | function mapCacheHas(key) {
function mapCacheSet (line 3631) | function mapCacheSet(key, value) {
function SetCache (line 3657) | function SetCache(values) {
function setCacheAdd (line 3677) | function setCacheAdd(value) {
function setCacheHas (line 3691) | function setCacheHas(value) {
function Stack (line 3708) | function Stack(entries) {
function stackClear (line 3720) | function stackClear() {
function stackDelete (line 3734) | function stackDelete(key) {
function stackGet (line 3751) | function stackGet(key) {
function stackHas (line 3764) | function stackHas(key) {
function stackSet (line 3778) | function stackSet(key, value) {
function arrayLikeKeys (line 3811) | function arrayLikeKeys(value, inherited) {
function arraySample (line 3845) | function arraySample(array) {
function arraySampleSize (line 3858) | function arraySampleSize(array, n) {
function arrayShuffle (line 3869) | function arrayShuffle(array) {
function assignMergeValue (line 3882) | function assignMergeValue(object, key, value) {
function assignValue (line 3899) | function assignValue(object, key, value) {
function assocIndexOf (line 3915) | function assocIndexOf(array, key) {
function baseAggregator (line 3936) | function baseAggregator(collection, setter, iteratee, accumulator) {
function baseAssign (line 3952) | function baseAssign(object, source) {
function baseAssignIn (line 3965) | function baseAssignIn(object, source) {
function baseAssignValue (line 3978) | function baseAssignValue(object, key, value) {
function baseAt (line 3999) | function baseAt(object, paths) {
function baseClamp (line 4020) | function baseClamp(number, lower, upper) {
function baseClone (line 4048) | function baseClone(value, bitmask, customizer, key, object, stack) {
function baseConforms (line 4131) | function baseConforms(source) {
function baseConformsTo (line 4146) | function baseConformsTo(object, source, props) {
function baseDelay (line 4174) | function baseDelay(func, wait, args) {
function baseDifference (line 4192) | function baseDifference(array, values, iteratee, comparator) {
function baseEvery (line 4266) | function baseEvery(collection, predicate) {
function baseExtremum (line 4285) | function baseExtremum(array, iteratee, comparator) {
function baseFill (line 4314) | function baseFill(array, value, start, end) {
function baseFilter (line 4340) | function baseFilter(collection, predicate) {
function baseFlatten (line 4361) | function baseFlatten(array, depth, predicate, isStrict, result) {
function baseForOwn (line 4417) | function baseForOwn(object, iteratee) {
function baseForOwnRight (line 4429) | function baseForOwnRight(object, iteratee) {
function baseFunctions (line 4442) | function baseFunctions(object, props) {
function baseGet (line 4456) | function baseGet(object, path) {
function baseGetAllKeys (line 4479) | function baseGetAllKeys(object, keysFunc, symbolsFunc) {
function baseGetTag (line 4491) | function baseGetTag(value) {
function baseGt (line 4509) | function baseGt(value, other) {
function baseHas (line 4521) | function baseHas(object, key) {
function baseHasIn (line 4533) | function baseHasIn(object, key) {
function baseInRange (line 4546) | function baseInRange(number, start, end) {
function baseIntersection (line 4560) | function baseIntersection(arrays, iteratee, comparator) {
function baseInverter (line 4624) | function baseInverter(object, setter, iteratee, accumulator) {
function baseInvoke (line 4641) | function baseInvoke(object, path, args) {
function baseIsArguments (line 4655) | function baseIsArguments(value) {
function baseIsArrayBuffer (line 4666) | function baseIsArrayBuffer(value) {
function baseIsDate (line 4677) | function baseIsDate(value) {
function baseIsEqual (line 4695) | function baseIsEqual(value, other, bitmask, customizer, stack) {
function baseIsEqualDeep (line 4719) | function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, ...
function baseIsMap (line 4771) | function baseIsMap(value) {
function baseIsMatch (line 4785) | function baseIsMatch(object, source, matchData, customizer) {
function baseIsNative (line 4837) | function baseIsNative(value) {
function baseIsRegExp (line 4852) | function baseIsRegExp(value) {
function baseIsSet (line 4863) | function baseIsSet(value) {
function baseIsTypedArray (line 4874) | function baseIsTypedArray(value) {
function baseIteratee (line 4886) | function baseIteratee(value) {
function baseKeys (line 4910) | function baseKeys(object) {
function baseKeysIn (line 4930) | function baseKeysIn(object) {
function baseLt (line 4954) | function baseLt(value, other) {
function baseMap (line 4966) | function baseMap(collection, iteratee) {
function baseMatches (line 4983) | function baseMatches(source) {
function baseMatchesProperty (line 5001) | function baseMatchesProperty(path, srcValue) {
function baseMerge (line 5024) | function baseMerge(object, source, srcIndex, customizer, stack) {
function baseMergeDeep (line 5061) | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customi...
function baseNth (line 5131) | function baseNth(array, n) {
function baseOrderBy (line 5149) | function baseOrderBy(collection, iteratees, orders) {
function basePick (line 5187) | function basePick(object, paths) {
function basePickBy (line 5202) | function basePickBy(object, paths, predicate) {
function basePropertyDeep (line 5225) | function basePropertyDeep(path) {
function basePullAll (line 5242) | function basePullAll(array, values, iteratee, comparator) {
function basePullAt (line 5278) | function basePullAt(array, indexes) {
function baseRandom (line 5305) | function baseRandom(lower, upper) {
function baseRange (line 5320) | function baseRange(start, end, step, fromRight) {
function baseRepeat (line 5340) | function baseRepeat(string, n) {
function baseRest (line 5368) | function baseRest(func, start) {
function baseSample (line 5379) | function baseSample(collection) {
function baseSampleSize (line 5391) | function baseSampleSize(collection, n) {
function baseSet (line 5406) | function baseSet(object, path, value, customizer) {
function baseShuffle (line 5477) | function baseShuffle(collection) {
function baseSlice (line 5490) | function baseSlice(array, start, end) {
function baseSome (line 5520) | function baseSome(collection, predicate) {
function baseSortedIndex (line 5542) | function baseSortedIndex(array, value, retHighest) {
function baseSortedIndexBy (line 5576) | function baseSortedIndexBy(array, value, iteratee, retHighest) {
function baseSortedUniq (line 5628) | function baseSortedUniq(array, iteratee) {
function baseToNumber (line 5654) | function baseToNumber(value) {
function baseToString (line 5672) | function baseToString(value) {
function baseUniq (line 5697) | function baseUniq(array, iteratee, comparator) {
function baseUnset (line 5757) | function baseUnset(object, path) {
function baseUpdate (line 5773) | function baseUpdate(object, path, updater, customizer) {
function baseWhile (line 5788) | function baseWhile(array, predicate, isDrop, fromRight) {
function baseWrapperValue (line 5810) | function baseWrapperValue(value, actions) {
function baseXor (line 5830) | function baseXor(arrays, iteratee, comparator) {
function baseZipObject (line 5860) | function baseZipObject(props, values, assignFunc) {
function castArrayLikeObject (line 5880) | function castArrayLikeObject(value) {
function castFunction (line 5891) | function castFunction(value) {
function castPath (line 5903) | function castPath(value, object) {
function castSlice (line 5930) | function castSlice(array, start, end) {
function cloneBuffer (line 5954) | function cloneBuffer(buffer, isDeep) {
function cloneArrayBuffer (line 5972) | function cloneArrayBuffer(arrayBuffer) {
function cloneDataView (line 5986) | function cloneDataView(dataView, isDeep) {
function cloneRegExp (line 5998) | function cloneRegExp(regexp) {
function cloneSymbol (line 6011) | function cloneSymbol(symbol) {
function cloneTypedArray (line 6023) | function cloneTypedArray(typedArray, isDeep) {
function compareAscending (line 6036) | function compareAscending(value, other) {
function compareMultiple (line 6080) | function compareMultiple(object, other, orders) {
function composeArgs (line 6118) | function composeArgs(args, partials, holders, isCurried) {
function composeArgsRight (line 6153) | function composeArgsRight(args, partials, holders, isCurried) {
function copyArray (line 6187) | function copyArray(source, array) {
function copyObject (line 6208) | function copyObject(source, props, object, customizer) {
function copySymbols (line 6242) | function copySymbols(source, object) {
function copySymbolsIn (line 6254) | function copySymbolsIn(source, object) {
function createAggregator (line 6266) | function createAggregator(setter, initializer) {
function createAssigner (line 6282) | function createAssigner(assigner) {
function createBaseEach (line 6316) | function createBaseEach(eachFunc, fromRight) {
function createBaseFor (line 6344) | function createBaseFor(fromRight) {
function createBind (line 6371) | function createBind(func, bitmask, thisArg) {
function createCaseFirst (line 6389) | function createCaseFirst(methodName) {
function createCompounder (line 6416) | function createCompounder(callback) {
function createCtor (line 6430) | function createCtor(Ctor) {
function createCurry (line 6464) | function createCurry(func, bitmask, arity) {
function createFind (line 6499) | function createFind(findIndexFunc) {
function createFlow (line 6519) | function createFlow(fromRight) {
function createHybrid (line 6592) | function createHybrid(func, bitmask, thisArg, partials, holders, partial...
function createInverter (line 6654) | function createInverter(setter, toIteratee) {
function createMathOperation (line 6668) | function createMathOperation(operator, defaultValue) {
function createOver (line 6701) | function createOver(arrayFunc) {
function createPadding (line 6722) | function createPadding(length, chars) {
function createPartial (line 6747) | function createPartial(func, bitmask, thisArg, partials) {
function createRange (line 6777) | function createRange(fromRight) {
function createRelationalOperation (line 6802) | function createRelationalOperation(operator) {
function createRecurry (line 6829) | function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, pa...
function createRound (line 6862) | function createRound(methodName) {
function createToPairs (line 6898) | function createToPairs(keysFunc) {
function createWrap (line 6936) | function createWrap(func, bitmask, thisArg, partials, holders, argPos, a...
function customDefaultsAssignIn (line 7003) | function customDefaultsAssignIn(objValue, srcValue, key, object) {
function customDefaultsMerge (line 7025) | function customDefaultsMerge(objValue, srcValue, key, object, source, st...
function customOmitClone (line 7044) | function customOmitClone(value) {
function equalArrays (line 7061) | function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
function equalByTag (line 7140) | function equalByTag(object, other, tag, bitmask, customizer, equalFunc, ...
function equalObjects (line 7218) | function equalObjects(object, other, bitmask, customizer, equalFunc, sta...
function flatRest (line 7290) | function flatRest(func) {
function getAllKeys (line 7301) | function getAllKeys(object) {
function getAllKeysIn (line 7313) | function getAllKeysIn(object) {
function getFuncName (line 7335) | function getFuncName(func) {
function getHolder (line 7357) | function getHolder(func) {
function getIteratee (line 7373) | function getIteratee() {
function getMapData (line 7387) | function getMapData(map, key) {
function getMatchData (line 7401) | function getMatchData(object) {
function getNative (line 7422) | function getNative(object, key) {
function getRawTag (line 7434) | function getRawTag(value) {
function getView (line 7530) | function getView(start, end, transforms) {
function getWrapDetails (line 7555) | function getWrapDetails(source) {
function hasPath (line 7569) | function hasPath(object, path, hasFunc) {
function initCloneArray (line 7598) | function initCloneArray(array) {
function initCloneObject (line 7617) | function initCloneObject(object) {
function initCloneByTag (line 7635) | function initCloneByTag(object, tag, isDeep) {
function insertWrapDetails (line 7679) | function insertWrapDetails(source, details) {
function isFlattenable (line 7697) | function isFlattenable(value) {
function isIndex (line 7710) | function isIndex(value, length) {
function isIterateeCall (line 7730) | function isIterateeCall(value, index, object) {
function isKey (line 7752) | function isKey(value, object) {
function isKeyable (line 7772) | function isKeyable(value) {
function isLaziable (line 7787) | function isLaziable(func) {
function isMasked (line 7808) | function isMasked(func) {
function isPrototype (line 7828) | function isPrototype(value) {
function isStrictComparable (line 7843) | function isStrictComparable(value) {
function matchesStrictComparable (line 7856) | function matchesStrictComparable(key, srcValue) {
function memoizeCapped (line 7874) | function memoizeCapped(func) {
function mergeData (line 7902) | function mergeData(data, source) {
function nativeKeysIn (line 7966) | function nativeKeysIn(object) {
function objectToString (line 7983) | function objectToString(value) {
function overRest (line 7996) | function overRest(func, start, transform) {
function parent (line 8025) | function parent(object, path) {
function reorder (line 8039) | function reorder(array, indexes) {
function safeGet (line 8059) | function safeGet(object, key) {
function setWrapToString (line 8119) | function setWrapToString(wrapper, reference, bitmask) {
function shortOut (line 8133) | function shortOut(func) {
function shuffleSelf (line 8161) | function shuffleSelf(array, size) {
function toKey (line 8203) | function toKey(value) {
function toSource (line 8218) | function toSource(func) {
function updateWrapDetails (line 8238) | function updateWrapDetails(details, bitmask) {
function wrapperClone (line 8255) | function wrapperClone(wrapper) {
function chunk (line 8289) | function chunk(array, size, guard) {
function compact (line 8324) | function compact(array) {
function concat (line 8361) | function concat() {
function drop (line 8497) | function drop(array, n, guard) {
function dropRight (line 8531) | function dropRight(array, n, guard) {
function dropRightWhile (line 8576) | function dropRightWhile(array, predicate) {
function dropWhile (line 8617) | function dropWhile(array, predicate) {
function fill (line 8652) | function fill(array, value, start, end) {
function findIndex (line 8699) | function findIndex(array, predicate, fromIndex) {
function findLastIndex (line 8746) | function findLastIndex(array, predicate, fromIndex) {
function flatten (line 8775) | function flatten(array) {
function flattenDeep (line 8794) | function flattenDeep(array) {
function flattenDepth (line 8819) | function flattenDepth(array, depth) {
function fromPairs (line 8843) | function fromPairs(pairs) {
function head (line 8873) | function head(array) {
function indexOf (line 8900) | function indexOf(array, value, fromIndex) {
function initial (line 8926) | function initial(array) {
function join (line 9041) | function join(array, separator) {
function last (line 9059) | function last(array) {
function lastIndexOf (line 9085) | function lastIndexOf(array, value, fromIndex) {
function nth (line 9121) | function nth(array, n) {
function pullAll (line 9170) | function pullAll(array, values) {
function pullAllBy (line 9199) | function pullAllBy(array, values, iteratee) {
function pullAllWith (line 9228) | function pullAllWith(array, values, comparator) {
function remove (line 9297) | function remove(array, predicate) {
function reverse (line 9341) | function reverse(array) {
function slice (line 9361) | function slice(array, start, end) {
function sortedIndex (line 9394) | function sortedIndex(array, value) {
function sortedIndexBy (line 9423) | function sortedIndexBy(array, value, iteratee) {
function sortedIndexOf (line 9443) | function sortedIndexOf(array, value) {
function sortedLastIndex (line 9472) | function sortedLastIndex(array, value) {
function sortedLastIndexBy (line 9501) | function sortedLastIndexBy(array, value, iteratee) {
function sortedLastIndexOf (line 9521) | function sortedLastIndexOf(array, value) {
function sortedUniq (line 9547) | function sortedUniq(array) {
function sortedUniqBy (line 9569) | function sortedUniqBy(array, iteratee) {
function tail (line 9589) | function tail(array) {
function take (line 9619) | function take(array, n, guard) {
function takeRight (line 9652) | function takeRight(array, n, guard) {
function takeRightWhile (line 9697) | function takeRightWhile(array, predicate) {
function takeWhile (line 9738) | function takeWhile(array, predicate) {
function uniq (line 9840) | function uniq(array) {
function uniqBy (line 9867) | function uniqBy(array, iteratee) {
function uniqWith (line 9891) | function uniqWith(array, comparator) {
function unzip (line 9915) | function unzip(array) {
function unzipWith (line 9952) | function unzipWith(array, iteratee) {
function zipObject (line 10105) | function zipObject(props, values) {
function zipObjectDeep (line 10124) | function zipObjectDeep(props, values) {
function chain (line 10187) | function chain(value) {
function tap (line 10216) | function tap(value, interceptor) {
function thru (line 10244) | function thru(value, interceptor) {
function wrapperChain (line 10315) | function wrapperChain() {
function wrapperCommit (line 10345) | function wrapperCommit() {
function wrapperNext (line 10371) | function wrapperNext() {
function wrapperToIterator (line 10399) | function wrapperToIterator() {
function wrapperPlant (line 10427) | function wrapperPlant(value) {
function wrapperReverse (line 10467) | function wrapperReverse() {
function wrapperValue (line 10499) | function wrapperValue() {
function every (line 10576) | function every(collection, predicate, guard) {
function filter (line 10625) | function filter(collection, predicate) {
function flatMap (line 10710) | function flatMap(collection, iteratee) {
function flatMapDeep (line 10734) | function flatMapDeep(collection, iteratee) {
function flatMapDepth (line 10759) | function flatMapDepth(collection, iteratee, depth) {
function forEach (line 10794) | function forEach(collection, iteratee) {
function forEachRight (line 10819) | function forEachRight(collection, iteratee) {
function includes (line 10885) | function includes(collection, value, fromIndex, guard) {
function map (line 11006) | function map(collection, iteratee) {
function orderBy (line 11040) | function orderBy(collection, iteratees, orders, guard) {
function reduce (line 11131) | function reduce(collection, iteratee, accumulator) {
function reduceRight (line 11160) | function reduceRight(collection, iteratee, accumulator) {
function reject (line 11201) | function reject(collection, predicate) {
function sample (line 11220) | function sample(collection) {
function sampleSize (line 11245) | function sampleSize(collection, n, guard) {
function shuffle (line 11270) | function shuffle(collection) {
function size (line 11296) | function size(collection) {
function some (line 11346) | function some(collection, predicate, guard) {
function after (line 11444) | function after(n, func) {
function ary (line 11473) | function ary(func, n, guard) {
function before (line 11496) | function before(n, func) {
function curry (line 11652) | function curry(func, arity, guard) {
function curryRight (line 11697) | function curryRight(func, arity, guard) {
function debounce (line 11758) | function debounce(func, wait, options) {
function flip (line 11946) | function flip(func) {
function memoize (line 11994) | function memoize(func, resolver) {
function negate (line 12037) | function negate(predicate) {
function once (line 12071) | function once(func) {
function rest (line 12249) | function rest(func, start) {
function spread (line 12291) | function spread(func, start) {
function throttle (line 12351) | function throttle(func, wait, options) {
function unary (line 12384) | function unary(func) {
function wrap (line 12410) | function wrap(value, wrapper) {
function castArray (line 12449) | function castArray() {
function clone (line 12483) | function clone(value) {
function cloneWith (line 12518) | function cloneWith(value, customizer) {
function cloneDeep (line 12541) | function cloneDeep(value) {
function cloneDeepWith (line 12573) | function cloneDeepWith(value, customizer) {
function conformsTo (line 12602) | function conformsTo(object, source) {
function eq (line 12638) | function eq(value, other) {
function isArrayLike (line 12786) | function isArrayLike(value) {
function isArrayLikeObject (line 12815) | function isArrayLikeObject(value) {
function isBoolean (line 12836) | function isBoolean(value) {
function isElement (line 12896) | function isElement(value) {
function isEmpty (line 12933) | function isEmpty(value) {
function isEqual (line 12985) | function isEqual(value, other) {
function isEqualWith (line 13021) | function isEqualWith(value, other, customizer) {
function isError (line 13045) | function isError(value) {
function isFinite (line 13080) | function isFinite(value) {
function isFunction (line 13101) | function isFunction(value) {
function isInteger (line 13137) | function isInteger(value) {
function isLength (line 13167) | function isLength(value) {
function isObject (line 13197) | function isObject(value) {
function isObjectLike (line 13226) | function isObjectLike(value) {
function isMatch (line 13277) | function isMatch(object, source) {
function isMatchWith (line 13313) | function isMatchWith(object, source, customizer) {
function isNaN (line 13346) | function isNaN(value) {
function isNative (line 13379) | function isNative(value) {
function isNull (line 13403) | function isNull(value) {
function isNil (line 13427) | function isNil(value) {
function isNumber (line 13457) | function isNumber(value) {
function isPlainObject (line 13490) | function isPlainObject(value) {
function isSafeInteger (line 13549) | function isSafeInteger(value) {
function isString (line 13589) | function isString(value) {
function isSymbol (line 13611) | function isSymbol(value) {
function isUndefined (line 13652) | function isUndefined(value) {
function isWeakMap (line 13673) | function isWeakMap(value) {
function isWeakSet (line 13694) | function isWeakSet(value) {
function toArray (line 13773) | function toArray(value) {
function toFinite (line 13812) | function toFinite(value) {
function toInteger (line 13850) | function toInteger(value) {
function toLength (line 13884) | function toLength(value) {
function toNumber (line 13911) | function toNumber(value) {
function toPlainObject (line 13956) | function toPlainObject(value) {
function toSafeInteger (line 13984) | function toSafeInteger(value) {
function toString (line 14011) | function toString(value) {
function create (line 14214) | function create(prototype, properties) {
function findKey (line 14330) | function findKey(object, predicate) {
function findLastKey (line 14369) | function findLastKey(object, predicate) {
function forIn (line 14401) | function forIn(object, iteratee) {
function forInRight (line 14433) | function forInRight(object, iteratee) {
function forOwn (line 14467) | function forOwn(object, iteratee) {
function forOwnRight (line 14497) | function forOwnRight(object, iteratee) {
function functions (line 14524) | function functions(object) {
function functionsIn (line 14551) | function functionsIn(object) {
function get (line 14580) | function get(object, path, defaultValue) {
function has (line 14612) | function has(object, path) {
function hasIn (line 14642) | function hasIn(object, path) {
function keys (line 14760) | function keys(object) {
function keysIn (line 14787) | function keysIn(object) {
function mapKeys (line 14812) | function mapKeys(object, iteratee) {
function mapValues (line 14850) | function mapValues(object, iteratee) {
function omitBy (line 14992) | function omitBy(object, predicate) {
function pickBy (line 15035) | function pickBy(object, predicate) {
function result (line 15077) | function result(object, path, defaultValue) {
function set (line 15127) | function set(object, path, value) {
function setWith (line 15155) | function setWith(object, path, value, customizer) {
function transform (line 15242) | function transform(object, iteratee, accumulator) {
function unset (line 15292) | function unset(object, path) {
function update (line 15323) | function update(object, path, updater) {
function updateWith (line 15351) | function updateWith(object, path, updater, customizer) {
function values (line 15382) | function values(object) {
function valuesIn (line 15410) | function valuesIn(object) {
function clamp (line 15435) | function clamp(number, lower, upper) {
function inRange (line 15489) | function inRange(number, start, end) {
function random (line 15532) | function random(lower, upper, floating) {
function capitalize (line 15613) | function capitalize(string) {
function deburr (line 15635) | function deburr(string) {
function endsWith (line 15663) | function endsWith(string, target, position) {
function escape (line 15705) | function escape(string) {
function escapeRegExp (line 15727) | function escapeRegExp(string) {
function pad (line 15825) | function pad(string, length, chars) {
function padEnd (line 15864) | function padEnd(string, length, chars) {
function padStart (line 15897) | function padStart(string, length, chars) {
function parseInt (line 15931) | function parseInt(string, radix, guard) {
function repeat (line 15962) | function repeat(string, n, guard) {
function replace (line 15990) | function replace() {
function split (line 16041) | function split(string, separator, limit) {
function startsWith (line 16110) | function startsWith(string, target, position) {
function template (line 16224) | function template(string, options, guard) {
function toLower (line 16356) | function toLower(value) {
function toUpper (line 16381) | function toUpper(value) {
function trim (line 16407) | function trim(string, chars, guard) {
function trimEnd (line 16442) | function trimEnd(string, chars, guard) {
function trimStart (line 16475) | function trimStart(string, chars, guard) {
function truncate (line 16526) | function truncate(string, options) {
function unescape (line 16601) | function unescape(string) {
function words (line 16670) | function words(string, pattern, guard) {
function cond (line 16775) | function cond(pairs) {
function conforms (line 16821) | function conforms(source) {
function constant (line 16844) | function constant(value) {
function defaultTo (line 16870) | function defaultTo(value, defaultValue) {
function identity (line 16937) | function identity(value) {
function iteratee (line 16983) | function iteratee(func) {
function matches (line 17022) | function matches(source) {
function matchesProperty (line 17059) | function matchesProperty(path, srcValue) {
function mixin (line 17158) | function mixin(object, source, options) {
function noConflict (line 17207) | function noConflict() {
function noop (line 17226) | function noop() {
function nthArg (line 17250) | function nthArg(n) {
function property (line 17362) | function property(path) {
function propertyOf (line 17387) | function propertyOf(object) {
function stubArray (line 17492) | function stubArray() {
function stubFalse (line 17509) | function stubFalse() {
function stubObject (line 17531) | function stubObject() {
function stubString (line 17548) | function stubString() {
function stubTrue (line 17565) | function stubTrue() {
function times (line 17588) | function times(n, iteratee) {
function toPath (line 17623) | function toPath(value) {
function uniqueId (line 17647) | function uniqueId(prefix) {
function max (line 17756) | function max(array) {
function maxBy (line 17785) | function maxBy(array, iteratee) {
function mean (line 17805) | function mean(array) {
function meanBy (line 17832) | function meanBy(array, iteratee) {
function min (line 17854) | function min(array) {
function minBy (line 17883) | function minBy(array, iteratee) {
function sum (line 17964) | function sum(array) {
function sumBy (line 17993) | function sumBy(array, iteratee) {
function drainQueue (line 18599) | function drainQueue() {
function noop (line 18631) | function noop() {}
function isHex (line 18701) | function isHex(str) {
function isHexDigit (line 18705) | function isHexDigit(str) {
function asyncTrigger (line 18712) | function asyncTrigger() {
function Lexer (line 18756) | function Lexer(source) {
function commentToken (line 19076) | function commentToken(label, body, opt) {
function isNonAsciiIdentifierStart (line 19275) | function isNonAsciiIdentifierStart(code) {
function isNonAsciiIdentifierPart (line 19279) | function isNonAsciiIdentifierPart(code) {
function removeEscapeSequences (line 19361) | function removeEscapeSequences(id) {
function isDecimalDigit (line 19430) | function isDecimalDigit(str) {
function isOctalDigit (line 19434) | function isOctalDigit(str) {
function isNonOctalDigit (line 19438) | function isNonOctalDigit(str) {
function isBinaryDigit (line 19442) | function isBinaryDigit(str) {
function isIdentifierStart (line 19446) | function isIdentifierStart(ch) {
function NameStack (line 21260) | function NameStack() {
function _newScope (line 22609) | function _newScope(type) {
function warning (line 22632) | function warning(code, token) {
function error (line 22640) | function error(code, token) {
function _setupUsages (line 22648) | function _setupUsages(bindingName) {
function _checkForUnused (line 22702) | function _checkForUnused() {
function _getBinding (line 22754) | function _getBinding(bindingName) {
function usedSoFarInCurrentFunction (line 22771) | function usedSoFarInCurrentFunction(bindingName) {
function _checkOuterShadow (line 22784) | function _checkOuterShadow(bindingName, token) {
function _latedefWarning (line 22810) | function _latedefWarning(type, bindingName, token) {
function checkOption (line 25409) | function checkOption(name, isStable, t) {
function isString (line 25436) | function isString(obj) {
function isIdentifier (line 25440) | function isIdentifier(tkn, value) {
function isReserved (line 25467) | function isReserved(context, token) {
function supplant (line 25506) | function supplant(str, data) {
function combine (line 25513) | function combine(dest, src) {
function processenforceall (line 25520) | function processenforceall() {
function applyOptions (line 25539) | function applyOptions() {
function quit (line 25675) | function quit(code, token, a, b) {
function removeIgnoredMessages (line 25696) | function removeIgnoredMessages() {
function warning (line 25703) | function warning(code, t, a, b, c, d) {
function warningAt (line 25751) | function warningAt(m, l, ch, a, b, c, d) {
function error (line 25758) | function error(m, t, a, b, c, d) {
function errorAt (line 25762) | function errorAt(m, l, ch, a, b, c, d) {
function addEvalCode (line 25770) | function addEvalCode(elem, token) {
function lintingDirective (line 25785) | function lintingDirective(directiveToken, previous) {
function peek (line 26104) | function peek(p) {
function peekIgnoreEOL (line 26135) | function peekIgnoreEOL() {
function advance (line 26157) | function advance(expected, relatedToken) {
function isOperator (line 26207) | function isOperator(token) {
function isEndOfExpr (line 26211) | function isEndOfExpr(context, curr, next) {
function expression (line 26263) | function expression(context, rbp) {
function sameLine (line 26341) | function sameLine(first, second) {
function nobreaknonadjacent (line 26345) | function nobreaknonadjacent(left, right) {
function nolinebreak (line 26351) | function nolinebreak(t) {
function checkComma (line 26372) | function checkComma(opts) {
function symbol (line 26452) | function symbol(s, p) {
function delim (line 26479) | function delim(s) {
function stmt (line 26495) | function stmt(s, f) {
function blockstmt (line 26515) | function blockstmt(s, f) {
function reserveName (line 26527) | function reserveName(x) {
function prefix (line 26546) | function prefix(s, f) {
function type (line 26581) | function type(s, f) {
function reserve (line 26601) | function reserve(name, func) {
function FutureReservedWord (line 26624) | function FutureReservedWord(name, meta) {
function infix (line 26652) | function infix(s, f, p, w) {
function application (line 26683) | function application(s) {
function relation (line 26707) | function relation(s, f) {
function beginsUnaryExpression (line 26746) | function beginsUnaryExpression(token) {
function isTypoTypeof (line 26782) | function isTypoTypeof(left, right, state) {
function isGlobalEval (line 26816) | function isGlobalEval(left, state) {
function findNativePrototype (line 26844) | function findNativePrototype(left) {
function checkLeftSideAssign (line 26889) | function checkLeftSideAssign(context, left, assignToken, options) {
function assignop (line 26964) | function assignop(s, f) {
function bitwise (line 26993) | function bitwise(s, f, p) {
function bitwiseassignop (line 27017) | function bitwiseassignop(s) {
function suffix (line 27041) | function suffix(s) {
function optionalidentifier (line 27071) | function optionalidentifier(context, isName, preserve) {
function spreadrest (line 27099) | function spreadrest(operation) {
function identifier (line 27129) | function identifier(context, isName) {
function reachable (line 27153) | function reachable(controlToken) {
function parseFinalSemicolon (line 27187) | function parseFinalSemicolon(stmt) {
function statement (line 27220) | function statement(context) {
function statements (line 27320) | function statements(context) {
function directives (line 27343) | function directives() {
function block (line 27397) | function block(context, ordinary, stmt, isfunc, isfatarrow, iscase) {
function countMember (line 27552) | function countMember(m) {
function classBody (line 28187) | function classBody(classToken, context) {
function doMethod (line 28316) | function doMethod(classToken, context, name, generator) {
function isTypicalCallExpression (line 28419) | function isTypicalCallExpression(token) {
function peekThroughParens (line 28525) | function peekThroughParens(parens) {
function comprehensiveArrayExpression (line 28720) | function comprehensiveArrayExpression(context) {
function isMethod (line 28844) | function isMethod() {
function propertyName (line 28857) | function propertyName(context) {
function functionparams (line 28888) | function functionparams(context, options) {
function functor (line 29007) | function functor(name, token, overwrites) {
function hasParsedCode (line 29059) | function hasParsedCode(funct) {
function doTemplateLiteral (line 29067) | function doTemplateLiteral(context, leftOrRbp) {
function doFunction (line 29126) | function doFunction(context, options) {
function createMetrics (line 29253) | function createMetrics(functionStartToken) {
function increaseComplexityCount (line 29292) | function increaseComplexityCount() {
function checkCondAssignment (line 29299) | function checkCondAssignment(token) {
function checkProperties (line 29332) | function checkProperties(props) {
function metaProperty (line 29344) | function metaProperty(context, name, c) {
function destructuringPattern (line 29533) | function destructuringPattern(context, options) {
function destructuringPatternRecursive (line 29546) | function destructuringPatternRecursive(context, options) {
function destructuringPatternMatch (line 29711) | function destructuringPatternMatch(tokens, value) {
function blockVariableStatement (line 29729) | function blockVariableStatement(type, statement, context) {
function isMozillaLet (line 29873) | function isMozillaLet() {
function catchParameter (line 30167) | function catchParameter() {
function supportsSuper (line 31229) | function supportsSuper(type, funct) {
function saveProperty (line 31354) | function saveProperty(props, name, tkn, isClass, isStatic, isComputed) {
function saveAccessor (line 31388) | function saveAccessor(accessorType, props, name, tkn, isClass, isStatic) {
function computedPropertyName (line 31433) | function computedPropertyName(context) {
function checkPunctuators (line 31460) | function checkPunctuators(token, values) {
function checkPunctuator (line 31478) | function checkPunctuator(token, value) {
function destructuringAssignOrJsonValue (line 31483) | function destructuringAssignOrJsonValue(context) {
function declare (line 31521) | function declare(v) {
function use (line 31531) | function use(v) {
function jsonValue (line 31615) | function jsonValue() {
function lintEvalCode (line 31707) | function lintEvalCode(internals, options, globals) {
function each (line 31753) | function each(obj, cb) {
method isJSON (line 31836) | get isJSON() {
FILE: web/assets/codemirror/jsonlint.js
function o (line 1) | function o(a){d.length=d.length-2*a,e.length=e.length-a,f.length=f.lengt...
function p (line 1) | function p(){var a;return a=c.lexer.lex()||1,typeof a!="number"&&(a=c.sy...
FILE: web/assets/codemirror/lint/javascript-lint.js
function validator (line 17) | function validator(text, options) {
function parseErrors (line 34) | function parseErrors(errors, output) {
FILE: web/assets/codemirror/lint/lint.js
function showTooltip (line 16) | function showTooltip(cm, e, content) {
function rm (line 37) | function rm(elt) {
function hideTooltip (line 40) | function hideTooltip(tt) {
function showTooltipFor (line 47) | function showTooltipFor(cm, e, content, node) {
function LintState (line 64) | function LintState(cm, conf, hasGutter) {
function clearMarks (line 96) | function clearMarks(cm) {
function clearErrorLines (line 105) | function clearErrorLines(cm) {
function makeMarker (line 112) | function makeMarker(cm, labels, severity, multiple, tooltips) {
function getMaxSeverity (line 127) | function getMaxSeverity(a, b) {
function groupByLine (line 132) | function groupByLine(annotations) {
function annotationTooltip (line 141) | function annotationTooltip(ann) {
function lintAsync (line 154) | function lintAsync(cm, getAnnotations) {
function startLinting (line 170) | function startLinting(cm) {
function updateLinting (line 192) | function updateLinting(cm, annotationsNotSorted) {
function onChange (line 231) | function onChange(cm) {
function popupTooltips (line 238) | function popupTooltips(cm, annotations, e) {
function onMouseOver (line 248) | function onMouseOver(cm, e) {
FILE: web/assets/js/langs.js
function getLang (line 44) | function getLang() {
function setLang (line 66) | function setLang(lang) {
function isSupportLang (line 75) | function isSupportLang(lang) {
FILE: web/assets/js/model/dbinbound.js
class DBInbound (line 1) | class DBInbound {
method constructor (line 3) | constructor(data) {
method totalGB (line 27) | get totalGB() {
method totalGB (line 31) | set totalGB(gb) {
method isVMess (line 35) | get isVMess() {
method isVLess (line 39) | get isVLess() {
method isTrojan (line 43) | get isTrojan() {
method isSS (line 47) | get isSS() {
method isSocks (line 51) | get isSocks() {
method isHTTP (line 55) | get isHTTP() {
method isWireguard (line 59) | get isWireguard() {
method address (line 63) | get address() {
method _expiryTime (line 71) | get _expiryTime() {
method _expiryTime (line 78) | set _expiryTime(t) {
method isExpiry (line 86) | get isExpiry() {
method toInbound (line 90) | toInbound() {
method isMultiUser (line 119) | isMultiUser() {
method hasLink (line 132) | hasLink() {
method genInboundLinks (line 144) | genInboundLinks(remarkModel) {
FILE: web/assets/js/model/outbound.js
constant TLS_FLOW_CONTROL (line 26) | const TLS_FLOW_CONTROL = {
constant UTLS_FINGERPRINT (line 31) | const UTLS_FINGERPRINT = {
constant ALPN_OPTION (line 44) | const ALPN_OPTION = {
class CommonClass (line 79) | class CommonClass {
method toJsonArray (line 81) | static toJsonArray(arr) {
method fromJson (line 85) | static fromJson() {
method toJson (line 89) | toJson() {
method toString (line 93) | toString(format=true) {
class TcpStreamSettings (line 98) | class TcpStreamSettings extends CommonClass {
method constructor (line 99) | constructor(type='none', host, path) {
method fromJson (line 106) | static fromJson(json={}) {
method toJson (line 119) | toJson() {
class KcpStreamSettings (line 134) | class KcpStreamSettings extends CommonClass {
method constructor (line 135) | constructor(mtu=1350, tti=20,
method fromJson (line 156) | static fromJson(json={}) {
method toJson (line 170) | toJson() {
class WsStreamSettings (line 187) | class WsStreamSettings extends CommonClass {
method constructor (line 188) | constructor(path='/', host='') {
method fromJson (line 194) | static fromJson(json={}) {
method toJson (line 201) | toJson() {
class HttpStreamSettings (line 209) | class HttpStreamSettings extends CommonClass {
method constructor (line 210) | constructor(path='/', host='') {
method fromJson (line 216) | static fromJson(json={}) {
method toJson (line 223) | toJson() {
class QuicStreamSettings (line 231) | class QuicStreamSettings extends CommonClass {
method constructor (line 232) | constructor(security='none',
method fromJson (line 240) | static fromJson(json={}) {
method toJson (line 248) | toJson() {
class GrpcStreamSettings (line 259) | class GrpcStreamSettings extends CommonClass {
method constructor (line 260) | constructor(serviceName="", authority="", multiMode=false) {
method fromJson (line 267) | static fromJson(json={}) {
method toJson (line 271) | toJson() {
class HttpUpgradeStreamSettings (line 280) | class HttpUpgradeStreamSettings extends CommonClass {
method constructor (line 281) | constructor(path='/', host='') {
method fromJson (line 287) | static fromJson(json={}) {
method toJson (line 294) | toJson() {
class SplitHTTPStreamSettings (line 302) | class SplitHTTPStreamSettings extends CommonClass {
method constructor (line 303) | constructor(path='/', host='') {
method fromJson (line 309) | static fromJson(json={}) {
method toJson (line 316) | toJson() {
class TlsStreamSettings (line 324) | class TlsStreamSettings extends CommonClass {
method constructor (line 325) | constructor(serverName='',
method fromJson (line 336) | static fromJson(json={}) {
method toJson (line 345) | toJson() {
class RealityStreamSettings (line 355) | class RealityStreamSettings extends CommonClass {
method constructor (line 356) | constructor(publicKey = '', fingerprint = '', serverName = '', shortId...
method fromJson (line 364) | static fromJson(json = {}) {
method toJson (line 373) | toJson() {
class SockoptStreamSettings (line 383) | class SockoptStreamSettings extends CommonClass {
method constructor (line 384) | constructor(dialerProxy = "", tcpFastOpen = false, tcpKeepAliveInterva...
method fromJson (line 393) | static fromJson(json = {}) {
method toJson (line 404) | toJson() {
class StreamSettings (line 415) | class StreamSettings extends CommonClass {
method constructor (line 416) | constructor(network='tcp',
method isTls (line 446) | get isTls() {
method isReality (line 450) | get isReality() {
method sockoptSwitch (line 454) | get sockoptSwitch() {
method sockoptSwitch (line 458) | set sockoptSwitch(value) {
method fromJson (line 462) | static fromJson(json={}) {
method toJson (line 480) | toJson() {
class Mux (line 500) | class Mux extends CommonClass {
method constructor (line 501) | constructor(enabled = false, concurrency = 8, xudpConcurrency = 16, xu...
method fromJson (line 509) | static fromJson(json = {}) {
method toJson (line 519) | toJson() {
class Outbound (line 529) | class Outbound extends CommonClass {
method constructor (line 530) | constructor(
method protocol (line 547) | get protocol() {
method protocol (line 551) | set protocol(protocol) {
method canEnableTls (line 557) | canEnableTls() {
method canEnableTlsFlow (line 563) | canEnableTlsFlow() {
method canEnableReality (line 570) | canEnableReality() {
method canEnableStream (line 575) | canEnableStream() {
method canEnableMux (line 579) | canEnableMux() {
method hasVnext (line 583) | hasVnext() {
method hasServers (line 587) | hasServers() {
method hasAddressPort (line 591) | hasAddressPort() {
method hasUsername (line 603) | hasUsername() {
method fromJson (line 607) | static fromJson(json={}) {
method toJson (line 618) | toJson() {
method fromLink (line 636) | static fromLink(link) {
method fromVmessLink (line 651) | static fromVmessLink(json={}){
method fromParamLink (line 697) | static fromParamLink(link){
method constructor (line 783) | constructor(protocol) {
method getSettings (line 788) | static getSettings(protocol) {
method fromJson (line 804) | static fromJson(protocol, json) {
method toJson (line 820) | toJson() {
method constructor (line 825) | constructor(domainStrategy='', fragment={}) {
method fromJson (line 831) | static fromJson(json={}) {
method toJson (line 838) | toJson() {
method constructor (line 846) | constructor(packets='1-3',length='',interval=''){
method fromJson (line 853) | static fromJson(json={}) {
method constructor (line 862) | constructor(type) {
method fromJson (line 867) | static fromJson(json={}) {
method toJson (line 873) | toJson() {
method constructor (line 880) | constructor(network='udp', address='1.1.1.1', port=53) {
method fromJson (line 887) | static fromJson(json={}){
method constructor (line 896) | constructor(address, port, id) {
method fromJson (line 903) | static fromJson(json={}) {
method toJson (line 912) | toJson() {
method constructor (line 923) | constructor(address, port, id, flow, encryption='none') {
method fromJson (line 932) | static fromJson(json={}) {
method toJson (line 943) | toJson() {
method constructor (line 954) | constructor(address, port, password) {
method fromJson (line 961) | static fromJson(json={}) {
method toJson (line 970) | toJson() {
method constructor (line 981) | constructor(address, port, password, method, uot, UoTVersion) {
method fromJson (line 991) | static fromJson(json={}) {
method toJson (line 1004) | toJson() {
method constructor (line 1019) | constructor(address, port, user, pass) {
method fromJson (line 1027) | static fromJson(json={}) {
method toJson (line 1038) | toJson() {
method constructor (line 1049) | constructor(address, port, user, pass) {
method fromJson (line 1057) | static fromJson(json={}) {
method toJson (line 1068) | toJson() {
method constructor (line 1080) | constructor(
method addPeer (line 1096) | addPeer() {
method delPeer (line 1100) | delPeer(index) {
method fromJson (line 1104) | static fromJson(json={}){
method toJson (line 1117) | toJson() {
method constructor (line 1132) | constructor(publicKey='', psk='', allowedIPs=['0.0.0.0/0','::/0'], endpo...
method fromJson (line 1141) | static fromJson(json={}){
method toJson (line 1151) | toJson() {
FILE: web/assets/js/model/setting.js
class AllSetting (line 1) | class AllSetting {
method constructor (line 3) | constructor(data) {
method equals (line 52) | equals(other) {
FILE: web/assets/js/model/xray.js
constant XTLS_FLOW_CONTROL (line 24) | const XTLS_FLOW_CONTROL = {
constant TLS_FLOW_CONTROL (line 29) | const TLS_FLOW_CONTROL = {
constant TLS_VERSION_OPTION (line 34) | const TLS_VERSION_OPTION = {
constant TLS_CIPHER_OPTION (line 41) | const TLS_CIPHER_OPTION = {
constant UTLS_FINGERPRINT (line 61) | const UTLS_FINGERPRINT = {
constant ALPN_OPTION (line 74) | const ALPN_OPTION = {
constant SNIFFING_OPTION (line 80) | const SNIFFING_OPTION = {
constant USAGE_OPTION (line 87) | const USAGE_OPTION = {
constant DOMAIN_STRATEGY_OPTION (line 93) | const DOMAIN_STRATEGY_OPTION = {
constant TCP_CONGESTION_OPTION (line 106) | const TCP_CONGESTION_OPTION = {
class XrayCommonClass (line 125) | class XrayCommonClass {
method toJsonArray (line 127) | static toJsonArray(arr) {
method fromJson (line 131) | static fromJson() {
method toJson (line 135) | toJson() {
method toString (line 139) | toString(format=true) {
method toHeaders (line 143) | static toHeaders(v2Headers) {
method toV2Headers (line 160) | static toV2Headers(headers, arr=true) {
class TcpStreamSettings (line 182) | class TcpStreamSettings extends XrayCommonClass {
method constructor (line 183) | constructor(acceptProxyProtocol=false,
method fromJson (line 195) | static fromJson(json={}) {
method toJson (line 207) | toJson() {
method constructor (line 220) | constructor(version='1.1',
method addPath (line 232) | addPath(path) {
method removePath (line 236) | removePath(index) {
method addHeader (line 240) | addHeader(name, value) {
method removeHeader (line 244) | removeHeader(index) {
method fromJson (line 248) | static fromJson(json={}) {
method toJson (line 257) | toJson() {
method constructor (line 268) | constructor(version='1.1',
method addHeader (line 280) | addHeader(name, value) {
method removeHeader (line 284) | removeHeader(index) {
method fromJson (line 288) | static fromJson(json={}) {
method toJson (line 297) | toJson() {
class KcpStreamSettings (line 307) | class KcpStreamSettings extends XrayCommonClass {
method constructor (line 308) | constructor(mtu=1350, tti=20,
method fromJson (line 329) | static fromJson(json={}) {
method toJson (line 343) | toJson() {
class WsStreamSettings (line 360) | class WsStreamSettings extends XrayCommonClass {
method constructor (line 361) | constructor(acceptProxyProtocol=false, path='/', host='', headers=[]) {
method addHeader (line 369) | addHeader(name, value) {
method removeHeader (line 373) | removeHeader(index) {
method fromJson (line 377) | static fromJson(json={}) {
method toJson (line 386) | toJson() {
class HttpStreamSettings (line 396) | class HttpStreamSettings extends XrayCommonClass {
method constructor (line 397) | constructor(
method addHost (line 406) | addHost(host) {
method removeHost (line 410) | removeHost(index) {
method fromJson (line 414) | static fromJson(json={}) {
method toJson (line 418) | toJson() {
class QuicStreamSettings (line 432) | class QuicStreamSettings extends XrayCommonClass {
method constructor (line 433) | constructor(security='none',
method fromJson (line 441) | static fromJson(json={}) {
method toJson (line 449) | toJson() {
class GrpcStreamSettings (line 460) | class GrpcStreamSettings extends XrayCommonClass {
method constructor (line 461) | constructor(
method fromJson (line 472) | static fromJson(json={}) {
method toJson (line 480) | toJson() {
class HTTPUpgradeStreamSettings (line 489) | class HTTPUpgradeStreamSettings extends XrayCommonClass {
method constructor (line 490) | constructor(acceptProxyProtocol=false, path='/', host='', headers=[]) {
method addHeader (line 498) | addHeader(name, value) {
method removeHeader (line 502) | removeHeader(index) {
method fromJson (line 506) | static fromJson(json={}) {
method toJson (line 515) | toJson() {
class SplitHTTPStreamSettings (line 525) | class SplitHTTPStreamSettings extends XrayCommonClass {
method constructor (line 526) | constructor(path='/', host='', headers=[] , maxUploadSize= 1000000, ma...
method addHeader (line 535) | addHeader(name, value) {
method removeHeader (line 539) | removeHeader(index) {
method fromJson (line 543) | static fromJson(json={}) {
method toJson (line 553) | toJson() {
class TlsStreamSettings (line 564) | class TlsStreamSettings extends XrayCommonClass {
method constructor (line 565) | constructor(serverName='',
method addCert (line 588) | addCert() {
method removeCert (line 592) | removeCert(index) {
method fromJson (line 596) | static fromJson(json={}) {
method toJson (line 620) | toJson() {
method constructor (line 637) | constructor(useFile=true, certificateFile='', keyFile='', certificate=''...
method fromJson (line 649) | static fromJson(json={}) {
method toJson (line 671) | toJson() {
method constructor (line 693) | constructor(allowInsecure = false, fingerprint = '') {
method fromJson (line 698) | static fromJson(json = {}) {
method toJson (line 704) | toJson() {
class XtlsStreamSettings (line 712) | class XtlsStreamSettings extends XrayCommonClass {
method constructor (line 713) | constructor(serverName='',
method addCert (line 724) | addCert() {
method removeCert (line 728) | removeCert(index) {
method fromJson (line 732) | static fromJson(json={}) {
method toJson (line 750) | toJson() {
method constructor (line 761) | constructor(useFile=true, certificateFile='', keyFile='', certificate=''...
method fromJson (line 773) | static fromJson(json={}) {
method toJson (line 795) | toJson() {
method constructor (line 817) | constructor(allowInsecure = false) {
method fromJson (line 821) | static fromJson(json = {}) {
method toJson (line 826) | toJson() {
class RealityStreamSettings (line 833) | class RealityStreamSettings extends XrayCommonClass {
method constructor (line 835) | constructor(
method fromJson (line 859) | static fromJson(json = {}) {
method toJson (line 878) | toJson() {
method constructor (line 895) | constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_CHROME, ...
method fromJson (line 902) | static fromJson(json = {}) {
method toJson (line 910) | toJson() {
class SockoptStreamSettings (line 920) | class SockoptStreamSettings extends XrayCommonClass {
method constructor (line 921) | constructor(
method fromJson (line 958) | static fromJson(json = {}) {
method toJson (line 980) | toJson() {
class StreamSettings (line 1002) | class StreamSettings extends XrayCommonClass {
method constructor (line 1003) | constructor(network='tcp',
method isTls (line 1037) | get isTls() {
method isTls (line 1041) | set isTls(isTls) {
method isXtls (line 1049) | get isXtls() {
method isXtls (line 1053) | set isXtls(isXtls) {
method isReality (line 1062) | get isReality() {
method isReality (line 1066) | set isReality(isReality) {
method sockoptSwitch (line 1074) | get sockoptSwitch() {
method sockoptSwitch (line 1078) | set sockoptSwitch(value) {
method fromJson (line 1082) | static fromJson(json={}) {
method toJson (line 1102) | toJson() {
class Sniffing (line 1124) | class Sniffing extends XrayCommonClass {
method constructor (line 1125) | constructor(
method fromJson (line 1137) | static fromJson(json={}) {
class Inbound (line 1153) | class Inbound extends XrayCommonClass {
method constructor (line 1154) | constructor(port=RandomUtil.randomIntRange(10000, 60000),
method getClientStats (line 1173) | getClientStats() {
method clients (line 1177) | get clients() {
method protocol (line 1187) | get protocol() {
method protocol (line 1191) | set protocol(protocol) {
method xtls (line 1199) | get xtls() {
method xtls (line 1203) | set xtls(isXtls) {
method network (line 1211) | get network() {
method network (line 1215) | set network(network) {
method isTcp (line 1219) | get isTcp() {
method isWs (line 1223) | get isWs() {
method isKcp (line 1227) | get isKcp() {
method isQuic (line 1231) | get isQuic() {
method isGrpc (line 1235) | get isGrpc() {
method isH2 (line 1239) | get isH2() {
method isHttpupgrade (line 1243) | get isHttpupgrade() {
method isSplithttp (line 1247) | get isSplithttp() {
method method (line 1252) | get method() {
method isSSMultiUser (line 1260) | get isSSMultiUser() {
method isSS2022 (line 1263) | get isSS2022(){
method serverName (line 1267) | get serverName() {
method getHeader (line 1274) | getHeader(obj, name) {
method host (line 1283) | get host() {
method path (line 1298) | get path() {
method quicSecurity (line 1313) | get quicSecurity() {
method quicKey (line 1317) | get quicKey() {
method quicType (line 1321) | get quicType() {
method kcpType (line 1325) | get kcpType() {
method kcpSeed (line 1329) | get kcpSeed() {
method serviceName (line 1333) | get serviceName() {
method isExpiry (line 1337) | isExpiry(index) {
method canEnableTls (line 1342) | canEnableTls() {
method canEnableTlsFlow (line 1348) | canEnableTlsFlow() {
method canEnableReality (line 1355) | canEnableReality() {
method canEnableXtls (line 1360) | canEnableXtls() {
method canEnableStream (line 1365) | canEnableStream() {
method reset (line 1369) | reset() {
method genVmessLink (line 1379) | genVmessLink(address='', port=this.port, forceTls, remark='', clientId) {
method genVLESSLink (line 1454) | genVLESSLink(address = '', port=this.port, forceTls, remark='', client...
method genSSLink (line 1575) | genSSLink(address = '', port = this.port, forceTls, remark = '', clien...
method genTrojanLink (line 1664) | genTrojanLink(address = '', port=this.port, forceTls, remark = '', cli...
method getWireguardLink (line 1778) | getWireguardLink(address, port, remark, peerId) {
method genLink (line 1800) | genLink(address='', port=this.port, forceTls='same', remark='', client) {
method genAllLinks (line 1814) | genAllLinks(remark='', remarkModel = '-ieo', client){
method genInboundLinks (line 1845) | genInboundLinks(remark = '', remarkModel = '-ieo') {
method fromJson (line 1868) | static fromJson(json={}) {
method toJson (line 1881) | toJson() {
method constructor (line 1900) | constructor(protocol) {
method getSettings (line 1905) | static getSettings(protocol) {
method fromJson (line 1919) | static fromJson(protocol, json) {
method toJson (line 1933) | toJson() {
method constructor (line 1939) | constructor(protocol,
method indexOfVmessById (line 1945) | indexOfVmessById(id) {
method addVmess (line 1949) | addVmess(vmess) {
method delVmess (line 1956) | delVmess(vmess) {
method fromJson (line 1963) | static fromJson(json={}) {
method toJson (line 1970) | toJson() {
method constructor (line 1977) | constructor(id=RandomUtil.randomUUID(), email=RandomUtil.randomLowerAndN...
method fromJson (line 1990) | static fromJson(json={}) {
method _expiryTime (line 2003) | get _expiryTime() {
method _expiryTime (line 2013) | set _expiryTime(t) {
method _totalGB (line 2020) | get _totalGB() {
method _totalGB (line 2024) | set _totalGB(gb) {
method constructor (line 2031) | constructor(protocol,
method addFallback (line 2041) | addFallback() {
method delFallback (line 2045) | delFallback(index) {
method fromJson (line 2050) | static fromJson(json={}) {
method toJson (line 2058) | toJson() {
method constructor (line 2068) | constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.random...
method fromJson (line 2082) | static fromJson(json={}) {
method _expiryTime (line 2097) | get _expiryTime() {
method _expiryTime (line 2107) | set _expiryTime(t) {
method _totalGB (line 2114) | get _totalGB() {
method _totalGB (line 2118) | set _totalGB(gb) {
method constructor (line 2123) | constructor(name="", alpn='', path='', dest='', xver=0) {
method toJson (line 2132) | toJson() {
method fromJson (line 2146) | static fromJson(json=[]) {
method constructor (line 2162) | constructor(protocol,
method addFallback (line 2170) | addFallback() {
method delFallback (line 2174) | delFallback(index) {
method fromJson (line 2178) | static fromJson(json={}) {
method toJson (line 2185) | toJson() {
method constructor (line 2193) | constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil...
method toJson (line 2207) | toJson() {
method fromJson (line 2222) | static fromJson(json = {}) {
method _expiryTime (line 2237) | get _expiryTime() {
method _expiryTime (line 2247) | set _expiryTime(t) {
method _totalGB (line 2254) | get _totalGB() {
method _totalGB (line 2258) | set _totalGB(gb) {
method constructor (line 2265) | constructor(name="", alpn='', path='', dest='', xver=0) {
method toJson (line 2274) | toJson() {
method fromJson (line 2288) | static fromJson(json=[]) {
method constructor (line 2304) | constructor(protocol,
method fromJson (line 2317) | static fromJson(json={}) {
method toJson (line 2327) | toJson() {
method constructor (line 2338) | constructor(method='', password=RandomUtil.randomShadowsocksPassword(), ...
method toJson (line 2352) | toJson() {
method fromJson (line 2367) | static fromJson(json = {}) {
method _expiryTime (line 2382) | get _expiryTime() {
method _expiryTime (line 2392) | set _expiryTime(t) {
method _totalGB (line 2399) | get _totalGB() {
method _totalGB (line 2403) | set _totalGB(gb) {
method constructor (line 2410) | constructor(protocol, address, port, network='tcp,udp', followRedirect=f...
method fromJson (line 2419) | static fromJson(json={}) {
method toJson (line 2430) | toJson() {
method constructor (line 2442) | constructor(protocol, auth='password', accounts=[new Inbound.SocksSettin...
method addAccount (line 2450) | addAccount(account) {
method delAccount (line 2454) | delAccount(index) {
method fromJson (line 2458) | static fromJson(json={}) {
method toJson (line 2474) | toJson() {
method constructor (line 2484) | constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
method fromJson (line 2490) | static fromJson(json={}) {
method constructor (line 2496) | constructor(protocol, accounts=[new Inbound.HttpSettings.HttpAccount()]) {
method addAccount (line 2501) | addAccount(account) {
method delAccount (line 2505) | delAccount(index) {
method fromJson (line 2509) | static fromJson(json={}) {
method toJson (line 2516) | toJson() {
method constructor (line 2524) | constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
method fromJson (line 2530) | static fromJson(json={}) {
method constructor (line 2536) | constructor(protocol, mtu=1420, secretKey=Wireguard.generateKeypair().pr...
method addPeer (line 2545) | addPeer() {
method delPeer (line 2549) | delPeer(index) {
method fromJson (line 2553) | static fromJson(json={}){
method toJson (line 2563) | toJson() {
method constructor (line 2574) | constructor(privateKey, publicKey, psk='', allowedIPs=['10.0.0.2/32'], k...
method fromJson (line 2589) | static fromJson(json={}){
method toJson (line 2599) | toJson() {
FILE: web/assets/js/util/common.js
constant ONE_KB (line 1) | const ONE_KB = 1024;
constant ONE_MB (line 2) | const ONE_MB = ONE_KB * 1024;
constant ONE_GB (line 3) | const ONE_GB = ONE_MB * 1024;
constant ONE_TB (line 4) | const ONE_TB = ONE_GB * 1024;
constant ONE_PB (line 5) | const ONE_PB = ONE_TB * 1024;
function sizeFormat (line 7) | function sizeFormat(size) {
function cpuSpeedFormat (line 25) | function cpuSpeedFormat(speed) {
function cpuCoreFormat (line 34) | function cpuCoreFormat(cores) {
function base64 (line 42) | function base64(str) {
function safeBase64 (line 46) | function safeBase64(str) {
function formatSecond (line 53) | function formatSecond(second) {
function addZero (line 67) | function addZero(num) {
function toFixed (line 75) | function toFixed(num, n) {
function debounce (line 80) | function debounce(fn, delay) {
function getCookie (line 92) | function getCookie(cname) {
function setCookie (line 109) | function setCookie(cname, cvalue, exdays) {
function usageColor (line 117) | function usageColor(data, threshold, total) {
function clientUsageColor (line 134) | function clientUsageColor(clientStats, trafficDiff) {
function userExpiryColor (line 147) | function userExpiryColor(threshold, client, isDark = false) {
function doAllItemsExist (line 169) | function doAllItemsExist(array1, array2) {
function buildURL (line 178) | function buildURL({ host, port, isTLS, base, path }) {
FILE: web/assets/js/util/date-util.js
class DateUtil (line 130) | class DateUtil {
method parseDate (line 132) | static parseDate(str) {
method formatMillis (line 136) | static formatMillis(millis) {
method firstDayOfMonth (line 140) | static firstDayOfMonth() {
FILE: web/assets/js/util/utils.js
class Msg (line 1) | class Msg {
method constructor (line 2) | constructor(success, msg, obj) {
class HttpUtil (line 19) | class HttpUtil {
method _handleMsg (line 20) | static _handleMsg(msg) {
method _respToMsg (line 34) | static _respToMsg(resp) {
method get (line 49) | static async get(url, data, options) {
method post (line 61) | static async post(url, data, options) {
method postWithModal (line 73) | static async postWithModal(url, data, modal) {
class PromiseUtil (line 88) | class PromiseUtil {
method sleep (line 89) | static async sleep(timeout) {
class RandomUtil (line 98) | class RandomUtil {
method randomIntRange (line 99) | static randomIntRange(min, max) {
method randomInt (line 103) | static randomInt(n) {
method randomSeq (line 107) | static randomSeq(count) {
method randomShortId (line 115) | static randomShortId() {
method randomLowerAndNum (line 123) | static randomLowerAndNum(len) {
method randomUUID (line 131) | static randomUUID() {
method randomShadowsocksPassword (line 142) | static randomShadowsocksPassword() {
class ObjectUtil (line 149) | class ObjectUtil {
method getPropIgnoreCase (line 150) | static getPropIgnoreCase(obj, prop) {
method deepSearch (line 162) | static deepSearch(obj, key) {
method isEmpty (line 184) | static isEmpty(obj) {
method isArrEmpty (line 188) | static isArrEmpty(arr) {
method copyArr (line 192) | static copyArr(dest, src) {
method clone (line 199) | static clone(obj) {
method deepClone (line 215) | static deepClone(obj) {
method cloneProps (line 233) | static cloneProps(dest, src, ...ignoreProps) {
method delProps (line 263) | static delProps(obj, ...props) {
method execute (line 271) | static execute(func, ...args) {
method orDefault (line 277) | static orDefault(obj, defaultValue) {
method equals (line 284) | static equals(a, b) {
class Wireguard (line 299) | class Wireguard {
method gf (line 300) | static gf(init) {
method pack (line 309) | static pack(o, n) {
method carry (line 333) | static carry(o) {
method cswap (line 341) | static cswap(p, q, b) {
method add (line 350) | static add(o, a, b) {
method subtract (line 355) | static subtract(o, a, b) {
method multmod (line 360) | static multmod(o, a, b) {
method invert (line 374) | static invert(o, i) {
method clamp (line 387) | static clamp(z) {
method generatePublicKey (line 392) | static generatePublicKey(privateKey) {
method generatePresharedKey (line 436) | static generatePresharedKey() {
method generatePrivateKey (line 442) | static generatePrivateKey() {
method encodeBase64 (line 448) | static encodeBase64(dest, src) {
method keyToBase64 (line 458) | static keyToBase64(key) {
method keyFromBase64 (line 467) | static keyFromBase64(encoded) {
method generateKeypair (line 476) | static generateKeypair(secretKey='') {
FILE: web/assets/vue/vue.common.dev.js
function isUndef (line 12) | function isUndef(v) {
function isDef (line 15) | function isDef(v) {
function isTrue (line 18) | function isTrue(v) {
function isFalse (line 21) | function isFalse(v) {
function isPrimitive (line 27) | function isPrimitive(value) {
function isFunction (line 34) | function isFunction(value) {
function isObject (line 42) | function isObject(obj) {
function toRawType (line 49) | function toRawType(value) {
function isPlainObject (line 56) | function isPlainObject(obj) {
function isRegExp (line 59) | function isRegExp(v) {
function isValidArrayIndex (line 65) | function isValidArrayIndex(val) {
function isPromise (line 69) | function isPromise(val) {
function toString (line 77) | function toString(val) {
function replacer (line 84) | function replacer(_key, val) {
function toNumber (line 95) | function toNumber(val) {
function makeMap (line 103) | function makeMap(str, expectsLowerCase) {
function remove$2 (line 122) | function remove$2(arr, item) {
function hasOwn (line 140) | function hasOwn(obj, key) {
function cached (line 146) | function cached(fn) {
function polyfillBind (line 181) | function polyfillBind(fn, ctx) {
function nativeBind (line 193) | function nativeBind(fn, ctx) {
function toArray (line 201) | function toArray(list, start) {
function extend (line 213) | function extend(to, _from) {
function toObject (line 222) | function toObject(arr) {
function noop (line 237) | function noop(a, b, c) { }
function genStaticKeys$1 (line 250) | function genStaticKeys$1(modules) {
function looseEqual (line 259) | function looseEqual(a, b) {
function looseIndexOf (line 307) | function looseIndexOf(arr, val) {
function once (line 317) | function once(fn) {
function hasChanged (line 327) | function hasChanged(x, y) {
constant SSR_ATTR (line 336) | const SSR_ATTR = 'data-server-rendered';
constant ASSET_TYPES (line 337) | const ASSET_TYPES = ['component', 'directive', 'filter'];
constant LIFECYCLE_HOOKS (line 338) | const LIFECYCLE_HOOKS = [
function isReserved (line 442) | function isReserved(str) {
function def (line 449) | function def(obj, key, val, enumerable) {
function parsePath (line 461) | function parsePath(path) {
method get (line 497) | get() {
function isNative (line 527) | function isNative(Ctor) {
method constructor (line 542) | constructor() {
method has (line 545) | has(key) {
method add (line 548) | add(key) {
method clear (line 551) | clear() {
function getCurrentInstance (line 565) | function getCurrentInstance() {
function setCurrentInstance (line 571) | function setCurrentInstance(vm = null) {
class VNode (line 581) | class VNode {
method constructor (line 582) | constructor(tag, data, children, text, elm, context, componentOptions,...
method child (line 609) | get child() {
function createTextVNode (line 619) | function createTextVNode(val) {
function cloneVNode (line 626) | function cloneVNode(vnode) {
method set (line 669) | set(target, key, value) {
method has (line 682) | has(target, key) {
method get (line 698) | get(target, key) {
class Dep (line 736) | class Dep {
method constructor (line 737) | constructor() {
method addSub (line 743) | addSub(sub) {
method removeSub (line 746) | removeSub(sub) {
method depend (line 757) | depend(info) {
method notify (line 765) | notify(info) {
function pushTarget (line 789) | function pushTarget(target) {
function popTarget (line 793) | function popTarget() {
constant NO_INITIAL_VALUE (line 847) | const NO_INITIAL_VALUE = {};
function toggleObserving (line 853) | function toggleObserving(value) {
class Observer (line 869) | class Observer {
method constructor (line 870) | constructor(value, shallow = false, mock = false) {
method observeArray (line 911) | observeArray(value) {
function observe (line 923) | function observe(value, shallow, ssrMockReactivity) {
function defineReactive (line 940) | function defineReactive(obj, key, val, customSetter, shallow, mock, obse...
function set (line 1012) | function set(target, key, val) {
function del (line 1055) | function del(target, key) {
function dependArray (line 1092) | function dependArray(value) {
function reactive (line 1104) | function reactive(target) {
function shallowReactive (line 1113) | function shallowReactive(target) {
function makeReactive (line 1118) | function makeReactive(target, shallow) {
function isReactive (line 1141) | function isReactive(value) {
function isShallow (line 1147) | function isShallow(value) {
function isReadonly (line 1150) | function isReadonly(value) {
function isProxy (line 1153) | function isProxy(value) {
function toRaw (line 1156) | function toRaw(observed) {
function markRaw (line 1160) | function markRaw(value) {
function isCollectionType (line 1170) | function isCollectionType(value) {
function isRef (line 1179) | function isRef(r) {
function ref$1 (line 1182) | function ref$1(value) {
function shallowRef (line 1185) | function shallowRef(value) {
function createRef (line 1188) | function createRef(rawValue, shallow) {
function triggerRef (line 1198) | function triggerRef(ref) {
function unref (line 1211) | function unref(ref) {
function proxyRefs (line 1214) | function proxyRefs(objectWithRefs) {
function proxyWithRefUnwrap (line 1225) | function proxyWithRefUnwrap(target, source, key) {
function customRef (line 1252) | function customRef(factory) {
function toRefs (line 1282) | function toRefs(object) {
function toRef (line 1292) | function toRef(object, key, defaultValue) {
function readonly (line 1312) | function readonly(target) {
function createReadonly (line 1315) | function createReadonly(target, shallow) {
function defineReadonlyProperty (line 1359) | function defineReadonlyProperty(proxy, target, key, shallow) {
function shallowReadonly (line 1378) | function shallowReadonly(target) {
function computed (line 1382) | function computed(getterOrOptions, debugOptions) {
function createFnInvoker (line 1477) | function createFnInvoker(fns, vm) {
function updateListeners (line 1494) | function updateListeners(on, oldOn, add, remove, createOnceHandler, vm) {
function mergeVNodeHook (line 1525) | function mergeVNodeHook(def, hookKey, hook) {
function extractPropsFromVNodeData (line 1557) | function extractPropsFromVNodeData(data, Ctor, tag) {
function checkProp (line 1589) | function checkProp(res, hash, key, altKey, preserve) {
function simpleNormalizeChildren (line 1620) | function simpleNormalizeChildren(children) {
function normalizeChildren (line 1632) | function normalizeChildren(children) {
function isTextNode (line 1639) | function isTextNode(node) {
function normalizeArrayChildren (line 1642) | function normalizeArrayChildren(children, nestedIndex) {
constant SIMPLE_NORMALIZE (line 1695) | const SIMPLE_NORMALIZE = 1;
constant ALWAYS_NORMALIZE (line 1696) | const ALWAYS_NORMALIZE = 2;
function createElement$1 (line 1699) | function createElement$1(context, tag, data, children, normalizationType...
function _createElement (line 1710) | function _createElement(context, tag, data, children, normalizationType) {
function applyNS (line 1783) | function applyNS(vnode, ns, force) {
function registerDeepBindings (line 1803) | function registerDeepBindings(data) {
function renderList (line 1815) | function renderList(val, render) {
function renderSlot (line 1858) | function renderSlot(name, fallbackRender, props, bindObject) {
function resolveFilter (line 1891) | function resolveFilter(id) {
function isKeyNotMatch (line 1895) | function isKeyNotMatch(expect, actual) {
function checkKeyCodes (line 1908) | function checkKeyCodes(eventKeyCode, key, builtInKeyCode, eventKeyName, ...
function bindObjectProps (line 1925) | function bindObjectProps(data, tag, value, asProp, isSync) {
function renderStatic (line 1966) | function renderStatic(index, isInFor) {
function markOnce (line 1984) | function markOnce(tree, index, key) {
function markStatic$1 (line 1988) | function markStatic$1(tree, key, isOnce) {
function markStaticNode (line 2000) | function markStaticNode(node, key, isOnce) {
function bindObjectListeners (line 2006) | function bindObjectListeners(data, value) {
function resolveScopedSlots (line 2023) | function resolveScopedSlots(fns, res,
function bindDynamicKeys (line 2049) | function bindDynamicKeys(baseObj, values) {
function prependModifier (line 2065) | function prependModifier(value, symbol) {
function installRenderHelpers (line 2069) | function installRenderHelpers(target) {
function resolveSlots (line 2092) | function resolveSlots(children, context) {
function isWhitespace (line 2130) | function isWhitespace(node) {
function isAsyncPlaceholder (line 2134) | function isAsyncPlaceholder(node) {
function normalizeScopedSlots (line 2139) | function normalizeScopedSlots(ownerVm, scopedSlots, normalSlots, prevSco...
function normalizeScopedSlot (line 2185) | function normalizeScopedSlot(vm, normalSlots, key, fn) {
function proxyNormalSlot (line 2214) | function proxyNormalSlot(slots, key) {
function initSetup (line 2218) | function initSetup(vm) {
function createSetupContext (line 2266) | function createSetupContext(vm) {
function syncSetupProxy (line 2301) | function syncSetupProxy(to, from, prev, instance, type) {
function defineProxyAttr (line 2320) | function defineProxyAttr(proxy, key, instance, type) {
function initSlotsProxy (line 2329) | function initSlotsProxy(vm) {
function syncSetupSlots (line 2335) | function syncSetupSlots(to, from) {
function useSlots (line 2349) | function useSlots() {
function useAttrs (line 2356) | function useAttrs() {
function useListeners (line 2364) | function useListeners() {
function getContext (line 2367) | function getContext() {
function mergeDefaults (line 2379) | function mergeDefaults(raw, defaults) {
function initRender (line 2403) | function initRender(vm) {
function renderMixin (line 2437) | function renderMixin(Vue) {
function ensureCtor (line 2504) | function ensureCtor(comp, base) {
function createAsyncPlaceholder (line 2510) | function createAsyncPlaceholder(factory, data, context, children, tag) {
function resolveAsyncComponent (line 2516) | function resolveAsyncComponent(factory, baseCtor) {
function getFirstComponentChild (line 2619) | function getFirstComponentChild(children) {
function initEvents (line 2630) | function initEvents(vm) {
function add$1 (line 2640) | function add$1(event, fn) {
function remove$1 (line 2643) | function remove$1(event, fn) {
function createOnceHandler$1 (line 2646) | function createOnceHandler$1(event, fn) {
function updateComponentListeners (line 2655) | function updateComponentListeners(vm, listeners, oldListeners) {
function eventsMixin (line 2660) | function eventsMixin(Vue) {
class EffectScope (line 2750) | class EffectScope {
method constructor (line 2751) | constructor(detached = false) {
method run (line 2771) | run(fn) {
method on (line 2790) | on() {
method off (line 2797) | off() {
method stop (line 2800) | stop(fromParent) {
function effectScope (line 2828) | function effectScope(detached) {
function recordEffectScope (line 2834) | function recordEffectScope(effect, scope = activeEffectScope) {
function getCurrentScope (line 2839) | function getCurrentScope() {
function onScopeDispose (line 2842) | function onScopeDispose(fn) {
function setActiveInstance (line 2854) | function setActiveInstance(vm) {
function initLifecycle (line 2861) | function initLifecycle(vm) {
function lifecycleMixin (line 2883) | function lifecycleMixin(Vue) {
function mountComponent (line 2964) | function mountComponent(vm, el, hydrating) {
function updateChildComponent (line 3038) | function updateChildComponent(vm, propsData, listeners, parentVnode, ren...
function isInInactiveTree (line 3110) | function isInInactiveTree(vm) {
function activateChildComponent (line 3117) | function activateChildComponent(vm, direct) {
function deactivateChildComponent (line 3135) | function deactivateChildComponent(vm, direct) {
function callHook$1 (line 3150) | function callHook$1(vm, hook, args, setContext = true) {
constant MAX_UPDATE_COUNT (line 3173) | const MAX_UPDATE_COUNT = 100;
function resetSchedulerState (line 3184) | function resetSchedulerState() {
function flushSchedulerQueue (line 3231) | function flushSchedulerQueue() {
function callUpdatedHooks (line 3280) | function callUpdatedHooks(queue) {
function queueActivatedComponent (line 3294) | function queueActivatedComponent(vm) {
function callActivatedHooks (line 3300) | function callActivatedHooks(queue) {
function queueWatcher (line 3311) | function queueWatcher(watcher) {
constant WATCHER (line 3343) | const WATCHER = `watcher`;
constant WATCHER_CB (line 3344) | const WATCHER_CB = `${WATCHER} callback`;
constant WATCHER_GETTER (line 3345) | const WATCHER_GETTER = `${WATCHER} getter`;
constant WATCHER_CLEANUP (line 3346) | const WATCHER_CLEANUP = `${WATCHER} cleanup`;
function watchEffect (line 3348) | function watchEffect(effect, options) {
function watchPostEffect (line 3351) | function watchPostEffect(effect, options) {
function watchSyncEffect (line 3354) | function watchSyncEffect(effect, options) {
constant INITIAL_WATCHER_VALUE (line 3358) | const INITIAL_WATCHER_VALUE = {};
function watch (line 3360) | function watch(source, cb, options) {
function doWatch (line 3368) | function doWatch(source, cb, { immediate, deep, flush = 'pre', onTrack, ...
function provide (line 3553) | function provide(key, value) {
function resolveProvided (line 3564) | function resolveProvided(vm) {
function inject (line 3579) | function inject(key, defaultValue, treatDefaultAsFactory = false) {
function h (line 3610) | function h(type, props, children) {
function handleError (line 3618) | function handleError(err, vm, info) {
function invokeWithErrorHandling (line 3647) | function invokeWithErrorHandling(handler, context, args, vm, info) {
function globalHandleError (line 3661) | function globalHandleError(err, vm, info) {
function logError (line 3676) | function logError(err, vm, info) {
function flushCallbacks (line 3693) | function flushCallbacks() {
function nextTick (line 3771) | function nextTick(cb, ctx) {
function useCssModule (line 3798) | function useCssModule(name = '$style') {
function useCssVars (line 3818) | function useCssVars(getter) {
function defineAsyncComponent (line 3843) | function defineAsyncComponent(source) {
function createLifeCycle (line 3909) | function createLifeCycle(hookName) {
function formatName (line 3920) | function formatName(name) {
function injectHook (line 3929) | function injectHook(instance, hookName, fn) {
function onErrorCaptured (line 3945) | function onErrorCaptured(hook, target = currentInstance) {
function defineComponent (line 3956) | function defineComponent(options) {
function traverse (line 4026) | function traverse(val) {
function _traverse (line 4031) | function _traverse(val, seen) {
class Watcher (line 4070) | class Watcher {
method constructor (line 4071) | constructor(vm, expOrFn, cb, options, isRenderWatcher) {
method get (line 4126) | get() {
method addDep (line 4155) | addDep(dep) {
method cleanupDeps (line 4168) | cleanupDeps() {
method update (line 4189) | update() {
method run (line 4205) | run() {
method evaluate (line 4231) | evaluate() {
method depend (line 4238) | depend() {
method teardown (line 4247) | teardown() {
function proxy (line 4270) | function proxy(target, sourceKey, key) {
function initState (line 4279) | function initState(vm) {
function initProps$1 (line 4300) | function initProps$1(vm, propsOptions) {
function initData (line 4339) | function initData(vm) {
function getData (line 4371) | function getData(data, vm) {
function initComputed$1 (line 4386) | function initComputed$1(vm, computed) {
function defineComputed (line 4420) | function defineComputed(target, key, userDef) {
function createComputedGetter (line 4443) | function createComputedGetter(key) {
function createGetterInvoker (line 4465) | function createGetterInvoker(fn) {
function initMethods (line 4470) | function initMethods(vm, methods) {
function initWatch (line 4489) | function initWatch(vm, watch) {
function createWatcher (line 4502) | function createWatcher(vm, expOrFn, handler, options) {
function stateMixin (line 4512) | function stateMixin(Vue) {
function initProvide (line 4557) | function initProvide(vm) {
function initInjections (line 4576) | function initInjections(vm) {
function resolveInject (line 4593) | function resolveInject(inject, vm) {
function initMixin$1 (line 4622) | function initMixin$1(Vue) {
function initInternalComponent (line 4680) | function initInternalComponent(vm, options) {
function resolveConstructorOptions (line 4696) | function resolveConstructorOptions(Ctor) {
function resolveModifiedOptions (line 4719) | function resolveModifiedOptions(Ctor) {
function FunctionalRenderContext (line 4733) | function FunctionalRenderContext(data, props, children, parent, Ctor) {
function createFunctionalComponent (line 4793) | function createFunctionalComponent(Ctor, propsData, data, contextVm, chi...
function cloneAndMarkFunctionalResult (line 4822) | function cloneAndMarkFunctionalResult(vnode, data, contextVm, options, r...
function mergeProps (line 4838) | function mergeProps(to, from) {
function getComponentName (line 4844) | function getComponentName(options) {
method init (line 4849) | init(vnode, hydrating) {
method prepatch (line 4862) | prepatch(oldVnode, vnode) {
method insert (line 4871) | insert(vnode) {
method destroy (line 4891) | destroy(vnode) {
function createComponent (line 4904) | function createComponent(Ctor, data, context, children, tag) {
function createComponentInstanceForVnode (line 4980) | function createComponentInstanceForVnode(
function installComponentHooks (line 4998) | function installComponentHooks(data) {
function mergeHook (line 5010) | function mergeHook(f1, f2) {
function transformModel (line 5021) | function transformModel(options, data) {
function mergeData (line 5145) | function mergeData(to, from, recursive = true) {
function mergeDataOrFn (line 5173) | function mergeDataOrFn(parentVal, childVal, vm) {
function mergeLifecycleHook (line 5224) | function mergeLifecycleHook(parentVal, childVal) {
function dedupeHooks (line 5234) | function dedupeHooks(hooks) {
function mergeAssets (line 5253) | function mergeAssets(parentVal, childVal, vm, key) {
function checkComponents (line 5341) | function checkComponents(options) {
function validateComponentName (line 5346) | function validateComponentName(name) {
function normalizeProps (line 5363) | function normalizeProps(options, vm) {
function normalizeInject (line 5398) | function normalizeInject(options, vm) {
function normalizeDirectives$1 (line 5424) | function normalizeDirectives$1(options) {
function assertObjectType (line 5435) | function assertObjectType(name, value, vm) {
function mergeOptions (line 5445) | function mergeOptions(parent, child, vm) {
function resolveAsset (line 5491) | function resolveAsset(options, type, id, warnMissing) {
function validateProp (line 5514) | function validateProp(key, propOptions, propsData, vm) {
function getPropDefaultValue (line 5551) | function getPropDefaultValue(vm, prop, key) {
function assertProp (line 5582) | function assertProp(prop, name, value, vm, absent) {
function assertType (line 5616) | function assertType(value, type, vm) {
function getType (line 5653) | function getType(fn) {
function isSameType (line 5657) | function isSameType(a, b) {
function getTypeIndex (line 5660) | function getTypeIndex(type, expectedTypes) {
function getInvalidTypeMessage (line 5671) | function getInvalidTypeMessage(name, value, expectedTypes) {
function styleValue (line 5690) | function styleValue(value, type) {
constant EXPLICABLE_TYPES (line 5701) | const EXPLICABLE_TYPES = ['string', 'number', 'boolean'];
function isExplicable (line 5702) | function isExplicable(value) {
function isBoolean (line 5705) | function isBoolean(...args) {
function Vue (line 5709) | function Vue(options) {
function initUse (line 5726) | function initUse(Vue) {
function initMixin (line 5746) | function initMixin(Vue) {
function initExtend (line 5753) | function initExtend(Vue) {
function initProps (line 5817) | function initProps(Comp) {
function initComputed (line 5823) | function initComputed(Comp) {
function initAssetRegisters (line 5830) | function initAssetRegisters(Vue) {
function _getComponentName (line 5860) | function _getComponentName(opts) {
function matches (line 5863) | function matches(pattern, name) {
function pruneCache (line 5876) | function pruneCache(keepAliveInstance, filter) {
function pruneCacheEntry (line 5889) | function pruneCacheEntry(cache, key, keys, current) {
method cacheVNode (line 5909) | cacheVNode() {
method created (line 5927) | created() {
method destroyed (line 5931) | destroyed() {
method mounted (line 5936) | mounted() {
method updated (line 5945) | updated() {
method render (line 5948) | render() {
function initGlobalAPI (line 5992) | function initGlobalAPI(Vue) {
method get (line 6038) | get() {
function genClassForVnode (line 6087) | function genClassForVnode(vnode) {
function mergeClassData (line 6105) | function mergeClassData(child, parent) {
function renderClass (line 6111) | function renderClass(staticClass, dynamicClass) {
function concat (line 6118) | function concat(a, b) {
function stringifyClass (line 6121) | function stringifyClass(value) {
function stringifyArray (line 6134) | function stringifyArray(value) {
function stringifyObject (line 6146) | function stringifyObject(value) {
function getTagNamespace (line 6182) | function getTagNamespace(tag) {
function isUnknownElement (line 6193) | function isUnknownElement(tag) {
function query (line 6222) | function query(el) {
function createElement (line 6236) | function createElement(tagName, vnode) {
function createElementNS (line 6249) | function createElementNS(namespace, tagName) {
function createTextNode (line 6252) | function createTextNode(text) {
function createComment (line 6255) | function createComment(text) {
function insertBefore (line 6258) | function insertBefore(parentNode, newNode, referenceNode) {
function removeChild (line 6261) | function removeChild(node, child) {
function appendChild (line 6264) | function appendChild(node, child) {
function parentNode (line 6267) | function parentNode(node) {
function nextSibling (line 6270) | function nextSibling(node) {
function tagName (line 6273) | function tagName(node) {
function setTextContent (line 6276) | function setTextContent(node, text) {
function setStyleScope (line 6279) | function setStyleScope(node, scopeId) {
method create (line 6300) | create(_, vnode) {
method update (line 6303) | update(oldVnode, vnode) {
method destroy (line 6309) | destroy(vnode) {
function registerRef (line 6313) | function registerRef(vnode, isRemoval) {
function setSetupRef (line 6368) | function setSetupRef({ _setupState }, key, val) {
function sameVnode (line 6392) | function sameVnode(a, b) {
function sameInputType (line 6401) | function sameInputType(a, b) {
function createKeyToOldIdx (line 6409) | function createKeyToOldIdx(children, beginIdx, endIdx) {
function createPatchFunction (line 6419) | function createPatchFunction(backend) {
function updateDirectives (line 7118) | function updateDirectives(oldVnode, vnode) {
function _update (line 7123) | function _update(oldVnode, vnode) {
function normalizeDirectives (line 7181) | function normalizeDirectives(dirs, vm) {
function getRawDirName (line 7212) | function getRawDirName(dir) {
function callHook (line 7215) | function callHook(dir, hook, vnode, oldVnode, isDestroy) {
function updateAttrs (line 7229) | function updateAttrs(oldVnode, vnode) {
function setAttr (line 7269) | function setAttr(el, key, value, isInPre) {
function baseSetAttr (line 7301) | function baseSetAttr(el, key, value) {
function updateClass (line 7332) | function updateClass(oldVnode, vnode) {
function parseFilters (line 7360) | function parseFilters(exp) {
function wrapFilter (line 7467) | function wrapFilter(exp, filter) {
function baseWarn (line 7481) | function baseWarn(msg, range) {
function pluckModuleFunction (line 7485) | function pluckModuleFunction(modules, key) {
function addProp (line 7488) | function addProp(el, name, value, range, dynamic) {
function addAttr (line 7492) | function addAttr(el, name, value, range, dynamic) {
function addRawAttr (line 7500) | function addRawAttr(el, name, value, range) {
function addDirective (line 7504) | function addDirective(el, name, rawName, value, arg, isDynamicArg, modif...
function prependModifierMarker (line 7515) | function prependModifierMarker(symbol, name, dynamic) {
function addHandler (line 7518) | function addHandler(el, name, value, modifiers, important, warn, range, ...
function getRawBindingAttr (line 7585) | function getRawBindingAttr(el, name) {
function getBindingAttr (line 7590) | function getBindingAttr(el, name, getStatic) {
function getAndRemoveAttr (line 7606) | function getAndRemoveAttr(el, name, removeFromMap) {
function getAndRemoveAttrByRegex (line 7622) | function getAndRemoveAttrByRegex(el, name) {
function rangeSetItem (line 7632) | function rangeSetItem(item, range) {
function genComponentModel (line 7647) | function genComponentModel(el, value, modifiers) {
function genAssignmentCode (line 7670) | function genAssignmentCode(value, assignment) {
function parseModel (line 7694) | function parseModel(val) {
function next (line 7731) | function next() {
function eof (line 7734) | function eof() {
function isStringStart (line 7737) | function isStringStart(chr) {
function parseBracket (line 7740) | function parseBracket(chr) {
function parseString (line 7759) | function parseString(chr) {
constant RANGE_TOKEN (line 7772) | const RANGE_TOKEN = '__r';
constant CHECKBOX_RADIO_TOKEN (line 7773) | const CHECKBOX_RADIO_TOKEN = '__c';
function model$1 (line 7774) | function model$1(el, dir, _warn) {
function genCheckboxModel (line 7819) | function genCheckboxModel(el, value, modifiers) {
function genRadioModel (line 7839) | function genRadioModel(el, value, modifiers) {
function genSelect (line 7846) | function genSelect(el, value, modifiers) {
function genDefaultModel (line 7857) | function genDefaultModel(el, value, modifiers) {
function normalizeEvents (line 7895) | function normalizeEvents(on) {
function createOnceHandler (line 7912) | function createOnceHandler(event, handler, capture) {
function add (line 7925) | function add(name, handler, capture, passive) {
function remove (line 7958) | function remove(name, handler, capture, _target) {
function updateDOMListeners (line 7963) | function updateDOMListeners(oldVnode, vnode) {
function updateDOMProps (line 7984) | function updateDOMProps(oldVnode, vnode) {
function shouldUpdateValue (line 8056) | function shouldUpdateValue(elm, checkVal) {
function isNotInFocusAndDirty (line 8064) | function isNotInFocusAndDirty(elm, checkVal) {
function isDirtyWithModifiers (line 8076) | function isDirtyWithModifiers(elm, newVal) {
function normalizeStyleData (line 8107) | function normalizeStyleData(data) {
function normalizeStyleBinding (line 8114) | function normalizeStyleBinding(bindingStyle) {
function getStyle (line 8127) | function getStyle(vnode, checkChild) {
function updateStyle (line 8195) | function updateStyle(oldVnode, vnode) {
function addClass (line 8237) | function addClass(el, cls) {
function removeClass (line 8262) | function removeClass(el, cls) {
function resolveTransition (line 8295) | function resolveTransition(def) {
constant TRANSITION (line 8323) | const TRANSITION = 'transition';
constant ANIMATION (line 8324) | const ANIMATION = 'animation';
function nextFrame (line 8349) | function nextFrame(fn) {
function addTransitionClass (line 8355) | function addTransitionClass(el, cls) {
function removeTransitionClass (line 8362) | function removeTransitionClass(el, cls) {
function whenTransitionEnds (line 8368) | function whenTransitionEnds(el, expectedType, cb) {
function getTransitionInfo (line 8393) | function getTransitionInfo(el, expectedType) {
function getTimeout (line 8442) | function getTimeout(delays, durations) {
function toMs (line 8455) | function toMs(s) {
function enter (line 8459) | function enter(vnode, toggleDisplay) {
function leave (line 8563) | function leave(vnode, rm) {
function checkDuration (line 8650) | function checkDuration(val, name, vnode) {
function isValidDuration (line 8660) | function isValidDuration(val) {
function getHookArgumentsLength (line 8669) | function getHookArgumentsLength(fn) {
function _enter (line 8684) | function _enter(_, vnode) {
method remove (line 8693) | remove(vnode, rm) {
method inserted (line 8729) | inserted(el, binding, vnode, oldVnode) {
method componentUpdated (line 8759) | componentUpdated(el, binding, vnode) {
function setSelected (line 8782) | function setSelected(el, binding, vm) {
function actuallySetSelected (line 8791) | function actuallySetSelected(el, binding, vm) {
function hasNoMatchingOption (line 8823) | function hasNoMatchingOption(value, options) {
function getValue (line 8826) | function getValue(option) {
function onCompositionStart (line 8829) | function onCompositionStart(e) {
function onCompositionEnd (line 8832) | function onCompositionEnd(e) {
function trigger (line 8839) | function trigger(el, type) {
function locateNode (line 8846) | function locateNode(vnode) {
method bind (line 8853) | bind(el, { value }, vnode) {
method update (line 8868) | update(el, { value, oldValue }, vnode) {
method unbind (line 8891) | unbind(el, binding, vnode, oldVnode, isDestroy) {
function getRealChild (line 8923) | function getRealChild(vnode) {
function extractTransitionData (line 8932) | function extractTransitionData(comp) {
function placeholder (line 8947) | function placeholder(h, rawChild) {
function hasParentTransition (line 8955) | function hasParentTransition(vnode) {
function isSameChild (line 8962) | function isSameChild(child, oldChild) {
method render (line 8971) | render(h) {
method beforeMount (line 9078) | beforeMount() {
method render (line 9091) | render(h) {
method updated (line 9135) | updated() {
method hasMove (line 9170) | hasMove(el, moveClass) {
function callPendingCbs (line 9199) | function callPendingCbs(c) {
function recordPosition (line 9209) | function recordPosition(c) {
function applyTranslation (line 9212) | function applyTranslation(c) {
function parseText (line 9277) | function parseText(text, delimiters) {
function transformNode$1 (line 9310) | function transformNode$1(el, options) {
function genData$2 (line 9330) | function genData$2(el) {
function transformNode (line 9346) | function transformNode(el, options) {
function genData$1 (line 9367) | function genData$1(el) {
method decode (line 9385) | decode(html) {
function decodeAttr (line 9437) | function decodeAttr(value, shouldDecodeNewlines) {
function parseHTML (line 9441) | function parseHTML(html, options) {
function createASTElement (line 9708) | function createASTElement(tag, attrs, parent) {
function parse (line 9722) | function parse(template, options) {
function processPre (line 10018) | function processPre(el) {
function processRawAttrs (line 10023) | function processRawAttrs(el) {
function processElement (line 10044) | function processElement(element, options) {
function processKey (line 10060) | function processKey(el) {
function processRef (line 10082) | function processRef(el) {
function processFor (line 10089) | function processFor(el) {
function parseFor (line 10101) | function parseFor(exp) {
function processIf (line 10121) | function processIf(el) {
function processIfConditions (line 10140) | function processIfConditions(el, parent) {
function findPrevElement (line 10153) | function findPrevElement(children) {
function addIfCondition (line 10168) | function addIfCondition(el, condition) {
function processOnce (line 10174) | function processOnce(el) {
function processSlotContent (line 10182) | function processSlotContent(el) {
function getSlotName (line 10273) | function getSlotName(binding) {
function processSlotOutlet (line 10290) | function processSlotOutlet(el) {
function processComponent (line 10300) | function processComponent(el) {
function processAttrs (line 10309) | function processAttrs(el) {
function checkInFor (line 10418) | function checkInFor(el) {
function parseModifiers (line 10428) | function parseModifiers(name) {
function makeAttrsMap (line 10438) | function makeAttrsMap(attrs) {
function isTextTag (line 10449) | function isTextTag(el) {
function isForbiddenTag (line 10452) | function isForbiddenTag(el) {
function guardIESVGBug (line 10460) | function guardIESVGBug(attrs) {
function checkForAliasModel (line 10471) | function checkForAliasModel(el, value) {
function preTransformNode (line 10494) | function preTransformNode(el, options) {
function cloneASTElement (line 10552) | function cloneASTElement(el) {
function text (line 10561) | function text(el, dir) {
function html (line 10567) | function html(el, dir) {
function optimize (line 10606) | function optimize(root, options) {
function genStaticKeys (line 10616) | function genStaticKeys(keys) {
function markStatic (line 10620) | function markStatic(node) {
function markStaticRoots (line 10649) | function markStaticRoots(node, isInFor) {
function isStatic (line 10678) | function isStatic(node) {
function isDirectChildOfTemplateFor (line 10696) | function isDirectChildOfTemplateFor(node) {
function genHandlers (line 10756) | function genHandlers(events, isNative) {
function genHandler (line 10778) | function genHandler(handler) {
function genKeyFilter (line 10834) | function genKeyFilter(keys) {
function genFilterCode (line 10842) | function genFilterCode(key) {
function on (line 10857) | function on(el, dir) {
function bind (line 10864) | function bind(el, dir) {
class CodegenState (line 10876) | class CodegenState {
method constructor (line 10877) | constructor(options) {
function generate (line 10890) | function generate(ast, options) {
function genElement (line 10903) | function genElement(el, state) {
function checkBindingType (line 10957) | function checkBindingType(bindings, key) {
function genStatic (line 10984) | function genStatic(el, state) {
function genOnce (line 10998) | function genOnce(el, state) {
function genIf (line 11023) | function genIf(el, state, altGen, altEmpty) {
function genIfConditions (line 11027) | function genIfConditions(conditions, state, altGen, altEmpty) {
function genFor (line 11047) | function genFor(el, state, altGen, altHelper) {
function genData (line 11066) | function genData(el, state) {
function genDirectives (line 11148) | function genDirectives(el, state) {
function genInlineTemplate (line 11175) | function genInlineTemplate(el, state) {
function genScopedSlots (line 11187) | function genScopedSlots(el, slots, state) {
function hash (line 11227) | function hash(str) {
function containsSlotChild (line 11235) | function containsSlotChild(el) {
function genScopedSlot (line 11244) | function genScopedSlot(el, state) {
function genChildren (line 11263) | function genChildren(el, state, checkSkip, altGenElement, altGenNode) {
function getNormalizationType (line 11290) | function getNormalizationType(children, maybeComponent) {
function needsNormalization (line 11310) | function needsNormalization(el) {
function genNode (line 11313) | function genNode(node, state) {
function genText (line 11324) | function genText(text) {
function genComment (line 11329) | function genComment(comment) {
function genSlot (line 11332) | function genSlot(el, state) {
function genComponent (line 11357) | function genComponent(componentName, el, state) {
function genProps (line 11361) | function genProps(props) {
function transformSpecialNewlines (line 11383) | function transformSpecialNewlines(text) {
function detectErrors (line 11403) | function detectErrors(ast, warn) {
function checkNode (line 11408) | function checkNode(node, warn) {
function checkEvent (line 11440) | function checkEvent(exp, text, warn, range) {
function checkFor (line 11449) | function checkFor(node, text, warn, range) {
function checkIdentifier (line 11455) | function checkIdentifier(ident, type, text, warn, range) {
function checkExpression (line 11465) | function checkExpression(exp, text, warn, range) {
function checkFunctionParameterExpression (line 11484) | function checkFunctionParameterExpression(exp, text, warn, range) {
function generateCodeFrame (line 11496) | function generateCodeFrame(source, start = 0, end = source.length) {
function repeat (line 11527) | function repeat(str, n) {
function createFunction (line 11544) | function createFunction(code, errors) {
function createCompileToFunctionFn (line 11553) | function createCompileToFunctionFn(compile) {
function createCompilerCreator (line 11631) | function createCompilerCreator(baseCompile) {
function getShouldDecode (line 11708) | function getShouldDecode(href) {
function getOuterHTML (line 11787) | function getOuterHTML(el) {
function effect (line 11804) | function effect(fn, scheduler) {
FILE: web/assets/vue/vue.common.prod.js
function n (line 6) | function n(t){return null==t}
function o (line 6) | function o(t){return null!=t}
function r (line 6) | function r(t){return!0===t}
function s (line 6) | function s(t){return"string"==typeof t||"number"==typeof t||"symbol"==ty...
function i (line 6) | function i(t){return"function"==typeof t}
function c (line 6) | function c(t){return null!==t&&"object"==typeof t}
function l (line 6) | function l(t){return"[object Object]"===a.call(t)}
function u (line 6) | function u(t){const e=parseFloat(String(t));return e>=0&&Math.floor(e)==...
function f (line 6) | function f(t){return o(t)&&"function"==typeof t.then&&"function"==typeof...
function d (line 6) | function d(t){return null==t?"":Array.isArray(t)||l(t)&&t.toString===a?J...
function p (line 6) | function p(t,e){return e&&e.__v_isRef?e.value:e}
function h (line 6) | function h(t){const e=parseFloat(t);return isNaN(e)?t:e}
function m (line 6) | function m(t,e){const n=Object.create(null),o=t.split(",");for(let t=0;t...
function y (line 6) | function y(t,e){const n=t.length;if(n){if(e===t[n-1])return void(t.lengt...
function $ (line 6) | function $(t,e){return _.call(t,e)}
function b (line 6) | function b(t){const e=Object.create(null);return function(n){return e[n]...
function n (line 6) | function n(n){const o=arguments.length;return o?o>1?t.apply(e,arguments)...
function T (line 6) | function T(t,e){e=e||0;let n=t.length-e;const o=new Array(n);for(;n--;)o...
function A (line 6) | function A(t,e){for(const n in e)t[n]=e[n];return t}
function j (line 6) | function j(t){const e={};for(let n=0;n<t.length;n++)t[n]&&A(e,t[n]);retu...
function E (line 6) | function E(t,e,n){}
function D (line 6) | function D(t,e){if(t===e)return!0;const n=c(t),o=c(e);if(!n||!o)return!n...
function M (line 6) | function M(t,e){for(let n=0;n<t.length;n++)if(D(t[n],e))return n;return-1}
function I (line 6) | function I(t){let e=!1;return function(){e||(e=!0,t.apply(this,arguments...
function L (line 6) | function L(t,e){return t===e?0===t&&1/t!=1/e:t==t||e==e}
function z (line 6) | function z(t){const e=(t+"").charCodeAt(0);return 36===e||95===e}
function V (line 6) | function V(t,e,n,o){Object.defineProperty(t,e,{value:n,enumerable:!!o,wr...
method get (line 6) | get(){nt=!0}
function st (line 6) | function st(t){return"function"==typeof t&&/native code/.test(t.toString...
method constructor (line 6) | constructor(){this.set=Object.create(null)}
method has (line 6) | has(t){return!0===this.set[t]}
method add (line 6) | add(t){this.set[t]=!0}
method clear (line 6) | clear(){this.set=Object.create(null)}
function lt (line 6) | function lt(t=null){t||at&&at._scope.off(),at=t,t&&t._scope.on()}
class ut (line 6) | class ut{constructor(t,e,n,o,r,s,i,c){this.tag=t,this.data=e,this.childr...
method constructor (line 6) | constructor(t,e,n,o,r,s,i,c){this.tag=t,this.data=e,this.children=n,th...
method child (line 6) | get child(){return this.componentInstance}
function dt (line 6) | function dt(t){return new ut(void 0,void 0,void 0,String(t))}
function pt (line 6) | function pt(t){const e=new ut(t.tag,t.data,t.children&&t.children.slice(...
class vt (line 6) | class vt{constructor(){this._pending=!1,this.id=ht++,this.subs=[]}addSub...
method constructor (line 6) | constructor(){this._pending=!1,this.id=ht++,this.subs=[]}
method addSub (line 6) | addSub(t){this.subs.push(t)}
method removeSub (line 6) | removeSub(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this...
method depend (line 6) | depend(t){vt.target&&vt.target.addDep(this)}
method notify (line 6) | notify(t){const e=this.subs.filter((t=>t));for(let t=0,n=e.length;t<n;...
function _t (line 6) | function _t(t){yt.push(t),vt.target=t}
function $t (line 6) | function $t(){yt.pop(),vt.target=yt[yt.length-1]}
function St (line 6) | function St(t){kt=t}
class Tt (line 6) | class Tt{constructor(t,n=!1,o=!1){if(this.value=t,this.shallow=n,this.mo...
method constructor (line 6) | constructor(t,n=!1,o=!1){if(this.value=t,this.shallow=n,this.mock=o,th...
method observeArray (line 6) | observeArray(t){for(let e=0,n=t.length;e<n;e++)At(t[e],!1,this.mock)}
function At (line 6) | function At(t,n,o){return t&&$(t,"__ob__")&&t.__ob__ instanceof Tt?t.__o...
function jt (line 6) | function jt(t,n,o,r,s,i,c=!1){const a=new vt,l=Object.getOwnPropertyDesc...
function Et (line 6) | function Et(t,n,o){if(Rt(t))return;const r=t.__ob__;return e(t)&&u(n)?(t...
function Nt (line 6) | function Nt(t,n){if(e(t)&&u(n))return void t.splice(n,1);const o=t.__ob_...
function Pt (line 6) | function Pt(t){for(let n,o=0,r=t.length;o<r;o++)n=t[o],n&&n.__ob__&&n.__...
function Dt (line 6) | function Dt(t){return Mt(t,!0),V(t,"__v_isShallow",!0),t}
function Mt (line 6) | function Mt(t,e){Rt(t)||At(t,e,ot())}
function It (line 6) | function It(t){return Rt(t)?It(t.__v_raw):!(!t||!t.__ob__)}
function Lt (line 6) | function Lt(t){return!(!t||!t.__v_isShallow)}
function Rt (line 6) | function Rt(t){return!(!t||!t.__v_isReadonly)}
function Ht (line 6) | function Ht(t){return!(!t||!0!==t.__v_isRef)}
function Bt (line 6) | function Bt(t,e){if(Ht(t))return t;const n={};return V(n,Ft,!0),V(n,"__v...
function Ut (line 6) | function Ut(t,e,n){Object.defineProperty(t,n,{enumerable:!0,configurable...
function zt (line 6) | function zt(t,e,n){const o=t[e];if(Ht(o))return o;const r={get value(){c...
function Jt (line 6) | function Jt(t){return qt(t,!1)}
function qt (line 6) | function qt(t,e){if(!l(t))return t;if(Rt(t))return t;const n=e?Kt:Vt,o=t...
function Wt (line 6) | function Wt(t,e,n,o){Object.defineProperty(t,n,{enumerable:!0,configurab...
function Gt (line 6) | function Gt(t,n){function o(){const t=o.fns;if(!e(t))return vn(t,null,ar...
function Xt (line 6) | function Xt(t,e,o,s,i,c){let a,l,u,f;for(a in t)l=t[a],u=e[a],f=Zt(a),n(...
function Yt (line 6) | function Yt(t,e,s){let i;t instanceof ut&&(t=t.data.hook||(t.data.hook={...
function Qt (line 6) | function Qt(t,e,n,r,s){if(o(e)){if($(e,n))return t[n]=e[n],s||delete e[n...
function te (line 6) | function te(t){return s(t)?[dt(t)]:e(t)?ne(t):void 0}
function ee (line 6) | function ee(t){return o(t)&&o(t.text)&&!1===t.isComment}
function ne (line 6) | function ne(t,i){const c=[];let a,l,u,f;for(a=0;a<t.length;a++)l=t[a],n(...
function se (line 6) | function se(t,n,a,l,u,f){return(e(a)||s(a))&&(u=l,l=a,a=void 0),r(f)&&(u...
function ie (line 6) | function ie(t,e,s){if(t.ns=e,"foreignObject"===t.tag&&(e=void 0,s=!0),o(...
function ce (line 6) | function ce(t,n){let r,s,i,a,l=null;if(e(t)||"string"==typeof t)for(l=ne...
function ae (line 6) | function ae(t,e,n,o){const r=this.$scopedSlots[t];let s;r?(n=n||{},o&&(n...
function le (line 6) | function le(t){return $o(this.$options,"filters",t)||P}
function ue (line 6) | function ue(t,n){return e(t)?-1===t.indexOf(n):t!==n}
function fe (line 6) | function fe(t,e,n,o,r){const s=B.keyCodes[e]||n;return r&&o&&!B.keyCodes...
function de (line 6) | function de(t,n,o,r,s){if(o)if(c(o)){let i;e(o)&&(o=j(o));for(const e in...
function pe (line 6) | function pe(t,e){const n=this._staticTrees||(this._staticTrees=[]);let o...
function he (line 6) | function he(t,e,n){return me(t,`__once__${e}${n?`_${n}`:""}`,!0),t}
function me (line 6) | function me(t,n,o){if(e(t))for(let e=0;e<t.length;e++)t[e]&&"string"!=ty...
function ge (line 6) | function ge(t,e,n){t.isStatic=!0,t.key=e,t.isOnce=n}
function ve (line 6) | function ve(t,e){if(e)if(l(e)){const n=t.on=t.on?A({},t.on):{};for(const...
function ye (line 6) | function ye(t,n,o,r){n=n||{$stable:!o};for(let r=0;r<t.length;r++){const...
function _e (line 6) | function _e(t,e){for(let n=0;n<e.length;n+=2){const o=e[n];"string"==typ...
function $e (line 6) | function $e(t,e){return"string"==typeof t?e+t:t}
function be (line 6) | function be(t){t._o=he,t._n=h,t._s=d,t._l=ce,t._t=ae,t._q=D,t._i=M,t._m=...
function we (line 6) | function we(t,e){if(!t||!t.length)return{};const n={};for(let o=0,r=t.le...
function xe (line 6) | function xe(t){return t.isComment&&!t.asyncFactory||" "===t.text}
function Ce (line 6) | function Ce(t){return t.isComment&&t.asyncFactory}
function ke (line 6) | function ke(e,n,o,r){let s;const i=Object.keys(o).length>0,c=n?!!n.$stab...
function Se (line 6) | function Se(t,n,o,r){const s=function(){const n=at;lt(t);let o=arguments...
function Oe (line 6) | function Oe(t,e){return()=>t[e]}
function Te (line 6) | function Te(e){return{get attrs(){if(!e._attrsProxy){const n=e._attrsPro...
function Ae (line 6) | function Ae(t,e,n,o,r){let s=!1;for(const i in e)i in t?e[i]!==n[i]&&(s=...
function je (line 6) | function je(t,e,n,o){Object.defineProperty(t,e,{enumerable:!0,configurab...
function Ee (line 6) | function Ee(t,e){for(const n in e)t[n]=e[n];for(const n in t)n in e||del...
function Ne (line 6) | function Ne(){const t=at;return t._setupContext||(t._setupContext=Te(t))}
function Ie (line 6) | function Ie(t,e){return(t.__esModule||it&&"Module"===t[Symbol.toStringTa...
function Le (line 6) | function Le(t){if(e(t))for(let e=0;e<t.length;e++){const n=t[e];if(o(n)&...
function Re (line 6) | function Re(t,e){Pe.$on(t,e)}
function Fe (line 6) | function Fe(t,e){Pe.$off(t,e)}
function He (line 6) | function He(t,e){const n=Pe;return function o(){null!==e.apply(null,argu...
function Be (line 6) | function Be(t,e,n){Pe=t,Xt(e,n||{},Re,Fe,He,t),Pe=void 0}
class Ue (line 6) | class Ue{constructor(t=!1){this.detached=t,this.active=!0,this.effects=[...
method constructor (line 6) | constructor(t=!1){this.detached=t,this.active=!0,this.effects=[],this....
method run (line 6) | run(t){if(this.active){const e=De;try{return De=this,t()}finally{De=e}}}
method on (line 6) | on(){De=this}
method off (line 6) | off(){De=this.parent}
method stop (line 6) | stop(t){if(this.active){let e,n;for(e=0,n=this.effects.length;e<n;e++)...
function ze (line 6) | function ze(){return De}
function Ke (line 6) | function Ke(t){const e=Ve;return Ve=t,()=>{Ve=e}}
function Je (line 6) | function Je(t){for(;t&&(t=t.$parent);)if(t._inactive)return!0;return!1}
function qe (line 6) | function qe(t,e){if(e){if(t._directInactive=!1,Je(t))return}else if(t._d...
function We (line 6) | function We(t,e){if(!(e&&(t._directInactive=!0,Je(t))||t._inactive)){t._...
function Ze (line 6) | function Ze(t,e,n,o=!0){_t();const r=at,s=ze();o&<(t);const i=t.$optio...
function sn (line 6) | function sn(){let t,e;for(nn=on(),tn=!0,Ge.sort(rn),en=0;en<Ge.length;en...
function cn (line 6) | function cn(t){const e=t.id;if(null==Ye[e]&&(t!==vt.target||!t.noRecurse...
function dn (line 6) | function dn(t,e){return hn(t,null,{flush:"post"})}
function hn (line 6) | function hn(n,o,{immediate:r,deep:s,flush:c="pre",onTrack:a,onTrigger:l}...
function mn (line 6) | function mn(t){const e=t._provided,n=t.$parent&&t.$parent._provided;retu...
function gn (line 6) | function gn(t,e,n){_t();try{if(e){let o=e;for(;o=o.$parent;){const r=o.$...
function vn (line 6) | function vn(t,e,n,o,r){let s;try{s=n?t.apply(e,n):t.call(e),s&&!s._isVue...
function yn (line 6) | function yn(t,e,n){if(B.errorHandler)try{return B.errorHandler.call(null...
function _n (line 6) | function _n(t,e,n){if(!q||"undefined"==typeof console)throw t;console.er...
function Cn (line 6) | function Cn(){xn=!1;const t=bn.slice(0);bn.length=0;for(let e=0;e<t.leng...
function kn (line 6) | function kn(t,e){let n;if(bn.push((()=>{if(t)try{t.call(e)}catch(t){gn(t...
function Sn (line 6) | function Sn(t){return(e,n=at)=>{if(n)return function(t,e,n){const o=t.$o...
method value (line 6) | get value(){return n()}
method value (line 6) | set value(t){o(t)}
method value (line 6) | get value(){return s?(s.dirty&&s.evaluate(),vt.target&&s.depend(),s.valu...
method value (line 6) | set value(t){o(t)}
function Un (line 6) | function Un(t){return zn(t,Bn),Bn.clear(),t}
function zn (line 6) | function zn(t,n){let o,r;const s=e(t);if(!(!s&&!c(t)||t.__v_skip||Object...
class Kn (line 6) | class Kn{constructor(t,e,n,o,r){!function(t,e=De){e&&e.active&&e.effects...
method constructor (line 6) | constructor(t,e,n,o,r){!function(t,e=De){e&&e.active&&e.effects.push(t...
method get (line 6) | get(){let t;_t(this);const e=this.vm;try{t=this.getter.call(e,e)}catch...
method addDep (line 6) | addDep(t){const e=t.id;this.newDepIds.has(e)||(this.newDepIds.add(e),t...
method cleanupDeps (line 6) | cleanupDeps(){let t=this.deps.length;for(;t--;){const e=this.deps[t];t...
method update (line 6) | update(){this.lazy?this.dirty=!0:this.sync?this.run():cn(this)}
method run (line 6) | run(){if(this.active){const t=this.get();if(t!==this.value||c(t)||this...
method evaluate (line 6) | evaluate(){this.value=this.get(),this.dirty=!1}
method depend (line 6) | depend(){let t=this.deps.length;for(;t--;)this.deps[t].depend()}
method teardown (line 6) | teardown(){if(this.vm&&!this.vm._isBeingDestroyed&&y(this.vm._scope.ef...
function qn (line 6) | function qn(t,e,n){Jn.get=function(){return this[e][n]},Jn.set=function(...
function Wn (line 6) | function Wn(t){const n=t.$options;if(n.props&&function(t,e){const n=t.$o...
function Gn (line 6) | function Gn(t,e,n){const o=!ot();i(n)?(Jn.get=o?Xn(e):Yn(n),Jn.set=E):(J...
function Xn (line 6) | function Xn(t){return function(){const e=this._computedWatchers&&this._c...
function Yn (line 6) | function Yn(t){return function(){return t.call(this,this)}}
function Qn (line 6) | function Qn(t,e,n,o){return l(n)&&(o=n,n=n.handler),"string"==typeof n&&...
function to (line 6) | function to(t,e){if(t){const n=Object.create(null),o=it?Reflect.ownKeys(...
function no (line 6) | function no(t){let e=t.options;if(t.super){const n=no(t.super);if(n!==t....
function oo (line 6) | function oo(n,o,s,i,c){const a=c.options;let l;$(i,"_uid")?(l=Object.cre...
function ro (line 6) | function ro(t,e,n,o,r){const s=pt(t);return s.fnContext=n,s.fnOptions=o,...
function so (line 6) | function so(t,e){for(const n in e)t[x(n)]=e[n]}
function io (line 6) | function io(t){return t.name||t.__name||t._componentTag}
method init (line 6) | init(t,e){if(t.componentInstance&&!t.componentInstance._isDestroyed&&t.d...
method prepatch (line 6) | prepatch(e,n){const o=n.componentOptions;!function(e,n,o,r,s){const i=r....
method insert (line 6) | insert(t){const{context:e,componentInstance:n}=t;var o;n._isMounted||(n....
method destroy (line 6) | destroy(t){const{componentInstance:e}=t;e._isDestroyed||(t.data.keepAliv...
function lo (line 6) | function lo(s,i,a,l,u){if(n(s))return;const d=a.$options._base;if(c(s)&&...
function uo (line 6) | function uo(t,e){const n=(n,o)=>{t(n,o),e(n,o)};return n._merged=!0,n}
function ho (line 6) | function ho(t,e,n=!0){if(!e)return t;let o,r,s;const i=it?Reflect.ownKey...
function mo (line 6) | function mo(t,e,n){return n?function(){const o=i(e)?e.call(n,n):e,r=i(t)...
function go (line 6) | function go(t,n){const o=n?t?t.concat(n):e(n)?n:[n]:t;return o?function(...
function vo (line 6) | function vo(t,e,n,o){const r=Object.create(t||null);return e?A(r,e):r}
function _o (line 6) | function _o(t,n,o){if(i(n)&&(n=n.options),function(t,n){const o=t.props;...
function $o (line 6) | function $o(t,e,n,o){if("string"!=typeof n)return;const r=t[e];if($(r,n)...
function bo (line 6) | function bo(t,e,n,o){const r=e[t],s=!$(n,t);let c=n[t];const a=ko(Boolea...
function xo (line 6) | function xo(t){const e=t&&t.toString().match(wo);return e?e[1]:""}
function Co (line 6) | function Co(t,e){return xo(t)===xo(e)}
function ko (line 6) | function ko(t,n){if(!e(n))return Co(n,t)?0:-1;for(let e=0,o=n.length;e<o...
function So (line 6) | function So(t){this._init(t)}
function Oo (line 6) | function Oo(t){t.cid=0;let e=1;t.extend=function(t){t=t||{};const n=this...
function To (line 6) | function To(t){return t&&(io(t.Ctor.options)||t.tag)}
function Ao (line 6) | function Ao(t,n){return e(t)?t.indexOf(n)>-1:"string"==typeof t?t.split(...
function jo (line 6) | function jo(t,e){const{cache:n,keys:o,_vnode:r,$vnode:s}=t;for(const t i...
function Eo (line 6) | function Eo(t,e,n,o){const r=t[e];!r||o&&r.tag===o.tag||r.componentInsta...
function o (line 6) | function o(){n.$off(t,o),e.apply(n,arguments)}
method cacheVNode (line 6) | cacheVNode(){const{cache:t,keys:e,vnodeToCache:n,keyToCache:o}=this;if(n...
method created (line 6) | created(){this.cache=Object.create(null),this.keys=[]}
method destroyed (line 6) | destroyed(){for(const t in this.cache)Eo(this.cache,t,this.keys)}
method mounted (line 6) | mounted(){this.cacheVNode(),this.$watch("include",(t=>{jo(this,(e=>Ao(t,...
method updated (line 6) | updated(){this.cacheVNode()}
method render (line 6) | render(){const t=this.$slots.default,e=Le(t),n=e&&e.componentOptions;if(...
method get (line 6) | get(){return this.$vnode&&this.$vnode.ssrContext}
function Ko (line 6) | function Ko(t){let e=t.data,n=t,r=t;for(;o(r.componentInstance);)r=r.com...
function Jo (line 6) | function Jo(t,e){return{staticClass:qo(t.staticClass,e.staticClass),clas...
function qo (line 6) | function qo(t,e){return t?e?t+" "+e:t:e||""}
function Wo (line 6) | function Wo(t){return Array.isArray(t)?function(t){let e,n="";for(let r=...
function Qo (line 6) | function Qo(t){return Xo(t)?"svg":"math"===t?"math":void 0}
function nr (line 6) | function nr(t){if("string"==typeof t){const e=document.querySelector(t);...
method create (line 6) | create(t,e){sr(e)}
method update (line 6) | update(t,e){t.data.ref!==e.data.ref&&(sr(t,!0),sr(e))}
method destroy (line 6) | destroy(t){sr(t,!0)}
function sr (line 6) | function sr(t,n){const r=t.data.ref;if(!o(r))return;const s=t.context,c=...
function ir (line 6) | function ir({_setupState:t},e,n){t&&$(t,e)&&(Ht(t[e])?t[e].value=n:t[e]=n)}
function lr (line 6) | function lr(t,e){return t.key===e.key&&t.asyncFactory===e.asyncFactory&&...
function ur (line 6) | function ur(t,e,n){let r,s;const i={};for(r=e;r<=n;++r)s=t[r].key,o(s)&&...
function dr (line 6) | function dr(t,e){(t.data.directives||e.data.directives)&&function(t,e){c...
function hr (line 6) | function hr(t,e){const n=Object.create(null);if(!t)return n;let o,r;for(...
function mr (line 6) | function mr(t){return t.rawName||`${t.name}.${Object.keys(t.modifiers||{...
function gr (line 6) | function gr(t,e,n,o,r){const s=t.def&&t.def[e];if(s)try{s(n.elm,t,n,o,r)...
function yr (line 6) | function yr(t,e){const s=e.componentOptions;if(o(s)&&!1===s.Ctor.options...
function _r (line 6) | function _r(t,e,n,o){o||t.tagName.indexOf("-")>-1?$r(t,e,n):Ho(e)?Vo(n)?...
function $r (line 6) | function $r(t,e,n){if(Vo(n))t.removeAttribute(e);else{if(Z&&!G&&"TEXTARE...
function wr (line 6) | function wr(t,e){const r=e.elm,s=e.data,i=t.data;if(n(s.staticClass)&&n(...
function kr (line 6) | function kr(t){let e,n,o,r,s,i=!1,c=!1,a=!1,l=!1,u=0,f=0,d=0,p=0;for(o=0...
function Sr (line 6) | function Sr(t,e){const n=e.indexOf("(");if(n<0)return`_f("${e}")(${t})`;...
function Or (line 6) | function Or(t,e){console.error(`[Vue compiler]: ${t}`)}
function Tr (line 6) | function Tr(t,e){return t?t.map((t=>t[e])).filter((t=>t)):[]}
function Ar (line 6) | function Ar(t,e,n,o,r){(t.props||(t.props=[])).push(Rr({name:e,value:n,d...
function jr (line 6) | function jr(t,e,n,o,r){(r?t.dynamicAttrs||(t.dynamicAttrs=[]):t.attrs||(...
function Er (line 6) | function Er(t,e,n,o){t.attrsMap[e]=n,t.attrsList.push(Rr({name:e,value:n...
function Nr (line 6) | function Nr(t,e,n,o,r,s,i,c){(t.directives||(t.directives=[])).push(Rr({...
function Pr (line 6) | function Pr(t,e,n){return n?`_p(${e},"${t}")`:t+e}
function Dr (line 6) | function Dr(e,n,o,r,s,i,c,a){let l;(r=r||t).right?a?n=`(${n})==='click'?...
function Mr (line 6) | function Mr(t,e,n){const o=Ir(t,":"+e)||Ir(t,"v-bind:"+e);if(null!=o)ret...
function Ir (line 6) | function Ir(t,e,n){let o;if(null!=(o=t.attrsMap[e])){const n=t.attrsList...
function Lr (line 6) | function Lr(t,e){const n=t.attrsList;for(let t=0,o=n.length;t<o;t++){con...
function Rr (line 6) | function Rr(t,e){return e&&(null!=e.start&&(t.start=e.start),null!=e.end...
function Fr (line 6) | function Fr(t,e,n){const{number:o,trim:r}=n||{},s="$$v";let i=s;r&&(i=`(...
function Hr (line 6) | function Hr(t,e){const n=function(t){if(t=t.trim(),Br=t.length,t.indexOf...
function qr (line 6) | function qr(){return Ur.charCodeAt(++Vr)}
function Wr (line 6) | function Wr(){return Vr>=Br}
function Zr (line 6) | function Zr(t){return 34===t||39===t}
function Gr (line 6) | function Gr(t){let e=1;for(Kr=Vr;!Wr();)if(Zr(t=qr()))Xr(t);else if(91==...
function Xr (line 6) | function Xr(t){const e=t;for(;!Wr()&&(t=qr())!==e;);}
function es (line 6) | function es(t,e,n){const o=ts;return function r(){null!==e.apply(null,ar...
function os (line 6) | function os(t,e,n,o){if(ns){const t=nn,n=e;e=n._wrapper=function(e){if(e...
function rs (line 6) | function rs(t,e,n,o){(o||ts).removeEventListener(t,e._wrapper||e,n)}
function ss (line 6) | function ss(t,e){if(n(t.data.on)&&n(e.data.on))return;const r=e.data.on|...
function as (line 6) | function as(t,e){if(n(t.data.domProps)&&n(e.data.domProps))return;let s,...
function ls (line 6) | function ls(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e...
function ds (line 6) | function ds(t){const e=ps(t.style);return t.staticStyle?A(t.staticStyle,...
function ps (line 6) | function ps(t){return Array.isArray(t)?j(t):"string"==typeof t?fs(t):t}
function $s (line 6) | function $s(t,e){const r=e.data,s=t.data;if(n(r.staticStyle)&&n(r.style)...
function xs (line 6) | function xs(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.s...
function Cs (line 6) | function Cs(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.s...
function ks (line 6) | function ks(t){if(t){if("object"==typeof t){const e={};return!1!==t.css&...
function Ms (line 6) | function Ms(t){Ds((()=>{Ds(t)}))}
function Is (line 6) | function Is(t,e){const n=t._transitionClasses||(t._transitionClasses=[])...
function Ls (line 6) | function Ls(t,e){t._transitionClasses&&y(t._transitionClasses,e),Cs(t,e)}
function Rs (line 6) | function Rs(t,e,n){const{type:o,timeout:r,propCount:s}=Hs(t,e);if(!o)ret...
function Hs (line 6) | function Hs(t,e){const n=window.getComputedStyle(t),o=(n[js+"Delay"]||""...
function Bs (line 6) | function Bs(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max.a...
function Us (line 6) | function Us(t){return 1e3*Number(t.slice(0,-1).replace(",","."))}
function zs (line 6) | function zs(t,e){const r=t.elm;o(r._leaveCb)&&(r._leaveCb.cancelled=!0,r...
function Vs (line 6) | function Vs(t,e){const r=t.elm;o(r._enterCb)&&(r._enterCb.cancelled=!0,r...
function Ks (line 6) | function Ks(t){return"number"==typeof t&&!isNaN(t)}
function Js (line 6) | function Js(t){if(n(t))return!1;const e=t.fns;return o(e)?Js(Array.isArr...
function qs (line 6) | function qs(t,e){!0!==e.data.show&&zs(e)}
function f (line 6) | function f(t){const e=u.parentNode(t);o(e)&&u.removeChild(e,t)}
function d (line 6) | function d(t,e,n,s,i,c,l){if(o(t.elm)&&o(c)&&(t=c[l]=pt(t)),t.isRootInse...
function p (line 6) | function p(t,e){o(t.data.pendingInsert)&&(e.push.apply(e,t.data.pendingI...
function h (line 6) | function h(t,e,n){o(t)&&(o(n)?u.parentNode(n)===t&&u.insertBefore(t,e,n)...
function g (line 6) | function g(t,n,o){if(e(n))for(let e=0;e<n.length;++e)d(n[e],o,t.elm,null...
function v (line 6) | function v(t){for(;t.componentInstance;)t=t.componentInstance._vnode;ret...
function y (line 6) | function y(t,e){for(let e=0;e<a.create.length;++e)a.create[e](cr,t);i=t....
function _ (line 6) | function _(t){let e;if(o(e=t.fnScopeId))u.setStyleScope(t.elm,e);else{le...
function $ (line 6) | function $(t,e,n,o,r,s){for(;o<=r;++o)d(n[o],s,t,e,!1,n,o)}
function b (line 6) | function b(t){let e,n;const r=t.data;if(o(r))for(o(e=r.hook)&&o(e=e.dest...
function w (line 6) | function w(t,e,n){for(;e<=n;++e){const n=t[e];o(n)&&(o(n.tag)?(x(n),b(n)...
function x (line 6) | function x(t,e){if(o(e)||o(t.data)){let n;const r=a.remove.length+1;for(...
function C (line 6) | function C(t,e,n,r){for(let s=n;s<r;s++){const n=e[s];if(o(n)&&lr(t,n))r...
function k (line 6) | function k(t,e,s,i,c,l){if(t===e)return;o(e.elm)&&o(i)&&(e=i[c]=pt(e));c...
function S (line 6) | function S(t,e,n){if(r(n)&&o(t.parent))t.parent.data.pendingInsert=e;els...
function T (line 6) | function T(t,e,n,s){let i;const{tag:c,data:a,children:l}=e;if(s=s||a&&a....
method remove (line 6) | remove(t,e){!0!==t.data.show?Vs(t,e):e()}
method inserted (line 6) | inserted(t,e,n,o){"select"===n.tag?(o.elm&&!o.elm._vOptions?Yt(n,"postpa...
method componentUpdated (line 6) | componentUpdated(t,e,n){if("select"===n.tag){Gs(t,e,n.context);const o=t...
function Gs (line 6) | function Gs(t,e,n){Xs(t,e),(Z||X)&&setTimeout((()=>{Xs(t,e)}),0)}
function Xs (line 6) | function Xs(t,e,n){const o=e.value,r=t.multiple;if(r&&!Array.isArray(o))...
function Ys (line 6) | function Ys(t,e){return e.every((e=>!D(e,t)))}
function Qs (line 6) | function Qs(t){return"_value"in t?t._value:t.value}
function ti (line 6) | function ti(t){t.target.composing=!0}
function ei (line 6) | function ei(t){t.target.composing&&(t.target.composing=!1,ni(t.target,"i...
function ni (line 6) | function ni(t,e){const n=document.createEvent("HTMLEvents");n.initEvent(...
function oi (line 6) | function oi(t){return!t.componentInstance||t.data&&t.data.transition?t:o...
method bind (line 6) | bind(t,{value:e},n){const o=(n=oi(n)).data&&n.data.transition,r=t.__vOri...
method update (line 6) | update(t,{value:e,oldValue:n},o){if(!e==!n)return;(o=oi(o)).data&&o.data...
method unbind (line 6) | unbind(t,e,n,o,r){r||(t.style.display=t.__vOriginalDisplay)}
function ci (line 6) | function ci(t){const e=t&&t.componentOptions;return e&&e.Ctor.options.ab...
function ai (line 6) | function ai(t){const e={},n=t.$options;for(const o in n.propsData)e[o]=t...
function li (line 6) | function li(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{...
method render (line 6) | render(t){let e=this.$slots.default;if(!e)return;if(e=e.filter(ui),!e.le...
method beforeMount (line 6) | beforeMount(){const t=this._update;this._update=(e,n)=>{const o=Ke(this)...
method render (line 6) | render(t){const e=this.tag||this.$vnode.data.tag||"span",n=Object.create...
method updated (line 6) | updated(){const t=this.prevChildren,e=this.moveClass||(this.name||"v")+"...
method hasMove (line 6) | hasMove(t,e){if(!Os)return!1;if(this._hasMove)return this._hasMove;const...
function mi (line 6) | function mi(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._ent...
function gi (line 6) | function gi(t){t.data.newPos=t.elm.getBoundingClientRect()}
function vi (line 6) | function vi(t){const e=t.data.pos,n=t.data.newPos,o=e.left-n.left,r=e.to...
method before (line 6) | before(){t._isMounted&&!t._isDestroyed&&Ze(t,"beforeUpdate")}
function Ji (line 6) | function Ji(t,e){const n=e?zi:Ui;return t.replace(n,(t=>Bi[t]))}
function mc (line 6) | function mc(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:wc(e),rawAtt...
function gc (line 6) | function gc(t,e){cc=e.warn||Or,dc=e.isPreTag||N,pc=e.mustUseProp||N,hc=e...
function vc (line 6) | function vc(t,e){var n;!function(t){const e=Mr(t,"key");e&&(t.key=e)}(t)...
function yc (line 6) | function yc(t){let e;if(e=Ir(t,"v-for")){const n=function(t){const e=t.m...
function _c (line 6) | function _c(t,e){t.ifConditions||(t.ifConditions=[]),t.ifConditions.push...
function $c (line 6) | function $c(t){let e=t.name.replace(nc,"");return e||"#"!==t.name[0]&&(e...
function bc (line 6) | function bc(t){const e=t.match(ec);if(e){const t={};return e.forEach((e=...
function wc (line 6) | function wc(t){const e={};for(let n=0,o=t.length;n<o;n++)e[t[n].name]=t[...
function kc (line 6) | function kc(t){return mc(t.tag,t.attrsList.slice(),t.parent)}
function Ec (line 6) | function Ec(t,e){t&&(Tc=jc(e.staticKeys||""),Ac=e.isReservedTag||N,Nc(t)...
function Nc (line 6) | function Nc(t){if(t.static=function(t){if(2===t.type)return!1;if(3===t.t...
function Pc (line 6) | function Pc(t,e){if(1===t.type){if((t.static||t.once)&&(t.staticInFor=e)...
function Bc (line 6) | function Bc(t,e){const n=e?"nativeOn:":"on:";let o="",r="";for(const e i...
function Uc (line 6) | function Uc(t){if(!t)return"function(){}";if(Array.isArray(t))return`[${...
function zc (line 6) | function zc(t){const e=parseInt(t,10);if(e)return`$event.keyCode!==${e}`...
class Kc (line 6) | class Kc{constructor(t){this.options=t,this.warn=t.warn||Or,this.transfo...
method constructor (line 6) | constructor(t){this.options=t,this.warn=t.warn||Or,this.transforms=Tr(...
function Jc (line 6) | function Jc(t,e){const n=new Kc(e);return{render:`with(this){return ${t?...
function qc (line 6) | function qc(t,e){if(t.parent&&(t.pre=t.pre||t.parent.pre),t.staticRoot&&...
function Wc (line 6) | function Wc(t,e){t.staticProcessed=!0;const n=e.pre;return t.pre&&(e.pre...
function Zc (line 6) | function Zc(t,e){if(t.onceProcessed=!0,t.if&&!t.ifProcessed)return Gc(t,...
function Gc (line 6) | function Gc(t,e,n,o){return t.ifProcessed=!0,Xc(t.ifConditions.slice(),e...
function Xc (line 6) | function Xc(t,e,n,o){if(!t.length)return o||"_e()";const r=t.shift();ret...
function Yc (line 6) | function Yc(t,e,n,o){const r=t.for,s=t.alias,i=t.iterator1?`,${t.iterato...
function Qc (line 6) | function Qc(t,e){let n="{";const o=function(t,e){const n=t.directives;if...
function ta (line 6) | function ta(t){return 1===t.type&&("slot"===t.tag||t.children.some(ta))}
function ea (line 6) | function ea(t,e){const n=t.attrsMap["slot-scope"];if(t.if&&!t.ifProcesse...
function na (line 6) | function na(t,e,n,o,r){const s=t.children;if(s.length){const t=s[0];if(1...
function oa (line 6) | function oa(t){return void 0!==t.for||"template"===t.tag||"slot"===t.tag}
function ra (line 6) | function ra(t,e){return 1===t.type?qc(t,e):3===t.type&&t.isComment?funct...
function sa (line 6) | function sa(t){let e="",n="";for(let o=0;o<t.length;o++){const r=t[o],s=...
function ia (line 6) | function ia(t){return t.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"...
function ca (line 6) | function ca(t,e){try{return new Function(t)}catch(n){return e.push({err:...
function aa (line 6) | function aa(t){const e=Object.create(null);return function(n,o,r){(o=A({...
function e (line 6) | function e(e,n){const o=Object.create(t),r=[],s=[];if(n){n.modules&&(o.m...
function ha (line 6) | function ha(t){return pa=pa||document.createElement("div"),pa.innerHTML=...
FILE: web/assets/vue/vue.esm.browser.js
function isUndef (line 10) | function isUndef(v) {
function isDef (line 13) | function isDef(v) {
function isTrue (line 16) | function isTrue(v) {
function isFalse (line 19) | function isFalse(v) {
function isPrimitive (line 25) | function isPrimitive(value) {
function isFunction (line 32) | function isFunction(value) {
function isObject (line 40) | function isObject(obj) {
function toRawType (line 47) | function toRawType(value) {
function isPlainObject (line 54) | function isPlainObject(obj) {
function isRegExp (line 57) | function isRegExp(v) {
function isValidArrayIndex (line 63) | function isValidArrayIndex(val) {
function isPromise (line 67) | function isPromise(
Condensed preview — 184 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,258K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 535,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 604,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is"
},
{
"path": ".github/ISSUE_TEMPLATE/question-.md",
"chars": 122,
"preview": "---\nname: 'Question '\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: question\nassignees: ''\n\n---\n"
},
{
"path": ".github/dependabot.yml",
"chars": 277,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"gomod\" # See documentation for possible values\n directory: \"/\" # Location"
},
{
"path": ".github/workflows/docker.yml",
"chars": 1074,
"preview": "name: Release 3X-UI for Docker\non:\n push:\n tags:\n - \"*\"\n workflow_dispatch:\n\njobs:\n build_and_push:\n runs-"
},
{
"path": ".github/workflows/release.yml",
"chars": 5217,
"preview": "name: Release 3X-UI\n\non:\n push:\n tags:\n - \"*\"\n workflow_dispatch:\n\njobs:\n build:\n strategy:\n matrix:\n"
},
{
"path": ".gitignore",
"chars": 119,
"preview": ".idea\n.vscode\n.cache\n.sync*\n*.tar.gz\n*.log\naccess.log\nerror.log\ntmp\nmain\nbackup/\nbin/\ndist/\nrelease/\n/release.sh\n/x-ui\n"
},
{
"path": "DockerEntrypoint.sh",
"chars": 80,
"preview": "#!/bin/sh\n\n# Start fail2ban\nfail2ban-client -x start\n\n# Run x-ui\nexec /app/x-ui\n"
},
{
"path": "DockerInit.sh",
"chars": 1284,
"preview": "#!/bin/sh\ncase $1 in\n amd64)\n ARCH=\"64\"\n FNAME=\"amd64\"\n ;;\n i386)\n ARCH=\"32\"\n F"
},
{
"path": "Dockerfile",
"chars": 1345,
"preview": "# ========================================================\n# Stage: Builder\n# =========================================="
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.es_ES.md",
"chars": 17285,
"preview": "[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)\n\n<p align=\"center\"><a href=\"#\"><img src=\""
},
{
"path": "README.md",
"chars": 19215,
"preview": "<p align=\"center\"><a href=\"#\"><img src=\"./media/3X-UI.png\" alt=\"Image\"></a></p>\n\n**------------------一个更好的面板 • 基于Xray Co"
},
{
"path": "README.zh.md",
"chars": 11256,
"preview": "[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)\n\n<p align=\"center\"><a href=\"#\"><img src=\""
},
{
"path": "config/config.go",
"chars": 1226,
"preview": "package config\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\n//go:embed version\nvar version string\n\n//go:embed name\nva"
},
{
"path": "config/name",
"chars": 4,
"preview": "x-ui"
},
{
"path": "config/version",
"chars": 5,
"preview": "2.3.8"
},
{
"path": "database/db.go",
"chars": 2091,
"preview": "package database\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\n\t\"x-ui/config\"\n\t\"x-ui/database/model\"\n\t\"x-ui/xray\"\n\n\t\""
},
{
"path": "database/model/model.go",
"chars": 3349,
"preview": "package model\n\nimport (\n\t\"fmt\"\n\n\t\"x-ui/util/json_util\"\n\t\"x-ui/xray\"\n)\n\ntype Protocol string\n\nconst (\n\tVMess Protoc"
},
{
"path": "docker-compose.yml",
"chars": 321,
"preview": "---\nversion: \"3\"\n\nservices:\n 3x-ui:\n image: ghcr.io/xeefei/3x-ui:latest\n container_name: 3x-ui\n hostname: your"
},
{
"path": "go.mod",
"chars": 4686,
"preview": "module x-ui\n\ngo 1.22.4\n\nrequire (\n\tgithub.com/gin-contrib/gzip v1.0.1\n\tgithub.com/gin-contrib/sessions v1.0.1\n\tgithub.co"
},
{
"path": "go.sum",
"chars": 39722,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.31.0/go.mod h1"
},
{
"path": "install.sh",
"chars": 13120,
"preview": "#!/bin/bash\n\nred='\\033[0;31m'\ngreen='\\033[0;32m'\nyellow='\\033[0;33m'\nplain='\\033[0m'\n\ncur_dir=$(pwd)\n\n# check root\n[[ $E"
},
{
"path": "logger/logger.go",
"chars": 2877,
"preview": "package logger\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/op/go-logging\"\n)\n\nvar (\n\tlogger *logging.Logger\n\tlogBuffe"
},
{
"path": "main.go",
"chars": 13427,
"preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"os/exec\"\n \"strings\"\n\t\"syscall\"\n\t_ \"unsafe\"\n\n\t\"x"
},
{
"path": "sub/default.json",
"chars": 1449,
"preview": "{\n \"remarks\": \"\",\n \"dns\": {\n \"tag\": \"dns_out\",\n \"queryStrategy\": \"UseIP\",\n \"servers\": [\n {\n \"addr"
},
{
"path": "sub/sub.go",
"chars": 3810,
"preview": "package sub\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"x-ui/config\"\n\t\"x-ui/logger\"\n\t\"x-ui"
},
{
"path": "sub/subController.go",
"chars": 2466,
"preview": "package sub\n\nimport (\n\t\"encoding/base64\"\n\t\"net\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype SUBController struct {\n\tsubPath "
},
{
"path": "sub/subJsonService.go",
"chars": 11493,
"preview": "package sub\n\nimport (\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"x-ui/database/model\"\n\t\"x-ui/logger\"\n\t\"x-ui/util/j"
},
{
"path": "sub/subService.go",
"chars": 32286,
"preview": "package sub\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-ui/database\"\n\t\"x-ui/database/model\"\n\t"
},
{
"path": "util/common/err.go",
"chars": 440,
"preview": "package common\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"x-ui/logger\"\n)\n\nfunc NewErrorf(format string, a ...interface{}) error {\n\tms"
},
{
"path": "util/common/format.go",
"chars": 795,
"preview": "package common\n\nimport (\n\t\"fmt\"\n)\n\nfunc FormatTraffic(trafficBytes int64) (size string) {\n\tif trafficBytes < 1024 {\n\t\tre"
},
{
"path": "util/common/multi_error.go",
"chars": 457,
"preview": "package common\n\nimport (\n\t\"strings\"\n)\n\ntype multiError []error\n\nfunc (e multiError) Error() string {\n\tvar r strings.Buil"
},
{
"path": "util/json_util/json.go",
"chars": 479,
"preview": "package json_util\n\nimport (\n\t\"errors\"\n)\n\ntype RawMessage []byte\n\n// MarshalJSON: Customize json.RawMessage default behav"
},
{
"path": "util/random/random.go",
"chars": 826,
"preview": "package random\n\nimport (\n\t\"math/rand\"\n)\n\nvar (\n\tnumSeq [10]rune\n\tlowerSeq [26]rune\n\tupperSeq [26]rune\n\tnumLow"
},
{
"path": "util/reflect_util/reflect.go",
"chars": 453,
"preview": "package reflect_util\n\nimport \"reflect\"\n\nfunc GetFields(t reflect.Type) []reflect.StructField {\n\tnum := t.NumField()\n\tfie"
},
{
"path": "util/sys/psutil.go",
"chars": 159,
"preview": "package sys\n\nimport (\n\t_ \"unsafe\"\n)\n\n//go:linkname HostProc github.com/shirou/gopsutil/v4/internal/common.HostProc\nfunc "
},
{
"path": "util/sys/sys_darwin.go",
"chars": 367,
"preview": "//go:build darwin\n// +build darwin\n\npackage sys\n\nimport (\n\t\"github.com/shirou/gopsutil/v4/net\"\n)\n\nfunc GetTCPCount() (in"
},
{
"path": "util/sys/sys_linux.go",
"chars": 1095,
"preview": "//go:build linux\n// +build linux\n\npackage sys\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\nfunc getLinesNum(filename string)"
},
{
"path": "util/sys/sys_windows.go",
"chars": 492,
"preview": "//go:build windows\n// +build windows\n\npackage sys\n\nimport (\n\t\"errors\"\n\n\t\"github.com/shirou/gopsutil/v4/net\"\n)\n\nfunc GetC"
},
{
"path": "web/assets/ant-design-vue/antd.less",
"chars": 183,
"preview": "@import \"../lib/style/index.less\";\n@import \"../lib/style/components.less\";\n\n@green-6: #008771;\n@primary-color: @green-6;"
},
{
"path": "web/assets/codemirror/codemirror.css",
"chars": 6338,
"preview": " .CodeMirror{font-family:monospace;height:300px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pr"
},
{
"path": "web/assets/codemirror/codemirror.js",
"chars": 401829,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/fold/brace-fold.js",
"chars": 4475,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/fold/foldcode.js",
"chars": 4985,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/fold/foldgutter.css",
"chars": 435,
"preview": ".CodeMirror-foldmarker {\n color: blue;\n text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1p"
},
{
"path": "web/assets/codemirror/fold/foldgutter.js",
"chars": 5539,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/hint/javascript-hint.js",
"chars": 6855,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/javascript.js",
"chars": 38894,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/jshint.js",
"chars": 1284243,
"preview": "/*! 2.13.2 */\nvar JSHINT;\nif (typeof window === 'undefined') window = {};\n(function () {\nvar require;\nrequire=(function "
},
{
"path": "web/assets/codemirror/jsonlint.js",
"chars": 8775,
"preview": "var jsonlint=function(){var a=!0,b=!1,c={},d=function(){var a={trace:function(){},yy:{},symbols_:{error:2,JSONString:3,S"
},
{
"path": "web/assets/codemirror/lint/javascript-lint.js",
"chars": 2161,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/lint/lint.css",
"chars": 3035,
"preview": "/* The lint marker gutter */\n.CodeMirror-lint-markers {\n width: 16px;\n}\n\n.CodeMirror-lint-tooltip {\n background-color:"
},
{
"path": "web/assets/codemirror/lint/lint.js",
"chars": 9841,
"preview": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/"
},
{
"path": "web/assets/codemirror/xq.css",
"chars": 5386,
"preview": "/*\nCopyright (C) 2011 by MarkLogic Corporation\nAuthor: Mike Brevoort <mike@brevoort.com>\n\nPermission is hereby granted, "
},
{
"path": "web/assets/css/custom.css",
"chars": 31308,
"preview": ":root{--color-primary-100:#008771;--dark-color-background:#0a1222;--dark-color-surface-100:#151f31;--dark-color-surface-"
},
{
"path": "web/assets/element-ui/theme-chalk/display.css",
"chars": 982,
"preview": "@media only screen and (max-width:767px){.hidden-xs-only{display:none!important}}@media only screen and (min-width:768px"
},
{
"path": "web/assets/js/axios-init.js",
"chars": 915,
"preview": "axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';\naxios.defaults.headers"
},
{
"path": "web/assets/js/langs.js",
"chars": 1537,
"preview": "const supportLangs = [\n {\n name: 'English',\n value: 'en-US',\n icon: '🇺🇸',\n },\n {\n n"
},
{
"path": "web/assets/js/model/dbinbound.js",
"chars": 3473,
"preview": "class DBInbound {\n\n constructor(data) {\n this.id = 0;\n this.userId = 0;\n this.up = 0;\n th"
},
{
"path": "web/assets/js/model/outbound.js",
"chars": 35439,
"preview": "const Protocols = {\n Freedom: \"freedom\",\n Blackhole: \"blackhole\",\n DNS: \"dns\",\n VMess: \"vmess\",\n VLESS: \""
},
{
"path": "web/assets/js/model/setting.js",
"chars": 1512,
"preview": "class AllSetting {\n\n constructor(data) {\n this.webListen = \"\";\n this.webDomain = \"\";\n this.webPo"
},
{
"path": "web/assets/js/model/xray.js",
"chars": 81516,
"preview": "const Protocols = {\n VMESS: 'vmess',\n VLESS: 'vless',\n TROJAN: 'trojan',\n SHADOWSOCKS: 'shadowsocks',\n DO"
},
{
"path": "web/assets/js/util/common.js",
"chars": 5109,
"preview": "const ONE_KB = 1024;\nconst ONE_MB = ONE_KB * 1024;\nconst ONE_GB = ONE_MB * 1024;\nconst ONE_TB = ONE_GB * 1024;\nconst ONE"
},
{
"path": "web/assets/js/util/date-util.js",
"chars": 3328,
"preview": "const oneMinute = 1000 * 60; // MilliseConds in a Minute\nconst oneHour = oneMinute * 60; // The milliseconds of one ho"
},
{
"path": "web/assets/js/util/utils.js",
"chars": 12226,
"preview": "class Msg {\n constructor(success, msg, obj) {\n this.success = false;\n this.msg = \"\";\n this.obj ="
},
{
"path": "web/assets/vue/vue.common.dev.js",
"chars": 399507,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n'use strict';\n\nconst emptyObject "
},
{
"path": "web/assets/vue/vue.common.js",
"chars": 157,
"preview": "if (process.env.NODE_ENV === 'production') {\n module.exports = require('./vue.common.prod.js')\n} else {\n module.export"
},
{
"path": "web/assets/vue/vue.common.prod.js",
"chars": 104066,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n\"use strict\";const t=Object.freez"
},
{
"path": "web/assets/vue/vue.esm.browser.js",
"chars": 397987,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\nconst emptyObject = Object.freeze"
},
{
"path": "web/assets/vue/vue.esm.js",
"chars": 419085,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\nvar emptyObject = Object.freeze({"
},
{
"path": "web/assets/vue/vue.js",
"chars": 434842,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n(function (global, factory) {\n t"
},
{
"path": "web/assets/vue/vue.runtime.common.dev.js",
"chars": 291035,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n'use strict';\n\nconst emptyObject "
},
{
"path": "web/assets/vue/vue.runtime.common.js",
"chars": 173,
"preview": "if (process.env.NODE_ENV === 'production') {\n module.exports = require('./vue.runtime.common.prod.js')\n} else {\n modul"
},
{
"path": "web/assets/vue/vue.runtime.common.prod.js",
"chars": 74574,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n\"use strict\";const t=Object.freez"
},
{
"path": "web/assets/vue/vue.runtime.esm.js",
"chars": 305145,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\nvar emptyObject = Object.freeze({"
},
{
"path": "web/assets/vue/vue.runtime.js",
"chars": 316330,
"preview": "/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\n(function (global, factory) {\n t"
},
{
"path": "web/assets/vue/vue.runtime.mjs",
"chars": 1024,
"preview": "import Vue from './vue.runtime.common.js'\nexport default Vue\n\n// this should be kept in sync with src/v3/index.ts\nexport"
},
{
"path": "web/controller/api.go",
"chars": 1895,
"preview": "package controller\n\nimport (\n\t\"x-ui/web/service\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype APIController struct {\n\tBaseContro"
},
{
"path": "web/controller/base.go",
"chars": 825,
"preview": "package controller\n\nimport (\n\t\"net/http\"\n\n\t\"x-ui/logger\"\n\t\"x-ui/web/locale\"\n\t\"x-ui/web/session\"\n\n\t\"github.com/gin-gonic/"
},
{
"path": "web/controller/inbound.go",
"chars": 8163,
"preview": "package controller\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"x-ui/database/model\"\n\t\"x-ui/web/service\"\n\t\"x-ui/web/s"
},
{
"path": "web/controller/index.go",
"chars": 2971,
"preview": "package controller\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"x-ui/logger\"\n\t\"x-ui/web/service\"\n\t\"x-ui/web/session\"\n\n\t\"github.com/g"
},
{
"path": "web/controller/server.go",
"chars": 4399,
"preview": "package controller\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"time\"\n\n\t\"x-ui/web/global\"\n\t\"x-ui/web/service\"\n\n\t\"github.com/"
},
{
"path": "web/controller/setting.go",
"chars": 4094,
"preview": "package controller\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"x-ui/web/entity\"\n\t\"x-ui/web/service\"\n\t\"x-ui/web/session\"\n\n\t\"github.com"
},
{
"path": "web/controller/util.go",
"chars": 1909,
"preview": "package controller\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"x-ui/config\"\n\t\"x-ui/logger\"\n\t\"x-ui/web/entity\"\n\n\t\"github.c"
},
{
"path": "web/controller/xray_setting.go",
"chars": 3045,
"preview": "package controller\n\nimport (\n\t\"x-ui/web/service\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype XraySettingController struct {\n\tXr"
},
{
"path": "web/controller/xui.go",
"chars": 1299,
"preview": "package controller\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype XUIController struct {\n\tBaseController\n\n\tinboundControl"
},
{
"path": "web/entity/entity.go",
"chars": 4566,
"preview": "package entity\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-ui/util/common\"\n)\n\ntype Msg struct {\n\tSuccess bool"
},
{
"path": "web/global/global.go",
"chars": 473,
"preview": "package global\n\nimport (\n\t\"context\"\n\t_ \"unsafe\"\n\n\t\"github.com/robfig/cron/v3\"\n)\n\nvar (\n\twebServer WebServer\n\tsubServer S"
},
{
"path": "web/global/hashStorage.go",
"chars": 1337,
"preview": "package global\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"regexp\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype HashEntry struct {\n\tHash s"
},
{
"path": "web/html/common/head.html",
"chars": 1304,
"preview": "{{define \"head\"}}\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"renderer\" content=\"webkit\">\n <meta http-equiv=\"X-UA-Com"
},
{
"path": "web/html/common/js.html",
"chars": 862,
"preview": "{{define \"js\"}}\n<script src=\"{{ .base_path }}assets/vue/vue.min.js?{{ .cur_ver }}\"></script>\n<script src=\"{{ .base_path "
},
{
"path": "web/html/common/prompt_modal.html",
"chars": 2077,
"preview": "{{define \"promptModal\"}}\n<a-modal id=\"prompt-modal\" v-model=\"promptModal.visible\" :title=\"promptModal.title\"\n :c"
},
{
"path": "web/html/common/qrcode_modal.html",
"chars": 4529,
"preview": "{{define \"qrcodeModal\"}}\n<style>\n.qr-container {\n display: flex;\n justify-content: center; /* 在水平方向上居中 */\n}\n.qr-bg {\n "
},
{
"path": "web/html/common/text_modal.html",
"chars": 1813,
"preview": "{{define \"textModal\"}}\n<a-modal id=\"text-modal\" v-model=\"txtModal.visible\" :title=\"txtModal.title\"\n :closable=\"t"
},
{
"path": "web/html/login.html",
"chars": 15561,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n{{template \"head\" .}}\n<style>\n html * {\n -webkit-font-smoothing: antialiased;\n -"
},
{
"path": "web/html/xui/client_bulk_modal.html",
"chars": 11732,
"preview": "{{define \"clientsBulkModal\"}}\n<a-modal id=\"client-bulk-modal\" v-model=\"clientsBulkModal.visible\" :title=\"clientsBulkModa"
},
{
"path": "web/html/xui/client_modal.html",
"chars": 7118,
"preview": "{{define \"clientsModal\"}}\n<a-modal id=\"client-modal\" v-model=\"clientModal.visible\" :title=\"clientModal.title\" @ok=\"clien"
},
{
"path": "web/html/xui/common_sider.html",
"chars": 2382,
"preview": "{{define \"menuItems\"}}\n<a-menu-item key=\"{{ .base_path }}panel/\">\n <a-icon type=\"dashboard\"></a-icon>\n <span>\n <b>{"
},
{
"path": "web/html/xui/component/password.html",
"chars": 977,
"preview": "{{define \"component/passwordInput\"}}\n<template>\n <a-input :value=\"value\" :type=\"showPassword ? 'text' : 'password'\"\n "
},
{
"path": "web/html/xui/component/persianDatepicker.html",
"chars": 2159,
"preview": "{{define \"component/persianDatepickerTemplate\"}}\n<template>\n <div>\n <a-input :value=\"value\" type=\"text\" v-mode"
},
{
"path": "web/html/xui/component/setting.html",
"chars": 1616,
"preview": "{{define \"component/settingListItem\"}}\n<a-list-item style=\"padding: 20px\">\n <a-row v-if=\"type === 'textarea'\">\n "
},
{
"path": "web/html/xui/component/sortableTable.html",
"chars": 7805,
"preview": "{{define \"component/sortableTableTrigger\"}}\n <a-icon type=\"drag\"\n class=\"sortable-icon\"\n style=\"cursor:"
},
{
"path": "web/html/xui/component/themeSwitch.html",
"chars": 2772,
"preview": "{{define \"component/themeSwitchTemplate\"}}\n<template>\n <a-menu class=\"change-theme\" :theme=\"themeSwitcher.currentTheme\""
},
{
"path": "web/html/xui/dns_modal.html",
"chars": 3184,
"preview": "{{define \"dnsModal\"}}\n<a-modal id=\"dns-modal\" v-model=\"dnsModal.visible\" :title=\"dnsModal.title\" @ok=\"dnsModal.ok\" :clos"
},
{
"path": "web/html/xui/fakedns_modal.html",
"chars": 1918,
"preview": "{{define \"fakednsModal\"}}\n<a-modal id=\"fakedns-modal\" v-model=\"fakednsModal.visible\" :title=\"fakednsModal.title\" @ok=\"fa"
},
{
"path": "web/html/xui/form/client.html",
"chars": 8128,
"preview": "{{define \"form/client\"}}\n<a-form layout=\"horizontal\" v-if=\"client\" :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper"
},
{
"path": "web/html/xui/form/inbound.html",
"chars": 3993,
"preview": "{{define \"form/inbound\"}}\n<!-- base -->\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:1"
},
{
"path": "web/html/xui/form/outbound.html",
"chars": 22640,
"preview": "{{define \"form/outbound\"}}\n<!-- base -->\n<a-tabs :active-key=\"outModal.activeKey\" style=\"padding: 0; background-color: "
},
{
"path": "web/html/xui/form/protocol/dokodemo.html",
"chars": 1146,
"preview": "{{define \"form/dokodemo\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <a"
},
{
"path": "web/html/xui/form/protocol/http.html",
"chars": 1167,
"preview": "{{define \"form/http\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <t"
},
{
"path": "web/html/xui/form/protocol/shadowsocks.html",
"chars": 2359,
"preview": "{{define \"form/shadowsocks\"}}\n<template v-if=\"inbound.isSSMultiUser\">\n <a-collapse activeKey=\"0\" v-for=\"(client, inde"
},
{
"path": "web/html/xui/form/protocol/socks.html",
"chars": 1759,
"preview": "{{define \"form/socks\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <a-fo"
},
{
"path": "web/html/xui/form/protocol/trojan.html",
"chars": 2325,
"preview": "{{define \"form/trojan\"}}\n<a-collapse activeKey=\"0\" v-for=\"(client, index) in inbound.settings.trojans.slice(0,1)\" v-if=\""
},
{
"path": "web/html/xui/form/protocol/vless.html",
"chars": 2386,
"preview": "{{define \"form/vless\"}}\n<a-collapse activeKey=\"0\" v-for=\"(client, index) in inbound.settings.vlesses.slice(0,1)\" v-if=\"!"
},
{
"path": "web/html/xui/form/protocol/vmess.html",
"chars": 870,
"preview": "{{define \"form/vmess\"}}\n<a-collapse activeKey=\"0\" v-for=\"(client, index) in inbound.settings.vmesses.slice(0,1)\" v-if=\"!"
},
{
"path": "web/html/xui/form/protocol/wireguard.html",
"chars": 3781,
"preview": "{{define \"form/wireguard\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <"
},
{
"path": "web/html/xui/form/sniffing.html",
"chars": 1116,
"preview": "{{define \"form/sniffing\"}}\n<a-divider style=\"margin:5px 0 0;\"></a-divider>\n<a-form :colon=\"false\" :label-col=\"{ md: {spa"
},
{
"path": "web/html/xui/form/stream/external_proxy.html",
"chars": 1706,
"preview": "{{define \"form/externalProxy\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n "
},
{
"path": "web/html/xui/form/stream/stream_grpc.html",
"chars": 521,
"preview": "{{define \"form/streamGRPC\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n "
},
{
"path": "web/html/xui/form/stream/stream_http.html",
"chars": 828,
"preview": "{{define \"form/streamHTTP\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n "
},
{
"path": "web/html/xui/form/stream/stream_httpupgrade.html",
"chars": 1406,
"preview": "{{define \"form/streamHTTPUpgrade\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }"
},
{
"path": "web/html/xui/form/stream/stream_kcp.html",
"chars": 2293,
"preview": "{{define \"form/streamKCP\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <"
},
{
"path": "web/html/xui/form/stream/stream_quic.html",
"chars": 1686,
"preview": "{{define \"form/streamQUIC\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n "
},
{
"path": "web/html/xui/form/stream/stream_settings.html",
"chars": 1980,
"preview": "{{define \"form/streamSettings\"}}\n<!-- select stream network -->\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wr"
},
{
"path": "web/html/xui/form/stream/stream_sockopt.html",
"chars": 3553,
"preview": "{{define \"form/streamSockopt\"}}\n<a-divider style=\"margin:5px 0 0;\"></a-divider>\n<a-form :colon=\"false\" :label-col=\"{ md:"
},
{
"path": "web/html/xui/form/stream/stream_splithttp.html",
"chars": 1655,
"preview": "{{define \"form/streamSplitHTTP\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">"
},
{
"path": "web/html/xui/form/stream/stream_tcp.html",
"chars": 4106,
"preview": "{{define \"form/streamTCP\"}}\n<!-- tcp type -->\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {"
},
{
"path": "web/html/xui/form/stream/stream_ws.html",
"chars": 1343,
"preview": "{{define \"form/streamWS\"}}\n<a-form :colon=\"false\" :label-col=\"{ md: {span:8} }\" :wrapper-col=\"{ md: {span:14} }\">\n <a-f"
},
{
"path": "web/html/xui/form/tls_settings.html",
"chars": 10542,
"preview": "{{define \"form/tlsSettings\"}}\n<!-- tls enable -->\n<a-form v-if=\"inbound.canEnableTls()\" :colon=\"false\" :label-col=\"{ md:"
},
{
"path": "web/html/xui/inbound_client_table.html",
"chars": 14973,
"preview": "{{define \"client_table\"}}\n<template slot=\"actions\" slot-scope=\"text, client, index\">\n <a-tooltip>\n <template s"
},
{
"path": "web/html/xui/inbound_info_modal.html",
"chars": 20651,
"preview": "{{define \"inboundInfoModal\"}}\n<a-modal id=\"inbound-info-modal\" v-model=\"infoModal.visible\" title='{{ i18n \"pages.inbound"
},
{
"path": "web/html/xui/inbound_modal.html",
"chars": 5986,
"preview": "{{define \"inboundModal\"}}\n<a-modal id=\"inbound-modal\" v-model=\"inModal.visible\" :title=\"inModal.title\"\n :dialog-s"
},
{
"path": "web/html/xui/inbounds.html",
"chars": 67772,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n{{template \"head\" .}}\n<style>\n @media (min-width: 769px) {\n .ant-layout-content {\n "
},
{
"path": "web/html/xui/index.html",
"chars": 27623,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n{{template \"head\" .}}\n<style>\n @media (min-width: 769px) {\n .ant-layout-conte"
},
{
"path": "web/html/xui/navigation.html",
"chars": 7722,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width"
},
{
"path": "web/html/xui/settings.html",
"chars": 35671,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n{{template \"head\" .}}\n<style>\n @media (min-width: 769px) {\n .ant-layout-content {\n "
},
{
"path": "web/html/xui/warp_modal.html",
"chars": 8708,
"preview": "{{define \"warpModal\"}}\n<a-modal id=\"warp-modal\" v-model=\"warpModal.visible\" title=\"Cloudflare WARP\"\n :confirm-lo"
},
{
"path": "web/html/xui/xray.html",
"chars": 118870,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n{{template \"head\" .}}\n<link rel=\"stylesheet\" href=\"{{ .base_path }}assets/codemirror/co"
},
{
"path": "web/html/xui/xray_balancer_modal.html",
"chars": 4405,
"preview": "{{define \"balancerModal\"}}\n<a-modal \n id=\"balancer-modal\"\n v-model=\"balancerModal.visible\"\n :title=\"balancerMod"
},
{
"path": "web/html/xui/xray_outbound_modal.html",
"chars": 4351,
"preview": "{{define \"outModal\"}}\n<a-modal id=\"out-modal\" v-model=\"outModal.visible\" :title=\"outModal.title\" @ok=\"outModal.ok\"\n "
},
{
"path": "web/html/xui/xray_reverse_modal.html",
"chars": 6253,
"preview": "{{define \"reverseModal\"}}\n<a-modal id=\"reverse-modal\" v-model=\"reverseModal.visible\" :title=\"reverseModal.title\" @ok=\"re"
},
{
"path": "web/html/xui/xray_rule_modal.html",
"chars": 11902,
"preview": "{{define \"ruleModal\"}}\n<a-modal id=\"rule-modal\" v-model=\"ruleModal.visible\" :title=\"ruleModal.title\" @ok=\"ruleModal.ok\"\n"
},
{
"path": "web/job/check_client_ip_job.go",
"chars": 7713,
"preview": "package job\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-"
},
{
"path": "web/job/check_cpu_usage.go",
"chars": 742,
"preview": "package job\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"x-ui/web/service\"\n\n\t\"github.com/shirou/gopsutil/v4/cpu\"\n)\n\ntype CheckCpuJob "
},
{
"path": "web/job/check_hash_storage.go",
"chars": 389,
"preview": "package job\n\nimport (\n\t\"x-ui/web/service\"\n)\n\ntype CheckHashStorageJob struct {\n\ttgbotService service.Tgbot\n}\n\nfunc NewCh"
},
{
"path": "web/job/check_xray_running_job.go",
"chars": 565,
"preview": "package job\n\nimport (\n\t\"x-ui/logger\"\n\t\"x-ui/web/service\"\n)\n\ntype CheckXrayRunningJob struct {\n\txrayService service.XrayS"
},
{
"path": "web/job/clear_logs_job.go",
"chars": 1974,
"preview": "package job\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"x-ui/logger\"\n\t\"x-ui/xray\"\n)\n\ntype ClearLogsJob struct{}\n\nfunc NewC"
},
{
"path": "web/job/stats_notify_job.go",
"chars": 471,
"preview": "package job\n\nimport (\n\t\"x-ui/web/service\"\n)\n\ntype LoginStatus byte\n\nconst (\n\tLoginSuccess LoginStatus = 1\n\tLoginFail "
},
{
"path": "web/job/xray_traffic_job.go",
"chars": 835,
"preview": "package job\n\nimport (\n\t\"x-ui/logger\"\n\t\"x-ui/web/service\"\n)\n\ntype XrayTrafficJob struct {\n\txrayService service.XraySe"
},
{
"path": "web/locale/locale.go",
"chars": 2791,
"preview": "package locale\n\nimport (\n\t\"embed\"\n\t\"io/fs\"\n\t\"strings\"\n\n\t\"x-ui/logger\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/nicksnyd"
},
{
"path": "web/middleware/domainValidator.go",
"chars": 446,
"preview": "package middleware\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc DomainValidatorMiddleware(domain st"
},
{
"path": "web/middleware/redirect.go",
"chars": 630,
"preview": "package middleware\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc RedirectMiddleware(basePath str"
},
{
"path": "web/network/auto_https_conn.go",
"chars": 1189,
"preview": "package network\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n)\n\ntype AutoHttpsConn struct {\n\tnet.Conn\n\n"
},
{
"path": "web/network/auto_https_listener.go",
"chars": 367,
"preview": "package network\n\nimport \"net\"\n\ntype AutoHttpsListener struct {\n\tnet.Listener\n}\n\nfunc NewAutoHttpsListener(listener net.L"
},
{
"path": "web/service/config.json",
"chars": 1434,
"preview": "{\n \"log\": {\n \"access\": \"none\",\n \"dnsLog\": false,\n \"error\": \"./error.log\",\n \"loglevel\": \"warning\"\n },\n \"ap"
},
{
"path": "web/service/inbound.go",
"chars": 51658,
"preview": "package service\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-ui/database\"\n\t\"x-ui/database/model\""
},
{
"path": "web/service/outbound.go",
"chars": 1925,
"preview": "package service\n\nimport (\n\t\"x-ui/database\"\n\t\"x-ui/database/model\"\n\t\"x-ui/logger\"\n\t\"x-ui/xray\"\n\n\t\"gorm.io/gorm\"\n)\n\ntype O"
},
{
"path": "web/service/panel.go",
"chars": 402,
"preview": "package service\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"x-ui/logger\"\n)\n\ntype PanelService struct{}\n\nfunc (s *PanelService)"
},
{
"path": "web/service/server.go",
"chars": 13445,
"preview": "package service\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t"
},
{
"path": "web/service/setting.go",
"chars": 14492,
"preview": "package service\n\nimport (\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-ui/"
},
{
"path": "web/service/tgbot.go",
"chars": 62926,
"preview": "package service\n\nimport (\n\t\"embed\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"x-ui/config\"\n\t\"x-ui/d"
},
{
"path": "web/service/user.go",
"chars": 2505,
"preview": "package service\n\nimport (\n\t\"errors\"\n\n\t\"x-ui/database\"\n\t\"x-ui/database/model\"\n\t\"x-ui/logger\"\n\n\t\"gorm.io/gorm\"\n)\n\ntype Use"
},
{
"path": "web/service/xray.go",
"chars": 5227,
"preview": "package service\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"sync\"\n\n\t\"x-ui/logger\"\n\t\"x-ui/xray\"\n\n\t\"go.uber.org/atomic\"\n)\n\nvar "
},
{
"path": "web/service/xray_setting.go",
"chars": 4290,
"preview": "package service\n\nimport (\n\t\"bytes\"\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"x-ui/util/common\"\n\t\"x"
},
{
"path": "web/session/session.go",
"chars": 1024,
"preview": "package session\n\nimport (\n\t\"encoding/gob\"\n\n\t\"x-ui/database/model\"\n\n\t\"github.com/gin-contrib/sessions\"\n\t\"github.com/gin-g"
},
{
"path": "web/translation/translate.en_US.toml",
"chars": 27178,
"preview": "\"username\" = \"Username\"\n\"password\" = \"Password\"\n\"login\" = \"Log In\"\n\"confirm\" = \"Confirm\"\n\"cancel\" = \"Cancel\"\n\"close\" = \""
},
{
"path": "web/translation/translate.es_ES.toml",
"chars": 32648,
"preview": "\"username\" = \"Nombre de Usuario\"\r\n\"password\" = \"Contraseña\"\r\n\"login\" = \"Acceder\"\r\n\"confirm\" = \"Confirmar\"\r\n\"cancel\" = \"C"
},
{
"path": "web/translation/translate.fa_IR.toml",
"chars": 26617,
"preview": "\"username\" = \"نامکاربری\"\n\"password\" = \"رمزعبور\"\n\"login\" = \"ورود\"\n\"confirm\" = \"تایید\"\n\"cancel\" = \"انصراف\"\n\"close\" = \"بست"
},
{
"path": "web/translation/translate.id_ID.toml",
"chars": 27856,
"preview": "\"username\" = \"Nama Pengguna\"\n\"password\" = \"Kata Sandi\"\n\"login\" = \"Masuk\"\n\"confirm\" = \"Konfirmasi\"\n\"cancel\" = \"Batal\"\n\"cl"
},
{
"path": "web/translation/translate.ru_RU.toml",
"chars": 30607,
"preview": "\"username\" = \"Имя пользователя\"\n\"password\" = \"Пароль\"\n\"login\" = \"Логин\"\n\"confirm\" = \"Подтвердить\"\n\"cancel\" = \"Отмена\"\n\"c"
},
{
"path": "web/translation/translate.uk_UA.toml",
"chars": 29237,
"preview": "\"username\" = \"Ім'я користувача\"\n\"password\" = \"Пароль\"\n\"login\" = \"Увійти\"\n\"confirm\" = \"Підтвердити\"\n\"cancel\" = \"Скасувати"
},
{
"path": "web/translation/translate.vi_VN.toml",
"chars": 30537,
"preview": "\"username\" = \"Tên người dùng\"\r\n\"password\" = \"Mật khẩu\"\r\n\"login\" = \"Đăng nhập\"\r\n\"confirm\" = \"Xác nhận\"\r\n\"cancel\" = \"Hủy b"
},
{
"path": "web/translation/translate.zh_Hans.toml",
"chars": 18540,
"preview": "\"username\" = \"用户名\"\n\"password\" = \"密码\"\n\"login\" = \"登录\"\n\"confirm\" = \"确定\"\n\"cancel\" = \"取消\"\n\"close\" = \"关闭\"\n\"copy\" = \"复制\"\n\"copie"
},
{
"path": "web/web.go",
"chars": 8873,
"preview": "package web\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"embed\"\n\t\"html/template\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"strco"
},
{
"path": "x-ui.service",
"chars": 275,
"preview": "[Unit]\nDescription=x-ui Service\nAfter=network.target\nWants=network.target\n\n[Service]\nEnvironment=\"XRAY_VMESS_AEAD_FORCED"
},
{
"path": "x-ui.sh",
"chars": 40579,
"preview": "#!/bin/bash\n\nred='\\033[0;31m'\ngreen='\\033[0;32m'\nyellow='\\033[0;33m'\nplain='\\033[0m'\n\n#Add some basic function here\nfunc"
},
{
"path": "xray/api.go",
"chars": 6612,
"preview": "package xray\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"time\"\n\n\t\"x-ui/logger\"\n\t\"x-ui/util/common\"\n\n\t\"githu"
},
{
"path": "xray/client_traffic.go",
"chars": 536,
"preview": "package xray\n\ntype ClientTraffic struct {\n\tId int `json:\"id\" form:\"id\" gorm:\"primaryKey;autoIncrement\"`\n\tInbo"
},
{
"path": "xray/config.go",
"chars": 1720,
"preview": "package xray\n\nimport (\n\t\"bytes\"\n\n\t\"x-ui/util/json_util\"\n)\n\ntype Config struct {\n\tLogConfig json_util.RawMessage `"
},
{
"path": "xray/inbound.go",
"chars": 990,
"preview": "package xray\n\nimport (\n\t\"bytes\"\n\n\t\"x-ui/util/json_util\"\n)\n\ntype InboundConfig struct {\n\tListen json_util.RawMess"
},
{
"path": "xray/log_writer.go",
"chars": 1068,
"preview": "package xray\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\n\t\"x-ui/logger\"\n)\n\nfunc NewLogWriter() *LogWriter {\n\treturn &LogWriter{}\n}\n\n"
},
{
"path": "xray/process.go",
"chars": 4686,
"preview": "package xray\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"syscall\"\n\t\"time"
},
{
"path": "xray/traffic.go",
"chars": 127,
"preview": "package xray\n\ntype Traffic struct {\n\tIsInbound bool\n\tIsOutbound bool\n\tTag string\n\tUp int64\n\tDown i"
}
]
About this extraction
This page contains the full source code of the gm-cx/3x-ui-cn GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 184 files (5.6 MB), approximately 1.5M tokens, and a symbol index with 5835 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.