Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHo3ein <ho3ein.sanaei@gmail.com>2023-12-10 17:42:52 +0300
committerGitHub <noreply@github.com>2023-12-10 17:42:52 +0300
commite3f1d3c892a1af48f27fdc36f273a55f38d13b40 (patch)
treeb11d0c1ed3c15c8f6f891a5e6df8e021d5db8ab6 /web/html/xui/xray.html
parent36cf7c0a8fda915b51e75958ce729fd9a61a5c90 (diff)
parent9fbe80f87f950673058f0001b3704251fa8b9243 (diff)
huge changes
Diffstat (limited to 'web/html/xui/xray.html')
-rw-r--r--web/html/xui/xray.html1401
1 files changed, 1401 insertions, 0 deletions
diff --git a/web/html/xui/xray.html b/web/html/xui/xray.html
new file mode 100644
index 00000000..99b1878d
--- /dev/null
+++ b/web/html/xui/xray.html
@@ -0,0 +1,1401 @@
+<!DOCTYPE html>
+<html lang="en">
+{{template "head" .}}
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/codemirror.css">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/fold/foldgutter.css">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/xq.css">
+<link rel="stylesheet" href="{{ .base_path }}assets/codemirror/lint/lint.css">
+
+<script src="{{ .base_path }}assets/js/model/outbound.js"></script>
+<script src="{{ .base_path }}assets/codemirror/codemirror.js"></script>
+<script src="{{ .base_path }}assets/codemirror/javascript.js"></script>
+<script src="{{ .base_path }}assets/codemirror/jshint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/jsonlint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/lint/lint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/lint/javascript-lint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/hint/javascript-hint.js"></script>
+<script src="{{ .base_path }}assets/codemirror/fold/foldcode.js"></script>
+<script src="{{ .base_path }}assets/codemirror/fold/foldgutter.js"></script>
+<script src="{{ .base_path }}assets/codemirror/fold/brace-fold.js"></script>
+<style>
+ @media (min-width: 769px) {
+ .ant-layout-content {
+ margin: 24px 16px;
+ }
+ }
+
+ @media (max-width: 768px) {
+ .ant-tabs-nav .ant-tabs-tab {
+ margin: 0;
+ padding: 12px .5rem;
+ }
+ }
+
+ .ant-tabs-bar {
+ margin: 0;
+ }
+
+ .ant-list-item {
+ display: block;
+ }
+
+ .collapse-title {
+ color: inherit;
+ font-weight: bold;
+ font-size: 18px;
+ padding: 10px 20px;
+ border-bottom: 2px solid;
+ }
+
+ .collapse-title > i {
+ color: inherit;
+ font-size: 24px;
+ }
+</style>
+<body>
+<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
+ {{ template "commonSider" . }}
+ <a-layout id="content-layout">
+ <a-layout-content>
+ <a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
+ <a-space direction="vertical">
+ <a-card hoverable style="margin-bottom: .5rem;">
+ <a-row>
+ <a-col :xs="24" :sm="8" style="padding: 4px;">
+ <a-space direction="horizontal">
+ <a-button type="primary" :disabled="saveBtnDisable" @click="updateXraySetting">{{ i18n "pages.xray.save" }}</a-button>
+ <a-button type="danger" :disabled="!saveBtnDisable" @click="restartXray">{{ i18n "pages.xray.restart" }}</a-button>
+ <a-popover v-if="restartResult"
+ :overlay-class-name="themeSwitcher.currentTheme">
+ <span slot="title" style="font-size: 12pt">Error in running xray-core</span>
+ <template slot="content">
+ <p style="max-width: 400px" v-for="line in restartResult.split('\n')">[[ line ]]</p>
+ </template>
+ <a-icon type="question-circle" theme="filled"></a-icon>
+ </a-popover>
+ </a-space>
+ </a-col>
+ <a-col :xs="24" :sm="16">
+ <a-back-top :target="() => document.getElementById('content-layout')" visibility-height="200">
+ </a-back-top>
+ <a-alert type="warning" style="float: right; width: fit-content"
+ message='{{ i18n "pages.settings.infoDesc" }}'
+ show-icon
+ >
+ </a-col>
+ </a-row>
+ </a-card>
+ <a-tabs class="ant-card-dark-box-nohover" default-active-key="tpl-1"
+ @change="(activeKey) => { if(activeKey == 'tpl-4') this.changeCode(); }"
+ :class="themeSwitcher.currentTheme">
+ <a-tab-pane key="tpl-1" tab='{{ i18n "pages.xray.basicTemplate"}}'>
+ <a-space direction="horizontal" style="padding: 20px 20px">
+ <a-button type="primary" @click="resetXrayConfigToDefault">{{ i18n "pages.settings.resetDefaultConfig" }}</a-button>
+ </a-space>
+ <a-collapse>
+ <a-collapse-panel header='{{ i18n "pages.xray.generalConfigs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.generalConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <a-list-item>
+ <a-row style="padding: 20px">
+ <a-col :lg="24" :xl="12">
+ <a-list-item-meta
+ title='{{ i18n "pages.xray.xrayConfigFreedomStrategy" }}'
+ description='{{ i18n "pages.xray.xrayConfigFreedomStrategyDesc" }}'/>
+ </a-col>
+ <a-col :lg="24" :xl="12">
+ <template>
+ <a-select
+ v-model="freedomStrategy"
+ :dropdown-class-name="themeSwitcher.currentTheme"
+ style="width: 100%">
+ <a-select-option v-for="s in outboundDomainStrategies" :value="s">[[ s ]]</a-select-option>
+ </a-select>
+ </template>
+ </a-col>
+ </a-row>
+ </a-list-item>
+ <a-row style="padding: 20px">
+ <a-col :lg="24" :xl="12">
+ <a-list-item-meta
+ title='{{ i18n "pages.xray.xrayConfigRoutingStrategy" }}'
+ description='{{ i18n "pages.xray.xrayConfigRoutingStrategyDesc" }}'/>
+ </a-col>
+ <a-col :lg="24" :xl="12">
+ <template>
+ <a-select
+ v-model="routingStrategy"
+ :dropdown-class-name="themeSwitcher.currentTheme"
+ style="width: 100%">
+ <a-select-option v-for="s in routingDomainStrategies" :value="s">[[ s ]]</a-select-option>
+ </a-select>
+ </template>
+ </a-col>
+ </a-row>
+ </a-list-item>
+ </a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.xray.blockConfigs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.blockConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigTorrent"}}' desc='{{ i18n "pages.xray.xrayConfigTorrentDesc"}}' v-model="torrentSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigPrivateIp"}}' desc='{{ i18n "pages.xray.xrayConfigPrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigAds"}}' desc='{{ i18n "pages.xray.xrayConfigAdsDesc"}}' v-model="AdsSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigFamily"}}' desc='{{ i18n "pages.xray.xrayConfigFamilyDesc"}}' v-model="familyProtectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigSpeedtest"}}' desc='{{ i18n "pages.xray.xrayConfigSpeedtestDesc"}}' v-model="SpeedTestSettings"></setting-list-item>
+ </a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.xray.blockCountryConfigs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.blockCountryConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigIRIp"}}' desc='{{ i18n "pages.xray.xrayConfigIRIpDesc"}}' v-model="IRIpSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigIRDomain"}}' desc='{{ i18n "pages.xray.xrayConfigIRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigChinaIp"}}' desc='{{ i18n "pages.xray.xrayConfigChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigChinaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigRussiaIp"}}' desc='{{ i18n "pages.xray.xrayConfigRussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigRussiaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigRussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item>
+ </a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.xray.directCountryConfigs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.directCountryConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectIRIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectIRIpDesc"}}' v-model="IRIpDirectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectIRDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectIRDomainDesc"}}' v-model="IRDomainDirectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectChinaIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectChinaIpDesc"}}' v-model="ChinaIpDirectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectChinaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectChinaDomainDesc"}}' v-model="ChinaDomainDirectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectRussiaIp"}}' desc='{{ i18n "pages.xray.xrayConfigDirectRussiaIpDesc"}}' v-model="RussiaIpDirectSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigDirectRussiaDomain"}}' desc='{{ i18n "pages.xray.xrayConfigDirectRussiaDomainDesc"}}' v-model="RussiaDomainDirectSettings"></setting-list-item>
+ </a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.xray.ipv4Configs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.ipv4ConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigGoogleIPv4"}}' desc='{{ i18n "pages.xray.xrayConfigGoogleIPv4Desc"}}' v-model="GoogleIPv4Settings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigNetflixIPv4"}}' desc='{{ i18n "pages.xray.xrayConfigNetflixIPv4Desc"}}' v-model="NetflixIPv4Settings"></setting-list-item>
+ </a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.xray.warpConfigs"}}'>
+ <a-row :xs="24" :sm="24" :lg="12">
+ <a-alert type="warning" style="text-align: center;">
+ <template slot="message">
+ <a-icon type="exclamation-circle" theme="filled" style="color: #FFA031"></a-icon>
+ {{ i18n "pages.xray.warpConfigsDesc" }}
+ </template>
+ </a-alert>
+ </a-row>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigGoogleWARP"}}' desc='{{ i18n "pages.xray.xrayConfigGoogleWARPDesc"}}' v-model="GoogleWARPSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigOpenAIWARP"}}' desc='{{ i18n "pages.xray.xrayConfigOpenAIWARPDesc"}}' v-model="OpenAIWARPSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigNetflixWARP"}}' desc='{{ i18n "pages.xray.xrayConfigNetflixWARPDesc"}}' v-model="NetflixWARPSettings"></setting-list-item>
+ <setting-list-item type="switch" title='{{ i18n "pages.xray.xrayConfigSpotifyWARP"}}' desc='{{ i18n "pages.xray.xrayConfigSpotifyWARPDesc"}}' v-model="SpotifyWARPSettings"></setting-list-item>
+ </a-collapse-panel>
+ </a-collapse>
+ </a-tab-pane>
+ <a-tab-pane key="tpl-2" tab='{{ i18n "pages.xray.Routings"}}' style="padding-top: 20px;">
+ <a-alert type="warning" style="margin-bottom: 10px; width: fit-content"
+ message='{{ i18n "pages.xray.RoutingsDesc"}}' show-icon></a-alert>
+ <a-button type="primary" icon="plus" @click="addRule">{{ i18n "pages.xray.rules.add" }}</a-button>
+ <a-table :columns="isMobile ? rulesMobileColumns : rulesColumns" bordered
+ :row-key="r => r.key"
+ :data-source="routingRuleData"
+ :scroll="isMobile ? {} : { x: 1000 }"
+ :pagination="false"
+ :indent-size="0"
+ :style="isMobile ? 'padding: 5px 0' : 'margin-top: 10px;'">
+ <template slot="action" slot-scope="text, rule, index">
+ [[ index+1 ]]
+ <a-dropdown :trigger="['click']">
+ <a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon>
+ <a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
+ <a-menu-item v-if="index>0" @click="replaceRule(index,0)">
+ <a-icon type="vertical-align-top"></a-icon>
+ {{ i18n "pages.xray.rules.first"}}
+ </a-menu-item>
+ <a-menu-item v-if="index>0" @click="replaceRule(index,index-1)">
+ <a-icon type="arrow-up"></a-icon>
+ {{ i18n "pages.xray.rules.up"}}
+ </a-menu-item>
+ <a-menu-item v-if="index<routingRuleData.length-1" @click="replaceRule(index,index+1)">
+ <a-icon type="arrow-down"></a-icon>
+ {{ i18n "pages.xray.rules.down"}}
+ </a-menu-item>
+ <a-menu-item v-if="index<routingRuleData.length-1" @click="replaceRule(index,routingRuleData.length-1)">
+ <a-icon type="vertical-align-bottom"></a-icon>
+ {{ i18n "pages.xray.rules.last"}}
+ </a-menu-item>
+ <a-menu-item @click="editRule(index)">
+ <a-icon type="edit"></a-icon>
+ {{ i18n "edit" }}
+ </a-menu-item>
+ <a-menu-item @click="deleteRule(index)">
+ <span style="color: #FF4D4F">
+ <a-icon type="delete"></a-icon> {{ i18n "delete"}}
+ </span>
+ </a-menu-item>
+ </a-menu>
+ </a-dropdown>
+ </template>
+ <template slot="inbound" slot-scope="text, rule, index">
+ <a-popover :overlay-class-name="themeSwitcher.currentTheme">
+ <template slot="content">
+ <p v-if="rule.inboundTag">Inbound Tag: [[ rule.inboundTag ]]</p>
+ <p v-if="rule.user">User email: [[ rule.user ]]</p>
+ </template>
+ [[ [rule.inboundTag,rule.user].join('\n') ]]
+ </a-popover>
+ </template>
+ <template slot="outbound" slot-scope="text, rule, index">
+ <a-popover :overlay-class-name="themeSwitcher.currentTheme">
+ <template slot="content">
+ <p v-if="rule.outboundTag">Outbound Tag: [[ rule.outboundTag ]]</p>
+ </template>
+ [[ rule.outboundTag ]]
+ </a-popover>
+ </template>
+ <template slot="info" slot-scope="text, rule, index">
+ <a-popover placement="bottomRight"
+ v-if="(rule.source+rule.sourcePort+rule.network+rule.protocol+rule.attrs+rule.ip+rule.domain+rule.port).length>0"
+ :overlay-class-name="themeSwitcher.currentTheme" trigger="click">
+ <template slot="content">
+ <table cellpadding="2" style="max-width: 300px;">
+ <tr v-if="rule.source">
+ <td>Source</td>
+ <td><a-tag color="blue" v-for="r in rule.source.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.sourcePort">
+ <td>Source Port</td>
+ <td><a-tag color="green" v-for="r in rule.sourcePort.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.network">
+ <td>Network</td>
+ <td><a-tag color="blue" v-for="r in rule.network.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.protocol">
+ <td>Protocol</td>
+ <td><a-tag color="green" v-for="r in rule.protocol.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.attrs">
+ <td>Attrs</td>
+ <td><a-tag color="blue" v-for="r in rule.attrs.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.ip">
+ <td>IP</td>
+ <td><a-tag color="green" v-for="r in rule.ip.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.domain">
+ <td>Domain</td>
+ <td><a-tag color="blue" v-for="r in rule.domain.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ <tr v-if="rule.port">
+ <td>Port</td>
+ <td><a-tag color="green" v-for="r in rule.port.split(',')">[[ r ]]</a-tag></td>
+ </tr>
+ </table>
+ </template>
+ <a-button shape="round" size="small" style="font-size: 14px; padding: 0 10px;">
+ <a-icon type="info"></a-icon>
+ </a-button>
+ </a-popover>
+ </template>
+ </a-table>
+ </a-tab-pane>
+ <a-tab-pane key="tpl-3" tab='{{ i18n "pages.xray.Outbounds"}}' style="padding-top: 20px;" force-render="true">
+ <a-button type="primary" icon="plus" @click="addOutbound()">{{ i18n "pages.xray.outbound.addOutbound" }}</a-button>
+ <a-button type="primary" icon="plus" @click="addReverse()">{{ i18n "pages.xray.outbound.addReverse" }}</a-button>
+ <a-row>
+ <a-col :sm="24" :md="12">
+ <p style="margin: 10px;">{{ i18n "pages.xray.Outbounds"}}</p>
+ <a-table :columns="outboundColumns" bordered
+ :row-key="r => r.key"
+ :data-source="outboundData"
+ :scroll="isMobile ? {} : { x: 200 }"
+ :pagination="false"
+ :indent-size="0"
+ :style="isMobile ? 'padding: 5px 5px' : 'margin-right: 1px;'">
+ <template slot="action" slot-scope="text, outbound, index">
+ [[ index+1 ]]
+ <a-dropdown :trigger="['click']">
+ <a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon>
+ <a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
+ <a-menu-item @click="editOutbound(index)">
+ <a-icon type="edit"></a-icon>
+ {{ i18n "edit" }}
+ </a-menu-item>
+ <a-menu-item @click="deleteOutbound(index)">
+ <span style="color: #FF4D4F">
+ <a-icon type="delete"></a-icon> {{ i18n "delete"}}
+ </span>
+ </a-menu-item>
+ </a-menu>
+ </a-dropdown>
+ </template>
+ <template slot="address" slot-scope="text, outbound, index">
+ <p style="margin: 0 5px;" v-for="addr in findOutboundAddress(outbound)">[[ addr ]]</p>
+ </template>
+ <template slot="protocol" slot-scope="text, outbound, index">
+ <a-tag style="margin:0;" color="purple">[[ outbound.protocol ]]</a-tag>
+ <template v-if="[Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(outbound.protocol)">
+ <a-tag style="margin:0;" color="blue">[[ outbound.streamSettings.network ]]</a-tag>
+ <a-tag style="margin:0;" v-if="outbound.streamSettings.security=='tls'" color="green">tls</a-tag>
+ <a-tag style="margin:0;" v-if="outbound.streamSettings.security=='reality'" color="green">reality</a-tag>
+ </template>
+ </template>
+ </a-table>
+ </a-col>
+ <a-col :sm="24" :md="12" v-if="reverseData.length>0">
+ <p style="margin: 10px;">{{ i18n "pages.xray.outbound.reverse"}}</p>
+ <a-table :columns="reverseColumns" bordered
+ :row-key="r => r.key"
+ :data-source="reverseData"
+ :scroll="isMobile ? {} : { x: 200 }"
+ :pagination="false"
+ :indent-size="0"
+ :style="isMobile ? 'padding: 5px 0' : 'margin-left: 1px;'">
+ <template slot="action" slot-scope="text, reverse, index">
+ [[ index+1 ]]
+ <a-dropdown :trigger="['click']">
+ <a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon>
+ <a-menu slot="overlay" :theme="themeSwitcher.currentTheme">
+ <a-menu-item @click="editReverse(index)">
+ <a-icon type="edit"></a-icon>
+ {{ i18n "edit" }}
+ </a-menu-item>
+ <a-menu-item @click="deleteReverse(index)">
+ <span style="color: #FF4D4F">
+ <a-icon type="delete"></a-icon> {{ i18n "delete"}}
+ </span>
+ </a-menu-item>
+ </a-menu>
+ </a-dropdown>
+ </template>
+ </a-table>
+ </a-col>
+ </a-row>
+ </a-tab-pane>
+ <a-tab-pane key="tpl-4" tab='{{ i18n "pages.xray.advancedTemplate"}}' style="padding-top: 20px;" force-render="true">
+ <a-list-item-meta title='{{ i18n "pages.xray.Template"}}' description='{{ i18n "pages.xray.TemplateDesc"}}'></a-list-item-meta>
+ <a-radio-group v-model="advSettings" @change="changeCode" button-style="solid" style="margin: 10px 0;" :size="isMobile ? 'small' : ''">
+ <a-radio-button value="xraySetting">{{ i18n "pages.xray.completeTemplate"}}</a-radio-button>
+ <a-radio-button value="inboundSettings">{{ i18n "pages.xray.Inbounds" }}</a-radio-button>
+ <a-radio-button value="outboundSettings">{{ i18n "pages.xray.Outbounds" }}</a-radio-button>
+ <a-radio-button value="routingRuleSettings">{{ i18n "pages.xray.Routings" }}</a-radio-button>
+ </a-radio-group>
+ <textarea style="position:absolute; left: -800px;" id="xraySetting"></textarea>
+ </a-tab-pane>
+ </a-tabs>
+ </a-space>
+ </a-spin>
+ </a-layout-content>
+ </a-layout>
+</a-layout>
+{{template "js" .}}
+{{template "component/themeSwitcher" .}}
+{{template "component/setting"}}
+{{template "ruleModal"}}
+{{template "outModal"}}
+{{template "reverseModal"}}
+<script>
+ const rulesColumns = [
+ { title: "#", align: 'center', width: 15, scopedSlots: { customRender: 'action' } },
+ { title: '{{ i18n "pages.xray.rules.source"}}', children: [
+ { title: 'IP', dataIndex: "source", align: 'center', width: 20, ellipsis: true },
+ { title: 'port', dataIndex: 'sourcePort', align: 'center', width: 10, ellipsis: true } ]},
+ { title: '{{ i18n "pages.inbounds.network"}}', children: [
+ { title: 'L4', dataIndex: 'network', align: 'center', width: 10 },
+ { title: 'Protocol', dataIndex: 'protocol', align: 'center', width: 10, ellipsis: true },
+ { title: 'Attrs', dataIndex: 'attrs', align: 'center', width: 20, ellipsis: true } ]},
+ { title: '{{ i18n "pages.xray.rules.dest"}}', children: [
+ { title: 'IP', dataIndex: 'ip', align: 'center', width: 20, ellipsis: true },
+ { title: 'Domain', dataIndex: 'domain', align: 'center', width: 20, ellipsis: true },
+ { title: 'Port', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]},
+ { title: '{{ i18n "pages.xray.rules.inbound"}}', children: [
+ { title: 'Inbound Tag', dataIndex: 'inboundTag', align: 'center', width: 20, ellipsis: true },
+ { title: 'User email', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]},
+ { title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 20 },
+ ];
+
+ const rulesMobileColumns = [
+ { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
+ { title: '{{ i18n "pages.xray.rules.inbound"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'inbound' } },
+ { title: '{{ i18n "pages.xray.rules.outbound"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'outbound' } },
+ { title: '{{ i18n "pages.xray.rules.info"}}', align: 'center', width: 50, ellipsis: true, scopedSlots: { customRender: 'info' } },
+ ];
+
+ const outboundColumns = [
+ { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
+ { title: '{{ i18n "pages.xray.outbound.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
+ { title: '{{ i18n "protocol"}}', align: 'center', width: 50, scopedSlots: { customRender: 'protocol' } },
+ { title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } },
+ ];
+
+ const reverseColumns = [
+ { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
+ { title: '{{ i18n "pages.xray.outbound.type"}}', dataIndex: 'type', align: 'center', width: 50 },
+ { title: '{{ i18n "pages.xray.outbound.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
+ { title: '{{ i18n "pages.xray.outbound.domain"}}', dataIndex: 'domain', align: 'center', width: 50 },
+ ];
+ const app = new Vue({
+ delimiters: ['[[', ']]'],
+ el: '#app',
+ data: {
+ siderDrawer,
+ themeSwitcher,
+ isDarkTheme: themeSwitcher.isDarkTheme,
+ spinning: false,
+ oldXraySetting: '',
+ xraySetting: '',
+ inboundTags: [],
+ saveBtnDisable: true,
+ restartResult: '',
+ isMobile: window.innerWidth <= 768,
+ advSettings: 'xraySetting',
+ cm: null,
+ cmOptions: {
+ lineNumbers: true,
+ mode: "application/json",
+ lint: true,
+ styleActiveLine: true,
+ matchBrackets: true,
+ theme: "xq",
+ autoCloseTags: true,
+ lineWrapping: true,
+ indentUnit: 2,
+ indentWithTabs: true,
+ smartIndent: true,
+ tabSize: 2,
+ lineWiseCopyCut: false,
+ foldGutter: true,
+ gutters: [
+ "CodeMirror-lint-markers",
+ "CodeMirror-linenumbers",
+ "CodeMirror-foldgutter",
+ ],
+ },
+ ipv4Settings: {
+ tag: "IPv4",
+ protocol: "freedom",
+ settings: {
+ domainStrategy: "UseIPv4"
+ }
+ },
+ warpSettings: {
+ tag: "WARP",
+ protocol: "socks",
+ settings: {
+ servers: [
+ {
+ address: "127.0.0.1",
+ port: 40000
+ }
+ ]
+ }
+ },
+ directSettings: {
+ tag: "direct",
+ protocol: "freedom"
+ },
+ outboundDomainStrategies: ["AsIs", "UseIP", "UseIPv4", "UseIPv6"],
+ routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"],
+ settingsData: {
+ protocols: {
+ bittorrent: ["bittorrent"],
+ },
+ ips: {
+ local: ["geoip:private"],
+ cn: ["geoip:cn"],
+ ir: ["ext:geoip_IR.dat:ir","ext:geoip_IR.dat:arvancloud","ext:geoip_IR.dat:derakcloud","ext:geoip_IR.dat:iranserver"],
+ ru: ["geoip:ru"],
+ },
+ domains: {
+ ads: [
+ "geosite:category-ads-all",
+ "ext:geosite_IR.dat:category-ads-all"
+ ],
+ speedtest: ["geosite:speedtest"],
+ openai: ["geosite:openai"],
+ google: ["geosite:google"],
+ spotify: ["geosite:spotify"],
+ netflix: ["geosite:netflix"],
+ cn: [
+ "geosite:cn",
+ "regexp:.*\\.cn$"
+ ],
+ ru: [
+ "geosite:category-gov-ru",
+ "regexp:.*\\.ru$"
+ ],
+ ir: [
+ "regexp:.*\\.ir$",
+ "regexp:.*\\.xn--mgba3a4f16a$", // .ایران
+ "ext:geosite_IR.dat:ir" // have rules to bypass all .ir domains.
+ ]
+ },
+ familyProtectDNS: {
+ "servers": [
+ "1.1.1.3", // https://developers.cloudflare.com/1.1.1.1/setup/
+ "1.0.0.3",
+ "94.140.14.15", // https://adguard-dns.io/kb/general/dns-providers/
+ "94.140.15.16"
+ ],
+ "queryStrategy": "UseIPv4"
+ },
+ }
+ },
+ methods: {
+ loading(spinning = true) {
+ this.spinning = spinning;
+ },
+ async getXraySetting() {
+ this.loading(true);
+ const msg = await HttpUtil.post("/panel/xray/");
+ this.loading(false);
+ if (msg.success) {
+ result = JSON.parse(msg.obj);
+ xs = JSON.stringify(result.xraySetting, null, 2);
+ this.oldXraySetting = xs;
+ this.xraySetting = xs;
+ this.inboundTags = result.inboundTags;
+ this.saveBtnDisable = true;
+ }
+ },
+ async updateXraySetting() {
+ this.loading(true);