- <%- local count = 0 -%>
-
+ <%- local count=0 -%>
+
+
+
+ <%- local isempty=true for i, k in ipairs(self.serverTable) do section=k isempty=false local
+ fc=(section.name==self.current) and "fast" or "" local flag_icon=(section.flag ~=nil)
+ and "flag-icon-" .. section.flag or "flag-icon-un" local switch_enable=(section.switch_enable=="1" )
+ and "" or "hidden" scope={ valueheader="cbi/cell_valueheader" , valuefooter="cbi/cell_valuefooter" }
+ -%>
- <%- local isempty = true
- for i, k in ipairs(self.serverTable) do
- section = k
- isempty = false
- local fc = (section.name == self.current) and "fast" or ""
- local flag_icon = (section.flag ~= nil) and "flag-icon-" .. section.flag or "flag-icon-un"
- local switch_enable = (section.switch_enable == "1") and "" or "hidden"
- scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
- -%>
-
-
-
-
-
-

-
<%=section.type%>
-
-
<%=section.alias%>
- <%- if self.extedit or self.addremove then -%>
-
+
+ <% if self.error then %>
+
+
+ <% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
+ -
+ <%=pcdata(e):gsub("\n","
")%>
+
+ <%- end end %>
+
-
- <%- end -%>
+ <% end %>
- <%- if isempty then -%>
-
-
<%:This section contains no values yet%>
-
- <%- end -%>
-
-
- <% if self.error then %>
-
-
<% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
- - <%=pcdata(e):gsub("\n","
")%>
- <%- end end %>
-
- <% end %>
-
- <%- if self.addremove then -%>
- <% if self.template_addremove then include(self.template_addremove) else -%>
-
- <%- end %>
- <%- end -%>
+ <%- if self.addremove then -%>
+ <% if self.template_addremove then include(self.template_addremove) else -%>
+
+ <%- end %>
+ <%- end -%>
@@ -120,15 +146,15 @@
$html += '
';
$html += '
';
$html += '
';
- if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "tw") {
+ //if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "tw") {
$html += '
';
- }
+ //}
$html += '
';
$html += '
';
$html += '
';
- if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "hk") {
+ //if ($('#cbi-' + CONFIG + '-' + node).attr("data-flag") == "hk") {
$html += '
';
- }
+ //}
$html += '
';
$html += '
';
Swal.fire({
@@ -165,9 +191,9 @@
}
})
}
-
+
//删除节点
- function delete_node(node){
+ function delete_node(node) {
XHR.halt();
$.each(ajaxArray, function (n, value) { value.abort(); }) //中断所有的ajax请求
$.get(DELETE_NODE_URL, { node: node },
@@ -223,10 +249,7 @@
function (data, status) {
currentCheckCount++
var host_con = $(target).find(".host_con");
- host_con.removeClass("fast");
- host_con.removeClass("middle");
- host_con.removeClass("slow");
- host_con.removeClass("nopass");
+ host_con.removeClass("fast middle slow nopass");
if (data.ret == 1) {
if (data.used == "") {
host_con.addClass("nopass");
diff --git a/package/ctcgfw/luci-app-vssr/luasrc/view/vssr/update_subscribe.htm b/package/ctcgfw/luci-app-vssr/luasrc/view/vssr/update_subscribe.htm
index 412d6916b2..ae787ab59f 100644
--- a/package/ctcgfw/luci-app-vssr/luasrc/view/vssr/update_subscribe.htm
+++ b/package/ctcgfw/luci-app-vssr/luasrc/view/vssr/update_subscribe.htm
@@ -1,5 +1,6 @@
<%+cbi/valueheader%>
+
<%+cbi/valuefooter%>
diff --git a/package/ctcgfw/luci-app-vssr/po/zh-cn/vssr.po b/package/ctcgfw/luci-app-vssr/po/zh-cn/vssr.po
index d39453b898..bfebab30af 100644
--- a/package/ctcgfw/luci-app-vssr/po/zh-cn/vssr.po
+++ b/package/ctcgfw/luci-app-vssr/po/zh-cn/vssr.po
@@ -128,13 +128,13 @@ msgid "SSR Server"
msgstr "服务端"
msgid "vssr Server"
-msgstr "vssr 服务端"
+msgstr "Hello World 服务端"
msgid "vssr Server is running"
-msgstr "vssr 服务端运行中"
+msgstr "Hello World 服务端运行中"
msgid "vssr Server is not running"
-msgstr "vssr 服务端未运行"
+msgstr "Hello World 服务端未运行"
msgid "Enable Server"
msgstr "启动服务端"
@@ -710,3 +710,15 @@ msgstr "TVB 域名"
msgid "Custom Domain"
msgstr "自定义域名"
+
+msgid "Subscribe"
+msgstr "订阅设置"
+
+msgid "Local Proxy"
+msgstr "本地代理"
+
+msgid "↑ Put your IP list here"
+msgstr "↑ 在上面放置你需要分流的IP列表"
+
+msgid "↑ Put your domain list here"
+msgstr "↑ 在上面放置你需要分流的域名列表"
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/init.d/vssr b/package/ctcgfw/luci-app-vssr/root/etc/init.d/vssr
index b8175707e0..dd75665473 100755
--- a/package/ctcgfw/luci-app-vssr/root/etc/init.d/vssr
+++ b/package/ctcgfw/luci-app-vssr/root/etc/init.d/vssr
@@ -609,6 +609,7 @@ EOF
/etc/init.d/dnsmasq restart >/dev/null 2>&1
start_server
start_local
+ scount=$(count_shunt)
if [ $scount != "0" ]; then
start_shunt
fi
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/custom_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/custom_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/disney_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/disney_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/netflix_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/netflix_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/prime_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/prime_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/tvb_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/tvb_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/tw_video_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/tw_video_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/etc/vssr/youtube_ip.list b/package/ctcgfw/luci-app-vssr/root/etc/vssr/youtube_ip.list
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/genconfig_v2ray.lua b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/genconfig_v2ray.lua
index c1c8ccdc1b..53e80ae4b8 100755
--- a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/genconfig_v2ray.lua
+++ b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/genconfig_v2ray.lua
@@ -1,6 +1,7 @@
local ucursor = require 'luci.model.uci'.cursor()
local name = 'vssr'
local json = require 'luci.jsonc'
+local nixio = require 'nixio'
local server_section = arg[1]
local proto = arg[2]
local local_port = arg[3]
@@ -8,6 +9,9 @@ local outbounds_table = {}
local rules_table = {}
function read_conf(file)
+ if not nixio.fs.access(file) then
+ return nil
+ end
local rfile = io.open(file, "r")
local ltable = {}
for line in rfile:lines() do
@@ -18,15 +22,30 @@ function read_conf(file)
return rtable
end
+
local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
local custom_domain = read_conf("/etc/vssr/custom_domain.list")
+local custom_ip = read_conf("/etc/vssr/custom_ip.list")
+
local youtube_domain = read_conf("/etc/vssr/youtube_domain.list")
+local youtube_ip = read_conf("/etc/vssr/youtube_ip.list")
+
local tw_video_domain = read_conf("/etc/vssr/tw_video_domain.list")
+local tw_video_ip = read_conf("/etc/vssr/tw_video_ip.list")
+
local netflix_domain = read_conf("/etc/vssr/netflix_domain.list")
+local netflix_ip = read_conf("/etc/vssr/netflix_ip.list")
+
local disney_domain = read_conf("/etc/vssr/disney_domain.list")
+local disney_ip = read_conf("/etc/vssr/disney_ip.list")
+
local prime_domain = read_conf("/etc/vssr/prime_domain.list")
+local prime_ip = read_conf("/etc/vssr/prime_ip.list")
+
local tvb_domain = read_conf("/etc/vssr/tvb_domain.list")
+local tvb_ip = read_conf("/etc/vssr/tvb_ip.list")
+
local flow_table = {
yotube = {
@@ -35,6 +54,7 @@ local flow_table = {
rules = {
type = 'field',
domain = youtube_domain,
+ ip = youtube_ip,
outboundTag = 'youtube'
}
},
@@ -44,6 +64,7 @@ local flow_table = {
rules = {
type = 'field',
domain = tw_video_domain,
+ ip = tw_video_ip,
outboundTag = 'tw_video'
}
},
@@ -53,6 +74,7 @@ local flow_table = {
rules = {
type = 'field',
domain = netflix_domain,
+ ip = netflix_ip,
outboundTag = 'netflix'
}
},
@@ -62,6 +84,7 @@ local flow_table = {
rules = {
type = 'field',
domain = disney_domain,
+ ip = disney_ip,
outboundTag = 'disney'
}
},
@@ -71,6 +94,7 @@ local flow_table = {
rules = {
type = 'field',
domain = prime_domain,
+ ip = prime_ip,
outboundTag = 'prime'
}
},
@@ -80,6 +104,7 @@ local flow_table = {
rules = {
type = 'field',
domain = tvb_domain,
+ ip = tvb_ip,
outboundTag = 'tvb'
}
},
@@ -89,6 +114,7 @@ local flow_table = {
rules = {
type = 'field',
domain = custom_domain,
+ ip = custom_ip,
outboundTag = 'custom'
}
}
@@ -113,7 +139,7 @@ local bt_rules1 = {
'BitTorrent',
'announce_peer',
'announce.php?passkey='
- },
+ }
}
function gen_outbound(server_node, tags, local_ports)
@@ -210,12 +236,30 @@ function gen_bt_outbounds()
end
if v2ray_flow == '1' then
+
table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080))
for _, v in pairs(flow_table) do
- if(v.rules.domain ~= nil) then
+ if(v.rules.domain ~= nil or v.rules.ip ~= nil) then
local server = ucursor:get_first(name, 'global', v.name .. '_server')
table.insert(outbounds_table, gen_outbound(server, v.name, v.port))
- table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and v.rules or nil)
+
+ if(v.rules.domain ~= nil) then
+ domain_rules = {
+ type = 'field',
+ domain = v.rules.domain,
+ outboundTag = v.rules.outboundTag
+ }
+ table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and domain_rules or nil)
+ end
+
+ if(v.rules.ip ~= nil) then
+ ip_rules = {
+ type = 'field',
+ ip = v.rules.ip,
+ outboundTag = v.rules.outboundTag
+ }
+ table.insert(rules_table, (server ~= nil and server ~= 'nil' ) and ip_rules or nil)
+ end
end
end
else
@@ -246,6 +290,6 @@ local v2ray = {
},
-- 传出连接
outbounds = outbounds_table,
- routing = {domainStrategy = 'AsIs', rules = rules_table}
+ routing = {domainStrategy = 'IPIfNonMatch', rules = rules_table}
}
print(json.stringify(v2ray, 1))
diff --git a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.lua b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.lua
index 6397a5b543..5a7e00c2cc 100644
--- a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.lua
+++ b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/subscribe.lua
@@ -33,6 +33,40 @@ local switch = '0'
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
+function print_r ( t )
+ local print_r_cache={}
+ local function sub_print_r(t,indent)
+ if (print_r_cache[tostring(t)]) then
+ print(indent.."*"..tostring(t))
+ else
+ print_r_cache[tostring(t)]=true
+ if (type(t)=="table") then
+ for pos,val in pairs(t) do
+ if (type(val)=="table") then
+ print(indent.."["..pos.."] => "..tostring(t).." {")
+ sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
+ print(indent..string.rep(" ",string.len(pos)+6).."}")
+ elseif (type(val)=="string") then
+ print(indent.."["..pos..'] => "'..val..'"')
+ else
+ print(indent.."["..pos.."] => "..tostring(val))
+ end
+ end
+ else
+ print(indent..tostring(t))
+ end
+ end
+ end
+ if (type(t)=="table") then
+ print(tostring(t).." {")
+ sub_print_r(t," ")
+ print("}")
+ else
+ sub_print_r(t," ")
+ end
+ print()
+end
+
local log = function(...)
print(os.date('%Y-%m-%d %H:%M:%S ') .. table.concat({...}, ' '))
end
@@ -55,6 +89,43 @@ local function split(full, sep)
end
return result
end
+
+--table去重
+
+local function clone( object )
+ local lookup_table = {}
+ local function copyObj( object )
+ if type( object ) ~= "table" then
+ return object
+ elseif lookup_table[object] then
+ return lookup_table[object]
+ end
+
+ local new_table = {}
+ lookup_table[object] = new_table
+ for key, value in pairs( object ) do
+ new_table[copyObj( key )] = copyObj( value )
+ end
+ return setmetatable( new_table, getmetatable( object ) )
+ end
+ return copyObj( object )
+end
+
+local function table_unique(list)
+ local temp1 = clone(list)
+ local temp2 = clone(list)
+ for k1, v1 in ipairs(temp1) do
+ for k2, v2 in ipairs(temp2) do
+ if v1.alias ~= v2.alias and v1.hashkey == v2.hashkey then
+ table.remove(temp1, k1)
+ table.remove(temp2, k1)
+
+ end
+ end
+ end
+ return temp1
+end
+
-- urlencode
local function get_urlencode(c)
return sformat('%%%02X', sbyte(c))
@@ -385,12 +456,21 @@ local execute = function()
end
end
log('成功解析节点数量: ' .. #nodes)
- end
+ else
+ log(url .. ': 获取内容为空')
+ end
end
end
-- diff
do
- assert(next(nodeResult), '获取不到节点信息,请检查路由器是否能够访问网络,或者订阅链接是否正确')
+ if next(nodeResult) == nil then
+ log("更新失败,没有可用的节点信息")
+ if proxy == '0' then
+ luci.sys.init.start(name)
+ log('订阅失败, 恢复服务')
+ end
+ return
+ end
local add, del = 0, 0
ucic:foreach(
name,
@@ -407,17 +487,24 @@ local execute = function()
setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}})
end
else
- if (old.alias ~= nil) then
- log('忽略手动添加的节点: ' .. old.alias)
+ if not old.alias then
+ if not old.server or old.server_port then
+ ucic:delete(name, old['.name'])
+ else
+ old.alias = old.server .. ':' .. old.server_port
+ log('忽略手动添加的节点: ' .. old.alias)
+ end
else
- log('忽略手动添加的无效节点')
+ log('忽略手动添加的节点: ' .. old.alias)
end
end
end
)
-
+
for k, v in ipairs(nodeResult) do
- for kk, vv in ipairs(v) do
+ -- 如果订阅节点中有相同的节点信息 需要先去重。
+ new_nodes = table_unique(v)
+ for kk, vv in ipairs(new_nodes) do
if not vv._ignore then
local section = ucic:add(name, uciType)
ucic:tset(name, section, vv)
diff --git a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.lua b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.lua
index 525970a7c8..94bcf307a2 100644
--- a/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.lua
+++ b/package/ctcgfw/luci-app-vssr/root/usr/share/vssr/update.lua
@@ -16,11 +16,7 @@ local log = function(...)
end
log('正在更新【GFW列表】数据库')
-if nixio.fs.access('/usr/bin/wget-ssl') then
- refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
-else
- refresh_cmd = 'wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64'
-end
+refresh_cmd = 'wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64'
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
if sret == 0 then
luci.sys.call('/usr/bin/vssr-gfw')
@@ -43,7 +39,7 @@ else
end
log('正在更新【国内IP段】数据库')
-refresh_cmd ="wget -O- 'https://ispip.clang.cn/all_cn.txt' > /tmp/china_ssr.txt 2>/dev/null"
+refresh_cmd ="wget-ssl -O- 'https://ispip.clang.cn/all_cn.txt' > /tmp/china_ssr.txt 2>/dev/null"
sret = luci.sys.call(refresh_cmd)
icount = luci.sys.exec('cat /tmp/china_ssr.txt | wc -l')
if sret == 0 then
@@ -69,12 +65,8 @@ end
if ucic:get_first('vssr', 'global', 'adblock', '') == '1' then
log('正在更新【广告屏蔽】数据库')
local need_process = 0
- if nixio.fs.access('/usr/bin/wget-ssl') then
- refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
- need_process = 1
- else
- refresh_cmd = 'wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf'
- end
+ refresh_cmd = 'wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf'
+ need_process = 1
sret = luci.sys.call(refresh_cmd .. ' 2>/dev/null')
if sret == 0 then
if need_process == 1 then
diff --git a/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/pure.css b/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/pure.css
new file mode 100644
index 0000000000..530341299d
--- /dev/null
+++ b/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/pure.css
@@ -0,0 +1,232 @@
+/*!
+Pure v1.0.1
+Copyright 2013 Yahoo!
+Licensed under the BSD License.
+https://github.com/pure-css/pure/blob/master/LICENSE.md
+*/
+.pure-g {
+ letter-spacing: -.31em;
+ text-rendering: optimizespeed;
+ font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -webkit-flex-flow: row wrap;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ -webkit-align-content: flex-start;
+ -ms-flex-line-pack: start;
+ align-content: flex-start
+}
+
+@media all and (-ms-high-contrast:none),
+(-ms-high-contrast:active) {
+ table .pure-g {
+ display: block
+ }
+}
+
+.opera-only :-o-prefocus,
+.pure-g {
+ word-spacing: -.43em
+}
+
+.pure-u {
+ display: inline-block;
+ zoom: 1;
+ letter-spacing: normal;
+ word-spacing: normal;
+ vertical-align: top;
+ text-rendering: auto
+}
+
+.pure-g [class*=pure-u] {
+ font-family: sans-serif
+}
+
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-1-12,
+.pure-u-1-2,
+.pure-u-1-24,
+.pure-u-1-3,
+.pure-u-1-4,
+.pure-u-1-5,
+.pure-u-1-6,
+.pure-u-1-8,
+.pure-u-10-24,
+.pure-u-11-12,
+.pure-u-11-24,
+.pure-u-12-24,
+.pure-u-13-24,
+.pure-u-14-24,
+.pure-u-15-24,
+.pure-u-16-24,
+.pure-u-17-24,
+.pure-u-18-24,
+.pure-u-19-24,
+.pure-u-2-24,
+.pure-u-2-3,
+.pure-u-2-5,
+.pure-u-20-24,
+.pure-u-21-24,
+.pure-u-22-24,
+.pure-u-23-24,
+.pure-u-24-24,
+.pure-u-3-24,
+.pure-u-3-4,
+.pure-u-3-5,
+.pure-u-3-8,
+.pure-u-4-24,
+.pure-u-4-5,
+.pure-u-5-12,
+.pure-u-5-24,
+.pure-u-5-5,
+.pure-u-5-6,
+.pure-u-5-8,
+.pure-u-6-24,
+.pure-u-7-12,
+.pure-u-7-24,
+.pure-u-7-8,
+.pure-u-8-24,
+.pure-u-9-24 {
+ display: inline-block;
+ zoom: 1;
+ letter-spacing: normal;
+ word-spacing: normal;
+ vertical-align: top;
+ text-rendering: auto
+}
+
+.pure-u-1-24 {
+ width: 4.1667%
+}
+
+.pure-u-1-12,
+.pure-u-2-24 {
+ width: 8.3333%
+}
+
+.pure-u-1-8,
+.pure-u-3-24 {
+ width: 12.5%
+}
+
+.pure-u-1-6,
+.pure-u-4-24 {
+ width: 16.6667%
+}
+
+.pure-u-1-5 {
+ width: 20%
+}
+
+.pure-u-5-24 {
+ width: 20.8333%
+}
+
+.pure-u-1-4,
+.pure-u-6-24 {
+ width: 25%
+}
+
+.pure-u-7-24 {
+ width: 29.1667%
+}
+
+.pure-u-1-3,
+.pure-u-8-24 {
+ width: 33.3333%
+}
+
+.pure-u-3-8,
+.pure-u-9-24 {
+ width: 37.5%
+}
+
+.pure-u-2-5 {
+ width: 40%
+}
+
+.pure-u-10-24,
+.pure-u-5-12 {
+ width: 41.6667%
+}
+
+.pure-u-11-24 {
+ width: 45.8333%
+}
+
+.pure-u-1-2,
+.pure-u-12-24 {
+ width: 50%
+}
+
+.pure-u-13-24 {
+ width: 54.1667%
+}
+
+.pure-u-14-24,
+.pure-u-7-12 {
+ width: 58.3333%
+}
+
+.pure-u-3-5 {
+ width: 60%
+}
+
+.pure-u-15-24,
+.pure-u-5-8 {
+ width: 62.5%
+}
+
+.pure-u-16-24,
+.pure-u-2-3 {
+ width: 66.6667%
+}
+
+.pure-u-17-24 {
+ width: 70.8333%
+}
+
+.pure-u-18-24,
+.pure-u-3-4 {
+ width: 75%
+}
+
+.pure-u-19-24 {
+ width: 79.1667%
+}
+
+.pure-u-4-5 {
+ width: 80%
+}
+
+.pure-u-20-24,
+.pure-u-5-6 {
+ width: 83.3333%
+}
+
+.pure-u-21-24,
+.pure-u-7-8 {
+ width: 87.5%
+}
+
+.pure-u-11-12,
+.pure-u-22-24 {
+ width: 91.6667%
+}
+
+.pure-u-23-24 {
+ width: 95.8333%
+}
+
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-24-24,
+.pure-u-5-5 {
+ width: 100%
+}
\ No newline at end of file
diff --git a/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/vssr.css b/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/vssr.css
index 394ed97a77..b696f7e5f0 100644
--- a/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/vssr.css
+++ b/package/ctcgfw/luci-app-vssr/root/www/luci-static/vssr/css/vssr.css
@@ -1,245 +1,73 @@
@import url("flag-icon.min.css?v=1.16");
@import url("sweetalert2.css?v=1.16");
-/*!
-Pure v1.0.1
-Copyright 2013 Yahoo!
-Licensed under the BSD License.
-https://github.com/pure-css/pure/blob/master/LICENSE.md
-*/
+@import url("pure.css?v=1.16");
-
-.pure-g {
- letter-spacing: -.31em;
- text-rendering: optimizespeed;
- font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -webkit-flex-flow: row wrap;
- -ms-flex-flow: row wrap;
- flex-flow: row wrap;
- -webkit-align-content: flex-start;
- -ms-flex-line-pack: start;
- align-content: flex-start
+/** Common **/
+.pure-img {
+ max-height: 100%;
+ width: auto;
}
-@media all and (-ms-high-contrast:none),
-(-ms-high-contrast:active) {
- table .pure-g {
- display: block
- }
+.pure-imgw {
+ max-width: 100%;
+ height: auto;
}
-.opera-only :-o-prefocus,
-.pure-g {
- word-spacing: -.43em
-}
-
-.pure-u {
- display: inline-block;
- zoom: 1;
- letter-spacing: normal;
- word-spacing: normal;
- vertical-align: top;
- text-rendering: auto
-}
-
-.pure-g [class*=pure-u] {
- font-family: sans-serif
-}
-
-.pure-u-1,
-.pure-u-1-1,
-.pure-u-1-12,
-.pure-u-1-2,
-.pure-u-1-24,
-.pure-u-1-3,
-.pure-u-1-4,
-.pure-u-1-5,
-.pure-u-1-6,
-.pure-u-1-8,
-.pure-u-10-24,
-.pure-u-11-12,
-.pure-u-11-24,
-.pure-u-12-24,
-.pure-u-13-24,
-.pure-u-14-24,
-.pure-u-15-24,
-.pure-u-16-24,
-.pure-u-17-24,
-.pure-u-18-24,
-.pure-u-19-24,
-.pure-u-2-24,
-.pure-u-2-3,
-.pure-u-2-5,
-.pure-u-20-24,
-.pure-u-21-24,
-.pure-u-22-24,
-.pure-u-23-24,
-.pure-u-24-24,
-.pure-u-3-24,
-.pure-u-3-4,
-.pure-u-3-5,
-.pure-u-3-8,
-.pure-u-4-24,
-.pure-u-4-5,
-.pure-u-5-12,
-.pure-u-5-24,
-.pure-u-5-5,
-.pure-u-5-6,
-.pure-u-5-8,
-.pure-u-6-24,
-.pure-u-7-12,
-.pure-u-7-24,
-.pure-u-7-8,
-.pure-u-8-24,
-.pure-u-9-24 {
- display: inline-block;
- zoom: 1;
- letter-spacing: normal;
- word-spacing: normal;
- vertical-align: top;
- text-rendering: auto
-}
-
-.pure-u-1-24 {
- width: 4.1667%
-}
-
-.pure-u-1-12,
-.pure-u-2-24 {
- width: 8.3333%
-}
-
-.pure-u-1-8,
-.pure-u-3-24 {
- width: 12.5%
-}
-
-.pure-u-1-6,
-.pure-u-4-24 {
- width: 16.6667%
-}
-
-.pure-u-1-5 {
- width: 20%
-}
-
-.pure-u-5-24 {
- width: 20.8333%
-}
-
-.pure-u-1-4,
-.pure-u-6-24 {
- width: 25%
-}
-
-.pure-u-7-24 {
- width: 29.1667%
-}
-
-.pure-u-1-3,
-.pure-u-8-24 {
- width: 33.3333%
-}
-
-.pure-u-3-8,
-.pure-u-9-24 {
- width: 37.5%
-}
-
-.pure-u-2-5 {
- width: 40%
-}
-
-.pure-u-10-24,
-.pure-u-5-12 {
- width: 41.6667%
-}
-
-.pure-u-11-24 {
- width: 45.8333%
-}
-
-.pure-u-1-2,
-.pure-u-12-24 {
- width: 50%
-}
-
-.pure-u-13-24 {
- width: 54.1667%
-}
-
-.pure-u-14-24,
-.pure-u-7-12 {
- width: 58.3333%
-}
-
-.pure-u-3-5 {
- width: 60%
-}
-
-.pure-u-15-24,
.pure-u-5-8 {
- width: 62.5%
+ display: flex;
+ align-items: center;
+
}
-.pure-u-16-24,
-.pure-u-2-3 {
- width: 66.6667%
+.gap {
+ margin-right: 0.5rem;
}
-.pure-u-17-24 {
- width: 70.8333%
+
+/** 复写theme **/
+
+.cbi-section {
+
+ border: 0;
+ border-radius: .375rem;
+
+ overflow-x: auto;
+ overflow-y: hidden;
}
-.pure-u-18-24,
-.pure-u-3-4 {
- width: 75%
+.cbi-section-node {
+
+ border: 0;
+ border-radius: .375rem;
+ margin-bottom: 0px;
+ overflow-x: auto;
+ overflow-y: hidden;
+ padding: 0rem 0;
}
-.pure-u-19-24 {
- width: 79.1667%
+#cbi-vssr {
+ overflow-x: hidden;
}
-.pure-u-4-5 {
- width: 80%
-}
-
-.pure-u-20-24,
-.pure-u-5-6 {
- width: 83.3333%
-}
-
-.pure-u-21-24,
-.pure-u-7-8 {
- width: 87.5%
-}
-
-.pure-u-11-12,
-.pure-u-22-24 {
- width: 91.6667%
-}
-
-.pure-u-23-24 {
- width: 95.8333%
-}
-
-.pure-u-1,
-.pure-u-1-1,
-.pure-u-24-24,
-.pure-u-5-5 {
- width: 100%
+#cbi-vssr .panel-title {
+ width: 100%;
+ display: block;
+ margin-bottom: 0;
+ padding: .8755rem 1.5rem;
+
+ margin-bottom: 0rem;
+ letter-spacing: .1rem;
+
+ font-weight: 600;
+ box-sizing: border-box;
}
+/** Top StatusBar **/
.status {
- margin: 1rem -0.5rem 1rem -0.5rem;
+ margin: 0.5rem -0.5rem 1rem -0.5rem;
}
-.block {
+.status .block {
margin: 0.5rem 0.5rem;
padding: 0;
font-weight: normal;
@@ -255,56 +83,28 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
}
-.img-con {
+.status .block .img-con {
margin: 1rem;
}
-.pure-img {
- max-height: 100%;
- width: auto;
-}
-
-.pure-imgw {
- max-width: 100%;
- height: auto;
-}
-
-.green {
+.status .block .green {
font-size: 1.25rem;
color: #2dce89;
}
-.red {
+.status .block .red {
font-size: 1.25rem;
color: #fb6340;
}
-.sk-text-success {
- color: #2dce89;
-}
-
-.sk-text-error {
- color: #fb6340;
-}
-
-.gap {
- margin-right: 0.5rem;
-}
-
-.block img {
+.status .block img {
width: 48px;
height: auto;
float: right;
}
-.pure-u-5-8 {
- display: flex;
- align-items: center;
-
-}
-
-.block h4 {
+.status .block h4 {
font-size: .8125rem;
font-weight: 600;
margin: 1rem;
@@ -312,12 +112,10 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
line-height: 1.8em;
}
-.p-in5 {
- padding: 8px;
-}
+/** Server List **/
-.flag-icon:before {
- position: absolute;
+.p-in5 {
+ margin: 8px !important;
}
.cbi-section-table-row {
@@ -346,6 +144,17 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color: #fff;
}
+.ssr-button:link,
+.ssr-button:hover,
+.ssr-button:focus,
+.ssr-button:visited,
+.ssr-button:active {
+
+ outline: 0;
+ text-decoration: none;
+ box-shadow: none;
+}
+
.cbi-section-table-row.fast .ssr-button {
color: #fff;
}
@@ -363,6 +172,15 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color: #fff !important;
}
+.host_con {
+ position: absolute;
+ left: 0;
+ width: 70px;
+ text-align: left;
+ height: 22px;
+ font-weight: bold;
+}
+
.host_con.fast {
color: #6f9a37;
}
@@ -379,7 +197,19 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color: #fb6340;
}
+.host_ok {
+ color: #fff;
+ background: #2dce89;
+ padding: 0.1rem 0.5rem;
+ border-radius: 0.2rem;
+}
+.host_error {
+ color: #fff;
+ background: #f5365c;
+ padding: 0.1rem 0.5rem;
+ border-radius: 0.2rem;
+}
.loadings.hide {
opacity: 0;
@@ -392,20 +222,20 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
height: 30px;
}
+.flag-icon:before {
+ position: absolute;
+}
.alias {
margin-bottom: 1px;
+ padding-left: 0px;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
}
.incon {
cursor: pointer;
-}
-
-.incon .pure-imgw {
- transition: all 0.2s;
-}
-
-.incon:nth-child(2) {
position: absolute;
left: 0;
top: 0;
@@ -414,10 +244,13 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
border: 0;
border-right: #d1dfed 1px solid;
background-position: top;
-
}
-.incon:nth-child(2) .tp {
+.incon .pure-imgw {
+ transition: all 0.2s;
+}
+
+.incon .tp {
position: absolute;
left: 0;
bottom: 0;
@@ -430,34 +263,29 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
background: #525f7f;
}
-.incon:nth-child(3) {
- padding-left: 0px;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
-}
-
-.incon:nth-child(5),
-.incon:nth-child(6) {
- display: none;
-}
.cbi-section-table-cell {
text-align: right;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ position: relative;
}
.ssr-button {
background: none;
+ border: none;
color: #525f7f;
- padding: 0 0 0 0;
+ padding: 0 0.2rem 0 0;
height: auto;
line-height: 1.5em;
+ box-shadow: none;
}
.ssr-button:hover,
.ssr-button:focus,
.ssr-button:active {
- color: #525f7f;
+
outline: 0;
text-decoration: none;
box-shadow: none;
@@ -472,37 +300,18 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color: #fff !important;
background-color: #337ab7 !important;
border-color: #2e6da4 !important;
+ background-image: none;
float: right;
margin-right: 18px;
- margin-top: 1rem;
+ margin-top: .25rem !important;
+ outline: none;
}
-.cbi-section-table-cell {
- position: relative;
+.cbi-button-check:focus {
+ outline: none;
}
-.host_con {
- position: absolute;
- left: 0;
- width: 70px;
- text-align: left;
- height: 22px;
- font-weight: bold;
-}
-
-.host_ok {
- color: #fff;
- background: #2dce89;
- padding: 0.1rem 0.5rem;
- border-radius: 0.2rem;
-}
-
-.host_error {
- color: #fff;
- background: #f5365c;
- padding: 0.1rem 0.5rem;
- border-radius: 0.2rem;
-}
+/** Bottom StatusBar **/
footer.mobile-hide {
display: block;
@@ -537,6 +346,7 @@ footer.mobile-hide {
.status-bar .inner .status-info {
font-weight: bold;
+ line-height: 1.5em;
}
.status-bar .icon-con {
@@ -544,6 +354,8 @@ footer.mobile-hide {
text-align: right;
}
+/** Node choose panel **/
+
.choose_node .gap {
margin: 0.5rem 1rem;
position: relative;
@@ -553,66 +365,8 @@ footer.mobile-hide {
width: 100% !important;
}
-@media screen and (max-width: 2000px) {
- .pure-u-1-5 {
- width: 25%;
- }
-}
-@media screen and (max-width: 1600px) {
- .pure-u-1-5 {
- width: 33.33333333%;
- }
-}
-
-@media screen and (max-width: 1200px) {
- .pure-u-1-5 {
- width: 50%;
- }
-
- .status .pure-u-1-5 {
- width: 33.333%;
- }
-}
-
-@media screen and (max-width: 700px) {
- .pure-u-1-4 {
- width: 50%;
- }
-
- .pure-u-1-2 {
- width: 100%;
- }
-
- .pure-u-1-5 {
- width: 100%;
- font-size: 14px;
- }
-
- .status .pure-u-1-5 {
- width: 50%;
- }
-
- .cbi-button-add {
- position: fixed;
- padding: 0.3rem 0.5rem;
- z-index: 1000;
- width: 50px !important;
- height: 50px;
- bottom: 90px;
- right: 5px;
- font-size: 16px;
- border-radius: 50%;
- display: block;
- background-color: #fb6340 !important;
- border-color: #fb6340 !important;
- box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
- }
-
- .choose_node .pure-u-1-2 {
- width: 50%;
- }
-}
+/** Subscribe panel **/
.modals-bg {
position: fixed;
@@ -625,7 +379,7 @@ footer.mobile-hide {
transition: all 0.2s;
}
-.modals-bg.hide{
+.modals-bg.hide {
visibility: hidden;
opacity: 0;
}
@@ -651,7 +405,7 @@ footer.mobile-hide {
transform: scale(1);
}
-.modals.hide{
+.modals.hide {
visibility: hidden;
opacity: 0;
transform: scale(0.5);
@@ -688,7 +442,27 @@ footer.mobile-hide {
overflow: hidden
}
-@media screen and (max-width: 1024px) {
+@media screen and (max-width: 2000px) {
+ .pure-u-1-5 {
+ width: 25%;
+ }
+}
+
+@media screen and (max-width: 1600px) {
+ .pure-u-1-5 {
+ width: 33.33333333%;
+ }
+}
+
+@media screen and (max-width: 1200px) {
+ .pure-u-1-5 {
+ width: 50%;
+ }
+
+ .status .pure-u-1-5 {
+ width: 33.333%;
+ }
+
.modals {
position: fixed;
z-index: 100;
@@ -704,6 +478,45 @@ footer.mobile-hide {
}
@media screen and (max-width: 700px) {
+ .pure-u-1-4 {
+ width: 50%;
+ }
+
+ .pure-u-1-2 {
+ width: 100%;
+ }
+
+ .pure-u-1-5 {
+ width: 100%;
+ font-size: 14px;
+ }
+
+ .status .pure-u-1-5 {
+ width: 50%;
+ }
+
+ .cbi-button-add {
+ position: fixed;
+ padding: 0.3rem 0.5rem;
+ z-index: 1000;
+ width: 50px !important;
+ height: 50px !important;
+ bottom: 90px;
+ color: #fff;
+ right: 5px;
+ font-size: 16px;
+ border-radius: 50%;
+ display: block;
+ background-color: #fb6340 !important;
+ border-color: #fb6340 !important;
+ box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
+ background-image: none;
+ }
+
+ .choose_node .pure-u-1-2 {
+ width: 50%;
+ }
+
.modals-bg {
position: fixed;
z-index: 100000;
@@ -732,6 +545,14 @@ footer.mobile-hide {
height: 2.5em;
text-align: right;
}
+
+ .p-in5 {
+ padding-bottom: 3rem;
+ }
+
+ .cbi-page-actions {
+ padding-bottom: 4rem !important;
+ }
}
@media (prefers-color-scheme: dark) {
@@ -753,4 +574,5 @@ footer.mobile-hide {
.ssr-button {
color: #ccc;
}
+
}
\ No newline at end of file